Bezugs-Anzeige inkl. Shot-Zusammenfassung ergänzt/erweitert
Bezugs-Anzeige inkl. Shot-Zusammenfassung ergänzt/erweitert
This commit is contained in:
@@ -1,4 +1,14 @@
|
|||||||
Version 1.0.10:
|
Version 1.0.10:
|
||||||
|
- Live-Bezugsschirm (abschaltbar): Beim Start eines echten Bezugs blendet sich ein Vollbild-Overlay
|
||||||
|
weich ein — große Bezugszeit, Live-Gewicht und Flow samt Flow-Verlaufskurve der letzten 30 Sekunden
|
||||||
|
(nur bei verbundener Waage), Fortschrittsbalken Richtung Zielgewicht (Brew-by-Weight) bzw. Zielzeit
|
||||||
|
(Brew-by-Time) und Pre-Infusion-Phasenhinweis mit Restzeit. Über das X oben rechts für den laufenden
|
||||||
|
Bezug schließbar; beim nächsten Bezug erscheint er wieder. Ein/Aus-Schalter auf der Info-Seite unter
|
||||||
|
„Darstellung", die Einstellung wird P4-lokal im NVS gespeichert und überlebt Neustarts. Während
|
||||||
|
Flush und Reinigungsassistent erscheint das Overlay bewusst nicht.
|
||||||
|
- Shot-Zusammenfassung aufgewertet: Die Karte nach Bezugsende blendet jetzt weich ein/aus (Fade),
|
||||||
|
wirft einen Schlagschatten und zeigt Dauer, Endgewicht und mittleren Flow als große Werte mit
|
||||||
|
gedimmter Beschriftung statt reiner Textzeilen (Gewicht/Flow nur bei aktiver Waage).
|
||||||
- Pre-Infusion-Phasenanzeige auf dem Dashboard: Während eines Bezugs mit aktiver Pre-Infusion zeigt
|
- Pre-Infusion-Phasenanzeige auf dem Dashboard: Während eines Bezugs mit aktiver Pre-Infusion zeigt
|
||||||
eine Schrittleiste die Phasen „Pre-Infusion → Pause → Extraktion" an — erledigte Schritte mit Haken,
|
eine Schrittleiste die Phasen „Pre-Infusion → Pause → Extraktion" an — erledigte Schritte mit Haken,
|
||||||
die aktive Phase hervorgehoben (Gold) inkl. Restzeit-Countdown (100-ms-Takt). Die aktive Phase kommt
|
die aktive Phase hervorgehoben (Gold) inkl. Restzeit-Countdown (100-ms-Takt). Die aktive Phase kommt
|
||||||
|
|||||||
+356
-23
@@ -119,10 +119,27 @@ static lv_obj_t* g_legW = nullptr; static lv_obj_t* g_legD = nullptr; static lv_
|
|||||||
static lv_obj_t* g_axHi = nullptr; static lv_obj_t* g_axMid = nullptr; static lv_obj_t* g_axLo = nullptr; // Y-Skala
|
static lv_obj_t* g_axHi = nullptr; static lv_obj_t* g_axMid = nullptr; static lv_obj_t* g_axLo = nullptr; // Y-Skala
|
||||||
#define COL_CASE lv_color_hex(0xba68c8) // Farbe Zusatzsensor im Chart (Violett; klar distinkt von Wasser-Gold/Dampf-Teal)
|
#define COL_CASE lv_color_hex(0xba68c8) // Farbe Zusatzsensor im Chart (Violett; klar distinkt von Wasser-Gold/Dampf-Teal)
|
||||||
|
|
||||||
// Shot-Zusammenfassung (Popup nach Bezug)
|
// Shot-Zusammenfassung (Karte nach Bezug; blendet weich ein/aus)
|
||||||
static lv_obj_t* g_shotSum = nullptr; static lv_obj_t* g_shotSumBody = nullptr;
|
static lv_obj_t* g_shotSum = nullptr;
|
||||||
|
static lv_obj_t* g_sumCol[3] = {}; // Spalten Dauer/Gewicht/Flow (Gewicht+Flow nur mit Waage)
|
||||||
|
static lv_obj_t* g_sumVal[3] = {};
|
||||||
static lv_timer_t* g_shotSumTimer = nullptr;
|
static lv_timer_t* g_shotSumTimer = nullptr;
|
||||||
static bool g_sumShotWas = false;
|
static bool g_sumShotWas = false;
|
||||||
|
// Live-Bezugsschirm (Vollbild-Overlay waehrend eines Bezugs; abschaltbar, NVS "brewlive")
|
||||||
|
static bool g_brewLiveEnabled = true;
|
||||||
|
static lv_obj_t* g_brewScreen = nullptr;
|
||||||
|
static lv_obj_t* g_bzTimer = nullptr; static lv_obj_t* g_bzWeight = nullptr;
|
||||||
|
static lv_obj_t* g_bzFlow = nullptr; static lv_obj_t* g_bzPhase = nullptr;
|
||||||
|
static lv_obj_t* g_bzWeightBlock = nullptr; static lv_obj_t* g_bzFlowBlock = nullptr;
|
||||||
|
static lv_obj_t* g_bzChartWrap = nullptr; // Chart samt Beschriftung (ohne Waage versteckt)
|
||||||
|
static lv_obj_t* g_bzChart = nullptr; static lv_chart_series_t* g_bzSer = nullptr;
|
||||||
|
static lv_obj_t* g_bzBarRow = nullptr; // Fortschritt Richtung Ziel (BBW/BBT), sonst versteckt
|
||||||
|
static lv_obj_t* g_bzBar = nullptr; static lv_obj_t* g_bzBarLbl = nullptr;
|
||||||
|
static float g_bzFlowMax = 0.0f; // Auto-Skalierung der Flow-Achse
|
||||||
|
static bool g_brewLiveShown = false; // Overlay ist fuer den laufenden Bezug sichtbar
|
||||||
|
static bool g_brewLiveClosed = false; // Nutzer hat das Overlay fuer diesen Bezug weggetippt
|
||||||
|
static uint8_t g_bzTick = 0; // Chart nur alle 200 ms fuettern (Timer laeuft mit 100 ms)
|
||||||
|
static lv_obj_t* swBrewLive = nullptr; // Ein/Aus-Schalter auf der Info-Seite
|
||||||
// Kombi-Zelle Eco/Gehaeuse (wechselt sich ab, wenn beide aktiv)
|
// Kombi-Zelle Eco/Gehaeuse (wechselt sich ab, wenn beide aktiv)
|
||||||
static lv_obj_t* cellEco; static lv_obj_t* lblEco; static lv_obj_t* lblEcoTitle;
|
static lv_obj_t* cellEco; static lv_obj_t* lblEco; static lv_obj_t* lblEcoTitle;
|
||||||
static bool g_ecoCasePhase = false; // false = Eco, true = Gehaeuse (bei Wechselanzeige)
|
static bool g_ecoCasePhase = false; // false = Eco, true = Gehaeuse (bei Wechselanzeige)
|
||||||
@@ -1356,32 +1373,315 @@ static void chart_sample_cb(lv_timer_t*) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// =====================================================================================
|
// =====================================================================================
|
||||||
// Shot-Zusammenfassung (Popup, blendet nach 8 s aus oder per Tipp)
|
// Shot-Zusammenfassung (Karte, blendet weich ein; nach 8 s oder per Tipp weich aus)
|
||||||
// =====================================================================================
|
// =====================================================================================
|
||||||
static void shot_sum_hide_cb(lv_timer_t*) {
|
static void shot_sum_hide_cb(lv_timer_t*) {
|
||||||
if (g_shotSum) lv_obj_add_flag(g_shotSum, LV_OBJ_FLAG_HIDDEN);
|
if (g_shotSum) ui_fade_out_hide(g_shotSum, UI_FADE_MS);
|
||||||
g_shotSumTimer = nullptr;
|
g_shotSumTimer = nullptr;
|
||||||
}
|
}
|
||||||
static void shot_sum_tap_cb(lv_event_t*) {
|
static void shot_sum_tap_cb(lv_event_t*) {
|
||||||
if (g_shotSum) lv_obj_add_flag(g_shotSum, LV_OBJ_FLAG_HIDDEN);
|
if (g_shotSum) ui_fade_out_hide(g_shotSum, UI_FADE_MS);
|
||||||
if (g_shotSumTimer) { lv_timer_del(g_shotSumTimer); g_shotSumTimer = nullptr; }
|
if (g_shotSumTimer) { lv_timer_del(g_shotSumTimer); g_shotSumTimer = nullptr; }
|
||||||
}
|
}
|
||||||
|
// Eine Wert-Spalte der Zusammenfassung (grosser Wert, gedimmte Beschriftung darunter)
|
||||||
|
static lv_obj_t* sum_stat_col(lv_obj_t* parent, const char* caption, lv_obj_t** valOut) {
|
||||||
|
lv_obj_t* col = lv_obj_create(parent);
|
||||||
|
lv_obj_set_size(col, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
|
||||||
|
lv_obj_set_style_bg_opa(col, LV_OPA_TRANSP, 0);
|
||||||
|
lv_obj_set_style_border_width(col, 0, 0);
|
||||||
|
lv_obj_set_style_pad_all(col, 0, 0);
|
||||||
|
lv_obj_set_style_pad_row(col, 2, 0);
|
||||||
|
lv_obj_set_flex_flow(col, LV_FLEX_FLOW_COLUMN);
|
||||||
|
lv_obj_set_flex_align(col, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
||||||
|
lv_obj_set_flex_grow(col, 1);
|
||||||
|
lv_obj_clear_flag(col, LV_OBJ_FLAG_SCROLLABLE);
|
||||||
|
lv_obj_clear_flag(col, LV_OBJ_FLAG_CLICKABLE); // Tipp faellt auf die Karte durch (schliessen)
|
||||||
|
lv_obj_t* v = lv_label_create(col);
|
||||||
|
lv_label_set_text(v, "--");
|
||||||
|
lv_obj_set_style_text_color(v, COL_TEXT, 0);
|
||||||
|
lv_obj_set_style_text_font(v, &lv_font_maven_pro_40, 0);
|
||||||
|
lv_obj_clear_flag(v, LV_OBJ_FLAG_CLICKABLE);
|
||||||
|
lv_obj_t* c = lv_label_create(col);
|
||||||
|
lv_label_set_text(c, caption);
|
||||||
|
lv_obj_set_style_text_color(c, COL_TEXT_DIM, 0);
|
||||||
|
lv_obj_set_style_text_font(c, &lv_font_maven_pro_14, 0);
|
||||||
|
lv_obj_clear_flag(c, LV_OBJ_FLAG_CLICKABLE);
|
||||||
|
if (valOut) *valOut = v;
|
||||||
|
return col;
|
||||||
|
}
|
||||||
static void show_shot_summary(uint32_t durMs, float weight, bool haveScale) {
|
static void show_shot_summary(uint32_t durMs, float weight, bool haveScale) {
|
||||||
if (!g_shotSum) return;
|
if (!g_shotSum) return;
|
||||||
float durS = durMs / 1000.0f;
|
float durS = durMs / 1000.0f;
|
||||||
String t = "Zeit: " + String(durS, 1) + " s";
|
char b[24];
|
||||||
|
snprintf(b, sizeof(b), "%.1f s", durS);
|
||||||
|
if (g_sumVal[0]) lv_label_set_text(g_sumVal[0], b);
|
||||||
if (haveScale) {
|
if (haveScale) {
|
||||||
t += "\nGewicht: " + String(weight, 1) + " g";
|
snprintf(b, sizeof(b), "%.1f g", weight);
|
||||||
|
if (g_sumVal[1]) lv_label_set_text(g_sumVal[1], b);
|
||||||
float avg = (durS > 0.1f) ? weight / durS : 0.0f;
|
float avg = (durS > 0.1f) ? weight / durS : 0.0f;
|
||||||
t += "\nMittl. Flow: " + String(avg, 1) + " g/s";
|
snprintf(b, sizeof(b), "%.1f g/s", avg);
|
||||||
|
if (g_sumVal[2]) lv_label_set_text(g_sumVal[2], b);
|
||||||
|
}
|
||||||
|
for (int i = 1; i < 3; i++) { // Gewicht/Flow nur mit Waage
|
||||||
|
if (!g_sumCol[i]) continue;
|
||||||
|
if (haveScale) lv_obj_remove_flag(g_sumCol[i], LV_OBJ_FLAG_HIDDEN);
|
||||||
|
else lv_obj_add_flag(g_sumCol[i], LV_OBJ_FLAG_HIDDEN);
|
||||||
}
|
}
|
||||||
lv_label_set_text(g_shotSumBody, t.c_str());
|
|
||||||
lv_obj_remove_flag(g_shotSum, LV_OBJ_FLAG_HIDDEN);
|
|
||||||
lv_obj_move_foreground(g_shotSum);
|
lv_obj_move_foreground(g_shotSum);
|
||||||
|
ui_fade_in(g_shotSum, UI_FADE_MS);
|
||||||
if (g_shotSumTimer) lv_timer_reset(g_shotSumTimer);
|
if (g_shotSumTimer) lv_timer_reset(g_shotSumTimer);
|
||||||
else { g_shotSumTimer = lv_timer_create(shot_sum_hide_cb, 8000, nullptr); lv_timer_set_repeat_count(g_shotSumTimer, 1); }
|
else { g_shotSumTimer = lv_timer_create(shot_sum_hide_cb, 8000, nullptr); lv_timer_set_repeat_count(g_shotSumTimer, 1); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =====================================================================================
|
||||||
|
// Live-Bezugsschirm (Vollbild-Overlay waehrend eines Bezugs)
|
||||||
|
// =====================================================================================
|
||||||
|
// Blendet sich beim Start eines echten Bezugs (kein Flush, kein Reinigungsassistent)
|
||||||
|
// weich ein: grosse Bezugszeit, Live-Gewicht + Flow samt Verlaufskurve (nur mit Waage),
|
||||||
|
// Fortschritt Richtung Zielgewicht (BBW) bzw. Zielzeit (BBT) und Pre-Infusion-Phase.
|
||||||
|
// Ueber das X fuer den laufenden Bezug schliessbar; Ein/Aus auf der Info-Seite (NVS).
|
||||||
|
// -------------------------------------------------------------------------------------
|
||||||
|
// Aktive Pre-Infusion-Phase (1..3): bevorzugt die echte S3-Statemachine (piState),
|
||||||
|
// sonst zeitbasiert aus den gelatchten Phasendauern (aeltere S3-Firmware).
|
||||||
|
static int pi_phase_now(uint32_t el) {
|
||||||
|
if (g_piStateS3 >= 1 && g_piStateS3 <= 3) return (int)g_piStateS3;
|
||||||
|
return (el < g_piDurMs) ? 1 : ((el < g_piDurMs + g_piPauseMs) ? 2 : 3);
|
||||||
|
}
|
||||||
|
static void brew_live_hide() {
|
||||||
|
if (!g_brewLiveShown) return;
|
||||||
|
g_brewLiveShown = false;
|
||||||
|
if (g_brewScreen) ui_fade_out_hide(g_brewScreen, UI_FADE_MS);
|
||||||
|
}
|
||||||
|
static void brew_live_close_cb(lv_event_t*) {
|
||||||
|
g_brewLiveClosed = true; // nur fuer den laufenden Bezug; naechster Bezug oeffnet wieder
|
||||||
|
brew_live_hide();
|
||||||
|
}
|
||||||
|
static void brew_live_show() {
|
||||||
|
if (!g_brewScreen || g_brewLiveShown) return;
|
||||||
|
bool scale = g_state.scaleEnabled && g_state.scaleConnected;
|
||||||
|
// Ohne Waage keine Gewicht-/Flow-Bloecke und keine Kurve - der Timer traegt den Schirm
|
||||||
|
if (g_bzWeightBlock) { if (scale) lv_obj_remove_flag(g_bzWeightBlock, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
else lv_obj_add_flag(g_bzWeightBlock, LV_OBJ_FLAG_HIDDEN); }
|
||||||
|
if (g_bzFlowBlock) { if (scale) lv_obj_remove_flag(g_bzFlowBlock, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
else lv_obj_add_flag(g_bzFlowBlock, LV_OBJ_FLAG_HIDDEN); }
|
||||||
|
if (g_bzChartWrap) { if (scale) lv_obj_remove_flag(g_bzChartWrap, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
else lv_obj_add_flag(g_bzChartWrap, LV_OBJ_FLAG_HIDDEN); }
|
||||||
|
if (g_bzChart && g_bzSer) {
|
||||||
|
lv_chart_set_all_value(g_bzChart, g_bzSer, LV_CHART_POINT_NONE);
|
||||||
|
lv_chart_set_range(g_bzChart, LV_CHART_AXIS_PRIMARY_Y, 0, 200); // 0..2 g/s Startskala
|
||||||
|
}
|
||||||
|
g_bzFlowMax = 0.0f;
|
||||||
|
g_bzTick = 0;
|
||||||
|
if (g_bzPhase) lv_obj_add_flag(g_bzPhase, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
if (g_bzBarRow) lv_obj_add_flag(g_bzBarRow, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
g_brewLiveShown = true;
|
||||||
|
ui_fade_in(g_brewScreen, 300); // etwas fixer als UI_FADE_MS - der Bezug laeuft schon
|
||||||
|
}
|
||||||
|
// 100-ms-Takt aus dash_timers_cb: Werte, Phase, Kurve und Zielfortschritt nachziehen
|
||||||
|
static void brew_live_tick() {
|
||||||
|
if (!g_brewLiveShown) return;
|
||||||
|
char b[48];
|
||||||
|
float el = g_shotFrozenMs / 1000.0f;
|
||||||
|
snprintf(b, sizeof(b), "%.1f s", el);
|
||||||
|
label_set_if_changed(g_bzTimer, b);
|
||||||
|
|
||||||
|
bool scale = g_state.scaleEnabled && g_state.scaleConnected;
|
||||||
|
float w = g_state.weight;
|
||||||
|
if (w > -0.05f && w <= 0.0f) w = 0.0f; // kein "-0.0 g"
|
||||||
|
float f = g_state.flowRate;
|
||||||
|
if (f < 0.0f) f = 0.0f;
|
||||||
|
if (scale) {
|
||||||
|
snprintf(b, sizeof(b), "%.1f g", w);
|
||||||
|
label_set_if_changed(g_bzWeight, b);
|
||||||
|
snprintf(b, sizeof(b), "%.1f g/s", f);
|
||||||
|
label_set_if_changed(g_bzFlow, b);
|
||||||
|
// Flow-Kurve alle 200 ms fuettern (150 Punkte = 30-s-Fenster, aeltere rutschen raus)
|
||||||
|
if (g_bzChart && g_bzSer && (++g_bzTick & 1) == 0) {
|
||||||
|
lv_chart_set_next_value(g_bzChart, g_bzSer, (int32_t)(f * 100.0f + 0.5f));
|
||||||
|
if (f > g_bzFlowMax) {
|
||||||
|
g_bzFlowMax = f;
|
||||||
|
int hi = (int)(g_bzFlowMax * 125.0f); // 25 % Luft ueber dem Maximum
|
||||||
|
if (hi < 200) hi = 200; // mindestens 0..2 g/s
|
||||||
|
lv_chart_set_range(g_bzChart, LV_CHART_AXIS_PRIMARY_Y, 0, hi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Pre-Infusion-Phase (nur bei PI-Bezug)
|
||||||
|
if (g_bzPhase) {
|
||||||
|
if (g_piShotMode) {
|
||||||
|
int phase = pi_phase_now(g_shotFrozenMs);
|
||||||
|
if (phase <= 2) {
|
||||||
|
uint32_t endMs = (phase == 1) ? g_piDurMs : (g_piDurMs + g_piPauseMs);
|
||||||
|
uint32_t remainMs = (g_shotFrozenMs < endMs) ? (endMs - g_shotFrozenMs) : 0;
|
||||||
|
snprintf(b, sizeof(b), "%s - noch %.1f s",
|
||||||
|
(phase == 1) ? "Pre-Infusion" : "Pause", remainMs / 1000.0f);
|
||||||
|
} else {
|
||||||
|
snprintf(b, sizeof(b), "Extraktion");
|
||||||
|
}
|
||||||
|
label_set_if_changed(g_bzPhase, b);
|
||||||
|
lv_obj_remove_flag(g_bzPhase, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
} else {
|
||||||
|
lv_obj_add_flag(g_bzPhase, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Zielfortschritt: Brew-by-Weight (Gewicht) vor Brew-by-Time (Zeit), sonst versteckt
|
||||||
|
if (g_bzBarRow && g_bzBar && g_bzBarLbl) {
|
||||||
|
bool bbw = scale && g_state.bbwEnabled && g_state.bbwTarget > 0.0f;
|
||||||
|
if (bbw || (g_shotBbtMode && g_bbtTarget > 0.0f)) {
|
||||||
|
int pct;
|
||||||
|
if (bbw) {
|
||||||
|
pct = (int)(w / g_state.bbwTarget * 100.0f + 0.5f);
|
||||||
|
snprintf(b, sizeof(b), "%.1f g / %.1f g", w, g_state.bbwTarget);
|
||||||
|
} else {
|
||||||
|
pct = (int)(el / g_bbtTarget * 100.0f + 0.5f);
|
||||||
|
snprintf(b, sizeof(b), "%.1f s / %.1f s", el, g_bbtTarget);
|
||||||
|
}
|
||||||
|
if (pct < 0) pct = 0; if (pct > 100) pct = 100;
|
||||||
|
lv_bar_set_value(g_bzBar, pct, LV_ANIM_OFF);
|
||||||
|
label_set_if_changed(g_bzBarLbl, b);
|
||||||
|
lv_obj_remove_flag(g_bzBarRow, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
} else {
|
||||||
|
lv_obj_add_flag(g_bzBarRow, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Beschriftete Wert-Zeile des Live-Bezugsschirms (Caption gedimmt, Wert gross darunter)
|
||||||
|
static lv_obj_t* bz_stat_block(lv_obj_t* parent, const char* caption, lv_obj_t** valOut,
|
||||||
|
const lv_font_t* font, lv_color_t col) {
|
||||||
|
lv_obj_t* blk = lv_obj_create(parent);
|
||||||
|
lv_obj_set_size(blk, LV_PCT(100), LV_SIZE_CONTENT);
|
||||||
|
lv_obj_set_style_bg_opa(blk, LV_OPA_TRANSP, 0);
|
||||||
|
lv_obj_set_style_border_width(blk, 0, 0);
|
||||||
|
lv_obj_set_style_pad_all(blk, 0, 0);
|
||||||
|
lv_obj_set_style_pad_row(blk, 0, 0);
|
||||||
|
lv_obj_set_flex_flow(blk, LV_FLEX_FLOW_COLUMN);
|
||||||
|
lv_obj_clear_flag(blk, LV_OBJ_FLAG_SCROLLABLE);
|
||||||
|
lv_obj_t* c = lv_label_create(blk);
|
||||||
|
lv_label_set_text(c, caption);
|
||||||
|
lv_obj_set_style_text_color(c, COL_TEXT_MUT, 0);
|
||||||
|
lv_obj_set_style_text_font(c, &lv_font_maven_pro_14, 0);
|
||||||
|
lv_obj_t* v = lv_label_create(blk);
|
||||||
|
lv_label_set_text(v, "--");
|
||||||
|
lv_obj_set_style_text_color(v, col, 0);
|
||||||
|
lv_obj_set_style_text_font(v, font, 0);
|
||||||
|
if (valOut) *valOut = v;
|
||||||
|
return blk;
|
||||||
|
}
|
||||||
|
static void build_brew_live_screen() {
|
||||||
|
g_brewScreen = lv_obj_create(lv_layer_top());
|
||||||
|
lv_obj_set_size(g_brewScreen, LV_PCT(100), LV_PCT(100));
|
||||||
|
lv_obj_set_style_bg_color(g_brewScreen, COL_BG, 0);
|
||||||
|
lv_obj_set_style_bg_opa(g_brewScreen, LV_OPA_COVER, 0);
|
||||||
|
lv_obj_set_style_border_width(g_brewScreen, 0, 0);
|
||||||
|
lv_obj_set_style_radius(g_brewScreen, 0, 0);
|
||||||
|
lv_obj_set_style_pad_all(g_brewScreen, 16, 0);
|
||||||
|
lv_obj_set_style_pad_row(g_brewScreen, 10, 0);
|
||||||
|
lv_obj_set_flex_flow(g_brewScreen, LV_FLEX_FLOW_COLUMN);
|
||||||
|
lv_obj_clear_flag(g_brewScreen, LV_OBJ_FLAG_SCROLLABLE);
|
||||||
|
lv_obj_add_flag(g_brewScreen, LV_OBJ_FLAG_CLICKABLE); // schirmt die UI darunter ab
|
||||||
|
|
||||||
|
// Kopfzeile: Titel links, Schliessen-X rechts
|
||||||
|
lv_obj_t* top = lv_obj_create(g_brewScreen);
|
||||||
|
lv_obj_set_size(top, LV_PCT(100), LV_SIZE_CONTENT);
|
||||||
|
lv_obj_set_style_bg_opa(top, LV_OPA_TRANSP, 0);
|
||||||
|
lv_obj_set_style_border_width(top, 0, 0);
|
||||||
|
lv_obj_set_style_pad_all(top, 0, 0);
|
||||||
|
lv_obj_set_flex_flow(top, LV_FLEX_FLOW_ROW);
|
||||||
|
lv_obj_set_flex_align(top, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
||||||
|
lv_obj_clear_flag(top, LV_OBJ_FLAG_SCROLLABLE);
|
||||||
|
lv_obj_t* title = lv_label_create(top);
|
||||||
|
lv_label_set_text(title, "Bezug läuft");
|
||||||
|
lv_obj_set_style_text_color(title, COL_ACCENT, 0);
|
||||||
|
lv_obj_set_style_text_font(title, &lv_font_maven_pro_28, 0);
|
||||||
|
lv_obj_t* closeBtn = th_button(top, LV_SYMBOL_CLOSE, COL_CARD2, COL_TEXT);
|
||||||
|
lv_obj_set_size(closeBtn, 56, 40);
|
||||||
|
lv_obj_add_event_cb(closeBtn, brew_live_close_cb, LV_EVENT_CLICKED, nullptr);
|
||||||
|
|
||||||
|
// Hauptbereich: Wertespalte links, Flow-Kurve rechts
|
||||||
|
lv_obj_t* main = lv_obj_create(g_brewScreen);
|
||||||
|
lv_obj_set_width(main, LV_PCT(100));
|
||||||
|
lv_obj_set_flex_grow(main, 1);
|
||||||
|
lv_obj_set_style_bg_opa(main, LV_OPA_TRANSP, 0);
|
||||||
|
lv_obj_set_style_border_width(main, 0, 0);
|
||||||
|
lv_obj_set_style_pad_all(main, 0, 0);
|
||||||
|
lv_obj_set_style_pad_column(main, 16, 0);
|
||||||
|
lv_obj_set_flex_flow(main, LV_FLEX_FLOW_ROW);
|
||||||
|
lv_obj_clear_flag(main, LV_OBJ_FLAG_SCROLLABLE);
|
||||||
|
|
||||||
|
lv_obj_t* left = lv_obj_create(main);
|
||||||
|
lv_obj_set_size(left, 300, LV_PCT(100));
|
||||||
|
lv_obj_set_style_bg_opa(left, LV_OPA_TRANSP, 0);
|
||||||
|
lv_obj_set_style_border_width(left, 0, 0);
|
||||||
|
lv_obj_set_style_pad_all(left, 0, 0);
|
||||||
|
lv_obj_set_style_pad_row(left, 10, 0);
|
||||||
|
lv_obj_set_flex_flow(left, LV_FLEX_FLOW_COLUMN);
|
||||||
|
lv_obj_clear_flag(left, LV_OBJ_FLAG_SCROLLABLE);
|
||||||
|
bz_stat_block(left, "ZEIT", &g_bzTimer, &lv_font_maven_pro_48, COL_ACCENT);
|
||||||
|
g_bzWeightBlock = bz_stat_block(left, "GEWICHT", &g_bzWeight, &lv_font_maven_pro_48, COL_TEXT);
|
||||||
|
g_bzFlowBlock = bz_stat_block(left, "FLOW", &g_bzFlow, &lv_font_maven_pro_28, COL_TEXT);
|
||||||
|
g_bzPhase = lv_label_create(left);
|
||||||
|
lv_label_set_text(g_bzPhase, "");
|
||||||
|
lv_obj_set_style_text_color(g_bzPhase, COL_ACCENT, 0);
|
||||||
|
lv_obj_set_style_text_font(g_bzPhase, &lv_font_maven_pro_18, 0);
|
||||||
|
lv_obj_add_flag(g_bzPhase, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
|
||||||
|
g_bzChartWrap = lv_obj_create(main);
|
||||||
|
lv_obj_set_height(g_bzChartWrap, LV_PCT(100));
|
||||||
|
lv_obj_set_flex_grow(g_bzChartWrap, 1);
|
||||||
|
lv_obj_set_style_bg_opa(g_bzChartWrap, LV_OPA_TRANSP, 0);
|
||||||
|
lv_obj_set_style_border_width(g_bzChartWrap, 0, 0);
|
||||||
|
lv_obj_set_style_pad_all(g_bzChartWrap, 0, 0);
|
||||||
|
lv_obj_set_style_pad_row(g_bzChartWrap, 4, 0);
|
||||||
|
lv_obj_set_flex_flow(g_bzChartWrap, LV_FLEX_FLOW_COLUMN);
|
||||||
|
lv_obj_clear_flag(g_bzChartWrap, LV_OBJ_FLAG_SCROLLABLE);
|
||||||
|
lv_obj_t* chartCap = lv_label_create(g_bzChartWrap);
|
||||||
|
lv_label_set_text(chartCap, "Flow-Verlauf (letzte 30 s)");
|
||||||
|
lv_obj_set_style_text_color(chartCap, COL_TEXT_MUT, 0);
|
||||||
|
lv_obj_set_style_text_font(chartCap, &lv_font_maven_pro_14, 0);
|
||||||
|
g_bzChart = lv_chart_create(g_bzChartWrap);
|
||||||
|
lv_obj_set_width(g_bzChart, LV_PCT(100));
|
||||||
|
lv_obj_set_flex_grow(g_bzChart, 1);
|
||||||
|
lv_obj_set_style_bg_color(g_bzChart, COL_CARD, 0);
|
||||||
|
lv_obj_set_style_border_color(g_bzChart, COL_BORDER, 0);
|
||||||
|
lv_obj_set_style_border_width(g_bzChart, 1, 0);
|
||||||
|
lv_obj_set_style_radius(g_bzChart, 8, 0);
|
||||||
|
lv_obj_set_style_line_width(g_bzChart, 3, LV_PART_ITEMS);
|
||||||
|
lv_obj_set_style_width(g_bzChart, 0, LV_PART_INDICATOR); // keine Punkt-Marker
|
||||||
|
lv_obj_set_style_height(g_bzChart, 0, LV_PART_INDICATOR);
|
||||||
|
lv_chart_set_type(g_bzChart, LV_CHART_TYPE_LINE);
|
||||||
|
lv_chart_set_point_count(g_bzChart, 150); // 150 * 200 ms = 30 s
|
||||||
|
lv_chart_set_update_mode(g_bzChart, LV_CHART_UPDATE_MODE_SHIFT);
|
||||||
|
lv_chart_set_div_line_count(g_bzChart, 4, 0);
|
||||||
|
lv_chart_set_range(g_bzChart, LV_CHART_AXIS_PRIMARY_Y, 0, 200); // Flow * 100 (0..2 g/s Start)
|
||||||
|
g_bzSer = lv_chart_add_series(g_bzChart, COL_ACCENT, LV_CHART_AXIS_PRIMARY_Y);
|
||||||
|
lv_chart_set_all_value(g_bzChart, g_bzSer, LV_CHART_POINT_NONE);
|
||||||
|
|
||||||
|
// Fusszeile: Fortschritt Richtung Zielgewicht/Zielzeit
|
||||||
|
g_bzBarRow = lv_obj_create(g_brewScreen);
|
||||||
|
lv_obj_set_size(g_bzBarRow, LV_PCT(100), LV_SIZE_CONTENT);
|
||||||
|
lv_obj_set_style_bg_opa(g_bzBarRow, LV_OPA_TRANSP, 0);
|
||||||
|
lv_obj_set_style_border_width(g_bzBarRow, 0, 0);
|
||||||
|
lv_obj_set_style_pad_all(g_bzBarRow, 0, 0);
|
||||||
|
lv_obj_set_style_pad_row(g_bzBarRow, 4, 0);
|
||||||
|
lv_obj_set_flex_flow(g_bzBarRow, LV_FLEX_FLOW_COLUMN);
|
||||||
|
lv_obj_set_flex_align(g_bzBarRow, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
||||||
|
lv_obj_clear_flag(g_bzBarRow, LV_OBJ_FLAG_SCROLLABLE);
|
||||||
|
g_bzBarLbl = lv_label_create(g_bzBarRow);
|
||||||
|
lv_label_set_text(g_bzBarLbl, "");
|
||||||
|
lv_obj_set_style_text_color(g_bzBarLbl, COL_TEXT_DIM, 0);
|
||||||
|
lv_obj_set_style_text_font(g_bzBarLbl, &lv_font_maven_pro_18, 0);
|
||||||
|
g_bzBar = lv_bar_create(g_bzBarRow);
|
||||||
|
lv_obj_set_size(g_bzBar, LV_PCT(100), 14);
|
||||||
|
lv_bar_set_range(g_bzBar, 0, 100);
|
||||||
|
lv_obj_set_style_radius(g_bzBar, 7, 0);
|
||||||
|
lv_obj_set_style_bg_color(g_bzBar, COL_CARD2, 0);
|
||||||
|
lv_obj_set_style_radius(g_bzBar, 7, LV_PART_INDICATOR);
|
||||||
|
lv_obj_set_style_bg_color(g_bzBar, COL_ACCENT, LV_PART_INDICATOR);
|
||||||
|
lv_obj_add_flag(g_bzBarRow, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
|
||||||
|
lv_obj_add_flag(g_brewScreen, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
}
|
||||||
|
|
||||||
// =====================================================================================
|
// =====================================================================================
|
||||||
// Brew-Control
|
// Brew-Control
|
||||||
// =====================================================================================
|
// =====================================================================================
|
||||||
@@ -1919,6 +2219,12 @@ static void design_btn_cb(lv_event_t* e) {
|
|||||||
build_temp_row_content();
|
build_temp_row_content();
|
||||||
ui_update(g_state); // neu aufgebaute Anzeige sofort mit den aktuellen Werten fuellen
|
ui_update(g_state); // neu aufgebaute Anzeige sofort mit den aktuellen Werten fuellen
|
||||||
}
|
}
|
||||||
|
// Live-Bezugsschirm ein-/ausschalten (P4-lokal in NVS gespeichert)
|
||||||
|
static void brew_live_sw_cb(lv_event_t* e) {
|
||||||
|
g_brewLiveEnabled = sw_get((lv_obj_t*)lv_event_get_target(e));
|
||||||
|
{ Preferences prefs; prefs.begin("ui", false); prefs.putBool("brewlive", g_brewLiveEnabled); prefs.end(); }
|
||||||
|
if (!g_brewLiveEnabled) brew_live_hide(); // laeuft gerade ein Bezug: sofort ausblenden
|
||||||
|
}
|
||||||
static void build_info(lv_obj_t* p) {
|
static void build_info(lv_obj_t* p) {
|
||||||
section_title(p, "Darstellung");
|
section_title(p, "Darstellung");
|
||||||
lv_obj_t* dcard = th_card(p);
|
lv_obj_t* dcard = th_card(p);
|
||||||
@@ -1938,6 +2244,9 @@ static void build_info(lv_obj_t* p) {
|
|||||||
lv_obj_add_event_cb(g_designBtn[i], design_btn_cb, LV_EVENT_CLICKED, (void*)(intptr_t)i);
|
lv_obj_add_event_cb(g_designBtn[i], design_btn_cb, LV_EVENT_CLICKED, (void*)(intptr_t)i);
|
||||||
}
|
}
|
||||||
design_btns_refresh();
|
design_btns_refresh();
|
||||||
|
swBrewLive = add_switch(dcard, "Live-Bezugsschirm (Vollbild während des Bezugs)");
|
||||||
|
sw_set(swBrewLive, g_brewLiveEnabled);
|
||||||
|
lv_obj_add_event_cb(swBrewLive, brew_live_sw_cb, LV_EVENT_VALUE_CHANGED, nullptr);
|
||||||
|
|
||||||
section_title(p, "Firmware-Stände & Verbindung");
|
section_title(p, "Firmware-Stände & Verbindung");
|
||||||
|
|
||||||
@@ -2072,9 +2381,7 @@ static void pi_bar_update() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint32_t el = g_shotFrozenMs;
|
uint32_t el = g_shotFrozenMs;
|
||||||
int phase;
|
int phase = pi_phase_now(el);
|
||||||
if (g_piStateS3 >= 1 && g_piStateS3 <= 3) phase = (int)g_piStateS3;
|
|
||||||
else phase = (el < g_piDurMs) ? 1 : ((el < g_piDurMs + g_piPauseMs) ? 2 : 3);
|
|
||||||
|
|
||||||
// Pause-Chip nur zeigen, wenn tatsaechlich eine Pause konfiguriert ist
|
// Pause-Chip nur zeigen, wenn tatsaechlich eine Pause konfiguriert ist
|
||||||
if (g_piChip[1]) {
|
if (g_piChip[1]) {
|
||||||
@@ -2251,6 +2558,8 @@ static void dash_timers_cb(lv_timer_t*) {
|
|||||||
}
|
}
|
||||||
label_set_if_changed(lblFlow, buf);
|
label_set_if_changed(lblFlow, buf);
|
||||||
}
|
}
|
||||||
|
// Live-Bezugsschirm (Werte/Kurve/Zielfortschritt im 100-ms-Takt)
|
||||||
|
brew_live_tick();
|
||||||
// Pre-Infusion-Phasenleiste (Sichtbarkeit/Phase/Restzeit)
|
// Pre-Infusion-Phasenleiste (Sichtbarkeit/Phase/Restzeit)
|
||||||
pi_bar_update();
|
pi_bar_update();
|
||||||
// Statuszeile (Einblenden/Rotation der konsolidierten Meldungen)
|
// Statuszeile (Einblenden/Rotation der konsolidierten Meldungen)
|
||||||
@@ -2263,9 +2572,10 @@ static void dash_timers_cb(lv_timer_t*) {
|
|||||||
void ui_init(ProtocolClient* client) {
|
void ui_init(ProtocolClient* client) {
|
||||||
g_client = client;
|
g_client = client;
|
||||||
|
|
||||||
// Gespeichertes Dashboard-Temperaturdesign laden (P4-lokal; Standard: Rundinstrumente)
|
// Gespeicherte Darstellungs-Einstellungen laden (P4-lokal; Design-Standard: Rundinstrumente)
|
||||||
{ Preferences prefs; prefs.begin("ui", false);
|
{ Preferences prefs; prefs.begin("ui", false);
|
||||||
g_tempDesign = prefs.getUChar("tempdsgn", TD_GAUGE);
|
g_tempDesign = prefs.getUChar("tempdsgn", TD_GAUGE);
|
||||||
|
g_brewLiveEnabled = prefs.getBool("brewlive", true);
|
||||||
prefs.end();
|
prefs.end();
|
||||||
if (g_tempDesign >= TD_DESIGN_COUNT) g_tempDesign = TD_GAUGE; }
|
if (g_tempDesign >= TD_DESIGN_COUNT) g_tempDesign = TD_GAUGE; }
|
||||||
|
|
||||||
@@ -2393,6 +2703,9 @@ void ui_init(ProtocolClient* client) {
|
|||||||
// --- Reinigungsassistent-Sub-Screen (oberste Ebene, unter Tastatur/Toast/Overlays) ---
|
// --- Reinigungsassistent-Sub-Screen (oberste Ebene, unter Tastatur/Toast/Overlays) ---
|
||||||
build_cleaning_screen();
|
build_cleaning_screen();
|
||||||
|
|
||||||
|
// --- Live-Bezugsschirm (ueber dem Reinigungs-Screen, unter Tastatur/Standby/OTA) ---
|
||||||
|
build_brew_live_screen();
|
||||||
|
|
||||||
// --- Gemeinsame Tastatur (oberste Ebene) ---
|
// --- Gemeinsame Tastatur (oberste Ebene) ---
|
||||||
g_kb = lv_keyboard_create(lv_layer_top());
|
g_kb = lv_keyboard_create(lv_layer_top());
|
||||||
lv_keyboard_set_map(g_kb, LV_KEYBOARD_MODE_TEXT_LOWER, kb_map_lc, kb_ctrl); // QWERTZ
|
lv_keyboard_set_map(g_kb, LV_KEYBOARD_MODE_TEXT_LOWER, kb_map_lc, kb_ctrl); // QWERTZ
|
||||||
@@ -2500,17 +2813,21 @@ void ui_init(ProtocolClient* client) {
|
|||||||
lv_obj_set_style_text_font(g_otaBytes, &lv_font_maven_pro_18, 0);
|
lv_obj_set_style_text_font(g_otaBytes, &lv_font_maven_pro_18, 0);
|
||||||
lv_obj_add_flag(g_otaScreen, LV_OBJ_FLAG_HIDDEN);
|
lv_obj_add_flag(g_otaScreen, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
|
||||||
// Shot-Zusammenfassung (zentrierte Karte, antippbar zum Schliessen)
|
// Shot-Zusammenfassung (zentrierte Karte mit grossen Werten, antippbar zum Schliessen)
|
||||||
g_shotSum = lv_obj_create(lv_layer_top());
|
g_shotSum = lv_obj_create(lv_layer_top());
|
||||||
lv_obj_set_size(g_shotSum, 360, LV_SIZE_CONTENT);
|
lv_obj_set_size(g_shotSum, 460, LV_SIZE_CONTENT);
|
||||||
lv_obj_set_style_bg_color(g_shotSum, COL_CARD, 0);
|
lv_obj_set_style_bg_color(g_shotSum, COL_CARD, 0);
|
||||||
lv_obj_set_style_bg_opa(g_shotSum, LV_OPA_COVER, 0);
|
lv_obj_set_style_bg_opa(g_shotSum, LV_OPA_COVER, 0);
|
||||||
lv_obj_set_style_border_color(g_shotSum, COL_ACCENT, 0);
|
lv_obj_set_style_border_color(g_shotSum, COL_ACCENT, 0);
|
||||||
lv_obj_set_style_border_width(g_shotSum, 2, 0);
|
lv_obj_set_style_border_width(g_shotSum, 2, 0);
|
||||||
lv_obj_set_style_radius(g_shotSum, 12, 0);
|
lv_obj_set_style_radius(g_shotSum, 14, 0);
|
||||||
lv_obj_set_style_pad_all(g_shotSum, 18, 0);
|
lv_obj_set_style_shadow_width(g_shotSum, 24, 0); // hebt die Karte vom Inhalt ab
|
||||||
lv_obj_set_style_pad_row(g_shotSum, 8, 0);
|
lv_obj_set_style_shadow_color(g_shotSum, lv_color_hex(0x000000), 0);
|
||||||
|
lv_obj_set_style_shadow_opa(g_shotSum, LV_OPA_60, 0);
|
||||||
|
lv_obj_set_style_pad_all(g_shotSum, 20, 0);
|
||||||
|
lv_obj_set_style_pad_row(g_shotSum, 14, 0);
|
||||||
lv_obj_set_flex_flow(g_shotSum, LV_FLEX_FLOW_COLUMN);
|
lv_obj_set_flex_flow(g_shotSum, LV_FLEX_FLOW_COLUMN);
|
||||||
|
lv_obj_set_flex_align(g_shotSum, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
||||||
lv_obj_clear_flag(g_shotSum, LV_OBJ_FLAG_SCROLLABLE);
|
lv_obj_clear_flag(g_shotSum, LV_OBJ_FLAG_SCROLLABLE);
|
||||||
lv_obj_add_flag(g_shotSum, LV_OBJ_FLAG_CLICKABLE);
|
lv_obj_add_flag(g_shotSum, LV_OBJ_FLAG_CLICKABLE);
|
||||||
lv_obj_add_event_cb(g_shotSum, shot_sum_tap_cb, LV_EVENT_CLICKED, nullptr);
|
lv_obj_add_event_cb(g_shotSum, shot_sum_tap_cb, LV_EVENT_CLICKED, nullptr);
|
||||||
@@ -2519,10 +2836,18 @@ void ui_init(ProtocolClient* client) {
|
|||||||
lv_label_set_text(sumTitle, "Bezug beendet");
|
lv_label_set_text(sumTitle, "Bezug beendet");
|
||||||
lv_obj_set_style_text_color(sumTitle, COL_ACCENT, 0);
|
lv_obj_set_style_text_color(sumTitle, COL_ACCENT, 0);
|
||||||
lv_obj_set_style_text_font(sumTitle, &lv_font_maven_pro_28, 0);
|
lv_obj_set_style_text_font(sumTitle, &lv_font_maven_pro_28, 0);
|
||||||
g_shotSumBody = lv_label_create(g_shotSum);
|
lv_obj_t* sumRow = lv_obj_create(g_shotSum);
|
||||||
lv_label_set_text(g_shotSumBody, "");
|
lv_obj_set_size(sumRow, LV_PCT(100), LV_SIZE_CONTENT);
|
||||||
lv_obj_set_style_text_color(g_shotSumBody, COL_TEXT, 0);
|
lv_obj_set_style_bg_opa(sumRow, LV_OPA_TRANSP, 0);
|
||||||
lv_obj_set_style_text_font(g_shotSumBody, &lv_font_maven_pro_18, 0);
|
lv_obj_set_style_border_width(sumRow, 0, 0);
|
||||||
|
lv_obj_set_style_pad_all(sumRow, 0, 0);
|
||||||
|
lv_obj_set_style_pad_column(sumRow, 10, 0);
|
||||||
|
lv_obj_set_flex_flow(sumRow, LV_FLEX_FLOW_ROW);
|
||||||
|
lv_obj_clear_flag(sumRow, LV_OBJ_FLAG_SCROLLABLE);
|
||||||
|
lv_obj_clear_flag(sumRow, LV_OBJ_FLAG_CLICKABLE); // Tipp faellt auf die Karte durch
|
||||||
|
g_sumCol[0] = sum_stat_col(sumRow, "Dauer", &g_sumVal[0]);
|
||||||
|
g_sumCol[1] = sum_stat_col(sumRow, "Gewicht", &g_sumVal[1]);
|
||||||
|
g_sumCol[2] = sum_stat_col(sumRow, "Mittl. Flow", &g_sumVal[2]);
|
||||||
lv_obj_add_flag(g_shotSum, LV_OBJ_FLAG_HIDDEN);
|
lv_obj_add_flag(g_shotSum, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
|
||||||
// --- Boot-Splash / Start-Animation (oberstes Overlay) ---
|
// --- Boot-Splash / Start-Animation (oberstes Overlay) ---
|
||||||
@@ -2824,7 +3149,13 @@ void ui_update(const MachineState& st) {
|
|||||||
g_piStateS3 = st.piState;
|
g_piStateS3 = st.piState;
|
||||||
g_piDurMs = (uint32_t)(st.piDurSecs * 1000.0f);
|
g_piDurMs = (uint32_t)(st.piDurSecs * 1000.0f);
|
||||||
g_piPauseMs = (uint32_t)(st.piPauseSecs * 1000.0f);
|
g_piPauseMs = (uint32_t)(st.piPauseSecs * 1000.0f);
|
||||||
|
// Live-Bezugsschirm einblenden (nur echte Bezuege; nicht im Reinigungsassistenten,
|
||||||
|
// nicht im Standby und nicht, wenn der Nutzer ihn fuer diesen Bezug weggetippt hat)
|
||||||
|
if (g_brewLiveEnabled && !g_brewLiveClosed && !g_brewLiveShown &&
|
||||||
|
!st.cleaningActive && !st.standbyActive)
|
||||||
|
brew_live_show();
|
||||||
} else if (st.flushActive) {
|
} else if (st.flushActive) {
|
||||||
|
brew_live_hide(); // Sicherheitsnetz: Flush zeigt nie den Bezugsschirm
|
||||||
g_shotStartMs = millis() - st.flushElapsedMs; // rueckwirkend koppeln (wie Bezug)
|
g_shotStartMs = millis() - st.flushElapsedMs; // rueckwirkend koppeln (wie Bezug)
|
||||||
g_shotActive = true;
|
g_shotActive = true;
|
||||||
g_shotWasFlush = true;
|
g_shotWasFlush = true;
|
||||||
@@ -2842,6 +3173,8 @@ void ui_update(const MachineState& st) {
|
|||||||
g_shotActive = false;
|
g_shotActive = false;
|
||||||
g_piShotMode = false; // Phasenleiste ausblenden (pi_bar_update)
|
g_piShotMode = false; // Phasenleiste ausblenden (pi_bar_update)
|
||||||
g_piStateS3 = 0;
|
g_piStateS3 = 0;
|
||||||
|
brew_live_hide(); // Bezug vorbei -> Overlay weich ausblenden
|
||||||
|
g_brewLiveClosed = false; // Wegtipp-Sperre gilt nur fuer den laufenden Bezug
|
||||||
}
|
}
|
||||||
// Shot-Zusammenfassung beim Ende eines echten Bezugs (kein Flush, min. 3 s)
|
// Shot-Zusammenfassung beim Ende eines echten Bezugs (kein Flush, min. 3 s)
|
||||||
if (g_sumShotWas && !st.shotActive) {
|
if (g_sumShotWas && !st.shotActive) {
|
||||||
|
|||||||
Reference in New Issue
Block a user