- Shell 53.6%
- Python 46.4%
Generalised toolkit to build, deploy and analyse a fleet of passive LoRa (MeshCore) observer kits: Raspberry Pi + SenseCAP T1000 listen-only radios that log every overheard packet for offline coverage/route analysis. Includes Pi-side scripts (capture, scheduled frequency switch, heartbeat), systemd units, a read-only laptop fleet health-check, an analysis skeleton, and full build/deploy/operate docs (docs/01-08). Secrets and personal data removed; configuration via .env / kits.conf. |
||
|---|---|---|
| analysis | ||
| docs | ||
| scripts | ||
| systemd | ||
| .env.example | ||
| .gitignore | ||
| LICENSE | ||
| README.md | ||
Mesh Observer Fleet
A toolkit for measuring how a LoRa mesh network actually performs in the field, using a fleet of cheap passive observer kits — a Raspberry Pi + a SenseCAP T1000 radio in listen-only firmware — that log every overheard packet (RSSI, SNR, message hash, route) to disk for offline analysis.
It covers the whole chain: build one observer, mass-produce the fleet from a golden image, deploy and health-check them, switch the radio frequency mid-test on a schedule (no SSH needed), then merge and analyse the logs.
Origin & status. Built for a real 6-kit MeshCore emergency-communication pilot in a Dutch city. It has been generalised: deployment specifics (locations, people, passwords, keys, device MACs) were removed and replaced with placeholders, so this is a reusable template rather than a turnkey config. The
analyse_observer.pyanalysis is a working skeleton — see docs/07-analysis.md.
Why this exists
Mesh radios don't keep a usable log of network behaviour. To answer "did the network carry itself?" with evidence you need independent listeners at the points that matter, each recording every packet. A key method here is the two-block test: run first on a shared community frequency, then switch the whole fleet to an isolated frequency, so you can separate "my network relayed it" from "the ambient mesh relayed it for me." Full reasoning in docs/01-architecture.md.
LoRa packets ──► T1000 (companion FW, RX only) ──BLE──► Raspberry Pi ──► JSON log on SD
(powerbank)
× N observers at the sites that matter ──► collect & merge ──► coverage / RSSI / routes
Hardware per kit
- Seeed SenseCAP T1000-E flashed to MeshCore Companion (Bluetooth) firmware
- Raspberry Pi Zero W v1 (or any single SBC with BLE+WiFi — keep the whole fleet on one architecture)
- 20 Ah+ powerbank, microSD, USB-C + micro-USB cables
Details and the ARMv6/clock caveats: docs/02-hardware.md.
Quick start
Work through the docs in order:
- 01 — Architecture & rationale
- 02 — Hardware
- 03 — Build one observer end-to-end
- 04 — Golden image & fleet
- 05 — The scheduled frequency switch
- 06 — Field deployment & operations
- 07 — Analysis
- 08 — Lessons & pitfalls ← read this early
Repo layout
README.md
LICENSE GNU AGPL-3.0
.env.example secrets/config you must supply (channel key, target freq, …)
.gitignore keeps secrets, logs and captured data out of git
docs/ 01–08, the full build-and-operate guide
scripts/ Pi-side scripts + laptop fleet health-check
run-capture.sh unique-file-per-session capture w/ BLE pre-disconnect fix
switch_freq.py set_radio + reboot (reads MAC from .env.local)
switch-frequency.sh robust scheduled switch wrapper (retry + guaranteed restart)
heartbeat.sh per-minute liveness stamp
check_all_pis.sh read-only PASS/WARN/FAIL fleet check from your laptop
kits.conf.example per-fleet config for the health-check
systemd/ meshcore-capture / switch (.service+.timer) / rfkill-unblock
analysis/
analyse_observer.py merge logs, heard-matrix, coverage, reception % (skeleton)
requirements.txt
Security & privacy
This repo is built to be safe to publish:
- No secrets are committed. WiFi passwords, the AES-128 channel key and device MACs
live in
.env/.env.local/scripts/kits.conf(all git-ignored). Copy.env.exampleandscripts/kits.conf.exampleand fill in your own. The MeshCore#Publicdefault key is a well-known public constant and is the only key left in code. - No personal data. Volunteer names, contacts and exact GPS coordinates from the
original deployment were removed;
PREFIX_MAPin the analysis uses example placeholders. - If you fork this for a real deployment, keep your real keys/locations out of git — git history is permanent.
Credits & dependencies
- agessaman/meshcore-packet-capture — the capture tool that runs on each Pi.
- meshcoredecoder — optional offline decode of sender/plaintext.
- MeshCore — firmware, web flasher, app.
- Alternative MQTT path: Andrew-a-g/meshcoretomqtt.
License
GNU Affero General Public License v3.0 — see LICENSE. You are free to use, study, share and modify this; derivatives (including networked services) must stay under the same license.