feat(station): Panel zeigt Rettungs-Bildsatz, Lebenszeichen und klarere LAN-Zeile
display.py/_read_imageset() prueft jetzt das zum Modus passende Verzeichnispaar (rescue-* im Rettungsmodus, migrate-* in der Migration) - vorher pruefte die Fusszeile immer nur den Migrationssatz, auch im Rettungsmodus. render.py haengt einen kleinen Punkt an die Servierzeile, solange display.py:_recent_request() eine Anfrage der letzten ACTIVITY_WINDOW_S Sekunden meldet - faehrt ueber den vorhandenen Textvergleich mit, kein zusaetzlicher Zeichentakt fuer das E-Paper. Aus-Zustand: "no network" hiess fuer einen Bediener wie "der Migrations-/ Rettungs-Zugangspunkt ist aus" - gemeint ist das Gegenteil, das Heimnetz. Jetzt "LAN: <ip>" bzw. "LAN: not connected". run_daemon() faengt jetzt jeden Fehler beim Erheben des Zustands ab (_safe_read_state) statt die Schleife zu beenden - sonst friert das Panel nach einem einzigen unerwarteten Lesefehler fuer immer auf dem letzten Bild ein, ohne dass das am Geraet zu erkennen waere.
This commit is contained in:
@@ -316,9 +316,17 @@ def blocks(state: dict) -> list[tuple[str, str]]:
|
||||
# die Zeile weg statt eine Adresse zu erfinden. Ist das Feld da, aber leer, sagt
|
||||
# die Zeile ausdruecklich, dass kein Netz da ist: "keine Zeile" und "kein Netz"
|
||||
# sind zwei verschiedene Auskuenfte, und die zweite erklaert, warum SSH scheitert.
|
||||
#
|
||||
# Beschriftung "LAN" statt eines nackten "IP"/"no network": Rueckmeldung eines
|
||||
# Bedieners (2026-09-23) las "no network" so, als sei damit der Migrations-/
|
||||
# Rettungs-Zugangspunkt gemeint (der ja tatsaechlich aus ist, die Station ist
|
||||
# ausgeschaltet). Gemeint ist hier aber das GEGENTEIL - das gewoehnliche Heimnetz,
|
||||
# in dem der Pi als normaler Rechner haengt, sobald die Station aus ist (siehe
|
||||
# Kommentar oben). "LAN" grenzt das eindeutig vom Zugangspunkt-Netz ab, das auf
|
||||
# jedem ANDEREN Statusbild als SSID steht.
|
||||
ip = state.get("ip")
|
||||
if isinstance(ip, str):
|
||||
out.append((f"IP {ip}" if ip else "no network", ROLE_DETAIL))
|
||||
out.append((f"LAN: {ip}" if ip else "LAN: not connected", ROLE_DETAIL))
|
||||
return out + footer
|
||||
|
||||
if mode not in ("recovery", "migration"):
|
||||
@@ -424,7 +432,18 @@ def blocks(state: dict) -> list[tuple[str, str]]:
|
||||
out.append(("Auto-off pending", ROLE_DETAIL))
|
||||
|
||||
served = state.get("served")
|
||||
out.append((f"Served: {served if isinstance(served, int) else 0}", ROLE_DETAIL))
|
||||
served_line = f"Served: {served if isinstance(served, int) else 0}"
|
||||
# Lebenszeichen: ein kleiner Punkt, sobald IRGENDEINE Anfrage vor kurzem hereinkam
|
||||
# (display.py:_recent_request() - auch eine erfolglose zaehlt). Angehaengt an eine
|
||||
# bereits bestehende, immer vorhandene Zeile statt an einer eigenen Stelle im Bild
|
||||
# gezeichnet: er braucht dadurch keine eigene Zeichenlogik in compose() und keinen
|
||||
# eigenen Platz im knappen Zeilenbudget, und er faehrt ueber denselben
|
||||
# Textvergleich (RefreshPlanner.decide() in display.py) mit, der ueber ein
|
||||
# Neuzeichnen entscheidet - kein zusaetzlicher Takt, kein zusaetzliches Wachhalten
|
||||
# des E-Papers, siehe display.py:ACTIVITY_WINDOW_S fuer die volle Begruendung.
|
||||
if state.get("activity"):
|
||||
served_line += " •"
|
||||
out.append((served_line, ROLE_DETAIL))
|
||||
|
||||
recent = state.get("recent")
|
||||
if isinstance(recent, list) and recent:
|
||||
|
||||
Reference in New Issue
Block a user