Commit e2b98afe authored by Oleg Dzhimiev's avatar Oleg Dzhimiev
Browse files

+system information

parent 5dae054c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
# Runs 'make', 'make install', and 'make clean' in specified subdirectories
SUBDIRS := src/php_top src/python_tests src/debugfs-webgui src/jp4-canvas src/update src/eyesis4pi src/index src/pointers src/snapshot src/jp4-viewer src/photofinish src/multicam # src1
SUBDIRS := src/php_top src/python_tests src/debugfs-webgui src/jp4-canvas src/update src/eyesis4pi src/index src/pointers src/snapshot src/jp4-viewer src/photofinish src/multicam src/diagnostics # src1
INSTALLDIRS = $(SUBDIRS:%=install-%)
CLEANDIRS =   $(SUBDIRS:%=clean-%)

+21 −0
Original line number Diff line number Diff line
DOCUMENTROOT=$(DESTDIR)/www/pages
OWN = -o root -g root
INSTDOCS = 0644
INSTALL = install
DOCS=       index.html \
            diagnostics.js \
            diagnostics.css

PHP_SCRIPTS= diagnostics.php

all:
	@echo "make all in src"

install:
	@echo "make install in src"
	$(INSTALL) $(OWN) -d $(DOCUMENTROOT) $(DOCUMENTROOT)/diagnostics
	$(INSTALL) $(OWN) -m $(INSTDOCS) $(DOCS) $(DOCUMENTROOT)/diagnostics
	$(INSTALL) $(OWN) -m $(INSTDOCS) $(PHP_SCRIPTS) $(DOCUMENTROOT)

clean:
	@echo "make clean in src"
+48 −0
Original line number Diff line number Diff line
#display_general, #display_pars, #display_ts{
  padding:5px;
}

#gen_table th, #pars_table th, #ts_table th{
  padding: 2px 5px;
  text-align:center;
  border: 1px solid rgb(150,150,150);
}

#gen_table td{
  padding: 2px 5px;
  text-align:center;
  border: 1px solid rgb(150,150,150);
}

#pars_table td, #ts_table td{
  padding: 0px 5px;
  border: 1px solid rgb(150,150,150);
}

.center{
  text-align:center;
}

.right{
  text-align:right;
}

.left{
  text-align:left;
}

h4{
  padding:0px 5px;
}

.vtop{
  vertical-align:top;
}

.timestamps{
  font-size: 0.9em;
}

.framenumbers{
  font-size: 0.9em;
}
 No newline at end of file
+520 −0
Original line number Diff line number Diff line

$(function(){
  init();
});

function parseURL(){
    var parameters=location.href.replace(/\?/ig,"&").split("&");
    for (var i=0;i<parameters.length;i++) parameters[i]=parameters[i].split("=");
    for (var i=1;i<parameters.length;i++) {
        switch (parameters[i][0]) {
            case "ip":
              ips_from_url = true;
              ips_str = parameters[i][1];
              ips_str = ips_str.replace(/,|;/gm,'\n');
              addrs_str2ips(ips_str);
              break;
        }
    }
}

function init(){
  parseURL();
  if (ips.length==0){
    ips.push(location.host);
  }
  for(var i=0;i<ips.length;i++){
    get_system_info(ips[i]);
  }
}

var ips = [];
var sysinfo = [];

function addrs_str2ips(str){
  var tmp_ips = str.split("\n");
  for(var i=0;i<tmp_ips.length;i++){
    str = tmp_ips[i].replace(/,|;|^\s+|\s+$/gm,'');
    if (str!==""){
      ips.push(str);
    }
  }
}


function get_system_info(ip){

  $.ajax({
    url: "http://"+ip+"/diagnostics.php",
    ip: ip,
    success:function(res){

      sysinfo.push(res);

      if (sysinfo.length==ips.length){
        analyze_sysinfo();
      }

    }
  }).fail(function(e){
    console.log("ERROR: Failed to get system info for "+this.ip);
    sysinfo.push("");
  });

}

