"""Météo via Open-Meteo (gratuit, sans clé API).""" from __future__ import annotations from dataclasses import dataclass import httpx from config import config API_URL = "https://api.open-meteo.com/v1/forecast" # Codes WMO -> (libellé court FR, emoji). Suffisant pour un dashboard e-ink. WMO = { 0: ("Dégagé", "☀"), 1: ("Peu nuageux", "🌤"), 2: ("Nuageux", "⛅"), 3: ("Couvert", "☁"), 45: ("Brouillard", "🌫"), 48: ("Brouillard givrant", "🌫"), 51: ("Bruine légère", "🌦"), 53: ("Bruine", "🌦"), 55: ("Bruine forte", "🌦"), 61: ("Pluie faible", "🌧"), 63: ("Pluie", "🌧"), 65: ("Pluie forte", "🌧"), 71: ("Neige faible", "🌨"), 73: ("Neige", "🌨"), 75: ("Neige forte", "🌨"), 80: ("Averses", "🌦"), 81: ("Averses", "🌧"), 82: ("Fortes averses", "⛈"), 95: ("Orage", "⛈"), 96: ("Orage + grêle", "⛈"), 99: ("Orage + grêle", "⛈"), } @dataclass class Weather: ok: bool error: str | None = None temp: float | None = None feels_like: float | None = None label: str = "" icon: str = "" temp_min: float | None = None temp_max: float | None = None precip_prob: int | None = None async def fetch_weather() -> Weather: params = { "latitude": config.weather_lat, "longitude": config.weather_lon, "current": "temperature_2m,apparent_temperature,weather_code", "daily": "temperature_2m_max,temperature_2m_min,precipitation_probability_max", "timezone": config.timezone, "forecast_days": 1, } try: async with httpx.AsyncClient(timeout=15) as client: resp = await client.get(API_URL, params=params) resp.raise_for_status() data = resp.json() except httpx.HTTPError as exc: return Weather(ok=False, error=f"réseau: {exc}") cur = data.get("current", {}) daily = data.get("daily", {}) code = int(cur.get("weather_code", -1)) label, icon = WMO.get(code, ("—", "·")) def _first(key: str): vals = daily.get(key) or [] return vals[0] if vals else None return Weather( ok=True, temp=cur.get("temperature_2m"), feels_like=cur.get("apparent_temperature"), label=label, icon=icon, temp_min=_first("temperature_2m_min"), temp_max=_first("temperature_2m_max"), precip_prob=_first("precipitation_probability_max"), )