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( 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( !$_GET['ignore_errors'] ) { 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( !$_GET['ignore_errors'] ) { 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 = imagecolorallocate($im, 0, 0, 0); $white = imagecolorallocate($im, 255, 255, 255); $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, 248, 255, 248); $dgreen = imagecolorallocate($im, 0, 160, 0); $red = imagecolorallocate($im, 255, 0, 0); $lred = imagecolorallocate($im, 255, 192, 192); $dred = imagecolorallocate($im, 160, 0, 0); $blue = imagecolorallocate($im, 0, 0, 224); $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 $linecolor = array( $blue, $purple, $dred, $dgreen ); $info_color = $red; // additional info: status changes // // 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; } // // Constants // $battery_state = array(); $battery_state[0] = 'ok'; $battery_state[1] = 'alarm'; $battery_state[3] = 'leeg'; $battery_state[7] = 'verwijderd'; // // 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 = 4 * 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 } // The grid is drawn _under_ the lines and ornaments like the title etc // Y tick marks every 1.0 for( $niveau = 0; $niveau <= $V; $niveau += 1.0 ) { $y = $y_off - ($y_ext * $niveau / $V); imageline($im, $x_off, $y, $x_off + $x_ext, $y, $lgrey); imageline($im, $x_off - 2, $y, $x_off, $y, $black); imagestringalign($im, $labelfont, $x_off - 2, $y, sprintf("%.1f", $niveau), $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) //error_log(serialize($t) . " + " . $t_step); $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 // if (!isset($_GET['hide_legend'])) { $y_legend_off = $y_off; $y_legend_off -= ($y_ext - (count($show_batterij) * (10+4) - 4 + 3) * imagefontwidth($labelfont)) >> 1; for( $batterij = 0; $batterij < $n_batterij; $batterij++ ) if( in_array($batterij, $show_batterij) ) { imagestringupalign($im, $labelfont, 0, $y_legend_off - 6 * imagefontwidth($labelfont), sprintf("batt %d", $batterij + 1), $gridcolor, ALV_TOP | ALH_LEFT); imageline($im, imagefontheight($labelfont) >> 1, $y_legend_off - 7 * imagefontwidth($labelfont), /* space */ imagefontheight($labelfont) >> 1, $y_legend_off - 10 * imagefontwidth($labelfont), /* line length */ $linecolor[$batterij] ); $y_legend_off -= (10+4) * imagefontwidth($labelfont); } imagestringupalign($im, $labelfont, 0, $y_legend_off - 3 * imagefontwidth($labelfont), "(V)", $gridcolor, ALV_TOP | ALH_LEFT); } // // 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; // $sdcard = $logfile['sdcard']; $rpgmcount = $logfile['rpgmcount']; $startup = $logfile['startup']; // cache minimum and maximum id; this is a lot faster for some reason if( $use_log_realtime ) { $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; if( ($result = mysql_run($query, $db_data_handle)) ) { $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]; } } // get the status changes if( !isset($_GET['hide_info']) ) { $batt_event = array(); for( $batterij = 0; $batterij < $n_batterij; $batterij++ ) $batt_event[$batterij] = array(); if( $logfile['file'] ) { // not implemented } else if( $use_log_realtime ) { // two batteries, initially both absent $status[0] = -1; $status[1] = -1; $sel = -1; $charger = 0; $query = "SELECT id,t,changes,mcu_state,rc_state,batt_sel,batt1_niveau,batt2_niveau "; $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 & 0x0805) != 0"; $query .= " )"; $query .= " ) "; $query .= "ORDER BY id"; $result = mysql_run($query, $db_data_handle); while( $row = mysql_fetch_assoc($result) ) { if( ($t = $row['t']) < $tmin ) $t = $tmin; if( (($row['mcu_state'] >> 8) & 0x000F) != $status[0] ) { $status[0] = (($row['mcu_state'] >> 8) & 0x000F); array_push($batt_event[0], array( 'id' => $row['id'], 't' => $t, 'batterij' => 0, 'niveau' => $row['batt1_niveau'], 'status' => $battery_state[$status[0]], 'leeftijd' => 0 ) ); } if( (($row['mcu_state'] >> 12) & 0x000F) != $status[1] ) { $status[1] = (($row['mcu_state'] >> 12) & 0x000F); array_push($batt_event[1], array( 'id' => $row['id'], 't' => $t, 'batterij' => 1, 'niveau' => $row['batt2_niveau'], 'status' => $battery_state[$status[1]], 'leeftijd' => 0 ) ); } if( $row['batt_sel'] != $sel ) { $sel = $row['batt_sel']; array_push($batt_event[0], array( 'id' => $row['id'], 't' => $t, 'batterij' => $sel, 'niveau' => $sel ? $row['batt2_niveau'] : $row['batt1_niveau'], 'status' => 'selectie', 'leeftijd' => 0 ) ); } if( isset($_GET['show_charger']) && (($row['rc_state'] >> 10) & 0x0001) != $charger ) { if( ($charger = (($row['rc_state'] >> 10) & 0x0001)) ) $event = 'charger on'; else $event = 'charger off'; array_push($batt_event[0], array( 'id' => $row['id'], 't' => $t, 'batterij' => 0, 'status' => $event, 'niveau' => $row['batt1_niveau'], 'leeftijd' => 0 ) ); } } } else { $query = "SELECT log_zkl.id,log_zkl.t,log_batterijstatus.batterij,log_batterijstatus.status,log_batterijstatus.leeftijd "; $query .= "FROM log_zkl,log_batterijstatus "; $query .= "WHERE "; $query .= " log_zkl.id=log_batterijstatus.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_zkl.major=6 AND log_zkl.minor=16 AND "; $query .= " log_batterijstatus.batterij IN (" . implode(",", $show_batterij) . ") "; $query .= "ORDER BY log_zkl.id"; $result = mysql_run($query, $db_data_handle); while( $row = mysql_fetch_assoc($result) ) { @array_push($batt_event[$row['batterij']], $row); } if( isset($_GET['show_charger']) ) { $query = "SELECT log_zkl.id,log_zkl.t,log_zkl.minor "; $query .= "FROM log_zkl "; $query .= "WHERE "; $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_zkl.major=10 AND "; $query .= " (log_zkl.minor=0x7C OR log_zkl.minor=0x7D) "; $query .= "ORDER BY log_zkl.id"; $result = mysql_run($query, $db_data_handle); while( $row = mysql_fetch_assoc($result) ) { if( $row['minor'] == 0x7C ) $row['status'] = "charger off"; else $row['status'] = "charger on"; $row['batterij'] = 0; @array_push($batt_event[0], $row); } } } } // get the data if( $logfile['file'] ) { } else if( $use_log_realtime ) { $query = "SELECT id,t,batt1_niveau,batt2_niveau "; $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 & 0x0F00) != 0"; $query .= " )"; $query .= " ) "; $query .= "ORDER BY id"; $result = mysql_run($query, $db_data_handle); // log_realtime, only two batteries $b_start = 0; $b_end = 1; } else { $query = "SELECT log_zkl.id,t,log_batterij.batterij,log_batterij.niveau "; $query .= "FROM log_zkl,log_batterij "; $query .= "WHERE "; $query .= " log_zkl.id=log_batterij.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_batterij.batterij IN (" . implode(",", $show_batterij) . ") "; $query .= "ORDER BY log_zkl.id"; $result = mysql_run($query, $db_data_handle); } for( $batterij = 0; $batterij < $n_batterij; $batterij++ ) { $p_event[$batterij] = 0; unset($t_begin[$batterij]); } while( $row = mysql_fetch_assoc($result) ) { if( !$use_log_realtime ) $b_start = $b_end = $row['batterij']; for( $batterij = $b_start; $batterij <= $b_end; $batterij++ ) if( in_array($batterij, $show_batterij) ) { if( !$use_log_realtime ) $niveau = $row['niveau']; else $niveau = $row[sprintf('batt%d_niveau', $batterij + 1)]; if( !isset($t_begin[$batterij]) ) { $t_begin[$batterij] = $row['t']; $level[$batterij] = $niveau; } else { $t_start = $t_begin[$batterij]; $t_this = $t_end = $row['t']; if( $t_end >= $log_tmin && $t_start <= $log_tmax ) { if( $t_start < $log_tmin ) $t_start = $log_tmin; if( $t_end < $log_tmin ) break; else if( $t_end > $log_tmax ) $t_end = $log_tmax; $prev_level = $level[$batterij]; imageline($im, $x_off + ((($t_start - $tmin) / $duration) * $x_ext), $y_off - ($y_ext * $prev_level / $V), $x_off + ((($t_end - $tmin) / $duration) * $x_ext), $y_off - ($y_ext * $prev_level / $V), $linecolor[$batterij] ); imageline($im, $x_off + ((($t_end - $tmin) / $duration) * $x_ext), $y_off - ($y_ext * $prev_level / $V), $x_off + ((($t_end - $tmin) / $duration) * $x_ext), $y_off - ($y_ext * $niveau / $V), $linecolor[$batterij] ); // status change? if( !isset($_GET['hide_info']) ) while( $p_event[$batterij] < count($batt_event[$batterij]) && $batt_event[$batterij][$p_event[$batterij]]['id'] < $row['id'] ) { if( $t_end - $batt_event[$batterij][$p_event[$batterij]]['t'] > 1 ) { // due to datacompression (nr of log entries stored in the database), // the level may have been stored in the past instead of immediately // after the status change. $batt_event[$batterij][$p_event[$batterij]]['niveau'] = $prev_level; $p_event[$batterij]++; } else { $batt_event[$batterij][$p_event[$batterij]]['niveau'] = $niveau; $p_event[$batterij]++; } } } $t_begin[$batterij] = $t_this; $level[$batterij] = $niveau; } } } // draw last segment for( $batterij = 0; $batterij < $n_batterij; $batterij++ ) if( in_array($batterij, $show_batterij) ) { $t_start = $t_begin[$batterij]; $t_end = $log_tmax; if( $t_end >= $log_tmin && $t_start <= $log_tmax ) { if( $t_start < $log_tmin ) $t_start = $log_tmin; if( $t_end > $log_tmin ) { if( $t_end > $log_tmax ) $t_end = $log_tmax; imageline($im, $x_off + ((($t_start - $tmin) / $duration) * $x_ext), $y_off - ($y_ext * $level[$batterij] / $V), $x_off + ((($t_end - $tmin) / $duration) * $x_ext), $y_off - ($y_ext * $level[$batterij] / $V), $linecolor[$batterij] ); } } } // // Print additional status // if( !isset($_GET['hide_info']) ) for( $batterij = 0; $batterij < $n_batterij; $batterij++ ) { foreach( $batt_event[$batterij] as $event ) { $x = $x_off + ((($event['t'] - $tmin) * $x_ext) / $duration); $y = $y_off - ($y_ext * $event['niveau'] / $V); $right = ($x <= $x_off + (1 + strlen($batt_event[$batterij][$t_end])) * imagefontwidth($infofont)); if( $event['status'] == 'ok' || $event['status'] == 'verwijderd' ) { $y_label = $y - (imagefontheight($infofont) >> 1); if( $right ) { imageline($im, $x, $y, $x , $y - imagefontwidth($infofont), $info_color); imageline($im, $x, $y, $x + imagefontwidth($infofont), $y, $info_color); imageline($im, $x, $y, $x + imagefontheight($infofont) * .7, $y - imagefontheight($infofont) * .7, $info_color); $x_label = $x + imagefontheight($infofont); $align = ALH_LEFT | ALV_BOTTOM; } else { imageline($im, $x, $y, $x , $y - imagefontwidth($infofont), $info_color); imageline($im, $x, $y, $x - imagefontwidth($infofont), $y, $info_color); imageline($im, $x, $y, $x - imagefontheight($infofont) * .7, $y - imagefontheight($infofont) * .7, $info_color); $x_label = $x - imagefontheight($infofont); $align = ALH_RIGHT | ALV_BOTTOM; } } else { $y_label = $y + (imagefontheight($infofont) >> 1); if( $right ) { imageline($im, $x, $y, $x , $y + imagefontwidth($infofont), $info_color); imageline($im, $x, $y, $x + imagefontwidth($infofont), $y, $info_color); imageline($im, $x, $y, $x + imagefontheight($infofont) * .7, $y + imagefontheight($infofont) * .7, $info_color); $x_label = $x + imagefontheight($infofont); $align = ALH_LEFT | ALV_TOP; } else { imageline($im, $x, $y, $x , $y + imagefontwidth($infofont), $info_color); imageline($im, $x, $y, $x - imagefontwidth($infofont), $y, $info_color); imageline($im, $x, $y, $x - imagefontheight($infofont) * .7, $y + imagefontheight($infofont) * .7, $info_color); $x_label = $x - imagefontheight($infofont); $align = ALH_RIGHT | ALV_TOP; } } imagestringborderalign($im, $infofont, $x_label, $y_label, _($event['status']), $info_color, $bgcolor_transp, $align); if( $zkl_info['wcpu_versie']['datecode'] >= 0x20090628 ) { if( $align & ALV_TOP ) $y_label += imagefontheight($infofont); else $y_label -= imagefontheight($infofont); $val = $event['leeftijd']; imagestringborderalign($im, $infofont, $x_label, $y_label, sprintf("%u:%02u:%02u", $val / 3600, ($val / 60) % 60, $val % 60), $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 - Battery - %s to %s"), $zkl_info['idcode'], strftime("%c", $tmin), strftime("%c", $tmax)), $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); ?>