Assumes you've already decided this makes sense for your repeater. If you're still deciding, see the Trifecta overview first.
Real-LoRa repeaters this runs on today: Heltec V3
(Heltec_v3_repeater_bridge_espnow_ip), Heltec V4
(heltec_v4_repeater_bridge_espnow_ip), and Xiao S3 WIO
(Xiao_S3_WIO_repeater_bridge_espnow_ip) — each also has an
_debug variant with full bridge/routing logging on, for
pairing with watch_boards.py below. Getting the right
environment onto your board (PlatformIO, a web flasher, whatever you
normally use) isn't covered here — this page picks up once you're
already running it.
set bridge.channel <selected wifi channel> set bridge.secret <your key>
Whatever you set here is exactly what a Sidecar board needs configured to match — see the Sidecar setup page.
set wifi.ssid <your ssid> set wifi.pwd <your password> set ip.host <peer host or IP> # set = dial out; empty = listen instead set ip.port <port> set ip.secret <key> # TLS-PSK, must match the peer exactly
bridge.channel must exactly match whichever channel your WiFi access point actually operates on — it doesn't get synced automatically. Make sure that AP is locked to a fixed channel rather than left on auto-select; many routers pick a new channel on reboot or via automatic interference avoidance, which would silently break this until you update bridge.channel to match again.Leaving ip.host empty makes this board a listener, and a listener can accept more than one peer at once — a remote repeater over the internet and a local no‑LoRa gateway, say — each with its own revocable credential instead of everyone sharing one ip.secret:
set ip.peer.add <8‑hex‑char id> <secret only this peer knows> get ip.peer.list set ip.peer.remove <id>
The id is the first 4 bytes of the connecting peer's public key (its get public.key, or shown in ip.status once connected). Matching is case‑insensitive. Each connecting peer still presents its own identity via its own ip.secret on its side — this only changes how the listener resolves and authenticates them.
A peer registered here doesn't have to be another repeater — a direct-IP companion connects the same way, presenting its own identity and secret exactly like any other peer.
Don't just assume — these cover every hop:
get wifi.status get bridge.channel get ip.status neighbors.all
wifi.status confirms the board actually associated
(connected, IP, RSSI). bridge.channel shows the configured
ESP‑NOW channel next to the radio's actual live channel and flags
it explicitly if they've drifted apart. ip.status reports
whether the TCP+TLS‑PSK tunnel to the peer is currently up.
neighbors.all merges RF-heard and bridge-heard neighbours
into one list with a via column.
$ python3 watch_boards.py
Auto-detects every connected board, connects to all of them, and streams debug output live in one terminal. Press n to dump neighbors.all, b for bridge status, c to toggle watching companion boards, from every connected board at once.