Merge branch 'main' of https://git.leuschner.dev/Tobias/Fichero
This commit is contained in:
@@ -4,6 +4,11 @@ All notable changes to this project are documented in this file.
|
|||||||
|
|
||||||
The format is based on Keep a Changelog and this project uses Semantic Versioning.
|
The format is based on Keep a Changelog and this project uses Semantic Versioning.
|
||||||
|
|
||||||
|
## [0.1.10] - 2026-03-07
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Added automatic BLE reconnect retry with linear backoff for transient timeout errors (including `br-connection-timeout`) before returning a failure.
|
||||||
|
|
||||||
## [0.1.9] - 2026-03-07
|
## [0.1.9] - 2026-03-07
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -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_RASTER_SETTLE = 0.50 # wait for printhead after raster transfer
|
||||||
DELAY_AFTER_FEED = 0.30 # wait after form feed before stop command
|
DELAY_AFTER_FEED = 0.30 # wait after form feed before stop command
|
||||||
DELAY_NOTIFY_EXTRA = 0.05 # extra wait for trailing BLE notification fragments
|
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 ---
|
# --- Exceptions ---
|
||||||
@@ -405,17 +407,38 @@ async def connect(
|
|||||||
raise PrinterError(f"Classic Bluetooth connection failed for '{address}'.")
|
raise PrinterError(f"Classic Bluetooth connection failed for '{address}'.")
|
||||||
else:
|
else:
|
||||||
addr = address or await find_printer()
|
addr = address or await find_printer()
|
||||||
try:
|
def _is_retryable_ble_error(exc: Exception) -> bool:
|
||||||
async with BleakClient(addr) as client:
|
msg = str(exc).lower()
|
||||||
pc = PrinterClient(client)
|
return any(token in msg for token in ("timeout", "timed out", "br-connection-timeout"))
|
||||||
await pc.start()
|
|
||||||
yield pc
|
last_exc: Exception | None = None
|
||||||
except BleakDBusError as exc:
|
for attempt in range(1, BLE_CONNECT_RETRIES + 1):
|
||||||
if "br-connection-not-supported" in str(exc).lower():
|
try:
|
||||||
raise PrinterError(
|
async with BleakClient(addr) as client:
|
||||||
"BLE connection failed (br-connection-not-supported). "
|
pc = PrinterClient(client)
|
||||||
"Try Classic Bluetooth with classic=true and channel=1."
|
await pc.start()
|
||||||
) from exc
|
yield pc
|
||||||
raise PrinterError(f"BLE connection failed: {exc}") from exc
|
return
|
||||||
except BleakError as exc:
|
except BleakDBusError as exc:
|
||||||
raise PrinterError(f"BLE error: {exc}") from 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.")
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 0.1.10
|
||||||
|
|
||||||
|
- Added automatic BLE reconnect retry with backoff for transient timeout errors (`br-connection-timeout`).
|
||||||
|
|
||||||
## 0.1.9
|
## 0.1.9
|
||||||
|
|
||||||
- Added add-on local changelog file so Home Assistant can display release notes.
|
- Added add-on local changelog file so Home Assistant can display release notes.
|
||||||
@@ -29,4 +33,3 @@
|
|||||||
## 0.1.3
|
## 0.1.3
|
||||||
|
|
||||||
- Added ingress/webui metadata updates.
|
- Added ingress/webui metadata updates.
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: "Fichero Printer"
|
name: "Fichero Printer"
|
||||||
version: "0.1.9"
|
version: "0.1.10"
|
||||||
slug: "fichero_printer"
|
slug: "fichero_printer"
|
||||||
description: "REST API for the Fichero D11s (AiYin) thermal label printer over Bluetooth"
|
description: "REST API for the Fichero D11s (AiYin) thermal label printer over Bluetooth"
|
||||||
url: "https://git.leuschner.dev/Tobias/Fichero"
|
url: "https://git.leuschner.dev/Tobias/Fichero"
|
||||||
|
|||||||
@@ -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_RASTER_SETTLE = 0.50 # wait for printhead after raster transfer
|
||||||
DELAY_AFTER_FEED = 0.30 # wait after form feed before stop command
|
DELAY_AFTER_FEED = 0.30 # wait after form feed before stop command
|
||||||
DELAY_NOTIFY_EXTRA = 0.05 # extra wait for trailing BLE notification fragments
|
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 ---
|
# --- Exceptions ---
|
||||||
@@ -405,17 +407,38 @@ async def connect(
|
|||||||
raise PrinterError(f"Classic Bluetooth connection failed for '{address}'.")
|
raise PrinterError(f"Classic Bluetooth connection failed for '{address}'.")
|
||||||
else:
|
else:
|
||||||
addr = address or await find_printer()
|
addr = address or await find_printer()
|
||||||
try:
|
def _is_retryable_ble_error(exc: Exception) -> bool:
|
||||||
async with BleakClient(addr) as client:
|
msg = str(exc).lower()
|
||||||
pc = PrinterClient(client)
|
return any(token in msg for token in ("timeout", "timed out", "br-connection-timeout"))
|
||||||
await pc.start()
|
|
||||||
yield pc
|
last_exc: Exception | None = None
|
||||||
except BleakDBusError as exc:
|
for attempt in range(1, BLE_CONNECT_RETRIES + 1):
|
||||||
if "br-connection-not-supported" in str(exc).lower():
|
try:
|
||||||
raise PrinterError(
|
async with BleakClient(addr) as client:
|
||||||
"BLE connection failed (br-connection-not-supported). "
|
pc = PrinterClient(client)
|
||||||
"Try Classic Bluetooth with classic=true and channel=1."
|
await pc.start()
|
||||||
) from exc
|
yield pc
|
||||||
raise PrinterError(f"BLE connection failed: {exc}") from exc
|
return
|
||||||
except BleakError as exc:
|
except BleakDBusError as exc:
|
||||||
raise PrinterError(f"BLE error: {exc}") from 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.")
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "fichero-printer"
|
name = "fichero-printer"
|
||||||
version = "0.1.9"
|
version = "0.1.10"
|
||||||
description = "Fichero D11s thermal label printer - BLE CLI tool"
|
description = "Fichero D11s thermal label printer - BLE CLI tool"
|
||||||
requires-python = ">=3.10"
|
requires-python = ">=3.10"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
|||||||
Reference in New Issue
Block a user