diff --git a/fichero_printer/config.yaml b/fichero_printer/config.yaml index 6cf6e1a..6029ed2 100644 --- a/fichero_printer/config.yaml +++ b/fichero_printer/config.yaml @@ -1,5 +1,11 @@ name: "Fichero Printer" version: "0.1.36" +host_dbus: true +host_network: true +devices: + - /dev/rfcomm0 +environment: + DBUS_SYSTEM_BUS_ADDRESS: "unix:path=/host/run/dbus/system_bus_socket" slug: "fichero_printer" description: "REST API for the Fichero D11s (AiYin) thermal label printer over Bluetooth" url: "https://git.leuschner.dev/Tobias/Fichero" diff --git a/fichero_printer/fichero/printer.py b/fichero_printer/fichero/printer.py index 0bee4fb..35504bc 100644 --- a/fichero_printer/fichero/printer.py +++ b/fichero_printer/fichero/printer.py @@ -426,15 +426,29 @@ async def connect( except (PrinterError, PrinterTimeout) as exc: # On Linux, a stale BlueZ device state can cause RFCOMM connect() # to fail with [Errno 12] Out of memory. This is a known quirk. - # We treat this specific error as a signal to fall back to BLE. + # We treat this specific error as a signal to clear cache and retry. if isinstance(exc.__cause__, OSError) and exc.__cause__.errno == errno.ENOMEM: print( - "Classic Bluetooth connection failed with [Errno 12] Out of memory. " - "Falling back to BLE connection." + f"Classic Bluetooth connection failed with [Errno 12] Out of memory on channel {ch}. " + "Clearing Bluetooth cache and retrying..." ) - classic = False # Modify flag to trigger BLE path below - last_exc = exc - break + try: + # Clear Bluetooth cache + remove_cmd = f'echo -e "remove {address}\nquit" | bluetoothctl' + proc = await asyncio.create_subprocess_shell( + remove_cmd, + stdout=asyncio.subprocess.DEVNULL, + stderr=asyncio.subprocess.DEVNULL, + ) + await asyncio.wait_for(proc.communicate(), timeout=10.0) + print(f" Bluetooth cache cleared for {address}") + except Exception as remove_exc: + print(f" Failed to clear Bluetooth cache: {remove_exc}") + + # Continue to next channel instead of breaking + continue + + # For other errors, continue to next channel last_exc = exc # If the 'classic' flag is still true, it means the loop completed without