The range of Philips Hue lights is definitely not cheap (there are a few alternatives, worth it, worth it.) but one thing I really appreciate is the well-documented API about building your own Hue apps. Today I’ll show you how to control the Arduino Hue lights and then add a simple motion sensor.

Why are we doing this? Because home automation systems can be quite rigid and expensive. By learning how to control Hue from an Arduino, you open the door to many custom home automation projects that just can’t be beaten by off-the-shelf components. If collaborative hacking isn’t your thing, try these 8 great Hue apps instead of this.

Shade system

Let’s understand the technique a bit so that you know the main systems you work with. Illumination creates a mesh network using a short-range wireless communication protocol called ZigBee — in particular, they are ZigBee Light Link certified, which means that other ZLL products should also work together with Hue (in theory).

Although technically limited, ZigBee’s mesh networking feature means that each new bulb expands the network by relaying messages to other bulbs. This means that if you are having trouble controlling a light source on the other side of the house, try installing another light source in between.

Zigbee is a great protocol, but it’s very different from Wi-Fi or a wired computer network, so we need a Philips Hue Bridge to bring them together. The Hue bridge runs a modified open source Linux firmware that translates the underlying web server.

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

It is by interacting with this local web server that you can find out the current state of the indicators and manage them.

This is a beautiful simple system ripe for DIY projects. Kudos to Philips for making this thing so hacky.

Beginning

Before you can access the API documentation, you need to register as a developer. It’s free, but you must accept the terms. Do it now.

Anyone familiar with standard web services or Javascript should be familiar with Hue: all data is sent and received as JSON packets.

To see this in action, you need to know the IP address of your Hue bridge. There are several ways to do this:

  • Look at the DHCP address assignment table in your router’s admin interface
  • Launch a network mapping program such as IP Scanner Home
  • Try the Philips UPnP broker tool
  • Ping «philips-hue.home»

network mapping to find the bridge

When you’re done, type it into your browser’s address bar, adding to URL file debug/clip.html . In my case it was:

http://192.168.1.216/debug/clip.html 

It is a debugging tool that allows you to send and receive JSON packets through a simple web interface. The first step is to enable the developer profile on Hue Bridge itself, which is disabled by default for security reasons. Paste the following in the BODY field, leave the url as /api/ and send a POST request by clicking button « Send»:

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

The first time you do this, you will see «reply link not clicked» somewhere in the response. This is a security feature that requires every new app you use to be physically authorized. Go and find your bridge, press the button and send the same request again to within 30 seconds . This time you will get a different response and the user will be logged in. If you want to use a different username, read the API docs on creating users. For now, this will be enough.

Once your user is set up, the base URL you need to interact with becomes /api/newdeveloper/ . You can send a GET request to find out everything your bridge knows about connected lights, alarms, scenes, and a short log of applications that have been used. Here is a sample of the status information that is contained in a single light 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 «on»: True the state doesn’t really show if the light bulb is on or not; only that, according to the bridge settings, it must be included. «Achievable»: the value is «false» may indicate that the lamp is too far away or simply turned off with 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 what 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 details:

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

You should see your light react like this:

demo version

What you have done is push a new state into the flask. You can also add a «transition time», which is a primitive animation method that shows how many seconds you want the state change to take.

The color can be set in several different ways, but unfortunately there is no easy way to send an RGB value. In the example above, we sent shade , saturation and brightness. Try changing the tint value and send the PUT request again.

Working from Arduino

There is an existing Hue/Arduino library called ArduinoHue that Philips themselves refer to in the API documentation, but the problem with this library is that it communicates via a USB connection to your PC, which must also be running a Python application all the time. Ehh You can also let your computer run the whole process at this point and disable the Arduino completely.

Instead, I will show you how to control Hue from Arduino, using an ethernet shield . Your Arduino doesn’t need to be connected to a computer, so it can work independently wherever you can plug in an Ethernet cable. In fact, it should also work with a Wi-Fi shield, but I have nothing to play with.

Ethernet-Sheild box

If you want to skip, the full code example is below or available here. I adapted this from an example posted by Gilson Ohime. If you’ve never played with your ethernet shield before, you might want to quickly go through the web client tutorial — I’m assuming you’re somewhat familiar with it, and won’t describe the code used to create the network. IP, etc. We have also shown how to create a mini web server with an Ethernet firewall. web server with firewall. web server with firewall. .

