Der Kunde soll mit einem Zettel zur Kasse gehen koennen, auf dem steht, was er zahlen muss. Drei Wege fuehren jetzt zu einem Bon: der Knopf "Bon" auf der Timer-Karte druckt den Zwischenstand und laesst den Timer weiterlaufen, "Beenden" druckt den Endbeleg, und in der Historie laesst sich jeder Beleg nachdrucken. Der Drucker haengt per USB an einem Raspberry Pi und ist damit vom Timer-Server aus nicht direkt erreichbar. Auf dem Pi laeuft deshalb eine kleine Bruecke (deploy/bondrucker/, nur Python-Standardbibliothek), die fertige ESC/POS-Daten per HTTP annimmt. Das Bon-Layout bleibt bewusst hier im Repo, damit Aenderungen daran nicht auf dem Pi angefasst werden muessen. Beim Beenden wird erst gespeichert und dann gedruckt. Eine leere Papierrolle ist damit ein Papierproblem und kein Datenproblem - der Vorgang steht in der Historie, die Oberflaeche sagt ausdruecklich, dass der Bon nicht gedruckt wurde, und nennt den Grund. Ohne PRINTER_HOST in der .env ist die Druckfunktion aus und die App verhaelt sich unveraendert. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
50 lines
1.4 KiB
Desktop File
50 lines
1.4 KiB
Desktop File
[Unit]
|
|
Description=Bondrucker-Bruecke (ESC/POS ueber HTTP an den USB-Kassendrucker)
|
|
Documentation=file:///opt/bondrucker/README.md
|
|
After=network-online.target
|
|
Wants=network-online.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
ExecStart=/usr/bin/python3 /opt/bondrucker/print-server.py
|
|
|
|
# Laeuft NICHT als root. Der Dienstbenutzer ist nur deshalb in der Gruppe "lp",
|
|
# weil /dev/usb/lp0 dem Besitzer root und der Gruppe lp gehoert (Rechte 660).
|
|
User=bondrucker
|
|
Group=bondrucker
|
|
SupplementaryGroups=lp
|
|
|
|
# Konfiguration. Das Token steht in /etc/bondrucker/env, damit es nicht in der
|
|
# Versionsverwaltung landet - die Datei legt install.sh an.
|
|
Environment=PRINT_DEVICE=/dev/usb/lp0
|
|
Environment=PRINT_HOST=0.0.0.0
|
|
Environment=PRINT_PORT=9100
|
|
EnvironmentFile=-/etc/bondrucker/env
|
|
|
|
Restart=always
|
|
RestartSec=5
|
|
|
|
StandardOutput=journal
|
|
StandardError=journal
|
|
|
|
# --- Haertung ---------------------------------------------------------------
|
|
NoNewPrivileges=true
|
|
PrivateTmp=true
|
|
ProtectSystem=strict
|
|
ProtectHome=true
|
|
ProtectKernelTunables=true
|
|
ProtectKernelModules=true
|
|
ProtectControlGroups=true
|
|
RestrictSUIDSGID=true
|
|
RestrictNamespaces=true
|
|
RestrictAddressFamilies=AF_INET AF_INET6
|
|
LockPersonality=true
|
|
MemoryDenyWriteExecute=true
|
|
|
|
# Der Dienst braucht nirgends Schreibrecht - er schreibt ausschliesslich in die
|
|
# Geraetedatei, und die ist von ProtectSystem nicht betroffen.
|
|
PrivateDevices=false
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|