Home Assistant Unofficial Reference 2024.12.1
atlantic_electrical_heater_with_adjustable_temperature_setpoint.py
Go to the documentation of this file.
1 """Support for Atlantic Electrical Heater (With Adjustable Temperature Setpoint)."""
2 
3 from __future__ import annotations
4 
5 from typing import Any
6 
7 from pyoverkiz.enums import OverkizCommand, OverkizCommandParam, OverkizState
8 
10  PRESET_BOOST,
11  PRESET_COMFORT,
12  PRESET_ECO,
13  PRESET_NONE,
14  ClimateEntity,
15  ClimateEntityFeature,
16  HVACMode,
17 )
18 from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature
19 
20 from ..const import DOMAIN
21 from ..coordinator import OverkizDataUpdateCoordinator
22 from ..entity import OverkizEntity
23 
24 PRESET_AUTO = "auto"
25 PRESET_COMFORT1 = "comfort-1"
26 PRESET_COMFORT2 = "comfort-2"
27 PRESET_FROST_PROTECTION = "frost_protection"
28 PRESET_PROG = "prog"
29 PRESET_EXTERNAL = "external"
30 
31 
32 # Map Overkiz presets to Home Assistant presets
33 OVERKIZ_TO_PRESET_MODE: dict[str, str] = {
34  OverkizCommandParam.OFF: PRESET_NONE,
35  OverkizCommandParam.FROSTPROTECTION: PRESET_FROST_PROTECTION,
36  OverkizCommandParam.ECO: PRESET_ECO,
37  OverkizCommandParam.COMFORT: PRESET_COMFORT,
38  OverkizCommandParam.COMFORT_1: PRESET_COMFORT1,
39  OverkizCommandParam.COMFORT_2: PRESET_COMFORT2,
40  OverkizCommandParam.AUTO: PRESET_AUTO,
41  OverkizCommandParam.BOOST: PRESET_BOOST,
42  OverkizCommandParam.EXTERNAL: PRESET_EXTERNAL,
43  OverkizCommandParam.INTERNAL: PRESET_PROG,
44 }
45 
46 PRESET_MODE_TO_OVERKIZ = {v: k for k, v in OVERKIZ_TO_PRESET_MODE.items()}
47 
48 # Map Overkiz HVAC modes to Home Assistant HVAC modes
49 OVERKIZ_TO_HVAC_MODE: dict[str, HVACMode] = {
50  OverkizCommandParam.ON: HVACMode.HEAT,
51  OverkizCommandParam.OFF: HVACMode.OFF,
52  OverkizCommandParam.AUTO: HVACMode.AUTO,
53  OverkizCommandParam.BASIC: HVACMode.HEAT,
54  OverkizCommandParam.STANDBY: HVACMode.OFF,
55  OverkizCommandParam.EXTERNAL: HVACMode.AUTO,
56  OverkizCommandParam.INTERNAL: HVACMode.AUTO,
57 }
58 
59 HVAC_MODE_TO_OVERKIZ = {v: k for k, v in OVERKIZ_TO_HVAC_MODE.items()}
60 
61 TEMPERATURE_SENSOR_DEVICE_INDEX = 2
62 
63 
65  OverkizEntity, ClimateEntity
66 ):
67  """Representation of Atlantic Electrical Heater (With Adjustable Temperature Setpoint)."""
68 
69  _attr_hvac_modes = [*HVAC_MODE_TO_OVERKIZ]
70  _attr_preset_modes = [*PRESET_MODE_TO_OVERKIZ]
71  _attr_temperature_unit = UnitOfTemperature.CELSIUS
72  _attr_supported_features = (
73  ClimateEntityFeature.PRESET_MODE
74  | ClimateEntityFeature.TARGET_TEMPERATURE
75  | ClimateEntityFeature.TURN_OFF
76  | ClimateEntityFeature.TURN_ON
77  )
78  _attr_translation_key = DOMAIN
79  _enable_turn_on_off_backwards_compatibility = False
80 
81  def __init__(
82  self, device_url: str, coordinator: OverkizDataUpdateCoordinator
83  ) -> None:
84  """Init method."""
85  super().__init__(device_url, coordinator)
86  self.temperature_devicetemperature_device = self.executorexecutor.linked_device(
87  TEMPERATURE_SENSOR_DEVICE_INDEX
88  )
89 
90  @property
91  def hvac_mode(self) -> HVACMode:
92  """Return hvac operation ie. heat, cool mode."""
93  states = self.devicedevice.states
94  if (state := states[OverkizState.CORE_OPERATING_MODE]) and state.value_as_str:
95  return OVERKIZ_TO_HVAC_MODE[state.value_as_str]
96  if (state := states[OverkizState.CORE_ON_OFF]) and state.value_as_str:
97  return OVERKIZ_TO_HVAC_MODE[state.value_as_str]
98  return HVACMode.OFF
99 
100  async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
101  """Set new target hvac mode."""
102  await self.executorexecutor.async_execute_command(
103  OverkizCommand.SET_OPERATING_MODE, HVAC_MODE_TO_OVERKIZ[hvac_mode]
104  )
105 
106  @property
107  def preset_mode(self) -> str | None:
108  """Return the current preset mode, e.g., home, away, temp."""
109 
110  states = self.devicedevice.states
111 
112  if (
113  operating_mode := states[OverkizState.CORE_OPERATING_MODE]
114  ) and operating_mode.value_as_str == OverkizCommandParam.EXTERNAL:
115  return PRESET_EXTERNAL
116 
117  if (
118  state := states[OverkizState.IO_TARGET_HEATING_LEVEL]
119  ) and state.value_as_str:
120  return OVERKIZ_TO_PRESET_MODE[state.value_as_str]
121  return None
122 
123  async def async_set_preset_mode(self, preset_mode: str) -> None:
124  """Set new preset mode."""
125 
126  if preset_mode == PRESET_EXTERNAL:
127  command = OverkizCommand.SET_SCHEDULING_TYPE
128  elif preset_mode in [PRESET_AUTO, PRESET_PROG]:
129  command = OverkizCommand.SET_OPERATING_MODE
130  else:
131  command = OverkizCommand.SET_HEATING_LEVEL
132  await self.executorexecutor.async_execute_command(
133  command, PRESET_MODE_TO_OVERKIZ[preset_mode]
134  )
135 
136  @property
137  def target_temperature(self) -> float | None:
138  """Return the temperature."""
139  if state := self.devicedevice.states[OverkizState.CORE_TARGET_TEMPERATURE]:
140  return state.value_as_float
141  return None
142 
143  @property
144  def current_temperature(self) -> float | None:
145  """Return the current temperature."""
146  if self.temperature_devicetemperature_device is not None and (
147  temperature := self.temperature_devicetemperature_device.states[OverkizState.CORE_TEMPERATURE]
148  ):
149  return temperature.value_as_float
150  return None
151 
152  async def async_set_temperature(self, **kwargs: Any) -> None:
153  """Set new temperature."""
154  temperature = kwargs[ATTR_TEMPERATURE]
155  await self.executorexecutor.async_execute_command(
156  OverkizCommand.SET_TARGET_TEMPERATURE, temperature
157  )