Web: poll for device reboot after OTA upload

After a successful firmware upload the UI previously showed a static
"Done. Device is rebooting..." message with no indication of progress.

Replace the static message with a live polling loop.  A dot is appended
to the message every second as a visual progress indicator.  After a
4-second initial delay (to allow the device to start rebooting), the
loop fetches "/" to check whether the HTTPS server is back up.  On a
successful response the interval is cleared and the user is redirected
to the login page after 1.5 s (the session token is invalidated by the
reboot).  On a network error the fetch is retried every 4 seconds.
A guard value of 1000 prevents a second fetch from being started while
the first is still in flight.  If the device does not respond within
60 seconds the loop stops and an error message is shown.
이 커밋은 다음에 포함됨:
Valentin V. Bartenev
2026-05-11 10:52:48 +03:00
부모 ac33787de5
커밋 34cadd3a8e
+17 -1
파일 보기
@@ -2641,7 +2641,23 @@ const char kWebPanelAppHtml[] PROGMEM = R"HTML(
}
if (xhr.status === 200) {
barEl.style.width = "100%";
msgEl.textContent = "Done. Device is rebooting...";
msgEl.textContent = "Done. Device is rebooting";
let wait = 4;
const iv = setInterval(async () => {
msgEl.textContent += '.';
if (msgEl.textContent.length > 85) { clearInterval(iv); msgEl.textContent = "Device did not come back online. =("; return; }
if (--wait) { return; }
wait = 1000; // prevent concurrent fetch
try {
if ((await fetch("/", { cache: "no-store" })).ok) {
clearInterval(iv);
msgEl.textContent = "Device is back online. Redirecting to login...";
setTimeout(redirectToLogin, 1500);
return;
}
} catch (_) {}
wait = 4;
}, 1000);
} else {
msgEl.textContent = "Failed: " + (xhr.responseText || String(xhr.status));
document.getElementById("otaUploadBtn").disabled = false;