diff --git a/homeassistant/components/melcloud/climate.py b/homeassistant/components/melcloud/climate.py index e2d1fdd984d814..ea57d86c216da8 100644 --- a/homeassistant/components/melcloud/climate.py +++ b/homeassistant/components/melcloud/climate.py @@ -37,14 +37,14 @@ from .const import ( ATTR_STATUS, ATTR_VANE_HORIZONTAL, - ATTR_VANE_HORIZONTAL_POSITIONS, ATTR_VANE_VERTICAL, - ATTR_VANE_VERTICAL_POSITIONS, CONF_POSITION, DOMAIN, SERVICE_SET_VANE_HORIZONTAL, SERVICE_SET_VANE_VERTICAL, TEMP_UNIT_LOOKUP, + HorSwingModes, + VertSwingModes, ) SCAN_INTERVAL = timedelta(seconds=60) @@ -62,6 +62,31 @@ ATA_HVAC_MODE_REVERSE_LOOKUP = {v: k for k, v in ATA_HVAC_MODE_LOOKUP.items()} +ATA_HVAC_HVANE_LOOKUP = { + ata.H_VANE_POSITION_AUTO: HorSwingModes.Auto, + ata.H_VANE_POSITION_1: HorSwingModes.Left, + ata.H_VANE_POSITION_2: HorSwingModes.MiddleLeft, + ata.H_VANE_POSITION_3: HorSwingModes.Middle, + ata.H_VANE_POSITION_4: HorSwingModes.MiddleRight, + ata.H_VANE_POSITION_5: HorSwingModes.Right, + ata.H_VANE_POSITION_SPLIT: HorSwingModes.Split, + ata.H_VANE_POSITION_SWING: HorSwingModes.Swing, +} +ATA_HVAC_HVANE_REVERSE_LOOKUP = {v: k for k, v in ATA_HVAC_HVANE_LOOKUP.items()} + + +ATA_HVAC_VVANE_LOOKUP = { + ata.V_VANE_POSITION_AUTO: VertSwingModes.Auto, + ata.V_VANE_POSITION_1: VertSwingModes.Top, + ata.V_VANE_POSITION_2: VertSwingModes.MiddleTop, + ata.V_VANE_POSITION_3: VertSwingModes.Middle, + ata.V_VANE_POSITION_4: VertSwingModes.MiddleBottom, + ata.V_VANE_POSITION_5: VertSwingModes.Bottom, + ata.V_VANE_POSITION_SWING: VertSwingModes.Swing, +} +ATA_HVAC_VVANE_REVERSE_LOOKUP = {v: k for k, v in ATA_HVAC_VVANE_LOOKUP.items()} + + ATW_ZONE_HVAC_MODE_LOOKUP = { atw.ZONE_OPERATION_MODE_HEAT: HVAC_MODE_HEAT, atw.ZONE_OPERATION_MODE_COOL: HVAC_MODE_COOL, @@ -131,6 +156,9 @@ def __init__(self, device: MelCloudDevice, ata_device: AtaDevice) -> None: """Initialize the climate.""" super().__init__(device) self._device = ata_device + self._support_ver_swing = len(self._device.vane_vertical_positions) > 0 + self._support_hor_swing = len(self._device.vane_horizontal_positions) > 0 + self._set_hor_swing = self._support_hor_swing and not self._support_ver_swing @property def unique_id(self) -> Optional[str]: @@ -150,19 +178,13 @@ def device_state_attributes(self) -> Optional[Dict[str, Any]]: vane_horizontal = self._device.vane_horizontal if vane_horizontal: attr.update( - { - ATTR_VANE_HORIZONTAL: vane_horizontal, - ATTR_VANE_HORIZONTAL_POSITIONS: self._device.vane_horizontal_positions, - } + {ATTR_VANE_HORIZONTAL: ATA_HVAC_HVANE_LOOKUP.get(vane_horizontal, None)} ) vane_vertical = self._device.vane_vertical if vane_vertical: attr.update( - { - ATTR_VANE_VERTICAL: vane_vertical, - ATTR_VANE_VERTICAL_POSITIONS: self._device.vane_vertical_positions, - } + {ATTR_VANE_VERTICAL: ATA_HVAC_VVANE_LOOKUP.get(vane_vertical, None)} ) return attr @@ -233,38 +255,93 @@ def fan_modes(self) -> Optional[List[str]]: async def async_set_vane_horizontal(self, position: str) -> None: """Set horizontal vane position.""" - if position not in self._device.vane_horizontal_positions: + operation_mode = ATA_HVAC_HVANE_REVERSE_LOOKUP.get(position, "") + if operation_mode not in self._device.vane_horizontal_positions: + valid_pos = [ + ATA_HVAC_HVANE_LOOKUP.get(mode) + for mode in self._device.vane_horizontal_positions + ] raise ValueError( - f"Invalid horizontal vane position {position}. Valid positions: [{self._device.vane_horizontal_positions}]." + f"Invalid horizontal vane position [{position}]. Valid positions: {valid_pos}." ) - await self._device.set({ata.PROPERTY_VANE_HORIZONTAL: position}) + await self._device.set({ata.PROPERTY_VANE_HORIZONTAL: operation_mode}) async def async_set_vane_vertical(self, position: str) -> None: """Set vertical vane position.""" - if position not in self._device.vane_vertical_positions: + operation_mode = ATA_HVAC_VVANE_REVERSE_LOOKUP.get(position, "") + if operation_mode not in self._device.vane_vertical_positions: + valid_pos = [ + ATA_HVAC_VVANE_LOOKUP.get(mode) + for mode in self._device.vane_vertical_positions + ] raise ValueError( - f"Invalid vertical vane position {position}. Valid positions: [{self._device.vane_vertical_positions}]." + f"Invalid vertical vane position [{position}]. Valid positions: {valid_pos}." ) - await self._device.set({ata.PROPERTY_VANE_VERTICAL: position}) + await self._device.set({ata.PROPERTY_VANE_VERTICAL: operation_mode}) @property def swing_mode(self) -> Optional[str]: - """Return vertical vane position or mode.""" - return self._device.vane_vertical + """Return the swing mode setting.""" + swing = None + if self._set_hor_swing and self._support_hor_swing: + mode = self._device.vane_horizontal + if mode is not None: + swing = ATA_HVAC_HVANE_LOOKUP.get(mode) + elif self._support_ver_swing: + mode = self._device.vane_vertical + if mode is not None: + swing = ATA_HVAC_VVANE_LOOKUP.get(mode) + + if swing is None: + return "Auto" + + return swing async def async_set_swing_mode(self, swing_mode) -> None: - """Set vertical vane position or mode.""" - await self.async_set_vane_vertical(swing_mode) + """Set new target swing mode.""" + is_hor_swing = False + operation_mode = ATA_HVAC_VVANE_REVERSE_LOOKUP.get(swing_mode) + if operation_mode is None: + operation_mode = ATA_HVAC_HVANE_REVERSE_LOOKUP.get(swing_mode) + if operation_mode is None: + raise ValueError(f"Invalid swing_mode [{swing_mode}].") + + is_hor_swing = True + curr_mode = self._device.vane_horizontal + valid_swing_modes = self._device.vane_horizontal_positions + props = {ata.PROPERTY_VANE_HORIZONTAL: operation_mode} + else: + curr_mode = self._device.vane_vertical + valid_swing_modes = self._device.vane_vertical_positions + props = {ata.PROPERTY_VANE_VERTICAL: operation_mode} + + if operation_mode not in valid_swing_modes: + raise ValueError(f"Invalid swing_mode [{swing_mode}].") + + self._set_hor_swing = is_hor_swing + if curr_mode != operation_mode: + await self._device.set(props) @property - def swing_modes(self) -> Optional[str]: - """Return a list of available vertical vane positions and modes.""" - return self._device.vane_vertical_positions + def swing_modes(self) -> Optional[List[str]]: + """Return the list of available swing modes.""" + list_modes = [ + ATA_HVAC_VVANE_LOOKUP.get(mode) + for mode in self._device.vane_vertical_positions + ] + for mode in self._device.vane_horizontal_positions: + list_modes.append(ATA_HVAC_HVANE_LOOKUP.get(mode)) + + return list_modes @property def supported_features(self) -> int: """Return the list of supported features.""" - return SUPPORT_FAN_MODE | SUPPORT_TARGET_TEMPERATURE | SUPPORT_SWING_MODE + supp_feature = SUPPORT_FAN_MODE | SUPPORT_TARGET_TEMPERATURE + if self._support_ver_swing or self._support_hor_swing: + supp_feature |= SUPPORT_SWING_MODE + + return supp_feature async def async_turn_on(self) -> None: """Turn the entity on.""" diff --git a/homeassistant/components/melcloud/const.py b/homeassistant/components/melcloud/const.py index d58f483d441eee..87fbd824961681 100644 --- a/homeassistant/components/melcloud/const.py +++ b/homeassistant/components/melcloud/const.py @@ -9,9 +9,7 @@ ATTR_STATUS = "status" ATTR_VANE_HORIZONTAL = "vane_horizontal" -ATTR_VANE_HORIZONTAL_POSITIONS = "vane_horizontal_positions" ATTR_VANE_VERTICAL = "vane_vertical" -ATTR_VANE_VERTICAL_POSITIONS = "vane_vertical_positions" SERVICE_SET_VANE_HORIZONTAL = "set_vane_horizontal" SERVICE_SET_VANE_VERTICAL = "set_vane_vertical" @@ -21,3 +19,28 @@ UNIT_TEMP_FAHRENHEIT: TEMP_FAHRENHEIT, } TEMP_UNIT_REVERSE_LOOKUP = {v: k for k, v in TEMP_UNIT_LOOKUP.items()} + + +class HorSwingModes: + """Horizontal swing modes names.""" + + Auto = "HorizontalAuto" + Left = "HorizontalLeft" + MiddleLeft = "HorizontalMiddleLeft" + Middle = "HorizontalMiddle" + MiddleRight = "HorizontalMiddleRight" + Right = "HorizontalRight" + Split = "HorizontalSplit" + Swing = "HorizontalSwing" + + +class VertSwingModes: + """Vertical swing modes names.""" + + Auto = "VerticalAuto" + Top = "VerticalTop" + MiddleTop = "VerticalMiddleTop" + Middle = "VerticalMiddle" + MiddleBottom = "VerticalMiddleBottom" + Bottom = "VerticalBottom" + Swing = "VerticalSwing"