mesh-test-bot
unofficial Β· not affiliated with Meshtastic

Automatic range tests for your Meshtastic network

A small bot that sends a few messages on a channel at random moments, listens for everyone else's, and writes a report of who was heard, over how many hops, with what signal β€” so you don't have to babysit a laptop to test coverage.

Not affiliated with or endorsed by the Meshtastic project. "Meshtastic" is a trademark of Meshtastic LLC, used here only to say what this bot is compatible with.

What it does

πŸ“€ Sends, on a schedule

A few short messages on your test channel, at random moments, so a whole community doesn't transmit at once.

πŸ‘‚ Listens the whole time

One long-lived connection to the radio hears everyone else running the same format, recording hops, SNR, RSSI, and whether a copy came via MQTT.

πŸ“ Writes a report

A readable text file and a JSON line per session β€” delivery rate, duplicates, relay hints, and any connection outages during the test.

πŸ€– Runs unattended

Docker image for amd64, arm64 and arm/v7 (Raspberry Pi included). Repeats itself every week, recovers from radio reboots and WiFi drops on its own.

πŸ—‚οΈ Several tests, one radio

Run more than one scheduled test: one bot per test, each on its own schedule, all through the same MeshMonitor. How to set it up.

✈️ Sends it to Telegram

Optional: each session's text report is also sent to a Telegram chat, via your own bot. Set a bot token and a chat id, and the report reaches your phone when the test ends.

What a report looks like

=== 2026-09-26 21:41 ===
Reporter: AB12 (!deadbeef) - Place: City - Sent: 3/3
ACK | CD34 | 0   | Villatown | RF
ACK | EF56 | 1-2 | Valley    | RF

One short, paste-friendly line per station heard. Each line carries the prefix, the station's name, hop range, the place it reported, and RF or MQTT. The matching report.jsonl line for the same session has the fuller numbers too:

report.jsonl is meant for a server to pick up later β€” reports stay local for now, but a future version may let you opt in to submitting them somewhere, for network-wide coverage stats across everyone running the bot.

Get started

New to this, or don't know what Docker is? Follow Start here.

Otherwise, on Linux, macOS or a Raspberry Pi, one command, if you already have Docker:

curl -fsSL https://raw.githubusercontent.com/cunhaax/mesh-test-bot/master/install/install.sh | sh

It asks a few questions β€” how the bot should reach the radio (directly, through an existing MeshMonitor, or by setting one up right here), the test channel, your city, the message prefixes, and whether to run once now or on a recurring schedule, and the session length, number of messages and report window β€” press Enter for any default. Then it prints the commands that start the bot(s): it never starts anything by itself. No WiFi on your radio (USB or Bluetooth only, like the RAK4631)? See radios without WiFi. See the README for installing from source or without Docker, and the MeshMonitor guide for the details of that path.

πŸ“ Size your test

LoRa has no real collision avoidance, so many stations sharing a short window can flood the channel β€” the very congestion a range test is meant to measure. Check how much of your window a coordinated test would actually use:

Rough model: the standard LoRa time-on-air formula (Semtech AN1200.13) times an estimated number of on-air retransmissions. Not a guarantee, and not enforced by the bot itself β€” message_count is capped at 10 and listen_minutes has a 30-minute floor, and the report window is at least 10 minutes, regardless of this calculator.

Links