# 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_<YYYY-MM-DD>.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