How To Add A WeatherBug
To give my web some sense of localization, I wanted to display some information about the local weather here in the Twin Cities. The perfect solution would be some kind of image that had the city, zip, temperature, wind, and maybe some kind of graphic keep it interesting.
The quick and easy solution to this problem is to use one of the 'weather on your website' solutions. These vendors get real-time weather data and format it into WeatherBug images that you can link to. While this does get you up and running quickly, it has two key drawbacks:
#1 - If the weather site is slow or down, your page loads slowly or simply hangs.
#2 - Every hit to your page is a hit to the weather site. That traffic can add up if you are on a large corporate Intranet.
The first version of a custom WeatherBug that eliminates the two problems above involve using a script that runs periodically that pulls down the WeatherBug image, and loads it on your local web server. Doing this limits the number of times that the WeatherBug image is downloaded to be 2 or 4 times per hour. In addition, if the latest WeatherBug fails to load, you can continue to serve out the most recent version that you were able to pull down.
While I do not have a script handy for this feature, it is easy enough to write one from this basic algorithm:
1) determine the URL required to download the WeatherBug image.
2) write a curl or wget command to execute that URL
3) write a short shell script that does the following:
a) pick a temp file name
b) erase that file name if it exists
c) run the curl or wget command, save the image to the temp file
d) check if the temp file name exists (ensure image was pulled down)
e) if it does exist, copy the temp image file to the web server
f) if it does not exist, raise an alarm in your monitoring system
The trick here is downloading the WeatherBug image to a temporary file name. That allows you to easily check if the download worked or not.
While this method is much more network friendly, it still has some serious problems:
#1 - Dotcom companies come and go, so weather sites frequently disappear.
#2 - Some weather sites are fronts for spyware or hacking.
#3 - Some sites depend on advertising, and the advertising is either unwelcome or is for a competitor.
#4 - The weather site sometimes doesn't notice problems for days at a time.
#5 - Some WeatherBug images have links that can potentially take away your visitors.
The thought behind the Perl/C solution is that I know that the National Weather Service publishes weather data, so why not use that data, but converted into a format that can be displayed on a web page?
As it turns out, the data is available by a web page request in XML format. This means that curl or wget will be able to pull down the data. Perl has a very simple XML module, so that will be ideal for reading the data, picking out selected data elements, and formatting the data for display. Writing the data to an image is a bit more difficult. The process uses the GD libraries plus a number of support libraries. GD allows you to write text to an image and copy one graphic to another graphic. The GD libraries are most easily called from a C program.
This architecture gives us the following process:
1) Use our caching algorithm from Example #1 to pull down the newest XML
file from the National Weather Service.
2) Use a Perl script to read the XML file and write out selected data elements in a format that is easy for the C program to read.
3) Use a C program to read the data from the Perl script and draw the data into an image using the GD libraries.
|Click to view:—WeatherBug Perl Program|
|Click to view:—WeatherBug C Program|
While this method works very well, it does have some drawbacks:
#1 - A C program using the GD libraries requires some deep skills to write, troubleshoot, and maintain.
#2 - GD libraries might not be installed on the systems that you need to run the WeatherBug, and they are very challenging to install.
#3 - Web server owners are not always willing to add modules to PERL, so the XML module might not be available.
#4 - A C compiler might not be available on the web server.
The next idea was to convert the program to Java to make it environment neutral. If a Java program works on one machine, it should, in theory, work the same way everywhere. Next, Java has an XML parser and graphics library built n, so installing software should not be a problem. Finally, Java should be available for just about any machine that can run a website.
|Click to view:—Main WeatherBug Program weatherbug.java|
As it turns out, the ideal of total portability is not yet 100% realized. First, my web host did not have Java installed. It turns out that can be worked around. If you have a shell level web hosting account, you can log into the shell and install the JRE and JDK in your home directory without needing root access. In addition, the fonts are not the same across machines.
When working on my watermark project, I discovered the ImageMagick tool suite. My line of thought was if ImageMagick can put text into an image, and copy one image onto another image, it can do everything that is needed to make the WeatherBug image. I also noticed that the XML data from the National Weather Service follows a very friendly layout that makes it easy to pick data from the file using grep and cut. As a result, I decided to rewrite the WeatherBug as a simple UNIX shell script that used grep and cut to pick data from the XML file, and call ImageMagick tools to make the WeatherBug image on the fly.
|Click to view:—Main WeatherBug Program wbug.sh|
|Click to view:—WeatherBug Driver get_weather.sh|
|Click to view:—Sample Data File KMSP.xml|
This version seems to work very well for me. It is easy to make changes to formatting because it is in shell code. It is quick to test the results because you don't have to compile the code. The graphics stay the same since I am calling a local font file, and can package up the fonts with the code for distribution. It maybe isn't as fast as a compiled version, but since it only runs once an hour, it doesn't have to have stellar performance.
Here are some notes on key pieces of code:
convert -size 166x90 xc:grey $FNAME
Convert will create a blank image 166 pixels wide by 90 pixes high, fill it with the color gray, and save it to the file KMSP.png, which is stored in the FNAME variable.
TX02=`grep '<weather>' $XMLF | cut -d'>' -f2 | cut -d'<' -f1`
This shell pipeline pulls the weather text string out of the XML file. It does this by searching the XML file for the weather tag, then splitting the line from the XML file after the close of the weather tag and before the end weather tag. The cut command is very handy for splitting lines as long as you can identify a unique spot to split the line.
convert $FNAME -font ./TimesBold.ttf -pointsize 14 -draw "text 3,14 '$TX01'" $FNAME
convert $FNAME -font ./HelveticaNeue.ttf -pointsize 12 -draw "text 62,29 '$TX02'" $FNAME
These two lines are examples of drawing text to an image. The first command writes the bold city and state name, while the second line writes the weather status. The convert command takes the named input file, sets up the named font and pointsize, then draws the text in the TX01 or TX02 variable, using the coordinates specified (3 over and 14 down, or 62 over and 29 down), and saves the result back to the same file name.
composite -geometry +4+16 icons/$ICN $FNAME $FNAME
The composite command layers one image on top of another image. In this case, we place the file named by the variable ICN on top of the file named by FNAME, and store the results in the same place. Further, the upper left corner of ICN should be placed 4 pixes to the right and 16 pixels down from the top left corner.
Authored by John A. Weeks III, Copyright © 1996—2012, all rights reserved.
For further information, contact: email@example.com