Home Assistant Unofficial Reference 2024.12.1
select.py
Go to the documentation of this file.
1 """Support for Magic Home select."""
2 
3 from __future__ import annotations
4 
5 import asyncio
6 
7 from flux_led.aio import AIOWifiLedBulb
8 from flux_led.base_device import DeviceType
9 from flux_led.const import (
10  DEFAULT_WHITE_CHANNEL_TYPE,
11  STATE_CHANGE_LATENCY,
12  WhiteChannelType,
13 )
14 from flux_led.protocol import PowerRestoreState, RemoteConfig
15 
16 from homeassistant import config_entries
17 from homeassistant.components.select import SelectEntity
18 from homeassistant.const import CONF_NAME, EntityCategory
19 from homeassistant.core import HomeAssistant, callback
20 from homeassistant.helpers.entity_platform import AddEntitiesCallback
21 
22 from .const import CONF_WHITE_CHANNEL_TYPE, DOMAIN, FLUX_COLOR_MODE_RGBW
23 from .coordinator import FluxLedUpdateCoordinator
24 from .entity import FluxBaseEntity, FluxEntity
25 from .util import _human_readable_option
26 
27 NAME_TO_POWER_RESTORE_STATE = {
28  _human_readable_option(option.name): option for option in PowerRestoreState
29 }
30 
31 
33  hass: HomeAssistant, entry: config_entries.ConfigEntry
34 ) -> None:
35  """Reload after making a change that will effect the operation of the device."""
36  await asyncio.sleep(STATE_CHANGE_LATENCY)
37  hass.async_create_task(hass.config_entries.async_reload(entry.entry_id))
38 
39 
41  hass: HomeAssistant,
43  async_add_entities: AddEntitiesCallback,
44 ) -> None:
45  """Set up the Flux selects."""
46  coordinator: FluxLedUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
47  device = coordinator.device
48  entities: list[
49  FluxPowerStateSelect
50  | FluxOperatingModesSelect
51  | FluxWiringsSelect
52  | FluxICTypeSelect
53  | FluxRemoteConfigSelect
54  | FluxWhiteChannelSelect
55  ] = []
56  entry.data.get(CONF_NAME, entry.title)
57  base_unique_id = entry.unique_id or entry.entry_id
58 
59  if device.device_type == DeviceType.Switch:
60  entities.append(FluxPowerStateSelect(coordinator.device, entry))
61  if device.operating_modes:
62  entities.append(
63  FluxOperatingModesSelect(coordinator, base_unique_id, "operating_mode")
64  )
65  if device.wirings and device.wiring is not None:
66  entities.append(FluxWiringsSelect(coordinator, base_unique_id, "wiring"))
67  if device.ic_types:
68  entities.append(FluxICTypeSelect(coordinator, base_unique_id, "ic_type"))
69  if device.remote_config:
70  entities.append(
71  FluxRemoteConfigSelect(coordinator, base_unique_id, "remote_config")
72  )
73  if FLUX_COLOR_MODE_RGBW in device.color_modes:
74  entities.append(FluxWhiteChannelSelect(coordinator.device, entry))
75 
76  async_add_entities(entities)
77 
78 
80  """Representation of a flux config entity that only updates at start or change."""
81 
82  _attr_entity_category = EntityCategory.CONFIG
83 
84 
86  """Representation of a flux config entity that updates."""
87 
88  _attr_entity_category = EntityCategory.CONFIG
89 
90 
92  """Representation of a Flux power restore state option."""
93 
94  _attr_translation_key = "power_restored"
95  _attr_options = list(NAME_TO_POWER_RESTORE_STATE)
96 
97  def __init__(
98  self,
99  device: AIOWifiLedBulb,
101  ) -> None:
102  """Initialize the power state select."""
103  super().__init__(device, entry)
104  base_unique_id = entry.unique_id or entry.entry_id
105  self._attr_unique_id_attr_unique_id = f"{base_unique_id}_power_restored"
106  self._async_set_current_option_from_device_async_set_current_option_from_device()
107 
108  @callback
110  """Set the option from the current power state."""
111  restore_states = self._device.power_restore_states
112  assert restore_states is not None
113  assert restore_states.channel1 is not None
114  self._attr_current_option_attr_current_option = _human_readable_option(restore_states.channel1.name)
115 
116  async def async_select_option(self, option: str) -> None:
117  """Change the power state."""
118  await self._device.async_set_power_restore(
119  channel1=NAME_TO_POWER_RESTORE_STATE[option]
120  )
121  self._async_set_current_option_from_device_async_set_current_option_from_device()
122  self.async_write_ha_stateasync_write_ha_state()
123 
124 
126  """Representation of Flux ic type."""
127 
128  _attr_translation_key = "ic_type"
129 
130  @property
131  def options(self) -> list[str]:
132  """Return the available ic types."""
133  assert self._device.ic_types is not None
134  return self._device.ic_types
135 
136  @property
137  def current_option(self) -> str | None:
138  """Return the current ic type."""
139  return self._device.ic_type
140 
141  async def async_select_option(self, option: str) -> None:
142  """Change the ic type."""
143  await self._device.async_set_device_config(ic_type=option)
144  await _async_delayed_reload(self.hasshasshass, self.coordinator.entry)
145 
146 
148  """Representation of Flux wirings."""
149 
150  _attr_translation_key = "wiring"
151 
152  @property
153  def options(self) -> list[str]:
154  """Return the available wiring options based on the strip protocol."""
155  assert self._device.wirings is not None
156  return self._device.wirings
157 
158  @property
159  def current_option(self) -> str | None:
160  """Return the current wiring."""
161  return self._device.wiring
162 
163  async def async_select_option(self, option: str) -> None:
164  """Change the wiring."""
165  await self._device.async_set_device_config(wiring=option)
166 
167 
169  """Representation of Flux operating modes."""
170 
171  _attr_translation_key = "operating_mode"
172 
173  @property
174  def options(self) -> list[str]:
175  """Return the current operating mode."""
176  assert self._device.operating_modes is not None
177  return self._device.operating_modes
178 
179  @property
180  def current_option(self) -> str | None:
181  """Return the current operating mode."""
182  return self._device.operating_mode
183 
184  async def async_select_option(self, option: str) -> None:
185  """Change the ic type."""
186  await self._device.async_set_device_config(operating_mode=option)
187  await _async_delayed_reload(self.hasshasshass, self.coordinator.entry)
188 
189 
191  """Representation of Flux remote config type."""
192 
193  _attr_translation_key = "remote_config"
194 
195  def __init__(
196  self,
197  coordinator: FluxLedUpdateCoordinator,
198  base_unique_id: str,
199  key: str,
200  ) -> None:
201  """Initialize the remote config type select."""
202  super().__init__(coordinator, base_unique_id, key)
203  assert self._device.remote_config is not None
204  self._name_to_state_name_to_state = {
205  _human_readable_option(option.name): option for option in RemoteConfig
206  }
207  self._attr_options_attr_options = list(self._name_to_state_name_to_state)
208 
209  @property
210  def current_option(self) -> str | None:
211  """Return the current remote config."""
212  assert self._device.remote_config is not None
213  return _human_readable_option(self._device.remote_config.name)
214 
215  async def async_select_option(self, option: str) -> None:
216  """Change the remote config setting."""
217  remote_config: RemoteConfig = self._name_to_state_name_to_state[option]
218  await self._device.async_config_remotes(remote_config)
219 
220 
222  """Representation of Flux white channel."""
223 
224  _attr_translation_key = "white_channel"
225 
226  _attr_options = [_human_readable_option(option.name) for option in WhiteChannelType]
227 
228  def __init__(
229  self,
230  device: AIOWifiLedBulb,
232  ) -> None:
233  """Initialize the white channel select."""
234  super().__init__(device, entry)
235  base_unique_id = entry.unique_id or entry.entry_id
236  self._attr_unique_id_attr_unique_id = f"{base_unique_id}_white_channel"
237 
238  @property
239  def current_option(self) -> str | None:
240  """Return the current white channel type."""
241  return _human_readable_option(
242  self.entryentry.data.get(
243  CONF_WHITE_CHANNEL_TYPE, DEFAULT_WHITE_CHANNEL_TYPE.name
244  )
245  )
246 
247  async def async_select_option(self, option: str) -> None:
248  """Change the white channel type."""
249  self.hasshass.config_entries.async_update_entry(
250  self.entryentry,
251  data={**self.entryentry.data, CONF_WHITE_CHANNEL_TYPE: option.lower()},
252  )
253  await _async_delayed_reload(self.hasshass, self.entryentry)
None __init__(self, AIOWifiLedBulb device, config_entries.ConfigEntry entry)
Definition: select.py:101
None __init__(self, FluxLedUpdateCoordinator coordinator, str base_unique_id, str key)
Definition: select.py:200
None __init__(self, AIOWifiLedBulb device, config_entries.ConfigEntry entry)
Definition: select.py:232
None async_setup_entry(HomeAssistant hass, config_entries.ConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: select.py:44
None _async_delayed_reload(HomeAssistant hass, config_entries.ConfigEntry entry)
Definition: select.py:34
str _human_readable_option(str const_option)
Definition: util.py:26