This feature implements persistent storage for all incoming messages, RX log entries, and contacts with configurable retention periods. The system uses a dual-layer architecture to balance real-time UI performance with comprehensive data retention.
Refactor to modular package architecture + new features
Summary
Restructures the single-file meshcore_gui.py (v2.0) into a proper Python package with clear separation of concerns, and adds three major features: message route visualization, a keyword auto-reply bot, and raw LoRa packet decoding with deduplication.
New features
Message route visualization
Click any message to open a route page (/route/{msg_index}) in a new tab showing:
Hop count summary with SNR
Interactive Leaflet map with sender → repeaters → receiver connected by polyline
Detailed route table (name, ID, node type, GPS coordinates per hop)
Pre-filled reply panel with route acknowledgement
Route data is resolved from two sources in priority order:
Path hashes decoded from the raw LoRa packet (via meshcoredecoder)
Stored out_path from the sender's contact record (fallback)
Keyword bot
Built-in auto-reply bot, toggled via 🤖 BOT checkbox in the filter bar.
Configurable keyword → reply template mapping (supports {bot}, {sender}, {snr}, {path} variables)
Listens on configurable channels only
Guards against reply loops (ignores own messages and senders ending in "Bot")
Cooldown between replies (default 5s)
Packet decoding & deduplication
Raw LoRa packets from RX_LOG_DATA are decoded and decrypted using channel keys via meshcoredecoder, extracting message hashes, path hashes and hop data
Dual-strategy deduplication (hash-based from decoded packets + content-based fallback) prevents duplicate messages
Architecture changes
Before (v2.0): Single 700+ line file with all logic intermixed.
After (v5.0): Modular package following SOLID principles:
meshcore_gui/
├── ble/ # BLE communication layer
│ ├── worker.py # Thread lifecycle and connection
│ ├── commands.py # Command execution (SRP)
│ ├── events.py # Event callbacks (SRP)
│ └── packet_decoder.py # LoRa packet decoding
├── core/ # Domain layer
│ ├── models.py # Typed dataclasses (Message, Contact, RouteNode, ...)
│ ├── shared_data.py # Thread-safe shared state
│ └── protocols.py # Protocol interfaces (ISP/DIP)
├── gui/ # Presentation layer
│ ├── dashboard.py # Main page orchestrator
│ ├── route_page.py # Route visualization page
│ └── panels/ # 8 modular UI panels
└── services/ # Business logic
├── bot.py # Keyword auto-reply
├── dedup.py # Message deduplication
└── route_builder.py # Route data construction
Key design decisions:
Protocol interfaces (typing.Protocol) decouple components — consumers depend on narrow interfaces, not the concrete SharedData class
Typed dataclasses replace untyped dicts for Message, Contact, RxLogEntry, RouteNode and DeviceInfo
Services layer keeps business logic (bot, dedup, route building) independent of both BLE and GUI
Dependencies
New dependency: meshcoredecoder (LoRa packet decoder and channel crypto)
bashpip install nicegui meshcore bleak meshcoredecoder
Breaking changes
Entry point is still python meshcore_gui.py <ADDRESS> but now delegates to the package
Channel configuration moved from meshcore_gui.py to meshcore_gui/config.py
--debug-on CLI flag added (replaces editing DEBUG = True in source)
Testing
Tested on Linux (Ubuntu 24.04) with SenseCAP T1000-E over BLE. macOS and Windows remain untested.
- Use BOT_NAME for self-reply detection instead of literal 'BOT'
- Suppress device name in bot message display to avoid duplication
- Add logging filter for NiceGUI deleted-client warning
- Reset local UI state on render() so browser reconnect repopulates
device info, contacts and channels from SharedData without BLE refetch
The ble_observe.py capture tool has been removed from the project.
Updated both NL and EN versions of the BLE explanation document:
- Rewrote intro (section 1) to focus on BLE concepts rather than captures
- Removed sections 8 (workflow), 9 (common mistakes), 10 (sequence diagram)
- Updated conclusion to remove capture references
- Renumbered remaining sections (conclusion → 8, references → 9)
Add English translation of BLE capture workflow explanation
Translated ble_capture_workflow_t_1000_e_uitleg.md to English as
ble_capture_workflow_t_1000_e_explanation.md. This companion document
covers BLE concepts, GATT services, NUS, the ownership problem, and
the capture workflow for the T1000-e on Linux.
Intended to make the documentation accessible to non-Dutch speakers
in the MeshCore community.