feat(station): Panel und CLI auf Englisch, IP-Zeile im Off-Bild
Die deutschen Texte sahen auf dem 2,13"-Panel merkwuerdig aus - jetzt sind alle Texte, die der Bediener am Geraet oder auf der Konsole sieht, englisch: Modus-, Phasen-, Bildsatz- und Abschlussbeschriftungen in render.py, die Bedientexte des Tasterdienstes und saemtliche Ausgaben von ninlight-station inklusive des Hilfetexts. Die Testbeschreibungen der Suiten bleiben deutsch - die liest nur, wer die Tests laufen laesst. Neu im Off-Bild: die Adresse, unter der der Pi gerade erreichbar ist. Ist die Station aus, ist der Pi ein gewoehnlicher Rechner im Heimnetz, und die einzige Auskunft, die man dann am Panel braucht, ist die fuer SSH. Die Adresse kommt aus einem UDP-Socket, der nur verbunden und nie benutzt wird (kein Datenverkehr, kein DNS, kein Unterprozess in einer 5-s-Schleife) und liefert genau die Adresse der Standardroute. Ohne Netz sagt die Zeile ausdruecklich "no network": eine fehlende Zeile wuerde offen lassen, warum SSH gerade scheitert. Die Zeile gibt es NUR im Off-Bild - im Betrieb traegt wlan0 die Adresse des Zugangspunkts, die ohnehin auf jedem Statusbild steht.
This commit is contained in:
@@ -172,7 +172,7 @@ FONT_SEARCH_PATHS = (
|
||||
("/Library/Fonts/Arial.ttf", "/Library/Fonts/Arial Bold.ttf"),
|
||||
)
|
||||
|
||||
MODE_LABELS = {"recovery": "RETTUNG", "migration": "MIGRATION"}
|
||||
MODE_LABELS = {"recovery": "RECOVERY", "migration": "MIGRATION"}
|
||||
# "armed" wird gesondert behandelt (es zieht zusaetzlich eine Beiwerkzeile mit dem
|
||||
# Zielnamen nach sich), deshalb hier nicht gelistet.
|
||||
PHASE_LABELS = {"auto": "AUTO", "listen": "LISTEN"}
|
||||
@@ -186,8 +186,8 @@ PHASE_LABELS = {"auto": "AUTO", "listen": "LISTEN"}
|
||||
# breiteren Schrift hoechstens am Ende beschnitten wird, ohne dass dabei eine Auskunft
|
||||
# verloren geht - der Zustand "freigegeben" ist der einzige mit diesem Label) und der
|
||||
# Zielname als eigene Beiwerkzeile ueber die volle Panelbreite.
|
||||
ARMED_LABEL = "FREIGEGEBEN"
|
||||
ARMED_DETAIL_PREFIX = "Freigabe: "
|
||||
ARMED_LABEL = "ARMED"
|
||||
ARMED_DETAIL_PREFIX = "Armed: "
|
||||
|
||||
# Der Bildsatz-Umschalter in der Fusszeile. Bewusst als Aussage ueber die LAMPE formuliert
|
||||
# und nicht ueber das Verzeichnis: "migrate-wlan" sagt dem Bediener am Geraet nichts,
|
||||
@@ -201,16 +201,16 @@ ARMED_DETAIL_PREFIX = "Freigabe: "
|
||||
# mit 246,0 von 246 px haarscharf; deshalb hat es niemand bemerkt. Breitenbudget siehe
|
||||
# test_imageset_footer_fits_the_panel_with_room_for_a_wider_font.
|
||||
IMAGESET_LABELS = {
|
||||
"ohne-wlan": "ohne WLAN-Daten (Onboarding-AP)",
|
||||
"mit-wlan": "MIT WLAN-Daten (eigenes Netz)",
|
||||
"ohne-wlan": "no Wi-Fi data (onboarding AP)",
|
||||
"mit-wlan": "WITH Wi-Fi data (own network)",
|
||||
}
|
||||
# Fehlt das Verzeichnis des gewaehlten Satzes, ERSETZT die Warnung die Zeile, statt sie
|
||||
# zu verlaengern. Als angehaengtes Suffix (" - SATZ FEHLT", bis 2026-09-15) war sie in
|
||||
# BEIDEN Richtungen und in beiden Schriften ausserhalb der Panelbreite - die einzige
|
||||
# Zeile, die sagt, dass die Station gar nichts ausliefern kann, war damit nie zu sehen.
|
||||
IMAGESET_MISSING_LABELS = {
|
||||
"ohne-wlan": "SATZ FEHLT: ohne WLAN-Daten",
|
||||
"mit-wlan": "SATZ FEHLT: MIT WLAN-Daten",
|
||||
"ohne-wlan": "SET MISSING: no Wi-Fi data",
|
||||
"mit-wlan": "SET MISSING: WITH Wi-Fi data",
|
||||
}
|
||||
|
||||
# Der Abschlussbildschirm: was auf dem Panel stehen bleibt, wenn der Pi heruntergefaehrt
|
||||
@@ -228,10 +228,10 @@ FINAL_LABELS = {
|
||||
# Geraet als "Strom kann getrennt wer..." an - siehe die Fusszeile weiter oben, es
|
||||
# ist derselbe Fehler. Alle festen Beschriftungen haengen jetzt an
|
||||
# test_fixed_labels_fit_the_panel_with_room_for_a_wider_font.
|
||||
"poweroff": ("AUSGESCHALTET", "Strom trennen erlaubt", []),
|
||||
"reboot": ("NEUSTART", "Strom NICHT trennen!",
|
||||
["Der Pi kommt in rund 2 min wieder.",
|
||||
"Solange bleibt dieses Bild stehen."]),
|
||||
"poweroff": ("POWERED OFF", "Safe to unplug", []),
|
||||
"reboot": ("REBOOTING", "Do NOT unplug!",
|
||||
["The Pi is back in about 2 min.",
|
||||
"This screen stays until then."]),
|
||||
}
|
||||
|
||||
# Woraus die Station die Signiervariante abgeleitet hat (products.classify_variant):
|
||||
@@ -293,7 +293,7 @@ def blocks(state: dict) -> list[tuple[str, str]]:
|
||||
if label is None:
|
||||
# Unbekannte Spielart - lieber ehrlich nichts behaupten als "ausgeschaltet"
|
||||
# zu sagen, wenn gleich wieder gebootet wird.
|
||||
return [("Faehrt herunter", ROLE_BIG)]
|
||||
return [("Shutting down", ROLE_BIG)]
|
||||
title, hero, details = label
|
||||
return ([(title, ROLE_HEADER), (hero, ROLE_HERO)]
|
||||
+ [(d, ROLE_DETAIL) for d in details])
|
||||
@@ -308,14 +308,24 @@ def blocks(state: dict) -> list[tuple[str, str]]:
|
||||
# diesen Modus selbst, server.py kennt ihn nicht. Bewusst keine weiteren Zeilen
|
||||
# (insbesondere keine SSID - die waere aus einer alten Konfigurationsdatei und
|
||||
# gerade nicht aktiv). Genau deshalb ROLE_BIG: die Zeile ist der ganze Inhalt.
|
||||
out.append(("Station aus", ROLE_BIG))
|
||||
out.append(("Station off", ROLE_BIG))
|
||||
# Die Adresse, unter der der Pi gerade erreichbar ist - die einzige Auskunft, die
|
||||
# man bei ausgeschalteter Station am Geraet wirklich braucht (per SSH draufgehen,
|
||||
# ohne den Router zu befragen). display.py legt sie nur in DIESEN Zustand; fehlt
|
||||
# das Feld (aeltere display.py-Fassung, von Hand gebauter Zustand im Test), bleibt
|
||||
# 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.
|
||||
ip = state.get("ip")
|
||||
if isinstance(ip, str):
|
||||
out.append((f"IP {ip}" if ip else "no network", ROLE_DETAIL))
|
||||
return out + footer
|
||||
|
||||
if mode not in ("recovery", "migration"):
|
||||
# Unbekannter oder fehlender Modus, z.B. ein frisch aufgesetzter Pi, auf dem noch
|
||||
# nichts geschrieben wurde. Lieber ehrlich "unbekannt" zeigen als einen Modus zu
|
||||
# unterstellen.
|
||||
out.append((f"Status unbekannt ({mode})" if mode else "Status unbekannt", ROLE_BIG))
|
||||
out.append((f"Status unknown ({mode})" if mode else "Status unknown", ROLE_BIG))
|
||||
return out + footer
|
||||
|
||||
out.append((MODE_LABELS[mode], ROLE_HEADER))
|
||||
@@ -409,12 +419,12 @@ def blocks(state: dict) -> list[tuple[str, str]]:
|
||||
autooff_minutes = state.get("autooff_minutes")
|
||||
if isinstance(autooff_minutes, int) and not isinstance(autooff_minutes, bool):
|
||||
if autooff_minutes > 0:
|
||||
out.append(("Auto-Aus in {} min".format(autooff_minutes), ROLE_DETAIL))
|
||||
out.append(("Auto-off in {} min".format(autooff_minutes), ROLE_DETAIL))
|
||||
else:
|
||||
out.append(("Auto-Aus steht an", ROLE_DETAIL))
|
||||
out.append(("Auto-off pending", ROLE_DETAIL))
|
||||
|
||||
served = state.get("served")
|
||||
out.append((f"Ausgeliefert: {served if isinstance(served, int) else 0}", ROLE_DETAIL))
|
||||
out.append((f"Served: {served if isinstance(served, int) else 0}", ROLE_DETAIL))
|
||||
|
||||
recent = state.get("recent")
|
||||
if isinstance(recent, list) and recent:
|
||||
@@ -467,7 +477,7 @@ def _ui_blocks(ui: dict) -> list[tuple[str, str]]:
|
||||
# Es laeuft eine Bedienung, aber die Datei traegt keinen brauchbaren Text
|
||||
# (abgeschnitten, fremde Fassung). Lieber gross sagen, dass bedient wird, als
|
||||
# ein leeres Panel zu zeigen, das nach "haengt" aussieht.
|
||||
out.append(("Bedienung", ROLE_BIG))
|
||||
out.append(("Button menu", ROLE_BIG))
|
||||
return out
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user