fix(display): Abschlussbild sagt 'Strom trennen erlaubt' - der alte Satz war abgeschnitten

Zweiter Fund derselben Art wie die Bildsatz-Fusszeile: 'Strom kann getrennt werden'
misst in der Hero-Schrift 262,1 px bei 246 px Platz und kam am Geraet als
'Strom kann getrennt wer...' an.

Der Test deckt jetzt ALLE festen Beschriftungen ab (Abschlussbilder, beide Bildsaetze,
beide Fehlt-Warnungen, Freigabe), nicht nur die zuerst entdeckte Stelle - sonst waere
genau dieser zweite Fall wieder durchgerutscht. Der Wortlauttest prueft die Zusage
('trennen erlaubt' gegen 'NICHT trennen') statt des genauen Satzes.
This commit is contained in:
Michael Sauer
2026-09-15 10:41:42 +02:00
parent f4dd1386ef
commit 71a579c0f9
2 changed files with 53 additions and 17 deletions
+5 -1
View File
@@ -224,7 +224,11 @@ IMAGESET_MISSING_LABELS = {
# der Anzeigedienst wieder zeichnet, und an genau diesem Pi hat ein Stromzug in dieser # der Anzeigedienst wieder zeichnet, und an genau diesem Pi hat ein Stromzug in dieser
# Wartezeit schon eine SD-Karte gekostet. # Wartezeit schon eine SD-Karte gekostet.
FINAL_LABELS = { FINAL_LABELS = {
"poweroff": ("AUSGESCHALTET", "Strom kann getrennt werden", []), # "Strom kann getrennt werden" war in der Hero-Schrift 262,1 px breit und kam am
# 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!", "reboot": ("NEUSTART", "Strom NICHT trennen!",
["Der Pi kommt in rund 2 min wieder.", ["Der Pi kommt in rund 2 min wieder.",
"Solange bleibt dieses Bild stehen."]), "Solange bleibt dieses Bild stehen."]),
+48 -16
View File
@@ -1885,11 +1885,13 @@ def test_the_shutdown_and_the_reboot_screen_differ():
off, reboot = _final_text("poweroff"), _final_text("reboot") off, reboot = _final_text("poweroff"), _final_text("reboot")
assert off != reboot assert off != reboot
assert "AUSGESCHALTET" in off and "NEUSTART" in reboot assert "AUSGESCHALTET" in off and "NEUSTART" in reboot
# Ausschalten: erlaubt das Trennen ausdruecklich. # Ausschalten: erlaubt das Trennen ausdruecklich. Geprueft wird die ZUSAGE, nicht
assert "kann getrennt werden" in off # der genaue Satz - der Wortlaut musste am 2026-09-15 kuerzer werden, weil die alte
# Fassung ("Strom kann getrennt werden", 262,1 px) auf dem Panel abgeschnitten war.
assert "trennen erlaubt" in off
# Neustart: verbietet es ebenso ausdruecklich - und sagt nirgends das Gegenteil. # Neustart: verbietet es ebenso ausdruecklich - und sagt nirgends das Gegenteil.
assert "NICHT trennen" in reboot assert "NICHT trennen" in reboot
assert "kann getrennt werden" not in reboot assert "trennen erlaubt" not in reboot
def test_the_reboot_screen_says_how_long_it_stays(): def test_the_reboot_screen_says_how_long_it_stays():
@@ -2094,19 +2096,49 @@ def _footer_width_px(text: str) -> float:
return draw.textlength(text, font=font) return draw.textlength(text, font=font)
@pytest.mark.parametrize("name", sorted(render.IMAGESET_LABELS)) def _fixed_labels():
@pytest.mark.parametrize("missing", [False, True]) """Jede fest im Code stehende Beschriftung mit der Rolle, in der sie gezeichnet wird.
def test_imageset_footer_fits_the_panel_with_room_for_a_wider_font(name, missing): Bewusst VOLLSTAENDIG und nicht auf die Fusszeile beschraenkt: der Geraetetermin hat
"""Jede Fusszeile des Umschalters - beide Saetze, mit und ohne Fehlt-Warnung - muss denselben Fehler an zwei Stellen gezeigt (Fusszeile UND das Abschlussbild "Strom kann
ungekuerzt auf das Panel passen, auch wenn die Schrift des Zielgeraets breiter baut getrennt werden", 262,1 px bei 246 px Platz). Eine Pruefung, die nur die zuerst
als die hier installierte. Der Fehlt-Fall ist der wichtigere der vier: er sagt, dass entdeckte Stelle abdeckt, haette die zweite wieder durchgelassen."""
der GEWAEHLTE Bildsatz nicht auf dem Pi liegt, und genau der war unsichtbar.""" out = []
text, = (t for t, role in render._imageset_blocks( for kind, (title, hero, details) in render.FINAL_LABELS.items():
{"imageset": name, "imageset_ok": not missing}) if role == render.ROLE_FOOTER) out.append(("FINAL/%s/titel" % kind, title, render.ROLE_HEADER))
out.append(("FINAL/%s/hero" % kind, hero, render.ROLE_HERO))
for i, detail in enumerate(details):
out.append(("FINAL/%s/detail%d" % (kind, i), detail, render.ROLE_DETAIL))
for name, label in render.IMAGESET_LABELS.items():
out.append(("BILDSATZ/%s" % name, label, render.ROLE_FOOTER))
for name, label in render.IMAGESET_MISSING_LABELS.items():
out.append(("BILDSATZ-FEHLT/%s" % name, label, render.ROLE_FOOTER))
out.append(("FREIGABE", render.ARMED_LABEL, render.ROLE_HERO))
return out
_ROLE_FONTS = {
render.ROLE_HEADER: (lambda: render.HEADER_FONT_PX, True),
render.ROLE_HERO: (lambda: render.HERO_FONT_PX, True),
render.ROLE_DETAIL: (lambda: render.DETAIL_FONT_PX, False),
render.ROLE_BIG: (lambda: render.BIG_FONT_PX, True),
render.ROLE_FOOTER: (lambda: render.FOOTER_FONT_PX, True),
}
@pytest.mark.parametrize("source,text,role", _fixed_labels(),
ids=[x[0] for x in _fixed_labels()])
def test_fixed_labels_fit_the_panel_with_room_for_a_wider_font(source, text, role):
"""Jede feste Beschriftung muss UNGEKUERZT auf das Panel passen, auch wenn die
Schrift des Zielgeraets breiter baut als die hier installierte."""
from PIL import Image, ImageDraw, ImageFont
draw = ImageDraw.Draw(Image.new("1", (render.PANEL_WIDTH_PX,
render.PANEL_HEIGHT_PX), 255))
size_px, bold = _ROLE_FONTS[role]
font = render._load_font(ImageFont, size_px(), bold=bold)
width_px = draw.textlength(text, font=font)
max_width_px = render.PANEL_WIDTH_PX - 2 * render.TEXT_MARGIN_PX max_width_px = render.PANEL_WIDTH_PX - 2 * render.TEXT_MARGIN_PX
width_px = _footer_width_px(text)
assert width_px * FOOTER_WIDTH_SAFETY <= max_width_px, ( assert width_px * FOOTER_WIDTH_SAFETY <= max_width_px, (
"Fusszeile {!r} misst {:.1f} px; mit {:.0f} %% Reserve fuer eine breitere " "{}: {!r} misst {:.1f} px; mit {:.0f} % Reserve fuer eine breitere Schrift "
"Schrift bleiben nur {:.1f} px Platz".format( "bleiben nur {:.1f} px Platz".format(
text, width_px, (FOOTER_WIDTH_SAFETY - 1) * 100, max_width_px)) source, text, width_px, (FOOTER_WIDTH_SAFETY - 1) * 100, max_width_px))