diff --git a/homeassistant/components/bluetooth/update_coordinator.py b/homeassistant/components/bluetooth/update_coordinator.py index 88263aa0a58..9c38bf2f520 100644 --- a/homeassistant/components/bluetooth/update_coordinator.py +++ b/homeassistant/components/bluetooth/update_coordinator.py @@ -39,6 +39,7 @@ class BasePassiveBluetoothCoordinator(ABC): self.mode = mode self._last_unavailable_time = 0.0 self._last_name = address + self._available = async_address_present(hass, address, connectable) @callback def async_start(self) -> CALLBACK_TYPE: @@ -85,7 +86,17 @@ class BasePassiveBluetoothCoordinator(ABC): @property def available(self) -> bool: """Return if the device is available.""" - return async_address_present(self.hass, self.address, self.connectable) + return self._available + + @callback + def _async_handle_bluetooth_event_internal( + self, + service_info: BluetoothServiceInfoBleak, + change: BluetoothChange, + ) -> None: + """Handle a bluetooth event.""" + self._available = True + self._async_handle_bluetooth_event(service_info, change) @callback def _async_start(self) -> None: @@ -93,7 +104,7 @@ class BasePassiveBluetoothCoordinator(ABC): self._on_stop.append( async_register_callback( self.hass, - self._async_handle_bluetooth_event, + self._async_handle_bluetooth_event_internal, BluetoothCallbackMatcher( address=self.address, connectable=self.connectable ), @@ -123,3 +134,4 @@ class BasePassiveBluetoothCoordinator(ABC): """Handle the device going unavailable.""" self._last_unavailable_time = service_info.time self._last_name = service_info.name + self._available = False diff --git a/tests/components/bluetooth/test_passive_update_processor.py b/tests/components/bluetooth/test_passive_update_processor.py index d11f5cd5ccd..c96fbfbfc99 100644 --- a/tests/components/bluetooth/test_passive_update_processor.py +++ b/tests/components/bluetooth/test_passive_update_processor.py @@ -406,7 +406,7 @@ async def test_exception_from_update_method( """Generate mock data.""" nonlocal run_count run_count += 1 - if run_count == 1: + if run_count == 2: raise Exception("Test exception") return GENERIC_PASSIVE_BLUETOOTH_DATA_UPDATE @@ -436,6 +436,7 @@ async def test_exception_from_update_method( processor.async_add_listener(MagicMock()) inject_bluetooth_service_info(hass, GENERIC_BLUETOOTH_SERVICE_INFO) + saved_callback(GENERIC_BLUETOOTH_SERVICE_INFO, BluetoothChange.ADVERTISEMENT) assert processor.available is True # We should go unavailable once we get an exception @@ -473,7 +474,7 @@ async def test_bad_data_from_update_method( """Generate mock data.""" nonlocal run_count run_count += 1 - if run_count == 1: + if run_count == 2: return "bad_data" return GENERIC_PASSIVE_BLUETOOTH_DATA_UPDATE @@ -503,6 +504,7 @@ async def test_bad_data_from_update_method( processor.async_add_listener(MagicMock()) inject_bluetooth_service_info(hass, GENERIC_BLUETOOTH_SERVICE_INFO) + saved_callback(GENERIC_BLUETOOTH_SERVICE_INFO, BluetoothChange.ADVERTISEMENT) assert processor.available is True # We should go unavailable once we get bad data