diff --git a/apps/abstraction/vendors/hottis_wago_modbus.py b/apps/abstraction/vendors/hottis_wago_modbus.py new file mode 100644 index 0000000..7cb8392 --- /dev/null +++ b/apps/abstraction/vendors/hottis_wago_modbus.py @@ -0,0 +1,58 @@ +"""Hottis Wago Modbus vendor transformations.""" + +import logging +from typing import Any + +logger = logging.getLogger(__name__) + +def transform_relay_to_vendor(payload: dict[str, Any]) -> str: + """Transform abstract relay payload to Hottis Wago Modbus format. + + Hottis Wago Modbus expects plain text 'true' or 'false' (not JSON). + + Example: + - Abstract: {'power': 'on'} + - Hottis Wago Modbus: 'true' or 'false' + """ + power = payload.get("power", "off") + + # Map abstract "on"/"off" to vendor "true"/"false" + if isinstance(power, str): + power_lower = power.lower() + if power_lower in {"on", "true", "1"}: + return "true" + if power_lower in {"off", "false", "0"}: + return "false" + + # Fallback: any truthy value -> "true", else "false" + return "true" if power else "false" + + +def transform_relay_to_abstract(payload: str) -> dict[str, Any]: + """Transform Hottis Wago Modbus relay payload to abstract format. + + Hottis Wago Modbus sends plain text 'true' or 'false'. + + Example: + - Hottis Wago Modbus: 'true' + - Abstract: {'power': 'on'} + """ + value = payload.strip().lower() + + if value == "true": + power = "on" + elif value == "false": + power = "off" + else: + # Fallback for unexpected values: keep as-is + logger.warning("Unexpected relay payload from Hottis Wago Modbus: %r", payload) + power = value + + return {"power": power} + + +# Registry of handlers for this vendor +HANDLERS = { + ("relay", "to_vendor"): transform_relay_to_vendor, + ("relay", "to_abstract"): transform_relay_to_abstract, +}