Compare commits

...

2 Commits

Author SHA1 Message Date
265cded661 Merge pull request 'add features' (#1) from Paul/Fichero:main into main
Some checks failed
Deploy to GitHub Pages / build (push) Has been cancelled
Deploy to GitHub Pages / deploy (push) Has been cancelled
Reviewed-on: #1
2026-03-07 12:40:44 +00:00
paul2212
09f340c6e9 add features 2026-03-07 13:39:00 +01: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. 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/) 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. 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 import FastAPI, File, Form, HTTPException, UploadFile
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import RedirectResponse
from PIL import Image from PIL import Image
from fichero.cli import DOTS_PER_MM, do_print from fichero.cli import DOTS_PER_MM, do_print
@@ -91,6 +92,11 @@ def _address(address: str | None) -> str | None:
# Endpoints # Endpoints
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@app.get("/", include_in_schema=False)
async def root():
"""Redirect root to interactive API docs."""
return RedirectResponse(url="/docs")
@app.get( @app.get(
"/status", "/status",

View File

@@ -12,6 +12,7 @@ from collections.abc import AsyncGenerator
from contextlib import asynccontextmanager from contextlib import asynccontextmanager
from bleak import BleakClient, BleakGATTCharacteristic, BleakScanner from bleak import BleakClient, BleakGATTCharacteristic, BleakScanner
from bleak.exc import BleakDBusError, BleakError
# --- RFCOMM (Classic Bluetooth) support - Linux + Windows (Python 3.9+) --- # --- RFCOMM (Classic Bluetooth) support - Linux + Windows (Python 3.9+) ---
@@ -374,7 +375,17 @@ async def connect(
yield pc yield pc
else: else:
addr = address or await find_printer() addr = address or await find_printer()
async with BleakClient(addr) as client: try:
pc = PrinterClient(client) async with BleakClient(addr) as client:
await pc.start() pc = PrinterClient(client)
yield pc 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 Thermodrucker. Das Add-on ermöglicht das Drucken von Textetiketten und Bildern
direkt aus Home Assistant-Automationen, Skripten oder externen Anwendungen. 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 ## Voraussetzungen
- Fichero D11s / AiYin D11s Drucker - Fichero D11s / AiYin D11s Drucker
@@ -21,8 +26,12 @@ direkt aus Home Assistant-Automationen, Skripten oder externen Anwendungen.
## Verwendung ## Verwendung
Nach dem Start ist die API unter `http://<HA-IP>:<port>` erreichbar. Das Add-on ist nach dem Start auf zwei Arten erreichbar:
Die interaktive Swagger-Dokumentation ist unter `http://<HA-IP>:<port>/docs` verfügbar.
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 ### Endpunkte

View File

@@ -14,6 +14,11 @@ arch:
init: false init: false
startup: application startup: application
boot: auto 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_network: true
host_dbus: true host_dbus: true

View File

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

View File

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