-
-
Save shinyquagsire23/f7907fdf6b470200702e75a30135caf3 to your computer and use it in GitHub Desktop.
| DeviceInfo(softwareRevision, isOn, | |
| SceneLightState(color, powerOnBehavior, deviceInfo | |
| Light(id, | |
| Capabilities(dimmable, customState | |
| PowerOnBehavior(option | |
| hueplay, huebloom, hueiris, huelightstrip, huego, plug, bollard, wallspot, groundspot, flexiblelamp, wallshade, walllantern | |
| [ea:44:13:bd:db:59] Service [b8843add-0000-4aa1-8794-c3f462030bda] Unknown, ble_firmware_update? | |
| [ea:44:13:bd:db:59] Characteristic [b8843add-0004-4aa1-8794-c3f462030bda] | |
| [ea:44:13:bd:db:59] Characteristic [b8843add-0003-4aa1-8794-c3f462030bda] | |
| [ea:44:13:bd:db:59] Characteristic [b8843add-0002-4aa1-8794-c3f462030bda] | |
| [ea:44:13:bd:db:59] Characteristic [b8843add-0001-4aa1-8794-c3f462030bda] | |
| [ea:44:13:bd:db:59] Service [932c32bd-0000-47a2-835a-a8d455b859dd] light_control - startupConfiguration, combinedControl | |
| [ea:44:13:bd:db:59] Characteristic [932c32bd-0001-47a2-835a-a8d455b859dd] unk, 00 01 03 01 02 99 00 02 02 F4 01 03 02 01 00 | |
| [ea:44:13:bd:db:59] Characteristic [932c32bd-0002-47a2-835a-a8d455b859dd] Light state, 01/00 | |
| [ea:44:13:bd:db:59] Characteristic [932c32bd-0003-47a2-835a-a8d455b859dd] Brightness | |
| [ea:44:13:bd:db:59] Characteristic [932c32bd-0004-47a2-835a-a8d455b859dd] unk, E9 00 | |
| [ea:44:13:bd:db:59] Characteristic [932c32bd-0005-47a2-835a-a8d455b859dd] Color | |
| [ea:44:13:bd:db:59] Characteristic [932c32bd-0006-47a2-835a-a8d455b859dd] unk, write-only | |
| [ea:44:13:bd:db:59] Characteristic [932c32bd-0007-47a2-835a-a8d455b859dd] everything, includes color and brightness combined_light_control_port | |
| [ea:44:13:bd:db:59] Characteristic [932c32bd-1005-47a2-835a-a8d455b859dd] Also everything, but last four bytes FF FF FF FF - default powerloss state? combined_light_control_port_factory? | |
| [ea:44:13:bd:db:59] Service [0000fe0f-0000-1000-8000-00805f9b34fb] device_configuration_service_info - ProximityPairingSetup somewhere | |
| [ea:44:13:bd:db:59] Characteristic [97fe6561-0001-4f62-86e9-b71ee2da3d22] zigbee address, 64 e2 7a 08 01 88 17 00 | |
| [ea:44:13:bd:db:59] Characteristic [97fe6561-0003-4f62-86e9-b71ee2da3d22] userDefinedDeviceName, "Lamp" | |
| [ea:44:13:bd:db:59] Characteristic [97fe6561-0004-4f62-86e9-b71ee2da3d22] | |
| [ea:44:13:bd:db:59] Characteristic [97fe6561-0008-4f62-86e9-b71ee2da3d22] | |
| [ea:44:13:bd:db:59] Characteristic [97fe6561-a001-4f62-86e9-b71ee2da3d22] write-only | |
| [ea:44:13:bd:db:59] Characteristic [97fe6561-2004-4f62-86e9-b71ee2da3d22] write-only | |
| [ea:44:13:bd:db:59] Characteristic [97fe6561-2002-4f62-86e9-b71ee2da3d22] write-only | |
| [ea:44:13:bd:db:59] Characteristic [97fe6561-2001-4f62-86e9-b71ee2da3d22] unk, 0A | |
| [ea:44:13:bd:db:59] Service [0000180a-0000-1000-8000-00805f9b34fb] | |
| [ea:44:13:bd:db:59] Characteristic [00002a28-0000-1000-8000-00805f9b34fb] fw version | |
| [ea:44:13:bd:db:59] Characteristic [00002a24-0000-1000-8000-00805f9b34fb] model | |
| [ea:44:13:bd:db:59] Characteristic [00002a29-0000-1000-8000-00805f9b34fb] manufacturer | |
| [ea:44:13:bd:db:59] Service [00001801-0000-1000-8000-00805f9b34fb] | |
| [ea:44:13:bd:db:59] Characteristic [00002a05-0000-1000-8000-00805f9b34fb] Service changed |
@evan-brass Man the timing is insane, I am currently trying to reverse engineer it and I was about to contribute to this gist for the flashing on 0006 ! Thank you a lot for what you provided !
I didn't figure out much more besides how to put the bulb into demo mode and possibly how to trigger a factory reset. In particular I couldn't figure out how to use the timer / clock / alarm / wake up features.
https://github.com/evan-brass/huecontrol
@evan-brass did you do any progress in how to trigger a factory reset? I am currently writing a script to try to do this but all the services and characteristics are hard to understand since philips haven't released any documentation. Only doing this because i cant physically reset my bulb (don't have a bridge or a dimmer, just use it as a bt bulb), its probably still "bonded" with my last phone that i dont have anymore and now i cant connect to it through the hue app on a new phone so trying to reset it with a python script.
@nattzp I think writing 0x01 to 97fe6561-0004-4f62-86e9-b71ee2da3d22 might be a factory reset, but it is only accessible after being paired. I imagine that there must be another way to factory reset the bulb, but I don't know. Sorry.
Hi @nattzp @evan-brass , I have been tinkering with my Hue bulb lately and found out how to create schedules.
The GATT UUID is 9da2ddf1‑0001‑44d0‑909c‑3f3d3cb34a7b (handle 0x0072), which is used to create a new schedule but also to activate/deactivate and delete existing schedules. I'll describe in detail my findings in the following.
I have created this Python script to manage and create schedules as an example.
List schedules
Listing schedules is a short query, not a full-body payload. You just want to send 0x00 to the GATT, and you'll receive a response like:
00 00 <unknown_or_status> <count> <id0_le> <id1_le> ...
Example response:
00 00 07 02 01 00 04 00
Common Full Schedule Payload Layout
Create and update operations both use the same full schedule-body format.
Confirmed byte layout:
| Offset | Size | Meaning | Status |
|---|---|---|---|
0 |
1 | Operation opcode 01 |
confirmed |
1..2 |
2 | Source schedule id, little-endian. ff ff for create, existing id for update |
confirmed |
3 |
1 | Constant 00 in captured create/update payloads |
confirmed |
4 |
1 | Enabled flag in update flows. 01 for active, 00 for disabled |
confirmed |
5 |
1 | Constant 00 in captured create/update payloads |
confirmed |
6..9 |
4 | Semantic schedule timestamp, little-endian Unix time | confirmed |
10..13 |
4 | Fixed bytes 00 0e 01 01 for standard wake/sleep payloads |
confirmed for standard wake/sleep |
14 |
1 | Schedule kind marker: 00 sleep, 01 wake |
confirmed |
15..22 |
8 | Type-specific fixed block identifying the schedule behavior | confirmed as fixed per kind |
23..24 |
2 | Fade duration in deciseconds, little-endian | confirmed |
25..26 |
2 | Type/title-derived field. For standard payloads this matches 0x0118 + title_len |
confirmed for standard wake/sleep builder |
27..42 in early notes / 28..43 in opcode-included payloads |
16 | Schedule UUIDv4 bytes | confirmed |
43 in early notes / 44 in opcode-included payloads |
1 | Type-specific flag. 01 for captured sleep schedules, 00 for captured wake schedules |
confirmed by capture, semantics inferred |
next 4 bytes |
4 | Constant recurrence/sentinel field ff ff ff ff |
confirmed |
next 1 byte |
1 | ASCII title length | confirmed |
next N bytes |
N | ASCII schedule title | confirmed |
| final byte | 1 | Enabled state in stored/read-back payloads and update flows | confirmed |
Important timestamp rule:
- Sleep schedules store the visible selected sleep time directly.
- Wake schedules store the fade-start time, not the visible wake completion time.
Important type-specific fixed blocks for standard payloads:
| Schedule kind | Fixed bytes at 10..22 |
Meaning |
|---|---|---|
| sleep | 00 0e 01 01 00 02 01 01 03 02 4c 02 05 02 |
standard go-to-sleep payload prefix |
| wake | 00 0e 01 01 01 02 01 fe 03 02 bf 01 05 02 |
standard wake-up payload prefix |
Create A New Schedule
Create uses the full schedule-body format with a source id of ffff.
Generic create payload shape:
01 ff ff 00 01 00 <timestamp_le> <type_specific_bytes> <fade_ds_le> <field_25_26> <uuid16> <kind_flag> ff ff ff ff <title_len> <title_ascii> 01
For a standard sleep schedule built from parameters:
- opcode
01 - source id
ff ff - enabled bytes
00 01 00 - timestamp = selected sleep time
- type-specific block =
00 0e 01 01 00 02 01 01 03 02 4c 02 05 02 - fade = requested fade in deciseconds
- title field =
0x0118 + title_len - type flag byte =
01 - recurrence/sentinel =
ff ff ff ff - final byte =
01
For a standard wake schedule built from parameters:
- opcode
01 - source id
ff ff - enabled bytes
00 01 00 - timestamp = visible wake time minus fade duration
- type-specific block =
00 0e 01 01 01 02 01 fe 03 02 bf 01 05 02 - fade = requested fade in deciseconds
- title field =
0x0118 + title_len - type flag byte =
00 - recurrence/sentinel =
ff ff ff ff - final byte =
01
Create success notifications:
01 00 ff ff <new_id_le>
04 ff ff <new_id_le>
Create failure notification:
01 01 ff ff ff ff
Read Back One Schedule In Detail
Detail-read is a short request followed by a containerized schedule body.
Request format:
02 <schedule_id_le> 00 00
Response shape:
02 00 <schedule_id_le> <body_len> 00 00 00 <body...>
The <body...> bytes can be reconstructed into a normal schedule-like payload as:
01 <schedule_id_le> <body...>
That reconstructed payload reuses the same offsets as create/update payloads, which is why read-back decoding can extract title, kind, fade, timestamp, UUID, and enabled flag directly.
5. Update An Existing Schedule
Update reuses the full schedule-body format from create, but changes the source id and, when toggling state, the enabled bytes.
Generic update prefix:
01 <source_id_le> 00 <enabled_flag> 00
Rules:
- the full body must be resent, not just the changed field
source_id_leis the existing schedule id to replace- the final byte of the payload mirrors the enabled flag
- the bulb does not mutate schedules in place; it returns a replacement id
Update success notifications:
01 00 <source_id_le> <new_id_le>
04 <source_id_le> <new_id_le>
Activate Or Deactivate A Schedule
Activate and deactivate are specialized update operations using the same full-body update format.
Deactivate:
01 <source_id_le> 00 00 00 ... <final_byte=00>
Activate:
01 <source_id_le> 00 01 00 ... <final_byte=01>
Confirmed live deactivate example:
01 02 00 00 00 00 ...
01 00 02 00 03 00
04 02 00 03 00
Meaning: schedule id 2 was replaced by disabled schedule id 3.
Confirmed live reactivate example:
01 03 00 00 01 00 ...
01 00 03 00 04 00
04 03 00 04 00
Meaning: schedule id 3 was replaced by enabled schedule id 4.
Delete A Schedule
Delete is a separate short command and does not use the full schedule body.
Request format:
03 <schedule_id_le>
Success notifications:
03 00 <schedule_id_le>
04 <schedule_id_le> ff ff
Confirmed example for deleting schedule id 5:
03 05 00
03 00 05 00
04 05 00 ff ff
Missing pieces
I don't have access to repeating schedules or other options which are paywalled on the app.
The following parts are still partly inferred even though the overall command format is operational:
- the exact semantics of the fixed bytes at offsets
10..22beyond their role as kind/behavior descriptors - the deeper meaning of the
0x0118 + title_lenfield at offsets25..26, even though it is confirmed for the standard wake/sleep builder - whether the sentinel
ff ff ff ffis strictly a recurrence mask, a default-all-days marker, or another scheduler bitfield - whether additional app-side wake or sleep styles use different type-specific fixed blocks beyond the standard variants already captured
More commands:
0x05 doesn't seem to do anything, but 0x06 seems to be an animation thing? 0x08 might be a timing param.
0x060101 -> Cold flicker
0x060102 -> Warm flicker
0x060103 -> Cycle through different colors
0x0601030801ff -> Fast party mode
0x060103080101 -> Slow party mode