Home Assistant Unofficial Reference 2024.12.1
number.py
Go to the documentation of this file.
1 """Component providing HA number support for Ring Door Bell/Chimes."""
2 
3 from collections.abc import Awaitable, Callable
4 from dataclasses import dataclass
5 from typing import Any, Generic, cast
6 
7 from ring_doorbell import RingChime, RingDoorBell, RingGeneric, RingOther
8 import ring_doorbell.const
9 
11  NumberEntity,
12  NumberEntityDescription,
13  NumberMode,
14 )
15 from homeassistant.core import HomeAssistant, callback
16 from homeassistant.helpers.entity_platform import AddEntitiesCallback
17 from homeassistant.helpers.typing import StateType
18 
19 from . import RingConfigEntry
20 from .coordinator import RingDataCoordinator
21 from .entity import RingDeviceT, RingEntity, refresh_after
22 
23 
25  hass: HomeAssistant,
26  entry: RingConfigEntry,
27  async_add_entities: AddEntitiesCallback,
28 ) -> None:
29  """Set up a numbers for a Ring device."""
30  ring_data = entry.runtime_data
31  devices_coordinator = ring_data.devices_coordinator
32 
34  RingNumber(device, devices_coordinator, description)
35  for description in NUMBER_TYPES
36  for device in ring_data.devices.all_devices
37  if description.exists_fn(device)
38  )
39 
40 
41 @dataclass(frozen=True, kw_only=True)
43  """Describes Ring number entity."""
44 
45  value_fn: Callable[[RingDeviceT], StateType]
46  setter_fn: Callable[[RingDeviceT, float], Awaitable[None]]
47  exists_fn: Callable[[RingGeneric], bool]
48 
49 
50 NUMBER_TYPES: tuple[RingNumberEntityDescription[Any], ...] = (
51  RingNumberEntityDescription[RingChime](
52  key="volume",
53  translation_key="volume",
54  mode=NumberMode.SLIDER,
55  native_min_value=ring_doorbell.const.CHIME_VOL_MIN,
56  native_max_value=ring_doorbell.const.CHIME_VOL_MAX,
57  native_step=1,
58  value_fn=lambda device: device.volume,
59  setter_fn=lambda device, value: device.async_set_volume(int(value)),
60  exists_fn=lambda device: isinstance(device, RingChime),
61  ),
62  RingNumberEntityDescription[RingDoorBell](
63  key="volume",
64  translation_key="volume",
65  mode=NumberMode.SLIDER,
66  native_min_value=ring_doorbell.const.DOORBELL_VOL_MIN,
67  native_max_value=ring_doorbell.const.DOORBELL_VOL_MAX,
68  native_step=1,
69  value_fn=lambda device: device.volume,
70  setter_fn=lambda device, value: device.async_set_volume(int(value)),
71  exists_fn=lambda device: isinstance(device, RingDoorBell),
72  ),
73  RingNumberEntityDescription[RingOther](
74  key="doorbell_volume",
75  translation_key="doorbell_volume",
76  mode=NumberMode.SLIDER,
77  native_min_value=ring_doorbell.const.OTHER_DOORBELL_VOL_MIN,
78  native_max_value=ring_doorbell.const.OTHER_DOORBELL_VOL_MAX,
79  native_step=1,
80  value_fn=lambda device: device.doorbell_volume,
81  setter_fn=lambda device, value: device.async_set_doorbell_volume(int(value)),
82  exists_fn=lambda device: isinstance(device, RingOther),
83  ),
84  RingNumberEntityDescription[RingOther](
85  key="mic_volume",
86  translation_key="mic_volume",
87  mode=NumberMode.SLIDER,
88  native_min_value=ring_doorbell.const.MIC_VOL_MIN,
89  native_max_value=ring_doorbell.const.MIC_VOL_MAX,
90  native_step=1,
91  value_fn=lambda device: device.mic_volume,
92  setter_fn=lambda device, value: device.async_set_mic_volume(int(value)),
93  exists_fn=lambda device: isinstance(device, RingOther),
94  ),
95  RingNumberEntityDescription[RingOther](
96  key="voice_volume",
97  translation_key="voice_volume",
98  mode=NumberMode.SLIDER,
99  native_min_value=ring_doorbell.const.VOICE_VOL_MIN,
100  native_max_value=ring_doorbell.const.VOICE_VOL_MAX,
101  native_step=1,
102  value_fn=lambda device: device.voice_volume,
103  setter_fn=lambda device, value: device.async_set_voice_volume(int(value)),
104  exists_fn=lambda device: isinstance(device, RingOther),
105  ),
106 )
107 
108 
109 class RingNumber(RingEntity[RingDeviceT], NumberEntity):
110  """A number implementation for Ring device."""
111 
112  entity_description: RingNumberEntityDescription[RingDeviceT]
113 
114  def __init__(
115  self,
116  device: RingDeviceT,
117  coordinator: RingDataCoordinator,
118  description: RingNumberEntityDescription[RingDeviceT],
119  ) -> None:
120  """Initialize a number for Ring device."""
121  super().__init__(device, coordinator)
122  self.entity_descriptionentity_description = description
123  self._attr_unique_id_attr_unique_id = f"{device.id}-{description.key}"
124  self._update_native_value_update_native_value()
125 
126  def _update_native_value(self) -> None:
127  native_value = self.entity_descriptionentity_description.value_fn(self._device_device_device_device)
128  if native_value is not None:
129  self._attr_native_value_attr_native_value = float(native_value)
130 
131  @callback
132  def _handle_coordinator_update(self) -> None:
133  """Call update method."""
134 
135  self._device_device_device_device = cast(
136  RingDeviceT,
137  self._get_coordinator_data_get_coordinator_data().get_device(self._device_device_device_device.device_api_id),
138  )
139 
140  self._update_native_value_update_native_value()
141 
143 
144  @refresh_after
145  async def async_set_native_value(self, value: float) -> None:
146  """Call setter on Ring device."""
147  await self.entity_descriptionentity_description.setter_fn(self._device_device_device_device, value)
148 
149  self._attr_native_value_attr_native_value = value
150  self.async_write_ha_stateasync_write_ha_state()
None async_set_native_value(self, float value)
Definition: number.py:145
None __init__(self, RingDeviceT device, RingDataCoordinator coordinator, RingNumberEntityDescription[RingDeviceT] description)
Definition: number.py:119
DeviceEntry get_device(HomeAssistant hass, str unique_id)
Definition: util.py:12
None async_setup_entry(HomeAssistant hass, RingConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: number.py:28