diff --git a/CHANGELOG.md b/CHANGELOG.md index 881b05d..9772777 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.1.0] - 2023-08-06 + +### Added + +- Add function get_delay_timers. +- Extend wtw.yaml with delay timer MQTT topics. + +### Fixed + +- Function get_fan_status had the wrong command in the documentation part. +- Reformatted the code using Black. + ## [1.0.1] - 2023-08-05 ### Added diff --git a/src/whr930.py b/src/whr930.py index 6f031af..0d85d14 100755 --- a/src/whr930.py +++ b/src/whr930.py @@ -15,6 +15,7 @@ import yaml from pathlib import Path + def debug_msg(message): if debug is True: print( @@ -51,13 +52,21 @@ def debug_data(serial_data): data_len = len(serial_data) if data_len == 2 and serial_data[0] == "07" and serial_data[1] == "f3": debug_msg( - "Recieved an ack packet: {0} {1}".format(serial_data[0], serial_data[1]) + "Recieved an ack packet: {0} {1}".format( + serial_data[0], serial_data[1] + ) ) else: debug_msg("Data length : {0}".format(len(serial_data))) - debug_msg("Ack : {0} {1}".format(serial_data[0], serial_data[1])) - debug_msg("Start : {0} {1}".format(serial_data[2], serial_data[3])) - debug_msg("Command : {0} {1}".format(serial_data[4], serial_data[5])) + debug_msg( + "Ack : {0} {1}".format(serial_data[0], serial_data[1]) + ) + debug_msg( + "Start : {0} {1}".format(serial_data[2], serial_data[3]) + ) + debug_msg( + "Command : {0} {1}".format(serial_data[4], serial_data[5]) + ) debug_msg( "Nr data bytes : {0} (integer {1})".format( serial_data[6], int(serial_data[6], 16) @@ -74,7 +83,9 @@ def debug_data(serial_data): n += 1 debug_msg("Checksum : {0}".format(serial_data[-2])) - debug_msg("End : {0} {1}".format(serial_data[-2], serial_data[-1])) + debug_msg( + "End : {0} {1}".format(serial_data[-2], serial_data[-1]) + ) if debug_level > 1: n = 0 @@ -85,6 +96,7 @@ def debug_data(serial_data): else: debug_msg("serial_data is empty") + def publish_message(msg, mqtt_path): mqttc.publish(mqtt_path, payload=msg, qos=0, retain=True) time.sleep(0.1) @@ -267,7 +279,7 @@ def status_8bit(inp): idx = 7 matches = {} - for num in (2 ** p for p in range(idx, -1, -1)): + for num in (2**p for p in range(idx, -1, -1)): if ((inp - num) > 0) or ((inp - num) == 0): inp = inp - num matches[idx] = True @@ -440,7 +452,7 @@ def get_ventilation_status(): def get_fan_status(): """ - Command: 0x00 0x99 + Command: 0x00 0x0B """ packet = create_packet([0x00, 0x0B]) data = serial_command(packet) @@ -829,6 +841,114 @@ def get_status(): warning_msg("get_status ignoring incomplete message") +def get_delay_timers(): + """ + Command: 0x00 0xC9 + """ + + packet = create_packet([0x00, 0xC9]) + data = serial_command(packet) + debug_data(data) + + try: + if data is None: + warning_msg("get_delay_timers function could not get serial data") + else: + """ + Number of minutes to delay after the badroom switch is set to high (3) + """ + BathroomSwitchOnDelayMinutes = int(data[7], 16) + + """ + Number of minutes to delay after the badroom switch is set to normal (2) + """ + BathroomSwitchOffDelayMinutes = int(data[8], 16) + + """ + Number of minutes where ventilation modes 3 will be kept if the WHR 930 is set + to 3 for a short moment (< 3 seconds) + """ + L1SwitchOffDelayMinutes = int(data[9], 16) + + """ + Boost minutes + + When "PARTY TIMER" is enabled, the unit will switch for this amount of minutes + to the high modus (3), after which is will go back to normal (2) + """ + BoostVentilationMinutes = int(data[10], 16) + + """ + Number of weeks before a "Filter" warning is given. Default 16, minimal 10 and maximal 26. + """ + FilterWarningWeeks = int(data[11], 16) + + """ + Number of minutes to go into high ventilation mode when the clock button on the RF reciever is + pressed SHORT (less then 2 seconds). + """ + RFHighTimeShortMinutes = int(data[12], 16) + + """ + Number of minutes to go into high ventilation mode when the clock button on the RF reciever is + pressed LONG (more then 2 seconds). + """ + RFHighTimeLongMinutes = int(data[13], 16) + + """ + Number of minutes after which the WHR will go back to normal (2) when the extractor hood switch is used + """ + ExtractorHoodSwitchOffDelayMinutes = int(data[14], 16) + + publish_message( + msg=BathroomSwitchOnDelayMinutes, + mqtt_path="house/2/attic/wtw/bathroom_switch_on_delay_minutes", + ) + publish_message( + msg=BathroomSwitchOffDelayMinutes, + mqtt_path="house/2/attic/wtw/bathroom_switch_off_delay_minutes", + ) + publish_message( + msg=L1SwitchOffDelayMinutes, + mqtt_path="house/2/attic/wtw/l1_switch_off_delay_minutes", + ) + publish_message( + msg=BoostVentilationMinutes, + mqtt_path="house/2/attic/wtw/boost_ventilation_minutes", + ) + publish_message( + msg=FilterWarningWeeks, + mqtt_path="house/2/attic/wtw/filter_warning_weeks", + ) + publish_message( + msg=RFHighTimeShortMinutes, + mqtt_path="house/2/attic/wtw/rf_high_time_short_minutes", + ) + publish_message( + msg=RFHighTimeLongMinutes, + mqtt_path="house/2/attic/wtw/rf_high_time_long_minutes", + ) + publish_message( + msg=ExtractorHoodSwitchOffDelayMinutes, + mqtt_path="house/2/attic/wtw/extractor_hood_switch_off_delay_minutes", + ) + + debug_msg( + "BathroomSwitchOnDelayMinutes: {}, BathroomSwitchOffDelayMinutes: {}, L1SwitchOffDelayMinutes: {}, BoostVentilationMinutes: {}, FilterWarningWeeks: {}, RFHighTimeShortMinutes: {}, RFHighTimeLongMinutes: {}, ExtractorHoodSwitchOffDelayMinutes: {}".format( + BathroomSwitchOnDelayMinutes, + BathroomSwitchOffDelayMinutes, + L1SwitchOffDelayMinutes, + BoostVentilationMinutes, + FilterWarningWeeks, + RFHighTimeShortMinutes, + RFHighTimeLongMinutes, + ExtractorHoodSwitchOffDelayMinutes, + ) + ) + except IndexError: + warning_msg("get_delay_timers ignoring incomplete message") + + def on_message(client, userdata, message): debug_msg( "message received: topic: {0}, payload: {1}, userdata: {2}".format( @@ -918,7 +1038,9 @@ def main(): """Connect to the MQTT broker""" mqttc = mqtt.Client("whr930") - mqttc.username_pw_set(username=config["mqtt_username"], password=config["mqtt_password"]) + mqttc.username_pw_set( + username=config["mqtt_username"], password=config["mqtt_password"] + ) """Define the mqtt callbacks""" mqttc.on_connect = on_connect @@ -949,13 +1071,14 @@ def main(): get_status, get_operating_hours, get_preheating_status, + get_delay_timers, ] while True: try: for func in functions: if len(pending_commands) == 0: - debug_msg('Executing function {}'.format(func)) + debug_msg("Executing function {}".format(func)) func() else: handle_commands() diff --git a/src/wtw.yaml b/src/wtw.yaml index a64b379..6af4a35 100644 --- a/src/wtw.yaml +++ b/src/wtw.yaml @@ -343,3 +343,43 @@ mqtt: state_topic: "house/2/attic/wtw/P97_active" unique_id: "wtw_p97_active" qos: 0 + - name: "WTW Bathroom Switch On Delay Minutes" + state_topic: "house/2/attic/wtw/bathroom_switch_on_delay_minutes" + unique_id: "wtw_bathroom_switch_on_delay_minutes" + unit_of_measurement: 'min' + qos: 0 + - name: "WTW Bathroom Switch Off Delay Minutes" + state_topic: "house/2/attic/wtw/bathroom_switch_off_delay_minutes" + unique_id: "wtw_bathroom_switch_off_delay_minutes" + qos: 0 + unit_of_measurement: 'min' + - name: "WTW L1 Switch Off Delay Minutes" + state_topic: "house/2/attic/wtw/l1_switch_off_delay_minutes" + unique_id: "wtw_l1_switch_off_delay_minutes" + qos: 0 + unit_of_measurement: 'min' + - name: "WTW Boost Ventilation Minutes" + state_topic: "house/2/attic/wtw/boost_ventilation_minutes" + unique_id: "wtw_boost_ventilation_minutes" + qos: 0 + unit_of_measurement: 'min' + - name: "WTW Filter Warning" + state_topic: "house/2/attic/wtw/filter_warning_weeks" + unique_id: "wtw_filter_warning_weeks" + qos: 0 + unit_of_measurement: 'weeks' + - name: "WTW RF High Time Short Minutes" + state_topic: "house/2/attic/wtw/rf_high_time_short_minutes" + unique_id: "wtw_rf_high_time_short_minutes" + qos: 0 + unit_of_measurement: 'min' + - name: "WTW RF High Time Long Minutes" + state_topic: "house/2/attic/wtw/rf_high_time_long_minutes" + unique_id: "wtw_rf_high_time_long_minutes" + qos: 0 + unit_of_measurement: 'min' + - name: "WTW Extractor Hood Switch Off Delay Minutes" + state_topic: "house/2/attic/wtw/extractor_hood_switch_off_delay_minutes" + unique_id: "wtw_extractor_hood_switch_off_delay_minutes" + qos: 0 + unit_of_measurement: 'min'