$blue, 'ntc' => $purple ); $zero_color = $lred; // 0 degrees line $info_color = $red; // additional info // // 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; } // Minimum time defined? if (!strlen($start)) { $tmin = $log_files[0]['tmin']; } else { $tmin = strtotime($start); } // Maximum time defined? if (!strlen($end)) { $tmax = time(); } else { $tmax = strtotime($end); } // Get zkl info $zkl_info = db_fetch_lance($zkl, "", 1); // Determine for which sensors to plot the data (in logical order) $supported_sensors = array(); if( db_check_system_device_capabilities($zkl_info['device'],"temperatuursensor on-board") ) $supported_sensors['on-board'] = db_fetch_system_device_status($zkl_info['device'], $_SESSION[$_PAGE_INFO['id']]['i18n'], '', 'on-board'); if( db_check_system_device_capabilities($zkl_info['device'], "temperatuursensor extern") ) $supported_sensors['ntc'] = db_fetch_system_device_status($zkl_info['device'], $_SESSION[$_PAGE_INFO['id']]['i18n'], '', 'extern'); // External sensor #2 are stored in the fields for the on-board sensor (MTinfo supports a maximum of two sensors in total) if( !db_check_system_device_capabilities($zkl_info['device'],"temperatuursensor on-board") && db_check_system_device_capabilities($zkl_info['device'], "temperatuursensor extern") && db_system_device_nr_tempsensors($zkl_info['device']) > 1 ) $supported_sensors['on-board'] = db_fetch_system_device_status($zkl_info['device'], $_SESSION[$_PAGE_INFO['id']]['i18n'], '', 'on-board'); $tz_offset = $tmin - intval(gmstrftime("%s", $tmin)); $tz_info = localtime($tmin, true); if( $tz_info['tm_isdst'] ) $tz_offset += 3600; $duration = $tmax - $tmin; // // Draw the grid // // draw background imagefill($im, 0, 0, $bgcolor); // offsets with the drawing grid // largest value label: 3 characters ("-10") // x: left to right // y: bottom to top global $x_off, $x_ext, $y_off, $y_ext; $x_off = 3 * 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 - 10 * imagefontwidth($labelfont)) - 1; // date/time $y_ext = $y_off; $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 5.0 C for( $T = $T_min; $T <= $T_max; $T += 5 ) { $y = ($y_ext * ($T - $T_min) / $T_range); imageline($im, $x_off, $y_off - $y, $x_off + $x_ext, $y_off - $y, $T == 0 ? $zero_color : $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("%d", $T), $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,2*60*60,4*60*60,6*60*60,8*60*60,12*60*60,24*60*60,7*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; } unset($x_save); for( $x = ($x_ext * $x_tick_val) / $duration; $x <= $x_ext; $x += $x_tick_step ) { $x_time = $tmin + $x_tick_val; if( $x_tick_off >= (24*60*60) ) { if ((!isset($x_save) || (($x_off + $x) >= ($x_save + (imagefontheight($labelfont) << 1))))) { if( strftime("%d", $x_time) == "01" ) { 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("%F", $x_time), $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, strftime("%F", $x_time), $gridcolor, ALV_TOP | ALH_CENTER); $x_save = $x_off + $x; } } else { if( strftime("%H%M%S", $x_time) == "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("%F", $x_time), $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", $x_time), $gridcolor, ALV_TOP | ALH_CENTER); } $x_tick_val += $x_tick_off; } if( $x_tick_off != (24*60*60) ) imagestringupalign($im, $labelfont, $x_off, $y_off - 2, strftime("%F", $tmin), $grey, ALV_BOTTOM | ALH_LEFT); // // Draw the legend // $y_legend_off = $y_off; // determine size of the legend; the lines are 3 characters long separated by a space; // the labels are separated by four spaces $y_legend_ext = 4; // (°C) foreach( $supported_sensors as $sensor => $sensor_info ) { $str = $sensor_info['display']; $y_legend_ext += strlen($str) + 4 + 4; } $y_legend_ext *= imagefontwidth($labelfont); if( $y_legend_ext < $y_ext ) $y_legend_off -= ($y_ext - $y_legend_ext) >> 1; foreach( $supported_sensors as $sensor => $sensor_info ) { $str = $sensor_info['display']; $y_legend_off -= strlen($str) * imagefontwidth($labelfont); imagestringupalign($im, $labelfont, 0, $y_legend_off, $str, $gridcolor, ALV_TOP | ALH_LEFT); $y_legend_off -= imagefontwidth($labelfont); imageline($im, imagefontheight($labelfont) >> 1, $y_legend_off , /* space */ imagefontheight($labelfont) >> 1, $y_legend_off - 3 * imagefontwidth($labelfont), /* line length */ $linecolor[$sensor] ); $y_legend_off -= (7 * imagefontwidth($labelfont)); } imagestringupalign($im, $labelfont, 0, $y_legend_off - 4 * imagefontwidth($labelfont), "(\xB0C)", $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 // // Initial values $skip_first = FALSE; $log_count = 0; // Valid data? if ((is_array($log_files)) && (is_array($log_rt))) { if ($log_files[0]['tmin'] > $log_rt[0]['t']) { // End of log_realtime is start of "first" log file $rt['end'] = $log_files[0]['tmin']; // Add dummy log_file entry to log_files array => and skip log files check $log_files = array_merge(array("Dummy"), $log_files); // Set skip flag $skip_first = TRUE; } } do { // Initial values $valid_entry = FALSE; // // LOG_ZKL // if (is_array($log_files)) { if (!$skip_first) { // get tmin,tmax for this logfile $log_tmin = $log_files[$log_count]['tmin']; $log_tmax = $log_files[$log_count]['tmax']; if ($log_tmin < $tmin && $log_tmax < $tmin) continue; if( $log_tmin < $tmin ) $log_tmin = $tmin; if( $log_tmax > $tmax ) $log_tmax = $tmax; // define logfile info $sdcard = $log_files[$log_count]['sdcard']; $rpgmcount = $log_files[$log_count]['rpgmcount']; $startup = $log_files[$log_count]['startup']; // get the data $query = "SELECT log_zkl.id,log_zkl.t,log_temp.sensor,log_temp.temp "; $query .= "FROM log_zkl,log_temp "; $query .= "WHERE "; $query .= " log_zkl.id=log_temp.id AND "; $query .= " log_zkl.zkl=" . $zkl . " AND "; $query .= " log_zkl.sdcard=" . $sdcard . " AND "; $query .= " log_zkl.rpgmcount=" . $rpgmcount . " AND "; $query .= " log_zkl.startup=" . $startup . " "; // select sensor foreach( $supported_sensors as $sensor => $sensor_info ) { $query .= " AND log_temp.sensor='" . $sensor . "' "; } $query .= "ORDER BY log_zkl.id"; $result = db_fetch_data($query, "log", null, 0); foreach($supported_sensors as $sensor => $sensor_info) { unset($t_begin[$sensor]); unset($stored_value[$sensor]); } $counter = 0; while($row = mysql_fetch_assoc($result['result'])) { // Get sensor info $sensor = $row['sensor']; // Increment counter $counter++; // Valid sensor if ($supported_sensors[$sensor]) { // First sensor data if(!isset($t_begin[$sensor])) { // Valid log data if ($row['t'] > $log_tmin) { $t_begin[$sensor] = $row['t']; } // Store last value $stored_value[$sensor] = $row; } else { // Changed or last log value if (($row['temp'] != $stored_value[$sensor]['temp']) || ($result['nr_rows'] == $counter)) { // Get start and end time $t_start = $t_begin[$sensor]; $t_end = $row['t']; if ($t_end >= $log_tmin && $t_start <= $log_tmax) { // Check boundaries if($t_start < $log_tmin) { $t_start = $log_tmin; } else if($t_end > $log_tmax) { $t_end = $log_tmax; } // Invalid timestamp => next sample if ($t_end < $t_start) continue; // Data too old (1 hour limit)? => Restart if (($t_begin[$sensor] < $t_end) && (($t_end - $t_begin[$sensor]) > 3600)) { $t_begin[$sensor] = $t_end; } // Average $row['temp'] = (($stored_value[$sensor]['temp'] + $row['temp'])/2); // Set flag $valid_entry = TRUE; // Draw line imageline($im, $x_off + ((($t_start - $tmin) / $duration) * $x_ext), $y_off - ($y_ext * ($stored_value[$sensor]['temp'] - $T_min) / $T_range), $x_off + ((($t_end - $tmin) / $duration) * $x_ext), $y_off - ($y_ext * ($row['temp'] - $T_min) / $T_range), $linecolor[$sensor]); // Update variables $t_begin[$sensor] = $t_end; $stored_value[$sensor] = $row; } } } } } // Last log entry foreach($supported_sensors as $sensor => $sensor_info) { if ((isset($t_begin[$sensor])) && (isset($stored_value[$sensor]))) { if ($log_tmax > $t_begin[$sensor]) { // Define start/end $t_start = $t_begin[$sensor]; $t_end = $log_tmax; // Set flag $valid_entry = TRUE; // Draw line imageline($im, $x_off + ((($t_start - $tmin) / $duration) * $x_ext), $y_off - ($y_ext * ($stored_value[$sensor]['temp'] - $T_min) / $T_range), $x_off + ((($t_end - $tmin) / $duration) * $x_ext), $y_off - ($y_ext * ($stored_value[$sensor]['temp'] - $T_min) / $T_range), $linecolor[$sensor]); } } } } } // Reset flag $skip_first = FALSE; if (is_array($log_files)) { // Valid entries found? Or searching for the end? if ($valid_entry) { // End of this log file is begin of log realtime $rt['begin'] = $tmax; } else { // No valid entries found => Retry with the log realtime, could be a "bug" $rt['begin'] = $tmin; } // Last log file => end of period, else begin of next log file $rt['end'] = (($log_count + 1) == sizeof($log_files)) ? $tmax : $log_files[$log_count + 1]['tmin']; // Check if end is not before begin if ((strlen($rt['begin'])) && (strlen($rt['end']))) { $rt['end'] = ($rt['end'] > $rt['begin']) ? $rt['end'] : $rt['begin']; } } else { $rt['begin'] = $tmin; $rt['end'] = $tmax; } // // LOG_REALTIME // if (is_array($log_rt)) { // Initial values $counter = 0; for ($i = 0; (($i < sizeof($log_rt)) && !((strlen($rt['end'])) && ($log_rt[$i]['t'] > $rt['end']))); $i++) { // Valid timeframe? if ((($log_rt[$i]['t'] >= $rt['begin']) || (!$rt['begin'])) && (($log_rt[$i]['t'] <= $rt['end']) || (!$rt['end']))) { // Increment counter $counter++; // Handle all temperature sensors foreach( $supported_sensors as $sensor => $sensor_info ) { // Valid data? if (!is_null($log_rt[$i]["temp_" . str_replace("-", "", $sensor)])) { // First sensor data if (!isset($t_begin[$sensor])) { // Valid log data $t_begin[$sensor] = $log_rt[$i]['t']; // Store last value $stored_value[$sensor] = $log_rt[$i]["temp_" . str_replace("-", "", $sensor)]; } else { if ($i) { //// Data too old (1 hour limit)? => Restart //if (($log_rt[$i - 1]['t'] < $log_rt[$i]['t']) && (($log_rt[$i]['t'] - $log_rt[$i - 1]['t']) > 3600)) { // $t_begin[$sensor] = $log_rt[$i]['t']; // // // Store last value // $stored_value[$sensor] = $log_rt[$i]["temp_" . str_replace("-", "", $sensor)]; //} } // Changed or last log value if ((($log_rt[$i]["temp_" . str_replace("-", "", $sensor)] != $stored_value[$sensor]) || (sizeof($log_rt) == $counter))) { // Get start and end time $t_start = $t_begin[$sensor]; $t_end = $log_rt[$i]['t']; // Average $temp = (($stored_value[$sensor] + $log_rt[$i]["temp_" . str_replace("-", "", $sensor)])/2); // Draw line imageline($im, $x_off + ((($t_start - $tmin) / $duration) * $x_ext), $y_off - ($y_ext * ($stored_value[$sensor] - $T_min) / $T_range), $x_off + ((($t_end - $tmin) / $duration) * $x_ext), $y_off - ($y_ext * ($temp - $T_min) / $T_range), $linecolor[$sensor]); // Update variables $t_begin[$sensor] = $t_end; $stored_value[$sensor] = $temp; } } } } } } } } while ((is_array($log_files)) && (++$log_count < sizeof($log_files))); // // Catch & destroy the final image // ob_start(); imagepng($im); download_document_data(ob_get_contents(), "write_file", "plot_temp"); ob_end_clean(); imagedestroy($im); } ?>