Fixrunde 3 zu Task 6a. EnvironmentFile=-/etc/ninlight-station.conf statt -EnvironmentFile= (Fixrunde 2 hatte das Praefix vor den Direktivennamen statt vor den Dateipfad gesetzt - systemd verwarf die Zeile komplett, die Konfigurationsdatei wurde ueberhaupt nicht mehr gelesen). clear() stellte die in Panel dokumentierte Awake-Invariante nicht her (kein 0x26-Referenzpuffer) und verwendet jetzt wie draw_full() displayPartBaseImage(). Die 30-Minuten- Vollaufbau-Uhr feuerte bisher auch ohne vorherige Teilaufbauten und erzeugte im eingeschwungenen Ruhezustand einen endlosen Schlaf-/Wach-Zyklus mit 33 Prozent Bias-Anteil - sie greift jetzt nur noch, wenn seit dem letzten Vollaufbau tatsaechlich Teilaufbauten stattfanden, und der Zaehler wird beim Einschlafen zurueckgesetzt. draw_partial() meldet zurueck, ob es intern zu einem Vollaufbau aufgewertet hat, damit die 30-Minuten-Uhr korrekt bleibt. compose() ersetzt eingebettete Zeilenumbrueche vor der Breitenmessung. Dazu ein Kommando-Rekorder fuer die Tests, der die tatsaechlich gesendete SPI-Byte-Folge protokolliert: die vorherigen Tests fuer den Referenzpuffer (N2) und die Registerfolge nach dem Schlafen (N3) pruefften nur "keine Ausnahme" und blieben laut Reviewer-Mutation gruen, wenn die eigentliche Fehlerursache wieder eingefuehrt wurde. Die neuen Tests pruefen die gesendeten Kommandos direkt und wurden gegen genau diese Mutationen verifiziert.
74 lines
4.3 KiB
Desktop File
74 lines
4.3 KiB
Desktop File
[Unit]
|
|
Description=ninlight E-Paper-Anzeige (Status der Migrations-/Rettungsstation)
|
|
# Nur eine Anzeige fuer den Hauptdienst - Wants=/After=, NICHT Requires=/BindsTo=: ein
|
|
# fehlendes oder abgestuerztes Panel darf server.py niemals mitreissen, und server.py
|
|
# darf umgekehrt starten, auch wenn dieser Dienst fehlt oder deaktiviert ist. Siehe
|
|
# display.py's Modul-Docstring: die Anzeige ist nirgends Voraussetzung fuer die
|
|
# Migration.
|
|
After=ninlight-station.service
|
|
Wants=ninlight-station.service
|
|
# Gehoeren seit systemd 229 ins [Unit], nicht ins [Service] (dort standen sie zuerst -
|
|
# Fixrunde 1, I1: systemd ignoriert sie dort mit "Unknown key name", die Vorgabe (5
|
|
# Starts/10s) greift dann bei RestartSec=5 nie, und genau das sollte die Deckelung unten
|
|
# eigentlich verhindern). ninlight-station.service (dieselbe Sektion) macht es richtig.
|
|
StartLimitIntervalSec=60
|
|
StartLimitBurst=5
|
|
|
|
[Service]
|
|
Type=simple
|
|
# Reihenfolge wichtig: systemd wendet Environment=/EnvironmentFile= in der Reihenfolge
|
|
# an, in der sie hier stehen, und eine spaetere Zuweisung ueberschreibt eine gleichnamige
|
|
# fruehere. EPD_REVISION=V3 hier ist nur der Vorgabewert, falls die Konfigurationsdatei
|
|
# (unten, per EnvironmentFile=) den Schluessel (noch) nicht enthaelt - z.B. auf einem Pi,
|
|
# der vor Task 6 aufgesetzt wurde. Steht er dort, gewinnt er.
|
|
Environment=EPD_REVISION=V3
|
|
Environment=NINLIGHT_RUN_DIR=/run/ninlight-station
|
|
Environment=NINLIGHT_STATION_CONF=/etc/ninlight-station.conf
|
|
# "-"-Praefix VOR dem Dateipfad, nicht vor dem Direktivennamen (Fixrunde 3, F1 - das war
|
|
# in Fixrunde 2 falsch herum: "-EnvironmentFile=..." ist kein gueltiger Schluesselname,
|
|
# systemd verwirft die Zeile komplett mit "Unknown key name", und die Konfigurationsdatei
|
|
# wurde dadurch ueberhaupt nicht mehr gelesen - Environment=EPD_REVISION=V3 oben haette
|
|
# IMMER gewonnen, unabhaengig davon, was in /etc/ninlight-station.conf steht). Mit dem
|
|
# Praefix am richtigen Platz gilt: ohne die Konfigurationsdatei startet die Anzeige
|
|
# trotzdem (mit den Environment=-Vorgaben oben) statt mit einem harten Fehler - "die
|
|
# Anzeige darf nirgends Voraussetzung sein" gilt auch fuer ihre eigene Konfiguration.
|
|
EnvironmentFile=-/etc/ninlight-station.conf
|
|
ExecStart=/usr/bin/python3 /opt/ninlight-station/display/display.py
|
|
|
|
# display.py faengt ein fehlendes/abgestuerztes Panel als DisplayUnavailable ab,
|
|
# protokolliert eine Zeile und beendet sich mit sys.exit(0) - das ist also nie ein
|
|
# "Fehlschlag" im systemd-Sinne und loest kein Restart= aus. Restart=on-failure (nicht
|
|
# always) greift nur fuer echte Abstuerze (z.B. ein Python-Traceback aus einem
|
|
# Programmierfehler); ohne den Deckel wuerde ein dauerhaft fehlendes Panel sonst NICHT
|
|
# staendig neu versucht (gut so), waehrend ein echter Bug endlos neu starten wuerde und
|
|
# so das Journal fluten koennte.
|
|
Restart=on-failure
|
|
RestartSec=5
|
|
|
|
NoNewPrivileges=yes
|
|
ProtectSystem=strict
|
|
ProtectHome=yes
|
|
PrivateTmp=yes
|
|
# KEIN ReadOnlyPaths=/run/ninlight-station hier (stand hier zuerst, Fixrunde 1, C3):
|
|
# server.py's Unit traegt RuntimeDirectory=ninlight-station, und "ninlight-station off"
|
|
# stoppt den Hauptdienst regulaer - dabei raeumt systemd dessen RuntimeDirectory auf,
|
|
# sofern nicht gerade ein Neustart lief (RuntimeDirectoryPreserve=restart deckt nur den
|
|
# Neustart-Fall ab, nicht den regulaeren Stop). Ein nicht mit "-" prefigierter Pfad in
|
|
# ReadOnlyPaths=/ReadWritePaths=/BindPaths=, der beim Start fehlt, laesst systemd die
|
|
# Namensraum-Einrichtung mit 226/NAMESPACE abbrechen - ausgerechnet dann, wenn die
|
|
# Anzeige "Station aus" zeigen soll, waere sie selbst nicht mehr startbar gewesen. Die
|
|
# Zeile war obendrein wirkungslos: ProtectSystem=strict macht "/" (und damit "/run",
|
|
# soweit nicht per ReadWritePaths= explizit freigegeben) bereits schreibgeschuetzt.
|
|
RestrictAddressFamilies=AF_UNIX AF_NETLINK
|
|
MemoryMax=64M
|
|
|
|
# Laeuft als root (wie der Hauptdienst) fuer /dev/spidev0.0 und die GPIO-Zeichenleitung -
|
|
# kein SupplementaryGroups=spi gpio hier (stand hier zuerst, Fixrunde 1, I2): auf reinem
|
|
# Debian (im Unterschied zu Raspberry Pi OS) gibt es diese Gruppen oft gar nicht, und
|
|
# eine fehlende Gruppe ist fuer systemd ein harter Startfehler (216/GROUP) - ausgerechnet
|
|
# in der Unit, die nie stoeren soll, wenn etwas an der Anzeige fehlt. Als root sind die
|
|
# Gruppen fuer den Geraetezugriff ohnehin nicht noetig.
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|