diff --git a/itho-wpu.py b/itho-wpu.py index 59bd02f..79c7f94 100755 --- a/itho-wpu.py +++ b/itho-wpu.py @@ -26,6 +26,7 @@ actions = { "getsetting": [0xA4, 0x10], "setsetting": [0xA4, 0x10], "getmanual": [0x40, 0x30], + "setmanual": [0x40, 0x30], } @@ -454,6 +455,46 @@ def process_manual(response, wpu): ) +def process_setmanual(wpu, args): + logger.info("Current manual operation:") + response = wpu.get("getmanual", int(args.id)) + if response is None: + return + process_response("getmanual", response, args, wpu) + message = response[5:] + datatype = message[3] + + # TODO: check if Max Handbedieningstijd > 0 + + if args.value is None: + value = input("Provide a new value: ") + else: + value = args.value + + # TODO: add support for negative values + if float(value) < 0: + logger.error("Negative values are not supported yet.") + return + + logger.debug(f"New manual operation datatype: {datatype}") + logger.debug(f"New manual operation (input): {value}") + normalized_value = int(value.replace(".", "")) + logger.debug(f"New manual operation (normalized): {normalized_value}") + hex_list_value = [hex(v) for v in list(normalized_value.to_bytes(2, byteorder="big"))] + logger.debug(f"New manual operation (hex): {hex_list_value}") + parsed_value = format_datatype(args.id, hex_list_value, datatype) + logger.debug(f"New manual operation (parsed): {parsed_value}") + + sure = input(f"Manual `{args.id}` will be changed to `{parsed_value}`? [y/N] ") + if sure in ["y", "Y"]: + logger.info(f"Updating manual operation {args.id} to `{parsed_value}`") + else: + logger.error("Aborted") + return + + response = wpu.get("setmanual", args.id, normalized_value) + + def format_datatype(name, m, dt): """ Transform a list of bytes to a readable number based on the datatype. @@ -534,7 +575,7 @@ def main(): logging.Formatter("%(asctime)-15s %(levelname)s: %(message)s") ) - if args.action in ["getsetting", "setsetting", "getmanual"] and args.id is None: + if args.action in ["getsetting", "setsetting", "getmanual", "setmanual"] and args.id is None: logger.error(f"`--id` is required with `--action {args.action}`") return @@ -548,6 +589,10 @@ def main(): process_setsetting(wpu, args) return + if args.action == "setmanual": + process_setmanual(wpu, args) + return + response = wpu.get(args.action, args.id) if response is not None: process_response(args.action, response, args, wpu) diff --git a/itho_i2c.py b/itho_i2c.py index aa5986d..04db68c 100644 --- a/itho_i2c.py +++ b/itho_i2c.py @@ -20,6 +20,7 @@ actions = { "getsetting": [0xA4, 0x10], "setsetting": [0xA4, 0x10], "getmanual": [0x40, 0x30], + "setmanual": [0x40, 0x30], } @@ -87,6 +88,19 @@ class I2CMaster: + byte_identifier + [0x01] # 1 = manual ) + elif action == "setmanual": + byte_identifier = list(identifier.to_bytes(2, byteorder="big")) + byte_list_value = list(value.to_bytes(2, byteorder="big")) + request = ( + [0x80] + + actions[action] + + [0x06, 0x07] # write, length + + [0x01] # bank + + byte_identifier + + [0x00] # datatype + + byte_list_value # new + + [0x01] # 1 = manual + ) else: # 0x80 = source, 0x04 = msg_type, 0x00 = length request = [0x80] + actions[action] + [0x04, 0x00] @@ -107,7 +121,7 @@ class I2CMaster: request_in_hex = [hex(c) for c in request] logger.debug(f"Request: {request_in_hex}") result = None - if action == "setsetting": + if action in ["setsetting", "setmanual"]: sure = input("Are you really sure? (Type uppercase yes): ") if sure != "YES": logger.error("Aborted") @@ -120,6 +134,8 @@ class I2CMaster: if self.queue.qsize() > 0: result = self.queue.get() break + elif action == "setmanual" and self.queue.qsize() == 0: + return None if result is None: logger.error("No valid result in 20 requests")