Commit Graph
336 Commits
Author SHA1 Message Date
Valentin V. Bartenev 9c8f884f11 ESP32: add reset reason to boot event, CLI, and web panel
Implement getResetReason() and getResetReasonString() for ESP32Board,
covering all esp_reset_reason_t values: power-on, external reset,
software reset, panic/exception, interrupt watchdog, task watchdog,
generic watchdog, deep sleep wake, brownout, and SDIO reset.

Extend the pwrmgt.bootreason CLI command to support ESP32 alongside
NRF52. On ESP32 only the reset reason is reported (no shutdown reason).

Pass the reset reason as the value field when recording the
HISTORY_EVENT_BOOT stats event so the reason is stored in the in-memory
ring buffer and persisted to the archive events log.

Add bootReasonLabel() to the web panel and update renderEventsSection()
to annotate boot events with the human-readable reset reason string,
e.g. "boot (panic/exception)", when a non-null value is present.
2026-05-31 02:41:57 +03:00
Valentin V. Bartenev e11d14e6cc Fix: expand HistorySample::recv_errors from uint16_t to uint32_t
The error_rate graph showed all zeros after ~65535 receive errors had
accumulated.  Root cause was a two-part bug:

1. In MyMesh::updateStatsHistory(), recv_errors was clamped to 0xFFFF
   via min<uint32_t>(..., 0xFFFF).  Once the counter reached 65535,
   every subsequent sample stored the same constant value, making the
   per-interval delta always zero and therefore error_rate always zero.

2. HistorySample::recv_errors was declared as uint16_t while the
   underlying counter (n_recv_errors) is uint32_t.  parseSummaryLine()
   also truncated the restored value back to uint16_t.

Fix:
- Remove the clamp in MyMesh::updateStatsHistory(); assign
  getPacketsRecvErrors() (uint32_t) directly.
- Change HistorySample::recv_errors from uint16_t to uint32_t,
  moving it next to the other uint32_t fields.
- Update both parseSummaryLine() code paths to cast recv_errors to
  uint32_t instead of uint16_t.

The archive format is unchanged: recv_errors is written as %u and
read back into an unsigned local, which is correct for a 32-bit
value on ESP32.
2026-05-20 19:53:12 +03:00
Valentin V. Bartenev a9273f02bb Redesign approach for CPU usage tracking
The previous implementation maintained three exponential moving averages
(1/5/15-minute) of CPU busy-fraction, sampled every 5 seconds. This had
two problems:

1. Wrong semantics: the metric was labelled "load_avg" (a Unix concept
   measuring run-queue depth), but the tracker actually measures CPU
   busy-time as a fraction of FreeRTOS ticks — i.e. utilization, not
   load.  The name was misleading.

2. Poor responsiveness: the 1-minute EMA (DECAY = exp(-5/60) ≈ 0.920)
   has a ~60-second time constant.  On a live web panel, this made the
   metric appear frozen, especially during short bursts of activity
   (e.g. an HTTP request from the panel itself).

This commit replaces the EMA with a 64-sample simple moving average
(SMA) over a compact uint8_t circular buffer. The sample interval is
60 s / 64 = 937,500 µs, so the window covers exactly 60 seconds:

Algorithm:
- Every 937,500 µs (= 60 s / 64), the FreeRTOS tick delta (busy vs
  idle ticks on core 0) is computed and stored as a uint8_t
  (0–255 = 0–100% utilization).
- The circular buffer holds 64 samples, spanning exactly 60 seconds
  (64 × 937,500 µs = 60,000,000 µs). The timer interval is derived
  directly from the window size: 60 000 000 / SMA_WINDOW µs.
- The index wraps with a bitwise AND (& 63) instead of modulo, since
  64 is a power of 2.
- The running sum is a uint16_t (max 64 × 255 = 16 320, fits easily).
- The result _sma_avg is a volatile float written atomically by the
  esp_timer task (core 0) and read from the main loop (core 1).
  No spinlock is needed: on Xtensa LX7, a 32-bit aligned float store
  is a single instruction.

The 60-second window smooths out short bursts (e.g. WiFi/HTTP spikes)
while reacting to sustained load changes within ~10–15 seconds.

Naming:
- The public API is now getCore0Util() returning a float in [0.0, 1.0].
  The name explicitly identifies which core is measured (core 0, which
  runs WiFi, MQTT, HTTP, and LwIP — see task_pinning.c).
- JSON keys: "load_avg" (array) → "core0_util" (scalar float, percent)
- HistorySample field: load_avg1_pct → core0_util_pct
- StatsHistory series key: "cpu_load" → "core0_util"
- Web panel label: "Load Avg" → "Core0 Util"

The history snapshot (once per minute) reads the same _sma_avg value,
which at that point represents the rolling average of the last 60
seconds — exactly one history interval.
2026-05-10 06:26:08 +03:00
Valentin V. Bartenev eaf3c4c263 Stats: add CPU load trend series to history and web panel
Wire the 1-minute CPU load average into the stats history pipeline:

- Rename HistorySample::reserved to load_avg1_pct (uint8_t, 0-100);
  struct size unchanged.
- Populate load_avg1_pct in updateStatsHistory on ESP32 from
  _cpu_tracker.getLoadAvg1() * 100.
- Register "cpu_load" series in buildPointValue / seriesTitle /
  seriesUnit so buildSeriesJson serves it via
  /api/stats?series=cpu_load.
- Persist load_avg1_pct as a 29th CSV column in flushSummaryLog.
  parseSummaryLine accepts both 28-column (old, load_avg1_pct=0)
  and 29-column (new) formats for backward compatibility.
- Add "cpu_load" to the web panel trend card order with orange
  sparkline color (#e07b39), "N %" hover formatting, and a Y-axis
  floored at 0 with a 10% minimum ceiling.
2026-05-09 22:31:02 +03:00
Valentin V. Bartenev a6f01d544e ESP32: add CPUUsageTracker – core-0 load averages (1/5/15 min)
Track CPU utilisation on core 0 using a FreeRTOS tick hook that
increments per-tick idle/busy counters, sampled every 5s by an
esp_timer callback.  Exponential moving averages with Linux-style
time constants (1 / 5 / 15 min) are maintained in software:

  DECAY1  = exp(-5/60)  ≈ 0.9200  (1-minute window)
  DECAY5  = exp(-5/300) ≈ 0.9835  (5-minute window)
  DECAY15 = exp(-5/900) ≈ 0.9945  (15-minute window)

Core 1 is excluded intentionally: it runs the Arduino loopTask at
100% load for LoRa packet processing, so its figure is always 1.0
and carries no diagnostic value.  All other tasks are pinned to
core 0 by task_pinning.c, so core-0 load reflects the true system
utilisation.

New files:
  arch/esp32/CPUUsageTracker.h   – class declaration
  arch/esp32/CPUUsageTracker.cpp – tick hook + esp_timer sampling

Integration:
  MyMesh::begin() calls _cpu_tracker.begin() on ESP32 builds.
  formatStatsReply() emits "load_avg":[<1m>,<5m>,<15m>] in the
  compact stats JSON payload.
  formatWebStatsSummaryJson() adds the same field to the web-panel
  stats endpoint under core.load_avg.
  The web-panel HUD gains a "Load Avg" metric tile showing all
  three values side-by-side; the core-metrics grid is widened from
  4 to 5 columns.  The tile is rendered conditionally so older
  firmware (or non-ESP32 builds) that omit the field degrade
  gracefully.
  CPUUsageTracker.cpp is added to the esp32_base build_src_filter
  in platformio.ini.
2026-05-09 17:26:27 +03:00
Valentin V. Bartenev afd5fc2f98 Unify firmware version format with release builds. 2026-04-29 01:07:11 +03:00
Valentin V. Bartenev 46b0df7a4b Removed EastMesh MQTT broker support.
It's intended for Eastern Australia repeaters only.  Using original EastMesh
firmware is prefered in this case.
2026-04-28 00:52:26 +03:00
Valentin V. Bartenev f1912ff184 Added support for MeshCoreTel broker. 2026-04-27 03:15:00 +03:00
Jared Dohrman 4b83142b9e fix: start ota is now consistent across command sources 2026-04-23 09:27:48 +10:00
Jared Dohrman 46f0496865 feat: add mqtt client version to repeater app and cli 2026-04-22 13:29:03 +10:00
Jared Dohrman b1a32fa56b fix: make repeater stats battery display board-aware 2026-04-22 10:57:04 +10:00
Jared Dohrman bbab7c95d4 refactor: remove legacy battery reporting toggle path 2026-04-22 09:57:51 +10:00
Jared Dohrman 274cb8b8c2 fix: reduce repeater battery polling 2026-04-22 08:50:07 +10:00
Jared Dohrman 63e9368c84 fix: improve stats archive rotation and satellites trend handling 2026-04-21 19:14:17 +10:00
Jared Dohrman 2ad3b134f2 fix: suspend web panel for OTA 2026-04-21 18:19:33 +10:00
Jared Dohrman 0ad50e5bd0 repeater-mqtt-eastmesh-v1.3.8 2026-04-21 18:07:04 +10:00
Jared Dohrman 746396aee9 fix: sd card shares the radio SPI object 2026-04-21 16:01:19 +10:00
Jared Dohrman bcce0071f1 feat: open full web CLI access and add panel redirect flow 2026-04-20 08:59:24 +10:00
Jared Dohrman 5a4adadbbf chore: add region to allowlist CLI 2026-04-19 15:49:57 +10:00
Jared Dohrman 2646d7177e Merge upstream/dev into develop 2026-04-19 12:21:01 +10:00
Scott Powell 3751785400 * version 1.15.0 2026-04-19 11:27:55 +10:00
Jared Dohrman 55d50f29d3 docs: sync web-panel CLI allowlist and note AGC reset workaround 2026-04-18 14:49:55 +10:00
Jared Dohrman e05c9bc09c Merge upstream/dev into develop 2026-04-17 17:54:47 +10:00
Jared Dohrman 64402c7f5e fix: improve web stats startup and memory indicators 2026-04-17 17:40:32 +10:00
Scott Powell d7a3d41843 Merge branch 'default-scope' into dev 2026-04-17 16:30:19 +10:00
Scott Powell 77d02e844f * bug fix 2026-04-17 14:38:03 +10:00
Jared Dohrman d412e3e84a fix: improve repeater stats UX and persist ESP32 fallback clock 2026-04-17 12:17:35 +10:00
Jared Dohrman b2ea2f882d fix(stats): lazy-init web stats and degrade non-PSRAM boards to live-only 2026-04-16 18:09:07 +10:00
Scott Powell df1e12de3e * Repeater, room server: rule change for sendFloodReply() 2026-04-16 13:22:39 +10:00
Jared Dohrman 785f5c2fd3 fix: restore /stats Wi-Fi signal quality and refresh web panel screenshots 2026-04-15 17:35:29 +10:00
Jared Dohrman f67aaebe7e feat: add SD-backed stats archive and dedicated /stats web console 2026-04-15 17:12:32 +10:00
Scott Powell 4131a455a2 * repeater: refactored 'region' CLI commands -> CommonCLI
* room server: added RegionMap, and new CommonCLI wiring, default_scope handling
* sensor: only minimal RegionMap wiring. Still needs work to handle default-scope
2026-04-15 13:32:49 +10:00
Scott Powell 569cfe177a * repeater: default-scope support 2026-04-14 17:51:34 +10:00
Jared Dohrman 71ddba8bdc feat: expand repeater web panel with radio presets, info cards, and clock sync controls 2026-04-12 10:33:13 +10:00
Jared Dohrman 4f4964e454 fix: add battery reporting toggle for Heltec V3 and clean up VS Code metadata 2026-04-11 18:14:30 +10:00
Jared Dohrman 6680e53ef5 fix: improve MQTT/web memory usage and streamline broker controls 2026-04-11 16:40:45 +10:00
Jared Dohrman 328a0ecf6f fix(mqtt): clear legacy prefs, restore status publishing, and expand web controls 2026-04-10 22:24:58 +10:00
Jared Dohrman 60648142a2 feat(mqtt,docs): add mqtt.status control and tighten migration guidance 2026-04-10 18:26:29 +10:00
Jared Dohrman b5374a705a feat(web,mqtt): add repeater dashboard, MQTT settings, and stabilise HTTPS/TLS startup 2026-04-10 15:18:19 +10:00
Jared Dohrman 98fe78a379 feat: add MQTT repeater support, web config panel, and EastMesh-specific firmware workflows 2026-04-09 15:00:53 +10:00
Wessel NieboerandWessel Nieboer 0a13ac7fc7 Default button polarity to active-LOW across all firmware types
Nearly all LoRa boards use a boot button that pulls to ground when
pressed.
2026-04-04 13:19:13 +02:00
terminalvelocity23 08de3fb01f Make sendNodeDiscoverReq() public for post-boot discovery 2026-03-30 22:35:05 +03:00
Scott Powell 467959cc3b * version 1.14.1 2026-03-20 12:32:41 +11:00
João BrázioandGitHub 92bef49c55 Merge branch 'dev' into 2026/remote-lna 2026-03-16 09:40:10 +00:00
João Brázio 274e00df50 Merge remote-tracking branch 'upstream/dev' into 2026/remote-lna 2026-03-16 09:37:55 +00:00
Scott Powell fcfdc5fc5b * Repeater and Room Server: flood advert timer now uses the path_hash_mode pref 2026-03-16 13:56:19 +11:00
Scott Powell bb8dc5b55b Merge branch 'main' into dev 2026-03-12 18:14:56 +11:00
ripplebizandGitHub 792f299986 Merge pull request #1873 from Specter242/codex/sensecap-solar-led-poweroff-parity
sensecap solar: add poweroff/shutdown support and nrf52 PM parity
2026-03-12 18:13:14 +11:00
ripplebizandGitHub cf0cc851d4 Merge pull request #1297 from ViezeVingertjes/feature/duty-cycle-token-bucket
Implement token bucket duty cycle enforcement
2026-03-08 23:54:32 +11:00
ripplebizandGitHub 29be7e293c Merge pull request #1877 from DanielNovak/fix-countbefore-sentinel-regression
Fix countBefore regression: replace sentinel with getOutboundTotal()
2026-03-07 18:48:02 +11:00