#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 #include #include #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;