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:
@@ -200,6 +200,23 @@ IMAGESET_LABELS = {
|
||||
}
|
||||
IMAGESET_MISSING_SUFFIX = " - SATZ FEHLT"
|
||||
|
||||
# Der Abschlussbildschirm: was auf dem Panel stehen bleibt, wenn der Pi heruntergefaehrt
|
||||
# oder neu gestartet wird. E-Paper ist bistabil - das zuletzt gezeichnete Bild bleibt fuer
|
||||
# immer stehen, auch stromlos. Ohne diesen Schritt behauptet das Panel nach dem
|
||||
# Ausschalten weiter den Zustand von vorher (bei der Abnahme stand dort die RUECKFRAGE,
|
||||
# und der Pi sah aus, als warte er noch auf eine Eingabe).
|
||||
#
|
||||
# Die beiden Texte unterscheiden sich, und das ist der Punkt: beim Ausschalten DARF man
|
||||
# den Stecker ziehen, beim Neustart NICHT - ein Zero W braucht gut anderthalb Minuten, bis
|
||||
# der Anzeigedienst wieder zeichnet, und an genau diesem Pi hat ein Stromzug in dieser
|
||||
# Wartezeit schon eine SD-Karte gekostet.
|
||||
FINAL_LABELS = {
|
||||
"poweroff": ("AUSGESCHALTET", "Strom kann getrennt werden", []),
|
||||
"reboot": ("NEUSTART", "Strom NICHT trennen!",
|
||||
["Der Pi kommt in rund 2 min wieder.",
|
||||
"Solange bleibt dieses Bild stehen."]),
|
||||
}
|
||||
|
||||
# Woraus die Station die Signiervariante abgeleitet hat (products.classify_variant):
|
||||
# "-dev" kann in der Produkt-ID stehen, in der Version, oder in beiden. Die Quelle steht
|
||||
# mit auf dem Panel, weil genau hier am 2026-09-15 ein falsch signiertes Image
|
||||
@@ -250,6 +267,20 @@ def blocks(state: dict) -> list[tuple[str, str]]:
|
||||
|
||||
mode = state.get("mode")
|
||||
out: list[tuple[str, str]] = []
|
||||
|
||||
if mode == "final":
|
||||
# Abschlussbildschirm - KEINE Fusszeile und keine weiteren Zeilen: die Station ist
|
||||
# im Begriff zu verschwinden, und die einzige Auskunft, auf die es jetzt ankommt,
|
||||
# ist "darf ich den Stecker ziehen?".
|
||||
label = FINAL_LABELS.get(state.get("final"))
|
||||
if label is None:
|
||||
# Unbekannte Spielart - lieber ehrlich nichts behaupten als "ausgeschaltet"
|
||||
# zu sagen, wenn gleich wieder gebootet wird.
|
||||
return [("Faehrt herunter", ROLE_BIG)]
|
||||
title, hero, details = label
|
||||
return ([(title, ROLE_HEADER), (hero, ROLE_HERO)]
|
||||
+ [(d, ROLE_DETAIL) for d in details])
|
||||
|
||||
# Die Fusszeile haengt an JEDEM Statusbild - auch an "Station aus" und an "Status
|
||||
# unbekannt", die beide sofort zurueckkehren. Sie wird deshalb hier gebaut und unten
|
||||
# bei jedem Rueckgabepunkt angehaengt.
|
||||
|
||||
Reference in New Issue
Block a user