Added credentials file.
This commit is contained in:
@@ -1,31 +1,37 @@
|
||||
#include "EggDuino.h"
|
||||
#include <ArduinoJson.h>
|
||||
#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(
|
||||
<!doctype html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
@@ -137,63 +143,74 @@ async function pollLogs() {
|
||||
</html>
|
||||
)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<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);
|
||||
server.send(200, "application/json", buildConfigJson());
|
||||
}
|
||||
|
||||
void handleGetLogs() {
|
||||
uint32_t since = 0;
|
||||
if (server.hasArg("since")) {
|
||||
since = static_cast<uint32_t>(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<JsonArray>();
|
||||
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<int>();
|
||||
}
|
||||
if (item.containsKey("description")) {
|
||||
if (item.containsKey("description"))
|
||||
{
|
||||
param->description = item["description"].as<String>();
|
||||
}
|
||||
}
|
||||
@@ -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<JsonArray>();
|
||||
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<int>();
|
||||
if (item.containsKey("description")) {
|
||||
if (item.containsKey("description"))
|
||||
{
|
||||
param->description = item["description"].as<String>();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user