More Desktop weather with GeekTool

I used to use GeekTool to put a little picture from Accuweather in the lower left corner of my desktop. The picture was actually mostly text, giving the current conditions for my hometown. It worked fine, and I wrote a little description of how I did it back in July of last year.

One thing I didn’t like about it was the size and readability of the text in the picture; the temperature—what I wanted most of the time—was kind of lost in all the other information. So today I went looking for another way to get the weather on my desktop. This writeup (which has lots of other GeekTool hints and examples) showed me how to scrape the info I wanted off a NOAA page. I made some adaptations, which I describe below.

First, I installed lynx, the venerable console browser. I used MacPorts, which put the lynx binary in /opt/local/bin/. Then I found the NOAA page for a weather station close to me. To do this, I went to and drilled down through their search system until I found the page for the Aurora, Illinois airport station—reasonably close to my home in Naperville.

I get the current weather by feeding the airport station’s URL to lynx. The text dump of the page is accomplished with this command:

lynx -dump -width 100

The -dump option causes lynx to send its interpretation of the page to STDOUT instead of opening in an interactive mode. The -width 100 option keeps lynx from wrapping some of the longer lines in the output. The “KARR” part of the URL is for the Aurora airport station.

Much of the information on the NOAA page is a list of readings over the past 24 hours. Since I’m only interested in the current conditions near the top of the page, I wrote a Perl program is called noaanow that plucks out some of the current data and arranges it the way I want.

#!/usr/bin/env perl

# Grab all the lines and put in an array.
@w = <>;

# Keep only certain lines for the current conditions.
@t = grep /^ +(Temperature \d|Wind|Relative)/, @w;

# Erase the leading spaces and parenthetical values.
for (@t){
  s/^ +//;
  s/ \([^)]+\)//g

# I want the temperature line to print on the bottom to make it
# easy to see on the desktop. The temperature is always on the
# second line, so exchange it with the last line.
($t[$#t], $t[1]) = ($t[1], $t[$#t]);

# Sometimes there's a windchill line, and sometimes there isn't.
# Add a blank line to the front of the array if there isn't.
unshift @t, "\n" if $#t == 2;

# Print the lines of interest in the order I want.
print join "", @t;

If I weren’t so fussy about how I want the data arranged, this could have been a one-liner. But I wanted the temperature to print at the bottom, so I had to do all the rearranging and adjusting in the middle of the program. (Update: There’s a bug in this script that prevents it from extracting the temperature on days below zero. The fixed script is here.)

Why at the bottom? Well, I usually don’t have my windows extend all the way to the bottom of the screen, so if noaanow prints the temperature at the bottom and I set the GeekTool location parameters just right, the temperature will always be visible in the lower left corner of my screen, like this.

I can hit F11 to see the other info if I’m interested (F11 is my keyboard shortcut to get Exposé to show the Desktop—I can’t remember if that’s the default or not). Most of the time I’m happy with just a glance at the temperature.

If you’re wondering why I have it in the lower left corner instead of the lower right, it’s because I have GeekTool showing my iTunes information in the lower right.

And speaking of GeekTool, I haven’t yet shown the full command I have GeekTool call. It is

/opt/local/bin/lynx -dump -width 120 |

but all on one line. You should note that:

I use Lucida Grande—colored white, bold, and with a drop shadow—to display the text on my blue desktop. This is basically the same font Apple has chosen for the names of items on the desktop, and it’s hard to argue with that choice.