Skip to main content

Simple Meshtastic monitoring UI + JSON API

Project description

Meshtastic Monitor

A tiny web dashboard + JSON API for Meshtastic over TCP (direct to your node, default port 4403).

What you need (before you start)

  1. A Meshtastic node reachable over Wi‑Fi (you know its IP/hostname)
  2. Python 3.9+

Start (2 minutes)

1) Install (one time)

pip install meshtastic-monitor

If pip is not available, use:

python3 -m pip install meshtastic-monitor

2) Run

python -m meshtastic_monitor --host YOUR_MESH_IP

If python is not available, use:

python3 -m meshtastic_monitor --host YOUR_MESH_IP

Then open:

  • UI: http://localhost:8880/
  • Health (JSON): http://localhost:8880/api/health

If you run this on another computer in your LAN, open:

  • http://SERVER_IP:8880/

2a) Config file (created automatically)

On first run, a config file is created in the current folder:

  • ./meshmon.ini

This file stores your mesh host/port, optional TCP relay, and SMS relay settings. You can also choose a custom path:

python -m meshtastic_monitor --config /path/to/meshmon.ini

3) Stop

Press Ctrl+C in the terminal where it is running.

Configure (if you didn’t pass --host)

  1. Open the UI
  2. Click Settings
  3. Put your Meshtastic IP/host + port (4403)
  4. Click Save & Apply

The UI stores these settings in your browser (localStorage) and the backend config file (meshmon.ini) when started via python -m meshtastic_monitor.

SMS relay (optional)

If you want every incoming packet forwarded via SMS, configure it in Settings:

  • Enable SMS relay
  • Set SMS API URL, API key, and Phone

You can also apply allow-list filters:

  • Allowed From IDs (comma-separated or ALL)
  • Allowed Types (comma-separated or ALL)
    • Types can be TEXT, app names (e.g. POSITION_APP), or port numbers (e.g. 5)

TCP relay (optional)

If you want more than one TCP client, enable the relay. The app will keep a single connection to your radio and expose a TCP port for other clients:

  • Enable TCP relay
  • Listen host: 0.0.0.0 (default)
  • Listen port: 4403 (default)

Other clients should then connect to your app machine on RELAY_HOST:RELAY_PORT instead of connecting directly to the radio.

Where to see relay status

  • UI: Stats → TCP Relay (upstream status + connected clients)
  • API: GET /api/relay

Security note

Binding to 0.0.0.0 exposes the relay to your LAN. Do not expose it to the public internet unless you add firewall rules.

Command-line options (copy/paste)

Show all options:

python -m meshtastic_monitor --help

Most used:

  • --host / --mesh-host (Meshtastic IP/hostname)
  • --mesh-port (default 4403)
  • --http-port (default 8880)
  • --log-file (default ./meshmon.log)
  • --log-level (default INFO)
  • --nodes-history-interval (default 60 seconds)
  • --config (path to meshmon.ini)
  • --sms-enabled / --sms-disabled
  • --sms-api-url
  • --sms-api-key
  • --sms-phone
  • --sms-allow-from (comma-separated sender IDs or ALL)
  • --sms-allow-types (comma-separated types or ALL)
  • --relay-enabled / --relay-disabled
  • --relay-host (default 0.0.0.0)
  • --relay-port (default 4403)

