Meshtastic Daemon
Overview
meshtastic-daemon is a Python script that connects to a Meshtastic node via TCP, retrieves position information and metrics from detected nodes, and generates a GeoJSON file used by the BRouter map to display LoRa mesh network nodes.
The daemon runs automatically every minute via a cron job and updates the file /data/brouter/www/meshtastic_nodes.json containing active node positions.
Key Features
- TCP connection to Meshtastic node (using
TCPInterface) - Position extraction (latitude, longitude) and metrics (battery, SNR, last contact)
- Active node filtering (last heard < 7 days)
- GeoJSON file generation for BRouter map display
- Atomic file writing (using temp file +
os.replace)
How it Works
Daemon Execution
The daemon is executed every minute by cron:
* * * * * root /data/brouter/meshtastic-daemon.py <NODE_IP>
The Meshtastic node IP address is passed as an argument and configured during installation via the Ansible variable recoverybox_meshtastic_node.ip.
Detailed Process
- Connection: The script establishes a TCP connection to the Meshtastic node
- Collection: It iterates over all visible nodes (
interface.nodes) - Filtering: Only nodes with valid coordinates and
lastHeard< 604800 seconds (7 days) are kept - GeoJSON Generation: Each node is converted to a GeoJSON feature with its properties
- Atomic Writing: The file is written to a temporary file then renamed to prevent corruption
GeoJSON Structure
Each node is represented as a GeoJSON point with the following properties:
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [longitude, latitude]
},
"properties": {
"name": "Node name",
"id": "Node ID",
"battery_level": 85,
"snr": 9.5,
"last_heard": "2024-01-15T10:30:00Z"
}
}
File Interactions
Main Files
| File | Description |
|---|---|
/data/brouter/meshtastic-daemon.py |
Main daemon script |
/data/meshtastic_env/ |
Python virtual environment containing the meshtastic package |
/etc/cron.d/meshtastic-daemon |
Cron configuration running the daemon every minute |
/data/brouter/www/meshtastic_nodes.json |
Output GeoJSON file (auto-updated) |
/data/brouter/www/recoverybox-mesh.js |
Client-side JavaScript for map display |
/data/brouter/www/mesh-node.png |
Icon for nodes displayed on the map |
Configuration
The daemon uses the following configuration defined in /etc/recoverybox/custom_config.yml:
recoverybox_meshtastic_node:
mac: "00:00:00:00:00:00"
ip: "192.168.200.101"
Advanced Configuration
Modifying the Node IP Address
To change the IP address of the Meshtastic node connected to the daemon:
- Edit the configuration file:
nano /etc/recoverybox/custom_config.yml
-
Modify the
recoverybox_meshtastic_node.ipvalue -
Restart the cron service to apply changes:
systemctl restart cron.service
Verification
You can verify the current cron configuration by checking the file /etc/cron.d/meshtastic-daemon.
Modifying the Execution Frequency
To change the daemon execution frequency (default: every minute):
- Edit the cron file:
nano /etc/cron.d/meshtastic-daemon
- Modify the cron line according to your needs. For example, to execute every 5 minutes:
*/5 * * * * root /data/brouter/meshtastic-daemon.py <NODE_IP>
- Save and exit. Changes will be applied automatically.
Debug
Check Cron Status
systemctl status cron.service
View Cron Logs
journalctl -u cron.service -f
Verify Output File
Check that the GeoJSON file is being updated:
ls -lh /data/brouter/www/meshtastic_nodes.json
cat /data/brouter/www/meshtastic_nodes.json | head -20
Manual Daemon Execution
To test the daemon manually:
python3 /data/brouter/meshtastic-daemon.py 192.168.200.101
Replace 192.168.200.101 with your Meshtastic node's IP address.
View Daemon Logs
The daemon does not write persistent logs. In case of errors, you can redirect output to a file:
python3 /data/brouter/meshtastic-daemon.py 192.168.200.101 > /tmp/meshtastic-debug.log 2>&1
Common Issues
| Issue | Probable Cause | Solution |
|---|---|---|
| Empty JSON file | Meshtastic node unreachable | Check IP and network connectivity |
ModuleNotFoundError |
Python environment not configured | Reinstall daemon via Ansible |
| No nodes displayed | No active nodes in range | Verify Meshtastic nodes are powered and in range |
Connectivity Testing
Test connection to Meshtastic node:
ping <NODE_IP>
Verify TCP port is accessible:
nc -zv <NODE_IP> 4403
External Documentation