Simple Meshtastic monitoring UI + JSON API
Project description
Meshtastic Monitor (simple)
A small, clean monitoring UI + JSON API for a Meshtastic network reachable over TCP (direct to node, default 4403).
Start in 2 minutes (the simple way)
chmod +x run.sh
./run.sh --host YOUR_MESH_IP
Then open:
- UI:
http://localhost:8080/ - API health:
http://localhost:8080/api/health
That’s it. You can also configure the IP/port later in Settings inside the UI.
Install via pip (simple)
pip install -r meshtastic-monitor
Run:
python -m meshtastic_monitor
You will be prompted for host/ports if not provided. Then open http://localhost:8880/.
Features
- Backend (data layer): Python + Flask +
meshtasticTCP client, robust reconnect, JSON-safe endpoints - Frontend (view layer): Vanilla HTML/CSS/JS that talks only to the JSON API
- No bytes in JSON: binary payload is base64-encoded (
payload_b64)
Repo layout
backend/
app.py
jsonsafe.py
mesh_service.py
requirements.txt
requirements-dev.txt
tests/
meshtastic-monitor
frontend/
index.html
app.js
styles.css
Install
python3 -m venv .venv
source .venv/bin/activate
pip install -r backend/requirements.txt
Run
One command (optional)
chmod +x run.sh
./run.sh
This will:
- create
.venv/(if missing) - install Python dependencies
- (optional) verify target is reachable (Meshtastic TCP)
- start the backend (which also serves the UI)
Then open http://localhost:8080/ and set the Meshtastic host/port in Settings.
Options:
./run.sh --host your-mesh-host --mesh-port 4403 --http-port 8080./run.sh --nodes-history-interval 60(store node history every 60s)./run.sh --no-check(start even if reachability check fails)
Manual (env vars)
# Optional: set here, or configure it in the UI Settings.
export MESH_HOST=your-mesh-host
export MESH_PORT=4403
export HTTP_PORT=8080
python3 -m backend.app
Then open:
- UI:
http://localhost:8080/ - Health:
http://localhost:8080/api/health
Backend config
- Env vars:
MESH_HOST(default empty; set via env or the UI)MESH_PORT(default4403)HTTP_PORT(default8080)NODES_REFRESH_SEC(default5)MAX_MESSAGES(default200)STATS_DB_PATH(defaultmeshmon.db, set tooffto disable)STATS_WINDOW_HOURS(default24) used by/api/statsNODES_HISTORY_INTERVAL_SEC(default60, set0to store every snapshot)
- Optional runtime update (used by the UI Settings modal):
POST /api/config(partial updates allowed), e.g.{ "meshHost":"...", "meshPort":4403 }- Settings modal also supports Export Config (downloads a JSON snapshot including device config)
API
GET /api/health
{
"ok": true,
"configured": true,
"meshHost": "your-mesh-host",
"meshPort": 4403,
"connected": true,
"generatedAt": 1730000000
}
GET /api/nodes
Returns direct + relayed nodes (sorted by freshness; lowest ageSec first).
GET /api/nodes/history
Returns history snapshots for all nodes (from SQLite). Query params:
nodeId(optional, filter by node)limit(default500, use0for all)since(epoch seconds, optional)order(ascordesc, defaultdesc)
GET /api/messages
Returns a list of messages from the persistent history (SQLite). Ordering: newest last (chronological). Query params:
limit(default200, use0for all)offset(default0)order(ascordesc, defaultasc)
History is stored when STATS_DB_PATH is enabled (default meshmon.db).
GET /api/channels
Returns configured channels (if available from the active interface). Secrets/PSKs are never included.
GET /api/radio
Returns a JSON-safe snapshot of your local radio (id, names, hops, metrics, position when available).
GET /api/device/config
Returns the full device configuration (local + module config, channels, metadata, myInfo).
Use ?includeSecrets=1 to include channel PSKs; default redacts PSKs.
GET /api/stats
Returns persisted counters and simple aggregates (SQLite at STATS_DB_PATH), including:
- message totals + per-hour buckets (
messages.windowHours,messages.hourlyWindow) - app appearance counts (
apps.counts) for Position/NodeInfo/Telemetry/Routing - requesters targeting you or broadcast (
apps.requestsToMe) - top talkers (
nodes.topFrom,nodes.topTo) - recent mesh/connectivity events (
events)
GET /api/node/<id>
Returns a combined view of live node data + persisted stats for a single node.
GET /api/node/<id>/history
Returns history snapshots for one node (from SQLite). Query params:
limit(default500, use0for all)since(epoch seconds, optional)order(ascordesc, defaultdesc)
POST /api/send
Body:
{ "text": "hello", "to": "!abcd1234", "channel": 0 }
Curl examples
curl -s http://localhost:8080/api/health | jq
curl -s http://localhost:8080/api/nodes | jq
curl -s http://localhost:8080/api/messages | jq
curl -s -X POST http://localhost:8080/api/send \
-H 'Content-Type: application/json' \
-d '{"text":"hello from curl"}' | jq
Tests
The test suite uses a fake mesh service (no Meshtastic device required).
pip install -r backend/requirements-dev.txt
pytest
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file meshtastic_monitor-0.1.4.tar.gz.
File metadata
- Download URL: meshtastic_monitor-0.1.4.tar.gz
- Upload date:
- Size: 53.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0836e94f3c35a21719bee8cb52d508bc74b54fda80d27fb21f2009a80d0131f7
|
|
| MD5 |
04e98451241295ad58b5ad9982096e44
|
|
| BLAKE2b-256 |
75458552c479a469db90cd6118a886e70b9d607c1a1c1938534d5e4c4a0d51bc
|
File details
Details for the file meshtastic_monitor-0.1.4-py3-none-any.whl.
File metadata
- Download URL: meshtastic_monitor-0.1.4-py3-none-any.whl
- Upload date:
- Size: 54.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2febbe3d04bd4abe110553ef6a873f2f8ae77e97641811f78915c085ca7f223f
|
|
| MD5 |
22bd287c41a379ec29ea0835ae477390
|
|
| BLAKE2b-256 |
0029d6e8b8f5bb38a1a73a9e712a5e1bdf0cbaff23012bc6c85aa26d0a2b4f16
|