Compare commits

...

3 Commits
0.8.2 ... 0.8.5

Author SHA1 Message Date
bd1f3bc8c9 Hottis PV Modbus sensor
All checks were successful
ci/woodpecker/tag/build/5 Pipeline was successful
ci/woodpecker/tag/build/6 Pipeline was successful
ci/woodpecker/tag/namespace Pipeline was successful
ci/woodpecker/tag/config Pipeline was successful
ci/woodpecker/tag/build/4 Pipeline was successful
ci/woodpecker/tag/build/1 Pipeline was successful
ci/woodpecker/tag/build/7 Pipeline was successful
ci/woodpecker/tag/build/2 Pipeline was successful
ci/woodpecker/tag/build/3 Pipeline was successful
ci/woodpecker/tag/deploy/1 Pipeline was successful
ci/woodpecker/tag/deploy/3 Pipeline was successful
ci/woodpecker/tag/deploy/2 Pipeline was successful
ci/woodpecker/tag/deploy/6 Pipeline was successful
ci/woodpecker/tag/deploy/4 Pipeline was successful
ci/woodpecker/tag/deploy/5 Pipeline was successful
ci/woodpecker/tag/ingress Pipeline was successful
2025-12-09 11:57:49 +01:00
f9df70cf68 Hottis PV Modbus transformation
All checks were successful
ci/woodpecker/tag/build/5 Pipeline was successful
ci/woodpecker/tag/build/6 Pipeline was successful
ci/woodpecker/tag/build/4 Pipeline was successful
ci/woodpecker/tag/namespace Pipeline was successful
ci/woodpecker/tag/build/1 Pipeline was successful
ci/woodpecker/tag/build/7 Pipeline was successful
ci/woodpecker/tag/build/3 Pipeline was successful
ci/woodpecker/tag/config Pipeline was successful
ci/woodpecker/tag/build/2 Pipeline was successful
ci/woodpecker/tag/deploy/2 Pipeline was successful
ci/woodpecker/tag/deploy/1 Pipeline was successful
ci/woodpecker/tag/deploy/6 Pipeline was successful
ci/woodpecker/tag/deploy/4 Pipeline was successful
ci/woodpecker/tag/deploy/5 Pipeline was successful
ci/woodpecker/tag/deploy/3 Pipeline was successful
ci/woodpecker/tag/ingress Pipeline was successful
2025-12-09 11:17:02 +01:00
5364b855aa add vendor hottis wago modbus 3
All checks were successful
ci/woodpecker/tag/build/5 Pipeline was successful
ci/woodpecker/tag/build/6 Pipeline was successful
ci/woodpecker/tag/build/4 Pipeline was successful
ci/woodpecker/tag/namespace Pipeline was successful
ci/woodpecker/tag/build/1 Pipeline was successful
ci/woodpecker/tag/build/7 Pipeline was successful
ci/woodpecker/tag/config Pipeline was successful
ci/woodpecker/tag/build/3 Pipeline was successful
ci/woodpecker/tag/build/2 Pipeline was successful
ci/woodpecker/tag/deploy/2 Pipeline was successful
ci/woodpecker/tag/deploy/1 Pipeline was successful
ci/woodpecker/tag/deploy/4 Pipeline was successful
ci/woodpecker/tag/deploy/3 Pipeline was successful
ci/woodpecker/tag/deploy/5 Pipeline was successful
ci/woodpecker/tag/deploy/6 Pipeline was successful
ci/woodpecker/tag/ingress Pipeline was successful
2025-12-08 16:57:57 +01:00
4 changed files with 100 additions and 9 deletions

View File

@@ -23,17 +23,40 @@ def transform_relay_to_vendor(payload: dict[str, Any]) -> str:
def transform_relay_to_abstract(payload: str) -> dict[str, Any]: def transform_relay_to_abstract(payload: str) -> dict[str, Any]:
"""Transform Hottis Modbus relay payload to abstract format. """Transform Hottis Modbus relay payload to abstract format.
Hottis Modbus sends JSON like: Hottis Modbus sends plain text 'on' or 'off'.
{"status": "Ok", "timestamp": "...", "state": false, "cnt": 528} Example:
- Hottis PV Modbus: 'on'
- Abstract: {'power': 'on'}
"""
return {"power": payload.strip()}
def transform_contact_sensor_to_vendor(payload: dict[str, Any]) -> str:
"""Transform abstract contact sensor payload to format.
Contact sensors are read-only.
"""
logger.warning("Contact sensors are read-only - SET commands should not be used")
return json.dumps(payload)
def transform_contact_sensor_to_abstract(payload: str) -> dict[str, Any]:
"""Transform contact sensor payload to abstract format.
MAX! sends "true"/"false" (string or bool) on STATE topic.
Transformations: Transformations:
- state: true -> power: 'on' - "true" or True -> "open" (window/door open)
- state: false -> power: 'off' - "false" or False -> "closed" (window/door closed)
Example:
- contact sensor: "off"
- Abstract: {"contact": "open"}
""" """
data = json.loads(payload) contact_value = payload.strip().lower() == "off"
state = data.get("state", False) return {
power = "on" if bool(state) else "off" "contact": "open" if contact_value else "closed"
return {"power": power} }
def transform_three_phase_powermeter_to_vendor(payload: dict[str, Any]) -> str: def transform_three_phase_powermeter_to_vendor(payload: dict[str, Any]) -> str:

View File

@@ -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,
}

View File

@@ -860,7 +860,6 @@ devices:
topics: topics:
set: "IoT/Car/Control" set: "IoT/Car/Control"
state: "IoT/Car/Control/State" state: "IoT/Car/Control/State"
- device_id: powermeter_caroutlet - device_id: powermeter_caroutlet
name: Car Outlet name: Car Outlet
type: three_phase_powermeter type: three_phase_powermeter
@@ -868,6 +867,13 @@ devices:
technology: hottis_pv_modbus technology: hottis_pv_modbus
topics: topics:
state: "IoT/Car/Values" state: "IoT/Car/Values"
- device_id: sensor_caroutlet
name: Car Outlet
type: contact
cap_version: contact_sensor@1.0.0
technology: hottis_pv_modbus
topics:
state: IoT/Car/Feedback/State
- device_id: schranklicht_flur_vor_kueche - device_id: schranklicht_flur_vor_kueche
name: Schranklicht Flur vor Küche name: Schranklicht Flur vor Küche

View File

@@ -321,5 +321,9 @@ rooms:
title: Ladestrom title: Ladestrom
icon: 📊 icon: 📊
rank: 320 rank: 320
- device_id: sensor_caroutlet
title: Ladestrom
icon: 🪟
rank: 330