Home Assistant Unofficial Reference 2024.12.1
climate.py
Go to the documentation of this file.
1 """Support for Huum wifi-enabled sauna."""
2 
3 from __future__ import annotations
4 
5 import logging
6 from typing import Any
7 
8 from huum.const import SaunaStatus
9 from huum.exceptions import SafetyException
10 from huum.huum import Huum
11 from huum.schemas import HuumStatusResponse
12 
14  ClimateEntity,
15  ClimateEntityFeature,
16  HVACMode,
17 )
18 from homeassistant.config_entries import ConfigEntry
19 from homeassistant.const import ATTR_TEMPERATURE, PRECISION_WHOLE, UnitOfTemperature
20 from homeassistant.core import HomeAssistant
21 from homeassistant.exceptions import HomeAssistantError
22 from homeassistant.helpers.device_registry import DeviceInfo
23 from homeassistant.helpers.entity_platform import AddEntitiesCallback
24 
25 from .const import DOMAIN
26 
27 _LOGGER = logging.getLogger(__name__)
28 
29 
31  hass: HomeAssistant,
32  entry: ConfigEntry,
33  async_add_entities: AddEntitiesCallback,
34 ) -> None:
35  """Set up the Huum sauna with config flow."""
36  huum_handler = hass.data.setdefault(DOMAIN, {})[entry.entry_id]
37 
38  async_add_entities([HuumDevice(huum_handler, entry.entry_id)], True)
39 
40 
42  """Representation of a heater."""
43 
44  _attr_hvac_modes = [HVACMode.HEAT, HVACMode.OFF]
45  _attr_supported_features = (
46  ClimateEntityFeature.TARGET_TEMPERATURE
47  | ClimateEntityFeature.TURN_OFF
48  | ClimateEntityFeature.TURN_ON
49  )
50  _attr_target_temperature_step = PRECISION_WHOLE
51  _attr_temperature_unit = UnitOfTemperature.CELSIUS
52  _attr_max_temp = 110
53  _attr_min_temp = 40
54  _attr_has_entity_name = True
55  _attr_name = None
56 
57  _target_temperature: int | None = None
58  _status: HuumStatusResponse | None = None
59  _enable_turn_on_off_backwards_compatibility = False
60 
61  def __init__(self, huum_handler: Huum, unique_id: str) -> None:
62  """Initialize the heater."""
63  self._attr_unique_id_attr_unique_id = unique_id
64  self._attr_device_info_attr_device_info = DeviceInfo(
65  identifiers={(DOMAIN, unique_id)},
66  name="Huum sauna",
67  manufacturer="Huum",
68  )
69 
70  self._huum_handler_huum_handler = huum_handler
71 
72  @property
73  def hvac_mode(self) -> HVACMode:
74  """Return hvac operation ie. heat, cool mode."""
75  if self._status_status and self._status_status.status == SaunaStatus.ONLINE_HEATING:
76  return HVACMode.HEAT
77  return HVACMode.OFF
78 
79  @property
80  def icon(self) -> str:
81  """Return nice icon for heater."""
82  if self.hvac_modehvac_modehvac_modehvac_modehvac_mode == HVACMode.HEAT:
83  return "mdi:radiator"
84  return "mdi:radiator-off"
85 
86  @property
87  def current_temperature(self) -> int | None:
88  """Return the current temperature."""
89  if (status := self._status_status) is not None:
90  return status.temperature
91  return None
92 
93  @property
94  def target_temperature(self) -> int:
95  """Return the temperature we try to reach."""
96  return self._target_temperature_target_temperature or int(self.min_tempmin_temp)
97 
98  async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
99  """Set hvac mode."""
100  if hvac_mode == HVACMode.HEAT:
101  await self._turn_on_turn_on(self.target_temperaturetarget_temperaturetarget_temperature)
102  elif hvac_mode == HVACMode.OFF:
103  await self._huum_handler_huum_handler.turn_off()
104 
105  async def async_set_temperature(self, **kwargs: Any) -> None:
106  """Set new target temperature."""
107  temperature = kwargs.get(ATTR_TEMPERATURE)
108  if temperature is None:
109  return
110  self._target_temperature_target_temperature = temperature
111 
112  if self.hvac_modehvac_modehvac_modehvac_modehvac_mode == HVACMode.HEAT:
113  await self._turn_on_turn_on(temperature)
114 
115  async def async_update(self) -> None:
116  """Get the latest status data.
117 
118  We get the latest status first from the status endpoints of the sauna.
119  If that data does not include the temperature, that means that the sauna
120  is off, we then call the off command which will in turn return the temperature.
121  This is a workaround for getting the temperature as the Huum API does not
122  return the target temperature of a sauna that is off, even if it can have
123  a target temperature at that time.
124  """
125  self._status_status = await self._huum_handler_huum_handler.status_from_status_or_stop()
126  if self._target_temperature_target_temperature is None or self.hvac_modehvac_modehvac_modehvac_modehvac_mode == HVACMode.HEAT:
127  self._target_temperature_target_temperature = self._status_status.target_temperature
128 
129  async def _turn_on(self, temperature: int) -> None:
130  try:
131  await self._huum_handler_huum_handler.turn_on(temperature)
132  except (ValueError, SafetyException) as err:
133  _LOGGER.error(str(err))
134  raise HomeAssistantError(f"Unable to turn on sauna: {err}") from err
None _turn_on(self, int temperature)
Definition: climate.py:129
None async_set_hvac_mode(self, HVACMode hvac_mode)
Definition: climate.py:98
None async_set_temperature(self, **Any kwargs)
Definition: climate.py:105
None __init__(self, Huum huum_handler, str unique_id)
Definition: climate.py:61
None async_setup_entry(HomeAssistant hass, ConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: climate.py:34