// ============================================================================= // wifi_connector.cpp – WiFi-Verbindungsmanagement via WiFiManager // ============================================================================= #include "wifi_connector.h" // Globale Instanz WifiConnector wifiConnector; // Static-Member Initialisierung WifiConnector* WifiConnector::_instance = nullptr; // --------------------------------------------------------------------------- WifiConnector::WifiConnector() : _cb(nullptr) , _status(WifiStatus::DISCONNECTED) , _lastConnectedMs(0) { _apPassword[0] = '\0'; _instance = this; } // --------------------------------------------------------------------------- void WifiConnector::setApPassword(const char* password) { strlcpy(_apPassword, password, sizeof(_apPassword)); } // --------------------------------------------------------------------------- void WifiConnector::onStatusChange(WifiStatusCallback cb) { _cb = cb; } // --------------------------------------------------------------------------- void WifiConnector::setStatus(WifiStatus s) { if (s == _status) return; _status = s; if (_cb) _cb(s); } // --------------------------------------------------------------------------- void WifiConnector::_onApStarted() { if (_instance) { _instance->setStatus(WifiStatus::AP_ACTIVE); LOG_I("WIFI", "Konfigurations-Portal gestartet – AP: %s", WIFI_AP_NAME); LOG_I("WIFI", "Verbinde mit AP und oeffne http://192.168.4.1"); } } void WifiConnector::_onApStopped() { if (_instance) { LOG_I("WIFI", "Konfigurations-Portal beendet"); } } // --------------------------------------------------------------------------- void WifiConnector::begin() { LOG_I("WIFI", "Starte WiFiManager (AP: %s, Timeout: %d s)", WIFI_AP_NAME, WIFI_AP_TIMEOUT_S); setStatus(WifiStatus::CONNECTING); WiFiManager wm; // Callbacks registrieren wm.setAPCallback([](WiFiManager*) { WifiConnector::_onApStarted(); }); wm.setSaveConfigCallback([]() { WifiConnector::_onApStopped(); }); // Portal-Timeout: nach WIFI_AP_TIMEOUT_S Sekunden ohne Konfiguration → Neustart wm.setConfigPortalTimeout(WIFI_AP_TIMEOUT_S); // Debug-Ausgabe des WiFiManagers unterdrücken (nutzen eigene Logs) wm.setDebugOutput(false); // Verbinden – blockiert bis Erfolg oder Timeout bool connected = (_apPassword[0] != '\0') ? wm.autoConnect(WIFI_AP_NAME, _apPassword) : wm.autoConnect(WIFI_AP_NAME); if (connected) { setStatus(WifiStatus::CONNECTED); _lastConnectedMs = millis(); LOG_I("WIFI", "Verbunden mit: %s", WiFi.SSID().c_str()); LOG_I("WIFI", "IP-Adresse : %s", WiFi.localIP().toString().c_str()); LOG_I("WIFI", "RSSI : %d dBm", WiFi.RSSI()); } else { LOG_E("WIFI", "Timeout – starte ESP32 neu ..."); delay(1000); ESP.restart(); } } // --------------------------------------------------------------------------- void WifiConnector::loop() { if (_status == WifiStatus::CONNECTED && WiFi.status() != WL_CONNECTED) { LOG_E("WIFI", "Verbindung verloren – versuche Reconnect ..."); setStatus(WifiStatus::DISCONNECTED); } if (_status == WifiStatus::DISCONNECTED) { setStatus(WifiStatus::CONNECTING); // WiFi.reconnect() reicht bei kurzen Unterbrechungen WiFi.reconnect(); uint32_t start = millis(); while (WiFi.status() != WL_CONNECTED && millis() - start < 15000) { delay(500); } if (WiFi.status() == WL_CONNECTED) { setStatus(WifiStatus::CONNECTED); LOG_I("WIFI", "Reconnect erfolgreich – IP: %s", WiFi.localIP().toString().c_str()); } else { LOG_E("WIFI", "Reconnect fehlgeschlagen – starte neu ..."); delay(1000); ESP.restart(); } } } // --------------------------------------------------------------------------- void WifiConnector::printToSerial() const { LOG_I("WIFI", "=== WiFi-Status ==="); switch (_status) { case WifiStatus::DISCONNECTED: LOG_I("WIFI", " Status : DISCONNECTED"); break; case WifiStatus::AP_ACTIVE: LOG_I("WIFI", " Status : AP_ACTIVE (%s)", WIFI_AP_NAME); break; case WifiStatus::CONNECTING: LOG_I("WIFI", " Status : CONNECTING"); break; case WifiStatus::CONNECTED: LOG_I("WIFI", " Status : CONNECTED"); LOG_I("WIFI", " SSID : %s", WiFi.SSID().c_str()); LOG_I("WIFI", " IP : %s", WiFi.localIP().toString().c_str()); LOG_I("WIFI", " RSSI : %d dBm", WiFi.RSSI()); break; } LOG_I("WIFI", "==================="); } // --------------------------------------------------------------------------- void WifiConnector::resetCredentials() { WiFiManager wm; wm.resetSettings(); LOG_I("WIFI", "WiFi-Credentials geloescht – AP wird beim naechsten Start geoeffnet"); }