andylockran / heatmiserV3

MIT License
11 stars 12 forks source link

Snapshot #71

Open andylockran opened 8 months ago

andylockran commented 8 months ago

Hey,

Can someone get me a read of their DCB for any specific model of any thermostat. I've done a lot of research and think I can come up with a much more rigorous library than this one so far.

Cheers in advance.

Andy

Azelphur commented 8 months ago

Is this what you need?

from heatmiserv3 import heatmiser, connection
import pprint
import logging

IP_ADDRESS = "192.168.1.187"
PORT = "4196"
TSTATS = {
    # I checked the cloakroom and utility thermostats
    # and got their model numbers from the back of the
    # wall plates so they should be correct. The rest
    # of the units I assume to be the same PRT-N TS
    # but I haven't pulled them off the wall to check
    "Cloakroom": 1, # PRT-N TS (Checked)
    "Utility": 2, # PRT/HW-N TS (Checked)
    "Pool": 3, # Assumed to be PRT-N TS
    "Hallway": 4, # Assumed to be PRT-N TS
    "Study": 5, # Assumed to be PRT-N TS
    "Sitting Room": 6, # Assumed to be PRT-N TS
    "Living Room": 7, # Assumed to be PRT-N TS
    "Dining Area": 8, # Assumed to be PRT-N TS
    "Kitchen": 9, # Assumed to be PRT-N TS
}

logging.basicConfig(level=logging.INFO)

# Create a HeatmiserUH1 connection
HeatmiserUH1 = connection.HeatmiserUH1(IP_ADDRESS, PORT)

for name, id_number in TSTATS.items():
    tstat = heatmiser.HeatmiserThermostat(1, "prt", HeatmiserUH1)
    dcb_pretty = pprint.pformat(tstat.dcb, indent=4)
    logging.info(f"Thermostat {id_number} {name}\n{dcb_pretty}")
INFO:root:Opening serial port.
INFO:root:Getting latest data from DCB....
INFO:root:CRC is correct
INFO:root:Thermostat 1 Cloakroom
{   0: {'label': 'High 8 bit', 'value': 0},
    1: {'label': 'Low 8 bit', 'value': 64},
    2: {'label': 'Vendor ID', 'value': 0},
    3: {'label': '0-6 bits = Version, bit 7 = floor limit state.', 'value': 15},
    4: {'label': 'Model', 'value': 2},
    5: {'label': 'Temperature format', 'value': 0},
    6: {'label': 'Switch Differential', 'value': 2},
    7: {'label': 'Frost Protection Mode', 'value': 1},
    8: {'label': 'Calibration - high 8 bit', 'value': 0},
    9: {'label': 'Calibration - low 8 bit', 'value': 0},
    10: {'label': 'Output delay', 'value': 0},
    11: {'label': 'Address', 'value': 1},
    12: {'label': 'Up down key limit', 'value': 0},
    13: {'label': 'Sensor Selection', 'value': 0},
    14: {'label': 'Optimum start', 'value': 0},
    15: {'label': 'Rate of change', 'value': 20},
    16: {'label': 'Program mode', 'value': 0},
    17: {'label': 'Frost protect temp', 'value': 15},
    18: {'label': 'Set room temp', 'value': 21},
    19: {'label': 'Floor max limit', 'value': 28},
    20: {'label': 'Floor max limit enable/disable', 'value': 1},
    21: {'label': 'On/off', 'value': 1},
    22: {'label': 'Key lock', 'value': 0},
    23: {'label': 'Run mode', 'value': 0},
    24: {'label': 'Holiday hours', 'value': 0},
    25: {'label': 'Holiday hours', 'value': 0},
    26: {'label': 'Temp hold mins', 'value': 0},
    27: {'label': 'Temp hold mins', 'value': 0},
    28: {'label': 'Remote air temp', 'value': 255},
    29: {'label': 'Remote air temp', 'value': 255},
    30: {'label': 'Floor temp', 'value': 255},
    31: {'label': 'Floor temp', 'value': 255},
    32: {'label': 'Built in air temp', 'value': 0},
    33: {'label': 'Built in air temp', 'value': 201},
    34: {'label': 'Error code', 'value': 0},
    35: {'label': 'Current state', 'value': 0},
    36: {'label': 'Week 1~7', 'value': 4},
    37: {'label': 'Hour', 'value': 16},
    38: {'label': 'Min', 'value': 22},
    39: {'label': 'Sec', 'value': 18},
    40: {'label': 'Weekday', 'value': 24},
    41: {'label': 'Weekday', 'value': 0},
    42: {'label': 'Weekday', 'value': 19},
    43: {'label': 'Weekday', 'value': 24},
    44: {'label': 'Weekday', 'value': 0},
    45: {'label': 'Weekday', 'value': 5},
    46: {'label': 'Weekday', 'value': 24},
    47: {'label': 'Weekday', 'value': 0},
    48: {'label': 'Weekday', 'value': 19},
    49: {'label': 'Weekday', 'value': 24},
    50: {'label': 'Weekday', 'value': 0},
    51: {'label': 'Weekday', 'value': 5},
    52: {'label': 'Weekend', 'value': 5},
    53: {'label': 'Weekend', 'value': 30},
    54: {'label': 'Weekend', 'value': 23},
    55: {'label': 'Weekend', 'value': 22},
    56: {'label': 'Weekend', 'value': 0},
    57: {'label': 'Weekend', 'value': 20},
    58: {'label': 'Weekend', 'value': 24},
    59: {'label': 'Weekend', 'value': 0},
    60: {'label': 'Weekend', 'value': 16},
    61: {'label': 'Weekend', 'value': 24},
    62: {'label': 'Weekend', 'value': 0},
    63: {'label': 'Weekend', 'value': 16}}
INFO:root:Getting latest data from DCB....
INFO:root:CRC is correct
INFO:root:Thermostat 2 Utility
{   0: {'label': 'High 8 bit', 'value': 0},
    1: {'label': 'Low 8 bit', 'value': 64},
    2: {'label': 'Vendor ID', 'value': 0},
    3: {'label': '0-6 bits = Version, bit 7 = floor limit state.', 'value': 15},
    4: {'label': 'Model', 'value': 2},
    5: {'label': 'Temperature format', 'value': 0},
    6: {'label': 'Switch Differential', 'value': 2},
    7: {'label': 'Frost Protection Mode', 'value': 1},
    8: {'label': 'Calibration - high 8 bit', 'value': 0},
    9: {'label': 'Calibration - low 8 bit', 'value': 0},
    10: {'label': 'Output delay', 'value': 0},
    11: {'label': 'Address', 'value': 1},
    12: {'label': 'Up down key limit', 'value': 0},
    13: {'label': 'Sensor Selection', 'value': 0},
    14: {'label': 'Optimum start', 'value': 0},
    15: {'label': 'Rate of change', 'value': 20},
    16: {'label': 'Program mode', 'value': 0},
    17: {'label': 'Frost protect temp', 'value': 15},
    18: {'label': 'Set room temp', 'value': 21},
    19: {'label': 'Floor max limit', 'value': 28},
    20: {'label': 'Floor max limit enable/disable', 'value': 1},
    21: {'label': 'On/off', 'value': 1},
    22: {'label': 'Key lock', 'value': 0},
    23: {'label': 'Run mode', 'value': 0},
    24: {'label': 'Holiday hours', 'value': 0},
    25: {'label': 'Holiday hours', 'value': 0},
    26: {'label': 'Temp hold mins', 'value': 0},
    27: {'label': 'Temp hold mins', 'value': 0},
    28: {'label': 'Remote air temp', 'value': 255},
    29: {'label': 'Remote air temp', 'value': 255},
    30: {'label': 'Floor temp', 'value': 255},
    31: {'label': 'Floor temp', 'value': 255},
    32: {'label': 'Built in air temp', 'value': 0},
    33: {'label': 'Built in air temp', 'value': 201},
    34: {'label': 'Error code', 'value': 0},
    35: {'label': 'Current state', 'value': 0},
    36: {'label': 'Week 1~7', 'value': 4},
    37: {'label': 'Hour', 'value': 16},
    38: {'label': 'Min', 'value': 22},
    39: {'label': 'Sec', 'value': 21},
    40: {'label': 'Weekday', 'value': 24},
    41: {'label': 'Weekday', 'value': 0},
    42: {'label': 'Weekday', 'value': 19},
    43: {'label': 'Weekday', 'value': 24},
    44: {'label': 'Weekday', 'value': 0},
    45: {'label': 'Weekday', 'value': 5},
    46: {'label': 'Weekday', 'value': 24},
    47: {'label': 'Weekday', 'value': 0},
    48: {'label': 'Weekday', 'value': 19},
    49: {'label': 'Weekday', 'value': 24},
    50: {'label': 'Weekday', 'value': 0},
    51: {'label': 'Weekday', 'value': 5},
    52: {'label': 'Weekend', 'value': 5},
    53: {'label': 'Weekend', 'value': 30},
    54: {'label': 'Weekend', 'value': 23},
    55: {'label': 'Weekend', 'value': 22},
    56: {'label': 'Weekend', 'value': 0},
    57: {'label': 'Weekend', 'value': 20},
    58: {'label': 'Weekend', 'value': 24},
    59: {'label': 'Weekend', 'value': 0},
    60: {'label': 'Weekend', 'value': 16},
    61: {'label': 'Weekend', 'value': 24},
    62: {'label': 'Weekend', 'value': 0},
    63: {'label': 'Weekend', 'value': 16}}