/*
Talking to Hue from an Arduino
By James Bruce (.com)
Adapted from code by Gilson Oguime. https://github.com/oguime/Hue_W5100_HT6P20B/blob/master/Hue_W5100_HT6P20B.ino
*/
#include
#include
// Hue constants
const char hueHubIP[] = «192.168.1.216»; // Hue hub IP
const char hueUsername[] = «new developer»; // Hue username
const int hueHubPort = 80;
// PIR
int pir = 2;
boolean activated = false;
// Hue variables
booleanhueOn; // on/off
int hueBri; // brightness value
long hueHue; // hue value
String hueCmd; // Hue command
unsigned long buffer=0; //buffer for received data storage
unsigned long addr;
// Ethernet
byte mac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 }; // W5100 MAC address
IPAddress ip(192,168,1,2); // Arduino IP
EthernetClient client;
/*
Setup
*/
void setup()
{
Serial.begin(9600);
ethernet.begin(mac,ip);
pinMode(pir, INPUT);
delay(2000);
Serial.println(«Ready.»);
}
void loop()
{
if(digitalRead(pir) == 1){
Serial.println(«activated»);
// A series of four sample commands, which color fades two lights between red and pink. Read up on the Hue API
// documentation for more details on the exact commands to be used, but note that quote marks must be escaped.
String command = «{\»on\»: true,\»hue\»: 50100,\»sat\»:255,\»bri\»:255,\»transitiontime\»:»+String(random(15 ,25))+»}»;
setHue(1,command);
command = «{\»on\»: true,\»hue\»: 65280,\»sat\»:255,\»bri\»:255,\»transitiontime\»:»+String(random(15, 25))+»}»;
setHue(2,command);
command = «{\»hue\»: 65280,\»sat\»:255,\»bri\»:255,\»transitiontime\»:»+String(random(15,25))+»}»;
setHue(1,command);
command = «{\»hue\»: 50100,\»sat\»:255,\»bri\»:255,\»transitiontime\»:»+String(random(15,25))+»}»;
setHue(2,command);
// so we can track state
activated = true;
}
else{
activated = false;
Serial.println(«deactivated»);
//was activated, so send a single off command
String command = «{\»on\»: false}»;
setHue(1,command);
setHue(2,command);
}
}
/* setHue() is our main command function, which needs to be passed a light number and a
* properly formatted command string in JSON format (basically a Javascript style array of variables
* and values. It then makes a simple HTTP PUT request to the Bridge at the IP specified at the start.
*/
boolean setHue(int lightNum,String command)
{
if (client.connect(hueHubIP, hueHubPort))
{
while(client.connected())
{
client.print(«PUT /api/»);
client.print(hueUsername);
client.print(«/lights/»);
client.print(lightNum); // hueLight zero based, add 1
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
}
client.stop();
return true; // command executed
}
else
return false; // command failed
}
/* A helper function in case your logic depends on the current state of the light.
* This sets a number of global variables which you can check to find out if a light is currently on or not
* and the hue etc. Not needed just to send out commands
*/
boolean getHue(int lightNum)
{
if (client.connect(hueHubIP, hueHubPort))
{
client.print(«GET /api/»);
client.print(hueUsername);
client.print(«/lights/»);
client.print(lightNum);
client.println(«HTTP/1.1»);
client.print(«Host: «);
client.println(hueHubIP);
client.println(«Content-type: application/json»);
client.println(«keep-alive»);
client.println();
while(client.connected())
{
if(client.available())
{
client.findUntil(«\»on\»:», «\0»);
hueOn = (client.readStringUntil(‘,’) == «true»); // if light is on, set variable to true
client.findUntil(«\»bri\»:», «\0»);
hueBri = client.readStringUntil(‘,’).toInt(); // set variable to brightness value
client.findUntil(«\»hue\»:», «\0»);
hueHue = client.readStringUntil(‘,’).toInt(); // set variable to hue value
break; // not capturing other light attributes yet
}
}
client.stop();
return true; // captured on,bri,hue
}
else
return false; // error reading on,bri,hue
}

view raw
Control Philips Hue from Arduino Ethernet Shield
hosted with ❤ by GitHub

Making state changes

Creating a new state to send to light bulbs is a simple case of creating a new one string variable and escaping all double quotes. I also added a function random(), to create some dynamic animation. Try making the hue variable random for different colors.

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

Sending a command

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

 setHue(1,command); 

All it does is connect to the bridge, spit out the command as a PUT request, along with all the other HTTP request-making nonsense.

 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 connected a simple HC-SR501 motion sensor to digital I/O pin 2. When motion is detected, a series of states for 2 lights are thrown onto the bridge to create a slow, dynamic animation. When the motion sensor is deactivated, both commands are sent one at a time. Ideally they should be back to the state they were in before movement was detected, but the logic isn’t that sensible — we’re just going to turn them on and off.

Restrictions

Although admittedly unoptimized code, it takes almost a second for the Arduino network interface 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 want to test). Therefore, any quick animation (I was trying to create a flickering candle effect) is simply not possible in the Arduino. This shouldn’t be a problem for most projects, only for high speed light animation, but it’s good to be aware of this limitation.

It’s also hard to completely parse any JSON response you get from the bridge; there is not enough RAM on the Arduino to store all the raw data. For this reason, you can limit yourself to sending.

Hack Hue

Now that you have the knowledge of how to operate Hue completely independently, this opens up the world of Hue home automation hacks. Real question: What are you going to do?

Похожие записи