# consigne.md — Scraping / Collecte des prévisions météo (Open-Meteo) ## Objectif Mettre en place une collecte **automatique** des données météo de **prévision** (et optionnellement d’historique) depuis **Open-Meteo** pour alimenter un **calendrier météo** dans l’application jardin. Le système doit : - récupérer les **prévisions** (horizon configurable, ex. 7 à 16 jours) - stocker les données dans un format exploitable (JSON + SQLite conseillé) - pouvoir recalculer/mettre à jour chaque jour sans dupliquer inutilement - gérer correctement le **fuseau Europe/Paris** - fournir une structure de données stable pour l’UI (calendrier jour + détail horaire) --- ## Source de données ### API Open-Meteo (sans clé) - Endpoint prévisions : `https://api.open-meteo.com/v1/forecast` - Endpoint historique (optionnel) : `https://api.open-meteo.com/v1/archive` - Format : JSON Variables recommandées (prévisions) : - **hourly** : - `temperature_2m` - `precipitation_probability` - `precipitation` - `relativehumidity_2m` - `windspeed_10m` - `winddirection_10m` - `cloudcover` - `weathercode` - **daily** : - `temperature_2m_max` - `temperature_2m_min` - `precipitation_sum` - `precipitation_probability_max` - `windspeed_10m_max` - `sunrise` - `sunset` - `weathercode` Remarques : - Toujours inclure `timezone=Europe/Paris` - Toujours inclure `timeformat=iso8601` (par défaut) - Conserver l’élévation renvoyée (utile pour contexte jardin) Documentation : - https://open-meteo.com/en/docs --- ## Paramètres de localisation Localisation cible : **Messinhac – Bessamorel** (ou proche). Le système doit permettre : - configuration par **latitude/longitude** - stockage de la localisation dans un fichier `config.yml` (ou `.env`) Exemple : - `latitude: 45.05` - `longitude: 3.48` --- ## Requêtes à implémenter ### 1) Prévisions quotidiennes + horaires (une seule requête) Exemple `curl` (référence) : ```bash curl "https://api.open-meteo.com/v1/forecast?latitude=45.05&longitude=3.48&hourly=temperature_2m,precipitation_probability,precipitation,relativehumidity_2m,windspeed_10m,winddirection_10m,cloudcover,weathercode&daily=temperature_2m_max,temperature_2m_min,precipitation_sum,precipitation_probability_max,windspeed_10m_max,sunrise,sunset,weathercode&timezone=Europe/Paris&forecast_days=16" Règles : forecast_days configurable (7/10/16) si forecast_days absent, Open-Meteo peut renvoyer une valeur par défaut (éviter : toujours préciser) 2) Historique (optionnel) pour “ce qui s’est réellement passé” Exemple curl : curl "https://api.open-meteo.com/v1/archive?latitude=45.05&longitude=3.48&start_date=2026-01-01&end_date=2026-02-21&daily=temperature_2m_max,temperature_2m_min,precipitation_sum&timezone=Europe/Paris" Règles : requête par tranche (ex. mensuelle) pour éviter des payloads trop gros historiser “source=archive” vs “source=forecast” Exigences de stockage (recommandé) 1) JSON brut (cache) Conserver la réponse JSON brute pour audit/debug : data/cache/openmeteo_forecast_.json Conserver un historique minimal des runs (ex. 30 derniers) : rotation ou purge automatique 2) SQLite (données normalisées) Créer 2 tables : Table meteo_daily date (YYYY-MM-DD) PRIMARY KEY tmin_c, tmax_c precip_mm (cumul) precip_prob_max_pct wind_max_kmh sunrise_local, sunset_local weathercode source (forecast|archive) fetched_at (timestamp) lat, lon, elevation Table meteo_hourly datetime_local (YYYY-MM-DDTHH:MM) PRIMARY KEY temp_c precip_mm precip_prob_pct humidity_pct wind_kmh wind_dir_deg cloud_pct weathercode source (forecast|archive) fetched_at lat, lon, elevation Règles d’upsert : si source=forecast : écraser les mêmes timestamps lors d’un nouveau run (les prévisions changent) si source=archive : ne pas écraser si déjà présent (ou écraser seulement si “qualité” supérieure) Normalisation / conversions Open-Meteo renvoie souvent les vitesses en km/h selon endpoint/paramètre, vérifier les unités : lire hourly_units et daily_units dans la réponse stocker les unités (au moins en logging) conserver les dates en timezone Europe/Paris pour affichage calendrier Plan de collecte (cron) Prévisions : fréquence : 1 fois par jour (ex. 06:10 Europe/Paris) stocker fetched_at pour savoir quand la prévision a été téléchargée Historique (optionnel) : 1 fois par jour pour la veille (ex. récupérer “hier” en archive) afin de figer le “réel” ou batch mensuel si besoin de rattrapage Contrôles qualité (obligatoires) Après chaque run : vérifier que daily.time contient au moins 7 jours vérifier cohérence : tmin <= tmax vérifier que les tableaux time et temperature_2m ont la même longueur si champs manquants : log d’erreur + sauvegarde JSON brute + arrêt gracieux Sorties attendues pour l’UI Vue calendrier (jour) Pour chaque jour : date Tmin/Tmax pluie cumulée probabilité max pluie icône/code météo (weathercode) lever/coucher du soleil badges : gel (tmin <= 0), pluie (precip_mm > 0), vent fort (wind_max_kmh > seuil) Vue détail (horaire) Pour une date sélectionnée : liste des heures (locales) température + probabilité pluie + pluie mm + vent + humidité + nuages Notes sur weathercode Open-Meteo utilise un weathercode (WMO). Le projet doit : stocker le code brut fournir une table de mapping côté UI (code -> libellé FR + icône) Livrables scripts/fetch_openmeteo_forecast.py récupère prévisions + écrit cache JSON + upsert SQLite scripts/fetch_openmeteo_archive.py (optionnel) récupère archive sur période + écrit cache JSON + insert SQLite db/schema.sql schéma SQLite (tables + index) config.yml.example latitude/longitude, timezone, forecast_days, chemins Commandes de test Test rapide (curl) curl -s "https://api.open-meteo.com/v1/forecast?latitude=45.05&longitude=3.48&daily=temperature_2m_max,temperature_2m_min,precipitation_sum&timezone=Europe/Paris&forecast_days=7" | head Test avec jq (si installé) curl -s "https://api.open-meteo.com/v1/forecast?latitude=45.05&longitude=3.48&daily=temperature_2m_max,temperature_2m_min,precipitation_sum&timezone=Europe/Paris&forecast_days=7" | jq '.daily' Critères d’acceptation Une exécution quotidienne met à jour les prévisions (forecast) sans dupliquer en base. Le calendrier UI peut afficher au minimum : Tmin/Tmax + pluie + probabilité pluie + code météo. Le détail horaire d’une journée est affichable (température + probabilité pluie). Les données sont en Europe/Paris (pas de décalage d’un jour). Les fichiers JSON de cache existent pour debug. https://api.open-meteo.com/v1/forecast?latitude=45.1412&longitude=4.0736&hourly=temperature_2m,weather_code,cloud_cover,evapotranspiration,precipitation,precipitation_probability&forecast_days=14 https://api.open-meteo.com/v1/forecast?latitude=45.1412&longitude=4.0736&hourly=temperature_2m,weather_code,cloud_cover,evapotranspiration,precipitation,precipitation_probability&forecast_days=14