INFO:root:Getting latest data from DCB....
INFO:root:CRC is correct
INFO:root:Thermostat 3 Pool
{   0: {'label': 'High 8 bit', 'value': 0},
    1: {'label': 'Low 8 bit', 'value': 64},
    2: {'label': 'Vendor ID', 'value': 0},
    3: {'label': '0-6 bits = Version, bit 7 = floor limit state.', 'value': 15},
    4: {'label': 'Model', 'value': 2},
    5: {'label': 'Temperature format', 'value': 0},
    6: {'label': 'Switch Differential', 'value': 2},
    7: {'label': 'Frost Protection Mode', 'value': 1},
    8: {'label': 'Calibration - high 8 bit', 'value': 0},
    9: {'label': 'Calibration - low 8 bit', 'value': 0},
    10: {'label': 'Output delay', 'value': 0},
    11: {'label': 'Address', 'value': 1},
    12: {'label': 'Up down key limit', 'value': 0},
    13: {'label': 'Sensor Selection', 'value': 0},
    14: {'label': 'Optimum start', 'value': 0},
    15: {'label': 'Rate of change', 'value': 20},
    16: {'label': 'Program mode', 'value': 0},
    17: {'label': 'Frost protect temp', 'value': 15},
    18: {'label': 'Set room temp', 'value': 21},
    19: {'label': 'Floor max limit', 'value': 28},
    20: {'label': 'Floor max limit enable/disable', 'value': 1},
    21: {'label': 'On/off', 'value': 1},
    22: {'label': 'Key lock', 'value': 0},
    23: {'label': 'Run mode', 'value': 0},
    24: {'label': 'Holiday hours', 'value': 0},
    25: {'label': 'Holiday hours', 'value': 0},
    26: {'label': 'Temp hold mins', 'value': 0},
    27: {'label': 'Temp hold mins', 'value': 0},
    28: {'label': 'Remote air temp', 'value': 255},
    29: {'label': 'Remote air temp', 'value': 255},
    30: {'label': 'Floor temp', 'value': 255},
    31: {'label': 'Floor temp', 'value': 255},
    32: {'label': 'Built in air temp', 'value': 0},
    33: {'label': 'Built in air temp', 'value': 201},
    34: {'label': 'Error code', 'value': 0},
    35: {'label': 'Current state', 'value': 0},
    36: {'label': 'Week 1~7', 'value': 4},
    37: {'label': 'Hour', 'value': 16},
    38: {'label': 'Min', 'value': 22},
    39: {'label': 'Sec', 'value': 24},
    40: {'label': 'Weekday', 'value': 24},
    41: {'label': 'Weekday', 'value': 0},
    42: {'label': 'Weekday', 'value': 19},
    43: {'label': 'Weekday', 'value': 24},
    44: {'label': 'Weekday', 'value': 0},
    45: {'label': 'Weekday', 'value': 5},
    46: {'label': 'Weekday', 'value': 24},
    47: {'label': 'Weekday', 'value': 0},
    48: {'label': 'Weekday', 'value': 19},
    49: {'label': 'Weekday', 'value': 24},
    50: {'label': 'Weekday', 'value': 0},
    51: {'label': 'Weekday', 'value': 5},
    52: {'label': 'Weekend', 'value': 5},
    53: {'label': 'Weekend', 'value': 30},
    54: {'label': 'Weekend', 'value': 23},
    55: {'label': 'Weekend', 'value': 22},
    56: {'label': 'Weekend', 'value': 0},
    57: {'label': 'Weekend', 'value': 20},
    58: {'label': 'Weekend', 'value': 24},
    59: {'label': 'Weekend', 'value': 0},
    60: {'label': 'Weekend', 'value': 16},
    61: {'label': 'Weekend', 'value': 24},
    62: {'label': 'Weekend', 'value': 0},
    63: {'label': 'Weekend', 'value': 16}}
INFO:root:Getting latest data from DCB....
INFO:root:CRC is correct
INFO:root:Thermostat 4 Hallway
{   0: {'label': 'High 8 bit', 'value': 0},
    1: {'label': 'Low 8 bit', 'value': 64},
    2: {'label': 'Vendor ID', 'value': 0},
    3: {'label': '0-6 bits = Version, bit 7 = floor limit state.', 'value': 15},
    4: {'label': 'Model', 'value': 2},
    5: {'label': 'Temperature format', 'value': 0},
    6: {'label': 'Switch Differential', 'value': 2},
    7: {'label': 'Frost Protection Mode', 'value': 1},
    8: {'label': 'Calibration - high 8 bit', 'value': 0},
    9: {'label': 'Calibration - low 8 bit', 'value': 0},
    10: {'label': 'Output delay', 'value': 0},
    11: {'label': 'Address', 'value': 1},
    12: {'label': 'Up down key limit', 'value': 0},
    13: {'label': 'Sensor Selection', 'value': 0},
    14: {'label': 'Optimum start', 'value': 0},
    15: {'label': 'Rate of change', 'value': 20},
    16: {'label': 'Program mode', 'value': 0},
    17: {'label': 'Frost protect temp', 'value': 15},
    18: {'label': 'Set room temp', 'value': 21},
    19: {'label': 'Floor max limit', 'value': 28},
    20: {'label': 'Floor max limit enable/disable', 'value': 1},
    21: {'label': 'On/off', 'value': 1},
    22: {'label': 'Key lock', 'value': 0},
    23: {'label': 'Run mode', 'value': 0},
    24: {'label': 'Holiday hours', 'value': 0},
    25: {'label': 'Holiday hours', 'value': 0},
    26: {'label': 'Temp hold mins', 'value': 0},
    27: {'label': 'Temp hold mins', 'value': 0},
    28: {'label': 'Remote air temp', 'value': 255},
    29: {'label': 'Remote air temp', 'value': 255},
    30: {'label': 'Floor temp', 'value': 255},
    31: {'label': 'Floor temp', 'value': 255},
    32: {'label': 'Built in air temp', 'value': 0},
    33: {'label': 'Built in air temp', 'value': 201},
    34: {'label': 'Error code', 'value': 0},
    35: {'label': 'Current state', 'value': 0},
    36: {'label': 'Week 1~7', 'value': 4},
    37: {'label': 'Hour', 'value': 16},
    38: {'label': 'Min', 'value': 22},
    39: {'label': 'Sec', 'value': 27},
    40: {'label': 'Weekday', 'value': 24},
    41: {'label': 'Weekday', 'value': 0},
    42: {'label': 'Weekday', 'value': 19},
    43: {'label': 'Weekday', 'value': 24},
    44: {'label': 'Weekday', 'value': 0},
    45: {'label': 'Weekday', 'value': 5},
    46: {'label': 'Weekday', 'value': 24},
    47: {'label': 'Weekday', 'value': 0},
    48: {'label': 'Weekday', 'value': 19},
    49: {'label': 'Weekday', 'value': 24},
    50: {'label': 'Weekday', 'value': 0},
    51: {'label': 'Weekday', 'value': 5},
    52: {'label': 'Weekend', 'value': 5},
    53: {'label': 'Weekend', 'value': 30},
    54: {'label': 'Weekend', 'value': 23},
    55: {'label': 'Weekend', 'value': 22},
    56: {'label': 'Weekend', 'value': 0},
    57: {'label': 'Weekend', 'value': 20},
    58: {'label': 'Weekend', 'value': 24},
    59: {'label': 'Weekend', 'value': 0},
    60: {'label': 'Weekend', 'value': 16},
    61: {'label': 'Weekend', 'value': 24},
    62: {'label': 'Weekend', 'value': 0},
    63: {'label': 'Weekend', 'value': 16}}
