Files
Dual-PID/JC_Display_Firmware/machine_state.h
T
raw-designsandClaude Fable 5 d97e4c34d5 feat(P4): Profil-Schnellwahl im Header + Anzeige des aktiven Profils
Neuer Profil-Chip im Header (alle Seiten): zeigt das zuletzt geladene
bzw. gespeicherte Profil aus den neuen S3-State-Feldern profile/profDirty
(S3 ab 5.1.1), „*" = seitdem geänderte Einstellungen. Antippen öffnet
ein Schnellwahl-Overlay mit allen Profilen (aktives mit Häkchen und
Akzentfarbe); ein Tap lädt direkt per loadProfile. Profile-Seite
markiert das aktive Profil in der Liste. Bei älterer S3-Firmware bleibt
der Chip unsichtbar. Version 1.0.13, Protokoll-Doku ergänzt.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 20:55:10 +02:00

115 lines
5.8 KiB
C

// =====================================================================================
// machine_state.h - Spiegelbild des 'state'-Objekts der Hauptplatine
// =====================================================================================
// Enthaelt genau die Felder, die die S3 im 'state'-Push sendet
// (siehe buildTouchUartStateJson() bzw. Doku/JC-Display_UART-Protokoll.md, Abschnitt 5).
// Das Display haelt KEINEN abweichenden Zustand - es spiegelt nur.
// =====================================================================================
#pragma once
#include <Arduino.h>
struct MachineState {
// --- Meta ---
uint16_t protocolVersion = 0;
String firmwareVersion;
// --- Temperaturen ---
float tempW = 0, setW = 0; // Wasser ist/soll
float tempD = 0, setD = 0; // Dampf ist/soll
// --- Status ---
String statusText; // Klartext (DE)
String statusKey; // sprachneutral: ready/error/standby/maintenance/...
bool wasserSensorError = false; // Wassersensor liefert ungueltigen Wert
bool wasserSafetyShutdown = false; // Wassertemperatur ueber Sicherheitslimit -> Heizung aus
bool dampfSensorError = false; // Dampfsensor liefert ungueltigen Wert
bool dampfSafetyShutdown = false; // Dampftemperatur ueber Sicherheitslimit -> Heizung aus
bool shotActive = false;
uint32_t shotElapsedMs = 0;
bool scaleTaring = false; // Tarier-Phase vor einem Brew-by-Weight-Bezug laeuft
bool steamCircuitActive = false;
uint32_t steamElapsedMs = 0; // verstrichene Dampfbezugszeit (fuer rueckwirkende Timer-Kopplung)
bool steamFlushActive = false;
uint32_t steamFlushElapsedMs = 0; // verstrichene Dampf-Flush-Zeit (aus steamFlushEndTime, race-frei)
bool flushActive = false;
uint32_t flushElapsedMs = 0; // verstrichene Wasser-Flush-Zeit (fuer rueckwirkende Timer-Kopplung)
bool ecoActive = false;
long ecoCountdownSec = -1; // Sekunden bis automatische Eco-Aktivierung (-1 = kein Timer scharf)
bool ecoShowInfo = false; // S3-Einstellung "Eco-Info auf dem Display anzeigen"
bool standbyActive = false;
bool standbyShowClock = false; // S3-Einstellung "Uhrzeit im Standby anzeigen"
uint8_t backlightActive = 100; // Helligkeit % wenn Display aktiv (von S3 konfiguriert)
uint8_t backlightStandbyClock = 30;// Helligkeit % fuer Standby-Uhr (von S3 konfiguriert)
bool maintenanceActive = false;
bool steamHeatDisabled = false;
bool steamDelayActive = false; // Dampf-Startverzoegerung laeuft
long steamDelayRemainSec = 0; // verbleibende Sekunden der Startverzoegerung
int heatUpMinutes = 0; // konfigurierte Aufheizzeit (Minuten); 0 = aus
long heatUpRemainSec = -1; // verbleibende Sekunden bis "durchgewaermt" (-1 = aus)
bool lightOn = false;
bool piezoEnabled = false;
String activeProfile; // zuletzt geladenes/gespeichertes Profil (leer = keines; seit S3 5.1.1)
bool profileDirty = false; // Einstellungen weichen seit dem Laden vom Profil ab
// --- Waage ---
float weight = 0, targetWeight = 0;
float lastShotWeight = 0; // Endgewicht des letzten Bezugs inkl. Offset (fuer Shot-Zusammenfassung)
bool lastShotByWeight = false;// war der letzte Bezug gewichtsbasiert? (dann lastShotWeight statt weight anzeigen)
float flowRate = 0; // aktuelle Flussrate in g/s (waehrend Bezug)
bool scaleEnabled = false;
uint8_t scaleType = 0;
bool scaleConnected = false;
// --- Brew-Control ---
bool piEnabled = false, bbtEnabled = false, bbwEnabled = false, sbtEnabled = false;
float bbtSecs = 0, sbtSecs = 0, piDurSecs = 0, piPauseSecs = 0;
float bbwTarget = 0, bbwOffset = 0;
uint8_t piState = 0; // Pre-Infusion-Phase (0=inaktiv,1=Pre-Infusion,2=Pause,3=Hauptbezug; seit S3 5.0.12)
// --- Gehaeusesensor ---
bool caseSensorEnabled = false;
bool caseTempDashboard = false;
uint8_t caseSensorType = 0; // 0 = Gehaeuse, 1 = Tassenablage
bool hasCaseTemp = false; // false => caseTemp war null
float caseTemp = 0;
// --- Service ---
int maintenanceInterval = 0;
uint32_t maintenanceIntervalCounter = 0;
uint8_t flushDurationSeconds = 0;
uint8_t steamFlushDurationSeconds = 0;
// --- Reinigungsassistent (Live-Status + Parameter) ---
bool cleaningActive = false;
bool cleaningWaiting = false; // heizt noch auf 93 C vor
bool cleaningBrewPhase = false; // true = Bezug, false = Pause
uint8_t cleaningCycle = 0; // aktueller Zyklus
uint8_t cleaningCycles = 0; // Gesamtzahl Zyklen
uint8_t cleaningBrewSeconds = 0; // Bezugsdauer je Zyklus
uint8_t cleaningPauseSeconds = 0; // Pausendauer je Zyklus
long cleaningPhaseRemainSec = 0; // verbleibende Sekunden der aktuellen Phase
// --- v2: Heizleistung / PID / AutoTune ---
float dutyW = 0, dutyD = 0;
float kpW = 0, kiW = 0, kdW = 0;
float kpD = 0, kiD = 0, kdD = 0;
bool autoTuneW = false, autoTuneD = false;
// Ergebnis/Grund des letzten Tuning-Laufs (0=Idle,1=laeuft,2=Erfolg,3=Failsafe,
// 4=degeneriert,5=Sensorfehler,6=Sicherheitsabsch.,7=manuell)
uint8_t autoTuneWStatus = 0, autoTuneDStatus = 0;
// --- v2: Netzwerk ---
bool wifiConnected = false;
bool apMode = false;
String ip;
String ssid;
int rssi = 0;
String timeStr; // "HH:MM" wenn NTP synchronisiert, sonst leer
// --- Verbindungsstatus (lokal, nicht von der S3) ---
bool linkUp = false; // UART-Verbindung steht (hello bestaetigt)
unsigned long lastRxMs = 0; // letzte empfangene Nachricht
};