# Consigne — Collecte météo Open‑Meteo (Prévisions + Historique) ## 1. Objectif Mettre en place une collecte automatique des données Open‑Meteo pour alimenter : - une vue calendrier météo (agrégat journalier), - une vue détail horaire. Le système doit : - récupérer les prévisions sur horizon configurable (`7`, `10`, `16` jours), - stocker un cache JSON brut (debug/audit), - upserter en SQLite sans duplication, - gérer `Europe/Paris` sans décalage de date, - permettre un mode historique (`archive`) optionnel. --- ## 2. Source de données - API prévisions : `https://api.open-meteo.com/v1/forecast` - API historique : `https://api.open-meteo.com/v1/archive` - Doc : `https://open-meteo.com/en/docs` Toujours envoyer : - `timezone=Europe/Paris` - `timeformat=iso8601` --- ## 3. Configuration Créer `config.yml` (et `config.yml.example`) : ```yaml open_meteo: latitude: 45.05 longitude: 3.48 timezone: Europe/Paris forecast_days: 14 cache_dir: data/cache db_path: data/jardin.db wind_strong_kmh: 40 ``` --- ## 4. Requête prévisions (obligatoire) Variables demandées : - `hourly`: `temperature_2m,precipitation_probability,precipitation,relative_humidity_2m,wind_speed_10m,wind_direction_10m,cloud_cover,weather_code` - `daily`: `temperature_2m_max,temperature_2m_min,precipitation_sum,precipitation_probability_max,wind_speed_10m_max,sunrise,sunset,weather_code` Exemple : ```bash curl -s "https://api.open-meteo.com/v1/forecast?latitude=45.05&longitude=3.48&hourly=temperature_2m,precipitation_probability,precipitation,relative_humidity_2m,wind_speed_10m,wind_direction_10m,cloud_cover,weather_code&daily=temperature_2m_max,temperature_2m_min,precipitation_sum,precipitation_probability_max,wind_speed_10m_max,sunrise,sunset,weather_code&timezone=Europe/Paris&timeformat=iso8601&forecast_days=14" ``` Règles : - `forecast_days` doit toujours être explicite. - Lire et logger `hourly_units` et `daily_units`. --- ## 5. Requête archive (optionnelle) Exemple : ```bash curl -s "https://api.open-meteo.com/v1/archive?latitude=45.05&longitude=3.48&start_date=2026-01-01&end_date=2026-01-31&daily=temperature_2m_max,temperature_2m_min,precipitation_sum&hourly=temperature_2m,precipitation,weather_code&timezone=Europe/Paris&timeformat=iso8601" ``` Règles : - exécuter par tranche (mensuelle recommandée), - source marquée `archive`. --- ## 6. Stockage ### 6.1 Cache JSON brut Fichiers à écrire à chaque run : - `data/cache/openmeteo_forecast_.json` - `data/cache/openmeteo_archive_.json` (si archive) Purge : - conserver les `30` derniers fichiers par type. ### 6.2 SQLite normalisée Table `meteo_daily` : - `date TEXT NOT NULL` - `source TEXT NOT NULL` (`forecast` | `archive`) - `tmin_c REAL` - `tmax_c REAL` - `precip_mm REAL` - `precip_prob_max_pct REAL` - `wind_max_kmh REAL` - `sunrise_local TEXT` - `sunset_local TEXT` - `weather_code INTEGER` - `fetched_at TEXT NOT NULL` - `lat REAL NOT NULL` - `lon REAL NOT NULL` - `elevation REAL` - `PRIMARY KEY (date, source)` Table `meteo_hourly` : - `datetime_local TEXT NOT NULL` (`YYYY-MM-DDTHH:MM`) - `source TEXT NOT NULL` (`forecast` | `archive`) - `temp_c REAL` - `precip_mm REAL` - `precip_prob_pct REAL` - `humidity_pct REAL` - `wind_kmh REAL` - `wind_dir_deg REAL` - `cloud_pct REAL` - `weather_code INTEGER` - `fetched_at TEXT NOT NULL` - `lat REAL NOT NULL` - `lon REAL NOT NULL` - `elevation REAL` - `PRIMARY KEY (datetime_local, source)` Index recommandés : - `idx_meteo_daily_date ON meteo_daily(date)` - `idx_meteo_hourly_dt ON meteo_hourly(datetime_local)` --- ## 7. Règles d’upsert - `forecast` : `INSERT ... ON CONFLICT (...) DO UPDATE` (les prévisions évoluent). - `archive` : `INSERT ... ON CONFLICT (...) DO NOTHING` (on fige l’observé). Conflits : - `meteo_daily` : `(date, source)` - `meteo_hourly` : `(datetime_local, source)` --- ## 8. Contrôles qualité obligatoires Après récupération JSON : - `daily.time` contient au moins `7` jours, - longueurs cohérentes des tableaux `hourly`, - pour chaque jour : `tmin_c <= tmax_c`, - présence de `timezone == Europe/Paris`. En cas d’échec : - logger erreur explicite, - conserver le JSON brut, - sortie non fatale avec code d’erreur contrôlé. --- ## 9. Champs attendus pour l’UI ### Vue calendrier (jour) - `date` - `tmin_c`, `tmax_c` - `precip_mm` - `precip_prob_max_pct` - `weather_code` - `sunrise_local`, `sunset_local` - badges calculés : - `gel` si `tmin_c <= 0` - `pluie` si `precip_mm > 0` - `vent_fort` si `wind_max_kmh >= wind_strong_kmh` ### Vue détail (horaire) - `datetime_local` - `temp_c` - `precip_prob_pct` - `precip_mm` - `wind_kmh`, `wind_dir_deg` - `humidity_pct` - `cloud_pct` - `weather_code` --- ## 10. Livrables - `prevision meteo/scripts/fetch_openmeteo_forecast.py` - `prevision meteo/scripts/fetch_openmeteo_archive.py` (optionnel) - `prevision meteo/db/schema.sql` - `prevision meteo/config.yml.example` --- ## 11. Exécution planifiée - Prévisions : tous les jours à `06:10` Europe/Paris. - Archive (optionnel) : tous les jours à `06:20` pour `J-1`. Exemple cron : ```cron 10 6 * * * /usr/bin/python3 /path/prevision\ meteo/scripts/fetch_openmeteo_forecast.py 20 6 * * * /usr/bin/python3 /path/prevision\ meteo/scripts/fetch_openmeteo_archive.py --yesterday ``` --- ## 12. Critères d’acceptation - Une exécution quotidienne met à jour `forecast` sans duplication. - Le calendrier UI affiche au minimum : Tmin/Tmax, pluie, probabilité pluie, weather code. - Le détail horaire est consultable pour un jour donné. - Les dates/heures sont correctes en `Europe/Paris`. - Les caches JSON sont présents et exploitables 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,rain,snowfall,wind_speed_10m,relative_humidity_2m,wind_direction_10m,soil_temperature_0cm,soil_temperature_6cm,soil_moisture_1_to_3cm,soil_moisture_3_to_9cm,sunshine_duration&forecast_days=14