Home Assistant Unofficial Reference 2024.12.1
select.py
Go to the documentation of this file.
1 """The Aprilaire select component."""
2 
3 from __future__ import annotations
4 
5 from collections.abc import Awaitable, Callable
6 from dataclasses import dataclass
7 from typing import cast
8 
9 from pyaprilaire.const import Attribute
10 
11 from homeassistant.components.select import SelectEntity, SelectEntityDescription
12 from homeassistant.core import HomeAssistant
13 from homeassistant.helpers.entity_platform import AddEntitiesCallback
14 
15 from .coordinator import AprilaireConfigEntry, AprilaireCoordinator
16 from .entity import BaseAprilaireEntity
17 
18 AIR_CLEANING_EVENT_MAP = {0: "off", 3: "event_clean", 4: "allergies"}
19 AIR_CLEANING_MODE_MAP = {0: "off", 1: "constant_clean", 2: "automatic"}
20 FRESH_AIR_EVENT_MAP = {0: "off", 2: "3hour", 3: "24hour"}
21 FRESH_AIR_MODE_MAP = {0: "off", 1: "automatic"}
22 
23 
25  hass: HomeAssistant,
26  config_entry: AprilaireConfigEntry,
27  async_add_entities: AddEntitiesCallback,
28 ) -> None:
29  """Set up Aprilaire select devices."""
30 
31  coordinator = config_entry.runtime_data
32 
33  assert config_entry.unique_id is not None
34 
35  descriptions: list[AprilaireSelectDescription] = []
36 
37  if coordinator.data.get(Attribute.AIR_CLEANING_AVAILABLE) == 1:
38  descriptions.extend(
39  [
41  key="air_cleaning_event",
42  translation_key="air_cleaning_event",
43  options_map=AIR_CLEANING_EVENT_MAP,
44  event_value_key=Attribute.AIR_CLEANING_EVENT,
45  mode_value_key=Attribute.AIR_CLEANING_MODE,
46  is_event=True,
47  select_option_fn=coordinator.client.set_air_cleaning,
48  ),
50  key="air_cleaning_mode",
51  translation_key="air_cleaning_mode",
52  options_map=AIR_CLEANING_MODE_MAP,
53  event_value_key=Attribute.AIR_CLEANING_EVENT,
54  mode_value_key=Attribute.AIR_CLEANING_MODE,
55  is_event=False,
56  select_option_fn=coordinator.client.set_air_cleaning,
57  ),
58  ]
59  )
60 
61  if coordinator.data.get(Attribute.VENTILATION_AVAILABLE) == 1:
62  descriptions.extend(
63  [
65  key="fresh_air_event",
66  translation_key="fresh_air_event",
67  options_map=FRESH_AIR_EVENT_MAP,
68  event_value_key=Attribute.FRESH_AIR_EVENT,
69  mode_value_key=Attribute.FRESH_AIR_MODE,
70  is_event=True,
71  select_option_fn=coordinator.client.set_fresh_air,
72  ),
74  key="fresh_air_mode",
75  translation_key="fresh_air_mode",
76  options_map=FRESH_AIR_MODE_MAP,
77  event_value_key=Attribute.FRESH_AIR_EVENT,
78  mode_value_key=Attribute.FRESH_AIR_MODE,
79  is_event=False,
80  select_option_fn=coordinator.client.set_fresh_air,
81  ),
82  ]
83  )
84 
86  AprilaireSelectEntity(coordinator, description, config_entry.unique_id)
87  for description in descriptions
88  )
89 
90 
91 @dataclass(frozen=True, kw_only=True)
93  """Class describing Aprilaire select entities."""
94 
95  options_map: dict[int, str]
96  event_value_key: str
97  mode_value_key: str
98  is_event: bool
99  select_option_fn: Callable[[int, int], Awaitable]
100 
101 
103  """Base select entity for Aprilaire."""
104 
105  entity_description: AprilaireSelectDescription
106 
107  def __init__(
108  self,
109  coordinator: AprilaireCoordinator,
110  description: AprilaireSelectDescription,
111  unique_id: str,
112  ) -> None:
113  """Initialize a select for an Aprilaire device."""
114 
115  self.entity_descriptionentity_description = description
116  self.values_mapvalues_map = {v: k for k, v in description.options_map.items()}
117 
118  super().__init__(coordinator, unique_id)
119 
120  self._attr_options_attr_options = list(description.options_map.values())
121 
122  @property
123  def current_option(self) -> str:
124  """Get the current option."""
125 
126  if self.entity_descriptionentity_description.is_event:
127  value_key = self.entity_descriptionentity_description.event_value_key
128  else:
129  value_key = self.entity_descriptionentity_description.mode_value_key
130 
131  current_value = int(self.coordinator.data.get(value_key, 0))
132 
133  return self.entity_descriptionentity_description.options_map.get(current_value, "off")
134 
135  async def async_select_option(self, option: str) -> None:
136  """Set the current option."""
137 
138  if self.entity_descriptionentity_description.is_event:
139  event_value = self.values_mapvalues_map[option]
140 
141  mode_value = cast(
142  int, self.coordinator.data.get(self.entity_descriptionentity_description.mode_value_key)
143  )
144  else:
145  mode_value = self.values_mapvalues_map[option]
146 
147  event_value = cast(
148  int, self.coordinator.data.get(self.entity_descriptionentity_description.event_value_key)
149  )
150 
151  await self.entity_descriptionentity_description.select_option_fn(mode_value, event_value)
None __init__(self, AprilaireCoordinator coordinator, AprilaireSelectDescription description, str unique_id)
Definition: select.py:112
None async_setup_entry(HomeAssistant hass, AprilaireConfigEntry config_entry, AddEntitiesCallback async_add_entities)
Definition: select.py:28