Couleurs EJP avec un ESP 32

[NDLMR : déplacé depuis la discussion Afficheur météo, couleur tempo, conso élec, production solaire, etc)

Bonjour
si ca interesse qq Pour l option EJP j ai réussi a récupère les couleur du jour sur le site hellowatt sans Api avec la technique du web scraping tester sur wokwi simulation wokwi

Bonjour 59jag,

Merci beaucoup pour ton programme.
Au premier essai j'ai eu l'infos du jour en attendant celui de demain pour personnaliser un montage.

L'Arsène.

59jag,

Je ne maitrise pas la technique du web scraping, comment écrirais-tu la ligne pour récupérer le nombre de jours restants sur le site interrogé ?
Mes essais sont infructueux avec cette ligne:
String Nbjoursrestants=find("class="remaining-day-right">",'<');

Merci d'avance.

Arsène.

J ai laisse tomber cette méthode car fallait des fois attendre 20h pour avoir la couleur du jour.
sur https://particulier.edf.fr/fr/accueil/gestion-contrat/options/ejp.html#/ c est plus réactif couleur entre 13 et 15h par contre j ai pas trouver les données voulus dans le html, j ai scanner les requêtes j ai vu que le site web appeler une API https://api-commerce.edf.fr .
donc je suis parti sur cette solution la requête dois contenir la date de debut et la date de fin(max le lendemain) du style:
https://api-commerce.edf.fr/commerce/activet/v1/calendrier-jours-effacement?option=EJP&dateApplicationBorneInf=2024-12-04&dateApplicationBorneSup=2024-12-05&identifiantConsommateur=src

et en reponse:
{"errors":[],"content":{"dateApplicationBorneInf":"2024-12-04","dateApplicationBorneSup":"2024-12-05","dateHeureTraitementActivET":"2024-12-04T18:19:38Z","options":[{"option":"EJP","calendrier":[{"dateApplication":"2024-12-04","statut":"EJP"},{"dateApplication":"2024-12-05","statut":"NON_EJP"}]}]}}

par contre il faut simuler que la requete vienne de https://particulier.edf.fr c est pour ca qu il faut rajouter un header .
mon programme test sur wokwi https://wokwi.com/projects/415196767389650945
donc si tu veux les jours restant faut prendre la date de debut 1 novenbre et date de fin la date du jour et compter le jours ejp
j ai tester ca donne ceci au 04/12/2024

