Schedules GATT Characteristic
UUID: b77abf7f-66b5-4899-821d-efb177843783
Service: Shelly (de8a5aac-a99b-c315-0c80-60d4cbb51225)
All multi-byte values are little-endian. Temperature target is an IEEE 754 float (4 bytes LE).
Max 10 rules (IDs 0-9). Timespec is a 6-field cron string: SEC MIN HOUR DOM MON DOW.
Read
Returns all active rules packed sequentially, terminated by 0xFF:
repeat per rule:
┌──────────┬──────────┬────────────────┬──────────┬──────────────────┐
│ rule_id │ enable │ target │ ts_len │ timespec │
│ uint8 │ uint8 │ float (4B LE) │ uint8 │ char[ts_len] │
└──────────┴──────────┴────────────────┴──────────┴──────────────────┘
terminator:
┌──────┐
│ 0xFF │
└──────┘
Example
Device has two rules — rule 0 (enabled, 21.5 °C, weekdays 07:00) and rule 3 (disabled, 18.0 °C, daily 22:30):
00 01 00 00 ac 41 11 30 20 30 20 37 20 2a 20 2a 20 4d 4f 4e 2d 46 52 49
03 00 00 00 90 41 0d 30 20 33 30 20 32 32 20 2a 20 2a 20 2a
ff
Breakdown:
| Bytes | Field | Value |
|---|---|---|
00 | rule_id | 0 |
01 | enable | 1 (yes) |
00 00 ac 41 | target | 21.5 °C |
11 | ts_len | 17 |
30 20 … 49 | timespec | 0 0 7 * * MON-FRI |
03 | rule_id | 3 |
00 | enable | 0 (no) |
00 00 90 41 | target | 18.0 °C |
0d | ts_len | 13 |
30 20 … 2a | timespec | 0 30 22 * * * |
ff | terminator | — |
Empty device returns a single byte: ff.
Write
Add rule (0x01)
Assigns the first free rule ID automatically.
┌──────┬──────────┬────────────────┬──────────┬──────────────────┐
│ 0x01 │ enable │ target │ ts_len │ timespec │
│ │ uint8 │ float (4B LE) │ uint8 │ char[ts_len] │
└──────┴──────────┴────────────────┴──────────┴──────────────────┘
Example — add enabled rule, 21.5 °C, weekdays at 07:00 (0 0 7 * * MON-FRI):
01 01 00 00 ac 41 11 30 20 30 20 37 20 2a 20 2a 20 4d 4f 4e 2d 46 52 49
Update rule (0x02)
Modifies an existing rule by ID.
┌──────┬──────────┬──────────┬────────────────┬──────────┬──────────────────┐
│ 0x02 │ rule_id │ enable │ target │ ts_len │ timespec │
│ │ uint8 │ uint8 │ float (4B LE) │ uint8 │ char[ts_len] │
└──────┴──────────┴──────────┴────────────────┴──────────┴──────────────────┘
Example — update rule 0, enabled, 18.0 °C, daily at 22:30 (0 30 22 * * *):
02 00 01 00 00 90 41 0d 30 20 33 30 20 32 32 20 2a 20 2a 20 2a
Remove rule (0x03)
┌──────┬──────────┐
│ 0x03 │ rule_id │
│ │ uint8 │
└──────┴──────────┘
Example — remove rule 2:
03 02
Remove all (0xFF)
┌──────┐
│ 0xFF │
└──────┘
Example:
ff
Error responses
Write errors are returned as ATT status codes:
| ATT status | Meaning |
|---|---|
0x00 | Success |
0x0D | Invalid length (missing fields, ts_len mismatch) |
0x11 | Out of range (rule_id >= 10) |
0x13 | Value not allowed (rule_id does not exist) |
0x11 | Insufficient resources (no free slot on add) |
0x06 | Request not supported (unknown command byte) |
Reference float values
| °C | Hex (LE) |
|---|---|
| 5.0 | 00 00 a0 40 |
| 18.0 | 00 00 90 41 |
| 20.0 | 00 00 a0 41 |
| 21.0 | 00 00 a8 41 |
| 21.5 | 00 00 ac 41 |
| 22.0 | 00 00 b0 41 |
| 25.0 | 00 00 c8 41 |
| 30.0 | 00 00 f0 41 |
GUI tool
python3 tools/schedules.py
Requires pip install bleak.