<?
// Input Variables
$node_id = empty($node_id) ? 0 : $node_id; // ID on the node we should draw data for
$nSizeX = empty($xsize) ? 450 : $xsize; // Total width of the picture
$nSizeY = empty($ysize) ? 80 : $ysize; // Total height of the picture
$font = empty($font) ? 2 : $font; // Font to all the text in the diagram
$dateStartTime = empty($starttime) ? null : $starttime; // The start of the time interval to draw
$dateStopTime = empty($stoptime) ? null : $stoptime; // The stop of the time interval to draw
$nDrawMode = empty($drawmode) ? 2 : $drawmode; // How the data should be drawn
$nHorPos = empty($xpos) ? 24 : $xpos; // Number of steps on the x-scale
$nDownTimeLevel = isset($downtime) ? $downtime : 5; // Help to decide the time that must go before a client is estimated as down
$nMode = empty($mode) ? 1 : $mode; // Text that explain what time (or %) it is between two delimitationlines on the x-scale
// Internal Variables
$strError = ""; // Error message
$bError = FALSE; // Tells if an error has occured or not
// Check if valid values. If not, set to default or set an error
$nMode = $nMode != 1 && $nMode != 2 && $nMode != 3 ? 1 : $nMode;
$nSizeX = $nSizeX < 1 ? 450 : $nSizeX;
$nSizeY = $nSizeY < 1 ? 80 : $nSizeY;
$font = $font < 1 || $font > 5 ? 2 : $font;
$nDrawMode = $nDrawMode < 1 || $nDrawMode > 2 ? 2 : $nDrawMode;
$nDownTimeLevel = $nDownTimeLevel < 0 ? 5 : $nDownTimeLevel;
$nHorPos = $nHorPos < 1 ? 24 : $nHorPos;
// is it a valid ID or not?
if ($node_id <= 0)
{
$strError .= "Not a valid node_id. ";
$bError = TRUE;
}
if(!empty($dateStopTime) && !empty($dateStartTime))
{
// If $dateStartTime and $dateStopTime have been sent as parameters to the program
// we calculate a valid $nStartTime && $nStopTime and finally we find a suitable $nHorPos also!
$nStopTime = mktime(substr($dateStopTime,6,2), 0, 0, substr($dateStopTime,2,2), substr($dateStopTime,4,2), substr($dateStopTime,0,2));
$nStartTime = mktime(substr($dateStartTime,6,2), 0, 0, substr($dateStartTime,2,2), substr($dateStartTime,4,2), substr($dateStartTime,0,2));
$nHorPos = ($nStopTime - $nStartTime) / 3600; // Presentation type: Hours
$nHorPos = $nMode == 2 ? ($nStopTime - $nStartTime) / 3600 / 24 : $nHorPos; // Presentation type: Days
$nHorPos = $nMode == 3 ? ($nStopTime - $nStartTime) / 3600 / 24 : $nHorPos; // Presentation type: Weeks
if ($nStartTime >= $nStopTime)
{
$bError = TRUE;
$strError .= "Not a valid time interval. ";
}
}
else
{
// If not $dateStartTime and $dateStopTime have been sent as parameters to the program
// we set $nStopTime to the time just now and calculate a valid $nStartTime with help of
// $nHorPos that was sent as a parameter.
$nStopTime = time();
//$nStopTime = 1015580663; // last value in the test database
switch($nMode)
{
case 1: $nStartTime = $nStopTime - $nHorPos * 3600; // 3600 = 60 * 60
break;
case 2: $nStartTime = $nStopTime - $nHorPos * 86400; // 86400 = 60 * 60 * 24
break;
case 3: $nStartTime = $nStopTime - $nHorPos * 86400;
break;
default: $nStartTime = $nStopTime - $nHorPos * 3600;
break;
}
}
// Internal Variables
$nFontHeight = ImageFontHeight($font); // Selected fonts height
$nFontWidth = ImageFontWidth($font); // Selected fonts width
$nLeft = 4; // the space to the left of drawn data
$nRight = 4; // the space to the right of drawn data
$nTop = 2 + $nFontHeight + 2; // the space over the drawn data
$nBottom = 4 + $nFontHeight + 2 + $nFontHeight + 5; // the space bellow the drawn data
$nHeight = $nSizeY - $nTop - $nBottom; // Height to use when drawing the data
$nWidth = $nSizeX - $nLeft - $nRight; // Width to use when drawing the data
$dStepX = ($nWidth / $nHorPos); // Size of each step on the x-scale
// Define header type
Header("Content-type: image/png");
// Create image
$im = ImageCreate($nSizeX, $nSizeY);
// Define colors
$clrWhite = ImageColorAllocate($im, 255, 255, 255); // Background color
$clrBlack = ImageColorAllocate($im, 0, 0, 0);
$clrUp = ImageColorAllocate($im, 0, 0, 224);
$clrDown = ImageColorAllocate($im, 224, 0, 0);
$clrTitle = ImageColorAllocate($im, 0, 0, 0);
$clrRed = ImageColorAllocate($im, 224, 0, 0);
// Draw outer border
ImageRectangle($im, 0, 0, $nSizeX-1, $nSizeY-1, $clrBlack);
ImageString($im, $font, $nSizeX-$nFontWidth*15-6, 2, "uptime", $clrUp);
ImageString($im, $font, $nSizeX-$nFontWidth*9-6, 2, "/", $clrTitle);
ImageString($im, $font, $nSizeX-$nFontWidth*8-6, 2, "downtime", $clrDown);
// Set style to the separator line
$arrSeparator=array($clrRed,$clrRed,$clrWhite,$clrWhite);
ImageSetStyle($im, $arrSeparator);
if (!$bError)
{
require_once("../../classes/dbconnection.php");
// Database access
$dbcn = new DBConnection();
$dbcn->Connect();
$query = "SELECT node_name FROM nodes WHERE node_id = '$node_id'";
$resultNodeName = $dbcn->Query($query); // Get the nodes name
$query = "SELECT utime FROM ping_times_log WHERE node_id = '$node_id' AND utime >= '$nStartTime' AND utime <= '$nStopTime' ORDER BY utime DESC LIMIT 30";
$result = $dbcn->Query($query); // Get data to check the minimum time between pings
if ($result)
{
$nCount = 0;
$nDataInterval = $nStopTime - $nStartTime;
while (List($utime) = $dbcn->FetchRow($result))
$time[$nCount++] = $utime;
// Check the minimum time between pings
for ($i = 1; $i < $nCount; $i++)
{
if (($time[$i - 1] - $time[$i]) < $nDataInterval)
$nDataInterval = $time[$i - 1] - $time[$i];
}
// Calculate the time that must go before a node is estimated as down
$nTimeBeforeDown = $nDataInterval * $nDownTimeLevel;
// Get all the values for the selected time
$query = "SELECT utime, ping_time FROM ping_times_log WHERE node_id = '$node_id' AND utime >= '$nStartTime' AND utime <= '$nStopTime' ORDER BY utime";
$result = $dbcn->Query($query);
}
$dbcn->Disconnect();
// Write title
if ($resultNodeName)
{
List($name) = $dbcn->FetchRow($resultNodeName);
ImageString($im, $font, 4, 2, "$name", $clrTitle);
}
else
{
ImageString($im, $font, 4, 2, "Unknown node", $clrTitle);
}
// Evaluate result
if ($result)
{
$nCount = 0;
$nLastTimeUp = $nCount; // index for the last time the node was up
while (List($utime, $ping_time) = $dbcn->FetchRow($result))
{
$time[$nCount] = $utime - $nStartTime;
if ($ping_time > 0)
{
$ping[$nCount] = 1;
$holder[$nCount] = 1;
$nLastUp = $nCount;
}
else
{
$holder[$nCount] = 0;
$bDown = TRUE;
// Filter out errors
// Wait for $nTimeBeforeDown seconds before ploting down
if (($time[$nCount] - $time[$nLastUp]) > $nTimeBeforeDown)
{
if ($ping[$nCount - 1] == 0)
$ping[$nCount] = 0;
else
{
for ($j = $nCount; $j > $nLastUp; $j--)
$ping[$j] = 0;
}
}
else
{
$ping[$nCount] = 1;
}
}
$nCount++;
}
if ($nCount > 0)
{
$nMinutes = strftime("%M", $nStopTime);
$nHours = strftime("%H", $nStopTime);
switch($nMode)
{
// $dPosTime Where to draw delimitation line on the x-scale
// $strMode Text that explain what time it is between two delimitationlines on the x-scale
// $nExtraPos Is to loop some extra times in the next for-loop when $nMode = 3. Otherwise the text to the left on the x-scale is missing
// hour
case 1: $nMinutesOffset = $dStepX / 60 * $nMinutes;
$dPosTime = $nLeft + ($nHorPos * $dStepX) - $nMinutesOffset;
$strMode = "hour";
$nExtraPos = 0;
break;
// day
case 2: $nHoursOffset = $dStepX / 24 * $nHours;
$nMinutesOffset = $dStepX / 1440 * $nMinutes; // (1440 = 24 * 60)
$dPosTime = $nLeft + ($nHorPos * $dStepX) - $nHoursOffset - $nMinutesOffset;
$strMode = "day";
$nExtraPos = 0;
break;
// week
case 3: $nHoursOffset = $dStepX / 24 * $nHours;
$nMinutesOffset = $dStepX / 1440 * $nMinutes; // (1440 = 24 * 60)
$dPosTime = $nLeft + ($nHorPos * $dStepX) - $nHoursOffset - $nMinutesOffset;
$strMode = "week";
$nExtraPos = 7; // Make sure all the text for the x-scale is printed
break;
default: break;
}
$bSeperator = FALSE;
$bDelimitationLine = TRUE;
$nStop = $nHorPos + $nExtraPos;
// Draw horizontal numbers or text
for($pos = 0; $pos <= $nStop; $pos++)
{
switch($nMode)
{
// $strTextX Text or number for x-scale
// $nTextOffset Dislocate $strTextX to the right place in relation to $nMode and the delimitationlines
// Hour
case 1: $strTextX = strftime("%H", $nStopTime - (3600 * $pos)); // 3600 = 60 * 60
$nTextOffset = $nFontWidth;
// Only print every other hour
if ((($strTextX % 2) == 0) && (($dPosTime + $nTextOffset) <= ($nLeft + $nWidth)) && (($dPosTime - $nTextOffset) >= $nLeft))
{
ImageString($im, $font, $dPosTime - $nTextOffset, $nTop + $nHeight + 4, $strTextX, $clrBlack);
}
// Should we draw separator line?
$bSeperator = $strTextX == "0" ? true : false;
break;
// Day
case 2: // Check if both name and number of the day fits between delimitationlines
if ($dStepX < (7 * $nFontWidth)) // Only number
{
$strTextX = strftime("%d", $nStopTime - (86400 * $pos)); // 86400 = 24 * 60 * 60
$nTextOffset = $nFontWidth;
}
else // Both name and number
{
$strTextX = strftime("%a %d", $nStopTime - (86400 * $pos));
$nTextOffset = 3 * $nFontWidth;
}
$nTextCenter = $dStepX / 2;
if ((($dPosTime + $nTextCenter + $nTextOffset) <= ($nLeft + $nWidth)) && (($dPosTime + $nTextCenter - $nTextOffset) >= $nLeft))
{
ImageString($im, $font, $dPosTime + $nTextCenter - $nTextOffset, $nTop + $nHeight + 4, $strTextX, $clrBlack);
}
// Should we draw separator line?
$bSeperator = strftime("%w", $nStopTime - 3600 * 24 * $pos) == "1" ? true : false;
break;
// Week
case 3: $strTextX = strftime("%V", $nStopTime - (86400 * $pos)); // 86400 = 24 * 60 *60
$nTextCenter = $dStepX * 7 / 2;
$nTextOffset = $nFontWidth;
if ($strTextX != strftime("%V", $nStopTime - 86400 * ($pos + 1)))
{
if (($dStepX * 7) >= (5 * $nFontWidth))
{
$strTextX = "w $strTextX";
$nTextOffset = 2 * $nFontWidth;
}
if ((($dPosTime + $nTextCenter + $nTextOffset) <= ($nLeft + $nWidth)) && (($dPosTime + $nTextCenter - $nTextOffset) >= $nLeft))
{
ImageString($im, $font, $dPosTime + $nTextCenter - $nTextOffset, $nTop + $nHeight + 4, $strTextX, $clrBlack);
}
$bDelimitationLine = true;
}
else
{
$bDelimitationLine = false;
}
// Should we draw separator line?
$bSeperator = strftime("%d", $nStopTime - 3600 * 24 * $pos) == "01" ? true : false;
break;
default: break;
}
if ($dPosTime >= $nLeft)
{
// draw separator line?
if ($bSeperator)
ImageLine($im, $dPosTime, $nTop, $dPosTime, $nTop + $nHeight, IMG_COLOR_STYLED);
// draw delimitation line?
if ($bDelimitationLine)
ImageLine($im, $dPosTime, $nSizeY - $nBottom - 3, $dPosTime, $nSizeY - $nBottom + 3, $clrBlack);
}
$dPosTime -= $dStepX;
}
// initiate the variables to use when drawing the data
$dPixelPerSec = $nWidth / ($nStopTime - $nStartTime);
$nLastChange = 0;
$bOldUp = $ping[0] > 0 ? TRUE : FALSE;
$nOldTime = $time[0];
$nOldStatus = $ping[0];
$nUpTime = 0;
$nDownTime = 0;
for ($i = 1; $i < $nCount; $i++)
{
$bUp = $ping[$i] > 0;
// Draw data
if ($bUp != $bOldUp || $i == ($nCount - 1))
{
$nOldX = ceil($time[$nLastChange] * $dPixelPerSec) + $nLeft;
$nX = ceil($time[$i] * $dPixelPerSec) + $nLeft;
$nExtraPixel = $nOldX == $nX ? 1 : 0; // maybe extra pixel so the width of the rectangle not is 0
if ($bOldUp) // Draw up
{
if ($nDrawMode == 1)
ImageFilledRectangle($im, $nOldX, $nTop, $nX - 1 + $nExtraPixel, $nTop + ($nHeight / 2) - 1, $clrUp);
else
ImageFilledRectangle($im, $nOldX, $nTop, $nX - 1 + $nExtraPixel, $nTop + $nHeight -1, $clrUp);
}
else // Draw down
{
if ($nDrawMode == 1)
ImageFilledRectangle($im, $nOldX, $nTop + ($nHeight / 2), $nX - 1 + $nExtraPixel, $nTop + $nHeight - 1, $clrDown);
else
ImageFilledRectangle($im, $nOldX, $nTop, $nX - 1 + $nExtraPixel, $nTop + $nHeight - 1, $clrDown);
}
$nLastChange = $i;
$bOldUp = $bUp;
}
// Count uptime and downtime
if ($nOldStatus != $ping[$i] || $i == ($nCount - 1))
{
if ($nOldStatus == 0)
$nDownTime += $time[$i] - $nOldTime;
else
$nUpTime += $time[$i] - $nOldTime;
$nOldTime = $time[$i];
$nOldStatus = $ping[$i];
}
}
// Calculate uptime in %
$nTotalTime = $time[$nCount - 1] - $time[0];
$dUpTime = round($nUpTime / $nTotalTime * 100, 1);
// Write uptime
ImageString($im, $font, ($nSizeX / 2) - (($nFontWidth * 9) / 2), 2, "Up: $dUpTime%" , $clrBlack);
}
else
{
$bError = TRUE;
$strError .= "There are no data in the database for the reqested time. ";
}
}
else
{
$bError = TRUE;
$strError .= "Not a valid query to the database. Check node_id. ";
}
}
// Write error message if an error has occurred
if ($bError)
ImageString($im, $font, $nLeft + 5, $nTop + ($nHeight / 2) - $nFontHeight, $strError, $clrTitle);
// Write time period
$strPeriodStart = strftime("%y-%m-%d %R", $nStartTime);
$strPeriodStop = strftime("%y-%m-%d %R", $nStopTime);
$str = "$strPeriodStart - $strPeriodStop [$strMode]";
ImageString($im, $font, ($nSizeX / 2) - (($nFontWidth * strlen($str)) / 2), $nSizeY - $nFontHeight - 2, $str , $clrTitle);
// Draw horizontal and vertical line
ImageLine($im, $nLeft, $nTop + $nHeight, $nLeft + $nWidth, $nTop + $nHeight, $clrBlack);
ImageLine($im, $nLeft, $nTop, $nLeft, $nTop + $nHeight, $clrBlack);
// Output Image
ImagePng($im);
ImageDestroy($im);
?>