LabelPrintAgent
Windows-Tray-Connector für den PaperlessManager.
Der Agent speichert keine Layouts, keine Nummernserver-Regeln und keine MySQL-Queue-Logik mehr. Das Backend entscheidet, welche Etiketten gedruckt werden, rendert bzw. liefert das fertige Etikett als Bild, und der Agent druckt dieses Bild über einen installierten Windows-Drucker.
Ablauf
LabelPrintAgent
-> fragt alle X Sekunden PaperlessManager-Backend
-> erhält druckfertige Etikettenjobs, bis kein Job mehr vorhanden ist
-> lädt/liest das Etikettbild
-> druckt über Windows-Drucker
-> meldet Erfolg oder Fehler ans Backend zurück
Der Agent unterstützt Server-Sent Events für Push-Benachrichtigungen und nutzt Polling als Fallback. Jeder Poll-Lauf ruft so lange /jobs/next auf, bis das Backend 204 No Content zurückgibt.
Backend-Vertrag
Die ausführliche API-Beschreibung liegt in BACKEND_API.md.
Der Agent fragt standardmäßig:
GET /api/label-print-agent/jobs/next?agentId={agentId}
Authorization: Bearer {apiToken}
Wenn nichts zu drucken ist:
204 No Content
Wenn ein Etikett vorhanden ist:
{
"jobId": 12345,
"printerId": "PC-BUERO_DYMO_LABELWRITER_450",
"labelType": "artikel",
"windowsPrinterName": "DYMO LabelWriter 450",
"labelImageBase64": "...",
"labelImageContentType": "image/png",
"labelWidthMm": 57,
"labelHeightMm": 32
}
Alternativ darf das Backend statt labelImageBase64 eine URL liefern:
{
"jobId": 12345,
"printerId": "PC-BUERO_DYMO_LABELWRITER_450",
"labelType": "artikel",
"windowsPrinterName": "DYMO LabelWriter 450",
"labelImageUrl": "/api/label-print-agent/jobs/12345/image",
"labelImageContentType": "image/png",
"labelWidthMm": 57,
"labelHeightMm": 32
}
Der Agent meldet Erfolg:
POST /api/label-print-agent/jobs/{jobId}/printed
Authorization: Bearer {apiToken}
Content-Type: application/json
{
"agentId": "PC-BUERO",
"printerName": "DYMO LabelWriter 450"
}
Der Agent meldet Fehler:
POST /api/label-print-agent/jobs/{jobId}/error
Authorization: Bearer {apiToken}
Content-Type: application/json
{
"agentId": "PC-BUERO",
"printerName": "DYMO LabelWriter 450",
"errorMessage": "Drucker ist nicht verfügbar."
}
Lokale Einstellungen
Die Einstellungen liegen unter:
C:\ProgramData\LabelPrintAgent\settings.json
Beispiel:
{
"backend": {
"baseUrl": "https://paperlessmanager.local",
"agentId": "PC-BUERO",
"encryptedApiToken": "",
"registerPrinterPath": "/api/label-print-agent/printers/register",
"nextJobPath": "/api/label-print-agent/jobs/next",
"imagePath": "/api/label-print-agent/jobs/{jobId}/image",
"reportSuccessPath": "/api/label-print-agent/jobs/{jobId}/printed",
"reportErrorPath": "/api/label-print-agent/jobs/{jobId}/error",
"useServerSentEvents": true,
"eventsPath": "/api/label-print-agent/events"
},
"printer": {
"printerName": "DYMO LabelWriter 450",
"labelWidthMm": 57,
"labelHeightMm": 32,
"dpi": 300
},
"printers": [
{
"printerId": "PC-BUERO_DYMO_LABELWRITER_450",
"name": "DYMO LabelWriter Regal",
"windowsPrinterName": "DYMO LabelWriter 450",
"dpi": 300,
"defaultWidthMm": 57,
"defaultHeightMm": 32
},
{
"printerId": "PC-BUERO_ZEBRA_GK420D",
"name": "Zebra GK420 Büro",
"windowsPrinterName": "Zebra GK420d",
"dpi": 203,
"defaultWidthMm": 101,
"defaultHeightMm": 76
}
],
"worker": {
"enabled": true,
"pollIntervalSeconds": 30
}
}
Der API-Token wird lokal mit Windows DPAPI verschlüsselt gespeichert.
Der Agent registriert Drucker nicht automatisch. Im Tab Drucker kann der Benutzer die freigegebenen Einträge aus printers bewusst mit Im Backend registrieren an das Backend melden. Das Feld printer bleibt als Kompatibilitätsfeld für ältere Einstellungen erhalten; neue Jobs werden anhand von windowsPrinterName aus der Backend-Antwort auf den passenden lokalen Windows-Drucker gedruckt.
Dymo-Druck
Der Dymo LabelWriter muss in Windows als normaler Drucker eingerichtet sein. Das Backend liefert ein fertiges Bild für das Etikett, typischerweise PNG in 57 x 32 mm.
Wichtig:
- Der Agent verwendet
PrintDocument. - Es wird kein ZPL, EPL oder TSPL verwendet.
- Das Bild wird auf die komplette Papierfläche gedruckt.
- Der Dymo-Treiber sollte auf das passende Etikettenformat eingestellt sein.
Bedienung
- Anwendung starten.
- Tray-Symbol öffnen.
- Im Tab
BackendBaseUrl, AgentId und optional API-Token eintragen. - Im Tab
Druckerdie freigegebenen Drucker konfigurieren und mitIm Backend registrierenans Backend melden. - Im Tab
AllgemeinPolling aktivieren und Intervall setzen. - Mit
Jetzt prüfenkann sofort ein Poll-Lauf ausgelöst werden; dabei werden alle aktuell verfügbaren Jobs verarbeitet.
Updates
Im Tab Updates kann der Agent gegen die Gitea-Release-API nach neuen Versionen suchen. Standardmäßig wird das neueste Release dieses Repositorys abgefragt:
https://gitea.poettker-cloud.de/api/v1/repos/bjoernpoettker/LabelPrintAgent/releases/latest
Für private Repositories kann ein Gitea-Access-Token hinterlegt werden. Der Token wird lokal verschlüsselt gespeichert.
Wenn ein neueres Release gefunden wird, sucht der Agent nach einem ZIP-Asset, bevorzugt mit dem Suffix -win-x64.zip. Das ZIP enthält den framework-dependent win-x64-Publish inklusive .exe, App-Dateien und zugehöriger NuGet-.dll-Dateien, aber ohne die normale .NET-Laufzeit. Beim Installieren lädt der Agent das ZIP herunter, entpackt es in ein temporäres Verzeichnis, startet ein lokales Update-Skript, beendet sich selbst, ersetzt die Dateien im Installationsordner und startet anschließend neu.
Tray-Status
Das Tray-Icon zeigt den aktuellen Zustand:
- Grün: Worker ist aktiviert, Backend-Konfiguration ist vollständig, Drucker ist verfügbar und der letzte Backend-Kontakt war erfolgreich.
- Rot: Konfiguration fehlt, Drucker ist nicht verfügbar, Worker ist deaktiviert oder der Backend-Kontakt ist fehlgeschlagen.
Logs und 401-Fehler
Logs liegen standardmäßig unter:
C:\ProgramData\LabelPrintAgent\logs\label-print-agent-YYYYMMDD.log
Bei HTTP-Fehlern wie 401 Unauthorized protokolliert der Agent:
- HTTP-Methode und URL
- Statuscode und Reason Phrase
- ob ein Authorization-Header gesetzt wurde
- Authorization-Scheme, z. B.
Bearer - Token-Länge, aber niemals den Token selbst
- kurzer SHA-256-Fingerprint des Tokens zum Abgleich mit dem Backend
WWW-Authenticate-Header des Backends- gekürzten Response-Body des Backends
Beim Speichern wird der API-Token normalisiert. Falls versehentlich Bearer ... oder Authorization: Bearer ... eingefügt wurde, speichert der Agent nur den eigentlichen Tokenwert.
Nicht mehr im Agent
- keine Layout-JSON-Verwaltung
- keine lokalen LabelTemplates
- keine MySQL-Verbindung
- keine Nummernserver-URLs
- keine Nummernreservierung im Agent
Diese Verantwortung liegt vollständig im PaperlessManager-Backend.