Add BLE retry/backoff for connection timeouts and bump to 0.1.10
Some checks failed
Deploy to GitHub Pages / build (push) Has been cancelled
Deploy to GitHub Pages / deploy (push) Has been cancelled

This commit is contained in:
paul2212
2026-03-07 14:29:44 +01:00
parent 54ba6795c0
commit 8513afe831
6 changed files with 85 additions and 31 deletions

View File

@@ -53,6 +53,8 @@ DELAY_CHUNK_GAP = 0.02 # inter-chunk pacing for BLE throughput
DELAY_RASTER_SETTLE = 0.50 # wait for printhead after raster transfer
DELAY_AFTER_FEED = 0.30 # wait after form feed before stop command
DELAY_NOTIFY_EXTRA = 0.05 # extra wait for trailing BLE notification fragments
BLE_CONNECT_RETRIES = 3 # retry transient BLE connect failures
BLE_CONNECT_BACKOFF = 0.7 # base backoff in seconds (linear: n * base)
# --- Exceptions ---
@@ -405,17 +407,38 @@ async def connect(
raise PrinterError(f"Classic Bluetooth connection failed for '{address}'.")
else:
addr = address or await find_printer()
try:
async with BleakClient(addr) as client:
pc = PrinterClient(client)
await pc.start()
yield pc
except BleakDBusError as exc:
if "br-connection-not-supported" in str(exc).lower():
raise PrinterError(
"BLE connection failed (br-connection-not-supported). "
"Try Classic Bluetooth with classic=true and channel=1."
) from exc
raise PrinterError(f"BLE connection failed: {exc}") from exc
except BleakError as exc:
raise PrinterError(f"BLE error: {exc}") from exc
def _is_retryable_ble_error(exc: Exception) -> bool:
msg = str(exc).lower()
return any(token in msg for token in ("timeout", "timed out", "br-connection-timeout"))
last_exc: Exception | None = None
for attempt in range(1, BLE_CONNECT_RETRIES + 1):
try:
async with BleakClient(addr) as client:
pc = PrinterClient(client)
await pc.start()
yield pc
return
except BleakDBusError as exc:
msg = str(exc).lower()
if "br-connection-not-supported" in msg:
raise PrinterError(
"BLE connection failed (br-connection-not-supported). "
"Try Classic Bluetooth with classic=true and channel=1."
) from exc
last_exc = exc
if _is_retryable_ble_error(exc) and attempt < BLE_CONNECT_RETRIES:
await asyncio.sleep(BLE_CONNECT_BACKOFF * attempt)
continue
raise PrinterError(f"BLE connection failed: {exc}") from exc
except BleakError as exc:
last_exc = exc
if _is_retryable_ble_error(exc) and attempt < BLE_CONNECT_RETRIES:
await asyncio.sleep(BLE_CONNECT_BACKOFF * attempt)
continue
raise PrinterError(f"BLE error: {exc}") from exc
if last_exc is not None:
raise PrinterError(
f"BLE connection failed after {BLE_CONNECT_RETRIES} attempts: {last_exc}"
) from last_exc
raise PrinterError("BLE connection failed for unknown reason.")