From 80701c8f2a390e381d161f6c49062d397b24ca89 Mon Sep 17 00:00:00 2001 From: Jc2k Date: Fri, 3 Jan 2020 20:22:27 +0000 Subject: [PATCH] Defer homekit_controller initial poll after all entities are created (#30355) * Make sure first poll happens after sub-platforms are loaded and entities are created. * Function dosn't need to return anything * Don't forward entry if already forwarded it --- .../homekit_controller/connection.py | 53 ++++++++++--------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/homeassistant/components/homekit_controller/connection.py b/homeassistant/components/homekit_controller/connection.py index 3ccfa8b0139..1a01291ba61 100644 --- a/homeassistant/components/homekit_controller/connection.py +++ b/homeassistant/components/homekit_controller/connection.py @@ -135,20 +135,33 @@ class HKDevice: self.accessories = cache["accessories"] self.config_num = cache["config_num"] - # Ensure the Pairing object has access to the latest version of the - # entity map. + 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 + + async def async_process_entity_map(self): + """ + Process the entity map and load any platforms or entities that need adding. + + This is idempotent and will be called at startup and when we detect metadata changes + via the c# counter on the zeroconf record. + """ + # Ensure the Pairing object has access to the latest version of the entity map. This + # 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.async_load_platforms() + await self.async_load_platforms() self.add_entities() await self.async_update() - self._polling_interval_remover = async_track_time_interval( - self.hass, self.async_update, DEFAULT_SCAN_INTERVAL - ) - return True async def async_unload(self): @@ -178,24 +191,14 @@ class HKDevice: except AccessoryDisconnectedError: # If we fail to refresh this data then we will naturally retry # later when Bonjour spots c# is still not up to date. - return + return False self.hass.data[ENTITY_MAP].async_create_or_update_map( self.unique_id, config_num, self.accessories ) self.config_num = config_num - - # For BLE, 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.async_load_platforms() - - # Register and add new entities that are available - self.add_entities() - - await self.async_update() + self.hass.async_create_task(self.async_process_entity_map()) return True @@ -225,7 +228,7 @@ class HKDevice: self.entities.append((aid, iid)) break - def async_load_platforms(self): + async def async_load_platforms(self): """Load any platforms needed by this HomeKit device.""" for accessory in self.accessories: for service in accessory["services"]: @@ -237,12 +240,14 @@ class HKDevice: if platform in self.platforms: continue - self.hass.async_create_task( - self.hass.config_entries.async_forward_entry_setup( + self.platforms.add(platform) + try: + await self.hass.config_entries.async_forward_entry_setup( self.config_entry, platform ) - ) - self.platforms.add(platform) + except Exception: + self.platforms.remove(platform) + raise async def async_update(self, now=None): """Poll state of all entities attached to this bridge/accessory."""