Automated sync from private repository. Commit: cea15b189fef6d0583664dcf666d994035049f9a
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 7 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
⚠️ Important: Branch Selection
During installation, you'll be asked to select a pyMC_Repeater branch. Select
feat/dmg(the default/recommended option). This branch contains the login/authentication functionality required for the dashboard to work properly.If you select
devormain, you may encounter "error 200" or login issues.
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 Management │
├─────────────────────────────────────┤
│ 1. Start Service │
│ 2. Stop Service │
│ 3. Restart Service │
│ 4. View Logs │
│ 5. Configure Radio │
│ 6. Configure GPIO │
│ 7. Upgrade │
│ 8. Uninstall │
│ 9. Exit │
└─────────────────────────────────────┘
Menu Options
- Start/Stop/Restart — Control the repeater service
- View Logs — Live log output from the repeater
- Configure Radio — Set frequency, power, bandwidth, SF via preset selection
- Configure GPIO — Set up SPI bus and GPIO pins for your LoRa module
- Upgrade — Pull latest updates and reinstall
- Uninstall — Remove the installation completely
Upgrading
To update to the latest version, use the TUI menu:
cd pymc_console
sudo bash manage.sh
Select Upgrade and choose:
- Console UI only — Updates just the web dashboard (recommended, quick)
- Full upgrade — 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.
Configuration
Radio Settings
Use the Configure Radio menu option, or edit directly:
sudo nano /etc/pymc_repeater/config.yaml
Key settings:
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 typically means you installed with the wrong pyMC_Repeater branch. The login functionality is only available in the feat/dmg branch.
To fix:
cd pymc_console
sudo bash manage.sh upgrade
Select Full pyMC Stack upgrade and choose the feat/dmg branch.
Note: When entering the branch name, use
feat/dmg(not justdmg).
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 75,000 packets in session memory (~2.5 days at 30k/day) for comprehensive topology evidence.
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




