From 5defbe362c47a84d6034a37590f85dcefdf25557 Mon Sep 17 00:00:00 2001 From: raw-designs Date: Wed, 2 Sep 2026 17:52:15 +0200 Subject: [PATCH] feat(P4): Cold Extraction und Wartung mehrspaltig (1.7.1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Zweiter Teil der Layoutumstellung für das 7-Zoll-Panel. Cold Extraction, drei Spalten: - Oben die Karten mit Erklärungstext (Modus, Vorbenetzung, Bezugsende), darunter die knappen (Grundeinstellung, Hauptbezug, Pumpenschutz). - Drei statt zwei Spalten, weil die Erklärungstexte keine volle Zeilenbreite brauchen und so keine halbleere Reihe stehen bleibt. - Der Warnhinweis stand als eigene Zeile am Seitenende, weit entfernt vom zugehörigen Schalter - er sitzt jetzt in der Modus-Karte. - Speichern frei unter allen Karten. Reinigung & Wartung, zwei Spalten, vier Karten: - Wartungszähler, Flush-Zeiten, Display-Helligkeit, Reinigung & Entkalkung. - Bisher lose Zeilen unter bloßen Zwischenüberschriften mit freistehenden Knöpfen dazwischen. - Hier sitzt Speichern IN der Karte: Jede Karte speichert etwas anderes. Die JC-Panels behalten ihr einspaltiges Layout; beide Varianten mit arduino-cli gegengebaut. Co-Authored-By: Claude Opus 5 --- P4_Display_Firmware/Changelog.txt | 17 ++++++++ P4_Display_Firmware/ui.cpp | 68 +++++++++++++++++++++++++++---- 2 files changed, 78 insertions(+), 7 deletions(-) diff --git a/P4_Display_Firmware/Changelog.txt b/P4_Display_Firmware/Changelog.txt index 3cb7c71..792ae4e 100644 --- a/P4_Display_Firmware/Changelog.txt +++ b/P4_Display_Firmware/Changelog.txt @@ -1,3 +1,20 @@ +Version 1.7.1: +- Cold Extraction ist auf dem 7-Zoll-Panel dreispaltig: oben die drei Karten mit + Erklaerungstext (Modus, Vorbenetzung, Bezugsende), darunter die knappen (Grundeinstellung, + Hauptbezug, Pumpenschutz), der Speichern-Knopf frei unter allen sechs. Drei statt zwei + Spalten, weil die Erklaerungstexte keine volle Zeilenbreite brauchen und so am Ende keine + halbleere Reihe stehen bleibt. +- Der Warnhinweis stand bisher als eigene Zeile am Seitenende, weit entfernt von dem + Schalter, auf den er sich bezieht. Er sitzt jetzt in der Modus-Karte. +- Reinigung & Wartung ist zweispaltig und besteht aus vier Karten: Wartungszaehler, + Flush-Zeiten, Display-Helligkeit sowie Reinigung & Entkalkung. Bisher standen dort lose + Zeilen unter blossen Zwischenueberschriften, dazwischen freistehende Knoepfe. +- Anders als bei Bruehen und Cold Extraction sitzt der Speichern-Knopf hier IN der Karte: + Jede Karte speichert etwas anderes, deshalb gehoert der Knopf zur Karte statt unter die + Seite. +- Alle drei umgestellten Seiten passen jetzt vollstaendig auf den Bildschirm. Die JC-Panels + behalten ihr einspaltiges Layout. + Version 1.7.0: - Brew-Control ist auf dem 7-Zoll-Panel zweispaltig: Pre-Infusion und Brew-by-Weight oben, Brew-by-Time und Dampf-Timer darunter, der Speichern-Knopf frei unter allen Karten. diff --git a/P4_Display_Firmware/ui.cpp b/P4_Display_Firmware/ui.cpp index 723ca1b..a955e6f 100644 --- a/P4_Display_Firmware/ui.cpp +++ b/P4_Display_Firmware/ui.cpp @@ -478,6 +478,10 @@ static const int32_t PAGE_COLS_2[] = { LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_TE // Zwei Kartenreihen, darunter eine Reihe fuer den Speichern-Knopf. static const int32_t PAGE_ROWS_2C[] = { LV_GRID_CONTENT, LV_GRID_CONTENT, LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST }; +// Drei Spalten fuer Seiten mit sechs Karten: Die Erklaerungstexte brauchen keine volle +// Zeilenbreite, und in drei Spalten bleibt am Ende keine halbleere Reihe stehen. +static const int32_t PAGE_COLS_3[] = { LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1), + LV_GRID_TEMPLATE_LAST }; static void page_grid(lv_obj_t* p, const int32_t* cols, const int32_t* rows) { lv_obj_set_layout(p, LV_LAYOUT_GRID); @@ -2217,14 +2221,28 @@ static void build_coldex(lv_obj_t* p) { taCxPumpMaxRun = add_num(cPump, "Max. Laufzeit (s)"); taCxPumpRest = add_num(cPump, "Zwangspause (s)"); - lblCxPageHint = lv_label_create(p); + // Der Warnhinweis stand frueher als eigene Zeile am Seitenende - weit entfernt von dem + // Schalter, auf den er sich bezieht. Er gehoert in die Modus-Karte. + lblCxPageHint = lv_label_create(cMode); lv_label_set_long_mode(lblCxPageHint, LV_LABEL_LONG_WRAP); lv_obj_set_width(lblCxPageHint, LV_PCT(100)); lv_obj_set_style_text_color(lblCxPageHint, COL_WARN, 0); lv_label_set_text(lblCxPageHint, ""); lv_obj_add_flag(lblCxPageHint, LV_OBJ_FLAG_HIDDEN); +#if JC_PANEL_TYPE == WS_PANEL_7H + // Drei Spalten, oben die Karten mit Erklaerungstext, darunter die knappen. + page_grid(p, PAGE_COLS_3, PAGE_ROWS_2C); + grid_at(cMode, 0, 0); grid_at(cPre, 1, 0); grid_at(cEnd, 2, 0); + grid_at(cBase, 0, 1); grid_at(cMain, 1, 1); grid_at(cPump, 2, 1); + + lv_obj_t* sbCx = th_accent_button(p, "Cold Extraction speichern"); + lv_obj_add_event_cb(sbCx, send_save_coldex, LV_EVENT_CLICKED, nullptr); + lv_obj_set_width(sbCx, LV_SIZE_CONTENT); + lv_obj_set_grid_cell(sbCx, LV_GRID_ALIGN_END, 0, 3, LV_GRID_ALIGN_START, 2, 1); +#else add_save_button(p, "Cold Extraction speichern", send_save_coldex); +#endif } // Felder nur beim Oeffnen der Seite fuellen - laufende State-Pushes duerfen eine // begonnene Eingabe nicht ueberschreiben (gleiches Muster wie populate_brew). @@ -2456,6 +2474,47 @@ static void send_reset_maint(lv_event_t*) { showToast("Wartungszähler zurückgesetzt", false); } static void build_service(lv_obj_t* p) { +#if JC_PANEL_TYPE == WS_PANEL_7H + // Vier Karten in zwei Spalten. Frueher standen hier lose Zeilen unter blossen + // Zwischenueberschriften, dazwischen freistehende Knoepfe - schwer auseinanderzuhalten + // und laenger als der Bildschirm. Jede Funktion ist jetzt eine Karte, und der + // zugehoerige Speichern-Knopf sitzt darin: Anders als bei Bruehen und Cold Extraction + // speichert hier jede Karte etwas anderes, deshalb gehoert der Knopf zur Karte. + lv_obj_t* cMaint = group_card(p, "Wartungszähler"); + lblMaintStatus = lv_label_create(cMaint); + lv_label_set_long_mode(lblMaintStatus, LV_LABEL_LONG_WRAP); + lv_obj_set_width(lblMaintStatus, LV_PCT(100)); + lv_label_set_text(lblMaintStatus, "Bezüge seit Reset: --"); + lv_obj_set_style_text_color(lblMaintStatus, COL_TEXT, 0); + taMaintInterval = add_num(cMaint, "Intervall (Bezüge)"); + lv_obj_t* rowM = row(cMaint, nullptr); + lv_obj_t* rb = th_button(rowM, "Zähler zurücksetzen", COL_WARN, lv_color_hex(0x000000)); + lv_obj_add_event_cb(rb, send_reset_maint, LV_EVENT_CLICKED, nullptr); + lv_obj_t* sbM = th_accent_button(rowM, "Speichern"); + lv_obj_add_event_cb(sbM, send_save_maint, LV_EVENT_CLICKED, nullptr); + + lv_obj_t* cFlush = group_card(p, "Flush-Zeiten", "Spüldauer für Wasser- und Dampfkreislauf"); + taFlushDur = add_num(cFlush, "Wasser-Flush (s)"); + taSteamFlushDur = add_num(cFlush, "Dampf-Flush (s)"); + add_save_button(cFlush, "Speichern", send_save_flush); + + lv_obj_t* cLight = group_card(p, "Display-Helligkeit", "Gilt für dieses Touch-Display"); + taBacklightActive = add_num(cLight, "Aktiv (%)"); + taBacklightStandby = add_num(cLight, "Standby-Uhr (%)"); + add_save_button(cLight, "Speichern", send_save_display); + + lv_obj_t* cCln = group_card(p, "Reinigung & Entkalkung", + "Der Assistent führt Schritt für Schritt durch den Vorgang"); + swMaint2 = add_switch(cCln, "Wartungsmodus"); + lv_obj_add_event_cb(swMaint2, maint_cb, LV_EVENT_VALUE_CHANGED, nullptr); + lv_obj_t* cb = th_accent_button(cCln, "Reinigungsassistent öffnen"); + lv_obj_set_width(cb, LV_PCT(100)); + lv_obj_add_event_cb(cb, cln_open, LV_EVENT_CLICKED, nullptr); + + page_grid(p, PAGE_COLS_2, PAGE_ROWS_2C); + grid_at(cMaint, 0, 0); grid_at(cFlush, 1, 0); + grid_at(cLight, 0, 1); grid_at(cCln, 1, 1); +#else section_title(p, "Reinigung & Wartung"); // Live-Status (Zaehler / Intervall / Faelligkeit) - aktualisiert ui_update @@ -2470,37 +2529,32 @@ static void build_service(lv_obj_t* p) { lv_label_set_text(lblMaintStatus, "Bezüge seit Reset: --"); lv_obj_set_style_text_color(lblMaintStatus, COL_TEXT, 0); - // Intervall einstellen + speichern taMaintInterval = add_num(p, "Intervall (Bezüge)"); add_save_button(p, "Intervall speichern", send_save_maint); - // Zaehler zuruecksetzen lv_obj_t* rb = th_button(p, "Wartungszähler zurücksetzen", COL_WARN, lv_color_hex(0x000000)); lv_obj_set_width(rb, LV_PCT(100)); lv_obj_add_event_cb(rb, send_reset_maint, LV_EVENT_CLICKED, nullptr); - // Flush-Zeiten (Wasser- und Dampfkreislauf), 1..30 s - wie in der Web-UI der S3 section_title(p, "Flush-Zeiten"); taFlushDur = add_num(p, "Wasser-Flush (s)"); taSteamFlushDur = add_num(p, "Dampf-Flush (s)"); add_save_button(p, "Flush-Zeiten speichern", send_save_flush); - // Display-Helligkeit dieses Touch-Displays (aktiv 5..100 %, Standby-Uhr 0..100 %) section_title(p, "Display-Helligkeit"); taBacklightActive = add_num(p, "Aktiv (%)"); taBacklightStandby = add_num(p, "Standby-Uhr (%)"); add_save_button(p, "Helligkeit speichern", send_save_display); - // Reinigungsassistent (eigener Sub-Screen mit Parametern + Live-Fortschritt) section_title(p, "Reinigungsassistent"); lv_obj_t* cb = th_accent_button(p, "Reinigungsassistent öffnen"); lv_obj_set_width(cb, LV_PCT(100)); lv_obj_add_event_cb(cb, cln_open, LV_EVENT_CLICKED, nullptr); - // Wartungsmodus-Toggle (gleiche Aktion wie auf der Temperatur-Seite) section_title(p, "Wartungsmodus (Entkalkung)"); swMaint2 = add_switch(p, "Wartungsmodus"); lv_obj_add_event_cb(swMaint2, maint_cb, LV_EVENT_VALUE_CHANGED, nullptr); +#endif } // ===================================================================================== -- 2.54.0