diff --git a/.gitignore b/.gitignore index 241ff6e..80da7d3 100644 --- a/.gitignore +++ b/.gitignore @@ -215,3 +215,4 @@ pip-log.txt #Mr Developer .mr.developer.cfg +src/credentials.h diff --git a/README.md b/README.md index b5be555..3f216ba 100644 --- a/README.md +++ b/README.md @@ -44,3 +44,15 @@ http://wiki.evilmadscientist.com/Installing_software # return serialPort - In my version lines 1355-1360 + +## Setup +Add credentials.h file with content like this: + + const char *kWifiSsid = "MySSID"; + const char *kWifiPassword = "MySecret"; + +To disable Wifi: + + const char *kWifiSsid = 0; + const char *kWifiPassword = 0; + diff --git a/src/Config_Web.cpp b/src/Config_Web.cpp index a842a74..43b9d41 100644 --- a/src/Config_Web.cpp +++ b/src/Config_Web.cpp @@ -1,31 +1,37 @@ #include "EggDuino.h" #include +#include "credentials.h" -namespace { -const char *kConfigPath = "/config.json"; -const char *kWifiSsid = "Sternenlabor"; -const char *kWifiPassword = "!Sternenlabor99!"; +namespace +{ + const char *kConfigPath = "/config.json"; -WebServer server(80); -bool configStoreReady = false; + WebServer server(80); + bool configStoreReady = false; -ConfigParameter *findParameter(const String &key) { - for (size_t i = 0; i < configParameterCount; ++i) { - if (key.equals(configParameters[i].key)) { - return &configParameters[i]; + ConfigParameter *findParameter(const String &key) + { + for (size_t i = 0; i < configParameterCount; ++i) + { + if (key.equals(configParameters[i].key)) + { + return &configParameters[i]; + } + } + return nullptr; + } + + void applyDefaults() + { + for (size_t i = 0; i < configParameterCount; ++i) + { + *configParameters[i].value = configParameters[i].defaultValue; } } - return nullptr; -} -void applyDefaults() { - for (size_t i = 0; i < configParameterCount; ++i) { - *configParameters[i].value = configParameters[i].defaultValue; - } -} - -void handleRoot() { - static const char kPage[] PROGMEM = R"HTML( + void handleRoot() + { + static const char kPage[] PROGMEM = R"HTML( @@ -137,63 +143,74 @@ async function pollLogs() { )HTML"; - server.send(200, "text/html", kPage); -} - -void handleGetConfig() { - if (!configStoreReady && !initConfigStore()) { - server.send(500, "text/plain", "Config storage not available"); - return; - } - server.sendHeader("Cache-Control", "no-store, no-cache, must-revalidate"); - server.sendHeader("Pragma", "no-cache"); - server.sendHeader("Expires", "0"); - server.send(200, "application/json", buildConfigJson()); -} - -void handlePostConfig() { - if (!configStoreReady && !initConfigStore()) { - server.send(500, "text/plain", "Config storage not available"); - return; + server.send(200, "text/html", kPage); } - if (!server.hasArg("plain")) { - server.send(400, "text/plain", "Missing JSON body"); - return; + void handleGetConfig() + { + if (!configStoreReady && !initConfigStore()) + { + server.send(500, "text/plain", "Config storage not available"); + return; + } + server.sendHeader("Cache-Control", "no-store, no-cache, must-revalidate"); + server.sendHeader("Pragma", "no-cache"); + server.sendHeader("Expires", "0"); + server.send(200, "application/json", buildConfigJson()); } - String error; - if (!applyConfigJson(server.arg("plain"), error)) { - Log(String("Config JSON fehlerhaft: ") + error); - server.send(400, "text/plain", error); - return; + void handlePostConfig() + { + if (!configStoreReady && !initConfigStore()) + { + server.send(500, "text/plain", "Config storage not available"); + return; + } + + if (!server.hasArg("plain")) + { + server.send(400, "text/plain", "Missing JSON body"); + return; + } + + String error; + if (!applyConfigJson(server.arg("plain"), error)) + { + Log(String("Config JSON fehlerhaft: ") + error); + server.send(400, "text/plain", error); + return; + } + + if (!saveConfigToFile()) + { + Log("Config konnte nicht gespeichert werden"); + server.send(500, "text/plain", "Could not save config"); + return; + } + + Log(String("Config gespeichert: penUpPos=") + g_iPEN_UP_POS + ", penDownPos=" + g_iPEN_DOWN_POS); + server.send(200, "application/json", buildConfigJson()); } - if (!saveConfigToFile()) { - Log("Config konnte nicht gespeichert werden"); - server.send(500, "text/plain", "Could not save config"); - return; + void handleGetLogs() + { + uint32_t since = 0; + if (server.hasArg("since")) + { + since = static_cast(server.arg("since").toInt()); + } + server.send(200, "application/json", buildLogsJson(since)); } - Log(String("Config gespeichert: penUpPos=") + g_iPEN_UP_POS + ", penDownPos=" + g_iPEN_DOWN_POS); - server.send(200, "application/json", buildConfigJson()); -} - -void handleGetLogs() { - uint32_t since = 0; - if (server.hasArg("since")) { - since = static_cast(server.arg("since").toInt()); + void handleNotFound() + { + if (server.uri().startsWith("/api/")) + { + server.send(404, "text/plain", "API endpoint not found"); + return; + } + handleRoot(); } - server.send(200, "application/json", buildLogsJson(since)); -} - -void handleNotFound() { - if (server.uri().startsWith("/api/")) { - server.send(404, "text/plain", "API endpoint not found"); - return; - } - handleRoot(); -} } // namespace ConfigParameter configParameters[] = { @@ -203,8 +220,10 @@ ConfigParameter configParameters[] = { const size_t configParameterCount = sizeof(configParameters) / sizeof(configParameters[0]); -bool initConfigStore() { - if (!SPIFFS.begin(true)) { +bool initConfigStore() +{ + if (!SPIFFS.begin(true)) + { configStoreReady = false; return false; } @@ -212,11 +231,13 @@ bool initConfigStore() { return configStoreReady; } -bool loadConfigFromFile() { +bool loadConfigFromFile() +{ applyDefaults(); File file = SPIFFS.open(kConfigPath, "r"); - if (!file) { + if (!file) + { Log("config.json fehlt, defaults werden gespeichert"); return saveConfigToFile(); } @@ -224,25 +245,31 @@ bool loadConfigFromFile() { StaticJsonDocument<1024> doc; DeserializationError err = deserializeJson(doc, file); file.close(); - if (err) { + if (err) + { Log("config.json ist ungueltig, defaults werden gespeichert"); return saveConfigToFile(); } JsonArray params = doc["parameters"].as(); - for (JsonObject item : params) { + for (JsonObject item : params) + { const char *key = item["key"]; - if (key == nullptr) { + if (key == nullptr) + { continue; } ConfigParameter *param = findParameter(String(key)); - if (param == nullptr) { + if (param == nullptr) + { continue; } - if (item.containsKey("value")) { + if (item.containsKey("value")) + { *param->value = item["value"].as(); } - if (item.containsKey("description")) { + if (item.containsKey("description")) + { param->description = item["description"].as(); } } @@ -251,16 +278,19 @@ bool loadConfigFromFile() { return true; } -bool saveConfigToFile() { +bool saveConfigToFile() +{ File file = SPIFFS.open(kConfigPath, "w"); - if (!file) { + if (!file) + { Log("SPIFFS open write failed"); return false; } StaticJsonDocument<1024> doc; JsonArray params = doc.createNestedArray("parameters"); - for (size_t i = 0; i < configParameterCount; ++i) { + for (size_t i = 0; i < configParameterCount; ++i) + { JsonObject item = params.createNestedObject(); item["key"] = configParameters[i].key; item["value"] = *configParameters[i].value; @@ -270,16 +300,19 @@ bool saveConfigToFile() { bool ok = serializeJsonPretty(doc, file) > 0; file.flush(); file.close(); - if (!ok) { + if (!ok) + { Log("serializeJsonPretty failed"); } return ok; } -String buildConfigJson() { +String buildConfigJson() +{ StaticJsonDocument<1024> doc; JsonArray params = doc.createNestedArray("parameters"); - for (size_t i = 0; i < configParameterCount; ++i) { + for (size_t i = 0; i < configParameterCount; ++i) + { JsonObject item = params.createNestedObject(); item["key"] = configParameters[i].key; item["value"] = *configParameters[i].value; @@ -291,33 +324,40 @@ String buildConfigJson() { return output; } -bool applyConfigJson(const String &payload, String &errorMessage) { +bool applyConfigJson(const String &payload, String &errorMessage) +{ StaticJsonDocument<1024> doc; DeserializationError err = deserializeJson(doc, payload); - if (err) { + if (err) + { errorMessage = "Invalid JSON payload"; return false; } JsonArray params = doc["parameters"].as(); - if (params.isNull()) { + if (params.isNull()) + { errorMessage = "JSON must contain 'parameters' array"; return false; } - for (JsonObject item : params) { + for (JsonObject item : params) + { const char *key = item["key"]; - if (key == nullptr || !item.containsKey("value")) { + if (key == nullptr || !item.containsKey("value")) + { continue; } ConfigParameter *param = findParameter(String(key)); - if (param == nullptr) { + if (param == nullptr) + { continue; } *param->value = item["value"].as(); - if (item.containsKey("description")) { + if (item.containsKey("description")) + { param->description = item["description"].as(); } } @@ -325,31 +365,48 @@ bool applyConfigJson(const String &payload, String &errorMessage) { return true; } -void startWebInterface() { - WiFi.mode(WIFI_STA); - WiFi.begin(kWifiSsid, kWifiPassword); +void startWebInterface() +{ + if (kWifiSsid != 0) + { - const unsigned long connectStart = millis(); - const unsigned long connectTimeoutMs = 20000; - while (WiFi.status() != WL_CONNECTED && millis() - connectStart < connectTimeoutMs) { - delay(250); + WiFi.mode(WIFI_STA); + WiFi.begin(kWifiSsid, kWifiPassword); + + const unsigned long connectStart = millis(); + const unsigned long connectTimeoutMs = 20000; + while (WiFi.status() != WL_CONNECTED && millis() - connectStart < connectTimeoutMs) + { + delay(250); + } + + initConfigStore(); + if (WiFi.status() == WL_CONNECTED) + { + Serial.println(String("WLAN verbunden, IP: ") + WiFi.localIP().toString()); + } + else + { + Serial.println("WLAN Verbindung fehlgeschlagen"); + } + + server.on("/", HTTP_GET, handleRoot); + server.on("/api/config", HTTP_GET, handleGetConfig); + server.on("/api/config", HTTP_POST, handlePostConfig); + server.on("/api/logs", HTTP_GET, handleGetLogs); + server.onNotFound(handleNotFound); + server.begin(); } - - initConfigStore(); - if (WiFi.status() == WL_CONNECTED) { - Serial.println(String("WLAN verbunden, IP: ") + WiFi.localIP().toString()); - } else { - Serial.println("WLAN Verbindung fehlgeschlagen"); + else + { + Serial.println("Verwende kein WLAN."); } - - server.on("/", HTTP_GET, handleRoot); - server.on("/api/config", HTTP_GET, handleGetConfig); - server.on("/api/config", HTTP_POST, handlePostConfig); - server.on("/api/logs", HTTP_GET, handleGetLogs); - server.onNotFound(handleNotFound); - server.begin(); } -void handleWebInterface() { - server.handleClient(); +void handleWebInterface() +{ + if (kWifiSsid != NULL) + { + server.handleClient(); + } }