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:
Robert Svensson 2022-02-08 23:03:37 +01:00 committed by GitHub
parent 911e488d48
commit b012b79167
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 114 additions and 52 deletions

View file

@ -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