diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..66c1c24d --- /dev/null +++ b/AGENTS.md @@ -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 +uv run pio device monitor --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. diff --git a/docs/cli_commands.md b/docs/cli_commands.md index 16066efa..a9c68901 100644 --- a/docs/cli_commands.md +++ b/docs/cli_commands.md @@ -25,58 +25,77 @@ This document provides an overview of CLI commands that can be sent to MeshCore ## Operational ### Reboot the node -**Usage:** + +**Usage:** + - `reboot` --- ### Reset the clock and reboot + **Usage:** + - `clkreboot` --- ### Sync the clock with the remote device -**Usage:** + +**Usage:** + - `clock sync` --- ### Display current time in UTC + **Usage:** + - `clock` --- ### Set the time to a specific timestamp -**Usage:** + +**Usage:** + - `time ` **Parameters:** + - `epoch_seconds`: Unix epoch time --- ### Send a flood advert -**Usage:** + +**Usage:** + - `advert` --- ### Send a zero-hop advert + **Usage:** + - `advert.zerohop` --- ### Start an Over-The-Air (OTA) firmware update + **Usage:** + - `start ota` --- ### Erase/Factory Reset + **Usage:** + - `erase` **Serial Only:** Yes @@ -88,7 +107,9 @@ This document provides an overview of CLI commands that can be sent to MeshCore ## Neighbors (Repeater Only) ### List nearby neighbors -**Usage:** + +**Usage:** + - `neighbors` **Note:** The output of this command is limited to the 8 most recent adverts. @@ -98,17 +119,21 @@ This document provides an overview of CLI commands that can be sent to MeshCore --- ### Remove a neighbor -**Usage:** + +**Usage:** + - `neighbor.remove ` -**Parameters:** +**Parameters:** + - `pubkey_prefix`: The public key of the node to remove from the neighbors list --- ### Discover zero hop neighbors -**Usage:** +**Usage:** + - `discover.neighbors` --- @@ -116,12 +141,15 @@ This document provides an overview of CLI commands that can be sent to MeshCore ## Statistics ### Clear Stats + **Usage:** `clear stats` --- ### System Stats - Battery, Uptime, Queue Length and Debug Flags -**Usage:** + +**Usage:** + - `stats-core` **Serial Only:** Yes @@ -129,13 +157,17 @@ This document provides an overview of CLI commands that can be sent to MeshCore --- ### Radio Stats - Noise floor, Last RSSI/SNR, Airtime, Receive errors + **Usage:** `stats-radio` +If `noise_floor` reports `0`, check `get agc.reset.interval`. If it is not `0`, try `set agc.reset.interval 0` and test again. + **Serial Only:** Yes --- ### Packet stats - Packet counters: Received, Sent + **Usage:** `stats-packets` **Serial Only:** Yes @@ -145,21 +177,25 @@ This document provides an overview of CLI commands that can be sent to MeshCore ## Logging ### Begin capture of rx log to node storage + **Usage:** `log start` --- ### End capture of rx log to node storage + **Usage:** `log stop` --- ### Erase captured log + **Usage:** `log erase` --- ### Print the captured log to the serial terminal + **Usage:** `log` **Serial Only:** Yes @@ -169,11 +205,13 @@ This document provides an overview of CLI commands that can be sent to MeshCore ## Info ### Get the Version + **Usage:** `ver` --- ### Show the hardware name + **Usage:** `board` --- @@ -183,11 +221,14 @@ This document provides an overview of CLI commands that can be sent to MeshCore ### Radio #### View or change this node's radio parameters + **Usage:** + - `get radio` - `set radio ,,,` **Parameters:** + - `freq`: Frequency in MHz - `bw`: Bandwidth in kHz - `sf`: Spreading factor (5-12) @@ -202,11 +243,14 @@ This document provides an overview of CLI commands that can be sent to MeshCore --- #### View or change this node's transmit power + **Usage:** + - `get tx` - `set tx ` **Parameters:** + - `dbm`: Power level in dBm (1-22) **Set by build flag:** `LORA_TX_POWER` @@ -218,10 +262,13 @@ This document provides an overview of CLI commands that can be sent to MeshCore --- #### Change the radio parameters for a set duration -**Usage:** + +**Usage:** + - `tempradio ,,,,` **Parameters:** + - `freq`: Frequency in MHz (300-2500) - `bw`: Bandwidth in kHz (7.8-500) - `sf`: Spreading factor (5-12) @@ -233,11 +280,14 @@ This document provides an overview of CLI commands that can be sent to MeshCore --- #### View or change this node's frequency + **Usage:** + - `get freq` - `set freq ` **Parameters:** + - `frequency`: Frequency in MHz **Default:** `869.525` @@ -248,12 +298,15 @@ This document provides an overview of CLI commands that can be sent to MeshCore --- #### View or change this node's rx boosted gain mode (SX12xx only, v1.14.1+) + **Usage:** + - `get radio.rxgain` - `set radio.rxgain ` **Parameters:** - - `state`: `on`|`off` + +- `state`: `on`|`off` **Default:** `on` @@ -264,11 +317,14 @@ This document provides an overview of CLI commands that can be sent to MeshCore ### System #### View or change this node's name + **Usage:** + - `get name` - `set name ` **Parameters:** + - `name`: Node name **Set by build flag:** `ADVERT_NAME` @@ -280,7 +336,9 @@ This document provides an overview of CLI commands that can be sent to MeshCore --- #### View or change this node's latitude + **Usage:** + - `get lat` - `set lat ` @@ -289,12 +347,15 @@ This document provides an overview of CLI commands that can be sent to MeshCore **Default:** `0` **Parameters:** + - `degrees`: Latitude in degrees --- #### View or change this node's longitude + **Usage:** + - `get lon` - `set lon ` @@ -303,19 +364,24 @@ This document provides an overview of CLI commands that can be sent to MeshCore **Default:** `0` **Parameters:** + - `degrees`: Longitude in degrees --- #### View or change this node's identity (Private Key) + **Usage:** + - `get prv.key` - `set prv.key ` **Parameters:** + - `private_key`: Private key in hex format (64 hex characters) **Serial Only:** + - `get prv.key`: Yes - `set prv.key`: No @@ -324,10 +390,13 @@ This document provides an overview of CLI commands that can be sent to MeshCore --- #### Change this node's admin password + **Usage:** + - `password ` **Parameters:** + - `new_password`: New admin password **Set by build flag:** `ADMIN_PASSWORD` @@ -341,11 +410,14 @@ This document provides an overview of CLI commands that can be sent to MeshCore --- #### View or change this node's guest password + **Usage:** + - `get guest.password` - `set guest.password ` **Parameters:** + - `password`: Guest password **Set by build flag:** `ROOM_PASSWORD` (Room Server only) @@ -355,11 +427,14 @@ This document provides an overview of CLI commands that can be sent to MeshCore --- #### View or change this node's owner info + **Usage:** + - `get owner.info` - `set owner.info ` **Parameters:** + - `text`: Owner information text **Default:** `` @@ -371,11 +446,14 @@ This document provides an overview of CLI commands that can be sent to MeshCore --- #### Fine-tune the battery reading + **Usage:** + - `get adc.multiplier` - `set adc.multiplier ` **Parameters:** + - `value`: ADC multiplier (0.0-10.0) **Default:** `0.0` (value defined by board) @@ -385,22 +463,27 @@ This document provides an overview of CLI commands that can be sent to MeshCore --- #### View this node's public key + **Usage:** `get public.key` --- #### View this node's configured role + **Usage:** `get role` --- #### View or change this node's power saving flag (Repeater Only) + **Usage:** + - `powersaving` - `powersaving on` - `powersaving off` -**Parameters:** +**Parameters:** + - `on`: enable power saving - `off`: disable power saving @@ -413,63 +496,75 @@ This document provides an overview of CLI commands that can be sent to MeshCore ### Routing #### View or change this node's repeat flag + **Usage:** + - `get repeat` - `set repeat ` **Parameters:** - - `state`: `on`|`off` + +- `state`: `on`|`off` **Default:** `on` --- #### View or change this node's advert path hash size + **Usage:** + - `get path.hash.mode` - `set path.hash.mode ` **Parameters:** + - `value`: Path hash size (0-2) - `0`: 1 Byte hash size (256 unique ids)[64 max flood] - `1`: 2 Byte hash size (65,536 unique ids)[32 max flood] - `2`: 3 Byte hash size (16,777,216 unique ids)[21 max flood] - - `3`: DO NOT USE (Reserved) + - `3`: DO NOT USE (Reserved) **Default:** `0` **Note:** the 'path.hash.mode' sets the low-level ID/hash encoding size used when the repeater adverts. This setting has no impact on what packet ID/hash size this repeater forwards, all sizes should be forwarded on firmware >= 1.14. This feature was added in firmware 1.14 -**Temporary Note:** adverts with ID/hash sizes of 2 or 3 bytes may have limited flood propogation in your network while this feature is new as v1.13.0 firmware and older will drop packets with multibyte path ID/hashes as only 1-byte hashes are suppored. Consider your install base of firmware >=1.14 has reached a criticality for effective network flooding before implementing higher ID/hash sizes. +**Temporary Note:** adverts with ID/hash sizes of 2 or 3 bytes may have limited flood propogation in your network while this feature is new as v1.13.0 firmware and older will drop packets with multibyte path ID/hashes as only 1-byte hashes are suppored. Consider your install base of firmware >=1.14 has reached a criticality for effective network flooding before implementing higher ID/hash sizes. --- #### View or change this node's loop detection + **Usage:** + - `get loop.detect` - `set loop.detect ` **Parameters:** -- `state`: + +- `state`: - `off`: no loop detection is performed - `minimal`: packets are dropped if repeater's ID/hash appears 4 or more times (1-byte), 2 or more (2-byte), 1 or more (3-byte) - `moderate`: packets are dropped if repeater's ID/hash appears 2 or more times (1-byte), 1 or more (2-byte), 1 or more (3-byte) - `strict`: packets are dropped if repeater's ID/hash appears 1 or more times (1-byte), 1 or more (2-byte), 1 or more (3-byte) - + **Default:** `off` **Note:** When it is enabled, repeaters will now reject flood packets which look like they are in a loop. This has been happening recently in some meshes when there is just a single 'bad' repeater firmware out there (prob some forked or custom firmware). If the payload is messed with, then forwarded, the same packet ends up causing a packet storm, repeated up to the max 64 hops. This feature was added in firmware 1.14 -**Example:** If preference is `loop.detect minimal`, and a 1-byte path size packet is received, the repeater will see if its own ID/hash is already in the path. If it's already encoded 4 times, it will reject the packet. If the packet uses 2-byte path size, and repeater's own ID/hash is already encoded 2 times, it rejects. If the packet uses 3-byte path size, and the repeater's own ID/hash is already encoded 1 time, it rejects. +**Example:** If preference is `loop.detect minimal`, and a 1-byte path size packet is received, the repeater will see if its own ID/hash is already in the path. If it's already encoded 4 times, it will reject the packet. If the packet uses 2-byte path size, and repeater's own ID/hash is already encoded 2 times, it rejects. If the packet uses 3-byte path size, and the repeater's own ID/hash is already encoded 1 time, it rejects. --- #### View or change the retransmit delay factor for flood traffic + **Usage:** + - `get txdelay` - `set txdelay ` **Parameters:** + - `value`: Transmit delay factor (0-2) **Default:** `0.5` @@ -477,11 +572,14 @@ This document provides an overview of CLI commands that can be sent to MeshCore --- #### View or change the retransmit delay factor for direct traffic + **Usage:** + - `get direct.txdelay` - `set direct.txdelay ` **Parameters:** + - `value`: Direct transmit delay factor (0-2) **Default:** `0.2` @@ -489,11 +587,14 @@ This document provides an overview of CLI commands that can be sent to MeshCore --- #### [Experimental] View or change the processing delay for received traffic + **Usage:** + - `get rxdelay` - `set rxdelay ` **Parameters:** + - `value`: Receive delay base (0-20) **Default:** `0.0` @@ -501,16 +602,20 @@ This document provides an overview of CLI commands that can be sent to MeshCore --- #### View or change the duty cycle limit + **Usage:** + - `get dutycycle` - `set dutycycle ` **Parameters:** + - `value`: Duty cycle percentage (1-100) **Default:** `50%` (equivalent to airtime factor 1.0) **Examples:** + - `set dutycycle 100` — no duty cycle limit - `set dutycycle 50` — 50% duty cycle (default) - `set dutycycle 10` — 10% duty cycle @@ -521,30 +626,36 @@ This document provides an overview of CLI commands that can be sent to MeshCore --- #### View or change the airtime factor (duty cycle limit) + > **Deprecated** as of firmware v1.15.0. Use [`get/set dutycycle`](#view-or-change-the-duty-cycle-limit) instead. **Usage:** + - `get af` - `set af ` **Parameters:** + - `value`: Airtime factor (0-9). After each transmission, the repeater enforces a silent period of approximately the on-air transmission time multiplied by the value. This results in a long-term duty cycle of roughly 1 divided by (1 plus the value). For example: - `af = 1` → ~50% duty - `af = 2` → ~33% duty - `af = 3` → ~25% duty - `af = 9` → ~10% duty - You are responsible for choosing a value that is appropriate for your jurisdiction and channel plan (for example EU 868 Mhz 10% duty cycle regulation). + You are responsible for choosing a value that is appropriate for your jurisdiction and channel plan (for example EU 868 Mhz 10% duty cycle regulation). **Default:** `1.0` --- #### View or change the local interference threshold + **Usage:** + - `get int.thresh` - `set int.thresh ` **Parameters:** + - `value`: Interference threshold value **Default:** `0.0` @@ -552,11 +663,14 @@ This document provides an overview of CLI commands that can be sent to MeshCore --- #### View or change the AGC Reset Interval + **Usage:** + - `get agc.reset.interval` - `set agc.reset.interval ` **Parameters:** + - `value`: Interval in seconds rounded down to a multiple of 4 (17 becomes 16). 0 to disable. **Default:** `0.0` @@ -564,11 +678,14 @@ This document provides an overview of CLI commands that can be sent to MeshCore --- #### Enable or disable Multi-Acks support + **Usage:** + - `get multi.acks` - `set multi.acks ` **Parameters:** + - `state`: `0` (disable) or `1` (enable) **Default:** `0` @@ -576,11 +693,14 @@ This document provides an overview of CLI commands that can be sent to MeshCore --- #### View or change the flood advert interval + **Usage:** + - `get flood.advert.interval` - `set flood.advert.interval ` **Parameters:** + - `hours`: Interval in hours (3-168) **Default:** `12` (Repeater) - `0` (Sensor) @@ -588,11 +708,14 @@ This document provides an overview of CLI commands that can be sent to MeshCore --- #### View or change the zero-hop advert interval + **Usage:** + - `get advert.interval` - `set advert.interval ` **Parameters:** + - `minutes`: Interval in minutes rounded down to the nearest multiple of 2 (61 becomes 60) (60-240) **Default:** `0` @@ -600,11 +723,14 @@ This document provides an overview of CLI commands that can be sent to MeshCore --- #### Limit the number of hops for a flood message + **Usage:** + - `get flood.max` - `set flood.max ` **Parameters:** + - `value`: Maximum flood hop count (0-64) **Default:** `64` @@ -614,12 +740,15 @@ This document provides an overview of CLI commands that can be sent to MeshCore ### ACL #### Add, update or remove permissions for a companion -**Usage:** + +**Usage:** + - `setperm ` **Parameters:** + - `pubkey`: Companion public key -- `permissions`: +- `permissions`: - `0`: Guest - `1`: Read-only - `2`: Read-write @@ -630,7 +759,9 @@ This document provides an overview of CLI commands that can be sent to MeshCore --- #### View the current ACL -**Usage:** + +**Usage:** + - `get acl` **Serial Only:** Yes @@ -638,11 +769,14 @@ This document provides an overview of CLI commands that can be sent to MeshCore --- #### View or change this room server's 'read-only' flag + **Usage:** + - `get allow.read.only` - `set allow.read.only ` **Parameters:** + - `state`: `on` (enable) or `off` (disable) **Default:** `off` @@ -652,11 +786,14 @@ This document provides an overview of CLI commands that can be sent to MeshCore ### Region Management (v1.10.+) #### Bulk-load region lists -**Usage:** + +**Usage:** + - `region load` - `region load [flood_flag]` **Parameters:** + - `name`: A name of a region. `*` represents the wildcard region **Note:** `flood_flag`: Optional `F` to allow flooding @@ -668,16 +805,21 @@ This document provides an overview of CLI commands that can be sent to MeshCore --- #### Save any changes to regions made since reboot -**Usage:** + +**Usage:** + - `region save` --- #### Allow a region -**Usage:** + +**Usage:** + - `region allowf ` -**Parameters:** +**Parameters:** + - `name`: Region name (or `*` for wildcard) **Note:** Setting on wildcard `*` allows packets without region transport codes @@ -685,10 +827,13 @@ This document provides an overview of CLI commands that can be sent to MeshCore --- #### Block a region -**Usage:** + +**Usage:** + - `region denyf ` -**Parameters:** +**Parameters:** + - `name`: Region name (or `*` for wildcard) **Note:** Setting on wildcard `*` drops packets without region transport codes @@ -696,62 +841,80 @@ This document provides an overview of CLI commands that can be sent to MeshCore --- #### Show information for a region -**Usage:** + +**Usage:** + - `region get ` **Parameters:** + - `name`: Region name (or `*` for wildcard) --- #### View or change the home region for this node -**Usage:** + +**Usage:** + - `region home` - `region home ` **Parameters:** + - `name`: Region name --- #### View or change the default scope region for this node -**Usage:** + +**Usage:** + - `region default` - `region default {name|}` **Parameters:** -- `name`: Region name, or to reset/clear + +- `name`: Region name, or to reset/clear --- #### Create a new region -**Usage:** + +**Usage:** + - `region put [parent_name]` **Parameters:** + - `name`: Region name - `parent_name`: Parent region name (optional, defaults to wildcard) --- #### Remove a region -**Usage:** + +**Usage:** + - `region remove ` **Parameters:** + - `name`: Region name -**Note:** Must remove all child regions before the region can be removed +**Note:** Must remove all child regions before the region can be removed --- #### View all regions -**Usage:** + +**Usage:** + - `region list ` **Serial Only:** Yes **Parameters:** + - `filter`: `allowed`|`denied` **Note:** Requires firmware 1.12.+ @@ -759,7 +922,9 @@ This document provides an overview of CLI commands that can be sent to MeshCore --- #### Dump all defined regions and flood permissions -**Usage:** + +**Usage:** + - `region` **Serial Only:** For firmware older than 1.12.0 @@ -769,6 +934,7 @@ This document provides an overview of CLI commands that can be sent to MeshCore ### Region Examples **Example 1: Using F Flag with Named Public Region** + ``` region load #Europe F @@ -777,20 +943,23 @@ region save ``` **Explanation:** + - Creates a region named `#Europe` with flooding enabled - Packets from this region will be flooded to other nodes --- **Example 2: Using Wildcard with F Flag** + ``` -region load +region load * F region save ``` **Explanation:** + - Creates a wildcard region `*` with flooding enabled - Enables flooding for all regions automatically - Applies only to packets without transport codes @@ -798,13 +967,16 @@ region save --- **Example 3: Using Wildcard Without F Flag** + ``` -region load +region load * region save ``` + **Explanation:** + - Creates a wildcard region `*` without flooding - This region exists but doesn't affect packet distribution - Used as a default/empty region @@ -812,8 +984,9 @@ region save --- **Example 4: Nested Public Region with F Flag** + ``` -region load +region load #Europe F #UK #London @@ -826,6 +999,7 @@ region save ``` **Explanation:** + - Creates `#Europe` region with flooding enabled - Adds nested child regions (`#UK`, `#France`) - All nested regions inherit the flooding flag from parent @@ -833,8 +1007,9 @@ region save --- **Example 5: Wildcard with Nested Public Regions** + ``` -region load +region load * F #NorthAmerica #USA @@ -848,49 +1023,62 @@ region save ``` **Explanation:** + - Creates wildcard region `*` with flooding enabled - Adds nested `#NorthAmerica` hierarchy - Enables flooding for all child regions automatically - Useful for global networks with specific regional rules --- + ### GPS (When GPS support is compiled in) #### View or change GPS state + **Usage:** + - `gps` - `gps ` **Parameters:** + - `state`: `on`|`off` **Default:** `off` **Note:** Output format: + - `off` when the GPS hardware is disabled - `on, {active|deactivated}, {fix|no fix}, {sat count} sats` when the GPS hardware is enabled --- #### Sync this node's clock with GPS time -**Usage:** + +**Usage:** + - `gps sync` --- #### Set this node's location based on the GPS coordinates -**Usage:** + +**Usage:** + - `gps setloc` --- #### View or change the GPS advert policy + **Usage:** + - `gps advert` - `gps advert ` -**Parameters:** -- `policy`: `none`|`share`|`prefs` +**Parameters:** + +- `policy`: `none`|`share`|`prefs` - `none`: don't include location in adverts - `share`: share gps location (from SensorManager) - `prefs`: location stored in node's lat and lon settings @@ -902,9 +1090,11 @@ region save ### Sensors (When sensor support is compiled in) #### View the list of sensors on this node + **Usage:** `sensor list [start]` **Parameters:** + - `start`: Optional starting index (defaults to 0) **Note:** Output format: `=\n` @@ -912,11 +1102,14 @@ region save --- #### View or change thevalue of a sensor -**Usage:** + +**Usage:** + - `sensor get ` - `sensor set ` **Parameters:** + - `key`: Sensor setting name - `value`: The value to set the sensor to @@ -925,16 +1118,20 @@ region save ### Bridge (When bridge support is compiled in) #### View the compiled bridge type + **Usage:** `get bridge.type` --- #### View or change the bridge enabled flag + **Usage:** + - `get bridge.enabled` - `set bridge.enabled ` **Parameters:** + - `state`: `on`|`off` **Default:** `off` @@ -942,11 +1139,14 @@ region save --- #### Add a delay to packets routed through this bridge + **Usage:** + - `get bridge.delay` - `set bridge.delay ` **Parameters:** + - `ms`: Delay in milliseconds (0-10000) **Default:** `500` @@ -954,12 +1154,15 @@ region save --- #### View or change the source of packets bridged to the external interface + **Usage:** + - `get bridge.source` - `set bridge.source ` **Parameters:** -- `source`: + +- `source`: - `logRx`: bridges received packets - `logTx`: bridges transmitted packets @@ -968,11 +1171,14 @@ region save --- #### View or change the speed of the bridge (RS-232 only) + **Usage:** + - `get bridge.baud` - `set bridge.baud ` **Parameters:** + - `rate`: Baud rate (`9600`, `19200`, `38400`, `57600`, or `115200`) **Default:** `115200` @@ -980,21 +1186,27 @@ region save --- #### View or change the channel used for bridging (ESPNow only) + **Usage:** + - `get bridge.channel` - `set bridge.channel ` **Parameters:** + - `channel`: Channel number (1-14) --- #### Set the ESP-Now secret -**Usage:** + +**Usage:** + - `get bridge.secret` - `set bridge.secret ` **Parameters:** + - `secret`: ESP-NOW bridge secret, up to 15 characters **Default:** Varies by board @@ -1002,16 +1214,19 @@ region save --- #### View the bootloader version (nRF52 only) + **Usage:** `get bootloader.ver` --- #### View power management support + **Usage:** `get pwrmgt.support` --- #### View the current power source + **Usage:** `get pwrmgt.source` **Note:** Returns an error on boards without power management support. @@ -1019,6 +1234,7 @@ region save --- #### View the boot reset and shutdown reasons + **Usage:** `get pwrmgt.bootreason` **Note:** Returns an error on boards without power management support. @@ -1026,6 +1242,7 @@ region save --- #### View the boot voltage + **Usage:** `get pwrmgt.bootmv` **Note:** Returns an error on boards without power management support. diff --git a/docs/custom-cli.md b/docs/custom-cli.md index 56381cbd..5cf6bfd0 100644 --- a/docs/custom-cli.md +++ b/docs/custom-cli.md @@ -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 ` +- `set wifi.pwd ` +- `set wifi.powersaving on|off` - `get mqtt.iata` - `set mqtt.iata ` - `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 ` - `get lat` - `set lat ` - `get lon` - `set lon ` +- `get radio` +- `set radio ` +- `get prv.key` - `get guest.password` +- `password ` - `set guest.password ` - `set prv.key <64-hex-char-private-key>` +- `get role` +- `get public.key` - `get advert.interval` - `set advert.interval ` +- `get agc.reset.interval` +- `set agc.reset.interval ` - `get flood.advert.interval` - `set flood.advert.interval ` +- `get repeat` +- `set repeat on|off` - `get flood.max` - `set flood.max ` +- `get path.hash.mode` +- `set path.hash.mode ` - `get owner.info` - `set owner.info ` +- `time ` +- `time.force ` ## Companion WiFi Rescue Commands diff --git a/docs/web-panel.md b/docs/web-panel.md index f01eca02..77f5b4ed 100644 --- a/docs/web-panel.md +++ b/docs/web-panel.md @@ -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. diff --git a/examples/simple_repeater/MyMesh.cpp b/examples/simple_repeater/MyMesh.cpp index 8df44975..04c6bd68 100644 --- a/examples/simple_repeater/MyMesh.cpp +++ b/examples/simple_repeater/MyMesh.cpp @@ -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 ") || diff --git a/release-notes.yml b/release-notes.yml index b89148d1..d2dea824 100644 --- a/release-notes.yml +++ b/release-notes.yml @@ -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: [] diff --git a/src/helpers/web/WebPanelServer.cpp b/src/helpers/web/WebPanelServer.cpp index 23d2b73a..9ee20e4e 100644 --- a/src/helpers/web/WebPanelServer.cpp +++ b/src/helpers/web/WebPanelServer.cpp @@ -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 `

Memory

${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))}
${renderMetric("Heap Free", formatBytes(heapFree))} ${renderMetric("Heap Min", formatBytes(memory.heap_min || 0))} diff --git a/variants/lilygo_tbeam_1w/platformio.ini b/variants/lilygo_tbeam_1w/platformio.ini index 7c845307..b76d637b 100644 --- a/variants/lilygo_tbeam_1w/platformio.ini +++ b/variants/lilygo_tbeam_1w/platformio.ini @@ -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