feat(P4): Uhr läuft lokal weiter, wenn die S3 keine Zeit liefert (1.8.6)

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 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01STPpZoK3ToDhrcniVqE6MJ
This commit is contained in:
raw-designs
2026-09-03 00:33:50 +02:00
co-authored by Claude Opus 5
parent 3c333f0280
commit 01d960258a
2 changed files with 53 additions and 4 deletions
+8
View File
@@ -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: Version 1.8.5:
- Die Verzögerung von rund zwei Sekunden rund um den Standby ist behoben. Sie lag nicht an - 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 der Helligkeitsumschaltung, sondern daran, dass die Standby-Uhr bei JEDER Zustandsmeldung
+45 -4
View File
@@ -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)); 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) { void ui_update(const MachineState& st) {
if (!g_uiReady) return; if (!g_uiReady) return;
@@ -3911,10 +3949,13 @@ void ui_update(const MachineState& st) {
bool wifiOk = st.wifiConnected && !st.apMode; 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); 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 (g_clock) {
if (st.timeStr.length()) { if (zeit.length()) {
lv_label_set_text(g_clock, st.timeStr.c_str()); label_set_if_changed(g_clock, zeit.c_str());
lv_obj_remove_flag(g_clock, LV_OBJ_FLAG_HIDDEN); lv_obj_remove_flag(g_clock, LV_OBJ_FLAG_HIDDEN);
} else { } else {
lv_obj_add_flag(g_clock, LV_OBJ_FLAG_HIDDEN); lv_obj_add_flag(g_clock, LV_OBJ_FLAG_HIDDEN);
@@ -3927,7 +3968,7 @@ void ui_update(const MachineState& st) {
if (g_standbyScreen) { if (g_standbyScreen) {
bool shouldShow = st.standbyActive && st.standbyShowClock; bool shouldShow = st.standbyActive && st.standbyShowClock;
if (shouldShow) { 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) { if (!g_standbyShown) {
ui_fade_in(g_standbyScreen, UI_FADE_MS); // Einschlaf-Animation ui_fade_in(g_standbyScreen, UI_FADE_MS); // Einschlaf-Animation
g_standbyShown = true; g_standbyShown = true;