Automating Philips Hue Motion Sensor Functionality

OK, this turned out to be a *lot* more complicated than I thought. Here’s what I wanted to do: we have a Hue motion sensor in the bathroom which I’ve set up to do nothing during the day, and then come on at night. Nothing too controversial there. But I wanted to have a 3rd option: for a certain section of the night – say after midnight – to come on at a nightlight setting.

There’s a ‘3 times a charm formula‘ from the Hue Labs which sounded promising, but that only allows you to set the idle time after motion activation. So I started looking at the API. There were a few obvious options I tried which didn’t work [like simply setting the brightness – over-written by whatever scene you have set in the accessory setup].

This article set me on the right track for what I needed to do insofar as rule settings. By toggling changes on the smartphone app and then looking at the results in the Clip API debugger I narrowed down the changes to two rules called ‘MotionSensor 5.night-on’ and ‘MotionSensor 5.night-dark-on’. [Obviously the number is dependent on the identifier the sensor is registered under.]

This isn’t enough on its own. I gave up on this after my first pass, waiting for a rainy day to come back to it – today.

I ended up using OWASP ZAP to proxy the Hue app traffic, to see what it was doing when you submit a change to the sensor configuration. That’s quite interesting actually: I was initially a bit puzzled at what looked like a mountain of traffic on first pass, but what in part turns out to be a very zealous keep-alive – roughly twice a second.

Long and short of it is that resetting the scene config using the app overwrites a ‘resourcelink’ with new scene specific values, as well as updating the rules.

I’ve roughed this out with my own iOS app just to check that it works in a way that I can transplant to another setup [a cron job on a Raspberry Pi would be a reasonable candidate]. To toggle on the ‘dim at night after midnight’ setting I make 3 API calls. You’ll need to fiddle around with the clip tool to get the equivalents for your hub – specifically, your sensor number will be different. For me, these are:

  • Rule: MotionSensor 5.night-on
  • Rule: MotionSensor 5.night-dark-on
  • Resourcelink:┬áMotionSensor 5

For the rules, I Post the same ‘actions’ payload to both of the corresponding endpoints. It looks like:

{"actions": [
                {
                        "address": "/groups/YourActionNumber/action",
                        "method": "PUT",
                        "body": {
                                "scene": "YourDimSceneIDHere"
                        }
                },
                {
                        "address": "/sensors/YourStateNumber/state",
                        "method": "PUT",
                        "body": {
                                "status": 1
                        }
                }
        ]
}

Then for the resourcelink, I post:

{
    "name": "MotionSensor 5",
    "description": "MotionSensor 5 behavior",
    "type": "Link",
    "classid": 10020,
    "owner": "OwnerIDHere",
    "recycle": false,
    "links": [
              "/sensors/5",
              "/sensors/6",
              "/sensors/19",
              "/groups/5",
              "/rules/4",
              "/rules/5",
              "/rules/6",
              [etc.....]
              "/scenes/YourDimSceneIDHere",
              "/scenes/RecoverRoomSceneIDHere"
              ]
}

The sensor and rule set you’re linking to will be specific to your own setup.

I’ve no idea what that ‘recover scene’ is. I’m guessing it’s something that’s created when you configure a sensor in the first instance, and is some sort of default state.

There’s a corresponding 3 API calls which I need to make to toggle back to the scene for ‘bright pre-midnight’, replacing the scene ID accordingly.

At the point I gave up – where I was just making the rule changes – I could tell that it wasn’t right by loading up the config in the app. The partial configuration – without the resourcelink change – manifest itself simply as ‘do nothing’ for the nighttime slot. Resetting this restored the full config. I guess there’s always the danger that if you run wild and free with setting values incorrectly, you might invalidate the ruleset to the point where unpicking it could be a problem. All I can say is that the above approach works for me, but test carefully!