Home Assistant Unofficial Reference 2024.12.1
climate.py
Go to the documentation of this file.
1 """BSBLAN platform to control a compatible Climate Device."""
2 
3 from __future__ import annotations
4 
5 from typing import Any
6 
7 from bsblan import BSBLANError
8 
10  ATTR_HVAC_MODE,
11  ATTR_PRESET_MODE,
12  PRESET_ECO,
13  PRESET_NONE,
14  ClimateEntity,
15  ClimateEntityFeature,
16  HVACMode,
17 )
18 from homeassistant.const import ATTR_TEMPERATURE
19 from homeassistant.core import HomeAssistant
20 from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
21 from homeassistant.helpers.device_registry import format_mac
22 from homeassistant.helpers.entity_platform import AddEntitiesCallback
23 from homeassistant.util.enum import try_parse_enum
24 
25 from . import BSBLanConfigEntry, BSBLanData
26 from .const import ATTR_TARGET_TEMPERATURE, DOMAIN
27 from .entity import BSBLanEntity
28 
29 PARALLEL_UPDATES = 1
30 
31 HVAC_MODES = [
32  HVACMode.AUTO,
33  HVACMode.HEAT,
34  HVACMode.OFF,
35 ]
36 
37 PRESET_MODES = [
38  PRESET_ECO,
39  PRESET_NONE,
40 ]
41 
42 
44  hass: HomeAssistant,
45  entry: BSBLanConfigEntry,
46  async_add_entities: AddEntitiesCallback,
47 ) -> None:
48  """Set up BSBLAN device based on a config entry."""
49  data = entry.runtime_data
51 
52 
54  """Defines a BSBLAN climate device."""
55 
56  _attr_has_entity_name = True
57  _attr_name = None
58  # Determine preset modes
59  _attr_supported_features = (
60  ClimateEntityFeature.TARGET_TEMPERATURE
61  | ClimateEntityFeature.PRESET_MODE
62  | ClimateEntityFeature.TURN_OFF
63  | ClimateEntityFeature.TURN_ON
64  )
65 
66  _attr_preset_modes = PRESET_MODES
67  _attr_hvac_modes = HVAC_MODES
68  _enable_turn_on_off_backwards_compatibility = False
69 
70  def __init__(
71  self,
72  data: BSBLanData,
73  ) -> None:
74  """Initialize BSBLAN climate device."""
75  super().__init__(data.coordinator, data)
76  self._attr_unique_id_attr_unique_id = f"{format_mac(data.device.MAC)}-climate"
77 
78  self._attr_min_temp_attr_min_temp = data.static.min_temp.value
79  self._attr_max_temp_attr_max_temp = data.static.max_temp.value
80  self._attr_temperature_unit_attr_temperature_unit = data.coordinator.client.get_temperature_unit
81 
82  @property
83  def current_temperature(self) -> float | None:
84  """Return the current temperature."""
85  return self.coordinator.data.state.current_temperature.value
86 
87  @property
88  def target_temperature(self) -> float | None:
89  """Return the temperature we try to reach."""
90  return self.coordinator.data.state.target_temperature.value
91 
92  @property
93  def hvac_mode(self) -> HVACMode | None:
94  """Return hvac operation ie. heat, cool mode."""
95  if self.coordinator.data.state.hvac_mode.value == PRESET_ECO:
96  return HVACMode.AUTO
97  return try_parse_enum(HVACMode, self.coordinator.data.state.hvac_mode.value)
98 
99  @property
100  def preset_mode(self) -> str | None:
101  """Return the current preset mode."""
102  if (
103  self.hvac_modehvac_modehvac_modehvac_modehvac_mode == HVACMode.AUTO
104  and self.coordinator.data.state.hvac_mode.value == PRESET_ECO
105  ):
106  return PRESET_ECO
107  return PRESET_NONE
108 
109  async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
110  """Set hvac mode."""
111  await self.async_set_dataasync_set_data(hvac_mode=hvac_mode)
112 
113  async def async_set_preset_mode(self, preset_mode: str) -> None:
114  """Set preset mode."""
115  if self.hvac_modehvac_modehvac_modehvac_modehvac_mode != HVACMode.AUTO and preset_mode != PRESET_NONE:
117  "Preset mode can only be set when HVAC mode is set to 'auto'",
118  translation_domain=DOMAIN,
119  translation_key="set_preset_mode_error",
120  translation_placeholders={"preset_mode": preset_mode},
121  )
122  await self.async_set_dataasync_set_data(preset_mode=preset_mode)
123 
124  async def async_set_temperature(self, **kwargs: Any) -> None:
125  """Set new target temperatures."""
126  await self.async_set_dataasync_set_data(**kwargs)
127 
128  async def async_set_data(self, **kwargs: Any) -> None:
129  """Set device settings using BSBLAN."""
130  data = {}
131  if ATTR_TEMPERATURE in kwargs:
132  data[ATTR_TARGET_TEMPERATURE] = kwargs[ATTR_TEMPERATURE]
133  if ATTR_HVAC_MODE in kwargs:
134  data[ATTR_HVAC_MODE] = kwargs[ATTR_HVAC_MODE]
135  if ATTR_PRESET_MODE in kwargs:
136  if kwargs[ATTR_PRESET_MODE] == PRESET_ECO:
137  data[ATTR_HVAC_MODE] = PRESET_ECO
138  elif kwargs[ATTR_PRESET_MODE] == PRESET_NONE:
139  data[ATTR_HVAC_MODE] = PRESET_NONE
140 
141  try:
142  await self.coordinator.client.thermostat(**data)
143  except BSBLANError as err:
144  raise HomeAssistantError(
145  "An error occurred while updating the BSBLAN device",
146  translation_domain=DOMAIN,
147  translation_key="set_data_error",
148  ) from err
149  await self.coordinator.async_request_refresh()
None async_set_hvac_mode(self, HVACMode hvac_mode)
Definition: climate.py:109
None async_set_preset_mode(self, str preset_mode)
Definition: climate.py:113
None async_setup_entry(HomeAssistant hass, BSBLanConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: climate.py:47