fix: Zielgewicht bei Cold Extraction ueberall korrekt anzeigen (S3 5.4.1 / P4 1.2.1) #20
@@ -1,3 +1,13 @@
|
|||||||
|
Version 5.4.1:
|
||||||
|
- Bug-Fix: Während einer kalten Extraktion stand als Zielgewicht überall noch der Brew-by-Weight-Wert
|
||||||
|
des normalen Espresso-Bezugs. Betroffen waren OLED, Web-Dashboard und Touch-Display, weil alle drei
|
||||||
|
direkt brewByWeightTargetGrams anzeigten - die kalte Extraktion ersetzt Brew-by-Weight aber und stoppt
|
||||||
|
nach coldExtractionTargetGrams. Neue Hilfsfunktion activeTargetWeightGrams() liefert jetzt das Ziel
|
||||||
|
des aktuellen bzw. nächsten Bezugs; das UART-Feld "targetWeight" führt diesen Wert (bbwTarget bleibt
|
||||||
|
unverändert die Roh-Einstellung).
|
||||||
|
- Auf dem OLED wird während eines kalten Bezugs jetzt überhaupt Gewicht angezeigt: Die Anzeige hing an
|
||||||
|
„Brew-by-Weight aktiv", das bei kalter Extraktion typischerweise aus ist - trotz vorhandenem Ziel.
|
||||||
|
|
||||||
Version 5.4.0:
|
Version 5.4.0:
|
||||||
- Cold Extraction hat eine eigene Seite: /Cold-Extraction, eigener Eintrag im Menü. Auf /Brew-Control
|
- Cold Extraction hat eine eigene Seite: /Cold-Extraction, eigener Eintrag im Menü. Auf /Brew-Control
|
||||||
steht nur noch ein Verweis darauf - die Seite war mit dem angehängten Block unübersichtlich geworden.
|
steht nur noch ein Verweis darauf - die Seite war mit dem angehängten Block unübersichtlich geworden.
|
||||||
|
|||||||
+15
-5
@@ -369,7 +369,7 @@ Adafruit_SH1106G display = Adafruit_SH1106G(128, 64, &Wire);
|
|||||||
* Firmware-Informationen
|
* Firmware-Informationen
|
||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
|
||||||
String version = "5.4.0";
|
String version = "5.4.1";
|
||||||
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>";
|
||||||
@@ -4060,6 +4060,14 @@ bool coldExtractionTemperatureOk() {
|
|||||||
return (InputWasser < (double)limit);
|
return (InputWasser < (double)limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Zielgewicht des aktuellen bzw. naechsten Bezugs. Bei aktiver Cold Extraction ist das
|
||||||
|
// coldExtractionTargetGrams - brewByWeightTargetGrams gilt dann nicht, weil die kalte
|
||||||
|
// Extraktion Brew-by-Weight ersetzt. Alle Anzeigen (OLED, Web, Display) muessen diesen
|
||||||
|
// Wert nehmen, sonst steht dort das Espresso-Ziel waehrend eines kalten Bezugs.
|
||||||
|
float activeTargetWeightGrams() {
|
||||||
|
return coldExtractionModeActive ? coldExtractionTargetGrams : brewByWeightTargetGrams;
|
||||||
|
}
|
||||||
|
|
||||||
// Steht eine nutzbare Waage bereit? Ohne sie laeuft die kalte Extraktion rein zeitgesteuert:
|
// Steht eine nutzbare Waage bereit? Ohne sie laeuft die kalte Extraktion rein zeitgesteuert:
|
||||||
// Zielgewicht und Stillstands-Erkennung greifen nicht, es bleibt nur die maximale Bezugsdauer.
|
// Zielgewicht und Stillstands-Erkennung greifen nicht, es bleibt nur die maximale Bezugsdauer.
|
||||||
// Bewusst kein Sperrgrund - ein kurz abgemeldeter HX711 soll die Funktion nicht blockieren.
|
// Bewusst kein Sperrgrund - ein kurz abgemeldeter HX711 soll die Funktion nicht blockieren.
|
||||||
@@ -6566,7 +6574,9 @@ if (scaleModeActive) {
|
|||||||
// Wenn die Zustandsmaschine nicht aktiv ist, zeige den laufenden Shot oder die Temperaturen
|
// Wenn die Zustandsmaschine nicht aktiv ist, zeige den laufenden Shot oder die Temperaturen
|
||||||
else if (shotActive) {
|
else if (shotActive) {
|
||||||
// Priorität: Shot läuft *aktuell*?
|
// Priorität: Shot läuft *aktuell*?
|
||||||
if (brewByWeightEnabled && scaleConnected) {
|
// Auch ein kalter Bezug hat ein Gewichtsziel - unabhaengig von Brew-by-Weight,
|
||||||
|
// das die Cold Extraction ersetzt.
|
||||||
|
if ((brewByWeightEnabled || coldExtractionShotActive) && scaleConnected) {
|
||||||
display.setTextSize(1);
|
display.setTextSize(1);
|
||||||
display.setCursor(0, 0);
|
display.setCursor(0, 0);
|
||||||
display.println(F("Bezug aktiv:"));
|
display.println(F("Bezug aktiv:"));
|
||||||
@@ -6583,7 +6593,7 @@ if (scaleModeActive) {
|
|||||||
netWeight = 0.0;
|
netWeight = 0.0;
|
||||||
}
|
}
|
||||||
char weightBuffer[15];
|
char weightBuffer[15];
|
||||||
snprintf(weightBuffer, sizeof(weightBuffer), "%.1f/%.1fg", netWeight, brewByWeightTargetGrams);
|
snprintf(weightBuffer, sizeof(weightBuffer), "%.1f/%.1fg", netWeight, activeTargetWeightGrams());
|
||||||
// --- ENDE ÄNDERUNG ---
|
// --- ENDE ÄNDERUNG ---
|
||||||
|
|
||||||
display.setCursor(0, 30);
|
display.setCursor(0, 30);
|
||||||
@@ -16325,7 +16335,7 @@ void buildDashboardJson(char *buffer, size_t bufferSize) {
|
|||||||
|
|
||||||
// Plattformdaten
|
// Plattformdaten
|
||||||
dtostrf(getWeightReadingForUi(), 4, 1, floatBuf); offset += snprintf(buffer + offset, bufferSize - offset, "\"weight\":%s,", floatBuf);
|
dtostrf(getWeightReadingForUi(), 4, 1, floatBuf); offset += snprintf(buffer + offset, bufferSize - offset, "\"weight\":%s,", floatBuf);
|
||||||
dtostrf(brewByWeightTargetGrams, 4, 1, floatBuf); offset += snprintf(buffer + offset, bufferSize - offset, "\"targetWeight\":%s,", floatBuf);
|
dtostrf(activeTargetWeightGrams(), 4, 1, floatBuf); offset += snprintf(buffer + offset, bufferSize - offset, "\"targetWeight\":%s,", floatBuf); // bei Cold Extraction das kalte Ziel
|
||||||
offset += snprintf(buffer + offset, bufferSize - offset, "\"scaleEnabled\":%s,", scaleEnabled ? "true" : "false");
|
offset += snprintf(buffer + offset, bufferSize - offset, "\"scaleEnabled\":%s,", scaleEnabled ? "true" : "false");
|
||||||
offset += snprintf(buffer + offset, bufferSize - offset, "\"scaleType\":%u,", (unsigned int)scaleType);
|
offset += snprintf(buffer + offset, bufferSize - offset, "\"scaleType\":%u,", (unsigned int)scaleType);
|
||||||
offset += snprintf(buffer + offset, bufferSize - offset, "\"scaleConnected\":%s,", scaleConnected ? "true" : "false");
|
offset += snprintf(buffer + offset, bufferSize - offset, "\"scaleConnected\":%s,", scaleConnected ? "true" : "false");
|
||||||
@@ -16610,7 +16620,7 @@ static void buildTouchUartStateJson(char *buffer, size_t bufferSize) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dtostrf(getWeightReadingForUi(), 4, 1, floatBuf); offset += snprintf(buffer + offset, bufferSize - offset, "\"weight\":%s,", floatBuf);
|
dtostrf(getWeightReadingForUi(), 4, 1, floatBuf); offset += snprintf(buffer + offset, bufferSize - offset, "\"weight\":%s,", floatBuf);
|
||||||
dtostrf(brewByWeightTargetGrams, 4, 1, floatBuf); offset += snprintf(buffer + offset, bufferSize - offset, "\"targetWeight\":%s,", floatBuf);
|
dtostrf(activeTargetWeightGrams(), 4, 1, floatBuf); offset += snprintf(buffer + offset, bufferSize - offset, "\"targetWeight\":%s,", floatBuf); // bei Cold Extraction das kalte Ziel
|
||||||
// Endgewicht des letzten Bezugs inkl. Offset (identisch zur OLED: Netto beim Stopp + Offset).
|
// Endgewicht des letzten Bezugs inkl. Offset (identisch zur OLED: Netto beim Stopp + Offset).
|
||||||
// Nur bei gewichtsbasiertem Bezug aussagekraeftig -> lastShotByWeight signalisiert das dem P4.
|
// Nur bei gewichtsbasiertem Bezug aussagekraeftig -> lastShotByWeight signalisiert das dem P4.
|
||||||
dtostrf(lastShotFinalNetWeight + brewByWeightOffsetGrams, 4, 1, floatBuf); offset += snprintf(buffer + offset, bufferSize - offset, "\"lastShotWeight\":%s,", floatBuf);
|
dtostrf(lastShotFinalNetWeight + brewByWeightOffsetGrams, 4, 1, floatBuf); offset += snprintf(buffer + offset, bufferSize - offset, "\"lastShotWeight\":%s,", floatBuf);
|
||||||
|
|||||||
@@ -1,3 +1,10 @@
|
|||||||
|
Version 1.2.1:
|
||||||
|
- Bug-Fix: Während einer kalten Extraktion zeigten Waage-Kachel und Live-Bezugsschirm das Zielgewicht
|
||||||
|
des normalen Espresso-Bezugs (bbwTarget) statt des Ziels der kalten Extraktion (cxTarget). Außerdem
|
||||||
|
erschienen Gewichtsanzeige und Fortschrittsbalken nur, wenn Brew-by-Weight aktiv war - bei kalter
|
||||||
|
Extraktion ist das typischerweise aus, obwohl ein Ziel existiert. Beide Anzeigen nutzen jetzt
|
||||||
|
cxTarget, sobald cxShot gesetzt ist.
|
||||||
|
|
||||||
Version 1.2.0:
|
Version 1.2.0:
|
||||||
- Neue Seite „Cold Extraction" mit eigenem Menüeintrag (braucht S3-Firmware ab 5.4.0). Dort stehen jetzt
|
- Neue Seite „Cold Extraction" mit eigenem Menüeintrag (braucht S3-Firmware ab 5.4.0). Dort stehen jetzt
|
||||||
alle Parameter der kalten Extraktion und lassen sich direkt am Display ändern: Freigabetemperatur,
|
alle Parameter der kalten Extraktion und lassen sich direkt am Display ändern: Freigabetemperatur,
|
||||||
|
|||||||
@@ -65,7 +65,7 @@
|
|||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
// Firmware
|
// Firmware
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
#define DISPLAY_FW_VERSION "1.2.0" // Firmware-Stand der P4-Display-Steuerung (Info-Seite)
|
#define DISPLAY_FW_VERSION "1.2.1" // Firmware-Stand der P4-Display-Steuerung (Info-Seite)
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
// Protokoll
|
// Protokoll
|
||||||
|
|||||||
@@ -1858,12 +1858,16 @@ static void brew_live_tick() {
|
|||||||
}
|
}
|
||||||
// Zielfortschritt: Brew-by-Weight (Gewicht) vor Brew-by-Time (Zeit), sonst versteckt
|
// Zielfortschritt: Brew-by-Weight (Gewicht) vor Brew-by-Time (Zeit), sonst versteckt
|
||||||
if (g_bzBarRow && g_bzBar && g_bzBarLbl) {
|
if (g_bzBarRow && g_bzBar && g_bzBarLbl) {
|
||||||
bool bbw = scale && g_state.bbwEnabled && g_state.bbwTarget > 0.0f;
|
// Ein kalter Bezug hat sein eigenes Ziel (cxTarget) und ersetzt Brew-by-Weight -
|
||||||
|
// sonst stuende hier das Espresso-Ziel.
|
||||||
|
const bool cxShotNow = g_state.cxShot && g_state.cxTarget > 0.0f;
|
||||||
|
const float wTarget = cxShotNow ? g_state.cxTarget : g_state.bbwTarget;
|
||||||
|
bool bbw = scale && (cxShotNow || (g_state.bbwEnabled && g_state.bbwTarget > 0.0f));
|
||||||
if (bbw || (g_shotBbtMode && g_bbtTarget > 0.0f)) {
|
if (bbw || (g_shotBbtMode && g_bbtTarget > 0.0f)) {
|
||||||
int pct;
|
int pct;
|
||||||
if (bbw) {
|
if (bbw) {
|
||||||
pct = (int)(w / g_state.bbwTarget * 100.0f + 0.5f);
|
pct = (int)(w / wTarget * 100.0f + 0.5f);
|
||||||
snprintf(b, sizeof(b), "%.1f g / %.1f g", w, g_state.bbwTarget);
|
snprintf(b, sizeof(b), "%.1f g / %.1f g", w, wTarget);
|
||||||
} else {
|
} else {
|
||||||
pct = (int)(el / g_bbtTarget * 100.0f + 0.5f);
|
pct = (int)(el / g_bbtTarget * 100.0f + 0.5f);
|
||||||
snprintf(b, sizeof(b), "%.1f s / %.1f s", el, g_bbtTarget);
|
snprintf(b, sizeof(b), "%.1f s / %.1f s", el, g_bbtTarget);
|
||||||
@@ -3915,7 +3919,10 @@ void ui_update(const MachineState& st) {
|
|||||||
else lv_obj_add_flag(cellBezug, LV_OBJ_FLAG_HIDDEN);
|
else lv_obj_add_flag(cellBezug, LV_OBJ_FLAG_HIDDEN);
|
||||||
}
|
}
|
||||||
if (lblBezug) {
|
if (lblBezug) {
|
||||||
bool bbwShot = st.shotActive && st.bbwEnabled && st.bbwTarget > 0.0f;
|
// Bei kaltem Bezug zaehlt cxTarget, nicht das Brew-by-Weight-Ziel
|
||||||
|
const bool cxShotNow = st.cxShot && st.cxTarget > 0.0f;
|
||||||
|
const float shotTarget = cxShotNow ? st.cxTarget : st.bbwTarget;
|
||||||
|
bool bbwShot = st.shotActive && (cxShotNow || (st.bbwEnabled && st.bbwTarget > 0.0f));
|
||||||
// Winzige negative Messwerte (z.B. -0.04 g) oder negatives Float-Null wuerden von
|
// Winzige negative Messwerte (z.B. -0.04 g) oder negatives Float-Null wuerden von
|
||||||
// "%.1f" als "-0.0" dargestellt -> auf 0.0 normalisieren (kein fuehrendes Minus).
|
// "%.1f" als "-0.0" dargestellt -> auf 0.0 normalisieren (kein fuehrendes Minus).
|
||||||
float wDisp = st.weight;
|
float wDisp = st.weight;
|
||||||
@@ -3924,14 +3931,14 @@ void ui_update(const MachineState& st) {
|
|||||||
lv_label_set_text(lblBezug, "--");
|
lv_label_set_text(lblBezug, "--");
|
||||||
} else if (bbwShot) {
|
} else if (bbwShot) {
|
||||||
// Waehrend des Bezugs mit Brew-by-Weight: Ist oben, Ziel darunter (zweizeilig)
|
// Waehrend des Bezugs mit Brew-by-Weight: Ist oben, Ziel darunter (zweizeilig)
|
||||||
lv_label_set_text_fmt(lblBezug, "%.1f g\n/ %.1f g", wDisp, st.bbwTarget);
|
lv_label_set_text_fmt(lblBezug, "%.1f g\n/ %.1f g", wDisp, shotTarget);
|
||||||
} else {
|
} else {
|
||||||
lv_label_set_text_fmt(lblBezug, "%.1f g", wDisp);
|
lv_label_set_text_fmt(lblBezug, "%.1f g", wDisp);
|
||||||
}
|
}
|
||||||
// Fortschrittsbalken Gewicht/Ziel (nur waehrend BBW-Bezug)
|
// Fortschrittsbalken Gewicht/Ziel (nur waehrend BBW-Bezug)
|
||||||
if (g_bbwBar) {
|
if (g_bbwBar) {
|
||||||
if (bbwShot) {
|
if (bbwShot) {
|
||||||
int pct = (int)(st.weight / st.bbwTarget * 100.0f + 0.5f);
|
int pct = (int)(st.weight / shotTarget * 100.0f + 0.5f);
|
||||||
if (pct < 0) pct = 0; if (pct > 100) pct = 100;
|
if (pct < 0) pct = 0; if (pct > 100) pct = 100;
|
||||||
lv_bar_set_value(g_bbwBar, pct, LV_ANIM_OFF);
|
lv_bar_set_value(g_bbwBar, pct, LV_ANIM_OFF);
|
||||||
lv_obj_remove_flag(g_bbwBar, LV_OBJ_FLAG_HIDDEN);
|
lv_obj_remove_flag(g_bbwBar, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
|||||||
Reference in New Issue
Block a user