Initial release: MeshCore Stats monitoring system

A Python-based monitoring system for MeshCore LoRa mesh networks.
Collects metrics from companion and repeater nodes, stores them in
a SQLite database, and generates a static website with interactive
SVG charts and statistics.

Features:
- Data collection from local companion and remote repeater nodes
- SQLite database with EAV schema for flexible metric storage
- Interactive SVG chart generation with matplotlib
- Static HTML site with day/week/month/year views
- Monthly and yearly statistics reports (HTML, TXT, JSON)
- Light and dark theme support
- Circuit breaker for unreliable LoRa connections
- Battery percentage calculation from 18650 discharge curves
- Automated releases via release-please

Live demo: https://meshcore.jorijn.com
This commit is contained in:
Jorijn Schrijvershof
2026-01-04 19:37:57 +01:00
commit 0f8b0a3492
45 changed files with 9252 additions and 0 deletions
+51
View File
@@ -0,0 +1,51 @@
#!/usr/bin/env python3
"""
Phase 2: Render charts from SQLite database.
Generates SVG charts for day/week/month/year for both companion and repeater
using matplotlib, reading directly from the SQLite metrics database.
"""
import sys
from pathlib import Path
# Add src to path for imports
sys.path.insert(0, str(Path(__file__).parent.parent / "src"))
from meshmon.db import init_db, get_metric_count
from meshmon import log
from meshmon.charts import render_all_charts, save_chart_stats
def main():
"""Render all charts and save statistics."""
# Ensure database is initialized
init_db()
log.info("Rendering charts from database...")
# Check if data exists before rendering
companion_count = get_metric_count("companion")
repeater_count = get_metric_count("repeater")
# Companion charts
if companion_count > 0:
charts, stats = render_all_charts("companion")
save_chart_stats("companion", stats)
log.info(f"Rendered {len(charts)} companion charts ({companion_count} data points)")
else:
log.warn("No companion metrics in database")
# Repeater charts
if repeater_count > 0:
charts, stats = render_all_charts("repeater")
save_chart_stats("repeater", stats)
log.info(f"Rendered {len(charts)} repeater charts ({repeater_count} data points)")
else:
log.warn("No repeater metrics in database")
log.info("Chart rendering complete")
if __name__ == "__main__":
main()