add features #1

Merged
Tobias merged 1 commits from Paul/Fichero:main into main 2026-03-07 12:40:45 +00:00
7 changed files with 63 additions and 10 deletions

View File

@@ -2,6 +2,11 @@
Web GUI, Python CLI, and protocol documentation for the Fichero D11s thermal label printer.
## Credits
- Original developer/project: [0xMH/fichero-printer](https://github.com/0xMH/fichero-printer)
- This repository version was additionally extended with AI-assisted changes.
Blog post: [Reverse Engineering Action's Cheap Fichero Labelprinter](https://blog.dbuglife.com/reverse-engineering-fichero-label-printer/)
The [Fichero](https://www.action.com/nl-nl/p/3212141/fichero-labelprinter/) is a cheap Bluetooth thermal label printer sold at Action. Internally it's an AiYin D11s made by Xiamen Print Future Technology. The official app is closed-source and doesn't expose the protocol, so this project reverse-engineers it from the decompiled APK.

View File

@@ -23,6 +23,7 @@ from typing import Annotated
from fastapi import FastAPI, File, Form, HTTPException, UploadFile
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import RedirectResponse
from PIL import Image
from fichero.cli import DOTS_PER_MM, do_print
@@ -91,6 +92,11 @@ def _address(address: str | None) -> str | None:
# Endpoints
# ---------------------------------------------------------------------------
@app.get("/", include_in_schema=False)
async def root():
"""Redirect root to interactive API docs."""
return RedirectResponse(url="/docs")
@app.get(
"/status",

View File

@@ -12,6 +12,7 @@ from collections.abc import AsyncGenerator
from contextlib import asynccontextmanager
from bleak import BleakClient, BleakGATTCharacteristic, BleakScanner
from bleak.exc import BleakDBusError, BleakError
# --- RFCOMM (Classic Bluetooth) support - Linux + Windows (Python 3.9+) ---
@@ -374,7 +375,17 @@ async def connect(
yield pc
else:
addr = address or await find_printer()
async with BleakClient(addr) as client:
pc = PrinterClient(client)
await pc.start()
yield pc
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

View File

@@ -4,6 +4,11 @@ Ein HTTP-REST-API-Server für den **Fichero D11s** (auch bekannt als AiYin D11s)
Thermodrucker. Das Add-on ermöglicht das Drucken von Textetiketten und Bildern
direkt aus Home Assistant-Automationen, Skripten oder externen Anwendungen.
## Herkunft / Credits
- Originalentwickler / Ursprungsprojekt: https://github.com/0xMH/fichero-printer
- Diese Variante wurde zusätzlich mit AI-unterstützten Erweiterungen ergänzt.
## Voraussetzungen
- Fichero D11s / AiYin D11s Drucker
@@ -21,8 +26,12 @@ direkt aus Home Assistant-Automationen, Skripten oder externen Anwendungen.
## Verwendung
Nach dem Start ist die API unter `http://<HA-IP>:<port>` erreichbar.
Die interaktive Swagger-Dokumentation ist unter `http://<HA-IP>:<port>/docs` verfügbar.
Das Add-on ist nach dem Start auf zwei Arten erreichbar:
1. Home Assistant UI (Ingress): In der Add-on-Seite auf **"Öffnen"** klicken.
2. Direkt per Port im Netzwerk: `http://<HA-IP>:<port>` (z.B. `http://homeassistant.local:8765`).
Hinweis: `/` leitet auf `/docs` weiter (Swagger UI).
### Endpunkte

View File

@@ -14,6 +14,11 @@ arch:
init: false
startup: application
boot: auto
ingress: true
ingress_port: 8765
panel_icon: mdi:printer
panel_title: Fichero Printer
webui: "http://[HOST]:[PORT:8765]/docs"
host_network: true
host_dbus: true

View File

@@ -23,6 +23,7 @@ from typing import Annotated
from fastapi import FastAPI, File, Form, HTTPException, UploadFile
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import RedirectResponse
from PIL import Image
from fichero.cli import DOTS_PER_MM, do_print
@@ -91,6 +92,11 @@ def _address(address: str | None) -> str | None:
# Endpoints
# ---------------------------------------------------------------------------
@app.get("/", include_in_schema=False)
async def root():
"""Redirect root to interactive API docs."""
return RedirectResponse(url="/docs")
@app.get(
"/status",

View File

@@ -12,6 +12,7 @@ from collections.abc import AsyncGenerator
from contextlib import asynccontextmanager
from bleak import BleakClient, BleakGATTCharacteristic, BleakScanner
from bleak.exc import BleakDBusError, BleakError
# --- RFCOMM (Classic Bluetooth) support - Linux + Windows (Python 3.9+) ---
@@ -374,7 +375,17 @@ async def connect(
yield pc
else:
addr = address or await find_printer()
async with BleakClient(addr) as client:
pc = PrinterClient(client)
await pc.start()
yield pc
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