Add support for homekit_controller secondary entities like power usage (#44013)

This commit is contained in:
Jc2k 2021-01-26 19:45:01 +00:00 committed by GitHub
parent f53a83e084
commit 3b0a440770
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 646 additions and 17 deletions

View file

@ -15,7 +15,13 @@ from aiohomekit.model.services import ServicesTypes
from homeassistant.core import callback
from homeassistant.helpers.event import async_track_time_interval
from .const import CONTROLLER, DOMAIN, ENTITY_MAP, HOMEKIT_ACCESSORY_DISPATCH
from .const import (
CHARACTERISTIC_PLATFORMS,
CONTROLLER,
DOMAIN,
ENTITY_MAP,
HOMEKIT_ACCESSORY_DISPATCH,
)
from .device_trigger import async_fire_triggers, async_setup_triggers_for_entry
DEFAULT_SCAN_INTERVAL = datetime.timedelta(seconds=60)
@ -82,6 +88,9 @@ class HKDevice:
# A list of callbacks that turn HK service metadata into entities
self.listeners = []
# A list of callbacks that turn HK characteristics into entities
self.char_factories = []
# The platorms we have forwarded the config entry so far. If a new
# accessory is added to a bridge we may have to load additional
# platforms. We don't want to load all platforms up front if its just
@ -306,6 +315,22 @@ class HKDevice:
self.entities.append((accessory.aid, None))
break
def add_char_factory(self, add_entities_cb):
"""Add a callback to run when discovering new entities for accessories."""
self.char_factories.append(add_entities_cb)
self._add_new_entities_for_char([add_entities_cb])
def _add_new_entities_for_char(self, handlers):
for accessory in self.entity_map.accessories:
for service in accessory.services:
for char in service.characteristics:
for handler in handlers:
if (accessory.aid, service.iid, char.iid) in self.entities:
continue
if handler(char):
self.entities.append((accessory.aid, service.iid, char.iid))
break
def add_listener(self, add_entities_cb):
"""Add a callback to run when discovering new entities for services."""
self.listeners.append(add_entities_cb)
@ -315,6 +340,7 @@ class HKDevice:
"""Process the entity map and create HA entities."""
self._add_new_entities(self.listeners)
self._add_new_entities_for_accessory(self.accessory_factories)
self._add_new_entities_for_char(self.char_factories)
def _add_new_entities(self, callbacks):
for accessory in self.entity_map.accessories:
@ -331,26 +357,33 @@ class HKDevice:
self.entities.append((aid, iid))
break
async def async_load_platform(self, platform):
"""Load a single platform idempotently."""
if platform in self.platforms:
return
self.platforms.add(platform)
try:
await self.hass.config_entries.async_forward_entry_setup(
self.config_entry, platform
)
except Exception:
self.platforms.remove(platform)
raise
async def async_load_platforms(self):
"""Load any platforms needed by this HomeKit device."""
for accessory in self.accessories:
for service in accessory["services"]:
stype = ServicesTypes.get_short(service["type"].upper())
if stype not in HOMEKIT_ACCESSORY_DISPATCH:
continue
if stype in HOMEKIT_ACCESSORY_DISPATCH:
platform = HOMEKIT_ACCESSORY_DISPATCH[stype]
await self.async_load_platform(platform)
platform = HOMEKIT_ACCESSORY_DISPATCH[stype]
if platform in self.platforms:
continue
self.platforms.add(platform)
try:
await self.hass.config_entries.async_forward_entry_setup(
self.config_entry, platform
)
except Exception:
self.platforms.remove(platform)
raise
for char in service["characteristics"]:
if char["type"].upper() in CHARACTERISTIC_PLATFORMS:
platform = CHARACTERISTIC_PLATFORMS[char["type"].upper()]
await self.async_load_platform(platform)
async def async_update(self, now=None):
"""Poll state of all entities attached to this bridge/accessory."""