Home Assistant Unofficial Reference 2024.12.1
switch.py
Go to the documentation of this file.
1 """Support for WLED switches."""
2 
3 from __future__ import annotations
4 
5 from functools import partial
6 from typing import Any
7 
8 from homeassistant.components.switch import SwitchEntity
9 from homeassistant.const import EntityCategory
10 from homeassistant.core import HomeAssistant, callback
11 from homeassistant.helpers.entity_platform import AddEntitiesCallback
12 
13 from . import WLEDConfigEntry
14 from .const import ATTR_DURATION, ATTR_TARGET_BRIGHTNESS, ATTR_UDP_PORT
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 switch based on a config entry."""
28  coordinator = entry.runtime_data
29 
31  [
32  WLEDNightlightSwitch(coordinator),
33  WLEDSyncSendSwitch(coordinator),
34  WLEDSyncReceiveSwitch(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  """Defines a WLED nightlight switch."""
50 
51  _attr_entity_category = EntityCategory.CONFIG
52  _attr_translation_key = "nightlight"
53 
54  def __init__(self, coordinator: WLEDDataUpdateCoordinator) -> None:
55  """Initialize WLED nightlight switch."""
56  super().__init__(coordinator=coordinator)
57  self._attr_unique_id_attr_unique_id = f"{coordinator.data.info.mac_address}_nightlight"
58 
59  @property
60  def extra_state_attributes(self) -> dict[str, Any] | None:
61  """Return the state attributes of the entity."""
62  state = self.coordinator.data.state
63  return {
64  ATTR_DURATION: state.nightlight.duration,
65  ATTR_TARGET_BRIGHTNESS: state.nightlight.target_brightness,
66  }
67 
68  @property
69  def is_on(self) -> bool:
70  """Return the state of the switch."""
71  return bool(self.coordinator.data.state.nightlight.on)
72 
73  @wled_exception_handler
74  async def async_turn_off(self, **kwargs: Any) -> None:
75  """Turn off the WLED nightlight switch."""
76  await self.coordinator.wled.nightlight(on=False)
77 
78  @wled_exception_handler
79  async def async_turn_on(self, **kwargs: Any) -> None:
80  """Turn on the WLED nightlight switch."""
81  await self.coordinator.wled.nightlight(on=True)
82 
83 
85  """Defines a WLED sync send switch."""
86 
87  _attr_entity_category = EntityCategory.CONFIG
88  _attr_translation_key = "sync_send"
89 
90  def __init__(self, coordinator: WLEDDataUpdateCoordinator) -> None:
91  """Initialize WLED sync send switch."""
92  super().__init__(coordinator=coordinator)
93  self._attr_unique_id_attr_unique_id = f"{coordinator.data.info.mac_address}_sync_send"
94 
95  @property
96  def extra_state_attributes(self) -> dict[str, Any] | None:
97  """Return the state attributes of the entity."""
98  return {ATTR_UDP_PORT: self.coordinator.data.info.udp_port}
99 
100  @property
101  def is_on(self) -> bool:
102  """Return the state of the switch."""
103  return bool(self.coordinator.data.state.sync.send)
104 
105  @wled_exception_handler
106  async def async_turn_off(self, **kwargs: Any) -> None:
107  """Turn off the WLED sync send switch."""
108  await self.coordinator.wled.sync(send=False)
109 
110  @wled_exception_handler
111  async def async_turn_on(self, **kwargs: Any) -> None:
112  """Turn on the WLED sync send switch."""
113  await self.coordinator.wled.sync(send=True)
114 
115 
117  """Defines a WLED sync receive switch."""
118 
119  _attr_entity_category = EntityCategory.CONFIG
120  _attr_translation_key = "sync_receive"
121 
122  def __init__(self, coordinator: WLEDDataUpdateCoordinator) -> None:
123  """Initialize WLED sync receive switch."""
124  super().__init__(coordinator=coordinator)
125  self._attr_unique_id_attr_unique_id = f"{coordinator.data.info.mac_address}_sync_receive"
126 
127  @property
128  def extra_state_attributes(self) -> dict[str, Any] | None:
129  """Return the state attributes of the entity."""
130  return {ATTR_UDP_PORT: self.coordinator.data.info.udp_port}
131 
132  @property
133  def is_on(self) -> bool:
134  """Return the state of the switch."""
135  return bool(self.coordinator.data.state.sync.receive)
136 
137  @wled_exception_handler
138  async def async_turn_off(self, **kwargs: Any) -> None:
139  """Turn off the WLED sync receive switch."""
140  await self.coordinator.wled.sync(receive=False)
141 
142  @wled_exception_handler
143  async def async_turn_on(self, **kwargs: Any) -> None:
144  """Turn on the WLED sync receive switch."""
145  await self.coordinator.wled.sync(receive=True)
146 
147 
149  """Defines a WLED reverse effect switch."""
150 
151  _attr_entity_category = EntityCategory.CONFIG
152  _attr_translation_key = "reverse"
153  _segment: int
154 
155  def __init__(self, coordinator: WLEDDataUpdateCoordinator, segment: int) -> None:
156  """Initialize WLED reverse effect switch."""
157  super().__init__(coordinator=coordinator)
158 
159  # Segment 0 uses a simpler name, which is more natural for when using
160  # a single segment / using WLED with one big LED strip.
161  if segment != 0:
162  self._attr_translation_key_attr_translation_key_attr_translation_key = "segment_reverse"
163  self._attr_translation_placeholders_attr_translation_placeholders = {"segment": str(segment)}
164 
165  self._attr_unique_id_attr_unique_id = f"{coordinator.data.info.mac_address}_reverse_{segment}"
166  self._segment_segment = segment
167 
168  @property
169  def available(self) -> bool:
170  """Return True if entity is available."""
171  try:
172  self.coordinator.data.state.segments[self._segment_segment]
173  except KeyError:
174  return False
175 
176  return super().available
177 
178  @property
179  def is_on(self) -> bool:
180  """Return the state of the switch."""
181  return self.coordinator.data.state.segments[self._segment_segment].reverse
182 
183  @wled_exception_handler
184  async def async_turn_off(self, **kwargs: Any) -> None:
185  """Turn off the WLED reverse effect switch."""
186  await self.coordinator.wled.segment(segment_id=self._segment_segment, reverse=False)
187 
188  @wled_exception_handler
189  async def async_turn_on(self, **kwargs: Any) -> None:
190  """Turn on the WLED reverse effect switch."""
191  await self.coordinator.wled.segment(segment_id=self._segment_segment, reverse=True)
192 
193 
194 @callback
196  coordinator: WLEDDataUpdateCoordinator,
197  current_ids: set[int],
198  async_add_entities: AddEntitiesCallback,
199 ) -> None:
200  """Update segments."""
201  segment_ids = {
202  segment.segment_id
203  for segment in coordinator.data.state.segments.values()
204  if segment.segment_id is not None
205  }
206 
207  new_entities: list[WLEDReverseSwitch] = []
208 
209  # Process new segments, add them to Home Assistant
210  for segment_id in segment_ids - current_ids:
211  current_ids.add(segment_id)
212  new_entities.append(WLEDReverseSwitch(coordinator, segment_id))
213 
214  async_add_entities(new_entities)
None __init__(self, WLEDDataUpdateCoordinator coordinator)
Definition: switch.py:54
None __init__(self, WLEDDataUpdateCoordinator coordinator, int segment)
Definition: switch.py:155
None __init__(self, WLEDDataUpdateCoordinator coordinator)
Definition: switch.py:122
dict[str, Any]|None extra_state_attributes(self)
Definition: switch.py:96
None __init__(self, WLEDDataUpdateCoordinator coordinator)
Definition: switch.py:90
None async_update_segments(WLEDDataUpdateCoordinator coordinator, set[int] current_ids, AddEntitiesCallback async_add_entities)
Definition: switch.py:199
None async_setup_entry(HomeAssistant hass, WLEDConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: switch.py:26