wolfgang ziegler


„make stuff and blog about it“

Using the Philips Hue Motion Sensor API

October 1, 2017

TL;DR:

  • One of my projects uses an IR motion sensor for detecting presence in a room.
  • The data I got back from this sensor was very unreliable.
  • Recently, I bought a Philips Hue Motion Sensor controlling the lights in that very same room.
  • Philips provides a very simple API fo its Hue hardware.
  • Turns out I can just replace my custom motion sensor with the data provided by the Hue sensor.

The Problem

A while ago, I blogged about my Family Dashboard project. As part of the build, I also included a small PIR sensor in the wooden frame, hoping it would easily allow me to turn the display on or off depending on presence in the room.

Dashboard with the built-in motion sensor

Unfortunately, the readings I got from this motion sensor where very unreliable and most of the time it reported motion / presence even if nobody was actually in the room.

After having tried a second sensor with the same results, I gave up and switched the frame's operation to a CRON based day / night / on / off operation.

Of course, I was not fully satisfied with this workaround.

The Solution

The solution came in the form of a neat piece of hardware I had bought just recently. Previously, I had installed a couple of Philips Hue lights and I extended this setup with the Hue Motion Sensor.

This sensor works really nicely and while the actual Hue bulbs are rather pricey, this hardware is absolutely worth its price.

But the best thing about all the Hue products is that they provide a neat Web API for setting and retrieving data.

Philips provides a great Web API for their lights and sensors!

I had already played around with the API of the light bulbs before (Philips provides a good getting started tutorial here) and it turned out to be really easy and straight-forward to also get the motion sensor's data.

Since the dashboard and the Hue motion sensor were in the same room, this pretty much solved my problem. Instead of relying on the flaky data reported by the sensor that I had built in, I just used the data provided by the Hue motion sensor.

Retrieving Sensor Data

While the getting started tutorial naturally focusses on controlling the light bulbs, reading the available sensors isn't difficult either. Mainly, replace the lights part in the URL with sensors and you're on the right track.

To retrieve an overview of all available sensor data, simply use this URL.

http://<HUE_BRIDGE>/api/<USER_ID>/sensors

The response will look familiar to this.

{
    "1": {
        "state": {
            "daylight": true,
            "lastupdated": "2017-10-01T11:10:05"
        },
        "config": {
            "on": true,
            "configured": true,
            "sunriseoffset": 30,
            "sunsetoffset": -30
        },
        "name": "Daylight",
        "type": "Daylight",
        "modelid": "PHDL00",
        "manufacturername": "Philips",
        "swversion": "1.0"
    },
    "8": {
        "state": {
            "presence": false,
            "lastupdated": "none"
        },
        "config": {
            "on": true,
            "reachable": true
        },
        . . . 
}

So to get data of a specific sensor, just add its ID to the URL above. In my case, ID 13 happens to be the motion detector's URL.

http://<HUE_BRIDGE>/api/<USER_ID>/sensors/13

The result is simply a subset of the previous call. The information we care about is the property presence.

{
    "state": {
        "presence": true,
        "lastupdated": "2017-10-01T12:37:30"
    },
    "swupdate": {
        "state": "noupdates",
        "lastinstall": null
    },
    "config": {
        "on": true,
        "battery": 100,
        "reachable": true,
        "alert": "none",
        "ledindication": false,
        "usertest": false,
        "sensitivity": 2,
        "sensitivitymax": 2,
        "pending": []
    },
    "name": "Hue motion sensor K├╝che",
    "type": "ZLLPresence",
    "modelid": "SML001",
    "manufacturername": "Philips",
    "swversion": "6.1.0.18912",
    "uniqueid": ". . ."
}

The Code

I had an existing python script, which read the state of the PIR sensor connected to GPIO. I simply replace this line of code with this new method that retrieves the data from the Web API. Job done!

def get_pir_state():
  try:
    response = requests.get('http://' + secrets.HUE_BRIDGE + '/api/' + secrets.USER_ID + '/sensors/13')
    json_data = json.loads(response.text)
    return 1 if json_data['state']['presence'] == True else 0
  except:
    print "error ...",  sys.exc_info()[0]
    return 1

The whole code for this python script can be found in the GitHub repository https://github.com/z1c0/dashydash of the project.

That Simple?

Can't be that simple, right? Actually it is. A couple of improvements are of course possible. First, UPnP discovery should be used to find the Hue bridge on the network instead of using a constant IP address. Also, the hard-coded sensor ID could be a problem maybe, in case these numbers change over time. A simple enumeration of all sensors before picking the one we care about will solve this easily.

Actually, this approach works nice enough that I got rid of my built-in sensor and added a push button to my dashboard frame. In case I want to turn the display on or off manually.

Replaced the PIR sensor with a push button