Skip to main content

Building a Mesh Network Dashboard

A community mesh network dashboard gives operators a real-time view of network health - which nodes are online, battery levels, channel utilization, and connectivity maps. This page covers building a monitoring stack for a Meshtastic network.

Architecture Overview

The standard monitoring stack for Meshtastic:

Meshtastic nodes
 ↓ (MQTT uplink)
MQTT Broker (Mosquitto)
 ↓
Telegraf (or Python consumer)
 ↓
InfluxDB (time-series database)
 ↓
Grafana (dashboard and alerting)

This stack can run on a Raspberry Pi 4 or any small Linux server. Total resource requirement: approximately 500 MB RAM, 10 GB storage for 30 days of data from a 50-node network.

Step 1: MQTT Broker Setup

Install Mosquitto on your monitoring server:

sudo apt install mosquitto mosquitto-clients
sudo systemctl enable mosquitto

Minimal config at /etc/mosquitto/mosquitto.conf:

listener 1883
allow_anonymous true
persistence true
persistence_location /var/lib/mosquitto/

For production, add TLS and password authentication.

Step 2: Configure Nodes to Uplink

On each node you want to monitor:

meshtastic --set mqtt.enabled true
meshtastic --set mqtt.address "YOUR_SERVER_IP"
meshtastic --set mqtt.uplink_enabled true
meshtastic --set mqtt.json_enabled true

JSON mode outputs human-readable JSON instead of protobuf binary - easier for custom consumers but includes less data. For full data including all telemetry, use protobuf mode and decode with the meshtastic Python library.

Step 3: InfluxDB

Install InfluxDB 2.x:

wget -q https://repos.influxdata.com/influxdata-archive_compat.key
sudo apt install influxdb2
sudo systemctl enable --now influxdb

Create a bucket named "meshtastic" with 90-day retention via the InfluxDB UI at http://localhost:8086.

Step 4: Python MQTT-to-InfluxDB Bridge

pip install paho-mqtt influxdb-client meshtastic

# bridge.py - subscribe to Meshtastic MQTT, write metrics to InfluxDB
import paho.mqtt.client as mqtt
from influxdb_client import InfluxDBClient, Point
from influxdb_client.client.write_api import SYNCHRONOUS
import json, time

INFLUX_URL = "http://localhost:8086"
INFLUX_TOKEN = "YOUR_TOKEN"
INFLUX_ORG = "meshamerica"
INFLUX_BUCKET = "meshtastic"

client = InfluxDBClient(url=INFLUX_URL, token=INFLUX_TOKEN, org=INFLUX_ORG)
write_api = client.write_api(write_options=SYNCHRONOUS)

def on_message(mqttc, userdata, msg):
 try:
 data = json.loads(msg.payload)
 node_id = data.get("from", "unknown")
 if "payload" in data:
 p = data["payload"]
 pt = Point("node_telemetry").tag("node_id", node_id)
 if "battery_level" in p:
 pt = pt.field("battery_pct", p["battery_level"])
 if "voltage" in p:
 pt = pt.field("voltage", p["voltage"])
 if "channel_utilization" in p:
 pt = pt.field("channel_util", p["channel_utilization"])
 write_api.write(INFLUX_BUCKET, record=pt)
 except Exception as e:
 print(f"Error: {e}")

mqttc = mqtt.Client()
mqttc.on_message = on_message
mqttc.connect("localhost", 1883)
mqttc.subscribe("msh/#")
mqttc.loop_forever()

Step 5: Grafana Dashboard

Install Grafana and add InfluxDB as a data source. Useful panels:

  • Battery Voltage by Node - Time series, grouped by node_id tag
  • Online Node Count - Count distinct nodes seen in last 30 minutes
  • Channel Utilization Heatmap - Spot congestion patterns over time
  • Last Seen Table - Node name and minutes since last packet

Alerting

Configure Grafana alerts to notify via email, Slack, or Telegram:

  • Battery below 20% - node needs attention
  • Node offline (no data in 2 hours) - repeater may be down
  • Channel utilization above 30% - network congestion warning