The Philips Hue range of lights are certainly not cheap (there are some alternatives), but one thing that I really appreciate is the well documented API for making your own Hue apps. Today I'll be showing you how to control your Hue lights from an Arduino - then adding a simple motion sensor.

Why are we doing this? Because home automation systems can be quite rigid and expensive. By learning how to control the Hue from Arduino, you open the doors to a variety of custom made home automation projects that simply can't be beaten by off-the-shelf components. If hacking things together just isn't your thing, try these 8 fabulous Hue apps instead.

The Hue System

Let's get technical for a bit so you'll know the underlying systems you're working with. Hue lights create a mesh network, using a short range wireless protocol called ZigBee - specifically, they are ZigBee Light Link certified, which means other ZLL products should also work alongside the Hue (in theory).

Although technically short range, the mesh networking feature of ZigBee means that each new bulb extends the network, relaying messages to other bulbs. This means that if you're having trouble controlling a light on the other side of the house, try placing another light in between the two.

Zigbee is a great protocol, but it's quite different to Wi-Fi or a wired computer network, so we need the Philips Hue Bridge to join the two together. The Hue bridge runs a modified open source linux firmware, which broadcasts a basic web server.

This is what you'll see if you just type in the IP address of your Hue bridge into your browser. You can't do much from here though.
This is what you'll see if you just type in the IP address of your Hue bridge into your browser. You can't do much from here though.

It's by interacting with this local web server that you can find out the current status of the lights, and control them.

It's a beautifully simple system, and ripe for DIY projects. Kudos to Philips for making this thing so hackable.

Starting Out

Before you can access the API documentation, you'll need to register as a developer. It's free, but you need to accept the terms and conditions. Do this now.

Anyone familiar with standard web services or Javascript should be able to work with the Hue: all data is passed and received as JSON packets.

To have a look at this in action, you'll need to know the IP address of your Hue bridge. There are a few ways to do this:

  • Look at the DHCP address assignment table in your router's admin interface
  • Run a network mapping program like IP Scanner Home
  • Try the Philips UPnP broker tool
  • Ping "philips-hue.home"
network mapping to find bridge

When you're done, go ahead and type it into your browser address bar with debug/clip.html appended to the URL. In my case, this was:

        http://192.168.1.216/debug/clip.html
    

This is a debugging tool that let's you send and receive the JSON packets through a simple web interface. The first step is to enable the developer profile on the Hue Bridge itself - which is disabled by default for security reasons. Paste the following into the BODY field, leave the URL as /api/, and send a POST request by clicking the post button:

        {"devicetype":"test user","username":"newdeveloper"}
    

The first time you do this, you'll see a "link button not pressed" somewhere in the response. This is a security feature that requires every new application you use to be physically authorized. Go and find your Bridge, press the button, and send the same request again within 30 seconds. This time you'll get a different response, and the user will be authorized. If you'd like to use a different username, read the API docs about creating users. For now, this will suffice.

Once your user is setup, the base URL you should interact with becomes /api/newdeveloper/ . You can send a GET request to find out everything your Bridge currently knows about connnected lights, alarms, scenes, and a short log of apps that have been used. Here's a sample of some of the status information contained for a single bulb.

        
"state": {
"on": true,
"bri": 254,
"hue": 14910,
"sat": 144,
"effect": "none",
"xy": [
0.4596,
0.4105
],
"ct": 369,
"alert": "none",
"colormode": "ct",
"reachable": false
},
"type": "Extended color light",
"name": "Bedroom 1",
"modelid": "LCT001",

Note that the "on":true state doesn't actually show you if the bulb is on or not; only that according to the Bridge settings, it should be on. "reachable":false can indicate both a bulb that is too far away, or simply turned off at the power switch.

One last example before we integrate this into the Arduino: make sure one of your lights is visible and on, and that you know which number it is. Change the URL to /api/newdevelopers/lights/1/state (changing the number to your light), and send a PUT request with the following data:

        {"hue": 50100,"sat":255,"bri":255}
    

You should see your light react like this:

hue demo

What you've done is to push a new state to the bulb. You can also add "transitiontime", which is a primitive animation method indicating how many seconds you'd like the state change to take.

The color can be set in a number of different ways, but unfortunately there's no simple way to send an RGB value. In the example above, we sent hue, saturation, and brightness. Try changing the hue value and sending the PUT request again.

Working From Arduino

There is an existing Hue / Arduino library called ArduinoHue which Philips themselves link to in the API documentation, but the problem with this library is that it communicates over the USB connection to your PC, which also needs to be running a Python application constantly. Eugh. You may as well let your computer run the entire thing at that point, and cut out the Arduino entirely.

Instead, I'll show you how to control the Hue from the Arduino using an Ethernet shield. Your Arduino needn't be connected to a computer, so it can operate independently anywhere you can put an Ethernet cable. In fact, it should also work with a Wi-Fi shield, but I don't have one to play with.

ehternet-sheild-box

If you'd like to skip ahead, the full sample code is embedded below, or available here. I've adapted it from an example posted by Gilson Oguime. If you've never played with your Ethernet shield before, you might want to have a quick run through the web client tutorial - I'll assume some level of familiarity with this, and won't be covering the code used to establish a network IP etc. We've also shown you how to create a mini web-server with the Ethernet shield.

Creating State Changes

Creating a new state to push to the bulbs is a simple case of creating a new String variable, and escaping all the double quotes. I've added a random() function in there as well to create a somewhat dynamic animation. Try making the hue variable random too for different colors.

        String command = "{\"on":true,\"hue\":50100,\"sat\":255,\"bri\":255,\"transitiontime\":"+String(random(15,25))+"}";
    

Sending the Command

To actually send the command, you have a helper function called setHue() which takes the light number and the command string as an argument, like so:

        setHue(1,command);
    

All it does then is it connects to the bridge, spits out the command as a PUT request, along with all the other nonsense that creating an HTTP request involves.

        
client.print("PUT /api/");
client.print(hueUsername);
client.print("/lights/");
client.print(lightNum);
client.println("/state HTTP/1.1");
client.println("keep-alive");
client.print("Host: ");
client.println(hueHubIP);
client.print("Content-Length: ");
client.println(command.length());
client.println("Content-Type: text/plain;charset=UTF-8");
client.println(); // blank line before body
client.println(command); // Hue command

Adding a Motion Sensor

Finally, I wired a simple HC-SR501 motion sensor to digital I/O pin 2. When motion is detected, a series of states are pushed to the bridge for 2 bulbs to create a slow, dynamic animation. When the motion sensor deactivates, a single off command is sent to both. Ideally, they would be reverted to the state they were in before motion was detected, but the logic isn't that smart - we're just going to turn them on and off.

Limitations

Although admittedly unoptimized code, it takes almost a second for the network interface of the Arduino to send a single command request. I tested the same command from a Mac, using the same Ethernet connection, and it was capable of ten to twenty times that speed (here's the AppleScript in case you'd like to test). Consequently, any kind of fast animation (I was attempting to create a flickering candle effect) just isn't possible from an Arduino. This shouldn't be a problem for most projects, just for high speed light animations, but it's good to be aware of the limitation.

It's also difficult to fully parse any JSON response you get back from the bridge; there just isn't enough RAM on the Arduino to store all the raw data. For this reason, you might want to mostly limit yourself to sending.

Hack the Hue

Now that you're armed with the knowledge of how to control Hue completely independently, it opens up a world of Hue home automation hacks. The real question is: what will you make?