#pragma once // ============================================================================= // laser_tracker.h - Laser-Signaldetektion, Debounce & Zeitmessung // Projekt: MQTT-Display LaserCutter // // Zwei getrennte Zeitkreise: // SESSION (RAM, reset bei Neustart / resetSession()): // Minuten-Anzeige auf dem Display. Akkumuliert Netto-Sekunden aller // Sessions der aktuellen Betriebssitzung. // Jede Session startet mit einem Gratis-Countdown. // Erst nach Ablauf der Gratiszeit zaehlt die Zeit zur Session. // Minuten-Inkrement: erst nach vollen 60 Netto-Sekunden (hart). // // GESAMT (NVS, persistiert): // Lifetime-Gesamtzeit fuer Wartungsstatistiken / Web-UI. // Wird nur nach jeder abgeschlossenen Session aktualisiert. // Wird NICHT auf dem Display angezeigt. // // Anzeige-Logik: // Module 1-3 (oben): getAllSessionsSumMinutes() - Summe aller Sessions seit Reset // Module 5-7 (unten): getCountdownRemaining() > 0 -> Countdown anzeigen // sonst -> showIdle() // // Verwendung: // laserTracker.begin(); // einmalig in setup() // laserTracker.loop(); // in jedem loop()-Aufruf // laserTracker.getAllSessionsSumMinutes(); // fuer Display Module 1-3 // laserTracker.getCountdownRemaining();// fuer Display Module 5-7 // laserTracker.resetSession(); // per MQTT / Web-Reset // ============================================================================= #include #include #include "config.h" #include "settings.h" // Session-Zustaende (eine "Session" = ein Laser-AN-Ereignis) enum class SessionState { INACTIVE, // Laser aus GRATIS, // Laser an, Gratiszeit laeuft NET_COUNTING, // Laser an, Gratiszeit abgelaufen, Netto-Zeit wird gezaehlt }; class LaserTracker { public: LaserTracker(); // GPIO konfigurieren, NVS laden (einmalig in setup()) void begin(); // Debounce + Burst-Zustandsmaschine - in jedem loop()-Aufruf aufrufen void loop(); // ---- Display-Getter ----------------------------------------------------- // Summe aller Sessions seit Neustart/resetSession() in ganzen Minuten // Entspricht: Summe Netto-Sekunden aller Sessions / 60 (hart, ganzzahlig) int getAllSessionsSumMinutes() const; // Verbleibende Gratiszeit des aktuellen Bursts in Sekunden // 0 wenn: Gratiszeit abgelaufen, Laser aus, oder NET_COUNTING int getCountdownRemaining() const; // ---- Zustandsabfragen --------------------------------------------------- // true = Laser ist physisch aktiv (nach Debounce) bool isActive() const; // Lifetime-Gesamtzeit aus NVS (fuer Web-UI / MQTT, nicht fuer Display) float getTotalMinutes() const; // Netto-Sekunden des zuletzt abgeschlossenen Session (fuer MQTT Publish) int getLastSessionSeconds() const; // Laufende Netto-Sekunden der aktuellen Session (live, waehrend NET_COUNTING) // 0 wenn GRATIS oder INACTIVE int getRunningSessionSeconds() const; // Unix-Timestamp (UTC) des letzten Session-Starts (0 wenn noch keine Session) time_t getSessionStartTime() const; // ---- Reset -------------------------------------------------------------- // Session-Minuten auf 0 (RAM). NVS-Gesamtzeit bleibt unveraendert. // Aufruf: automatisch in begin(), spaeter per MQTT oder Weboberflaeche. void resetSession(); // Gesamtzeit (NVS + RAM-Session) auf 0 zuruecksetzen (Wartungsreset) void resetTotal(); // Prueft ob seit dem letzten Aufruf eine Session beendet wurde ("consume"). // Gibt true zurueck, wenn eine neue Session abgeschlossen ist – danach // kann getLastSessionSeconds() + getTotalMinutes() sicher gelesen werden. // Wird in main.cpp fuer mqttClient.publishSession() verwendet. bool consumeSessionEnd(); // Debug-Ausgabe auf Serial void printToSerial() const; private: // ---- Debounce ----------------------------------------------------------- bool _debouncedActive; // bestaedigter Laser-Zustand bool _pendingActive; // zu bestaetigender Zustand bool _debounceRunning; // laeuft gerade ein Debounce-Fenster uint32_t _debounceStartMs; // ---- Session-Zustand --------------------------------------------------- SessionState _state; // aktueller Session-Zustand uint32_t _sessionStartMs; // millis() beim Laser-AN (Session-Start) time_t _sessionStartTime; // Unix-Timestamp (UTC) beim Laser-AN uint32_t _netStartMs; // millis() beim Uebergang GRATIS -> NET_COUNTING // ---- Zeitakkumulatoren -------------------------------------------------- int _sessionNetSec; // Netto-Sekunden der Session (RAM, 0 nach begin/resetSession) int _sessionNetMin; // Aufgerundete Minuten je Session aufsummiert (Ceiling pro Session) float _totalMinutesBase; // NVS-Gesamtzeit (nach jedem Burst aktualisiert) int _lastSessionSec; // Netto-Sekunden der letzten abgeschlossenen Session bool _sessionEndPending; // true = Session gerade beendet, noch nicht consumed // ---- Hilfsmethoden ------------------------------------------------------ bool readRaw() const; // GPIO lesen + Polaritaet anwenden void onSessionStart(); // Laser AN (nach Debounce) void onSessionEnd(); // Laser AUS (nach Debounce) int gratisSeconds() const; // Gratiszeit aus Settings // Laufende Netto-Sekunden der aktuellen Session (0 wenn GRATIS oder INACTIVE) int currentSessionNetSec() const; }; // Globale Instanz extern LaserTracker laserTracker;