Home Assistant Unofficial Reference 2024.12.1
climate.py
Go to the documentation of this file.
1 """Platform for climate integration."""
2 
3 from __future__ import annotations
4 
5 import logging
6 from typing import Any
7 
8 from aiohttp import ClientSession
9 from whirlpool.aircon import Aircon, FanSpeed as AirconFanSpeed, Mode as AirconMode
10 from whirlpool.auth import Auth
11 from whirlpool.backendselector import BackendSelector
12 
14  ENTITY_ID_FORMAT,
15  FAN_AUTO,
16  FAN_HIGH,
17  FAN_LOW,
18  FAN_MEDIUM,
19  FAN_OFF,
20  SWING_HORIZONTAL,
21  SWING_OFF,
22  ClimateEntity,
23  ClimateEntityFeature,
24  HVACMode,
25 )
26 from homeassistant.config_entries import ConfigEntry
27 from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature
28 from homeassistant.core import HomeAssistant
29 from homeassistant.helpers.aiohttp_client import async_get_clientsession
30 from homeassistant.helpers.device_registry import DeviceInfo
31 from homeassistant.helpers.entity import generate_entity_id
32 from homeassistant.helpers.entity_platform import AddEntitiesCallback
33 
34 from . import WhirlpoolData
35 from .const import DOMAIN
36 
37 _LOGGER = logging.getLogger(__name__)
38 
39 
40 AIRCON_MODE_MAP = {
41  AirconMode.Cool: HVACMode.COOL,
42  AirconMode.Heat: HVACMode.HEAT,
43  AirconMode.Fan: HVACMode.FAN_ONLY,
44 }
45 
46 HVAC_MODE_TO_AIRCON_MODE = {v: k for k, v in AIRCON_MODE_MAP.items()}
47 
48 AIRCON_FANSPEED_MAP = {
49  AirconFanSpeed.Off: FAN_OFF,
50  AirconFanSpeed.Auto: FAN_AUTO,
51  AirconFanSpeed.Low: FAN_LOW,
52  AirconFanSpeed.Medium: FAN_MEDIUM,
53  AirconFanSpeed.High: FAN_HIGH,
54 }
55 
56 FAN_MODE_TO_AIRCON_FANSPEED = {v: k for k, v in AIRCON_FANSPEED_MAP.items()}
57 
58 SUPPORTED_FAN_MODES = [FAN_AUTO, FAN_HIGH, FAN_MEDIUM, FAN_LOW, FAN_OFF]
59 SUPPORTED_HVAC_MODES = [
60  HVACMode.COOL,
61  HVACMode.HEAT,
62  HVACMode.FAN_ONLY,
63  HVACMode.OFF,
64 ]
65 SUPPORTED_MAX_TEMP = 30
66 SUPPORTED_MIN_TEMP = 16
67 SUPPORTED_SWING_MODES = [SWING_HORIZONTAL, SWING_OFF]
68 SUPPORTED_TARGET_TEMPERATURE_STEP = 1
69 
70 
72  hass: HomeAssistant,
73  config_entry: ConfigEntry,
74  async_add_entities: AddEntitiesCallback,
75 ) -> None:
76  """Set up entry."""
77  whirlpool_data: WhirlpoolData = hass.data[DOMAIN][config_entry.entry_id]
78 
79  aircons = [
81  hass,
82  ac_data["SAID"],
83  ac_data["NAME"],
84  whirlpool_data.backend_selector,
85  whirlpool_data.auth,
87  )
88  for ac_data in whirlpool_data.appliances_manager.aircons
89  ]
90  async_add_entities(aircons, True)
91 
92 
94  """Representation of an air conditioner."""
95 
96  _attr_fan_modes = SUPPORTED_FAN_MODES
97  _attr_has_entity_name = True
98  _attr_name = None
99  _attr_hvac_modes = SUPPORTED_HVAC_MODES
100  _attr_max_temp = SUPPORTED_MAX_TEMP
101  _attr_min_temp = SUPPORTED_MIN_TEMP
102  _attr_should_poll = False
103  _attr_supported_features = (
104  ClimateEntityFeature.TARGET_TEMPERATURE
105  | ClimateEntityFeature.FAN_MODE
106  | ClimateEntityFeature.SWING_MODE
107  | ClimateEntityFeature.TURN_OFF
108  | ClimateEntityFeature.TURN_ON
109  )
110  _attr_swing_modes = SUPPORTED_SWING_MODES
111  _attr_target_temperature_step = SUPPORTED_TARGET_TEMPERATURE_STEP
112  _attr_temperature_unit = UnitOfTemperature.CELSIUS
113  _enable_turn_on_off_backwards_compatibility = False
114 
115  def __init__(
116  self,
117  hass: HomeAssistant,
118  said: str,
119  name: str | None,
120  backend_selector: BackendSelector,
121  auth: Auth,
122  session: ClientSession,
123  ) -> None:
124  """Initialize the entity."""
125  self._aircon_aircon = Aircon(backend_selector, auth, said, session)
126  self.entity_identity_identity_id = generate_entity_id(ENTITY_ID_FORMAT, said, hass=hass)
127  self._attr_unique_id_attr_unique_id = said
128 
129  self._attr_device_info_attr_device_info = DeviceInfo(
130  identifiers={(DOMAIN, said)},
131  name=name if name is not None else said,
132  manufacturer="Whirlpool",
133  model="Sixth Sense",
134  )
135 
136  async def async_added_to_hass(self) -> None:
137  """Connect aircon to the cloud."""
138  self._aircon_aircon.register_attr_callback(self.async_write_ha_stateasync_write_ha_state)
139  await self._aircon_aircon.connect()
140 
141  async def async_will_remove_from_hass(self) -> None:
142  """Close Whrilpool Appliance sockets before removing."""
143  self._aircon_aircon.unregister_attr_callback(self.async_write_ha_stateasync_write_ha_state)
144  await self._aircon_aircon.disconnect()
145 
146  @property
147  def available(self) -> bool:
148  """Return True if entity is available."""
149  return self._aircon_aircon.get_online()
150 
151  @property
152  def current_temperature(self) -> float:
153  """Return the current temperature."""
154  return self._aircon_aircon.get_current_temp()
155 
156  @property
157  def target_temperature(self) -> float:
158  """Return the temperature we try to reach."""
159  return self._aircon_aircon.get_temp()
160 
161  async def async_set_temperature(self, **kwargs: Any) -> None:
162  """Set new target temperature."""
163  await self._aircon_aircon.set_temp(kwargs.get(ATTR_TEMPERATURE))
164 
165  @property
166  def current_humidity(self) -> int:
167  """Return the current humidity."""
168  return self._aircon_aircon.get_current_humidity()
169 
170  @property
171  def target_humidity(self) -> int:
172  """Return the humidity we try to reach."""
173  return self._aircon_aircon.get_humidity()
174 
175  async def async_set_humidity(self, humidity: int) -> None:
176  """Set new target humidity."""
177  await self._aircon_aircon.set_humidity(humidity)
178 
179  @property
180  def hvac_mode(self) -> HVACMode | None:
181  """Return current operation ie. heat, cool, fan."""
182  if not self._aircon_aircon.get_power_on():
183  return HVACMode.OFF
184 
185  mode: AirconMode = self._aircon_aircon.get_mode()
186  return AIRCON_MODE_MAP.get(mode)
187 
188  async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
189  """Set HVAC mode."""
190  if hvac_mode == HVACMode.OFF:
191  await self._aircon_aircon.set_power_on(False)
192  return
193 
194  if not (mode := HVAC_MODE_TO_AIRCON_MODE.get(hvac_mode)):
195  raise ValueError(f"Invalid hvac mode {hvac_mode}")
196 
197  await self._aircon_aircon.set_mode(mode)
198  if not self._aircon_aircon.get_power_on():
199  await self._aircon_aircon.set_power_on(True)
200 
201  @property
202  def fan_mode(self) -> str:
203  """Return the fan setting."""
204  fanspeed = self._aircon_aircon.get_fanspeed()
205  return AIRCON_FANSPEED_MAP.get(fanspeed, FAN_OFF)
206 
207  async def async_set_fan_mode(self, fan_mode: str) -> None:
208  """Set fan mode."""
209  if not (fanspeed := FAN_MODE_TO_AIRCON_FANSPEED.get(fan_mode)):
210  raise ValueError(f"Invalid fan mode {fan_mode}")
211  await self._aircon_aircon.set_fanspeed(fanspeed)
212 
213  @property
214  def swing_mode(self) -> str:
215  """Return the swing setting."""
216  return SWING_HORIZONTAL if self._aircon_aircon.get_h_louver_swing() else SWING_OFF
217 
218  async def async_set_swing_mode(self, swing_mode: str) -> None:
219  """Set new target temperature."""
220  await self._aircon_aircon.set_h_louver_swing(swing_mode == SWING_HORIZONTAL)
221 
222  async def async_turn_on(self) -> None:
223  """Turn device on."""
224  await self._aircon_aircon.set_power_on(True)
225 
226  async def async_turn_off(self) -> None:
227  """Turn device off."""
228  await self._aircon_aircon.set_power_on(False)
None async_set_hvac_mode(self, HVACMode hvac_mode)
Definition: climate.py:188
None __init__(self, HomeAssistant hass, str said, str|None name, BackendSelector backend_selector, Auth auth, ClientSession session)
Definition: climate.py:123
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)
Definition: climate.py:75
aiohttp.ClientSession async_get_clientsession(HomeAssistant hass, bool verify_ssl=True, socket.AddressFamily family=socket.AF_UNSPEC, ssl_util.SSLCipherList ssl_cipher=ssl_util.SSLCipherList.PYTHON_DEFAULT)
str generate_entity_id(str entity_id_format, str|None name, list[str]|None current_ids=None, HomeAssistant|None hass=None)
Definition: entity.py:108