Await startup in homekit controller (#75021)
This commit is contained in:
parent
a3c1926da5
commit
a31dde9cb4
7 changed files with 133 additions and 30 deletions
|
@ -7,6 +7,7 @@ import datetime
|
|||
import logging
|
||||
from typing import Any
|
||||
|
||||
from aiohomekit import Controller
|
||||
from aiohomekit.exceptions import (
|
||||
AccessoryDisconnectedError,
|
||||
AccessoryNotFoundError,
|
||||
|
@ -35,6 +36,7 @@ from .const import (
|
|||
IDENTIFIER_SERIAL_NUMBER,
|
||||
)
|
||||
from .device_trigger import async_fire_triggers, async_setup_triggers_for_entry
|
||||
from .storage import EntityMapStorage
|
||||
|
||||
DEFAULT_SCAN_INTERVAL = datetime.timedelta(seconds=60)
|
||||
RETRY_INTERVAL = 60 # seconds
|
||||
|
@ -70,11 +72,13 @@ class HKDevice:
|
|||
# don't want to mutate a dict owned by a config entry.
|
||||
self.pairing_data = pairing_data.copy()
|
||||
|
||||
self.pairing = hass.data[CONTROLLER].load_pairing(
|
||||
connection: Controller = hass.data[CONTROLLER]
|
||||
|
||||
self.pairing = connection.load_pairing(
|
||||
self.pairing_data["AccessoryPairingID"], self.pairing_data
|
||||
)
|
||||
|
||||
self.accessories = None
|
||||
self.accessories: list[Any] | None = None
|
||||
self.config_num = 0
|
||||
|
||||
self.entity_map = Accessories()
|
||||
|
@ -167,26 +171,23 @@ class HKDevice:
|
|||
|
||||
async def async_setup(self) -> bool:
|
||||
"""Prepare to use a paired HomeKit device in Home Assistant."""
|
||||
cache = self.hass.data[ENTITY_MAP].get_map(self.unique_id)
|
||||
if not cache:
|
||||
if await self.async_refresh_entity_map(self.config_num):
|
||||
self._polling_interval_remover = async_track_time_interval(
|
||||
self.hass, self.async_update, DEFAULT_SCAN_INTERVAL
|
||||
)
|
||||
return True
|
||||
entity_storage: EntityMapStorage = self.hass.data[ENTITY_MAP]
|
||||
if cache := entity_storage.get_map(self.unique_id):
|
||||
self.accessories = cache["accessories"]
|
||||
self.config_num = cache["config_num"]
|
||||
self.entity_map = Accessories.from_list(self.accessories)
|
||||
elif not await self.async_refresh_entity_map(self.config_num):
|
||||
return False
|
||||
|
||||
self.accessories = cache["accessories"]
|
||||
self.config_num = cache["config_num"]
|
||||
|
||||
self.entity_map = Accessories.from_list(self.accessories)
|
||||
|
||||
await self.async_process_entity_map()
|
||||
if not self.pairing.is_connected:
|
||||
return False
|
||||
# If everything is up to date, we can create the entities
|
||||
# since we know the data is not stale.
|
||||
self.add_entities()
|
||||
self._polling_interval_remover = async_track_time_interval(
|
||||
self.hass, self.async_update, DEFAULT_SCAN_INTERVAL
|
||||
)
|
||||
|
||||
self.hass.async_create_task(self.async_process_entity_map())
|
||||
|
||||
return True
|
||||
|
||||
def device_info_for_accessory(self, accessory: Accessory) -> DeviceInfo:
|
||||
|
@ -361,7 +362,7 @@ class HKDevice:
|
|||
# is especially important for BLE, as the Pairing instance relies on the entity map
|
||||
# to map aid/iid to GATT characteristics. So push it to there as well.
|
||||
|
||||
self.pairing.pairing_data["accessories"] = self.accessories
|
||||
self.pairing.pairing_data["accessories"] = self.accessories # type: ignore[attr-defined]
|
||||
|
||||
self.async_detect_workarounds()
|
||||
|
||||
|
@ -375,8 +376,6 @@ class HKDevice:
|
|||
# Load any triggers for this config entry
|
||||
await async_setup_triggers_for_entry(self.hass, self.config_entry)
|
||||
|
||||
self.add_entities()
|
||||
|
||||
if self.watchable_characteristics:
|
||||
await self.pairing.subscribe(self.watchable_characteristics)
|
||||
if not self.pairing.is_connected:
|
||||
|
@ -395,6 +394,12 @@ class HKDevice:
|
|||
self.config_entry, self.platforms
|
||||
)
|
||||
|
||||
async def async_refresh_entity_map_and_entities(self, config_num: int) -> None:
|
||||
"""Refresh the entity map and entities for this pairing."""
|
||||
await self.async_refresh_entity_map(config_num)
|
||||
await self.async_process_entity_map()
|
||||
self.add_entities()
|
||||
|
||||
async def async_refresh_entity_map(self, config_num: int) -> bool:
|
||||
"""Handle setup of a HomeKit accessory."""
|
||||
try:
|
||||
|
@ -404,15 +409,17 @@ class HKDevice:
|
|||
# later when Bonjour spots c# is still not up to date.
|
||||
return False
|
||||
|
||||
assert self.accessories is not None
|
||||
|
||||
self.entity_map = Accessories.from_list(self.accessories)
|
||||
|
||||
self.hass.data[ENTITY_MAP].async_create_or_update_map(
|
||||
entity_storage: EntityMapStorage = self.hass.data[ENTITY_MAP]
|
||||
|
||||
entity_storage.async_create_or_update_map(
|
||||
self.unique_id, config_num, self.accessories
|
||||
)
|
||||
|
||||
self.config_num = config_num
|
||||
self.hass.async_create_task(self.async_process_entity_map())
|
||||
|
||||
return True
|
||||
|
||||
def add_accessory_factory(self, add_entities_cb) -> None:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue