""" A custom data class to manage specific HVAC modes for VTherm. """ import logging from vtherm_api.log_collector import get_vtherm_logger from homeassistant.components.climate.const import HVACMode from homeassistant.const import STATE_UNAVAILABLE, STATE_UNKNOWN OFF = HVACMode.OFF.value HEAT = HVACMode.HEAT.value COOL = HVACMode.COOL.value AUTO = HVACMode.AUTO.value DRY = HVACMode.DRY.value FAN_ONLY = HVACMode.FAN_ONLY.value HEAT_COOL = HVACMode.HEAT_COOL.value SLEEP = "sleep" VALID_HVAC_MODES = {OFF, HEAT, COOL, AUTO, DRY, FAN_ONLY, HEAT_COOL, SLEEP, STATE_UNAVAILABLE, STATE_UNKNOWN} _LOGGER = get_vtherm_logger(__name__) class VThermHvacMode: """ Container and validator for supported HVAC operating modes. """ def __init__(self, hvac_mode: str): """ Initialize a VThermHvacMode instance. Args: hvac_mode (VThermHvacMode): The HVAC mode to set. Raises: ValueError: If the mode is not supported. """ if str(hvac_mode) not in VALID_HVAC_MODES or not isinstance(hvac_mode, str): _LOGGER.warning("Unsupported HVAC mode: '%s'. It may be temporary at startup. Your VTherm will be set to OFF mode.", hvac_mode) hvac_mode = STATE_UNKNOWN self._hvac_mode: str = hvac_mode def __str__(self): return self._hvac_mode def __eq__(self, other: object) -> bool: if isinstance(other, str): return self._hvac_mode == other else: return self._hvac_mode == str(other) def __repr__(self): return f"[VThermHvacMode: {self._hvac_mode}]" def to_json(self) -> str: """Convert to JSON serializable string.""" return self._hvac_mode @classmethod def from_json(cls, json_value: str) -> "VThermHvacMode": """Create instance from JSON serializable string.""" return cls(json_value) VThermHvacMode_OFF = VThermHvacMode(OFF) VThermHvacMode_HEAT = VThermHvacMode(HEAT) VThermHvacMode_COOL = VThermHvacMode(COOL) VThermHvacMode_AUTO = VThermHvacMode(AUTO) VThermHvacMode_DRY = VThermHvacMode(DRY) VThermHvacMode_FAN_ONLY = VThermHvacMode(FAN_ONLY) VThermHvacMode_HEAT_COOL = VThermHvacMode(HEAT_COOL) VThermHvacMode_SLEEP = VThermHvacMode(SLEEP) VThermHvacMode_UNKNOWN = VThermHvacMode(STATE_UNKNOWN) VThermHvacMode_UNAVAILABLE = VThermHvacMode(STATE_UNAVAILABLE) # Map statique pour conversion HA -> VTherm HA_TO_VTHERM_MAP = { HVACMode.OFF: VThermHvacMode_OFF, HVACMode.HEAT: VThermHvacMode_HEAT, HVACMode.COOL: VThermHvacMode_COOL, HVACMode.AUTO: VThermHvacMode_AUTO, HVACMode.DRY: VThermHvacMode_DRY, HVACMode.FAN_ONLY: VThermHvacMode_FAN_ONLY, HVACMode.HEAT_COOL: VThermHvacMode_HEAT_COOL, SLEEP: VThermHvacMode_SLEEP, STATE_UNAVAILABLE: VThermHvacMode_UNAVAILABLE, STATE_UNKNOWN: VThermHvacMode_UNKNOWN, } # Map statique pour conversion VTherm -> HA VTHERM_TO_HA_MAP = { OFF: HVACMode.OFF, HEAT: HVACMode.HEAT, COOL: HVACMode.COOL, AUTO: HVACMode.AUTO, DRY: HVACMode.DRY, FAN_ONLY: HVACMode.FAN_ONLY, HEAT_COOL: HVACMode.HEAT_COOL, SLEEP: SLEEP, # SLEEP doesn't exist in HA, we map to a new string STATE_UNAVAILABLE: STATE_UNAVAILABLE, STATE_UNKNOWN: STATE_UNKNOWN, } VTHERM_TO_LEGACY_HA_MAP = { OFF: HVACMode.OFF, HEAT: HVACMode.HEAT, COOL: HVACMode.COOL, AUTO: HVACMode.AUTO, DRY: HVACMode.DRY, FAN_ONLY: HVACMode.FAN_ONLY, HEAT_COOL: HVACMode.HEAT_COOL, SLEEP: HVACMode.OFF, # SLEEP is mapped to OFF STATE_UNAVAILABLE: STATE_UNAVAILABLE, STATE_UNKNOWN: STATE_UNKNOWN, } def from_ha_hvac_mode(ha_hvac_mode: HVACMode | None) -> VThermHvacMode | None: """ Convert a Home Assistant HVACMode (enum or str) to a VThermHvacMode instance. Args: ha_hvac_mode (HVACMode | str): The Home Assistant HVAC mode. Returns: VThermHvacMode: The corresponding VThermHvacMode instance. """ if ha_hvac_mode is None: return None # Si enum, utiliser la map if isinstance(ha_hvac_mode, HVACMode): converter = HA_TO_VTHERM_MAP.get(ha_hvac_mode) if converter: return converter else: raise ValueError(f"HA HVACMode not found: {ha_hvac_mode}") def to_ha_hvac_mode(vtherm_hvac_mode: VThermHvacMode | None) -> HVACMode | None: """ Convert a VThermHvacMode instance to a Home Assistant HVACMode (enum or str). Args: vtherm_hvac_mode (VThermHvacMode): The VThermHvacMode instance. Returns: HVACMode | None: The corresponding Home Assistant HVACMode or None. """ if vtherm_hvac_mode is None: return None return VTHERM_TO_HA_MAP.get(str(vtherm_hvac_mode)) def to_legacy_ha_hvac_mode(vtherm_hvac_mode: VThermHvacMode | None) -> HVACMode | None: """ Convert a VThermHvacMode instance to a Home Assistant HVACMode (enum or str) and replace SLEEP with OFF. Args: vtherm_hvac_mode (VThermHvacMode): The VThermHvacMode instance. Returns: HVACMode | None: The corresponding Home Assistant HVACMode or None. """ if vtherm_hvac_mode is None: return None return VTHERM_TO_LEGACY_HA_MAP.get(str(vtherm_hvac_mode))