Home Assistant Unofficial Reference 2024.12.1
number.py
Go to the documentation of this file.
1 """Support for LED numbers."""
2 
3 from __future__ import annotations
4 
5 from collections.abc import Callable
6 from dataclasses import dataclass
7 from functools import partial
8 
9 from wled import Segment
10 
11 from homeassistant.components.number import NumberEntity, NumberEntityDescription
12 from homeassistant.const import EntityCategory
13 from homeassistant.core import HomeAssistant, callback
14 from homeassistant.helpers.entity_platform import AddEntitiesCallback
15 
16 from . import WLEDConfigEntry
17 from .const import ATTR_INTENSITY, ATTR_SPEED
18 from .coordinator import WLEDDataUpdateCoordinator
19 from .entity import WLEDEntity
20 from .helpers import wled_exception_handler
21 
22 PARALLEL_UPDATES = 1
23 
24 
26  hass: HomeAssistant,
27  entry: WLEDConfigEntry,
28  async_add_entities: AddEntitiesCallback,
29 ) -> None:
30  """Set up WLED number based on a config entry."""
31  coordinator = entry.runtime_data
32 
33  update_segments = partial(
34  async_update_segments,
35  coordinator,
36  set(),
37  async_add_entities,
38  )
39  coordinator.async_add_listener(update_segments)
40  update_segments()
41 
42 
43 @dataclass(frozen=True, kw_only=True)
45  """Class describing WLED number entities."""
46 
47  value_fn: Callable[[Segment], int | None]
48 
49 
50 NUMBERS = [
52  key=ATTR_SPEED,
53  translation_key="speed",
54  entity_category=EntityCategory.CONFIG,
55  native_step=1,
56  native_min_value=0,
57  native_max_value=255,
58  value_fn=lambda segment: segment.speed,
59  ),
61  key=ATTR_INTENSITY,
62  translation_key="intensity",
63  entity_category=EntityCategory.CONFIG,
64  native_step=1,
65  native_min_value=0,
66  native_max_value=255,
67  value_fn=lambda segment: int(segment.intensity),
68  ),
69 ]
70 
71 
73  """Defines a WLED speed number."""
74 
75  entity_description: WLEDNumberEntityDescription
76 
77  def __init__(
78  self,
79  coordinator: WLEDDataUpdateCoordinator,
80  segment: int,
81  description: WLEDNumberEntityDescription,
82  ) -> None:
83  """Initialize WLED ."""
84  super().__init__(coordinator=coordinator)
85  self.entity_descriptionentity_description = description
86 
87  # Segment 0 uses a simpler name, which is more natural for when using
88  # a single segment / using WLED with one big LED strip.
89  if segment != 0:
90  self._attr_translation_key_attr_translation_key = f"segment_{description.translation_key}"
91  self._attr_translation_placeholders_attr_translation_placeholders = {"segment": str(segment)}
92 
93  self._attr_unique_id_attr_unique_id = (
94  f"{coordinator.data.info.mac_address}_{description.key}_{segment}"
95  )
96  self._segment_segment = segment
97 
98  @property
99  def available(self) -> bool:
100  """Return True if entity is available."""
101  try:
102  self.coordinator.data.state.segments[self._segment_segment]
103  except KeyError:
104  return False
105 
106  return super().available
107 
108  @property
109  def native_value(self) -> float | None:
110  """Return the current WLED segment number value."""
111  return self.entity_descriptionentity_description.value_fn(
112  self.coordinator.data.state.segments[self._segment_segment]
113  )
114 
115  @wled_exception_handler
116  async def async_set_native_value(self, value: float) -> None:
117  """Set the WLED segment value."""
118  key = self.entity_descriptionentity_description.key
119  if key == ATTR_SPEED:
120  await self.coordinator.wled.segment(
121  segment_id=self._segment_segment, speed=int(value)
122  )
123  elif key == ATTR_INTENSITY:
124  await self.coordinator.wled.segment(
125  segment_id=self._segment_segment, intensity=int(value)
126  )
127 
128 
129 @callback
131  coordinator: WLEDDataUpdateCoordinator,
132  current_ids: set[int],
133  async_add_entities: AddEntitiesCallback,
134 ) -> None:
135  """Update segments."""
136  segment_ids = {
137  segment.segment_id
138  for segment in coordinator.data.state.segments.values()
139  if segment.segment_id is not None
140  }
141 
142  new_entities: list[WLEDNumber] = []
143 
144  # Process new segments, add them to Home Assistant
145  for segment_id in segment_ids - current_ids:
146  current_ids.add(segment_id)
147  new_entities.extend(
148  WLEDNumber(coordinator, segment_id, desc) for desc in NUMBERS
149  )
150 
151  async_add_entities(new_entities)
None async_set_native_value(self, float value)
Definition: number.py:116
None __init__(self, WLEDDataUpdateCoordinator coordinator, int segment, WLEDNumberEntityDescription description)
Definition: number.py:82
None async_update_segments(WLEDDataUpdateCoordinator coordinator, set[int] current_ids, AddEntitiesCallback async_add_entities)
Definition: number.py:134
None async_setup_entry(HomeAssistant hass, WLEDConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: number.py:29