Home Assistant Unofficial Reference 2024.12.1
number.py
Go to the documentation of this file.
1 """Component providing number entities for UniFi Protect."""
2 
3 from __future__ import annotations
4 
5 from collections.abc import Sequence
6 from dataclasses import dataclass
7 from datetime import timedelta
8 
9 from uiprotect.data import (
10  Camera,
11  Doorlock,
12  Light,
13  ModelType,
14  ProtectAdoptableDeviceModel,
15 )
16 
17 from homeassistant.components.number import NumberEntity, NumberEntityDescription
18 from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfTime
19 from homeassistant.core import HomeAssistant, callback
20 from homeassistant.helpers.entity_platform import AddEntitiesCallback
21 
22 from .data import ProtectData, ProtectDeviceType, UFPConfigEntry
23 from .entity import (
24  PermRequired,
25  ProtectDeviceEntity,
26  ProtectEntityDescription,
27  ProtectSetableKeysMixin,
28  T,
29  async_all_device_entities,
30 )
31 
32 
33 @dataclass(frozen=True, kw_only=True)
35  ProtectSetableKeysMixin[T], NumberEntityDescription
36 ):
37  """Describes UniFi Protect Number entity."""
38 
39  ufp_max: int | float
40  ufp_min: int | float
41  ufp_step: int | float
42 
43 
44 def _get_pir_duration(obj: Light) -> int:
45  return int(obj.light_device_settings.pir_duration.total_seconds())
46 
47 
48 async def _set_pir_duration(obj: Light, value: float) -> None:
49  await obj.set_duration(timedelta(seconds=value))
50 
51 
52 def _get_auto_close(obj: Doorlock) -> int:
53  return int(obj.auto_close_time.total_seconds())
54 
55 
56 async def _set_auto_close(obj: Doorlock, value: float) -> None:
57  await obj.set_auto_close_time(timedelta(seconds=value))
58 
59 
60 def _get_chime_duration(obj: Camera) -> int:
61  return int(obj.chime_duration_seconds)
62 
63 
64 CAMERA_NUMBERS: tuple[ProtectNumberEntityDescription, ...] = (
66  key="wdr_value",
67  name="Wide dynamic range",
68  icon="mdi:state-machine",
69  entity_category=EntityCategory.CONFIG,
70  ufp_min=0,
71  ufp_max=3,
72  ufp_step=1,
73  ufp_required_field="feature_flags.has_wdr",
74  ufp_value="isp_settings.wdr",
75  ufp_set_method="set_wdr_level",
76  ufp_perm=PermRequired.WRITE,
77  ),
79  key="mic_level",
80  name="Microphone level",
81  icon="mdi:microphone",
82  entity_category=EntityCategory.CONFIG,
83  native_unit_of_measurement=PERCENTAGE,
84  ufp_min=0,
85  ufp_max=100,
86  ufp_step=1,
87  ufp_required_field="has_mic",
88  ufp_value="mic_volume",
89  ufp_enabled="feature_flags.has_mic",
90  ufp_set_method="set_mic_volume",
91  ufp_perm=PermRequired.WRITE,
92  ),
94  key="zoom_position",
95  name="Zoom level",
96  icon="mdi:magnify-plus-outline",
97  entity_category=EntityCategory.CONFIG,
98  native_unit_of_measurement=PERCENTAGE,
99  ufp_min=0,
100  ufp_max=100,
101  ufp_step=1,
102  ufp_required_field="feature_flags.can_optical_zoom",
103  ufp_value="isp_settings.zoom_position",
104  ufp_set_method="set_camera_zoom",
105  ufp_perm=PermRequired.WRITE,
106  ),
108  key="chime_duration",
109  name="Chime duration",
110  icon="mdi:bell",
111  entity_category=EntityCategory.CONFIG,
112  native_unit_of_measurement=UnitOfTime.SECONDS,
113  ufp_min=1,
114  ufp_max=10,
115  ufp_step=0.1,
116  ufp_required_field="feature_flags.has_chime",
117  ufp_enabled="is_digital_chime",
118  ufp_value_fn=_get_chime_duration,
119  ufp_set_method="set_chime_duration",
120  ufp_perm=PermRequired.WRITE,
121  ),
123  key="icr_lux",
124  name="Infrared custom lux trigger",
125  icon="mdi:white-balance-sunny",
126  entity_category=EntityCategory.CONFIG,
127  ufp_min=0,
128  ufp_max=30,
129  ufp_step=1,
130  ufp_required_field="feature_flags.has_led_ir",
131  ufp_value="icr_lux_display",
132  ufp_set_method="set_icr_custom_lux",
133  ufp_enabled="is_ir_led_slider_enabled",
134  ufp_perm=PermRequired.WRITE,
135  ),
136 )
137 
138 LIGHT_NUMBERS: tuple[ProtectNumberEntityDescription, ...] = (
140  key="sensitivity",
141  name="Motion sensitivity",
142  icon="mdi:walk",
143  entity_category=EntityCategory.CONFIG,
144  native_unit_of_measurement=PERCENTAGE,
145  ufp_min=0,
146  ufp_max=100,
147  ufp_step=1,
148  ufp_required_field=None,
149  ufp_value="light_device_settings.pir_sensitivity",
150  ufp_set_method="set_sensitivity",
151  ufp_perm=PermRequired.WRITE,
152  ),
153  ProtectNumberEntityDescription[Light](
154  key="duration",
155  name="Auto-shutoff duration",
156  icon="mdi:camera-timer",
157  entity_category=EntityCategory.CONFIG,
158  native_unit_of_measurement=UnitOfTime.SECONDS,
159  ufp_min=15,
160  ufp_max=900,
161  ufp_step=15,
162  ufp_required_field=None,
163  ufp_value_fn=_get_pir_duration,
164  ufp_set_method_fn=_set_pir_duration,
165  ufp_perm=PermRequired.WRITE,
166  ),
167 )
168 
169 SENSE_NUMBERS: tuple[ProtectNumberEntityDescription, ...] = (
171  key="sensitivity",
172  name="Motion sensitivity",
173  icon="mdi:walk",
174  entity_category=EntityCategory.CONFIG,
175  native_unit_of_measurement=PERCENTAGE,
176  ufp_min=0,
177  ufp_max=100,
178  ufp_step=1,
179  ufp_required_field=None,
180  ufp_value="motion_settings.sensitivity",
181  ufp_set_method="set_motion_sensitivity",
182  ufp_perm=PermRequired.WRITE,
183  ),
184 )
185 
186 DOORLOCK_NUMBERS: tuple[ProtectNumberEntityDescription, ...] = (
187  ProtectNumberEntityDescription[Doorlock](
188  key="auto_lock_time",
189  name="Auto-lock timeout",
190  icon="mdi:walk",
191  entity_category=EntityCategory.CONFIG,
192  native_unit_of_measurement=UnitOfTime.SECONDS,
193  ufp_min=0,
194  ufp_max=3600,
195  ufp_step=15,
196  ufp_required_field=None,
197  ufp_value_fn=_get_auto_close,
198  ufp_set_method_fn=_set_auto_close,
199  ufp_perm=PermRequired.WRITE,
200  ),
201 )
202 
203 CHIME_NUMBERS: tuple[ProtectNumberEntityDescription, ...] = (
205  key="volume",
206  name="Volume",
207  icon="mdi:speaker",
208  entity_category=EntityCategory.CONFIG,
209  native_unit_of_measurement=PERCENTAGE,
210  ufp_min=0,
211  ufp_max=100,
212  ufp_step=1,
213  ufp_value="volume",
214  ufp_set_method="set_volume",
215  ufp_perm=PermRequired.WRITE,
216  ),
217 )
218 _MODEL_DESCRIPTIONS: dict[ModelType, Sequence[ProtectEntityDescription]] = {
219  ModelType.CAMERA: CAMERA_NUMBERS,
220  ModelType.LIGHT: LIGHT_NUMBERS,
221  ModelType.SENSOR: SENSE_NUMBERS,
222  ModelType.DOORLOCK: DOORLOCK_NUMBERS,
223  ModelType.CHIME: CHIME_NUMBERS,
224 }
225 
226 
228  hass: HomeAssistant,
229  entry: UFPConfigEntry,
230  async_add_entities: AddEntitiesCallback,
231 ) -> None:
232  """Set up number entities for UniFi Protect integration."""
233  data = entry.runtime_data
234 
235  @callback
236  def _add_new_device(device: ProtectAdoptableDeviceModel) -> None:
239  data,
240  ProtectNumbers,
241  model_descriptions=_MODEL_DESCRIPTIONS,
242  ufp_device=device,
243  )
244  )
245 
246  data.async_subscribe_adopt(_add_new_device)
249  data,
250  ProtectNumbers,
251  model_descriptions=_MODEL_DESCRIPTIONS,
252  )
253  )
254 
255 
257  """A UniFi Protect Number Entity."""
258 
259  device: Camera | Light
260  entity_description: ProtectNumberEntityDescription
261  _state_attrs = ("_attr_available", "_attr_native_value")
262 
263  def __init__(
264  self,
265  data: ProtectData,
266  device: Camera | Light,
267  description: ProtectNumberEntityDescription,
268  ) -> None:
269  """Initialize the Number Entities."""
270  super().__init__(data, device, description)
271  self._attr_native_max_value_attr_native_max_value = self.entity_descriptionentity_description.ufp_max
272  self._attr_native_min_value_attr_native_min_value = self.entity_descriptionentity_description.ufp_min
273  self._attr_native_step_attr_native_step = self.entity_descriptionentity_description.ufp_step
274 
275  @callback
276  def _async_update_device_from_protect(self, device: ProtectDeviceType) -> None:
277  super()._async_update_device_from_protect(device)
278  self._attr_native_value_attr_native_value = self.entity_descriptionentity_description.get_ufp_value(self.devicedevice)
279 
280  async def async_set_native_value(self, value: float) -> None:
281  """Set new value."""
282  await self.entity_descriptionentity_description.ufp_set(self.devicedevice, value)
None _async_update_device_from_protect(self, ProtectDeviceType device)
Definition: number.py:276
None __init__(self, ProtectData data, Camera|Light device, ProtectNumberEntityDescription description)
Definition: number.py:268
list[BaseProtectEntity] async_all_device_entities(ProtectData data, type[BaseProtectEntity] klass, dict[ModelType, Sequence[ProtectEntityDescription]]|None model_descriptions=None, Sequence[ProtectEntityDescription]|None all_descs=None, list[ProtectEntityDescription]|None unadopted_descs=None, ProtectAdoptableDeviceModel|None ufp_device=None)
Definition: entity.py:153
None _set_pir_duration(Light obj, float value)
Definition: number.py:48
None _set_auto_close(Doorlock obj, float value)
Definition: number.py:56
None async_setup_entry(HomeAssistant hass, UFPConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: number.py:231