1 """UniFi entity representation."""
3 from __future__
import annotations
5 from abc
import abstractmethod
6 from collections.abc
import Callable
7 from dataclasses
import dataclass
8 from typing
import TYPE_CHECKING, Generic, TypeVar
11 from aiounifi.interfaces.api_handlers
import (
17 from aiounifi.models.api
import ApiItemT
18 from aiounifi.models.event
import Event, EventKey
23 CONNECTION_NETWORK_MAC,
30 from .const
import ATTR_MANUFACTURER, DOMAIN
33 from .hub
import UnifiHub
35 HandlerT = TypeVar(
"HandlerT", bound=APIHandler)
36 SubscriptionT = Callable[[CallbackType, ItemEvent], UnsubscribeType]
41 """Check if device is available."""
43 obj_id = obj_id.partition(
"_")[0]
45 device = hub.api.devices[obj_id]
46 return hub.available
and not device.disabled
51 """Check if WLAN is available."""
52 wlan = hub.api.wlans[obj_id]
53 return hub.available
and wlan.enabled
58 """Create device registry entry for device."""
60 obj_id = obj_id.partition(
"_")[0]
62 device = hub.api.devices[obj_id]
64 connections={(CONNECTION_NETWORK_MAC, device.mac)},
65 manufacturer=ATTR_MANUFACTURER,
67 name=device.name
or None,
68 sw_version=device.version,
69 hw_version=
str(device.board_revision),
75 """Create device registry entry for WLAN."""
76 wlan = hub.api.wlans[obj_id]
78 entry_type=DeviceEntryType.SERVICE,
79 identifiers={(DOMAIN, wlan.id)},
80 manufacturer=ATTR_MANUFACTURER,
88 """Create device registry entry for client."""
89 client = hub.api.clients[obj_id]
91 connections={(CONNECTION_NETWORK_MAC, obj_id)},
92 default_manufacturer=client.oui,
93 default_name=client.name
or client.hostname,
97 @dataclass(frozen=True, kw_only=True)
99 """UniFi Entity Description."""
101 api_handler_fn: Callable[[aiounifi.Controller], HandlerT]
102 """Provide api_handler from api."""
103 device_info_fn: Callable[[UnifiHub, str], DeviceInfo |
None]
104 """Provide device info object based on hub and obj_id."""
105 object_fn: Callable[[aiounifi.Controller, str], ApiItemT]
106 """Retrieve object based on api and obj_id."""
107 unique_id_fn: Callable[[UnifiHub, str], str]
108 """Provide a unique ID based on hub and obj_id."""
111 allowed_fn: Callable[[UnifiHub, str], bool] =
lambda hub, obj_id:
True
112 """Determine if config entry options allow creation of entity."""
113 available_fn: Callable[[UnifiHub, str], bool] =
lambda hub, obj_id: hub.available
114 """Determine if entity is available, default is if connection is working."""
115 name_fn: Callable[[ApiItemT], str |
None] =
lambda obj:
None
116 """Entity name function, can be used to extend entity name beyond device name."""
117 supported_fn: Callable[[UnifiHub, str], bool] =
lambda hub, obj_id:
True
118 """Determine if UniFi object supports providing relevant data for entity."""
121 has_entity_name =
True
122 """Has entity name defaults to true."""
123 event_is_on: set[EventKey] |
None =
None
124 """Which UniFi events should be used to consider state 'on'."""
125 event_to_subscribe: tuple[EventKey, ...] |
None =
None
126 """Which UniFi events to listen on."""
127 should_poll: bool =
False
128 """If entity needs to do regular checks on state."""
132 """Representation of a UniFi entity."""
134 entity_description: UnifiEntityDescription[HandlerT, ApiItemT]
141 description: UnifiEntityDescription[HandlerT, ApiItemT],
143 """Set up UniFi switch entity."""
149 hub.entity_loader.known_objects.add((description.key, obj_id))
158 obj = description.object_fn(self.
apiapi, obj_id)
163 """Register callbacks."""
165 handler = description.api_handler_fn(self.
apiapi)
168 def unregister_object() -> None:
169 """Remove object ID from known_objects when unloaded."""
170 self.
hubhub.entity_loader.known_objects.discard(
171 (description.key, self.
_obj_id_obj_id)
188 self.
hubhub.signal_reachable,
197 self.
hubhub.signal_options_update,
203 if description.event_to_subscribe
is not None:
205 self.
apiapi.events.subscribe(
207 description.event_to_subscribe,
213 """Update the entity state."""
214 if event
is ItemEvent.DELETED
and obj_id == self.
_obj_id_obj_id:
219 if not description.supported_fn(self.
hubhub, self.
_obj_id_obj_id):
229 """Call when hub connection state change."""
233 """Config entry options are updated, remove entity if option is disabled."""
238 """Remove entity if object ID is part of set."""
248 """Update state if polling is configured."""
253 """Initiate entity state.
255 Perform additional actions setting up platform entity child class state.
256 Defaults to using async_update_state to set initial state.
263 """Update entity state.
265 Perform additional actions updating platform entity child class state.
270 """Update entity state based on subscribed event.
272 Perform additional action updating platform entity child class state.
274 raise NotImplementedError
None remove_item(self, set keys)
None async_signalling_callback(self, ItemEvent event, str obj_id)
None __init__(self, str obj_id, UnifiHub hub, UnifiEntityDescription[HandlerT, ApiItemT] description)
None async_update_state(self, ItemEvent event, str obj_id)
None async_signal_reachable_callback(self)
None async_added_to_hass(self)
None async_initiate_state(self)
None async_event_callback(self, Event event)
None async_signal_options_updated(self)
None async_write_ha_state(self)
None async_on_remove(self, CALLBACK_TYPE func)
None async_remove(self, *bool force_remove=False)
bool async_device_available_fn(UnifiHub hub, str obj_id)
DeviceInfo async_wlan_device_info_fn(UnifiHub hub, str obj_id)
DeviceInfo async_client_device_info_fn(UnifiHub hub, str obj_id)
bool async_wlan_available_fn(UnifiHub hub, str obj_id)
DeviceInfo async_device_device_info_fn(UnifiHub hub, str obj_id)
Callable[[], None] async_dispatcher_connect(HomeAssistant hass, str signal, Callable[..., Any] target)