Skip to content

Commit

Permalink
fix: do not attempt to disconnect non-bluez bledevices (#54)
Browse files Browse the repository at this point in the history
  • Loading branch information
bdraco authored Oct 18, 2022
1 parent d4dca1a commit 54b6c84
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 21 deletions.
37 changes: 19 additions & 18 deletions src/bleak_retry_connector/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
from typing import Any, TypeVar

import async_timeout
from bleak import BleakClient, BleakError
from bleak import BleakClient
from bleak.backends.device import BLEDevice
from bleak.backends.service import BleakGATTServiceCollection
from bleak.exc import BleakDBusError
from bleak.exc import BleakDBusError, BleakError

DISCONNECT_TIMEOUT = 5

Expand All @@ -33,7 +33,7 @@
get_global_bluez_manager,
)

UNREACHABLE_RSSI = -127
NO_RSSI_VALUE = -127


# Make sure bleak and dbus-next have time
Expand All @@ -43,7 +43,7 @@
BLEAK_BACKOFF_TIME = 0.1


RSSI_SWITCH_THRESHOLD = 6
RSSI_SWITCH_THRESHOLD = 5

__all__ = [
"establish_connection",
Expand All @@ -54,8 +54,9 @@
"BleakClientWithServiceCache",
"BleakAbortedError",
"BleakNotFoundError",
"BleakDisconnectedError",
"BLEAK_RETRY_EXCEPTIONS",
"RSSI_SWITCH_THRESHOLD",
"NO_RSSI_VALUE",
]


Expand Down Expand Up @@ -171,7 +172,7 @@ async def freshen_ble_device(device: BLEDevice) -> BLEDevice | None:
):
return None
return await get_bluez_device(
device.name, device.details["path"], _get_rssi(device)
device.name or device.address, device.details["path"], _get_rssi(device)
)


Expand Down Expand Up @@ -218,7 +219,7 @@ async def get_bluez_device(
) -> BLEDevice | None:
"""Get a BLEDevice object for a BlueZ DBus path."""
best_path = device_path = path
rssi_to_beat = device_rssi = rssi or UNREACHABLE_RSSI
rssi_to_beat: int = rssi or NO_RSSI_VALUE

try:
manager = await get_global_bluez_manager()
Expand All @@ -231,7 +232,7 @@ async def get_bluez_device(
# anything over the current path
if _log_disappearance:
_LOGGER.debug("%s - %s: Device has disappeared", name, device_path)
rssi_to_beat = device_rssi = UNREACHABLE_RSSI
rssi_to_beat = NO_RSSI_VALUE

for path in _get_possible_paths(device_path):
if path not in properties or not (
Expand All @@ -254,22 +255,22 @@ async def get_bluez_device(
# cause the device to be used anyways.
continue

rssi = device_props.get("RSSI") or UNREACHABLE_RSSI
if rssi_to_beat != UNREACHABLE_RSSI and (
not rssi
or rssi - RSSI_SWITCH_THRESHOLD < device_rssi
or rssi < rssi_to_beat
alternate_device_rssi: int = device_props.get("RSSI") or NO_RSSI_VALUE
if (
rssi_to_beat != NO_RSSI_VALUE
and alternate_device_rssi - RSSI_SWITCH_THRESHOLD < rssi_to_beat
):
continue
best_path = path
rssi_to_beat = rssi
_LOGGER.debug(
"%s - %s: Found path %s with better RSSI %s",
"%s - %s: Found path %s with better RSSI %s > %s",
name,
device_path,
path,
rssi,
alternate_device_rssi,
rssi_to_beat,
)
rssi_to_beat = alternate_device_rssi

if best_path == device_path:
return None
Expand All @@ -291,7 +292,7 @@ def ble_device_from_properties(path: str, props: dict[str, Any]) -> BLEDevice:
props["Address"],
props["Alias"],
{"path": path, "props": props},
props.get("RSSI") or UNREACHABLE_RSSI,
props.get("RSSI") or NO_RSSI_VALUE,
uuids=props.get("UUIDs", []),
manufacturer_data={
k: bytes(v) for k, v in props.get("ManufacturerData", {}).items()
Expand Down Expand Up @@ -399,7 +400,7 @@ def _get_rssi(device: BLEDevice) -> int:
"""Get the RSSI for the device."""
if not isinstance(device.details, dict) or "props" not in device.details:
return device.rssi
return device.details["props"].get("RSSI") or device.rssi or UNREACHABLE_RSSI
return device.details["props"].get("RSSI") or device.rssi or NO_RSSI_VALUE


async def establish_connection(
Expand Down
4 changes: 2 additions & 2 deletions src/bleak_retry_connector/dbus.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import async_timeout
from bleak.backends.bluezdbus import defs
from bleak.backends.device import BLEDevice
from dbus_fast.aio import MessageBus
from dbus_fast.aio.message_bus import MessageBus
from dbus_fast.constants import BusType
from dbus_fast.message import Message

Expand All @@ -22,7 +22,7 @@ async def disconnect_devices(devices: list[BLEDevice]) -> None:
if not valid_devices:
return
bus = await MessageBus(bus_type=BusType.SYSTEM, negotiate_unix_fd=True).connect()
for device in devices:
for device in valid_devices:
with contextlib.suppress(Exception):
async with async_timeout.timeout(DISCONNECT_TIMEOUT):
await bus.call(
Expand Down
4 changes: 3 additions & 1 deletion tests/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -677,7 +677,9 @@ def __init__(self):
)
bleak_retry_connector.defs = defs

with patch.object(bleak_retry_connector, "IS_LINUX", True):
with patch.object(bleak_retry_connector, "IS_LINUX", True), patch(
"bleak.get_platform_client_backend_type"
):

client = await establish_connection(
FakeBleakClientWithServiceCache,
Expand Down

0 comments on commit 54b6c84

Please sign in to comment.