Add ota check/update/branch, display, and diagnostic commands to the
observer guide; condense MQTT_IMPLEMENTATION.md and ALERTS.md; fix the
nonexistent 'set bridge off' instruction; mark the T-LoRa observer envs
parked; update the SNMP build-target list; move local-testing notes to
MQTT_INTERNALS.md; drop MEMORY_MONITORING.md (its script never existed).
Heltec_v2_repeater_observer_mqtt and Heltec_v2_room_server_observer_mqtt,
modelled on the Heltec V3 observer envs. The V2 is a classic ESP32 without
PSRAM, so like the T-LoRa observer it is documented as one active WSS broker
and leaves MQTT_NEIGHBORS_WITHOUT_PSRAM off. Its 8 MB flash and the board's
default_8MB.csv layout fit the image (48% of the app slot), so no partition
change or erase is needed.
Both channels move together: the beta workflow's FIRMWARE_VERSION must equal
production's. Resets the per-base build counter so the first builds are
v1.18.0.1. The flasher repo's config.json version key still needs the
matching bump.
Preserve observer discovery when forwarding is disabled while honoring hidden-node settings. Keep GPS power ownership paired and incorporate upstream GPS diagnostics.
- Clip requested power to the active PA's range instead of failing. A
stored 22 dBm was rejected at 2.4 GHz (HF PA max 13 dBm), and since
setTxPower ignores errors the sub-GHz PA stayed configured.
- Re-apply the requested power after every successful retune: PA choice
depends on the band, and set radio / tempradio only call setParams.
- Clip requested power to the active PA's range instead of failing. A
stored 22 dBm was rejected at 2.4 GHz (HF PA max 13 dBm), and since
setTxPower ignores errors the sub-GHz PA stayed configured.
- Re-apply the requested power after every successful retune: PA choice
depends on the band, and set radio / tempradio only call setParams.
ESP32-S3FH4R2 (4MB flash, 2MB PSRAM, native USB-CDC) with an LR1121.
Pins, the DIO5/DIO6 RF switch table and the 1.8 V TCXO follow the HF
schematic and Waveshare's examples. Envs: repeater, room server,
companion USB/BLE and KISS modem, all on min_spiffs so roles share one
partition layout.
Only RFO_HP_LF is wired (R4 on RFO_LP_LF is not fitted), so the new
opt-in LR1121_FORCE_HP_PA flag keeps RadioLib on the HP PA at <= 14 dBm,
where it would otherwise select the unconnected LP PA.
ESP32-S3FH4R2 (4MB flash, 2MB PSRAM, native USB-CDC) with an LR1121.
Pins, the DIO5/DIO6 RF switch table and the 1.8 V TCXO follow the HF
schematic and Waveshare's examples. Envs: repeater, room server,
companion USB/BLE and KISS modem, all on min_spiffs so roles share one
partition layout.
Only RFO_HP_LF is wired (R4 on RFO_LP_LF is not fitted), so the new
opt-in LR1121_FORCE_HP_PA flag keeps RadioLib on the HP PA at <= 14 dBm,
where it would otherwise select the unconnected LP PA.
Received packets are uploaded before Mesh::onRecvPacket validates them, so
an advert corrupted over the air that still passes the LoRa CRC is published
with a mangled name or location. `set mqtt.advert.verify on` verifies each
received advert's Ed25519 signature (same message layout as Mesh.cpp,
including the 32-byte app-data clamp) and skips publishing failures.
Defaults off so collectors keep seeing RF corruption on the mesh. Dropped
adverts are counted as badsig= in `get mqtt.stats`. Exposed in the web
config Publishing card and persisted as mqtt.advert_verify in prefs JSON.
DHCP can fill all DNS_MAX_SERVERS (3) slots, but only two were saved and restored, so a third server from one medium survived a switch to the other. link.dns now drops trailing empty slots to keep remote replies under 160 bytes.
Shows lwIP's live global DNS server list next to the DNS each medium's DHCP lease installed, so a node that is linked but failing to resolve can be diagnosed remotely.
A switch can land on an older build: e.g. prod cannot read dev's /mqtt.json,
and prod's M7 image has no Ethernet. Each image carries an ota-compat tag
(state generation + transports). A switch is flashed without rebooting, the
new image's tag is read (bounded by its length), and boot is pointed back at
the running image unless the target keeps this node's state and transports.
CI now requires the tag in every published binary.
Prod and beta are often built from one commit (e.g. after a dev->prod merge),
so a hash match does not mean the images are the same: the native base differs.
After the flash the target channel is native, so this cannot loop.
Every observer build now carries both channel URLs, so checking for a URL's
presence or absence can no longer tell prod from beta (and the old checks would
reject every build). Read the ota-base-* tags from every .bin in out/ instead
of a single ELF, with URLs shared by build.sh and both workflows.