kugelmuehle/web_server.h
2026-10-11 21:41:53 +02:00

64 lines
2.2 KiB
C

#pragma once
#include <Arduino.h>
#include <ESPAsyncWebServer.h>
#include <ArduinoJson.h>
#include "web_ui.h"
// ---------------------------------------------------------------
// Der Async-Webserver läuft in einem eigenen Task. Damit es keine
// Race-Conditions mit loop() gibt, ändern die Callbacks NIE direkt
// settings/stepper, sondern legen nur Befehle in eine Queue.
// loop() arbeitet die Queue ab (handleWebCommands in main.cpp).
// ---------------------------------------------------------------
enum WebCmdType : uint8_t { WC_TIMER, WC_SPEED, WC_RUN, WC_MAXTEMP, WC_ACCEL, WC_WINDOW };
struct WebCmd {
WebCmdType type;
int32_t v[4];
};
static AsyncWebServer webServer(80);
static AsyncWebSocket webSocket("/ws");
static QueueHandle_t webQueue = nullptr;
static void onWsEvent(AsyncWebSocket *, AsyncWebSocketClient *, AwsEventType type,
void *arg, uint8_t *data, size_t len) {
if (type != WS_EVT_DATA) return;
AwsFrameInfo *info = (AwsFrameInfo *)arg;
if (!(info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT)) return;
JsonDocument doc;
if (deserializeJson(doc, (const char *)data, len)) return; // ungültiges JSON ignorieren
const char *c = doc["cmd"] | "";
WebCmd cmd = {};
if (!strcmp(c, "timer")) { cmd.type = WC_TIMER; cmd.v[0] = doc["v"] | 0; }
else if (!strcmp(c, "speed")) { cmd.type = WC_SPEED; cmd.v[0] = doc["v"] | 0; }
else if (!strcmp(c, "run")) { cmd.type = WC_RUN; cmd.v[0] = doc["v"] | 0; }
else if (!strcmp(c, "maxTemp")) { cmd.type = WC_MAXTEMP; cmd.v[0] = doc["v"] | 0; }
else if (!strcmp(c, "accel")) { cmd.type = WC_ACCEL; cmd.v[0] = doc["v"] | 0; }
else if (!strcmp(c, "window")) {
cmd.type = WC_WINDOW;
for (int i = 0; i < 4; i++) cmd.v[i] = doc["v"][i] | 0;
}
else return;
xQueueSend(webQueue, &cmd, 0);
}
inline void initWebServer() {
webQueue = xQueueCreate(8, sizeof(WebCmd));
webSocket.onEvent(onWsEvent);
webServer.addHandler(&webSocket);
webServer.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
request->send(200, "text/html", INDEX_HTML);
});
webServer.begin();
Serial.println("[Web] Server gestartet");
}