-
-
Notifications
You must be signed in to change notification settings - Fork 32k
/
Copy pathnumber.py
129 lines (108 loc) · 4.02 KB
/
number.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
"""Support for configuring different deCONZ numbers."""
from __future__ import annotations
from collections.abc import Callable, Coroutine
from dataclasses import dataclass
from typing import Any
from pydeconz.gateway import DeconzSession
from pydeconz.interfaces.sensors import SensorResources
from pydeconz.models.event import EventType
from pydeconz.models.sensor import SensorBase as PydeconzSensorBase
from pydeconz.models.sensor.presence import Presence
from homeassistant.components.number import (
DOMAIN as NUMBER_DOMAIN,
NumberEntity,
NumberEntityDescription,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .entity import DeconzDevice
from .hub import DeconzHub
@dataclass(frozen=True, kw_only=True)
class DeconzNumberDescription[_T: (Presence, PydeconzSensorBase)](
NumberEntityDescription
):
"""Class describing deCONZ number entities."""
instance_check: type[_T]
name_suffix: str
set_fn: Callable[[DeconzSession, str, int], Coroutine[Any, Any, dict[str, Any]]]
update_key: str
value_fn: Callable[[_T], float | None]
ENTITY_DESCRIPTIONS: tuple[DeconzNumberDescription, ...] = (
DeconzNumberDescription[Presence](
key="delay",
instance_check=Presence,
name_suffix="Delay",
set_fn=lambda api, id, v: api.sensors.presence.set_config(id=id, delay=v),
update_key="delay",
value_fn=lambda device: device.delay,
native_max_value=65535,
native_min_value=0,
native_step=1,
entity_category=EntityCategory.CONFIG,
),
DeconzNumberDescription[Presence](
key="duration",
instance_check=Presence,
name_suffix="Duration",
set_fn=lambda api, id, v: api.sensors.presence.set_config(id=id, duration=v),
update_key="duration",
value_fn=lambda device: device.duration,
native_max_value=65535,
native_min_value=0,
native_step=1,
entity_category=EntityCategory.CONFIG,
),
)
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the deCONZ number entity."""
hub = DeconzHub.get_hub(hass, config_entry)
hub.entities[NUMBER_DOMAIN] = set()
@callback
def async_add_sensor(_: EventType, sensor_id: str) -> None:
"""Add sensor from deCONZ."""
sensor = hub.api.sensors.presence[sensor_id]
for description in ENTITY_DESCRIPTIONS:
if (
not isinstance(sensor, description.instance_check)
or description.value_fn(sensor) is None
):
continue
async_add_entities([DeconzNumber(sensor, hub, description)])
hub.register_platform_add_device_callback(
async_add_sensor,
hub.api.sensors.presence,
always_ignore_clip_sensors=True,
)
class DeconzNumber(DeconzDevice[SensorResources], NumberEntity):
"""Representation of a deCONZ number entity."""
TYPE = NUMBER_DOMAIN
entity_description: DeconzNumberDescription
def __init__(
self,
device: SensorResources,
hub: DeconzHub,
description: DeconzNumberDescription,
) -> None:
"""Initialize deCONZ number entity."""
self.entity_description = description
self.unique_id_suffix = description.key
self._name_suffix = description.name_suffix
self._update_key = description.update_key
super().__init__(device, hub)
@property
def native_value(self) -> float | None:
"""Return the value of the sensor property."""
return self.entity_description.value_fn(self._device)
async def async_set_native_value(self, value: float) -> None:
"""Set sensor config."""
await self.entity_description.set_fn(
self.hub.api,
self._device.resource_id,
int(value),
)