Added credentials file.

This commit is contained in:
Holger Weber
2026-02-13 01:36:23 +01:00
parent 53e51dc50b
commit 076b5ba3e5
3 changed files with 183 additions and 113 deletions

1
.gitignore vendored
View File

@@ -215,3 +215,4 @@ pip-log.txt
#Mr Developer #Mr Developer
.mr.developer.cfg .mr.developer.cfg
src/credentials.h

View File

@@ -44,3 +44,15 @@ http://wiki.evilmadscientist.com/Installing_software
# return serialPort # return serialPort
- In my version lines 1355-1360 - 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;

View File

@@ -1,31 +1,37 @@
#include "EggDuino.h" #include "EggDuino.h"
#include <ArduinoJson.h> #include <ArduinoJson.h>
#include "credentials.h"
namespace { namespace
const char *kConfigPath = "/config.json"; {
const char *kWifiSsid = "Sternenlabor"; const char *kConfigPath = "/config.json";
const char *kWifiPassword = "!Sternenlabor99!";
WebServer server(80); WebServer server(80);
bool configStoreReady = false; bool configStoreReady = false;
ConfigParameter *findParameter(const String &key) { ConfigParameter *findParameter(const String &key)
for (size_t i = 0; i < configParameterCount; ++i) { {
if (key.equals(configParameters[i].key)) { for (size_t i = 0; i < configParameterCount; ++i)
return &configParameters[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() { void handleRoot()
for (size_t i = 0; i < configParameterCount; ++i) { {
*configParameters[i].value = configParameters[i].defaultValue; static const char kPage[] PROGMEM = R"HTML(
}
}
void handleRoot() {
static const char kPage[] PROGMEM = R"HTML(
<!doctype html> <!doctype html>
<html lang="de"> <html lang="de">
<head> <head>
@@ -137,63 +143,74 @@ async function pollLogs() {
</html> </html>
)HTML"; )HTML";
server.send(200, "text/html", kPage); 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;
} }
if (!server.hasArg("plain")) { void handleGetConfig()
server.send(400, "text/plain", "Missing JSON body"); {
return; 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; void handlePostConfig()
if (!applyConfigJson(server.arg("plain"), error)) { {
Log(String("Config JSON fehlerhaft: ") + error); if (!configStoreReady && !initConfigStore())
server.send(400, "text/plain", error); {
return; 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()) { void handleGetLogs()
Log("Config konnte nicht gespeichert werden"); {
server.send(500, "text/plain", "Could not save config"); uint32_t since = 0;
return; if (server.hasArg("since"))
{
since = static_cast<uint32_t>(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); void handleNotFound()
server.send(200, "application/json", buildConfigJson()); {
} if (server.uri().startsWith("/api/"))
{
void handleGetLogs() { server.send(404, "text/plain", "API endpoint not found");
uint32_t since = 0; return;
if (server.hasArg("since")) { }
since = static_cast<uint32_t>(server.arg("since").toInt()); 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 } // namespace
ConfigParameter configParameters[] = { ConfigParameter configParameters[] = {
@@ -203,8 +220,10 @@ ConfigParameter configParameters[] = {
const size_t configParameterCount = sizeof(configParameters) / sizeof(configParameters[0]); const size_t configParameterCount = sizeof(configParameters) / sizeof(configParameters[0]);
bool initConfigStore() { bool initConfigStore()
if (!SPIFFS.begin(true)) { {
if (!SPIFFS.begin(true))
{
configStoreReady = false; configStoreReady = false;
return false; return false;
} }
@@ -212,11 +231,13 @@ bool initConfigStore() {
return configStoreReady; return configStoreReady;
} }
bool loadConfigFromFile() { bool loadConfigFromFile()
{
applyDefaults(); applyDefaults();
File file = SPIFFS.open(kConfigPath, "r"); File file = SPIFFS.open(kConfigPath, "r");
if (!file) { if (!file)
{
Log("config.json fehlt, defaults werden gespeichert"); Log("config.json fehlt, defaults werden gespeichert");
return saveConfigToFile(); return saveConfigToFile();
} }
@@ -224,25 +245,31 @@ bool loadConfigFromFile() {
StaticJsonDocument<1024> doc; StaticJsonDocument<1024> doc;
DeserializationError err = deserializeJson(doc, file); DeserializationError err = deserializeJson(doc, file);
file.close(); file.close();
if (err) { if (err)
{
Log("config.json ist ungueltig, defaults werden gespeichert"); Log("config.json ist ungueltig, defaults werden gespeichert");
return saveConfigToFile(); return saveConfigToFile();
} }
JsonArray params = doc["parameters"].as<JsonArray>(); JsonArray params = doc["parameters"].as<JsonArray>();
for (JsonObject item : params) { for (JsonObject item : params)
{
const char *key = item["key"]; const char *key = item["key"];
if (key == nullptr) { if (key == nullptr)
{
continue; continue;
} }
ConfigParameter *param = findParameter(String(key)); ConfigParameter *param = findParameter(String(key));
if (param == nullptr) { if (param == nullptr)
{
continue; continue;
} }
if (item.containsKey("value")) { if (item.containsKey("value"))
{
*param->value = item["value"].as<int>(); *param->value = item["value"].as<int>();
} }
if (item.containsKey("description")) { if (item.containsKey("description"))
{
param->description = item["description"].as<String>(); param->description = item["description"].as<String>();
} }
} }
@@ -251,16 +278,19 @@ bool loadConfigFromFile() {
return true; return true;
} }
bool saveConfigToFile() { bool saveConfigToFile()
{
File file = SPIFFS.open(kConfigPath, "w"); File file = SPIFFS.open(kConfigPath, "w");
if (!file) { if (!file)
{
Log("SPIFFS open write failed"); Log("SPIFFS open write failed");
return false; return false;
} }
StaticJsonDocument<1024> doc; StaticJsonDocument<1024> doc;
JsonArray params = doc.createNestedArray("parameters"); 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(); JsonObject item = params.createNestedObject();
item["key"] = configParameters[i].key; item["key"] = configParameters[i].key;
item["value"] = *configParameters[i].value; item["value"] = *configParameters[i].value;
@@ -270,16 +300,19 @@ bool saveConfigToFile() {
bool ok = serializeJsonPretty(doc, file) > 0; bool ok = serializeJsonPretty(doc, file) > 0;
file.flush(); file.flush();
file.close(); file.close();
if (!ok) { if (!ok)
{
Log("serializeJsonPretty failed"); Log("serializeJsonPretty failed");
} }
return ok; return ok;
} }
String buildConfigJson() { String buildConfigJson()
{
StaticJsonDocument<1024> doc; StaticJsonDocument<1024> doc;
JsonArray params = doc.createNestedArray("parameters"); 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(); JsonObject item = params.createNestedObject();
item["key"] = configParameters[i].key; item["key"] = configParameters[i].key;
item["value"] = *configParameters[i].value; item["value"] = *configParameters[i].value;
@@ -291,33 +324,40 @@ String buildConfigJson() {
return output; return output;
} }
bool applyConfigJson(const String &payload, String &errorMessage) { bool applyConfigJson(const String &payload, String &errorMessage)
{
StaticJsonDocument<1024> doc; StaticJsonDocument<1024> doc;
DeserializationError err = deserializeJson(doc, payload); DeserializationError err = deserializeJson(doc, payload);
if (err) { if (err)
{
errorMessage = "Invalid JSON payload"; errorMessage = "Invalid JSON payload";
return false; return false;
} }
JsonArray params = doc["parameters"].as<JsonArray>(); JsonArray params = doc["parameters"].as<JsonArray>();
if (params.isNull()) { if (params.isNull())
{
errorMessage = "JSON must contain 'parameters' array"; errorMessage = "JSON must contain 'parameters' array";
return false; return false;
} }
for (JsonObject item : params) { for (JsonObject item : params)
{
const char *key = item["key"]; const char *key = item["key"];
if (key == nullptr || !item.containsKey("value")) { if (key == nullptr || !item.containsKey("value"))
{
continue; continue;
} }
ConfigParameter *param = findParameter(String(key)); ConfigParameter *param = findParameter(String(key));
if (param == nullptr) { if (param == nullptr)
{
continue; continue;
} }
*param->value = item["value"].as<int>(); *param->value = item["value"].as<int>();
if (item.containsKey("description")) { if (item.containsKey("description"))
{
param->description = item["description"].as<String>(); param->description = item["description"].as<String>();
} }
} }
@@ -325,31 +365,48 @@ bool applyConfigJson(const String &payload, String &errorMessage) {
return true; return true;
} }
void startWebInterface() { void startWebInterface()
WiFi.mode(WIFI_STA); {
WiFi.begin(kWifiSsid, kWifiPassword); if (kWifiSsid != 0)
{
const unsigned long connectStart = millis(); WiFi.mode(WIFI_STA);
const unsigned long connectTimeoutMs = 20000; WiFi.begin(kWifiSsid, kWifiPassword);
while (WiFi.status() != WL_CONNECTED && millis() - connectStart < connectTimeoutMs) {
delay(250); 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();
} }
else
initConfigStore(); {
if (WiFi.status() == WL_CONNECTED) { Serial.println("Verwende kein WLAN.");
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();
} }
void handleWebInterface() { void handleWebInterface()
server.handleClient(); {
if (kWifiSsid != NULL)
{
server.handleClient();
}
} }