1 """AirTouch 5 component to control AirTouch 5 Climate Devices."""
6 from airtouch5py.airtouch5_simple_client
import Airtouch5SimpleClient
7 from airtouch5py.packets.ac_ability
import AcAbility
8 from airtouch5py.packets.ac_control
import (
15 from airtouch5py.packets.ac_status
import AcFanSpeed, AcMode, AcPowerState, AcStatus
16 from airtouch5py.packets.zone_control
import (
21 from airtouch5py.packets.zone_name
import ZoneName
22 from airtouch5py.packets.zone_status
import ZonePowerState, ZoneStatusZone
42 from .
import Airtouch5ConfigEntry
43 from .const
import DOMAIN, FAN_INTELLIGENT_AUTO, FAN_TURBO
44 from .entity
import Airtouch5Entity
46 _LOGGER = logging.getLogger(__name__)
48 AC_MODE_TO_HVAC_MODE = {
49 AcMode.AUTO: HVACMode.AUTO,
50 AcMode.AUTO_COOL: HVACMode.AUTO,
51 AcMode.AUTO_HEAT: HVACMode.AUTO,
52 AcMode.COOL: HVACMode.COOL,
53 AcMode.DRY: HVACMode.DRY,
54 AcMode.FAN: HVACMode.FAN_ONLY,
55 AcMode.HEAT: HVACMode.HEAT,
57 HVAC_MODE_TO_SET_AC_MODE = {
58 HVACMode.AUTO: SetAcMode.SET_TO_AUTO,
59 HVACMode.COOL: SetAcMode.SET_TO_COOL,
60 HVACMode.DRY: SetAcMode.SET_TO_DRY,
61 HVACMode.FAN_ONLY: SetAcMode.SET_TO_FAN,
62 HVACMode.HEAT: SetAcMode.SET_TO_HEAT,
66 AC_FAN_SPEED_TO_FAN_SPEED = {
67 AcFanSpeed.AUTO: FAN_AUTO,
68 AcFanSpeed.QUIET: FAN_DIFFUSE,
69 AcFanSpeed.LOW: FAN_LOW,
70 AcFanSpeed.MEDIUM: FAN_MEDIUM,
71 AcFanSpeed.HIGH: FAN_HIGH,
72 AcFanSpeed.POWERFUL: FAN_FOCUS,
73 AcFanSpeed.TURBO: FAN_TURBO,
74 AcFanSpeed.INTELLIGENT_AUTO_1: FAN_INTELLIGENT_AUTO,
75 AcFanSpeed.INTELLIGENT_AUTO_2: FAN_INTELLIGENT_AUTO,
76 AcFanSpeed.INTELLIGENT_AUTO_3: FAN_INTELLIGENT_AUTO,
77 AcFanSpeed.INTELLIGENT_AUTO_4: FAN_INTELLIGENT_AUTO,
78 AcFanSpeed.INTELLIGENT_AUTO_5: FAN_INTELLIGENT_AUTO,
79 AcFanSpeed.INTELLIGENT_AUTO_6: FAN_INTELLIGENT_AUTO,
81 FAN_MODE_TO_SET_AC_FAN_SPEED = {
82 FAN_AUTO: SetAcFanSpeed.SET_TO_AUTO,
83 FAN_DIFFUSE: SetAcFanSpeed.SET_TO_QUIET,
84 FAN_LOW: SetAcFanSpeed.SET_TO_LOW,
85 FAN_MEDIUM: SetAcFanSpeed.SET_TO_MEDIUM,
86 FAN_HIGH: SetAcFanSpeed.SET_TO_HIGH,
87 FAN_FOCUS: SetAcFanSpeed.SET_TO_POWERFUL,
88 FAN_TURBO: SetAcFanSpeed.SET_TO_TURBO,
89 FAN_INTELLIGENT_AUTO: SetAcFanSpeed.SET_TO_INTELLIGENT_AUTO,
95 config_entry: Airtouch5ConfigEntry,
96 async_add_entities: AddEntitiesCallback,
98 """Set up the Airtouch 5 Climate entities."""
99 client = config_entry.runtime_data
101 entities: list[ClimateEntity] = []
105 zone_to_ac: dict[int, AcAbility] = {}
107 for i
in range(ac.start_zone_number, ac.start_zone_number + ac.zone_count):
114 for zone
in client.zones
121 """Base class for Airtouch5 Climate Entities."""
123 _attr_temperature_unit = UnitOfTemperature.CELSIUS
124 _attr_translation_key = DOMAIN
125 _attr_target_temperature_step = 1
127 _enable_turn_on_off_backwards_compatibility =
False
131 """Representation of the AC unit. Used to control the overall HVAC Mode."""
133 def __init__(self, client: Airtouch5SimpleClient, ability: AcAbility) ->
None:
134 """Initialise the Climate Entity."""
139 identifiers={(DOMAIN, f
"ac_{ability.ac_number}")},
140 name=f
"AC {ability.ac_number}",
141 manufacturer=
"Polyaire",
145 if ability.supports_mode_auto:
147 if ability.supports_mode_cool:
149 if ability.supports_mode_dry:
151 if ability.supports_mode_fan:
153 if ability.supports_mode_heat:
157 ClimateEntityFeature.TARGET_TEMPERATURE | ClimateEntityFeature.FAN_MODE
161 ClimateEntityFeature.TURN_OFF | ClimateEntityFeature.TURN_ON
165 if ability.supports_fan_speed_quiet:
167 if ability.supports_fan_speed_low:
169 if ability.supports_fan_speed_medium:
171 if ability.supports_fan_speed_high:
173 if ability.supports_fan_speed_powerful:
175 if ability.supports_fan_speed_turbo:
177 if ability.supports_fan_speed_auto:
179 if ability.supports_fan_speed_intelligent_auto:
184 ability.min_cool_set_point, ability.min_heat_set_point
187 ability.max_cool_set_point, ability.max_heat_set_point
192 if self.
_ability_ability.ac_number
not in data:
194 status = data[self.
_ability_ability.ac_number]
198 if status.ac_power_state
in [AcPowerState.OFF, AcPowerState.AWAY_OFF]:
201 self.
_attr_hvac_mode_attr_hvac_mode = AC_MODE_TO_HVAC_MODE[status.ac_mode]
202 self.
_attr_fan_mode_attr_fan_mode = AC_FAN_SPEED_TO_FAN_SPEED[status.ac_fan_speed]
206 """Add data updated listener after this object has been initialized."""
212 """Remove data updated listener after this object has been initialized."""
219 power: SetPowerSetting = SetPowerSetting.KEEP_POWER_SETTING,
220 ac_mode: SetAcMode = SetAcMode.KEEP_AC_MODE,
221 fan: SetAcFanSpeed = SetAcFanSpeed.KEEP_AC_FAN_SPEED,
222 setpoint: SetpointControl = SetpointControl.KEEP_SETPOINT_VALUE,
233 packet = self.
_client_client.data_packet_factory.ac_control([control])
234 await self.
_client_client.send_packet(packet)
237 """Set new operation mode."""
238 set_power_setting: SetPowerSetting
239 set_ac_mode: SetAcMode
241 if hvac_mode == HVACMode.OFF:
242 set_power_setting = SetPowerSetting.SET_TO_OFF
243 set_ac_mode = SetAcMode.KEEP_AC_MODE
245 set_power_setting = SetPowerSetting.SET_TO_ON
246 if hvac_mode
not in HVAC_MODE_TO_SET_AC_MODE:
247 raise ValueError(f
"Unsupported hvac mode: {hvac_mode}")
248 set_ac_mode = HVAC_MODE_TO_SET_AC_MODE[hvac_mode]
250 await self.
_control_control(power=set_power_setting, ac_mode=set_ac_mode)
253 """Set new fan mode."""
254 if fan_mode
not in FAN_MODE_TO_SET_AC_FAN_SPEED:
255 raise ValueError(f
"Unsupported fan mode: {fan_mode}")
256 fan_speed = FAN_MODE_TO_SET_AC_FAN_SPEED[fan_mode]
257 await self.
_control_control(fan=fan_speed)
260 """Set new target temperatures."""
261 if (temp := kwargs.get(ATTR_TEMPERATURE))
is None:
262 _LOGGER.debug(
"Argument `temperature` is missing in set_temperature")
265 await self.
_control_control(setpoint=SetpointControl.CHANGE_SETPOINT, temp=temp)
269 """Representation of a Zone. Used to control the AC effect in the zone."""
271 _attr_hvac_modes = [HVACMode.OFF, HVACMode.FAN_ONLY]
272 _attr_preset_modes = [PRESET_NONE, PRESET_BOOST]
273 _attr_supported_features = (
274 ClimateEntityFeature.TARGET_TEMPERATURE
275 | ClimateEntityFeature.PRESET_MODE
276 | ClimateEntityFeature.TURN_OFF
277 | ClimateEntityFeature.TURN_ON
281 self, client: Airtouch5SimpleClient, name: ZoneName, ac: AcAbility
283 """Initialise the Climate Entity."""
289 identifiers={(DOMAIN, f
"zone_{name.zone_number}")},
291 manufacturer=
"Polyaire",
300 if self.
_name_name.zone_number
not in data:
302 status = data[self.
_name_name.zone_number]
306 if status.zone_power_state == ZonePowerState.OFF:
309 elif status.zone_power_state == ZonePowerState.ON:
312 elif status.zone_power_state == ZonePowerState.TURBO:
321 """Add data updated listener after this object has been initialized."""
327 """Remove data updated listener after this object has been initialized."""
334 zsv: ZoneSettingValue = ZoneSettingValue.KEEP_SETTING_VALUE,
335 power: ZoneSettingPower = ZoneSettingPower.KEEP_POWER_STATE,
338 control = ZoneControlZone(self.
_name_name.zone_number, zsv, power, value)
339 packet = self.
_client_client.data_packet_factory.zone_control([control])
340 await self.
_client_client.send_packet(packet)
343 """Set new operation mode."""
344 power: ZoneSettingPower
346 if hvac_mode
is HVACMode.OFF:
347 power = ZoneSettingPower.SET_TO_OFF
349 power = ZoneSettingPower.SET_TO_TURBO
351 power = ZoneSettingPower.SET_TO_ON
353 await self.
_control_control(power=power)
356 """Enable or disable Turbo. Done this way as we can't have a turbo HVACMode."""
357 power: ZoneSettingPower
358 if preset_mode == PRESET_BOOST:
359 power = ZoneSettingPower.SET_TO_TURBO
361 power = ZoneSettingPower.SET_TO_ON
363 await self.
_control_control(power=power)
366 """Set new target temperatures."""
368 if (temp := kwargs.get(ATTR_TEMPERATURE))
is None:
369 _LOGGER.debug(
"Argument `temperature` is missing in set_temperature")
373 zsv=ZoneSettingValue.SET_TARGET_SETPOINT,
378 """Turn the zone on."""
382 """Turn the zone off."""
None async_set_hvac_mode(self, HVACMode hvac_mode)
None async_set_temperature(self, **Any kwargs)
None __init__(self, Airtouch5SimpleClient client, AcAbility ability)
None async_added_to_hass(self)
None async_will_remove_from_hass(self)
None async_set_fan_mode(self, str fan_mode)
None _async_update_attrs(self, dict[int, AcStatus] data)
_attr_current_temperature
None _control(self, *SetPowerSetting power=SetPowerSetting.KEEP_POWER_SETTING, SetAcMode ac_mode=SetAcMode.KEEP_AC_MODE, SetAcFanSpeed fan=SetAcFanSpeed.KEEP_AC_FAN_SPEED, SetpointControl setpoint=SetpointControl.KEEP_SETPOINT_VALUE, int temp=0)
None _control(self, *ZoneSettingValue zsv=ZoneSettingValue.KEEP_SETTING_VALUE, ZoneSettingPower power=ZoneSettingPower.KEEP_POWER_STATE, float value=0)
None async_set_hvac_mode(self, HVACMode hvac_mode)
None async_turn_off(self)
None async_added_to_hass(self)
None async_will_remove_from_hass(self)
_attr_current_temperature
None async_set_temperature(self, **Any kwargs)
None __init__(self, Airtouch5SimpleClient client, ZoneName name, AcAbility ac)
None async_set_preset_mode(self, str preset_mode)
None _async_update_attrs(self, dict[int, ZoneStatusZone] data)
None async_set_hvac_mode(self, HVACMode hvac_mode)
list[HVACMode] hvac_modes(self)
None async_write_ha_state(self)
None async_setup_entry(HomeAssistant hass, Airtouch5ConfigEntry config_entry, AddEntitiesCallback async_add_entities)