From c61a67f81231d0c75cce06abb109af8b31e09682 Mon Sep 17 00:00:00 2001 From: MaPaLo76 <72209721+MaPaLo76@users.noreply.github.com> Date: Sun, 1 Mar 2026 17:28:47 +0100 Subject: [PATCH] feat(web+mqtt): FR-010 Webinterface-Redesign + MQTT-Steuerung Webinterface: - /: oeffentlich, Laser Cutter Status, m:ss, an/aus, Display-Toggle (fetch/204) - /config: H2-Abschnitte (Status, MQTT, Webzugang, Geraet, Tools) Maschinenlaufzeit h:mm:ss, Reboot-Button (disabled bei aktivem Laser) - /reset-total: neue POST-Route fuer NVS-Maschinenlaufzeit-Reset (Auth) - /display-toggle: POST, 204, kein Seitenwechsel - /reboot: POST, Auth, ESP.restart() DisplayManager: - setEnabled()/isEnabled() via MAX7219 SHUTDOWN-Modus MQTT: - lasercutter/reset -> lasercutter/cmd (MQTT_TOPIC_CMD) - Kommandos: reset_session_nvs, reset_session_ram, display, reboot - Heartbeat lasercutter/status: display_on-Feld hinzugefuegt --- Feature-Requests.md | 28 ++- README.md | 40 ++-- html-template/Laser-Cutter-Display.html | 49 +++++ include/config.h | 2 +- include/display_manager.h | 7 + platformio.ini | 2 +- src/display_manager.cpp | 7 + src/mqtt_client.cpp | 77 ++++---- src/web_server.cpp | 241 ++++++++++++++++-------- 9 files changed, 316 insertions(+), 137 deletions(-) create mode 100644 html-template/Laser-Cutter-Display.html diff --git a/Feature-Requests.md b/Feature-Requests.md index 18b9171..529e85c 100644 --- a/Feature-Requests.md +++ b/Feature-Requests.md @@ -19,12 +19,36 @@ Status: `[ ]` = offen · `[x]` = erledigt ## Offen -*(keine offenen Punkte)* - --- ## Erledigt +### Version 1.4.0 + +- [x] **FR-010** Feature: Webinterface-Redesign + MQTT-Steuerung ✅ + - **`/` – Laser Cutter Status** (öffentlich, kein Auth) + - Seitentitel `Laser Cutter Status`, bereinigte Tabelle: Laserzeit Summe, Laserzeit Aktuell (m:ss), Laserstatus (an/aus), Gratiszeit, Firmware + - Button `Summe Laserzeit zurücksetzen` (kein Auth, bewusst öffentlich) + - Button `💡 Display ausschalten/einschalten` – Toggle via `fetch()` ohne Seitenwechsel, Route `POST /display-toggle` antwortet 204 + - Button `🔒 Laser Cutter Setup & Status` → `/config` + - Auto-Refresh alle 10 s + - **`/config` – Laser Cutter Setup & Status** (Auth erforderlich) + - H2: Laser Cutter Status – Maschinenlaufzeit h:mm:ss, roter Reset-Button (`/reset-total`) + - H2: MQTT Broker, H2: Webzugang, WLAN-Abschnitt + - H2: Gerät – Reboot-Button `🔄 ESP32 neu starten` (grau, bei aktivem Laser `disabled`) + - H2: Tools – OTA Update, Log Console + - Button `← Laser Cutter Status` zurück auf `/` + - **MQTT-Steuerung**: `lasercutter/reset` ersetzt durch `lasercutter/cmd` + - `{"reset_session_nvs":true}` – Session-Summe + NVS-Maschinenlaufzeit auf 0 + - `{"reset_session_ram":true}` – nur RAM-Session-Summe auf 0, NVS bleibt + - `{"display":true/false}` – Display ein-/ausschalten + - `{"reboot":true}` – ESP32 neu starten + - **Heartbeat `lasercutter/status`**: Feld `"display_on": true/false` hinzugefügt + - **`DisplayManager`**: `setEnabled()` / `isEnabled()` via MAX7219 SHUTDOWN-Modus + - Betroffene Dateien: `src/web_server.cpp`, `src/mqtt_client.cpp`, `include/config.h`, `include/display_manager.h`, `src/display_manager.cpp` + - Commit: `TODO` + - Version: 1.4.0 + ### Version 1.2.0 - [x] **FR-009** Bug: `session_start_time` bei nachgelieferten Sessions (Queue) falsch ✅ diff --git a/README.md b/README.md index 184e8e4..14bb8f0 100644 --- a/README.md +++ b/README.md @@ -211,11 +211,10 @@ Der ESP32 verbindet sich mit einem MQTT-Broker (konfigurierbar über Webinterfac ### Topics | Richtung | Topic | Format | Beschreibung | -|------------|---------------------------|------------------------------|-------------------------------------------| +|------------|---------------------------|------------------------------|-----------------------------------------| | Publish | `lasercutter/session` | JSON | Wird beim **Ende eines Laser-Bursts** oder nach **Session-Reset** gesendet | | Publish | `lasercutter/status` | JSON (retained) | Heartbeat alle 60 Sekunden + LWT (online/offline) | -| Subscribe | `lasercutter/reset` | `{"reset":true}` oder `"1"` | Setzt die **gesamte** akkumulierte Laserzeit (NVS + RAM) auf 0 | -| Subscribe | `lasercutter/reset` | `{"reset_session":true}` | Setzt nur die **Session-Summe** (RAM) auf 0, NVS bleibt erhalten | +| Subscribe | `lasercutter/cmd` | JSON | Steuerkommandos: Reset, Display, Reboot | ### JSON-Format `lasercutter/session` ```json @@ -231,7 +230,7 @@ Der ESP32 verbindet sich mit einem MQTT-Broker (konfigurierbar über Webinterfac > `session_start_time` ist ein Lokalzeit-Zeitstempel (ISO 8601, CET/CEST), synchronisiert via NTP (`pool.ntp.org`) unmittelbar nach WLAN-Connect. Zeitzone wird automatisch zwischen CET (UTC+1) und CEST (UTC+2) umgeschaltet. > Wert `"unknown"` wenn die NTP-Synchronisation beim Session-Start noch nicht abgeschlossen war. -> Bei einem **Session-Reset** (Web oder MQTT `{"reset_session":true}`) wird ebenfalls ein `lasercutter/session`-Publish ausgelöst mit den bis dahin akkumulierten Werten – identisches Format wie beim normalen Session-Ende. +> Bei einem **Session-Reset** (Web oder MQTT `{"reset_session_ram":true}`) wird ebenfalls ein `lasercutter/session`-Publish ausgelöst mit den bis dahin akkumulierten Werten – identisches Format wie beim normalen Session-Ende. ### JSON-Format `lasercutter/status` ```json @@ -239,6 +238,7 @@ Der ESP32 verbindet sich mit einem MQTT-Broker (konfigurierbar über Webinterfac "online": true, "session_sum": "42.50", "machine_running_time_min": "1234.75", + "display_on": true, "ip": "192.168.1.100", "uptime_s": 3600, "firmware_version": "1.2.1 (Mar 1 2026)", @@ -248,6 +248,20 @@ Der ESP32 verbindet sich mit einem MQTT-Broker (konfigurierbar über Webinterfac > `reset_reason` mögliche Werte: `POWERON`, `SOFTWARE`, `PANIC`, `TASK_WDT`, `INT_WDT`, `WDT`, `BROWNOUT`, `EXT_PIN`, `DEEPSLEEP`, `SDIO`, `UNKNOWN`. Der Wert wird einmalig beim Start gespeichert und bleibt für die gesamte Laufzeit konstant. +### JSON-Format `lasercutter/cmd` + +Alle Steuerkommandos werden als JSON an `lasercutter/cmd` gesendet: + +```json +{ "reset_session_nvs": true } // Session-Summe + NVS-Maschinenlaufzeit auf 0 +{ "reset_session_ram": true } // nur RAM-Session-Summe auf 0, NVS bleibt +{ "display": true } // Display einschalten +{ "display": false } // Display ausschalten +{ "reboot": true } // ESP32 neu starten +``` + +> Mehrere Kommandos können in einem JSON kombiniert werden, z. B. `{"reset_session_ram":true, "display":false}`. + ### LWT (Last Will and Testament) Bei Verbindungsabbruch sendet der Broker automatisch auf `lasercutter/status`: ```json @@ -266,14 +280,18 @@ Bei Verbindungsabbruch sendet der Broker automatisch auf `lasercutter/status`: Das Webinterface ist über die IP-Adresse des ESP32 im Browser erreichbar. -| Seite | URL | Funktion | -|------------------|-------------|--------------------------------------------------------------| -| Status | `/` | Aktuelle Laserzeit, letzter Session-Wert, Systemstatus | -| Konfiguration | `/config` | MQTT-Broker (IP, Port, User, Passwort), Gratiszeit, Polarität, Web-Passwort | -| Reset | `/reset` | Setzt die **Session-Summe** (RAM) auf 0 zurück – NVS-Gesamtzeit bleibt erhalten | -| OTA Update | `/update` | Firmware-Update über Browser | +| Seite | URL | Auth | Funktion | +|--------------------------|-------------------|------|-----------------------------------------------------------------------| +| Laser Cutter Status | `/` | – | Laserzeit, Laserstatus, Display-Toggle, Session-Reset | +| Laser Cutter Setup | `/config` | ✔ | MQTT, Web-Auth, WLAN, Maschinenlaufzeit-Reset, Gratiszeit, Polarität, Reboot | +| Session-Reset | `/reset` | – | Setzt die **Session-Summe** (RAM) auf 0 – NVS bleibt erhalten | +| Maschinenlaufzeit-Reset | `/reset-total` | ✔ | Setzt Maschinenlaufzeit im NVS auf 0 | +| Display-Toggle | `/display-toggle` | – | Display ein-/ausschalten (POST, antwortet 204) | +| Reboot | `/reboot` | ✔ | ESP32 sofort neu starten | +| OTA Update | `/update` | – | Firmware-Update über Browser (ElegantOTA) | +| Log Console | `/log` | ✔ | Live-Log über WebSocket | -> Alle Seiten sind per **HTTP Basic Auth** geschützt, wenn in der Konfiguration ein Web-Passwort gesetzt ist. +> `/` ist **öffentlich** (kein Passwortschutz) – der Display-Toggle und Session-Reset sind bewusst ohne Auth erreichbar. Alle sicherheitsrelevanten Seiten (Setup, Reboot, Maschinenlaufzeit-Reset) erfordern HTTP Basic Auth, sofern ein Web-Passwort gesetzt ist. --- diff --git a/html-template/Laser-Cutter-Display.html b/html-template/Laser-Cutter-Display.html new file mode 100644 index 0000000..757e9f6 --- /dev/null +++ b/html-template/Laser-Cutter-Display.html @@ -0,0 +1,49 @@ + + +
+ + +| Summe Laserzeit | 8 min |
| Aktuelle Laserzeit | 423 s |
| Letzte Laserzeit | 0 s |
| Laser | aktiv |
| Maschinenlaufzeit (gesamt) | 619.50 min |
| IP-Adresse | 192.168.2.62 |
| MQTT | ✓verbunden |
| Broker | mqtt.majufilo.eu:8883 |
| Gratiszeit | 10 s |
| Firmware | v1.3.0 (Mar 1 2026) |