dommarion a écrit:Bonjour,
J’ai fait “lier à nouveau”, tout s’est déroulé comme prévu puis cela se termine avec un onglet avec ce message:
{
"reasons" : [ ],
"details" : {
"msgId" : "Id-57563f652e401xxxxxxxxxxx"
}
}
Avec vous cela ?
Bonne semaine
Dommarion
https://mon-compte-particulier.enedis.fr/dataconnect/v1/oauth2/authorize?client_id=xxx&state=yyy&duration=zzz&response_type=code
Bart (eedomus team) a écrit:Bonjour,
nous sommes en attente de la résolution de l'incident qui concerne l'API "Authorize" chez Enedis :
https://datahub-enedis.fr/services-api/ ... -services/
// =====================================
// Paramètres généraux (à personnaliser)
// =====================================
$data = [
"hml" => [
"base_url" => "https://ext.hml.api.enedis.fr",
"client_id" => "XXXXX", //A remplacer par votre clé publique en bac à sable
"secret" => "YYYYY", //A remplacert par votre clé secrète en bac à sable
"prm_cons" => "114532vvvvvvv823",
"prm_prod" => "xxxxxxxxx"
],
"prod" => [
"base_url" => "https://ext.prod.api.enedis.fr",
"client_id" => "xxxxxxxxxxxxxxxxxxxxxxxxxxxx", //A remplacer par votre clé publique en production
"secret" => "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy", //A remplacer par votre clé publique en production
"prm_cons" => "25227496311688" //Indiquer le/les PRM de votre client avec un profil de consommation (soutirage/C5/C5P4)
// "prm_prod" => "xxxx" //Indiquer le/les PRM de votre client avec un profil de production (injection/C5/C5P4)
]
];
define("ENV", "prod"); // Environnement de travail ("prod" ou "hml")
define("BASE_URL", $data[ENV]['base_url']);
define("CLIENT_ID", $data[ENV]['client_id']);
define("SECRET", $data[ENV]['secret']);
define("PRM_CONS", $data[ENV]['prm_cons']);
define("PRM_PROD", $data[ENV]['prm_prod']);
define("START", "2023-11-01"); //Valeur à modifier par la date de début souhaitée
define("END", "2023-11-10"); //Valeur à modifier par la date de fin souhaitée
define("AUTHORIZE", BASE_URL . "/oauth2/v3/token");
/*
********************************************************
***************** PROGRAMME PRINCIPAL ******************
********************************************************
*/
// Récupération du token
define("TOKEN", get_token());
/*
********************************************************
* FONCTIONS *
********************************************************
*/
function get_token() : string {
// Préparation des headers obligatoires
$headers = [
"Content-Type: application/x-www-form-urlencoded; charset=UTF-8",
];
// Préparation des params obligatoires
$data = [
"grant_type" => "client_credentials"
];
// Création d'une ressource cURL
$ch = curl_init(AUTHORIZE);
// Définition des options cURL
curl_setopt($ch, CURLOPT_POST, true); // méthode POST
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); // injection des headers
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); // injection des datas
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // retourne le résultat de la requête au lieu du statut cURL
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); // Basic Auth
curl_setopt($ch, CURLOPT_USERPWD, CLIENT_ID.":".SECRET); // encodage en base64 du credential == base64_encode("username:password")
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // pas de vérification du certificat ssl
curl_setopt($ch, CURLINFO_HEADER_OUT, true); // récupération des entêtes de la requête
var_dump($ch);
// Exécution de la requête POST avec cURL
$response = curl_exec($ch);
$curl_errno = curl_errno($ch);
$curl_error = curl_error($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); // status code de la réponse
$requestHeaders = curl_getinfo($ch, CURLINFO_HEADER_OUT);
// Fermeture de la ressource cURL et libération des ressources systèmes
curl_close($ch);
// Debug (à supprimer en prod)
echo "</br>_____________________________________ AUTHORIZE _______________________________________________</br>";
var_dump("[POST] => " .AUTHORIZE);
echo "</br>_____________________________________ HEADER _______________________________________________</br>";
var_dump($requestHeaders);
print_r($requestHeaders);
// Fin debug
// Gestion des éventuelles erreurs
if ($curl_errno > 0 ) {
display_curl_error($curl_errno, $curl_error);
}
if ($http_code != 200 || !$response) {
display_http_error($http_code, $response);
}
// Récupération du token dans le body de la réponse
$json = json_decode($response);
$access_token = $json->access_token;
// Debug (à supprimer en prod)
echo "</br>___________________________________ TOKEN _____________________________________</br>";
var_dump("[TOKEN] => " .$access_token);
// Fin debug
return $access_token;
}
<?php
// script créé par Connected Object pour eedomus
// les données sont mises à jour 1x par jour entre 7h et 8h
// Enedis nous demande d'être raisonnable et de ne réaliser qu'un appel par jour
// merci de ne pas modifier les valeurs de fréquences et de cache pour le maintien du service
// 29/01/21 : Adaptation API Enedis V4 (Merci Merguez07)
/* 11/11/23 : Adaptation API Enedis V5
API Management
Ancienne plateforme : https://gw.prd.api.enedis.fr
Nouvelle plateforme : https://ext.prod.api.enedis.fr
API d’Authentification
Ancienne plateforme : /v1/oauth2/…
Nouvelle plateforme : /oauth2/v3/…
L’ancienne API d’authentification fonctionnait par le biais d’un stockage du consentement utilisateur au sein même du jeton d’accès.
Cela nécessitait de toujours conserver son jeton d’accès et de le renouveler fréquemment.
Avec la nouvelle API, cela évolue et cette action n’est plus nécessaire : après avoir récupéré le consentement du client, une génération simple de jeton
sera suffisante pour pouvoir avoir accès aux données. La vérification du consentement est conservée : c’est une autre brique du SI qui s’en chargera.
En conséquence, l’obtention d’un jeton d’accès par une simple requête, avec la méthode d’authentification « Client Credential » accompagnée des identifiants
de l’application, suffira pour faire des appels à une API.
curl -X POST https://ext.prod.api.enedis.fr/oauth2/v3/token
--header "Content-Type: application/x-www-form-urlencoded"
--data-raw "grant_type=client_credentials&client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET"
API Metering
Ancienne plateforme : /v2/grid_connection_simulation/…
Nouvelle plateforme : /grid_connection_simulation/v4/…
Données souhaitée Path API Ancienne Plateforme Path API Nouvelle Plateforme
Consommation quotidienne /v4/metering_data/daily_consumption /metering_data_dc/v5/daily_consumption
Puissance maximum de consommation quotidienne /v4/metering_data/daily_consumption_max_power /metering_data_dcmp/v5/daily_consumption_max_power
Consommation par demi-heure /v4/metering_data/consumption_load_curve /metering_data_clc/v5/consumption_load_curve
Production quotidienne /v4/metering_data/daily_production /metering_data_dp/v5/daily_production
Production par demi-heure /v4/metering_data/production_load_curve /metering_data_plc/v5/production_load_curve
Fonctionnellement, l’API ne change pas : le contrat d’interface reste le même que sur l’ancienne plateforme. Un seul élément évolue :
lors des appels, il faut envoyer un header « Accept » valorisé à « Application/json »
API Customers
Données souhaitée Path API Ancienne Plateforme Path API Nouvelle Plateforme
Identité /v3/customers/identity /customers_i/v5/identity
Données de contact /v3/customers/contact_data /customers_cd/v5/contact_data
Données contractuelles /v3/customers/usage_points/contracts /customers_upc/v5/usage_points/contracts
Adresse /v3/customers/usage_points/addresses /customers_upa/v5/usage_points/addresses
Fonctionnellement, l’API ne change pas : le contrat d’interface reste le même que sur l’ancienne plateforme. Un seul élément évolue :
lors des appels, il faut envoyer un header « Accept » valorisé à « Application/json »
*/
function sdk_echo_xml($xml, $usage_point_id, $is_cache)
{
$xml = str_replace("</root><?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<root>", '', $xml);
$xml = str_replace('</root>', "<debug>".$debug."</debug>\n</root>", $xml);
if ($is_cache)
{
$xml = str_replace('<root>', "<root><cached>1</cached>", $xml);
}
else
{
$xml = str_replace('<root>', "<root><cached>0</cached>", $xml);
if ($xml != '' && strpos($xml, 'Invalid_request') === false) // non vide
{
// semble se produire si les données ne sont pas encore disponible
// dans ce cas inutile de mettre en cache
if (strpos($xml, 'no_data_found') === false)
{
saveVariable('cached_xml_'.$usage_point_id, $xml);
saveVariable('last_xml_success_'.$usage_point_id, time());
}
}
}
sdk_header('text/xml');
echo $xml;
}
$api_url = 'https://ext.prod.api.enedis.fr/';
$prev_code = loadVariable('code');
// on reprend le dernier refresh_token seulement s'il correspond au même code
$refresh_token = loadVariable('refresh_token');
$expire_time = loadVariable('expire_time');
// s'il n'a pas expiré, on peut reprendre l'access_token
if (time() < $expire_time)
{
$access_token = loadVariable('access_token');
}
// on a déjà un token d'accés non expiré pour le code demandée
if ($access_token == '' || $_GET['oauth_code'] != '')
{
if ($_GET['oauth_code'] != '')
{
$code = $_GET['oauth_code'];
}
else
{
$code = $prev_code;
}
if (strlen($refresh_token) > 1 && $_GET['oauth_code'] == '')
{
// on peut juste rafraichir le token
$grant_type = 'refresh_token';
$postdata = 'grant_type='.$grant_type.'&refresh_token='.$refresh_token;
}
else
{
if ($code == '')
{
echo "## ERROR: Empty code for grant_type=".$grant_type;
die();
}
// 1ère utilisation aprés obtention du code
$grant_type = 'client_credentials';
$redirect_uri = 'https://secure.eedomus.com/sdk/plugins/enedis_app/callback';
$postdata = 'grant_type='.$grant_type.'&client_id='.$CLIENT_ID.'&client_secret='.$CLIENT_SECRET;
// $postdata = 'grant_type='.$grant_type.'&code='.$code.'&redirect_uri='.($redirect_uri);
}
$url = $api_url.'oauth2/v3/token';
$response = httpQuery($url, 'POST', $postdata, 'enedis_oauth');
//var_dump($url, $postdata, $response);
$params = sdk_json_decode($response);
if ($params['error'] != '')
{
die("Erreur lors de l'authentification:"." [".$params['error'].'] (grant_type='.$grant_type.'),<br>vous pouvez lier à nouveau votre compte en cliquant sur [Lier à nouveau] depuis la configuration de votre périphérique<br><br>'.$response);
}
// on sauvegarde l'access_token et le refresh_token pour les authentifications suivantes
if (isset($params['refresh_token']))
{
$access_token = $params['access_token'];
saveVariable('access_token', $access_token);
saveVariable('refresh_token', $params['refresh_token']);
saveVariable('expire_time', time()+$params['expires_in']);
if ($code != '')
{
saveVariable('code', $code);
}
}
else if ($access_token == '')
{
die("Erreur lors de l'authentification,<br>vous pouvez lier à nouveau votre compte en cliquant sur [Lier à nouveau] depuis la configuration de votre périphérique\n\n".$response);
}
}
if ($_GET['mode'] == 'verify')
{
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>eedomus</title>
<style type="text/css">
body,td,th {
font-family: Arial, Helvetica, sans-serif;
font-size: 14px;
}
</style>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head><?
$usage_point_id = $_GET['usage_point_id'];
saveVariable('last_daily_consumption_'.$usage_point_id, '');
saveVariable('last_consumption_load_curve_'.$usage_point_id, '');
echo '<br>';
echo "Voici votre identifiant de point d'usage Enedis, à copier/coller dans votre périphérique eedomus :";
echo '<br>';
echo '<br>';
echo '<input type="text" name="usage_point_id" value="'.$usage_point_id.'" onclick="this.select();" readonly>';
die();
}
//nouvel headers pour OAuth avec Token sans refresh
$basicAuth = base64_encode(urlencode($client_ID).":".urlencode($client_Secret));
$headers = array("Accept: application/json", "Authorization: Basic ".$basicAuth, '"Content-Type": "application/x-www-form-urlencoded"');
//ancien headers pour OAuth avec Token et refresh
// $headers = array("Accept: application/json", "Authorization: Bearer $access_token");
$usage_point_id = getArg('usage_point_id');
$last_xml_success = loadVariable('last_xml_success_'.$usage_point_id);
if ((date('G') >= 8 && date('G') <= 23 && date('Ymd') != date('Ymd', $last_xml_success))||($_GET['mode'] == 'test'))
{
$is_cache = 0;
// sinon à minuit : "The end date parameter must be earlier than the current date."
$tms = mktime() - 60 * 60;
$today = date('Y-m-d', $tms);
$yesterday = $today;
while ($yesterday == $today)
{
$tms -= 24*60*60;
$yesterday = date('Y-m-d', $tms);
}
$url = $api_url.'customers_upc/v5/usage_points/contracts?usage_point_id='.$usage_point_id;
$response = httpQuery($url, 'GET', NULL, NULL, $headers);
//var_dump($url, $response);
$xml .= jsonToXML($response);
saveVariable('contracts_'.$usage_point_id, $response);
$url = $api_url.'metering_data_dc/v5/daily_consumption?start='.$yesterday.'&end='.$today.'&usage_point_id='.$usage_point_id;
$response = httpQuery($url, 'GET', NULL, NULL, $headers);
saveVariable('response_daily_consumption_'.$usage_point_id, $response);
//var_dump($url, $response);
$xml .= jsonToXML($response);
}
else
{
$is_cache = 1;
$response = loadVariable('contracts_'.$usage_point_id);
$xml .= jsonToXML($response);
$response = loadVariable('response_daily_consumption_'.$usage_point_id);
$xml .= jsonToXML($response);
}
$json = sdk_json_decode($response);
$consumption_date = $json['usage_point'][0]['meter_reading']['end'];
$consumption_value = $json['usage_point'][0]['meter_reading']['interval_reading'][0]['value'];
$last_daily_consumption = loadVariable('last_daily_consumption_'.$usage_point_id);
$daily_consumption_count = 0;
if ($consumption_date != '' && $last_daily_consumption != $consumption_date)
{
$list = getPeriphList($show_notes = false, $filter_device_id = $_GET['eedomus_controller_module_id']);
foreach ($list as $device)
{
if ($device['unit'] == 'Wh')
{
$daily_consumption_controller_module_id = $device['device_id'];
}
}
if ($daily_consumption_controller_module_id > 0)
{
$cur_consumption_time = strtotime($consumption_date);
$cur_consumption_time_txt = date('Y-m-d H:i:s', $cur_consumption_time);
if ($consumption_value !== '')
{
setValue($daily_consumption_controller_module_id, $consumption_value, $verify_value_list = false, $update_only = false, $cur_consumption_time_txt);
saveVariable('last_daily_consumption_'.$usage_point_id, $consumption_date);
$daily_consumption_count++;
}
}
}
//$is_cache=0;
if ($is_cache)
{
$response = loadVariable('consumption_load_curve_'.$usage_point_id);
}
else
{
$url = $api_url.'/metering_data_clc/v5/consumption_load_curve?start='.$yesterday.'&end='.$today.'&usage_point_id='.$usage_point_id;
$response = httpQuery($url, 'GET', NULL, NULL, $headers);
$json = sdk_json_decode($response);
if ($json['error']!=NULL) {
$xml .= jsonToXML($response);
sdk_echo_xml($xml, $usage_point_id, $is_cache);
die;
}
saveVariable('consumption_load_curve_'.$usage_point_id, $response);
}
//var_dump($url, $response);
$xml .= jsonToXML($response);
$json = sdk_json_decode($response);
if ($json['error']!=NULL) {
sdk_echo_xml($xml, $usage_point_id, $is_cache);
die;
}
//var_dump($json);die;
//$consumption_date = $json['usage_point'][0]['meter_reading']['start'];
$consumption_date = $json['meter_reading']['start'];
$last_consumption_load_curve = loadVariable('last_consumption_load_curve_'.$usage_point_id);
$consumption_load_count = 0;
if ($consumption_date != '' && $last_consumption_load_curve != $consumption_date)
{
$list = getPeriphList($show_notes = false, $filter_device_id = $_GET['eedomus_controller_module_id']);
foreach ($list as $device)
{
if ($device['unit'] == 'W')
{
$consumption_load_curve_controller_module_id = $device['device_id'];
}
}
if ($consumption_load_curve_controller_module_id > 0)
{
foreach($json['meter_reading']['interval_reading'] as $reading)
{
//$consumption_rank = $reading['rank'];
//$cur_consumption_time = strtotime($consumption_date) + $consumption_rank * 30 * 60;
//$cur_consumption_time_txt = date('Y-m-d H:i:s', $cur_consumption_time);
$cur_consumption_time_txt = $reading['date'];
if ($consumption_value !== '')
{
$consumption_value = $reading['value'];
setValue($consumption_load_curve_controller_module_id, $consumption_value, $verify_value_list = false, $update_only = false, $cur_consumption_time_txt);
$consumption_load_count++;
}
}
if ($consumption_load_count > 0)
{
saveVariable('last_consumption_load_curve_'.$usage_point_id, $consumption_date);
}
}
}
$debug = "\ndaily_consumption_controller_module_id = $daily_consumption_controller_module_id,
daily_consumption_count = $daily_consumption_count,
consumption_load_curve_controller_module_id = $consumption_load_curve_controller_module_id,
consumption_date = $consumption_date,
consumption_load_count = $consumption_load_count\n";
sdk_echo_xml($xml, $usage_point_id, $is_cache);
?>
"dump de headers"
array(3) {
[0]=>
string(24) "Accept: application/json"
[1]=>
string(121) "Authorization: Basic MGRiZWI3YjMtYTBkOS00Zjg0LWFlMjAtMTgyMmUxZDM1MDkzOmI3ODI3YjNmLTY1ZTItNDU4Ny04MTZhLTkxOTY1ZGYzM2ZmZQ=="
[2]=>
string(30) "Content-Type: application/json"
}
<?xml version="1.0" encoding="ISO-8859-1"?>
<root><cached>0</cached><fault><code>900902</code>
<message>Missing Credentials</message>
<description>Invalid Credentials. Make sure your API invocation call has a header: 'Authorization : Bearer ACCESS_TOKEN' or 'Authorization : Basic ACCESS_TOKEN' or 'apikey: API_KEY'</description>
</fault>
<fault><code>900902</code>
<message>Missing Credentials</message>
<description>Invalid Credentials. Make sure your API invocation call has a header: 'Authorization : Bearer ACCESS_TOKEN' or 'Authorization : Basic ACCESS_TOKEN' or 'apikey: API_KEY'</description>
</fault>
Retour vers Nouveautés & Annonces
Utilisateurs parcourant ce forum : Aucun utilisateur inscrit et 23 invité(s)