function analyze_sysinfo(){

  // filter out empty
  for(var i=0;i<sysinfo.length;i++){
    if (sysinfo[i]==""){
      sysinfo.splice(i,1);
    }
  }

  for(var i=0;i<sysinfo.length;i++){
    var f = $(sysinfo[i]);
    var tr = [
      '<tr>',
      '  <td>'+f.find("camera").attr('ip')+'</td>',
      '  <td title=\''+f.find("systime").text()+'\'>'+f.find("systimestamp").text()+'</td>',
      '  <td>'+f.find("uptime").text()+'</td>',
      '  <td class=\'right\'>'+parse_temperature(f.find("temperature"))+'</td>',
      '  <td class=\'right\'>'+parse_storage(f.find("storage"))+'</td>',
      '  <td class=\'right\'>'+parse_recorder(f.find("recorder").text())+'</td>',
      '  <td class=\'right\'>'+f.find("master_port").text()+'</td>',
      '  <td class=\'right\'>'+parse_gps(f.find("gps"))+'</td>',
      '  <td class=\'right\'></td>',
      '',
      '</tr>'
    ].join('\n');

    $("#gen_table").append(tr);

    var colspan = $("#pars_table").find("th").length;

    var tr2 = [
      '<tr><td style=\'background:rgba(240,240,240,0.5);\' class=\'left\' colspan=\''+colspan+'\'><b>'+f.find("camera").attr('ip')+'</b></td></tr>'
    ];

    var ports = f.find('port');

    for(var j=0;j<ports.length;j++){
      tr2.push(parse_port(ports[j]));
    }

    $("#pars_table").append(tr2.join('\n'));

  }

  parse_timestamps();

}

function parse_timestamps(){

  for(var i=0;i<sysinfo.length;i++){
    var f = $(sysinfo[i]);
    var ports = f.find('port');

    var thead = [];
    thead.push('<tr>');
    for(var j=0;j<ports.length;j++){
      thead.push('<th>p</th><th>frame</th><th>timestamp</th>');
    }
    thead.push('</tr>');

    $("#ts_table").append(thead);

    var colspan = $("#ts_table").find("th").length;

    var tr3 = [
      '<tr><td style=\'background:rgba(240,240,240,0.5);\' class=\'left\' colspan=\''+colspan+'\'><b>'+f.find("camera").attr('ip')+'</b></td></tr>'
    ];

    tr3.push('<tr>');

    for(var j=0;j<ports.length;j++){
      tr3.push(pt_parse_port(i,ports[j]));
    }

    tr3.push('</tr>');

    $("#ts_table").append(tr3.join('\n'));

  }

  // analyze, search forware
  analyze_timestamps();

}

var BAT = [];
var BAF = [];
var TOTAL_PORTS = 0;
var RES = [];

function analyze_timestamps(){

  // create an array
  for(var i=0;i<sysinfo.length;i++){
    var f = $(sysinfo[i]);
    var ports = f.find('port');
    BAT[i] = [];
    BAF[i] = [];
    TOTAL_PORTS += ports.length;
    for(var j=0;j<ports.length;j++){
      var ts = $(ports[j]).find('ts');
      BAT[i][j] = [];
      BAF[i][j] = [];
      for(var k=0;k<ts.length;k++){
        BAT[i][j][k] = $(ts[k]).text();
        BAF[i][j][k] = $(ts[k]).attr('frame');
      }
    }
  }

  for(var i=0;i<BAT.length;i++){
    for(var j=0;j<BAT[i].length;j++){
      for(var k=0;k<BAT[i][j].length;k++){
        var res = process_timestamp(BAT[i][j][k],BAF[i][j][k]);
      }
    }
  }

  var color_inc = 256/(sysinfo.length*TOTAL_PORTS);

  for(var ts in RES){
    var count = RES[ts].count;
    var r = (count==1)?200:0;
    var g = parseInt((count-1)*color_inc);
    var b = 0;
    color = "rgba("+r+","+g+","+b+",1)";
    console.log(ts+" "+count+" "+color);
    $(".timestamps[ts='"+ts+"']").css({
      color: color
    });
  }

}

function process_timestamp(ts,fr){

  if (RES[ts]==null){
    RES[ts] = {count: 1, frame:[fr]}
  }else{
    RES[ts].count++;
    RES[ts].frame.push(fr);
  }

}

