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