INFO:root:Getting latest data from DCB....
INFO:root:CRC is correct
INFO:root:Thermostat 5 Study
{   0: {'label': 'High 8 bit', 'value': 0},
    1: {'label': 'Low 8 bit', 'value': 64},
    2: {'label': 'Vendor ID', 'value': 0},
    3: {'label': '0-6 bits = Version, bit 7 = floor limit state.', 'value': 15},
    4: {'label': 'Model', 'value': 2},
    5: {'label': 'Temperature format', 'value': 0},
    6: {'label': 'Switch Differential', 'value': 2},
    7: {'label': 'Frost Protection Mode', 'value': 1},
    8: {'label': 'Calibration - high 8 bit', 'value': 0},
    9: {'label': 'Calibration - low 8 bit', 'value': 0},
    10: {'label': 'Output delay', 'value': 0},
    11: {'label': 'Address', 'value': 1},
    12: {'label': 'Up down key limit', 'value': 0},
    13: {'label': 'Sensor Selection', 'value': 0},
    14: {'label': 'Optimum start', 'value': 0},
    15: {'label': 'Rate of change', 'value': 20},
    16: {'label': 'Program mode', 'value': 0},
    17: {'label': 'Frost protect temp', 'value': 15},
    18: {'label': 'Set room temp', 'value': 21},
    19: {'label': 'Floor max limit', 'value': 28},
    20: {'label': 'Floor max limit enable/disable', 'value': 1},
    21: {'label': 'On/off', 'value': 1},
    22: {'label': 'Key lock', 'value': 0},
    23: {'label': 'Run mode', 'value': 0},
    24: {'label': 'Holiday hours', 'value': 0},
    25: {'label': 'Holiday hours', 'value': 0},
    26: {'label': 'Temp hold mins', 'value': 0},
    27: {'label': 'Temp hold mins', 'value': 0},
    28: {'label': 'Remote air temp', 'value': 255},
    29: {'label': 'Remote air temp', 'value': 255},
    30: {'label': 'Floor temp', 'value': 255},
    31: {'label': 'Floor temp', 'value': 255},
    32: {'label': 'Built in air temp', 'value': 0},
    33: {'label': 'Built in air temp', 'value': 201},
    34: {'label': 'Error code', 'value': 0},
    35: {'label': 'Current state', 'value': 0},
    36: {'label': 'Week 1~7', 'value': 4},
    37: {'label': 'Hour', 'value': 16},
    38: {'label': 'Min', 'value': 22},
    39: {'label': 'Sec', 'value': 30},
    40: {'label': 'Weekday', 'value': 24},
    41: {'label': 'Weekday', 'value': 0},
    42: {'label': 'Weekday', 'value': 19},
    43: {'label': 'Weekday', 'value': 24},
    44: {'label': 'Weekday', 'value': 0},
    45: {'label': 'Weekday', 'value': 5},
    46: {'label': 'Weekday', 'value': 24},
    47: {'label': 'Weekday', 'value': 0},
    48: {'label': 'Weekday', 'value': 19},
    49: {'label': 'Weekday', 'value': 24},
    50: {'label': 'Weekday', 'value': 0},
    51: {'label': 'Weekday', 'value': 5},
    52: {'label': 'Weekend', 'value': 5},
    53: {'label': 'Weekend', 'value': 30},
    54: {'label': 'Weekend', 'value': 23},
    55: {'label': 'Weekend', 'value': 22},
    56: {'label': 'Weekend', 'value': 0},
    57: {'label': 'Weekend', 'value': 20},
    58: {'label': 'Weekend', 'value': 24},
    59: {'label': 'Weekend', 'value': 0},
    60: {'label': 'Weekend', 'value': 16},
    61: {'label': 'Weekend', 'value': 24},
    62: {'label': 'Weekend', 'value': 0},
    63: {'label': 'Weekend', 'value': 16}}
INFO:root:Getting latest data from DCB....
INFO:root:CRC is correct
INFO:root:Thermostat 6 Sitting Room
{   0: {'label': 'High 8 bit', 'value': 0},
    1: {'label': 'Low 8 bit', 'value': 64},
    2: {'label': 'Vendor ID', 'value': 0},
    3: {'label': '0-6 bits = Version, bit 7 = floor limit state.', 'value': 15},
    4: {'label': 'Model', 'value': 2},
    5: {'label': 'Temperature format', 'value': 0},
    6: {'label': 'Switch Differential', 'value': 2},
    7: {'label': 'Frost Protection Mode', 'value': 1},
    8: {'label': 'Calibration - high 8 bit', 'value': 0},
    9: {'label': 'Calibration - low 8 bit', 'value': 0},
    10: {'label': 'Output delay', 'value': 0},
    11: {'label': 'Address', 'value': 1},
    12: {'label': 'Up down key limit', 'value': 0},
    13: {'label': 'Sensor Selection', 'value': 0},
    14: {'label': 'Optimum start', 'value': 0},
    15: {'label': 'Rate of change', 'value': 20},
    16: {'label': 'Program mode', 'value': 0},
    17: {'label': 'Frost protect temp', 'value': 15},
    18: {'label': 'Set room temp', 'value': 21},
    19: {'label': 'Floor max limit', 'value': 28},
    20: {'label': 'Floor max limit enable/disable', 'value': 1},
    21: {'label': 'On/off', 'value': 1},
    22: {'label': 'Key lock', 'value': 0},
    23: {'label': 'Run mode', 'value': 0},
    24: {'label': 'Holiday hours', 'value': 0},
    25: {'label': 'Holiday hours', 'value': 0},
    26: {'label': 'Temp hold mins', 'value': 0},
    27: {'label': 'Temp hold mins', 'value': 0},
    28: {'label': 'Remote air temp', 'value': 255},
    29: {'label': 'Remote air temp', 'value': 255},
    30: {'label': 'Floor temp', 'value': 255},
    31: {'label': 'Floor temp', 'value': 255},
    32: {'label': 'Built in air temp', 'value': 0},
    33: {'label': 'Built in air temp', 'value': 201},
    34: {'label': 'Error code', 'value': 0},
    35: {'label': 'Current state', 'value': 0},
    36: {'label': 'Week 1~7', 'value': 4},
    37: {'label': 'Hour', 'value': 16},
    38: {'label': 'Min', 'value': 22},
    39: {'label': 'Sec', 'value': 33},
    40: {'label': 'Weekday', 'value': 24},
    41: {'label': 'Weekday', 'value': 0},
    42: {'label': 'Weekday', 'value': 19},
    43: {'label': 'Weekday', 'value': 24},
    44: {'label': 'Weekday', 'value': 0},
    45: {'label': 'Weekday', 'value': 5},
    46: {'label': 'Weekday', 'value': 24},
    47: {'label': 'Weekday', 'value': 0},
    48: {'label': 'Weekday', 'value': 19},
    49: {'label': 'Weekday', 'value': 24},
    50: {'label': 'Weekday', 'value': 0},
    51: {'label': 'Weekday', 'value': 5},
    52: {'label': 'Weekend', 'value': 5},
    53: {'label': 'Weekend', 'value': 30},
    54: {'label': 'Weekend', 'value': 23},
    55: {'label': 'Weekend', 'value': 22},
    56: {'label': 'Weekend', 'value': 0},
    57: {'label': 'Weekend', 'value': 20},
    58: {'label': 'Weekend', 'value': 24},
    59: {'label': 'Weekend', 'value': 0},
    60: {'label': 'Weekend', 'value': 16},
    61: {'label': 'Weekend', 'value': 24},
    62: {'label': 'Weekend', 'value': 0},
    63: {'label': 'Weekend', 'value': 16}}
INFO:root:Getting latest data from DCB....
INFO:root:CRC is correct
INFO:root:Thermostat 7 Living Room
{   0: {'label': 'High 8 bit', 'value': 0},
    1: {'label': 'Low 8 bit', 'value': 64},
    2: {'label': 'Vendor ID', 'value': 0},
    3: {'label': '0-6 bits = Version, bit 7 = floor limit state.', 'value': 15},
    4: {'label': 'Model', 'value': 2},
    5: {'label': 'Temperature format', 'value': 0},
    6: {'label': 'Switch Differential', 'value': 2},
    7: {'label': 'Frost Protection Mode', 'value': 1},
    8: {'label': 'Calibration - high 8 bit', 'value': 0},
    9: {'label': 'Calibration - low 8 bit', 'value': 0},
    10: {'label': 'Output delay', 'value': 0},
    11: {'label': 'Address', 'value': 1},
    12: {'label': 'Up down key limit', 'value': 0},
    13: {'label': 'Sensor Selection', 'value': 0},
    14: {'label': 'Optimum start', 'value': 0},
    15: {'label': 'Rate of change', 'value': 20},
    16: {'label': 'Program mode', 'value': 0},
    17: {'label': 'Frost protect temp', 'value': 15},
    18: {'label': 'Set room temp', 'value': 21},
    19: {'label': 'Floor max limit', 'value': 28},
    20: {'label': 'Floor max limit enable/disable', 'value': 1},
    21: {'label': 'On/off', 'value': 1},
    22: {'label': 'Key lock', 'value': 0},
    23: {'label': 'Run mode', 'value': 0},
    24: {'label': 'Holiday hours', 'value': 0},
    25: {'label': 'Holiday hours', 'value': 0},
    26: {'label': 'Temp hold mins', 'value': 0},
    27: {'label': 'Temp hold mins', 'value': 0},
    28: {'label': 'Remote air temp', 'value': 255},
    29: {'label': 'Remote air temp', 'value': 255},
    30: {'label': 'Floor temp', 'value': 255},
    31: {'label': 'Floor temp', 'value': 255},
    32: {'label': 'Built in air temp', 'value': 0},
    33: {'label': 'Built in air temp', 'value': 201},
    34: {'label': 'Error code', 'value': 0},
    35: {'label': 'Current state', 'value': 0},
    36: {'label': 'Week 1~7', 'value': 4},
    37: {'label': 'Hour', 'value': 16},
    38: {'label': 'Min', 'value': 22},
    39: {'label': 'Sec', 'value': 36},
    40: {'label': 'Weekday', 'value': 24},
    41: {'label': 'Weekday', 'value': 0},
    42: {'label': 'Weekday', 'value': 19},
    43: {'label': 'Weekday', 'value': 24},
    44: {'label': 'Weekday', 'value': 0},
    45: {'label': 'Weekday', 'value': 5},
    46: {'label': 'Weekday', 'value': 24},
    47: {'label': 'Weekday', 'value': 0},
    48: {'label': 'Weekday', 'value': 19},
    49: {'label': 'Weekday', 'value': 24},
    50: {'label': 'Weekday', 'value': 0},
    51: {'label': 'Weekday', 'value': 5},
    52: {'label': 'Weekend', 'value': 5},
    53: {'label': 'Weekend', 'value': 30},
    54: {'label': 'Weekend', 'value': 23},
    55: {'label': 'Weekend', 'value': 22},
    56: {'label': 'Weekend', 'value': 0},
    57: {'label': 'Weekend', 'value': 20},
    58: {'label': 'Weekend', 'value': 24},
    59: {'label': 'Weekend', 'value': 0},
    60: {'label': 'Weekend', 'value': 16},
    61: {'label': 'Weekend', 'value': 24},
    62: {'label': 'Weekend', 'value': 0},
    63: {'label': 'Weekend', 'value': 16}}
