From 2882f707baa7182ccd6d25d4f4de25bb6a767e1d Mon Sep 17 00:00:00 2001 From: Holger Pieta Date: Mon, 30 Apr 2018 13:17:35 +0200 Subject: [PATCH] Made WebServer more reusable Only non-general (non-reusable) part of WebServer was the device reboot after the submitted configuration had been stored. Removed this from the WebServer and added it (via a function reference call) to Basecamp. Added a reset function, which clears all interface elements such that new elemets can be added at will. The reset function can be used if the web server should be reconfigured during runtime. But it might not work yet. --- Basecamp.cpp | 6 +++++- WebServer.cpp | 22 +++++++++++++++++----- WebServer.hpp | 8 +++++++- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/Basecamp.cpp b/Basecamp.cpp index 77435f2..a470102 100644 --- a/Basecamp.cpp +++ b/Basecamp.cpp @@ -192,7 +192,11 @@ bool Basecamp::begin(String fixedWiFiApEncryptionPassword) if (shouldEnableConfigWebserver()) { // Start webserver and pass the configuration object to it - web.begin(configuration); + // Also pass a Lambda-function that restarts the device after the configuration has been saved. + web.begin(configuration, [](){ + delay(2000); + esp_restart(); + }); // Add a webinterface element for the h1 that contains the device name. It is a child of the #wrapper-element. web.addInterfaceElement("heading", "h1", "","#wrapper"); web.setInterfaceElementAttribute("heading", "class", "fat-border"); diff --git a/WebServer.cpp b/WebServer.cpp index 72ba055..bdcae68 100644 --- a/WebServer.cpp +++ b/WebServer.cpp @@ -26,7 +26,7 @@ WebServer::WebServer() #endif } -void WebServer::begin(Configuration &configuration) { +void WebServer::begin(Configuration &configuration, std::function submitFunc) { SPIFFS.begin(); server.on("/" , HTTP_GET, [](AsyncWebServerRequest * request) @@ -98,7 +98,7 @@ void WebServer::begin(Configuration &configuration) { request->send(response); }); - server.on("/submitconfig", HTTP_POST, [&configuration, this](AsyncWebServerRequest *request) + server.on("/submitconfig", HTTP_POST, [&configuration, submitFunc, this](AsyncWebServerRequest *request) { if (request->params() == 0) { DEBUG_PRINTLN("Refusing to take over an empty configuration submission."); @@ -119,9 +119,8 @@ void WebServer::begin(Configuration &configuration) { configuration.save(); request->send(201); - // Why? What is this magic value for? - delay(2000); - esp_restart(); + // Only call submitFunc when it has been set to something useful + if( submitFunc ) submitFunc(); }); server.onNotFound([this](AsyncWebServerRequest *request) @@ -208,3 +207,16 @@ void WebServer::setInterfaceElementAttribute(const String &id, const String &key } } } + +void WebServer::reset() { + interfaceElements.clear(); + // We should also reset the server itself, according to documentation, but it will cause a crash. + // It works without reset, if you only configure one server after a reboot. Not sure what happens if you want to reconfigure during runtime. + //server.reset(); + //server.addHandler(&events); +//#ifdef BASECAMP_USEDNS +//#ifdef DNSServer_h + //server.addHandler(new CaptiveRequestHandler()).setFilter(ON_AP_FILTER); +//#endif +//#endif +} diff --git a/WebServer.hpp b/WebServer.hpp index e0545ec..7df678e 100644 --- a/WebServer.hpp +++ b/WebServer.hpp @@ -30,12 +30,18 @@ class WebServer { WebServer(); ~WebServer() = default; - void begin(Configuration &configuration); + void begin(Configuration &configuration, std::function submitFunc = 0); bool addURL(const char* url, const char* content, const char* mimetype); + + // Remark: The server should be stopped before any changes to the interface elements are done to avoid inconsistent results if a request comes in at that very moment. + // However, ESPAsyncWebServer does not support any kind of end() function or something like that in the moment. void addInterfaceElement(const String &id, String element, String content, String parent = "#configform", String configvariable = ""); // Sets "key" to "value" in element with id "id" if exists. void setInterfaceElementAttribute(const String &id, const String &key, String value); + + // Removes all interface elements + void reset(); struct cmp_str {