From 05fcffc838304425c8d1427471671ea4e9fc48d7 Mon Sep 17 00:00:00 2001 From: Jared Dohrman Date: Fri, 17 Apr 2026 14:42:51 +1000 Subject: [PATCH] fix: start web stats capture from boot on >=4MB PSRAM boards --- docs/web-panel.md | 18 ++++++++++-------- src/helpers/StatsHistory.cpp | 18 ++++++++++++++++++ src/helpers/StatsHistory.h | 1 + src/helpers/web/WebPanelServer.cpp | 2 +- 4 files changed, 30 insertions(+), 9 deletions(-) diff --git a/docs/web-panel.md b/docs/web-panel.md index dd83ea06..3a009aba 100644 --- a/docs/web-panel.md +++ b/docs/web-panel.md @@ -28,12 +28,12 @@ Operational guidance: The screenshots below show the current split between the lighter `/app` admin page and the dedicated `/stats` status page. -### `/app` +### `/app` screenshot ![Repeater web panel `/app` overview](./_assets/repeater_web_panel_app_light.png#only-light) ![Repeater web panel `/app` overview](./_assets/repeater_web_panel_app_dark.png#only-dark) -### `/stats` +### `/stats` screenshot ![Repeater web panel `/stats` overview](./_assets/repeater_web_panel_stats_light.png#only-light) ![Repeater web panel `/stats` overview](./_assets/repeater_web_panel_stats_dark.png#only-dark) @@ -210,12 +210,14 @@ Stats samples are collected once per minute. Current in-memory history caps are: -| Board class | Sample cap | Event cap | Approx. sampled history | -| ------------------------------ | ---------: | --------: | ------------------------ | -| No PSRAM | `24` | `8` | Live-only recent history | -| Less than `4MB` PSRAM | `240` | `96` | About `4` hours | -| `4MB` to less than `8MB` PSRAM | `480` | `192` | About `8` hours | -| `8MB` PSRAM or more | `720` | `288` | About `12` hours | +| Board class | Sample cap | Event cap | Approx. sampled history | +| -------------------------------- | ---------: | --------: | ------------------------ | +| No PSRAM | `24` | `8` | Live-only recent history | +| Less than `4 MB` PSRAM | `240` | `96` | About `4` hours | +| `4 MB` to less than `8 MB` PSRAM | `480` | `192` | About `8` hours | +| `8 MB` PSRAM or more | `720` | `288` | About `12` hours | + +On boards with `4 MB` PSRAM or more, stats history starts capturing from boot when `web.stats` is enabled, even if `/stats` has not been opened yet. Archive-backed restore requires `web.stats` enabled plus a mounted SD card on boards that support the EastMesh archive path. diff --git a/src/helpers/StatsHistory.cpp b/src/helpers/StatsHistory.cpp index aee29c95..a37d4193 100644 --- a/src/helpers/StatsHistory.cpp +++ b/src/helpers/StatsHistory.cpp @@ -64,6 +64,14 @@ bool shouldUseLiveOnlyStats() { #endif } +bool hasBootAutoCapturePsram() { +#if defined(ESP32) + return psramFound() && ESP.getPsramSize() >= (4UL * 1024UL * 1024UL); +#else + return false; +#endif +} + template T* allocHistoryBuffer(size_t count) { #if defined(ESP32) @@ -291,6 +299,9 @@ void StatsHistory::begin(bool enabled, ArchiveStorage* archive) { _enabled = enabled; _next_summary_flush_ms = millis() + kSummaryFlushIntervalMs; _next_event_flush_ms = millis() + kEventFlushIntervalMs; + if (_enabled && shouldAutoActivateFromBoot()) { + activate(); + } } void StatsHistory::setArchive(ArchiveStorage* archive) { @@ -315,6 +326,9 @@ void StatsHistory::setEnabled(bool enabled) { _last_access_ms = 0; _next_summary_flush_ms = millis() + kSummaryFlushIntervalMs; _next_event_flush_ms = millis() + kEventFlushIntervalMs; + if (shouldAutoActivateFromBoot()) { + activate(); + } } } @@ -397,6 +411,10 @@ bool StatsHistory::supportsPersistence() const { return !_live_only; } +bool StatsHistory::shouldAutoActivateFromBoot() const { + return _enabled && !_live_only && hasBootAutoCapturePsram(); +} + bool StatsHistory::isAccessActive(uint32_t now_ms) const { if (!_live_only) { return true; diff --git a/src/helpers/StatsHistory.h b/src/helpers/StatsHistory.h index 040aa858..976578aa 100644 --- a/src/helpers/StatsHistory.h +++ b/src/helpers/StatsHistory.h @@ -106,6 +106,7 @@ private: bool ensureBuffers(); void releaseBuffers(); bool supportsPersistence() const; + bool shouldAutoActivateFromBoot() const; bool isAccessActive(uint32_t now_ms) const; bool restoreSummaryLog(); bool restoreEventsLog(); diff --git a/src/helpers/web/WebPanelServer.cpp b/src/helpers/web/WebPanelServer.cpp index cd15eb43..d53b865e 100644 --- a/src/helpers/web/WebPanelServer.cpp +++ b/src/helpers/web/WebPanelServer.cpp @@ -1684,7 +1684,7 @@ const char kWebPanelAppHtml[] PROGMEM = R"HTML( function sparkStrokeColor(key, points) { if (key === "packets") return "#d97706"; if (key === "signal") return "#3b82f6"; - if (key === "noise_floor") return "#ef4444"; + if (key === "noise_floor") return "#94a3b8"; if (key === "memory") { const values = Array.isArray(points) ? points.map((item) => item && item[1]).filter((value) => Number.isFinite(value)) : []; const current = values.length ? values[values.length - 1] : NaN;