function pt_parse_port(cn,port){

  var p = $(port);

  var pn = p.attr('index');
  var mux = p.attr('mux');
  var sensors = p.attr('sensor');

  var res = [
    '  <td class=\'center\'>'+pn+'</td>',
    '  <td class=\'center vtop\'>'+pt_parse_framenumbers(cn,pn,p.find('ts'))+'</td>',
    '  <td class=\'center vtop\'>'+pt_parse_timestamps(cn,pn,p.find('ts'))+'</td>',
  ].join('\n');

  return res;
}

function pt_parse_timestamps(cn,pn,ts){

  res = [];

  for(var i=0;i<ts.length;i++){
    var frame = $(ts[i]).attr('frame');
    var timestamp = $(ts[i]).text();
    res.push("<span class='timestamps' ts='"+timestamp+"' fn='"+frame+"'>"+timestamp+"</span>");
  }

  return res.join('<br/>');
}

function pt_parse_framenumbers(cn,pn,ts){

  res = [];

  for(var i=0;i<ts.length;i++){
    var frame = $(ts[i]).attr('frame');
    var timestamp = $(ts[i]).text();
    res.push("<span class='framenumbers' ts='"+timestamp+"' fn='"+frame+"'>"+frame+"</span>");
  }

  return res.join('<br/>');

}

function parse_port(port){

  var p = $(port);

  var pn = p.attr('index');
  var mux = p.attr('mux');
  var sensors = p.attr('sensor');

  var res = [
    '<tr>',
    '  <td class=\'center\'>'+pn+'</td>',
    '  <td>'+mux+'</td>',
    '  <td>'+sensors+'</td>',
    '  <td class=\'center\'>'+pp_parse_sensor_run(p.find('sensor_run'))+'</td>',
    '  <td class=\'center\'>'+pp_parse_sensor_run(p.find('compressor_run'))+'</td>',
    '  <td class=\'center\'>'+pp_parse_format(p.find('color'))+'</td>',
    '  <td class=\'center\'>'+p.find('quality').text()+'%</td>',
    '  <td class=\'center\'>'+p.find('woi_width').text()+'x'+p.find('woi_height').text()+'</td>',
    '  <td class=\'center\'>'+p.find('trig').text()+'</td>',
    '  <td class=\'center\'>'+p.find('trig_master').text()+'</td>',
    '  <td class=\'center\'>'+pp_parse_trig_period(p.find('trig_period').text(),p.find('expos').text())+'</td>',
    '  <td class=\'center\'>'+pp_parse_trig_p(p.find('trig_out').text())+'</td>',
    '  <td class=\'center\'>'+pp_parse_trig_p(p.find('trig_condition').text())+'</td>',
    '  <td class=\'right\'>'+pp_parse_expos(p.find('expos').text(),p.find('trig_period').text())+'</td>',
    '  <td class=\'center\'>'+pp_parse_gain(p.find('gainr').text())+'</td>',
    '  <td class=\'center\'>'+pp_parse_gain(p.find('gaing').text())+'</td>',
    '  <td class=\'center\'>'+pp_parse_gain(p.find('gainb').text())+'</td>',
    '  <td class=\'center\'>'+pp_parse_gain(p.find('gaingb').text())+'</td>',
    '</tr>'
  ].join('\n');

  return res;

}

function pp_parse_expos(str,period){

  var exp = pp_calc_exposure(str);
  var per = pp_calc_trig_period(period);

  /*
  if (v>100){
    color = "rgb(240,160,0)";
  }
  */

  var color = "";
  if (exp>per*1000){
    color = "rgb(230,0,0)";
  }

  var res = "<span style='color:"+color+";'>"+exp+" ms</span>";
  return res;

}

function pp_parse_gain(str){

  var v = parseInt(str);
  v = v/0x10000;

  color = "";

  if (v>5){
    color = "rgb(240,160,0)";
  }

  res = "<span style='color:"+color+";'>"+v.toFixed(2)+"</span>";

  return res;
}

function pp_parse_trig_p(str){

  var v = parseInt(str);
  return "0x"+v.toString(16);

}

