Automated sync from private repository. Built with obfuscation enabled.
pyMC Console
A modern web dashboard for monitoring and managing your MeshCore LoRa mesh repeater.
Built on pyMC_Repeater by RightUp, pyMC Console provides real-time visibility into your mesh network with an intuitive, feature-rich interface.
How It All Fits Together
The MeshCore Python ecosystem has three components:
┌─────────────────────────────────────────────────────────────┐
│ pyMC Console │
│ (this repo - web dashboard UI) │
│ │
│ • React dashboard served on port 8000 │
│ • Visualizes packets, topology, stats │
│ • manage.sh installer handles everything │
└─────────────────────┬───────────────────────────────────────┘
│ uses API from
┌─────────────────────▼───────────────────────────────────────┐
│ pyMC_Repeater │
│ (RightUp's repeater daemon) │
│ │
│ • Python daemon that runs the repeater │
│ • Provides REST API on port 8000 │
│ • Handles packet forwarding, logging, config │
└─────────────────────┬───────────────────────────────────────┘
│ built on
┌─────────────────────▼───────────────────────────────────────┐
│ pyMC_core │
│ (RightUp's protocol library) │
│ │
│ • Low-level MeshCore protocol implementation │
│ • Radio drivers (SX1262, SX1276) │
│ • Packet encoding/decoding │
└─────────────────────────────────────────────────────────────┘
Key points:
- Console does NOT replace Repeater — they work together
- Console's
manage.shinstalls both Repeater and Console side-by-side - Console provides the web UI; Repeater provides the backend API and radio control
- You can upgrade Console independently without touching Repeater/Core
Feature Highlights
🗺️ Mesh Topology Analysis
The topology analyzer reconstructs your network's structure from packet paths using a Viterbi HMM decoder — resolving prefix collisions with physics-based constraints and observation evidence.
- Deep Analysis — One-click full topology rebuild from 75K packets
- Viterbi HMM decoding — Hidden Markov Model resolves prefix collisions using geographic distance and LoRa range constraints
- Ghost node discovery — Detects unknown repeaters when no known candidate is geographically plausible
- 3D terrain mode — Real-world topographic terrain with hillshading; markers and edges drape onto the landscape
- 3D arc edges — Topology edges rendered as elevated arcs via deck.gl (GPU-accelerated)
- Edge confidence visualization — Line thickness scales with observation count; color indicates certainty
- Wardriving overlay — H3 hexagonal tiles from coverage servers with SNR-based coloring
📡 Link Quality Radar
The polar chart visualizes all contacts at their actual compass bearing and distance from your node.
- Zero-hop neighbors — Colored by SNR quality (green → yellow → orange → red)
- Non-neighbors — Rendered at 33% opacity to distinguish direct RF contacts
- Hover interaction — Full opacity with detailed signal metrics tooltip
📊 Statistics Dashboard
Comprehensive RF metrics and network composition analysis.
- Airtime utilization — RX/TX spectrum with peak and mean metrics
- Packet types treemap — Distribution of ADVERT, TXT_MSG, ACK, RESPONSE, etc.
- Network composition — Breakdown of repeaters, companions, and room servers
- RF noise floor — Heatmap showing interference patterns over time
- Prefix disambiguation health — Confidence metrics for topology inference
🛤️ Packet Path Tracing
Click any packet to visualize its route through the mesh with hop-by-hop confidence indicators.
- Confidence coloring — Green (100%), Yellow (50-99%), Orange (25-49%), Red (<25%), Gray (ghost node)
- Interactive map — Shows the resolved path with all intermediate hops
- Signal details — RSSI, SNR, and timing for each packet
🎨 Themes & Terminal
Six color schemes and a built-in terminal for direct repeater interaction.
- Color schemes — Seoul256, Gruvbox, Deus, Gotham, Sonokai, Kanagawa
- Background images — Multiple ambient backgrounds with adjustable brightness
- Terminal — Direct CLI access to the repeater for advanced operations
- Live logs — Stream from repeater daemon with DEBUG/INFO toggle
All Features
Dashboard
- Live packet metrics — Received, forwarded, dropped packets with sparkline charts
- TX Delay Recommendations — Slot-based delay optimization with network role classification (edge/relay/hub/backbone)
- LBT Insights widgets — Channel health, collision risk, noise floor, link quality at a glance
- Time range selector — View stats from 20 minutes to 14 days
- Recent packets — Live feed of incoming traffic with centralized polling (every 3s)
Contacts & Topology
- Interactive map — MapLibre GL with dark theme, smooth animations
- Filter toggles — Solo view for hub nodes, direct neighbors, or traffic-based filtering
- Loop detection — Identifies redundant paths (double-line rendering)
- High-contrast markers — Light fill with dark outline ensures visibility against any overlay
- Path health panel — Health scores, weakest links, and latency estimates
- Mobile node detection — Identifies volatile nodes that appear/disappear frequently
Packets
- Searchable history — Filter by type, route, time range
- Packet details — Hash, path, payload, signal info, duplicates
- Path visualization — Interactive map showing packet route with hop confidence
Settings
- Mode toggle — Forward (repeating) or Monitor (RX only)
- Duty cycle — Enable/disable enforcement
- Radio config — Live frequency, power, SF, bandwidth changes
System & Logs
- System resources — 20-minute rolling CPU and memory utilization chart
- Disk usage — Storage utilization with progress bar
- Temperature — Multi-sensor temperature gauges with threshold coloring
Quick Start
Requirements
- Raspberry Pi (3, 4, 5, or Zero 2 W)
- LoRa module (SX1262 or SX1276 based)
- Raspbian/Raspberry Pi OS (Bookworm recommended)
Installation
# Clone this repository
git clone https://github.com/dmduran12/pymc_console-dist.git pymc_console
cd pymc_console
# Run the installer (requires sudo)
sudo bash manage.sh install
Note: Branch Selection
During installation, you'll be asked to select a pyMC_Repeater branch. Select
dev(the default/recommended option). Thedevbranch contains the latest features and improvements.
The installer will:
- Install all system dependencies (Python, pip, etc.)
- Clone and install pyMC_Repeater as a sibling directory
- Install pyMC_core (the protocol library)
- Deploy the Console web dashboard
- Configure and start the systemd service
After installation, your directory structure looks like:
~/pymc_console/ ← Console (this repo)
~/pyMC_Repeater/ ← Repeater daemon (cloned by installer)
/opt/pymc_repeater/ ← Installed repeater files
/opt/pymc_console/ ← Installed console files
Once complete, access your dashboard at http://<your-pi-ip>:8000
Management Menu
After installation, run sudo bash manage.sh to access the management menu:
┌────────────────────────────────────────────────┐
│ pyMC Console │
│ Status: Running │
├────────────────────────────────────────────────┤
│ install Fresh installation │
│ upgrade Upgrade existing │
│ uninstall Remove everything │
│ status Show versions │
│ logs View live logs │
│ exit Exit │
└────────────────────────────────────────────────┘
Menu Options
- Install — Fresh installation (Full Stack or Console-only)
- Upgrade — Update Console dashboard and/or full pyMC stack
- Uninstall — Remove Console, Repeater, and cloned repos
- Status — Show installed versions (Core, Repeater, Console)
- Logs — Live log output from the repeater
Radio/GPIO Configuration
Radio and GPIO settings are managed by upstream pyMC_Repeater:
cd ~/pyMC_Repeater && sudo ./manage.sh
Upgrading
To update to the latest version:
cd pymc_console
sudo bash manage.sh upgrade
Or use the interactive menu and select Upgrade, then choose:
- Console only — Updates just the web dashboard (quick, safe)
- Full Stack — Updates Console + pulls latest pyMC_Repeater/pyMC_core
Note: You can safely upgrade Console without affecting your Repeater installation. This is useful when you want new dashboard features but your repeater is running stable.
The script auto-updates itself before upgrading, so you always get the latest installer.
Configuration
Radio Settings
Radio configuration is handled by upstream pyMC_Repeater. Use their management script:
cd ~/pyMC_Repeater && sudo ./manage.sh
Or edit the config directly:
radio:
frequency: 927875000 # Frequency in Hz
spreading_factor: 7 # SF7-SF12
bandwidth: 62500 # Bandwidth in Hz
tx_power: 28 # TX power in dBm
coding_rate: 6 # 4/5, 4/6, 4/7, or 4/8
Advanced: DIO2 and DIO3 Configuration
Some LoRa modules require specific DIO pin configurations. These are independent settings that serve different purposes:
- DIO3 (TCXO) — Temperature Compensated Crystal Oscillator control. Set
use_dio3_tcxo: trueif your module has a TCXO that needs DIO3 for voltage supply. - DIO2 (RF Switch) — Antenna RF switch control for TX/RX path switching. Set
use_dio2_rf: trueif your module requires DIO2 to control an external RF switch.
Note: These settings are available on the pyMC_Repeater
devbranch (which uses pyMC_coredev). Themainbranch hardcodessetDio2RfSwitch(False).
Example for modules requiring both:
radio:
use_dio3_tcxo: true # Enable TCXO via DIO3
use_dio2_rf: true # Enable RF switch via DIO2 (dev branch only)
Important: Setting use_dio3_tcxo: true does NOT automatically enable DIO2. They are independent configurations for different hardware features.
Service Management
# Check status
sudo systemctl status pymc-repeater
# Start/stop/restart
sudo systemctl start pymc-repeater
sudo systemctl stop pymc-repeater
sudo systemctl restart pymc-repeater
# View live logs
sudo journalctl -u pymc-repeater -f
Hardware Requirements
- Raspberry Pi (3, 4, 5, or Zero 2 W recommended)
- LoRa Module — SX1262 or SX1276 based (e.g., Waveshare SX1262, LILYGO T3S3)
- SPI Connection — Module connected via SPI with GPIO for reset/busy/DIO1
Tested Modules
- Waveshare SX1262 HAT
- LILYGO T3S3 (via USB serial)
- Ebyte E22 modules
- Heltec LoRa 32
Troubleshooting
"Error 200" or Login Issues
This can occur with older installations or mismatched versions.
To fix:
cd pymc_console
sudo bash manage.sh upgrade
Select Full pyMC Stack upgrade to update pyMC_Repeater and pyMC_core to the latest versions.
Service won't start
# Check for errors
sudo journalctl -u pymc-repeater -n 50
# Verify config syntax
cat /etc/pymc_repeater/config.yaml
No packets being received
- Verify SPI is enabled:
ls /dev/spidev* - Check GPIO configuration in manage.sh → Configure GPIO
- Confirm frequency matches your network
Dashboard not loading
- Verify service is running:
sudo systemctl status pymc-repeater - Check if port 8000 is accessible:
curl http://localhost:8000/api/stats
"Radio presets file not found" warning
This warning during installation is non-fatal. The installer will continue and you can configure radio settings manually. The presets are fetched from an API; if the API is unavailable, common presets are offered as fallback options.
Uninstalling
cd pymc_console
sudo bash manage.sh
Select Uninstall from the menu. This removes:
/opt/pymc_repeater(installation)/etc/pymc_repeater(configuration)/var/log/pymc_repeater(logs)- The systemd service
How It Works
Mesh Topology Analysis
The dashboard reconstructs network topology from packet paths. MeshCore packets contain 2-character hex prefixes representing the route through the mesh:
Packet path: ["FA", "79", "24", "19"]
Origin → Hop1 → Hop2 → Local
The Challenge: Multiple nodes may share the same 2-char prefix (1 in 256 collision chance). The system uses a Viterbi HMM decoder to find the most likely sequence of actual nodes:
Viterbi Path Decoding
Inspired by d40cht/meshcore-connectivity-analysis, the decoder treats path disambiguation as a Hidden Markov Model problem:
- States — All candidate nodes matching each prefix, plus a "ghost" state for unknown nodes
- Priors — Based on recency (recently-seen nodes are more likely) and disambiguation confidence
- Transitions — Physics-based costs using geographic distance and LoRa range constraints
Key principle: Observation beats theory. When edge observations have ≥80% confidence, real-world evidence overrides physics-based costs.
Ghost Node Discovery
When no known candidate is geographically plausible for a prefix, the decoder selects a "ghost" state. These are aggregated to discover unknown repeaters:
- Clustering — Ghost observations grouped by prefix
- Location estimation — Weighted centroid of anchor node midpoints
- Confidence scoring — Based on observation count, common neighbors, and location variance
- UI panel — Shows likely-real ghost nodes with estimated coordinates and adjacent known nodes
Four-Factor Scoring (Pre-Viterbi)
Before Viterbi decoding, candidates are scored using four-factor analysis inspired by meshcore-bot:
- Position (15%) — Where in paths does this prefix typically appear?
- Co-occurrence (15%) — Which prefixes appear adjacent to this one?
- Geographic (35%) — How close is the candidate to anchor points?
- Recency (35%) — How recently was this node seen?
Key techniques:
- Recency scoring — Exponential decay
e^(-hours/12)favors recently-active nodes - Age filtering — Nodes not seen in 14 days are excluded from consideration
- Dual-hop anchoring — Candidates scored by distance to both previous and next hops (a relay must be within RF range of both neighbors)
- Score-weighted redistribution — Appearance counts redistributed proportionally by combined score
The system maintains up to 500,000 packets in session memory for comprehensive topology evidence, with tiered loading (24h initial → 3d → 7d → 14d on demand).
Edge Rendering
Topology edges are rendered with visual cues indicating confidence:
- Line thickness — Scales from 1.5px (5 validations) to 10px (100+ validations)
- Validation threshold — Edges require 5+ certain observations to render
- Certainty conditions — An edge is "certain" when:
- Both endpoints have ≥0.6 confidence (HIGH threshold), OR
- The destination has ≥0.9 confidence (VERY_HIGH threshold), OR
- It's the last hop to local node
- Inclusion threshold — Edges require ≥0.4 confidence (MEDIUM threshold) for topology
- Trace animation — Edges "draw" from point A to B when topology is enabled
- Fade animation — Edges smoothly fade out when topology is disabled
- Loop edges — Redundant paths rendered as parallel double-lines in accent color
3D Terrain & Visualization
The Contacts map supports full 3D terrain rendering:
- Terrain tiles — AWS Terrarium elevation data (free, no API key)
- Hillshading — Visual depth tuned for dark map themes
- 3D arcs — Topology edges and neighbor lines rendered as elevated arcs via deck.gl
- GPU acceleration — deck.gl PathLayer and IconLayer for smooth pan/zoom/tilt
- Automatic draping — All markers and edges align to terrain elevation
Path Visualization
Clicking a packet shows its route on a map with confidence indicators:
- Green — 100% confidence (unique prefix, no collision)
- Yellow — 50-99% confidence (high certainty)
- Orange — 25-49% confidence (medium certainty)
- Red — 1-24% confidence (low certainty)
- Gray/Ghost — Unknown prefix resolved to ghost node
License
MIT — See LICENSE
Credits
Built on the excellent work of:
- RightUp — Creator of pyMC_Repeater, pymc_core, and the MeshCore ecosystem
- pyMC_Repeater — Core repeater daemon for LoRa communication and mesh routing
- pymc_core — Underlying mesh protocol library
- d40cht/meshcore-connectivity-analysis — Viterbi HMM approach for path disambiguation and ghost node discovery
- meshcore-bot — Inspiration for recency scoring and dual-hop anchor disambiguation
- MeshCore — The MeshCore project and community