INFO:root:Getting latest data from DCB....
INFO:root:CRC is correct
INFO:root:Thermostat 8 Dining Area
{   0: {'label': 'High 8 bit', 'value': 0},
    1: {'label': 'Low 8 bit', 'value': 64},
    2: {'label': 'Vendor ID', 'value': 0},
    3: {'label': '0-6 bits = Version, bit 7 = floor limit state.', 'value': 15},
    4: {'label': 'Model', 'value': 2},
    5: {'label': 'Temperature format', 'value': 0},
    6: {'label': 'Switch Differential', 'value': 2},
    7: {'label': 'Frost Protection Mode', 'value': 1},
    8: {'label': 'Calibration - high 8 bit', 'value': 0},
    9: {'label': 'Calibration - low 8 bit', 'value': 0},
    10: {'label': 'Output delay', 'value': 0},
    11: {'label': 'Address', 'value': 1},
    12: {'label': 'Up down key limit', 'value': 0},
    13: {'label': 'Sensor Selection', 'value': 0},
    14: {'label': 'Optimum start', 'value': 0},
    15: {'label': 'Rate of change', 'value': 20},
    16: {'label': 'Program mode', 'value': 0},
    17: {'label': 'Frost protect temp', 'value': 15},
    18: {'label': 'Set room temp', 'value': 21},
    19: {'label': 'Floor max limit', 'value': 28},
    20: {'label': 'Floor max limit enable/disable', 'value': 1},
    21: {'label': 'On/off', 'value': 1},
    22: {'label': 'Key lock', 'value': 0},
    23: {'label': 'Run mode', 'value': 0},
    24: {'label': 'Holiday hours', 'value': 0},
    25: {'label': 'Holiday hours', 'value': 0},
    26: {'label': 'Temp hold mins', 'value': 0},
    27: {'label': 'Temp hold mins', 'value': 0},
    28: {'label': 'Remote air temp', 'value': 255},
    29: {'label': 'Remote air temp', 'value': 255},
    30: {'label': 'Floor temp', 'value': 255},
    31: {'label': 'Floor temp', 'value': 255},
    32: {'label': 'Built in air temp', 'value': 0},
    33: {'label': 'Built in air temp', 'value': 201},
    34: {'label': 'Error code', 'value': 0},
    35: {'label': 'Current state', 'value': 0},
    36: {'label': 'Week 1~7', 'value': 4},
    37: {'label': 'Hour', 'value': 16},
    38: {'label': 'Min', 'value': 22},
    39: {'label': 'Sec', 'value': 39},
    40: {'label': 'Weekday', 'value': 24},
    41: {'label': 'Weekday', 'value': 0},
    42: {'label': 'Weekday', 'value': 19},
    43: {'label': 'Weekday', 'value': 24},
    44: {'label': 'Weekday', 'value': 0},
    45: {'label': 'Weekday', 'value': 5},
    46: {'label': 'Weekday', 'value': 24},
    47: {'label': 'Weekday', 'value': 0},
    48: {'label': 'Weekday', 'value': 19},
    49: {'label': 'Weekday', 'value': 24},
    50: {'label': 'Weekday', 'value': 0},
    51: {'label': 'Weekday', 'value': 5},
    52: {'label': 'Weekend', 'value': 5},
    53: {'label': 'Weekend', 'value': 30},
    54: {'label': 'Weekend', 'value': 23},
    55: {'label': 'Weekend', 'value': 22},
    56: {'label': 'Weekend', 'value': 0},
    57: {'label': 'Weekend', 'value': 20},
    58: {'label': 'Weekend', 'value': 24},
    59: {'label': 'Weekend', 'value': 0},
    60: {'label': 'Weekend', 'value': 16},
    61: {'label': 'Weekend', 'value': 24},
    62: {'label': 'Weekend', 'value': 0},
    63: {'label': 'Weekend', 'value': 16}}
INFO:root:Getting latest data from DCB....
INFO:root:CRC is correct
INFO:root:Thermostat 9 Kitchen
{   0: {'label': 'High 8 bit', 'value': 0},
    1: {'label': 'Low 8 bit', 'value': 64},
    2: {'label': 'Vendor ID', 'value': 0},
    3: {'label': '0-6 bits = Version, bit 7 = floor limit state.', 'value': 15},
    4: {'label': 'Model', 'value': 2},
    5: {'label': 'Temperature format', 'value': 0},
    6: {'label': 'Switch Differential', 'value': 2},
    7: {'label': 'Frost Protection Mode', 'value': 1},
    8: {'label': 'Calibration - high 8 bit', 'value': 0},
    9: {'label': 'Calibration - low 8 bit', 'value': 0},
    10: {'label': 'Output delay', 'value': 0},
    11: {'label': 'Address', 'value': 1},
    12: {'label': 'Up down key limit', 'value': 0},
    13: {'label': 'Sensor Selection', 'value': 0},
    14: {'label': 'Optimum start', 'value': 0},
    15: {'label': 'Rate of change', 'value': 20},
    16: {'label': 'Program mode', 'value': 0},
    17: {'label': 'Frost protect temp', 'value': 15},
    18: {'label': 'Set room temp', 'value': 21},
    19: {'label': 'Floor max limit', 'value': 28},
    20: {'label': 'Floor max limit enable/disable', 'value': 1},
    21: {'label': 'On/off', 'value': 1},
    22: {'label': 'Key lock', 'value': 0},
    23: {'label': 'Run mode', 'value': 0},
    24: {'label': 'Holiday hours', 'value': 0},
    25: {'label': 'Holiday hours', 'value': 0},
    26: {'label': 'Temp hold mins', 'value': 0},
    27: {'label': 'Temp hold mins', 'value': 0},
    28: {'label': 'Remote air temp', 'value': 255},
    29: {'label': 'Remote air temp', 'value': 255},
    30: {'label': 'Floor temp', 'value': 255},
    31: {'label': 'Floor temp', 'value': 255},
    32: {'label': 'Built in air temp', 'value': 0},
    33: {'label': 'Built in air temp', 'value': 201},
    34: {'label': 'Error code', 'value': 0},
    35: {'label': 'Current state', 'value': 0},
    36: {'label': 'Week 1~7', 'value': 4},
    37: {'label': 'Hour', 'value': 16},
    38: {'label': 'Min', 'value': 22},
    39: {'label': 'Sec', 'value': 42},
    40: {'label': 'Weekday', 'value': 24},
    41: {'label': 'Weekday', 'value': 0},
    42: {'label': 'Weekday', 'value': 19},
    43: {'label': 'Weekday', 'value': 24},
    44: {'label': 'Weekday', 'value': 0},
    45: {'label': 'Weekday', 'value': 5},
    46: {'label': 'Weekday', 'value': 24},
    47: {'label': 'Weekday', 'value': 0},
    48: {'label': 'Weekday', 'value': 19},
    49: {'label': 'Weekday', 'value': 24},
    50: {'label': 'Weekday', 'value': 0},
    51: {'label': 'Weekday', 'value': 5},
    52: {'label': 'Weekend', 'value': 5},
    53: {'label': 'Weekend', 'value': 30},
    54: {'label': 'Weekend', 'value': 23},
    55: {'label': 'Weekend', 'value': 22},
    56: {'label': 'Weekend', 'value': 0},
    57: {'label': 'Weekend', 'value': 20},
    58: {'label': 'Weekend', 'value': 24},
    59: {'label': 'Weekend', 'value': 0},
    60: {'label': 'Weekend', 'value': 16},
    61: {'label': 'Weekend', 'value': 24},
    62: {'label': 'Weekend', 'value': 0},
    63: {'label': 'Weekend', 'value': 16}}
INFO:root:Closing serial port.
andylockran commented 8 months ago

This is perfect; thanks so much :D

andylockran commented 8 months ago

