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`.
|
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
|
## 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.
|
- [ ] 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 asyncio
|
||||||
import sys
|
import sys
|
||||||
|
import errno
|
||||||
from collections.abc import AsyncGenerator
|
from collections.abc import AsyncGenerator
|
||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
|
|
||||||
@@ -427,14 +428,31 @@ async def connect(
|
|||||||
yield pc
|
yield pc
|
||||||
return
|
return
|
||||||
except (PrinterError, PrinterTimeout) as exc:
|
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
|
last_exc = exc
|
||||||
if last_exc is not None:
|
|
||||||
raise PrinterError(
|
# If the 'classic' flag is still true, it means the loop completed without
|
||||||
f"Classic Bluetooth connection failed for '{address}'. "
|
# hitting the ENOMEM fallback case, so all classic attempts failed.
|
||||||
f"Tried channels: {channels}. Last error: {last_exc}"
|
if classic:
|
||||||
) from last_exc
|
if last_exc is not None:
|
||||||
raise PrinterError(f"Classic Bluetooth connection failed for '{address}'.")
|
raise PrinterError(
|
||||||
else:
|
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}'.")
|
||||||
|
|
||||||
|
# If classic=False initially, or if it was set to False for the ENOMEM fallback:
|
||||||
|
if not classic:
|
||||||
target = await resolve_ble_target(address)
|
target = await resolve_ble_target(address)
|
||||||
def _is_retryable_ble_error(exc: Exception) -> bool:
|
def _is_retryable_ble_error(exc: Exception) -> bool:
|
||||||
msg = str(exc).lower()
|
msg = str(exc).lower()
|
||||||
|
|||||||
Reference in New Issue
Block a user