maj via codex

This commit is contained in:
2026-02-22 18:34:50 +01:00
parent 20af00d653
commit 55387f4b0e
90 changed files with 9902 additions and 1251 deletions

View File

@@ -2,7 +2,7 @@
from datetime import date, timedelta
from typing import Any, Optional
from fastapi import APIRouter, Depends, Query
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy import text
from sqlmodel import Session
@@ -15,7 +15,7 @@ def _station_daily_summary(session: Session, iso_date: str) -> Optional[dict]:
"""Agrège les mesures horaires d'une journée en résumé."""
rows = session.exec(
text(
"SELECT temp_ext, pluie_mm, vent_kmh, humidite "
"SELECT temp_ext, t_min, t_max, pluie_mm, vent_kmh, humidite "
"FROM meteostation WHERE substr(date_heure, 1, 10) = :d"
),
params={"d": iso_date},
@@ -25,14 +25,20 @@ def _station_daily_summary(session: Session, iso_date: str) -> Optional[dict]:
return None
temps = [r[0] for r in rows if r[0] is not None]
pluies = [r[1] for r in rows if r[1] is not None]
vents = [r[2] for r in rows if r[2] is not None]
hums = [r[3] for r in rows if r[3] is not None]
t_mins = [r[1] for r in rows if r[1] is not None]
t_maxs = [r[2] for r in rows if r[2] is not None]
pluies = [r[3] for r in rows if r[3] is not None]
vents = [r[4] for r in rows if r[4] is not None]
hums = [r[5] for r in rows if r[5] is not None]
min_candidates = temps + t_mins
max_candidates = temps + t_maxs
return {
"t_min": round(min(temps), 1) if temps else None,
"t_max": round(max(temps), 1) if temps else None,
"pluie_mm": round(sum(pluies), 1) if pluies else 0.0,
"t_min": round(min(min_candidates), 1) if min_candidates else None,
"t_max": round(max(max_candidates), 1) if max_candidates else None,
# WeeWX RSS expose souvent une pluie cumulée journalière.
"pluie_mm": round(max(pluies), 1) if pluies else 0.0,
"vent_kmh": round(max(vents), 1) if vents else None,
"humidite": round(sum(hums) / len(hums), 0) if hums else None,
}
@@ -77,22 +83,36 @@ def _open_meteo_day(session: Session, iso_date: str) -> Optional[dict]:
@router.get("/meteo/tableau")
def get_tableau(session: Session = Depends(get_session)) -> dict[str, Any]:
"""Tableau synthétique : 7j passé + J0 + 7j futur."""
def get_tableau(
center_date: Optional[str] = Query(None, description="Date centrale YYYY-MM-DD"),
span: int = Query(7, ge=1, le=31, description="Nombre de jours avant/après la date centrale"),
session: Session = Depends(get_session),
) -> dict[str, Any]:
"""Tableau synthétique centré sur une date, avec historique + prévision."""
today = date.today()
center = today
if center_date:
try:
center = date.fromisoformat(center_date)
except ValueError as exc:
raise HTTPException(status_code=400, detail="center_date invalide (format YYYY-MM-DD)") from exc
rows = []
for delta in range(-7, 8):
d = today + timedelta(days=delta)
for delta in range(-span, span + 1):
d = center + timedelta(days=delta)
iso = d.isoformat()
delta_today = (d - today).days
if delta < 0:
if delta_today < 0:
row_type = "passe"
station = _station_daily_summary(session, iso)
om = None # Pas de prévision pour le passé
elif delta == 0:
om = _open_meteo_day(session, iso)
elif delta_today == 0:
row_type = "aujourd_hui"
station = _station_current_row(session)
station_current = _station_current_row(session) or {}
station_daily = _station_daily_summary(session, iso) or {}
station = {**station_daily, **station_current} or None
om = _open_meteo_day(session, iso)
else:
row_type = "futur"