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

38
web/app/routers/cps.py Normal file
View File

@ -0,0 +1,38 @@
from fastapi import APIRouter, Query
from app.config import CPS_LOG_PATH
import json
router = APIRouter()
@router.get("/timeline")
async def get_cps_timeline(hours: int = Query(default=24, ge=1, le=720)):
"""CPS data points for the last N hours."""
if not CPS_LOG_PATH.exists():
return {"data_points": [], "hours": hours}
from datetime import datetime, timedelta
cutoff = datetime.now() - timedelta(hours=hours)
data_points = []
try:
with open(CPS_LOG_PATH) as f:
for line in f:
line = line.strip()
if not line:
continue
try:
entry = json.loads(line)
ts = datetime.fromisoformat(entry["ts"])
if ts >= cutoff:
data_points.append(entry)
except (json.JSONDecodeError, KeyError, ValueError):
continue
except OSError:
return {"data_points": [], "hours": hours}
return {
"hours": hours,
"data_points": data_points,
}