From 6310fedeeacddc6b65d5d26ebc1b8b991fd91559 Mon Sep 17 00:00:00 2001 From: Wolfgang Hottgenroth Date: Mon, 10 Nov 2025 17:07:41 +0100 Subject: [PATCH] zigbee2mqtt thermostat transformation --- apps/abstraction/transformation.py | 43 +++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/apps/abstraction/transformation.py b/apps/abstraction/transformation.py index 964f8ff..fbc3976 100644 --- a/apps/abstraction/transformation.py +++ b/apps/abstraction/transformation.py @@ -111,17 +111,52 @@ def _transform_light_zigbee2mqtt_to_abstract(payload: dict[str, Any]) -> dict[st def _transform_thermostat_zigbee2mqtt_to_vendor(payload: dict[str, Any]) -> dict[str, Any]: """Transform abstract thermostat payload to zigbee2mqtt format. - zigbee2mqtt uses same format as abstract protocol (no transformation needed). + Transformations: + - target -> current_heating_setpoint (as string) + - mode is ignored (zigbee2mqtt thermostats use system_mode in state only) + + Example: + - Abstract: {'target': 22.0} + - zigbee2mqtt: {'current_heating_setpoint': '22.0'} """ - return payload + vendor_payload = {} + + if "target" in payload: + # zigbee2mqtt expects current_heating_setpoint as string + vendor_payload["current_heating_setpoint"] = str(payload["target"]) + + return vendor_payload def _transform_thermostat_zigbee2mqtt_to_abstract(payload: dict[str, Any]) -> dict[str, Any]: """Transform zigbee2mqtt thermostat payload to abstract format. - zigbee2mqtt uses same format as abstract protocol (no transformation needed). + Transformations: + - current_heating_setpoint -> target (as float) + - local_temperature -> current (as float) + - system_mode -> mode + + Example: + - zigbee2mqtt: {'current_heating_setpoint': 15, 'local_temperature': 23, 'system_mode': 'heat'} + - Abstract: {'target': 15.0, 'current': 23.0, 'mode': 'heat'} """ - return payload + abstract_payload = {} + + # Extract target temperature + if "current_heating_setpoint" in payload: + setpoint = payload["current_heating_setpoint"] + abstract_payload["target"] = float(setpoint) + + # Extract current temperature + if "local_temperature" in payload: + current = payload["local_temperature"] + abstract_payload["current"] = float(current) + + # Extract mode + if "system_mode" in payload: + abstract_payload["mode"] = payload["system_mode"] + + return abstract_payload # ============================================================================