MeshMonitor v4.12.0
A large feature release headlined by two new capabilities: a node/builder-based Automation Engine ("when this happens, do that" — triggers → conditions → actions, with variables, {{ }} token substitution, geofence/schedule/system triggers, an "Apprise notify"/"Run a script" action set, and an in-app dry-run tester), and MeshCore Regions/Scopes (per-channel and per-source scope tagging, a Discover Regions sweep, per-message scope overrides, a saved-regions catalog, and received-message scope display). It also lands a deep round of multi-source correctness work — channel/backup/permission queries are now consistently scoped by sourceId (closing a cross-source permission leak), the unified message feed no longer drops messages, and MQTT channels are identified by name and key. Position history was substantially fixed: every fix now renders with full backward pagination, hover/click tooltips with hop count and direct-heard SNR work, and ground_speed is correctly treated as km/h (it was being inflated ~3.6×). MeshCore gains channel unread indicators, a "heard repeaters" badge, per-message hop/route lines, a live byte-accurate character counter, on-demand telemetry polling, and a manual Define-Path editor with 1/2/3-byte hash widths. Other highlights: customizable login branding via env vars, Null-Island position filtering, richer Map-Analysis node popups, git-native LXC templates with in-place updates, and a hardened PostgreSQL channel_database rebuild path. The documentation site was brought current with all of the above, including a new Automation Engine page. This release supersedes the 4.12.0-rc1/rc2 pre-releases.
✨ Features
Automation Engine (#3653) — #3721, #3726, #3727, #3739, #3746 — visual builder, schedule (cron)/geofence/system triggers, multi-source/unified-channel send, "Run a script" + JSON result variables, and in-builder {{ }} token validation.
MeshCore Regions / Scopes (#3667) — #3704 (per-message scope override), #3762 (received-message scope display, Phase 2), #3765 (0-hop region discovery), #3783 (saved-regions catalog + pickers).
MeshCore UI — #3707 (channel "heard repeaters" badge), #3716 (channel unread indicators), #3750 (hop count + relay route under received messages), #3790 (byte-accurate character counter + readability).
Other — #3781 (custom login title/logo via env vars), #3764 (filter out Null Island 0,0 positions), #3692 (rich multi-source Map-Analysis node popups), #3779 (compact {ROUTE} auto-ack variable), #3768 (git-native LXC templates with bundled in-place updater).
🐛 Bug Fixes
Position history & maps — #3795 (render every fix + paginate full history), #3800 (ground_speed is km/h, not m/s — fixes ~3.6× speed inflation), #3801 (Analysis-Map cross-source neighbor links: union not intersection), #3687 (spiderfy + auto-collapse), #3784 (neighbor-link dedup + MQTT transport class), #3694 (position-packet channel from decryption context).
Multi-source / MQTT — #3736, #3738 (messages no longer vanish from the unified feed), #3717 (channel queries scoped by sourceId), #3714 (manual backup scoped to source), #3757 (local-node lookup scoped to source), #3713/#3708/#3754 (MQTT channels identified by name and key), #3748 (batch per-source reads — fixes source-toggle 429s).
MeshCore — #3794 (heartbeat/auto-reconnect + drop detection + reconnect-after-disconnect), #3706 (stop virtual node server on transport teardown), #3702 (Discover Regions timeout), #3722/#3728 (serialize binary-response/raw-frame ack handling), #3737/#3715 ({ROUTE}/{SNR} resolve on routed messages), #3733 (room-server author pubkey), #3760/#3766 (no DM UI for repeaters / unmessagable nodes), #3785 (preserve node name on empty advert), #3761/#3778 (CLI focus + metadata readability).
Notifications / auto-favorite — #3799 (new-node notification fires for direct Meshtastic nodes), #3786 (never auto-favorite CLIENT/CLIENT_MUTE on CLIENT_BASE locals).
Traceroute — #3699/#3723 (route over the default-keyed channel + channel-selection dropdowns).
🔒 Security
- #3749 — scope
filterNodesByChannelPermissionbysourceId(cross-source permission leak for guests). - #3730 — hide node identity from unauthenticated users in the header and poll API.
🛠️ Data / Migrations
- #3753 — rebuild
channel_databaseon PostgreSQL column-tombstone exhaustion (1600-attnum limit), now hardened to run atomically (BEGIN/COMMIT/ROLLBACK) so a mid-rebuild failure rolls back to the original table intact.
🤝 Contributors
Thanks to @BeerMan81 for the LXC template work (#3768, #3793).
Issues Resolved
#3791, #3792, #3796, #3797, #3798, #3787, #3782, #3780, #3777, #3776, #3774, #3773, #3770, #3769, #3763, #3756, #3755, #3752, #3751, #3745, #3744, #3743, #3742, #3740, #3735, #3734, #3732, #3729, #3725, #3720, #3719, #3712, #3711, #3710, #3709, #3703, #3701, #3700, #3698, #3696.
Full changelog: v4.11.6...v4.12.0
🚀 MeshMonitor v4.12.0
📦 Installation
Docker (recommended):
docker run -d \
--name meshmonitor \
-p 8080:3001 \
-v meshmonitor-data:/data \
ghcr.io/Yeraze/meshmonitor:4.12.0🧪 Testing
✅ All tests passed
✅ TypeScript checks passed
✅ Docker images built for linux/amd64, linux/arm64, linux/arm/v7
📋 Changes
See commit history for detailed changes.