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['firmware']['mcu'] = zkl_get_fw_version($zkl_info['mcu_versie']); $zkl_info['firmware']['wcpu'] = zkl_get_fw_version($zkl_info['wcpu_versie']); putenv("TZ=" . $zkl_info['tz']); if( isset($_GET['lc']) ) { i18n_settext_language($_GET['lc']); setlocale(LC_ALL, $_GET['lc']); } else { i18n_settext_language('nl'); setlocale(LC_ALL, "nl"); } // // Draw the graph // header("Content-type: image/png"); if( isset($_GET['plot']) ) { // database data: can be cached header('Cache-Control: public'); header('Expires: '); } else { // live data: do not cache header('Pragma: no-cache'); header('Expires: ' . date("r", strtotime("+1 year"))); } // error message global $error_str; $error_str = NULL; // create the image $im = imagecreatetruecolor($width,$height); if( function_exists("imageantialias") ) imageantialias($im, true); $black = imagecolorallocate($im, 0, 0, 0); $white = imagecolorallocate($im, 255, 255, 255); $grey = imagecolorallocate($im, 192, 192, 192); $lgrey = imagecolorallocate($im, 240, 240, 240); $green = imagecolorallocate($im, 0, 192, 0); $red = imagecolorallocate($im, 255, 0, 0); $dred = imagecolorallocate($im, 160, 0, 0); $blue = imagecolorallocate($im, 0, 0, 192); $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; if( $width <= 320 || $height <= 240 ) $labelfont = 1; else $labelfont = 2; if( isset($_GET['colors']) ) { $colors = explode(',', $_GET['colors']); for( $i = 0; $i < count($colors); $i++ ) $linecolor[$i] = imagecolorallocate($im, intval(substr($colors[$i], 0, 2), 16), intval(substr($colors[$i], 2, 2), 16), intval(substr($colors[$i], 4, 2), 16) ); } else { $linecolor = array( imagecolorallocate($im, 0, 0, 224), imagecolorallocate($im, 224, 0, 0), imagecolorallocate($im, 0, 0, 96), imagecolorallocate($im, 96, 0, 0) ); } // white background imagefill($im, 0, 0, $white); // plot data if( isset($_GET['plot']) ) { $plot = explode(',', $_GET['plot']); $samples = array(); $samples['count'] = 0; foreach( $plot as $id_to_plot ) { $query = "SELECT * FROM log_samples WHERE id=" . $id_to_plot; $result = mysql_run($query, $db_data_handle); if( $result ) { $row = mysql_fetch_assoc($result); if( $row['count'] > $samples['count'] ) $samples['count'] = $row['count']; // collect the samples $sample_array = array(); $buffer_ptr = 0; for( $sample = 0; $sample < $row['count']; $sample++ ) { $val = intval(substr($row['samples'], $buffer_ptr , 2), 16) + (intval(substr($row['samples'], $buffer_ptr + 2, 2), 16) << 8); $buffer_ptr += 4; if( $val & 0x8000 ) { // 2's complement negative number $val -= 0x10000; } array_push($sample_array, $val); } array_push($samples, $sample_array); } else array_push($samples, array()); } // timestamps should be the same $query = "SELECT t,sdcard,rpgmcount,startup FROM log_zkl WHERE id=" . $plot[0]; $result = mysql_run($query, $db_data_handle); $log_info = mysql_fetch_assoc($result); $time = $log_info['t']; // get environmental information, if requested if( !$_GET['hide-info']) { $status = array(); // get last temperature logged before the samples $query = "SELECT temp FROM log_temp WHERE id="; $query .= "("; $query .= "SELECT MAX(id) FROM log_zkl WHERE "; $query .= "zkl=" . $_GET['zkl'] . " AND "; $query .= "id < " . $plot[0] . " AND "; $query .= "sdcard=" . $log_info['sdcard'] . " AND "; $query .= "rpgmcount=" . $log_info['rpgmcount'] . " AND "; $query .= "startup=" . $log_info['startup'] . " AND "; $query .= "major=0xD AND minor=0x40"; $query .= ")"; $result = mysql_run($query, $db_data_handle); $row = mysql_fetch_array($result); $status['temp']['on-board'] = $row[0]; // re-calculate b/a $query = "SELECT v_reference,v_measure "; $query .= "FROM log_meting_detail "; $query .= "WHERE id ="; $query .= "("; $query .= "SELECT MIN(id) FROM log_zkl WHERE "; $query .= "zkl=" . $_GET['zkl'] . " AND "; $query .= "id BETWEEN " . $plot[0] . " AND " . $plot[count($plot) - 1] . " AND "; $query .= "sdcard=" . $log_info['sdcard'] . " AND "; $query .= "rpgmcount=" . $log_info['rpgmcount'] . " AND "; $query .= "startup=" . $log_info['startup'] . " AND "; $query .= "major=0x5 AND minor=0x12"; $query .= ")"; $result = mysql_run($query, $db_data_handle); if( $result ) { // calculate b/a $row = mysql_fetch_assoc($result); $status['detection']['b/a'] = $row['v_measure'] / $row['v_reference']; // get rms $query = "SELECT v_reference,v_measure "; $query .= "FROM log_meting_detail "; $query .= "WHERE id ="; $query .= "("; $query .= "SELECT MIN(id) FROM log_zkl WHERE "; $query .= "zkl=" . $_GET['zkl'] . " AND "; $query .= "id BETWEEN " . $plot[0] . " AND " . $plot[count($plot) - 1] . " AND "; $query .= "sdcard=" . $log_info['sdcard'] . " AND "; $query .= "rpgmcount=" . $log_info['rpgmcount'] . " AND "; $query .= "startup=" . $log_info['startup'] . " AND "; $query .= "major=0x5 AND minor=0x16"; $query .= ")"; $result = mysql_run($query, $db_data_handle); $row = mysql_fetch_assoc($result); $status['detection']['rms'] = $row['v_reference']; } else { // for new firmware, this will find the average b/a and not the last b/a, so // it is only used as a fall-back $query = "SELECT rms,b_a FROM log_meting WHERE id="; $query .= "("; $query .= "SELECT MIN(id) FROM log_zkl WHERE "; $query .= "zkl=" . $_GET['zkl'] . " AND "; $query .= "id > " . $plot[count($plot) - 1] . " AND "; $query .= "sdcard=" . $log_info['sdcard'] . " AND "; $query .= "rpgmcount=" . $log_info['rpgmcount'] . " AND "; $query .= "startup=" . $log_info['startup'] . " AND "; $query .= "major=0x5 AND (minor=0x10 OR minor=0x90)"; $query .= ")"; $result = mysql_run($query, $db_data_handle); if( $result ) { $row = mysql_fetch_assoc($result); $status['detection']['rms'] = $row['rms']; $status['detection']['b/a'] = $row['b_a']; } } // get last PWM frequency logged before the samples $query = "SELECT freq,b_a FROM log_calibratie WHERE id="; $query .= "("; $query .= "SELECT MAX(id) FROM log_zkl WHERE "; $query .= "zkl=" . $_GET['zkl'] . " AND "; $query .= "id < " . $plot[0] . " AND "; $query .= "sdcard=" . $log_info['sdcard'] . " AND "; $query .= "rpgmcount=" . $log_info['rpgmcount'] . " AND "; $query .= "startup=" . $log_info['startup'] . " AND "; $query .= "major=0x5 AND (minor=0x18 OR minor=0x24)"; $query .= ")"; $result = mysql_run($query, $db_data_handle); if( $result ) { $row = mysql_fetch_array($result); $status['detection']['freq'] = $row[0]; $status['detection']['quality'] = zkl_measurement_quality($status['detection']['b/a'], $row['b_a']); } } // time of one sampling+conversion sequence (this is a fixed value in ns) $samples['t_seq'] = 9769.2; } else { // login with the TCP-server if( FALSE ) {//isset($zkl_info['stcp_server']) ) { $server = $zkl_info['stcp_server']; zkl_set_private_key( "cert/private/mtinfo.key", "cert/private/passphrase" ); zkl_set_public_key( "cert/public/mtinfo.crt", "cert/public/di-ca.crt" ); } else $server = $zkl_info['tcp_server']; if( ($tcp_channel = zkl_tcplogin($_GET['zkl'], $server)) === FALSE ) { global $error_str; if( !$_GET['zkl'] || !$server ) $error_str = "Invalid parameters"; else $error_str = sprintf("%02X: %s", $zkl_status, $zkl_error); error_log("plot-samples: log-in with " . $server . " failed: " . $error_str); imagestringalign($im, $font, $width / 2, $height / 2, $error_str, $dred, AL_CENTERED); imagepng($im); imagedestroy($im); exit(1); } // get the measurement samples $samples = zkl_get_measurement($tcp_channel, 10.0); if( $samples === FALSE ) { global $error_str; if( !$_GET['zkl'] || !$server ) $error_str = "Invalid parameters"; else $error_str = sprintf(_("Error code") . " %02X: %s", $zkl_status, $zkl_error); error_log("plot-samples: read from " . $server . " failed: " . $error_str); } $time = time(); $samples[0] = $samples['v_ref']['raw']; $samples[1] = $samples['v_meas']['raw']; $samples[2] = $samples['v_ref']['filtered']; $samples[3] = $samples['v_meas']['filtered']; // extra info wanted? if( !$_GET['hide-info'] ) { $status = zkl_get_status($tcp_channel, 3.0); } // close connection to TCP server zkl_tcplogout($tcp_channel); } if( isset($_GET['show']) ) $channels = explode(",", $_GET['show']); // sanity check if( $error_str ) { imagestringalign($im, $labelfont, $width >> 1, 0, sprintf("%s - %s - %s", $zkl_info['idcode'], strftime("%c %z", $time), $error_str), $gridcolor, ALV_TOP | ALH_CENTER); // output the final image imagepng($im); imagedestroy($im); exit(1); } else if( $samples['count'] == 0 ) { error_log("plot-samples: no data in plot=" . $_GET['plot']); imagestringalign($im, $labelfont, $width >> 1, 0, sprintf("%s - %s - %s", $zkl_info['idcode'], strftime("%c %z", $time), _("Geen samples")), $gridcolor, ALV_TOP | ALH_CENTER); // output the final image imagepng($im); imagedestroy($im); exit(1); } // offsets with the drawing grid // largest string: -1.00 $x_off = 5 * imagefontwidth($labelfont) + 2; $x_ext = $width - $x_off - 3 * imagefontwidth($labelfont); // " ms" $y_off = ($height - imagefontheight($labelfont)) >> 1; $y_ext = (($height >> 1) - imagefontheight($labelfont)) * $scale; // // The grid is drawn _under_ the lines and ornaments like the title etc // // X tick marks if( $samples['t_seq'] ) { $duration = ($samples['count'] * $samples['t_seq']) / 1000.0; $x_tick_val = 0; $x_tick_off = 250; $x_tick_step = ($x_ext * $x_tick_off) / $duration; if( $x_tick_step > 0 ) for( $x = 0; $x <= $x_ext; $x += $x_tick_step) { imageline($im, $x_off + $x, $y_off - $y_ext, $x_off + $x, $y_off + $y_ext + 1, $lgrey); imageline($im, $x_off + $x, $y_off + 2, $x_off + $x, $y_off, $black); imagestringupalign($im, $labelfont, $x_off + $x, $y_off + 2, sprintf("%.3f", (float)$x_tick_val / 1000.0), $gridcolor, ALV_TOP | ALH_CENTER); $x_tick_val += $x_tick_off; } else imagestringalign($im, $labelfont, $x_off, $y_off + 2, sprintf("step: %.6f", $x_tick_step, $duration), $gridcolor, ALV_TOP | ALH_LEFT); imagestringalign($im, $labelfont, $width, $y_off + 2, "ms", $gridcolor, ALV_TOP | ALH_RIGHT); } // Y tick marks every 25%; label "amp" between 0.0 and 0.25 for( $y = -$y_ext; $y <= $y_ext; $y += ($y_ext / 4) ) { imageline($im, $x_off - 2, $y_off + $y, $x_off, $y_off + $y, $gridcolor); imagestringalign($im, $labelfont, $x_off - 2, $y_off + $y, sprintf("%.2f", -$y / $y_ext), $gridcolor, ALV_MIDDLE | ALH_RIGHT); } // draw legend imageline($im, $x_off, $y_off - $y_ext, $x_off, $y_off + $y_ext + 1, $gridcolor); imageline($im, $x_off, $y_off, $x_off + $x_ext, $y_off, $gridcolor); // // Draw the graph // $count = 0; for( $i = 0; $i < count($samples); $i++ ) if( count($samples[$i]) > $count ) $count = count($samples[$i]); for( $i = 0; $i < count($samples); $i++ ) if( !isset($channels) || in_array($i, $channels) ) draw_samples($im, $x_off, $y_off, $x_ext, $y_ext, 0.0, $count, $samples[$i], $linecolor[$i]); // // Ornaments (labels, title, etc) are drawn _over_ the graph // // show extra info if( !$_GET['hide-info'] ) { $y = 0; imagestringborderalign($im, $labelfont, $width, $y, sprintf("T = %3u\xB0C", $status['temp']['on-board']['C']), $gridcolor, $bgcolor_transp, ALV_TOP | ALH_RIGHT); $y += imagefontheight($labelfont); imagestringborderalign($im, $labelfont, $width, $y, sprintf("Q = %4u%%", $status['detection']['quality']), $gridcolor, $bgcolor_transp, ALV_TOP | ALH_RIGHT); $y += imagefontheight($labelfont) + 4; imagestringborderalign($im, $labelfont, $width, $y, sprintf("rms = %5u", $status['detection']['rms']), $gridcolor, $bgcolor_transp, ALV_TOP | ALH_RIGHT); $y += imagefontheight($labelfont); imagestringborderalign($im, $labelfont, $width, $y, sprintf("b/a = %.3f", $status['detection']['b/a']), $gridcolor, $bgcolor_transp, ALV_TOP | ALH_RIGHT); $y += imagefontheight($labelfont); imagestringborderalign($im, $labelfont, $width, $y, sprintf("f = %4u Hz", $status['detection']['freq']), $gridcolor, $bgcolor_transp, ALV_TOP | ALH_RIGHT); } // finally the title, on top of everything else imagestringborderalign($im, $labelfont, $width >> 1, 0, sprintf("%s - %s", $zkl_info['idcode'], strftime("%c", $time)), $gridcolor, $bgcolor_transp, ALV_TOP | ALH_CENTER); // output the final image imagepng($im); imagedestroy($im); // // Draw the samples // function draw_samples($im, $x_off, $y_off, $x_ext, $y_ext, $x_shift, $n, $samples, $color) { if( $n == 0 ) return FALSE; $x_step = $x_ext / $n; $x = $x_prev = $x_off + $x_shift * $x_step; $y = $y_prev = $y_off + ($samples[0] / 32768.0) * $y_ext; for( $i = 1; $i < $n; $i++ ) { $x += $x_step; $y = $y_off + ($samples[$i] / 32768.0) * $y_ext; imageline($im, $x_prev, $y_prev, $x, $y, $color); $x_prev = $x; $y_prev = $y; } } ?>