- Python 99.1%
- Shell 0.9%
- Bot: add `nodes` command listing discoverable RNS nodes within 50km of Moscow via rnstatus - Map: add HaLow node type fetched from rnode-halow.ru with full popup/list support - Map: switch discovery clustering from lat/lon bucketing to pixel-distance threshold - Map: add ProxyFix middleware for correct client IP behind reverse proxy - Map: fix heatmap hover tip to only show when heatmap is visible - Map: default heatmap off (require explicit opt-in via localStorage) - Map: add uptime formatter and expose HaLow-specific fields (freq, bw, fw, uptime, lxmf, tx/rx) - Map: re-render discovery on zoomend when no group is expanded Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|---|---|---|
| bot | ||
| init_scripts | ||
| map | ||
| plugin | ||
| README.md | ||
rns-wardrive-tools
A collection of tools for wardriving LoRa coverage using the Reticulum Network Stack and Sideband.
Components
plugin/ — Sideband Plugin
A Sideband service plugin that runs on your mobile device and periodically sends your GPS location to the collector bot over RNS.
Installation:
Copy wardrive_plugin.py and wardrive_config.json to your Sideband plugins directory (configured in Sideband settings under Plugins path).
Configuration (wardrive_config.json):
{
"announce_interval_secs": 30,
"announce_mode": "auto",
"send_mode": "packet",
"bot_hashes": ["<bot collector destination hash>"]
}
| Option | Values | Description |
|---|---|---|
announce_interval_secs |
integer (min 15) | How often to send location in auto mode |
announce_mode |
auto / manual |
auto: sends on interval; manual: sends when you press Sideband's announce button |
send_mode |
announce / packet |
announce: broadcasts on the network; packet: sends directly and privately to the bot |
bot_hashes |
list of hex strings | Collector destination hashes of bots to send to (packet mode only) |
In packet mode, location data is sent encrypted directly to each listed bot — it is not broadcast to the wider network. RSSI/SNR are still recorded on the receiving end.
In announce mode, location is broadcast as a wardrive.beacon announce visible to all nodes.
bot/ — Collector Bot
A server-side RNS daemon that listens for incoming location data, records RF signal statistics, and responds to LXMF commands.
Requirements: rns, lxmf, rnsd running
Installation:
Copy wardrive_bot.py to /opt/reticulum/bin/ (or any location on your $PATH).
Usage:
python3 wardrive_bot.py
The bot writes to ~/wardrive_bot.db (SQLite) and logs to /etc/reticulum/wardrive_bot_logfile.
LXMF commands (send via Sideband or any LXMF client):
| Command | Response |
|---|---|
ping |
Pong! [14:32:01, RSSI: -74dBm, SNR: 6.5dB] — RF stats included if message arrived over LoRa |
status |
Point count and timestamp of last received beacon |
map/ — Coverage Map Server
A Flask web server that reads the bot's database and serves a live interactive coverage heatmap.
Requirements: flask, rns
Installation:
Copy map_server.py to /opt/reticulum/bin/ and wardrive_map.json to /etc/reticulum/.
Configuration (wardrive_map.json):
{
"db_path": "~/wardrive_bot.db",
"discovery_dir": "/etc/reticulum/storage/discovery/interfaces",
"listen_on": "0.0.0.0",
"port": 5000,
"page_title": "Wardrive Coverage Map",
"initial_lat": null,
"initial_lon": null,
"initial_zoom": null
}
Set initial_lat, initial_lon, and initial_zoom to pre-position the map on load; leave all three as null to auto-fit to recorded points.
Usage:
python3 map_server.py
Serves on http://0.0.0.0:5000 by default.
Features:
- Live heatmap of recorded coverage points, coloured by RSSI
- Live data stream panel showing incoming packets in real time (source, coordinates, RSSI/SNR/Q)
- Date range filter with day/week/month/year presets
- Light/dark UI theme with tileset selector (Dark, Voyager, Voyager no labels, Light, OSM)
- RNS infrastructure discovery panel — shows RNodes, Backbone, and I2P interfaces that have GPS coordinates, sourced from the local RNS discovery cache
- Toggleable node labels per interface type
init_scripts/ — Service Files
Systemd and OpenRC service files for both the bot and the map server.
OpenRC:
cp init_scripts/openrc/wardrive-bot /etc/init.d/
cp init_scripts/openrc/wardrive-map /etc/init.d/
chmod +x /etc/init.d/wardrive-bot /etc/init.d/wardrive-map
rc-update add wardrive-bot default
rc-update add wardrive-map default
Systemd:
cp init_scripts/systemd/wardrive-bot.service /etc/systemd/system/
cp init_scripts/systemd/wardrive-map.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable --now wardrive-bot wardrive-map
Data Flow
[Sideband + plugin]
|
| wardrive.beacon announce (announce mode, visible to all)
| wardrive.collector packet (packet mode, encrypted to bot only)
|
[wardrive_bot.py] ──── wardrive_bot.db ────[map_server.py]──── browser
|
LXMF replies (ping, status)