feat: Espresso/Cold-Auswahl bei jedem Aufwecken, auch per Schalter (S3 5.6.0 / P4 1.4.0)
Die Abfrage war eine reine Vorab-Abfrage des Displays und erschien nur beim Antippen des Standby-Bildschirms. Beim Aufwecken über den Schalter ist der Standby aber schon beendet, bevor das Display überhaupt fragen könnte — dieser Weg war nie abgedeckt. Die Steuerung hält jetzt nach dem Aufwecken ein Auswahlfenster offen (20 s): Der Wasserkreis heizt in dieser Zeit nicht, das Display blendet die Auswahl von sich aus ein und zeigt einen Countdown. Ohne Entscheidung wird danach normal geheizt, es geht also nichts verloren, wenn niemand hinsieht. Das Fenster öffnet nur mit angeschlossenem Display (sonst könnte niemand wählen), bei freigeschalteter Funktion und aktiver Einstellung "Abfrage beim Aufwecken", und nur wenn der Modus nicht ohnehin schon läuft. Es schließt bei Entscheidung, Bezug/Spülen oder erneutem Standby. Neue Aktion wakeEspresso (beendet Standby falls aktiv und schließt das Fenster) — das Display sendet sie statt deactivateStandby, sobald die Auswahl relevant ist, sonst würde direkt nach dem Aufwecken nochmal gefragt. Neue State-Felder cxWakeChoice und cxWakeChoiceSec. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
7d14f94a72
commit
7c1e485722
@@ -1,3 +1,14 @@
|
||||
Version 1.4.0:
|
||||
- Die Auswahl „Espresso oder Cold Extraction" erscheint jetzt auch beim Aufwecken über den Schalter
|
||||
(braucht S3-Firmware ab 5.6.0). Meldet die S3 ein offenes Auswahlfenster (cxWakeChoice), blendet das
|
||||
Display den Dialog von sich aus ein - ohne Antippen - und zeigt die verbleibende Bedenkzeit als
|
||||
Countdown. „Abbrechen" entfällt in diesem Fall, weil es nichts abzubrechen gibt: Läuft die Zeit ab,
|
||||
heizt die Maschine normal auf.
|
||||
- Der Espresso-Knopf sendet „wakeEspresso" statt „deactivateStandby", sobald die Auswahl relevant ist.
|
||||
Damit wird die Entscheidung auf der S3 vermerkt und nicht direkt danach erneut gefragt.
|
||||
- Der Cold-Extraction-Knopf beendet den Standby nur noch, wenn er überhaupt aktiv ist - im Auswahlfenster
|
||||
nach dem Aufwecken schaltet er nur den Modus.
|
||||
|
||||
Version 1.3.0:
|
||||
- Der Aufweck-Dialog wird zur Auswahl: „Womit aufwecken?" mit den Knöpfen „Espresso" (heizt normal auf)
|
||||
und „Cold Extraction (Wasser bleibt kalt)". Braucht S3-Firmware ab 5.5.0.
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
// -------------------------------------------------------------------------------------
|
||||
// Firmware
|
||||
// -------------------------------------------------------------------------------------
|
||||
#define DISPLAY_FW_VERSION "1.3.0" // Firmware-Stand der P4-Display-Steuerung (Info-Seite)
|
||||
#define DISPLAY_FW_VERSION "1.4.0" // Firmware-Stand der P4-Display-Steuerung (Info-Seite)
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
// Protokoll
|
||||
|
||||
@@ -85,6 +85,8 @@ struct MachineState {
|
||||
float cxPumpMaxRun = 0; // Pumpenschutz: max. kumulierte Laufzeit in s
|
||||
float cxPumpRest = 0; // Pumpenschutz: Zwangspause in s
|
||||
bool cxAskOnWake = false; // Beim Aufwecken aus dem Standby fragen (seit S3 5.5.0)
|
||||
bool cxWakeChoice = false; // Auswahlfenster nach dem Aufwecken offen (seit S3 5.6.0)
|
||||
long cxWakeChoiceSec = 0; // Restsekunden der Bedenkzeit
|
||||
float cxMaxSecs = 0; // Sicherheits-Timeout des Bezugs in s
|
||||
// Sperrgrund: 0=frei, 1=nicht freigeschaltet, 2=Standby, 3=Wartung, 4=Reinigungsassistent,
|
||||
// 5=PID-Tuning, 6=Sensorfehler, 7=Wasserkessel zu warm
|
||||
|
||||
@@ -237,6 +237,8 @@ void ProtocolClient::applyState(const String& json) {
|
||||
s.cxPumpMaxRun = doc["cxPumpMaxRun"] | s.cxPumpMaxRun;
|
||||
s.cxPumpRest = doc["cxPumpRest"] | s.cxPumpRest;
|
||||
s.cxAskOnWake = doc["cxAskOnWake"] | false;
|
||||
s.cxWakeChoice = doc["cxWakeChoice"] | false;
|
||||
s.cxWakeChoiceSec = doc["cxWakeChoiceSec"] | (long)0;
|
||||
s.cxMaxSecs = doc["cxMaxSecs"] | s.cxMaxSecs;
|
||||
s.cxBlock = doc["cxBlock"] | (uint8_t)0;
|
||||
s.cxNotice = doc["cxNotice"] | (uint8_t)0;
|
||||
|
||||
@@ -41,6 +41,7 @@ static lv_obj_t* g_wakeConfirm = nullptr; // Bestaetigungsdialog "Aus dem Stan
|
||||
static lv_obj_t* g_wakeColdBtn = nullptr; // "Cold Extraction" im Aufweck-Dialog
|
||||
static lv_obj_t* g_wakeMsg = nullptr; // Text des Aufweck-Dialogs (wechselt bei Abfrage-Modus)
|
||||
static lv_obj_t* g_wakeYesLbl = nullptr; // Beschriftung des Bestaetigen-Knopfs
|
||||
static lv_obj_t* g_wakeNoBtn = nullptr; // "Abbrechen" (entfaellt beim Auswahlfenster nach dem Aufwecken)
|
||||
static bool g_wakeDialogOpen = false; // Dialog sichtbar -> Display hell schalten (lesbar)
|
||||
static bool g_standbyShown = false; // Standby-Uhr-Overlay zuletzt als sichtbar geschaltet (fuer Ein-/Ausblend-Uebergang)
|
||||
|
||||
@@ -607,7 +608,12 @@ static void wake_yes_cb(lv_event_t*) { // Aufwecken -> hell lassen, S3 bee
|
||||
wake_confirm_hide();
|
||||
// g_wakeDialogOpen bleibt true, bis der Standby wirklich endet (ui_update) - sonst wuerde
|
||||
// das Display in der Uebergangsphase kurz auf Standby-Helligkeit abdunkeln.
|
||||
if (g_client) { g_client->sendAction("deactivateStandby"); showToast("Maschine wird aufgeweckt...", false); }
|
||||
if (!g_client) return;
|
||||
// "wakeEspresso" beendet den Standby UND schliesst das Auswahlfenster der S3. Ohne das
|
||||
// wuerde nach dem Aufwecken noch einmal gefragt bzw. der Wasserkreis bliebe kurz aus.
|
||||
const bool choiceRelevant = g_state.cxWakeChoice || (g_state.cxEnabled && g_state.cxAskOnWake);
|
||||
g_client->sendAction(choiceRelevant ? "wakeEspresso" : "deactivateStandby");
|
||||
showToast(g_state.standbyActive ? "Maschine wird aufgeweckt..." : "Espresso: Kessel heizt auf.", false);
|
||||
}
|
||||
// Aufwecken direkt in die kalte Extraktion. Reihenfolge ist wichtig: erst den Modus scharf
|
||||
// stellen, dann den Standby beenden - sonst heizt der Wasserkreis in der Zwischenzeit an,
|
||||
@@ -616,8 +622,8 @@ static void wake_cold_cb(lv_event_t*) {
|
||||
wake_confirm_hide();
|
||||
if (g_client) {
|
||||
g_client->sendAction("startColdExtraction");
|
||||
g_client->sendAction("deactivateStandby");
|
||||
showToast("Aufwecken mit Cold Extraction...", false);
|
||||
if (g_state.standbyActive) g_client->sendAction("deactivateStandby");
|
||||
showToast("Cold Extraction aktiviert.", false);
|
||||
}
|
||||
}
|
||||
bool ui_wake_dialog_open() { return g_wakeDialogOpen; } // fuer die Helligkeitssteuerung in onState
|
||||
@@ -3349,6 +3355,7 @@ void ui_init(ProtocolClient* client) {
|
||||
lv_obj_t* wakeNo = th_button(wakeBtns, "Abbrechen", COL_CARD2, COL_TEXT);
|
||||
lv_obj_set_width(wakeNo, 150);
|
||||
lv_obj_add_event_cb(wakeNo, wake_no_cb, LV_EVENT_CLICKED, nullptr);
|
||||
g_wakeNoBtn = wakeNo;
|
||||
lv_obj_t* wakeYes = th_accent_button(wakeBtns, "Aufwecken");
|
||||
lv_obj_set_width(wakeYes, 150);
|
||||
lv_obj_add_event_cb(wakeYes, wake_yes_cb, LV_EVENT_CLICKED, nullptr);
|
||||
@@ -3555,7 +3562,9 @@ void ui_update(const MachineState& st) {
|
||||
}
|
||||
// Aufweck-Ablauf: nach beendetem Standby Dialog schliessen und Helligkeits-Flag loeschen
|
||||
// (auch wenn der Dialog schon ausgeblendet ist, weil "Aufwecken" das Flag bewusst haelt).
|
||||
if (!st.standbyActive) {
|
||||
// Bei offenem Auswahlfenster (cxWakeChoice) bleibt der Dialog stehen, obwohl der Standby
|
||||
// schon beendet ist - genau dafuer ist er da.
|
||||
if (!st.standbyActive && !st.cxWakeChoice) {
|
||||
g_wakeDialogOpen = false;
|
||||
if (g_wakeConfirm && !lv_obj_has_flag(g_wakeConfirm, LV_OBJ_FLAG_HIDDEN))
|
||||
lv_obj_add_flag(g_wakeConfirm, LV_OBJ_FLAG_HIDDEN);
|
||||
@@ -3591,19 +3600,45 @@ void ui_update(const MachineState& st) {
|
||||
// Abschaltbar ueber die Einstellung cxAskOnWake, damit man sich den Zwischenschritt
|
||||
// sparen kann, wenn gerade keine kalten Bezuege anstehen.
|
||||
{
|
||||
const bool askMode = st.cxEnabled && st.cxArmable && !st.cxActive && st.cxAskOnWake;
|
||||
// Zwei Faelle: Vorab-Abfrage beim Antippen im Standby (askMode) und das von der S3
|
||||
// geoeffnete Auswahlfenster NACH dem Aufwecken (choiceOpen) - letzteres deckt auch
|
||||
// das Aufwecken per Schalter ab, wo es keine Vorab-Abfrage geben kann.
|
||||
const bool choiceOpen = st.cxWakeChoice;
|
||||
const bool askMode = choiceOpen ||
|
||||
(st.cxEnabled && st.cxArmable && !st.cxActive && st.cxAskOnWake);
|
||||
if (g_wakeColdBtn) {
|
||||
if (askMode) lv_obj_remove_flag(g_wakeColdBtn, LV_OBJ_FLAG_HIDDEN);
|
||||
else lv_obj_add_flag(g_wakeColdBtn, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
// Im Auswahlfenster gibt es nichts abzubrechen - laeuft die Zeit ab, wird geheizt.
|
||||
if (g_wakeNoBtn) {
|
||||
if (choiceOpen) lv_obj_add_flag(g_wakeNoBtn, LV_OBJ_FLAG_HIDDEN);
|
||||
else lv_obj_remove_flag(g_wakeNoBtn, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
if (g_wakeMsg) {
|
||||
label_set_if_changed(g_wakeMsg, askMode
|
||||
? "Die Maschine befindet sich im Standby.\nWomit aufwecken?"
|
||||
: "Die Maschine befindet sich im Standby.\nAus dem Standby aufwecken?");
|
||||
if (choiceOpen) {
|
||||
char b[128];
|
||||
snprintf(b, sizeof(b),
|
||||
"Womit weiter?\nEspresso heizt auf, Cold Extraction bleibt kalt.\n"
|
||||
"Ohne Auswahl wird in %ld s geheizt.", st.cxWakeChoiceSec);
|
||||
label_set_if_changed(g_wakeMsg, b);
|
||||
} else {
|
||||
label_set_if_changed(g_wakeMsg, askMode
|
||||
? "Die Maschine befindet sich im Standby.\nWomit aufwecken?"
|
||||
: "Die Maschine befindet sich im Standby.\nAus dem Standby aufwecken?");
|
||||
}
|
||||
}
|
||||
if (g_wakeYesLbl) {
|
||||
label_set_if_changed(g_wakeYesLbl, askMode ? "Espresso" : "Aufwecken");
|
||||
}
|
||||
// Auswahlfenster von der S3 -> Dialog von sich aus zeigen (kein Antippen noetig)
|
||||
if (choiceOpen && g_wakeConfirm && lv_obj_has_flag(g_wakeConfirm, LV_OBJ_FLAG_HIDDEN)) {
|
||||
wake_confirm_show();
|
||||
} else if (!choiceOpen && !st.standbyActive && g_wakeConfirm &&
|
||||
!lv_obj_has_flag(g_wakeConfirm, LV_OBJ_FLAG_HIDDEN)) {
|
||||
wake_confirm_hide(); // Fenster abgelaufen oder entschieden
|
||||
g_wakeDialogOpen = false;
|
||||
}
|
||||
}
|
||||
if (st.cxNotice == 2) {
|
||||
status_set(ST_COLDEX, true, LV_SYMBOL_WARNING " Cold Extraction beendet: kein Zulauf",
|
||||
|
||||
Reference in New Issue
Block a user