You can also set env vars instead of flags:

  • MESH_HOST (default empty; can also be set via UI)
  • MESH_PORT (default 4403)
  • HTTP_PORT (default 8880 when using python -m meshtastic_monitor)
  • NODES_REFRESH_SEC (default 5) refresh live node snapshot
  • MAX_MESSAGES (default 200) in-memory ring buffer size
  • STATS_DB_PATH (default meshmon.db, set to off to disable persistence)
  • NODES_HISTORY_INTERVAL_SEC (default 60) how often to store node history samples
  • STATUS_HISTORY_INTERVAL_SEC (default 60) how often to store status samples
  • STATS_WINDOW_HOURS (default 24) used by /api/stats
  • MESH_HTTP_PORT (default 80) for http://MESH_HOST[:port]/json/report
  • STATUS_TTL_SEC (default 5) cache /json/report for this many seconds
  • LOG_LEVEL (default INFO)
  • MESHMON_LOG_FILE (default ./meshmon.log)
  • MESHMON_CONFIG (path to meshmon.ini)
  • SMS_ENABLED (1/0)
  • SMS_API_URL (base URL, e.g. https://your-sms-gateway.example/api)
  • SMS_API_KEY
  • SMS_PHONE
  • SMS_ALLOW_FROM_IDS (comma-separated sender IDs or ALL)
  • SMS_ALLOW_TYPES (comma-separated types or ALL)
  • SMS_TIMEOUT_SEC (seconds, default 4)
  • RELAY_ENABLED (1/0)
  • RELAY_HOST (default 0.0.0.0)
  • RELAY_PORT (default 4403)

Logs (where are they?)

By default the app writes logs to:

  • ./meshmon.log (the directory where you started the command)

You can change it:

python -m meshtastic_monitor --log-file /path/to/meshmon.log

Logs are rotated (to avoid infinite growth): ~2MB per file, up to 3 backups.

TCP relay events (listen/upstream/client connect/disconnect) are logged to the same file.

How it works (simple mental model)

Two layers

  1. Backend (Python/Flask) exposes JSON endpoints under /api/* and serves the UI.
  2. Frontend (HTML/JS) is just static files that poll the JSON API.

What it connects to

  • Meshtastic TCP interface (library: meshtastic, class: TCPInterface)
  • Your node’s optional HTTP status endpoint: http://<mesh-host>/json/report

Data flow (incoming packets)

  1. Backend connects to your node over TCP (MESH_HOST:MESH_PORT)
  2. The meshtastic library publishes received packets on meshtastic.receive (via pypubsub)
  3. We convert every packet to a thin, JSON-safe dict (no raw bytes) and:
    • keep the last MAX_MESSAGES in memory
    • store everything in SQLite (if enabled)
  4. If SMS relay is enabled, the packet is forwarded to your SMS gateway URL

Nodes

  • Live node list comes from the Meshtastic node DB (iface.nodes)
  • Node history is sampled to the DB every NODES_HISTORY_INTERVAL_SEC seconds (default 60) to avoid DB explosion

Status (“/json/report”)

  • The UI shows a nice summary of http://<mesh-host>/json/report (if your node exposes it)
  • Backend caches it for STATUS_TTL_SEC and stores a compact subset in SQLite every STATUS_HISTORY_INTERVAL_SEC

Persistence (history / database)

By default, the app creates a SQLite file:

  • meshmon.db

It stores:

  • message history (so you can scroll back)
  • per-node counters (fromCount, toCount, last RSSI/SNR, etc.)
  • node “quality over time” samples (SNR/quality/hops/lastHeard)
  • mesh connect/disconnect/error events
  • compact status samples (battery/utilization/wifi/etc.)

To disable persistence:

export STATS_DB_PATH=off
python -m meshtastic_monitor --host YOUR_MESH_IP

To reset history: stop the app and delete meshmon.db.

Security notes (important)

  • There is no login/auth. Run this only on a trusted network.
  • GET /api/device/config redacts PSKs by default.
    • GET /api/device/config?includeSecrets=1 will include secrets — do this only if you understand the risk.

API (for developers)

Quick overview:

  • GET /api/health – backend status + mesh connection status
  • GET /api/status – cached /json/report + link to the JSON
  • GET /api/config – current runtime config (mesh + SMS, no secrets)
  • GET /api/nodes – live nodes (direct + relayed)
  • GET /api/messages – message history (SQLite if enabled, else memory)
  • POST /api/send – send text (optional to and channel)
  • GET /api/relay – TCP relay status + connected clients
  • GET /api/stats – aggregates + charts data
  • GET /api/node/<id> – combined live + persisted stats for one node
  • GET /api/nodes/history / GET /api/node/<id>/history – history samples

Example:

curl -s http://localhost:8880/api/health
curl -s http://localhost:8880/api/nodes
curl -s http://localhost:8880/api/messages?limit=20
curl -s -X POST http://localhost:8880/api/send -H 'Content-Type: application/json' -d '{"text":"hello","channel":0}'

Development (optional)

From a git checkout:

pip install -U pip
pip install -e .
pip install -r backend/requirements-dev.txt
pytest -q

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

meshtastic_monitor-0.1.27.tar.gz (74.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

meshtastic_monitor-0.1.27-py3-none-any.whl (75.9 kB view details)

Uploaded Python 3

File details

Details for the file meshtastic_monitor-0.1.27.tar.gz.

File metadata

  • Download URL: meshtastic_monitor-0.1.27.tar.gz
  • Upload date:
  • Size: 74.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for meshtastic_monitor-0.1.27.tar.gz
Algorithm Hash digest
SHA256 2d9e57290e3f1e7caaf629c423f0fddcc3aa616807f5d8c329f52dd0870694d2
MD5 1c228e0feefa467c978672ebb8d18b0f
BLAKE2b-256 0f7185fdfe27dce207e37fc9f45b113d9b9c2655f1ac79da33d95bfd857df386

See more details on using hashes here.

File details

Details for the file meshtastic_monitor-0.1.27-py3-none-any.whl.

File metadata

File hashes

Hashes for meshtastic_monitor-0.1.27-py3-none-any.whl
Algorithm Hash digest
SHA256 a049f1a5d43e04ba9925304e61e0a29e8e7bff09e1ff8103b6873b191a32292d
MD5 7123d8f749bcd01d06434e64bc886747
BLAKE2b-256 92c7956f36eeda518f39da2c66ca87d5f6cde02c6d4d186bff7bed857b4e9bf7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page