Just spotted a potential minor bug: for name, id_number in TSTATS.items(): tstat = heatmiser.HeatmiserThermostat(id_number, "prt", HeatmiserUH1) dcb_pretty = pprint.pformat(tstat.dcb, indent=4) logging.info(f"Thermostat {id_number} {name}\n{dcb_pretty}")

On line 2, the index '1' needs changing to id_number otherwise it's the same printout for all thermostats.
Azelphur commented 8 months ago

Whoops, good catch, here's the corrected version.

As an aside, if you happen to be in the home assistant discord, feel free to drop me a DM. I'm on there as Azelphur. Since I'm going to be running this integration for the forseeable future I am of course happy to help out with things. I'd be really interested in seeing if new features could be added to control more stuff on the thermostats.

from heatmiserv3 import heatmiser, connection
import pprint
import logging

IP_ADDRESS = "192.168.1.187"
PORT = "4196"
TSTATS = {
    # I checked the cloakroom and utility thermostats
    # and got their model numbers from the back of the
    # wall plates so they should be correct. The rest
    # of the units I assume to be the same PRT-N TS
    # but I haven't pulled them off the wall to check
    "Cloakroom": 1, # PRT-N TS (Checked)
    "Utility": 2, # PRT/HW-N TS (Checked)
    "Pool": 3, # Assumed to be PRT-N TS
    "Hallway": 4, # Assumed to be PRT-N TS
    "Study": 5, # Assumed to be PRT-N TS
    "Sitting Room": 6, # Assumed to be PRT-N TS
    "Living Room": 7, # Assumed to be PRT-N TS
    "Dining Area": 8, # Assumed to be PRT-N TS
    "Kitchen": 9, # Assumed to be PRT-N TS
}

logging.basicConfig(level=logging.INFO)

# Create a HeatmiserUH1 connection
HeatmiserUH1 = connection.HeatmiserUH1(IP_ADDRESS, PORT)

for name, id_number in TSTATS.items():
    tstat = heatmiser.HeatmiserThermostat(id_number, "prt", HeatmiserUH1)
    dcb_pretty = pprint.pformat(tstat.dcb, indent=4)
    logging.info(f"Thermostat {id_number} {name}\n{dcb_pretty}")
INFO:root:SerialPortResponse: None
INFO:root:Opening serial port.
INFO:root:Getting latest data from DCB....
INFO:root:CRC is correct
INFO:root:Thermostat 1 Cloakroom
{   0: {'label': 'High 8 bit', 'value': 0},
    1: {'label': 'Low 8 bit', 'value': 64},
    2: {'label': 'Vendor ID', 'value': 0},
    3: {'label': '0-6 bits = Version, bit 7 = floor limit state.', 'value': 15},
    4: {'label': 'Model', 'value': 2},
    5: {'label': 'Temperature format', 'value': 0},
    6: {'label': 'Switch Differential', 'value': 2},
    7: {'label': 'Frost Protection Mode', 'value': 1},
    8: {'label': 'Calibration - high 8 bit', 'value': 0},
    9: {'label': 'Calibration - low 8 bit', 'value': 0},
    10: {'label': 'Output delay', 'value': 0},
    11: {'label': 'Address', 'value': 1},
    12: {'label': 'Up down key limit', 'value': 0},
    13: {'label': 'Sensor Selection', 'value': 0},
    14: {'label': 'Optimum start', 'value': 0},
    15: {'label': 'Rate of change', 'value': 20},
    16: {'label': 'Program mode', 'value': 0},
    17: {'label': 'Frost protect temp', 'value': 15},
    18: {'label': 'Set room temp', 'value': 21},
    19: {'label': 'Floor max limit', 'value': 28},
    20: {'label': 'Floor max limit enable/disable', 'value': 1},
    21: {'label': 'On/off', 'value': 1},
    22: {'label': 'Key lock', 'value': 0},
    23: {'label': 'Run mode', 'value': 0},
    24: {'label': 'Holiday hours', 'value': 0},
    25: {'label': 'Holiday hours', 'value': 0},
    26: {'label': 'Temp hold mins', 'value': 0},
    27: {'label': 'Temp hold mins', 'value': 0},
    28: {'label': 'Remote air temp', 'value': 255},
    29: {'label': 'Remote air temp', 'value': 255},
    30: {'label': 'Floor temp', 'value': 255},
    31: {'label': 'Floor temp', 'value': 255},
    32: {'label': 'Built in air temp', 'value': 0},
    33: {'label': 'Built in air temp', 'value': 204},
    34: {'label': 'Error code', 'value': 0},
    35: {'label': 'Current state', 'value': 0},
    36: {'label': 'Week 1~7', 'value': 1},
    37: {'label': 'Hour', 'value': 16},
    38: {'label': 'Min', 'value': 5},
    39: {'label': 'Sec', 'value': 15},
    40: {'label': 'Weekday', 'value': 24},
    41: {'label': 'Weekday', 'value': 0},
    42: {'label': 'Weekday', 'value': 19},
    43: {'label': 'Weekday', 'value': 24},
    44: {'label': 'Weekday', 'value': 0},
    45: {'label': 'Weekday', 'value': 5},
    46: {'label': 'Weekday', 'value': 24},
    47: {'label': 'Weekday', 'value': 0},
    48: {'label': 'Weekday', 'value': 19},
    49: {'label': 'Weekday', 'value': 24},
    50: {'label': 'Weekday', 'value': 0},
    51: {'label': 'Weekday', 'value': 5},
    52: {'label': 'Weekend', 'value': 24},
    53: {'label': 'Weekend', 'value': 0},
    54: {'label': 'Weekend', 'value': 23},
    55: {'label': 'Weekend', 'value': 24},
    56: {'label': 'Weekend', 'value': 0},
    57: {'label': 'Weekend', 'value': 20},
    58: {'label': 'Weekend', 'value': 24},
    59: {'label': 'Weekend', 'value': 0},
    60: {'label': 'Weekend', 'value': 16},
    61: {'label': 'Weekend', 'value': 24},
    62: {'label': 'Weekend', 'value': 0},
    63: {'label': 'Weekend', 'value': 16}}
INFO:root:Getting latest data from DCB....
INFO:root:CRC is correct
INFO:root:Thermostat 2 Utility
{   0: {'label': 'High 8 bit', 'value': 0},
    1: {'label': 'Low 8 bit', 'value': 97},
    2: {'label': 'Vendor ID', 'value': 0},
    3: {'label': '0-6 bits = Version, bit 7 = floor limit state.', 'value': 15},
    4: {'label': 'Model', 'value': 4},
    5: {'label': 'Temperature format', 'value': 0},
    6: {'label': 'Switch Differential', 'value': 2},
    7: {'label': 'Frost Protection Mode', 'value': 1},
    8: {'label': 'Calibration - high 8 bit', 'value': 0},
    9: {'label': 'Calibration - low 8 bit', 'value': 0},
    10: {'label': 'Output delay', 'value': 0},
    11: {'label': 'Address', 'value': 2},
    12: {'label': 'Up down key limit', 'value': 0},
    13: {'label': 'Sensor Selection', 'value': 0},
    14: {'label': 'Optimum start', 'value': 0},
    15: {'label': 'Rate of change', 'value': 20},
    16: {'label': 'Program mode', 'value': 0},
    17: {'label': 'Frost protect temp', 'value': 15},
    18: {'label': 'Set room temp', 'value': 5},
    19: {'label': 'Floor max limit', 'value': 28},
    20: {'label': 'Floor max limit enable/disable', 'value': 1},
    21: {'label': 'On/off', 'value': 1},
    22: {'label': 'Key lock', 'value': 0},
    23: {'label': 'Run mode', 'value': 0},
    24: {'label': 'Holiday hours', 'value': 0},
    25: {'label': 'Holiday hours', 'value': 0},
    26: {'label': 'Temp hold mins', 'value': 0},
    27: {'label': 'Temp hold mins', 'value': 0},
    28: {'label': 'Remote air temp', 'value': 255},
    29: {'label': 'Remote air temp', 'value': 255},
    30: {'label': 'Floor temp', 'value': 255},
    31: {'label': 'Floor temp', 'value': 255},
    32: {'label': 'Built in air temp', 'value': 0},
    33: {'label': 'Built in air temp', 'value': 219},
    34: {'label': 'Error code', 'value': 0},
    35: {'label': 'Current state', 'value': 0},
    36: {'label': 'Week 1~7', 'value': 1},
    37: {'label': 'Hour', 'value': 1},
    38: {'label': 'Min', 'value': 18},
    39: {'label': 'Sec', 'value': 0},
    40: {'label': 'Weekday', 'value': 58},
    41: {'label': 'Weekday', 'value': 24},
    42: {'label': 'Weekday', 'value': 0},
    43: {'label': 'Weekday', 'value': 21},
    44: {'label': 'Weekday', 'value': 24},
    45: {'label': 'Weekday', 'value': 0},
    46: {'label': 'Weekday', 'value': 20},
    47: {'label': 'Weekday', 'value': 24},
    48: {'label': 'Weekday', 'value': 0},
    49: {'label': 'Weekday', 'value': 21},
    50: {'label': 'Weekday', 'value': 24},
    51: {'label': 'Weekday', 'value': 0},
    52: {'label': 'Weekend', 'value': 19},
    53: {'label': 'Weekend', 'value': 24},
    54: {'label': 'Weekend', 'value': 0},
    55: {'label': 'Weekend', 'value': 21},
    56: {'label': 'Weekend', 'value': 24},
    57: {'label': 'Weekend', 'value': 0},
    58: {'label': 'Weekend', 'value': 16},
    59: {'label': 'Weekend', 'value': 24},
    60: {'label': 'Weekend', 'value': 0},
    61: {'label': 'Weekend', 'value': 16},
    62: {'label': 'Weekend', 'value': 24},
    63: {'label': 'Weekend', 'value': 0}}
