From 39cec02c816b1f058b6e07c0fcdeac98462da468 Mon Sep 17 00:00:00 2001 From: criticallimit Date: Sat, 27 Jun 2026 20:37:38 +0200 Subject: [PATCH 01/13] Update client.py --- grobro/ha/client.py | 73 ++++++++++++++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 24 deletions(-) diff --git a/grobro/ha/client.py b/grobro/ha/client.py index 92e2965..148b79a 100644 --- a/grobro/ha/client.py +++ b/grobro/ha/client.py @@ -221,7 +221,7 @@ def __init__(self, mqtt_config: model.MQTTConfig): self._client.connect(mqtt_config.host, mqtt_config.port, 60) # Subscriptions - for cmd_type in ["number", "button", "switch", "config"]: + for cmd_type in ["number", "time", "button", "switch", "config"]: for action in ["set", "read"]: topic = f"{HA_BASE_TOPIC}/{cmd_type}/grobro/+/+/{action}" self._client.subscribe(topic) @@ -426,29 +426,54 @@ def __on_message(self, client, userdata, msg: mqtt.MQTTMessage): return # Number / Switch - if cmd_type in {"number", "switch"} and action == "set": - raw_value = msg.payload.decode() - if cmd_type == "switch": - parsed_value = 1 if raw_value.upper() == "ON" else 0 - elif "_start_time" in cmd_name or "_end_time" in cmd_name: - hour, minute = divmod(int(raw_value), 100) - parsed_value = (hour * 256) + minute - else: - parsed_value = int(raw_value) - - pos = known_registers.holding_registers[cmd_name].growatt.position - LOG.debug("Setting %s register %s to value %s", cmd_name, pos.register_no, parsed_value) - - # write - self.on_command(make_modbus_command( - device_id, GrowattModbusFunction.PRESET_SINGLE_REGISTER, pos.register_no, parsed_value - )) - # read-after-write - LOG.debug("Triggering read-after-write for Command %s register %s", cmd_name, pos.register_no) - self.on_command(make_modbus_command( - device_id, GrowattModbusFunction.READ_SINGLE_REGISTER, pos.register_no - )) - + if cmd_type in {"number", "switch", "time"} and action == "set": + raw_value = msg.payload.decode().strip() + + if cmd_type == "switch": + parsed_value = 1 if raw_value.upper() == "ON" else 0 + + elif cmd_type == "time": + hour, minute = map(int, raw_value.split(":")) + parsed_value = (hour << 8) | minute + + elif "_start_time" in cmd_name or "_end_time" in cmd_name: + hour, minute = divmod(int(raw_value), 100) + parsed_value = (hour << 8) | minute + + else: + parsed_value = int(raw_value) + + pos = known_registers.holding_registers[cmd_name].growatt.position + LOG.debug( + "Setting %s register %s to value %s", + cmd_name, + pos.register_no, + parsed_value, + ) + + # write + self.on_command( + make_modbus_command( + device_id, + GrowattModbusFunction.PRESET_SINGLE_REGISTER, + pos.register_no, + parsed_value, + ) + ) + + # read-after-write + LOG.debug( + "Triggering read-after-write for Command %s register %s", + cmd_name, + pos.register_no, + ) + self.on_command( + make_modbus_command( + device_id, + GrowattModbusFunction.READ_SINGLE_REGISTER, + pos.register_no, + ) + ) # Config if parts[0] == "config" and action == "set": register_no = int(cmd_name) From c06b3ea5e140c53deef358b0fb7ee05fd73edea8 Mon Sep 17 00:00:00 2001 From: criticallimit Date: Sat, 27 Jun 2026 20:39:02 +0200 Subject: [PATCH 02/13] Update growatt_registers.py --- grobro/model/growatt_registers.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/grobro/model/growatt_registers.py b/grobro/model/growatt_registers.py index 4a32d24..b72b3c3 100644 --- a/grobro/model/growatt_registers.py +++ b/grobro/model/growatt_registers.py @@ -55,9 +55,9 @@ def parse(self, data_raw: bytes): return round(value, 3) elif self.data_type == GrowattRegisterDataTypes.TIME_HHMM: value = struct.unpack(unpack_type, data_raw)[0] - h = value // 256 - m = value % 256 - return (h * 100) + m + hour = (value >> 8) & 0xFF + minute = value & 0xFF + return f"{hour:02d}:{minute:02d}" elif self.data_type in [GrowattRegisterDataTypes.INT, GrowattRegisterDataTypes.SIGNED_INT]: value = struct.unpack(unpack_type, data_raw)[0] return value From c2bfb09d7aebf81a108afd42ec5a619e852ac440 Mon Sep 17 00:00:00 2001 From: criticallimit Date: Sat, 27 Jun 2026 20:46:38 +0200 Subject: [PATCH 03/13] Update growatt_noah_registers.json --- grobro/model/growatt_noah_registers.json | 90 +++++------------------- 1 file changed, 18 insertions(+), 72 deletions(-) diff --git a/grobro/model/growatt_noah_registers.json b/grobro/model/growatt_noah_registers.json index 6349be0..42ce95a 100644 --- a/grobro/model/growatt_noah_registers.json +++ b/grobro/model/growatt_noah_registers.json @@ -76,10 +76,7 @@ "homeassistant": { "publish": true, "name": "Slot 1 Start Time", - "type": "number", - "min": 0, - "max": 2358, - "step": 1, + "type": "time", "icon": "mdi:clock-start" } }, @@ -97,10 +94,7 @@ "homeassistant": { "publish": true, "name": "Slot 1 End Time", - "type": "number", - "min": 0, - "max": 2359, - "step": 1, + "type": "time", "icon": "mdi:clock-end" } }, @@ -176,10 +170,7 @@ "homeassistant": { "publish": true, "name": "Slot 2 Start Time", - "type": "number", - "min": 0, - "max": 2358, - "step": 1, + "type": "time", "icon": "mdi:clock-start" } }, @@ -197,10 +188,7 @@ "homeassistant": { "publish": true, "name": "Slot 2 End Time", - "type": "number", - "min": 0, - "max": 2359, - "step": 1, + "type": "time", "icon": "mdi:clock-end" } }, @@ -276,10 +264,7 @@ "homeassistant": { "publish": true, "name": "Slot 3 Start Time", - "type": "number", - "min": 0, - "max": 2358, - "step": 1, + "type": "time", "icon": "mdi:clock-start" } }, @@ -297,10 +282,7 @@ "homeassistant": { "publish": true, "name": "Slot 3 End Time", - "type": "number", - "min": 0, - "max": 2359, - "step": 1, + "type": "time", "icon": "mdi:clock-end" } }, @@ -376,10 +358,7 @@ "homeassistant": { "publish": true, "name": "Slot 4 Start Time", - "type": "number", - "min": 0, - "max": 2358, - "step": 1, + "type": "time", "icon": "mdi:clock-start" } }, @@ -397,10 +376,7 @@ "homeassistant": { "publish": true, "name": "Slot 4 End Time", - "type": "number", - "min": 0, - "max": 2359, - "step": 1, + "type": "time", "icon": "mdi:clock-end" } }, @@ -476,10 +452,7 @@ "homeassistant": { "publish": true, "name": "Slot 5 Start Time", - "type": "number", - "min": 0, - "max": 2358, - "step": 1, + "type": "time", "icon": "mdi:clock-start" } }, @@ -497,10 +470,7 @@ "homeassistant": { "publish": true, "name": "Slot 5 End Time", - "type": "number", - "min": 0, - "max": 2359, - "step": 1, + "type": "time", "icon": "mdi:clock-end" } }, @@ -576,10 +546,7 @@ "homeassistant": { "publish": true, "name": "Slot 6 Start Time", - "type": "number", - "min": 0, - "max": 2358, - "step": 1, + "type": "time", "icon": "mdi:clock-start" } }, @@ -597,10 +564,7 @@ "homeassistant": { "publish": true, "name": "Slot 6 End Time", - "type": "number", - "min": 0, - "max": 2359, - "step": 1, + "type": "time", "icon": "mdi:clock-end" } }, @@ -676,10 +640,7 @@ "homeassistant": { "publish": true, "name": "Slot 7 Start Time", - "type": "number", - "min": 0, - "max": 2358, - "step": 1, + "type": "time", "icon": "mdi:clock-start" } }, @@ -697,10 +658,7 @@ "homeassistant": { "publish": true, "name": "Slot 7 End Time", - "type": "number", - "min": 0, - "max": 2359, - "step": 1, + "type": "time", "icon": "mdi:clock-end" } }, @@ -776,10 +734,7 @@ "homeassistant": { "publish": true, "name": "Slot 8 Start Time", - "type": "number", - "min": 0, - "max": 2358, - "step": 1, + "type": "time", "icon": "mdi:clock-start" } }, @@ -797,10 +752,7 @@ "homeassistant": { "publish": true, "name": "Slot 8 End Time", - "type": "number", - "min": 0, - "max": 2359, - "step": 1, + "type": "time", "icon": "mdi:clock-end" } }, @@ -876,10 +828,7 @@ "homeassistant": { "publish": true, "name": "Slot 9 Start Time", - "type": "number", - "min": 0, - "max": 2358, - "step": 1, + "type": "time", "icon": "mdi:clock-start" } }, @@ -897,10 +846,7 @@ "homeassistant": { "publish": true, "name": "Slot 9 End Time", - "type": "number", - "min": 0, - "max": 2359, - "step": 1, + "type": "time", "icon": "mdi:clock-end" } }, From d9c8313f077b7cac64c6b7ca06dd7b7d60d4246b Mon Sep 17 00:00:00 2001 From: criticallimit Date: Sat, 27 Jun 2026 20:57:08 +0200 Subject: [PATCH 04/13] Update client.py --- grobro/ha/client.py | 135 ++++++++++++++++++++++++-------------------- 1 file changed, 75 insertions(+), 60 deletions(-) diff --git a/grobro/ha/client.py b/grobro/ha/client.py index 148b79a..9284f0a 100644 --- a/grobro/ha/client.py +++ b/grobro/ha/client.py @@ -387,7 +387,7 @@ def __on_message(self, client, userdata, msg: mqtt.MQTTMessage): # Buttons if cmd_type == "button": if cmd_name == "read_all": - # Send all modbus reads first + # Send all modbus reads first for name, register in known_registers.holding_registers.items(): if name.startswith("slot"): try: @@ -395,85 +395,100 @@ def __on_message(self, client, userdata, msg: mqtt.MQTTMessage): continue except ValueError: continue + pos = register.growatt.position - self.on_command(make_modbus_command( - device_id, - GrowattModbusFunction.READ_SINGLE_REGISTER, - pos.register_no, - )) + self.on_command( + make_modbus_command( + device_id, + GrowattModbusFunction.READ_SINGLE_REGISTER, + pos.register_no, + ) + ) # Queue config reads if self.on_config_read: with self._config_read_lock: q = self._config_read_queues.setdefault(device_id, deque()) + for cfg in known_registers.config_registers.values(): q.append(cfg.growatt.register_no) # give the datalogger time to answer modbus reads Timer( - 3.0, # small delay is enough + 3.0, self.__kickoff_next_config_read, args=(device_id,), ).start() return - + if action == "read": pos = known_registers.holding_registers[cmd_name].growatt.position - self.on_command(make_modbus_command( - device_id, GrowattModbusFunction.READ_SINGLE_REGISTER, pos.register_no - )) + + self.on_command( + make_modbus_command( + device_id, + GrowattModbusFunction.READ_SINGLE_REGISTER, + pos.register_no, + ) + ) + return - # Number / Switch - if cmd_type in {"number", "switch", "time"} and action == "set": - raw_value = msg.payload.decode().strip() - - if cmd_type == "switch": - parsed_value = 1 if raw_value.upper() == "ON" else 0 - - elif cmd_type == "time": - hour, minute = map(int, raw_value.split(":")) - parsed_value = (hour << 8) | minute - - elif "_start_time" in cmd_name or "_end_time" in cmd_name: - hour, minute = divmod(int(raw_value), 100) - parsed_value = (hour << 8) | minute - - else: - parsed_value = int(raw_value) - - pos = known_registers.holding_registers[cmd_name].growatt.position - LOG.debug( - "Setting %s register %s to value %s", - cmd_name, - pos.register_no, - parsed_value, - ) - - # write - self.on_command( - make_modbus_command( - device_id, - GrowattModbusFunction.PRESET_SINGLE_REGISTER, - pos.register_no, - parsed_value, - ) - ) - - # read-after-write - LOG.debug( - "Triggering read-after-write for Command %s register %s", - cmd_name, - pos.register_no, - ) - self.on_command( - make_modbus_command( - device_id, - GrowattModbusFunction.READ_SINGLE_REGISTER, - pos.register_no, - ) - ) + # Number / Switch / Time + if cmd_type in {"number", "switch", "time"} and action == "set": + raw_value = msg.payload.decode().strip() + + if cmd_type == "switch": + parsed_value = 1 if raw_value.upper() == "ON" else 0 + + elif cmd_type == "time": + hour, minute = map(int, raw_value.split(":")) + parsed_value = (hour << 8) | minute + + elif "_start_time" in cmd_name or "_end_time" in cmd_name: + hour, minute = divmod(int(raw_value), 100) + parsed_value = (hour << 8) | minute + + else: + parsed_value = int(raw_value) + + pos = known_registers.holding_registers[cmd_name].growatt.position + + LOG.debug( + "Setting %s register %s to value %s", + cmd_name, + pos.register_no, + parsed_value, + ) + + # write + self.on_command( + make_modbus_command( + device_id, + GrowattModbusFunction.PRESET_SINGLE_REGISTER, + pos.register_no, + parsed_value, + ) + ) + + # read-after-write + LOG.debug( + "Triggering read-after-write for Command %s register %s", + cmd_name, + pos.register_no, + ) + + self.on_command( + make_modbus_command( + device_id, + GrowattModbusFunction.READ_SINGLE_REGISTER, + pos.register_no, + ) + ) + + return + # Config if parts[0] == "config" and action == "set": register_no = int(cmd_name) From a7fde5ca40261415d74959cb76aa72edfc51906d Mon Sep 17 00:00:00 2001 From: criticallimit Date: Sat, 27 Jun 2026 21:23:18 +0200 Subject: [PATCH 05/13] Update growatt_nexa_registers.json --- grobro/model/growatt_nexa_registers.json | 92 +++++------------------- 1 file changed, 19 insertions(+), 73 deletions(-) diff --git a/grobro/model/growatt_nexa_registers.json b/grobro/model/growatt_nexa_registers.json index fc6e4bc..8fe8885 100644 --- a/grobro/model/growatt_nexa_registers.json +++ b/grobro/model/growatt_nexa_registers.json @@ -163,10 +163,7 @@ "homeassistant": { "publish": true, "name": "Slot 1 Start Time", - "type": "number", - "min": 0, - "max": 2358, - "step": 1, + "type": "time", "icon": "mdi:clock-start" } }, @@ -184,10 +181,7 @@ "homeassistant": { "publish": true, "name": "Slot 1 End Time", - "type": "number", - "min": 0, - "max": 2359, - "step": 1, + "type": "time", "icon": "mdi:clock-end" } }, @@ -263,10 +257,7 @@ "homeassistant": { "publish": true, "name": "Slot 2 Start Time", - "type": "number", - "min": 0, - "max": 2358, - "step": 1, + "type": "time", "icon": "mdi:clock-start" } }, @@ -284,10 +275,7 @@ "homeassistant": { "publish": true, "name": "Slot 2 End Time", - "type": "number", - "min": 0, - "max": 2359, - "step": 1, + "type": "time", "icon": "mdi:clock-end" } }, @@ -363,10 +351,7 @@ "homeassistant": { "publish": true, "name": "Slot 3 Start Time", - "type": "number", - "min": 0, - "max": 2358, - "step": 1, + "type": "time", "icon": "mdi:clock-start" } }, @@ -384,10 +369,7 @@ "homeassistant": { "publish": true, "name": "Slot 3 End Time", - "type": "number", - "min": 0, - "max": 2359, - "step": 1, + "type": "time", "icon": "mdi:clock-end" } }, @@ -463,10 +445,7 @@ "homeassistant": { "publish": true, "name": "Slot 4 Start Time", - "type": "number", - "min": 0, - "max": 2358, - "step": 1, + "type": "time", "icon": "mdi:clock-start" } }, @@ -484,10 +463,7 @@ "homeassistant": { "publish": true, "name": "Slot 4 End Time", - "type": "number", - "min": 0, - "max": 2359, - "step": 1, + "type": "time", "icon": "mdi:clock-end" } }, @@ -563,11 +539,8 @@ "homeassistant": { "publish": true, "name": "Slot 5 Start Time", - "type": "number", - "min": 0, - "max": 2358, - "step": 1, - "icon": "mdi:clock-start" + "type": "time", + "icon": "mdi:clock-end" } }, "slot5_end_time": { @@ -584,10 +557,7 @@ "homeassistant": { "publish": true, "name": "Slot 5 End Time", - "type": "number", - "min": 0, - "max": 2359, - "step": 1, + "type": "time", "icon": "mdi:clock-end" } }, @@ -663,10 +633,7 @@ "homeassistant": { "publish": true, "name": "Slot 6 Start Time", - "type": "number", - "min": 0, - "max": 2358, - "step": 1, + "type": "time", "icon": "mdi:clock-start" } }, @@ -684,10 +651,7 @@ "homeassistant": { "publish": true, "name": "Slot 6 End Time", - "type": "number", - "min": 0, - "max": 2359, - "step": 1, + "type": "time", "icon": "mdi:clock-end" } }, @@ -763,10 +727,7 @@ "homeassistant": { "publish": true, "name": "Slot 7 Start Time", - "type": "number", - "min": 0, - "max": 2358, - "step": 1, + "type": "time", "icon": "mdi:clock-start" } }, @@ -784,10 +745,7 @@ "homeassistant": { "publish": true, "name": "Slot 7 End Time", - "type": "number", - "min": 0, - "max": 2359, - "step": 1, + "type": "time", "icon": "mdi:clock-end" } }, @@ -863,10 +821,7 @@ "homeassistant": { "publish": true, "name": "Slot 8 Start Time", - "type": "number", - "min": 0, - "max": 2358, - "step": 1, + "type": "time", "icon": "mdi:clock-start" } }, @@ -884,10 +839,7 @@ "homeassistant": { "publish": true, "name": "Slot 8 End Time", - "type": "number", - "min": 0, - "max": 2359, - "step": 1, + "type": "time", "icon": "mdi:clock-end" } }, @@ -963,10 +915,7 @@ "homeassistant": { "publish": true, "name": "Slot 9 Start Time", - "type": "number", - "min": 0, - "max": 2358, - "step": 1, + "type": "time", "icon": "mdi:clock-start" } }, @@ -984,10 +933,7 @@ "homeassistant": { "publish": true, "name": "Slot 9 End Time", - "type": "number", - "min": 0, - "max": 2359, - "step": 1, + "type": "time", "icon": "mdi:clock-end" } }, From abc95136484ba28668c8cc14bb7a95e7e37d7285 Mon Sep 17 00:00:00 2001 From: criticallimit Date: Sat, 27 Jun 2026 23:24:48 +0200 Subject: [PATCH 06/13] Update client.py --- grobro/ha/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grobro/ha/client.py b/grobro/ha/client.py index 9284f0a..a9b0e9b 100644 --- a/grobro/ha/client.py +++ b/grobro/ha/client.py @@ -443,7 +443,7 @@ def __on_message(self, client, userdata, msg: mqtt.MQTTMessage): parsed_value = 1 if raw_value.upper() == "ON" else 0 elif cmd_type == "time": - hour, minute = map(int, raw_value.split(":")) + hour, minute = map(int, raw_value) parsed_value = (hour << 8) | minute elif "_start_time" in cmd_name or "_end_time" in cmd_name: From ab74276dfc12073597c3b94255bdaef6c416f9a9 Mon Sep 17 00:00:00 2001 From: criticallimit Date: Sat, 27 Jun 2026 23:33:46 +0200 Subject: [PATCH 07/13] Update client.py --- grobro/ha/client.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/grobro/ha/client.py b/grobro/ha/client.py index a9b0e9b..25f6725 100644 --- a/grobro/ha/client.py +++ b/grobro/ha/client.py @@ -446,10 +446,6 @@ def __on_message(self, client, userdata, msg: mqtt.MQTTMessage): hour, minute = map(int, raw_value) parsed_value = (hour << 8) | minute - elif "_start_time" in cmd_name or "_end_time" in cmd_name: - hour, minute = divmod(int(raw_value), 100) - parsed_value = (hour << 8) | minute - else: parsed_value = int(raw_value) From a732cad2384484910aa02eb1157170b125eff9d0 Mon Sep 17 00:00:00 2001 From: criticallimit Date: Sat, 27 Jun 2026 23:52:18 +0200 Subject: [PATCH 08/13] Update client.py --- grobro/ha/client.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/grobro/ha/client.py b/grobro/ha/client.py index 25f6725..a9387ef 100644 --- a/grobro/ha/client.py +++ b/grobro/ha/client.py @@ -442,10 +442,6 @@ def __on_message(self, client, userdata, msg: mqtt.MQTTMessage): if cmd_type == "switch": parsed_value = 1 if raw_value.upper() == "ON" else 0 - elif cmd_type == "time": - hour, minute = map(int, raw_value) - parsed_value = (hour << 8) | minute - else: parsed_value = int(raw_value) From e75e2348a217f2adae0680e0ca57f58ddf8c7998 Mon Sep 17 00:00:00 2001 From: criticallimit Date: Sun, 28 Jun 2026 00:03:01 +0200 Subject: [PATCH 09/13] Update client.py --- grobro/ha/client.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/grobro/ha/client.py b/grobro/ha/client.py index a9387ef..f4ea21d 100644 --- a/grobro/ha/client.py +++ b/grobro/ha/client.py @@ -442,6 +442,9 @@ def __on_message(self, client, userdata, msg: mqtt.MQTTMessage): if cmd_type == "switch": parsed_value = 1 if raw_value.upper() == "ON" else 0 + elif cmd_type == "time": + parsed_value = int(raw_value) + else: parsed_value = int(raw_value) From e42221df32abd759645874bbf4cd1200e86498e7 Mon Sep 17 00:00:00 2001 From: criticallimit Date: Sun, 28 Jun 2026 00:11:21 +0200 Subject: [PATCH 10/13] Update client.py --- grobro/ha/client.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/grobro/ha/client.py b/grobro/ha/client.py index f4ea21d..3248d18 100644 --- a/grobro/ha/client.py +++ b/grobro/ha/client.py @@ -443,7 +443,12 @@ def __on_message(self, client, userdata, msg: mqtt.MQTTMessage): parsed_value = 1 if raw_value.upper() == "ON" else 0 elif cmd_type == "time": - parsed_value = int(raw_value) + raw_value = raw_value.zfill(4) + + hour = int(raw_value[:2]) + minute = int(raw_value[2:]) + + parsed_value = (hour << 8) | minute else: parsed_value = int(raw_value) From 9b6c794bcb1516647b0ab961cb489318c25cc25c Mon Sep 17 00:00:00 2001 From: criticallimit Date: Sun, 28 Jun 2026 00:20:23 +0200 Subject: [PATCH 11/13] Update client.py --- grobro/ha/client.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/grobro/ha/client.py b/grobro/ha/client.py index 3248d18..510e91d 100644 --- a/grobro/ha/client.py +++ b/grobro/ha/client.py @@ -442,13 +442,9 @@ def __on_message(self, client, userdata, msg: mqtt.MQTTMessage): if cmd_type == "switch": parsed_value = 1 if raw_value.upper() == "ON" else 0 - elif cmd_type == "time": - raw_value = raw_value.zfill(4) - - hour = int(raw_value[:2]) - minute = int(raw_value[2:]) - - parsed_value = (hour << 8) | minute + elif "_start_time" in cmd_name or "_end_time" in cmd_name: + hour, minute = divmod(int(raw_value), 100) + parsed_value = (hour * 256) + minute else: parsed_value = int(raw_value) From fe9af3f07e8fd58eaf164ec626f67cd7bbcb2265 Mon Sep 17 00:00:00 2001 From: criticallimit Date: Sun, 28 Jun 2026 00:30:22 +0200 Subject: [PATCH 12/13] Update client.py --- grobro/ha/client.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grobro/ha/client.py b/grobro/ha/client.py index 510e91d..439d827 100644 --- a/grobro/ha/client.py +++ b/grobro/ha/client.py @@ -442,8 +442,8 @@ def __on_message(self, client, userdata, msg: mqtt.MQTTMessage): if cmd_type == "switch": parsed_value = 1 if raw_value.upper() == "ON" else 0 - elif "_start_time" in cmd_name or "_end_time" in cmd_name: - hour, minute = divmod(int(raw_value), 100) + elif cmd_type == "time": + hour, minute = map(int, raw_value.split(":")[:2]) parsed_value = (hour * 256) + minute else: From 1d0a537d5354832fc738351a2506ba12a26c9027 Mon Sep 17 00:00:00 2001 From: criticallimit Date: Sun, 28 Jun 2026 00:42:31 +0200 Subject: [PATCH 13/13] Update client.py --- grobro/ha/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grobro/ha/client.py b/grobro/ha/client.py index 439d827..7bc3416 100644 --- a/grobro/ha/client.py +++ b/grobro/ha/client.py @@ -373,7 +373,7 @@ def __on_connect(self, client, userdata, flags, reason_code, properties): def __on_message(self, client, userdata, msg: mqtt.MQTTMessage): parts = msg.topic.removeprefix(f"{HA_BASE_TOPIC}/").split("/") - if len(parts) != 5 or parts[0] not in {"number", "button", "switch", "config"}: + if len(parts) != 5 or parts[0] not in {"number", "time", "button", "switch", "config"}: return cmd_type, _, device_id, cmd_name, action = parts