Commit e2b98afe authored by Oleg Dzhimiev's avatar Oleg Dzhimiev

+system information

parent 5dae054c
# 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-%)
......
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"
#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
$(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;
}
<?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;
}
?>
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>System info</title>
<script src="../js/jquery-3.1.1.js"></script>
<link rel="stylesheet" href="../js/bootstrap/css/bootstrap.css">
<script type='text/javascript' src='diagnostics.js'></script>
<link rel='stylesheet' type='text/css' href='diagnostics.css'></link>
</head>
<body>
<h4>General info</h4>
<div id='display_general'>
<table id='gen_table'>
<tr>
<th>ip</th>
<th>time</th>
<th>uptime</th>
<th title='Temperature, &deg;C'>t</th>
<th>storage</th>
<th>camogm</th>
<th>master port</th>
<th>GPS</th>
<th>IMU</th>
</tr>
</table>
</div>
<h4>Port info</h4>
<div id='display_pars'>
<table id='pars_table'>
<tr>
<th>port</th>
<th>mux</th>
<th>sensors</th>
<th>sensor run</th>
<th>compressor run</th>
<th title='image format'>format</th>
<th>quality</th>
<th>wxh</th>
<th>TRIG</th>
<th>master</th>
<th title='TRIG_PERIOD'>period</th>
<th title='TRIG_OUT'>T_OUT</th>
<th title='TRIG_CONDITION'>T_COND</th>
<th>exposure</th>
<th>gainR</th>
<th>gainG</th>
<th>gainB</th>
<th>gainGB</th>
</tr>
</table>
</div>
<h4>Timestamps info</h4>
<div id='display_ts'>
<table id='ts_table'>
</table>
</div>
</body>
</html>
\ No newline at end of file
......@@ -44,6 +44,11 @@
</div>
</td>
</tr>
<tr>
<td>
<button id='system_tests' title='system info' class="btn btn-sm btn-success">tests</button>
</td>
</tr>
<tr>
<td hidden>
<br/>
......
......@@ -118,4 +118,8 @@ hr{
.port_preview canvas,#display{
padding:0px;
}
#system_tests{
margin:5px;
}
\ No newline at end of file
......@@ -283,7 +283,7 @@ function rec_button_update_state(){
rec_button_switch(recording);
}
refresh_previews_intvl = setInterval(refresh_previews,1000);
refresh_previews_intvl = setInterval(refresh_previews,2000);
refresh_status_intvl = setInterval(refresh_status,2000);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment