From 01d960258af48897c4394ba8c445c7bafd5d43ea Mon Sep 17 00:00:00 2001 From: raw-designs Date: Thu, 3 Sep 2026 00:33:50 +0200 Subject: [PATCH] =?UTF-8?q?feat(P4):=20Uhr=20l=C3=A4uft=20lokal=20weiter,?= =?UTF-8?q?=20wenn=20die=20S3=20keine=20Zeit=20liefert=20(1.8.6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Die Uhrzeit kommt von der Hauptplatine und ist leer, solange dort keine Zeitquelle synchronisiert ist. Bei einem erneuten Abgleich ist sie kurz weg, und die Uhr verschwand für ein paar Sekunden - im Standby unruhig. Der P4 merkt sich jetzt die zuletzt empfangene Zeit (Minuten seit Mitternacht plus lv_tick zum Empfangszeitpunkt) und rechnet zwischen den Meldungen selbst weiter. Sobald die S3 wieder eine Zeit schickt, gilt deren Wert - der P4 stellt nichts richtig und ersetzt keine Zeitquelle, er überbrückt nur die Lücke. Ohne je empfangene Zeit bleibt die Anzeige leer wie bisher. Gilt für die Kopfleisten-Uhr und die große Standby-Uhr; beide setzen den Text jetzt über label_set_if_changed, sparen also unnötige Neuzeichnungen. Beide Panel-Varianten mit arduino-cli gegengebaut. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01STPpZoK3ToDhrcniVqE6MJ --- P4_Display_Firmware/Changelog.txt | 8 +++++ P4_Display_Firmware/ui.cpp | 49 ++++++++++++++++++++++++++++--- 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/P4_Display_Firmware/Changelog.txt b/P4_Display_Firmware/Changelog.txt index d5df872..e21f6a8 100644 --- a/P4_Display_Firmware/Changelog.txt +++ b/P4_Display_Firmware/Changelog.txt @@ -1,3 +1,11 @@ +Version 1.8.6: +- Die Uhrzeit verschwindet nicht mehr, wenn die Hauptplatine ihre Zeit gerade neu abgleicht. + Der P4 merkt sich die zuletzt empfangene Uhrzeit und zählt zwischen den Meldungen selbst + weiter; sobald die Hauptplatine wieder eine Zeit schickt, gilt deren Wert. +- Der P4 stellt dabei nichts richtig und ersetzt keine Zeitquelle - er überbrückt nur die + Lücke. Hat er noch nie eine Uhrzeit bekommen, bleibt die Anzeige wie bisher leer. +- Gilt für die Uhr in der Kopfleiste und für die große Standby-Uhr. + Version 1.8.5: - Die Verzögerung von rund zwei Sekunden rund um den Standby ist behoben. Sie lag nicht an der Helligkeitsumschaltung, sondern daran, dass die Standby-Uhr bei JEDER Zustandsmeldung diff --git a/P4_Display_Firmware/ui.cpp b/P4_Display_Firmware/ui.cpp index 55035fc..98d4d43 100644 --- a/P4_Display_Firmware/ui.cpp +++ b/P4_Display_Firmware/ui.cpp @@ -3895,6 +3895,44 @@ static void dash_brew_mode_tick(const MachineState& st) { dash_brew_mode(aktiv || (war && (uint32_t)(jetzt - zuletzt) < DASH_BREW_HOLD_MS)); } + +// ------------------------------------------------------------------------------------ +// Uhr läuft lokal weiter +// +// Die Uhrzeit kommt von der Hauptplatine und ist leer, solange dort keine Zeitquelle +// synchronisiert ist. Bei einem erneuten Abgleich ist sie kurz weg - auf dem Display +// verschwand die Uhr dann fuer ein paar Sekunden, was gerade im Standby unruhig wirkt. +// +// Deshalb merkt sich der P4 die zuletzt empfangene Zeit und zaehlt zwischen den Meldungen +// selbst weiter. Er stellt nichts richtig: Sobald die Hauptplatine wieder eine Zeit +// schickt, gilt deren Wert. Die lokale Uhr ueberbrueckt nur die Luecke. +// ------------------------------------------------------------------------------------ +static bool g_clockKnown = false; // schon einmal eine Zeit empfangen? +static uint32_t g_clockMinute = 0; // zuletzt bekannte Uhrzeit in Minuten seit Mitternacht +static uint32_t g_clockTick = 0; // Zeitpunkt (lv_tick), zu dem sie galt + +// "HH:MM" der Hauptplatine uebernehmen. Andere Formate werden nicht angetastet. +static void clock_note(const String& hhmm) { + if (hhmm.length() < 5 || hhmm.charAt(2) != ':') return; + int h = hhmm.substring(0, 2).toInt(); + int m = hhmm.substring(3, 5).toInt(); + if (h < 0 || h > 23 || m < 0 || m > 59) return; + g_clockMinute = (uint32_t)(h * 60 + m); + g_clockTick = lv_tick_get(); + g_clockKnown = true; +} + +// Anzuzeigende Uhrzeit: die der Hauptplatine, solange sie eine schickt - sonst die lokal +// weitergezaehlte. Leerer Rueckgabewert heisst: noch nie eine Zeit gehabt, nichts anzeigen. +static String clock_text(const String& vonS3) { + if (vonS3.length()) return vonS3; + if (!g_clockKnown) return String(); + uint32_t min = g_clockMinute + (uint32_t)((lv_tick_get() - g_clockTick) / 60000UL); + char b[6]; + snprintf(b, sizeof(b), "%02u:%02u", (unsigned)((min / 60) % 24), (unsigned)(min % 60)); + return String(b); +} + void ui_update(const MachineState& st) { if (!g_uiReady) return; @@ -3911,10 +3949,13 @@ void ui_update(const MachineState& st) { bool wifiOk = st.wifiConnected && !st.apMode; if (g_wifiIcon) lv_obj_set_style_text_color(g_wifiIcon, wifiOk ? COL_OK : (st.apMode ? COL_WARN : COL_TEXT_MUT), 0); - // Uhrzeit (nur wenn NTP synchronisiert) + // Uhrzeit. Angezeigt wird die der Hauptplatine; faellt sie voruebergehend aus, zaehlt + // der P4 die zuletzt bekannte Zeit selbst weiter (siehe clock_text). + clock_note(st.timeStr); + String zeit = clock_text(st.timeStr); if (g_clock) { - if (st.timeStr.length()) { - lv_label_set_text(g_clock, st.timeStr.c_str()); + if (zeit.length()) { + label_set_if_changed(g_clock, zeit.c_str()); lv_obj_remove_flag(g_clock, LV_OBJ_FLAG_HIDDEN); } else { lv_obj_add_flag(g_clock, LV_OBJ_FLAG_HIDDEN); @@ -3927,7 +3968,7 @@ void ui_update(const MachineState& st) { if (g_standbyScreen) { bool shouldShow = st.standbyActive && st.standbyShowClock; if (shouldShow) { - lv_label_set_text(g_standbyClock, st.timeStr.length() ? st.timeStr.c_str() : "--:--"); + label_set_if_changed(g_standbyClock, zeit.length() ? zeit.c_str() : "--:--"); if (!g_standbyShown) { ui_fade_in(g_standbyScreen, UI_FADE_MS); // Einschlaf-Animation g_standbyShown = true;