Define and use entity description in Axis entity base class (#114007)
Define and use entity description in entity base class
This commit is contained in:
parent
68e170284f
commit
817d931df0
4 changed files with 51 additions and 47 deletions
|
@ -23,21 +23,14 @@ from homeassistant.core import HomeAssistant, callback
|
|||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.event import async_call_later
|
||||
|
||||
from .entity import AxisEventEntity
|
||||
from .entity import AxisEventDescription, AxisEventEntity
|
||||
from .hub import AxisHub
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
class AxisBinarySensorDescription(BinarySensorEntityDescription):
|
||||
class AxisBinarySensorDescription(AxisEventDescription, BinarySensorEntityDescription):
|
||||
"""Axis binary sensor entity description."""
|
||||
|
||||
event_topic: tuple[EventTopic, ...] | EventTopic
|
||||
"""Event topic that provides state updates."""
|
||||
name_fn: Callable[[AxisHub, Event], str] = lambda hub, event: ""
|
||||
"""Function providing the corresponding name to the event ID."""
|
||||
supported_fn: Callable[[AxisHub, Event], bool] = lambda hub, event: True
|
||||
"""Function validating if event is supported."""
|
||||
|
||||
|
||||
@callback
|
||||
def event_id_is_int(event_id: str) -> bool:
|
||||
|
@ -216,15 +209,15 @@ async def async_setup_entry(
|
|||
class AxisBinarySensor(AxisEventEntity, BinarySensorEntity):
|
||||
"""Representation of a binary Axis event."""
|
||||
|
||||
entity_description: AxisBinarySensorDescription
|
||||
|
||||
def __init__(
|
||||
self, hub: AxisHub, description: AxisBinarySensorDescription, event: Event
|
||||
) -> None:
|
||||
"""Initialize the Axis binary sensor."""
|
||||
super().__init__(event, hub)
|
||||
self.entity_description = description
|
||||
self._attr_name = description.name_fn(hub, event) or self._attr_name
|
||||
super().__init__(hub, description, event)
|
||||
|
||||
self._attr_is_on = event.is_tripped
|
||||
self._attr_device_class = description.device_class # temporary
|
||||
self.cancel_scheduled_update: Callable[[], None] | None = None
|
||||
|
||||
@callback
|
||||
|
|
|
@ -1,16 +1,23 @@
|
|||
"""Base classes for Axis entities."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from abc import abstractmethod
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from axis.models.event import Event, EventTopic
|
||||
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers.device_registry import DeviceInfo
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.helpers.entity import Entity, EntityDescription
|
||||
|
||||
from .const import DOMAIN as AXIS_DOMAIN
|
||||
from .hub import AxisHub
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .hub import AxisHub
|
||||
|
||||
TOPIC_TO_EVENT_TYPE = {
|
||||
EventTopic.DAY_NIGHT_VISION: "DayNight",
|
||||
|
@ -32,6 +39,18 @@ TOPIC_TO_EVENT_TYPE = {
|
|||
}
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
class AxisEventDescription(EntityDescription):
|
||||
"""Axis event based entity description."""
|
||||
|
||||
event_topic: tuple[EventTopic, ...] | EventTopic
|
||||
"""Event topic that provides state updates."""
|
||||
name_fn: Callable[[AxisHub, Event], str] = lambda hub, event: ""
|
||||
"""Function providing the corresponding name to the event ID."""
|
||||
supported_fn: Callable[[AxisHub, Event], bool] = lambda hub, event: True
|
||||
"""Function validating if event is supported."""
|
||||
|
||||
|
||||
class AxisEntity(Entity):
|
||||
"""Base common to all Axis entities."""
|
||||
|
||||
|
@ -66,21 +85,26 @@ class AxisEntity(Entity):
|
|||
class AxisEventEntity(AxisEntity):
|
||||
"""Base common to all Axis entities from event stream."""
|
||||
|
||||
entity_description: AxisEventDescription
|
||||
|
||||
_attr_should_poll = False
|
||||
|
||||
def __init__(self, event: Event, hub: AxisHub) -> None:
|
||||
def __init__(
|
||||
self, hub: AxisHub, description: AxisEventDescription, event: Event
|
||||
) -> None:
|
||||
"""Initialize the Axis event."""
|
||||
super().__init__(hub)
|
||||
|
||||
self.entity_description = description
|
||||
|
||||
self._event_id = event.id
|
||||
self._event_topic = event.topic_base
|
||||
self._event_type = TOPIC_TO_EVENT_TYPE[event.topic_base]
|
||||
event_type = TOPIC_TO_EVENT_TYPE[event.topic_base]
|
||||
|
||||
self._attr_name = description.name_fn(hub, event) or f"{event_type} {event.id}"
|
||||
|
||||
self._attr_name = f"{self._event_type} {event.id}"
|
||||
self._attr_unique_id = f"{hub.unique_id}-{event.topic}-{event.id}"
|
||||
|
||||
self._attr_device_class = event.group.value
|
||||
|
||||
@callback
|
||||
@abstractmethod
|
||||
def async_event_callback(self, event: Event) -> None:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
"""Support for Axis lights."""
|
||||
|
||||
from collections.abc import Callable, Iterable
|
||||
from collections.abc import Iterable
|
||||
from dataclasses import dataclass
|
||||
from functools import partial
|
||||
from typing import Any
|
||||
|
@ -17,7 +17,7 @@ from homeassistant.config_entries import ConfigEntry
|
|||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from .entity import TOPIC_TO_EVENT_TYPE, AxisEventEntity
|
||||
from .entity import TOPIC_TO_EVENT_TYPE, AxisEventDescription, AxisEventEntity
|
||||
from .hub import AxisHub
|
||||
|
||||
|
||||
|
@ -31,16 +31,9 @@ def light_name_fn(hub: AxisHub, event: Event) -> str:
|
|||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
class AxisLightDescription(LightEntityDescription):
|
||||
class AxisLightDescription(AxisEventDescription, LightEntityDescription):
|
||||
"""Axis light entity description."""
|
||||
|
||||
event_topic: EventTopic
|
||||
"""Event topic that provides state updates."""
|
||||
name_fn: Callable[[AxisHub, Event], str]
|
||||
"""Function providing the corresponding name to the event ID."""
|
||||
supported_fn: Callable[[AxisHub, Event], bool]
|
||||
"""Function validating if event is supported."""
|
||||
|
||||
|
||||
ENTITY_DESCRIPTIONS = (
|
||||
AxisLightDescription(
|
||||
|
@ -83,6 +76,8 @@ async def async_setup_entry(
|
|||
class AxisLight(AxisEventEntity, LightEntity):
|
||||
"""Representation of an Axis light."""
|
||||
|
||||
entity_description: AxisLightDescription
|
||||
|
||||
_attr_should_poll = True
|
||||
_attr_color_mode = ColorMode.BRIGHTNESS
|
||||
_attr_supported_color_modes = {ColorMode.BRIGHTNESS}
|
||||
|
@ -91,11 +86,9 @@ class AxisLight(AxisEventEntity, LightEntity):
|
|||
self, hub: AxisHub, description: AxisLightDescription, event: Event
|
||||
) -> None:
|
||||
"""Initialize the Axis light."""
|
||||
super().__init__(event, hub)
|
||||
self.entity_description = description
|
||||
self._attr_name = description.name_fn(hub, event)
|
||||
self._attr_is_on = event.is_tripped
|
||||
super().__init__(hub, description, event)
|
||||
|
||||
self._attr_is_on = event.is_tripped
|
||||
self._light_id = f"led{event.id}"
|
||||
self.current_intensity = 0
|
||||
self.max_intensity = 0
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
"""Support for Axis switches."""
|
||||
|
||||
from collections.abc import Callable, Iterable
|
||||
from collections.abc import Iterable
|
||||
from dataclasses import dataclass
|
||||
from functools import partial
|
||||
from typing import Any
|
||||
|
@ -17,21 +17,14 @@ from homeassistant.const import EntityCategory
|
|||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from .entity import AxisEventEntity
|
||||
from .entity import AxisEventDescription, AxisEventEntity
|
||||
from .hub import AxisHub
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
class AxisSwitchDescription(SwitchEntityDescription):
|
||||
class AxisSwitchDescription(AxisEventDescription, SwitchEntityDescription):
|
||||
"""Axis switch entity description."""
|
||||
|
||||
event_topic: EventTopic
|
||||
"""Event topic that provides state updates."""
|
||||
name_fn: Callable[[AxisHub, Event], str]
|
||||
"""Function providing the corresponding name to the event ID."""
|
||||
supported_fn: Callable[[AxisHub, Event], bool]
|
||||
"""Function validating if event is supported."""
|
||||
|
||||
|
||||
ENTITY_DESCRIPTIONS = (
|
||||
AxisSwitchDescription(
|
||||
|
@ -76,13 +69,14 @@ async def async_setup_entry(
|
|||
class AxisSwitch(AxisEventEntity, SwitchEntity):
|
||||
"""Representation of a Axis switch."""
|
||||
|
||||
entity_description: AxisSwitchDescription
|
||||
|
||||
def __init__(
|
||||
self, hub: AxisHub, description: AxisSwitchDescription, event: Event
|
||||
) -> None:
|
||||
"""Initialize the Axis switch."""
|
||||
super().__init__(event, hub)
|
||||
self.entity_description = description
|
||||
self._attr_name = description.name_fn(hub, event) or self._attr_name
|
||||
super().__init__(hub, description, event)
|
||||
|
||||
self._attr_is_on = event.is_tripped
|
||||
|
||||
@callback
|
||||
|
|
Loading…
Add table
Reference in a new issue