INFO:root:Getting latest data from DCB....
INFO:root:CRC is correct
INFO:root:Thermostat 3 Pool
{   0: {'label': 'High 8 bit', 'value': 0},
    1: {'label': 'Low 8 bit', 'value': 64},
    2: {'label': 'Vendor ID', 'value': 0},
    3: {'label': '0-6 bits = Version, bit 7 = floor limit state.', 'value': 15},
    4: {'label': 'Model', 'value': 3},
    5: {'label': 'Temperature format', 'value': 0},
    6: {'label': 'Switch Differential', 'value': 2},
    7: {'label': 'Frost Protection Mode', 'value': 0},
    8: {'label': 'Calibration - high 8 bit', 'value': 0},
    9: {'label': 'Calibration - low 8 bit', 'value': 0},
    10: {'label': 'Output delay', 'value': 3},
    11: {'label': 'Address', 'value': 3},
    12: {'label': 'Up down key limit', 'value': 7},
    13: {'label': 'Sensor Selection', 'value': 2},
    14: {'label': 'Optimum start', 'value': 0},
    15: {'label': 'Rate of change', 'value': 20},
    16: {'label': 'Program mode', 'value': 0},
    17: {'label': 'Frost protect temp', 'value': 9},
    18: {'label': 'Set room temp', 'value': 5},
    19: {'label': 'Floor max limit', 'value': 33},
    20: {'label': 'Floor max limit enable/disable', 'value': 1},
    21: {'label': 'On/off', 'value': 1},
    22: {'label': 'Key lock', 'value': 0},
    23: {'label': 'Run mode', 'value': 0},
    24: {'label': 'Holiday hours', 'value': 0},
    25: {'label': 'Holiday hours', 'value': 0},
    26: {'label': 'Temp hold mins', 'value': 0},
    27: {'label': 'Temp hold mins', 'value': 0},
    28: {'label': 'Remote air temp', 'value': 255},
    29: {'label': 'Remote air temp', 'value': 255},
    30: {'label': 'Floor temp', 'value': 0},
    31: {'label': 'Floor temp', 'value': 176},
    32: {'label': 'Built in air temp', 'value': 255},
    33: {'label': 'Built in air temp', 'value': 255},
    34: {'label': 'Error code', 'value': 0},
    35: {'label': 'Current state', 'value': 0},
    36: {'label': 'Week 1~7', 'value': 1},
    37: {'label': 'Hour', 'value': 17},
    38: {'label': 'Min', 'value': 31},
    39: {'label': 'Sec', 'value': 30},
    40: {'label': 'Weekday', 'value': 24},
    41: {'label': 'Weekday', 'value': 0},
    42: {'label': 'Weekday', 'value': 21},
    43: {'label': 'Weekday', 'value': 24},
    44: {'label': 'Weekday', 'value': 0},
    45: {'label': 'Weekday', 'value': 20},
    46: {'label': 'Weekday', 'value': 24},
    47: {'label': 'Weekday', 'value': 0},
    48: {'label': 'Weekday', 'value': 27},
    49: {'label': 'Weekday', 'value': 24},
    50: {'label': 'Weekday', 'value': 0},
    51: {'label': 'Weekday', 'value': 23},
    52: {'label': 'Weekend', 'value': 24},
    53: {'label': 'Weekend', 'value': 0},
    54: {'label': 'Weekend', 'value': 8},
    55: {'label': 'Weekend', 'value': 24},
    56: {'label': 'Weekend', 'value': 0},
    57: {'label': 'Weekend', 'value': 20},
    58: {'label': 'Weekend', 'value': 24},
    59: {'label': 'Weekend', 'value': 0},
    60: {'label': 'Weekend', 'value': 16},
    61: {'label': 'Weekend', 'value': 24},
    62: {'label': 'Weekend', 'value': 0},
    63: {'label': 'Weekend', 'value': 16}}
INFO:root:Getting latest data from DCB....
INFO:root:CRC is correct
INFO:root:Thermostat 4 Hallway
{   0: {'label': 'High 8 bit', 'value': 0},
    1: {'label': 'Low 8 bit', 'value': 64},
    2: {'label': 'Vendor ID', 'value': 0},
    3: {'label': '0-6 bits = Version, bit 7 = floor limit state.', 'value': 15},
    4: {'label': 'Model', 'value': 2},
    5: {'label': 'Temperature format', 'value': 0},
    6: {'label': 'Switch Differential', 'value': 2},
    7: {'label': 'Frost Protection Mode', 'value': 1},
    8: {'label': 'Calibration - high 8 bit', 'value': 0},
    9: {'label': 'Calibration - low 8 bit', 'value': 0},
    10: {'label': 'Output delay', 'value': 0},
    11: {'label': 'Address', 'value': 4},
    12: {'label': 'Up down key limit', 'value': 0},
    13: {'label': 'Sensor Selection', 'value': 0},
    14: {'label': 'Optimum start', 'value': 0},
    15: {'label': 'Rate of change', 'value': 20},
    16: {'label': 'Program mode', 'value': 0},
    17: {'label': 'Frost protect temp', 'value': 15},
    18: {'label': 'Set room temp', 'value': 21},
    19: {'label': 'Floor max limit', 'value': 28},
    20: {'label': 'Floor max limit enable/disable', 'value': 1},
    21: {'label': 'On/off', 'value': 1},
    22: {'label': 'Key lock', 'value': 0},
    23: {'label': 'Run mode', 'value': 0},
    24: {'label': 'Holiday hours', 'value': 0},
    25: {'label': 'Holiday hours', 'value': 0},
    26: {'label': 'Temp hold mins', 'value': 0},
    27: {'label': 'Temp hold mins', 'value': 0},
    28: {'label': 'Remote air temp', 'value': 255},
    29: {'label': 'Remote air temp', 'value': 255},
    30: {'label': 'Floor temp', 'value': 255},
    31: {'label': 'Floor temp', 'value': 255},
    32: {'label': 'Built in air temp', 'value': 0},
    33: {'label': 'Built in air temp', 'value': 201},
    34: {'label': 'Error code', 'value': 0},
    35: {'label': 'Current state', 'value': 0},
    36: {'label': 'Week 1~7', 'value': 1},
    37: {'label': 'Hour', 'value': 17},
    38: {'label': 'Min', 'value': 56},
    39: {'label': 'Sec', 'value': 25},
    40: {'label': 'Weekday', 'value': 24},
    41: {'label': 'Weekday', 'value': 0},
    42: {'label': 'Weekday', 'value': 21},
    43: {'label': 'Weekday', 'value': 24},
    44: {'label': 'Weekday', 'value': 0},
    45: {'label': 'Weekday', 'value': 19},
    46: {'label': 'Weekday', 'value': 24},
    47: {'label': 'Weekday', 'value': 0},
    48: {'label': 'Weekday', 'value': 23},
    49: {'label': 'Weekday', 'value': 24},
    50: {'label': 'Weekday', 'value': 0},
    51: {'label': 'Weekday', 'value': 5},
    52: {'label': 'Weekend', 'value': 24},
    53: {'label': 'Weekend', 'value': 0},
    54: {'label': 'Weekend', 'value': 21},
    55: {'label': 'Weekend', 'value': 24},
    56: {'label': 'Weekend', 'value': 0},
    57: {'label': 'Weekend', 'value': 20},
    58: {'label': 'Weekend', 'value': 24},
    59: {'label': 'Weekend', 'value': 0},
    60: {'label': 'Weekend', 'value': 16},
    61: {'label': 'Weekend', 'value': 24},
    62: {'label': 'Weekend', 'value': 0},
    63: {'label': 'Weekend', 'value': 5}}
