Home Assistant Unofficial Reference 2024.12.1
select.py
Go to the documentation of this file.
1 """Support for LED selects."""
2 
3 from __future__ import annotations
4 
5 from functools import partial
6 
7 from wled import LiveDataOverride
8 
9 from homeassistant.components.select import SelectEntity
10 from homeassistant.const import EntityCategory
11 from homeassistant.core import HomeAssistant, callback
12 from homeassistant.helpers.entity_platform import AddEntitiesCallback
13 
14 from . import WLEDConfigEntry
15 from .coordinator import WLEDDataUpdateCoordinator
16 from .entity import WLEDEntity
17 from .helpers import wled_exception_handler
18 
19 PARALLEL_UPDATES = 1
20 
21 
23  hass: HomeAssistant,
24  entry: WLEDConfigEntry,
25  async_add_entities: AddEntitiesCallback,
26 ) -> None:
27  """Set up WLED select based on a config entry."""
28  coordinator = entry.runtime_data
29 
31  [
32  WLEDLiveOverrideSelect(coordinator),
33  WLEDPlaylistSelect(coordinator),
34  WLEDPresetSelect(coordinator),
35  ]
36  )
37 
38  update_segments = partial(
39  async_update_segments,
40  coordinator,
41  set(),
42  async_add_entities,
43  )
44  coordinator.async_add_listener(update_segments)
45  update_segments()
46 
47 
49  """Defined a WLED Live Override select."""
50 
51  _attr_entity_category = EntityCategory.CONFIG
52  _attr_translation_key = "live_override"
53 
54  def __init__(self, coordinator: WLEDDataUpdateCoordinator) -> None:
55  """Initialize WLED ."""
56  super().__init__(coordinator=coordinator)
57 
58  self._attr_unique_id_attr_unique_id = f"{coordinator.data.info.mac_address}_live_override"
59  self._attr_options_attr_options = [str(live.value) for live in LiveDataOverride]
60 
61  @property
62  def current_option(self) -> str:
63  """Return the current selected live override."""
64  return str(self.coordinator.data.state.live_data_override.value)
65 
66  @wled_exception_handler
67  async def async_select_option(self, option: str) -> None:
68  """Set WLED state to the selected live override state."""
69  await self.coordinator.wled.live(live=LiveDataOverride(int(option)))
70 
71 
73  """Defined a WLED Preset select."""
74 
75  _attr_translation_key = "preset"
76 
77  def __init__(self, coordinator: WLEDDataUpdateCoordinator) -> None:
78  """Initialize WLED ."""
79  super().__init__(coordinator=coordinator)
80 
81  self._attr_unique_id_attr_unique_id = f"{coordinator.data.info.mac_address}_preset"
82  self._attr_options_attr_options = [
83  preset.name for preset in self.coordinator.data.presets.values()
84  ]
85 
86  @property
87  def available(self) -> bool:
88  """Return True if entity is available."""
89  return len(self.coordinator.data.presets) > 0 and super().available
90 
91  @property
92  def current_option(self) -> str | None:
93  """Return the current selected preset."""
94  if not self.coordinator.data.state.preset_id:
95  return None
96  if preset := self.coordinator.data.presets.get(
97  self.coordinator.data.state.preset_id
98  ):
99  return preset.name
100  return None
101 
102  @wled_exception_handler
103  async def async_select_option(self, option: str) -> None:
104  """Set WLED segment to the selected preset."""
105  await self.coordinator.wled.preset(preset=option)
106 
107 
109  """Define a WLED Playlist select."""
110 
111  _attr_translation_key = "playlist"
112 
113  def __init__(self, coordinator: WLEDDataUpdateCoordinator) -> None:
114  """Initialize WLED playlist."""
115  super().__init__(coordinator=coordinator)
116 
117  self._attr_unique_id_attr_unique_id = f"{coordinator.data.info.mac_address}_playlist"
118  self._attr_options_attr_options = [
119  playlist.name for playlist in self.coordinator.data.playlists.values()
120  ]
121 
122  @property
123  def available(self) -> bool:
124  """Return True if entity is available."""
125  return len(self.coordinator.data.playlists) > 0 and super().available
126 
127  @property
128  def current_option(self) -> str | None:
129  """Return the currently selected playlist."""
130  if not self.coordinator.data.state.playlist_id:
131  return None
132  if playlist := self.coordinator.data.playlists.get(
133  self.coordinator.data.state.playlist_id
134  ):
135  return playlist.name
136  return None
137 
138  @wled_exception_handler
139  async def async_select_option(self, option: str) -> None:
140  """Set WLED segment to the selected playlist."""
141  await self.coordinator.wled.playlist(playlist=option)
142 
143 
145  """Defines a WLED Palette select."""
146 
147  _attr_entity_category = EntityCategory.CONFIG
148  _attr_translation_key = "color_palette"
149  _segment: int
150 
151  def __init__(self, coordinator: WLEDDataUpdateCoordinator, segment: int) -> None:
152  """Initialize WLED ."""
153  super().__init__(coordinator=coordinator)
154 
155  # Segment 0 uses a simpler name, which is more natural for when using
156  # a single segment / using WLED with one big LED strip.
157  if segment != 0:
158  self._attr_translation_key_attr_translation_key_attr_translation_key = "segment_color_palette"
159  self._attr_translation_placeholders_attr_translation_placeholders = {"segment": str(segment)}
160 
161  self._attr_unique_id_attr_unique_id = f"{coordinator.data.info.mac_address}_palette_{segment}"
162  self._attr_options_attr_options = [
163  palette.name for palette in self.coordinator.data.palettes.values()
164  ]
165  self._segment_segment = segment
166 
167  @property
168  def available(self) -> bool:
169  """Return True if entity is available."""
170  try:
171  self.coordinator.data.state.segments[self._segment_segment]
172  except KeyError:
173  return False
174 
175  return super().available
176 
177  @property
178  def current_option(self) -> str | None:
179  """Return the current selected color palette."""
180  return self.coordinator.data.palettes[
181  int(self.coordinator.data.state.segments[self._segment_segment].palette_id)
182  ].name
183 
184  @wled_exception_handler
185  async def async_select_option(self, option: str) -> None:
186  """Set WLED segment to the selected color palette."""
187  await self.coordinator.wled.segment(segment_id=self._segment_segment, palette=option)
188 
189 
190 @callback
192  coordinator: WLEDDataUpdateCoordinator,
193  current_ids: set[int],
194  async_add_entities: AddEntitiesCallback,
195 ) -> None:
196  """Update segments."""
197  segment_ids = {
198  segment.segment_id
199  for segment in coordinator.data.state.segments.values()
200  if segment.segment_id is not None
201  }
202 
203  new_entities: list[WLEDPaletteSelect] = []
204 
205  # Process new segments, add them to Home Assistant
206  for segment_id in segment_ids - current_ids:
207  current_ids.add(segment_id)
208  new_entities.append(WLEDPaletteSelect(coordinator, segment_id))
209 
210  async_add_entities(new_entities)
None __init__(self, WLEDDataUpdateCoordinator coordinator)
Definition: select.py:54
None __init__(self, WLEDDataUpdateCoordinator coordinator, int segment)
Definition: select.py:151
None __init__(self, WLEDDataUpdateCoordinator coordinator)
Definition: select.py:113
None __init__(self, WLEDDataUpdateCoordinator coordinator)
Definition: select.py:77
None async_setup_entry(HomeAssistant hass, WLEDConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: select.py:26
None async_update_segments(WLEDDataUpdateCoordinator coordinator, set[int] current_ids, AddEntitiesCallback async_add_entities)
Definition: select.py:195