de mon coté j ai deja integré directement dans mon routeur, en terme de prevision je regarde la prevision du GTI qui est l image la plus fidele du rayonnemnt solaire.
Je n ai pas mis plein de paramètres our calculer le vrai GTI en fonction de l expo de mes panneaux, je l'utilise en relatif avec des seuils empiriques, l avantage par rapport une prevision meteo le GTI est representatif été comme hiver. Donc à minuit je prend en compte la prevision GTI moyenne du lendemain, empiriquement avec mon instalmation de PV je sais que j aurais assez de soleil pour chauffer completement mon CE avec une prévision GTI>450
L api api.open-meteo.com semble etre perenne, elle donne des resultats fiables, une api très bien documentée et simple
Le principe à retenir:
Une seule requête HTTP GET vers Open-Meteo, avec global_tilted_irradiance demandé dans hourly. Pas de clé API, pas d'authentification.
L'API renvoie deux tableaux parallèles (time[] et global_tilted_irradiance[]) qu'on lit par index — l'index i de l'un correspond à l'index i de l'autre.
Deux exploitations distinctes : une valeur instantanée (moyenne autour de l'heure courante) et une prévision (moyenne des heures de jour de demain).
Pour le callcul de la moyenne du lendemain je fais la moyenne entre la première et la derniere valeur GTI non nulle ca permet de determier le "vrai" lever et coucher de sommeil . La durée du jour n'a donc plus d influence sur ma moyenne
Je ne cherche pas à calculer des wh par integration car la valeur depend de trop de paramètres qu'ils faudraient renseigner ( Peut etre faire une integration , avec un parametre d'etalonnage basé sur le relevé des wh produit et du GTI annoncé ? bof)
( J'ai modfifié volonatirement mes coordonnées de localisation)
Code :
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
// =========================================================
// RÉCUPÉRATION DE L'ENSOLEILLEMENT (GTI) VIA OPEN-METEO
// Exemple pédagogique — ESP32
// =========================================================
// --- 1. L'URL DE L'API ---------------------------------------------------
// On interroge Open-Meteo (gratuit, sans clé). Le paramètre clé est
// "global_tilted_irradiance" placé dans le bloc "hourly" : c'est lui qui
// renvoie l'ensoleillement (W/m²) heure par heure, pour un panneau incliné.
// forecast_days=2 => on récupère aujourd'hui ET demain.
const char* METEO_URL =
"http://api.open-meteo.com/v1/forecast"
"?latitude=46.7667&longitude=4.2667"
"¤t_weather=true"
"&hourly=global_tilted_irradiance"
"&timezone=Europe%2FParis"
"&forecast_days=2";
void recupererEnsoleillement() {
if (WiFi.status() != WL_CONNECTED) return;
// --- 2. REQUÊTE HTTP -------------------------------------------------
HTTPClient http;
http.begin(METEO_URL);
int httpCode = http.GET();
if (httpCode != HTTP_CODE_OK) { // 200 attendu
http.end();
return;
}
String payload = http.getString(); // le JSON renvoyé par l'API
http.end();
// --- 3. PARSING DU JSON ----------------------------------------------
// Le buffer doit être assez grand pour 48h de données (2 jours).
DynamicJsonDocument doc(3072);
if (deserializeJson(doc, payload)) return; // échec => on sort
// L'API renvoie deux tableaux parallèles dans "hourly" :
// "time" : ["2026-06-23T00:00", "2026-06-23T01:00", ...]
// "global_tilted_irradiance" : [0, 0, ..., 850, 920, ...]
JsonArray hourlyTime = doc["hourly"]["time"];
JsonArray hourlyGti = doc["hourly"]["global_tilted_irradiance"];
// --- 4. TROUVER L'HEURE COURANTE DANS LE TABLEAU ---------------------
// On lit l'heure actuelle fournie par l'API, puis on cherche l'index
// correspondant dans le tableau horaire.
String currentTimeStr = doc["current_weather"]["time"].as<String>();
int currentHour = currentTimeStr.substring(11, 13).toInt(); // "14" -> 14
int currentHourIndex = 0;
for (int i = 0; i < hourlyTime.size(); i++) {
int hour = hourlyTime[i].as<String>().substring(11, 13).toInt();
if (hour == currentHour) { currentHourIndex = i; break; }
}
// --- 5. GTI "ACTUEL" : moyenne glissante h-1 / h / h+1 ---------------
// On lisse la valeur instantanée sur 3 heures (zéros inclus).
float gtiActuel = 0.0; int n = 0;
for (int offset = -1; offset <= 1; offset++) {
int idx = currentHourIndex + offset;
if (idx >= 0 && idx < hourlyGti.size()) {
gtiActuel += hourlyGti[idx].as<float>();
n++;
}
}
if (n > 0) gtiActuel /= n;
// --- 6. PRÉVISION J+1 : moyenne des heures ensoleillées de demain ----
// On repère le 1er créneau horaire de demain via sa date "YYYY-MM-DD",
// puis on moyenne les 24 valeurs en ignorant les heures de nuit (GTI = 0).
String demain = doc["daily"]["time"][1].as<String>(); // <-- voir note
// (Avec cette URL simplifiée il faut aussi demander &daily=...; sinon
// on peut déduire la date de demain à partir de hourlyTime.)
float gtiPrevuD1 = 0.0; int countJour = 0;
int startDemain = -1;
for (int i = 0; i < hourlyTime.size(); i++) {
if (hourlyTime[i].as<String>().startsWith(demain.substring(0, 10))) {
startDemain = i; break;
}
}
if (startDemain != -1) {
for (int i = 0; i < 24; i++) {
int idx = startDemain + i;
if (idx < (int)hourlyGti.size()) {
float g = hourlyGti[idx].as<float>();
if (g > 0.0) { gtiPrevuD1 += g; countJour++; } // nuit ignorée
}
}
if (countJour > 0) gtiPrevuD1 /= countJour;
}
// --- 7. RÉSULTAT -----------------------------------------------------
Serial.printf("GTI actuel : %.0f W/m2\n", gtiActuel);
Serial.printf("GTI moyen J+1 : %.0f W/m2\n", gtiPrevuD1);
}