Home Assistant Unofficial Reference 2024.12.1
climate.py
Go to the documentation of this file.
1 """Support for Freedompro climate."""
2 
3 from __future__ import annotations
4 
5 import json
6 import logging
7 from typing import Any
8 
9 from aiohttp.client import ClientSession
10 from pyfreedompro import put_state
11 
13  ATTR_HVAC_MODE,
14  ClimateEntity,
15  ClimateEntityFeature,
16  HVACMode,
17 )
18 from homeassistant.config_entries import ConfigEntry
19 from homeassistant.const import ATTR_TEMPERATURE, CONF_API_KEY, UnitOfTemperature
20 from homeassistant.core import HomeAssistant, callback
21 from homeassistant.helpers import aiohttp_client
22 from homeassistant.helpers.device_registry import DeviceInfo
23 from homeassistant.helpers.entity_platform import AddEntitiesCallback
24 from homeassistant.helpers.update_coordinator import CoordinatorEntity
25 
26 from .const import DOMAIN
27 from .coordinator import FreedomproDataUpdateCoordinator
28 
29 _LOGGER = logging.getLogger(__name__)
30 
31 HVAC_MAP = {
32  0: HVACMode.OFF,
33  1: HVACMode.HEAT,
34  2: HVACMode.COOL,
35 }
36 
37 HVAC_INVERT_MAP = {v: k for k, v in HVAC_MAP.items()}
38 
39 SUPPORTED_HVAC_MODES = [
40  HVACMode.OFF,
41  HVACMode.HEAT,
42  HVACMode.COOL,
43 ]
44 
45 
47  hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
48 ) -> None:
49  """Set up Freedompro climate."""
50  api_key: str = entry.data[CONF_API_KEY]
51  coordinator: FreedomproDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
53  Device(
54  aiohttp_client.async_get_clientsession(hass), api_key, device, coordinator
55  )
56  for device in coordinator.data
57  if device["type"] == "thermostat"
58  )
59 
60 
61 class Device(CoordinatorEntity[FreedomproDataUpdateCoordinator], ClimateEntity):
62  """Representation of a Freedompro climate."""
63 
64  _attr_has_entity_name = True
65  _attr_hvac_modes = SUPPORTED_HVAC_MODES
66  _attr_temperature_unit = UnitOfTemperature.CELSIUS
67  _attr_name = None
68  _attr_supported_features = (
69  ClimateEntityFeature.TARGET_TEMPERATURE
70  | ClimateEntityFeature.TURN_OFF
71  | ClimateEntityFeature.TURN_ON
72  )
73  _attr_current_temperature = 0
74  _attr_target_temperature = 0
75  _attr_hvac_mode = HVACMode.OFF
76  _enable_turn_on_off_backwards_compatibility = False
77 
78  def __init__(
79  self,
80  session: ClientSession,
81  api_key: str,
82  device: dict[str, Any],
83  coordinator: FreedomproDataUpdateCoordinator,
84  ) -> None:
85  """Initialize the Freedompro climate."""
86  super().__init__(coordinator)
87  self._session_session = session
88  self._api_key_api_key_api_key = api_key
89  self._attr_unique_id_attr_unique_id = device["uid"]
90  self._characteristics_characteristics = device["characteristics"]
91  self._attr_device_info_attr_device_info = DeviceInfo(
92  identifiers={
93  (DOMAIN, device["uid"]),
94  },
95  manufacturer="Freedompro",
96  model=device["type"],
97  name=device["name"],
98  )
99 
100  @callback
101  def _handle_coordinator_update(self) -> None:
102  """Handle updated data from the coordinator."""
103  device = next(
104  (
105  device
106  for device in self.coordinator.data
107  if device["uid"] == self._attr_unique_id_attr_unique_id
108  ),
109  None,
110  )
111  if device is not None and "state" in device:
112  state = device["state"]
113  if "currentTemperature" in state:
114  self._attr_current_temperature_attr_current_temperature_attr_current_temperature = state["currentTemperature"]
115  if "targetTemperature" in state:
116  self._attr_target_temperature_attr_target_temperature_attr_target_temperature = state["targetTemperature"]
117  if "heatingCoolingState" in state:
118  self._attr_hvac_mode_attr_hvac_mode = HVAC_MAP[state["heatingCoolingState"]]
120 
121  async def async_added_to_hass(self) -> None:
122  """When entity is added to hass."""
123  await super().async_added_to_hass()
124  self._handle_coordinator_update_handle_coordinator_update()
125 
126  async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
127  """Async function to set mode to climate."""
128  if hvac_mode not in SUPPORTED_HVAC_MODES:
129  raise ValueError(f"Got unsupported hvac_mode {hvac_mode}")
130 
131  payload = {"heatingCoolingState": HVAC_INVERT_MAP[hvac_mode]}
132  await put_state(
133  self._session_session,
134  self._api_key_api_key_api_key,
135  self.unique_idunique_id,
136  json.dumps(payload),
137  )
138  await self.coordinator.async_request_refresh()
139 
140  async def async_set_temperature(self, **kwargs: Any) -> None:
141  """Async function to set temperature to climate."""
142  payload = {}
143  if ATTR_HVAC_MODE in kwargs:
144  if kwargs[ATTR_HVAC_MODE] not in SUPPORTED_HVAC_MODES:
145  _LOGGER.error(
146  "Got unsupported hvac_mode %s, expected one of %s",
147  kwargs[ATTR_HVAC_MODE],
148  SUPPORTED_HVAC_MODES,
149  )
150  return
151  payload["heatingCoolingState"] = HVAC_INVERT_MAP[kwargs[ATTR_HVAC_MODE]]
152  if ATTR_TEMPERATURE in kwargs:
153  payload["targetTemperature"] = kwargs[ATTR_TEMPERATURE]
154  await put_state(
155  self._session_session,
156  self._api_key_api_key_api_key,
157  self.unique_idunique_id,
158  json.dumps(payload),
159  )
160  await self.coordinator.async_request_refresh()
None async_set_hvac_mode(self, HVACMode hvac_mode)
Definition: climate.py:126
None __init__(self, ClientSession session, str api_key, dict[str, Any] device, FreedomproDataUpdateCoordinator coordinator)
Definition: climate.py:84
None async_set_temperature(self, **Any kwargs)
Definition: climate.py:140
None async_setup_entry(HomeAssistant hass, ConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: climate.py:48