{
  "errors": [],
  "content": {
    "dateApplicationBorneInf": "2024-11-01",
    "dateApplicationBorneSup": "2024-12-05",
    "dateHeureTraitementActivET": "2024-12-04T18:47:57Z",
    "options": [
      {
        "option": "EJP",
        "calendrier": [
          { "dateApplication": "2024-11-01", "statut": "NON_EJP" },
          { "dateApplication": "2024-11-02", "statut": "NON_EJP" },
          { "dateApplication": "2024-11-03", "statut": "NON_EJP" },
          { "dateApplication": "2024-11-04", "statut": "NON_EJP" },
          { "dateApplication": "2024-11-05", "statut": "NON_EJP" },
          { "dateApplication": "2024-11-06", "statut": "NON_EJP" },
          { "dateApplication": "2024-11-07", "statut": "NON_EJP" },
          { "dateApplication": "2024-11-08", "statut": "NON_EJP" },
          { "dateApplication": "2024-11-09", "statut": "NON_EJP" },
          { "dateApplication": "2024-11-10", "statut": "NON_EJP" },
          { "dateApplication": "2024-11-11", "statut": "NON_EJP" },
          { "dateApplication": "2024-11-12", "statut": "NON_EJP" },
          { "dateApplication": "2024-11-13", "statut": "EJP" },
          { "dateApplication": "2024-11-14", "statut": "EJP" },
          { "dateApplication": "2024-11-15", "statut": "NON_EJP" },
          { "dateApplication": "2024-11-16", "statut": "NON_EJP" },
          { "dateApplication": "2024-11-17", "statut": "NON_EJP" },
          { "dateApplication": "2024-11-18", "statut": "NON_EJP" },
          { "dateApplication": "2024-11-19", "statut": "NON_EJP" },
          { "dateApplication": "2024-11-20", "statut": "NON_EJP" },
          { "dateApplication": "2024-11-21", "statut": "NON_EJP" },
          { "dateApplication": "2024-11-22", "statut": "NON_EJP" },
          { "dateApplication": "2024-11-23", "statut": "NON_EJP" },
          { "dateApplication": "2024-11-24", "statut": "NON_EJP" },
          { "dateApplication": "2024-11-25", "statut": "NON_EJP" },
          { "dateApplication": "2024-11-26", "statut": "NON_EJP" },
          { "dateApplication": "2024-11-27", "statut": "NON_EJP" },
          { "dateApplication": "2024-11-28", "statut": "NON_EJP" },
          { "dateApplication": "2024-11-29", "statut": "NON_EJP" },
          { "dateApplication": "2024-11-30", "statut": "NON_EJP" },
          { "dateApplication": "2024-12-01", "statut": "NON_EJP" },
          { "dateApplication": "2024-12-02", "statut": "NON_EJP" },
          { "dateApplication": "2024-12-03", "statut": "EJP" },
          { "dateApplication": "2024-12-04", "statut": "EJP" },
          { "dateApplication": "2024-12-05", "statut": "NON_EJP" }
        ]
      }
    ]
  }
}

voila si ca peux t aider.

59jag,

Merci beaucoup pour ton aide.
Récupérer la valeur du nombre de jours restants en EJP aurait été plus simple que de totaliser puis soustraire.
Je vais faire des essais de ton nouveau programme et y rajouter les lignes pour les calculs.

L'Arsène.

Voici le programme avec le totaliseur de jours EN EJP jusqu'au jour J.


//************************************      Auteur  59Jag       *******************************************************
//Ce programme Arduino pour ESP32 récupère les informations relatives aux jours EJP via une API d'EDF. 
//Vérifie si la date est dans la période EJP (entre le 1er novembre et le 30 avril).
//Écarte automatiquement les week-ends (EJP ne s'applique pas les samedis et dimanches).
//Génère une URL pour interroger l'API EDF avec les dates d'aujourd'hui et de demain.
//Récupère et analyse les informations sur les statuts EJP (jourStatus et demainStatus) via une requête HTTP GET.
//ajout des en-têtes HTTP (HTTP headers) à la requête pour Définir l'origine de la requête, 
//simulant qu'elle provient d'un navigateur accédant au site officiel d'EDF.
//cela donne l'impression que la requête est envoyée depuis la page web du portail EDF https://particulier.edf.fr
//*****************************************************************************************************************************

#include <WiFi.h>
#include <HTTPClient.h>

#define WIFI_SSID "*********************"
#define WIFI_PASSWORD "**************"
#define NTP_SERVER     "pool.ntp.org"
#define UTC_OFFSET     0
#define UTC_OFFSET_DST 0

int mois;
int jour;
int jourSemaine;
int endIndex;
String jourStatus;             
String demainStatus; 
String dateDebut = "2024-11-01";
String calculStatus;
int Total_EJP;
String EJPdatastr; 
String dateCalcul;
int calcul;




