From 1f8f84c8b07589affe36dc74d8aee468609bbf96 Mon Sep 17 00:00:00 2001 From: burnsed Date: Wed, 23 Jan 2019 13:45:49 -0800 Subject: [PATCH 01/20] Get ConfigTool working for ESP32 --- src/ConfigTool.cpp | 25 ++++++++++++++++--------- src/ConfigTool.h | 22 +++++++++++++++++----- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/ConfigTool.cpp b/src/ConfigTool.cpp index 4cc2a63..3b0b920 100644 --- a/src/ConfigTool.cpp +++ b/src/ConfigTool.cpp @@ -3,14 +3,21 @@ Author: Tvde1 */ -#include "ConfigTool.h"; -#include "FS.h"; -#include "ArduinoJson.h"; -#include "ESP8266WebServer.h"; -#include ; +#include "ConfigTool.h" +#include +#include +#include + +#ifdef ESP8266 +#include +#endif + +#include void ConfigTool::load() { - SPIFFS.begin(); + if (!SPIFFS.begin(true)) { + Serial.println("SPIFFS Failed"); + } File f = SPIFFS.open("/config.json", "r"); if (!f) { return; @@ -18,7 +25,6 @@ void ConfigTool::load() { DynamicJsonBuffer jsonBuffer; JsonObject& root = jsonBuffer.parseObject(f.readStringUntil('\n')); - for (auto item : variables_) { item.second->deserialize(&root); } @@ -37,12 +43,12 @@ void ConfigTool::save() { SPIFFS.begin(); File f = SPIFFS.open("/config.json", "w"); - String output = ""; root.printTo(f); f.close(); } +#ifdef ESP8266 String ConfigTool::createWebPage(bool updated) { const String beginHtml = "Config Tool

ConfigTool Web Interface

Edit the config variables here and click save.

"; const String continueHtml = "
"; @@ -99,9 +105,10 @@ std::function ConfigTool::getWebHandler(ESP8266WebServer* server) { return; }; } +#endif void ConfigTool::reset() { - SPIFFS.begin(); + SPIFFS.begin(true); SPIFFS.remove("/config.json"); for (auto item : variables_) { diff --git a/src/ConfigTool.h b/src/ConfigTool.h index 2d416e8..1776b31 100644 --- a/src/ConfigTool.h +++ b/src/ConfigTool.h @@ -3,11 +3,15 @@ Author: Tvde1 */ -#include ; -#include ; -#include "ArduinoJson.h" -#include "ESP8266WebServer.h"; -#include ; +#include +#include +#include + +#ifdef ESP8266 +#include +#endif + +#include #ifndef _ConfigTool_h #define _ConfigTool_h @@ -148,11 +152,19 @@ struct ConfigTool { }; void load(); void save(); + +#ifdef ESP8266 std::function getWebHandler(ESP8266WebServer*); +#endif + void reset(); private: std::map variables_; + +#ifdef ESP8266 String createWebPage(bool); +#endif + }; #endif From 51369fad3c387dc5446028ffecfc437b9763fdd1 Mon Sep 17 00:00:00 2001 From: Ryan Burns Date: Wed, 23 Jan 2019 14:01:13 -0800 Subject: [PATCH 02/20] Update readme --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index dcd2e6f..5e701ef 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # ConfigTool - -Arduino or ESP8266 libraryy for easy saving and storing config variables. -Also has a handler to edit them via a webserver. +ESP32 and ESP8266 Arduino library for easy saving and storing config variables. +Also has a handler to edit them via a webserver (ESP8266 Only). See [this example](https://github.com/Tvde1/ConfigTool/blob/master/examples/ConfigTool/ConfigTool.ino). From 8a15a14ece6034a66c0f95cfcc7b093058dcae2f Mon Sep 17 00:00:00 2001 From: burnsed Date: Sat, 27 Apr 2019 20:01:09 -0700 Subject: [PATCH 03/20] Update for ArduinoJson v6 --- src/ConfigTool.cpp | 81 ++++------------------------------------------ src/ConfigTool.h | 62 ++++++++++++----------------------- 2 files changed, 28 insertions(+), 115 deletions(-) diff --git a/src/ConfigTool.cpp b/src/ConfigTool.cpp index 3b0b920..0de9f3f 100644 --- a/src/ConfigTool.cpp +++ b/src/ConfigTool.cpp @@ -7,11 +7,6 @@ #include #include #include - -#ifdef ESP8266 -#include -#endif - #include void ConfigTool::load() { @@ -23,90 +18,27 @@ void ConfigTool::load() { return; } - DynamicJsonBuffer jsonBuffer; - JsonObject& root = jsonBuffer.parseObject(f.readStringUntil('\n')); + DynamicJsonDocument root(ConfigSize); + deserializeJson(root, f.readStringUntil('\n')); for (auto item : variables_) { - item.second->deserialize(&root); + item.second->deserialize(root); } f.close(); } void ConfigTool::save() { - DynamicJsonBuffer jsonBuffer; - JsonObject& root = jsonBuffer.createObject(); + DynamicJsonDocument root(ConfigSize); for (auto item : variables_) { - item.second->serialize(&root); + item.second->serialize(root); } SPIFFS.begin(); File f = SPIFFS.open("/config.json", "w"); - - root.printTo(f); - - f.close(); + serializeJson(root, f); } -#ifdef ESP8266 -String ConfigTool::createWebPage(bool updated) { - const String beginHtml = "Config Tool

ConfigTool Web Interface

Edit the config variables here and click save.

