MAX transformation added

This commit is contained in:
2025-11-10 16:11:28 +01:00
parent a49d56df60
commit b57ddb1589
3 changed files with 346 additions and 15 deletions

View File

@@ -124,6 +124,79 @@ def _transform_thermostat_zigbee2mqtt_to_abstract(payload: dict[str, Any]) -> di
return payload
# ============================================================================
# HANDLER FUNCTIONS: max technology (Homegear MAX!)
# ============================================================================
def _transform_thermostat_max_to_vendor(payload: dict[str, Any]) -> str:
"""Transform abstract thermostat payload to MAX! (Homegear) format.
MAX! expects only the integer temperature value (no JSON).
Transformations:
- Extract 'target' temperature from payload
- Convert float to integer (MAX! only accepts integers)
- Return as plain string value
Example:
- Abstract: {'mode': 'heat', 'target': 22.5}
- MAX!: "22"
Note: MAX! ignores mode - it's always in heating mode
"""
if "target" not in payload:
logger.warning(f"MAX! thermostat payload missing 'target': {payload}")
return "21" # Default fallback
target_temp = payload["target"]
# Convert to integer (MAX! protocol requirement)
if isinstance(target_temp, (int, float)):
int_temp = int(round(target_temp))
return str(int_temp)
logger.warning(f"MAX! invalid target temperature type: {type(target_temp)}, value: {target_temp}")
return "21"
def _transform_thermostat_max_to_abstract(payload: str | int | float) -> dict[str, Any]:
"""Transform MAX! (Homegear) thermostat payload to abstract format.
MAX! sends only the integer temperature value (no JSON).
Transformations:
- Parse plain string/int value
- Convert to float for abstract protocol
- Wrap in abstract payload structure with mode='heat'
Example:
- MAX!: "22" or 22
- Abstract: {'target': 22.0, 'mode': 'heat'}
Note: MAX! doesn't send current temperature via SET_TEMPERATURE topic
"""
try:
# Handle both string and numeric input
if isinstance(payload, str):
target_temp = float(payload.strip())
elif isinstance(payload, (int, float)):
target_temp = float(payload)
else:
logger.warning(f"MAX! unexpected payload type: {type(payload)}, value: {payload}")
target_temp = 21.0
return {
"target": target_temp,
"mode": "heat" # MAX! is always in heating mode
}
except (ValueError, TypeError) as e:
logger.error(f"MAX! failed to parse temperature: {payload}, error: {e}")
return {
"target": 21.0,
"mode": "heat"
}
# ============================================================================
# REGISTRY: Maps (device_type, technology, direction) -> handler function
# ============================================================================
@@ -142,6 +215,8 @@ TRANSFORM_HANDLERS: dict[tuple[str, str, str], TransformHandler] = {
("thermostat", "simulator", "to_abstract"): _transform_thermostat_simulator_to_abstract,
("thermostat", "zigbee2mqtt", "to_vendor"): _transform_thermostat_zigbee2mqtt_to_vendor,
("thermostat", "zigbee2mqtt", "to_abstract"): _transform_thermostat_zigbee2mqtt_to_abstract,
("thermostat", "max", "to_vendor"): _transform_thermostat_max_to_vendor,
("thermostat", "max", "to_abstract"): _transform_thermostat_max_to_abstract,
}