void setup() {////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  Serial.begin(115200);
  delay(1000);

  Serial.println(WIFI_SSID);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
 
  Serial.print("Connexion au Wi-Fi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nConnecté au Wi-Fi !");
  Serial.println(WiFi.localIP());
  configTime(UTC_OFFSET, UTC_OFFSET_DST, NTP_SERVER);
  if (mois > 10 || mois < 5){                                                               //ejp seulement entre  1 novembre au 31 Avril
     if (!(jourSemaine == 6)) {                                                             //samedi dimanche pas d ejp (0 = dimanche, ..., 6 = samedi)
       Serial.println("Periode EJP ");        
       recupDataApi(); 
     }else{  
       Serial.println("pas de ejp le WeeekEnd");
      jourStatus="NON_EJP"; 
      demainStatus ="NON_EJP";                                                   
    }                                                               
  }else{
    Serial.println("hors Periode ejp du 1 novembre au 31 Avril");
    jourStatus="NON_EJP"; 
    demainStatus ="NON_EJP"; 
  }
   Serial.println("Resultat");  
   Serial.print("Nombre de jours en EJP: ");
   Serial.println(Total_EJP);
   Serial.println("aujourd hui "+ jourStatus);
   Serial.println("demain " + demainStatus);
} 
////////////////////////////////////////////////////////////////////////////////////////
String extractValue(String source, String startDelimiter, String endDelimiter) {
  int startIndex = source.indexOf(startDelimiter);
  if (startIndex == -1) return "";                              // Délimiteur de début introuvable
  startIndex += startDelimiter.length();                        // Avancer après le délimiteur de début
  int endIndex = source.indexOf(endDelimiter, startIndex);
  if (endIndex == -1) return "";                                // Délimiteur de fin introuvable
  return source.substring(startIndex, endIndex);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
String getFormattedDate(int daysOffset = 0) {
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) {
    Serial.println("impossible de recup time");
    return "";
  }
  // Ajouter un décalage en jours si nécessaire (pour "demain")
  time_t rawTime = mktime(&timeinfo) + (daysOffset * 24 * 3600); // Ajout en secondes
  localtime_r(&rawTime, &timeinfo);                              // Appliquer le décalage
  jour = timeinfo.tm_mday;                                       // Jour du mois (1-31)
  mois = timeinfo.tm_mon + 1;                                    // Mois (0-11, donc +1 pour avoir 1-12)
  jourSemaine = timeinfo.tm_wday;                                // Jour de la semaine (0 = dimanche, ..., 6 = samedi)
  char dateBuffer[11];                                           // AAAA-MM-JJ : 10 caractères + null terminator
  strftime(dateBuffer, sizeof(dateBuffer), "%Y-%m-%d", &timeinfo);
  return String(dateBuffer);
}
///////////////////////////////////////////////////////////////////////////////////////////////
void recupDataApi() {
if (WiFi.status() == WL_CONNECTED) {
String dateJour = getFormattedDate(); // Date d'aujourd'hui au format AAAA-MM-JJ
Serial.println("Date aujourd hui "+ dateJour);
String dateDemain = getFormattedDate(1); // Date de demain au format AAAA-MM-JJ
Serial.println("Date demain "+ dateDemain);
String apiURL = "https://api-commerce.edf.fr/commerce/activet/v1/calendrier-jours-effacement";
apiURL += "?option=EJP";
// apiURL += "&dateApplicationBorneInf=" + dateJour;
// apiURL += "&dateApplicationBorneSup=" + dateDemain;

apiURL += "&dateApplicationBorneInf=" + dateDebut;
apiURL += "&dateApplicationBorneSup=" + dateDemain;


apiURL += "&identifiantConsommateur=src";
Serial.println("URL générée : " + apiURL);
Serial.println(" ");
HTTPClient http;
http.begin(apiURL);
http.addHeader("Accept", "application/json");
http.addHeader("Content-Type", "application/json");
http.addHeader("Origin", "https://particulier.edf.fr");
http.addHeader("Referer", "https://particulier.edf.fr/");
http.addHeader("application-origine-controlee", "site_RC");
http.addHeader("situation-usage", "Jours Effacement");
int httpResponseCode = http.GET();
if (httpResponseCode > 0) {
  String EJPdata = http.getString(); 
  Serial.println("Reponse de l API "); 
  Serial.println(EJPdata);
  jourStatus = extractValue(EJPdata, dateJour + "\",\"statut\":\"", "\"");       // Extraction du status du jour j
  demainStatus = extractValue(EJPdata, dateDemain +"\",\"statut\":\"" , "\"}]"); // Extraction du status du jour j+1

  Total_EJP = 0;                                    // On met à 0 avant calculs
  calcul = 0;                                       

// Extraction des jours EJP

    while (dateCalcul != dateDebut) {               // Tant que l'extraction du status du jour n'est pas celui du début de la saison
     dateCalcul = getFormattedDate(- calcul);       // On retire le jour le jour de la date 
     calcul ++ ;                                    // On incrémente la variable 
    //  Serial.print("Calcul en cours  ");
    //  Serial.println(dateCalcul),"%Y-%m-%d";
    //  delay(500);

       calculStatus = extractValue(EJPdata, dateCalcul + "\",\"statut\":\"", "\""); // Extraction du status jour par jour
       if(calculStatus == "EJP") {                 // Si le status est >EJP
          Total_EJP ++;                            // On incrémente la variable Total EJP
         }

     } // Fin du while


} else {
  Serial.print("Erreur dans la requête HTTP : ");
  Serial.println(httpResponseCode);
}
http.end(); // Fin de la requête
} else {
Serial.println("Wi-Fi non connecté !");
}
}
///////////////////////////////////////////////////////////////////////////////////////////////
void loop() {
//zzzzzzzzzzzzzz
}

