Bringing Light Bulbs To Life With Twilio SMS

October 08, 2013
Written by
Michael Wawra
Contributor
Opinions expressed by Twilio contributors are their own

michael-wawra-lo-res

On my way back to London, I recently bought myself a Philips Hue. These are wirelessly controlled light bulbs that allow you to control both brightness and colour. They come with a base station and an app, are very easy to use and most importantly the Philips Hue has an API.

At Twilio, we love APIs!

Ooooohhhhhh!!! SMS to change the colour of my light in the flat!!

— Michael Wawra (@xmjw) August 13, 2013

 

My thinking is simple. Having control of my own lights is okay, but letting random strangers on the internet change the colour of my lights would be fun! Letting them change the colour with an SMS message would be epic!

So how does the Philips Hue work? Basically, it is a base station with an ethernet connection and 3 bulbs. The base station is connected to your router and can control the bulbs through some other protocol that we don’t need to worry about. All we need to do is send requests to the base station and it will do everything else for us.

Before we can write any code however, we need to setup the API on our Philips Hue. This step creates a username to validate that we have physical access to the device. With that out the way let’s write a little Ruby and Sinatra and see what we can do. Create a new file called ‘sms-hue.rb’ and add the following:

require "net/http"
require "json"
require "sinatra"

Next, we need to create some settings to use in the rest of the application. We need the username you created when you, the IP address of the base station and the ID of the bulb we’ll be using. You could make this work with all your light bulbs at the same time, but I like to give the internet access to my home one room at a time.

configure do
  set :hue_user, ENV['HUE_USERNAME']
  set :hue_ip, ENV['HUE_IP']
  set :hue_bulb, ENV['HUE_BULB']
end

Because the Philips Hue has a REST API we need to make HTTP requests to change the state of our bulbs. All we really need in this example is code that makes an HTTP PUT request with some JSON data. Lets create a method called ‘send_to_single_bulb’ that can do this for us:

def send_to_single_bulb id, json_data
  path = "/api/#{settings.hue_user}/lights/#{id}/state"

  http = Net::HTTP.new(settings.hue_ip)
  response = http.request_put(path, json_data)
end

Now that we have everything setup to send data to the Philips Hue, we need look at the JSON data we have to send. Looking at the Philips Hue API documentation, we need to send a ‘hue’, ‘sat’, and ‘bri’ value to the API. These are for Hue, Saturation, and Brightness. In order to set a specific colour, we need to learn how these values work.

The hue value describes the colour. The Philips Hue can manage an impressing 65,000+ colours, so it uses the range 0 – 65535. To make life simple, we will use 0 – 360 for our hue values, and multiply this by about 182, which gives the full range, without the full fidelity. (65535/360 is a little over 182.)

colorwheel

This makes it easy to visualise the colours. Shown in the colour wheel 0° (and 360°) are Red at the top, 90° is yellowy-green, 270° is blue-purple and so on. You can try out how these values work a little with this colour picker that displays HSL values, as well as the more familiar HTML and RGB codes.

Saturation is basically how colourful our colour is compared to how white it is. (There is a more indepth explanation of this on Wikipedia) Brightness is how ‘on’ the lightbulb is: 0 is not very on, and a high number is very, very on. Philips Hue uses 0 – 255 for saturation and brightness. We are going to use 255 for saturation to make sure the colours are strong, but only 70 for brightness as looking at bright lights directly isn’t a very good idea…

Now we need some code that can receive the SMS and pass the colour value as JSON to the Philips Hue. The following code creates a Sinatra route ‘/sms’ that will do this:

post '/sms' do
  hue_val = params[:Body].to_i * 182
  json_data = {hue: hue_val, sat: 255, bri: 170}.to_json

  send_to_single_bulb(settings.hue_bulb, json_data )
  content_type 'text/xml'
  ""
end

The Ruby String class has a to_i method that will return an integer if it finds an numeric value at the beginning of the string. If it cannot find a value, it simply returns 0. This makes it very safe to use, as it will not cause an exception.

Twilio provides the SMS message text using the Body parameter. So we use to_i to convert it into an integer, multiply it by 182, and store it in a variable called ‘hue_val’. Now we must create some JSON data. In Ruby we can create a Hash and use the to_json method that is included from the JSON library above.

For the final step of our code, we pass that JSON data to our ‘send_to_single_bulb’ method, and return some TwiML telling Twilio that no further action is required.

Now things get interesting. We need to run this code on the same network as our Philips Hue base station. If you do not have an internet routable home/office network, then you might want to use a service like localtunnel or NGrok. These tools help tunnel your local webserver to the Internet – you may want to look into a task manager or port forwarding on your home router as a permanent solution.

We need to do this because we must provide Twilio with a routable URL so it can contact the code above. Once you have that working, you should have a routable URL that connects to your Sinatra application. Log into Twilio, and under the Numbers tab, select (or buy) a number you want to use with your lights. Set the Messaging Request URL to your applications URL:

addURL

Now for the fun part. Tweet the number, or post it Facebook, and see how many people send an SMS to your service to change the colour of your light bulb! It think 256 is a particularly pleasing shade of blue.
Tweet or email your light changing numbers to @xmjw, @twilio or wawra@twilio.com.