Giving Better Weather to Alexa

Nearly every day, someone in our family asks Alexa for the day's weather. The default response is fine -- high temp, low temp, sun or rain.

But given our three nor'easters, intense wind chills, and high-wind days, that wasn't enough. How much rain? When will it start? How much snow? How cold will it feel?

We needed something better.

Fortunately the US National Weather Service does a fantastic job writing up little descriptions of what's in store for every spot in the country. It's been my go-to source for years. Could I get Alexa to say that?

Short answer: Yes, I could. And now you can add "Better Weather" to your Alexa, too. For free. (In the US only, for now.)

For a longer description of how I made it, read on. 

Getting the Weather Words

Initially, I explored using the National Weather Service API to get the info I wanted. But I was surprised to find it incredibly unreliable. It was unpredictability unreachable and sometimes didn't update for days.

The words I wanted are on National Weather Service pages as the "Detailed Forecast," so I decided to read it right from there. 

To get the page with the right forecast, I need to put the user's latitude and longitude in the URL, like this:

https://forecast.weather.gov/MapClick.php?lat=40.74913000000009&lon=-73.99236000000002

Where's Are You?

When someone installs the Alexa skill, I've requested that Amazon ask for permission to know that user's zip code (the US postal code).

With that, I can look up the latitude and longitude for the "centroid" of that zip code using this table Eric Hurst put together from US Census Bureau data.

Leaning an Lambda

Calculations for Alexa skulls are typically done in a "lambda function," which is your custom code stored on Amazon's servers. Whenever needed, a lambda function wakes up, does its thing, and goes back to sleep. (I really should make a lambda function startup guide; short of that, here are some basic instructions.)

So when someone says "Alexa, open Better Weather," here's what happens:

  • The Alexa system pokes the lambda function awake and hands it the user's zip code. 
  • The lambda function converts the zip code to latitude and longitude with Hurst's table, which I turned into JSON
  • The lambda function builds the url for the forecast page, and then hits that web page. 
  • It then grabs the titles and text blocks fro the first two items in the "Detailed Forecast" part of the page. 
  • It strings that text together and sends it back to the Alexa system.
  • The user's Alexa device speaks the forecast!

One Moment, Please

It turns out that all those steps take a little bit longer than feels comfortable. The forecast arrives just about the time you start thinking, "is this thing working?"

That's no good. 

My fix is to send a message that says "Okay, let me get that for you ..." the moment the lambda function wakes up. That helps a lot.

This "just a moment" message is a bit more interesting than it may seem. Usually you can't send anything back to the Alexa system until the lambda function completes its task. But here, it's the task-completing that we want to acknowledge. To solve this, Amazon allows coders to send a short "progressive message" even before the lambda function is done.

Going Further

Here's my code for the Better Weather Alexa skill. If you want to actually make something like this, check out my process notes file. That's my real-time log about how I worked through this, and includes more detail about building the skill.

If this post helps you, I'd love to hear about it. Just drop a note in the comments.