Bonne bidouille.
L'Arsène.

dans le html

<div class="remaining-day-right">
                            <span>
                                18 jours
                            </span>
                            <span>
                                jusqu’au 31 mars 2025
                            </span>
                        </div>

String Nbjoursrestants=find("class="remaining-day-right">",'<');
c est presque ca mais quand tu utilise des guillemet entre des guillement faut metre anti slash devant donc ca devient

find("class=\"remaining-day-right\">",'<'); 

puis le caractere apres 18 c est un j donc

 find("class=\"remaining-day-right\">",'j');

Nbjoursrestants sera =

<span>
                                18

puis une petite manip de string pour recup juste 18

Merci pour ton aide.
Je vais faire des essais.
Du fait que le lien https://particulier.edf.fr/fr/accueil/gestion-contrat/options/ejp.html#/ est plus réactif, effectivement les infos du lendemain sont visibles dès le matin, je penche plutôt pour ce dernier. Je peaufine ton programme pour le personnaliser du même genre que pour la tarification TEMPO sur le fil de rollmops67.

L'Arsène.

attention sur le site il est dit:

La mise à jour des données est effectuée quotidiennement entre 13h et 15h, cependant des contraintes d'exploitation peuvent la retarder jusqu'à 5h du matin du jour EJP.

par defaut le lendemain est toujours non_ejp donc a partir de 13h il faut tester plusieurs fois la journée pour voir si le status a changé.

Merci , je vais suivre les infos selon la couleur du jour EJP avant et après 16h00.
A savoir que le site https://www.services-rte.com/cms/open_data/v1/tempo?season="
me donne la couleur du jour dès le matin et que le site donne la situation UNKNOW !

L'Arsène.

Bonjour J M L,

Dans le fil "Afficheur-meteo-couleur-tempo-conso-elec-production-solaire-etc" les derniers posts échangés avec 59jag concernant les infos EJP recueillis sur le net ont dévié du sujet !
Serai ce possible d'ouvrir un nouveau fil intitulé par exp. "Couleurs EJP avec un ESP 32", y déplacer ces derniers posts et y laisser un message de lien entre fils ?
D'avance merci pour la suite.

LArsène57.

À partir de quel N° de post ?

Voilà c'est déplacé

Merci.

Bonjour,

J'ai remarqué que lorsque l'on demande la valeur du jour de la semaine (programme originel), la valeur est décalée ! Pour aujourd'hui samedi la valeur est 5 !
Je n'ai pas encore vérifier un autre jour .

