Home Assistant Unofficial Reference 2024.12.1
select.py
Go to the documentation of this file.
1 """Support for RainMachine selects."""
2 
3 from __future__ import annotations
4 
5 from dataclasses import dataclass
6 
7 from regenmaschine.errors import RainMachineError
8 
9 from homeassistant.components.select import SelectEntity, SelectEntityDescription
10 from homeassistant.config_entries import ConfigEntry
11 from homeassistant.const import EntityCategory
12 from homeassistant.core import HomeAssistant, callback
13 from homeassistant.exceptions import HomeAssistantError
14 from homeassistant.helpers.entity_platform import AddEntitiesCallback
15 from homeassistant.util.unit_system import US_CUSTOMARY_SYSTEM, UnitSystem
16 
17 from . import RainMachineConfigEntry, RainMachineData
18 from .const import DATA_RESTRICTIONS_UNIVERSAL
19 from .entity import RainMachineEntity, RainMachineEntityDescription
20 from .util import key_exists
21 
22 
23 @dataclass(frozen=True, kw_only=True)
25  SelectEntityDescription, RainMachineEntityDescription
26 ):
27  """Describe a generic RainMachine select."""
28 
29  data_key: str
30 
31 
32 @dataclass
34  """Define an option for a freeze selection select."""
35 
36  api_value: float
37  imperial_label: str
38  metric_label: str
39 
40 
41 @dataclass(frozen=True, kw_only=True)
43  """Describe a freeze protection temperature select."""
44 
45  extended_options: list[FreezeProtectionSelectOption]
46 
47 
48 TYPE_FREEZE_PROTECTION_TEMPERATURE = "freeze_protection_temperature"
49 
50 SELECT_DESCRIPTIONS = (
52  key=TYPE_FREEZE_PROTECTION_TEMPERATURE,
53  translation_key=TYPE_FREEZE_PROTECTION_TEMPERATURE,
54  entity_category=EntityCategory.CONFIG,
55  api_category=DATA_RESTRICTIONS_UNIVERSAL,
56  data_key="freezeProtectTemp",
57  extended_options=[
59  api_value=0.0,
60  imperial_label="32°F",
61  metric_label="0°C",
62  ),
64  api_value=2.0,
65  imperial_label="35.6°F",
66  metric_label="2°C",
67  ),
69  api_value=5.0,
70  imperial_label="41°F",
71  metric_label="5°C",
72  ),
74  api_value=10.0,
75  imperial_label="50°F",
76  metric_label="10°C",
77  ),
78  ],
79  ),
80 )
81 
82 
84  hass: HomeAssistant,
85  entry: RainMachineConfigEntry,
86  async_add_entities: AddEntitiesCallback,
87 ) -> None:
88  """Set up RainMachine selects based on a config entry."""
89  data = entry.runtime_data
90 
91  entity_map = {
92  TYPE_FREEZE_PROTECTION_TEMPERATURE: FreezeProtectionTemperatureSelect,
93  }
94 
96  entity_map[description.key](entry, data, description, hass.config.units)
97  for description in SELECT_DESCRIPTIONS
98  if (
99  (coordinator := data.coordinators[description.api_category]) is not None
100  and coordinator.data
101  and key_exists(coordinator.data, description.data_key)
102  )
103  )
104 
105 
107  """Define a RainMachine select."""
108 
109  entity_description: FreezeProtectionSelectDescription
110 
111  def __init__(
112  self,
113  entry: ConfigEntry,
114  data: RainMachineData,
115  description: FreezeProtectionSelectDescription,
116  unit_system: UnitSystem,
117  ) -> None:
118  """Initialize."""
119  super().__init__(entry, data, description)
120 
121  self._api_value_to_label_map_api_value_to_label_map = {}
122  self._label_to_api_value_map_label_to_api_value_map = {}
123 
124  for option in description.extended_options:
125  if unit_system is US_CUSTOMARY_SYSTEM:
126  label = option.imperial_label
127  else:
128  label = option.metric_label
129  self._api_value_to_label_map_api_value_to_label_map[option.api_value] = label
130  self._label_to_api_value_map_label_to_api_value_map[label] = option.api_value
131 
132  self._attr_options_attr_options = list(self._label_to_api_value_map_label_to_api_value_map)
133 
134  async def async_select_option(self, option: str) -> None:
135  """Change the selected option."""
136  try:
137  await self._data_data.controller.restrictions.set_universal(
138  {self.entity_descriptionentity_description.data_key: self._label_to_api_value_map_label_to_api_value_map[option]}
139  )
140  except RainMachineError as err:
141  raise HomeAssistantError(f"Error while setting {self.name}: {err}") from err
142 
143  @callback
144  def update_from_latest_data(self) -> None:
145  """Update the entity when new data is received."""
146  raw_value = self.coordinator.data[self.entity_descriptionentity_description.data_key]
147  self._attr_current_option_attr_current_option = self._api_value_to_label_map_api_value_to_label_map[raw_value]
None __init__(self, ConfigEntry entry, RainMachineData data, FreezeProtectionSelectDescription description, UnitSystem unit_system)
Definition: select.py:117
None async_setup_entry(HomeAssistant hass, RainMachineConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: select.py:87
bool key_exists(dict[str, Any] data, str search_key)
Definition: util.py:70