From 0f71cf24b27d08ecc5d3dd7d53f6ddab6a9dd1d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20SAILLANT?= <108685187+electron-rare@users.noreply.github.com> Date: Fri, 20 Feb 2026 23:49:49 +0100 Subject: [PATCH 1/2] add web controls for wifi reconnect espnow on off and mqtt publish --- data/webui/index.html | 6 +++++ data/webui/script.js | 48 ++++++++++++++++++++++++++++++++++-- src/web/WebServerManager.cpp | 6 +++++ 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/data/webui/index.html b/data/webui/index.html index 2e17a04..27030f8 100644 --- a/data/webui/index.html +++ b/data/webui/index.html @@ -46,6 +46,7 @@
+

@@ -57,6 +58,11 @@
             
             
           
+          
+ + + +

         
 
diff --git a/data/webui/script.js b/data/webui/script.js
index 7584b9a..d718899 100644
--- a/data/webui/script.js
+++ b/data/webui/script.js
@@ -169,6 +169,20 @@ function bindEvents() {
     }
   });
 
+  document.getElementById("wifiReconnectBtn").addEventListener("click", async () => {
+    try {
+      const result = await requestJson("/api/network/wifi/reconnect", {
+        method: "POST",
+        headers: jsonHeaders(),
+        body: "{}",
+      });
+      setJson("actionResult", result);
+      await Promise.all([refreshStatus(), refreshNetwork()]);
+    } catch (error) {
+      setJson("actionResult", { error: error.message });
+    }
+  });
+
   document.getElementById("wifiScanBtn").addEventListener("click", async () => {
     try {
       const result = await requestJson("/api/network/wifi/scan", {
@@ -211,9 +225,33 @@ function bindEvents() {
     }
   });
 
+  document.getElementById("mqttPublishForm").addEventListener("submit", async (event) => {
+    event.preventDefault();
+    const topic = document.getElementById("mqttTopic").value.trim();
+    const payloadRaw = document.getElementById("mqttPayload").value;
+    const payload = parsePayloadValue(payloadRaw);
+    try {
+      const result = await requestJson("/api/network/mqtt/publish", {
+        method: "POST",
+        headers: jsonHeaders(),
+        body: JSON.stringify({ topic, payload }),
+      });
+      setJson("actionResult", result);
+      await Promise.all([refreshStatus(), refreshNetwork()]);
+    } catch (error) {
+      setJson("actionResult", { error: error.message });
+    }
+  });
+
   document.getElementById("espnowOnBtn").addEventListener("click", async () => {
     try {
-      await sendControl("ESPNOW_ON");
+      const result = await requestJson("/api/network/espnow/on", {
+        method: "POST",
+        headers: jsonHeaders(),
+        body: "{}",
+      });
+      setJson("actionResult", result);
+      await Promise.all([refreshStatus(), refreshNetwork()]);
     } catch (error) {
       setJson("actionResult", { error: error.message });
     }
@@ -221,7 +259,13 @@ function bindEvents() {
 
   document.getElementById("espnowOffBtn").addEventListener("click", async () => {
     try {
-      await sendControl("ESPNOW_OFF");
+      const result = await requestJson("/api/network/espnow/off", {
+        method: "POST",
+        headers: jsonHeaders(),
+        body: "{}",
+      });
+      setJson("actionResult", result);
+      await Promise.all([refreshStatus(), refreshNetwork()]);
     } catch (error) {
       setJson("actionResult", { error: error.message });
     }
diff --git a/src/web/WebServerManager.cpp b/src/web/WebServerManager.cpp
index db0e0eb..191cb99 100644
--- a/src/web/WebServerManager.cpp
+++ b/src/web/WebServerManager.cpp
@@ -148,6 +148,8 @@ void WebServerManager::registerRoutes() {
     });
     server_.on("/api/network/wifi/disconnect", HTTP_POST,
                [this](AsyncWebServerRequest* request) { handleDispatch(request, "WIFI_DISCONNECT"); });
+    server_.on("/api/network/wifi/reconnect", HTTP_POST,
+               [this](AsyncWebServerRequest* request) { handleDispatch(request, "WIFI_RECONNECT"); });
     server_.on("/api/network/wifi/scan", HTTP_POST,
                [this](AsyncWebServerRequest* request) { handleDispatch(request, "WIFI_SCAN"); });
 
@@ -176,6 +178,10 @@ void WebServerManager::registerRoutes() {
     // ESP-NOW.
     server_.on("/api/network/espnow", HTTP_GET,
                [this](AsyncWebServerRequest* request) { handleDispatch(request, "ESPNOW_STATUS"); });
+    server_.on("/api/network/espnow/on", HTTP_POST,
+               [this](AsyncWebServerRequest* request) { handleDispatch(request, "ESPNOW_ON"); });
+    server_.on("/api/network/espnow/off", HTTP_POST,
+               [this](AsyncWebServerRequest* request) { handleDispatch(request, "ESPNOW_OFF"); });
     server_.on("/api/network/espnow/peer", HTTP_GET,
                [this](AsyncWebServerRequest* request) { handleDispatch(request, "ESPNOW_PEER_LIST"); });
     server_.on("/api/network/espnow/peer", HTTP_POST, [this](AsyncWebServerRequest* request) {
-- 
2.54.0


From 4f857b4dd4a7b12387a4e334f1513646841e9b59 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cl=C3=A9ment=20SAILLANT?=
 <108685187+electron-rare@users.noreply.github.com>
Date: Fri, 20 Feb 2026 23:57:24 +0100
Subject: [PATCH 2/2] fix mqtt web publish payload serialization for firmware
 api

---
 data/webui/script.js | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/data/webui/script.js b/data/webui/script.js
index d718899..f664b66 100644
--- a/data/webui/script.js
+++ b/data/webui/script.js
@@ -228,8 +228,7 @@ function bindEvents() {
   document.getElementById("mqttPublishForm").addEventListener("submit", async (event) => {
     event.preventDefault();
     const topic = document.getElementById("mqttTopic").value.trim();
-    const payloadRaw = document.getElementById("mqttPayload").value;
-    const payload = parsePayloadValue(payloadRaw);
+    const payload = document.getElementById("mqttPayload").value;
     try {
       const result = await requestJson("/api/network/mqtt/publish", {
         method: "POST",
-- 
2.54.0