2 // Thermometer image script
3 // Ken True - webmaster@Saratoga-weather.org
4 // error_reporting(E_ALL); // uncomment to run testing
5 // Version 1.00 - 17-Sep-2007 - Initial release
6 // Version 1.01 - 18-Nov-2007 - added GD test, autoscale function, updated for sce=view on IIS systems
7 // Version 1.02 - 23-Nov-2007 - fixed Notice: errata on min/max calculations
8 // Version 1.03 - 28-Feb-2008 - added support for Carterlake/AJAX/PHP template integration
9 // Version 1.04 - 02-Feb-2009 - added support for 'dark' template (white text instead of black)
10 // Version 1.05 - 21-Oct-2009 - added support for Cumulus realtime.txt
12 // script available at http://saratoga-weather.org/scripts.php
14 // you may copy/modify/use this script as you see fit,
15 // no warranty is expressed or implied.
17 // This script reads WD clientraw.txt , VWS wflash.txt/wflash2.txt, or Cumulus realtime.txt
18 // gets the current, high, low temperature and draws a
19 // thermometer image (filled area + scale) on a transparent-background thermometer graphic
21 // usage on your page:
23 // <img src="thermometer.php" height="170" width="54" alt="current temperature, daily low/high" />
25 // New with version 1.01 - $autoScale = true; enables autoranging on output scale. The program will
26 // add majortick values to maximum or substract majortick values from minimum to always show the
27 // scale, current, minimum, maximum on the graphic.
28 //------------ settings ------------------
29 $wxSoftware = 'WD'; // 'WD' for Weather-Display, 'VWS' for Virtual Weather Station,
32 $UOM = 'F'; // set to 'C' for Celsius/Centigrade, 'F'=Fahrenheit
34 $autoScale = true; // set to false to disable autoscale.
36 // you only have to set one of these correctly based on the $useWD selection
37 // $wxSoftware = 'WD' : set the $clientrawfile
38 // $wxSoftware = 'VWS': set the $wflashDir
39 // $wxSoftware = 'CU': set the $realtimefile
41 $clientrawfile = './clientraw.txt'; // relative file address for WD clientraw.txt
42 $wflashDir = './wflash/Data/'; // directory for the the VWS wflash.txt and wflash2.txt files
43 // // relative to directory location of this script (include
44 // // trailing '/' in the specification
45 $realtimefile = './realtime.txt'; // relative file location for Cumulus realtime.txt file
47 // settings for ranges -- adjust for your climate :-)
48 // Fahrenheit settings
49 $TmaxF = 105; // maximum °F temperature on thermometer
50 $TminF = 10; // minimum °F temperature on thermometer
51 $TincrF = 5; // increment number of degrees °F for major/minor ticks on thermometer
52 $TMajTickF = 10; // major tick with value when °F scale number divisible by this
53 // Centigrade settings
54 $TmaxC = 40; // maximum °C temperature on thermometer
55 $TminC = -10; // minimum °C temperature on thermometer
56 $TincrC = 2; // increment number of degrees °C for major/minor ticks on thermometer
57 $TMajTickC = 10; // major tick with value when °C scale number divisible by this
59 $invertColor = true; // set to true if thermometer display is over black background
60 $BlankGraphic = './thermometer-blank.png'; // relative file address for thermometer blank image PNG
61 $BlankGraphicBlack = './thermometer-blank-black.png'; // for black background use
62 //------------ end settings --------------
63 // overrides from Settings.php if available
64 if(file_exists("Settings.php")) { include_once("Settings.php"); }
66 if (isset($SITE['uomTemp'])) {
67 $UOM = preg_replace('|°|is','',$SITE['uomTemp']);
68 if ($UOM <> 'F' and $UOM <> 'C') { $UOM = 'F'; }
70 if (isset($SITE['clientrawfile']) ) {$clientrawfile = $SITE['clientrawfile']; }
71 if (isset($SITE['wflashdir']) ) {$wflashDir = $SITE['wflashdir']; }
72 if (isset($SITE['realtimefile']) ) {$realtimefile = $SITE['realtimefile']; }
74 # was there a style selected from the form input
75 if (isset($_COOKIE['CSSstyle'])) {
76 $_SESSION['CSSstyle'] = $_COOKIE['CSSstyle'];
77 $CSSstyle = $_COOKIE['CSSstyle'];
78 } else if (isset($_SESSION['CSSstyle']) and $_SESSION['CSSstyle'] <> '' ) {
79 $CSSstyle = $_SESSION['CSSstyle'];
81 if (preg_match('|black|i',$CSSstyle) ) {
84 // end of overrides from Settings.php
86 // -------------------begin code ------------------------------------------
87 if (isset($_REQUEST['sce']) && strtolower($_REQUEST['sce']) == 'view' ) {
88 //--self downloader --
89 $filenameReal = __FILE__;
90 $download_size = filesize($filenameReal);
91 header('Pragma: public');
92 header('Cache-Control: private');
93 header('Cache-Control: no-cache, must-revalidate');
94 header("Content-type: text/plain");
95 header("Accept-Ranges: bytes");
96 header("Content-Length: $download_size");
97 header('Connection: close');
99 readfile($filenameReal);
103 if( ! function_exists("gd_info")){
104 die("Sorry.. this script requires the GD library in PHP to function.");
108 if (isset($_REQUEST['sw']) and strtolower($_REQUEST['sw']) == 'wd') { $wxSoftware = 'WD'; } // testing
109 if (isset($_REQUEST['sw']) and strtolower($_REQUEST['sw']) == 'vws') { $wxSoftware = 'VWS'; } // testing
110 if (isset($_REQUEST['sw']) and strtolower($_REQUEST['sw']) == 'cu') { $wxSoftware = 'CU'; } // testing
112 if (isset($_REQUEST['uom']) and strtolower($_REQUEST['uom']) == 'c') { $UOM = 'C'; }
113 if (isset($_REQUEST['uom']) and strtolower($_REQUEST['uom']) == 'f') { $UOM = 'F'; }
114 if (isset($_REQUEST['dark'])) {$invertColor = strtolower($_REQUEST['dark'])=='y'; }
116 if ($wxSoftware == 'WD') { // Get the Weather-Display clientraw.txt data file
118 //$dataraw = file_get_contents($clientrawfile);
120 // clean up any blank lines
122 #$dataraw = trim($dataraw);
123 $dataraw = preg_replace("/[\r\n]+[\s\t]*[\r\n]+/","\n",$dataraw);
124 $data = explode(" ", $dataraw);
126 //$curtemp = CtoF('50',1);
127 //$mintemp = CtoF('20',1);
128 //$maxtemp = CtoF('80',1);
129 #$curtemp = '<!--outsideTemp-->';
130 $curtemp = $_GET['t'];
131 $mintemp = $_GET['mint'];
132 $maxtemp = $_GET['maxt'];
134 } // end Weather Display data
136 if ($wxSoftware == 'VWS') { // Get the VWS Weather Flash data files
138 $filename = "${wflashDir}wflash.txt";
139 $file = file($filename);
140 $file = implode('',$file);
141 $data = explode(",",$file);;
143 $curtemp = FtoC($data[9],1);
145 $filename = "${wflashDir}wflash2.txt";
146 $file = file($filename);
147 $file = implode('',$file);
148 $data = explode(",",$file);;
150 $mintemp = FtoC($data[92],1);
151 $maxtemp = FtoC($data[36],1);
154 if ($wxSoftware == 'CU') { // Get the Cumulus realtime.txt file
156 $dataraw = file_get_contents($realtimefile);
158 // clean up any blank lines
159 $dataraw = trim($dataraw);
160 $dataraw = preg_replace("/[\r\n]+[\s\t]*[\r\n]+/","\n",$dataraw);
161 $data = explode(" ", $dataraw);
163 if ($inUOM == 'F' and $UOM == 'C') {
164 $curtemp = FtoC($data[2],1);
165 $mintemp = FtoC($data[28],1);
166 $maxtemp = FtoC($data[26],1);
167 } elseif ($inUOM == 'C' and $UOM == 'F') {
168 $curtemp = CtoF($data[2],1);
169 $mintemp = CtoF($data[28],1);
170 $maxtemp = CtoF($data[26],1);
173 $mintemp = $data[28];
174 $maxtemp = $data[26];
179 if (isset($_REQUEST['current'])) { $curtemp = $_REQUEST['current']; } // for testing
180 if (isset($_REQUEST['min'])) { $mintemp = $_REQUEST['min']; } // for testing
181 if (isset($_REQUEST['max'])) { $maxtemp = $_REQUEST['max']; } // for testing
184 if ($UOM == 'F') { // use Fahrenheit settings
185 $Tmax = $TmaxF; // maximum temperature on thermometer
186 $Tmin = $TminF; // minimum temperature on thermometer
187 $Tincr = $TincrF; // increment number of degrees for major/minor ticks on thermometer
188 $TMajTick = $TMajTickF;// major tick with value when scale number divisible by this
189 } else { // use Centigrade settings
190 $Tmax = $TmaxC; // maximum temperature on thermometer
191 $Tmin = $TminC; // minimum temperature on thermometer
192 $Tincr = $TincrC; // increment number of degrees for major/minor ticks on thermometer
193 $TMajTick = $TMajTickC;// major tick with value when scale number divisible by this
196 if($autoScale) { autoscale($curtemp,$mintemp,$maxtemp); }
198 genThermometer($curtemp, $mintemp,$maxtemp); // make graphic!
202 // ----------- functions ----------------------------------------------------------
204 function genThermometer( $current,$min,$max ) {
206 global $UOM,$BlankGraphic,$BlankGraphicBlack,$wxSoftware,$invertColor;
207 global $Tmax,$Tmin,$Tincr,$TMajTick;
209 // draw a filled thermometer with scale, min max on a blank thermometer image
210 $BGfile = $invertColor?$BlankGraphicBlack:$BlankGraphic;
211 $image = LoadPNG($BGfile);
213 // settings relative to the thermometer image file defines the drawing area
214 // for the thermometer filling
215 // these settings are SPECIFICALLY for the thermometer-blank.png image background
220 $maxY = 140;// bottom
223 $width = imagesx($image);
224 $height = imagesy($image);
227 $bg = imagecolorallocate($image,255,255,255 );
228 $tx = imagecolorallocate($image,0,0,0);
229 $blue = imagecolorallocate($image,0,0,255);
230 $red = imagecolorallocate($image,255,0,0);
232 $tx = imagecolorallocate($image,255,255,255);
233 $blue = imagecolorallocate($image,0,192,255);
234 $red = imagecolorallocate($image,255,32,32);
237 $Trange = $Tmax - $Tmin; // total temperature range
239 $Tpct = ($current-$Tmin)/($Trange); // percent for current temperature of range
241 $Y = (1-$Tpct)*($maxY-$minY)+$minY; // upper location for fill
243 // fill the thermometer with a red bar from bottom to $Y
244 imagefilledrectangle( $image,
251 // Draw tick marks and scale values on right
253 for ($T=$Tmin;$T<=$Tmax;$T+=$Tincr) {
255 $Tpct = ($T-$Tmin)/($Trange);
256 $Y = (1-$Tpct)*($maxY-$minY)+$minY;
258 if ($T == 0 or ($T % $TMajTick) == 0) { // Major Tick
260 imagefilledrectangle( $image,
266 imagestring($image, $font,
268 $Y - (ImageFontHeight($font)/2),
269 sprintf( "%2d", $T),$tx);
270 } else { // Minor tick
271 imagefilledrectangle( $image,
279 } // end do ticks legend
281 if(isset($min)) { // put on minimum temp bar/value
283 // $Tpct = ($min-$Tmin)/($Trange);
284 $Tpct = ( ( (float)$min-$Tmin )/ $Trange );
285 $Y = (1-$Tpct)*($maxY-$minY)+$minY;
286 imagefilledrectangle( $image,
291 $tstr = sprintf('%2d',round($min,0));
292 $tsize = strlen($tstr)*imagefontwidth($font+1);
293 imagestring($image, $font+1,
300 if(isset($max)) { // put on maximum temp bar/value
302 $Tpct = ($max-$Tmin)/($Trange);
303 $Y = (1-$Tpct)*($maxY-$minY)+$minY;
304 imagefilledrectangle( $image,
310 $tstr = sprintf('%2d',round($max,0));
311 $tsize = strlen($tstr)*imagefontwidth($font+1);
313 imagestring($image, $font+1,
315 $Y - imagefontheight($font+1),
319 // put legend on top with UOM
322 imagestring( $image, $font+2, ($width/2)-((strlen($cnt)/2)*ImageFontWidth($font+2)),
323 (10-(ImageFontHeight($font+2) / 2)),
326 // write current temperature on thermometer bulb
327 // $tstr = sprintf('%2d',round($current,0));
328 // $tsize = strlen($cnt)*imagefontwidth($font);
330 // imagestring($image, $font,
331 // ($minX+$maxX)/2 - $tsize/2 -2 ,
336 //imagestring( $image, $font, ($width/2)-((strlen($wxSoftware)/2)*imagefontwidth($font)),
337 // $height-imagefontheight($font),
341 header("content-type: image/png");
343 imagedestroy($image);
345 } // end genThermometer
348 function LoadPNG ($imgname) {
349 $im = @imagecreatefrompng ($imgname); /* Attempt to open */
350 if (!$im) { /* See if it failed */
351 $im = imagecreate (150, 30); /* Create a blank image */
352 $bgc = imagecolorallocate ($im, 255, 255, 255);
353 $tc = imagecolorallocate ($im, 0, 0, 0);
354 imagefilledrectangle ($im, 0, 0, 150, 30, $bgc);
355 /* Output an errmsg */
356 imagestring ($im, 1, 5, 5, "Error loading $imgname", $tc);
361 // CtoF: converts degrees Celcius to degress Farenheight (from Anolecomputing.com)
362 function CtoF($value, $precision) {
365 return round($value,$precision);
367 return round($value = (($value * 9 / 5) + 32),$precision);
369 } // end function C_to_F
371 // FtoC: converts degress Farenheight to degrees Celcius (from Anolecomputing.com)
372 function FtoC($value, $precision) {
375 return round($value,$precision);
377 return round(($value - 32) * (5/9),$precision);
379 } // end function F to C
381 // autoscale function .. adjust scale to fit current conditions if need be.
383 function autoscale($curtemp,$mintemp,$maxtemp) {
385 global $Tmax,$Tmin,$Tincr,$TMajTick;
387 $highest = max($curtemp,$Tmax,$maxtemp);
388 $lowest = min($curtemp,$Tmin,$mintemp);
391 while ($Tmax < $highest) {
395 while ($Tmin > $lowest) {
396 $Tmin = $Tmin - $TMajTick;