fix(ble): use BleakScanner to find device before connecting

In bleak 3.x, BleakClient(address_string) can't find paired BLE
devices that aren't actively advertising.  This caused
BleakDeviceNotFoundError or 30-second connection timeouts.

Fix: pre-scan via BleakScanner.find_device_by_address() which queries
BlueZ's D-Bus object tree directly, then pass the BLEDevice object to
MeshCore.create_ble(device=...) instead of the raw MAC address.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
MarekWo
2026-04-05 14:10:47 +02:00
parent a92b505975
commit 9c692fac8b
+19 -3
View File
@@ -358,10 +358,26 @@ class DeviceManager:
# to prevent BlueZ auto-reconnect during bleak's connect phase.
await self._ble_force_disconnect(self.config.MC_BLE_ADDRESS)
try:
self.mc = await MeshCore.create_ble(
address=self.config.MC_BLE_ADDRESS,
auto_reconnect=False,
# bleak 3.x: BleakClient(address_string) can't find paired
# devices that aren't advertising. Pre-scan via
# BleakScanner.find_device_by_address which queries BlueZ's
# D-Bus object tree directly, then pass the BLEDevice to
# MeshCore.create_ble(device=...).
from bleak import BleakScanner
ble_device = await BleakScanner.find_device_by_address(
self.config.MC_BLE_ADDRESS, timeout=10
)
if ble_device:
logger.info(f"BLE device found: {ble_device.name}")
self.mc = await MeshCore.create_ble(
device=ble_device,
auto_reconnect=False,
)
else:
raise RuntimeError(
f"BLE device {self.config.MC_BLE_ADDRESS} not found "
"in BlueZ — check pairing"
)
finally:
# Always re-trust the device (even on failure) so BlueZ
# maintains the bond for future connections