"; - const String continueHtml = ""; - const String savedAlert = "
The config has been saved.
"; - - const String endHtml = "
"; - - String result = beginHtml; - - if (updated) { - result += savedAlert; - } - - result += continueHtml; - - for (auto item : variables_) { - result += "
toString() + "\" />
"; - } - - result += endHtml; - - return result; -} - -std::function ConfigTool::getWebHandler(ESP8266WebServer* server) { - return [this, server]() { - bool updated = false; - - if (server->args() == 1 && server->hasArg("reset") && server->arg("reset") == "true") { - Serial.println("Reset is true."); - for (auto item : variables_) { - item.second->reset(); - } - updated = true; - } - else { - Serial.write("Args hit: "); - for (int i = 0; i < server->args(); i++) { - String name = server->argName(i); - auto item = variables_.find(name); - Serial.print(name + " | "); - if (item == variables_.end()) { - continue; - } - updated = true; - item->second->fromString(server->arg(name)); - } - Serial.println(); - } - save(); - - String html = createWebPage(updated); - server->send(200, "text/html", html); - return; - }; -} -#endif - void ConfigTool::reset() { SPIFFS.begin(true); SPIFFS.remove("/config.json"); @@ -115,3 +47,4 @@ void ConfigTool::reset() { item.second->reset(); } } + diff --git a/src/ConfigTool.h b/src/ConfigTool.h index 1776b31..a2f1ac7 100644 --- a/src/ConfigTool.h +++ b/src/ConfigTool.h @@ -2,24 +2,18 @@ Name: ConfigTool.h Author: Tvde1 */ +#ifndef _ConfigTool_h +#define _ConfigTool_h #include #include #include -#ifdef ESP8266 -#include -#endif - -#include - -#ifndef _ConfigTool_h -#define _ConfigTool_h struct BaseVar { String name; - virtual void serialize(JsonObject*) = 0; - virtual void deserialize(JsonObject*) = 0; + virtual void serialize(JsonDocument) = 0; + virtual void deserialize(JsonDocument) = 0; virtual void reset() = 0; virtual String toString() = 0; virtual void fromString(String) = 0; @@ -29,9 +23,9 @@ template struct ConfigVar : BaseVar { ConfigVar(String n, T* p) {}; - void deserialize(JsonObject *json) {}; + void deserialize(JsonDocument json) {}; - void serialize(JsonObject* json) {}; + void serialize(JsonDocument json) {}; void reset() {}; @@ -50,16 +44,12 @@ struct ConfigVar : BaseVar { defaultValue = *p; }; - void deserialize(JsonObject *json) { - if (json->containsKey(name) && json->is(name)) { - - *pointer = String{ json->get(name) }; - json->remove(name); - } + void deserialize(JsonDocument json) { + *pointer = String{ json[name] | defaultValue }; } - void serialize(JsonObject* json) { - json->set(name, *pointer); + void serialize(JsonDocument json) { + json[name] = *pointer; } void reset() { @@ -85,16 +75,14 @@ struct ConfigVar : BaseVar { defaultValue = *p; }; - void deserialize(JsonObject *json) { - if (json->containsKey(name) && json->is(name)) { - - *pointer = json->get(name); - json->remove(name); + void deserialize(JsonDocument json) { + if (!json[name].isNull()) { + *pointer = json[name]; } } - void serialize(JsonObject* json) { - json->set(name, *pointer); + void serialize(JsonDocument json) { + json[name] = *pointer; } void reset() { @@ -120,15 +108,14 @@ struct ConfigVar : BaseVar { defaultValue = *p; }; - void deserialize(JsonObject *json) { - if (json->containsKey(name) && json->is(name)) { - *pointer = json->get(name); - json->remove(name); + void deserialize(JsonDocument json) { + if (!json[name].isNull()) { + *pointer = json[name]; } } - void serialize(JsonObject* json) { - json->set(name, *pointer); + void serialize(JsonDocument json) { + json[name] = *pointer; } void reset() { @@ -152,19 +139,12 @@ struct ConfigTool { }; void load(); void save(); - -#ifdef ESP8266 - std::function getWebHandler(ESP8266WebServer*); -#endif + int ConfigSize = 1024; void reset(); private: std::map variables_; -#ifdef ESP8266 - String createWebPage(bool); -#endif - }; #endif From f69678f01f25372b9616d1f3c4c8a83e8e7b654b Mon Sep 17 00:00:00 2001 From: gerdlanger <34196043+gerdlanger@users.noreply.github.com> Date: Sun, 6 Oct 2019 19:47:02 +0200 Subject: [PATCH 04/20] Update library.properties --- library.properties | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library.properties b/library.properties index f6a6231..fbeaa28 100644 --- a/library.properties +++ b/library.properties @@ -1,9 +1,9 @@ name=ConfigTool version=1.0 author=Tvde1 -maintainer=Tvde1 +maintainer=gerdlanger sentence=Save config variable and edit them online. paragraph=No more hardcoding. This library will save and load config variables and you can edit them at an endpoint you choose. category=Data Storage -url=https://github.com/Tvde1/ConfigTool -includes=ConfigTool.h \ No newline at end of file +url=https://github.com/gerdlanger/ConfigTool +includes=ConfigTool.h From f6404358f7ac123efb3deaa1b1b19caceab9c0cf Mon Sep 17 00:00:00 2001 From: Gerd Langer Date: Sun, 6 Oct 2019 23:05:25 +0200 Subject: [PATCH 05/20] fix save values using byRef parameters --- .gitignore | 5 ++++- src/ConfigTool.cpp | 11 +++++------ src/ConfigTool.h | 37 ++++++++++++++++++------------------- 3 files changed, 27 insertions(+), 26 deletions(-) diff --git a/.gitignore b/.gitignore index 3c4efe2..ff8bc3f 100644 --- a/.gitignore +++ b/.gitignore @@ -258,4 +258,7 @@ paket-files/ # Python Tools for Visual Studio (PTVS) __pycache__/ -*.pyc \ No newline at end of file +*.pyc + + +*.cpp__ diff --git a/src/ConfigTool.cpp b/src/ConfigTool.cpp index 0de9f3f..1e697ed 100644 --- a/src/ConfigTool.cpp +++ b/src/ConfigTool.cpp @@ -5,9 +5,7 @@ #include "ConfigTool.h" #include -#include #include -#include void ConfigTool::load() { if (!SPIFFS.begin(true)) { @@ -21,7 +19,7 @@ void ConfigTool::load() { DynamicJsonDocument root(ConfigSize); deserializeJson(root, f.readStringUntil('\n')); for (auto item : variables_) { - item.second->deserialize(root); + item.second->deserialize(&root); } f.close(); @@ -31,12 +29,13 @@ void ConfigTool::save() { DynamicJsonDocument root(ConfigSize); for (auto item : variables_) { - item.second->serialize(root); + item.second->serialize(&root); } - - SPIFFS.begin(); + + SPIFFS.begin(true); File f = SPIFFS.open("/config.json", "w"); serializeJson(root, f); + f.close(); } void ConfigTool::reset() { diff --git a/src/ConfigTool.h b/src/ConfigTool.h index a2f1ac7..c616c1a 100644 --- a/src/ConfigTool.h +++ b/src/ConfigTool.h @@ -5,15 +5,14 @@ #ifndef _ConfigTool_h #define _ConfigTool_h -#include #include #include struct BaseVar { String name; - virtual void serialize(JsonDocument) = 0; - virtual void deserialize(JsonDocument) = 0; + virtual void serialize(JsonDocument*) = 0; + virtual void deserialize(JsonDocument*) = 0; virtual void reset() = 0; virtual String toString() = 0; virtual void fromString(String) = 0; @@ -23,9 +22,9 @@ template struct ConfigVar : BaseVar { ConfigVar(String n, T* p) {}; - void deserialize(JsonDocument json) {}; + void deserialize(JsonDocument* json) {}; - void serialize(JsonDocument json) {}; + void serialize(JsonDocument* json) {}; void reset() {}; @@ -44,12 +43,12 @@ struct ConfigVar : BaseVar { defaultValue = *p; }; - void deserialize(JsonDocument json) { - *pointer = String{ json[name] | defaultValue }; + void deserialize(JsonDocument* json) { + *pointer = String{ (*json)[name] | defaultValue }; } - void serialize(JsonDocument json) { - json[name] = *pointer; + void serialize(JsonDocument* json) { + (*json)[name] = *pointer; } void reset() { @@ -75,14 +74,14 @@ struct ConfigVar : BaseVar { defaultValue = *p; }; - void deserialize(JsonDocument json) { - if (!json[name].isNull()) { - *pointer = json[name]; + void deserialize(JsonDocument* json) { + if (!(*json)[name].isNull()) { + *pointer = (*json)[name]; } } - void serialize(JsonDocument json) { - json[name] = *pointer; + void serialize(JsonDocument* json) { + (*json)[name] = *pointer; } void reset() { @@ -108,14 +107,14 @@ struct ConfigVar : BaseVar { defaultValue = *p; }; - void deserialize(JsonDocument json) { - if (!json[name].isNull()) { - *pointer = json[name]; + void deserialize(JsonDocument* json) { + if (!(*json)[name].isNull()) { + *pointer = (*json)[name]; } } - void serialize(JsonDocument json) { - json[name] = *pointer; + void serialize(JsonDocument* json) { + (*json)[name] = *pointer; } void reset() { From cabcd3b6eac26f920fa82824b273150068988260 Mon Sep 17 00:00:00 2001 From: Gerd Langer Date: Mon, 7 Oct 2019 00:52:50 +0200 Subject: [PATCH 06/20] added small test --- .gitignore | 2 +- test/ConfigToolTest/ConfigToolTest.ino | 110 +++++++++++++++++++++++++ 2 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 test/ConfigToolTest/ConfigToolTest.ino diff --git a/.gitignore b/.gitignore index ff8bc3f..aa42daa 100644 --- a/.gitignore +++ b/.gitignore @@ -261,4 +261,4 @@ __pycache__/ *.pyc -*.cpp__ +tmp/* diff --git a/test/ConfigToolTest/ConfigToolTest.ino b/test/ConfigToolTest/ConfigToolTest.ino new file mode 100644 index 0000000..4efb564 --- /dev/null +++ b/test/ConfigToolTest/ConfigToolTest.ino @@ -0,0 +1,110 @@ +/** + * Test functionality of ConfigTool. + * + * TAKE CARE !!! This DELETES exisintg "/config.json" files !!! + * + */ + + +#include +#include + +String config_String_1 = "Default"; +String config_String_2 = "Test"; +int config_int_1 = 100; +int config_int_2 = 200; +bool config_bool_F = false; +bool config_bool_T = true; + +ConfigTool configTool; + +bool dumpConfig(bool check){ + + File file = SPIFFS.open("/config.json"); + if(!file){ + Serial.println("reading - config failed"); + return false; + } + + Serial.println("reading - dumpfile:"); + while(file.available()){ + Serial.write(file.read()); + } + Serial.println(); + // if requested, print the comparison for "zeroVariables": + if (check) Serial.println("{\"String1\":\"-1-\",\"String2\":\"-2-\",\"bool__F\":false,\"bool__T\":false,\"int___1\":0,\"int___2\":0}"); + + return true; +} + +void initVariables() { + configTool.addVariable("String1", &config_String_1); + configTool.addVariable("String2", &config_String_2); + configTool.addVariable("int___1", &config_int_1); + configTool.addVariable("int___2", &config_int_2); + configTool.addVariable("bool__F", &config_bool_F); + configTool.addVariable("bool__T", &config_bool_T); +} + +void zeroVariables() { + config_String_1 = "-1-"; + config_String_2 = "-2-"; + config_int_1 = 0; + config_int_2 = 0; + config_bool_F = false; + config_bool_T = false; +} + +void checkDefaultValues() { + Serial.printf("String1 OK=%d\n", (config_String_1 == "Default")); + Serial.printf("String2 OK=%d\n", (config_String_2 == "Test")); + Serial.printf("int1 OK=%d\n", (config_int_1 == 100)); + Serial.printf("int2 OK=%d\n", (config_int_2 == 200)); + Serial.printf("bool_F OK=%d\n", (config_bool_F == false)); + Serial.printf("bool_T OK=%d\n", (config_bool_T == true)); +} + +void setup(){ + Serial.begin(115200); + Serial.println("Setup begin"); + + if(!SPIFFS.begin(false)){ + Serial.println("setup - SPIFFS begin failed"); + return; + } + + Serial.println("setup - dump at start"); + dumpConfig(true); + + Serial.println("setup - init variables to default and save"); + initVariables(); + configTool.save(); + dumpConfig(false); + + Serial.println("setup - manipulate variables and load again"); + zeroVariables(); + configTool.load(); + checkDefaultValues(); + + Serial.println("setup - manipulate variables and save"); + zeroVariables(); + configTool.save(); + dumpConfig(true); + + Serial.println("setup - reset stored values"); + configTool.reset(); + dumpConfig(false); + checkDefaultValues(); + + Serial.println("setup - again manipulate variables and save"); + zeroVariables(); + configTool.save(); + dumpConfig(true); + + Serial.println( "Setup end" ); + Serial.println( "Test complete" ); +} + +void loop(){ + // NOP +} From 9d53ea68d3babcdc6f1932633a3e9a707b624e04 Mon Sep 17 00:00:00 2001 From: gerdlanger <34196043+gerdlanger@users.noreply.github.com> Date: Mon, 7 Oct 2019 00:58:48 +0200 Subject: [PATCH 07/20] v1.0.1 prep in properties --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index fbeaa28..15242bc 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ConfigTool -version=1.0 +version=1.0.1 author=Tvde1 maintainer=gerdlanger sentence=Save config variable and edit them online. From a8cd787347764ceedab4493ac062441639805485 Mon Sep 17 00:00:00 2001 From: gerdlanger <34196043+gerdlanger@users.noreply.github.com> Date: Mon, 7 Oct 2019 01:04:55 +0200 Subject: [PATCH 08/20] Update README.md --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5e701ef..6c44c33 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # ConfigTool -ESP32 and ESP8266 Arduino library for easy saving and storing config variables. -Also has a handler to edit them via a webserver (ESP8266 Only). +ESP32 Arduino library for easy saving and storing config variables. + +TODO (port this to ESP32): Also has a handler to edit them via a webserver (ESP8266 Only). See [this example](https://github.com/Tvde1/ConfigTool/blob/master/examples/ConfigTool/ConfigTool.ino). From f75a1ef0476aa059d8f074ed9e95d9ec36bd3605 Mon Sep 17 00:00:00 2001 From: Gerd Langer Date: Thu, 10 Oct 2019 20:00:09 +0200 Subject: [PATCH 09/20] web-page generator added --- examples/WebConfig/WebConfig.ino | 91 ++++++++++++++++++++++++++++++++ src/ConfigTool.cpp | 71 +++++++++++++++++++++++++ src/ConfigTool.h | 11 ++-- 3 files changed, 170 insertions(+), 3 deletions(-) create mode 100644 examples/WebConfig/WebConfig.ino diff --git a/examples/WebConfig/WebConfig.ino b/examples/WebConfig/WebConfig.ino new file mode 100644 index 0000000..5caf6ce --- /dev/null +++ b/examples/WebConfig/WebConfig.ino @@ -0,0 +1,91 @@ +/** + * WebServer for ConfigTool. + */ + +#include +#include +#include +#include +#include + +const char* ssid = ""; +const char* password = "pwd>"; + +String config_String_1 = "Default"; +String config_String_2 = "Test"; +int config_int_1 = 100; +int config_int_2 = 200; +bool config_bool_F = false; +bool config_bool_T = true; + +ConfigTool configTool; +WebServer server(80); + +void initVariables() { + configTool.addVariable("String1", &config_String_1); + configTool.addVariable("String2", &config_String_2); + configTool.addVariable("int___1", &config_int_1); + configTool.addVariable("int___2", &config_int_2); + configTool.addVariable("bool__F", &config_bool_F); + configTool.addVariable("bool__T", &config_bool_T); +} + + +void handleRoot() { + server.send(200, "text/plain", "hello from esp32!"); +} + +void handleNotFound() { + String message = "File Not Found\n\n"; + message += "URI: "; + message += server.uri(); + message += "\nMethod: "; + message += (server.method() == HTTP_GET) ? "GET" : "POST"; + message += "\nArguments: "; + message += server.args(); + message += "\n"; + for (uint8_t i = 0; i < server.args(); i++) { + message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; + } + server.send(404, "text/plain", message); +} + +void setup(){ + Serial.begin(115200); + Serial.println("Setup begin"); + + initVariables(); + configTool.load(); + + WiFi.mode(WIFI_STA); + WiFi.begin(ssid, password); + Serial.println(""); + + // Wait for connection + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println(""); + Serial.print("Connected to "); + Serial.println(ssid); + Serial.print("IP address: "); + Serial.println(WiFi.localIP()); + + if (MDNS.begin("esp32")) { + Serial.println("MDNS responder started"); + } + + server.on("/", handleRoot); + + server.on("/config", configTool.getWebHandler(server)); + + server.onNotFound(handleNotFound); + + server.begin(); + Serial.println("HTTP server started"); +} + +void loop(void) { + server.handleClient(); +} \ No newline at end of file diff --git a/src/ConfigTool.cpp b/src/ConfigTool.cpp index 1e697ed..7281b4a 100644 --- a/src/ConfigTool.cpp +++ b/src/ConfigTool.cpp @@ -47,3 +47,74 @@ void ConfigTool::reset() { } } +String ConfigTool::createWebPage(bool updated) { + const String beginHtml = "" + "Config Tool" + "" + "

ConfigTool Web Interface

" + "

Edit the config variables here and click save.

" + "
"; + + const String endHtml = "
" + "" + "" + "
" + ""; + + String result = beginHtml; + + //if (updated) { + // result += savedAlert; + //} + + //result += continueHtml; + + for (auto item : variables_) { + result += "" + "" + "toString() + "\" />" + ""; + } + + result += endHtml; + + Serial.println(result); + + return result; +} + +std::function ConfigTool::getWebHandler(WebServer* server) { + return [this, server]() { + bool updated = false; + + if (/*server->args() == 1 &&*/ server->hasArg("reset")) { //} && server->arg("reset") == "true") { + Serial.println("Reset is true."); + for (auto item : variables_) { + item.second->reset(); + } + updated = true; + } + else { + Serial.write("Args hit: "); + for (int i = 0; i < server->args(); i++) { + String name = server->argName(i); + + if (name == "reset") Serial.print("....oops...."); + + auto item = variables_.find(name); + Serial.print(name + " | "); + if (item == variables_.end()) { + continue; + } + updated = true; + item->second->fromString(server->arg(name)); + } + Serial.println(); + } + save(); + + String html = createWebPage(updated); + server->send(200, "text/html", html); + return; + }; +} \ No newline at end of file diff --git a/src/ConfigTool.h b/src/ConfigTool.h index c616c1a..741f161 100644 --- a/src/ConfigTool.h +++ b/src/ConfigTool.h @@ -7,6 +7,7 @@ #include #include +#include struct BaseVar { @@ -132,18 +133,22 @@ struct ConfigVar : BaseVar { struct ConfigTool { public: + int ConfigSize = 1024; + template void addVariable(String name, T* pointer) { variables_[name] = (new ConfigVar(name, pointer)); }; + void load(); void save(); - int ConfigSize = 1024; - void reset(); + + std::function getWebHandler(WebServer*); + private: std::map variables_; - + String createWebPage(bool); }; #endif From 1fe185918680854d0f5580d8bdad2f75968707cb Mon Sep 17 00:00:00 2001 From: Gerd Langer Date: Thu, 10 Oct 2019 20:02:54 +0200 Subject: [PATCH 10/20] pass web-server by ref --- examples/WebConfig/WebConfig.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/WebConfig/WebConfig.ino b/examples/WebConfig/WebConfig.ino index 5caf6ce..a305d23 100644 --- a/examples/WebConfig/WebConfig.ino +++ b/examples/WebConfig/WebConfig.ino @@ -9,7 +9,7 @@ #include const char* ssid = ""; -const char* password = "pwd>"; +const char* password = ""; String config_String_1 = "Default"; String config_String_2 = "Test"; @@ -78,7 +78,7 @@ void setup(){ server.on("/", handleRoot); - server.on("/config", configTool.getWebHandler(server)); + server.on("/config", configTool.getWebHandler(&server)); server.onNotFound(handleNotFound); From 35888ffa885e52cf22d17c65fa6dda74e41f2cf1 Mon Sep 17 00:00:00 2001 From: Gerd Langer Date: Thu, 10 Oct 2019 21:42:57 +0200 Subject: [PATCH 11/20] type specific web editors --- src/ConfigTool.cpp | 90 +++++++++++++++++++++++++++++++++++----------- src/ConfigTool.h | 24 ++++++++++--- 2 files changed, 90 insertions(+), 24 deletions(-) diff --git a/src/ConfigTool.cpp b/src/ConfigTool.cpp index 7281b4a..cb17d0a 100644 --- a/src/ConfigTool.cpp +++ b/src/ConfigTool.cpp @@ -47,38 +47,88 @@ void ConfigTool::reset() { } } +String ConfigTool::createBoolTag(String name, String label, String display, bool checked) { + + String result = "" +display+ " "; + + return result; +} + String ConfigTool::createWebPage(bool updated) { - const String beginHtml = "" - "Config Tool" - "" - "

ConfigTool Web Interface

" - "

Edit the config variables here and click save.

" - "
"; + static const String beginHtml = + "" + "" + "Config Tool" + "" + "" + "

ConfigTool Web Interface

" + "

Edit the config variables here and click save.

"; + + static const String savedAlert = + "

The config has been saved.

"; + + static const String continueHtml = + "" + "
"; - const String endHtml = "
" - "" - "" - "
" - ""; + static const String endHtml = + "" + "

" + "" + "" + "

" + "" + "" + ""; String result = beginHtml; - //if (updated) { - // result += savedAlert; - //} + if (updated) { + result += savedAlert; + } - //result += continueHtml; + result += continueHtml; for (auto item : variables_) { - result += "" - "" - "toString() + "\" />" + result += + "" + "" + ""; + + switch (item.second->varType()) { + + case VT_TEXT: + result += + "toString() + "\" />"; + break; + + case VT_NUM: + result += + "toString() + "\" />"; + break; + + case VT_BOOL: + const bool val = *(((ConfigVar*)item.second)->pointer); + result += "
"; + result += createBoolTag(item.first, "true", "on", val); + result += createBoolTag(item.first, "false", "off", !val); + result += "
"; + break; + + } + + result += + "" ""; } result += endHtml; - Serial.println(result); + //Serial.println(result); return result; } @@ -102,7 +152,7 @@ std::function ConfigTool::getWebHandler(WebServer* server) { if (name == "reset") Serial.print("....oops...."); auto item = variables_.find(name); - Serial.print(name + " | "); + Serial.print(name + "=" + server->arg(name) + " | "); if (item == variables_.end()) { continue; } diff --git a/src/ConfigTool.h b/src/ConfigTool.h index 741f161..689c83b 100644 --- a/src/ConfigTool.h +++ b/src/ConfigTool.h @@ -9,6 +9,9 @@ #include #include +#define VT_TEXT 1 +#define VT_BOOL 2 +#define VT_NUM 3 struct BaseVar { String name; @@ -17,6 +20,8 @@ struct BaseVar { virtual void reset() = 0; virtual String toString() = 0; virtual void fromString(String) = 0; + + virtual int varType() = 0; }; template @@ -24,14 +29,12 @@ struct ConfigVar : BaseVar { ConfigVar(String n, T* p) {}; void deserialize(JsonDocument* json) {}; - void serialize(JsonDocument* json) {}; - void reset() {}; - String toString() { return ""; }; - void fromString(String) {}; + + int varType() {return -1;}; }; template <> @@ -63,6 +66,10 @@ struct ConfigVar : BaseVar { void fromString(String value) { *pointer = value; } + + int varType() { + return VT_TEXT; + } }; template <> @@ -96,6 +103,10 @@ struct ConfigVar : BaseVar { void fromString(String value) { *pointer = value == "true"; } + + int varType() { + return VT_BOOL; + } }; template <> @@ -129,6 +140,10 @@ struct ConfigVar : BaseVar { void fromString(String value) { *pointer = value.toInt(); } + + int varType() { + return VT_NUM; + } }; struct ConfigTool { @@ -148,6 +163,7 @@ struct ConfigTool { private: std::map variables_; + String createBoolTag(String, String, String, bool); String createWebPage(bool); }; From be1d0839b5ae501245d71f3b89b9164e754bdc10 Mon Sep 17 00:00:00 2001 From: Gerd Langer Date: Thu, 10 Oct 2019 23:10:40 +0200 Subject: [PATCH 12/20] merge --- examples/WebConfig/WebConfig.ino | 5 ++- src/ConfigTool.cpp | 66 ++++++++++++++++++++++---------- src/ConfigTool.h | 13 +++++-- 3 files changed, 58 insertions(+), 26 deletions(-) diff --git a/examples/WebConfig/WebConfig.ino b/examples/WebConfig/WebConfig.ino index a305d23..8ec8f72 100644 --- a/examples/WebConfig/WebConfig.ino +++ b/examples/WebConfig/WebConfig.ino @@ -23,11 +23,12 @@ WebServer server(80); void initVariables() { configTool.addVariable("String1", &config_String_1); - configTool.addVariable("String2", &config_String_2); + configTool.addVariable("String2", &config_String_2, false, true); configTool.addVariable("int___1", &config_int_1); - configTool.addVariable("int___2", &config_int_2); + configTool.addVariable("int___2", &config_int_2, true); configTool.addVariable("bool__F", &config_bool_F); configTool.addVariable("bool__T", &config_bool_T); + configTool.addVariable("bool__X", &config_bool_T, false, true); } diff --git a/src/ConfigTool.cpp b/src/ConfigTool.cpp index cb17d0a..16883fa 100644 --- a/src/ConfigTool.cpp +++ b/src/ConfigTool.cpp @@ -47,13 +47,25 @@ void ConfigTool::reset() { } } -String ConfigTool::createBoolTag(String name, String label, String display, bool checked) { +String ConfigTool::createInput(BaseVar *item, String type) { + String result = "name + "\" type=\"" +type+ "\" value=\""; - String result = "hideValueInWeb) { + result += item->toString(); + } + result += "\" />"; - if (checked) result += "checked "; - - result += "> "; + return result; +} + +String ConfigTool::createBoolSelector(ConfigVar *item, String label, String display, bool checked) { + + String result = "name + "\" type=\"radio\" id=\"_" +label+ "_\" value=\"" +label+ "\" "; + + if (checked) { + result += "checked "; + } + result += "> "; return result; } @@ -78,8 +90,8 @@ String ConfigTool::createWebPage(bool updated) { static const String endHtml = "" "

" - "" - "" + "

" + " be careful!" "

" "" "" @@ -90,10 +102,12 @@ String ConfigTool::createWebPage(bool updated) { if (updated) { result += savedAlert; } - result += continueHtml; for (auto item : variables_) { + + if (item.second->hideInWeb) continue; + result += "" "" @@ -102,20 +116,26 @@ String ConfigTool::createWebPage(bool updated) { switch (item.second->varType()) { case VT_TEXT: - result += - "toString() + "\" />"; + result += createInput(item.second, "text"); + //hideValueInWeb) result += item.second->toString(); + //result += "\" />"; break; case VT_NUM: - result += - "toString() + "\" />"; + result += createInput(item.second, "number"); + //result += "hideValueInWeb) result += item.second->toString(); + //result += "\" />"; break; case VT_BOOL: - const bool val = *(((ConfigVar*)item.second)->pointer); + bool val = *(((ConfigVar*)item.second)->pointer); result += "
"; - result += createBoolTag(item.first, "true", "on", val); - result += createBoolTag(item.first, "false", "off", !val); + result += createBoolSelector((ConfigVar*)item.second, "true", "on", val && !item.second->hideValueInWeb); + result += createBoolSelector((ConfigVar*)item.second, "false", "off", !val && !item.second->hideValueInWeb); +// result += createBoolTag(item.first, "true", "on", val && !item.second->hideValueInWeb); +// result += createBoolTag(item.first, "false", "off", !val && !item.second->hideValueInWeb); result += "
"; break; @@ -145,21 +165,25 @@ std::function ConfigTool::getWebHandler(WebServer* server) { updated = true; } else { - Serial.write("Args hit: "); for (int i = 0; i < server->args(); i++) { String name = server->argName(i); - if (name == "reset") Serial.print("....oops...."); - auto item = variables_.find(name); - Serial.print(name + "=" + server->arg(name) + " | "); if (item == variables_.end()) { continue; } + String val = server->arg(name); + + Serial.println(name + "=" + val); + + // skip empty input for values that are not displayed + if (item->second->hideValueInWeb && val == "") { + continue; + } + updated = true; - item->second->fromString(server->arg(name)); + item->second->fromString(val); } - Serial.println(); } save(); diff --git a/src/ConfigTool.h b/src/ConfigTool.h index 689c83b..407885e 100644 --- a/src/ConfigTool.h +++ b/src/ConfigTool.h @@ -15,6 +15,9 @@ struct BaseVar { String name; + bool hideInWeb = false; + bool hideValueInWeb = false; + virtual void serialize(JsonDocument*) = 0; virtual void deserialize(JsonDocument*) = 0; virtual void reset() = 0; @@ -151,8 +154,11 @@ struct ConfigTool { int ConfigSize = 1024; template - void addVariable(String name, T* pointer) { - variables_[name] = (new ConfigVar(name, pointer)); + void addVariable(String name, T* pointer, bool hide = false, bool hideVal = false) { + ConfigVar* var = new ConfigVar(name, pointer); + var->hideInWeb = hide; + var->hideValueInWeb = hideVal; + variables_[name] = var; }; void load(); @@ -163,7 +169,8 @@ struct ConfigTool { private: std::map variables_; - String createBoolTag(String, String, String, bool); + String createInput(BaseVar*, String); + String createBoolSelector(ConfigVar*, String, String, bool); String createWebPage(bool); }; From e51a5468d3cb69fb8444fa146f1cfe3513322303 Mon Sep 17 00:00:00 2001 From: Gerd Langer Date: Thu, 10 Oct 2019 23:13:48 +0200 Subject: [PATCH 13/20] v1.1 prep --- LICENSE | 2 +- library.properties | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/LICENSE b/LICENSE index e69e113..760aeba 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2018 Tim van den Essen +Copyright (c) 2018 Tim van den Essen, 2019 Gerd Langer Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/library.properties b/library.properties index fbeaa28..369388c 100644 --- a/library.properties +++ b/library.properties @@ -1,6 +1,6 @@ name=ConfigTool -version=1.0 -author=Tvde1 +version=1.1 +author=Tvde1,gerdlanger maintainer=gerdlanger sentence=Save config variable and edit them online. paragraph=No more hardcoding. This library will save and load config variables and you can edit them at an endpoint you choose. From fc787fde11948b78542262ee491c7ff539983bbd Mon Sep 17 00:00:00 2001 From: gerdlanger <34196043+gerdlanger@users.noreply.github.com> Date: Thu, 10 Oct 2019 23:19:19 +0200 Subject: [PATCH 14/20] Update README.md v1.1 prep --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6c44c33..05346fb 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # ConfigTool ESP32 Arduino library for easy saving and storing config variables. -TODO (port this to ESP32): Also has a handler to edit them via a webserver (ESP8266 Only). - -See [this example](https://github.com/Tvde1/ConfigTool/blob/master/examples/ConfigTool/ConfigTool.ino). +Handler to edit config via a webserver added in simple layout. +Each config variables can be hidden fully or its value. From c9453eaf4c7d4c64d91ff4f2d35170b772c475f5 Mon Sep 17 00:00:00 2001 From: Gerd Langer Date: Mon, 14 Oct 2019 22:54:27 +0200 Subject: [PATCH 15/20] added keywords.txt and architectures in library.properties --- keywords.txt | 13 +++++++++++++ library.properties | 1 + 2 files changed, 14 insertions(+) create mode 100644 keywords.txt diff --git a/keywords.txt b/keywords.txt new file mode 100644 index 0000000..b87e924 --- /dev/null +++ b/keywords.txt @@ -0,0 +1,13 @@ +# main class +ConfigTool KEYWORD1 + +# structs for variables +BaseVar KEYWORD3 +ConfigVar KEYWORD3 + +# public functions of ConfigTool +load KEYWORD2 +save KEYWORD2 +reset KEYWORD2 +addVariable KEYWORD2 +getWebHandler KEYWORD2 diff --git a/library.properties b/library.properties index 369388c..988b671 100644 --- a/library.properties +++ b/library.properties @@ -7,3 +7,4 @@ paragraph=No more hardcoding. This library will save and load config variables a category=Data Storage url=https://github.com/gerdlanger/ConfigTool includes=ConfigTool.h +architectures=esp32 \ No newline at end of file From 0eabf743ada6e0f835d7bc56fd9b2212d3543f6b Mon Sep 17 00:00:00 2001 From: Gerd Langer Date: Sun, 20 Oct 2019 23:16:19 +0200 Subject: [PATCH 16/20] support for ESP32 and ESP8266 via #define.s --- examples/WebConfig/WebConfig.ino | 22 ++++++++++++++++------ library.properties | 2 +- src/ConfigTool.cpp | 12 +++++++++--- src/ConfigTool.h | 13 +++++++++++-- 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/examples/WebConfig/WebConfig.ino b/examples/WebConfig/WebConfig.ino index 8ec8f72..7fc8262 100644 --- a/examples/WebConfig/WebConfig.ino +++ b/examples/WebConfig/WebConfig.ino @@ -3,10 +3,19 @@ */ #include -#include -#include -#include -#include + +#if defined(ARDUINO_ARCH_ESP8266) //ESP8266 + #include + #include + #include + #define MDNS_NAME "esp8266" +#elif defined(ARDUINO_ARCH_ESP32) //ESP32 + #include + #include + #include + #include + #define MDNS_NAME "esp32" +#endif const char* ssid = ""; const char* password = ""; @@ -18,6 +27,7 @@ int config_int_2 = 200; bool config_bool_F = false; bool config_bool_T = true; + ConfigTool configTool; WebServer server(80); @@ -73,7 +83,7 @@ void setup(){ Serial.print("IP address: "); Serial.println(WiFi.localIP()); - if (MDNS.begin("esp32")) { + if (MDNS.begin(MDNS_NAME)) { Serial.println("MDNS responder started"); } @@ -89,4 +99,4 @@ void setup(){ void loop(void) { server.handleClient(); -} \ No newline at end of file +} diff --git a/library.properties b/library.properties index 988b671..ce166be 100644 --- a/library.properties +++ b/library.properties @@ -7,4 +7,4 @@ paragraph=No more hardcoding. This library will save and load config variables a category=Data Storage url=https://github.com/gerdlanger/ConfigTool includes=ConfigTool.h -architectures=esp32 \ No newline at end of file +architectures=esp32,esp8266 \ No newline at end of file diff --git a/src/ConfigTool.cpp b/src/ConfigTool.cpp index 16883fa..3856479 100644 --- a/src/ConfigTool.cpp +++ b/src/ConfigTool.cpp @@ -5,10 +5,16 @@ #include "ConfigTool.h" #include -#include +#if defined(ARDUINO_ARCH_ESP32) //ESP32 + #include +#endif void ConfigTool::load() { +#if defined(ARDUINO_ARCH_ESP32) //ESP32 if (!SPIFFS.begin(true)) { +#else + if (!SPIFFS.begin()) { +#endif Serial.println("SPIFFS Failed"); } File f = SPIFFS.open("/config.json", "r"); @@ -32,14 +38,14 @@ void ConfigTool::save() { item.second->serialize(&root); } - SPIFFS.begin(true); + SPIFFS.begin(); File f = SPIFFS.open("/config.json", "w"); serializeJson(root, f); f.close(); } void ConfigTool::reset() { - SPIFFS.begin(true); + SPIFFS.begin(); SPIFFS.remove("/config.json"); for (auto item : variables_) { diff --git a/src/ConfigTool.h b/src/ConfigTool.h index 407885e..8bd429c 100644 --- a/src/ConfigTool.h +++ b/src/ConfigTool.h @@ -7,7 +7,16 @@ #include #include -#include + +#if defined(ARDUINO_ARCH_ESP8266) //ESP8266 + #include + #define WebServer ESP8266WebServer +#elif defined(ARDUINO_ARCH_ESP32) //ESP32 + #include + #include +#else + #error "unsupported architecture - intended for ESP32 and ESP8266" +#endif #define VT_TEXT 1 #define VT_BOOL 2 @@ -166,7 +175,7 @@ struct ConfigTool { void reset(); std::function getWebHandler(WebServer*); - + private: std::map variables_; String createInput(BaseVar*, String); From a5be10dabe9bbde3744ead1229e5ccdc4f4a528c Mon Sep 17 00:00:00 2001 From: gerdlanger <34196043+gerdlanger@users.noreply.github.com> Date: Sun, 20 Oct 2019 23:19:36 +0200 Subject: [PATCH 17/20] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 05346fb..180611c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # ConfigTool -ESP32 Arduino library for easy saving and storing config variables. +ESP32 and ESP8266 Arduino library for easy saving and storing config variables. Handler to edit config via a webserver added in simple layout. Each config variables can be hidden fully or its value. From a43de5cb20e966d7b75601372f48c21685de3e1c Mon Sep 17 00:00:00 2001 From: Gerd Langer Date: Sun, 20 Oct 2019 23:30:30 +0200 Subject: [PATCH 18/20] ConfigToolTest fix for multi architecture --- test/ConfigToolTest/ConfigToolTest.ino | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/test/ConfigToolTest/ConfigToolTest.ino b/test/ConfigToolTest/ConfigToolTest.ino index 4efb564..016d425 100644 --- a/test/ConfigToolTest/ConfigToolTest.ino +++ b/test/ConfigToolTest/ConfigToolTest.ino @@ -5,8 +5,11 @@ * */ - -#include +#ifdef ARDUINO_ARCH_ESP8266 + #include +#elif ARDUINO_ARCH_ESP32 + #include +#endif #include String config_String_1 = "Default"; @@ -20,7 +23,7 @@ ConfigTool configTool; bool dumpConfig(bool check){ - File file = SPIFFS.open("/config.json"); + File file = SPIFFS.open("/config.json", "r"); if(!file){ Serial.println("reading - config failed"); return false; @@ -68,7 +71,7 @@ void setup(){ Serial.begin(115200); Serial.println("Setup begin"); - if(!SPIFFS.begin(false)){ + if(!SPIFFS.begin()){ Serial.println("setup - SPIFFS begin failed"); return; } @@ -107,4 +110,4 @@ void setup(){ void loop(){ // NOP -} +} \ No newline at end of file From 5ad3d7a7a43d0e8bbafda57767c425d8a7b58fe4 Mon Sep 17 00:00:00 2001 From: Gerd Langer Date: Tue, 22 Oct 2019 23:46:56 +0200 Subject: [PATCH 19/20] added mac info to test --- examples/WebConfig/WebConfig.ino | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/WebConfig/WebConfig.ino b/examples/WebConfig/WebConfig.ino index 7fc8262..51c7a7d 100644 --- a/examples/WebConfig/WebConfig.ino +++ b/examples/WebConfig/WebConfig.ino @@ -43,7 +43,7 @@ void initVariables() { void handleRoot() { - server.send(200, "text/plain", "hello from esp32!"); + server.send(200, "text/plain", "hello from esp!"); } void handleNotFound() { @@ -69,6 +69,9 @@ void setup(){ configTool.load(); WiFi.mode(WIFI_STA); + Serial.print("MAC: "); + Serial.println(WiFi.macAddress()); + WiFi.begin(ssid, password); Serial.println(""); From 6ab3507606d5d1dfb013fa469bc769fbf7aa1a39 Mon Sep 17 00:00:00 2001 From: Gerd Langer Date: Mon, 18 Nov 2019 23:29:42 +0100 Subject: [PATCH 20/20] added IPAddress type --- examples/WebConfig/WebConfig.ino | 3 ++- src/ConfigTool.cpp | 13 +++++++++ src/ConfigTool.h | 45 +++++++++++++++++++++++++++++++- 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/examples/WebConfig/WebConfig.ino b/examples/WebConfig/WebConfig.ino index 51c7a7d..e7d3d10 100644 --- a/examples/WebConfig/WebConfig.ino +++ b/examples/WebConfig/WebConfig.ino @@ -26,7 +26,7 @@ int config_int_1 = 100; int config_int_2 = 200; bool config_bool_F = false; bool config_bool_T = true; - +IPAddress config_IP_1 = IPAddress(192,168,1,99); ConfigTool configTool; WebServer server(80); @@ -39,6 +39,7 @@ void initVariables() { configTool.addVariable("bool__F", &config_bool_F); configTool.addVariable("bool__T", &config_bool_T); configTool.addVariable("bool__X", &config_bool_T, false, true); + configTool.addVariable("IP____1", &config_IP_1); } diff --git a/src/ConfigTool.cpp b/src/ConfigTool.cpp index 3856479..8e1e710 100644 --- a/src/ConfigTool.cpp +++ b/src/ConfigTool.cpp @@ -135,6 +135,10 @@ String ConfigTool::createWebPage(bool updated) { //result += "\" />"; break; + case VT_IP: + result += createInput(item.second, "text"); + break; + case VT_BOOL: bool val = *(((ConfigVar*)item.second)->pointer); result += "
"; @@ -152,6 +156,15 @@ String ConfigTool::createWebPage(bool updated) { ""; } +/* + result+=""; + File f = SPIFFS.open("/config.json", "r"); + while (f and f.available()) { + result += f.read(); + } + result+=""; +*/ + result += endHtml; //Serial.println(result); diff --git a/src/ConfigTool.h b/src/ConfigTool.h index 8bd429c..d5febd6 100644 --- a/src/ConfigTool.h +++ b/src/ConfigTool.h @@ -20,7 +20,8 @@ #define VT_TEXT 1 #define VT_BOOL 2 -#define VT_NUM 3 +#define VT_NUM 3 +#define VT_IP 4 struct BaseVar { String name; @@ -158,6 +159,48 @@ struct ConfigVar : BaseVar { } }; +template <> +struct ConfigVar : BaseVar { + IPAddress* pointer; + IPAddress defaultValue; + ConfigVar(String n, IPAddress* p) { + name = n; + pointer = p; + defaultValue = *p; + }; + + void deserialize(JsonDocument* json) { + if (!(*json)[name].isNull()) { + String txt = String{ (*json)[name] | "" }; + Serial.println(txt); + if (!pointer->fromString(txt)) { + reset(); + } + } + } + + void serialize(JsonDocument* json) { + (*json)[name] = toString(); + } + + void reset() { + *pointer = uint32_t(defaultValue); + } + + String toString() { + return pointer->toString(); + } + + void fromString(String value) { + pointer->fromString(value); + } + + int varType() { + return VT_IP; + } +}; + + struct ConfigTool { public: int ConfigSize = 1024;