Ok, this is a wierd one, but I thought it was worth sharing anyway.

Some of you know that I enjoy sailing. The problem is you really never know when you'll get that urge to drop everything and go down to the marina. Sometimes this will happen at times when an immediate weather forecast isn't readily available. And in sailing, weather is important.

Sure, I could drive down to the marina and turn on the weather radio, or tune in the station on the car stereo, but where's the fun in that?

This script is the answer. I have set up a procmail filter that intercepts email messages sent from my AT&T Wireless cell phone to a particular email address. If the message has in its subject: "Forecast", and in its body a city, and a state abbreviation, the filter invokes the following script.

The script then goes to the NOAA website, grabs the forecast for the city in question (including storm warnings if there are any), and sends off a series of email messages back to my cellphone.

For testing purposes, if the script is not given an email address to respond to, it will just print the output.

Here's the tricky part. AT&T Wireless truncates email messages at 120 characters. So this script does its best to try to abbreviate most of the words in the forecast. The output takes a little getting used to, but almost always fits into 120 characters per day. The script sends one email per day, and one per storm-warning. So if you run it with an email address, it'll spew out six or more 120 character messages, each representing one day's worth of forecast, plus however many messages it takes to communicate any relevant storm warnings.

The usage is as follows:

First, using the defaults:

./ __OUTPUT__ tnite: mostly clr eve, low clouds/ fog ovrngt. lows arnd 60. W wind arnd 15 mph eve. Thu: low clouds/ fog am. othrwse mostly sunny. highs mid 60s to upr 70s. W wind 15 to 20 mph pm. Thu nite: mostly clr eve, low clouds/ fog ovrngt. lows lwr 60s. W wind 15 to 20 mph eve. Fri: low clouds/ fog am. othrwse mostly sunny. highs upr 60s/ 70s. Fri nite: mostly clr eve, low clouds/ fog ovrngt. lows lwr 60s. Sat - Wed: areas of nite/ am low clouds/ fog, othrwse mostly clr. highs near 70 at beach to mid 70s to lwr 80s inlnd. lows arnd 60.
This will give you the forecast for Los Angeles, CA. You can also invoke the script like this:
./ 'Los Angeles' 'CA' which case, it will give you the forecast for the city and state you've specified.

If you want to supply an email address, you may also do that:

./ 'Los Angeles' 'CA' ''

And finally, for you windows folks (myself included), you may specify a mailhost to use for a direct SMTP mailing:

perl "Los Angeles" "CA" "" ""

If you don't want to bother with all the work of setting up an email filter to invoke the script, you may just set it up in a cron job or a Windows Scheduler job to have the forecast sent to your mobile device once every 24 hours.

If you're one of the lucky people whos cell phone carrier doesn't truncate messages at 120 characters, you should be able to easily modify the script to send everything at once, in one single email. ...not too difficult.

This is mostly a proof of concept for myself, and something that I just wanted to play with. I wanted to try out the Geo::WeatherNOAA. I hope it sparks some ideas out there... Here's the code:

use strict; use warnings; use Geo::WeatherNOAA; use MIME::Lite; my ( $city, $state, $email, $mailhost ) = @ARGV; $city = $city || 'Los Angeles'; $state = $state || 'CA'; if ( $^O =~ /MSWin32/ and defined $mailhost ) { MIME::Lite->send( 'smtp', $mailhost, Timeout=>60 ) } { my %abbrev = map { chomp; split /\s*\|\s*/ } <DATA>; my $keywords = join '|', keys %abbrev; sub abbreviate { my ( $prefix, $text ) = @_; my $out = lc ( $prefix . ': ' . $text ); $out =~ s/\b($keywords)\b/$abbrev{$1}/g; # Abbreviate $out =~ s/\.{3}/./; # Repunctuate $out =~ s/\s\bin\b//g; # drop 'in' $out =~ s/\s\bthe\b//g; # drop 'the' $out =~ s/\s*([,.;\/]+)\s*/$1 /g; # Too much space. return $out; } } my ( $date, $warnings, $forecast, $coverage ) = process_city_zone( $city , $state, '', 'get'); foreach my $warning ( @$warnings ) { if ( $warning =~ /\w/ ) { my $out = abbreviate ( '!!!', $warning ); if ( defined $email ) { my $msg = MIME::Lite->new( 'From' => $email, 'To' => $email, 'Subject' => 'Warning', 'Data' => $out ); $msg->send; } else { print "Warning:\n$out\n"; } } } foreach my $frame ( @{ prepare_forecast( $forecast ) } ) { if ( defined $email ) { my $msg = MIME::Lite->new( 'From' => $email, 'To' => $email, 'Subject' => 'Forecast', 'Data' => $frame ); $msg->send; } else { print "$frame\n"; } } sub prepare_forecast { my ( $info ) = shift; return [ map { abbreviate( $_, $info->{$_} ) } keys %$info ]; } __DATA__ tonight| tnite patchy| ptch clear| clr evening| eve cloudy| cldy overnight| ovrngt upper| upr morning| am afternoon| pm south| S north| N east| E west| W northeast| NE southeast| SE southwest| SW northwest| NW winds| wind monday| Mon tuesday| Tue wednesday| Wed thursday| Thu friday| Fri saturday| Sat sunday| Sun tomorrow| Tomrw through| - otherwise| othrwse then| , night| nite inland| inlnd beaches| beach lower| lwr and| / around| arnd

I've found that the NOAA website is kind of finacky about its forecast cities. I had to fiddle a bit to find which cities work and which don't. For example, for some reason, Oxnard, CA doesn't work.

Comments are welcomed; I'm always interested in sharpening my skills.


Replies are listed 'Best First'.
Re: Weather Forecasts emailed to cell phone
by zakzebrowski (Curate) on Jul 02, 2004 at 13:45 UTC
    As a complete aside, if you're really worried about sudden storms etc, you may wish to consider paying $5 anually to They have a capability to automatically send you email for when there are weather alerts in your area. The advantage of using this service over your script, is that if your home pc goes down because of a thunderstorm, you would still get the warning... They have a really nice selection of weather output, including for non-us locations. (Note, I'm not affiliated with this site, just an FYI.)

    Zak - the office

      Actually the whole thing is mostly moot: The boat's VHF radio has something like eight channels on which to receive NOAA weather forecasts and current conditions, including marine conditions such as wave height and swells data.

      And if the boat's VHF isn't handy, my FRS radio has the same weather channels.

      I have found that the easiest to use source, however, is, as it displays both regular forecast data and marine information, including small craft advisories.

      And of course, I live in Southern California, where weather problems are rare anyway. Still, I found the exercise of putting together this little script to be educational and fun. I think I may take the time to add better command-line argument handling with Getopt::Long.