Make switch platform use common UniFi entity class (#84458)

* Make switch platform use common UniFi entity class

* Consolidate common functions between update and switch platforms

* Use controller.register_platform_add_entities

* Rename UnfiEntityLoader to UnifiUpdateEntityDescriptionMixin
This commit is contained in:
Robert Svensson 2023-01-03 22:57:44 +01:00 committed by GitHub
parent 799d527fb5
commit 6718b40181
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 147 additions and 238 deletions

View file

@ -4,27 +4,65 @@ from __future__ import annotations
from abc import abstractmethod
from collections.abc import Callable
from dataclasses import dataclass
from typing import TYPE_CHECKING, Generic, TypeVar
from typing import TYPE_CHECKING, Generic, TypeVar, Union
import aiounifi
from aiounifi.interfaces.api_handlers import CallbackType, ItemEvent, UnsubscribeType
from aiounifi.interfaces.devices import Devices
from aiounifi.models.device import Device
from aiounifi.models.event import EventKey
from aiounifi.interfaces.api_handlers import (
APIHandler,
CallbackType,
ItemEvent,
UnsubscribeType,
)
from aiounifi.interfaces.outlets import Outlets
from aiounifi.interfaces.ports import Ports
from aiounifi.models.api import APIItem
from aiounifi.models.event import Event, EventKey
from aiounifi.models.outlet import Outlet
from aiounifi.models.port import Port
from homeassistant.core import callback
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity import DeviceInfo, Entity, EntityDescription
from .const import ATTR_MANUFACTURER
if TYPE_CHECKING:
from .controller import UniFiController
DataT = TypeVar("DataT", bound=Device)
HandlerT = TypeVar("HandlerT", bound=Devices)
DataT = TypeVar("DataT", bound=Union[APIItem, Outlet, Port])
HandlerT = TypeVar("HandlerT", bound=Union[APIHandler, Outlets, Ports])
SubscriptionT = Callable[[CallbackType, ItemEvent], UnsubscribeType]
@callback
def async_device_available_fn(controller: UniFiController, obj_id: str) -> bool:
"""Check if device is available."""
if "_" in obj_id: # Sub device (outlet or port)
obj_id = obj_id.partition("_")[0]
device = controller.api.devices[obj_id]
return controller.available and not device.disabled
@callback
def async_device_device_info_fn(api: aiounifi.Controller, obj_id: str) -> DeviceInfo:
"""Create device registry entry for device."""
if "_" in obj_id: # Sub device (outlet or port)
obj_id = obj_id.partition("_")[0]
device = api.devices[obj_id]
return DeviceInfo(
connections={(CONNECTION_NETWORK_MAC, device.mac)},
manufacturer=ATTR_MANUFACTURER,
model=device.model,
name=device.name or None,
sw_version=device.version,
hw_version=str(device.board_revision),
)
@dataclass
class UnifiDescription(Generic[HandlerT, DataT]):
"""Validate and load entities from different UniFi handlers."""
@ -106,6 +144,15 @@ class UnifiEntity(Entity, Generic[HandlerT, DataT]):
)
)
# Subscribe to events if defined
if description.event_to_subscribe is not None:
self.async_on_remove(
self.controller.api.events.subscribe(
self.async_event_callback,
description.event_to_subscribe,
)
)
@callback
def async_signalling_callback(self, event: ItemEvent, obj_id: str) -> None:
"""Update the entity state."""
@ -157,3 +204,11 @@ class UnifiEntity(Entity, Generic[HandlerT, DataT]):
Perform additional actions updating platform entity child class state.
"""
@callback
def async_event_callback(self, event: Event) -> None:
"""Update entity state based on subscribed event.
Perform additional action updating platform entity child class state.
"""
raise NotImplementedError()