INFO:root:Getting latest data from DCB....
INFO:root:CRC is correct
INFO:root:Thermostat 5 Study
{   0: {'label': 'High 8 bit', 'value': 0},
    1: {'label': 'Low 8 bit', 'value': 64},
    2: {'label': 'Vendor ID', 'value': 0},
    3: {'label': '0-6 bits = Version, bit 7 = floor limit state.', 'value': 15},
    4: {'label': 'Model', 'value': 2},
    5: {'label': 'Temperature format', 'value': 0},
    6: {'label': 'Switch Differential', 'value': 2},
    7: {'label': 'Frost Protection Mode', 'value': 1},
    8: {'label': 'Calibration - high 8 bit', 'value': 0},
    9: {'label': 'Calibration - low 8 bit', 'value': 0},
    10: {'label': 'Output delay', 'value': 0},
    11: {'label': 'Address', 'value': 5},
    12: {'label': 'Up down key limit', 'value': 0},
    13: {'label': 'Sensor Selection', 'value': 0},
    14: {'label': 'Optimum start', 'value': 0},
    15: {'label': 'Rate of change', 'value': 20},
    16: {'label': 'Program mode', 'value': 0},
    17: {'label': 'Frost protect temp', 'value': 15},
    18: {'label': 'Set room temp', 'value': 5},
    19: {'label': 'Floor max limit', 'value': 28},
    20: {'label': 'Floor max limit enable/disable', 'value': 1},
    21: {'label': 'On/off', 'value': 1},
    22: {'label': 'Key lock', 'value': 0},
    23: {'label': 'Run mode', 'value': 0},
    24: {'label': 'Holiday hours', 'value': 0},
    25: {'label': 'Holiday hours', 'value': 0},
    26: {'label': 'Temp hold mins', 'value': 0},
    27: {'label': 'Temp hold mins', 'value': 0},
    28: {'label': 'Remote air temp', 'value': 255},
    29: {'label': 'Remote air temp', 'value': 255},
    30: {'label': 'Floor temp', 'value': 255},
    31: {'label': 'Floor temp', 'value': 255},
    32: {'label': 'Built in air temp', 'value': 0},
    33: {'label': 'Built in air temp', 'value': 201},
    34: {'label': 'Error code', 'value': 0},
    35: {'label': 'Current state', 'value': 0},
    36: {'label': 'Week 1~7', 'value': 1},
    37: {'label': 'Hour', 'value': 18},
    38: {'label': 'Min', 'value': 2},
    39: {'label': 'Sec', 'value': 9},
    40: {'label': 'Weekday', 'value': 24},
    41: {'label': 'Weekday', 'value': 0},
    42: {'label': 'Weekday', 'value': 22},
    43: {'label': 'Weekday', 'value': 24},
    44: {'label': 'Weekday', 'value': 0},
    45: {'label': 'Weekday', 'value': 19},
    46: {'label': 'Weekday', 'value': 24},
    47: {'label': 'Weekday', 'value': 0},
    48: {'label': 'Weekday', 'value': 23},
    49: {'label': 'Weekday', 'value': 24},
    50: {'label': 'Weekday', 'value': 0},
    51: {'label': 'Weekday', 'value': 19},
    52: {'label': 'Weekend', 'value': 24},
    53: {'label': 'Weekend', 'value': 0},
    54: {'label': 'Weekend', 'value': 23},
    55: {'label': 'Weekend', 'value': 24},
    56: {'label': 'Weekend', 'value': 0},
    57: {'label': 'Weekend', 'value': 20},
    58: {'label': 'Weekend', 'value': 24},
    59: {'label': 'Weekend', 'value': 0},
    60: {'label': 'Weekend', 'value': 16},
    61: {'label': 'Weekend', 'value': 24},
    62: {'label': 'Weekend', 'value': 0},
    63: {'label': 'Weekend', 'value': 16}}
INFO:root:Getting latest data from DCB....
INFO:root:CRC is correct
INFO:root:Thermostat 6 Sitting Room
{   0: {'label': 'High 8 bit', 'value': 0},
    1: {'label': 'Low 8 bit', 'value': 64},
    2: {'label': 'Vendor ID', 'value': 0},
    3: {'label': '0-6 bits = Version, bit 7 = floor limit state.', 'value': 15},
    4: {'label': 'Model', 'value': 2},
    5: {'label': 'Temperature format', 'value': 0},
    6: {'label': 'Switch Differential', 'value': 2},
    7: {'label': 'Frost Protection Mode', 'value': 1},
    8: {'label': 'Calibration - high 8 bit', 'value': 0},
    9: {'label': 'Calibration - low 8 bit', 'value': 0},
    10: {'label': 'Output delay', 'value': 0},
    11: {'label': 'Address', 'value': 6},
    12: {'label': 'Up down key limit', 'value': 0},
    13: {'label': 'Sensor Selection', 'value': 0},
    14: {'label': 'Optimum start', 'value': 0},
    15: {'label': 'Rate of change', 'value': 20},
    16: {'label': 'Program mode', 'value': 0},
    17: {'label': 'Frost protect temp', 'value': 15},
    18: {'label': 'Set room temp', 'value': 5},
    19: {'label': 'Floor max limit', 'value': 28},
    20: {'label': 'Floor max limit enable/disable', 'value': 1},
    21: {'label': 'On/off', 'value': 1},
    22: {'label': 'Key lock', 'value': 0},
    23: {'label': 'Run mode', 'value': 0},
    24: {'label': 'Holiday hours', 'value': 0},
    25: {'label': 'Holiday hours', 'value': 0},
    26: {'label': 'Temp hold mins', 'value': 0},
    27: {'label': 'Temp hold mins', 'value': 0},
    28: {'label': 'Remote air temp', 'value': 255},
    29: {'label': 'Remote air temp', 'value': 255},
    30: {'label': 'Floor temp', 'value': 255},
    31: {'label': 'Floor temp', 'value': 255},
    32: {'label': 'Built in air temp', 'value': 0},
    33: {'label': 'Built in air temp', 'value': 187},
    34: {'label': 'Error code', 'value': 0},
    35: {'label': 'Current state', 'value': 0},
    36: {'label': 'Week 1~7', 'value': 1},
    37: {'label': 'Hour', 'value': 17},
    38: {'label': 'Min', 'value': 56},
    39: {'label': 'Sec', 'value': 48},
    40: {'label': 'Weekday', 'value': 24},
    41: {'label': 'Weekday', 'value': 0},
    42: {'label': 'Weekday', 'value': 21},
    43: {'label': 'Weekday', 'value': 24},
    44: {'label': 'Weekday', 'value': 0},
    45: {'label': 'Weekday', 'value': 20},
    46: {'label': 'Weekday', 'value': 24},
    47: {'label': 'Weekday', 'value': 0},
    48: {'label': 'Weekday', 'value': 24},
    49: {'label': 'Weekday', 'value': 24},
    50: {'label': 'Weekday', 'value': 0},
    51: {'label': 'Weekday', 'value': 19},
    52: {'label': 'Weekend', 'value': 24},
    53: {'label': 'Weekend', 'value': 0},
    54: {'label': 'Weekend', 'value': 22},
    55: {'label': 'Weekend', 'value': 24},
    56: {'label': 'Weekend', 'value': 0},
    57: {'label': 'Weekend', 'value': 20},
    58: {'label': 'Weekend', 'value': 24},
    59: {'label': 'Weekend', 'value': 0},
    60: {'label': 'Weekend', 'value': 16},
    61: {'label': 'Weekend', 'value': 24},
    62: {'label': 'Weekend', 'value': 0},
    63: {'label': 'Weekend', 'value': 16}}
INFO:root:Getting latest data from DCB....
INFO:root:CRC is correct
INFO:root:Thermostat 7 Living Room
{   0: {'label': 'High 8 bit', 'value': 0},
    1: {'label': 'Low 8 bit', 'value': 64},
    2: {'label': 'Vendor ID', 'value': 0},
    3: {'label': '0-6 bits = Version, bit 7 = floor limit state.', 'value': 15},
    4: {'label': 'Model', 'value': 2},
    5: {'label': 'Temperature format', 'value': 0},
    6: {'label': 'Switch Differential', 'value': 2},
    7: {'label': 'Frost Protection Mode', 'value': 1},
    8: {'label': 'Calibration - high 8 bit', 'value': 0},
    9: {'label': 'Calibration - low 8 bit', 'value': 0},
    10: {'label': 'Output delay', 'value': 0},
    11: {'label': 'Address', 'value': 7},
    12: {'label': 'Up down key limit', 'value': 0},
    13: {'label': 'Sensor Selection', 'value': 0},
    14: {'label': 'Optimum start', 'value': 0},
    15: {'label': 'Rate of change', 'value': 20},
    16: {'label': 'Program mode', 'value': 0},
    17: {'label': 'Frost protect temp', 'value': 16},
    18: {'label': 'Set room temp', 'value': 21},
    19: {'label': 'Floor max limit', 'value': 28},
    20: {'label': 'Floor max limit enable/disable', 'value': 1},
    21: {'label': 'On/off', 'value': 1},
    22: {'label': 'Key lock', 'value': 0},
    23: {'label': 'Run mode', 'value': 0},
    24: {'label': 'Holiday hours', 'value': 0},
    25: {'label': 'Holiday hours', 'value': 0},
    26: {'label': 'Temp hold mins', 'value': 0},
    27: {'label': 'Temp hold mins', 'value': 0},
    28: {'label': 'Remote air temp', 'value': 255},
    29: {'label': 'Remote air temp', 'value': 255},
    30: {'label': 'Floor temp', 'value': 255},
    31: {'label': 'Floor temp', 'value': 255},
    32: {'label': 'Built in air temp', 'value': 0},
    33: {'label': 'Built in air temp', 'value': 202},
    34: {'label': 'Error code', 'value': 0},
    35: {'label': 'Current state', 'value': 0},
    36: {'label': 'Week 1~7', 'value': 1},
    37: {'label': 'Hour', 'value': 16},
    38: {'label': 'Min', 'value': 4},
    39: {'label': 'Sec', 'value': 0},
    40: {'label': 'Weekday', 'value': 24},
    41: {'label': 'Weekday', 'value': 0},
    42: {'label': 'Weekday', 'value': 21},
    43: {'label': 'Weekday', 'value': 24},
    44: {'label': 'Weekday', 'value': 0},
    45: {'label': 'Weekday', 'value': 21},
    46: {'label': 'Weekday', 'value': 24},
    47: {'label': 'Weekday', 'value': 0},
    48: {'label': 'Weekday', 'value': 21},
    49: {'label': 'Weekday', 'value': 24},
    50: {'label': 'Weekday', 'value': 0},
    51: {'label': 'Weekday', 'value': 5},
    52: {'label': 'Weekend', 'value': 24},
    53: {'label': 'Weekend', 'value': 0},
    54: {'label': 'Weekend', 'value': 21},
    55: {'label': 'Weekend', 'value': 24},
    56: {'label': 'Weekend', 'value': 0},
    57: {'label': 'Weekend', 'value': 20},
    58: {'label': 'Weekend', 'value': 24},
    59: {'label': 'Weekend', 'value': 0},
    60: {'label': 'Weekend', 'value': 23},
    61: {'label': 'Weekend', 'value': 24},
    62: {'label': 'Weekend', 'value': 0},
    63: {'label': 'Weekend', 'value': 5}}
