Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a410da6e72 | ||
|
|
f0a214d712 | ||
|
|
21f273aae4 | ||
|
|
e42d2b3de2 | ||
|
|
785f64331d | ||
|
|
40aabe48bc |
@@ -1,3 +1,41 @@
|
||||
Version 1.8.3:
|
||||
- Fehlerbehebung: Bei allen Darstellungen stand hinter der Temperatur ein leeres Rechteck
|
||||
statt des C. Die beiden großen Schriften waren auf Ziffern, Komma, Punkt, Minus und
|
||||
Gradzeichen beschränkt - das C fehlte darin schlicht. Es ist jetzt enthalten, ebenso g
|
||||
und s für die Gewichts- und Zeitanzeige während eines Bezugs.
|
||||
- Fehlerbehebung: Bei der Darstellung „Verlauf" war keine Kurve zu sehen. Ein frisch
|
||||
angelegtes Diagramm enthält lauter „kein Wert"-Punkte und zeichnet deshalb nichts; ohne
|
||||
Hintergrund war der Bereich vollständig unsichtbar, bis nach einer Minute genug Messwerte
|
||||
zusammengekommen wären. Die Kurve startet jetzt beim aktuellen Messwert, und ihre Fläche
|
||||
ist leicht abgesetzt.
|
||||
- Die großen Zahlen des Dashboards stehen jetzt im fetten Schnitt und etwas enger, wie im
|
||||
Entwurf. Erzeugt aus der variablen Maven-Pro-Datei mit Gewicht 700 - dieselbe Schriftart
|
||||
wie bisher, nur kräftiger. Die übrige Oberfläche bleibt unverändert.
|
||||
|
||||
Version 1.8.2:
|
||||
- Die Liste der letzten Bezüge auf der Statistikseite ist jetzt eine Tabelle mit festen
|
||||
Spalten: Zeitpunkt, Dauer, Gewicht und gegebenenfalls die Kennzeichnung „kalt".
|
||||
- Vorher war es ein einziges mehrzeiliges Textfeld, in dem die Werte durch Leerzeichen
|
||||
getrennt aneinandergereiht standen. Weil Zahlen unterschiedlich breit sind, stand nichts
|
||||
untereinander - zwei Bezüge ließen sich nicht vergleichen, ohne jede Zeile einzeln zu
|
||||
lesen. Genau das sah unruhig aus.
|
||||
- Ziffern haben jetzt gleiche Breite, jede zweite Zeile ist leicht abgesetzt, und eine
|
||||
Kopfzeile benennt die Spalten. Wurde ohne Waage bezogen, bleibt die Gewichtsspalte leer,
|
||||
statt eine Null vorzutäuschen.
|
||||
- Die Zeilen werden einmal angelegt und danach nur gefüllt oder ausgeblendet, statt bei
|
||||
jeder Aktualisierung neu zu entstehen.
|
||||
|
||||
Version 1.8.1:
|
||||
- Die Bezugsanzeige ist da, und zwar für alle vier Darstellungen gemeinsam: Sobald ein
|
||||
Bezug oder Dampfbezug läuft, schrumpft der Temperaturbereich und die untere Zeile wächst.
|
||||
Shot-Timer und Gewicht werden dabei auf 96 Pixel vergrößert - während eines Bezugs zählen
|
||||
Zeit und Gewicht, die Kesseltemperaturen sind dann Nebensache.
|
||||
- Es gibt keine zweite Ansicht: Die Seite verschiebt nur das Gewicht zwischen ihren beiden
|
||||
Bereichen. Damit bleibt alles an seinem Platz, und es gibt nichts doppelt zu pflegen.
|
||||
- Der Wechsel hält nach dem Bezug noch vier Sekunden an. Ohne dieses Nachhalten würde die
|
||||
Seite bei jeder kurzen Unterbrechung hin- und herspringen - das wäre unruhiger als gar
|
||||
kein Wechsel.
|
||||
|
||||
Version 1.8.0:
|
||||
- Das Dashboard hat vier neue Darstellungen, die die bisherigen fünf ersetzen. Sie sind
|
||||
keine Varianten desselben Bildes, sondern vier Antworten auf die Frage, was die große
|
||||
|
||||
@@ -567,8 +567,8 @@
|
||||
LV_FONT_DECLARE(lv_font_maven_pro_28) \
|
||||
LV_FONT_DECLARE(lv_font_maven_pro_40) \
|
||||
LV_FONT_DECLARE(lv_font_maven_pro_48) \
|
||||
LV_FONT_DECLARE(lv_font_maven_pro_96) \
|
||||
LV_FONT_DECLARE(lv_font_maven_pro_140) \
|
||||
LV_FONT_DECLARE(lv_font_maven_pro_bold_96) \
|
||||
LV_FONT_DECLARE(lv_font_maven_pro_bold_140) \
|
||||
LV_FONT_DECLARE(lv_font_clock_240)
|
||||
|
||||
/*Always set a default font*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+190
-36
@@ -189,6 +189,10 @@ static lv_obj_t* g_profChip = nullptr;
|
||||
static lv_obj_t* g_profPicker = nullptr; // Schnellwahl-Overlay (Vollbild-Abdunkelung)
|
||||
static lv_obj_t* g_profPickerList = nullptr; // Button-Liste im Overlay
|
||||
static lv_obj_t* g_profPickerInfo = nullptr; // "Lade Profile..."-Hinweis im Overlay
|
||||
static lv_obj_t* g_infoRow = nullptr; // untere Zeile; waechst waehrend eines Bezugs
|
||||
static bool g_dashBrewMode = false;
|
||||
static const lv_font_t* g_shotFontNormal = nullptr;
|
||||
static const lv_font_t* g_bezugFontNormal = nullptr;
|
||||
static lv_obj_t* cellShot; static lv_obj_t* lblShotTimer; static lv_obj_t* g_bbtBar = nullptr;
|
||||
static lv_obj_t* cellSteam; static lv_obj_t* lblSteamTimer; static lv_obj_t* g_sbtBar = nullptr;
|
||||
static lv_obj_t* cellBezug; static lv_obj_t* lblBezug; static lv_obj_t* g_bbwBar = nullptr;
|
||||
@@ -355,7 +359,6 @@ static String g_selProfile;
|
||||
|
||||
// Statistik (Nutzungsverlauf)
|
||||
static lv_obj_t* g_statSummary = nullptr; // Aggregate (Heute/Woche/Gesamt)
|
||||
static lv_obj_t* g_statList = nullptr; // Liste der letzten Einzelbezuege
|
||||
|
||||
// =====================================================================================
|
||||
// Hilfen
|
||||
@@ -574,6 +577,112 @@ static void grid_at(lv_obj_t* c, uint8_t col, uint8_t row, uint8_t col_span = 1)
|
||||
}
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
// Liste der letzten Bezuege
|
||||
//
|
||||
// Frueher war das EIN mehrzeiliges Textfeld: Zeitpunkt, Dauer und Gewicht standen in einer
|
||||
// Zeile aneinandergereiht, durch Leerzeichen getrennt. Weil die Zahlen unterschiedlich
|
||||
// breit sind, stand nichts untereinander - man konnte zwei Bezuege nicht vergleichen, ohne
|
||||
// jede Zeile einzeln zu lesen.
|
||||
//
|
||||
// Jetzt eine Tabelle mit festen Spalten und Ziffern gleicher Breite. Die Zeilen werden
|
||||
// einmal angelegt und danach nur noch gefuellt oder ausgeblendet - eine Statistikseite,
|
||||
// die bei jeder Aktualisierung Dutzende Objekte neu anlegt, waere unnoetig teuer.
|
||||
// ------------------------------------------------------------------------------------
|
||||
#define STAT_ROW_COUNT 12
|
||||
|
||||
static lv_obj_t* g_statRow[STAT_ROW_COUNT] = {};
|
||||
static lv_obj_t* g_statTime[STAT_ROW_COUNT] = {};
|
||||
static lv_obj_t* g_statDur[STAT_ROW_COUNT] = {};
|
||||
static lv_obj_t* g_statWgt[STAT_ROW_COUNT] = {};
|
||||
static lv_obj_t* g_statCold[STAT_ROW_COUNT] = {};
|
||||
static lv_obj_t* g_statEmpty = nullptr;
|
||||
|
||||
static lv_obj_t* stat_cell(lv_obj_t* row, int32_t width, bool rechts, lv_color_t col) {
|
||||
lv_obj_t* l = lv_label_create(row);
|
||||
if (width > 0) lv_obj_set_width(l, width);
|
||||
else lv_obj_set_flex_grow(l, 1);
|
||||
lv_obj_set_style_text_color(l, col, 0);
|
||||
lv_obj_set_style_text_align(l, rechts ? LV_TEXT_ALIGN_RIGHT : LV_TEXT_ALIGN_LEFT, 0);
|
||||
lv_label_set_text(l, "");
|
||||
return l;
|
||||
}
|
||||
|
||||
static void stat_list_build(lv_obj_t* parent) {
|
||||
lv_obj_t* card = th_card(parent);
|
||||
lv_obj_set_width(card, LV_PCT(100));
|
||||
lv_obj_set_height(card, LV_SIZE_CONTENT);
|
||||
lv_obj_set_flex_flow(card, LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_set_style_pad_row(card, 0, 0);
|
||||
lv_obj_clear_flag(card, LV_OBJ_FLAG_SCROLLABLE);
|
||||
|
||||
// Kopfzeile - benennt die Spalten, damit die Zahlen ohne Einheit auskommen
|
||||
lv_obj_t* head = lv_obj_create(card);
|
||||
lv_obj_set_width(head, LV_PCT(100));
|
||||
lv_obj_set_height(head, LV_SIZE_CONTENT);
|
||||
lv_obj_set_style_bg_opa(head, LV_OPA_TRANSP, 0);
|
||||
lv_obj_set_style_border_width(head, 0, 0);
|
||||
lv_obj_set_style_pad_all(head, 4, 0);
|
||||
lv_obj_set_style_pad_column(head, 10, 0);
|
||||
lv_obj_set_flex_flow(head, LV_FLEX_FLOW_ROW);
|
||||
lv_obj_clear_flag(head, LV_OBJ_FLAG_SCROLLABLE);
|
||||
stat_cell(head, 0, false, COL_TEXT_MUT);
|
||||
lv_label_set_text(lv_obj_get_child(head, 0), "Zeitpunkt");
|
||||
lv_label_set_text(stat_cell(head, 96, true, COL_TEXT_MUT), "Dauer");
|
||||
lv_label_set_text(stat_cell(head, 96, true, COL_TEXT_MUT), "Gewicht");
|
||||
lv_label_set_text(stat_cell(head, 58, true, COL_TEXT_MUT), "");
|
||||
|
||||
for (int i = 0; i < STAT_ROW_COUNT; i++) {
|
||||
lv_obj_t* r = lv_obj_create(card);
|
||||
lv_obj_set_width(r, LV_PCT(100));
|
||||
lv_obj_set_height(r, LV_SIZE_CONTENT);
|
||||
// Jede zweite Zeile leicht abgesetzt - fuehrt das Auge ueber die Zeile, ohne dass
|
||||
// dafuer Trennlinien noetig waeren.
|
||||
lv_obj_set_style_bg_color(r, lv_color_hex(0x242424), 0);
|
||||
lv_obj_set_style_bg_opa(r, (i % 2) ? LV_OPA_COVER : LV_OPA_TRANSP, 0);
|
||||
lv_obj_set_style_border_width(r, 0, 0);
|
||||
lv_obj_set_style_radius(r, 5, 0);
|
||||
lv_obj_set_style_pad_all(r, 5, 0);
|
||||
lv_obj_set_style_pad_column(r, 10, 0);
|
||||
lv_obj_set_flex_flow(r, LV_FLEX_FLOW_ROW);
|
||||
lv_obj_set_flex_align(r, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
||||
lv_obj_clear_flag(r, LV_OBJ_FLAG_SCROLLABLE);
|
||||
g_statTime[i] = stat_cell(r, 0, false, COL_TEXT_DIM);
|
||||
g_statDur[i] = stat_cell(r, 96, true, COL_TEXT);
|
||||
g_statWgt[i] = stat_cell(r, 96, true, COL_TEXT);
|
||||
g_statCold[i] = stat_cell(r, 58, true, lv_color_hex(0x80cbc4));
|
||||
g_statRow[i] = r;
|
||||
lv_obj_add_flag(r, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
|
||||
g_statEmpty = lv_label_create(card);
|
||||
lv_obj_set_width(g_statEmpty, LV_PCT(100));
|
||||
lv_label_set_text(g_statEmpty, "Noch keine Bezüge aufgezeichnet.");
|
||||
lv_obj_set_style_text_color(g_statEmpty, COL_TEXT_MUT, 0);
|
||||
lv_obj_set_style_pad_all(g_statEmpty, 5, 0);
|
||||
}
|
||||
|
||||
// Eine Zeile fuellen. 'w' unter 0 bedeutet: ohne Waage bezogen, dann bleibt die Spalte leer
|
||||
// statt eine Null vorzutaeuschen.
|
||||
static void stat_list_set(int i, const char* dt, float d, float w, bool kalt) {
|
||||
if (i < 0 || i >= STAT_ROW_COUNT || !g_statRow[i]) return;
|
||||
lv_obj_remove_flag(g_statRow[i], LV_OBJ_FLAG_HIDDEN);
|
||||
lv_label_set_text(g_statTime[i], dt);
|
||||
lv_label_set_text_fmt(g_statDur[i], "%.1f s", d);
|
||||
if (w >= 0.0f) lv_label_set_text_fmt(g_statWgt[i], "%.1f g", w);
|
||||
else lv_label_set_text(g_statWgt[i], "–");
|
||||
lv_label_set_text(g_statCold[i], kalt ? "kalt" : "");
|
||||
}
|
||||
|
||||
static void stat_list_finish(int used) {
|
||||
for (int i = used; i < STAT_ROW_COUNT; i++)
|
||||
if (g_statRow[i]) lv_obj_add_flag(g_statRow[i], LV_OBJ_FLAG_HIDDEN);
|
||||
if (g_statEmpty) {
|
||||
if (used > 0) lv_obj_add_flag(g_statEmpty, LV_OBJ_FLAG_HIDDEN);
|
||||
else lv_obj_remove_flag(g_statEmpty, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
}
|
||||
|
||||
static void scroll_ohne_nachlauf(lv_obj_t* o) {
|
||||
#if JC_PANEL_TYPE == WS_PANEL_7H
|
||||
lv_obj_clear_flag(o, LV_OBJ_FLAG_SCROLL_MOMENTUM);
|
||||
@@ -859,6 +968,10 @@ static lv_obj_t* tempField(lv_obj_t* parent, const char* title, lv_color_t accen
|
||||
lv_label_set_text(*big, "--.-");
|
||||
lv_obj_set_style_text_color(*big, COL_TEXT, 0);
|
||||
lv_obj_set_style_text_font(*big, valueFont, 0);
|
||||
// Grosse Zahlen etwas enger setzen. Bei dieser Groesse wirken die Werksabstaende
|
||||
// auseinandergezogen; ein paar Pixel weniger binden die Ziffern zu einer Zahl zusammen.
|
||||
if (valueFont == &lv_font_maven_pro_bold_140) lv_obj_set_style_text_letter_space(*big, -3, 0);
|
||||
else if (valueFont == &lv_font_maven_pro_bold_96) lv_obj_set_style_text_letter_space(*big, -2, 0);
|
||||
|
||||
*setp = lv_label_create(c);
|
||||
lv_label_set_text(*setp, "Soll --.-");
|
||||
@@ -881,19 +994,31 @@ static lv_obj_t* tempField(lv_obj_t* parent, const char* title, lv_color_t accen
|
||||
// Flache Verlaufskurve unter einer Temperatur. Zeigt, ob die Regelung haelt - das ist die
|
||||
// eigentliche Frage an eine PID-Regelung, und eine Zahl kann sie grundsaetzlich nicht
|
||||
// beantworten. Gespeist wird sie aus derselben Sekundenabtastung wie die Verlaufsseite.
|
||||
static lv_obj_t* tempSpark(lv_obj_t* parent, lv_color_t col, lv_chart_series_t** ser) {
|
||||
static lv_obj_t* tempSpark(lv_obj_t* parent, lv_color_t col, lv_chart_series_t** ser,
|
||||
float jetzt, float soll) {
|
||||
lv_obj_t* ch = lv_chart_create(parent);
|
||||
lv_obj_set_size(ch, LV_PCT(96), 72);
|
||||
lv_obj_set_size(ch, LV_PCT(96), 64);
|
||||
lv_chart_set_type(ch, LV_CHART_TYPE_LINE);
|
||||
lv_chart_set_point_count(ch, DASH_SPARK_POINTS);
|
||||
lv_chart_set_div_line_count(ch, 0, 0);
|
||||
lv_obj_set_style_bg_opa(ch, LV_OPA_TRANSP, 0);
|
||||
// Schwach abgesetzte Flaeche: Ohne sie waere der Bereich vor dem ersten Messwert
|
||||
// vollstaendig unsichtbar - man haette gar nicht erkannt, dass dort eine Kurve gehoert.
|
||||
lv_obj_set_style_bg_color(ch, lv_color_hex(0x151515), 0);
|
||||
lv_obj_set_style_bg_opa(ch, LV_OPA_COVER, 0);
|
||||
lv_obj_set_style_radius(ch, 6, 0);
|
||||
lv_obj_set_style_border_width(ch, 0, 0);
|
||||
lv_obj_set_style_pad_all(ch, 0, 0);
|
||||
lv_obj_set_style_pad_all(ch, 4, 0);
|
||||
lv_obj_set_style_size(ch, 0, 0, LV_PART_INDICATOR); // keine Punktmarkierungen
|
||||
lv_obj_set_style_line_width(ch, 3, LV_PART_ITEMS);
|
||||
lv_obj_clear_flag(ch, LV_OBJ_FLAG_SCROLLABLE);
|
||||
*ser = lv_chart_add_series(ch, col, LV_CHART_AXIS_PRIMARY_Y);
|
||||
|
||||
// Ausschnitt und Startwert sofort setzen. Ein frisch angelegtes Diagramm hat lauter
|
||||
// "kein Wert"-Punkte und zeichnet deshalb nichts - beim Umschalten der Darstellung
|
||||
// saehe man bis zur ersten Sekundenprobe eine leere Flaeche.
|
||||
int32_t sollT = (int32_t)(soll * 10.0f);
|
||||
lv_chart_set_range(ch, LV_CHART_AXIS_PRIMARY_Y, sollT - 60, sollT + 30);
|
||||
lv_chart_set_all_value(ch, *ser, (int32_t)(jetzt * 10.0f));
|
||||
return ch;
|
||||
}
|
||||
|
||||
@@ -922,7 +1047,7 @@ static void build_temp_row_content() {
|
||||
// zwei Drittel Flaeche fuer Wasser, ein Drittel fuer Dampf - die Asymmetrie ist die
|
||||
// Aussage, nicht ein Versehen.
|
||||
tempField(g_tempRow, "WASSER", COL_ACCENT, &lblTempW, &lblSetW, &barDutyW,
|
||||
2, &lv_font_maven_pro_140, false, 0);
|
||||
2, &lv_font_maven_pro_bold_140, false, 0);
|
||||
tempField(g_tempRow, "DAMPF", teal, &lblTempD, &lblSetD, &barDutyD,
|
||||
1, &lv_font_maven_pro_48, false, 0);
|
||||
break;
|
||||
@@ -930,11 +1055,11 @@ static void build_temp_row_content() {
|
||||
|
||||
case TD_VERLAUF: {
|
||||
lv_obj_t* cw = tempField(g_tempRow, "WASSER", COL_ACCENT, &lblTempW, &lblSetW, &barDutyW,
|
||||
1, &lv_font_maven_pro_96, false, 0);
|
||||
g_sparkW = tempSpark(cw, COL_OK, &g_sparkSerW);
|
||||
1, &lv_font_maven_pro_bold_96, false, 0);
|
||||
g_sparkW = tempSpark(cw, COL_OK, &g_sparkSerW, g_state.tempW, g_state.setW);
|
||||
lv_obj_t* cd = tempField(g_tempRow, "DAMPF", teal, &lblTempD, &lblSetD, &barDutyD,
|
||||
1, &lv_font_maven_pro_96, false, 0);
|
||||
g_sparkD = tempSpark(cd, COL_ACCENT, &g_sparkSerD);
|
||||
1, &lv_font_maven_pro_bold_96, false, 0);
|
||||
g_sparkD = tempSpark(cd, COL_ACCENT, &g_sparkSerD, g_state.tempD, g_state.setD);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -942,9 +1067,9 @@ static void build_temp_row_content() {
|
||||
// Keine Kartenkanten: Der Bereich ist in zwei Felder geteilt, getrennt nur durch
|
||||
// einen Hauch Helligkeitsunterschied.
|
||||
tempField(g_tempRow, "WASSER", COL_ACCENT, &lblTempW, &lblSetW, &barDutyW,
|
||||
1, &lv_font_maven_pro_140, true, 0x0d0d0d);
|
||||
1, &lv_font_maven_pro_bold_140, true, 0x0d0d0d);
|
||||
tempField(g_tempRow, "DAMPF", teal, &lblTempD, &lblSetD, &barDutyD,
|
||||
1, &lv_font_maven_pro_140, true, 0x151515);
|
||||
1, &lv_font_maven_pro_bold_140, true, 0x151515);
|
||||
lv_obj_set_style_pad_column(g_tempRow, 0, 0); // Felder stossen direkt aneinander
|
||||
break;
|
||||
}
|
||||
@@ -975,9 +1100,9 @@ static void build_temp_row_content() {
|
||||
lv_obj_set_flex_flow(inner, LV_FLEX_FLOW_ROW);
|
||||
lv_obj_clear_flag(inner, LV_OBJ_FLAG_SCROLLABLE);
|
||||
tempField(inner, "WASSER", COL_ACCENT, &lblTempW, &lblSetW, &barDutyW,
|
||||
1, &lv_font_maven_pro_96, false, 0);
|
||||
1, &lv_font_maven_pro_bold_96, false, 0);
|
||||
tempField(inner, "DAMPF", teal, &lblTempD, &lblSetD, &barDutyD,
|
||||
1, &lv_font_maven_pro_96, false, 0);
|
||||
1, &lv_font_maven_pro_bold_96, false, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1075,6 +1200,7 @@ static void build_dashboard(lv_obj_t* p) {
|
||||
|
||||
// Info-Zeile: Timer / Bezug / Eco-Countdown / Gehaeuse (teilen sich die Breite)
|
||||
lv_obj_t* ir = lv_obj_create(p);
|
||||
g_infoRow = ir;
|
||||
lv_obj_set_width(ir, LV_PCT(100));
|
||||
lv_obj_set_flex_grow(ir, 2);
|
||||
lv_obj_set_style_bg_opa(ir, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(ir, 0, 0);
|
||||
@@ -1110,6 +1236,10 @@ static void build_dashboard(lv_obj_t* p) {
|
||||
lv_bar_set_range(g_bbwBar, 0, 100);
|
||||
lv_bar_set_value(g_bbwBar, 0, LV_ANIM_OFF);
|
||||
lv_obj_add_flag(g_bbwBar, LV_OBJ_FLAG_HIDDEN);
|
||||
// Normalschriften merken, damit der Bezugsmodus sie wieder herstellen kann
|
||||
g_shotFontNormal = lv_obj_get_style_text_font(lblShotTimer, LV_PART_MAIN);
|
||||
g_bezugFontNormal = lv_obj_get_style_text_font(lblBezug, LV_PART_MAIN);
|
||||
|
||||
cellFlow = infoCell(ir, "FLOW", &lblFlow, lv_color_hex(0x64b5f6));
|
||||
lv_obj_add_flag(cellFlow, LV_OBJ_FLAG_CLICKABLE); // antippbar -> Brew-Control
|
||||
lv_obj_add_event_cb(cellFlow, brew_cell_cb, LV_EVENT_CLICKED, nullptr);
|
||||
@@ -2913,11 +3043,12 @@ static void build_info(lv_obj_t* p) {
|
||||
static void stats_request() {
|
||||
if (!g_client) return;
|
||||
if (g_statSummary) label_set_if_changed(g_statSummary, "Lade Statistik...");
|
||||
if (g_statList) label_set_if_changed(g_statList, "");
|
||||
stat_list_finish(0);
|
||||
g_client->sendGetUsageStats();
|
||||
}
|
||||
static void stats_refresh_cb(lv_event_t*) { stats_request(); }
|
||||
|
||||
|
||||
static void build_stats(lv_obj_t* p) {
|
||||
lv_obj_set_scroll_dir(p, LV_DIR_VER);
|
||||
lv_obj_set_scrollbar_mode(p, LV_SCROLLBAR_MODE_AUTO);
|
||||
@@ -2942,15 +3073,7 @@ static void build_stats(lv_obj_t* p) {
|
||||
|
||||
// Letzte Einzelbezuege
|
||||
section_title(p, "Letzte Bezüge");
|
||||
lv_obj_t* lc = th_card(p);
|
||||
lv_obj_set_width(lc, LV_PCT(100));
|
||||
lv_obj_set_height(lc, LV_SIZE_CONTENT);
|
||||
lv_obj_set_flex_flow(lc, LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_clear_flag(lc, LV_OBJ_FLAG_SCROLLABLE);
|
||||
g_statList = lv_label_create(lc);
|
||||
lv_obj_set_width(g_statList, LV_PCT(100));
|
||||
lv_label_set_text(g_statList, "");
|
||||
lv_obj_set_style_text_color(g_statList, COL_TEXT_DIM, 0);
|
||||
stat_list_build(p);
|
||||
}
|
||||
|
||||
// =====================================================================================
|
||||
@@ -3659,6 +3782,43 @@ static void ready_band_update(const MachineState& st) {
|
||||
lv_obj_set_style_bg_opa(g_readyBand, LV_OPA_COVER, 0);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
// Bezugsanzeige: die untere Zeile wechselt ihren Zustand
|
||||
//
|
||||
// Im Ruhezustand ist der Temperaturbereich das Wichtigste - die haeufigste Frage lautet
|
||||
// "ist sie bereit?". Waehrend eines Bezugs kehrt sich das um: Dann zaehlen Zeit und
|
||||
// Gewicht, und die Kesseltemperaturen sind Nebensache. Statt zweier getrennter Ansichten
|
||||
// verschiebt die Seite nur das Gewicht zwischen ihren beiden Bereichen und vergroessert
|
||||
// die beiden Zahlen, auf die es dann ankommt.
|
||||
//
|
||||
// Der Wechsel haelt nach dem Bezug noch kurz an. Ohne dieses Nachhalten wuerde die Seite
|
||||
// bei jeder kurzen Unterbrechung hin- und herspringen - das waere unruhiger als gar kein
|
||||
// Wechsel.
|
||||
// ------------------------------------------------------------------------------------
|
||||
#define DASH_BREW_HOLD_MS 4000
|
||||
|
||||
static void dash_brew_mode(bool on) {
|
||||
if (on == g_dashBrewMode) return; // nur bei echtem Wechsel neu anordnen
|
||||
g_dashBrewMode = on;
|
||||
if (!g_tempRow || !g_infoRow) return;
|
||||
lv_obj_set_flex_grow(g_tempRow, on ? 1 : 3);
|
||||
lv_obj_set_flex_grow(g_infoRow, on ? 3 : 2);
|
||||
if (lblShotTimer && g_shotFontNormal)
|
||||
lv_obj_set_style_text_font(lblShotTimer, on ? &lv_font_maven_pro_bold_96 : g_shotFontNormal, 0);
|
||||
if (lblBezug && g_bezugFontNormal)
|
||||
lv_obj_set_style_text_font(lblBezug, on ? &lv_font_maven_pro_bold_96 : g_bezugFontNormal, 0);
|
||||
}
|
||||
|
||||
static void dash_brew_mode_tick(const MachineState& st) {
|
||||
static bool war = false; // schon einmal ein Bezug gesehen?
|
||||
static uint32_t zuletzt = 0;
|
||||
bool aktiv = st.shotActive || st.steamCircuitActive;
|
||||
uint32_t jetzt = lv_tick_get();
|
||||
if (aktiv) { war = true; zuletzt = jetzt; }
|
||||
dash_brew_mode(aktiv || (war && (uint32_t)(jetzt - zuletzt) < DASH_BREW_HOLD_MS));
|
||||
}
|
||||
|
||||
void ui_update(const MachineState& st) {
|
||||
if (!g_uiReady) return;
|
||||
|
||||
@@ -3999,6 +4159,7 @@ void ui_update(const MachineState& st) {
|
||||
temp_progress_set(barDutyD, arcTempD, bulbTempD, pctD, colD);
|
||||
}
|
||||
ready_band_update(st);
|
||||
dash_brew_mode_tick(st);
|
||||
if (false) {
|
||||
}
|
||||
}
|
||||
@@ -4377,13 +4538,13 @@ void ui_set_usage_stats(const String& json) {
|
||||
JsonDocument doc;
|
||||
if (deserializeJson(doc, json)) {
|
||||
label_set_if_changed(g_statSummary, "Statistik konnte nicht gelesen werden.");
|
||||
if (g_statList) label_set_if_changed(g_statList, "");
|
||||
stat_list_finish(0);
|
||||
return;
|
||||
}
|
||||
bool avail = doc["available"] | false;
|
||||
if (!avail) {
|
||||
label_set_if_changed(g_statSummary, "Noch keine Nutzungsdaten vorhanden.");
|
||||
if (g_statList) label_set_if_changed(g_statList, "");
|
||||
stat_list_finish(0);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4392,8 +4553,7 @@ void ui_set_usage_stats(const String& json) {
|
||||
long week = doc["week"] | 0;
|
||||
bool partial = doc["partial"] | false;
|
||||
|
||||
// Liste + Mittelwert der angezeigten Bezuege aufbauen
|
||||
String l;
|
||||
// Mittelwert der angezeigten Bezuege; die Liste fuellt stat_list_set()
|
||||
int n = 0;
|
||||
float durSum = 0.0f;
|
||||
int nDur = 0; // Anzahl der Bezuege, die in den Mittelwert eingehen (ohne kalte)
|
||||
@@ -4402,10 +4562,7 @@ void ui_set_usage_stats(const String& json) {
|
||||
float d = v["d"] | 0.0f;
|
||||
float w = v["w"] | -1.0f;
|
||||
bool cold = v["cx"] | false; // kalte Extraktion (fehlt bei S3-FW < 5.3.0)
|
||||
if (n > 0) l += "\n";
|
||||
l += String(dt) + " " + String(d, 1) + " s";
|
||||
if (w >= 0.0f) l += " " + String(w, 1) + " g";
|
||||
if (cold) l += " (kalt)";
|
||||
stat_list_set(n, dt, d, w, cold);
|
||||
// Minutenlange kalte Bezuege wuerden den Mittelwert unbrauchbar machen -> raus
|
||||
// (gleiche Regel wie in der S3-Statistik)
|
||||
if (!cold) { durSum += d; nDur++; }
|
||||
@@ -4423,10 +4580,7 @@ void ui_set_usage_stats(const String& json) {
|
||||
}
|
||||
label_set_if_changed(g_statSummary, s.c_str());
|
||||
|
||||
if (g_statList) {
|
||||
if (n == 0) l = "Keine Einzelbezüge vorhanden.";
|
||||
label_set_if_changed(g_statList, l.c_str());
|
||||
}
|
||||
stat_list_finish(n);
|
||||
}
|
||||
|
||||
void ui_set_wifi_networks(const String& json) {
|
||||
|
||||
Reference in New Issue
Block a user