From 488b04fc8bc0c11bea4bcbbab419513a5d3e76a4 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 21 Sep 2022 11:03:50 -1000 Subject: [PATCH] Handle default RSSI values from bleak in bluetooth (#78908) --- homeassistant/components/bluetooth/manager.py | 3 +- tests/components/bluetooth/test_manager.py | 56 +++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/bluetooth/manager.py b/homeassistant/components/bluetooth/manager.py index 0dcf11fd1e2..06eb71b5a71 100644 --- a/homeassistant/components/bluetooth/manager.py +++ b/homeassistant/components/bluetooth/manager.py @@ -65,6 +65,7 @@ APPLE_START_BYTES_WANTED: Final = { } RSSI_SWITCH_THRESHOLD = 6 +NO_RSSI_VALUE = -1000 _LOGGER = logging.getLogger(__name__) @@ -88,7 +89,7 @@ def _prefer_previous_adv( STALE_ADVERTISEMENT_SECONDS, ) return False - if new.device.rssi - RSSI_SWITCH_THRESHOLD > old.device.rssi: + if new.device.rssi - RSSI_SWITCH_THRESHOLD > (old.device.rssi or NO_RSSI_VALUE): # If new advertisement is RSSI_SWITCH_THRESHOLD more, the new one is preferred if new.source != old.source: _LOGGER.debug( diff --git a/tests/components/bluetooth/test_manager.py b/tests/components/bluetooth/test_manager.py index c05b9424508..f3f3d1b3664 100644 --- a/tests/components/bluetooth/test_manager.py +++ b/tests/components/bluetooth/test_manager.py @@ -119,6 +119,62 @@ async def test_switching_adapters_based_on_rssi(hass, enable_bluetooth): ) +async def test_switching_adapters_based_on_zero_rssi(hass, enable_bluetooth): + """Test switching adapters based on zero rssi.""" + + address = "44:44:33:11:23:45" + + switchbot_device_no_rssi = BLEDevice(address, "wohand_poor_signal", rssi=0) + switchbot_adv_no_rssi = AdvertisementData( + local_name="wohand_no_rssi", service_uuids=[] + ) + inject_advertisement_with_source( + hass, switchbot_device_no_rssi, switchbot_adv_no_rssi, "hci0" + ) + + assert ( + bluetooth.async_ble_device_from_address(hass, address) + is switchbot_device_no_rssi + ) + + switchbot_device_good_signal = BLEDevice(address, "wohand_good_signal", rssi=-60) + switchbot_adv_good_signal = AdvertisementData( + local_name="wohand_good_signal", service_uuids=[] + ) + inject_advertisement_with_source( + hass, switchbot_device_good_signal, switchbot_adv_good_signal, "hci1" + ) + + assert ( + bluetooth.async_ble_device_from_address(hass, address) + is switchbot_device_good_signal + ) + + inject_advertisement_with_source( + hass, switchbot_device_good_signal, switchbot_adv_no_rssi, "hci0" + ) + assert ( + bluetooth.async_ble_device_from_address(hass, address) + is switchbot_device_good_signal + ) + + # We should not switch adapters unless the signal hits the threshold + switchbot_device_similar_signal = BLEDevice( + address, "wohand_similar_signal", rssi=-62 + ) + switchbot_adv_similar_signal = AdvertisementData( + local_name="wohand_similar_signal", service_uuids=[] + ) + + inject_advertisement_with_source( + hass, switchbot_device_similar_signal, switchbot_adv_similar_signal, "hci0" + ) + assert ( + bluetooth.async_ble_device_from_address(hass, address) + is switchbot_device_good_signal + ) + + async def test_switching_adapters_based_on_stale(hass, enable_bluetooth): """Test switching adapters based on the previous advertisement being stale."""