Bot for Meshtastic Networks to monitor high traffic users and kindly ask them to check settings.
Project description
MeshPatrol
MeshPatrol is a Meshtastic packet-monitoring bot that:
- subscribes to incoming packets from a Meshtastic node (serial or TCP)
- stores packet payloads using
meshdb - tracks per-node and per-packet-type hourly counts in SQLite
- sends a direct message (DM) to nodes that exceed configured thresholds
- serves a dashboard over HTTP (window follows configured threshold unit)
Requirements
- Python
>=3.9,<3.15 - A Meshtastic-compatible radio reachable by USB serial or Meshtastic TCP
- Runtime dependencies:
meshtasticmeshdbPyPubSubFlask
Installation
Install from PyPI (recommended)
pip install meshpatrol
Install from source
git clone https://github.com/pdxlocations/meshpatrol.git
cd meshpatrol
python3 -m venv .venv
source .venv/bin/activate
pip install -U pip
pip install -e .
Running MeshPatrol
After installation, run:
meshpatrol
You can also run directly as a module:
python -m meshpatrol
Connection selection (CLI)
Use one of these optional flags to pick the interface at runtime:
# Serial device path
python -m meshpatrol --serial /dev/ttyUSB0
# TCP host:port
python -m meshpatrol --tcp 192.168.1.50:4403
# IPv6 TCP target
python -m meshpatrol --tcp [fe80::1]:4403
On startup, MeshPatrol:
- connects to your Meshtastic interface (
SerialInterfaceorTCPInterface) - subscribes to
meshtastic.receive - starts a web dashboard on
0.0.0.0:5050(by default), accessible from your LAN viahttp://<host-ip>:5050
Stop with Ctrl+C.
Configuration
Runtime settings live in APP_SETTINGS in meshpatrol/__main__.py.
Threshold values are loaded from config/thresholds.json.
APP_SETTINGS = {
"interface": "serial",
"port": None,
"tcp_hostname": "127.0.0.1",
"tcp_port": 4403,
"meshdb_path": "./meshpatrol-data/databases/mesh_packets.db",
"counter_db_path": "./meshpatrol-data/databases/packet_counters.db",
"thresholds_path": "./meshpatrol-data/thresholds.json",
"threshold_unit": "hour",
"default_threshold": 120,
"threshold_overrides": [],
"alert_template": "...",
"log_level": "INFO",
"web_ui": True,
"web_host": "0.0.0.0",
"web_port": 5050,
}
Key settings
interface:"serial"or"tcp"(used when no CLI override is provided).port: serial device path. UseNonefor Meshtastic auto-detect.tcp_hostname/tcp_port: TCP destination wheninterface="tcp".thresholds_path: JSON file for threshold configuration.threshold_unit: legacy fallback default unit if missing from thresholds JSON ("hour"or"24h").default_threshold/threshold_overrides: legacy fallback only, used ifthresholds_pathfile is missing.alert_template: DM text. Supports{node_id},{packet_type},{count},{threshold},{hour_bucket},{window_label},{threshold_unit}.web_ui: enable/disable dashboard.meshdb_path: SQLite file used bymeshdbpacket storage.counter_db_path: SQLite file used for rate counters and alert history.
Threshold file format
config/thresholds.json:
{
"threshold_unit": "hour",
"default_threshold": 120,
"overrides": {
"POSITION_APP": 300,
"TELEMETRY_APP": {
"threshold": 180,
"unit": "24h"
}
}
}
threshold_unit: default unit ("hour"or"24h") for entries that do not specify a unit.default_threshold: fallback threshold value in the default unit for packet types without an override.overrides: per-port thresholds keyed by Meshtastic port name. Each value can be:- integer: threshold using default
threshold_unit - object:
{ "threshold": <int>, "unit": "hour" | "24h" }for per-port unit override
- integer: threshold using default
Dashboard and API
When web_ui is enabled, MeshPatrol serves:
GET /- HTML dashboardGET /api/snapshot- JSON snapshot for the active threshold windows (hour, 24h, or mixed)
Dashboard includes:
- top nodes by packet count (active window)
- totals by packet type (active window)
- configured thresholds
- node+type breakdown with ETA to threshold (per-port threshold unit)
- recent alerts (active window)
Data files
By default, MeshPatrol creates/updates files in the working-directory ./meshpatrol-data/ folder:
./meshpatrol-data/databases/mesh_packets.<owner_node_num>.db(created bymeshdb)./meshpatrol-data/databases/packet_counters.db./meshpatrol-data/thresholds.json
If WAL mode is active, you may also see -wal and -shm sidecar files.
Logging
Logging is controlled by APP_SETTINGS["log_level"] and defaults to INFO.
Development
Install editable with dependencies:
pip install -e .
Run directly:
python -m meshpatrol
Release process
This repository includes a GitHub Actions workflow at .github/workflows/release.yaml that:
- triggers on semantic version tags (for example:
1.2.3,1.2.3rc1) - checks the new tag version is greater than the latest on PyPI
- builds with Poetry
- publishes artifacts to PyPI
- creates a GitHub Release with generated notes
License
GPL-3.0-only. See LICENSE.
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 meshpatrol-0.0.18.tar.gz.
File metadata
- Download URL: meshpatrol-0.0.18.tar.gz
- Upload date:
- Size: 33.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e4eaf0ab20e55b5c51984d29edfe19ab7ad3e66da7ae7d2a62f18f42072fe27b
|
|
| MD5 |
e82e0971dc0950d90ce1397f8bbe3e47
|
|
| BLAKE2b-256 |
6e5a6098f4ac6014b8cb220f31afa5f8a8835e2aa92203b2aefd60d2d1a2f6fd
|
Provenance
The following attestation bundles were made for meshpatrol-0.0.18.tar.gz:
Publisher:
release.yaml on pdxlocations/meshpatrol
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
meshpatrol-0.0.18.tar.gz -
Subject digest:
e4eaf0ab20e55b5c51984d29edfe19ab7ad3e66da7ae7d2a62f18f42072fe27b - Sigstore transparency entry: 1062633231
- Sigstore integration time:
-
Permalink:
pdxlocations/meshpatrol@d181f0b1925c3a28ef969370a1256c44dd32b4e1 -
Branch / Tag:
refs/tags/0.0.18 - Owner: https://github.com/pdxlocations
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yaml@d181f0b1925c3a28ef969370a1256c44dd32b4e1 -
Trigger Event:
push
-
Statement type:
File details
Details for the file meshpatrol-0.0.18-py3-none-any.whl.
File metadata
- Download URL: meshpatrol-0.0.18-py3-none-any.whl
- Upload date:
- Size: 32.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c9d5643031217751ab224db922f3e72acf1eb9295dfc8ab709dc990260e4c6e3
|
|
| MD5 |
74e62207ca0441979370b753a94430e5
|
|
| BLAKE2b-256 |
1a6cacfb51171df8b3fe4d883e4780858abdbda865fe5dad87919ed6fe1fcc50
|
Provenance
The following attestation bundles were made for meshpatrol-0.0.18-py3-none-any.whl:
Publisher:
release.yaml on pdxlocations/meshpatrol
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
meshpatrol-0.0.18-py3-none-any.whl -
Subject digest:
c9d5643031217751ab224db922f3e72acf1eb9295dfc8ab709dc990260e4c6e3 - Sigstore transparency entry: 1062633265
- Sigstore integration time:
-
Permalink:
pdxlocations/meshpatrol@d181f0b1925c3a28ef969370a1256c44dd32b4e1 -
Branch / Tag:
refs/tags/0.0.18 - Owner: https://github.com/pdxlocations
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yaml@d181f0b1925c3a28ef969370a1256c44dd32b4e1 -
Trigger Event:
push
-
Statement type: