Improve repeater reliability and build tooling

This commit is contained in:
mikecarper committed 2026-07-13 01:03:27 -07:00
1 parent 2b4aed4ef1
commit da00a00436
31 files changed
+1079 -229

No files matched your search

+22 -4
View File
@@ -465,11 +465,25 @@ send text.flood checking ridge link
#### View or change battery alert state
**Usage:**
- `get battery.alert`
- `set battery.alert <on|off>`
- `get battery.alert.region`
- `set battery.alert on [region]`
- `set battery.alert off`
**Default:** `off`
**Parameters:**
- `region`: Optional named region scope. When omitted, the repeater selects the single deepest (most narrow) named region in the configured hierarchy. If multiple regions tie for deepest, specify one explicitly.
**Note:** When enabled, the repeater checks battery level once per minute and sends low-battery warnings to the `#repeaters` flood channel.
**Defaults:**
- `battery.alert`: `off`
- `battery.alert.region`: `<unset>`
**Notes:**
- Enabling fails until at least one usable named region is defined. Alerts are never sent as unscoped floods. If the selected region is later removed, alerts stop until battery alerts are enabled again with a valid region.
- Region hierarchy edits are not persistent until `region save` is run. After `region def west pnw wa w-wa sea`, run `region save` before enabling the alert if the hierarchy must survive a reboot.
- A region must have a usable transport key. Public named regions derive one automatically; a private region without an available key is rejected.
- The first alert is suppressed until the repeater has been up for at least 30 minutes. After that, the repeater checks every 30 minutes and sends low-battery warnings to the `#repeaters` channel in the selected region.
- With `region def west pnw wa w-wa sea`, `set battery.alert on` selects `sea`; `set battery.alert on w-wa` overrides that default.
- `get battery.alert.region` returns the selected scope, for example `> sea`.
- The battery check never requests a wake earlier than its 30-minute deadline. If the normal loop is already awake when that deadline has elapsed, the check is effectively free of an additional wake. Time in light/event sleep counts toward the startup delay, and a queued alert keeps the repeater awake until the packet is handled.
---
@@ -1378,6 +1392,10 @@ set flood.retry.ignore none
Flood retry timing retains its fixed maximum-frame plus 20 packet-airtime wait, then adds a random `0-200%` of one additional packet airtime on every attempt. This de-synchronizes repeaters that may have missed the same echo while capping the added wait at two frames.
Only one active retry sequence is kept for a given logical flood packet. An identical flood can still transmit normally, but it does not create a second sequence of extra attempts. Retry state is released if a queued packet is evicted, and the final echo window retains metadata without reserving a packet-pool entry.
Bridge reachability learned from earlier hops in a successful echo is cached separately from `recent.repeater`. Only the final RF hop updates `recent.repeater` and its SNR, so indirect path entries cannot affect direct-retry SNR gating or coding-rate selection.
**Examples:**
```
get flood.retry.bridge
@@ -1833,7 +1851,7 @@ Requires WiFi connected and the MQTT bridge running.
- `set bridge.secret <secret>`
**Parameters:**
- `secret`: ESP-NOW bridge secret, up to 15 characters
- `secret`: ESP-NOW bridge secret, 1-15 characters
**Default:** Varies by board
+33 -4
View File
@@ -73,7 +73,7 @@ set flood.retry.ignore none
| Setting | What it does | How to use | Example |
| --- | --- | --- | --- |
| `battery.alert` | Sends opt-in low-battery warnings to `#repeaters`. | `get battery.alert`, `set battery.alert on/off` | `set battery.alert on` |
| `battery.alert` | Sends opt-in, region-scoped low-battery warnings to `#repeaters` after 30 minutes of uptime. | `get battery.alert`, `get battery.alert.region`, `set battery.alert on [region]`, `set battery.alert off` | `set battery.alert on sea` |
| `battery.alert.low` | Warning threshold percentage. Must be greater than `battery.alert.critical`. | `get battery.alert.low`, `set battery.alert.low <1-100>` | `set battery.alert.low 20` |
| `battery.alert.critical` | Critical threshold percentage. Critical warnings repeat more often. | `get battery.alert.critical`, `set battery.alert.critical <0-99>` | `set battery.alert.critical 10` |
| `recent.repeater` | Shows, seeds, or clears the recent repeater prefix/SNR table used by direct retry and bridge freshness checks. | `get recent.repeater`, `get recent.repeater <page>`, `set recent.repeater <prefix> <snr_db>`, `clear recent.repeater` | `set recent.repeater A1B2C3 -8.5` |
@@ -92,9 +92,18 @@ set flood.retry.ignore none
## Battery Alerts
Battery alerts are off by default. When enabled, the repeater checks once per
minute and sends a flood text warning to `#repeaters` when voltage is above
`1 V` and the estimated battery percent is below `battery.alert.low`.
Battery alerts are off by default. Enabling requires a named region. With no
region argument, the repeater selects the single deepest (most narrow) region
in the hierarchy; if multiple regions tie, the command asks for an explicit
region. For example, after `region def west pnw wa w-wa sea`, `set
battery.alert on` selects `sea`, while `set battery.alert on w-wa` overrides
the default. Alerts are never sent as unscoped floods, and removing the selected
region stops alerts until a valid scope is selected again.
The repeater suppresses alerts for its first 30 minutes of uptime. It then
checks every 30 minutes and sends a flood text warning to `#repeaters` when
voltage is above `1 V` and the estimated battery percent is below
`battery.alert.low`.
Warnings repeat every `24` hours, or every `12` hours when the estimate is
below `battery.alert.critical`.
@@ -104,6 +113,7 @@ Defaults:
| Setting | Default |
| --- | ---: |
| `battery.alert` | `off` |
| `battery.alert.region` | `<unset>` |
| `battery.alert.low` | `20` |
| `battery.alert.critical` | `10` |
@@ -114,8 +124,17 @@ set battery.alert.low 20
set battery.alert.critical 10
set battery.alert on
get battery.alert
get battery.alert.region
```
CPU power saving remains compatible with the check. The battery timer never
requests a wake earlier than its 30-minute deadline; when the normal loop is
already awake after that deadline, no additional wake is needed. Sleeping time
counts toward the startup delay, and an outbound warning prevents another sleep
until the queued packet has been handled. This is separate from RX duty-cycle
power saving, which only cycles the LoRa receiver and does not stop the main
loop's battery timer.
## Recent Repeater Table
Direct retry uses the recent repeater table when `direct.retry.heard` is `on`.
@@ -350,6 +369,16 @@ delay, then adds random jitter from zero to 200 percent of one additional packet
airtime. This keeps nearby repeaters from repeating a collision on fixed timing
while capping the added wait at two frames.
Only one enhanced retry sequence can be active for the same logical flood
packet. Identical floods still receive their normal transmission, but do not
multiply the extra attempts. Evicted queued retries release their bridge state,
and the final echo wait does not reserve a packet-pool entry.
Earlier path hops from a successful bridge echo refresh a separate per-bucket
reachability cache without an SNR value. Only the final hop, which actually sent
the received RF frame, updates `recent.repeater` and its SNR. Indirect path hops
therefore cannot change direct-retry SNR gating or coding-rate selection.
## Troubleshooting
If advert packets are still retrying: