Skip to content

Commit

Permalink
fix: avoid logging connecting and connected since our BLEDevice may b…
Browse files Browse the repository at this point in the history
…e stale (#72)
  • Loading branch information
bdraco authored Dec 2, 2022
1 parent 8bbe3f2 commit 10e040c
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 40 deletions.
67 changes: 30 additions & 37 deletions src/bleak_retry_connector/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,15 @@
BLEAK_DBUS_BACKOFF_TIME = 0.25
BLEAK_OUT_OF_SLOTS_BACKOFF_TIME = 4.00
BLEAK_BACKOFF_TIME = 0.1
# Expected disconnect or ran out of slots
# after checking, don't backoff since we
# want to retry immediately.
BLEAK_DISCONNECTED_BACKOFF_TIME = 0.0

RSSI_SWITCH_THRESHOLD = 5

__all__ = [
"ble_device_description",
"establish_connection",
"close_stale_connections",
"get_device",
Expand Down Expand Up @@ -137,6 +142,8 @@
"Add additional proxies near this device"
)

NORMAL_DISCONNECT = "Disconnected"


class BleakNotFoundError(BleakError):
"""The device was not found."""
Expand Down Expand Up @@ -184,13 +191,18 @@ def ble_device_description(device: BLEDevice) -> str:
"""Get the device description."""
details = device.details
address = device.address
name = device.name
if name != address:
base_name = f"{address} - {name}"
else:
base_name = address
if isinstance(details, dict):
if path := details.get("path"):
# /org/bluez/hci2
return f"{address} -> {path[0:15]}"
return f"{base_name} -> {path[0:15]}"
if source := details.get("source"):
return f"{address} -> {source}"
return address
return f"{base_name} -> {source}"
return base_name


def _get_possible_paths(path: str) -> Generator[str, None, None]:
Expand Down Expand Up @@ -248,6 +260,8 @@ def calculate_backoff_time(exc: Exception) -> float:
return BLEAK_TRANSIENT_LONG_BACKOFF_TIME
if any(error in bleak_error for error in TRANSIENT_ERRORS):
return BLEAK_TRANSIENT_BACKOFF_TIME
if NORMAL_DISCONNECT in bleak_error:
return BLEAK_DISCONNECTED_BACKOFF_TIME
return BLEAK_BACKOFF_TIME


Expand Down Expand Up @@ -413,18 +427,17 @@ async def close_stale_connections(
return
to_disconnect: list[BLEDevice] = []
for connected_device in devices:
description = ble_device_description(connected_device)
if only_other_adapters and not ble_device_has_changed(connected_device, device):
_LOGGER.debug(
"%s - %s: unexpectedly connected, not disconnecting since only_other_adapters is set",
connected_device.name,
description,
connected_device.address,
)
else:
_LOGGER.debug(
"%s - %s: unexpectedly connected, disconnecting",
connected_device.name,
description,
connected_device.address,
)
to_disconnect.append(connected_device)

Expand Down Expand Up @@ -459,7 +472,7 @@ async def wait_for_disconnect(device: BLEDevice, min_wait_time: float) -> None:
_LOGGER.debug(
"%s - %s: Waited %s seconds to disconnect",
device.name,
ble_device_description(device),
device.address,
waited,
)
if min_wait_time and waited < min_wait_time:
Expand All @@ -475,7 +488,7 @@ async def wait_for_disconnect(device: BLEDevice, min_wait_time: float) -> None:
_LOGGER.debug(
"%s - %s: Device was removed from bus, waiting %s for it to re-appear: %s",
device.name,
ble_device_description(device),
device.address,
min_wait_time,
ex,
)
Expand All @@ -484,7 +497,7 @@ async def wait_for_disconnect(device: BLEDevice, min_wait_time: float) -> None:
_LOGGER.debug(
"%s - %s: Failed waiting for disconnect",
device.name,
ble_device_description(device),
device.address,
exc_info=True,
)

Expand Down Expand Up @@ -555,18 +568,6 @@ def _raise_if_needed(name: str, description: str, exc: Exception) -> None:
if not create_client:
create_client = ble_device_has_changed(original_device, device)

description = ble_device_description(device)

if debug_enabled:
rssi = _get_rssi(device)
_LOGGER.debug(
"%s - %s: Connecting (attempt: %s, last rssi: %s)",
name,
description,
attempt,
rssi,
)

if create_client:
client = client_class(
device, disconnected_callback=disconnected_callback, **kwargs
Expand All @@ -593,13 +594,13 @@ def _raise_if_needed(name: str, description: str, exc: Exception) -> None:
_LOGGER.debug(
"%s - %s: Timed out trying to connect (attempt: %s, last rssi: %s)",
name,
description,
device.address,
attempt,
rssi,
)
backoff_time = calculate_backoff_time(exc)
await wait_for_disconnect(device, backoff_time)
_raise_if_needed(name, description, exc)
_raise_if_needed(name, device.address, exc)
except BrokenPipeError as exc:
# BrokenPipeError is raised by dbus-next when the device disconnects
#
Expand All @@ -616,27 +617,27 @@ def _raise_if_needed(name: str, description: str, exc: Exception) -> None:
_LOGGER.debug(
"%s - %s: Failed to connect: %s (attempt: %s, last rssi: %s)",
name,
description,
device.address,
str(exc),
attempt,
rssi,
)
_raise_if_needed(name, description, exc)
_raise_if_needed(name, device.address, exc)
except EOFError as exc:
transient_errors += 1
backoff_time = calculate_backoff_time(exc)
if debug_enabled:
_LOGGER.debug(
"%s - %s: Failed to connect: %s, backing off: %s (attempt: %s, last rssi: %s)",
name,
description,
device.address,
str(exc),
backoff_time,
attempt,
rssi,
)
await wait_for_disconnect(device, backoff_time)
_raise_if_needed(name, description, exc)
_raise_if_needed(name, device.address, exc)
except BLEAK_EXCEPTIONS as exc:
bleak_error = str(exc)
# BleakDeviceNotFoundError can mean that the adapter has run out of
Expand All @@ -652,23 +653,15 @@ def _raise_if_needed(name: str, description: str, exc: Exception) -> None:
_LOGGER.debug(
"%s - %s: Failed to connect: %s, backing off: %s (attempt: %s, last rssi: %s)",
name,
description,
device.address,
bleak_error,
backoff_time,
attempt,
rssi,
)
await wait_for_disconnect(device, backoff_time)
_raise_if_needed(name, description, exc)
_raise_if_needed(name, device.address, exc)
else:
if debug_enabled:
_LOGGER.debug(
"%s - %s: Connected (attempt: %s, last rssi: %s)",
name,
description,
attempt,
rssi,
)
return client
# Ensure the disconnect callback
# has a chance to run before we try to reconnect
Expand Down
31 changes: 28 additions & 3 deletions tests/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
BleakNotFoundError,
BleakOutOfConnectionSlotsError,
_reset_dbus_socket_cache,
ble_device_description,
ble_device_has_changed,
calculate_backoff_time,
establish_connection,
Expand Down Expand Up @@ -441,7 +442,7 @@ async def disconnect(self, *args, **kwargs):

assert isinstance(exc, BleakAbortedError)
assert str(exc) == (
"test - aa:bb:cc:dd:ee:ff -> /org/bluez/hci2: "
"test - aa:bb:cc:dd:ee:ff: "
"Failed to connect: "
"le-connection-abort-by-local: "
"Interference/range; "
Expand Down Expand Up @@ -474,7 +475,7 @@ async def disconnect(self, *args, **kwargs):

assert isinstance(exc, BleakOutOfConnectionSlotsError)
assert str(exc) == (
"test - aa:bb:cc:dd:ee:ff -> esphome_proxy_1: "
"test - aa:bb:cc:dd:ee:ff: "
"Failed to connect: "
"out of connection slots: "
"The proxy/adapter is out of connection slots; "
Expand Down Expand Up @@ -515,7 +516,7 @@ async def disconnect(self, *args, **kwargs):

assert isinstance(exc, BleakNotFoundError)
assert str(exc) == (
"test - aa:bb:cc:dd:ee:ff -> /org/bluez/hci2: "
"test - aa:bb:cc:dd:ee:ff: "
"Failed to connect: "
"[org.freedesktop.DBus.Error.UnknownObject] "
'Method "Connect" with signature "" on interface "org.bluez.Device1" '
Expand Down Expand Up @@ -1643,3 +1644,27 @@ def __init__(self):
device = await get_device("FA:23:9D:AA:45:46")

assert device is not None


@pytest.mark.asyncio
async def test_ble_device_description():
device = BLEDevice(
"aa:bb:cc:dd:ee:ff",
"name",
{"path": "/org/bluez/hci2/dev_FA_23_9D_AA_45_46"},
)
assert (
ble_device_description(device) == "aa:bb:cc:dd:ee:ff - name -> /org/bluez/hci2"
)
device2 = BLEDevice(
"aa:bb:cc:dd:ee:ff",
"name",
{"path": "/org/bluez/hci2/dev_FA_23_9D_AA_45_46"},
)
assert (
ble_device_description(device2) == "aa:bb:cc:dd:ee:ff - name -> /org/bluez/hci2"
)
device3 = BLEDevice("aa:bb:cc:dd:ee:ff", "name", {"source": "esphome_proxy_1"})
assert (
ble_device_description(device3) == "aa:bb:cc:dd:ee:ff - name -> esphome_proxy_1"
)

0 comments on commit 10e040c

Please sign in to comment.