Skip to content

0404: Zone Schedule

David Bonnes edited this page Jun 15, 2020 · 22 revisions

The controller will respond to a RQ / 0404 with the schedule for that zone:

095 RQ --- 18:013393 01:145038 --:------ 0404 007 00200008000100
045 RP --- 01:145038 18:013393 --:------ 0404 048 0020000829010568816DD1BD...

All RQ packets consist of a 7-byte header (only), while RP packets are variable-length, with a similar 7-byte header and the remaining bytes making up a fragment of the overall message.

This message is large, and will usually require a sequence of 3-5 RP packets to obtain all the fragments needed to obtain a zone's schedule - the first RP will indicate the number of these packets.

Payload header

All RQ packets consist only of a header in this form (edited for readability):

00-200008-00-01-00
field name RQ
[0:2] zone_idx 00 to 0B
[2:8] unknown_0 always 200008
[8:10] fragment_length 00 for all RQs, up to 29 for RPs
[10:12] fragment_ordinal from 01 to total_fragments
[12:14] total_fragments but is 00 for first RQ

Note: Although payload lengths are in decimal: 048 = 48, fragment lengths are in hexadecimal: 29 = 0x29 = 41.

RP packets have the same header format, which will provide the total fragments for that zone's schedule (above, the fragment is 0x29 bytes long, and begins 68816DD1BD0...):

00-200008-29-01-05 68816DD1BD0...

Subsequent RQ packets must have the total fragments set correctly, as well as the fragment number, otherwise they will be ignored. So the complete exchange of RQ / RP packets for zone 9 would be (payloads edited for readability):

095 RQ --- 18:013393 01:145038 --:------ 0404 007  09 200008 00 01-00
045 RP --- 01:145038 18:013393 --:------ 0404 048  09 200008 29 01-05 68816DD1BD...
095 RQ --- 18:013393 01:145038 --:------ 0404 007  09 200008 00 02-05
045 RP --- 01:145038 18:013393 --:------ 0404 048  09 200008 29 02-05 A42BEEC9F1...
095 RQ --- 18:013393 01:145038 --:------ 0404 007  09 200008 00 03-05
045 RP --- 01:145038 18:013393 --:------ 0404 048  09 200008 29 03-05 1BB833CBA4...
095 RQ --- 18:013393 01:145038 --:------ 0404 007  09 200008 00 04-05
045 RP --- 01:145038 18:013393 --:------ 0404 048  09 200008 29 04-05 3BB13AE93A...
095 RQ --- 18:013393 01:145038 --:------ 0404 007  09 200008 00 05-05
045 RP --- 01:145038 18:013393 --:------ 0404 010  09 200008 03 05-05 C9E63E

The last RP is the end of the sequence of fragments because it is fragment 5 of 5 (05-05). Note also, in this specific instance, the final fragment_length is 03 rather than 29 and so the payload length is 010 rather than 048.

Payload fragments

The fragments, once concatenated into a complete block, can be inflated using zlib to obtain a sequence of 20-byte setpoints that can be decoded thus:

fragments = ["68816D...", "A42BEE...", "1BB833...", "3BB13A...", "C9E63E"]
message = zlib.decompress(bytearray.fromhex("".join(fragments)))

for i in range(0, len(message), 20):
    (zone, day, time, temp, _) = struct.unpack("<xxxxBxxxBxxxHxxHH", message[i : i + 20])
    print(
        "ZONE={0:d} DAY={1:d} TIME={2:02d}:{3:02d} TEMP={4:.2f}".format(
            zone, day, *divmod(time, 60), temp / 100
        )
    )
Clone this wiki locally