INFO:root:Getting latest data from DCB....
INFO:root:CRC is correct
INFO:root:Thermostat 8 Dining Area
{   0: {'label': 'High 8 bit', 'value': 0},
    1: {'label': 'Low 8 bit', 'value': 64},
    2: {'label': 'Vendor ID', 'value': 0},
    3: {'label': '0-6 bits = Version, bit 7 = floor limit state.', 'value': 15},
    4: {'label': 'Model', 'value': 2},
    5: {'label': 'Temperature format', 'value': 0},
    6: {'label': 'Switch Differential', 'value': 2},
    7: {'label': 'Frost Protection Mode', 'value': 1},
    8: {'label': 'Calibration - high 8 bit', 'value': 0},
    9: {'label': 'Calibration - low 8 bit', 'value': 0},
    10: {'label': 'Output delay', 'value': 0},
    11: {'label': 'Address', 'value': 8},
    12: {'label': 'Up down key limit', 'value': 0},
    13: {'label': 'Sensor Selection', 'value': 0},
    14: {'label': 'Optimum start', 'value': 0},
    15: {'label': 'Rate of change', 'value': 20},
    16: {'label': 'Program mode', 'value': 0},
    17: {'label': 'Frost protect temp', 'value': 15},
    18: {'label': 'Set room temp', 'value': 21},
    19: {'label': 'Floor max limit', 'value': 28},
    20: {'label': 'Floor max limit enable/disable', 'value': 1},
    21: {'label': 'On/off', 'value': 1},
    22: {'label': 'Key lock', 'value': 0},
    23: {'label': 'Run mode', 'value': 0},
    24: {'label': 'Holiday hours', 'value': 0},
    25: {'label': 'Holiday hours', 'value': 0},
    26: {'label': 'Temp hold mins', 'value': 0},
    27: {'label': 'Temp hold mins', 'value': 0},
    28: {'label': 'Remote air temp', 'value': 255},
    29: {'label': 'Remote air temp', 'value': 255},
    30: {'label': 'Floor temp', 'value': 255},
    31: {'label': 'Floor temp', 'value': 255},
    32: {'label': 'Built in air temp', 'value': 0},
    33: {'label': 'Built in air temp', 'value': 210},
    34: {'label': 'Error code', 'value': 0},
    35: {'label': 'Current state', 'value': 0},
    36: {'label': 'Week 1~7', 'value': 1},
    37: {'label': 'Hour', 'value': 17},
    38: {'label': 'Min', 'value': 56},
    39: {'label': 'Sec', 'value': 3},
    40: {'label': 'Weekday', 'value': 24},
    41: {'label': 'Weekday', 'value': 0},
    42: {'label': 'Weekday', 'value': 21},
    43: {'label': 'Weekday', 'value': 24},
    44: {'label': 'Weekday', 'value': 0},
    45: {'label': 'Weekday', 'value': 21},
    46: {'label': 'Weekday', 'value': 24},
    47: {'label': 'Weekday', 'value': 0},
    48: {'label': 'Weekday', 'value': 21},
    49: {'label': 'Weekday', 'value': 24},
    50: {'label': 'Weekday', 'value': 0},
    51: {'label': 'Weekday', 'value': 5},
    52: {'label': 'Weekend', 'value': 24},
    53: {'label': 'Weekend', 'value': 0},
    54: {'label': 'Weekend', 'value': 21},
    55: {'label': 'Weekend', 'value': 24},
    56: {'label': 'Weekend', 'value': 0},
    57: {'label': 'Weekend', 'value': 21},
    58: {'label': 'Weekend', 'value': 24},
    59: {'label': 'Weekend', 'value': 0},
    60: {'label': 'Weekend', 'value': 21},
    61: {'label': 'Weekend', 'value': 24},
    62: {'label': 'Weekend', 'value': 0},
    63: {'label': 'Weekend', 'value': 5}}
INFO:root:Getting latest data from DCB....
INFO:root:CRC is correct
INFO:root:Thermostat 9 Kitchen
{   0: {'label': 'High 8 bit', 'value': 0},
    1: {'label': 'Low 8 bit', 'value': 64},
    2: {'label': 'Vendor ID', 'value': 0},
    3: {'label': '0-6 bits = Version, bit 7 = floor limit state.', 'value': 15},
    4: {'label': 'Model', 'value': 2},
    5: {'label': 'Temperature format', 'value': 0},
    6: {'label': 'Switch Differential', 'value': 2},
    7: {'label': 'Frost Protection Mode', 'value': 1},
    8: {'label': 'Calibration - high 8 bit', 'value': 0},
    9: {'label': 'Calibration - low 8 bit', 'value': 0},
    10: {'label': 'Output delay', 'value': 0},
    11: {'label': 'Address', 'value': 9},
    12: {'label': 'Up down key limit', 'value': 0},
    13: {'label': 'Sensor Selection', 'value': 0},
    14: {'label': 'Optimum start', 'value': 0},
    15: {'label': 'Rate of change', 'value': 20},
    16: {'label': 'Program mode', 'value': 0},
    17: {'label': 'Frost protect temp', 'value': 15},
    18: {'label': 'Set room temp', 'value': 21},
    19: {'label': 'Floor max limit', 'value': 28},
    20: {'label': 'Floor max limit enable/disable', 'value': 1},
    21: {'label': 'On/off', 'value': 1},
    22: {'label': 'Key lock', 'value': 0},
    23: {'label': 'Run mode', 'value': 0},
    24: {'label': 'Holiday hours', 'value': 0},
    25: {'label': 'Holiday hours', 'value': 0},
    26: {'label': 'Temp hold mins', 'value': 0},
    27: {'label': 'Temp hold mins', 'value': 0},
    28: {'label': 'Remote air temp', 'value': 255},
    29: {'label': 'Remote air temp', 'value': 255},
    30: {'label': 'Floor temp', 'value': 255},
    31: {'label': 'Floor temp', 'value': 255},
    32: {'label': 'Built in air temp', 'value': 0},
    33: {'label': 'Built in air temp', 'value': 207},
    34: {'label': 'Error code', 'value': 0},
    35: {'label': 'Current state', 'value': 0},
    36: {'label': 'Week 1~7', 'value': 1},
    37: {'label': 'Hour', 'value': 17},
    38: {'label': 'Min', 'value': 37},
    39: {'label': 'Sec', 'value': 34},
    40: {'label': 'Weekday', 'value': 24},
    41: {'label': 'Weekday', 'value': 0},
    42: {'label': 'Weekday', 'value': 21},
    43: {'label': 'Weekday', 'value': 24},
    44: {'label': 'Weekday', 'value': 0},
    45: {'label': 'Weekday', 'value': 19},
    46: {'label': 'Weekday', 'value': 24},
    47: {'label': 'Weekday', 'value': 0},
    48: {'label': 'Weekday', 'value': 24},
    49: {'label': 'Weekday', 'value': 24},
    50: {'label': 'Weekday', 'value': 0},
    51: {'label': 'Weekday', 'value': 5},
    52: {'label': 'Weekend', 'value': 24},
    53: {'label': 'Weekend', 'value': 0},
    54: {'label': 'Weekend', 'value': 21},
    55: {'label': 'Weekend', 'value': 24},
    56: {'label': 'Weekend', 'value': 0},
    57: {'label': 'Weekend', 'value': 20},
    58: {'label': 'Weekend', 'value': 24},
    59: {'label': 'Weekend', 'value': 0},
    60: {'label': 'Weekend', 'value': 16},
    61: {'label': 'Weekend', 'value': 24},
    62: {'label': 'Weekend', 'value': 0},
    63: {'label': 'Weekend', 'value': 5}}
INFO:root:Closing serial port.