Home Assistant Unofficial Reference 2024.12.1
climate.py
Go to the documentation of this file.
1 """Support for Schluter thermostats."""
2 
3 from __future__ import annotations
4 
5 import logging
6 from typing import Any
7 
8 from requests import RequestException
9 import voluptuous as vol
10 
12  PLATFORM_SCHEMA as CLIMATE_PLATFORM_SCHEMA,
13  SCAN_INTERVAL,
14  ClimateEntity,
15  ClimateEntityFeature,
16  HVACAction,
17  HVACMode,
18 )
19 from homeassistant.const import ATTR_TEMPERATURE, CONF_SCAN_INTERVAL, UnitOfTemperature
20 from homeassistant.core import HomeAssistant
21 from homeassistant.helpers.entity_platform import AddEntitiesCallback
22 from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
24  CoordinatorEntity,
25  DataUpdateCoordinator,
26  UpdateFailed,
27 )
28 
29 from . import DATA_SCHLUTER_API, DATA_SCHLUTER_SESSION, DOMAIN
30 
31 _LOGGER = logging.getLogger(__name__)
32 PLATFORM_SCHEMA = CLIMATE_PLATFORM_SCHEMA.extend(
33  {vol.Optional(CONF_SCAN_INTERVAL): vol.All(vol.Coerce(int), vol.Range(min=1))}
34 )
35 
36 
38  hass: HomeAssistant,
39  config: ConfigType,
40  async_add_entities: AddEntitiesCallback,
41  discovery_info: DiscoveryInfoType | None = None,
42 ) -> None:
43  """Set up the Schluter thermostats."""
44  if discovery_info is None:
45  return
46  session_id = hass.data[DOMAIN][DATA_SCHLUTER_SESSION]
47  api = hass.data[DOMAIN][DATA_SCHLUTER_API]
48 
49  async def async_update_data():
50  try:
51  thermostats = await hass.async_add_executor_job(
52  api.get_thermostats, session_id
53  )
54  except RequestException as err:
55  raise UpdateFailed(f"Error communicating with Schluter API: {err}") from err
56 
57  if thermostats is None:
58  return {}
59 
60  return {thermo.serial_number: thermo for thermo in thermostats}
61 
62  coordinator = DataUpdateCoordinator(
63  hass,
64  _LOGGER,
65  name="schluter",
66  update_method=async_update_data,
67  update_interval=SCAN_INTERVAL,
68  )
69 
70  await coordinator.async_refresh()
71 
73  SchluterThermostat(coordinator, serial_number, api, session_id)
74  for serial_number, thermostat in coordinator.data.items()
75  )
76 
77 
79  """Representation of a Schluter thermostat."""
80 
81  _attr_hvac_mode = HVACMode.HEAT
82  _attr_hvac_modes = [HVACMode.HEAT]
83  _attr_supported_features = ClimateEntityFeature.TARGET_TEMPERATURE
84  _attr_temperature_unit = UnitOfTemperature.CELSIUS
85  _enable_turn_on_off_backwards_compatibility = False
86 
87  def __init__(self, coordinator, serial_number, api, session_id):
88  """Initialize the thermostat."""
89  super().__init__(coordinator)
90  self._serial_number_serial_number = serial_number
91  self._api_api = api
92  self._session_id_session_id = session_id
93 
94  @property
95  def unique_id(self):
96  """Return unique ID for this device."""
97  return self._serial_number_serial_number
98 
99  @property
100  def name(self):
101  """Return the name of the thermostat."""
102  return self.coordinator.data[self._serial_number_serial_number].name
103 
104  @property
106  """Return the current temperature."""
107  return self.coordinator.data[self._serial_number_serial_number].temperature
108 
109  @property
110  def hvac_action(self) -> HVACAction:
111  """Return current operation. Can only be heating or idle."""
112  if self.coordinator.data[self._serial_number_serial_number].is_heating:
113  return HVACAction.HEATING
114  return HVACAction.IDLE
115 
116  @property
118  """Return the temperature we try to reach."""
119  return self.coordinator.data[self._serial_number_serial_number].set_point_temp
120 
121  @property
122  def min_temp(self):
123  """Identify min_temp in Schluter API."""
124  return self.coordinator.data[self._serial_number_serial_number].min_temp
125 
126  @property
127  def max_temp(self):
128  """Identify max_temp in Schluter API."""
129  return self.coordinator.data[self._serial_number_serial_number].max_temp
130 
131  async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
132  """Mode is always heating, so do nothing."""
133 
134  def set_temperature(self, **kwargs: Any) -> None:
135  """Set new target temperature."""
136  target_temp = None
137  target_temp = kwargs.get(ATTR_TEMPERATURE)
138  serial_number = self.coordinator.data[self._serial_number_serial_number].serial_number
139  _LOGGER.debug("Setting thermostat temperature: %s", target_temp)
140 
141  try:
142  if target_temp is not None:
143  self._api_api.set_temperature(self._session_id_session_id, serial_number, target_temp)
144  except RequestException as ex:
145  _LOGGER.error("An error occurred while setting temperature: %s", ex)
def __init__(self, coordinator, serial_number, api, session_id)
Definition: climate.py:87
None async_setup_platform(HomeAssistant hass, ConfigType config, AddEntitiesCallback async_add_entities, DiscoveryInfoType|None discovery_info=None)
Definition: climate.py:42