Home Assistant Unofficial Reference 2024.12.1
climate.py
Go to the documentation of this file.
1 """Support for LCN climate control."""
2 
3 from collections.abc import Iterable
4 from functools import partial
5 from typing import Any, cast
6 
7 import pypck
8 
10  DOMAIN as DOMAIN_CLIMATE,
11  ClimateEntity,
12  ClimateEntityFeature,
13  HVACMode,
14 )
15 from homeassistant.config_entries import ConfigEntry
16 from homeassistant.const import (
17  ATTR_TEMPERATURE,
18  CONF_DOMAIN,
19  CONF_ENTITIES,
20  CONF_SOURCE,
21  CONF_UNIT_OF_MEASUREMENT,
22  UnitOfTemperature,
23 )
24 from homeassistant.core import HomeAssistant
25 from homeassistant.helpers.entity_platform import AddEntitiesCallback
26 from homeassistant.helpers.typing import ConfigType
27 
28 from .const import (
29  ADD_ENTITIES_CALLBACKS,
30  CONF_DOMAIN_DATA,
31  CONF_LOCKABLE,
32  CONF_MAX_TEMP,
33  CONF_MIN_TEMP,
34  CONF_SETPOINT,
35  DOMAIN,
36 )
37 from .entity import LcnEntity
38 from .helpers import InputType
39 
40 PARALLEL_UPDATES = 0
41 
42 
44  config_entry: ConfigEntry,
45  async_add_entities: AddEntitiesCallback,
46  entity_configs: Iterable[ConfigType],
47 ) -> None:
48  """Add entities for this domain."""
49  entities = [
50  LcnClimate(entity_config, config_entry) for entity_config in entity_configs
51  ]
52 
53  async_add_entities(entities)
54 
55 
57  hass: HomeAssistant,
58  config_entry: ConfigEntry,
59  async_add_entities: AddEntitiesCallback,
60 ) -> None:
61  """Set up LCN switch entities from a config entry."""
62  add_entities = partial(
63  add_lcn_entities,
64  config_entry,
65  async_add_entities,
66  )
67 
68  hass.data[DOMAIN][config_entry.entry_id][ADD_ENTITIES_CALLBACKS].update(
69  {DOMAIN_CLIMATE: add_entities}
70  )
71 
73  (
74  entity_config
75  for entity_config in config_entry.data[CONF_ENTITIES]
76  if entity_config[CONF_DOMAIN] == DOMAIN_CLIMATE
77  ),
78  )
79 
80 
82  """Representation of a LCN climate device."""
83 
84  _enable_turn_on_off_backwards_compatibility = False
85 
86  def __init__(self, config: ConfigType, config_entry: ConfigEntry) -> None:
87  """Initialize of a LCN climate device."""
88  super().__init__(config, config_entry)
89 
90  self.variablevariable = pypck.lcn_defs.Var[config[CONF_DOMAIN_DATA][CONF_SOURCE]]
91  self.setpointsetpoint = pypck.lcn_defs.Var[config[CONF_DOMAIN_DATA][CONF_SETPOINT]]
92  self.unitunit = pypck.lcn_defs.VarUnit.parse(
93  config[CONF_DOMAIN_DATA][CONF_UNIT_OF_MEASUREMENT]
94  )
95 
96  self.regulator_idregulator_id = pypck.lcn_defs.Var.to_set_point_id(self.setpointsetpoint)
97  self.is_lockableis_lockable = config[CONF_DOMAIN_DATA][CONF_LOCKABLE]
98  self._max_temp_max_temp = config[CONF_DOMAIN_DATA][CONF_MAX_TEMP]
99  self._min_temp_min_temp = config[CONF_DOMAIN_DATA][CONF_MIN_TEMP]
100 
101  self._current_temperature_current_temperature = None
102  self._target_temperature_target_temperature = None
103  self._is_on_is_on = True
104 
105  self._attr_hvac_modes_attr_hvac_modes = [HVACMode.HEAT]
106  if self.is_lockableis_lockable:
107  self._attr_hvac_modes_attr_hvac_modes.append(HVACMode.OFF)
108  self._attr_supported_features_attr_supported_features = ClimateEntityFeature.TARGET_TEMPERATURE
109  if len(self.hvac_modeshvac_modes) > 1:
110  self._attr_supported_features_attr_supported_features |= (
111  ClimateEntityFeature.TURN_OFF | ClimateEntityFeature.TURN_ON
112  )
113 
114  async def async_added_to_hass(self) -> None:
115  """Run when entity about to be added to hass."""
116  await super().async_added_to_hass()
117  if not self.device_connectiondevice_connection.is_group:
118  await self.device_connectiondevice_connection.activate_status_request_handler(self.variablevariable)
119  await self.device_connectiondevice_connection.activate_status_request_handler(self.setpointsetpoint)
120 
121  async def async_will_remove_from_hass(self) -> None:
122  """Run when entity will be removed from hass."""
123  await super().async_will_remove_from_hass()
124  if not self.device_connectiondevice_connection.is_group:
125  await self.device_connectiondevice_connection.cancel_status_request_handler(self.variablevariable)
126  await self.device_connectiondevice_connection.cancel_status_request_handler(self.setpointsetpoint)
127 
128  @property
129  def temperature_unit(self) -> str:
130  """Return the unit of measurement."""
131  # Config schema only allows for: UnitOfTemperature.CELSIUS and UnitOfTemperature.FAHRENHEIT
132  if self.unitunit == pypck.lcn_defs.VarUnit.FAHRENHEIT:
133  return UnitOfTemperature.FAHRENHEIT
134  return UnitOfTemperature.CELSIUS
135 
136  @property
137  def current_temperature(self) -> float | None:
138  """Return the current temperature."""
139  return self._current_temperature_current_temperature
140 
141  @property
142  def target_temperature(self) -> float | None:
143  """Return the temperature we try to reach."""
144  return self._target_temperature_target_temperature
145 
146  @property
147  def hvac_mode(self) -> HVACMode:
148  """Return hvac operation ie. heat, cool mode.
149 
150  Need to be one of HVAC_MODE_*.
151  """
152  if self._is_on_is_on:
153  return HVACMode.HEAT
154  return HVACMode.OFF
155 
156  @property
157  def max_temp(self) -> float:
158  """Return the maximum temperature."""
159  return cast(float, self._max_temp_max_temp)
160 
161  @property
162  def min_temp(self) -> float:
163  """Return the minimum temperature."""
164  return cast(float, self._min_temp_min_temp)
165 
166  async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
167  """Set new target hvac mode."""
168  if hvac_mode == HVACMode.HEAT:
169  if not await self.device_connectiondevice_connection.lock_regulator(
170  self.regulator_idregulator_id, False
171  ):
172  return
173  self._is_on_is_on = True
174  self.async_write_ha_stateasync_write_ha_state()
175  elif hvac_mode == HVACMode.OFF:
176  if not await self.device_connectiondevice_connection.lock_regulator(self.regulator_idregulator_id, True):
177  return
178  self._is_on_is_on = False
179  self._target_temperature_target_temperature = None
180  self.async_write_ha_stateasync_write_ha_state()
181 
182  async def async_set_temperature(self, **kwargs: Any) -> None:
183  """Set new target temperature."""
184  if (temperature := kwargs.get(ATTR_TEMPERATURE)) is None:
185  return
186 
187  if not await self.device_connectiondevice_connection.var_abs(
188  self.setpointsetpoint, temperature, self.unitunit
189  ):
190  return
191  self._target_temperature_target_temperature = temperature
192  self.async_write_ha_stateasync_write_ha_state()
193 
194  def input_received(self, input_obj: InputType) -> None:
195  """Set temperature value when LCN input object is received."""
196  if not isinstance(input_obj, pypck.inputs.ModStatusVar):
197  return
198 
199  if input_obj.get_var() == self.variablevariable:
200  self._current_temperature_current_temperature = input_obj.get_value().to_var_unit(self.unitunit)
201  elif input_obj.get_var() == self.setpointsetpoint:
202  self._is_on_is_on = not input_obj.get_value().is_locked_regulator()
203  if self._is_on_is_on:
204  self._target_temperature_target_temperature = input_obj.get_value().to_var_unit(self.unitunit)
205 
206  self.async_write_ha_stateasync_write_ha_state()
None __init__(self, ConfigType config, ConfigEntry config_entry)
Definition: climate.py:86
None input_received(self, InputType input_obj)
Definition: climate.py:194
None async_set_hvac_mode(self, HVACMode hvac_mode)
Definition: climate.py:166
None async_set_temperature(self, **Any kwargs)
Definition: climate.py:182
None add_entities(AsusWrtRouter router, AddEntitiesCallback async_add_entities, set[str] tracked)
IssData update(pyiss.ISS iss)
Definition: __init__.py:33
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)
Definition: climate.py:60
None add_lcn_entities(ConfigEntry config_entry, AddEntitiesCallback async_add_entities, Iterable[ConfigType] entity_configs)
Definition: climate.py:47