J'ai les 2 pour ma part.
J'ai réussi à les faire fonctionner (les volets via interrupteur LeGrand), pour ceux qui sont également ennuyé (en attendant que le support résolve le souci pour de bon) il faut remplacer la ligne 193 :
- Code : Tout sélectionner
if (substr($device_type, 0, 2) == 'NB')
par
- Code : Tout sélectionner
if (substr($device_type, 0, 2) == 'NB' || $device_type == 'NLV')
EDIT :
J'ai réussi à faire fonctionner également les scenarios
:
Pour l'utiliser/exploiter :
1. Remplacer le code du script par celui-ci dessous.
2. Mettre en [VAR2] du périphérique le nom du scénario parmi les suivants:
- home
- away
- wake_up
- bedtime
- custom_1
- custom_2
- custom_3
- custom_4
3. Créer une valeur avec pour action :
- Code : Tout sélectionner
&action=[RAW_VALUE]&sceneID=[VAR2]
Et cela fonctionne.
A noter que j'ai ajouté dans mon code :
- les champs Home ID et Bridge ID qui sont très utiles en cas de dépannage/test.
- Un petit libellé en complément des codes, ne pas hésiter à la compléter.
- Récupération de l'état des volets (qui ne fonctionnait plus, mais encore en test, j'ai parfois des erreurs)
NB : Voici le code modifié (@Connected Object : Je te laisse regarder pour éventuellement le mettre comme code officiel lors de l'ajout d'un périphérique) :
- Code : Tout sélectionner
<?php
// script créé par Connected Object pour eedomus
// ce script permet de générer un XML facilement lisible par eedomus
$api_url = 'https://api.netatmo.com';
$CACHE_DURATION = 1; // minutes
// nettoyage d'éventuels codes précédents
if ($_GET['mode'] == 'verify' && $_GET['oauth_code'] != '')
{
saveVariable('access_token', '');
saveVariable('refresh_token', '');
}
// 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é
if ($access_token == '')
{
if (strlen($refresh_token) > 1)
{
// on peut juste rafraichir le token
$grant_type = 'refresh_token';
$postdata = 'grant_type='.$grant_type.'&refresh_token='.$refresh_token;
}
else
{
$code = getArg('oauth_code');
// 1ère utilisation aprés obtention du code
$grant_type = 'authorization_code';
$redirect_uri = 'https://secure.eedomus.com/sdk/plugins/legrand_netatmo/callback.php';
//$scope = 'read_station';
$postdata = 'grant_type='.$grant_type.'&code='.$code.'&redirect_uri='.$redirect_uri; //.'&scope='.$scope;
}
// https://api.netatmo.com/oauth2/token
$response = httpQuery($api_url.'/oauth2/token', 'POST', $postdata, 'legrand_netatmo2_oauth');
$params = sdk_json_decode($response);
if ($params['error'] != '')
{
die("Erreur lors de l'authentification: <b>".$params['error'].'</b> (grant_type='.$grant_type.' '.$params['error_description'].'), vous pouvez lier à nouveau votre compte en cliquant sur [Lier à nouveau] depuis la configuration de votre périphérique'."\n\n".$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']);
saveVariable('code', $code);
}
else if ($access_token == '')
{
die("Erreur lors de l'authentification, vous pouvez lier à nouveau votre compte en cliquant sur [Lier à nouveau] depuis la configuration de votre périphérique\n\n".$response);
}
}
$headers = array("Authorization: Bearer $access_token");
if ($_GET['mode'] == 'verify')
{
$url = $api_url.'/api/homesdata';
$result = httpQuery($url, 'GET', /*$post*/ NULL, 'legrand_netatmo_oauth', $headers);
$ar = sdk_json_decode($result);
//var_dump($url, $ar['body']);
foreach ($ar['body']['homes'] as $p)
{
$html .= 'Domicile : <b>'.$p['name'].'</b><br>'; // ('.$p['id'].')
$home_id = $p['id'];
foreach ($p['modules'] as $m)
{
if ($m['bridge'] != '')
{
$m['name'] = utf8_decode($m['name']);
//$m['name'] = htmlentities($m['name'], ENT_COMPAT, "UTF-8");
// http://www.eteks.com/tips/tip3.html
$m['name'] = str_replace('\u00e0', 'à', $m['name']);
$m['name'] = str_replace('\u00e2', 'â', $m['name']);
$m['name'] = str_replace('\u00e4', 'ä', $m['name']);
$m['name'] = str_replace('\u00e7', 'ç', $m['name']);
$m['name'] = str_replace('\u00e8', 'è', $m['name']);
$m['name'] = str_replace('\u00e9', 'é', $m['name']);
$m['name'] = str_replace('\u00ea', 'ê', $m['name']);
$m['name'] = str_replace('\u00eb', 'ë', $m['name']);
$m['name'] = str_replace('\u00ee', 'î', $m['name']);
$m['name'] = str_replace('\u00ef', 'ï', $m['name']);
$m['name'] = str_replace('\u00f4', 'ô', $m['name']);
$m['name'] = str_replace('\u00f6', 'ö', $m['name']);
$m['name'] = str_replace('\u00f9', 'ù', $m['name']);
$m['name'] = str_replace('\u00fb', 'û', $m['name']);
$m['name'] = str_replace('\u00fc', 'ü', $m['name']);
$clean_module_id = str_replace(':', '', $m['id']);
saveVariable('device_type_'.$clean_module_id, $m['type']);
saveVariable('home_'.$clean_module_id, $home_id);
saveVariable('bridge_'.$clean_module_id, $m['bridge']);
// Traduction code
// Début ajout Vinky
$list = array("NBS","NLP","NLT","NLV","NLF","NLM","NLLF","NLPM","NLFN","NLPT","NBR");
$newlist = array("Volet Battant Bubendorff (NBS)","Prise (NLP)","Interrupteur (NLT)","Volet (NLV)","Lumière (NLF)","Micromodule lumière (NLM)","Ventillation (NLLF)","Prise mobile (NLPM)","Lumière avec Neutre NLFN","Télérupteur (NLPT)","Volet roulant Bubendorff (NBR)");
$m['type'] = str_replace($list,$newlist,$m['type']);
// Fin ajout Vinky
$html .= '<span style="margin-left: 60px;">Périphérique de type <b>"'.$m['type'].'"</b> : <b>'.$m['name'].'</b>, identifiant : <input style="background-color: #DDD;" type="text" value="'.$m['id'].'" onclick="this.select();" readonly></span><br>';
}
}
}
?><!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><?
echo '<br>';
echo "Votre compte <b>Legrand® with Netatmo</b> est maintenant associé à eedomus.";
echo '<br>';
echo '<br>';
echo "Voici vos identifiants domiciles et périphériques :";
echo '<br>';
echo '<br>';
echo '<span><b>Home ID : </b><input style="background-color: #DDD;" type="text" value="'.$home_id.'" onclick="this.select();" readonly></span><br>';
// Début ajout Vinky
$bridge_id = loadVariable('bridge_'.$clean_module_id);
echo '<span><b>Bridge ID : </b><input style="background-color: #DDD;" type="text" value="'.$bridge_id.'" onclick="this.select();" readonly></span><br>';
echo '<br>';
// Fin ajout Vinky
echo $html;
die();
}
$module_id = getArg('module_id');
$clean_module_id = str_replace(':', '', $module_id);
$home_id = loadVariable('home_'.$clean_module_id);
$bridge_id = loadVariable('bridge_'.$clean_module_id);
if ($_GET['action'] != '')
{
$device_type = loadVariable('device_type_'.$clean_module_id);
if ($device_type == 'automation')
{
// -1 = shutter stop
if ($_GET['action'] >= -1 && $_GET['action'] <= 100)
{
// https://portal.developer.legrand.com/docs/services/59e9ad7f8bda9e0b3caea28c/operations/setautomationstatus
$post = '{ "ids": [ "string" ], "level": '.$_GET['action'].' }';
}
else
{
echo "Unsupported action value for automation [".$_GET['action']."]";
die();
}
}
else
{
if ($_GET['action'] > 0)
{
$verb = 'on';
$action_json = 'true';
}
else if ($_GET['action'] <= 0)
{
$verb = 'on';
$action_json = 'false';
}
else
{
echo "Unsupported action value [".$_GET['action']."]";
die();
}
}
$headers[] = 'Content-Type: application/json';
// Bubendorff shutters
// NBG (gateway)
// NBR (roller shutter)
// NBO (orientable shutter)
// NBS (swing shutter)
// roller : target_position
if (substr($device_type, 0, 2) == 'NB' || $device_type == 'NLV') // Modif Vinky
{
$verb = 'target_position';
$action_json = $_GET['action'];
}
else if ($device_type == 'NLF')
{
$more_action = ', "brightness": '.($_GET['action']*1);
}
// scenario :
// Début ajout Vinky
if(isset($_GET['sceneID']))
{
$sceneID = $_GET['sceneID'];
$post = '{"home": { "id": "'.$home_id.'", "modules": [ { "id": "'.$bridge_id.'", "scenario": "'.$sceneID.'"} ] } }';
}
else
// Fin ajout Vinky
{
$post = '{"home": { "id": "'.$home_id.'", "modules": [ { "id": "'.$module_id.'", "'.$verb.'": '.$action_json.', "bridge": "'.$bridge_id.'" '.$more_action.'} ] } }';
}
$url = $api_url.'/api/setstate';
saveVariable('last_xml_success_'.$home_id, 0); // force cache expiration
$result = httpQuery($url, 'POST', $post, 'legrand_netatmo2_oauth', $headers, $use_cookies = false, $ignore_errors = false);
die($result);
}
$last_xml_success = loadVariable('last_xml_success_'.$home_id);
if ((time() - $last_xml_success) / 60 < $CACHE_DURATION)
{
sdk_header('text/xml');
$cached_xml = loadVariable('cached_xml_'.$home_id);
echo $cached_xml;
die();
}
$cached_xml = '<?xml version="1.0" encoding="utf8" ?>';
$cached_xml .= '<legrand>';
$cached_xml .= '<cached>0</cached>';
// Get all home's modules status
$url = $api_url.'/api/homestatus?home_id='.$home_id;
$result = httpQuery($url, 'GET', /*$post*/ NULL, 'legrand_netatmo2_oauth', $headers);
//var_dump($result);
$ar = sdk_json_decode($result);
if ($ar["errors"] != '' || $ar["statusCode"] == 403)
{
// { "statusCode": 403, "message": "Out of call volume quota. Quota will be replenished in 15:09:04." }
// ex: {"errors":[{"userMessage":"","internalMessage":"gateway unreachable","code":41}]}
die($result);
}
foreach ($ar['body']['home']['modules'] as $id => $m)
{
if ($m['on'] !== '' || $m['level'] !== '')
{
if ($m['on'] == true)
{
if ($m['level'] > 0) // dimmers
{
$value = $m['level'];
}
else
{
$value = 100;
}
}
else
{
if ($m['level'] > 0) // automations
{
$value = $m['level'];
}
else
{
$value = 0;
}
}
// Début ajout Vinky
if ($m['type'] == 'NLV' || $m['type'] == 'NBS' ) //Volets
{
$value = $m[2];
}
// Fin ajout Vinky
$clean_module_id = str_replace(':', '', $m['id']);
if ($m['type'] != '')
{
saveVariable('device_type_'.$clean_module_id, $m['type']);
}
// consumption pour la rétrocompatibilité avec l'ancienne API
$xml_content .= '<device id="'.$m['id'].'"><value>'.$value.'</value><type>'.$m['type'].'</type><reachable>'.$m['reachable'].'</reachable><power>'.$m['power'].'</power><consumption>'.$m['power'].'</consumption></device>';
}
}
// permet d'avoir une mise en forme plus lisible dans un browser
sdk_header('text/xml');
// XML de sortie
$cached_xml .= $xml_content;
$cached_xml .= '</legrand>';
echo $cached_xml;
$cached_xml = str_replace('<cached>0</cached>', '<cached>1</cached>', $cached_xml);
if ($xml_content != '') // non vide
{
saveVariable('cached_xml_'.$home_id, $cached_xml);
saveVariable('last_xml_success_'.$home_id, time());
}
?>