Protocol running.
This commit is contained in:
@@ -1,16 +1,12 @@
|
||||
#include "EggDuino.h"
|
||||
#include <ArduinoJson.h>
|
||||
#include <DNSServer.h>
|
||||
|
||||
namespace {
|
||||
const char *kConfigPath = "/config.json";
|
||||
const char *kApSsid = "EggDuino";
|
||||
const uint16_t kDnsPort = 53;
|
||||
const IPAddress kApIp(192, 168, 4, 1);
|
||||
const IPAddress kApSubnet(255, 255, 255, 0);
|
||||
const char *kWifiSsid = "Sternenlabor";
|
||||
const char *kWifiPassword = "!Sternenlabor99!";
|
||||
|
||||
WebServer server(80);
|
||||
DNSServer dnsServer;
|
||||
bool configStoreReady = false;
|
||||
|
||||
ConfigParameter *findParameter(const String &key) {
|
||||
@@ -38,12 +34,14 @@ void handleRoot() {
|
||||
<title>EggDuino Konfiguration</title>
|
||||
<style>
|
||||
body { font-family: "Segoe UI", sans-serif; margin: 20px; background: #f3f6fb; color: #1a1a1a; }
|
||||
main { max-width: 560px; margin: 0 auto; background: #fff; border-radius: 12px; padding: 20px; box-shadow: 0 8px 24px rgba(0,0,0,0.08); }
|
||||
main { max-width: 760px; margin: 0 auto; background: #fff; border-radius: 12px; padding: 20px; box-shadow: 0 8px 24px rgba(0,0,0,0.08); }
|
||||
h1 { margin-top: 0; font-size: 1.35rem; }
|
||||
label { display: block; margin: 14px 0 6px; font-weight: 600; }
|
||||
input[type='number'] { width: 100%; padding: 10px; border: 1px solid #c7d2e5; border-radius: 8px; box-sizing: border-box; }
|
||||
button { margin-top: 18px; border: 0; background: #0b5ed7; color: white; padding: 10px 14px; border-radius: 8px; cursor: pointer; }
|
||||
#status { margin-top: 12px; min-height: 1.2em; }
|
||||
#log { margin-top: 20px; border: 1px solid #d6dfef; border-radius: 8px; background: #0f172a; color: #d2e3ff; padding: 10px; height: 220px; overflow-y: auto; white-space: pre-wrap; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: 0.9rem; }
|
||||
#logTitle { margin-top: 24px; margin-bottom: 8px; font-weight: 700; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -52,8 +50,12 @@ button { margin-top: 18px; border: 0; background: #0b5ed7; color: white; padding
|
||||
<form id="cfgForm"></form>
|
||||
<button id="saveBtn" type="button">Speichern</button>
|
||||
<div id="status"></div>
|
||||
<div id="logTitle">Logs</div>
|
||||
<div id="log"></div>
|
||||
</main>
|
||||
<script>
|
||||
let lastSeq = 0;
|
||||
|
||||
async function loadConfig() {
|
||||
const resp = await fetch('/api/config');
|
||||
if (!resp.ok) throw new Error('Konfiguration konnte nicht geladen werden');
|
||||
@@ -93,6 +95,22 @@ async function saveConfig() {
|
||||
status.textContent = 'Gespeichert';
|
||||
}
|
||||
|
||||
async function pollLogs() {
|
||||
const box = document.getElementById('log');
|
||||
const resp = await fetch('/api/logs?since=' + lastSeq);
|
||||
if (!resp.ok) {
|
||||
return;
|
||||
}
|
||||
const payload = await resp.json();
|
||||
(payload.logs || []).forEach(entry => {
|
||||
box.textContent += entry.text + '\n';
|
||||
});
|
||||
if (typeof payload.lastSeq === 'number') {
|
||||
lastSeq = payload.lastSeq;
|
||||
}
|
||||
box.scrollTop = box.scrollHeight;
|
||||
}
|
||||
|
||||
(async function init() {
|
||||
const status = document.getElementById('status');
|
||||
try {
|
||||
@@ -109,6 +127,8 @@ async function saveConfig() {
|
||||
status.textContent = e.message;
|
||||
}
|
||||
});
|
||||
pollLogs();
|
||||
setInterval(pollLogs, 800);
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
@@ -118,14 +138,6 @@ async function saveConfig() {
|
||||
server.send(200, "text/html", kPage);
|
||||
}
|
||||
|
||||
void redirectToPortal() {
|
||||
server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
|
||||
server.sendHeader("Pragma", "no-cache");
|
||||
server.sendHeader("Expires", "-1");
|
||||
server.sendHeader("Location", String("http://") + WiFi.softAPIP().toString() + "/", true);
|
||||
server.send(302, "text/plain", "");
|
||||
}
|
||||
|
||||
void handleGetConfig() {
|
||||
if (!configStoreReady && !initConfigStore()) {
|
||||
server.send(500, "text/plain", "Config storage not available");
|
||||
@@ -160,6 +172,14 @@ void handlePostConfig() {
|
||||
// penServo.write(penState);
|
||||
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());
|
||||
}
|
||||
server.send(200, "application/json", buildLogsJson(since));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
ConfigParameter configParameters[] = {
|
||||
@@ -284,28 +304,30 @@ bool applyConfigJson(const String &payload, String &errorMessage) {
|
||||
}
|
||||
|
||||
void startWebInterface() {
|
||||
WiFi.mode(WIFI_AP);
|
||||
WiFi.softAPConfig(kApIp, kApIp, kApSubnet);
|
||||
WiFi.softAP(kApSsid);
|
||||
dnsServer.start(kDnsPort, "*", WiFi.softAPIP());
|
||||
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();
|
||||
Serial.print("Config AP IP: ");
|
||||
Serial.println(WiFi.softAPIP());
|
||||
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("/generate_204", HTTP_GET, redirectToPortal);
|
||||
server.on("/gen_204", HTTP_GET, redirectToPortal);
|
||||
server.on("/hotspot-detect.html", HTTP_GET, redirectToPortal);
|
||||
server.on("/library/test/success.html", HTTP_GET, redirectToPortal);
|
||||
server.on("/ncsi.txt", HTTP_GET, redirectToPortal);
|
||||
server.on("/connecttest.txt", HTTP_GET, redirectToPortal);
|
||||
server.onNotFound(redirectToPortal);
|
||||
server.on("/api/logs", HTTP_GET, handleGetLogs);
|
||||
server.onNotFound(handleRoot);
|
||||
server.begin();
|
||||
}
|
||||
|
||||
void handleWebInterface() {
|
||||
dnsServer.processNextRequest();
|
||||
server.handleClient();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user