release/0.1.20 #4
12
README.md
12
README.md
@@ -140,6 +140,18 @@ asyncio.run(main())
|
||||
|
||||
The package exports `PrinterClient`, `connect`, `PrinterError`, `PrinterNotFound`, `PrinterTimeout`, `PrinterNotReady`, and `PrinterStatus`.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Classic Bluetooth: [Errno 12] Out of memory
|
||||
|
||||
If you encounter `[Errno 12] Out of memory` failures on Classic Bluetooth connections, it typically implies a stale state in the BlueZ stack or the printer's radio. As of v0.1.17, the library automatically falls back to a BLE connection when this specific error occurs.
|
||||
|
||||
If you wish to resolve the underlying Classic Bluetooth issue, these steps can help:
|
||||
|
||||
- **Power cycle the printer**: This clears the printer's radio state and is often the only fix if the device is rejecting RFCOMM.
|
||||
- **Verify Pairing**: Classic Bluetooth (RFCOMM) requires the device to be paired and trusted in the OS. You can use the "Pair Device" or "Unpair Device" buttons in the Home Assistant add-on's web UI, or run `bluetoothctl pair <MAC>` and `bluetoothctl trust <MAC>` (or `bluetoothctl remove <MAC>`) on the host. Pairing is not required for BLE.
|
||||
- **Restart Bluetooth**: `systemctl restart bluetooth` on the host can clear stuck socket handles.
|
||||
|
||||
## TODO
|
||||
|
||||
- [ ] Emoji support in text labels. The default Pillow font has no emoji glyphs, so they render as squares. Needs two-pass rendering: split text into emoji/non-emoji segments, render emoji with Apple Color Emoji (macOS) or Noto Color Emoji (Linux) using `embedded_color=True`, then composite onto the label.
|
||||
|
||||
@@ -8,6 +8,7 @@ Device class: AiYinNormalDevice (LuckPrinter SDK)
|
||||
|
||||
import asyncio
|
||||
import sys
|
||||
import errno
|
||||
from collections.abc import AsyncGenerator
|
||||
from contextlib import asynccontextmanager
|
||||
|
||||
@@ -427,14 +428,31 @@ async def connect(
|
||||
yield pc
|
||||
return
|
||||
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.
|
||||
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."
|
||||
)
|
||||
classic = False # Modify flag to trigger BLE path below
|
||||
last_exc = exc
|
||||
break
|
||||
last_exc = exc
|
||||
|
||||
# If the 'classic' flag is still true, it means the loop completed without
|
||||
# hitting the ENOMEM fallback case, so all classic attempts failed.
|
||||
if classic:
|
||||
if last_exc is not None:
|
||||
raise PrinterError(
|
||||
f"Classic Bluetooth connection failed for '{address}'. "
|
||||
f"Tried channels: {channels}. Last error: {last_exc}"
|
||||
) from last_exc
|
||||
raise PrinterError(f"Classic Bluetooth connection failed for '{address}'.")
|
||||
else:
|
||||
|
||||
# If classic=False initially, or if it was set to False for the ENOMEM fallback:
|
||||
if not classic:
|
||||
target = await resolve_ble_target(address)
|
||||
def _is_retryable_ble_error(exc: Exception) -> bool:
|
||||
msg = str(exc).lower()
|
||||
|
||||
Reference in New Issue
Block a user