API RTE ecowatt

Ok. tenez voici un code qui je pense devrait marcher. Je n'ai pas pu tester donc vous me direz si ça fonctionne :slight_smile:

il n'y a que 3 lignes à modifier pour adapter cela à votre environnement

const char* ssid =          "**********";
const char* password =      "**********";
#define identificationRTE   "*****************************=="  // ID Client et ID Secret en base 64
  • la première ligne c'est le nom de votre réseau Wi-Fi
  • la deuxième ligne c'est le mot de passe pour y accéder
  • la troisième, c'est ce que vous obtenez d'après la doc que j'ai pu consulter en créant une application dans l'interface web de RTE sous votre compte pour Ecowatt, puis en allant ensuite dans "Mes Applications" et en cliquant sur le bouton "copier en base 64" comme expliqué dans leur tuto vidéo

Puis dans le code j'ai mis l'URL pour la Sandbox (leur environnement de test) mais si vous voulez tester pour de vrai (une requête toutes les 15 minutes seulement) alors vous commentez le premier http.begin (celui de la sandbox) et vous dé-commentez le second.

  // si on veut tester le code sans être gêné par la limite d'un appel toutes les 15 minutes, on utilise la sandbox
   http.begin(client, signalsSandboxURI);

  // si on veut avoir l'information réelle, on utilise la vraie API. On est limité à un appel toutes les 15 minutes
  // http.begin(client, signalsURI);

➜ voici le code

/* ============================================
  KEEP THIS INFORMATION IF YOU USE THIS CODE

  This "API RTE ecowatt" demo code for ESP 32 is placed under the MIT license
  Copyright (c) 2022 J-M-L For the Arduino Forum

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:

  The above copyright notice and this permission notice shall be included in
  all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  THE SOFTWARE.
  ===============================================
*/

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

// *****************************************
// *****************************************
//
//     ! ATTENTION ELEMENTS SECRETS !
//
// *****************************************
// *****************************************

const char* ssid =          "**********";
const char* password =      "**********";
#define identificationRTE   "*****************************************************************************=="  // ID Client et ID Secret en base 64

// *****************************************
// *****************************************


const char * idRTE = "Basic " identificationRTE; // le compilateur se charge de concaténer "Basic " + ID Client et ID Secret en base 64

// le certificat racine (format PEM) de https://digital.iservices.rte-france.com
const char* root_ca = \
                      "-----BEGIN CERTIFICATE-----\n" \
                      "MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G\n" \
                      "A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp\n" \
                      "Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4\n" \
                      "MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG\n" \
                      "A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI\n" \
                      "hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8\n" \
                      "RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT\n" \
                      "gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm\n" \
                      "KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd\n" \
                      "QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ\n" \
                      "XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw\n" \
                      "DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o\n" \
                      "LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU\n" \
                      "RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp\n" \
                      "jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK\n" \
                      "6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX\n" \
                      "mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs\n" \
                      "Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH\n" \
                      "WD9f\n" \
                      "-----END CERTIFICATE-----\n";

const char* oauthURI =          "https://digital.iservices.rte-france.com/token/oauth/";
const char* signalsURI =        "https://digital.iservices.rte-france.com/open_api/ecowatt/v4/signals";
const char* signalsSandboxURI = "https://digital.iservices.rte-france.com/open_api/ecowatt/v4/sandbox/signals";


// obtention d'une transcription des codes d'erreurs spécifique à l'API RTE ou message général
String errorDescription(int code, HTTPClient& http) {
  switch (code) {
    case 401: return "l'authentification a échouée";
    case 403: return "l’appelant n’est pas habilité à appeler la ressource";
    case 413: return "La taille de la réponse de la requête dépasse 7Mo";
    case 414: return "L’URI transmise par l’appelant dépasse 2048 caractères";
    case 429: return "Le nombre d’appel maximum dans un certain laps de temps est dépassé";
    case 509: return "L‘ensemble des requêtes des clients atteint la limite maximale";
    default: break;
  }
  return http.errorToString(code);
}

// effectue une requête. Nécessite une connexion WiFi active.

bool getRTEData() {
  String oauthPayload;
  String signalsPayload;
  int codeReponseHTTP;
  const char* access_token;

  bool requeteOK = true;

  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("WiFI non disponible. Requête impossible");
    return false;
  }

  WiFiClientSecure client;
  HTTPClient http;

  client.setCACert(root_ca);
  http.begin(client, oauthURI);

  // Specify content-type header
  http.addHeader("Content-Type", "application/x-www-form-urlencoded");
  http.addHeader("Authorization", idRTE);

  // Send HTTP POST request
  codeReponseHTTP = http.POST(nullptr, 0);

  if (codeReponseHTTP == HTTP_CODE_OK) {
    oauthPayload = http.getString();
    Serial.println(oauthPayload);

    StaticJsonDocument<192> doc;
    DeserializationError error = deserializeJson(doc, oauthPayload);

    if (error) {
      Serial.print("deserializeJson() failed: ");
      Serial.println(error.c_str());
      access_token = "";
      requeteOK = false;
    } else {
      access_token = doc["access_token"];
      Serial.print("access_token : "); Serial.println(access_token);
    }
  } else {
    Serial.print("erreur HTTP POST: ");
    Serial.println(errorDescription(codeReponseHTTP, http));
    requeteOK = false;
  }

  // on libère les resources
  http.end();

  if (!requeteOK) return false;

  // on a récupéré l'access_token, on peut l'utiliser pour faire notre requête GET sur l'API
  String signalsAutorization = "Bearer ";
  signalsAutorization += String(access_token);

  // si on veut tester le code sans être gêné par la limite d'un appel toutes les 15 minutes, on utilise la sandbox
   http.begin(client, signalsSandboxURI);

  // si on veut avoir l'information réelle, on utilise la vraie API. On est limité à un appel toutes les 15 minutes
  // http.begin(client, signalsURI);

  http.addHeader("Authorization", signalsAutorization.c_str());

  // On envoie la requête HTTP GET
  codeReponseHTTP = http.GET();

  if (codeReponseHTTP == HTTP_CODE_OK) {
    signalsPayload = http.getString();
    Serial.println("----------------------");
    Serial.println("       RTE JSON");
    Serial.println("----------------------\n");
    Serial.println(signalsPayload);
  } else {
    Serial.print("erreur HTTP GET: ");
    Serial.print(codeReponseHTTP);
    Serial.print(" => ");
    Serial.println(http.errorToString(codeReponseHTTP));
    requeteOK = false;
  }
  http.end();
  return requeteOK;
}


void setup() {

  Serial.begin(115200);
  delay(1000);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.write('.');
  }
  Serial.print("\nConnected to WiFi network with IP Address: ");
  Serial.println(WiFi.localIP());

  getRTEData();
}

void loop() {}

Si vous chargez cela sur un ESP32, ouvrez le moniteur série à 115200 bauds vous devriez voir d'abord le JSON pour le token puis le JSON correspondant au message Ecowatt.


dites moi si ça fonctionne quand vous aurez reçu votre ESP.

1 Like