Skip to content

Commit f62458c

Browse files
committed
Extract WiFi config REST endpoints into WiFi Manager
1 parent eae2260 commit f62458c

5 files changed

Lines changed: 101 additions & 81 deletions

File tree

platformio.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ lib_deps =
1919
https://github.com/mathieucarbou/AsyncTCP.git#v3.2.4
2020
https://github.com/mathieucarbou/ESPAsyncWebServer.git#v3.1.5
2121
https://github.com/GuLinux/AsyncBufferedTcpLogger#v0.0.2
22-
https://github.com/GuLinux/AsyncWebserverUtils#v0.0.1
22+
https://github.com/GuLinux/AsyncWebserverUtils#v0.0.2
2323
ayushsharma82/ElegantOTA @ 3.1.1
2424
bblanchon/ArduinoJson@^7.2.0
2525
adafruit/Adafruit Unified Sensor@^1.1.14

src/webserver.cpp

Lines changed: 18 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -36,29 +36,29 @@ void APB::WebServer::setup() {
3636
ElegantOTA.onEnd([this](bool success){ Log.infoln(LOG_SCOPE "OTA Finished, success=%d", success); });
3737
Log.traceln(LOG_SCOPE "ElegantOTA setup");
3838

39-
onJsonRequest("/api/config/accessPoint", std::bind(&APB::WebServer::onConfigAccessPoint, this, _1, _2), HTTP_POST | HTTP_DELETE);
40-
onJsonRequest("/api/config/station", std::bind(&APB::WebServer::onConfigStation, this, _1, _2), HTTP_POST | HTTP_DELETE);
41-
onJsonRequest("/api/config/statusLedDuty", std::bind(&APB::WebServer::onConfigStatusLedDuty, this, _1, _2), HTTP_POST);
42-
server.on("/api/metrics", HTTP_GET, std::bind(&APB::WebServer::onGetMetrics, this, _1));
43-
server.on("/api/config/write", HTTP_POST, std::bind(&APB::WebServer::onPostWriteConfig, this, _1));
44-
server.on("/api/config", HTTP_GET, std::bind(&APB::WebServer::onGetConfig, this, _1));
45-
server.on("/api/info", HTTP_GET, std::bind(&APB::WebServer::onGetESPInfo, this, _1));
46-
server.on("/api/history", HTTP_GET, std::bind(&APB::WebServer::onGetHistory, this, _1));
47-
server.on("/api/power", HTTP_GET, std::bind(&APB::WebServer::onGetPower, this, _1));
48-
server.on("/api/wifi/connect", HTTP_POST, std::bind(&APB::WebServer::onPostReconnectWiFi, this, _1));
39+
onJsonRequest("/api/config/accessPoint", std::bind(&WiFiManager::onConfigAccessPoint, &WiFiManager::Instance, _1, _2), HTTP_POST | HTTP_DELETE);
40+
onJsonRequest("/api/config/station", std::bind(&WiFiManager::onConfigStation, &WiFiManager::Instance, _1, _2), HTTP_POST | HTTP_DELETE);
41+
onJsonRequest("/api/config/statusLedDuty", std::bind(&WebServer::onConfigStatusLedDuty, this, _1, _2), HTTP_POST);
42+
server.on("/api/metrics", HTTP_GET, std::bind(&WebServer::onGetMetrics, this, _1));
43+
server.on("/api/config/write", HTTP_POST, std::bind(&WebServer::onPostWriteConfig, this, _1));
44+
server.on("/api/config", HTTP_GET, std::bind(&WebServer::onGetConfig, this, _1));
45+
server.on("/api/info", HTTP_GET, std::bind(&WebServer::onGetESPInfo, this, _1));
46+
server.on("/api/history", HTTP_GET, std::bind(&WebServer::onGetHistory, this, _1));
47+
server.on("/api/power", HTTP_GET, std::bind(&WebServer::onGetPower, this, _1));
48+
server.on("/api/wifi/connect", HTTP_POST, std::bind(&WiFiManager::onPostReconnectWiFi, &WiFiManager::Instance, _1));
4949
#ifdef CONFIGURATION_FOR_PROTOTYPE
5050
server.on("/api/wifi", HTTP_DELETE, [this](AsyncWebServerRequest *request){
5151
new Task(1'000, TASK_ONCE, [](){WiFi.disconnect();}, &scheduler, true);
5252
JsonResponse response(request);
5353
response.root()["status"] = "Dropping WiFi";
5454
});
5555
#endif
56-
server.on("/api/wifi", HTTP_GET, std::bind(&APB::WebServer::onGetWiFiStatus, this, _1));
57-
server.on("/api/restart", HTTP_POST, std::bind(&APB::WebServer::onRestart, this, _1));
56+
server.on("/api/wifi", HTTP_GET, std::bind(&WiFiManager::onGetWiFiStatus, &WiFiManager::Instance, _1));
57+
server.on("/api/restart", HTTP_POST, std::bind(&WebServer::onRestart, this, _1));
5858

59-
server.on("/api/status", HTTP_GET, std::bind(&APB::WebServer::onGetStatus, this, _1));
60-
server.on("/api/ambient", HTTP_GET, std::bind(&APB::WebServer::onGetAmbient, this, _1));
61-
server.on("/api/heaters", HTTP_GET, std::bind(&APB::WebServer::onGetHeaters, this, _1));
59+
server.on("/api/status", HTTP_GET, std::bind(&WebServer::onGetStatus, this, _1));
60+
server.on("/api/ambient", HTTP_GET, std::bind(&WebServer::onGetAmbient, this, _1));
61+
server.on("/api/heaters", HTTP_GET, std::bind(&WebServer::onGetHeaters, this, _1));
6262
server.serveStatic("/", LittleFS, "/web/").setDefaultFile("index.html");
6363
server.serveStatic("/static", LittleFS, "/web/static").setDefaultFile("index.html");
6464
server.addHandler(&events);
@@ -103,14 +103,9 @@ void APB::WebServer::onGetStatus(AsyncWebServerRequest *request) {
103103

104104
void APB::WebServer::onGetConfig(AsyncWebServerRequest *request) {
105105
JsonResponse response(request);
106-
response.root()["accessPoint"]["essid"] = Settings::Instance.wifi().apConfiguration().essid;
107-
response.root()["accessPoint"]["psk"] = Settings::Instance.wifi().apConfiguration().psk;
108-
for(uint8_t i=0; i<APB_MAX_STATIONS; i++) {
109-
auto station = Settings::Instance.wifi().station(i);
110-
response.root()["stations"][i]["essid"] = station.essid;
111-
response.root()["stations"][i]["psk"] = station.psk;
112-
}
113-
response.root()["ledDuty"] = Settings::Instance.statusLedDuty();
106+
JsonObject rootObject = response.root().to<JsonObject>();
107+
WiFiManager::Instance.onGetConfig(rootObject);
108+
rootObject["ledDuty"] = Settings::Instance.statusLedDuty();
114109
}
115110

116111
void APB::WebServer::onGetHistory(AsyncWebServerRequest *request) {
@@ -129,65 +124,12 @@ void APB::WebServer::onNotFound(AsyncWebServerRequest *request) {
129124
response.root()["url"] = request->url();
130125
}
131126

132-
void APB::WebServer::onConfigAccessPoint(AsyncWebServerRequest *request, JsonVariant &json) {
133-
if(request->method() == HTTP_DELETE) {
134-
Log.traceln(LOG_SCOPE "onConfigAccessPoint: method=%d (%s)", request->method(), request->methodToString());
135-
Settings::Instance.wifi().setAPConfiguration("", "");
136-
}
137-
if(request->method() == HTTP_POST) {
138-
if(Validation{request, json}.required<const char*>({"essid", "psk"}).notEmpty("essid").invalid()) return;
139-
140-
String essid = json["essid"];
141-
String psk = json["psk"];
142-
Log.traceln(LOG_SCOPE "onConfigAccessPoint: essid=%s, psk=%s, method=%d (%s)",
143-
essid.c_str(), psk.c_str(), request->method(), request->methodToString());
144-
Settings::Instance.wifi().setAPConfiguration(essid.c_str(), psk.c_str());
145-
146-
}
147-
onGetConfig(request);
148-
}
149-
150-
151-
152-
void APB::WebServer::onConfigStation(AsyncWebServerRequest *request, JsonVariant &json) {
153-
Validation validation{request, json};
154-
validation.required<int>("index").range("index", {0}, {APB_MAX_STATIONS-1});
155-
156-
if(request->method() == HTTP_POST) {
157-
validation.required<const char*>({"essid", "psk"}).notEmpty("essid");
158-
}
159-
if(validation.invalid()) return;
160-
int stationIndex = json["index"];
161-
String essid = json["essid"];
162-
String psk = json["psk"];
163-
Log.traceln(LOG_SCOPE "onConfigStation: `%d`, essid=`%s`, psk=`%s`, method=%d (%s)",
164-
stationIndex, essid.c_str(), psk.c_str(), request->method(), request->methodToString());
165-
if(request->method() == HTTP_POST) {
166-
Settings::Instance.wifi().setStationConfiguration(stationIndex, essid.c_str(), psk.c_str());
167-
} else if(request->method() == HTTP_DELETE) {
168-
Settings::Instance.wifi().setStationConfiguration(stationIndex, "", "");
169-
}
170-
onGetConfig(request);
171-
}
172127

173128
void APB::WebServer::onPostWriteConfig(AsyncWebServerRequest *request) {
174129
Settings::Instance.save();
175130
onGetConfig(request);
176131
}
177132

178-
void APB::WebServer::onGetWiFiStatus(AsyncWebServerRequest *request) {
179-
JsonResponse response(request);
180-
response.root()["wifi"]["status"] = WiFiManager::Instance.statusAsString();
181-
response.root()["wifi"]["essid"] = WiFiManager::Instance.essid();
182-
response.root()["wifi"]["ip"] = WiFiManager::Instance.ipAddress();
183-
response.root()["wifi"]["gateway"] = WiFiManager::Instance.gateway();
184-
}
185-
186-
void APB::WebServer::onPostReconnectWiFi(AsyncWebServerRequest *request) {
187-
WiFiManager::Instance.reconnect();
188-
onGetConfig(request);
189-
}
190-
191133
void APB::WebServer::onGetAmbient(AsyncWebServerRequest *request) {
192134
if(!Ambient::Instance.reading()) {
193135
JsonResponse::error(500, "Ambient reading not available", request);

src/webserver.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,12 @@ class WebServer {
2727
JsonDocument eventsDocument;
2828
std::array<char, 800> eventsString;
2929

30+
3031
void onGetStatus(AsyncWebServerRequest *request);
3132
void onGetConfig(AsyncWebServerRequest *request);
3233
void onGetHistory(AsyncWebServerRequest *request);
3334
void onNotFound(AsyncWebServerRequest *request);
34-
void onConfigStation(AsyncWebServerRequest *request, JsonVariant &json);
35-
void onConfigAccessPoint(AsyncWebServerRequest *request, JsonVariant &json);
3635
void onPostWriteConfig(AsyncWebServerRequest *request);
37-
void onPostReconnectWiFi(AsyncWebServerRequest *request);
38-
void onGetWiFiStatus(AsyncWebServerRequest *request);
3936
void onGetAmbient(AsyncWebServerRequest *request);
4037
void onGetPower(AsyncWebServerRequest *request);
4138
void onGetHeaters(AsyncWebServerRequest *request);

src/wifimanager.cpp

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#include "wifimanager.h"
22
#include <ArduinoLog.h>
33
#include <WiFi.h>
4+
#include <jsonresponse.h>
5+
#include <validation.h>
46

57
#define LOG_SCOPE "WiFiManager:"
68

@@ -175,3 +177,72 @@ String APB::WiFiManager::gateway() const {
175177
return "N/A";
176178
}
177179

180+
void APB::WiFiManager::onGetConfig(AsyncWebServerRequest *request) {
181+
JsonResponse response(request);
182+
auto rootObject = response.root().to<JsonObject>();
183+
onGetConfig(rootObject);
184+
}
185+
186+
void APB::WiFiManager::onGetConfig(JsonObject &responseObject) {
187+
responseObject["accessPoint"]["essid"] = wifiSettings->apConfiguration().essid;
188+
responseObject["accessPoint"]["psk"] = wifiSettings->apConfiguration().psk;
189+
for(uint8_t i=0; i<APB_MAX_STATIONS; i++) {
190+
auto station = Settings::Instance.wifi().station(i);
191+
responseObject["stations"][i]["essid"] = station.essid;
192+
responseObject["stations"][i]["psk"] = station.psk;
193+
}
194+
}
195+
196+
void APB::WiFiManager::onGetWiFiStatus(AsyncWebServerRequest *request) {
197+
JsonResponse response(request);
198+
response.root()["wifi"]["status"] = WiFiManager::Instance.statusAsString();
199+
response.root()["wifi"]["essid"] = WiFiManager::Instance.essid();
200+
response.root()["wifi"]["ip"] = WiFiManager::Instance.ipAddress();
201+
response.root()["wifi"]["gateway"] = WiFiManager::Instance.gateway();
202+
}
203+
204+
void APB::WiFiManager::onPostReconnectWiFi(AsyncWebServerRequest *request) {
205+
reconnect();
206+
onGetConfig(request);
207+
}
208+
209+
void APB::WiFiManager::onConfigAccessPoint(AsyncWebServerRequest *request, JsonVariant &json) {
210+
if(request->method() == HTTP_DELETE) {
211+
Log.traceln(LOG_SCOPE "onConfigAccessPoint: method=%d (%s)", request->method(), request->methodToString());
212+
Settings::Instance.wifi().setAPConfiguration("", "");
213+
}
214+
if(request->method() == HTTP_POST) {
215+
if(Validation{request, json}.required<const char*>({"essid", "psk"}).notEmpty("essid").invalid()) return;
216+
217+
String essid = json["essid"];
218+
String psk = json["psk"];
219+
Log.traceln(LOG_SCOPE "onConfigAccessPoint: essid=%s, psk=%s, method=%d (%s)",
220+
essid.c_str(), psk.c_str(), request->method(), request->methodToString());
221+
Settings::Instance.wifi().setAPConfiguration(essid.c_str(), psk.c_str());
222+
223+
}
224+
onGetConfig(request);
225+
}
226+
227+
228+
229+
void APB::WiFiManager::onConfigStation(AsyncWebServerRequest *request, JsonVariant &json) {
230+
Validation validation{request, json};
231+
validation.required<int>("index").range("index", {0}, {APB_MAX_STATIONS-1});
232+
233+
if(request->method() == HTTP_POST) {
234+
validation.required<const char*>({"essid", "psk"}).notEmpty("essid");
235+
}
236+
if(validation.invalid()) return;
237+
int stationIndex = json["index"];
238+
String essid = json["essid"];
239+
String psk = json["psk"];
240+
Log.traceln(LOG_SCOPE "onConfigStation: `%d`, essid=`%s`, psk=`%s`, method=%d (%s)",
241+
stationIndex, essid.c_str(), psk.c_str(), request->method(), request->methodToString());
242+
if(request->method() == HTTP_POST) {
243+
Settings::Instance.wifi().setStationConfiguration(stationIndex, essid.c_str(), psk.c_str());
244+
} else if(request->method() == HTTP_DELETE) {
245+
Settings::Instance.wifi().setStationConfiguration(stationIndex, "", "");
246+
}
247+
onGetConfig(request);
248+
}

src/wifimanager.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include "settings.h"
88
#include <TaskSchedulerDeclarations.h>
99
#include "wifisettings.h"
10+
#include <ESPAsyncWebServer.h>
11+
#include <ArduinoJson.h>
1012

1113
namespace APB {
1214

@@ -26,6 +28,14 @@ class WiFiManager {
2628
String gateway() const;
2729
void loop();
2830
void addOnConnectedListener(const OnConnectCallback &onConnected);
31+
32+
void onGetConfig(AsyncWebServerRequest *request);
33+
void onGetConfig(JsonObject &responseObject);
34+
void onPostReconnectWiFi(AsyncWebServerRequest *request);
35+
void onGetWiFiStatus(AsyncWebServerRequest *request);
36+
void onConfigStation(AsyncWebServerRequest *request, JsonVariant &json);
37+
void onConfigAccessPoint(AsyncWebServerRequest *request, JsonVariant &json);
38+
2939
private:
3040
GuLinux::WiFiSettings *wifiSettings;
3141
WiFiMulti wifiMulti;

0 commit comments

Comments
 (0)