For Christmas, we got a few Osram Lightify A19 RGBW bulbs and a Google Home over Christmas, but were missing the hub. We ended up getting the Osram Gateway and playing with that for a bit; then we realized that SmartThings is where all the fun is. So, now we have Home talking to the SmartThings v2 hub which talks to the lights.
One feature that we noticed is missing from the SmartThings device profile is “Dynamic Presets” or “Dynamic Scenes”. For example, “Fireplace” causes the lights to flicker between various shades of red and orange to simulate a fire, while “Candy” cycles through various shades of green, purple, and blue. Some of the presets aren’t very convincing (the fireplace one I actually don’t care for), but it’s neat that you can apply them or define your own to make the bulbs a bit more dynamic.
Based on the way it works, it seems like the bulbs actually handle the animation directly (i.e. the preset is uploaded to the bulbs for execution) so that the controller isn’t tied up having to constantly adjust the values on each bulb. I suspect that the way this works is proprietary to Osram and does not necessarily neatly fit into the Zigbee standard.
Regardless, if I enable detailed logging on the Osram Android app, I learn several things:
- Osram is using an API provided by Arrayent (endpoints are at https://na-srmprod02-api.arrayent.com:8081/zdk/services/zamapi/).
- In cloud-only mode, the app interacts with the bulbs by writing key-value pairs via Arrayent’s setMultiDeviceAttributes2 RPC method (http://developer.arrayent.com/developer-apis/acc-apis/acc-customer-operations/#setMultiDeviceAttributes2).
- The more advanced presets require RGBW firmware version 1.2.4.12 (01020412).
- The default presets come from a JSON file – curves.json – that ships with the app. The preset values get encoded into hexadecimal values that are then base64-encoded into a “ColorDimming” device action.
Here’s a sample preset:
"Candy": [
[
{
"hue": 227,
"sat": 255,
"level": 255,
"time": 52
},
{
"hue": 170,
"sat": 255,
"level": 255,
"time": 52
},
{
"hue": 85,
"sat": 255,
"level": 255,
"time": 52
},
{
"hue": 163,
"sat": 255,
"level": 255,
"time": 52
},
{
"hue": 128,
"sat": 255,
"level": 255,
"time": 52
},
{
"hue": 251,
"sat": 255,
"level": 255,
"time": 52
},
{
"hue": 1,
"sat": 255,
"level": 255,
"time": 52
},
{
"hue": 177,
"sat": 255,
"level": 255,
"time": 52
},
{
"hue": 113,
"sat": 255,
"level": 255,
"time": 52
},
{
"hue": 191,
"sat": 255,
"level": 255,
"time": 52
},
{
"hue": 234,
"sat": 255,
"level": 255,
"time": 52
},
{
"hue": 198,
"sat": 255,
"level": 255,
"time": 52
},
{
"hue": 152,
"sat": 255,
"level": 255,
"time": 52
},
{
"hue": 85,
"sat": 255,
"level": 255,
"time": 52
},
{
"hue": 234,
"sat": 255,
"level": 255,
"checksum": "2A23"
}
],
[
{
"hue": 234,
"sat": 255,
"level": 255,
"time": 52
},
{
"hue": 198,
"sat": 255,
"level": 255,
"time": 55
},
{
"hue": 152,
"sat": 255,
"level": 255,
"time": 55
},
{
"hue": 85,
"sat": 255,
"level": 255,
"time": 55
},
{
"hue": 234,
"sat": 255,
"level": 255,
"time": 55
},
{
"hue": 227,
"sat": 255,
"level": 255,
"time": 55
},
{
"hue": 170,
"sat": 255,
"level": 255,
"time": 55
},
{
"hue": 85,
"sat": 255,
"level": 255,
"time": 55
},
{
"hue": 163,
"sat": 255,
"level": 255,
"time": 55
},
{
"hue": 128,
"sat": 255,
"level": 255,
"time": 55
},
{
"hue": 251,
"sat": 255,
"level": 255,
"time": 55
},
{
"hue": 1,
"sat": 255,
"level": 255,
"time": 55
},
{
"hue": 177,
"sat": 255,
"level": 255,
"time": 55
},
{
"hue": 113,
"sat": 255,
"level": 255,
"time": 55
},
{
"hue": 191,
"sat": 255,
"level": 255,
"checksum": "2A4A"
}
],
[
{
"hue": 251,
"sat": 255,
"level": 255,
"time": 52
},
{
"hue": 1,
"sat": 255,
"level": 255,
"time": 55
},
{
"hue": 177,
"sat": 255,
"level": 255,
"time": 55
},
{
"hue": 113,
"sat": 255,
"level": 255,
"time": 55
},
{
"hue": 191,
"sat": 255,
"level": 255,
"time": 55
},
{
"hue": 234,
"sat": 255,
"level": 255,
"time": 55
},
{
"hue": 198,
"sat": 255,
"level": 255,
"time": 55
},
{
"hue": 152,
"sat": 255,
"level": 255,
"time": 55
},
{
"hue": 85,
"sat": 255,
"level": 255,
"time": 55
},
{
"hue": 234,
"sat": 255,
"level": 255,
"time": 55
},
{
"hue": 227,
"sat": 255,
"level": 255,
"time": 55
},
{
"hue": 170,
"sat": 255,
"level": 255,
"time": 55
},
{
"hue": 85,
"sat": 255,
"level": 255,
"time": 55
},
{
"hue": 163,
"sat": 255,
"level": 255,
"time": 55
},
{
"hue": 128,
"sat": 255,
"level": 255,
"checksum": "2A4A"
}
]
],
Here’s a sample of the log for that preset:
01-15 03:05:48.190 17444 17444 D Logger (c): pre execute : PlayDynamicSceneTask
01-15 03:05:48.190 17444 17878 D Logger (b): applying dynamic curve scene Candy
01-15 03:05:48.191 17444 17878 D Logger (b): generating curves from the in-app curves.json
01-15 03:05:48.227 17444 17878 D Logger (c): compare versions min required: 1.2.4.12 with current: 01020491
01-15 03:05:48.227 17444 17878 D Logger (b): unsupported device::0
01-15 03:05:48.230 17444 17878 D Logger (c): compare versions min required: 1.2.4.12 with current: 01020491
01-15 03:05:48.230 17444 17878 D Logger (b): applying curve; brightness=-1 ; agility=-1
01-15 03:05:48.231 17444 17878 D Logger (c): curveNumber: 1, agility: 85, calculated agility: 39
01-15 03:05:48.232 17444 17878 D Logger (c): curveNumber: 2, agility: 85, calculated agility: 39
01-15 03:05:48.232 17444 17878 D Logger (c): curveNumber: 3, agility: 85, calculated agility: 39
01-15 03:05:48.232 17444 17878 D Logger (c): curveNumber: 4, agility: 85, calculated agility: 39
01-15 03:05:48.232 17444 17878 D Logger (c): curveNumber: 5, agility: 85, calculated agility: 39
01-15 03:05:48.232 17444 17878 D Logger (c): curveNumber: 6, agility: 85, calculated agility: 39
01-15 03:05:48.232 17444 17878 D Logger (c): curveNumber: 7, agility: 85, calculated agility: 39
01-15 03:05:48.232 17444 17878 D Logger (c): curveNumber: 8, agility: 85, calculated agility: 39
01-15 03:05:48.232 17444 17878 D Logger (c): curveNumber: 9, agility: 85, calculated agility: 39
01-15 03:05:48.232 17444 17878 D Logger (c): curveNumber: 10, agility: 85, calculated agility: 39
01-15 03:05:48.232 17444 17878 D Logger (c): curveNumber: 11, agility: 85, calculated agility: 39
01-15 03:05:48.238 17444 17878 D Logger (c): curveNumber: 12, agility: 85, calculated agility: 39
01-15 03:05:48.238 17444 17878 D Logger (c): curveNumber: 13, agility: 85, calculated agility: 39
01-15 03:05:48.238 17444 17878 D Logger (c): curveNumber: 14, agility: 85, calculated agility: 39
01-15 03:05:48.238 17444 17878 D Logger (c): curveNumber: 15, agility: 85, calculated agility: 39
01-15 03:05:48.242 17444 17878 D Logger (c): json brightness: 255, pointNumber: 1, numberOfPoints: 15, calculated: 255
01-15 03:05:48.242 17444 17878 D Logger (c): json brightness: 255, pointNumber: 2, numberOfPoints: 15, calculated: 255
01-15 03:05:48.242 17444 17878 D Logger (c): json brightness: 255, pointNumber: 3, numberOfPoints: 15, calculated: 255
01-15 03:05:48.243 17444 17878 D Logger (c): json brightness: 255, pointNumber: 4, numberOfPoints: 15, calculated: 255
01-15 03:05:48.243 17444 17878 D Logger (c): json brightness: 255, pointNumber: 5, numberOfPoints: 15, calculated: 255
01-15 03:05:48.243 17444 17878 D Logger (c): json brightness: 255, pointNumber: 6, numberOfPoints: 15, calculated: 255
01-15 03:05:48.243 17444 17878 D Logger (c): json brightness: 255, pointNumber: 7, numberOfPoints: 15, calculated: 255
01-15 03:05:48.243 17444 17878 D Logger (c): json brightness: 255, pointNumber: 8, numberOfPoints: 15, calculated: 255
01-15 03:05:48.243 17444 17878 D Logger (c): json brightness: 255, pointNumber: 9, numberOfPoints: 15, calculated: 255
01-15 03:05:48.243 17444 17878 D Logger (c): json brightness: 255, pointNumber: 10, numberOfPoints: 15, calculated: 255
01-15 03:05:48.243 17444 17878 D Logger (c): json brightness: 255, pointNumber: 11, numberOfPoints: 15, calculated: 255
01-15 03:05:48.243 17444 17878 D Logger (c): json brightness: 255, pointNumber: 12, numberOfPoints: 15, calculated: 255
01-15 03:05:48.243 17444 17878 D Logger (c): json brightness: 255, pointNumber: 13, numberOfPoints: 15, calculated: 255
01-15 03:05:48.243 17444 17878 D Logger (c): json brightness: 255, pointNumber: 14, numberOfPoints: 15, calculated: 255
01-15 03:05:48.243 17444 17878 D Logger (c): json brightness: 255, pointNumber: 15, numberOfPoints: 15, calculated: 255
01-15 03:05:48.244 17444 17878 D Logger (1): you have NOT configured min and max hue for this curve
01-15 03:05:48.244 17444 17878 D Logger (c): curve hue: 227; calculated hue: 227
01-15 03:05:48.244 17444 17878 D Logger (1): you have NOT configured min and max hue for this curve
01-15 03:05:48.244 17444 17878 D Logger (c): curve hue: 170; calculated hue: 170
01-15 03:05:48.244 17444 17878 D Logger (1): you have NOT configured min and max hue for this curve
01-15 03:05:48.244 17444 17878 D Logger (c): curve hue: 85; calculated hue: 85
01-15 03:05:48.244 17444 17878 D Logger (1): you have NOT configured min and max hue for this curve
01-15 03:05:48.244 17444 17878 D Logger (c): curve hue: 163; calculated hue: 163
01-15 03:05:48.244 17444 17878 D Logger (1): you have NOT configured min and max hue for this curve
01-15 03:05:48.244 17444 17878 D Logger (c): curve hue: 128; calculated hue: 128
01-15 03:05:48.253 17444 17878 D Logger (1): you have NOT configured min and max hue for this curve
01-15 03:05:48.253 17444 17878 D Logger (c): curve hue: 251; calculated hue: 251
01-15 03:05:48.253 17444 17878 D Logger (1): you have NOT configured min and max hue for this curve
01-15 03:05:48.253 17444 17878 D Logger (c): curve hue: 1; calculated hue: 1
01-15 03:05:48.253 17444 17878 D Logger (1): you have NOT configured min and max hue for this curve
01-15 03:05:48.253 17444 17878 D Logger (c): curve hue: 177; calculated hue: 177
01-15 03:05:48.253 17444 17878 D Logger (1): you have NOT configured min and max hue for this curve
01-15 03:05:48.253 17444 17878 D Logger (c): curve hue: 113; calculated hue: 113
01-15 03:05:48.253 17444 17878 D Logger (1): you have NOT configured min and max hue for this curve
01-15 03:05:48.253 17444 17878 D Logger (c): curve hue: 191; calculated hue: 191
01-15 03:05:48.253 17444 17878 D Logger (1): you have NOT configured min and max hue for this curve
01-15 03:05:48.253 17444 17878 D Logger (c): curve hue: 234; calculated hue: 234
01-15 03:05:48.253 17444 17878 D Logger (1): you have NOT configured min and max hue for this curve
01-15 03:05:48.253 17444 17878 D Logger (c): curve hue: 198; calculated hue: 198
01-15 03:05:48.253 17444 17878 D Logger (1): you have NOT configured min and max hue for this curve
01-15 03:05:48.253 17444 17878 D Logger (c): curve hue: 152; calculated hue: 152
01-15 03:05:48.253 17444 17878 D Logger (1): you have NOT configured min and max hue for this curve
01-15 03:05:48.253 17444 17878 D Logger (c): curve hue: 85; calculated hue: 85
01-15 03:05:48.254 17444 17878 D Logger (1): you have NOT configured min and max hue for this curve
01-15 03:05:48.254 17444 17878 D Logger (c): curve hue: 234; calculated hue: 234
01-15 03:05:48.254 17444 17878 D Logger (c): minutesOfDay: -1, pointNumber: 1, cct: -1, calculated: -1
01-15 03:05:48.254 17444 17878 D Logger (c): minutesOfDay: -1, pointNumber: 2, cct: -1, calculated: -1
01-15 03:05:48.254 17444 17878 D Logger (c): minutesOfDay: -1, pointNumber: 3, cct: -1, calculated: -1
01-15 03:05:48.254 17444 17878 D Logger (c): minutesOfDay: -1, pointNumber: 4, cct: -1, calculated: -1
01-15 03:05:48.254 17444 17878 D Logger (c): minutesOfDay: -1, pointNumber: 5, cct: -1, calculated: -1
01-15 03:05:48.254 17444 17878 D Logger (c): minutesOfDay: -1, pointNumber: 6, cct: -1, calculated: -1
01-15 03:05:48.254 17444 17878 D Logger (c): minutesOfDay: -1, pointNumber: 7, cct: -1, calculated: -1
01-15 03:05:48.254 17444 17878 D Logger (c): minutesOfDay: -1, pointNumber: 8, cct: -1, calculated: -1
01-15 03:05:48.254 17444 17878 D Logger (c): minutesOfDay: -1, pointNumber: 9, cct: -1, calculated: -1
01-15 03:05:48.254 17444 17878 D Logger (c): minutesOfDay: -1, pointNumber: 10, cct: -1, calculated: -1
01-15 03:05:48.254 17444 17878 D Logger (c): minutesOfDay: -1, pointNumber: 11, cct: -1, calculated: -1
01-15 03:05:48.254 17444 17878 D Logger (c): minutesOfDay: -1, pointNumber: 12, cct: -1, calculated: -1
01-15 03:05:48.254 17444 17878 D Logger (c): minutesOfDay: -1, pointNumber: 13, cct: -1, calculated: -1
01-15 03:05:48.254 17444 17878 D Logger (c): minutesOfDay: -1, pointNumber: 14, cct: -1, calculated: -1
01-15 03:05:48.254 17444 17878 D Logger (c): minutesOfDay: -1, pointNumber: 15, cct: -1, calculated: -1
01-15 03:05:48.255 17444 17878 D Logger (b): DynamicCurve hex = 01ff00ff003c00003c e3ffff27aaffff2755ffff27a3ffff2780ffff27fbffff2701ffff27b1ffff2771ffff27bfffff27eaffff27c6ffff2798ffff2755ffff27eaffff92
01-15 03:05:48.255 17444 17878 D Logger (b): DynamicCurve base64 = Af8A/wA8AAA84///J6r//ydV//8no///J4D//yf7//8nAf//J7H//ydx//8nv///J+r//yfG//8nmP//J1X//yfq//+S
01-15 03:05:48.277 17444 17878 D Logger (b): device action= device01,ColorDimming,2,Af8A/wA8AAA84///J6r//ydV//8no///J4D//yf7//8nAf//J7H//ydx//8nv///J+r//yfG//8nmP//J1X//yfq//+S
01-15 03:05:48.292 17444 17878 D Logger (SMDA): {name1=DeviceAction, value1=device01,ColorDimming,2,Af8A/wA8AAA84///J6r//ydV//8no///J4D//yf7//8nAf//J7H//ydx//8nv///J+r//yfG//8nmP//J1X//yfq//+S, devId=201392459, secToken=**OMITTED**}
01-15 03:05:49.337 17444 17444 D Logger (b): dynamic scene applied
01-15 03:05:50.434 17444 17444 D Logger (c): stop progress : PlayDynamicSceneTask
01-15 03:05:50.434 17444 17444 D Logger (b): dynamic scene applied
01-15 03:05:50.434 17444 17444 D Logger (c): post execute : PlayDynamicSceneTask
Any thoughts on how we might be able to send this type of action over Zigbee through Smart Things?