Bon WE.
L'Arsène.

moi j ai 6 pour samedi

Dans programme j'ai rajouter deux lignes Serial.print() pour visualiser la valeur de jourSemaine. Le résultat est 5 pour hier et aujourd'hui !

void setup() {////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  Serial.begin(115200);
  delay(1000);

  Serial.println(WIFI_SSID);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
 
  Serial.print("Connexion au Wi-Fi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nConnecté au Wi-Fi !");
  Serial.println(WiFi.localIP());
  configTime(UTC_OFFSET, UTC_OFFSET_DST, NTP_SERVER);
  if (mois > 10 || mois < 5){                                                               //ejp seulement entre  1 novembre au 31 Avril
     if (!(jourSemaine == 6)) {                                                             //samedi dimanche pas d ejp (0 = dimanche, ..., 6 = samedi)
       Serial.println("Periode EJP ");        
       recupDataApi();
       Serial.print("Le jour de la semaine: ");
       Serial.println(jourSemaine); 
     }else{  
       Serial.println("pas de ejp le WeeekEnd");
      jourStatus="NON_EJP"; 
      demainStatus ="NON_EJP";                                                   
    }                                                               
  }else{
    Serial.println("hors Periode ejp du 1 novembre au 31 Avril");
    jourStatus="NON_EJP"; 
    demainStatus ="NON_EJP"; 
  }
   Serial.println("Resultat");  
   Serial.print("Nombre de jours en EJP: ");
   Serial.println(Total_EJP);
   Serial.println("aujourd hui "+ jourStatus);
   Serial.println("demain " + demainStatus);
} 

Pour la période EJP, une petite erreur, ce n'est pas 31 avril mais 31 mars. :wink:

j ai bien 0 pour dimanche


https://wokwi.com/projects/415196767389650945

Bonjour

#define WIFI_SSID "*********************"
#define WIFI_PASSWORD "**************"
#define NTP_SERVER     "pool.ntp.org"
#define UTC_OFFSET     0
#define UTC_OFFSET_DST 0



  configTime(UTC_OFFSET, UTC_OFFSET_DST, NTP_SERVER);
  if (mois > 10 || mois < 5){                                                               //ejp seulement entre  1 novembre au 31 Avril
     if (!(jourSemaine == 6)) {                                                             //samedi dimanche pas d ejp (0 = dimanche, ..., 6 = samedi)



Les dates/heures EJP utilisées comme références pour les calculs sont probablement basées sur l'heure locale (Europe/Paris), mais le système (de l'ESP32) est mis à l'heure UTC (par configTime()) fournie par le serveur NTP, donc les calculs se font sur des valeurs qui ne sont pas basées sur la même référence.

Mais j'ai peut-être mal interprété tout ça en essayant de recoller des extraits de code provenant de vos différents messages dans ce fil de discussion.

Bonsoir,

Merci pour le retour.
Du fait que j'ai fractionner le programme de base pour mon application (photo) me servant d'un RTC (DS3231) et d'un afficheur, le programme tourne seulement pour afficher la date et heure et chaque heure une mise à jour est demandée.
J'ai donc déplacer les lignes de mise en forme de la date et heure, voila pourquoi le résultat de la valeur du jour de la semaine était fausse !
J'ai réussi de former ces ensemble par une autre méthode et qui est bien adaptée pour informer le RTC (en int).

  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) {
    Serial.println("Non obtension de la date/heure");
    return;
  }
  Serial.println();
  Serial.print("Date optenue : ");
  Serial.println(&timeinfo, "%F");

  char timewDay[3];
  strftime(timewDay, 2, "%wd", &timeinfo);
  JourSemaine = String(timewDay);
  JourSemaine_int = String(timewDay).toInt();  // Conversion du String en int

etc pour les autres valeurs.


La couleur du lendemain clignotait de CYAN vers ROUGE.

L'Arsène.