function pp_calc_trig_period(str){
  var clock = 100000000;
  var v = parseInt(str);
  v = v/clock;
  return v;
}

function pp_calc_exposure(str){
  var v = parseInt(str);
  v = v/1000;
  return v;
}

function pp_parse_trig_period(period,str){

  var per = pp_calc_trig_period(period);
  var exp = pp_calc_exposure(str);

  var fps = (1/per);

  if (per<1){
    res = (per*1000)+" ms";
  }else{
    res = per+" s";
  }

  var color = "";
  if (exp>per*1000){
    color = "rgb(230,0,0)";
  }

  res = "<span style='color:"+color+";'>"+res+" ("+fps+" fps)</span>";

  return res;

}

function pp_parse_format(str){
  var fmt = $(str).text();

  color = "";

  if (fmt==5){
    fmt = "jp4";
  }else if (fmt==0){
    color = "rgb(240,160,0)";
    fmt = "jpeg";
  }else{
    color = "rgb(230,0,0)";
    fmt = "else";
  }

  res = "<span style='color:"+color+";'>"+fmt+"</span>";

  return res;

}

function pp_parse_sensor_run(str){

  var v = parseInt($(str).text());

  if (v==2){
    color = "rgb(0,0,0)";
    v = "ok";
  }

  if (v==1){
    color = "rgb(240,160,0)";
    v = "idle";
  }

  if (v==0){
    v = "stopped";
    color = "rgb(230,0,0)";
  }

  res = "<span style='color:"+color+"'>"+v+"</span>";

  return res;

}

function parse_temperature(str){
  temps = ["cpu","b10389","sda","sdb"];
  res = [];
  for(var i=0;i<temps.length;i++){
    res.push(color_temperature(str.find(temps[i]).text(),temps[i]));
  }

  return res.join(', ');
}

function color_temperature(str,title){

  color = "rgb(0,0,0)";

  if (str!="-"){
    var t = parseFloat(str);

    if (t>85){
      color = "rgb(230,0,0)";
    }else if(t>70){
      color = "rgb(240,160,0)";
    }else{
      color = "rgb(0,150,0)";
    }
  }

  temp = "<span title='"+title+"' style='color:"+color+";'>"+str+"&deg;</span>";

  return temp;

}

function parse_storage(str){

  var devs = str.find("device");

  var res = "";

  ds = [];
  for(var i=0;i<devs.length;i++){
    var ds_str = "";

    var devname = $(devs[i]).attr('name');
    var devsize = (parseFloat($(devs[i]).attr('size'))/1024/1024).toFixed(2);
    var parts = $(devs[i]).find("partition");

    ds_str += "<b>"+devname+"("+devsize+"G)</b>: ";

    if (parts.length==0){
      ds_str += "unpartitioned";
    }else{
      ps = []
      for (var j=0;j<parts.length;j++){
        pname = $(parts[j]).attr('name');
        psize = (parseFloat($(parts[j]).attr('size'))/1024/1024).toFixed(2);
        ps.push(pname+"("+psize+"G)");
      }
      ds_str += ps.join(', ');
    }

    ds.push(ds_str);

  }

  res = ds.join('; ');

  return res;

}

function parse_recorder(str){

  color = "rgb(0,0,0)";

  if (str!="on"){
    color = "rgb(230,0,0)";
  }

  res = "<span style='color:"+color+";'>"+str+"</span>";

  return res;

}

function parse_gps(str){
  var lat = $(str).find("lat");
  var lon = $(str).find("lon");

  var na = $(str).text();


  if ((lat.length==0)||(lon.length==0)){
    res = "<span style='color:rgb(230,0,0)'>"+na.toLowerCase()+"</span>";
  }else{
    res = "<span>"+$(lat).text()+", "+$(lon).text()+"</span>";
  }

  return res;
}



+274 −0
Original line number Diff line number Diff line
<?php

// GLOBALS
// path to sysfs for port scanning
$portspath = "/sys/devices/soc0/elphel393-detect_sensors@0";
// total number of ports in 10393
$nports = 4;
$muxports = 3;
$port0 = 2323;

