Dashboard web FastAPI + Chart.js

- 4 vues : spectre temps reel, historique detections, background, timeline CPS
- API REST : /api/status, /api/spectrum/current, /api/spectrum/difference,
  /api/background, /api/background/spectrum, /api/history, /api/cps/timeline
- Frontend vanilla JS + Chart.js (pas de Node.js, leger pour Pi 4)
- Moniteur modifie pour exporter son etat dans /data/monitor_state.json
  et le CPS dans /data/cps_log.jsonl chaque cycle
- Nouveau conteneur Docker 'web' sur port 8080
- Theme sombre, calibration energie (E = 0.33 + 2.97 * canal)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jacquin Antoine
2026-05-19 13:33:07 +02:00
parent 27ef0727e8
commit 1e0c1a5ea5
22 changed files with 1031 additions and 2 deletions

View File

@ -0,0 +1,45 @@
import json
from fastapi import APIRouter
from app.config import LOG_DIR
router = APIRouter()
@router.get("")
async def list_reports():
"""List all daily detection reports with summaries."""
reports = []
for path in sorted(LOG_DIR.glob("report_*.json"), reverse=True):
try:
with open(path) as f:
data = json.load(f)
iso_count = len(data.get("isotopes_detected", []))
reports.append({
"date": data.get("date", ""),
"live_time_hours": data.get("live_time_hours", 0),
"total_counts": data.get("total_counts", 0),
"cps_mean": data.get("cps_mean", 0),
"background_subtracted": data.get("background_subtracted", False),
"isotope_count": iso_count,
"isotopes": [i["isotope"] for i in data.get("isotopes_detected", [])],
})
except (json.JSONDecodeError, OSError):
continue
return reports
@router.get("/{date}")
async def get_report(date: str):
"""Get a specific day's full report."""
report_path = LOG_DIR / f"report_{date}.json"
if not report_path.exists():
from fastapi import HTTPException
raise HTTPException(status_code=404, detail=f"No report for {date}")
try:
with open(report_path) as f:
data = json.load(f)
except (json.JSONDecodeError, OSError):
raise HTTPException(status_code=500, detail="Report file corrupt")
return data