Home Assistant Unofficial Reference 2024.12.1
climate.py
Go to the documentation of this file.
1 """Support for Balboa Spa Wifi adaptor."""
2 
3 from __future__ import annotations
4 
5 from enum import IntEnum
6 from typing import Any
7 
8 from pybalboa import SpaClient, SpaControl
9 from pybalboa.enums import HeatMode, HeatState, TemperatureUnit
10 
12  ClimateEntity,
13  ClimateEntityFeature,
14  HVACAction,
15  HVACMode,
16 )
17 from homeassistant.const import (
18  ATTR_TEMPERATURE,
19  PRECISION_HALVES,
20  PRECISION_WHOLE,
21  UnitOfTemperature,
22 )
23 from homeassistant.core import HomeAssistant
24 from homeassistant.helpers.entity_platform import AddEntitiesCallback
25 
26 from . import BalboaConfigEntry
27 from .const import DOMAIN
28 from .entity import BalboaEntity
29 
30 HEAT_HVAC_MODE_MAP: dict[IntEnum, HVACMode] = {
31  HeatMode.READY: HVACMode.HEAT,
32  HeatMode.REST: HVACMode.OFF,
33  HeatMode.READY_IN_REST: HVACMode.AUTO,
34 }
35 HVAC_HEAT_MODE_MAP = {value: key for key, value in HEAT_HVAC_MODE_MAP.items()}
36 HEAT_STATE_HVAC_ACTION_MAP = {
37  HeatState.OFF: HVACAction.OFF,
38  HeatState.HEATING: HVACAction.HEATING,
39  HeatState.HEAT_WAITING: HVACAction.IDLE,
40 }
41 TEMPERATURE_UNIT_MAP = {
42  TemperatureUnit.CELSIUS: UnitOfTemperature.CELSIUS,
43  TemperatureUnit.FAHRENHEIT: UnitOfTemperature.FAHRENHEIT,
44 }
45 
46 
48  hass: HomeAssistant,
49  entry: BalboaConfigEntry,
50  async_add_entities: AddEntitiesCallback,
51 ) -> None:
52  """Set up the spa climate entity."""
53  async_add_entities([BalboaClimateEntity(entry.runtime_data)])
54 
55 
57  """Representation of a Balboa spa climate entity."""
58 
59  _attr_hvac_modes = [HVACMode.HEAT, HVACMode.OFF]
60  _attr_supported_features = (
61  ClimateEntityFeature.TARGET_TEMPERATURE
62  | ClimateEntityFeature.PRESET_MODE
63  | ClimateEntityFeature.TURN_OFF
64  | ClimateEntityFeature.TURN_ON
65  )
66  _attr_translation_key = DOMAIN
67  _attr_name = None
68  _enable_turn_on_off_backwards_compatibility = False
69 
70  def __init__(self, client: SpaClient) -> None:
71  """Initialize the climate entity."""
72  super().__init__(client, "Climate")
73  self._attr_preset_modes_attr_preset_modes = [opt.name.lower() for opt in client.heat_mode.options]
74 
75  self._blower_blower: SpaControl | None = None
76  if client.blowers and (blower := client.blowers[0]) is not None:
77  self._blower_blower = blower
78  self._attr_supported_features_attr_supported_features |= ClimateEntityFeature.FAN_MODE
79  self._fan_mode_map_fan_mode_map = {opt.name.lower(): opt for opt in blower.options}
80  self._attr_fan_modes_attr_fan_modes = list(self._fan_mode_map_fan_mode_map)
81 
82  @property
83  def hvac_mode(self) -> HVACMode | None:
84  """Return the current HVAC mode."""
85  return HEAT_HVAC_MODE_MAP.get(self._client_client.heat_mode.state)
86 
87  @property
88  def hvac_action(self) -> HVACAction:
89  """Return the current operation mode."""
90  return HEAT_STATE_HVAC_ACTION_MAP[self._client_client.heat_state]
91 
92  @property
93  def fan_mode(self) -> str | None:
94  """Return the fan setting."""
95  if (blower := self._blower_blower) is not None:
96  return blower.state.name.lower()
97  return None
98 
99  @property
100  def precision(self) -> float:
101  """Return the precision of the system."""
102  if self.hasshass.config.units.temperature_unit == UnitOfTemperature.CELSIUS:
103  return PRECISION_HALVES
104  return PRECISION_WHOLE
105 
106  @property
107  def temperature_unit(self) -> str:
108  """Return the unit of measurement used by the platform."""
109  return TEMPERATURE_UNIT_MAP[self._client_client.temperature_unit]
110 
111  @property
112  def current_temperature(self) -> float | None:
113  """Return the current temperature."""
114  return self._client_client.temperature
115 
116  @property
117  def target_temperature(self) -> float:
118  """Return the target temperature we try to reach."""
119  return self._client_client.target_temperature
120 
121  @property
122  def min_temp(self) -> float:
123  """Return the minimum temperature supported by the spa."""
124  return self._client_client.temperature_minimum
125 
126  @property
127  def max_temp(self) -> float:
128  """Return the minimum temperature supported by the spa."""
129  return self._client_client.temperature_maximum
130 
131  @property
132  def preset_mode(self) -> str:
133  """Return current preset mode."""
134  return self._client_client.heat_mode.state.name.lower()
135 
136  async def async_set_temperature(self, **kwargs: Any) -> None:
137  """Set a new target temperature."""
138  await self._client_client.set_temperature(kwargs[ATTR_TEMPERATURE])
139 
140  async def async_set_preset_mode(self, preset_mode: str) -> None:
141  """Set new preset mode."""
142  await self._client_client.heat_mode.set_state(HeatMode[preset_mode.upper()])
143 
144  async def async_set_fan_mode(self, fan_mode: str) -> None:
145  """Set new fan mode."""
146  if (blower := self._blower_blower) is not None:
147  await blower.set_state(self._fan_mode_map_fan_mode_map[fan_mode])
148 
149  async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
150  """Set new target hvac mode."""
151  await self._client_client.heat_mode.set_state(HVAC_HEAT_MODE_MAP[hvac_mode])
None async_set_hvac_mode(self, HVACMode hvac_mode)
Definition: climate.py:149
None set_temperature(self, **Any kwargs)
Definition: __init__.py:771
None async_setup_entry(HomeAssistant hass, BalboaConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: climate.py:51