Home Assistant Unofficial Reference 2024.12.1
humidifier.py
Go to the documentation of this file.
1 """Support for humidifiers."""
2 
3 from __future__ import annotations
4 
5 from enum import StrEnum
6 from typing import Any
7 
8 from aiocomelit import ComelitSerialBridgeObject
9 from aiocomelit.const import CLIMATE
10 
12  MODE_AUTO,
13  MODE_NORMAL,
14  HumidifierAction,
15  HumidifierDeviceClass,
16  HumidifierEntity,
17  HumidifierEntityFeature,
18 )
19 from homeassistant.config_entries import ConfigEntry
20 from homeassistant.core import HomeAssistant
21 from homeassistant.exceptions import ServiceValidationError
22 from homeassistant.helpers.entity_platform import AddEntitiesCallback
23 from homeassistant.helpers.update_coordinator import CoordinatorEntity
24 
25 from .const import DOMAIN
26 from .coordinator import ComelitSerialBridge
27 
28 
29 class HumidifierComelitMode(StrEnum):
30  """Serial Bridge humidifier modes."""
31 
32  AUTO = "A"
33  OFF = "O"
34  LOWER = "L"
35  UPPER = "U"
36 
37 
38 class HumidifierComelitCommand(StrEnum):
39  """Serial Bridge humidifier commands."""
40 
41  OFF = "off"
42  ON = "on"
43  MANUAL = "man"
44  SET = "set"
45  AUTO = "auto"
46  LOWER = "lower"
47  UPPER = "upper"
48 
49 
50 MODE_TO_ACTION: dict[str, HumidifierComelitCommand] = {
51  MODE_AUTO: HumidifierComelitCommand.AUTO,
52  MODE_NORMAL: HumidifierComelitCommand.MANUAL,
53 }
54 
55 
57  hass: HomeAssistant,
58  config_entry: ConfigEntry,
59  async_add_entities: AddEntitiesCallback,
60 ) -> None:
61  """Set up Comelit humidifiers."""
62 
63  coordinator: ComelitSerialBridge = hass.data[DOMAIN][config_entry.entry_id]
64 
65  entities: list[ComelitHumidifierEntity] = []
66  for device in coordinator.data[CLIMATE].values():
67  entities.append(
69  coordinator,
70  device,
71  config_entry.entry_id,
72  active_mode=HumidifierComelitMode.LOWER,
73  active_action=HumidifierAction.DRYING,
74  set_command=HumidifierComelitCommand.LOWER,
75  device_class=HumidifierDeviceClass.DEHUMIDIFIER,
76  )
77  )
78  entities.append(
80  coordinator,
81  device,
82  config_entry.entry_id,
83  active_mode=HumidifierComelitMode.UPPER,
84  active_action=HumidifierAction.HUMIDIFYING,
85  set_command=HumidifierComelitCommand.UPPER,
86  device_class=HumidifierDeviceClass.HUMIDIFIER,
87  ),
88  )
89 
90  async_add_entities(entities)
91 
92 
93 class ComelitHumidifierEntity(CoordinatorEntity[ComelitSerialBridge], HumidifierEntity):
94  """Humidifier device."""
95 
96  _attr_supported_features = HumidifierEntityFeature.MODES
97  _attr_available_modes = [MODE_NORMAL, MODE_AUTO]
98  _attr_min_humidity = 10
99  _attr_max_humidity = 90
100  _attr_has_entity_name = True
101 
102  def __init__(
103  self,
104  coordinator: ComelitSerialBridge,
105  device: ComelitSerialBridgeObject,
106  config_entry_entry_id: str,
107  active_mode: HumidifierComelitMode,
108  active_action: HumidifierAction,
109  set_command: HumidifierComelitCommand,
110  device_class: HumidifierDeviceClass,
111  ) -> None:
112  """Init light entity."""
113  self._api_api = coordinator.api
114  self._device_device_device = device
115  super().__init__(coordinator)
116  # Use config_entry.entry_id as base for unique_id
117  # because no serial number or mac is available
118  self._attr_unique_id_attr_unique_id = f"{config_entry_entry_id}-{device.index}-{device_class}"
119  self._attr_device_info_attr_device_info = coordinator.platform_device_info(device, device_class)
120  self._attr_device_class_attr_device_class = device_class
121  self._attr_translation_key_attr_translation_key = device_class.value
122  self._active_mode_active_mode = active_mode
123  self._active_action_active_action = active_action
124  self._set_command_set_command = set_command
125 
126  @property
127  def _humidifier(self) -> list[Any]:
128  """Return humidifier device data."""
129  # CLIMATE has a 2 item tuple:
130  # - first for Clima
131  # - second for Humidifier
132  return self.coordinator.data[CLIMATE][self._device_device_device.index].val[1]
133 
134  @property
135  def _api_mode(self) -> str:
136  """Return device mode."""
137  # Values from API: "O", "L", "U"
138  return self._humidifier_humidifier[2]
139 
140  @property
141  def _api_active(self) -> bool:
142  "Return device active/idle."
143  return self._humidifier_humidifier[1]
144 
145  @property
146  def _api_automatic(self) -> bool:
147  """Return device in automatic/manual mode."""
148  return self._humidifier_humidifier[3] == HumidifierComelitMode.AUTO
149 
150  @property
151  def target_humidity(self) -> float:
152  """Set target humidity."""
153  return self._humidifier_humidifier[4] / 10
154 
155  @property
156  def current_humidity(self) -> float:
157  """Return current humidity."""
158  return self._humidifier_humidifier[0] / 10
159 
160  @property
161  def is_on(self) -> bool | None:
162  """Return true is humidifier is on."""
163  return self._api_mode_api_mode_api_mode == self._active_mode_active_mode
164 
165  @property
166  def mode(self) -> str | None:
167  """Return current mode."""
168  return MODE_AUTO if self._api_automatic_api_automatic else MODE_NORMAL
169 
170  @property
171  def action(self) -> HumidifierAction | None:
172  """Return current action."""
173 
174  if self._api_mode_api_mode_api_mode == HumidifierComelitMode.OFF:
175  return HumidifierAction.OFF
176 
177  if self._api_active_api_active and self._api_mode_api_mode_api_mode == self._active_mode_active_mode:
178  return self._active_action_active_action
179 
180  return HumidifierAction.IDLE
181 
182  async def async_set_humidity(self, humidity: int) -> None:
183  """Set new target humidity."""
184  if self.modemodemodemode == HumidifierComelitMode.OFF:
186  translation_domain=DOMAIN,
187  translation_key="humidity_while_off",
188  )
189 
190  await self.coordinator.api.set_humidity_status(
191  self._device_device_device.index, HumidifierComelitCommand.MANUAL
192  )
193  await self.coordinator.api.set_humidity_status(
194  self._device_device_device.index, HumidifierComelitCommand.SET, humidity
195  )
196 
197  async def async_set_mode(self, mode: str) -> None:
198  """Set humidifier mode."""
199  await self.coordinator.api.set_humidity_status(
200  self._device_device_device.index, MODE_TO_ACTION[mode]
201  )
202 
203  async def async_turn_on(self, **kwargs: Any) -> None:
204  """Turn on."""
205  await self.coordinator.api.set_humidity_status(
206  self._device_device_device.index, self._set_command_set_command
207  )
208 
209  async def async_turn_off(self, **kwargs: Any) -> None:
210  """Turn off."""
211  await self.coordinator.api.set_humidity_status(
212  self._device_device_device.index, HumidifierComelitCommand.OFF
213  )
None __init__(self, ComelitSerialBridge coordinator, ComelitSerialBridgeObject device, str config_entry_entry_id, HumidifierComelitMode active_mode, HumidifierAction active_action, HumidifierComelitCommand set_command, HumidifierDeviceClass device_class)
Definition: humidifier.py:111
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)
Definition: humidifier.py:60