$ports = getports();
$sample_port = get_sample_port($ports);
$master_port = elphel_get_P_value($sample_port,ELPHEL_TRIG_MASTER);

//print("<pre>");
//print_r($ports);
//print("sample port = ".$sample_port);


$res = "";
$res .= "<camera ip='".$_SERVER['SERVER_ADDR']."'>\n";
$res .= "\t<master_port>".$master_port."</master_port>\n";
$res .= "\t<systime>".get_system_time()."</systime>\n";
$res .= "\t<systimestamp>".time()."</systimestamp>\n";
$res .= "\t<uptime>".get_uptime()."</uptime>\n";
$res .= "\t<temperature>".get_temperature()."\t</temperature>\n";
$res .= "\t<storage>".check_storage()."\t</storage>\n";
$res .= "\t<recorder name='camogm'>".check_camogm_running()."</recorder>\n";
$res .= "\t<gps>".check_gps($master_port)."\t</gps>\n";

for($i=0;$i<count($ports);$i++){
  $s = implode(', ',$ports[$i]['sensors']);
  $m = $ports[$i]['mux'];
  $res .= "\t<port index='$i' sensor='$s' mux='$m'>".get_port_info($i)."\t</port>\n";
}

$res .= "</camera>\n";

// allow CORS
header('Access-Control-Allow-Origin: *');
$xml  = "<?xml version='1.0' standalone='yes'?>\n";
$xml .= "<Document>\n";
$xml .= $res;
$xml .= "</Document>\n";
print($xml);

//functions

function check_camogm_running(){

  $camogm_running = false;
  exec('ps | grep "camogm"', $arr);
  $check = implode("<br/>",$arr);

  foreach($arr as $line){
    $result = preg_match('/grep/',$line);
    if (!$result) {
      $camogm_running = true;
    }
  }

  if ($camogm_running) $res = "on";
  else                 $res = "off";

  return $res;
}

function getports(){

  global $nports, $muxports, $portspath, $port0;

  $res = array();

  for($i=0;$i<$nports;$i++){
    $subres = array();

    $subres['mux'] = read_port_file($portspath."/port_mux{$i}");
    $subres['sensors'] = array();

    for($j=0;$j<$muxports+1;$j++){
      array_push($subres['sensors'],read_port_file($portspath."/sensor{$i}{$j}"));
    }

    array_push($res,$subres);
  }

  return $res;

}

function read_port_file($file){
  $v = "";
  if(is_file($file)){
    $v = trim(file_get_contents($file));
  }
  return $v;
}

function get_sample_port($a){
  $sample_found = false;
  // errors are not expected here
  //$res = -1;
  $res = 0;
  foreach($a as $k0=>$port){
    $b = $port['sensors'];
    foreach($b as $k1=>$sensor){
      if ($sensor!='none'){
        $sample_found = true;
        break;
      }
    }
    if ($sample_found){
      $res = $k0;
      break;
    }
  }
  return $res;
}

function check_storage(){

  $names = array();
  $regexp = '/([0-9]+) +(sd[a-z0-9]+$)/';
  exec("cat /proc/partitions", $partitions);

  // the first two elements of an array are table header and empty line delimiter, skip them
  for ($i = 2; $i < count($partitions); $i++) {
    // select SATA devices only
    if (preg_match($regexp, $partitions[$i], $name) == 1) {
      $names[$name[2]] = $name[1];
      $j++;
    }
  }

  //print_r($names);
  $res = "";
  foreach($names as $name=>$size){
    if (preg_match('/^sd[a-z]$/',$name,$matches)) {
      $dev = $matches[0];
      $res .= "\n\t\t<device name='$dev' size='$size'>\n";
      foreach($names as $partition=>$psize){
        if (preg_match('/^'.$dev.'[0-9]+$/',$partition)){
          $res .= "\t\t\t<partition name='$partition' size='$psize'></partition>\n";
        }
      }
      $res .= "\t\t</device>\n";

    }
  }

  return $res;
}

