MQTT-Display-LaserCutter/include/wifi_connector.h
MaPaLo76 974616aee2 refactor(wifi): non-blocking WiFi-Architektur (Proposal B+D)
- WiFiManager als Pointer, lazy new in begin() verhindert Crash durch
  globale Konstruktoren vor Arduino-Framework-Init
- WiFi.mode(WIFI_STA) vor Credentials-Pruefung; getWiFiSSID(true) statt
  WiFi.SSID() (erfordert gestarteten Stack)
- Credentials vorhanden: WiFi.begin() non-blocking, Ergebnis in loop()
- Keine Credentials: setConfigPortalBlocking(false) + process() in loop()
- Nach 3 Fehlversuchen: startConfigPortal() automatisch
- onConnect(): stopWebPortal() vor AsyncWebServer-Start (Port-80-Konflikt)
- main.cpp: LaserTracker startet vor WiFi (Prioritaet 1)
- MQTT + WebServer: Lazy-Init beim ersten WiFi-Connect
- Display rate-limited: W 500ms-Blinker, Minuten 60s, Sekunden 1s, M bei Aenderung
- Manuell getestet: LaserTracker laeuft sofort, WiFi non-blocking verifiziert
2026-02-26 21:05:22 +01:00

97 lines
3.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
// =============================================================================
// wifi_connector.h WiFi-Verbindungsmanagement via WiFiManager
// Projekt: MQTT-Display LaserCutter
//
// Design-Prinzip: begin() ist vollständig NON-BLOCKING.
// LaserTracker und Display laufen sofort nach begin() kein Warten auf WiFi.
//
// Zwei Startszenarien:
// 1) Credentials gespeichert → WiFi.begin() direkt, Ergebnis in loop() prüfen
// 2) Keine Credentials → Captive Portal sofort async öffnen, loop() ruft
// wm.process() auf bis User Daten eingibt
//
// Verwendung:
// wifi.onStatusChange(myCallback); // optional, vor begin()
// wifi.begin(); // KEhrt sofort zurück (non-blocking)
// // in loop():
// wifi.loop(); // Reconnect + Portal-Processing
// if (wifi.isConnected()) { ... }
// =============================================================================
#include <Arduino.h>
#include <WiFi.h>
#include <WiFiManager.h>
#include "config.h"
// ---------------------------------------------------------------------------
// Verbindungsstatus
// ---------------------------------------------------------------------------
enum class WifiStatus {
DISCONNECTED, // Nicht verbunden, kein AP aktiv
AP_ACTIVE, // Konfigurations-Portal läuft (AP-Modus)
CONNECTING, // Verbindungsversuch läuft
CONNECTED // Verbunden mit WLAN
};
// Callback-Typ: wird bei Statusänderungen aufgerufen
using WifiStatusCallback = void (*)(WifiStatus newStatus);
// ---------------------------------------------------------------------------
// WifiConnector
// ---------------------------------------------------------------------------
class WifiConnector {
public:
WifiConnector();
// Optionaler AP-Passwortschutz (Standard: kein Passwort)
void setApPassword(const char* password);
// Callback vor begin() registrieren
void onStatusChange(WifiStatusCallback cb);
// WiFi starten NICHT blockierend, kehrt sofort zurück.
// Hat das Gerät Credentials: startet WiFi.begin() im Hintergrund.
// Hat es keine Credentials: öffnet Captive Portal asynchron.
void begin();
// In loop() aufrufen: Portal-Processing + Verbindungscheck + Reconnect.
// Darf niemals lange blockieren.
void loop();
// Aktuellen Status abfragen
WifiStatus getStatus() const { return _status; }
bool isConnected() const { return _status == WifiStatus::CONNECTED; }
bool isPortalActive() const { return _portalRunning; }
IPAddress getIP() const { return WiFi.localIP(); }
String getSSID() const { return WiFi.SSID(); }
int8_t getRSSI() const { return WiFi.RSSI(); }
// Debug-Ausgabe auf Serial
void printToSerial() const;
// Gespeicherte WiFi-Credentials löschen (zwingt den AP beim nächsten Start)
void resetCredentials();
private:
WiFiManager* _wm; // lazy-konstruiert in begin() (nicht global!)
WifiStatusCallback _cb;
WifiStatus _status;
char _apPassword[32];
uint32_t _lastReconnectMs; // Zeitstempel letzter Reconnect-Versuch
bool _portalRunning; // Captive Portal aktiv
uint8_t _failCount; // Anzahl fehlgeschlagener Verbindungsversuche
void setStatus(WifiStatus s);
void onConnect(); // NTP + Log bei jedem Verbindungsaufbau
// Callbacks für WiFiManager (static nötig, C-Funktionszeiger)
static WifiConnector* _instance;
static void _onApStarted();
static void _onApStopped();
};
// Globale Instanz
extern WifiConnector wifiConnector;