Weather Report

If you’ve been following along in our blogs, you’ve hopefully read my posts about using the SAPI.SPVoice COM object. I’ve been trying to come up with some practical applications. I’ve developed one that gets a weather report for your zip code and delivers the weather to you. The script uses a .NET weblclient object to retrieve an XML page from Yahoo! weather.

The script’s primary function is called Get-Weather and takes as a parameter a zip code and temperature scale indicator (“f” for Farenhiet or “c” for Celsius). The script as written will prompt you for a zip code and defaults to Farenheit.

# WeatherReport.ps1
# This script will get the current weather conditions and forecast for the specified zip code
# from Yahoo weather, and using the SAPI.SPvoice object, speak the information for you.

Function Get-Weather($zip=$(Throw(“You need to specify a zip code!”)),$Unit=$(Throw(“Specify F or C for the temperature scale!”)))
{
    [string]$urlbase=”http://xml.weather.yahoo.com/forecastrss”
   
    #validate temperature scale
    if ($Unit -eq “c”) {
        [string]$scale=”Celsius”
        $Unit=”c”}
        else {
        [string]$scale=”Farenheit”
        $Unit=”f”}
   
    [string]$url=$urlbase + “?p=”+$zip+”&u=”+$Unit
   
    #create the text to speech object
    $voice=New-Object -com “SAPI.SPVoice”
    Write-Host Connecting to $url
   
    #Create .NET Webclient object
    $webclient=New-Object “System.Net.WebClient”
    [xml]$data=$webclient.DownloadString($url)
   
    if ($data.rss.channel.item.Title -eq “City not found”) {
        Write-Host “Could not find a location for” $zip}
    else {
        Write-Host $data.rss.channel.item.Title
        #Speak the current conditions
        [void]$voice.speak(“You asked about the weather.”)
        [void]$voice.Speak($data.rss.channel.item.Title)
        [void]$voice.speak(“The current condition is”)
        [void]$voice.speak($data.rss.channel.item.condition.text+”!”)
        [void]$voice.speak(“The current temperature is” +$data.rss.channel.item.condition.temp+” degrees “+$scale)
        #get forecast
        for ($i=0; $i -le ($data.rss.channel.item.forecast.length)-1;$i++) {
        [void]$voice.speak(“The forecast for “+`
        $data.rss.channel.item.forecast[$i].date+`
        “is, “+$data.rss.channel.item.forecast[$i].text+”with a low of”+`
        $data.rss.channel.item.forecast[$i].low+” degrees “+$scale+`
        “, and a high of”+$data.rss.channel.item.forecast[$i].low+” degrees “+$scale)
        }
    }
}

$zip=Read-Host “Enter a zip code for your weather query”
Get-Weather $zip “f”

I’m using a System.Net.WebClient object ($webclient) to download the url.  I’m intentionally casting the return object as XML so that it is easier to work with. As an XML document I can easily return any element in the hierarchy. The script then uses the SPVoice object to “speak” the different elements of the returned XML data.

This is not perfect.  For example, the text to speech engine tries to speak abbreviations. So when it sees a time stamp that ends in EST, it thinks this is “established” and not Eastern Standard Time as in my case.  You might also get some weird pronunciations of your town or city. I’ve added some punctuation such as commas to add some brief pauses so that it is easier to listen to text to speech.

PowerShell obviously can’t make the weather, but as you can see, it can tell you what you are missing while you are stuck in a windowless cubicle or in the bowels of your datacenter.