From 22ca28b93d4c88eda928b4e22b2d5510a369821c Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 24 Jul 2022 19:23:23 -0500 Subject: [PATCH] Ensure bluetooth can be reloaded when hot plugging a bluetooth adapter (#75699) --- homeassistant/components/bluetooth/__init__.py | 8 +++++++- tests/components/bluetooth/test_init.py | 17 +++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/bluetooth/__init__.py b/homeassistant/components/bluetooth/__init__.py index fb514a33e99..9266603839c 100644 --- a/homeassistant/components/bluetooth/__init__.py +++ b/homeassistant/components/bluetooth/__init__.py @@ -440,5 +440,11 @@ class BluetoothManager: self._cancel_unavailable_tracking() self._cancel_unavailable_tracking = None if self.scanner: - await self.scanner.stop() + try: + await self.scanner.stop() + except BleakError as ex: + # This is not fatal, and they may want to reload + # the config entry to restart the scanner if they + # change the bluetooth dongle. + _LOGGER.error("Error stopping scanner: %s", ex) uninstall_multiple_bleak_catcher() diff --git a/tests/components/bluetooth/test_init.py b/tests/components/bluetooth/test_init.py index 8b0d60bc42d..aa3a6253b83 100644 --- a/tests/components/bluetooth/test_init.py +++ b/tests/components/bluetooth/test_init.py @@ -1213,3 +1213,20 @@ async def test_getting_the_scanner_returns_the_wrapped_instance(hass, enable_blu """Test getting the scanner returns the wrapped instance.""" scanner = bluetooth.async_get_scanner(hass) assert isinstance(scanner, models.HaBleakScannerWrapper) + + +async def test_config_entry_can_be_reloaded_when_stop_raises( + hass, caplog, enable_bluetooth +): + """Test we can reload if stopping the scanner raises.""" + entry = hass.config_entries.async_entries(bluetooth.DOMAIN)[0] + assert entry.state == ConfigEntryState.LOADED + + with patch( + "homeassistant.components.bluetooth.HaBleakScanner.stop", side_effect=BleakError + ): + await hass.config_entries.async_reload(entry.entry_id) + await hass.async_block_till_done() + + assert entry.state == ConfigEntryState.LOADED + assert "Error stopping scanner" in caplog.text