function check_gps($port){
  $circbuf_pointers = elphel_get_circbuf_pointers($port,1);
  $pointer = $circbuf_pointers[count($circbuf_pointers)-1];
  $exif = elphel_get_exif_elphel($port,$pointer['exif_pointer']);
  if ((isset($exif['GPSLongitude']))&&(isset($exif['GPSLatitude']))){
    $res = "\n";
    $res .= "\t\t<lat>".$exif['GPSLatitude']."</lat>\n";
    $res .= "\t\t<lon>".$exif['GPSLongitude']."</lon>\n";
  }else{
    $res = "N/A";
  }
  return $res;
}

function get_system_time(){
  $res = exec('date');
  return $res;
}

function get_uptime(){
  $res = exec('uptime');
  $res = trim($res);
  $res = preg_replace('/\s+/',' ',$res);
  $res = explode(' ',$res);
  $out = trim($res[2],',');
  return $out;
}

function get_temperature(){

  $t_cpu = round(floatval(trim(file_get_contents("/tmp/core_temp"))),1);
  $t_10389 = "";
  $t_sda = "";
  $t_sdb = "";

  $temp1_input = "/sys/devices/soc0/amba@0/e0004000.ps7-i2c/i2c-0/0-001a/hwmon/hwmon0/temp1_input";

  if (is_file($temp1_input)){
    $t_10389 = trim(file_get_contents($temp1_input));
    $t_10389 = intval($t_10389)/1000;
  }

  $t_sda = exec("smartctl -A /dev/sda | egrep ^194 | awk '{print $10}'");
  if ($t_sda=="") $t_sda = "-";
  else            $t_sda = intval($t_sda);

  $t_sdb = exec("smartctl -A /dev/sdb | egrep ^194 | awk '{print $10}'");
  $t_sdb = "";
  if ($t_sdb=="") $t_sdb = "-";
  else            $t_sdb = intval($t_sdb);

  $res = "\n\t\t<cpu>$t_cpu</cpu>\n";
  $res .= "\t\t<b10389>$t_10389</b10389>\n";
  $res .= "\t\t<sda>$t_sda</sda>\n";
  $res .= "\t\t<sdb>$t_sdb</sdb>\n";

  return $res;
}

function get_port_info($port){

  $pars_res = "";
  $ts_res = "";

  $pars = array(
    'WB_EN' => 0,
    'AUTOEXP_EN' => 0,
    'COMPRESSOR_RUN'=> 0,
    'SENSOR_RUN'=> 0,
    'COLOR' => 0,
    'QUALITY' => 0,
    'EXPOS' => 0,
    'WOI_WIDTH' => 0,
    'WOI_HEIGHT' => 0,
    'TRIG' => 0,
    'TRIG_MASTER' => 0,
    'TRIG_PERIOD' => 0,
    'TRIG_CONDITION' => 0,
    'TRIG_OUT' => 0,
    'GAINR' => 0,
    'GAING' => 0,
    'GAINB' => 0,
    'GAINGB' => 0,
  );

  $ps = elphel_get_P_arr($port,$pars);

  $pars_res .= "\n\t\t<parameters>\n";
  foreach($ps as $k=>$v){
    $pars_res .= "\t\t\t<".strtolower($k).">$v</".strtolower($k).">\n";
  }
  $pars_res .= "\t\t</parameters>\n";


  // get recent timestamps
  $circbuf_pointers = elphel_get_circbuf_pointers($port,1);
  $meta = array();
  foreach($circbuf_pointers as $k=>$v){
    $meta[$k] = array (
      'circbuf_pointer' => $v['circbuf_pointer'],
      'meta' => elphel_get_interframe_meta($port,$v['circbuf_pointer']),
      'Exif' => elphel_get_exif_elphel($port, $v['exif_pointer'])
    );
  }

  $ts_res .= "\t\t<timestamps>\n";

  foreach($meta as $m){
    $sec  = $m['meta']['timestamp_sec'];
    $usec = sprintf("%06d", $m['meta']['timestamp_usec']);
    $ts_res .= "\t\t\t<ts frame='{$m['Exif']['FrameNumber']}'>$sec.$usec</ts>\n";
  }

  $ts_res .= "\t\t</timestamps>\n";

  $res = $pars_res.$ts_res;

  return $res;
}

?>
Loading