MeshMonitor v4.10.0 is here. The headline features both come down to one theme: seeing more of the mesh you don't physically touch β polling the health of remote nodes you don't own, and untangling the map when dozens of those nodes pile up on top of each other.
Auto Remote LocalStats: graph the health of nodes you don't own β
Until now, the rich LocalStats telemetry β noise floor, channel/air utilization, uptime, packet counts β was only available for nodes you could ask directly. If a key repeater two hops away was quietly drowning in channel utilization, you had no way to watch it over time.
Auto Remote LocalStats fixes that. It's a new per-source automation (modeled on Auto Traceroute) that periodically requests local_stats telemetry from remote nodes and graphs the replies right alongside your own device metrics. You pick which nodes to poll with a union of filters:
- an explicit node list,
- by role (e.g. all repeaters),
- the favorite flag, and
- a name regex.
A round-robin scheduler polls one least-recently-polled target per tick, with jitter, a schedule window, an airtime gate, and a minimum-interval rate limit so it stays a polite citizen of the mesh β and it's passive-mode aware, so it goes quiet when you tell MeshMonitor to stop transmitting.
There's some firmware nuance worth knowing about. The requests go out as a unicast on the node's channel (using the shared channel PSK), not as a PKI direct message. That choice is deliberate:
- A unicast bypasses the firmware's multi-hop-broadcast role gate, so
REPEATERandCLIENTnodes will actually answer β a broadcast request would be ignored by exactly the infrastructure nodes you most want to monitor. - Channel routing uses the shared PSK, which sidesteps the stale-key fragility you'd hit with a PKI DM.
hop_limit is sized to each target's observed distance, and the replies persist through the existing telemetry pipeline β no new storage, and your noise-floor and ChUtil graphs just start filling in for remote nodes.
Find it under Automation β Auto Remote LocalStats.
Map Analysis: search, spiderfy, and directional traceroutes β
The Map Analysis view got four upgrades that make a busy mesh legible.
Node search. A toolbar search box hides every marker that doesn't match β by long/short name, node id, or hex/decimal nodeNum β and the same term constrains which traceroute links are drawn. Type a name and the map collapses to just what you care about.
Marker spiderfy (untangling the pile-up). When several nodes report the same coordinates β a common site with multiple radios, or a cluster of nodes that all inherited one position β they used to stack into a single un-clickable marker. They now fan out ("spiderfy") so each node is individually selectable.
Inbound vs. outbound traceroutes. Each hop in a traceroute has its SNR measured at the receiver, so a hop arriving at the selected node is inbound (RX) and a hop leaving it is outbound (TX). MeshMonitor now decomposes traceroutes into those directed legs and draws them with direction colours, opposite curvature, and SNR-tooltip arrows β so you can see, at a glance, whether a weak link is weak coming in or going out.
Weak-link filtering + per-node summary. Persisted min-occurrences and min-SNR filters dedupe and declutter the link overlay, and the inspector now shows a per-node summary: distinct links, in/out counts, observation counts, and average SNR.
All of this is frontend-only over the existing traceroute data β no new permissions, no migration.
GeoJSON overlays everywhere β
Custom GeoJSON overlay layers used to reach only authenticated users. Each layer now has an opt-in Public toggle (default off). Flagged layers render on the public/anonymous map, the embed map, and the unified dashboard map β so you can share region boundaries, repeater coverage, or evacuation routes with anonymous and embedded viewers β while private layers stay private. It's opt-in and secure by default: anonymous callers only ever receive layers you've explicitly marked public, and private layer data returns a 404.
Desktop: Apprise notifications, no Python required β
The Docker image has always run Apprise as a Python sidecar to fan notifications out to 100+ services. Desktop (Tauri) builds shipped the Node backend but no Python, so desktop users could only point at a remote Apprise API.
v4.10.0 freezes Apprise β with every notification plugin bundled β into a single self-contained executable that ships alongside the desktop app. The Rust shell starts it on a loopback-only port, wires the backend to it, and keeps it alive across restarts. Desktop now has full local Apprise support with no system Python to install.
One known gap: Intel (x86_64) macOS builds are cross-compiled on an Apple-silicon runner where PyInstaller can't cross-compile, so they omit the bundled sidecar and fall back to a remote Apprise API. Apple-silicon macOS, Windows, and Linux desktop builds all ship the sidecar.
Also in 4.10.0 β
- Noise Floor telemetry (#3396): the
noiseFloor(dBm) field added in Meshtastic firmware 2.7.25 is now captured and charted alongside the rest of LocalStats, on Device Info and every local-stats graph. (And remember β with Auto Remote LocalStats above, you can now watch it for nodes you don't own.) - Radio Statistics legend & Packet Distribution total (#3400, #3401): the legend no longer clips counts mid-value, and the Packet Distribution panel shows a prominent grand total.
- Security tab source-scoping (#3406): the Dead Nodes and Key Mismatch tables no longer leak rows across sources β both are now scoped to the source you're viewing.
- Custom analytics CSP domains (#3409): "CSP Allowed Domains" configured for a Custom Script now actually reach the
Content-Security-Policyheader.
Upgrade β
# Docker
docker pull ghcr.io/yeraze/meshmonitor:4.10.0
docker compose down && docker compose up -d
# Helm
helm repo update
helm upgrade meshmonitor meshmonitor/meshmonitor --version 4.10.0Desktop builds are on the Releases page.