Make Every Week: Entryway Weatherbot

As the kids hustle to get out the door, the question always pops up: What’s the weather going to be?

So this week’s #MakeEveryWeek project is an internet-driven forecast bot for our entryway.

It combines kid drawings, cool LEDs, a wifi-connected chip and an online weather service to display the forecast.

The Parts

Assembling the hardware was pretty easy, though it involves pieces you might not have lying around the house:

After soldering the “headers,” or pins, to the Neopixel matrix (don’t let soldering scare you — it’s not hard!), it was just a matter of plugging the Neopixel matrix, Spark Core and power cord into the Shield Shield. Except for one glitch, I describe here, it worked great.

Connecting DIY projects to wifi used to be a pain, but the Spark.io folks pretty much solved that with a smartphone app. Just have to make sure the phone is on the same wifi network.

Digital doodles

My plan was to get data from the nifty Forecast.io API, which provides the forecast for a given location and time. The forecast includes an “icon” field, with names for the forecast I wanted to represent: clear-day, cloudy, partly-cloudy-day, rain, snow, sleet and wind. I’ll use only daytime forecasts, so I didn’t need nighttime icons like clear-night.

I asked my daughter Natalie, age 9, if she would use her colored pencils to make pictures of those conditions on grids I printed that match the 5-by-8 LED matrix.

I translated those drawings into code, which looks like this:

void drawSun() {
    matrix.drawLine( 0,1, 4,5, YELLOW);
    matrix.drawLine( 0,5, 4,1, YELLOW);
    matrix.drawLine( 0,3, 4,3, YELLOW);
    matrix.drawLine( 2,0, 2,6, YELLOW);
}

These drawing commands are documented here as part of an Arduino library I’ll use later.

I used the same commands to build a set of digits, from 0 to 9, to display the high temperature. The drawing library actually comes with a character set, but the letters are too tall when the matrix is used horizontally.

Coding the Core

Coding for a Core is just like coding for an Arduino. But unlike an Arduino, you write the code into a web page and send it to the Core over the internet. More on that here.

This the program I wrote for the Core. I’ve tried to add lots of comments to explain what’s going on along the way.

My program relies on three extra libraries I had to add to my Spark Core application:

  • NEOPIXEL
  • NEOMATRIX
  • ADAFRUIT_GFS

If you’re trying my code yourself, you need to add these to your project, too. Here’s how I did it:

  1. First go to https://www.spark.io/build and create a new application, maybe called “weatherbot.”
  2. Click the “libraries” icon, which looks like a ribbon.
  3. Search for the first library listed above, NEOPIXEL.
  4. Click on its name.
  5. Click “Include in App.”
  6. Click on the app’s name (ie. “weatherbot”).
  7. Click “Add to this app.”
  8. Repeat for NEOMATRIX and ADAFRUIT_GFS.

Then you can delete all of the code in the “weatherbot” window, and paste mine there instead. Send, or “flash,” it to your Core with the lightning icon.

The “ready” state for the weatherbot program is a flashing pink zero.

Nabbing the forecast

Time to get the forecast to the Spark Core. I do this by checking the high temperature and forecast icon at forecast.io, and then sending it to the Core as a single string — the first three characters of which are the temperature, and the rest are the name of the icon.

Here’s the forecast-fetching code I wrote to do this.

It’s written in JavaScript for node.js, and relies on a couple of node modules I added by running this from the project directory:

npm install request moment

Both the forecast and Spark services require keys. I got my free API key from Forecast.io. I got Spark Core’s ID number on the spark.io/build page by clicking the thing that looks light a gun sight and then the carrot next to the core’s name. I got the Spark access token by clicking the gear icon.

I store these elsewhere on my server, to make my code easier to post openly. You can paste yours into the code where they are indicated by “keys.FORECASTIOKEY” and the like. Just be sure to delete the require = keys ... line near the top, too.

To test it out, I run:

node weather-matrix

If all works well, I get a response from the Core, like this:

{
    "id": "xxxxxxxx",
    "name": "jkeefe-weatherbot",
    "last_app": null,
    "connected": true,
    "return_value": 1
}

Please do this hourly, bot!

I want to check the forecast hourly, even if my laptop is off, so — as with the Lunch Bot — I put the fetching code on an Amazon EC2 instance.

(You, too, can spin up a computer in the cloud! Here’s how I teach journalism students to do just that.)

Again, I’ll rely on the built-in program called “cron” that lets you schedule things to run at specific times by editing a document called “crontab.” To run this every hour, on the :00’s, the crontab line looks like this:

0 * * * * /home/ubuntu/bothouse/weatherbot-matrix/cron.sh

Translation: On the 0th minute, of every hour, of every day, of every month, on every weekday, look in the /home/ubuntu/bothouse/weather-matrix directory and run my cron.sh file — which runs the bot.

Once again I had to solve some hiccups by, granting permissions to cron.sh and cron.log. Details on that are here.

Improvements

This thing is BRIGHT! So the absolute next thing necessary is a “display” push-button, programmed to turn on the display if the button is pushed. This was always part of the plan, but I ran out of time.