Add PlatformIO project for the ESP32-2432S028R that: - Reads ThermoPro BLE BBQ thermometers via NimBLE-Arduino - Exposes /api/health, /api/latest, and /api/settings HTTP endpoints - Serves a captive-portal setup UI and touch dashboard - Persists WiFi/BLE/settings in NVS via Preferences Builds cleanly with pio run.
128 lines
3.4 KiB
C++
128 lines
3.4 KiB
C++
#include "WiFiManager.hpp"
|
|
|
|
namespace cyd {
|
|
|
|
WiFiManager::WiFiManager(SettingsManager& settings) : settings_(settings) {
|
|
}
|
|
|
|
void WiFiManager::begin() {
|
|
WiFi.disconnect(true);
|
|
delay(100);
|
|
|
|
if (settings_.hasWifiCredentials()) {
|
|
Serial.printf("WiFiManager: loaded SSID '%s', connecting...\n", settings_.getWifiSsid().c_str());
|
|
startStation_();
|
|
} else {
|
|
Serial.println("WiFiManager: no credentials stored, starting setup AP");
|
|
startAccessPoint_();
|
|
}
|
|
}
|
|
|
|
void WiFiManager::update() {
|
|
switch (state_) {
|
|
case State::Uninitialized:
|
|
break;
|
|
|
|
case State::Connecting:
|
|
if (WiFi.status() == WL_CONNECTED) {
|
|
Serial.printf("WiFiManager: connected, IP %s\n", WiFi.localIP().toString().c_str());
|
|
state_ = State::StationConnected;
|
|
if (modeCallback_) {
|
|
modeCallback_(false);
|
|
}
|
|
return;
|
|
}
|
|
if (millis() - connectStartMillis_ > kConnectTimeoutMs) {
|
|
Serial.println("WiFiManager: station connection timeout");
|
|
WiFi.disconnect(true);
|
|
state_ = State::StationFailed;
|
|
startAccessPoint_();
|
|
}
|
|
break;
|
|
|
|
case State::StationConnected:
|
|
if (WiFi.status() != WL_CONNECTED) {
|
|
Serial.println("WiFiManager: station lost connection, retrying");
|
|
state_ = State::Connecting;
|
|
connectStartMillis_ = millis();
|
|
WiFi.reconnect();
|
|
}
|
|
break;
|
|
|
|
case State::AccessPoint:
|
|
case State::FallbackToAp:
|
|
if (apRunning_) {
|
|
dnsServer_.processNextRequest();
|
|
}
|
|
break;
|
|
|
|
case State::StationFailed:
|
|
// Should have transitioned to AP above.
|
|
break;
|
|
}
|
|
}
|
|
|
|
String WiFiManager::getIpAddress() const {
|
|
if (isApMode()) {
|
|
return WiFi.softAPIP().toString();
|
|
}
|
|
if (state_ == State::StationConnected) {
|
|
return WiFi.localIP().toString();
|
|
}
|
|
return "0.0.0.0";
|
|
}
|
|
|
|
void WiFiManager::enterSetupMode() {
|
|
if (state_ == State::StationConnected || state_ == State::Connecting) {
|
|
WiFi.disconnect(true);
|
|
}
|
|
startAccessPoint_();
|
|
}
|
|
|
|
void WiFiManager::configureAndConnect(const String& ssid, const String& pass) {
|
|
settings_.setWifiSsid(ssid);
|
|
settings_.setWifiPass(pass);
|
|
settings_.save();
|
|
stopAccessPoint_();
|
|
startStation_();
|
|
}
|
|
|
|
void WiFiManager::startStation_() {
|
|
state_ = State::Connecting;
|
|
connectStartMillis_ = millis();
|
|
|
|
WiFi.mode(WIFI_STA);
|
|
WiFi.begin(settings_.getWifiSsid().c_str(), settings_.getWifiPass().c_str());
|
|
|
|
if (modeCallback_) {
|
|
modeCallback_(false);
|
|
}
|
|
}
|
|
|
|
void WiFiManager::startAccessPoint_() {
|
|
state_ = State::AccessPoint;
|
|
|
|
WiFi.mode(WIFI_AP);
|
|
WiFi.softAP(kApSsid, kApPass);
|
|
|
|
IPAddress ip = WiFi.softAPIP();
|
|
Serial.printf("WiFiManager: AP '%s' started at %s\n", kApSsid, ip.toString().c_str());
|
|
|
|
// DNS redirect: any hostname requested while connected to the AP resolves
|
|
// to the CYD. The HTTP server in ApiServer serves the setup page at /.
|
|
dnsServer_.start(53, "*", ip);
|
|
apRunning_ = true;
|
|
|
|
if (modeCallback_) {
|
|
modeCallback_(true);
|
|
}
|
|
}
|
|
|
|
void WiFiManager::stopAccessPoint_() {
|
|
apRunning_ = false;
|
|
dnsServer_.stop();
|
|
WiFi.softAPdisconnect(true);
|
|
}
|
|
|
|
} // namespace cyd
|