1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284
|
#!/usr/bin/perl
# -*- Perl -*-
#
# DigiTemp v2.1 gnuplot script
# Modified by Brian C. Lane <bcl@brianlane.com> www.brianlane.com
#
# Modified plot script from Russell Nelson <nelson@crynwr.com>
# for use with the GD module for Perl
#
# The GD module can be found at:
# http://www.perl.com/CPAN-local//modules/by-module/GD/
#
# More mods to add maximum and minimum temp display for each day
# NOTE: You will need to change the commands at the bottom that tell
# where to store and move the final .gif file to.
#
use GD;
# Transform the temperature into graph coordinates. Convert to Farenheit
# I already have fahrenheight data, so no conversion is needed.
sub ytransform {
$temp = shift;
# $temp = $temp * 9 / 5 + 32;
return int(250 - 2*$temp);
}
# You will need to customize these values for your setup
$height = 350;
$hmargin = 40;
$middlex = 300;
# display them all!
$dx=2.0/1.0;
# # of temperatures per sample (number of sensors)
$sensors = 3;
$samples_per_hour = 2;
# 5 Days, 24 hours a day, 2 samples per hour
$samples = 5*24* $samples_per_hour;
$width = $hmargin + $samples*$dx + $hmargin;
# print PLOT "create plot $width $height\n";
$im = new GD::Image( $width, $height );
# Allocate a bunch of colors
($white,$black,$red,$green,$orange,$lightgreen,$blue,$skyblue) =
(
$im->colorAllocate(255, 255, 255),
$im->colorAllocate(0, 0, 0),
$im->colorAllocate(255, 0, 0),
$im->colorAllocate(0,255,0),
$im->colorAllocate(255,0,255),
$im->colorAllocate(0,128,0),
$im->colorAllocate(0,0,255),
$im->colorAllocate(100,100,255)
);
# Grayscale -- Not currently used. I'll skip for now
#for ($i=0; $i<128; $i++) {
# print PLOT "colorallocate plot gray$i ".$i*2 ." ".$i*2 ." ".$i*2 ."\n";
#}
#sub dogray {
# ($light) = @_;
#
# if ($light < -70) {
# $gray = int(0.5 + 32 * ($light - -92) / (-70 - -92));
# } elsif ($light < 265) {
# $gray = int(32.5 + 32 * ($light - -70) / (265 - -70));
# } else {
# $gray = int(64.5 + 64 * ($light - 265) / (290 - 265));
# }
# $gray = 0 if ($gray < 0);
# $gray = 127 if ($gray > 127);
# print PLOT "filledrectangle plot ";
# print PLOT "$x 20 ";
# print PLOT $x+$dx." ".($height-20)." gray$gray\n";
#}
# Draw a Horizontal line at a temperature point
sub hline {
($y,$color) = @_;
$color = $skyblue unless $color;
$yname = $y;
$y = &ytransform($y);
$ychar = $y-6;
$numleft = 10;
$lineleft = 26;
$lineright = $width - 24;
$numright = $width - 20;
# print PLOT "string plot gdFont6x13 $numleft $ychar \"$yname\" $color\n";
$im->string(gdSmallFont,$numleft,$ychar,$yname,$color);
# print PLOT "line plot $lineleft $y $lineright $y $color\n";
$im->line($lineleft,$y,$lineright,$y,$color);
# print PLOT "string plot gdFont6x13 $numright $ychar \"$yname\" $color\n";
$im->string(gdSmallFont,$numright,$ychar,$yname,$color);
}
# Draw the temperature reference lines
#&hline(-20);
&hline(0 );
&hline(20 );
&hline(32, $lightgreen );
&hline(40 );
&hline(60 );
&hline(80 );
&hline(100 );
sub xtransform {
return $hmargin + $dx * shift;
}
# Draw a vertical line
sub vline {
($x,$label,$color) = @_;
$color = $skyblue unless $color;
$x = &xtransform($x);
$linetop = &ytransform(100);
$linebot = &ytransform(-20);
$ychar = &ytransform(107);
# print PLOT "string plot gdFont6x13 $x $ychar \"$label\" $color\n";
$im->string(gdSmallFont,$x-5,$ychar,$label,$color);
# print PLOT "line plot $x $linetop $x $linebot $color\n";
$im->line($x,$linetop,$x,$linebot,$color);
}
# See if the min or max data for the current day should be changed
# This function has been tested and works
sub minmax {
($sample,$temp,$sensor) = @_;
$day = int($sample / (24 * $samples_per_hour ) );
if( $temp > $max_temp[$day][$sensor] )
{
#print "oldmax[$day][$sensor] = $max_temp[$day][$sensor]\n";
$max_temp[$day][$sensor] = $temp;
#print "newmax[$day][$sensor] = $max_temp[$day][$sensor]\n";
}
if( $temp < $min_temp[$day][$sensor] )
{
#print "oldmin[$day][$sensor] = $min_temp[$day][$sensor]\n";
$min_temp[$day][$sensor] = $temp;
#print "newmin[$day][$sensor] = $min_temp[$day][$sensor]\n";
}
}
# --------------------------------[ MAIN CODE ]----------------------------
# Draw the vertical day lines
&vline(0*24*$samples_per_hour," -5d");
&vline(1*24*$samples_per_hour," -4d");
&vline(2*24*$samples_per_hour," -3d");
&vline(3*24*$samples_per_hour," -2d");
&vline(4*24*$samples_per_hour," yesterday");
&vline(5*24*$samples_per_hour," now");
# Here we read in all the samples. I have 3 temps for every
# 30 minutes within the day.
$lines = $sensors * $samples;
open(DOTTEMP, "tail -$lines /gonzo/var/log/temperatures|");
@dottemp = <DOTTEMP>;
close(DOTTEMP);
# Now all the temps are in dottemp -- it might be better to read it line
# by line for bigger files?
# Initialize the initial variables - I should use a list for this
$x = $hmargin;
$_= $dottemp[0];
@_ = split( " ", $_ );
$lasty0 = &ytransform($_[8]);
$_= $dottemp[1];
@_ = split( " ", $_ );
$lasty1 = &ytransform($_[8]);
$_= $dottemp[2];
@_ = split( " ", $_ );
$lasty2 = &ytransform($_[8]);
# Init the max and min temps and their points on the graph
# Keep track of data for all of the last 5 days
for( 0 .. 4 )
{
$day = $_;
for( 0 .. 2 )
{
$max_temp[$day][$_] = -50;
$min_temp[$day][$_] = 200;
}
}
$sample = 0;
# Plot each of the datapoints.
foreach (@dottemp) {
# Get the time and date, sensor number, temperature in c and f
($month,$day,$time,$d1,$sensor,$d1,$centigrade,$d1,$fahrenheight) = split(" ", $_ );
# Plot the next line for each sensor
# 0 - Harddrive #1 in gonzo
# 2 - Room Temperature
# 1 - Outside temperature
if( $sensor eq '0' )
{
$color = $red;
$y0 = &ytransform($fahrenheight);
$im->line(int($x),$lasty0,int($x+$dx),$y0,$color);
$lasty0 = $y0;
# Run minmax for the current day and sensor
&minmax( $sample, $fahrenheight, 0 );
}
if( $sensor eq '1' )
{
$color = $green;
$y1 = &ytransform($fahrenheight);
$im->line(int($x),$lasty1,int($x+$dx),$y1,$color);
$lasty1 = $y1;
# Run minmax for the current day and sensor
&minmax( $sample, $fahrenheight, 1 );
}
if( $sensor eq '2' )
{
$color = $orange;
$y2 = &ytransform($fahrenheight);
$im->line(int($x),$lasty2,int($x+$dx),$y2,$color);
$lasty2 = $y2;
# Run minmax for the current day and sensor
&minmax( $sample, $fahrenheight, 2 );
# Count the number of samples so we can figure out what day it is
$sample++;
# move to next position
$x += $dx;
}
}
# Print the Header for the Min/Max data for each day
for( 0 .. 4 )
{
$im->string(gdSmallFont,3+&xtransform($_*24*$samples_per_hour),&ytransform(-1),"Min Max",$black);
}
# Print the min and max temperatures
# Print the min/max for each day and sensor
for( 0 .. 4 )
{
$im->string(gdSmallFont,3+&xtransform($_*24*$samples_per_hour),&ytransform(-6),sprintf("%-6s %s",$min_temp[$_][0],$max_temp[$_][0]),$red);
$im->string(gdSmallFont,3+&xtransform($_*24*$samples_per_hour),&ytransform(-11),sprintf("%-6s %s",$min_temp[$_][1],$max_temp[$_][1]),$green);
$im->string(gdSmallFont,3+&xtransform($_*24*$samples_per_hour),&ytransform(-16),sprintf("%-6s %s",$min_temp[$_][2],$max_temp[$_][2]),$orange);
}
# Add the Date and time
$date = `date "+Generated at %H:%M on %a, %b %d %Y"`;
chop $date;
$im->string(gdSmallFont,$middlex-5,&ytransform(-30),$date,$black);
# Advertise!
$im->string(gdSmallFont,$middlex-5,&ytransform(-35),"with DigiTemp - http://www.brianlane.com",$black);
# Print the Color Key
$im->string(gdSmallFont,$hmargin,&ytransform(-30),"Harddrive #1",$red);
$im->string(gdSmallFont,$hmargin,&ytransform(-35),"Room Temperature",$green);
$im->string(gdSmallFont,$hmargin,&ytransform(-40),"Outside Temperature",$orange);
# Output it to a .gif image file
open( PLOT, ">/tmp/tempplot.gif");
print PLOT $im->gif;
close(PLOT);
# copy the image to its final destination and make sure it is owned
# by the right person.
system "cp /tmp/tempplot.gif /home/nexus/.public_html/tempplot.gif";
system "chown nexus.users /home/nexus/.public_html/tempplot.gif";
system "chmod 0644 /home/nexus/.public_html/tempplot.gif";
|