If you'd like to be able to give your Asterisk users the current weather and optionally the forecast, you can install the Weather::Underground module from CPAN and then use a Perl script to pull the weather conditions from Wunderground on a periodic basis. The weather conditions can be converted, using Festival, to a wave file which can be played by Asterisk, to a user.
Begin by installing the Weather::Underground Perl module:
su perl -MCPAN -e shell install Weather::Underground
Then, put this perl script in a convenient location.
/etc/asterisk/local/FetchWeather.pl:
#!/usr/bin/perl # # Get the local weather from Weather Underground. # # # Usage # ----- # # FetchWeather.pl [--Forecast] [--Place=place] [output_file] # # Forecast Switch indicating that the forecast is to be retrieved # as well as the weather data. If the forecast can be # fetched, it will be appended to the current conditions. # # Place The name of place whose weather data is to be retrieved. # This should be a string like "Norwood, Massachusetts". # The default place name is defined by the $DEFAULTPLACE # variable herein ("Norwood, Massachusetts"). # # output_file Optional output file name prefix. Two files will be # generated, one with a ".txt" extension and one with a # ".wav" extension. The prefix given here will be used to # name those files. The default file name prefix is defined # by the $DEFAULTFILE variable herein # ("/home/monitor/wunderground/Weather-Norwood"). # # # Description # ----------- # # This program gets the current weather information (and optionally the # forecast) from Wunderground and produces a wave file which can be played by # Asterisk, when the user asks for the weather. # ############################################################################## # # Include all of the modules that we use. # use Getopt::Long; use LWP::UserAgent; # One include covers all of them! #db use LWP::Debug qw(+); # LWP debugging, if needed use URI::URL; # Or, perhaps not use Weather::Underground; # # Local information, if not specified. # my $DEFAULTPLACE = "Norwood, Massachusetts"; my $DEFAULTFILE = "/home/monitor/wunderground/Weather-Norwood"; # # Wunderground XML API URL, used to pull forecasts. Don't include the # "http://" on the front. We add it automatically. # my $FORECASTURL = "api.wunderground.com/auto/wui/geo/ForecastXML/" . "index.xml?query="; # # Table to convert Wunderground wind directions into something Festival # can say. # my %WindDir = ( "N" => "North", "NNE" => "North North East", "NE" => "North East", "ENE" => "East North East", "E" => "East", "ESE" => "East South East", "SE" => "South East", "SSE" => "South South East", "S" => "South", "SSW" => "South South West", "SW" => "South West", "WSW" => "West South West", "W" => "West", "WNW" => "West North West", "NW" => "North West", "NNW" => "North North West" ); # # Options. # my $Place = ""; # Place to retrieve weather for my $OutputFile = ""; # Prefix to use for generated files # # Option switches. # $WantForecast = 0; # Set true if we want the forecast # # The forecast, if there is one. # $Forecast = ""; # # Process the command line options. If this fails, give a summary of the # program's usage. # ProcessOptions() || UsageInfo(); # # Use the default place, if we weren't given one. # $Place = $DEFAULTPLACE if ($Place eq ""); # # Get the output file prefix, if any. # $OutputFile = shift; $OutputFile = $DEFAULTFILE if (length($OutputFile) <= 0); # # Open the output file. # open(TXTFILE, ">".$OutputFile.".txt") or die("Error, could not open ".$OutputFile.".txt: ".$@."\n"); # # Get the weather from Wunderground. # my $WeatherHand = Weather::Underground->new( place => $Place, debug => 0) || die("Error, could not create new weather object: ".$@."\n"); $Weather = $WeatherHand->get_weather() || die("Error, calling get_weather() failed: $@\n"); # # Dump the weather data to a text file. # my ($Key, $Value); print(TXTFILE "Weather search for ".$Place.":\n\n"); foreach (@$Weather) { print(TXTFILE "Matched weather for ".${%{$_}}{place}.":\n"); while (($Key, $Value) = each %{$}) { print(TXTFILE "\t$Key = $Value\n"); } }
#
# If the user wants the forecast, see if we can get it.
#
if ($WantForecast)
{ my ($URLFCast, $Req, $Resp, $FCast); # # Set up the HTTP headers used to fetch the forecast. Just in case # they're watching, we pretend to be Mozilla. # my $HTTPHdrs = HTTP::Headers->new( 'Accept' => 'text/xml,application/xml,application/xhtml+xml,' . 'text/html;q=0.9,text/plain;q=0.8,*/;q=0.5', 'Accept-Charset' => 'ISO-8859-1,utf-8;q=0.7,;q=0.7', 'Accept-Language' => 'en-us,en;q=0.5', 'User-Agent' => 'Mozilla/5.0 (Windows; U; Windows NT 5.0; ' . 'en-US; rv:1.7.13) Gecko/20060414'); # # Set up a user agent to do the fetching. The agent looks like a # full-fledged browser. And, it handles just about everything the remote # site can throw at it. # my $UserAgent = LWP::UserAgent->new( requestsredirectable => ['GET', 'HEAD', 'POST']); # # Build a URL that we can use to look up the forecast. # $URLFCast = $Place; $URLFCast =~ s/^\s+//; $URLFCast =~ s/\s+$//; $URLFCast =~ s/\s,\s+/,/g; $URLFCast =~ s/\s+/+/g; $URLFCast = URI::URL->new("http://".$FORECASTURL.$URLFCast); # # See if we can get the forecast. # $Req = HTTP::Request->new("GET", $URLFCast, $HTTPHdrs); $Resp = $UserAgent->request($Req); # # If we got a forecast, process all of the day forecasts within. # if ($Resp->is_success) { $Resp->content =~ /\<txt_forecast.?\>(.+?)\<\/txt_forecast/gis; $_ = $1; # # Loop through all of the day forecasts. # while (m/\<forecastday.?\>(.+?)\<\/forecastday/gis) { $FCast = $1; # # If we have a title, compose the forecast for that period. # if ($FCast =~ /\<title.?\>(.+?)\<\/title/) { $Forecast .= ("Forecast for ".lc($1)); if ($FCast =~ /\<fcttext.?\>(.+?)\<\/fcttext/) { # # The droid has trouble with a few expressions and some # of the punctuation that Wunderground likes to use. # $FCast = $1; $FCast =~ s/\s\r?\n\s/ /gs; $FCast =~ s/\s\.\.\.\s*/, /gs; $FCast =~ s/\'/\'\'/gs; $FCast =~ s/\bmph\b/miles per hour/gis; $FCast =~ s/\bmph\.]/miles per hour./gis; $Forecast .= (". ".$FCast." "); } else { $Forecast .= " is not available. "; } } } } }
#
# Turn the wind speed and direction into English.
#
my ($Wind);
if ($Weather->[0]->{wind_milesperhour} eq "0.0") { $Wind = "the winds are calm"; } else { $Wind = "wind direction is ". ((exists($WindDir{$Weather->[0]->{wind_direction}})) ? $WindDir{$Weather->[0]->{wind_direction}} : $Weather->[0]->{wind_direction})." " . "at ".$Weather->[0]->{wind_milesperhour}." miles per hour"; } # # Figure out how to end the weather information. # my ($Sec, $Min, $Hour, $Finish); ($Sec, $Min, $Hour) = localtime(time()); if (($Hour >= 23) || (($Hour >= 0) && ($Hour < 4))) { $Finish = "good night"; } elsif ($Hour >= 18) { $Finish = "pleasant evening"; } else { $Finish = "pleasant day"; } # # Let's get Festival to turn this into a wave file that Asterisk can use. # system("echo 'Weather for ".$Place.". " . "Current temperature is ".$Weather->[0]->{temperature_fahrenheit}." " . "degrees, " . "conditions are ".$Weather->[0]->{conditions}.", " . "visibility is ".$Weather->[0]->{visibility_miles}." miles, and " . $Wind.". " . "Current humidity is ".$Weather->[0]->{humidity}." percent, " . "and the dew point is ".$Weather->[0]->{dewpoint_fahrenheit}.". " . $Forecast . "Have a ".$Finish.".' " . "| /usr/bin/text2wave -F 8000 -o ".$OutputFile.".wav"); # # We're getting outta here. # close(TXTFILE); exit 0; ############################################################################## sub ProcessOptions # # Process command line options and set the appropriate variables. # { my ($Result); # # Get options using standard option processor. # $Result = &GetOptions( "Forecast", \$WantForecast, # Switch for forecast as well "Place=s", \$Place); # The place to get weather for # # Return success if options gotten OK. # return ($Result); } ############################################################################## sub UsageInfo # # Routine to display program usage information. Called whenever the command # line parameters don't make sense. # { # # Exit after giving help. # print <<USAGE ;