From b9b52b5e6d3c17e8a1e3fefe7fe60c278fb28f75 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 24 Feb 2024 11:31:45 -1000 Subject: [PATCH] Reduce Bluetooth setup time (#111304) --- .../components/bluetooth/__init__.py | 60 ++++++++++++------- homeassistant/components/bluetooth/manager.py | 5 +- 2 files changed, 43 insertions(+), 22 deletions(-) diff --git a/homeassistant/components/bluetooth/__init__.py b/homeassistant/components/bluetooth/__init__.py index 3438f4725a2..e3d1db5a86e 100644 --- a/homeassistant/components/bluetooth/__init__.py +++ b/homeassistant/components/bluetooth/__init__.py @@ -16,6 +16,7 @@ from bluetooth_adapters import ( DEFAULT_ADDRESS, DEFAULT_CONNECTION_SLOTS, AdapterDetails, + BluetoothAdapters, adapter_human_name, adapter_model, adapter_unique_name, @@ -135,27 +136,13 @@ async def _async_get_adapter_from_address( return await _get_manager(hass).async_get_adapter_from_address(address) -async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: - """Set up the bluetooth integration.""" - await passive_update_processor.async_setup(hass) - integration_matcher = IntegrationMatcher(await async_get_bluetooth(hass)) - integration_matcher.async_setup() - bluetooth_adapters = get_adapters() - bluetooth_storage = BluetoothStorage(hass) - await bluetooth_storage.async_setup() - slot_manager = BleakSlotManager() - await slot_manager.async_setup() - manager = HomeAssistantBluetoothManager( - hass, integration_matcher, bluetooth_adapters, bluetooth_storage, slot_manager - ) - set_manager(manager) - await manager.async_setup() - hass.bus.async_listen_once( - EVENT_HOMEASSISTANT_STOP, hass_callback(lambda event: manager.async_stop()) - ) - hass.data[DATA_MANAGER] = models.MANAGER = manager +async def _async_start_adapter_discovery( + hass: HomeAssistant, + manager: HomeAssistantBluetoothManager, + bluetooth_adapters: BluetoothAdapters, +) -> None: + """Start adapter discovery.""" adapters = await manager.async_get_bluetooth_adapters() - async_migrate_entries(hass, adapters, bluetooth_adapters.default_adapter) await async_discover_adapters(hass, adapters) @@ -212,7 +199,40 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: EVENT_HOMEASSISTANT_STOP, hass_callback(lambda event: cancel()) ) + +async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: + """Set up the bluetooth integration.""" + bluetooth_adapters = get_adapters() + bluetooth_storage = BluetoothStorage(hass) + slot_manager = BleakSlotManager() + integration_matcher = IntegrationMatcher(await async_get_bluetooth(hass)) + + slot_manager_setup_task = hass.async_create_task( + slot_manager.async_setup(), "slot_manager setup" + ) + processor_setup_task = hass.async_create_task( + passive_update_processor.async_setup(hass), "passive_update_processor setup" + ) + storage_setup_task = hass.async_create_task( + bluetooth_storage.async_setup(), "bluetooth storage setup" + ) + integration_matcher.async_setup() + manager = HomeAssistantBluetoothManager( + hass, integration_matcher, bluetooth_adapters, bluetooth_storage, slot_manager + ) + set_manager(manager) + + await storage_setup_task + await manager.async_setup() + hass.data[DATA_MANAGER] = models.MANAGER = manager + + hass.async_create_background_task( + _async_start_adapter_discovery(hass, manager, bluetooth_adapters), + "start_adapter_discovery", + ) + await slot_manager_setup_task async_delete_issue(hass, DOMAIN, "haos_outdated") + await processor_setup_task return True diff --git a/homeassistant/components/bluetooth/manager.py b/homeassistant/components/bluetooth/manager.py index 381beb02520..32589d822d3 100644 --- a/homeassistant/components/bluetooth/manager.py +++ b/homeassistant/components/bluetooth/manager.py @@ -11,7 +11,7 @@ from bluetooth_adapters import BluetoothAdapters from habluetooth import BaseHaRemoteScanner, BaseHaScanner, BluetoothManager from homeassistant import config_entries -from homeassistant.const import EVENT_LOGGING_CHANGED +from homeassistant.const import EVENT_HOMEASSISTANT_STOP, EVENT_LOGGING_CHANGED from homeassistant.core import ( CALLBACK_TYPE, Event, @@ -136,6 +136,7 @@ class HomeAssistantBluetoothManager(BluetoothManager): self._cancel_logging_listener = self.hass.bus.async_listen( EVENT_LOGGING_CHANGED, self._async_logging_changed ) + self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, self.async_stop) seen: set[str] = set() for address, service_info in itertools.chain( self._connectable_history.items(), self._all_history.items() @@ -187,7 +188,7 @@ class HomeAssistantBluetoothManager(BluetoothManager): return _async_remove_callback @hass_callback - def async_stop(self) -> None: + def async_stop(self, event: Event | None = None) -> None: """Stop the Bluetooth integration at shutdown.""" _LOGGER.debug("Stopping bluetooth manager") self._async_save_scanner_histories()