Skip to content

2349: Setpoint Override

David Bonnes edited this page Mar 29, 2021 · 24 revisions

WIP - Setpoint Override

This packet has two distinct payload formats either 7 or 13 bytes long, dependant upon an optional trailing datetime field.

 I --- 01:063844 --:------ 01:063844 2349 013 03070804FFFFFF0017030B07E4
 I --- 01:063844 --:------ 01:063844 2349 007 06070800FFFFFF

Payload length 7: The following

 W --- 22:081652 01:063844 --:------ 2349 007 01086600FFFFFF
 I --- 01:063844 22:081652 --:------ 2349 007 01086600FFFFFF

The following was seen with a DTS92(E) that was placed into eco mode, which lasts for an hour.

2020-09-16T20:17:07.669 043  W --- 22:081652 01:063844 --:------ 2349 007 0106400300003C
2020-09-16T20:17:07.685 044  I --- 01:063844 22:081652 --:------ 2349 007 0106400300003C
2020-09-16T20:20:07.649 042 RQ --- 22:081652 01:063844 --:------ 2349 007 01064003000039
2020-09-16T20:20:07.666 044 RP --- 01:063844 22:081652 --:------ 2349 007 01064003000039
2020-09-16T20:23:07.642 042 RQ --- 22:081652 01:063844 --:------ 2349 007 01064003000036
2020-09-16T20:23:07.659 044 RP --- 01:063844 22:081652 --:------ 2349 007 01064003000036
   ...
2020-09-16T21:11:07.623 044 RP --- 01:063844 22:081652 --:------ 2349 007 01064003000006
2020-09-16T21:14:07.615 043 RQ --- 22:081652 01:063844 --:------ 2349 007 01064003000003
2020-09-16T21:14:07.642 044 RP --- 01:063844 22:081652 --:------ 2349 007 01064003000003

You can see it start with a duration of 0x3C (60 in decimal), dropping regularly, and reaching 0x03 (3 in decimal) some 57 minutes later.

Payload length 13:

2020-11-03T21:32:35.019421 043  I --- 01:063844 --:------ 01:063844 2349 007 01086600FFFFFF

2020-11-03T21:35:37.843776 057  W --- 22:081652 01:063844 --:------ 2349 007 01086600FFFFFF
2020-11-03T21:35:37.860222 043  I --- 01:063844 22:081652 --:------ 2349 007 01086600FFFFFF

2020-11-03T21:35:48.389720 043  I --- 01:063844 --:------ 01:063844 2349 013 0101F404FFFFFF0017030B07E4

2020-11-03T21:41:10.398336 060  I --- 01:063844 --:------ 01:063844 2349 013 01086604FFFFFF0017030B07E4
2020-11-03T21:41:16.600527 058  I --- 01:063844 --:------ 01:063844 2349 007 01086600FFFFFF

2020-11-03T21:42:40.832053 055  W --- 22:070483 01:063844 --:------ 2349 007 06076C00FFFFFF
2020-11-03T21:42:40.854956 043  I --- 01:063844 --:------ 01:063844 2349 007 06070800FFFFFF
2020-11-03T21:42:40.882790 042  I --- 01:063844 22:070483 --:------ 2349 007 06070800FFFFFF

2020-11-03T21:42:42.492518 043  I --- 01:063844 --:------ 01:063844 2349 013 06070804FFFFFF0017030B07E4
2020-11-03T21:46:59.850895 042  I --- 01:063844 --:------ 01:063844 2349 007 06070800FFFFFF
2020-11-03T22:31:15.765656 042  I --- 01:063844 --:------ 01:063844 2349 013 0101F404FFFFFF0017030B07E4

Payload structure

This is the same example as above, but dashes have been added to the payload for readability:

 I --- 01:063844 --:------ 01:063844 2349 013 03-0708-04-FFFFFF-0017030B07E4
 I --- 01:063844 --:------ 01:063844 2349 007 06-0708-00-FFFFFF
Payload decode: Split
zone_idx [0:2]
setpoint [2:6] in Celsius
zone_mode [6:8] see notes below
countdown [8:14] in minutes, for mode 03
time_until [14:26] a datetime, for mode 04

Zone mode is one of:

ZONE_MODE_FOLLOW_SCHEDULE = "00"
ZONE_MODE_ADVANCED_OVERRIDE = "01"  # until the next scheduled setpoint
ZONE_MODE_PERMANENT_OVERRIDE = "02"  # indefinitely
ZONE_MODE_COUNTDOWN_OVERRIDE = "03"  # for a number of minutes
ZONE_MODE_TEMPORARY_OVERRIDE = "04"  # until a given date/time

This is code to convert the time_until field into a datetime:

def dtm_from_hex(value: str) -> str:  # from parsers
    """Convert a hex string to an (naive, local) isoformat string."""
    #        00141B0A07E3  (...HH:MM:00)    for system_mode, zone_mode (schedules?)
    #      0400041C0A07E3  (...HH:MM:SS)    for sync_datetime

    if value == "FF" * 6:
        return None

    if len(value) == 12:
        value = f"00{value}"
    # assert len(value) == 14
    return dt(
        year=int(value[10:14], 16),
        month=int(value[8:10], 16),
        day=int(value[6:8], 16),
        hour=int(value[4:6], 16) & 0b11111,  # 1st 3 bits: DayOfWeek
        minute=int(value[2:4], 16),
        second=int(value[:2], 16) & 0b1111111,  # 1st bit: used for DST
    ).strftime("%Y-%m-%d %H:%M:%S")
Clone this wiki locally