+++
title = "How Does The Phillips Hue Wake-Up Feature Work?"
author = ["Correl Roush"]
date = 2018-03-13T00:00:00-04:00
keywords = ["emacs", "org-mode", "themes"]
tags = ["home-automation"]
draft = false
+++
I recently got myself a set of Phillips Hue White and Color Ambiance
lights. One of the features I was looking forward to in particular
(besides playing with all the color options) was setting a wake-up
alarm with the lights gradually brightening. This was pretty painless
to get set up using the phone app. I'm pretty happy with the result,
but there's certainly some things I wouldn't mind tweaking. For
example, the initial brightness of the bulbs (at the lowest setting)
still seems a bit bright, so I might want to delay the bedside lamps
and let the more distant lamp start fading in first. I also want to
see if I can fiddle it into transitioning between some colors to get
more of a sunrise effect (perhaps "rising" from the other side of the
room, with the light spreading towards the head of the bed).
Figuring out how the wake-up settings that the app installed on my
bridge seemed a good first step towards introducing my own
customizations.
Information on getting access to a Hue bridge to make REST API calls
to it can be found in the [Hue API getting started guide](https://www.developers.meethue.com/documentation/getting-started).
## My wake-up settings {#my-wake-up-settings}
My wake-up is scheduled for 7:00 to gradually brighten the lights with
a half-hour fade-in each weekday. I also toggled on the setting to
automatically turn the lights off at 9:00.
![](/images/Screenshot_20180313-182434.png) ![](/images/Screenshot_20180313-182438.png)
## Finding things on the bridge {#finding-things-on-the-bridge}
The most natural starting point is to check the schedules. Right off
the bat, I find what I'm after:
### The schedule ... {#the-schedule-dot-dot-dot}
```http
GET http://bridge/api/${username}/schedules/1
```
```js
{
"name": "Wake up",
"description": "L_04_fidlv_start wake up",
"command": {
"address": "/api/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/sensors/2/state",
"body": {
"flag": true
},
"method": "PUT"
},
"localtime": "W124/T06:30:00",
"time": "W124/T10:30:00",
"created": "2018-03-11T19:46:54",
"status": "enabled",
"recycle": true
}
```
This is a recurring schedule item that runs every weekday at 6:30. We
can tell this by looking at the `localtime` field. From the
documentation on [time patterns](https://www.developers.meethue.com/documentation/datatypes-and-time-patterns#16%5Ftime%5Fpatterns), we can see that it's a recurring time
pattern specifying days of the week as a bitmask, and a time (6:30).
Table 1:
Unraveling the weekday portion
| `0MTWTFSS` |
|:----------------------------|
| `01111100` (124 in decimal) |
Since this schedule is enabled, we can be assured that it will run,
and in doing so, will issue a `PUT` to a sensors endpoint, setting a
flag to true.
### ... triggers the sensor ... {#dot-dot-dot-triggers-the-sensor-dot-dot-dot}
```http
GET http://bridge/api/${username}/sensors/2
```
```js
{
"state": {
"flag": false,
"lastupdated": "2018-03-13T13:00:00"
},
"config": {
"on": true,
"reachable": true
},
"name": "Sensor for wakeup",
"type": "CLIPGenericFlag",
"modelid": "WAKEUP",
"manufacturername": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"swversion": "A_1801260942",
"uniqueid": "L_04_fidlv",
"recycle": true
}
```
The sensor is what's _really_ setting things in motion. Here we've got
a [generic CLIP flag sensor](https://www.developers.meethue.com/documentation/supported-sensors#clipSensors) that is triggered exclusively by our
schedule. Essentially, by updating the flag state, we trigger the
sensor.
### ... triggers a rule ... {#dot-dot-dot-triggers-a-rule-dot-dot-dot}
```http
GET http://bridge/api/${username}/rules/1
```
```js
{
"name": "L_04_fidlv_Start",
"owner": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"created": "2018-03-11T19:46:51",
"lasttriggered": "2018-03-13T10:30:00",
"timestriggered": 2,
"status": "enabled",
"recycle": true,
"conditions": [
{
"address": "/sensors/2/state/flag",
"operator": "eq",
"value": "true"
}
],
"actions": [
{
"address": "/groups/1/action",
"method": "PUT",
"body": {
"scene": "7GJer2-5ahGIqz6"
}
},
{
"address": "/schedules/2",
"method": "PUT",
"body": {
"status": "enabled"
}
}
]
}
```
Now things are happening. Looking at the conditions, we can see that
this rule triggers when the wakeup sensor updates, and its flag is set
to `true`. When that happens, the bridge will iterate through its
rules, find that the above condition has been met, and iterate through
each of the actions.
### ... which sets the scene ... {#dot-dot-dot-which-sets-the-scene-dot-dot-dot}
The bedroom group (`/groups/1` in the rule's action list) is set to
the following scene, which turns on the lights at minimum brightness:
```http
GET http://bridge/api/${username}/scenes/7GJer2-5ahGIqz6
```
```js
{
"name": "Wake Up init",
"lights": [
"2",
"3",
"5"
],
"owner": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"recycle": true,
"locked": true,
"appdata": {},
"picture": "",
"lastupdated": "2018-03-11T19:46:50",
"version": 2,
"lightstates": {
"2": {
"on": true,
"bri": 1,
"ct": 447
},
"3": {
"on": true,
"bri": 1,
"ct": 447
},
"5": {
"on": true,
"bri": 1,
"ct": 447
}
}
}
```
### ... and schedules the transition ... {#dot-dot-dot-and-schedules-the-transition-dot-dot-dot}
Another schedule (`/schedules/2` in the rule's action list) is enabled
by the rule.
```http
GET http://bridge/api/${username}/schedules/2
```
```js
{
"name": "L_04_fidlv",
"description": "L_04_fidlv_trigger end scene",
"command": {
"address": "/api/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/groups/0/action",
"body": {
"scene": "gXdkB1um68N1sZL"
},
"method": "PUT"
},
"localtime": "PT00:01:00",
"time": "PT00:01:00",
"created": "2018-03-11T19:46:51",
"status": "disabled",
"autodelete": false,
"starttime": "2018-03-13T10:30:00",
"recycle": true
}
```
_This_ schedule is a bit different from the one we saw before. It is
normally disabled, and it's time pattern (in `localtime`) is
different. The `PT` prefix specifies that this is a timer which
expires after the given amount of time has passed. In this case, it is
set to one minute (the first 60 seconds of our wake-up will be spent
in minimal lighting). Enabling this schedule starts up the timer. When
one minute is up, another scene will be set.
This one, strangely, is applied to group `0`, the meta-group including
all lights, but since the scene itself specifies to which lights it
applies, there's no real problem with it.
### ... to a fully lit room ... {#dot-dot-dot-to-a-fully-lit-room-dot-dot-dot}
```http
GET http://bridge/api/${username}/scenes/gXdkB1um68N1sZL
```
```js
{
"name": "Wake Up end",
"lights": [
"2",
"3",
"5"
],
"owner": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"recycle": true,
"locked": true,
"appdata": {},
"picture": "",
"lastupdated": "2018-03-11T19:46:51",
"version": 2,
"lightstates": {
"2": {
"on": true,
"bri": 254,
"ct": 447,
"transitiontime": 17400
},
"3": {
"on": true,
"bri": 254,
"ct": 447,
"transitiontime": 17400
},
"5": {
"on": true,
"bri": 254,
"ct": 447,
"transitiontime": 17400
}
}
}
```
This scene transitions the lights to full brightness over the next 29
minutes (1740 seconds), per the specified `transitiontime` (which is
specified in deciseconds).
### ... which will be switched off later. {#dot-dot-dot-which-will-be-switched-off-later-dot}
Finally, an additional rule takes care of turning the lights off and
the wake-up sensor at 9:00 (Two and a half hours after the initial
triggering of the sensor).
```http
GET http://bridge/api/${username}/rules/2
```
```js
{
"name": "Wake up 1.end",
"owner": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"created": "2018-03-11T19:46:51",
"lasttriggered": "2018-03-13T13:00:00",
"timestriggered": 2,
"status": "enabled",
"recycle": true,
"conditions": [
{
"address": "/sensors/2/state/flag",
"operator": "eq",
"value": "true"
},
{
"address": "/sensors/2/state/flag",
"operator": "ddx",
"value": "PT02:30:00"
}
],
"actions": [
{
"address": "/groups/2/action",
"method": "PUT",
"body": {
"on": false
}
},
{
"address": "/sensors/2/state",
"method": "PUT",
"body": {
"flag": false
}
}
]
}
```
Unlike the first rule, this one doesn't trigger immediately. It has an
additional condition on the sensor state flag using the special `ddx`
operator, which (given the timer specified) is true **two and a half
hours after** the flag has been set. As the schedule sets it at 6:30,
that means that this rule will trigger at 9:00, turn the lights off in
the bedroom, and set the sensor's flag to `false`.
## Where to go from here {#where-to-go-from-here}
The wake-up config in the phone app touched on pretty much every major
aspect of the Hue bridge API. Given the insight I now have into how it
works, I can start constructing my own schedules and transitions, and
playing with different ways of triggering them and even having them
trigger each other.
If I get around to building my rolling sunrise, I'll be sure to get a
post up on it :)