Voice Spoken Weather Report

Here is a Powershell script that is fun, and useful if you like to be able to get a spoken weather report quickly.  It uses the SAPI com object in Windows to convert text to voice. If you have more than one TTS engine on your PC, you will be able to modify it under the Windows Control Panel.

To start with you will need to create a function that will be used to convert text to voice.

function say

{

$Voice = new-object -com SAPI.SpVoice #Make a voice object using the com object.

$Voice.Speak( $Args[0], 0 )|out-null

}

The second part of this script comes from /\/\o\/\/. You’ll find a detailed post on how to connect to a web-service to capture weather information.  That is located here:

http://thepowershellguy.com/blogs/posh/archive/2009/05/15/powershell-v2-get-weather-function-using-a-web-service.aspx

What I’ve done is to put his work into a function that allows you to select a country or city based on command line parameters, and then speak the results over your computer speakers. If you select the -help parameter and use the -country countryname parameter, all of the cities for your country will be selected.

Here is that function:

Function Get-Weather ([switch]$help,$city,$country,$filter = ”)

{

$weather = New-WebServiceProxy -uri http://www.webservicex.com/globalweather.asmx?WSDL

if ($help)

{

write-host “Starting help.”

$xml = [xml]$weather.GetCitiesByCountry($Country)

$xml.NewDataSet.table | sort city | Out-GridView

}
else

{

([xml]$weather.GetWeather($City,$country)).CurrentWeather

}

}

Now that the functions are out of the way, here is the “main” portion of the script.

#Main
#Determine if help switch is active.

switch ($help)

{

{$_ -eq $true }

{

get-weather -help -country $country

break

}

default

{

if ($full)#This is the full text output. No audio.

{

Get-Weather  -country $country -city $city

}

else #Audio output, streamlined for quicker information.

{

$currentWeather = get-weather -city $city

Write-Host $currentWeather

$currentTemperature = $currentWeather.temperature

$currentTemperature = $currentTemperature.split()

$currentSkyConditions = $currentWeather.SkyConditions

$wrsentence = “Here is the weather information you needed. In ” +  $city + ” the temperature is ” + [int]$currentTemperature[1] + ” degrees fahrenheit, and it is ” + $currentSkyConditions

say $wrsentence

}

}

}

I’ve used the default city of Memphis that I set up in the parameters, but it works just as well if I used the command line parameters.

I’ve saved all of this in a script called get-weather.ps1

Here is a sample using  Quebec, Canada

.\get-weather  -country Canada -city Quebec

If  I am not sure of all of the city names that are available for Mexico, then I can type:

.\get-weather  -country Mexico -help

This will open up an out-grid view with all of the cities available in Mexico.

Since I set Memphis as the default city in the parameters, just typing the following will give me local weather information.

.\get-weather.ps1

If I want just screen output for a city, I can use something like the following:

.\get-weather -full -country canada -city Quebec

Give this a try and see if it works. Let me know if you have any questions.

Thanks,

Patrick

Text To Voice Conversion

Here is a little script that is fun to use, and could be useful in some applications.

I put this in my profile, so that I am greeted with the data whenever I start a Powershell session.

$today = [DateTime]::Now # Get Current time and date.
$Voice = new-object -com SAPI.SpVoice #Make a voice object using the com object.
$Voice.Speak( “Good Day Patrick!”, 1 )#1 causes function to continue w/o wating.
$day = $today.DayOfWeek #Determine the day.
$dayNumber = $today.Day #Determine the day number
$Voice.Speak( “Today is $day the $dayNumber”, 1 )

The only down side to this is the fact that there is no suffix on the $dayNumber value. A good way to work around that would be to create a switch statement.

Here is an example of how that could be implemented.

switch ($dayNumber)
{
19 {$properDay = “nineteenth” }
20 {$properDay = “twentieth” }
}

To implement this for the entire month, you would add the entire range of possible day numbers from 1 to 31.
Here is how the whole script would look.

$today = [DateTime]::Now # Get Current time and date.
$Voice = new-object -com SAPI.SpVoice #Make a voice object using the com object.
$Voice.Speak( “Good Day Patrick!”, 1 ) #The 1 parameter after the text causes the function to continue without wating.
$day = $today.DayOfWeek #Determine the day.$dayNumber = $today.Day #Determine the day number

switch ($dayNumber)

{
1 {$properDay = “first” }
2 {$properDay = “second” }
3 {$properDay = “third” }
4 {$properDay = “fourth” }
5 {$properDay = “fifth” }
6 {$properDay = “sixth” }
7 {$properDay = “seventh” }
8 {$properDay = “eigth” }
9 {$properDay = “ninth” }
10 {$properDay = “tenth” }
11 {$properDay = “eleventh” }
12 {$properDay = “tweflth” }
13 {$properDay = “thirteenth” }
14 {$properDay = “four-teenth” }
15 {$properDay = “fifteenth” }
16 {$properDay = “sixteenth” }
17 {$properDay = “seventeenth” }
18 {$properDay = “eighteenth” }
19 {$properDay = “nineteenth” }
20 {$properDay = “twentieth” }
21 {$properDay = “twenty-first” }
22 {$properDay = “twenty-second” }
23 {$properDay = “twenty-third” }
24 {$properDay = “twenty-fourth” }
25 {$properDay = “twenty-fifth” }
26 {$properDay = “twenty-sixth” }
27 {$properDay = “twenty-seventh” }
28 {$properDay = “twenty-eight” }
29 {$properDay = “twenty-ninth” }
30 {$properDay = “thirtieth” }
31 {$properDay = “thirty-first” }

}
$Voice.Speak( “Today is $day the $properDay”, 1 )

The voice utilized by this com object reminds me of the voice from the movie
“War Games”. The classic line is “Would you like to play a game?”