From 5c502955522291f89bb5d2aaa4b3d414c1d1b9bc Mon Sep 17 00:00:00 2001 From: Jared Dohrman Date: Wed, 22 Apr 2026 18:06:29 +1000 Subject: [PATCH 1/4] fix: hide battery voltage range text for PMU-backed web stats --- docs/web-panel.md | 2 +- src/helpers/web/WebPanelServer.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/web-panel.md b/docs/web-panel.md index d8bc858c..e056fd0d 100644 --- a/docs/web-panel.md +++ b/docs/web-panel.md @@ -233,7 +233,7 @@ For boards that expose extra telemetry, the optional `Environment` summary card Metrics with no current value are hidden rather than showing placeholder rows, so the cards vary by board and by current sensor state. -The `Core` battery meter prefers a board-reported battery percentage when the target exposes one. Otherwise it scales the displayed percentage from the board's configured battery voltage range rather than assuming a fixed single-cell `3000-4200 mV` pack. +The `Core` battery meter prefers a board-reported battery percentage when the target exposes one. On those boards, the meter detail shows the live battery millivolt reading only. Otherwise it scales the displayed percentage from the board's configured battery voltage range and shows that range in the detail text rather than assuming a fixed single-cell `3000-4200 mV` pack. The trend graphs load sequentially rather than as one large payload: diff --git a/src/helpers/web/WebPanelServer.cpp b/src/helpers/web/WebPanelServer.cpp index a9ce9aee..39dc3996 100644 --- a/src/helpers/web/WebPanelServer.cpp +++ b/src/helpers/web/WebPanelServer.cpp @@ -1472,7 +1472,8 @@ const char kWebPanelAppHtml[] PROGMEM = R"HTML( : pctRange(core.battery_mv, batteryMin, batteryMax); const queuePct = pctRange(core.queue_len, 0, 12); const errorsPct = core.errors > 0 ? 100 : 0; - const batteryDetail = batteryMin < batteryMax + const usesBoardBatteryPercent = Number.isFinite(core.battery_pct) && core.battery_pct >= 0; + const batteryDetail = !usesBoardBatteryPercent && batteryMin < batteryMax ? (core.battery_mv || 0) + " mV (" + batteryMin + "-" + batteryMax + " mV)" : (core.battery_mv || 0) + " mV"; return `
From 908526563738d0139f99565ebed4c7d258573dcc Mon Sep 17 00:00:00 2001 From: Jared Dohrman Date: Thu, 23 Apr 2026 09:18:52 +1000 Subject: [PATCH 2/4] fix: add missing USE_SX1262 for TBeam 1W --- variants/lilygo_tbeam_1w/platformio.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/variants/lilygo_tbeam_1w/platformio.ini b/variants/lilygo_tbeam_1w/platformio.ini index b76d637b..947d7bd4 100644 --- a/variants/lilygo_tbeam_1w/platformio.ini +++ b/variants/lilygo_tbeam_1w/platformio.ini @@ -10,6 +10,7 @@ build_flags = ; Radio - SX1262 with high-power PA (32dBm max output) ; Note: Set SX1262 output to 22dBm max, external PA provides additional gain + -D USE_SX1262 -D RADIO_CLASS=CustomSX1262 -D WRAPPER_CLASS=CustomSX1262Wrapper -D P_LORA_DIO_1=1 From 4b83142b9e665bfad58c59fbd32f3c0f762ca7bc Mon Sep 17 00:00:00 2001 From: Jared Dohrman Date: Thu, 23 Apr 2026 09:27:48 +1000 Subject: [PATCH 3/4] fix: start ota is now consistent across command sources --- docs/custom-cli.md | 2 +- examples/simple_repeater/MyMesh.cpp | 3 +++ src/helpers/web/WebPanelServer.cpp | 8 +++----- src/helpers/web/WebPanelServer.h | 2 +- src/helpers/web/WebService.cpp | 15 ++++++++++++++- src/helpers/web/WebService.h | 1 + 6 files changed, 23 insertions(+), 8 deletions(-) diff --git a/docs/custom-cli.md b/docs/custom-cli.md index 3b574cea..8150e0de 100644 --- a/docs/custom-cli.md +++ b/docs/custom-cli.md @@ -123,7 +123,7 @@ Notes: - the panel still uses the repeater admin password for access - commands run with the same care as if you typed them into the repeater CLI directly - this is intended for local admin use on a trusted network -- `start ota` releases the local HTTP redirect listener on port `80` so the OTA HTTP listener can take over without stopping the rest of the repeater services +- `start ota` releases the local HTTP redirect listener on port `80` so the OTA HTTP listener can take over without stopping the rest of the repeater services, regardless of whether the command is run from the web panel, serial CLI, or a remote companion/app CLI session ## Companion WiFi Rescue Commands diff --git a/examples/simple_repeater/MyMesh.cpp b/examples/simple_repeater/MyMesh.cpp index cf0ede95..a615f00f 100644 --- a/examples/simple_repeater/MyMesh.cpp +++ b/examples/simple_repeater/MyMesh.cpp @@ -2056,6 +2056,9 @@ void MyMesh::clearStats() { } void MyMesh::prepareForOTAStart() { +#if defined(ESP_PLATFORM) && WITH_WEB_PANEL + web.prepareForOTAStart(); +#endif } void MyMesh::handleCommand(uint32_t sender_timestamp, char *command, char *reply) { diff --git a/src/helpers/web/WebPanelServer.cpp b/src/helpers/web/WebPanelServer.cpp index 39dc3996..5b397bd9 100644 --- a/src/helpers/web/WebPanelServer.cpp +++ b/src/helpers/web/WebPanelServer.cpp @@ -2816,11 +2816,6 @@ esp_err_t WebPanelServer::handleCommand(httpd_req_t* req) { ctx->self->noteActivity(); memset(reply, 0, kWebReplyBufferSize); - if (strcmp(command, "start ota") == 0) { - // OTA serves its own HTTP listener on port 80, so release the - // web-panel redirect listener first or it will keep owning that port. - ctx->self->stopRedirectServer(); - } ctx->self->_runner->runWebCommand(command, reply, kWebReplyBufferSize); httpd_resp_set_type(req, "text/plain; charset=utf-8"); httpd_resp_set_hdr(req, "Cache-Control", "no-store"); @@ -2937,6 +2932,9 @@ bool WebPanelServer::start() { void WebPanelServer::stop() { } +void WebPanelServer::stopRedirectServer() { +} + bool WebPanelServer::isRunning() const { return false; } diff --git a/src/helpers/web/WebPanelServer.h b/src/helpers/web/WebPanelServer.h index ba63808e..7c76ed08 100644 --- a/src/helpers/web/WebPanelServer.h +++ b/src/helpers/web/WebPanelServer.h @@ -41,6 +41,7 @@ public: void setCommandRunner(WebPanelCommandRunner* runner); bool start(); void stop(); + void stopRedirectServer(); bool isRunning() const; bool hasSessionToken() const; bool shouldAutoLock(unsigned long now_ms) const; @@ -71,7 +72,6 @@ private: void refreshToken(); bool isAuthorized(httpd_req_t* req) const; void noteActivity(); - void stopRedirectServer(); #else WebPanelCommandRunner* _runner; #endif diff --git a/src/helpers/web/WebService.cpp b/src/helpers/web/WebService.cpp index 1420526d..2f588d11 100644 --- a/src/helpers/web/WebService.cpp +++ b/src/helpers/web/WebService.cpp @@ -26,6 +26,13 @@ void WebService::suspendForOTA() { #endif } +void WebService::prepareForOTAStart() { +#if defined(ESP_PLATFORM) && WITH_WEB_PANEL + _suspended_for_ota = true; + _panel.stopRedirectServer(); +#endif +} + void WebService::loop() { #if defined(ESP_PLATFORM) && WITH_WEB_PANEL ensureWebServer(); @@ -91,10 +98,16 @@ void WebService::formatWebStatusReply(char* reply, size_t reply_size) const { #if defined(ESP_PLATFORM) && WITH_WEB_PANEL void WebService::ensureWebServer() { - if (_suspended_for_ota || _runner == nullptr || _prefs.web_enabled == 0 || _network == nullptr || !_network->isWifiConnected()) { + if (_runner == nullptr || _prefs.web_enabled == 0 || _network == nullptr || !_network->isWifiConnected()) { _panel.stop(); return; } + if (_suspended_for_ota) { + if (_panel.isRunning()) { + _panel.stopRedirectServer(); + } + return; + } if (_panel.isRunning()) { return; } diff --git a/src/helpers/web/WebService.h b/src/helpers/web/WebService.h index 4275b890..be6aa43e 100644 --- a/src/helpers/web/WebService.h +++ b/src/helpers/web/WebService.h @@ -15,6 +15,7 @@ public: void end(); void loop(); void suspendForOTA(); + void prepareForOTAStart(); void setCommandRunner(WebPanelCommandRunner* runner); void setNetworkStateProvider(NetworkStateProvider* network) { _network = network; } From d75e9b140c50f4c832e41ff72d5242082b013e8b Mon Sep 17 00:00:00 2001 From: Jared Dohrman Date: Thu, 23 Apr 2026 09:37:29 +1000 Subject: [PATCH 4/4] docs: add repeater-mqtt-eastmesh-v1.3.11 release notes --- docs/web-panel.md | 2 ++ release-notes.yml | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/docs/web-panel.md b/docs/web-panel.md index e056fd0d..76452eaf 100644 --- a/docs/web-panel.md +++ b/docs/web-panel.md @@ -315,6 +315,8 @@ On mobile: 3. The local HTTP redirect listener on port `80` is released so OTA can take over that port. 4. Continue with your normal OTA workflow. +If an older build sends you through a strange redirect after `start ota`, use the web `Start OTA` button to begin the upgrade anyway. The `repeater-mqtt-eastmesh-v1.3.11` release fixes that redirect issue. + ### Use Historical Stats 1. Enable stats if needed with `set web.stats on`. diff --git a/release-notes.yml b/release-notes.yml index bea35781..184142fc 100644 --- a/release-notes.yml +++ b/release-notes.yml @@ -455,3 +455,18 @@ releases: area: docs text: "Updated the web panel, API, and custom CLI docs to describe the board-aware battery display, the new MQTT client-version command, and the revised `/app` layout." breaking_changes: [] + + - track: repeater-mqtt + version: "1.3.11" + tag: "repeater-mqtt-eastmesh-v1.3.11" + date: "2026-04-23" + previous_version: "1.3.10" + summary: "Fixes the OTA start flow so the repeater web panel no longer falls into the old redirect glitch before upgrade." + changes: + - type: fixed + area: web-panel + text: "Fixed the repeater OTA start path so beginning an upgrade from the web panel no longer trips the earlier odd redirect behaviour before the OTA page loads." + - type: docs + area: web-panel + text: "Added a web-panel callout noting that if an older build hits the `start ota` redirect glitch, use the web `Start OTA` button to continue the upgrade, and that this release resolves the issue moving forward." + breaking_changes: []