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:
@@ -560,6 +560,24 @@ def run_test(revision: str) -> None:
|
||||
log.info("Testbild gezeichnet (EPD_REVISION=%s)", revision)
|
||||
|
||||
|
||||
def run_final(revision: str, kind: str) -> None:
|
||||
"""Zeichnet den Abschlussbildschirm ("poweroff"/"reboot") und legt das Panel schlafen.
|
||||
|
||||
Das ist das Bild, das nach dem Herunterfahren DAUERHAFT stehen bleibt - E-Paper ist
|
||||
bistabil, es haelt sein Bild auch ohne Strom. Bewusst ein VOLLAUFBAU: ein Teilaufbau
|
||||
liesse Reste des vorigen Bildes stehen, und dieses eine Bild ueberdauert alle anderen.
|
||||
|
||||
Aufgerufen wird das ausschliesslich ueber "ninlight-station display final <kind>" aus
|
||||
einer systemd-Unit heraus, und zwar ERST, nachdem der Anzeigedienst gestoppt ist - er
|
||||
haelt sonst die GPIO-/SPI-Leitungen ("lgpio.error: 'GPIO busy'"). Diese Uebergabe
|
||||
macht das CLI (display_final()), nicht diese Funktion."""
|
||||
panel = Panel(revision)
|
||||
panel.clear()
|
||||
panel.draw_full(render.compose({"mode": "final", "final": kind}))
|
||||
panel.sleep()
|
||||
log.info("Abschlussbild gezeichnet (%s, EPD_REVISION=%s)", kind, revision)
|
||||
|
||||
|
||||
def run_clear(revision: str) -> None:
|
||||
panel = Panel(revision)
|
||||
panel.clear()
|
||||
@@ -634,6 +652,9 @@ def main() -> None:
|
||||
group = parser.add_mutually_exclusive_group()
|
||||
group.add_argument("--test", action="store_true", help="Testbild zeichnen und beenden")
|
||||
group.add_argument("--clear", action="store_true", help="Panel leeren und beenden")
|
||||
group.add_argument("--final", choices=sorted(render.FINAL_LABELS),
|
||||
help="Abschlussbild zeichnen und beenden (beim Herunterfahren "
|
||||
"bzw. Neustart; die Texte unterscheiden sich)")
|
||||
args = parser.parse_args()
|
||||
|
||||
revision = os.environ.get("EPD_REVISION", "V3")
|
||||
@@ -643,6 +664,8 @@ def main() -> None:
|
||||
run_test(revision)
|
||||
elif args.clear:
|
||||
run_clear(revision)
|
||||
elif args.final:
|
||||
run_final(revision, args.final)
|
||||
else:
|
||||
run_daemon(revision)
|
||||
except (DisplayUnavailable, ImportError) as e:
|
||||
|
||||
Reference in New Issue
Block a user