Get the daily forecast in your console, with PowerShell

Today I saw a post on reddit about scraping a webpage for weather information. Reading over the comments, I had an idea, and I quickly looked away wanting to try this myself before seeing what someone else posted.

http://www.reddit.com/r/PowerShell/comments/2jitvn/help_with_screen_scraping_or_interpreting_web/

If you don’t care about how this is done, skip to the bottom for the code, here is a preview of the finished product:

weather_00

Reading the OP’s question, he basically wanted to get a weather alert if it was going to rain. I thought this a nice goal, but expanded further to wanting to get certain weather information like the temp, forecast and wind speed, right in the console when I started it up.

Knowing that PowerShell has exceptional WebService and Remote API capabilities, I started my search trying to locate a web service out there somewhere with a nice REST or JSON API available to get my weather info from.  I read about ForeCast.IO, an open API made for weather applications, with a very reasonable price (free for up to 1,000 queries a day!) and quickly signed up.

A note on APIs

One thing to keep in mind when setting up a tool like this is that you’ll need to generally register for an account to use most APIs. Many places will provide these services free for the first 1,000 or 10,000 queries, but then charge you a pittance beyond that. Keep this in mind when sharing code about things like this. If someone has your API Key, they are effectively you. If they leave your script running on a loop constantly hammering an API somewhere, you can be on the hook for $100’s.

Don’t give people your API key unless you’d feel safe giving them your physical or digital wallet.

weather_01
Make note of your API Key on this page.

If you’re OK with all of this,

Go to ForeCast.IO and sign up for an account then make note of the API key

Great, copy down your API and then hide it!

If we take a look at the documentation, we’ll see that to make a call, we simply need to run a web request, subbing in certain values, and in response we’ll get something back…

https://api.forecast.io/forecast/APIKEY/LATITUDE,LONGITUDE

As stated above, we need to replace our API Key for the word APIKEY anywhere found in docs. We’ll also need to substitute in the latitude and longitude. If you look at the example on the site, they give the following to get the weather in Alcatraz. I’m hiding my API Key in $API_key

https://api.forecast.io/forecast/$API_key/37.8267,-122.423

If you run Invoke-WebRequest, then convert From JSON, you’ll have a nice PowerShell object.

weather_02
Um, the weather looks to be very bad in Alkatraz. Let’s cancel our vacation!

Now, if you want to look up your own city, you can get your latitude and longitude here.

This all all well and good, except the time comes back in Unix time format, which measures ticks on the clock since January 1st, 1970, so you can convert that with the following PowerShell code.  I got this approach from this answer from Keith Hill on StackOverflow.

[TimeZone]::CurrentTimeZone.ToLocalTime(([datetime]'1/1/1970').AddSeconds($weather.currently.time))

So, after pulling out a little bit of data, I have the following code. This will get the current temp, weekly summary, and also play an alert sound if any weather alerts are encountered! Hope you enjoy it!

A preview picture of the finished product:

weather_03

function Get-Weather{
param($city = "33.9533,-84.5406")
$API_key = "****PUT YOUR APIKEY HERE******"
$url = "https://api.forecast.io/forecast/$APIkey/$city"

If 

$weather = Invoke-WebRequest $url | ConvertFrom-Json

$ForeCastTime = [TimeZone]::CurrentTimeZone.ToLocalTime(([datetime]'1/1/1970').AddSeconds($weather.currently.time))

("The weather is generally " + $weather.currently.summary + " and currently " + $weather.currently.temperature + " degrees Fahrenheit at " + $ForeCastTime.DateTime)
("wind is gusting up to " + $weather.currently.windspeed + " m/PH with a chance of precipitation at " +  $weather.currently.precipProbability)
#it is currently 54.9 degrees Fahrenheit at Monday, October 20, 2014 10:23:11 AM

("The weekly forecast is " + (($weather.daily.summary) -creplace '\?',"").ToLower())

("The following Weather alerts were found for the requested area")
$weather.Alerts | % {write-host `a;
        Write-host -ForegroundColor YELLOW $_.Title
        Write-host -ForegroundColor Red $_.Description}

#return a Global weather object for us to play with
$Global:weather = $weather
}

Advertisements

7 thoughts on “Get the daily forecast in your console, with PowerShell

    • FoxDeploy October 22, 2014 / 12:00 pm

      Hey! That’s the thread!

      This out to sms would make an awesome function

      • william Griffin October 22, 2014 / 1:46 pm

        I love running into people on this small internet. lol How about pulling the location from google’s location tracking?

        • FoxDeploy October 22, 2014 / 2:12 pm

          The only thing is getting around the prompt for ‘this would like to get your location’. There probably is a dotnet class for getting location though… Lemme dig in and find out!

        • FoxDeploy October 23, 2014 / 2:22 pm

          Hey man, check out my newest post, where I go into how to get the current location coordinate!

    • FoxDeploy October 24, 2014 / 11:43 am

      Yeah, that’s left over from testing and good chance!

Have a code issue? Share your code by going to Gist.github.com and pasting your code there, then post the link here!

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s