Bonjour,
J’ai mis en place un scénario qui permet de récupérer les informations de linky et de les mettres dans un virtuel en passant par leurs API intermédiaire.
Pré-requis :
- Avoir autorisé l’historique des données à 1h dans votre espace client Enedis sur l’onglet historique des mesures (ou avoir renouvellé l’autorisation, nécessaire tous les 1 ans)
- Créer un virtuel contenant les infos suivants
device_code
access_token
token_type
refresh_token
usage_point_id
value
maxPower - Remplacez tous les [Automatismes généraux][EnedisDomoticz] dans le scénario par le nom de vos objets par celui correspondant à votre virtuel
!!! Attention, il faut exécuter l’étape 3 assez rapidement après avoir créé le partage Enedis !!!
- Executer le scénario d’abord avec $code=1
- Aller dans les logs et rentrer le code fournit dans l’url indiqué. Ca va vous demander de vous connecter à Linky et d’accepter de partager vos données de Enedis
- Remettre $code=0 et mettre $firstConnexion=1 et lancer le scénario de nouveau
- Ensuite planifier l’execution de votre scénario une fois par jour en mettant
$code=1;
$firstConnexion=0;
$refreshToken=0;
$getDailyConsumption=0;
$getDailyMaxPower=0;
$getLoadCurve=0;
/*
PDL xxx
*/
//Configuration
$debug=0; // Mettre à 1 si vous voulez interroger les sites de tests / devs
$device_code = ''; // A compléter si vous avez activé votre code avec un autre device code que le dernier généré
$access_token = ''; // A compléter si vous avez un token obtenu autrement
$refresh_token = ''; // A compléter si vous avez un refresh token obtenu autrement
$usage_point_id = ''; // A compléter si vous avez fait l'operation autrement pour indique le PDL
$startDate = date("Y-m-d", time() - 60 * 60 * 24 * 7); // YYYY-MM-DD (J-8 pour récupérer 7 jours de data)
$avantHierDate = date("Y-m-d", time() - 60 * 60 * 24 * 2); // YYYY-MM-DD (Avant-hier)
$endDate = date("Y-m-d", time() - 60 * 60 * 24); // YYYY-MM-DD (Hier)
//Etape du processus
$code=0; // mettre à 1 si vous avez besoin d'un code d'autorisation sinon mettre 0
$firstConnexion=0; // Après validation du code, génère le 1er refresh token
$refreshToken=1; // Permet de renouveller un token après expiration
$getDailyConsumption=1; //Récupération de la consommation Enedis par jour, ne mettre 1 que si étape firstConnexion ou refreshToken
$getDailyMaxPower=1; //Permet d'avoir l'heure à laquelle la consommation était au maximum
$getLoadCurve=1; // Permet d'avoir la consommation par heure (must have, doit être autorisé au préalable sur le site Enedis)
if(!empty($device_code)){
cmd::byString("#[Automatismes généraux][EnedisDomoticz][device_code]#")->event(($device_code));
} else {
$vDevice_code = cmd::byString("#[Automatismes généraux][EnedisDomoticz][device_code]#");
$device_code = $vDevice_code->execCmd();
}
if(!empty($access_token)){
cmd::byString("#[Automatismes généraux][EnedisDomoticz][access_token]#")->event(($access_token));
} else {
$vAccess_token = cmd::byString("#[Automatismes généraux][EnedisDomoticz][access_token]#");
$access_token = $vAccess_token->execCmd();
}
if(!empty($refresh_token)){
cmd::byString("#[Automatismes généraux][EnedisDomoticz][refresh_token]#")->event(($refresh_token));
} else {
$vRefresh_token = cmd::byString("#[Automatismes généraux][EnedisDomoticz][refresh_token]#");
$refresh_token = $vRefresh_token->execCmd();
$scenario->setLog("\n Récupération du token : ".$refresh_token. " \n");
}
if(!empty($usage_point_id)){
cmd::byString("#[Automatismes généraux][EnedisDomoticz][usage_point_id]#")->event(($usage_point_id));
} else {
$vUsage_point_id = cmd::byString("#[Automatismes généraux][EnedisDomoticz][usage_point_id]#");
$usage_point_id = $vUsage_point_id->execCmd();
}
$vToken_type = cmd::byString("#[Automatismes généraux][EnedisDomoticz][token_type]#");
$token_type = $vToken_type->execCmd();
//Site d'autorisation, gestion des tokens etc...
$CLIENT_ID = array("d198fd52-61c0-4b77-8725-06a1ef90da9f", "9c551777-9d1b-447c-9e68-bfe6896ee002");
$LOGIN_BASE_URI = array('enedis.domoticz.russandol.pro', 'opensrcdev.alwaysdata.net');
$API_ENDPOINT_DEVICE_CODE = array('/device/code', '/domoticzlinkyconnect/device/code');
$API_ENDPOINT_DEVICE_TOKEN = array('/device/token', '/domoticzlinkyconnect/device/token');
$API_ENDPOINT_PROXY = array('/device/proxy', '/domoticzlinkyconnect/device/proxy');
$VERIFY_CODE_URI = array("https://" + $LOGIN_BASE_URI[0] + "/device?code=",
"https://" + $LOGIN_BASE_URI[1] + "/domoticzlinkyconnect/device?code=");
//Site d'Enedis
$API_BASE_URI = array("gw.prd.api.enedis.fr", "gw.hml.api.enedis.fr");
$API_ENDPOINT_DATA_CONSUMPTION_LOAD_CURVE = '/v4/metering_data/consumption_load_curve';
$API_ENDPOINT_DATA_CONSUMPTION_MAX_POWER = '/v4/metering_data/daily_consumption_max_power';
$API_ENDPOINT_DATA_DAILY_CONSUMPTION = '/v4/metering_data/daily_consumption';
$API_ENDPOINT_DATA_PRODUCTION_LOAD_CURVE = '/v4/metering_data/production_load_curve';
$API_ENDPOINT_DATA_DAILY_PRODUCTION = '/v4/metering_data/daily_production';
//Initie la variable permettant de relancer le scénario si l'api enedis a été trop appelé
$relaunchScenario = "relaunchScenario";
$scenario->setData($relaunchScenario, '0');
//Obtention du code
if($code){
$scenario->setLog("Première connexion... \n");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$LOGIN_BASE_URI[$debug].$API_ENDPOINT_DEVICE_CODE[$debug]);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "client_id=".$CLIENT_ID[$debug]);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("User-Agent: DomoticzLinkyPlugin/100.0.0","Content-Type: application/x-www-form-urlencoded","Accept: application/json","Host: ".$LOGIN_BASE_URI[$debug].":443"));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$scenario->setLog("Appel de ".$LOGIN_BASE_URI[$debug].$API_ENDPOINT_DEVICE_CODE[$debug]." client_id = ".$CLIENT_ID[$debug]);
$result = json_decode(curl_exec($ch),true) or die("Curl Failed\n");
$scenario->setLog("\n device_code : ".$result['device_code']."\n user_code : ".$result['user_code']."\n url de verification : ".$result['verification_uri']."\n Délai d'expiration (en secondes) : ".$result['expires_in']."\n");
if(empty($device_code) && !empty($result['device_code'])){
$device_code = $result['device_code'];
cmd::byString("#[Automatismes généraux][EnedisDomoticz][device_code]#")->event(($result['device_code']));
}
}
if($firstConnexion){
$scenario->setLog("Demande de token à ".$LOGIN_BASE_URI[$debug].$API_ENDPOINT_DEVICE_CODE[$debug]." avec le device_id : ".$device_code." \n");
$scenario->setLog("Paramètre data envoyés : client_id=".$CLIENT_ID[$debug]."&grant_type=urn:ietf:params:oauth:grant-type:device_code&device_code=".$device_code_value);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$LOGIN_BASE_URI[$debug].$API_ENDPOINT_DEVICE_TOKEN[$debug]);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "client_id=".$CLIENT_ID[$debug]."&grant_type=urn:ietf:params:oauth:grant-type:device_code&device_code=".$device_code);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("User-Agent: DomoticzLinkyPlugin/100.0.0","Content-Type: application/x-www-form-urlencoded","Accept: application/json","Host: ".$LOGIN_BASE_URI[$debug].":443"));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
// Then, after your curl_exec call:
$response = curl_exec($ch);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$header = substr($response, 0, $header_size);
$body = substr($response, $header_size);
curl_close ($ch);
$scenario->setLog("\n Header ...".$header);
$scenario->setLog("\n Body ...".$body);
$result = json_decode($response,true) or die("Curl Failed\n");
$scenario->setLog("\n access_token : ".$result['access_token']."\n token_type : ".$result['token_type']."\n expires_in : ".$result['expires_in']."\n refresh_token : ".$result['refresh_token']."\n usage_point_id : ".$result['usage_point_id']);
if(!empty($result['access_token'])){
cmd::byString("#[Automatismes généraux][EnedisDomoticz][access_token]#")->event(($result['access_token']));
cmd::byString("#[Automatismes généraux][EnedisDomoticz][token_type]#")->event(($result['token_type']));
cmd::byString("#[Automatismes généraux][EnedisDomoticz][refresh_token]#")->event(($result['refresh_token']));
cmd::byString("#[Automatismes généraux][EnedisDomoticz][usage_point_id]#")->event(($result['usage_point_id']));
$access_token = $result['access_token'];
$token_type = $result['token_type'];
}
}
if($refreshToken){
$scenario->setLog("Demande de refresh token à ".$LOGIN_BASE_URI[$debug].$API_ENDPOINT_PROXY[$debug]." \n");
$scenario->setLog("Avec le data : grant_type=refresh_token&client_id=".$CLIENT_ID[$debug]."&refresh_token=".$refresh_token." \n");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$LOGIN_BASE_URI[$debug].$API_ENDPOINT_PROXY[$debug]);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "grant_type=refresh_token&client_id=".$CLIENT_ID[$debug]."&refresh_token=".$refresh_token);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("User-Agent: DomoticzLinkyPlugin/100.0.0","Content-Type: application/x-www-form-urlencoded","Accept: application/json","Host: ".$LOGIN_BASE_URI[$debug].":443"));
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Then, after your curl_exec call:
$response = curl_exec($ch);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$header = substr($response, 0, $header_size);
$body = substr($response, $header_size);
$http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close ($ch);
$scenario->setLog("\n http_status ...".$http_status);
$scenario->setLog("\n Header ...".$header);
$scenario->setLog("\n Body ...".$body);
$result = json_decode($response,true) or die("Curl Failed\n");
$scenario->setLog("\n Refresh - access_token : ".$result['access_token']."\n token_type : ".$result['token_type']."\n expires_in : ".$result['expires_in']."\n refresh_token : ".$result['refresh_token']."\n usage_point_id : ".$result['usage_point_id']);
if(!empty($result['access_token'])){
cmd::byString("#[Automatismes généraux][EnedisDomoticz][access_token]#")->event(($result['access_token']));
cmd::byString("#[Automatismes généraux][EnedisDomoticz][token_type]#")->event(($result['token_type']));
cmd::byString("#[Automatismes généraux][EnedisDomoticz][refresh_token]#")->event(($result['refresh_token']));
cmd::byString("#[Automatismes généraux][EnedisDomoticz][usage_point_id]#")->event(($result['usage_point_id']));
$access_token = $result['access_token'];
$token_type = $result['token_type'];
}
}
if($getDailyConsumption){
$scenario->setLog("Demande de consommation : https://".$API_BASE_URI[$debug].":443".$API_ENDPOINT_DATA_DAILY_CONSUMPTION."?start=".$startDate."&end=".$endDate."&usage_point_id=".$usage_point_id." \n");
$scenario->setLog("Authorization: ".$token_type." ".$access_token,"Accept: application/json \n");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"https://".$API_BASE_URI[$debug].":443".$API_ENDPOINT_DATA_DAILY_CONSUMPTION."?start=".$startDate."&end=".$endDate."&usage_point_id=".$usage_point_id);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Authorization: ".$token_type." ".$access_token,"Accept: application/json"));
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Then, after your curl_exec call:
$response = curl_exec($ch);
$scenario->setLog("\n Response ...".$response);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$header = substr($response, 0, $header_size);
$body = substr($response, $header_size);
$http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close ($ch);
$scenario->setLog("\n http_status ...".$http_status);
$scenario->setLog("\n Header ...".$header);
$scenario->setLog("\n Body ...".$body);
if($http_status == "200"){
$result = json_decode($response,true) or die("Curl Failed\n");
$value = cmd::byString("#[Automatismes généraux][EnedisDomoticz][value]#");
foreach($result['meter_reading']['interval_reading'] as $interval_reading){
//$scenario->setLog("\n value ...".$interval_reading['value']." date ... ".$interval_reading['date']." 12:00:00");
$value->addHistoryValue($interval_reading['value'], $interval_reading['date']." 12:00:00");
}
} else {
//Relancer le scénario dans 3 heures
$scenario->setData($relaunchScenario, '1');
}
}
if($getDailyMaxPower){
$scenario->setLog("Demande de daily max power : https://".$API_BASE_URI[$debug].":443".$API_ENDPOINT_DATA_CONSUMPTION_MAX_POWER."?start=".$avantHierDate."&end=".$endDate."&usage_point_id=".$usage_point_id." \n");
$scenario->setLog("Authorization: ".$token_type." ".$access_token,"Accept: application/json \n");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"https://".$API_BASE_URI[$debug].":443".$API_ENDPOINT_DATA_CONSUMPTION_MAX_POWER."?start=".$avantHierDate."&end=".$endDate."&usage_point_id=".$usage_point_id);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Authorization: ".$token_type." ".$access_token,"Accept: application/json"));
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Then, after your curl_exec call:
$response = curl_exec($ch);
$scenario->setLog("\n Response ...".$response);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$header = substr($response, 0, $header_size);
$body = substr($response, $header_size);
$http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close ($ch);
$scenario->setLog("\n http_status ...".$http_status);
$scenario->setLog("\n Header ...".$header);
$scenario->setLog("\n Body ...".$body);
if($http_status == "200"){
$result = json_decode($response,true) or die("Curl Failed\n");
$value = cmd::byString("#[Automatismes généraux][EnedisDomoticz][maxPower]#");
foreach($result['meter_reading']['interval_reading'] as $interval_reading){
//$scenario->setLog("\n value ...".$interval_reading['value']." date ... ".$interval_reading['date']);
$value->addHistoryValue($interval_reading['value'], $interval_reading['date']);
}
} else {
//Relancer le scénario dans 3 heures
$scenario->setData($relaunchScenario, '1');
}
}
if($getLoadCurve){
$scenario->setLog("Demande de consumption load curve : https://".$API_BASE_URI[$debug].":443".$API_ENDPOINT_DATA_CONSUMPTION_LOAD_CURVE."?start=".$startDate."&end=".$endDate."&usage_point_id=".$usage_point_id." \n");
$scenario->setLog("Authorization: ".$token_type." ".$access_token,"Accept: application/json \n");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"https://".$API_BASE_URI[$debug].":443".$API_ENDPOINT_DATA_CONSUMPTION_LOAD_CURVE."?start=".$startDate."&end=".$endDate."&usage_point_id=".$usage_point_id);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Authorization: ".$token_type." ".$access_token,"Accept: application/json"));
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Then, after your curl_exec call:
$response = curl_exec($ch);
$scenario->setLog("\n Response ...".$response);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$header = substr($response, 0, $header_size);
$body = substr($response, $header_size);
$http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close ($ch);
$scenario->setLog("\n http_status ...".$http_status);
$scenario->setLog("\n Header ...".$header);
$scenario->setLog("\n Body ...".$body);
if($http_status == "200"){
$result = json_decode($response,true) or die("Curl Failed\n");
$value = cmd::byString("#[Automatismes généraux][EnedisDomoticz][value]#");
foreach($result['meter_reading']['interval_reading'] as $interval_reading){
//$scenario->setLog("\n value ...".$interval_reading['value']." date ... ".$interval_reading['date']);
$value->addHistoryValue($interval_reading['value'], $interval_reading['date']);
}
} else {
//Relancer le scénario dans 3 heures
$scenario->setData($relaunchScenario, '1');
}
}
Pour la récupération des valeurs et l'exploitation dans un virtuel :
Récupération en KwH de la veille :
statisticsbetween(#[Automatismes généraux][EnedisDomoticz][value]#,sum,2 days ago 00:00, 2 days ago 23:59)/1000
Récupération en KwH de la semaine en cours
statisticsbetween(#[Automatismes généraux][EnedisDomoticz][value]#,sum,previous monday 00:00:00, Today)/1000
Récupération en KwH de la semaine dernière
statisticsbetween(#[Automatismes généraux][EnedisDomoticz][value]#,sum,monday last week 00:00, sunday last week 23:59)/1000
Récupération en KwH du mois en cours
statisticsbetween(#[Automatismes généraux][EnedisDomoticz][value]#,sum,first day of this month 00:00:00, Today)/1000
Récupération en KwH du mois dernier
statisticsbetween(#[Automatismes généraux][EnedisDomoticz][value]#,sum,first day of last month 00:00:00, last day of last month 23:59:59)/1000
Récupération en KwH de l'année en cours
statisticsbetween(#[Automatismes généraux][EnedisDomoticz][value]#,sum,first day of january this year 00:00:00, Today)/1000
Cordialement,