Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
743c38e994 | ||
|
|
535f640bbd | ||
|
|
f8d51a57b7 | ||
|
|
8432bd3f15 | ||
|
|
49bdc686c4 | ||
|
|
8dcebaa22f |
@@ -1,3 +1,43 @@
|
|||||||
|
Version 5.6.3:
|
||||||
|
- Bug-Fix: Beim Aufwecken über das Touch-Display blieb die Auswahl „Espresso oder Cold Extraction"
|
||||||
|
manchmal aus, während sie über den Schalter kam. Ursache waren zwei unterschiedliche Bedingungen für
|
||||||
|
ein und dieselbe Sache: Das Display prüfte zum ANZEIGEN der Auswahl zusätzlich, ob der Modus gerade
|
||||||
|
scharfschaltbar ist (cxArmable) - zum UNTERDRÜCKEN der Rückfrage der S3 („wakeEspresso") aber nicht.
|
||||||
|
Fiel diese Bedingung weg, zeigte der Dialog nur noch „Aufwecken", schloss aber trotzdem das
|
||||||
|
Auswahlfenster der S3: Die Frage war auf beiden Seiten weg. Der Schalterweg hatte diese Lücke nie,
|
||||||
|
weil er allein an der S3 hängt. Behoben in der Display-Firmware 1.4.2.
|
||||||
|
- Diagnose: /Cold-Extraction zeigt jetzt zusätzlich zum Live-Stand der Voraussetzungen auch das
|
||||||
|
LETZTE Aufwecken - über welchen Weg (Schalter/Timer/Web oder Display, dort mit getroffener Wahl)
|
||||||
|
und mit welchem Ergebnis (Fenster geöffnet, am Display bereits entschieden, Abfrage aus, kein
|
||||||
|
Display verbunden, Wartung/Reinigung/Tuning aktiv, nicht freigeschaltet). Hintergrund: Die
|
||||||
|
Live-Liste zeigt nur den jetzigen Stand - blieb die Frage aus, hatte sich die Lage bis zum
|
||||||
|
Nachsehen längst wieder geändert, und der Grund war nicht mehr zu ermitteln.
|
||||||
|
- Die Entscheidung über das Auswahlfenster ist als Bedingungskette geschrieben, damit jeder Zweig
|
||||||
|
seinen Grund hinterlässt (vorher eine einzige verknüpfte Bedingung ohne Rückmeldung).
|
||||||
|
|
||||||
|
Version 5.6.2:
|
||||||
|
- Bug-Fix: Die Abfrage beim Aufwecken erschien nicht, sobald der Cold-Extraction-Modus noch aktiv war -
|
||||||
|
und da er persistent ist, war er das nach dem ersten kalten Bezug dauerhaft. Die Bedingung „Modus ist
|
||||||
|
aus" war falsch gedacht („sonst gibt es nichts zu fragen"): Die Auswahl muss in BEIDE Richtungen gehen,
|
||||||
|
also auch von kalt zurück auf Espresso. Ohne das hing man nach dem ersten kalten Bezug im kalten Modus
|
||||||
|
fest, ohne beim Aufwecken je wieder gefragt zu werden.
|
||||||
|
- „Espresso" beendet jetzt einen laufenden Cold-Extraction-Modus, statt ihn nur nicht einzuschalten.
|
||||||
|
Sonst wäre die Auswahl eine Einbahnstraße gewesen.
|
||||||
|
- Das Auswahlfenster bleibt bei aktivem Modus offen (bisher wurde es sofort geschlossen); die Frage
|
||||||
|
lautet dann „weiter kalt oder zurück auf Espresso?".
|
||||||
|
- Die Diagnose auf /Cold-Extraction listet den Modus nicht mehr als Voraussetzung, sondern zeigt ihn
|
||||||
|
als Ist-Zustand an.
|
||||||
|
|
||||||
|
Version 5.6.1:
|
||||||
|
- Diagnose: Die Seite /Cold-Extraction zeigt jetzt live, welche Voraussetzungen der Abfrage beim
|
||||||
|
Aufwecken erfüllt sind (freigeschaltet, Abfrage eingeschaltet, Touch-Display verbunden, Modus
|
||||||
|
gerade aus, kein Wartungsmodus/Reinigung/Tuning) und ob das Auswahlfenster gerade offen ist.
|
||||||
|
Hintergrund: Die Abfrage hängt an fünf Bedingungen gleichzeitig - fehlt eine, passiert einfach
|
||||||
|
nichts, und es war von außen nicht erkennbar welche.
|
||||||
|
- Die Abfrage kommt jetzt auch nach einem Kaltstart, nicht nur nach dem Standby. Wer die Maschine
|
||||||
|
am Netzschalter einschaltet, durchläuft nie einen Standby-Übergang; dieser Weg war deshalb bisher
|
||||||
|
nicht abgedeckt. Startet die Maschine in den Standby hinein, bleibt es beim Standby-Übergang.
|
||||||
|
|
||||||
Version 5.6.0:
|
Version 5.6.0:
|
||||||
- Die Abfrage „Espresso oder Cold Extraction" kommt jetzt bei JEDEM Weg aus dem Standby, also auch beim
|
- Die Abfrage „Espresso oder Cold Extraction" kommt jetzt bei JEDEM Weg aus dem Standby, also auch beim
|
||||||
Aufwecken über den Schalter. Bisher war sie eine reine Vorab-Abfrage des Touch-Displays und erschien nur
|
Aufwecken über den Schalter. Bisher war sie eine reine Vorab-Abfrage des Touch-Displays und erschien nur
|
||||||
|
|||||||
+148
-6
@@ -369,7 +369,7 @@ Adafruit_SH1106G display = Adafruit_SH1106G(128, 64, &Wire);
|
|||||||
* Firmware-Informationen
|
* Firmware-Informationen
|
||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
|
||||||
String version = "5.6.0";
|
String version = "5.6.3";
|
||||||
String versionHersteller = "Thomas Müller";
|
String versionHersteller = "Thomas Müller";
|
||||||
String versionHerstellerMail =
|
String versionHerstellerMail =
|
||||||
"<a href='mailto:thomas@mueller.black' class='info-link'>thomas@mueller.black</a>";
|
"<a href='mailto:thomas@mueller.black' class='info-link'>thomas@mueller.black</a>";
|
||||||
@@ -804,6 +804,28 @@ unsigned long coldExtractionWakeDecisionMs = 0; // Zeitpunkt der letzten ex
|
|||||||
const unsigned long COLDEX_WAKE_CHOICE_MS = 20000UL; // Bedenkzeit
|
const unsigned long COLDEX_WAKE_CHOICE_MS = 20000UL; // Bedenkzeit
|
||||||
const unsigned long COLDEX_WAKE_DECISION_GRACE_MS = 5000UL; // frisch entschieden -> kein Fenster
|
const unsigned long COLDEX_WAKE_DECISION_GRACE_MS = 5000UL; // frisch entschieden -> kein Fenster
|
||||||
|
|
||||||
|
// Diagnose des letzten Aufweckens: Bleibt die Abfrage aus, ist von aussen nicht erkennbar,
|
||||||
|
// welche der Voraussetzungen gefehlt hat - die Live-Anzeige auf /Cold-Extraction zeigt nur
|
||||||
|
// den JETZIGEN Stand, und der kann sich bis zum Nachsehen laengst wieder geaendert haben.
|
||||||
|
// Deshalb wird das Ergebnis beim Aufwecken festgehalten. Reine Anzeige, keine Logik.
|
||||||
|
#define COLDEX_WAKE_SRC_UNKNOWN 0 // Schalter, Timer, Web - alles ohne Display-Beteiligung
|
||||||
|
#define COLDEX_WAKE_SRC_TOUCH 1 // Display: "Aufwecken" (ohne Auswahl im Dialog)
|
||||||
|
#define COLDEX_WAKE_SRC_ESPRESSO 2 // Display: "Espresso" gewaehlt
|
||||||
|
#define COLDEX_WAKE_SRC_COLD 3 // Display: "Cold Extraction" gewaehlt
|
||||||
|
#define COLDEX_WAKE_RES_NONE 0 // seit dem Start noch nicht aufgeweckt
|
||||||
|
#define COLDEX_WAKE_RES_OPENED 1 // Auswahlfenster geoeffnet
|
||||||
|
#define COLDEX_WAKE_RES_DECIDED 2 // am Display bereits entschieden -> keine zweite Frage
|
||||||
|
#define COLDEX_WAKE_RES_ASK_OFF 3 // Abfrage in den Einstellungen ausgeschaltet
|
||||||
|
#define COLDEX_WAKE_RES_NO_DISP 4 // kein Touch-Display verbunden
|
||||||
|
#define COLDEX_WAKE_RES_NOT_ARM 5 // Wartung / Reinigung / PID-Tuning aktiv
|
||||||
|
#define COLDEX_WAKE_RES_DISABLED 6 // Funktion nicht freigeschaltet
|
||||||
|
uint8_t coldExtractionWakeSource = COLDEX_WAKE_SRC_UNKNOWN; // Quelle des laufenden Aufweckens
|
||||||
|
unsigned long coldExtractionWakeSourceMs = 0; // ... wann gemeldet (verfaellt)
|
||||||
|
const unsigned long COLDEX_WAKE_SRC_VALID_MS = 3000UL; // danach gilt sie als veraltet
|
||||||
|
uint8_t coldExtractionLastWakeSource = COLDEX_WAKE_SRC_UNKNOWN; // ... des letzten, fuer die Anzeige
|
||||||
|
uint8_t coldExtractionLastWakeResult = COLDEX_WAKE_RES_NONE;
|
||||||
|
unsigned long coldExtractionLastWakeMs = 0;
|
||||||
|
|
||||||
const bool defaultColdExtractionEnabled = false;
|
const bool defaultColdExtractionEnabled = false;
|
||||||
const float defaultColdExtractionMaxTempC = 30.0f;
|
const float defaultColdExtractionMaxTempC = 30.0f;
|
||||||
const float defaultColdExtractionPreInfusionSeconds = 10.0f;
|
const float defaultColdExtractionPreInfusionSeconds = 10.0f;
|
||||||
@@ -5448,17 +5470,62 @@ void loop() {
|
|||||||
// Auswahlfenster oeffnen: gilt fuer JEDEN Weg aus dem Standby (Schalter, Touch, Web,
|
// Auswahlfenster oeffnen: gilt fuer JEDEN Weg aus dem Standby (Schalter, Touch, Web,
|
||||||
// Timer). Nur sinnvoll mit angeschlossenem Display - ohne das koennte niemand waehlen,
|
// Timer). Nur sinnvoll mit angeschlossenem Display - ohne das koennte niemand waehlen,
|
||||||
// und die Maschine wuerde nur unnoetig spaeter heizen.
|
// und die Maschine wuerde nur unnoetig spaeter heizen.
|
||||||
if (coldExtractionEnabled && coldExtractionAskOnWake && touchUartClientActive &&
|
// Bewusst OHNE Pruefung auf coldExtractionModeActive: Der Modus ist persistent, und
|
||||||
!coldExtractionModeActive && coldExtractionArmable() &&
|
// die Abfrage muss in BEIDE Richtungen gehen - auch von "kalt" zurueck auf Espresso.
|
||||||
(coldExtractionWakeDecisionMs == 0 ||
|
// Sonst bliebe man nach dem ersten kalten Bezug dauerhaft im kalten Modus haengen,
|
||||||
(currentMillis - coldExtractionWakeDecisionMs) > COLDEX_WAKE_DECISION_GRACE_MS)) {
|
// ohne beim Aufwecken je wieder gefragt zu werden.
|
||||||
|
// Als Kette geschrieben, damit jeder Zweig seinen Grund hinterlaesst (Anzeige auf
|
||||||
|
// /Cold-Extraction). Ohne das bleibt ein ausgebliebenes Fenster nicht nachvollziehbar.
|
||||||
|
// Eine gemeldete Quelle gilt nur kurz: Wird der Modus im Standby ueber die
|
||||||
|
// Einstellseite scharfgestellt, ohne dass ein Aufwecken folgt, darf sie nicht
|
||||||
|
// spaeter am naechsten Aufwecken kleben.
|
||||||
|
coldExtractionLastWakeSource =
|
||||||
|
(coldExtractionWakeSourceMs != 0 &&
|
||||||
|
(currentMillis - coldExtractionWakeSourceMs) <= COLDEX_WAKE_SRC_VALID_MS)
|
||||||
|
? coldExtractionWakeSource : COLDEX_WAKE_SRC_UNKNOWN;
|
||||||
|
coldExtractionWakeSource = COLDEX_WAKE_SRC_UNKNOWN;
|
||||||
|
coldExtractionWakeSourceMs = 0;
|
||||||
|
coldExtractionLastWakeMs = currentMillis;
|
||||||
|
if (!coldExtractionEnabled) {
|
||||||
|
coldExtractionLastWakeResult = COLDEX_WAKE_RES_DISABLED;
|
||||||
|
} else if (!coldExtractionAskOnWake) {
|
||||||
|
coldExtractionLastWakeResult = COLDEX_WAKE_RES_ASK_OFF;
|
||||||
|
} else if (!touchUartClientActive) {
|
||||||
|
coldExtractionLastWakeResult = COLDEX_WAKE_RES_NO_DISP;
|
||||||
|
} else if (!coldExtractionArmable()) {
|
||||||
|
coldExtractionLastWakeResult = COLDEX_WAKE_RES_NOT_ARM;
|
||||||
|
} else if (coldExtractionWakeDecisionMs != 0 &&
|
||||||
|
(currentMillis - coldExtractionWakeDecisionMs) <= COLDEX_WAKE_DECISION_GRACE_MS) {
|
||||||
|
// Am Display wurde gerade gewaehlt - eine zweite Frage waere nur laestig.
|
||||||
|
coldExtractionLastWakeResult = COLDEX_WAKE_RES_DECIDED;
|
||||||
|
} else {
|
||||||
coldExtractionWakeChoicePending = true;
|
coldExtractionWakeChoicePending = true;
|
||||||
coldExtractionWakeChoiceUntilMs = currentMillis + COLDEX_WAKE_CHOICE_MS;
|
coldExtractionWakeChoiceUntilMs = currentMillis + COLDEX_WAKE_CHOICE_MS;
|
||||||
|
coldExtractionLastWakeResult = COLDEX_WAKE_RES_OPENED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Gleiche Auswahl nach einem Kaltstart: Wer die Maschine am Netzschalter einschaltet,
|
||||||
|
// kommt nie durch den Standby-Uebergang - ohne diesen Zweig gaebe es dort keine Abfrage.
|
||||||
|
// Einmal pro Laufzeit, sobald sich das Display gemeldet hat.
|
||||||
|
static bool coldExtractionBootChoiceDone = false;
|
||||||
|
if (!coldExtractionBootChoiceDone && !standbyModeActive && touchUartClientActive &&
|
||||||
|
coldExtractionEnabled && coldExtractionAskOnWake && coldExtractionArmable()) {
|
||||||
|
coldExtractionBootChoiceDone = true;
|
||||||
|
coldExtractionWakeChoicePending = true;
|
||||||
|
coldExtractionWakeChoiceUntilMs = currentMillis + COLDEX_WAKE_CHOICE_MS;
|
||||||
|
coldExtractionLastWakeSource = COLDEX_WAKE_SRC_UNKNOWN;
|
||||||
|
coldExtractionLastWakeResult = COLDEX_WAKE_RES_OPENED;
|
||||||
|
coldExtractionLastWakeMs = currentMillis;
|
||||||
|
} else if (!coldExtractionBootChoiceDone && touchUartClientActive && standbyModeActive) {
|
||||||
|
// Start in den Standby hinein: Der Standby-Uebergang uebernimmt die Abfrage.
|
||||||
|
coldExtractionBootChoiceDone = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Auswahlfenster beenden: Zeit abgelaufen, Standby, oder es wird ohnehin schon bezogen
|
// Auswahlfenster beenden: Zeit abgelaufen, Standby, oder es wird ohnehin schon bezogen
|
||||||
if (coldExtractionWakeChoicePending) {
|
if (coldExtractionWakeChoicePending) {
|
||||||
if (standbyModeActive || coldExtractionModeActive || shotActive || shotSoftwareActive ||
|
// coldExtractionModeActive ist hier KEIN Abbruchgrund: Bei aktivem Modus ist die
|
||||||
|
// Frage "weiter kalt oder zurueck auf Espresso?" - das Fenster muss offen bleiben.
|
||||||
|
if (standbyModeActive || shotActive || shotSoftwareActive ||
|
||||||
flushActive || !coldExtractionEnabled ||
|
flushActive || !coldExtractionEnabled ||
|
||||||
(long)(currentMillis - coldExtractionWakeChoiceUntilMs) >= 0) {
|
(long)(currentMillis - coldExtractionWakeChoiceUntilMs) >= 0) {
|
||||||
coldExtractionWakeChoicePending = false;
|
coldExtractionWakeChoicePending = false;
|
||||||
@@ -7339,6 +7406,7 @@ static const char brewControlCX_Fields[] PROGMEM = R"rawliteral(
|
|||||||
<small class="toggle-description-input">(Beim Aufwecken aus dem Standby fragt das Touch-Display, ob normal geheizt oder kalt
|
<small class="toggle-description-input">(Beim Aufwecken aus dem Standby fragt das Touch-Display, ob normal geheizt oder kalt
|
||||||
extrahiert werden soll - so entscheidet man das bei jedem Aufwecken neu, ohne vorher die Web-UI zu bedienen.
|
extrahiert werden soll - so entscheidet man das bei jedem Aufwecken neu, ohne vorher die Web-UI zu bedienen.
|
||||||
Ohne angeschlossenes Touch-Display oder bei nicht freigeschalteter Funktion hat die Einstellung keine Wirkung.)</small>
|
Ohne angeschlossenes Touch-Display oder bei nicht freigeschalteter Funktion hat die Einstellung keine Wirkung.)</small>
|
||||||
|
{CX_ASK_DIAG}
|
||||||
|
|
||||||
<h3>Vorbenetzung</h3>
|
<h3>Vorbenetzung</h3>
|
||||||
<label for='cxPreInf'>Dauer (Sekunden):</label>
|
<label for='cxPreInf'>Dauer (Sekunden):</label>
|
||||||
@@ -7827,6 +7895,56 @@ void handleColdExtraction(AsyncWebServerRequest *request) {
|
|||||||
snprintf(buffer, sizeof(buffer), "%.1f", coldExtractionPumpRestSec);
|
snprintf(buffer, sizeof(buffer), "%.1f", coldExtractionPumpRestSec);
|
||||||
cxFieldsHtml.replace("{CX_PUMP_REST}", buffer);
|
cxFieldsHtml.replace("{CX_PUMP_REST}", buffer);
|
||||||
cxFieldsHtml.replace("{CX_ASK_CHECKED}", coldExtractionAskOnWake ? " checked" : "");
|
cxFieldsHtml.replace("{CX_ASK_CHECKED}", coldExtractionAskOnWake ? " checked" : "");
|
||||||
|
// Live-Status der Bedingungen: Die Abfrage haengt an mehreren Voraussetzungen gleichzeitig.
|
||||||
|
// Fehlt eine, passiert schlicht nichts - ohne diese Anzeige ist nicht erkennbar, welche.
|
||||||
|
{
|
||||||
|
String diag = "<br><small><b>Voraussetzungen der Abfrage:</b><br>";
|
||||||
|
auto flag = [](bool ok, const String& text) {
|
||||||
|
return String("<span style='color:") + (ok ? "#66CC66" : "#FFCC00") + ";'>" +
|
||||||
|
(ok ? "✔ " : "✘ ") + text + "</span><br>";
|
||||||
|
};
|
||||||
|
diag += flag(coldExtractionEnabled, "Funktion freigeschaltet");
|
||||||
|
diag += flag(coldExtractionAskOnWake, "Abfrage beim Aufwecken eingeschaltet");
|
||||||
|
diag += flag(touchUartClientActive, "Touch-Display verbunden");
|
||||||
|
diag += flag(coldExtractionArmable(), "Kein Wartungsmodus / Reinigung / PID-Tuning");
|
||||||
|
diag += "<span style='color:#b0b0b0;'>Aktueller Modus: ";
|
||||||
|
diag += coldExtractionModeActive ? "Cold Extraction aktiv" : "normal (Espresso)";
|
||||||
|
diag += " - die Abfrage geht in beide Richtungen.</span><br>";
|
||||||
|
if (coldExtractionWakeChoicePending) {
|
||||||
|
long remainMs = (long)(coldExtractionWakeChoiceUntilMs - millis());
|
||||||
|
long remainSec = (remainMs > 0) ? ((remainMs + 999) / 1000) : 0;
|
||||||
|
diag += "<b style='color:#66CC66;'>Auswahlfenster ist gerade offen (noch " + String(remainSec) + " s).</b><br>";
|
||||||
|
}
|
||||||
|
// Letztes Aufwecken: Die Liste darueber zeigt nur den jetzigen Stand. Blieb die Frage
|
||||||
|
// aus, ist der Grund von damals hier festgehalten - sonst muesste man ihn raten.
|
||||||
|
if (coldExtractionLastWakeResult != COLDEX_WAKE_RES_NONE) {
|
||||||
|
String src;
|
||||||
|
switch (coldExtractionLastWakeSource) {
|
||||||
|
case COLDEX_WAKE_SRC_TOUCH: src = "Display (Aufwecken)"; break;
|
||||||
|
case COLDEX_WAKE_SRC_ESPRESSO: src = "Display (Espresso gewählt)"; break;
|
||||||
|
case COLDEX_WAKE_SRC_COLD: src = "Display (Cold Extraction gewählt)"; break;
|
||||||
|
default: src = "Schalter / Timer / Web"; break;
|
||||||
|
}
|
||||||
|
String res;
|
||||||
|
bool resOk = false;
|
||||||
|
switch (coldExtractionLastWakeResult) {
|
||||||
|
case COLDEX_WAKE_RES_OPENED: res = "Auswahlfenster geöffnet"; resOk = true; break;
|
||||||
|
case COLDEX_WAKE_RES_DECIDED: res = "am Display bereits entschieden"; resOk = true; break;
|
||||||
|
case COLDEX_WAKE_RES_ASK_OFF: res = "Abfrage ist ausgeschaltet"; break;
|
||||||
|
case COLDEX_WAKE_RES_NO_DISP: res = "kein Touch-Display verbunden"; break;
|
||||||
|
case COLDEX_WAKE_RES_NOT_ARM: res = "Wartung / Reinigung / PID-Tuning aktiv"; break;
|
||||||
|
case COLDEX_WAKE_RES_DISABLED: res = "Funktion nicht freigeschaltet"; break;
|
||||||
|
default: res = "unbekannt"; break;
|
||||||
|
}
|
||||||
|
unsigned long agoSec = (millis() - coldExtractionLastWakeMs) / 1000UL;
|
||||||
|
diag += "<span style='color:#b0b0b0;'>Letztes Aufwecken vor " + String(agoSec) + " s über " + src +
|
||||||
|
": <span style='color:";
|
||||||
|
diag += resOk ? "#66CC66" : "#FFCC00";
|
||||||
|
diag += ";'>" + res + "</span>.</span><br>";
|
||||||
|
}
|
||||||
|
diag += "</small>";
|
||||||
|
cxFieldsHtml.replace("{CX_ASK_DIAG}", diag);
|
||||||
|
}
|
||||||
|
|
||||||
if (coldExtractionEnabled) {
|
if (coldExtractionEnabled) {
|
||||||
String cxStatus;
|
String cxStatus;
|
||||||
@@ -15691,6 +15809,13 @@ bool executeDashboardAction(const String& action, const String& value,
|
|||||||
else if (action == "wakeEspresso") {
|
else if (action == "wakeEspresso") {
|
||||||
coldExtractionWakeDecisionMs = millis();
|
coldExtractionWakeDecisionMs = millis();
|
||||||
coldExtractionWakeChoicePending = false;
|
coldExtractionWakeChoicePending = false;
|
||||||
|
// "Espresso" heisst auch: einen noch laufenden Cold-Extraction-Modus beenden.
|
||||||
|
// Ohne das waere die Auswahl eine Einbahnstrasse - der Modus ist persistent und
|
||||||
|
// liesse sich beim Aufwecken nie wieder abwaehlen.
|
||||||
|
if (coldExtractionModeActive && !shotActive && !shotSoftwareActive) {
|
||||||
|
String cxMsg;
|
||||||
|
setColdExtractionMode(false, cxMsg);
|
||||||
|
}
|
||||||
if (standbyModeActive) {
|
if (standbyModeActive) {
|
||||||
standbyModeActive = false;
|
standbyModeActive = false;
|
||||||
startupTime = millis();
|
startupTime = millis();
|
||||||
@@ -17391,6 +17516,23 @@ static bool touchUartHandleCommandLine(const String& line) {
|
|||||||
String message = "";
|
String message = "";
|
||||||
bool settingsChanged = false;
|
bool settingsChanged = false;
|
||||||
bool pidNeedsUpdate = false;
|
bool pidNeedsUpdate = false;
|
||||||
|
// Herkunft des Aufweckens fuer die Diagnose festhalten - nur hier ist bekannt, dass
|
||||||
|
// die Aktion vom Touch-Display kommt und nicht aus der Web-UI. "Cold Extraction"
|
||||||
|
// schickt erst den Modus und dann das Aufwecken, deshalb darf das nachfolgende
|
||||||
|
// deactivateStandby die schon gesetzte Quelle nicht ueberschreiben.
|
||||||
|
if (standbyModeActive) {
|
||||||
|
if (action == "wakeEspresso") {
|
||||||
|
coldExtractionWakeSource = COLDEX_WAKE_SRC_ESPRESSO;
|
||||||
|
coldExtractionWakeSourceMs = millis();
|
||||||
|
} else if (action == "startColdExtraction") {
|
||||||
|
coldExtractionWakeSource = COLDEX_WAKE_SRC_COLD;
|
||||||
|
coldExtractionWakeSourceMs = millis();
|
||||||
|
} else if (action == "deactivateStandby" &&
|
||||||
|
coldExtractionWakeSource == COLDEX_WAKE_SRC_UNKNOWN) {
|
||||||
|
coldExtractionWakeSource = COLDEX_WAKE_SRC_TOUCH;
|
||||||
|
coldExtractionWakeSourceMs = millis();
|
||||||
|
}
|
||||||
|
}
|
||||||
executeDashboardAction(action, value, success, message, settingsChanged, pidNeedsUpdate);
|
executeDashboardAction(action, value, success, message, settingsChanged, pidNeedsUpdate);
|
||||||
touchUartSendAck(id, success, message);
|
touchUartSendAck(id, success, message);
|
||||||
touchUartSendState();
|
touchUartSendState();
|
||||||
|
|||||||
@@ -1,3 +1,20 @@
|
|||||||
|
Version 1.4.2:
|
||||||
|
- Bug-Fix: Beim Aufwecken über Antippen erschien die Auswahl „Espresso oder Cold Extraction"
|
||||||
|
manchmal nicht. Der Dialog entschied nach einer anderen Bedingung, ob er die Auswahl ANZEIGT
|
||||||
|
(verlangte zusätzlich cxArmable), als er beim Absenden benutzte, um die Rückfrage der S3 zu
|
||||||
|
UNTERDRÜCKEN. In der Lücke dazwischen zeigte er nur „Aufwecken", sendete aber „wakeEspresso" -
|
||||||
|
und damit war die Frage auch auf der S3 erledigt. Beide Stellen benutzen jetzt dieselbe Funktion
|
||||||
|
wake_choice_offered().
|
||||||
|
- Hat der Dialog die Auswahl nicht angeboten, sendet er wieder „deactivateStandby". Dann öffnet die
|
||||||
|
S3 ihr eigenes Auswahlfenster, und die Frage kommt trotzdem - derselbe Weg wie beim Aufwecken über
|
||||||
|
den Schalter. Die Auswahl kann damit nicht mehr ersatzlos entfallen.
|
||||||
|
|
||||||
|
Version 1.4.1:
|
||||||
|
- Passend zu S3 5.6.2: Die Auswahl beim Aufwecken erscheint auch dann, wenn der Cold-Extraction-Modus
|
||||||
|
bereits aktiv ist - sie geht in beide Richtungen. „Espresso" schaltet den Modus dann ab.
|
||||||
|
- Der Cold-Extraction-Knopf zeigt den Ist-Zustand: Bei aktivem Modus ist er hervorgehoben und heißt
|
||||||
|
„Cold Extraction (aktiv lassen)", sonst „Cold Extraction (Wasser bleibt kalt)".
|
||||||
|
|
||||||
Version 1.4.0:
|
Version 1.4.0:
|
||||||
- Die Auswahl „Espresso oder Cold Extraction" erscheint jetzt auch beim Aufwecken über den Schalter
|
- 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
|
(braucht S3-Firmware ab 5.6.0). Meldet die S3 ein offenes Auswahlfenster (cxWakeChoice), blendet das
|
||||||
|
|||||||
@@ -65,7 +65,7 @@
|
|||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
// Firmware
|
// Firmware
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
#define DISPLAY_FW_VERSION "1.4.0" // Firmware-Stand der P4-Display-Steuerung (Info-Seite)
|
#define DISPLAY_FW_VERSION "1.4.2" // Firmware-Stand der P4-Display-Steuerung (Info-Seite)
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
// Protokoll
|
// Protokoll
|
||||||
|
|||||||
@@ -598,6 +598,16 @@ static void wake_confirm_show() {
|
|||||||
lv_obj_move_foreground(g_wakeConfirm);
|
lv_obj_move_foreground(g_wakeConfirm);
|
||||||
}
|
}
|
||||||
static void wake_confirm_hide() { if (g_wakeConfirm) lv_obj_add_flag(g_wakeConfirm, LV_OBJ_FLAG_HIDDEN); }
|
static void wake_confirm_hide() { if (g_wakeConfirm) lv_obj_add_flag(g_wakeConfirm, LV_OBJ_FLAG_HIDDEN); }
|
||||||
|
// Einzige Quelle der Wahrheit dafuer, ob der Aufweck-Dialog die Auswahl "Espresso oder Cold
|
||||||
|
// Extraction" wirklich anbietet. Wird an ZWEI Stellen gebraucht: beim Aufbau des Dialogs und
|
||||||
|
// beim Absenden. Standen dort verschiedene Bedingungen, konnte der Dialog nur "Aufwecken"
|
||||||
|
// zeigen, aber trotzdem "wakeEspresso" senden - und damit das Auswahlfenster der S3
|
||||||
|
// schliessen. Dann war die Frage auf beiden Seiten weg (der Schalterweg hat diese Luecke
|
||||||
|
// nicht, weil er allein am S3 haengt).
|
||||||
|
static bool wake_choice_offered() {
|
||||||
|
return g_state.cxWakeChoice ||
|
||||||
|
(g_state.cxEnabled && g_state.cxArmable && g_state.cxAskOnWake);
|
||||||
|
}
|
||||||
static void standby_screen_cb(lv_event_t*) { wake_confirm_show(); } // Tipp auf Standby-Uhr -> nachfragen
|
static void standby_screen_cb(lv_event_t*) { wake_confirm_show(); } // Tipp auf Standby-Uhr -> nachfragen
|
||||||
static void wake_no_cb(lv_event_t*) { // Abbrechen -> zurueck in die Standby-Helligkeit
|
static void wake_no_cb(lv_event_t*) { // Abbrechen -> zurueck in die Standby-Helligkeit
|
||||||
wake_confirm_hide();
|
wake_confirm_hide();
|
||||||
@@ -609,10 +619,11 @@ static void wake_yes_cb(lv_event_t*) { // Aufwecken -> hell lassen, S3 bee
|
|||||||
// g_wakeDialogOpen bleibt true, bis der Standby wirklich endet (ui_update) - sonst wuerde
|
// g_wakeDialogOpen bleibt true, bis der Standby wirklich endet (ui_update) - sonst wuerde
|
||||||
// das Display in der Uebergangsphase kurz auf Standby-Helligkeit abdunkeln.
|
// das Display in der Uebergangsphase kurz auf Standby-Helligkeit abdunkeln.
|
||||||
if (!g_client) return;
|
if (!g_client) return;
|
||||||
// "wakeEspresso" beendet den Standby UND schliesst das Auswahlfenster der S3. Ohne das
|
// "wakeEspresso" beendet den Standby UND schliesst das Auswahlfenster der S3 - das ist
|
||||||
// wuerde nach dem Aufwecken noch einmal gefragt bzw. der Wasserkreis bliebe kurz aus.
|
// nur dann richtig, wenn dieser Dialog die Auswahl gerade wirklich angeboten hat. Sonst
|
||||||
const bool choiceRelevant = g_state.cxWakeChoice || (g_state.cxEnabled && g_state.cxAskOnWake);
|
// "deactivateStandby": dann oeffnet die S3 ihr eigenes Auswahlfenster, und die Frage
|
||||||
g_client->sendAction(choiceRelevant ? "wakeEspresso" : "deactivateStandby");
|
// kommt trotzdem (gleicher Weg wie beim Aufwecken ueber den Schalter).
|
||||||
|
g_client->sendAction(wake_choice_offered() ? "wakeEspresso" : "deactivateStandby");
|
||||||
showToast(g_state.standbyActive ? "Maschine wird aufgeweckt..." : "Espresso: Kessel heizt auf.", false);
|
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
|
// Aufwecken direkt in die kalte Extraktion. Reihenfolge ist wichtig: erst den Modus scharf
|
||||||
@@ -3603,9 +3614,10 @@ void ui_update(const MachineState& st) {
|
|||||||
// Zwei Faelle: Vorab-Abfrage beim Antippen im Standby (askMode) und das von der S3
|
// Zwei Faelle: Vorab-Abfrage beim Antippen im Standby (askMode) und das von der S3
|
||||||
// geoeffnete Auswahlfenster NACH dem Aufwecken (choiceOpen) - letzteres deckt auch
|
// geoeffnete Auswahlfenster NACH dem Aufwecken (choiceOpen) - letzteres deckt auch
|
||||||
// das Aufwecken per Schalter ab, wo es keine Vorab-Abfrage geben kann.
|
// das Aufwecken per Schalter ab, wo es keine Vorab-Abfrage geben kann.
|
||||||
|
// Kein "!st.cxActive": Der Modus ist persistent, die Auswahl muss in beide
|
||||||
|
// Richtungen gehen - sonst haengt man nach dem ersten kalten Bezug dauerhaft fest.
|
||||||
const bool choiceOpen = st.cxWakeChoice;
|
const bool choiceOpen = st.cxWakeChoice;
|
||||||
const bool askMode = choiceOpen ||
|
const bool askMode = wake_choice_offered(); // g_state == st (oben zugewiesen)
|
||||||
(st.cxEnabled && st.cxArmable && !st.cxActive && st.cxAskOnWake);
|
|
||||||
if (g_wakeColdBtn) {
|
if (g_wakeColdBtn) {
|
||||||
if (askMode) lv_obj_remove_flag(g_wakeColdBtn, LV_OBJ_FLAG_HIDDEN);
|
if (askMode) lv_obj_remove_flag(g_wakeColdBtn, LV_OBJ_FLAG_HIDDEN);
|
||||||
else lv_obj_add_flag(g_wakeColdBtn, LV_OBJ_FLAG_HIDDEN);
|
else lv_obj_add_flag(g_wakeColdBtn, LV_OBJ_FLAG_HIDDEN);
|
||||||
@@ -3631,6 +3643,17 @@ void ui_update(const MachineState& st) {
|
|||||||
if (g_wakeYesLbl) {
|
if (g_wakeYesLbl) {
|
||||||
label_set_if_changed(g_wakeYesLbl, askMode ? "Espresso" : "Aufwecken");
|
label_set_if_changed(g_wakeYesLbl, askMode ? "Espresso" : "Aufwecken");
|
||||||
}
|
}
|
||||||
|
// Aktive Wahl hervorheben: Bei laufendem Modus ist "Cold Extraction" der Ist-Zustand,
|
||||||
|
// "Espresso" schaltet ihn ab - andersherum genauso.
|
||||||
|
if (g_wakeColdBtn && askMode) {
|
||||||
|
lv_obj_set_style_bg_color(g_wakeColdBtn, st.cxActive ? COL_ACCENT : COL_CARD2, 0);
|
||||||
|
lv_obj_t* coldLbl = lv_obj_get_child(g_wakeColdBtn, 0);
|
||||||
|
if (coldLbl) {
|
||||||
|
lv_obj_set_style_text_color(coldLbl, st.cxActive ? lv_color_hex(0x000000) : COL_ACCENT, 0);
|
||||||
|
label_set_if_changed(coldLbl, st.cxActive ? "Cold Extraction (aktiv lassen)"
|
||||||
|
: "Cold Extraction (Wasser bleibt kalt)");
|
||||||
|
}
|
||||||
|
}
|
||||||
// Auswahlfenster von der S3 -> Dialog von sich aus zeigen (kein Antippen noetig)
|
// 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)) {
|
if (choiceOpen && g_wakeConfirm && lv_obj_has_flag(g_wakeConfirm, LV_OBJ_FLAG_HIDDEN)) {
|
||||||
wake_confirm_show();
|
wake_confirm_show();
|
||||||
|
|||||||
Reference in New Issue
Block a user