From c57dcacadedea3f3b4bc022139bf1bba7b8da83c Mon Sep 17 00:00:00 2001 From: Robert Svensson Date: Sat, 16 Mar 2024 20:47:54 +0100 Subject: [PATCH] Axis use entity description in switch platform (#113595) * Draft * Make a generic register platform --- homeassistant/components/axis/switch.py | 68 ++++++++++++++++++++----- 1 file changed, 55 insertions(+), 13 deletions(-) diff --git a/homeassistant/components/axis/switch.py b/homeassistant/components/axis/switch.py index d7072bb877f..8364d1317f9 100644 --- a/homeassistant/components/axis/switch.py +++ b/homeassistant/components/axis/switch.py @@ -1,11 +1,19 @@ """Support for Axis switches.""" +from collections.abc import Callable, Iterable +from dataclasses import dataclass +from functools import partial from typing import Any from axis.models.event import Event, EventOperation, EventTopic -from homeassistant.components.switch import SwitchEntity +from homeassistant.components.switch import ( + SwitchDeviceClass, + SwitchEntity, + SwitchEntityDescription, +) from homeassistant.config_entries import ConfigEntry +from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.entity_platform import AddEntitiesCallback @@ -13,34 +21,68 @@ from .entity import AxisEventEntity from .hub import AxisHub +@dataclass(frozen=True, kw_only=True) +class AxisSwitchDescription(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( + key="Relay state control", + device_class=SwitchDeviceClass.OUTLET, + entity_category=EntityCategory.CONFIG, + event_topic=EventTopic.RELAY, + supported_fn=lambda hub, event: isinstance(int(event.id), int), + name_fn=lambda hub, event: hub.api.vapix.ports[event.id].name, + ), +) + + async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: - """Set up a Axis switch.""" + """Set up the Axis switch platform.""" hub = AxisHub.get_hub(hass, config_entry) @callback - def async_create_entity(event: Event) -> None: - """Create Axis switch entity.""" - async_add_entities([AxisSwitch(event, hub)]) + def register_platform(descriptions: Iterable[AxisSwitchDescription]) -> None: + """Register entity platform to create entities on event initialized signal.""" - hub.api.event.subscribe( - async_create_entity, - topic_filter=EventTopic.RELAY, - operation_filter=EventOperation.INITIALIZED, - ) + @callback + def create_entity(description: AxisSwitchDescription, event: Event) -> None: + """Create Axis entity.""" + if description.supported_fn(hub, event): + async_add_entities([AxisSwitch(hub, description, event)]) + + for description in descriptions: + hub.api.event.subscribe( + partial(create_entity, description), + topic_filter=description.event_topic, + operation_filter=EventOperation.INITIALIZED, + ) + + register_platform(ENTITY_DESCRIPTIONS) class AxisSwitch(AxisEventEntity, SwitchEntity): """Representation of a Axis switch.""" - def __init__(self, event: Event, hub: AxisHub) -> None: + def __init__( + self, hub: AxisHub, description: AxisSwitchDescription, event: Event + ) -> None: """Initialize the Axis switch.""" super().__init__(event, hub) - if event.id and hub.api.vapix.ports[event.id].name: - self._attr_name = hub.api.vapix.ports[event.id].name + self.entity_description = description + self._attr_name = description.name_fn(hub, event) or self._attr_name self._attr_is_on = event.is_tripped @callback