feat(station): Abschlussbild beim Herunterfahren und beim Neustart

E-Paper behaelt sein Bild dauerhaft, auch stromlos. Faehrt der Pi
herunter, wird der Anzeigedienst mit abgeraeumt und das zuletzt
gezeichnete Bild bleibt fuer immer stehen - bei der Abnahme stand dort
die Rueckfrage des Tastermenues, und der ausgeschaltete Pi sah aus, als
warte er noch auf eine Eingabe.

Zwei neue Units, ninlight-poweroff.service (WantedBy=poweroff.target)
und ninlight-reboot.service (WantedBy=reboot.target). Sie haengen am
System, nicht am Tasterdienst: so greifen sie bei jedem Herunterfahren -
Menue, "poweroff" per SSH, "reboot" - und nicht nur auf einem von drei
Wegen. Zwei Units statt einer Fallunterscheidung, weil systemd einem
ExecStart nicht sagt, wohin die Reise geht.

Die Texte unterscheiden sich: "AUSGESCHALTET / Strom kann getrennt
werden" gegen "NEUSTART / Strom NICHT trennen!" samt Hinweis auf die
rund zwei Minuten, die der Zero W bis zum Anzeigedienst braucht. An
diesem Pi hat ein Stromzug in genau dieser Wartezeit schon eine
SD-Karte gekostet.

Reihenfolge: die Units ordnen sich per After=ninlight-display.service
hinter dessen Stop ein, und "ninlight-station display final <kind>"
wartet zusaetzlich, bis systemctl is-active nicht mehr anschlaegt -
dasselbe Muster wie display_handover(), nur ohne Wiederanfahren. Gibt
der Dienst die Leitungen nicht frei, wird nicht gezeichnet (GPIO busy),
sondern gewarnt: ein Anzeigefehler haelt das Herunterfahren nie auf.

Nebenbei behoben: display_run() reichte nur "$1" an display.py weiter
und haette "--final poweroff" halbiert.
This commit is contained in:
Michael Sauer
2026-09-15 03:02:21 +02:00
parent 300edafc3e
commit 4e1a965cbb
12 changed files with 572 additions and 4 deletions
+32
View File
@@ -99,6 +99,38 @@ den Tasterdienst wie den Anzeigedienst; `deploy.sh` liefert `button/` bei jedem
aus. Ein fehlgeschlagenes Aktivieren/Starten ist dabei nur eine Warnung — eine Station
ohne Taster muss vollständig benutzbar bleiben.
## Abschlussbildschirm beim Herunterfahren und beim Neustart
E-Paper behält sein Bild **dauerhaft**, auch stromlos. Fährt der Pi herunter, wird der
Anzeigedienst mit abgeräumt, und das zuletzt gezeichnete Bild bleibt für immer stehen —
bei der Abnahme stand dort die **Rückfrage** des Tastermenüs, und der ausgeschaltete Pi
sah aus, als warte er noch auf eine Eingabe.
Dafür gibt es zwei systemd-Units, `ninlight-poweroff.service` (`WantedBy=poweroff.target`)
und `ninlight-reboot.service` (`WantedBy=reboot.target`). Sie hängen am **System**, nicht
am Tasterdienst: so greifen sie bei jedem Herunterfahren — über das Menü, über `poweroff`
per SSH, über `reboot` — und nicht nur auf einem von drei Wegen.
**Die Texte unterscheiden sich, und das ist der Punkt:**
| | Panel |
|---|---|
| Herunterfahren | „AUSGESCHALTET — Strom kann getrennt werden" |
| Neustart | „NEUSTART — Strom NICHT trennen!" plus der Hinweis, dass es rund 2 min dauert |
Ein Zero W braucht gut anderthalb Minuten, bis der Anzeigedienst wieder zeichnet. Stünde
dort währenddessen „Strom kann getrennt werden", wäre das eine Aufforderung zu genau dem
Griff, der an diesem Pi schon eine SD-Karte gekostet hat.
**Reihenfolge:** der Anzeigedienst hält die GPIO-/SPI-Leitungen; zwei Prozesse darauf
ergeben `lgpio.error: 'GPIO busy'`. Die Units ordnen sich deshalb per
`After=ninlight-display.service` hinter dessen Stop ein, und `ninlight-station display
final <poweroff|reboot>` wartet zusätzlich, bis `systemctl is-active ninlight-display`
nicht mehr anschlägt — dasselbe Muster wie `display_handover()` bei `display test`, nur
ohne Wiederanfahren. Gibt der Dienst die Leitungen nicht frei, wird **nicht** gezeichnet,
sondern eine Zeile ins Journal geschrieben: ein Fehler an der Anzeige darf das
Herunterfahren nie aufhalten.
SSID und Passwort stehen in `/etc/ninlight-station.conf` auf dem Pi und müssen zu den
Build-Parametern `NINLIGHT_RECOVERY_SSID` und `NINLIGHT_RECOVERY_PASSWORD` aus
`config.local.cmake` passen. Weicht eines ab, findet die Lampe die Station nicht.