<?php
// script créé par Patrice Gauchon pour eedomus
// modification authentification par Parabellum
// Version 1.1.0 / 23 novembre 2021
$url_token = 'https://api.groupe-atlantic.com/token';
$url_jwt = 'https://api.groupe-atlantic.com/gacoma/gacomawcfservice/accounts/jwt';
//$url_login = 'https://ha110-1.overkiz.com/enduser-mobile-web/enduserAPI/login';
$url_login = '';
$api_urls = array(
'cozytouch' => 'https://ha110-1.overkiz.com/enduser-mobile-web/enduserAPI/',
'connexoon' => 'https://ha101-1.overkiz.com/enduser-mobile-web/enduserAPI/',
'tahoma' => 'https://www.tahomalink.com/enduser-mobile-web/enduserAPI/',
);
$cache_time = 240; // 4 minutes
$action = getArg('action', false);
$cache = loadVariable('cache');
//------------------------------
// Fonctions
//------------------------------
// Envoi une requête à l'API
function sdk_make_request($path, $method='POST', $data=NULL, $content_type=NULL)
{
global $api_url;
$header = NULL;
if ($content_type == 'json')
{
$header = array('Content-Type: application/json');
}
else if (!empty($data))
{
$data = http_build_query($data);
}
$result = httpQuery($api_url.$path, $method, $data, NULL, $header, true);
return sdk_json_decode($result);
}
// Login
function sdk_login($ignore_cache=false)
{
global $api_url, $api_urls, $url_token, $url_jwt, $url_login;
$bridge = loadVariable('bridge');
if (empty($bridge))
{
$bridge = 'cozytouch';
}
$api_url = $api_urls[$bridge];
$url_login = $api_url.'login';
$last_login = loadVariable('last_login');
if (!$ignore_cache and !empty($last_login) and $last_login > (time()-120))
{
return;
}
//Tentative de login direct avec le jeton en mÈmoire
$headers = array('Content-Type: application/x-www-form-urlencoded');
$data = array('jwt' => loadVariable('jeton'));
$data = http_build_query($data);
$result = httpQuery($url_login, 'POST', $data, null, $headers, true);
$result = sdk_json_decode($result);
if (isset($result['success']) and $result['success'])
{
//echo 'login direct avec succËs: '.'<br/>';
}
else
{
//echo 'login direct KO donc nouvelle authentification'.'<br/>';
//RÈcupÈration access_token
$headers = array('Authorization: Basic czduc0RZZXdWbjVGbVV4UmlYN1pVSUM3ZFI4YTphSDEzOXZmbzA1ZGdqeDJkSFVSQkFTbmhCRW9h');
$data = array(
'grant_type' => 'password',
'username' => loadVariable('username'),
'password' => loadVariable('password'),
);
$data = http_build_query($data);
$result = httpQuery($url_token, 'POST', $data, null, $headers, true);
$result = sdk_json_decode($result);
$atlantic_token = $result['access_token'];
//echo 'atlantic_token:'.$atlantic_token.'<br/>';
//RÈcupÈration nouveau jeton
$headers = array('Authorization: Bearer '.$atlantic_token);
$result = httpQuery($url_jwt, 'GET',null, null, $headers, true);
$jeton = sdk_json_decode($result);
//echo 'jeton:'.$jeton.'<br/>';
saveVariable('jeton', $jeton);
//Login avec nouveau jeton
$headers = array('Content-Type: application/x-www-form-urlencoded');
$data = array('jwt' => $jeton);
$data = http_build_query($data);
$result = httpQuery($url_login, 'POST', $data, null, $headers, true);
//echo 'resultat login: '.$result.'<br/>';
$result = sdk_json_decode($result);
}
if (isset($result['success']) and $result['success'])
{
saveVariable('last_login', time());
}
return $result; //pas sur...voir comment c'Ètait avant
////// code d'origine/////////
//////////////////////////////
//$data = array(
// 'userId' => loadVariable('username'),
// 'userPassword' => loadVariable('password'),
//);
//return sdk_make_request('login', 'POST', $data);
}
// Récupère toutes les pièces
function sdk_get_places($places)
{
$result = array();
foreach ($places as $place)
{
$result[$place['oid']] = $place['label'];
if (!empty($place['subPlaces']))
{
$result += sdk_get_places($place['subPlaces']);
}
}
return $result;
}
// Récupère les pièces et les périphériques
function sdk_get_setup($ignore_cache=false)
{
global $cache, $cache_time;
if (getArg('ignoreCache', false) == 'true')
{
$ignore_cache = true;
}
// retourne la sauvegarde en cache si dernière requête < $cache_time
if (!$ignore_cache and isset($cache['time']) and time() - $cache['time'] < $cache_time
and !empty($cache['devices']) and !empty($cache['places']))
{
return array(
'devices' => $cache['devices'],
'places' => $cache['places'],
'time' => $cache['time'],
);
}
// Login
sdk_login();
// On attend que les commandes en cours se terminent
$count = 0;
while ($count < 10)
{
$result = sdk_make_request('exec/current', 'GET');
if (empty($result))
{
break;
}
usleep(200000);
$count++;
}
// On rafraichit les états
sdk_make_request('setup/devices/states/refresh', 'POST');
// On récupère les périphériques
$setup = sdk_make_request('setup', 'GET');
$devices = array();
foreach ($setup['devices'] as $device)
{
if (!empty($device['placeOID']) and preg_match('%^(
io://.*?/\d*?)$%', $device['deviceURL'], $match))
{
$device_url = $match[1];
$devices[$device_url]['place_oid'] = $device['placeOID'];
foreach ($device['states'] as $state)
{
if (preg_match('%^(core|io):(.*?)State$%', $state['name'], $match2))
{
$devices[$device_url]['states'][$match2[2]] = $state['value'];
}
}
}
}
// On récupère les pièces
$places = sdk_get_places($setup['rootPlace']['subPlaces']);
// Sauvegarde des données en cache
$time = time();
$cache['devices'] = $devices;
$cache['places'] = $places;
$cache['time'] = $time;
saveVariable('cache', $cache);
return array(
'places' => $places,
'devices' => $devices,
'time' => $time,
);
}
// On applique une commande aux périphériques d'une pièce
function sdk_apply_command($place_oid, $commands, $path='exec/apply')
{
global $cache;
$actions = array();
foreach ($cache['devices'] as $device_url => $device)
{
if ($device['place_oid'] == $place_oid)
{
$commands_str = array();
foreach ($commands as $command_name => $value)
{
$commands_str[] = '{"name":"'.$command_name.'","parameters":['.$value.']}';
}
$actions[] = '{"deviceURL":"'.$device_url.'","commands":['.implode($commands_str,',').']}';
}
}
$json = '{"label":"eedomus command","notificationTypeMask":"0","notificationCondition":"NEVER","actions":['.implode($actions,',').']}';
return sdk_make_request($path, 'POST', $json, 'json');
}
// Ecran de login
function sdk_display_login_form($message='', $error='')
{
$bridge = loadVariable('bridge');
echo '<html><head><title>eedomus</title></head><body>';
if (!empty($message)) echo '<p><b>'.$message.'</b></p>';
if (!empty($error)) echo '<p style="color:red"><b>'.$error.'</b></p>';
echo '<form method="post">';
echo 'Type de bridge :<br><select name="bridge">';
echo '<option value="cozytouch" '.($bridge == 'cozytouch' ? 'selected' : '').'>Cozytouch</option>';
echo '<option value="connexoon" '.($bridge == 'connexoon' ? 'selected' : '').'>Connexoon</option>';
echo '<option value="tahoma" '.($bridge == 'tahoma' ? 'selected' : '').'>Tahoma</option></select><br><br>';
echo 'Nom d\'utilisateur Cozytouch :<br><input type="text" name="username" value="'.loadVariable('username').'"><br><br>';
echo 'Mot de passe Cozytouch :<br><input type="password" name="password" value="'.loadVariable('password').'"><br><br>';
echo '<input type="submit" name="submit" value="'.'Connexion'.'">';
echo '</body>';
die;
}
// Ecran des pièces
function sdk_display_places($places)
{
echo '<html><head><title>eedomus</title></head><body><p><b>'.'Liste des Pièces'.' :</b></p>';
foreach ($places as $place_id => $place_label)
{
echo '<p>'.$place_label.'<br><input onclick="this.select();" type="text" size="40" readonly="readonly" value="'.$place_id.'"></p>';
}
echo '</body>';
die;
}
//------------------------------
// Page de configuration
//------------------------------
if (empty($action))
{
if (empty($_POST['submit']))
{
sdk_display_login_form('Veuillez renseigner vos identifiants.');
}
saveVariable('username', $_POST['username']);
saveVariable('password', $_POST['password']);
saveVariable('bridge', $_POST['bridge']);
$result = sdk_login(true);
if (isset($result['error']) and $result['error'] == 'Bad credentials')
{
sdk_display_login_form('', 'Identifiants de connexion incorrects');
}
if (!isset($result['success']) and !$result['success'])
{
sdk_display_login_form('', 'Impossible de se connecter au serveur Cozytouch');
}
$setup = sdk_get_setup(true);
if (!count($setup['devices']))
{
sdk_display_login_form('', 'Aucun périphérique détecté.');
}
sdk_display_places($setup['places']);
}
//------------------------------
// Actions
//------------------------------
// Set Mode
if ($action == 'setMode')
{
sdk_login();
$value = getArg('value');
$place_oid = getArg('place');
$commands = array('setHeatingLevel' => '"'.$value.'"');
sdk_apply_command($place_oid, $commands);
// Reset cache time
$cache['time'] = 0;
saveVariable('cache', $cache);
}
//------------------------------
// Polling (XML)
//------------------------------
if ($action == 'getState')
{
$setup = sdk_get_setup();
$places = $setup['places'];
sdk_header('text/xml');
$xml = '<?xml version="1.0" encoding="ISO-8859-1"?>';
$xml .= '<cozytouch>';
foreach ($places as $place_id => $place_label)
{
$xml .= '<place id="'.$place_id.'" label="'.$place_label.'">';
$xml .= '<devices>';
foreach ($setup['devices'] as $device_url => $device)
{
if ($device['place_oid'] == $place_id)
{
$xml .= '<device url="'.$device_url.'">';
foreach ($device['states'] as $state => $value)
{
$xml .= '<'.$state.'>'.$value.'</'.$state.'>';
}
$xml .= '</device>';
}
}
$xml .= '</devices>';
$xml .= '</place>';
}
$xml .= '<Timestamp>'.$setup['time'].'</Timestamp>';
$xml .= '</cozytouch>';
echo $xml;
}
?>