add features
This commit is contained in:
@@ -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.
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user