Building an information radiator, Part 2

Andrew Fisher

December 31st, 2014

Code: https://gist.github.com/ajfisher/844975b824ec96c27c7c

Python

// An information radiator light showing the forecast temperature in Melbourne.

I love lights; specifically I love LEDs - which have been described to me as "catnip for geeks". LEDs are low powered but bright which means they can be embedded into all sorts of interesting places and, when coupled with a network, can be used for all sorts of ambient display purposes.

In the first part in this series I explained how to use an Arduino and an RGB light disc attached to the network in order to create a networked light. In this part I’ll show you how to scrape some data from a weather web site and use that to make your light change colors periodically to show the day or night time forecast temperature.

Scraping the data

Weather data is easy to get hold of using APIs, however I'm going to do this the old fashioned way as many interesting data sources may not have an API available for you to hit. This technique is going to use good old fashioned html scraping.

To scrape the data I'll use a simple python script. If you’ve never used python before then go start here to get installed and get some familiarity with the language.

I’ll use the standard library’s urllib2 module to request a page from Accuweather’s site The URL in this case being the for the weather in Melbourne, Australia (where I live). You'll want to change this to your own home town.

Once the request comes back, you get the html content of the page. It's possible to parse through all of this using regular expressions, however a python module called beautifulsoup can interpret the response as a document of nodes rather than just text. Install beautifulsoup using:

pip install beautifulsoup 

To get to the appropriate data you need to walk the document structure using selectors. If you read through the html you can see that the temperature data is available in two LIs (li#feed-sml-1 and li#feed-sml-2), both of which use IDs so that makes the job very easy to pull the information out. The resulting text can be cleaned up with some string manipulation.

The code below shows how to do this in beautifulsoup in order to get the forecasted max and overnight min temperatures.

// code snippet
# load this up into beautiful soup                                              
soup = BeautifulSoup(response.read())                                           

# these IDs were discovered by reading the html and gettng to the               
# point where the next forecast occurs                                                                              
temp = soup.find('li', {'id':'feed-sml-1'})                                                               

# grab the temps and remove the cruft                                           
temp_val = int(today.find('strong', {'class':'temp'}).text.replace("°", ""))

print("Forecast: %d" % temp_val)

The other main part of the code looks at the temperature and makes some decisions about what colours mean what. In this case I'm using the following ranges:

  • <10C is bright blue - it's really chilly
  • 10-20C is green - cool to mild
  • 20-30C is yellow - lovely weather
  • 30-40C is orange - hot
  • >40C is red - really really hot!

These ranges are based on the climate I have here in Melbourne where it never gets below 0C but in summer regularly goes over 40, you can adjust these to what makes sense for where you live.

This final snippet of code uses the telnet library to connect to the Arduino and send the payload. 

tn = Telnet()                                                                   
tn.open(arduino_ip)                                                             
tn.write(str(colour))                                                           
tn.write("\n")

The full code listing is below:

 #!/usr/bin/python
 
# This script will periodically go and check the weather for a given
# location and return the max and min forecasted temperature for the next
# 24 hours.
# Once this is retrieved it sends a message to a networked arduino in the form
# of an RGB colour map in order to control a light showing expected temps.
#
# Author:   Andrew Fisher <ajfisher>
# Version:  0.1
from datetime import datetime
from telnetlib import Telnet
import urllib2
from BeautifulSoup import BeautifulSoup

# This is specific to melbourne, change it to your location

weather_url = "http://www.accuweather.com/en/au/melbourne/26216/weather-forecast/26216"

# details of your arduino on you network. Change to yours

arduino_ip = "10.0.1.91" 
response = urllib2.urlopen(weather_url) 

# load this up into beautiful soup

soup = BeautifulSoup(response.read()) 

# these IDs were discovered by reading the html and gettng to the

# point where the forecast exists. Use the "next" item

forecast = soup.find('li', {'id':'feed-sml-1'}) 

# grab the temps and remove the cruft

temp_val = int(forecast.find('strong', {'class':'temp'}).text.replace("&deg;", ""))
 print("Forecast temp is %d" % temp_val)
 
# convert to colour range
if temp_val <= 10:
    red = 0
    blue = 255
    green = 20
elif temp_val > 10 and temp_val <=20:
    red = 128
    blue = 0
    green = 255
elif temp_val >20 and temp_val <= 30:
    red = 128
    blue = 0
    green = 128
elif temp_val > 30 and temp_val <= 40:
    red = 255
    blue = 0
    green = 128
else:
    red = 255
    blue = 0
    green = 0
 
colour = { "r": red, "b": blue,"g": green }
 
# Send message to arduino
tn = Telnet()
tn.open(arduino_ip)
tn.write(str(colour))
tn.write("\n")

You can test this now by running python weather.py

If everything is working you will see the arduino light up with the appropriate colour based on your forecast.

To automate this, make a scheduled task on windows or a cron job on linux / mac to run each hour to run this script and it will update the light display.

Mount your light somewhere you can see it and you’ll be able to determine whether it’s shorts weather or you’ll need an extra blanket on the bed tonight.

Python

// A lovely day in Melbourne forecast. Perfect t-shirt weather.

## Going further

Now you know how to make an information radiator from a networked device you can make your own. Here are some ideas to take it further

  • Upgrade the protocol to include a duration so the light will turn off or dim after a period of time (good for frequent messages).
  • Use python to talk to an API instead of scraping - eg twitter's public stream looking for keywords.
  • Include multiple lights in a display in order to show probability of rain as well as forecasted temperature
  • Mill, mould or 3d print a light fitting to go around your device and make it a piece of ambient art.

About the author

Andrew Fisher is a creator (and destroyer) of things that combine mobile web, ubicomp, and lots of data. He is a programmer, interaction researcher, and CTO at JBA, a data consultancy in Melbourne, Australia. He can be found on Twitter at @ajfisher.