From 1de98433d4766ebedb5435c3968745c0892e7570 Mon Sep 17 00:00:00 2001 From: MarekWo Date: Sun, 5 Apr 2026 13:40:53 +0200 Subject: [PATCH] fix(ble): add adapter power-cycle to startup retry loop On startup, _connect_with_retry also needs adapter power-cycling every 3rd failed attempt to clear stale GATT state from previous sessions. Without this, the container can fail all 10 startup retries when BlueZ holds stale notification handles. Co-Authored-By: Claude Opus 4.6 --- app/device_manager.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/device_manager.py b/app/device_manager.py index 6eee7e5..ce7be12 100644 --- a/app/device_manager.py +++ b/app/device_manager.py @@ -168,11 +168,17 @@ class DeviceManager: logger.error(f"Connection attempt {attempt}/{max_retries} failed: {e}") if attempt < max_retries: + # BLE: power-cycle adapter every 3rd failed attempt to clear + # stale GATT notification handles from previous sessions + if self.config.use_ble and attempt % 3 == 0: + await self._ble_power_cycle_adapter() delay = min(base_delay * attempt, 30.0) logger.info(f"Retrying in {delay:.0f}s...") await asyncio.sleep(delay) logger.error(f"Failed to connect after {max_retries} attempts") + if self.config.use_ble: + self._ble_permanently_failed = True def _detect_serial_port(self) -> str: """Auto-detect serial port when configured as 'auto'."""