MQTT-Display-LaserCutter/include/laser_tracker.h
MaPaLo76 d114a58de6 fix(phase5): LaserTracker neu - Session/Burst-Logik korrigiert
- BurstState-Maschine: INACTIVE -> GRATIS -> NET_COUNTING
- _sessionNetSec (RAM): Netto-Sekunden der Betriebssitzung, reset beim Start
- _totalMinutesBase (NVS via settings.saveTotalMinutes): persistierte Gesamtzeit
- Gratis-Countdown startet bei JEDEM Laser-AN-Ereignis neu
- Netto-Zeit wird erst nach Ablauf der Gratiszeit gezaehlt
- getSessionMinutes(): sessionNetSec / 60 (ganzzahlig, hart)
- getCountdownRemaining(): nur 0 wenn INACTIVE oder NET_COUNTING
- Display Module 1-3: Session-Minuten (nicht Gesamtzeit)
- Display Module 5-7: Countdown waehrend GRATIS, sonst Idle
- settings.saveTotalMinutes() statt direkter Preferences-Calls
- main.cpp + test_laser_tracker.cpp auf neue API umgestellt
2026-02-22 18:48:35 +01:00

115 lines
4.6 KiB
C++

#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
// Laser-Bursts der aktuellen Betriebssitzung.
// Jeder Laser-Burst 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 jedem Laser-Burst aktualisiert.
// Wird NICHT auf dem Display angezeigt.
//
// Anzeige-Logik:
// Module 1-3 (oben): getSessionMinutes() - ganze Minuten der Session
// Module 5-7 (unten): getCountdownRemaining() > 0 -> Countdown anzeigen
// sonst -> showIdle()
//
// Verwendung:
// laserTracker.begin(); // einmalig in setup()
// laserTracker.loop(); // in jedem loop()-Aufruf
// laserTracker.getSessionMinutes(); // fuer Display Module 1-3
// laserTracker.getCountdownRemaining();// fuer Display Module 5-7
// laserTracker.resetSession(); // per MQTT / Web-Reset
// =============================================================================
#include <Arduino.h>
#include "config.h"
#include "settings.h"
// Interne Burst-Zustaende (ein "Burst" = ein Laser-AN-Ereignis)
enum class BurstState {
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 -----------------------------------------------------
// Session-Minuten (hart, ganzzahlig): SessionNetSekunden / 60
// Startet bei 0 nach Neustart oder resetSession()
int getSessionMinutes() 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 Bursts (fuer MQTT Publish)
int getLastBurstSeconds() 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();
// 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;
// ---- Burst-Zustand ------------------------------------------------------
BurstState _burst; // aktueller Burst-State
uint32_t _burstStartMs; // millis() beim Laser-AN (Burst-Start)
uint32_t _netStartMs; // millis() beim Uebergang GRATIS -> NET_COUNTING
// ---- Zeitakkumulatoren --------------------------------------------------
int _sessionNetSec; // Netto-Sekunden der Session (RAM, 0 nach begin/resetSession)
float _totalMinutesBase; // NVS-Gesamtzeit (nach jedem Burst aktualisiert)
int _lastBurstSec; // Netto-Sekunden des letzten abgeschlossenen Bursts
// ---- Hilfsmethoden ------------------------------------------------------
bool readRaw() const; // GPIO lesen + Polaritaet anwenden
void onBurstStart(); // Laser AN (nach Debounce)
void onBurstEnd(); // Laser AUS (nach Debounce)
int gratisSeconds() const; // Gratiszeit aus Settings
// Laufende Netto-Sekunden des aktuellen Bursts (0 wenn GRATIS oder INACTIVE)
int currentBurstNetSec() const;
};
// Globale Instanz
extern LaserTracker laserTracker;