commit 7bbefd61593c2f7c47963a634472ca9561f74bdb Author: Dominic Reich Date: Mon Oct 26 11:16:41 2020 +0100 initial commit (partly taken over from YSF Dashboard (by OE7DRT)) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..79f9a60 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +pub diff --git a/conf.php b/conf.php new file mode 100644 index 0000000..b9b3d78 --- /dev/null +++ b/conf.php @@ -0,0 +1,33 @@ + diff --git a/dash.min.css b/dash.min.css new file mode 100644 index 0000000..0b9d846 --- /dev/null +++ b/dash.min.css @@ -0,0 +1,370 @@ +/*! + * CSS File for OE7DRT Dashboard + */ + +#toptable, #lhtable { + margin-bottom: 0.5em; +} + +.container { + width: 95%; + text-align: left; + margin: auto; + background : #ffffff; + border-radius: 10px 10px 10px 10px; + -moz-border-radius: 10px 10px 10px 10px; + -webkit-border-radius: 10px 10px 10px 10px; + -khtml-border-radius: 10px 10px 10px 10px; + -ms-border-radius: 10px 10px 10px 10px; + box-shadow: 3px 3px 3px #707070; +} + +body, font { + font: 12px verdana,arial,sans-serif; + color: #ffffff; +} + +.header { + background : #2d2d2d; + text-decoration : none; + color : #ffffff; + font-family : verdana, arial, sans-serif; + text-align : left; + padding : 5px 5px 5px 5px; + border-radius: 10px 10px 0 0; + -moz-border-radius: 10px 10px 0px 0px; + -webkit-border-radius: 10px 10px 0px 0px; + -khtml-border-radius: 10px 10px 0px 0px; + -ms-border-radius: 10px 10px 0px 0px; + overflow-wrap: break-word; + } + +.content { + padding : 5px 5px 5px 5px; + color : #000000; + background : #ffffff; + text-align: center; + font-size: 1.4em; + overflow: auto; +} + +.contentwide { + padding: 5px 5px 5px 5px; + color: #000000; + background: #ffffff; + text-align: center; + font-size: 1.4em; +} + +.contentwide h2 { + color: #000000; + font: 1em verdana,arial,sans-serif; + text-align: center; + font-weight: bold; + padding: 0px; + margin: 0px; +} + +.footer { + background : #2d2d2d; + text-decoration : none; + color : #ffffff; + font-family : verdana, arial, sans-serif; + font-size : 9px; + text-align : center; + padding : 10px 5px 10px 5px; + border-radius: 0 0 10px 10px; + -moz-border-radius: 0px 0px 10px 10px; + -webkit-border-radius: 0px 0px 10px 10px; + -khtml-border-radius: 0px 0px 10px 10px; + -ms-border-radius: 0px 0px 10px 10px; + clear : both; + overflow-wrap: break-word; +} + +#tail { + height: 450px; + width: 805px; + overflow-y: scroll; + overflow-x: scroll; + color: #00ff00; + background: #000000; +} + +table { + vertical-align: middle; + text-align: center; + empty-cells: show; + padding-left: 0px; + padding-right: 0px; + padding-top: 0px; + padding-bottom: 0px; + border-collapse:collapse; + border-color: #000000; + border-style: solid; + border-spacing: 4px; + border-width: 2px; + text-decoration: none; + color: #ffffff; + background: #000000; + font-family: verdana,arial,sans-serif; + width: 80%; + white-space: nowrap; +} + +table th { + font-family: "Lucidia Console",Monaco,monospace; + text-shadow: 1px 1px #3d3d3d; + text-decoration: none; + background: #2d2d2d; + border: 1px solid #c0c0c0; +} + +table tr:nth-child(even) { + background: #f7f7f7; +} + +table tr:nth-child(odd) { + background: #d0d0d0; +} + +table td { + color: #000000; + font-family: "Lucidia Console",Monaco,monospace; + text-decoration: none; + border: 1px solid #000000; + overflow-x: hidden; +} + +body { + background: #edf0f5; + color: #000000; +} + +a { + text-decoration:none; + +} + +a:link, a:visited { + text-decoration: none; + color: #0000e0; + font-weight: normal; +} + +a.tooltip, a.tooltip:link, a.tooltip:visited, a.tooltip:active { + text-decoration: none; + position: relative; + color: #FFFFFF; +} + +a.tooltip:hover { + text-shadow: none; + text-decoration: none; + color: #FFFFFF; + background: transparent; +} + +a.tooltip span { + text-shadow: none; + text-decoration: none; + display: none; +} + +a.tooltip:hover span { + text-shadow: none; + text-decoration: none; + display: block; + position: absolute; + top: 20px; + left: 0; + width: 200px; + z-index: 100; + color: #000000; + border:1px solid #000000; + background: #f7f7f7; + font: 12px Verdana, sans-serif; + text-align: left; +} + +a.tooltip span b { + text-shadow: none; + text-decoration: none; + display: block; + color: #000000; + margin: 0; + padding: 0; + font-size: 12px; + font-weight: bold; + border: 0px; + border-bottom: 1px solid black; + background: #d0d0d0; +} + +a.tooltip2, a.tooltip2:link, a.tooltip2:visited, a.tooltip2:active { + text-shadow: none; + text-decoration: none; + position: relative; + font-weight: bold; + color: #000000; +} + +a.tooltip2:hover { + text-shadow: none; + text-decoration: none; + color: #000000; + background: transparent; +} + +a.tooltip2 span { + text-shadow: none; + text-decoration: none; + display: none; +} + +a.tooltip2:hover span { + text-shadow: none; + text-decoration: none; + display: block; + position: absolute; + top: 20px; + left: 0; + width: 200px; + z-index: 100; + color: #000000; + border:1px solid #000000; + background: #f7f7f7; + font: 12px Verdana, sans-serif; + text-align: left; +} + +a.tooltip2 span b { + text-shadow: none; + text-decoration: none; + display: block; + color: #000000; + margin: 0; + padding: 0; + font-size: 12px; + font-weight: bold; + border: 0px; + border-bottom: 1px solid black; + background: #d0d0d0; +} + +ul { + padding: 5px; + margin: 10px 0; + list-style: none; + float: left; +} + +ul li { + float: left; + display: inline; /*For ignore double margin in IE6*/ + margin: 0 10px; +} + +ul li a { + text-decoration: none; + float:left; + color: #999; + cursor: pointer; + font: 900 14px/22px "Arial", Helvetica, sans-serif; +} + +ul li a span { + margin: 0 10px 0 -10px; + padding: 1px 8px 5px 18px; + position: relative; /*To fix IE6 problem (not displaying)*/ + float:left; +} + +ul.mmenu li a.current, ul.mmenu li a:hover { + background: url(/images/buttonbg.png) no-repeat top right; + color: #0d5f83; +} + +ul.mmenu li a.current span, ul.mmenu li a:hover span { + background: url(/images/buttonbg.png) no-repeat top left; +} + +h1 { + text-shadow: 2px 2px #000000; + text-align: center; +} + +/* CSS Toggle Code here */ +.toggle { + position: absolute; + margin-left: -9999px; + visibility: hidden; +} + +.toggle + label { + display: block; + position: relative; + cursor: pointer; + outline: none; +} + +input.toggle-round-flat + label { + padding: 1px; + width: 33px; + height: 18px; + background-color: #dddddd; + border-radius: 10px; + transition: background 0.4s; +} + +input.toggle-round-flat + label:before, +input.toggle-round-flat + label:after { + display: block; + position: absolute; + content: ""; +} + +input.toggle-round-flat + label:before { + top: 1px; + left: 1px; + bottom: 1px; + right: 1px; + background-color: #fff; + border-radius: 10px; + transition: background 0.4s; +} + +input.toggle-round-flat + label:after { + top: 2px; + left: 2px; + bottom: 2px; + width: 16px; + background-color: #dddddd; + border-radius: 12px; + transition: margin 0.4s, background 0.4s; +} + +input.toggle-round-flat:checked + label { + background-color: #2d2d2d; +} + +input.toggle-round-flat:checked + label:after { + margin-left: 14px; + background-color: #2d2d2d; +} + +/* Tame Firefox Buttons */ +@-moz-document url-prefix() { + select, + input { + margin : 0; + padding : 0; + border-width : 1px; + font : 12px verdana,arial,sans-serif; + } + input[type="button"], button, input[type="submit"] { + padding : 0px 3px 0px 3px; + border-radius : 3px 3px 3px 3px; + -moz-border-radius : 3px 3px 3px 3px; + } +} diff --git a/func.php b/func.php new file mode 100644 index 0000000..c5d1836 --- /dev/null +++ b/func.php @@ -0,0 +1,211 @@ += 60 ) { + // in minutes + $minutes = intval( $uptime / 60 ); + $seconds = $uptime % 60; + if( $minutes >= 60 ) { + $hours = intval( $minutes / 60 ); + $minutes = $minutes % 60; + if( $hours >= 24 ) { + $days = intval( $hours / 24 ); + $hours = $hours % 24; + $out = "$days days $hours hours $minutes minutes and $seconds seconds"; + } else { + // no days, only hours minutes and seconds + $out = "$hours hours $minutes minutes and $seconds seconds"; + } + } else { + // mintes < 60 only minuts, hours + $out = "$minutes minutes and $seconds seconds"; + } + } else { + // only seconds + $out = "$uptime seconds"; + } + + return $out; +} + +function linkCallsign( $callsign ) { + $tmp = explode( "-", $callsign ); + $call = $tmp[0]; + $suffix = $tmp[1]; + if( !empty( $suffix )) { + $suffix="-$suffix"; + } + if( !is_numeric( $call )) { + $call = "$call" . "$suffix"; + } elseif( strlen( $call ) == 7 ) { + $call = "$call"; + } + + return $call; +} + +function rssiCalc( $val ) { + if( $val > -53 ) $rssi = "S9+40dB"; + else if( $val > -63 ) $rssi = "S9+30dB"; + else if( $val > -73 ) $rssi = "S9+20dB"; + else if( $val > -83 ) $rssi = "S9+10dB"; + else if( $val > -93 ) $rssi = "S9"; + else if( $val > -99 ) $rssi = "S8"; + else if( $val > -105 ) $rssi = "S7"; + else if( $val > -111 ) $rssi = "S6"; + else if( $val > -117 ) $rssi = "S5"; + else if( $val > -123 ) $rssi = "S4"; + else if( $val > -129 ) $rssi = "S3"; + else if( $val > -135 ) $rssi = "S2"; + else if( $val > -141 ) $rssi = "S1"; + return "$rssi ($val dBm)"; +} + +function printTable( $time, $callsign, $dgid, $duration, $repeater, $loss = "---", $ber = "---" ) { + if( $duration >= 60 ) { + $min = str_pad( intval( $duration / 60 ), 2, "0", STR_PAD_LEFT ); + $sec = str_pad( $duration % 60, 2, "0", STR_PAD_LEFT ); + $duration = "$min:$sec"; + } else { + $duration = "00:" . str_pad( $duration, 2, "0", STR_PAD_LEFT ); + } + echo " \n" . + "$time\n" . + "" . linkCallsign( $callsign ) ."\n" . + "$dgid\n" . + "$repeater\n" . + "$duration\n" . + "$loss\n" . + "$ber\n" . + "\n"; +} + +function getLastHeard($limit = MAXENTRIES) { + $logPath = LOGPATH."/".MMDVM_PREFIX."-*.log"; + //$logLines = explode( "\n", `egrep -h "network (data|watchdog)|RF end of transmission" $logPath | tail -$limit` ); + //$logLines = explode( "\n", `egrep -h "YSF" $logPath | tail -$limit` ); + $logLines = explode( "\n", `egrep -h "YSF," $logPath` ); + + $oldline = ""; + + $time = ""; + $loss = ""; + $ber = ""; + $rssi = ""; + $call = ""; + $duration = ""; + $repeater = ""; + + $printLines = []; + + foreach( $logLines as $line ) { + if( empty( $oldline ) && strpos( $line, "network watchdog" )) { + // $oldine=$line; + continue; + } + + if( strpos( $line, "RF end of transmission" )) { + $time = date( "Y-m-d H:i:s", strtotime( substr( $line, 3, 23 )." UTC" )); + $callsign = substr( $line, 69, strpos( $line, "to" ) - 69 ); + $dgid = substr( $line, 89, strpos( $line, ",", 89 ) - 89 ); + $duration = round( trim( substr( $line, 92, strpos( $line, "seconds,", 92 ) - 92 ), " ," )); + $rssi_values = explode( "/", substr( $line, 113, strpos( $line, "dBm", 113 ) - 113 )); + $rssi = rssiCalc( round( array_sum( $rssi_values ) / count( $rssi_values ))); + $loss = "---"; + $ber = substr( $line, 111, strpos( $line, ",", 111 ) - 111 ); + if( empty( $ber )) $ber = "---"; + $repeater = $rssi; // use this testwise, debug + } elseif( strpos( $line, "network data" )) { + if( strpos( $oldline, "network data" )) { + $oldline = $line; + continue; + } else { + $time = date( "Y-m-d H:i:s", strtotime( substr( $line, 3, 23 )." UTC" )); + $old_time = strtotime( $time ); + $oldline=$line; + continue; + } + } elseif( strpos( $line, "network watchdog" )) { + $time = date( "Y-m-d H:i:s", strtotime( substr( $oldline, 3, 23 )." UTC" )); + $callsign = substr( $oldline, 59, strpos( $oldline, "to" ) - 59 ); + $dgid = substr( $oldline, 79, strpos( $oldline, "at " ) - 79 ); + $new_time = strtotime( date( "Y-m-d H:i:s", strtotime( substr( $oldline, 3, 23 )." UTC" ))); + // echo "
\$callsign: $callsign at \$dgid: $dgid\n\$old_time: ".date("Y-m-d H:i:s", $old_time ).
+		  // "\n\$new_time: ".date("Y-m-d H:i:s", $new_time )."
\n"; + // $duration = intval(( $new_time - $old_time )) . ".0"; + $duration = intval(( $new_time - $old_time )); + $repeater = substr( $oldline, strpos( $oldline, "at " ) + 3, strpos( $oldline, " ", strpos( $oldline, "at " ) + 3) - strpos( $oldline, "at " ) + 3 ); + $loss = substr( $line, 75, strpos( $line, "%", 75 ) - 74 ); + if( $loss == "0%" ) { + $loss = "-x-"; + } + $ber = substr( $line, 96, strpos( $line, "%", 96 ) - 95 ); + if( $ber == "0.0%" ) $ber = "-x-"; + } else { + continue; + } + // echo "
\$callsign: $callsign at \$dgid: $dgid\n\$old_time: ".date("Y-m-d H:i:s", $old_time ).
+      //   "\n\$new_time: ".date("Y-m-d H:i:s", $new_time )."
\n"; + + // echo "
OLD LINE: $oldline\nLINE: $line\n
\n"; + + $tmp = []; + $tmp['time'] = $time; + $tmp['callsign'] = $callsign; + $tmp['dgid'] = $dgid; + $tmp['duration'] = $duration; + $tmp['repeater'] = $repeater; + $tmp['loss'] = $loss; + $tmp['ber'] = $ber; + array_unshift( $printLines, $tmp ); + unset( $tmp ); + + // Lastly we set $oldline as the actual line + $oldline = $line; + } + + $c = 0; + + foreach( $printLines as $key=>$line ) { + printTable( + $line['time'], + $line['callsign'], + $line['dgid'], + $line['duration'], + $line['repeater'], + $line['loss'], + $line['ber'] + ); + if( ++$c >= MAXENTRIES ) break; + } // end foreach $printLines +} // end function + +function printLogs($limit = MAXLOGENTRIES) { + $logPath = LOGPATH."/*-".gmdate("Y-m-d").".log"; + $logLines = explode("\n", `tail -n $limit $logPath`); + + echo "\n\n

DEBUG LOGFILES OUTPUT

\n"; + echo "
\n";
+
+  foreach( $logLines as $line ) {
+    if ( substr( $line, 0, 4) == "==> " ) {
+      echo "$line\n";
+    } else {
+      echo "$line\n";
+    }
+  }
+
+  echo "\n
\n\n\n"; + return 0; +} + diff --git a/index.php b/index.php new file mode 100644 index 0000000..1af68ee --- /dev/null +++ b/index.php @@ -0,0 +1,104 @@ + + + + + + OE7DRT DMR Hotspot Dashboard + + + + +
+
+
+ Hostname: ()
+ +
+
\n"; + echo "Uptime: " . getUptime(); + ?>
+

Dashboard for DMR Hotspot OE7DRT

+

+ Dashboard + | + IPSC2-OE-DMO + | + IPSC2-OE-MASTER + | + IPSC2-OE-MLINK + | + My personal website +

+
+
+
+
+ + + + + + + + + + + + + +
ModelCPU Freq.LoadTemp.
()
+ + + + + + + + + + + + +
Time ()CallsignSlotTalkgroupDur(s)LossBER
+ +
+ + + + +