Adapt deCONZ number platform to align with updated design of binary sensor and sensor platforms (#65248)
* Adapt number to align with binary sensor and sensor platforms * Make number tests easier to expand
This commit is contained in:
parent
911e488d48
commit
b012b79167
2 changed files with 114 additions and 52 deletions
|
@ -2,10 +2,10 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import ValuesView
|
||||
from collections.abc import Callable, ValuesView
|
||||
from dataclasses import dataclass
|
||||
|
||||
from pydeconz.sensor import PRESENCE_DELAY, Presence
|
||||
from pydeconz.sensor import PRESENCE_DELAY, DeconzSensor as PydeconzSensor, Presence
|
||||
|
||||
from homeassistant.components.number import (
|
||||
DOMAIN,
|
||||
|
@ -23,33 +23,30 @@ from .gateway import DeconzGateway, get_gateway_from_config_entry
|
|||
|
||||
|
||||
@dataclass
|
||||
class DeconzNumberEntityDescriptionBase:
|
||||
class DeconzNumberDescriptionMixin:
|
||||
"""Required values when describing deCONZ number entities."""
|
||||
|
||||
device_property: str
|
||||
suffix: str
|
||||
update_key: str
|
||||
value_fn: Callable[[PydeconzSensor], bool | None]
|
||||
|
||||
|
||||
@dataclass
|
||||
class DeconzNumberEntityDescription(
|
||||
NumberEntityDescription, DeconzNumberEntityDescriptionBase
|
||||
):
|
||||
class DeconzNumberDescription(NumberEntityDescription, DeconzNumberDescriptionMixin):
|
||||
"""Class describing deCONZ number entities."""
|
||||
|
||||
entity_category = EntityCategory.CONFIG
|
||||
|
||||
|
||||
ENTITY_DESCRIPTIONS = {
|
||||
Presence: [
|
||||
DeconzNumberEntityDescription(
|
||||
DeconzNumberDescription(
|
||||
key="delay",
|
||||
device_property="delay",
|
||||
value_fn=lambda device: device.delay,
|
||||
suffix="Delay",
|
||||
update_key=PRESENCE_DELAY,
|
||||
max_value=65535,
|
||||
min_value=0,
|
||||
step=1,
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
)
|
||||
]
|
||||
}
|
||||
|
@ -76,15 +73,18 @@ async def async_setup_entry(
|
|||
if sensor.type.startswith("CLIP"):
|
||||
continue
|
||||
|
||||
known_number_entities = set(gateway.entities[DOMAIN])
|
||||
known_entities = set(gateway.entities[DOMAIN])
|
||||
for description in ENTITY_DESCRIPTIONS.get(type(sensor), []):
|
||||
|
||||
if getattr(sensor, description.device_property) is None:
|
||||
if (
|
||||
not hasattr(sensor, description.key)
|
||||
or description.value_fn(sensor) is None
|
||||
):
|
||||
continue
|
||||
|
||||
new_number_entity = DeconzNumber(sensor, gateway, description)
|
||||
if new_number_entity.unique_id not in known_number_entities:
|
||||
entities.append(new_number_entity)
|
||||
new_entity = DeconzNumber(sensor, gateway, description)
|
||||
if new_entity.unique_id not in known_entities:
|
||||
entities.append(new_entity)
|
||||
|
||||
if entities:
|
||||
async_add_entities(entities)
|
||||
|
@ -112,29 +112,29 @@ class DeconzNumber(DeconzDevice, NumberEntity):
|
|||
self,
|
||||
device: Presence,
|
||||
gateway: DeconzGateway,
|
||||
description: DeconzNumberEntityDescription,
|
||||
description: DeconzNumberDescription,
|
||||
) -> None:
|
||||
"""Initialize deCONZ number entity."""
|
||||
self.entity_description: DeconzNumberEntityDescription = description
|
||||
self.entity_description: DeconzNumberDescription = description
|
||||
super().__init__(device, gateway)
|
||||
|
||||
self._attr_name = f"{device.name} {description.suffix}"
|
||||
self._update_keys = {self.entity_description.update_key, "reachable"}
|
||||
|
||||
@callback
|
||||
def async_update_callback(self) -> None:
|
||||
"""Update the number value."""
|
||||
keys = {self.entity_description.update_key, "reachable"}
|
||||
if self._device.changed_keys.intersection(keys):
|
||||
if self._device.changed_keys.intersection(self._update_keys):
|
||||
super().async_update_callback()
|
||||
|
||||
@property
|
||||
def value(self) -> float:
|
||||
"""Return the value of the sensor property."""
|
||||
return getattr(self._device, self.entity_description.device_property) # type: ignore[no-any-return]
|
||||
return self.entity_description.value_fn(self._device) # type: ignore[no-any-return]
|
||||
|
||||
async def async_set_value(self, value: float) -> None:
|
||||
"""Set sensor config."""
|
||||
data = {self.entity_description.device_property: int(value)}
|
||||
data = {self.entity_description.key: int(value)}
|
||||
await self._device.set_config(**data)
|
||||
|
||||
@property
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue