Merge pull request #35 from xJARiD/develop
fix TBeam 1W, improve cache, sync docs, add AGENTS.md
This commit is contained in:
@@ -0,0 +1,222 @@
|
||||
# AGENTS.md
|
||||
|
||||
## Purpose
|
||||
|
||||
EastMesh layer on top of upstream MeshCore.
|
||||
|
||||
**Default:** preserve upstream behavior.
|
||||
Only modify code for clearly scoped EastMesh features:
|
||||
|
||||
- `*_repeater_mqtt`
|
||||
- `*_companion_radio_wifi`
|
||||
- MQTT uplink/broker
|
||||
- repeater web panel
|
||||
- docs, releases, automation
|
||||
|
||||
## Principles
|
||||
|
||||
- Minimal, targeted changes
|
||||
- Prefer additive over modifying upstream code
|
||||
- Avoid unrelated refactors
|
||||
- Maintain parity with upstream behavior
|
||||
|
||||
## Guardrails
|
||||
|
||||
### Upstream
|
||||
|
||||
- Do not modify unrelated MeshCore logic
|
||||
- Do not change CLI semantics unless explicitly required
|
||||
- Do not introduce breaking changes to existing targets
|
||||
|
||||
### Docs (update in same PR when practical)
|
||||
|
||||
| Change | File |
|
||||
| --------------------- | -------------------- |
|
||||
| CLI / allowlist | `docs/custom-cli.md` |
|
||||
| Web panel UI/behavior | `docs/web-panel.md` |
|
||||
| Releases | `release-notes.yml` |
|
||||
| Flashing guidance | `docs/releases.md` |
|
||||
|
||||
### Web Panel Gate
|
||||
|
||||
If editing `examples/simple_repeater/MyMesh.cpp`, also update `docs/custom-cli.md`.
|
||||
|
||||
## Tooling
|
||||
|
||||
- Use `uv` + PlatformIO via `uv run`
|
||||
- Do not assume global `pio`
|
||||
|
||||
### Build Policy
|
||||
|
||||
Builds are expensive. Avoid unless necessary.
|
||||
|
||||
Do NOT build for:
|
||||
|
||||
- docs / HTML / CSS only
|
||||
|
||||
Prefer:
|
||||
|
||||
- user-run local builds
|
||||
- reasoning over execution
|
||||
|
||||
Build only if:
|
||||
|
||||
- high-risk change
|
||||
- firmware behavior must be verified
|
||||
|
||||
### Commands
|
||||
|
||||
```bash
|
||||
uv sync
|
||||
uv run pio run -e <env>
|
||||
uv run pio device monitor --port <port> --baud 115200
|
||||
uv run --group docs zensical serve
|
||||
uv run --group docs zensical build
|
||||
```
|
||||
|
||||
Do not assume `pio` is installed globally.
|
||||
|
||||
## Common Commands
|
||||
|
||||
List build targets:
|
||||
|
||||
```bash
|
||||
bash build.sh list
|
||||
```
|
||||
|
||||
Build a single target:
|
||||
|
||||
```bash
|
||||
uv run pio run -e heltec_v4_repeater_mqtt
|
||||
uv run pio run -e T_Beam_S3_Supreme_SX1262_repeater_mqtt
|
||||
uv run pio run -e heltec_v4_companion_radio_wifi
|
||||
uv run pio run -e T_Beam_S3_Supreme_SX1262_companion_radio_wifi
|
||||
```
|
||||
|
||||
Build with release-style metadata:
|
||||
|
||||
```bash
|
||||
export FIRMWARE_VERSION=v1.14.1
|
||||
export EASTMESH_VERSION=v1.0.1
|
||||
bash build.sh build-firmware heltec_v4_repeater_mqtt
|
||||
bash build.sh build-firmware T_Beam_S3_Supreme_SX1262_repeater_mqtt
|
||||
```
|
||||
|
||||
Flash a target:
|
||||
|
||||
```bash
|
||||
uv run pio run -e heltec_v4_repeater_mqtt -t upload --upload-port /dev/tty.usbmodemXXXX
|
||||
uv run pio run -e T_Beam_S3_Supreme_SX1262_repeater_mqtt -t upload --upload-port /dev/tty.usbmodemXXXX
|
||||
```
|
||||
|
||||
## Key Files
|
||||
|
||||
- `build.sh` — build wrapper
|
||||
- `platformio.ini`
|
||||
- `variants/eastmesh_mqtt/platformio.ini`
|
||||
- `examples/simple_repeater/MyMesh.cpp`
|
||||
- `src/helpers/mqtt/MQTTUplink.cpp`
|
||||
- `docs/*.md`
|
||||
- `RELEASE.md`
|
||||
- `release-notes.yml`
|
||||
|
||||
## Docs Sync Requirements
|
||||
|
||||
If you change any of the following, update docs in the same PR when practical:
|
||||
|
||||
- Web-panel allowlisted commands:
|
||||
- update `docs/custom-cli.md`
|
||||
- Web-panel user-facing behavior, sections, controls, or troubleshooting:
|
||||
- update `docs/web-panel.md`
|
||||
- EastMesh CLI additions or changed semantics:
|
||||
- update `docs/custom-cli.md`
|
||||
- Release/tag preparation:
|
||||
- update `release-notes.yml`
|
||||
- Flashing/release asset guidance:
|
||||
- update `docs/releases.md`
|
||||
|
||||
## Repeater MQTT Notes
|
||||
|
||||
`*_repeater_mqtt` builds may include the local HTTPS web panel on supported ESP32 targets.
|
||||
|
||||
Operational guidance already reflected in docs:
|
||||
|
||||
- use for initial setup and troubleshooting
|
||||
- prefer `set web off` afterward for maximum heap headroom
|
||||
|
||||
## Companion WiFi Notes
|
||||
|
||||
`*_companion_radio_wifi` targets support persisted Wi-Fi rescue commands via serial `CLI Rescue`.
|
||||
|
||||
Do not document companion rescue commands in repeater docs. Do not assume web-panel behavior applies.
|
||||
|
||||
Companion release/version rule:
|
||||
|
||||
- companion tags use the official upstream MeshCore release version only
|
||||
- the current official MeshCore version is `v1.14.1`
|
||||
- companion releases are only cut when `meshcore-dev/MeshCore` has made an official release
|
||||
- do not invent separate EastMesh companion version numbers
|
||||
|
||||
## Release Workflow
|
||||
|
||||
Current tag formats:
|
||||
|
||||
```bash
|
||||
git tag companion-wifi-v1.2.3
|
||||
git tag repeater-mqtt-eastmesh-v1.0.1
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- `companion-wifi` tags use the upstream MeshCore version directly
|
||||
- `repeater-mqtt` tags use the EastMesh release version in the tag
|
||||
- GitHub Actions variable `OFFICIAL_MESHCORE_VERSION` supplies the upstream base version for repeater MQTT release builds
|
||||
- if the upstream MeshCore release version changes, update `OFFICIAL_MESHCORE_VERSION` in GitHub before cutting release tags
|
||||
|
||||
Typical release flow:
|
||||
|
||||
1. Update `OFFICIAL_MESHCORE_VERSION` if upstream changed.
|
||||
2. Update `release-notes.yml` on `develop`.
|
||||
3. Merge the release PR from `develop` to `main`.
|
||||
4. Create the desired release tag or tags on the target commit on `main`.
|
||||
5. Push the tags.
|
||||
|
||||
## Upstream Sync Workflow
|
||||
|
||||
When asked to pull from upstream MeshCore:
|
||||
|
||||
- pull from `meshcore-dev/MeshCore:dev`
|
||||
- start from local `develop`
|
||||
- create a temporary integration branch off `develop`
|
||||
- merge upstream `dev` into that temporary integration branch
|
||||
- resolve conflicts in a way that preserves EastMesh-specific changes
|
||||
- merge the finished integration branch back into `develop`
|
||||
|
||||
Do not merge upstream directly into `main`.
|
||||
|
||||
## Scope Boundaries
|
||||
|
||||
Do NOT (unless asked):
|
||||
|
||||
- rename tracks
|
||||
- change tag formats
|
||||
- expand allowlist without updating docs
|
||||
- change upstream CLI semantics
|
||||
- introduce new versioning schemes
|
||||
|
||||
## Commit Messages
|
||||
|
||||
Use concise, conventional prefixes:
|
||||
|
||||
- `feat:` new functionality
|
||||
- `fix:` bug fixes
|
||||
- `docs:` documentation changes
|
||||
- `chore:` maintenance, tooling, non-functional
|
||||
- `refactor:` code changes without behavior change
|
||||
|
||||
Keep messages short and scoped.
|
||||
|
||||
## Decision Rule
|
||||
|
||||
If a change is not clearly EastMesh-specific, do not modify the code.
|
||||
When uncertain, prefer no change or request clarification.
|
||||
+265
-48
File diff soppresso perché troppo grande
Carica Diff
+27
-1
@@ -75,6 +75,8 @@ Legacy dotted aliases are also accepted:
|
||||
- `stats-radio`: shows radio noise floor, last RSSI, last SNR, and TX/RX airtime.
|
||||
- `stats-packets`: shows packet receive/send totals, flood/direct breakdown, and receive errors.
|
||||
|
||||
> If `noise_floor` reports `0`, check `get agc.reset.interval`; if it is not `0`, try `set agc.reset.interval 0` and test again.
|
||||
|
||||
### Board Battery Reporting
|
||||
|
||||
- `get battery.reporting`: shows whether board battery reporting is enabled. Support is board-dependent.
|
||||
@@ -94,13 +96,15 @@ That allowlist currently includes:
|
||||
- `advert`
|
||||
- `reboot`
|
||||
- `start ota`
|
||||
- `set repeat on|off`
|
||||
- `memory`
|
||||
- `stats-core`
|
||||
- `stats-radio`
|
||||
- `stats-packets`
|
||||
- `get wifi.status`
|
||||
- `get wifi.powersaving`
|
||||
- `set wifi.ssid <ssid>`
|
||||
- `set wifi.pwd <password>`
|
||||
- `set wifi.powersaving on|off`
|
||||
- `get mqtt.iata`
|
||||
- `set mqtt.iata <code>`
|
||||
- `get mqtt.owner`
|
||||
@@ -117,29 +121,51 @@ That allowlist currently includes:
|
||||
- `set mqtt.tx on|off`
|
||||
- `get mqtt.eastmesh-au`
|
||||
- `set mqtt.eastmesh-au on|off`
|
||||
- `get mqtt.eastmesh.au`
|
||||
- `set mqtt.eastmesh.au on|off`
|
||||
- `get mqtt.letsmesh-eu`
|
||||
- `set mqtt.letsmesh-eu on|off`
|
||||
- `get mqtt.letsmesh.eu`
|
||||
- `set mqtt.letsmesh.eu on|off`
|
||||
- `get mqtt.letsmesh-us`
|
||||
- `set mqtt.letsmesh-us on|off`
|
||||
- `get mqtt.letsmesh.us`
|
||||
- `set mqtt.letsmesh.us on|off`
|
||||
- `set web on|off`
|
||||
- `set.web on|off`
|
||||
- `set web.stats on|off`
|
||||
- `set.web.stats on|off`
|
||||
- `get name`
|
||||
- `set name <device-name>`
|
||||
- `get lat`
|
||||
- `set lat <latitude>`
|
||||
- `get lon`
|
||||
- `set lon <longitude>`
|
||||
- `get radio`
|
||||
- `set radio <freq> <bw> <sf> <cr>`
|
||||
- `get prv.key`
|
||||
- `get guest.password`
|
||||
- `password <admin-password>`
|
||||
- `set guest.password <password>`
|
||||
- `set prv.key <64-hex-char-private-key>`
|
||||
- `get role`
|
||||
- `get public.key`
|
||||
- `get advert.interval`
|
||||
- `set advert.interval <minutes>`
|
||||
- `get agc.reset.interval`
|
||||
- `set agc.reset.interval <seconds>`
|
||||
- `get flood.advert.interval`
|
||||
- `set flood.advert.interval <hours>`
|
||||
- `get repeat`
|
||||
- `set repeat on|off`
|
||||
- `get flood.max`
|
||||
- `set flood.max <count>`
|
||||
- `get path.hash.mode`
|
||||
- `set path.hash.mode <mode>`
|
||||
- `get owner.info`
|
||||
- `set owner.info <text>`
|
||||
- `time <iso-or-epoch>`
|
||||
- `time.force <iso-or-epoch>`
|
||||
|
||||
## Companion WiFi Rescue Commands
|
||||
|
||||
|
||||
@@ -140,6 +140,7 @@ This is a small terminal for allowlisted commands.
|
||||
- command history is shown in the terminal box below
|
||||
- save buttons elsewhere in the page also show the generated command and the reply here
|
||||
- `clock` is available here if you want to check the repeater's current board time
|
||||
- the full current allowlist is documented in `docs/custom-cli.md` under `Web Panel Allowlisted Commands`
|
||||
|
||||
This makes it easy to see exactly what the panel sent to the repeater.
|
||||
|
||||
|
||||
@@ -2036,6 +2036,7 @@ void MyMesh::runWebCommand(const char* command, char* reply, size_t reply_size)
|
||||
matches_exact("get role") ||
|
||||
matches_exact("get public.key") ||
|
||||
matches_exact("get advert.interval") ||
|
||||
matches_exact("get agc.reset.interval") ||
|
||||
matches_exact("get flood.advert.interval") ||
|
||||
matches_exact("get repeat") ||
|
||||
matches_exact("get flood.max") ||
|
||||
@@ -2070,6 +2071,7 @@ void MyMesh::runWebCommand(const char* command, char* reply, size_t reply_size)
|
||||
matches_prefix("set guest.password ") ||
|
||||
matches_prefix("set prv.key ") ||
|
||||
matches_prefix("set advert.interval ") ||
|
||||
matches_prefix("set agc.reset.interval ") ||
|
||||
matches_prefix("set flood.advert.interval ") ||
|
||||
matches_prefix("set repeat ") ||
|
||||
matches_prefix("set flood.max ") ||
|
||||
|
||||
@@ -275,3 +275,24 @@ releases:
|
||||
area: web-panel
|
||||
text: "Updated the web panel docs to describe the rough 2 MB PSRAM boot-history cutoff."
|
||||
breaking_changes: []
|
||||
|
||||
- track: repeater-mqtt
|
||||
version: "1.3.4"
|
||||
tag: "repeater-mqtt-eastmesh-v1.3.4"
|
||||
date: "2026-04-18"
|
||||
previous_version: "1.3.3"
|
||||
summary: "Polished the repeater web panel, fixed a T-Beam 1W build issue, and synced the documented web CLI allowlist with the shipped browser console."
|
||||
changes:
|
||||
- type: fixed
|
||||
area: board-support
|
||||
text: "Added the missing T-Beam 1W flash partition size so the repeater_mqtt target builds with the correct partition layout."
|
||||
- type: changed
|
||||
area: web-panel
|
||||
text: "Cached the repeater title across both the /app and /stats pages so the local admin UI presents a more consistent device label."
|
||||
- type: changed
|
||||
area: web-panel
|
||||
text: "Applied the newer four-band threshold styling to the largest-block memory meters in the /stats Memory card."
|
||||
- type: docs
|
||||
area: web-panel
|
||||
text: "Updated the documented web CLI allowlist to match the actual browser command gate, including the AGC reset interval commands and the troubleshooting note for `noise_floor` reporting `0`."
|
||||
breaking_changes: []
|
||||
|
||||
@@ -994,6 +994,7 @@ const char kWebPanelAppHtml[] PROGMEM = R"HTML(
|
||||
const RADIO_PRESETS_URL = "https://api.meshcore.nz/api/v1/config";
|
||||
const isStatsPage = window.location.pathname === "/stats";
|
||||
const LAST_PAGE_KEY = "repeater-last-page";
|
||||
const PANEL_TITLE_KEY = "repeater-panel-title";
|
||||
let token = sessionStorage.getItem("repeater-token") || "";
|
||||
let commandQueue = Promise.resolve();
|
||||
let radioPresetEntries = [];
|
||||
@@ -1005,7 +1006,19 @@ const char kWebPanelAppHtml[] PROGMEM = R"HTML(
|
||||
function updatePanelTitle(nameValue) {
|
||||
const fallbackTitle = "Repeater Config";
|
||||
const trimmedName = String(nameValue == null ? "" : nameValue).trim();
|
||||
document.title = trimmedName ? trimmedName : fallbackTitle;
|
||||
const nextTitle = trimmedName ? trimmedName : fallbackTitle;
|
||||
document.title = nextTitle;
|
||||
if (trimmedName) {
|
||||
localStorage.setItem(PANEL_TITLE_KEY, trimmedName);
|
||||
} else {
|
||||
localStorage.removeItem(PANEL_TITLE_KEY);
|
||||
}
|
||||
}
|
||||
function applyCachedPanelTitle() {
|
||||
const cachedTitle = localStorage.getItem(PANEL_TITLE_KEY);
|
||||
if (cachedTitle && cachedTitle.trim()) {
|
||||
document.title = cachedTitle.trim();
|
||||
}
|
||||
}
|
||||
function rememberCurrentPage() {
|
||||
localStorage.setItem(LAST_PAGE_KEY, isStatsPage ? "/stats" : "/app");
|
||||
@@ -1017,6 +1030,7 @@ const char kWebPanelAppHtml[] PROGMEM = R"HTML(
|
||||
window.location.replace("/");
|
||||
}
|
||||
rememberCurrentPage();
|
||||
applyCachedPanelTitle();
|
||||
function getPreferredTheme() {
|
||||
const saved = localStorage.getItem("repeater-theme");
|
||||
if (saved === "light" || saved === "dark") return saved;
|
||||
@@ -1340,6 +1354,13 @@ const char kWebPanelAppHtml[] PROGMEM = R"HTML(
|
||||
if (percent >= 35) return "warn";
|
||||
return "bad";
|
||||
}
|
||||
function toneForLargestBlockPercent(percent) {
|
||||
if (!Number.isFinite(percent)) return "bad";
|
||||
if (percent >= 75) return "";
|
||||
if (percent >= 55) return "ok";
|
||||
if (percent >= 35) return "warn";
|
||||
return "bad";
|
||||
}
|
||||
function colorForHeapFreePercent(percent) {
|
||||
const tone = toneForHeapFreePercent(percent);
|
||||
if (tone === "ok") return "#6ea43f";
|
||||
@@ -1511,11 +1532,13 @@ const char kWebPanelAppHtml[] PROGMEM = R"HTML(
|
||||
const psramFree = memory.psram_free || 0;
|
||||
const psramMax = memory.psram_max || 0;
|
||||
const heapFreePct = pctRange(heapFree, 0, 128 * 1024);
|
||||
const heapLargestPct = pctRatio(heapMax, heapFree);
|
||||
const psramLargestPct = pctRatio(psramMax, psramFree);
|
||||
return `<section class="hud-card">
|
||||
<h3>Memory</h3>
|
||||
${renderMeter("Heap Free", formatBytes(heapFree), heapFreePct, "total free heap", toneForHeapFreePercent(heapFreePct))}
|
||||
${renderMeter("Heap Largest Block", formatBytes(heapMax), pctRatio(heapMax, heapFree), "largest alloc vs free", false)}
|
||||
${renderMeter("PSRAM Largest Block", formatBytes(psramMax), pctRatio(psramMax, psramFree), "largest alloc vs free", false)}
|
||||
${renderMeter("Heap Largest Block", formatBytes(heapMax), heapLargestPct, "largest alloc vs free", toneForLargestBlockPercent(heapLargestPct))}
|
||||
${renderMeter("PSRAM Largest Block", formatBytes(psramMax), psramLargestPct, "largest alloc vs free", toneForLargestBlockPercent(psramLargestPct))}
|
||||
<div class="metric-grid">
|
||||
${renderMetric("Heap Free", formatBytes(heapFree))}
|
||||
${renderMetric("Heap Min", formatBytes(memory.heap_min || 0))}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
[LilyGo_TBeam_1W]
|
||||
extends = esp32_base
|
||||
board = t_beam_1w
|
||||
board_build.partitions = default_8MB.csv
|
||||
board_upload.maximum_size = 8388608
|
||||
build_flags =
|
||||
${esp32_base.build_flags}
|
||||
-I variants/lilygo_tbeam_1w
|
||||
|
||||
Fai riferimento in un nuovo problema
Block a user