1189 lines
43 KiB
PHP
1189 lines
43 KiB
PHP
<?php
|
|
/*
|
|
************************************************************************
|
|
**
|
|
** Copyright (c) 2009..2013 by
|
|
** Core|Vision B.V.
|
|
** Hambakenwetering 1
|
|
** 5231 DD 's-Hertogenbosch
|
|
** The Netherlands
|
|
**
|
|
** All Rights Reserved
|
|
**
|
|
************************************************************************
|
|
*/
|
|
/*
|
|
************************************************************************
|
|
**
|
|
** Project name: Dual Inventive: MTinfo Support Scripts
|
|
** Filename: plot-meting.php
|
|
** Author: Jack Weeland
|
|
** Date: July 6, 2009
|
|
** File version: $Revision: 1.25 $
|
|
** $Date: 2013/12/19 14:49:58 $
|
|
**
|
|
************************************************************************
|
|
*/
|
|
/*
|
|
************************************************************************
|
|
**
|
|
** Display a measurement in a graph.
|
|
**
|
|
** Mandatory parameters, via "GET", all of which are retrieved from
|
|
** the database
|
|
** zkl - database ID of the ZKL to query
|
|
** logfile - sdcard,rpgmcount,startup of the logfile to plot
|
|
** or
|
|
** file - text file (output of logrdr)
|
|
** and/or
|
|
** tmin,tmax - date/time of the time frame (the current time will
|
|
** be used if tmax is ommitted)
|
|
** Optional output options:
|
|
** tz - override timezone info in the database
|
|
** w - width of the output image
|
|
** h - height of the output image
|
|
** show_rms - also plot the RMS values
|
|
** hide_title - do not device id-code and date
|
|
** hide_info - do not show additional info
|
|
** log_realtime - use 'log_realtime' instead of 'log_meting'
|
|
** (with 'tmin' and 'tmax'; _not_ 'logfile')
|
|
**
|
|
** Notes:
|
|
** - If both 'logfile' and a 'tmin'/'tmax' are specified, then the data
|
|
** from the logfile will be scaled to the specified time frame.
|
|
** - If _no_ 'logfile' is specified, all logfiles with data in the time
|
|
** frame will be shown.
|
|
** - Logfiles with an invalid date (i.e. 1970-1-1) are _never_ plotted.
|
|
**
|
|
************************************************************************
|
|
*/
|
|
|
|
//
|
|
// Check inputs for SQL statement injection and such.
|
|
// Items not tested below are not vulnerable for SQL statement injection, e.g.
|
|
// a time is always converted using 'strtotime()' and other items are only
|
|
// used in the PHP but never in the composition of an SQL statement
|
|
// [security audit 2013-10-23]
|
|
//
|
|
if(
|
|
(isset($_GET['zkl']) && !is_numeric($_GET['zkl'])) ||
|
|
(isset($_GET['logfile']) && !preg_match('/^[0-9]+,[0-9]+,[0-9]+$/', $_GET['logfile']) && !in_array($_GET['logfile'], array('log_tcp','log_versienummer','log_realtime','log_secure_zkl'))) ||
|
|
(isset($_GET['db']) && dirname($_GET['db']) != ".")
|
|
) {
|
|
// don't do anything fancy or interruptive as fiddling with the GET parameters
|
|
// is intended by the author
|
|
die("Parameter error");
|
|
}
|
|
|
|
require_once("../include/graphics.php");
|
|
require_once("../include/i18n.php");
|
|
require_once("../include/cp3000-tcpclient.php");
|
|
require_once("support.inc.php");
|
|
|
|
set_time_limit(0);
|
|
|
|
function clip($val, $min, $max)
|
|
{
|
|
if( $val < $min )
|
|
return $min;
|
|
else if( $val > $max )
|
|
return $max;
|
|
else
|
|
return $val;
|
|
}
|
|
|
|
function get_tmin_tmax_from_file($fname, &$tmin, &$tmax)
|
|
{
|
|
$fp = fopen($fname, "r");
|
|
|
|
while( ($str = fgets($fp)) !== FALSE ) {
|
|
if( preg_match("/timestamp ([0-9]{4}-[0-9]{2}-[0-9]{2}\s+[0-9]{1,2}:[0-9]{2}:[0-9]{2})/", $str, $matches) > 0 ) {
|
|
$t = strtotime($matches[1]);
|
|
|
|
if( $t >= strtotime("2007-01-01 00:00:00") ) {
|
|
if( $tmin == 0 ) {
|
|
$tmin = $tmax = $t;
|
|
}
|
|
else {
|
|
if( $t < $tmin ) $tmin = $t;
|
|
if( $t > $tmax ) $tmax = $t;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fclose($fp);
|
|
}
|
|
|
|
function file_fetch_line($fp, &$date)
|
|
{
|
|
while( 1 ) {
|
|
$str = fgets($fp);
|
|
if( $str === FALSE ) return FALSE;
|
|
|
|
if( strpos($str, "timestamp") !== FALSE ) {
|
|
if( substr($str, 0, 8) == "00:00:00" ) $date += 24 * 60 * 60;
|
|
}
|
|
else if( strpos($str, "measurement details") !== FALSE ) {
|
|
if( preg_match("/rms=([0-9A-F]{4}), b\/a=([0-9A-F]{4})/", $str, $matches) > 0 ) {
|
|
return array(
|
|
't' => strtotime(date("Y-m-d", $date) . " " . substr($str, 0, 8)),
|
|
'b_a' => intval($matches[2], 16) / 65536.0,
|
|
'rms' => intval($matches[1], 16)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// which table?
|
|
$use_log_realtime = isset($_GET['log_realtime']);
|
|
$use_file = isset($_GET['file']);
|
|
|
|
// TO DO: include the right file with definitions for the database
|
|
if( !$use_file ) {
|
|
// read the database information
|
|
if( isset($_GET['db']) ) $db_info = read_database(DBCONFIG_DIR, $_GET['db']);
|
|
else $db_info = array();
|
|
if( !isset($db_info['host']) ) $db_info['host'] = "localhost";
|
|
if( !isset($db_info['user']) ) $db_info['user'] = "root";
|
|
if( !isset($db_info['passwd']) ) $db_info['passwd'] = "";
|
|
if( !isset($db_info['db']) ) $db_info['db'] = "di_zkl";
|
|
|
|
// open the database
|
|
$db_data_handle = mysql_connect($db_info['host'], $db_info['user'], $db_info['passwd']);
|
|
if( $db_data_handle === FALSE ) {
|
|
echo mysql_error();
|
|
exit(1);
|
|
}
|
|
mysql_select_db($db_info['database'], $db_data_handle);
|
|
if( $db_info['main'] ) {
|
|
$db_main_info = read_database(DBCONFIG_DIR, $db_info['main']);
|
|
$db_main_handle = mysql_connect($db_main_info['host'], $db_main_info['user'], $db_main_info['passwd'], true);
|
|
if( $db_main_handle === FALSE ) {
|
|
echo mysql_error();
|
|
exit(1);
|
|
}
|
|
mysql_select_db($db_main_info['database'], $db_main_handle);
|
|
}
|
|
else {
|
|
$db_main_handle = $db_data_handle;
|
|
$db_main_info = $db_info;
|
|
}
|
|
}
|
|
|
|
// determine width and height
|
|
$width = $_GET['w'];
|
|
$height = $_GET['h'];
|
|
if( !$width ) $width = 640;
|
|
if( !$height ) $height = 480;
|
|
|
|
// get information about the device
|
|
if( isset($_GET['logfile']) ) {
|
|
list($sdcard,$rpgmcount,$startup) = explode(',', $_GET['logfile']);
|
|
}
|
|
$query = "SELECT serienr,idcode,tcp_server,mcu_versie,wcpu_versie,IFNULL(gebruiker,eigenaar) AS gebruiker FROM zkl WHERE id=" . $_GET['zkl'];
|
|
$result = mysql_run($query, $db_main_handle);
|
|
$zkl_info = mysql_fetch_assoc($result);
|
|
if( $zkl_info['gebruiker'] ) {
|
|
$query = "SELECT tz,i18n FROM klant WHERE id=" . $zkl_info['gebruiker'];
|
|
$result = mysql_run($query, $db_main_handle);
|
|
$tz_info = mysql_fetch_assoc($result);
|
|
}
|
|
else {
|
|
$tz_info = array( 'tz' => date("e"), 'i18n' => "nl" );
|
|
}
|
|
if( $_GET['tz'] ) $tz_info['tz'] = $_GET['tz'];
|
|
if( $_GET['lc'] ) $tz_info['i18n'] = $_GET['lc'];
|
|
$zkl_info['tz'] = $tz_info['tz'];
|
|
$zkl_info['i18n'] = $tz_info['i18n'];
|
|
$zkl_info['mcu_versie'] = zkl_get_fw_version($zkl_info['mcu_versie']);
|
|
$zkl_info['wcpu_versie'] = zkl_get_fw_version($zkl_info['wcpu_versie']);
|
|
putenv("TZ=" . $zkl_info['tz']);
|
|
i18n_settext_language($zkl_info['i18n']);
|
|
setlocale(LC_ALL, $zkl_info['i18n']);
|
|
|
|
// get timeframe and log files
|
|
$logfiles = array();
|
|
if( $use_file ) {
|
|
// get tmin,tmax from the log file
|
|
if( is_array($_GET['file']) ) {
|
|
}
|
|
else {
|
|
$tmin = $tmax = 0;
|
|
get_tmin_tmax_from_file($_GET['file'], $tmin, $tmax);
|
|
array_push($logfiles, array('file' => $_GET['file'], 'tmin' => $tmin, 'tmax' => $tmax));
|
|
}
|
|
}
|
|
if( isset($_GET['tmin']) ) {
|
|
$tmin = strtotime($_GET['tmin']);
|
|
if( isset($_GET['tmax']) && $_GET['tmax'] ) $tmax = strtotime($_GET['tmax']);
|
|
else $tmax = time();
|
|
if( isset($_GET['logfile']) ) {
|
|
if( is_array($_GET['logfile']) ) foreach( $_GET['logfile'] as $logfile ) {
|
|
list($sdcard,$rpgmcount,$startup) = explode(',', $logfile);
|
|
$query = "SELECT MIN(t) AS tmin,MAX(t) AS tmax ";
|
|
$query .= "FROM log_zkl ";
|
|
$query .= "WHERE ";
|
|
$query .= " zkl=" . $_GET['zkl'] . " AND ";
|
|
$query .= " sdcard=" . $sdcard . " AND ";
|
|
$query .= " rpgmcount=" . $rpgmcount . " AND ";
|
|
$query .= " startup=" . $startup;
|
|
$result = mysql_run($query, $db_data_handle);
|
|
$row = mysql_fetch_assoc($result);
|
|
if( $row['tmax'] > time() ) {
|
|
error_log($_SERVER['PHP_SELF'] . ": logfile " . $_GET['zkl'] . "-" . $sdcard . "," . $rpgmcount . "," . $startup . " has bogus 'max(t)'; using 'now'");
|
|
$row['tmax'] = time();
|
|
}
|
|
array_push($logfiles, array('sdcard' => $sdcard, 'rpgmcount' => $rpgmcount, 'startup' => $startup, 'tmin' => $row['tmin'], 'tmax' => $row['tmax']));
|
|
}
|
|
else {
|
|
list($sdcard,$rpgmcount,$startup) = explode(',', $_GET['logfile']);
|
|
$query = "SELECT MIN(t) AS tmin,MAX(t) AS tmax ";
|
|
$query .= "FROM log_zkl ";
|
|
$query .= "WHERE ";
|
|
$query .= " zkl=" . $_GET['zkl'] . " AND ";
|
|
$query .= " sdcard=" . $sdcard . " AND ";
|
|
$query .= " rpgmcount=" . $rpgmcount . " AND ";
|
|
$query .= " startup=" . $startup;
|
|
$result = mysql_run($query, $db_data_handle);
|
|
$row = mysql_fetch_assoc($result);
|
|
if( $row['tmax'] > time() ) {
|
|
error_log($_SERVER['PHP_SELF'] . ": logfile " . $_GET['zkl'] . "-" . $sdcard . "," . $rpgmcount . "," . $startup . " has bogus 'max(t)'; using 'now'");
|
|
$row['tmax'] = time();
|
|
}
|
|
array_push($logfiles, array('sdcard' => $sdcard, 'rpgmcount' => $rpgmcount, 'startup' => $startup, 'tmin' => $row['tmin'], 'tmax' => $row['tmax']));
|
|
}
|
|
}
|
|
else if( $use_log_realtime ) {
|
|
// fake a log file for the drawing loop below
|
|
array_push($logfiles,
|
|
array(
|
|
'sdcard' => 0,
|
|
'rpgmcount' => 0,
|
|
'startup' => 0,
|
|
'tmin' => $tmin,
|
|
'tmax' => $tmax
|
|
)
|
|
);
|
|
}
|
|
else if( !isset($_GET['file']) ) {
|
|
// retrieve logfiles from the database
|
|
$query = "SELECT sdcard,rpgmcount,startup,MIN(t) AS tmin,MAX(t) AS tmax ";
|
|
$query .= "FROM log_zkl ";
|
|
$query .= "WHERE ";
|
|
$query .= " zkl=" . $_GET['zkl'] . " AND ";
|
|
$query .= " t BETWEEN '" . $tmin . "' AND '". $tmax . "' ";
|
|
$query .= "GROUP BY sdcard,rpgmcount,startup";
|
|
$result = mysql_run($query, $db_data_handle);
|
|
while( $row = mysql_fetch_assoc($result) ) {
|
|
array_push($logfiles, $row);
|
|
}
|
|
}
|
|
}
|
|
else if( !isset($_GET['file']) ) {
|
|
if( !isset($_GET['logfile']) ) {
|
|
error_log($_SERVER['PHP_SELF'] . ": no log file or time range defined");
|
|
exit(1);
|
|
}
|
|
list($sdcard,$rpgmcount,$startup) = explode(',', $_GET['logfile']);
|
|
$query = "SELECT MIN(t) AS tmin,MAX(t) AS tmax ";
|
|
$query .= "FROM log_zkl ";
|
|
$query .= "WHERE ";
|
|
$query .= " zkl=" . $_GET['zkl'] . " AND ";
|
|
$query .= " sdcard=" . $sdcard . " AND ";
|
|
$query .= " rpgmcount=" . $rpgmcount . " AND ";
|
|
$query .= " startup=" . $startup;
|
|
$result = mysql_run($query, $db_data_handle);
|
|
$row = mysql_fetch_assoc($result);
|
|
if( $row['tmin'] < strtotime("2000-1-1") ) {
|
|
error_log($_SERVER['PHP_SELF'] . ": logfile " . $_GET['zkl'] . "-" . $sdcard . "," . $rpgmcount . "," . $startup . " has bogus 'min(t)'; using only data from 2000");
|
|
$result = mysql_run($query . " AND t >= " . strtotime('2000-1-1'), $db_data_handle);
|
|
$row = mysql_fetch_assoc($result);
|
|
}
|
|
$tmin = $row['tmin'];
|
|
if( isset($_GET['tmax']) ) $tmax = strtotime($_GET['tmax']);
|
|
else {
|
|
if( $row['tmax'] > time() ) {
|
|
error_log($_SERVER['PHP_SELF'] . ": logfile " . $_GET['zkl'] . "-" . $sdcard . "," . $rpgmcount . "," . $startup . " has bogus 'max(t)'; using 'now'");
|
|
$tmax = time();
|
|
}
|
|
else $tmax = $row['tmax'];
|
|
}
|
|
array_push($logfiles, array('sdcard' => $sdcard, 'rpgmcount' => $rpgmcount, 'startup' => $startup, 'tmin' => $tmin, 'tmax' => $tmax));
|
|
}
|
|
if( $tmin >= $tmax ) {
|
|
error_log($_SERVER['PHP_SELF'] . ": empty time range: " . strftime("%D %T", $tmin) . "-" . strftime("%D %T", $tmax));
|
|
exit(1);
|
|
}
|
|
$tz_offset = date("Z", $tmin);
|
|
$duration = $tmax - $tmin;
|
|
|
|
//
|
|
// Draw the graph
|
|
//
|
|
|
|
header("Content-type: image/png");
|
|
header('Pragma: no-cache');
|
|
header('Expires: ' . date("r"));
|
|
|
|
// create the image
|
|
$im = imagecreatetruecolor($width,$height);
|
|
if( function_exists("imageantialias") )
|
|
imageantialias($im, true);
|
|
$black = imagecolorstring($im, "black");
|
|
$white = imagecolorstring($im, "white");
|
|
$grey = imagecolorallocate($im, 192, 192, 192);
|
|
$lgrey = imagecolorallocate($im, 240, 240, 240);
|
|
$dgrey = imagecolorallocate($im, 128, 128, 128);
|
|
$green = imagecolorallocate($im, 0, 192, 0);
|
|
$lgreen = imagecolorallocate($im, 192, 255, 192);
|
|
$llgreen = imagecolorallocate($im, 218, 255, 218);
|
|
$dgreen = imagecolorallocate($im, 0, 160, 0);
|
|
$tdgreen = imagecolorallocatealpha($im, 0, 160, 0, 96);
|
|
$red = imagecolorstring($im, "red");
|
|
$lred = imagecolorstring($im, "#FFC0C0");
|
|
$dred = imagecolorallocate($im, 160, 0, 0);
|
|
$blue = imagecolorallocate($im, 0, 0, 224);
|
|
$tblue = imagecolorallocatealpha($im, 0, 0, 224, 96);
|
|
$dblue = imagecolorallocate($im, 0, 0, 160);
|
|
$purple = imagecolorallocate($im, 224, 0, 224);
|
|
$dpurple = imagecolorallocate($im, 160, 0, 160);
|
|
$font = 2; // 6x13
|
|
$bfont = 3; // 7x13 medium bold
|
|
$tfont = 1; // 5x8
|
|
|
|
//
|
|
// Colors and font to use
|
|
//
|
|
$bgcolor = imagecolorallocatealpha($im, 255, 255, 255, $_GET['transparent'] ? 127 : 0);
|
|
$bgcolor_transp = imagecolorallocatealpha($im, 255, 255, 255, 96);
|
|
$gridcolor = $black; // main grid and markers
|
|
$sgridcolor = $lgrey; // guides in the gred
|
|
$nextdaycolor = $grey; // next day line
|
|
$cal_b_a_color = $lred; // b/a limit line
|
|
$cal_info_color = $red; // info with the above
|
|
$cal_rms_color = $llgreen; // very light green
|
|
$cal_rms_bcolor = $lgreen; // border for legend, a bit darker light green
|
|
$b_a_color = $blue; // line of the b/a graph
|
|
$b_a_tcolor = $tblue; // line of the b/a graph
|
|
$rms_color = $dgreen; // line of the rms graph
|
|
$rms_tcolor = $tdgreen; // line of the rms graph
|
|
|
|
//
|
|
// Font selection (dependent on image size)
|
|
//
|
|
// labels and legenda
|
|
if( $width <= 320 || $height <= 240 ) {
|
|
$labelfont = 1;
|
|
$infofont = 1;
|
|
}
|
|
else if( $width >= 2048 && $height >= 1536 ) {
|
|
$labelfont = 5;
|
|
$infofont = 3;
|
|
}
|
|
else if( $width >= 1280 && $height >= 1024 ) {
|
|
$labelfont = 3;
|
|
$infofont = 2;
|
|
}
|
|
else {
|
|
$labelfont = 2;
|
|
$infofont = 1;
|
|
}
|
|
|
|
//
|
|
// Draw the grid
|
|
//
|
|
|
|
// draw background
|
|
imagefill($im, 0, 0, $bgcolor);
|
|
|
|
// offsets with the drawing grid
|
|
// largest value label: 1.000
|
|
// x: left to right
|
|
// y: bottom to top
|
|
global $x_off, $x_ext, $y_off, $y_ext;
|
|
$x_off = 5 * imagefontwidth($labelfont) // value labels +
|
|
+ imagefontheight($labelfont) // legend +
|
|
+ (imagefontheight($labelfont) >> 1); // extra spacing
|
|
$x_ext = $width - $x_off - (imagefontheight($labelfont) >> 1); // + extent of the last date label
|
|
$y_off = $height - 3 - (strlen(strftime("%X")) * imagefontwidth($labelfont)); // date/time
|
|
$y_ext = $y_off;
|
|
if( !isset($_GET['hide_title']) ) {
|
|
$y_ext -= imagefontheight($labelfont); // title
|
|
if( $use_log_realtime ) $y_ext -= imagefontheight($labelfont);
|
|
}
|
|
else {
|
|
$y_ext -= imagefontheight($labelfont) >> 1; // extent of the top value label
|
|
}
|
|
if( !isset($_GET['hide_info']) )
|
|
$y_ext -= imagefontheight($infofont) * 2; // info + arrow
|
|
|
|
// draw valid/okay RMS indicator below anything else
|
|
if( isset($_GET['show_rms']) ) {
|
|
imagefilledrectangle($im,
|
|
$x_off, $y_off - ($y_ext * (sqrt(5735) / 100.0)),
|
|
$x_off + $x_ext, $y_off - ($y_ext * (sqrt( 800) / 100.0)),
|
|
$cal_rms_color
|
|
);
|
|
}
|
|
|
|
// The grid is drawn _under_ the lines and ornaments like the title etc
|
|
// Y tick marks every 0.100
|
|
for( $y_tick = 0; $y_tick <= 1.0; $y_tick += 0.1 ) {
|
|
$y = $y_tick * $y_ext;
|
|
imageline($im, $x_off, $y_off - $y, $x_off + $x_ext, $y_off - $y, $lgrey);
|
|
imageline($im, $x_off - 2, $y_off - $y, $x_off, $y_off - $y, $black);
|
|
imagestringalign($im, $labelfont, $x_off - 2, $y_off - $y, sprintf("%.2f", $y / $y_ext), $gridcolor, ALV_MIDDLE | ALH_RIGHT);
|
|
}
|
|
// X tick marks
|
|
// find a correct stepping for the date labels first
|
|
$x_tick_sec = array(5,15,1*60,5*60,15*60,30*60,60*60,4*60*60,6*60*60,8*60*60,12*60*60,24*60*60,7*24*60*60,30*24*60*60,365*24*60*60);
|
|
for(
|
|
$step = 0, $x_tick_step = 0;
|
|
$x_tick_step < (imagefontheight($labelfont) << 1) && $step < count($x_tick_sec);
|
|
$step++
|
|
) {
|
|
$x_tick_off = $x_tick_sec[$step];
|
|
$x_tick_step = ($x_ext * $x_tick_off) / $duration;
|
|
$x_tick_val = $x_tick_off - (($tmin + $tz_offset) % $x_tick_off);
|
|
if( $x_tick_val == $x_tick_off ) $x_tick_val = 0;
|
|
}
|
|
if( $x_tick_off >= (24*60*60) ) {
|
|
if( strtotime("first day of next year", time()) !== FALSE ) {
|
|
// big steps; use days/weeks/months/years for DST and leap years
|
|
if( $x_tick_off == (365*24*60*60) ) {
|
|
$t = strtotime("this year January 01 midnight", $tmin);
|
|
$t_step = "first day of next year";
|
|
}
|
|
else if( $x_tick_off == (30*24*60*60) ) {
|
|
$t = strtotime("first day of this month midnight", $tmin);
|
|
$t_step = "first day of next month";
|
|
}
|
|
else if( $x_tick_off == (7*24*60*60) ) {
|
|
$t = strtotime("this week Monday midnight", $tmin);
|
|
$t_step = "+1 weeks";
|
|
}
|
|
else {
|
|
$t = strtotime("midnight", $tmin);
|
|
$t_step = "tomorrow";
|
|
}
|
|
}
|
|
else {
|
|
// "nice" arithmatic is not supported
|
|
if( $x_tick_off == (365*24*60*60) ) {
|
|
$t = strtotime("this year January 01 midnight", $tmin);
|
|
$t_step = "+1 year";
|
|
}
|
|
else if( $x_tick_off == (30*24*60*60) ) {
|
|
$t = strtotime("first day of this month midnight", $tmin);
|
|
$t_step = "+1 month";
|
|
}
|
|
else if( $x_tick_off == (7*24*60*60) ) {
|
|
$t = strtotime("this week Monday midnight", $tmin);
|
|
$t_step = "+1 weeks";
|
|
}
|
|
else {
|
|
$t = strtotime("midnight", $tmin);
|
|
$t_step = "tomorrow";
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if( $x_tick_off >= 60*60 ) {
|
|
$t_step = "+" . ($x_tick_off / (60*60)) . " hours";
|
|
}
|
|
else if( $x_tick_off >= 60 ) {
|
|
$t_step = "+" . ($x_tick_off / 60) . " minutes";
|
|
}
|
|
else {
|
|
$t_step = "+" . $x_tick_off . " seconds";
|
|
}
|
|
$t = $tmin;
|
|
if( $x_tick_val > 0 ) $t = strtotime("+" . $x_tick_val . " seconds", $t);
|
|
}
|
|
while( $t <= $tmax ) {
|
|
if( $t >= $tmin ) {
|
|
$x = ((($t - $tmin) / $duration) * $x_ext);
|
|
if( $x_tick_off >= (24*60*60) ) {
|
|
if( $x_tick_off == (30*24*60*60) ) {
|
|
// month name
|
|
imageline($im, $x_off + $x, $y_off , $x_off + $x, $y_off - $y_ext - 1, $nextdaycolor);
|
|
imageline($im, $x_off + $x, $y_off + 2, $x_off + $x, $y_off, $gridcolor);
|
|
imagestringupalign($im, $labelfont, $x_off + $x, $y_off - 2, strftime("%B", $t), $nextdaycolor, ALV_BOTTOM | ALH_LEFT);
|
|
}
|
|
else if( $x_tick_off == (7*24*60*60) ) {
|
|
// month name
|
|
imageline($im, $x_off + $x, $y_off , $x_off + $x, $y_off - $y_ext - 1, $nextdaycolor);
|
|
imageline($im, $x_off + $x, $y_off + 2, $x_off + $x, $y_off, $gridcolor);
|
|
imagestringupalign($im, $labelfont, $x_off + $x, $y_off - 2, strftime("%V", $t), $nextdaycolor, ALV_BOTTOM | ALH_LEFT);
|
|
}
|
|
else {
|
|
imageline($im, $x_off + $x, $y_off , $x_off + $x, $y_off - $y_ext - 1, $sgridcolor);
|
|
imageline($im, $x_off + $x, $y_off + 2, $x_off + $x, $y_off, $gridcolor);
|
|
}
|
|
imagestringupalign($im, $labelfont, $x_off + $x, $y_off + 2, strftime("%x", $t), $gridcolor, ALV_TOP | ALH_CENTER);
|
|
}
|
|
else {
|
|
if( strftime("%H%M%S", $t) == "000000" ) {
|
|
imageline($im, $x_off + $x, $y_off , $x_off + $x, $y_off - $y_ext - 1, $nextdaycolor);
|
|
imageline($im, $x_off + $x, $y_off + 2, $x_off + $x, $y_off, $gridcolor);
|
|
imagestringupalign($im, $labelfont, $x_off + $x, $y_off - 2, strftime("%x", $t), $nextdaycolor, ALV_BOTTOM | ALH_LEFT);
|
|
}
|
|
else {
|
|
imageline($im, $x_off + $x, $y_off , $x_off + $x, $y_off - $y_ext - 1, $sgridcolor);
|
|
imageline($im, $x_off + $x, $y_off + 2, $x_off + $x, $y_off, $gridcolor);
|
|
}
|
|
imagestringupalign($im, $labelfont, $x_off + $x, $y_off + 2, strftime("%X", $t), $gridcolor, ALV_TOP | ALH_CENTER);
|
|
}
|
|
}
|
|
// increment $t (yup, that's what the line below does)
|
|
$t = strtotime($t_step, $t);
|
|
if( $t === FALSE ) {
|
|
trigger_error("Date/time error when adding \"" . $t_step . "\"", E_USER_ERROR);
|
|
}
|
|
}
|
|
if( $x_tick_off < (24*60*60) && (($x_tick_val / $duration) * $x_ext) > imagefontheight($labelfont) ) {
|
|
// show start day only on detailed plots (it is already in the titles)
|
|
imagestringupalign($im, $labelfont, $x_off, $y_off - 2, strftime("%x", $tmin), $grey, ALV_BOTTOM | ALH_LEFT);
|
|
}
|
|
|
|
//
|
|
// Draw the legend
|
|
//
|
|
$y_legend_off = $y_off;
|
|
if( isset($_GET['show_rms']) ) {
|
|
$y_legend_off -= ($y_ext - (8+4+11+4+8+4+14) * imagefontwidth($labelfont)) >> 1;
|
|
imagestringupalign($im, $labelfont, 0, $y_legend_off - 4 * imagefontwidth($labelfont), "rms", $gridcolor, ALV_TOP | ALH_LEFT);
|
|
imageline($im,
|
|
imagefontheight($labelfont) >> 1, $y_legend_off - 5.5 * imagefontwidth($labelfont), /* space */
|
|
imagefontheight($labelfont) >> 1, $y_legend_off - 8 * imagefontwidth($labelfont), /* line length */
|
|
$rms_color
|
|
);
|
|
$y_legend_off -= (8+4) * imagefontwidth($labelfont);
|
|
|
|
imagestringupalign($im, $labelfont, 0, $y_legend_off - 7 * imagefontwidth($labelfont), "rms ok", $gridcolor, ALV_TOP | ALH_LEFT);
|
|
imagefilledrectangle($im,
|
|
0, $y_legend_off - 11 * imagefontwidth($labelfont),
|
|
imagefontheight($labelfont), $y_legend_off - 8 * imagefontwidth($labelfont),
|
|
$cal_rms_color
|
|
);
|
|
imagerectangle($im,
|
|
0, $y_legend_off - 11 * imagefontwidth($labelfont),
|
|
imagefontheight($labelfont), $y_legend_off - 8 * imagefontwidth($labelfont),
|
|
$cal_rms_bcolor
|
|
);
|
|
$y_legend_off -= (11+4) * imagefontwidth($labelfont);
|
|
}
|
|
else {
|
|
$y_legend_off -= ($y_ext - (8+4+14) * imagefontwidth($labelfont)) >> 1;
|
|
};
|
|
imagestringupalign($im, $labelfont, 0, $y_legend_off - 4 * imagefontwidth($labelfont), "b/a", $gridcolor, ALV_TOP | ALH_LEFT);
|
|
imageline($im,
|
|
imagefontheight($labelfont) >> 1, $y_legend_off - 5 * imagefontwidth($labelfont), /* space */
|
|
imagefontheight($labelfont) >> 1, $y_legend_off - 8 * imagefontwidth($labelfont), /* line length */
|
|
$b_a_color
|
|
);
|
|
$y_legend_off -= (8+4) * imagefontwidth($labelfont);
|
|
|
|
imagestringupalign($im, $labelfont, 0, $y_legend_off - 10 * imagefontwidth($labelfont), "b/a limit", $gridcolor, ALV_TOP | ALH_LEFT);
|
|
imageline($im,
|
|
imagefontheight($labelfont) >> 1, $y_legend_off - 11 * imagefontwidth($labelfont), /* space */
|
|
imagefontheight($labelfont) >> 1, $y_legend_off - 14 * imagefontwidth($labelfont), /* line length */
|
|
$cal_b_a_color
|
|
);
|
|
|
|
//
|
|
// Draw the border to the left and bottom of the canvas
|
|
//
|
|
imageline($im, $x_off, $y_off, $x_off, $y_off - $y_ext + 1, $gridcolor);
|
|
imageline($im, $x_off, $y_off, $x_off + $x_ext, $y_off, $gridcolor);
|
|
|
|
//
|
|
// Plot the data
|
|
//
|
|
foreach( $logfiles as $logfile ) {
|
|
// get tmin,tmax for this logfile
|
|
$log_tmin = $logfile['tmin'];
|
|
$log_tmax = $logfile['tmax'];
|
|
if( $log_tmin < $tmin ) $log_tmin = $tmin;
|
|
if( $log_tmax > $tmax ) $log_tmax = $tmax;
|
|
//error_log("logfile(" . $logfile['sdcard'] . "," . $logfile['rpgmcount'] . "," . $logfile['startup'] . ") " . date("Y-m-d H:i:s", $log_tmin) . "->" . date("Y-m-d H:i:s", $log_tmax));
|
|
|
|
//
|
|
$sdcard = $logfile['sdcard'];
|
|
$rpgmcount = $logfile['rpgmcount'];
|
|
$startup = $logfile['startup'];
|
|
|
|
// measurement start/end
|
|
$m_begin = array();
|
|
$m_end = array();
|
|
$p = 0;
|
|
$t_cal_start = array();
|
|
if( $logfile['file'] ) {
|
|
// data already collected
|
|
$fp = fopen($logfile['file'], "r");
|
|
|
|
$date = strtotime(date("Y-m-d", $logfile['tmin']));
|
|
while( ($str = fgets($fp)) !== FALSE ) {
|
|
if( strpos($str, "timestamp") !== FALSE ) {
|
|
if( substr($str, 0, 8) == "00:00:00" ) $date += 24 * 60 * 60;
|
|
}
|
|
else if( strpos($str, "measurement start") !== FALSE ) {
|
|
$m_begin[$p] = strtotime(date("Y-m-d", $date) . " " . substr($str, 0, 8));
|
|
}
|
|
else if( strpos($str, "measurement end") !== FALSE ) {
|
|
$m_end[$p++] = strtotime(date("Y-m-d", $date) . " " . substr($str, 0, 8));
|
|
}
|
|
else if( strpos($str, "measurement details") !== FALSE ) {
|
|
if( preg_match("/default b\/a threshold=([01]\.[0-9]{3})/", $str, $matches) > 0 ) {
|
|
$b_a_threshold = $matches[1];
|
|
}
|
|
else if( preg_match("/PWM updated, period=[0-9]+ \(([0-9.]+)kHz\)/", $str, $matches) > 0 ) {
|
|
array_push($t_cal_start, array(
|
|
'tijd' => strtotime(date("Y-m-d", $date) . " " . substr($str, 0, 8)),
|
|
'minor' => 0x18,
|
|
'b_a' => $b_a_threshold,
|
|
'freq' => $matches[1] * 1000
|
|
));
|
|
}
|
|
}
|
|
}
|
|
|
|
fclose($fp);
|
|
}
|
|
else if( $use_log_realtime ) {
|
|
// cache minimum and maximum id; this is a lot faster for some reason
|
|
$query = "SELECT MIN(id),MAX(id) FROM log_realtime WHERE zkl=" . $_GET['zkl'] . " AND t BETWEEN " . $log_tmin . " AND " . $log_tmax;
|
|
if( ($result = mysql_run($query, $db_data_handle)) ) {
|
|
$row = mysql_fetch_array($result);
|
|
$id_min = $row[0];
|
|
$id_max = $row[1];
|
|
}
|
|
else exit(im_print_error($im, "No data"));
|
|
$query = "SELECT MAX(id) FROM log_realtime WHERE zkl=" . $_GET['zkl'] . " AND t <= " . $log_tmin;
|
|
$result = mysql_run($query, $db_data_handle);
|
|
if( $result ) {
|
|
$row = mysql_fetch_array($result);
|
|
$id_tmin = $row[0];
|
|
}
|
|
else {
|
|
// no suitable minimum
|
|
$query = "SELECT MIN(id) FROM log_realtime WHERE zkl=" . $_GET['zkl'];
|
|
$result = mysql_run($query, $db_data_handle);
|
|
$row = mysql_fetch_array($result);
|
|
$id_tmin = $row[0];
|
|
}
|
|
|
|
$meting = 0;
|
|
$query = "SELECT t,changes,mcu_state,b_a_autocal,freq ";
|
|
$query .= "FROM log_realtime ";
|
|
$query .= "WHERE ";
|
|
$query .= " zkl=" . $_GET['zkl'] . " AND ";
|
|
$query .= " (";
|
|
if( $id_tmin ) $query .= " id = " . $id_tmin . " OR ";
|
|
$query .= " (";
|
|
$query .= " id BETWEEN " . $id_min . " AND " . $id_max . " AND ";
|
|
$query .= " (changes & 0x0081) != 0";
|
|
$query .= " )";
|
|
$query .= " ) ";
|
|
$query .= "ORDER BY id";
|
|
$result = mysql_run($query, $db_data_handle);
|
|
while( $row = mysql_fetch_assoc($result) ) {
|
|
if( ($row['mcu_state'] & 0x0001) != $meting ) {
|
|
if( ($meting = ($row['mcu_state'] & 0x0001)) ) {
|
|
// measurement start
|
|
$m_begin[$p] = $row['t'];
|
|
$m_end[$p] = -1;
|
|
// measurement start (or start of data) or auto-calibration
|
|
array_push(
|
|
$t_cal_start,
|
|
array(
|
|
't' => $row['t'],
|
|
'minor' => (($row['changes'] & 0x0080) ? 0x24 : 0x18), // auto-calibration? if not, measurement start
|
|
'b_a' => $row['b_a_autocal'],
|
|
'freq' => $row['freq']
|
|
)
|
|
);
|
|
$p++;
|
|
}
|
|
else {
|
|
// measurement end
|
|
$m_end[$p - 1] = $row['t'];
|
|
}
|
|
}
|
|
else if( ($row['changes'] & 0x0080) && $row['b_a_autocal'] ) {
|
|
array_push(
|
|
$t_cal_start,
|
|
array(
|
|
't' => $row['t'],
|
|
'minor' => 0x24, // auto-calibration (or start of log)
|
|
'b_a' => $row['b_a_autocal'],
|
|
'freq' => $row['freq']
|
|
)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
// normal log data
|
|
$query = "SELECT t,major ";
|
|
$query .= "FROM log_zkl ";
|
|
$query .= "WHERE ";
|
|
$query .= " zkl=" . $_GET['zkl'] . " AND ";
|
|
$query .= " sdcard=" . $sdcard . " AND ";
|
|
$query .= " rpgmcount=" . $rpgmcount . " AND ";
|
|
$query .= " startup=" . $startup . " AND ";
|
|
$query .= " (major=1 OR major=2) ";
|
|
$query .= "ORDER BY id";
|
|
$result = mysql_run($query, $db_data_handle);
|
|
while( $row = mysql_fetch_assoc($result) ) {
|
|
if( $row['major'] == 1 ) {
|
|
$m_begin[$p] = $row['t'];
|
|
$m_end[$p] = -1;
|
|
if( $p > 0 && $m_end[$p - 1] == -1 ) {
|
|
$m_end[$p - 1] = $row['t'];
|
|
}
|
|
$p++;
|
|
}
|
|
else if( $p > 0 ) {
|
|
$m_end[$p - 1] = $row['t'];
|
|
}
|
|
}
|
|
}
|
|
if( $p > 0 && $m_end[$p - 1] == -1 ) $m_end[$p - 1] = $tmax;
|
|
// valid measurements? if not, bail out here
|
|
if( $p == 0 && !$_GET['all'] ) continue;
|
|
$n = $p;
|
|
|
|
//
|
|
// Draw b/a limit line
|
|
//
|
|
if( $logfile['file'] ) {
|
|
}
|
|
else if( $use_log_realtime ) {
|
|
// data already collected
|
|
}
|
|
else {
|
|
$query = "SELECT log_zkl.t,log_zkl.minor,log_calibratie.b_a,log_calibratie.freq ";
|
|
$query .= "FROM log_zkl,log_calibratie ";
|
|
$query .= "WHERE ";
|
|
$query .= " log_zkl.id=log_calibratie.id AND ";
|
|
$query .= " log_zkl.zkl=" . $_GET['zkl'] . " AND ";
|
|
$query .= " log_zkl.sdcard=" . $sdcard . " AND ";
|
|
$query .= " log_zkl.rpgmcount=" . $rpgmcount . " AND ";
|
|
$query .= " log_zkl.startup=" . $startup . " AND ";
|
|
$query .= " log_calibratie.b_a <> 0 "; // failed auto-calibration
|
|
$query .= "ORDER BY log_zkl.id";
|
|
$result = mysql_run($query, $db_data_handle);
|
|
while( $row = mysql_fetch_assoc($result) ) {
|
|
array_push($t_cal_start, $row);
|
|
}
|
|
}
|
|
$p = 0;
|
|
$p_cal = 0;
|
|
while( $p < $n && $m_end[$p] < $tmin ) $p++;
|
|
while( $p_cal < count($t_cal_start) && $p < $n ) {
|
|
$b_a = $t_cal_start[$p_cal]['b_a'];
|
|
$t_begin = $t_cal_start[$p_cal]['t'];
|
|
$t_end = ($p_cal + 1 == count($t_cal_start)) ? $log_tmax : $t_cal_start[$p_cal + 1]['t'];
|
|
if( $t_begin > $log_tmax ) {
|
|
$p_cal++;
|
|
continue;
|
|
}
|
|
if( $t_end < $log_tmin ) {
|
|
$p_cal++;
|
|
continue;
|
|
}
|
|
if( $t_begin < $m_begin[$p] ) $t_begin = $m_begin[$p];
|
|
if( $t_begin < $log_tmin ) $t_begin = $log_tmin;
|
|
if( $t_end > $m_end[$p] ) $t_end = $m_end[$p];
|
|
if( $t_end > $log_tmax ) $t_end = $log_tmax;
|
|
if( $t_end < $m_begin[$p] ) {
|
|
$p_cal++;
|
|
continue;
|
|
}
|
|
|
|
imageline($im,
|
|
$x_off + ((($t_begin - $tmin) / $duration) * $x_ext), $y_off - ($y_ext * $b_a),
|
|
$x_off + ((($t_end - $tmin) / $duration) * $x_ext), $y_off - ($y_ext * $b_a),
|
|
$lred
|
|
);
|
|
$p_cal++;
|
|
if( $t_end >= $m_end[$p] ) $p++;
|
|
}
|
|
|
|
//
|
|
// Plot the data
|
|
//
|
|
// get the data
|
|
if( $logfile['file'] ) {
|
|
$fp = fopen($logfile['file'], "r");
|
|
$date = strtotime(date("Y-m-d", $logfile['tmin']));
|
|
}
|
|
else if( $use_log_realtime ) {
|
|
$query = "SELECT t,b_a,rms ";
|
|
$query .= "FROM log_realtime ";
|
|
$query .= "WHERE ";
|
|
$query .= " zkl=" . $_GET['zkl'] . " AND ";
|
|
$query .= " (";
|
|
if( $id_tmin ) $query .= " id = " . $id_tmin . " OR ";
|
|
$query .= " (";
|
|
$query .= " id BETWEEN " . $id_min . " AND " . $id_max . " AND ";
|
|
$query .= " (changes & 0x0030) != 0 AND ";
|
|
$query .= " (mcu_state & 0x0001) != 0 ";
|
|
$query .= " )";
|
|
$query .= " ) ";
|
|
$query .= "ORDER BY id";
|
|
$result = mysql_run($query, $db_data_handle);
|
|
}
|
|
else {
|
|
// normal log data
|
|
$query = "SELECT log_zkl.t,log_meting.b_a,log_meting.rms";
|
|
if( $zkl_info['wcpu_versie']['datecode'] >= 0x20091006 )
|
|
$query .= ",log_meting.d_b_a,log_meting.d_rms";
|
|
$query .= " ";
|
|
$query .= "FROM log_zkl,log_meting ";
|
|
$query .= "WHERE ";
|
|
$query .= " log_zkl.id=log_meting.id AND ";
|
|
$query .= " log_zkl.zkl=" . $_GET['zkl'] . " AND ";
|
|
$query .= " log_zkl.sdcard=" . $sdcard . " AND ";
|
|
$query .= " log_zkl.rpgmcount=" . $rpgmcount . " AND ";
|
|
$query .= " log_zkl.startup=" . $startup . " ";
|
|
$query .= "ORDER BY log_zkl.id";
|
|
$result = mysql_run($query, $db_data_handle);
|
|
}
|
|
unset($t_start);
|
|
$p = 0;
|
|
while( $logfile['file'] ? $row = file_fetch_line($fp, $date) : $row = mysql_fetch_assoc($result) ) {
|
|
if( !isset($t_start) ) {
|
|
$t_start = $row['t'];
|
|
$b_a = $row['b_a'];
|
|
$rms = $row['rms'];
|
|
$d_b_a = $row['d_b_a'];
|
|
$d_rms = $row['d_rms'];
|
|
}
|
|
else {
|
|
$t_this = $t_end = $row['t'];
|
|
if(
|
|
(
|
|
$_GET['all'] &&
|
|
$t_end >= $log_tmin &&
|
|
$t_start <= $log_tmax
|
|
) ||
|
|
(
|
|
$p < $n &&
|
|
$t_end >= $m_begin[$p] &&
|
|
$t_end >= $log_tmin &&
|
|
($p == $n || $t_start < $m_end[$p]) &&
|
|
$t_start <= $log_tmax
|
|
)
|
|
) {
|
|
// adjust start and end of the line
|
|
if( $t_start < $log_tmin ) $t_start = $log_tmin;
|
|
if( $t_end > $log_tmax ) $t_end = $log_tmax;
|
|
if( !$_GET['all'] ) {
|
|
if( $t_start < $m_begin[$p] ) {
|
|
$t_start = $m_begin[$p];
|
|
// new measurement
|
|
$b_a = $row['b_a'];
|
|
$rms = $row['rms'];
|
|
}
|
|
if( $p < $n && $t_end >= $m_end[$p] ) {
|
|
$t_end = $m_end[$p];
|
|
$p++;
|
|
}
|
|
}
|
|
|
|
// b/a is more important than the rms-value
|
|
if( isset($_GET['show_rms']) ) {
|
|
$prev_rms = sqrt($rms) / 100.0;
|
|
$new_rms = sqrt($row['rms']) / 100.0;
|
|
|
|
if(
|
|
$zkl_info['wcpu_versie']['datecode'] >= 0x20091006 &&
|
|
$d_rms &&
|
|
($d_rms * $y_ext) > 1
|
|
) {
|
|
// draw a (lighter) rectangle to show the delta
|
|
$min_rms = sqrt($rms + $d_rms) / 100.0;
|
|
$max_rms = sqrt($rms - $d_rms) / 100.0;
|
|
|
|
imagefilledrectangle($im,
|
|
$x_off + ((($t_start - $tmin) / $duration) * $x_ext) , $y_off - ($y_ext * clip($min_rms, 0.0, 1.0)),
|
|
$x_off + ((($t_end - $tmin) / $duration) * $x_ext) - 1, $y_off - ($y_ext * clip($max_rms, 0.0, 1.0)),
|
|
$rms_tcolor
|
|
);
|
|
}
|
|
imageline($im,
|
|
$x_off + ((($t_start - $tmin) / $duration) * $x_ext), $y_off - ($y_ext * $prev_rms),
|
|
$x_off + ((($t_end - $tmin) / $duration) * $x_ext), $y_off - ($y_ext * $prev_rms),
|
|
$rms_color
|
|
);
|
|
if( $t_end == $t_this ) {
|
|
// draw connecting line for the next segment
|
|
imageline($im,
|
|
$x_off + ((($t_end - $tmin) / $duration) * $x_ext), $y_off - ($y_ext * $prev_rms),
|
|
$x_off + ((($t_end - $tmin) / $duration) * $x_ext), $y_off - ($y_ext * $new_rms),
|
|
$rms_color
|
|
);
|
|
}
|
|
}
|
|
|
|
if(
|
|
$zkl_info['wcpu_versie']['datecode'] >= 0x20091006 &&
|
|
$d_b_a &&
|
|
($d_b_a * $y_ext) > 1
|
|
) {
|
|
// draw a (lighter) rectangle to show the delta
|
|
imagefilledrectangle($im,
|
|
$x_off + ((($t_start - $tmin) / $duration) * $x_ext) , $y_off - ($y_ext * clip($b_a + $d_b_a, 0.0, 1.0)),
|
|
$x_off + ((($t_end - $tmin) / $duration) * $x_ext) - 1, $y_off - ($y_ext * clip($b_a - $d_b_a, 0.0, 1.0)),
|
|
$b_a_tcolor
|
|
);
|
|
}
|
|
imageline($im,
|
|
$x_off + ((($t_start - $tmin) / $duration) * $x_ext), $y_off - ($y_ext * $b_a),
|
|
$x_off + ((($t_end - $tmin) / $duration) * $x_ext), $y_off - ($y_ext * $b_a),
|
|
$b_a_color
|
|
);
|
|
if( $t_end == $t_this ) {
|
|
// draw connecting line for the next segment
|
|
imageline($im,
|
|
$x_off + ((($t_end - $tmin) / $duration) * $x_ext), $y_off - ($y_ext * $b_a),
|
|
$x_off + ((($t_end - $tmin) / $duration) * $x_ext), $y_off - ($y_ext * $row['b_a']),
|
|
$b_a_color
|
|
);
|
|
}
|
|
}
|
|
else if( $p < $n && $t_end >= $m_end[$p] ) {
|
|
$p++;
|
|
}
|
|
$t_start = $t_this;
|
|
$b_a = $row['b_a'];
|
|
$rms = $row['rms'];
|
|
$d_b_a = $row['d_b_a'];
|
|
$d_rms = $row['d_rms'];
|
|
}
|
|
}
|
|
// draw last segment
|
|
$t_end = $log_tmax;
|
|
if(
|
|
$p < $n &&
|
|
$t_end >= $m_begin[$p] &&
|
|
$t_end >= $log_tmin &&
|
|
($p == $n || $t_start < $m_end[$p]) &&
|
|
$t_start <= $log_tmax
|
|
) {
|
|
// adjust start and end of the line
|
|
if( $t_start < $m_begin[$p] ) $t_start = $m_begin[$p];
|
|
if( $p < $n && $t_end >= $m_end[$p] ) {
|
|
$t_end = $m_end[$p];
|
|
}
|
|
|
|
if( $t_start < $log_tmin ) $t_start = $log_tmin;
|
|
if( $t_end > $log_tmin ) {
|
|
if( $t_end > $log_tmax ) $t_end = $log_tmax;
|
|
|
|
if( isset($_GET['show_rms']) ) {
|
|
$prev_rms = sqrt($rms) / 100.0;
|
|
|
|
if(
|
|
$zkl_info['wcpu_versie']['datecode'] >= 0x20091006 &&
|
|
$d_rms &&
|
|
($d_rms * $y_ext) > 1
|
|
) {
|
|
// draw a (lighter) rectangle to show the delta
|
|
$min_rms = sqrt($rms + $d_rms) / 100.0;
|
|
$max_rms = sqrt($rms - $d_rms) / 100.0;
|
|
|
|
imagefilledrectangle($im,
|
|
$x_off + ((($t_start - $tmin) / $duration) * $x_ext), $y_off - ($y_ext * clip($min_rms, 0.0, 1.0)),
|
|
$x_off + ((($t_end - $tmin) / $duration) * $x_ext), $y_off - ($y_ext * clip($max_rms, 0.0, 1.0)),
|
|
$rms_tcolor
|
|
);
|
|
}
|
|
imageline($im,
|
|
$x_off + ((($t_start - $tmin) / $duration) * $x_ext), $y_off - ($y_ext * $prev_rms),
|
|
$x_off + ((($t_end - $tmin) / $duration) * $x_ext), $y_off - ($y_ext * $prev_rms),
|
|
$rms_color
|
|
);
|
|
}
|
|
|
|
if(
|
|
$zkl_info['wcpu_versie']['datecode'] >= 0x20091006 &&
|
|
$d_b_a &&
|
|
($d_b_a * $y_ext) > 1
|
|
) {
|
|
// draw a (lighter) rectangle to show the delta
|
|
imagefilledrectangle($im,
|
|
$x_off + ((($t_start - $tmin) / $duration) * $x_ext), $y_off - ($y_ext * clip($b_a + $d_b_a, 0.0, 1.0)),
|
|
$x_off + ((($t_end - $tmin) / $duration) * $x_ext), $y_off - ($y_ext * clip($b_a - $d_b_a, 0.0, 1.0)),
|
|
$b_a_tcolor
|
|
);
|
|
}
|
|
imageline($im,
|
|
$x_off + ((($t_start - $tmin) / $duration) * $x_ext), $y_off - ($y_ext * $b_a),
|
|
$x_off + ((($t_end - $tmin) / $duration) * $x_ext), $y_off - ($y_ext * $b_a),
|
|
$b_a_color
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Print additional info
|
|
//
|
|
if( !isset($_GET['hide_info']) ) {
|
|
// discard "doubles" in the $t_cal_start array
|
|
$dt = (9 * imagefontwidth($infofont) * $duration) / $x_ext;
|
|
$db_a = (4 * imagefontheight($infofont)) / $y_ext;
|
|
for( $i = 1; $i < count($t_cal_start); $i++ ) {
|
|
$j = $i;
|
|
while( --$j >= 0 ) {
|
|
if(
|
|
abs($t_cal_start[$j]['t'] - $t_cal_start[$i]['t']) < $dt &&
|
|
abs($t_cal_start[$j]['b_a'] - $t_cal_start[$i]['b_a']) < $db_a
|
|
) $t_cal_start[$j]['hide'] = TRUE;
|
|
}
|
|
}
|
|
// get "events"
|
|
$query = "SELECT id,t,minor ";
|
|
$query .= "FROM log_zkl ";
|
|
$query .= "WHERE ";
|
|
$query .= " zkl=" . $_GET['zkl'] . " AND ";
|
|
$query .= " sdcard=" . $sdcard . " AND ";
|
|
$query .= " rpgmcount=" . $rpgmcount . " AND ";
|
|
$query .= " startup=" . $startup . " AND ";
|
|
$query .= " major=5 AND ";
|
|
$query .= " (minor=0x11 OR minor=0x23) ";
|
|
$query .= "ORDER BY id";
|
|
$result = mysql_run($query, $db_data_handle);
|
|
// try to match the events with an entry in the array of calibration data
|
|
while( $row = mysql_fetch_assoc($result) ) {
|
|
for( $i = 0; $i < count($t_cal_start); $i++ ) {
|
|
if( $t_cal_start[$i]['t'] >= $row['t'] && !$t_cal_start[$i]['hide'] ) {
|
|
switch( $row['minor'] ) {
|
|
case 0x23:
|
|
$autocal_query = "SELECT aan_uit,status FROM log_calibratiestart WHERE id=" . $row['id'];
|
|
$autocal_result = mysql_run($autocal_query, $db_data_handle);
|
|
$autocal_row = mysql_fetch_assoc($autocal_result);
|
|
if( $autocal_row['aan_uit'] == 'uit' && $autocal_row['status'] == 'ok' )
|
|
$t_cal_start[$i]['event'] = 'auto-cal';
|
|
break;
|
|
case 0x11:
|
|
$t_cal_start[$i]['event'] = 'sweep';
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
// plot them in the graph
|
|
$p = 0;
|
|
$p_cal = 0;
|
|
while( $p < $n && $m_end[$p] < $tmin ) $p++;
|
|
while( $p_cal < count($t_cal_start) && $p < $n ) {
|
|
$b_a = $t_cal_start[$p_cal]['b_a'];
|
|
$f = $t_cal_start[$p_cal]['freq'];
|
|
$t_begin = $t_cal_start[$p_cal]['t'];
|
|
$t_end = ($p_cal + 1 == count($t_cal_start)) ? $log_tmax : $t_cal_start[$p_cal + 1]['t'];
|
|
if( $t_begin > $log_tmax ) {
|
|
$p_cal++;
|
|
continue;
|
|
}
|
|
if( $t_end < $log_tmin ) {
|
|
$p_cal++;
|
|
continue;
|
|
}
|
|
if( $t_begin < $m_begin[$p] ) $t_begin = $m_begin[$p];
|
|
if( $t_begin < $log_tmin ) $t_begin = $log_tmin;
|
|
if( $t_end > $m_end[$p] ) $t_end = $m_end[$p];
|
|
if( $t_end > $log_tmax ) $t_end = $log_tmax;
|
|
if( $t_end < $m_begin[$p] ) {
|
|
$p_cal++;
|
|
continue;
|
|
}
|
|
|
|
$x = $x_off + ((($t_begin - $tmin) * $x_ext) / $duration);
|
|
$y = $y_off - ($y_ext * $b_a);
|
|
if( $x < $x_off + 9 * imagefontwidth($infofont) ) {
|
|
imageline($im, $x, $y, $x , $y - imagefontwidth($infofont), $cal_info_color);
|
|
imageline($im, $x, $y, $x + imagefontwidth($infofont), $y, $cal_info_color);
|
|
imageline($im, $x, $y, $x + imagefontheight($infofont) * .7, $y - imagefontheight($infofont) * .7, $cal_info_color);
|
|
$x += imagefontheight($infofont);
|
|
$align = ALH_LEFT | ALV_BOTTOM;
|
|
}
|
|
else {
|
|
imageline($im, $x, $y - 1, $x - (imagefontwidth($infofont) >> 1), $y - 1 -(imagefontwidth($infofont) >> 1), $cal_info_color);
|
|
imageline($im, $x, $y - 1, $x + (imagefontwidth($infofont) >> 1), $y - 1 - (imagefontwidth($infofont) >> 1), $cal_info_color);
|
|
imageline($im, $x, $y, $x, $y - imagefontheight($infofont), $cal_info_color);
|
|
$align = ALH_CENTER | ALV_BOTTOM;
|
|
}
|
|
imagestringborderalign($im, $infofont, $x, $y - imagefontheight($infofont), $cal_info['event'] . "\n" . sprintf("b/a=%.3f", $b_a) . "\n" . sprintf("f =%5.0f", $f), $cal_info_color, $bgcolor_transp, $align);
|
|
$p_cal++;
|
|
if( $t_end >= $m_end[$p] ) $p++;
|
|
}
|
|
|
|
// get switch events (relay events are no longer plotted as the relay
|
|
// is no longer used to switch the short circuit between the rails
|
|
if( $logfile['file'] ) {
|
|
}
|
|
else if( $use_log_realtime ) {
|
|
}
|
|
else {
|
|
$query = "SELECT t,major,minor ";
|
|
$query .= "FROM log_zkl ";
|
|
$query .= "WHERE ";
|
|
$query .= " zkl=" . $_GET['zkl'] . " AND ";
|
|
$query .= " sdcard=" . $sdcard . " AND ";
|
|
$query .= " rpgmcount=" . $rpgmcount . " AND ";
|
|
$query .= " startup=" . $startup . " AND ";
|
|
$query .= " (";
|
|
$query .= " major=0xA AND ";
|
|
$query .= " (minor=0x68 OR minor=0x69)";
|
|
$query .= " ) ";
|
|
$query .= "ORDER BY id";
|
|
$result = mysql_run($query, $db_data_handle);
|
|
while( $row = mysql_fetch_assoc($result) ) {
|
|
$t_cal = $row['t'];
|
|
//if( $t_cal < $log_tmin ) $t_cal = $log_tmin;
|
|
//if( $t_cal > $log_tmax ) $t_cal = $log_tmax;
|
|
if( $t_cal >= $log_tmin && $t_cal <= $log_tmax ) {
|
|
$x = $x_off + ((($t_cal - $tmin) * $x_ext) / $duration);
|
|
$y = $y_off - $y_ext; // always at the b/a=1.000 line
|
|
imageline($im, $x, $y - 1, $x - (imagefontwidth($infofont) >> 1), $y - 1 -(imagefontwidth($infofont) >> 1), $cal_info_color);
|
|
imageline($im, $x, $y - 1, $x + (imagefontwidth($infofont) >> 1), $y - 1 - (imagefontwidth($infofont) >> 1), $cal_info_color);
|
|
imageline($im, $x, $y, $x, $y - imagefontheight($infofont), $cal_info_color);
|
|
$align = ALH_CENTER | ALV_BOTTOM;
|
|
imagestringborderalign(
|
|
$im, $infofont, $x, $y - imagefontheight($infofont),
|
|
($row['major'] == 0xD ? _("relais") : _("switch")) . " " . (($row['minor'] & 0x01) == 0 ? _("uit") : _("aan")),
|
|
$cal_info_color, $bgcolor_transp, $align
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Draw the title, on top of everything else
|
|
//
|
|
if( !isset($_GET['hide_title']) ) {
|
|
imagestringborderalign($im, $labelfont, $width >> 1, 0, sprintf(_("%s - Meting - %s tot %s"), $zkl_info['idcode'], strftime("%c", $tmin), strftime("%c", $tmax)), $gridcolor, $bgcolor_transp, ALV_TOP | ALH_CENTER);
|
|
if( $use_log_realtime )
|
|
imagestringborderalign($im, $labelfont, $width >> 1, imagefontheight($labelfont), _("(real-time data log)"), $gridcolor, $bgcolor_transp, ALV_TOP | ALH_CENTER);
|
|
}
|
|
|
|
//
|
|
// Output the final image
|
|
//
|
|
imagepng($im);
|
|
imagedestroy($im);
|
|
|
|
// clean-up
|
|
if( $db_main_info['file'] != $db_info['file'] ) mysql_close($db_main_handle);
|
|
mysql_close($db_data_handle);
|
|
|
|
?>
|