Home Assistant Unofficial Reference 2024.12.1
humidifier.py
Go to the documentation of this file.
1 """Representation of Z-Wave humidifiers."""
2 
3 from __future__ import annotations
4 
5 from dataclasses import dataclass
6 from typing import Any
7 
8 from zwave_js_server.client import Client as ZwaveClient
9 from zwave_js_server.const import CommandClass
10 from zwave_js_server.const.command_class.humidity_control import (
11  HUMIDITY_CONTROL_SETPOINT_PROPERTY,
12  HumidityControlMode,
13  HumidityControlSetpointType,
14 )
15 from zwave_js_server.model.driver import Driver
16 from zwave_js_server.model.value import Value as ZwaveValue
17 
19  DEFAULT_MAX_HUMIDITY,
20  DEFAULT_MIN_HUMIDITY,
21  DOMAIN as HUMIDIFIER_DOMAIN,
22  HumidifierDeviceClass,
23  HumidifierEntity,
24  HumidifierEntityDescription,
25 )
26 from homeassistant.config_entries import ConfigEntry
27 from homeassistant.core import HomeAssistant, callback
28 from homeassistant.helpers.dispatcher import async_dispatcher_connect
29 from homeassistant.helpers.entity_platform import AddEntitiesCallback
30 
31 from .const import DATA_CLIENT, DOMAIN
32 from .discovery import ZwaveDiscoveryInfo
33 from .entity import ZWaveBaseEntity
34 
35 PARALLEL_UPDATES = 0
36 
37 
38 @dataclass(frozen=True, kw_only=True)
40  """A class that describes the humidifier or dehumidifier entity."""
41 
42  # The "on" control mode for this entity, e.g. HUMIDIFY for humidifier
43  on_mode: HumidityControlMode
44 
45  # The "on" control mode for the inverse entity, e.g. DEHUMIDIFY for humidifier
46  inverse_mode: HumidityControlMode
47 
48  # The setpoint type controlled by this entity
49  setpoint_type: HumidityControlSetpointType
50 
51 
52 HUMIDIFIER_ENTITY_DESCRIPTION = ZwaveHumidifierEntityDescription(
53  key="humidifier",
54  device_class=HumidifierDeviceClass.HUMIDIFIER,
55  on_mode=HumidityControlMode.HUMIDIFY,
56  inverse_mode=HumidityControlMode.DEHUMIDIFY,
57  setpoint_type=HumidityControlSetpointType.HUMIDIFIER,
58 )
59 
60 
61 DEHUMIDIFIER_ENTITY_DESCRIPTION = ZwaveHumidifierEntityDescription(
62  key="dehumidifier",
63  device_class=HumidifierDeviceClass.DEHUMIDIFIER,
64  on_mode=HumidityControlMode.DEHUMIDIFY,
65  inverse_mode=HumidityControlMode.HUMIDIFY,
66  setpoint_type=HumidityControlSetpointType.DEHUMIDIFIER,
67 )
68 
69 
71  hass: HomeAssistant,
72  config_entry: ConfigEntry,
73  async_add_entities: AddEntitiesCallback,
74 ) -> None:
75  """Set up Z-Wave humidifier from config entry."""
76  client: ZwaveClient = config_entry.runtime_data[DATA_CLIENT]
77 
78  @callback
79  def async_add_humidifier(info: ZwaveDiscoveryInfo) -> None:
80  """Add Z-Wave Humidifier."""
81  driver = client.driver
82  assert driver is not None # Driver is ready before platforms are loaded.
83  entities: list[ZWaveBaseEntity] = []
84 
85  if (
86  str(HumidityControlMode.HUMIDIFY.value)
87  in info.primary_value.metadata.states
88  ):
89  entities.append(
91  config_entry, driver, info, HUMIDIFIER_ENTITY_DESCRIPTION
92  )
93  )
94 
95  if (
96  str(HumidityControlMode.DEHUMIDIFY.value)
97  in info.primary_value.metadata.states
98  ):
99  entities.append(
101  config_entry, driver, info, DEHUMIDIFIER_ENTITY_DESCRIPTION
102  )
103  )
104 
105  async_add_entities(entities)
106 
107  config_entry.async_on_unload(
109  hass,
110  f"{DOMAIN}_{config_entry.entry_id}_add_{HUMIDIFIER_DOMAIN}",
111  async_add_humidifier,
112  )
113  )
114 
115 
117  """Representation of a Z-Wave Humidifier or Dehumidifier."""
118 
119  entity_description: ZwaveHumidifierEntityDescription
120  _current_mode: ZwaveValue
121  _setpoint: ZwaveValue | None = None
122 
123  def __init__(
124  self,
125  config_entry: ConfigEntry,
126  driver: Driver,
127  info: ZwaveDiscoveryInfo,
128  description: ZwaveHumidifierEntityDescription,
129  ) -> None:
130  """Initialize humidifier."""
131  super().__init__(config_entry, driver, info)
132 
133  self.entity_descriptionentity_description = description
134 
135  self._attr_name_attr_name_attr_name = f"{self._attr_name} {description.key}"
136  self._attr_unique_id_attr_unique_id_attr_unique_id = f"{self._attr_unique_id}_{description.key}"
137 
138  self._current_mode_current_mode = self.infoinfo.primary_value
139 
140  self._setpoint_setpoint = self.get_zwave_valueget_zwave_value(
141  HUMIDITY_CONTROL_SETPOINT_PROPERTY,
142  command_class=CommandClass.HUMIDITY_CONTROL_SETPOINT,
143  value_property_key=description.setpoint_type,
144  add_to_watched_value_ids=True,
145  )
146 
147  @property
148  def is_on(self) -> bool | None:
149  """Return True if entity is on."""
150  if (value := self._current_mode_current_mode.value) is None:
151  return None
152  return int(value) in [self.entity_descriptionentity_description.on_mode, HumidityControlMode.AUTO]
153 
154  def _supports_inverse_mode(self) -> bool:
155  return (
156  str(self.entity_descriptionentity_description.inverse_mode.value)
157  in self._current_mode_current_mode.metadata.states
158  )
159 
160  async def async_turn_on(self, **kwargs: Any) -> None:
161  """Turn on device."""
162  if (value := self._current_mode_current_mode.value) is None:
163  return
164  mode = int(value)
165  if mode == HumidityControlMode.OFF:
166  new_mode = self.entity_descriptionentity_description.on_mode
167  elif mode == self.entity_descriptionentity_description.inverse_mode:
168  new_mode = HumidityControlMode.AUTO
169  else:
170  return
171 
172  await self._async_set_value_async_set_value(self._current_mode_current_mode, new_mode)
173 
174  async def async_turn_off(self, **kwargs: Any) -> None:
175  """Turn off device."""
176  if (value := self._current_mode_current_mode.value) is None:
177  return
178  mode = int(value)
179  if mode == HumidityControlMode.AUTO:
180  if self._supports_inverse_mode_supports_inverse_mode():
181  new_mode = self.entity_descriptionentity_description.inverse_mode
182  else:
183  new_mode = HumidityControlMode.OFF
184  elif mode == self.entity_descriptionentity_description.on_mode:
185  new_mode = HumidityControlMode.OFF
186  else:
187  return
188 
189  await self._async_set_value_async_set_value(self._current_mode_current_mode, new_mode)
190 
191  @property
192  def target_humidity(self) -> int | None:
193  """Return the humidity we try to reach."""
194  if not self._setpoint_setpoint or self._setpoint_setpoint.value is None:
195  return None
196  return int(self._setpoint_setpoint.value)
197 
198  async def async_set_humidity(self, humidity: int) -> None:
199  """Set new target humidity."""
200  if self._setpoint_setpoint:
201  await self._async_set_value_async_set_value(self._setpoint_setpoint, humidity)
202 
203  @property
204  def min_humidity(self) -> int:
205  """Return the minimum humidity."""
206  min_value = DEFAULT_MIN_HUMIDITY
207  if self._setpoint_setpoint and self._setpoint_setpoint.metadata.min:
208  min_value = self._setpoint_setpoint.metadata.min
209  return min_value
210 
211  @property
212  def max_humidity(self) -> int:
213  """Return the maximum humidity."""
214  max_value = DEFAULT_MAX_HUMIDITY
215  if self._setpoint_setpoint and self._setpoint_setpoint.metadata.max:
216  max_value = self._setpoint_setpoint.metadata.max
217  return max_value
SetValueResult|None _async_set_value(self, ZwaveValue value, Any new_value, dict|None options=None, bool|None wait_for_result=None)
Definition: entity.py:330
ZwaveValue|None get_zwave_value(self, str|int value_property, int|None command_class=None, int|None endpoint=None, int|str|None value_property_key=None, bool add_to_watched_value_ids=True, bool check_all_endpoints=False)
Definition: entity.py:280
None __init__(self, ConfigEntry config_entry, Driver driver, ZwaveDiscoveryInfo info, ZwaveHumidifierEntityDescription description)
Definition: humidifier.py:129
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)
Definition: humidifier.py:74
Callable[[], None] async_dispatcher_connect(HomeAssistant hass, str signal, Callable[..., Any] target)
Definition: dispatcher.py:103