![Souriant :-)](./images/smilies/icon_e_smile.gif)
https://api.health.nokia.com/measure?action=getmeas&userid=xxxxxxx
galaksy2001 a écrit:C'est quand même déjà pas mal !
Pour les autres types (76, 77, 88, 93, 94, 95), je comprends pas pourquoi ça ne fonctionne pas car à priori c'est toi qui fixe, à la ligne 92 du script, le nom des types par rapport à leur numéro , il ne peut donc pas y avoir d'erreurs de syntaxes par rapport à ton chemin Xpath
Edith : pour le poids, la valeur "1", c'est de la coquetterie ou c'est un bug ?
<?php
// script créé par Connected Object pour eedomus, basé sur la documentation API Withings: https://developer.withings.com/api-reference
// encodage iso-8859-1 pour les accents
// Modifié dommarion le 16/06/2024 Ajout des mesures d'une montre connectée
// l'appel url est le suivant:
// http://localhost/script/?exec=withings_oauth.php&mode=[MODE]&action=[ACTION]&history=true&userid=[VAR1]&debug=1
// [MODE]=user et [ACTION]=activate ou get ou getdevice ou getgoals ou link ou unlink
// [MODE]=measure et [ACTION]=getmeas ou getactivity ou getintradayactivity ou getworkouts
// [MODE]=heart et [ACTION]=get ou list
// [MODE]=stetho et [ACTION]=get ou list
// [MODE]=sleep et [ACTION]=get ou getsummary
// [MODE]=notify et [ACTION]=get ou list ou revoke ou subscribe ou update
// [MODE]=signature et [ACTION]=getnonce
// [MODE]=rawdata et [ACTION]=activate ou desactivate ou get
// [MODE]=device et [ACTION]=disablefeature ou enablefeature ou updatesimstatus
// Optionnels:
// history=true (pour récupérer l'intégralité de l'historique
// debug=1 (pour activer le mode debug)
//
$mode=array(
'user',
'measure',
'heart',
'stetho',
'sleep',
'notify',
'signature',
'rawdata',
'device',
'verify'
);
$action=array(
'activate',
'desactivate',
'disablefeature',
'enablefeature',
'get',
'getactivity',
'getdevice',
'getgoals',
'getintradayactivity',
'getmeas',
'getnonce',
'getsummary',
'getworkouts',
'link',
'list',
'revoke',
'subscribe',
'unlink',
'update',
'updatesimstatus'
);
$measure_type = array(
1 => 'Weight',
4 => 'Height',
5 => 'Fat_Free_Mass',
6 => 'Fat_Ratio',
8 => 'Fat_Mass_Weight',
9 => 'Diastolic_Blood_Pressure',
10 => 'Systolic_Blood_Pressure',
11 => 'Heart_Pulse',
12 => 'Temperature',
54 => 'SP02',
71 => 'Body_Temperature',
73 => 'Skin_Temperature',
76 => 'Muscle_Mass',
77 => 'Hydration',
88 => 'Bone_Mass',
91 => 'Pulse_Wave_Velocity',
123 => 'VO2_Max',
130 => 'Atrial_Fibrillation',
135 => 'QRS_ECG_Signal',
136 => 'PR_ECG_Signal',
137 => 'QT_ECG_Signal',
138 => 'Corrected_QT_ECG_Signal',
139 => 'Atrial_Fibrillation_PPG',
155 => 'Vascular_Age',
167 => 'Nerve_Health_Score',
168 => 'Extracellular_Water',
169 => 'Intracellular_Water',
170 => 'Visceral_Fat',
174 => 'Fat_Mass',
175 => 'Muscle_Mass_Segments',
196 => 'Electrodermal_activity',
226 => 'Basal_Metabolic_Rate'
);
$api_url = 'https://wbsapi.withings.net/v2/oauth2';
$code = $_GET['oauth_code'];
$userid = $_GET['userid']; // peut être vide
$prev_code = loadVariable('code'.$userid);
$mode_selection = getArg('mode', false, 'measure');
if (!in_array($mode_selection, $mode, false)) {$mode_selection = 'measure';}
$action_selection = getArg('action', false, 'getmeas');
if (!in_array($action_selection, $action, false)) {$action_selection = 'getmeas';}
$history = getArg('history', false, NULL);
$date=date("Y-m-d",time());
$startdate=strtotime(date($date.' 00:00:00'));
$startdateymd=date("Y-m-d",$startdate);
$enddate=time();
$enddateymd=date("Y-m-d",$enddate);
$debug = getArg('debug', false, NULL);
if ($code == '')
{
$code = loadVariable('code'.$userid);
}
if (strlen($prev_code) > 1 && $code == $prev_code)
{
// on reprend le dernier refresh_token seulement s'il correspond au même code
$refresh_token = loadVariable('refresh_token'.$userid);
$expire_time = loadVariable('expire_time'.$userid);
// s'il n'a pas expiré, on peut reprendre l'access_token
if (time() < $expire_time)
{
$access_token = loadVariable('access_token'.$userid);
}
}
// 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 = 'action=requesttoken&grant_type='.$grant_type.'&refresh_token='.$refresh_token;
}
else
{
// 1ère utilisation aprés obtention du code
$grant_type = 'authorization_code';
$redirect_uri = 'https://secure.eedomus.com/sdk/plugins/withings/callback.php';
$postdata = 'action=requesttoken&grant_type='.$grant_type.'&code='.$code.'&redirect_uri='.$redirect_uri;
}
$response = httpQuery($api_url, 'POST', $postdata, 'withings_oauth');
if ($debug == 1) {var_dump($url, $response);}
$json = sdk_json_decode($response);
$params = $json['body'];
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'."\n\n".$response);
}
// on sauvegarde l'access_token et le refresh_token pour les authentifications suivantes
if (isset($params['access_token']) && !isset($params['refresh_token']))
{
$access_token = $params['access_token'];
saveVariable('access_token'.$userid, $access_token);
saveVariable('expire_time'.$userid, time()+$params['expires_in']);
saveVariable('code'.$userid, $code);
}
else if (isset($params['access_token']) && isset($params['refresh_token']))
{
$access_token = $params['access_token'];
saveVariable('access_token'.$userid, $access_token);
saveVariable('refresh_token'.$userid, $params['refresh_token']);
saveVariable('expire_time'.$userid, time()+$params['expires_in']);
if ($code != '')
{
saveVariable('code'.$userid, $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);
}
if ($mode_selection == '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><?
$userid = $params['userid'];
// sauvegarde pour l'utilisateur donné
saveVariable('access_token'.$userid, $access_token);
if ($params['refresh_token'] != '')
{
saveVariable('refresh_token'.$userid, $params['refresh_token']);
}
saveVariable('expire_time'.$userid, time()+$params['expires_in']);
if ($code != '')
{
saveVariable('code'.$userid, $code);
}
echo "<img width='64' src='https://secure.eedomus.com/img/mdm/01/check.png' align='absmiddle'> Votre box eedomus est maintenant autorisée à consulter vos données Withings !";
echo '<br><br>';
echo "Votre <b>Code utilisateur</b> Withings est : ".'<input onclick="this.select();" type="text" size="10" readonly="readonly" value="'.$userid .'" />, vous pouvez le copier-coller dans votre périphérique Withings eedomus.';
die();
}
}
$userid = getArg('userid');
$lastupdate = loadVariable('lastupdate'.$userid);
if ($lastupdate == '') { $lastupdate = 0; } // tout l'historique
if (($mode_selection == 'user') && ($action_selection == 'getdevice'))
{
$url = "https://wbsapi.withings.net/v2/$mode_selection?action=$action_selection&access_token=$access_token";
$response = httpQuery($url, 'GET');
if ($debug == 1) {var_dump($url, $response);}
$json = sdk_json_decode($response);
if ($json['error'] != '')
{
if ($json['status'] == '401') // XRequestID: Not provided invalid_token: The access token provided is invalid
{
// force the use of the refresh token
saveVariable('expire_time'.$userid, 0);
}
die("Erreur lors de l'authentification".": [".$params['error'].'] (access_token = '.$access_token.')<br>, vous pouvez lier à nouveau votre compte en cliquant sur [Lier à nouveau] depuis la configuration de votre périphérique'."\n\n".$response);
}
sdk_header('text/xml');
$new_xml = "<root>";
$has_devices = false;
for($i = 0; $i < sizeof($json['body']['devices']); $i++)
{
if ($i == 0 || $json['body']['devices'][$i]['deviceid'] != $json['body']['devices'][$i-1]['deviceid'])
{
$new_xml .= "<device>";
$new_xml .= "<type>".$json['body']['devices'][$i]['type']."</type>";
$new_xml .= "<battery>".$json['body']['devices'][$i]['battery']."</battery>";
$new_xml .= "<model>".$json['body']['devices'][$i]['model']."</model>";
$new_xml .= "<model_id>".$json['body']['devices'][$i]['model_id']."</model_id>";
$new_xml .= "<deviceid>".$json['body']['devices'][$i]['deviceid']."</deviceid>";
$new_xml .= "<hash_deviceid>".$json['body']['devices'][$i]['hash_deviceid']."</hash_deviceid>";
$new_xml .= "</device>";
$has_devices = true;
}
}
$new_xml .= "<token>".$access_token."</token>";
$new_xml .= "</root>";
if (!$has_devices)
{
saveVariable('lastupdate'.$userid, 0);
}
$last_xml = loadVariable('last_xml_'.$userid);
$last_xml_time = loadVariable('last_xml_time_'.$userid);
if ($last_xml != $new_xml)
{
saveVariable('last_xml_time_'.$userid, time());
saveVariable('last_xml_'.$userid, $new_xml);
if ($last_date != '')
{
saveVariable('lastupdate'.$userid, $last_date);
}
}
echo $new_xml;
}
if (($mode_selection == 'user') && ($action_selection == 'getgoals'))
{
$url = "https://wbsapi.withings.net/v2/$mode_selection?action=$action_selection&access_token=$access_token";
$response = httpQuery($url, 'GET');
if ($debug == 1) {var_dump($url, $response);}
$json = sdk_json_decode($response);
if ($json['error'] != '')
{
if ($json['status'] == '401') // XRequestID: Not provided invalid_token: The access token provided is invalid
{
// force the use of the refresh token
saveVariable('expire_time'.$userid, 0);
}
die("Erreur lors de l'authentification".": [".$params['error'].'] (access_token = '.$access_token.')<br>, vous pouvez lier à nouveau votre compte en cliquant sur [Lier à nouveau] depuis la configuration de votre périphérique'."\n\n".$response);
}
sdk_header('text/xml');
$new_xml = "<root>";
$new_xml .= "<goals>";
$has_goals = false;
if (sizeof($json['body']['goals'])>0)
{
$new_xml .= "<steps>".$json['body']['goals']['steps']."</steps>";
$new_xml .= "<sleep>".$json['body']['goals']['sleep']."</sleep>";
$new_xml .= "<weight>";
$new_xml .= "<value>".$json['body']['goals']['weight']['value']."</value>";
$new_xml .= "<unit>".$json['body']['goals']['weight']['unit']."</unit>";
$new_xml .= "</weight>";
$has_goals = true;
}
$new_xml .= "</goals>";
$new_xml .= "<token>".$access_token."</token>";
$new_xml .= "</root>";
if (!$has_devices)
{
saveVariable('lastupdate'.$userid, 0);
}
$last_xml = loadVariable('last_xml_'.$userid);
$last_xml_time = loadVariable('last_xml_time_'.$userid);
if ($last_xml != $new_xml)
{
saveVariable('last_xml_time_'.$userid, time());
saveVariable('last_xml_'.$userid, $new_xml);
if ($last_date != '')
{
saveVariable('lastupdate'.$userid, $last_date);
}
}
echo $new_xml;
}
if (($mode_selection == 'measure') && ($action_selection == 'getactivity'))
{
if (isset($history))
{ $url = "https://wbsapi.withings.net/v2/$mode_selection?action=$action_selection&access_token=$access_token&lastupdate=0";}
else
{ $url = "https://wbsapi.withings.net/v2/$mode_selection?action=$action_selection&access_token=$access_token&startdateymd=$startdateymd&enddateymd=$enddateymd";}
$response = httpQuery($url, 'GET');
if ($debug == 1) {var_dump($url, $response);}
$json = sdk_json_decode($response);
if ($json['error'] != '')
{
if ($json['status'] == '401') // XRequestID: Not provided invalid_token: The access token provided is invalid
{
// force the use of the refresh token
saveVariable('expire_time'.$userid, 0);
}
die("Erreur lors de l'authentification".": [".$params['error'].'] (access_token = '.$access_token.')<br>, vous pouvez lier à nouveau votre compte en cliquant sur [Lier à nouveau] depuis la configuration de votre périphérique'."\n\n".$response);
}
sdk_header('text/xml');
$new_xml = "<root>";
$has_activities = false;
for($i = 0; $i < sizeof($json['body']['activities']); $i++)
{
if ($i == 0 || $json['body']['activities'][$i]['date'] != $json['body']['activities'][$i-1]['date'])
{
$new_xml .= "<activity>";
$new_xml .= "<date>".$json['body']['activities'][$i]['date']."</date>";
$new_xml .= "<steps>".$json['body']['activities'][$i]['steps']."</steps>";
$new_xml .= "<distance>".$json['body']['activities'][$i]['distance']."</distance>";
$new_xml .= "<calories>".$json['body']['activities'][$i]['calories']."</calories>";
$new_xml .= "<model>".$json['body']['activities'][$i]['model']."</model>";
$new_xml .= "</activity>";
$last_date = $json['body']['activities'][$i]['modified'];
$has_activities = true;
}
}
$new_xml .= "<token>".$access_token."</token>";
$new_xml .= "</root>";
if (!$has_activities)
{
saveVariable('lastupdate'.$userid, 0);
}
$last_xml = loadVariable('last_xml_'.$userid);
$last_xml_time = loadVariable('last_xml_time_'.$userid);
if ($last_xml != $new_xml)
{
saveVariable('last_xml_time_'.$userid, time());
saveVariable('last_xml_'.$userid, $new_xml);
if ($last_date != '')
{
saveVariable('lastupdate'.$userid, $last_date);
}
}
echo $new_xml;
}
if (($mode_selection == 'measure') && ($action_selection == 'getintradayactivity'))
{
if (isset($history))
{ $startdate=$enddate-3*24*60*60;
$url = "https://wbsapi.withings.net/v2/$mode_selection?action=$action_selection&access_token=$access_token&startdate=$startdate&enddate=$enddate";}
else
{ $url = "https://wbsapi.withings.net/v2/$mode_selection?action=$action_selection&access_token=$access_token&startdateymd=$startdateymd&enddateymd=$enddateymd";}
$response = httpQuery($url, 'GET');
if ($debug == 1) {var_dump($url, $response);}
$json = sdk_json_decode($response);
if ($json['error'] != '')
{
if ($json['status'] == '401') // XRequestID: Not provided invalid_token: The access token provided is invalid
{
// force the use of the refresh token
saveVariable('expire_time'.$userid, 0);
}
die("Erreur lors de l'authentification".": [".$params['error'].'] (access_token = '.$access_token.')<br>, vous pouvez lier à nouveau votre compte en cliquant sur [Lier à nouveau] depuis la configuration de votre périphérique'."\n\n".$response);
}
sdk_header('text/xml');
$new_xml = "<root>";
$has_intradayactivities = false;
if (count($json['body']['series'])>0)
{
$new_xml .="<intradayactivity>";
foreach ($json['body']['series'] as $key=>$value)
{
$new_xml .= "<$key>";
foreach ($value as $key2=>$value2)
{
$new_xml .= "<$key2>".$value2."</$key2>";
}
$new_xml .= "</$key>";
}
$new_xml .="</intradayactivity>";
$has_intradayactivities = true;
}
$new_xml .= "<token>".$access_token."</token>";
$new_xml .= "</root>";
if (!$has_intradayactivities)
{
saveVariable('lastupdate'.$userid, 0);
}
$last_xml = loadVariable('last_xml_'.$userid);
$last_xml_time = loadVariable('last_xml_time_'.$userid);
if ($last_xml != $new_xml)
{
saveVariable('last_xml_time_'.$userid, time());
saveVariable('last_xml_'.$userid, $new_xml);
if ($last_date != '')
{
saveVariable('lastupdate'.$userid, $last_date);
}
}
echo $new_xml;
}
if (($mode_selection == 'measure') && ($action_selection == 'getworkouts'))
{
if (isset($history))
{ $url = "https://wbsapi.withings.net/v2/$mode_selection?action=$action_selection&access_token=$access_token&lastupdate=0";}
else
{ $url = "https://wbsapi.withings.net/v2/$mode_selection?action=$action_selection&access_token=$access_token&startdateymd=$startdateymd&enddateymd=$enddateymd";}
$response = httpQuery($url, 'GET');
if ($debug == 1) {var_dump($url, $response);}
$json = sdk_json_decode($response);
if ($json['error'] != '')
{
if ($json['status'] == '401') // XRequestID: Not provided invalid_token: The access token provided is invalid
{
// force the use of the refresh token
saveVariable('expire_time'.$userid, 0);
}
die("Erreur lors de l'authentification".": [".$params['error'].'] (access_token = '.$access_token.')<br>, vous pouvez lier à nouveau votre compte en cliquant sur [Lier à nouveau] depuis la configuration de votre périphérique'."\n\n".$response);
}
sdk_header('text/xml');
$new_xml = "<root>";
$has_workouts = false;
for($i = 0; $i < sizeof($json['body']['series']); $i++)
{
if ($i == 0 || $json['body']['series'][$i]['date'] != $json['body']['series'][$i-1]['date'])
{
$new_xml .= "<workout>";
$new_xml .= "<date>".$json['body']['series'][$i]['date']."</date>";
$new_xml .= "<deviceid>".$json['body']['series'][$i]['deviceid']."</deviceid>";
$new_xml .= "<calories>".$json['body']['series'][$i]['data']['calories']."</calories>";
$new_xml .= "<intensity>".$json['body']['series'][$i]['data']['intensity']."</intensity>";
$new_xml .= "<steps>".$json['body']['series'][$i]['data']['steps']."</steps>";
$new_xml .= "<distance>".$json['body']['series'][$i]['data']['distance']."</distance>";
$new_xml .= "</workout>";
$last_date = $json['body']['series'][$i]['modified'];
$has_workouts = true;
}
}
$new_xml .= "<token>".$access_token."</token>";
$new_xml .= "</root>";
if (!$has_workouts)
{
saveVariable('lastupdate'.$userid, 0);
}
$last_xml = loadVariable('last_xml_'.$userid);
$last_xml_time = loadVariable('last_xml_time_'.$userid);
if ($last_xml != $new_xml)
{
saveVariable('last_xml_time_'.$userid, time());
saveVariable('last_xml_'.$userid, $new_xml);
if ($last_date != '')
{
saveVariable('lastupdate'.$userid, $last_date);
}
}
echo $new_xml;
}
if (($mode_selection == 'sleep') && ($action_selection == 'get'))
{
if (isset($history))
{ $url = "https://wbsapi.withings.net/v2/$mode_selection?action=$action_selection&data_fields=hr,rr,snoring,sdnn_1,rmssd,mvt_score&access_token=$access_token&startdate=0&enddate=$enddate";}
else
{ $url = "https://wbsapi.withings.net/v2/$mode_selection?action=$action_selection&data_fields=hr,rr,snoring,sdnn_1,rmssd,mvt_score&access_token=$access_token&startdate=$startdate&enddate=$enddate";}
$response = httpQuery($url, 'GET');
if ($debug == 1) {var_dump($url, $response);}
$json = sdk_json_decode($response);
if ($json['error'] != '')
{
if ($json['status'] == '401') // XRequestID: Not provided invalid_token: The access token provided is invalid
{
// force the use of the refresh token
saveVariable('expire_time'.$userid, 0);
}
die("Erreur lors de l'authentification".": [".$params['error'].'] (access_token = '.$access_token.')<br>, vous pouvez lier à nouveau votre compte en cliquant sur [Lier à nouveau] depuis la configuration de votre périphérique'."\n\n".$response);
}
sdk_header('text/xml');
$new_xml = "<root>";
$has_sleep = false;
for($i = 0; $i < sizeof($json['body']['series']); $i++)
{
if (isset($json['body']['series'][$i]['hr']))
{
if ($i == 0 || $json['body']['series'][$i]['startdate'] != $json['body']['series'][$i-1]['startdate'])
{
$new_xml .= "<sleep>";
$new_xml .= "<startdate>".date('Y-m-d H:i:s',$json['body']['series'][$i]['startdate'])."</startdate>";
$new_xml .= "<enddate>".date('Y-m-d H:i:s',$json['body']['series'][$i]['enddate'])."</enddate>";
$new_xml .= "<model>".$json['body']['series'][$i]['model']."</model>";
$j=0;
$moyenne=0;
foreach ($json['body']['series'][$i]['hr'] as $key=>$value)
{
$new_xml .= "<hr_time$j>".date("Y-m-d H:i:s",$key)."</hr_time$j>";
$new_xml .= "<hr_value$j>".$value."</hr_value$j>";
$j++;
$moyenne = $moyenne+$value;
}
$moyenne = round($moyenne/$j,0);
$new_xml .= "<hr_average>".$moyenne."</hr_average>";
$new_xml .= "</sleep>";
$has_sleep = true;
}
}
}
$new_xml .= "<token>".$access_token."</token>";
$new_xml .= "</root>";
if (!$has_sleep)
{
saveVariable('lastupdate'.$userid, 0);
}
$last_xml = loadVariable('last_xml_'.$userid);
$last_xml_time = loadVariable('last_xml_time_'.$userid);
if ($last_xml != $new_xml)
{
saveVariable('last_xml_time_'.$userid, time());
saveVariable('last_xml_'.$userid, $new_xml);
if ($last_date != '')
{
saveVariable('lastupdate'.$userid, $last_date);
}
}
echo $new_xml;
}
if (($mode_selection == 'sleep') && ($action_selection == 'getsummary'))
{
if (isset($history))
{ $url = "https://wbsapi.withings.net/v2/$mode_selection?action=$action_selection&access_token=$access_token&lastupdate=0";}
else
{ $url = "https://wbsapi.withings.net/v2/$mode_selection?action=$action_selection&access_token=$access_token&startdateymd=$startdateymd&enddateymd=$enddateymd";}
$response = httpQuery($url, 'GET');
if ($debug == 1) {var_dump($url, $response);}
$json = sdk_json_decode($response);
if ($json['error'] != '')
{
if ($json['status'] == '401') // XRequestID: Not provided invalid_token: The access token provided is invalid
{
// force the use of the refresh token
saveVariable('expire_time'.$userid, 0);
}
die("Erreur lors de l'authentification".": [".$params['error'].'] (access_token = '.$access_token.')<br>, vous pouvez lier à nouveau votre compte en cliquant sur [Lier à nouveau] depuis la configuration de votre périphérique'."\n\n".$response);
}
sdk_header('text/xml');
$new_xml = "<root>";
$has_sleep = false;
for($i = 0; $i < sizeof($json['body']['series']); $i++)
{
if (isset($json['body']['series'][$i]['data']))
{
if ($i == 0 || $json['body']['series'][$i]['startdate'] != $json['body']['series'][$i-1]['startdate'])
{
$new_xml .= "<sleep_summary>";
$new_xml .= "<startdate>".date('Y-m-d H:i:s',$json['body']['series'][$i]['startdate'])."</startdate>";
$new_xml .= "<enddate>".date('Y-m-d H:i:s',$json['body']['series'][$i]['enddate'])."</enddate>";
$new_xml .= "<data>";
foreach ($json['body']['series'][$i]['data'] as $key=>$value)
{
$new_xml .= "<$key>".$value."</$key>";
}
$new_xml .= "</data>";
$new_xml .= "</sleep_summary>";
$has_sleep = true;
}
}
}
$new_xml .= "<token>".$access_token."</token>";
$new_xml .= "</root>";
if (!$has_sleep)
{
saveVariable('lastupdate'.$userid, 0);
}
$last_xml = loadVariable('last_xml_'.$userid);
$last_xml_time = loadVariable('last_xml_time_'.$userid);
if ($last_xml != $new_xml)
{
saveVariable('last_xml_time_'.$userid, time());
saveVariable('last_xml_'.$userid, $new_xml);
if ($last_date != '')
{
saveVariable('lastupdate'.$userid, $last_date);
}
}
echo $new_xml;
}
if (($mode_selection == 'measure') && ($action_selection == 'getmeas'))
{
if (isset($history))
{ $url = "https://wbsapi.withings.net/v2/$mode_selection?action=$action_selection&access_token=$access_token&lastupdate=0";}
else
{ $url = "https://wbsapi.withings.net/v2/$mode_selection?action=$action_selection&access_token=$access_token&startdate=$startdate&enddate=$enddate";}
$response = httpQuery($url, 'GET');
if ($debug == 1) {var_dump($url, $response);}
$json = sdk_json_decode($response);
if ($json['error'] != '')
{
if ($json['status'] == '401') // XRequestID: Not provided invalid_token: The access token provided is invalid
{
// force the use of the refresh token
saveVariable('expire_time'.$userid, 0);
}
die("Erreur lors de l'authentification".": [".$params['error'].'] (access_token = '.$access_token.')<br>, vous pouvez lier à nouveau votre compte en cliquant sur [Lier à nouveau] depuis la configuration de votre périphérique'."\n\n".$response);
}
sdk_header('text/xml');
$new_xml = "<root>";
$has_measures = false;
for($i = 0; $i < sizeof($json['body']['measuregrps']); $i++)
{
if ($i == 0 || $json['body']['measuregrps'][$i]['date'] != $json['body']['measuregrps'][$i-1]['date'])
{
$new_xml .= "<measure>";
$new_xml .= "<date>".date('Y-m-d H:i:s', $json['body']['measuregrps'][$i]['date']*1)."</date>";
$last_date = $json['body']['measuregrps'][$i]['date']*1;
}
for($j = 0; $j < sizeof($json['body']['measuregrps'][$i]['measures']); $j++)
{
$type = $measure_type[$json['body']['measuregrps'][$i]['measures'][$j]['type']*1];
if ($type == '')
{
$type = "unknown_type_".$json['body']['measuregrps'][$i]['measures'][$j]['type'];
}
if ($type != '')
{
$new_xml .= "<$type>".($json['body']['measuregrps'][$i]['measures'][$j]['value']*pow(10, $json['body']['measuregrps'][$i]['measures'][$j]['unit']))."</$type>";
$has_measures = true;
}
}
if ($i<sizeof($json['body']['measuregrps'])-1)
{
if (($json['body']['measuregrps'][$i+1]['date'] != $json['body']['measuregrps'][$i]['date']) && has_measures)
{
$new_xml .= "</measure>";
}
}
}
$new_xml .= "<token>".$access_token."</token>";
$new_xml .= "<userid>".$userid."</userid>";
$new_xml .= "</root>";
if (!$has_measures)
{
saveVariable('lastupdate'.$userid, 0);
}
$last_xml = loadVariable('last_xml_'.$userid);
$last_xml_time = loadVariable('last_xml_time_'.$userid);
if ($last_xml != $new_xml)
{
saveVariable('last_xml_time_'.$userid, time());
saveVariable('last_xml_'.$userid, $new_xml);
if ($last_date != '')
{
saveVariable('lastupdate'.$userid, $last_date);
}
}
echo $new_xml;
}
?>
http://localhost/script/?exec=withings_oauth.php&userid=[VAR1]&height=[VAR2]&period=[VAR3]
sum(//Weight)div(count(//Weight))
7&deltat=179
<?php
// script créé par Connected Object pour eedomus
// encodage iso-8859-1 pour les accents
// Modifié dommarion le 16/06/2024 Ajout des mesures d'une montre connectée
// aout 2024 : ajout nouvelles valeurs et nouvelles données balance (opa95)
// possibilite de renseigner la taille pour avoir l'IMC
// Commande http://localhost/script/?exec=withings_oauth.php&mode=measure&action=getmeas&userid=[VAR1]&height=[VAR2]&period=[VAR3]
// ou pour mesure http://localhost/script/?exec=withings_oauth.phpuserid=[VAR1]&height=[VAR2]&period=[VAR3]
// Commandes complémentaires
// &print=json -> impression json et var_dump, Résultat du XPATH valide
// &deltat=x -> écart minimal entre 2 lectures (x minutes)
// [VAR1] -> identifiant Withing
// [VAR2] -> vide ou taille en metres 1.80, 0 par défaut
// [VAR3] -> vide ou période de relévés, par défaut 7; si 0 -> illimité si historique pas trop long (balance, 1 mesure/jour -> plante si valeur>environ 700)
// 7 derniers jours
// dernières valeurs XPATH -> //Nom ou /root/measure[1]/Nom
// moyennes XPATH -> sum(//Nom)div(count(//Npm)) moyenne semaine
// Nom parmi la liste ci-dessous
/*
1 => 'Weight',
4 => 'Height',
5 => 'Fat_Free_Mass',
6 => 'Fat_Ratio',
8 => 'Fat_Mass_Weight',
9 => 'Diastolic_Blood_Pressure',
10 => 'Systolic_Blood_Pressure',
11 => 'Heart_Pulse',
12 => 'Temperature',
54 => 'SP02',
71 => 'Body_Temperature',
73 => 'Skin_Temperature',
76 => 'Muscle_Mass',
77 => 'Hydration',
88 => 'Bone_Mass',
91 => 'Pulse_Wave_Velocity',
123 => 'VO2_max',
130 => 'Atrial_fibrillation',
135 => 'QRS_ECG_Signal',
136 => 'PR_ECG_Signal',
137 => 'QT_ECG_Signal',
138 => 'Corrected_QT_ECG_Signal',
139 => 'Atrial_Fibrillation_PPG',
155 => 'Vascular_Age',
167 => 'Nerve_Health_Score',
168 => 'Extracellular_Water',
169 => 'Intracellular_Water',
170 => 'Visceral_Fat',
174 => 'Fat_Mass_Segments',
175 => 'Muscle_Mass_Segments',
196 => 'Electrodermal_Activity',
226 => 'Basal_Metabolic_Rate'
autres
Date, Fat_Free_Ratio, Muscle_Mass_Ratio, Hydration_Ratio, Bone_Mass_Ratio, Heart
Depuis la fenêtre de test &print=json renvoie les valeurs brutes et le tableau
*/
/*
mémoires internes :
$code = $_GET['oauth_code'] si vide $code = loadVariable('code'.$userid);
$userid = $_GET['userid']; $userid : contenu de VAR1
'code'.$userid -> $prev_code
'refresh_token'.$userid -> $refresh_token
'expire_time'.$userid -> $expire_time
'access_token'.$userid -> access_token
'lastupdate'.$userid -> lastupdate
'last_xml_'.$userid -> $last_xml
'last_xml_time_'.$userid -> last_xmltime
*/
function sdk_abort($comment) {
global $params,$access_token,$response;
die("Erreur lors de l'authentification".": [".$params['error'].'] (access_token = '.$access_token.')<br>, vous pouvez lier à nouveau votre compte en cliquant sur [Lier à nouveau] depuis la configuration de votre périphérique'."\n".$comment."\n".$response);
}
$mode=array(
'user',
'measure',
'heart',
'stetho',
'sleep',
'notify',
'signature',
'rawdata',
'device',
'verify'
);
$action=array(
'activate',
'desactivate',
'disablefeature',
'enablefeature',
'get',
'getactivity',
'getdevice',
'getgoals',
'getintradayactivity',
'getmeas',
'getnonce',
'getsummary',
'getworkouts',
'link',
'list',
'revoke',
'subscribe',
'unlink',
'update',
'updatesimstatus'
);
$measure_type = array(
1 => 'Weight',
4 => 'Height',
5 => 'Fat_Free_Mass',
6 => 'Fat_Ratio',
8 => 'Fat_Mass_Weight',
9 => 'Diastolic_Blood_Pressure',
10 => 'Systolic_Blood_Pressure',
11 => 'Heart_Pulse',
12 => 'Temperature',
54 => 'SP02',
71 => 'Body_Temperature',
73 => 'Skin_Temperature',
76 => 'Muscle_Mass',
77 => 'Hydration',
88 => 'Bone_Mass',
91 => 'Pulse_Wave_Velocity',
123 => 'VO2_Max',
130 => 'Atrial_Fibrillation',
135 => 'QRS_ECG_Signal',
136 => 'PR_ECG_Signal',
137 => 'QT_ECG_Signal',
138 => 'Corrected_QT_ECG_Signal',
139 => 'Atrial_Fibrillation_PPG',
155 => 'Vascular_Age',
167 => 'Nerve_Health_Score',
168 => 'Extracellular_Water',
169 => 'Intracellular_Water',
170 => 'Visceral_Fat',
174 => 'Fat_Mass_Segments',
175 => 'Muscle_Mass_Segments',
196 => 'Electrodermal_Activity',
226 => 'Basal_Metabolic_Rate'
);
$api_url = 'https://wbsapi.withings.net/v2/oauth2';
$code = $_GET['oauth_code'];
$userid = $_GET['userid']; // peut être vide ssi demande d'association
$prev_code = loadVariable('code'.$userid);
$mode_selection = getArg('mode', false, 'measure');
if (!in_array($mode_selection, $mode, false)) {$mode_selection = 'measure';}
$action_selection = getArg('action', false, 'getmeas');
if (!in_array($action_selection, $action, false)) {$action_selection = 'getmeas';}
$history = getArg('history', false, NULL);
$date=date("Y-m-d",time());
$startdate=strtotime(date($date.' 00:00:00'));
$startdateymd=date("Y-m-d",$startdate);
$enddate=time();
$enddateymd=date("Y-m-d",$enddate);
$debug = getArg('debug', false, NULL);
//******** Lecture du Code d'accès *********
if ($code == '') {$code = loadVariable('code'.$userid);}
if (strlen($prev_code) > 1 && $code == $prev_code) {
// on reprend le dernier refresh_token seulement s'il correspond au même code
$refresh_token = loadVariable('refresh_token'.$userid);//code pour rafraichir l'access_token
$expire_time = loadVariable('expire_time'.$userid);// expiration de l'access_code (3 heures)
// s'il n'a pas expiré, on peut reprendre l'access_token
if (time() < $expire_time) {
// on a déjà un token d'accés non expiré pour le code demandé
$access_token = loadVariable('access_token'.$userid);
}
}
if ($access_token == '') {//obtention d'un code valide
if (strlen($refresh_token) > 1) {
// on peut juste rafraichir le token
$grant_type = 'refresh_token';
$postdata = 'action=requesttoken&grant_type='.$grant_type.'&refresh_token='.$refresh_token;
} else {
// 1ère utilisation après obtention du code
$grant_type = 'authorization_code';
$redirect_uri = 'https://secure.eedomus.com/sdk/plugins/withings/callback.php';
$postdata = 'action=requesttoken&grant_type='.$grant_type.'&code='.$code.'&redirect_uri='.$redirect_uri;
}
$response = httpQuery($api_url, 'POST', $postdata, 'withings_oauth');
$json = sdk_json_decode($response);
$params = $json['body'];
if ($params['error'] != '') {sdk_abort(1);}
// on sauvegarde l'access_token et le refresh_token pour les authentifications suivantes
if (isset($params['access_token']) && !isset($params['refresh_token'])) {
$access_token = $params['access_token'];
saveVariable('access_token'.$userid, $access_token);
saveVariable('expire_time'.$userid, time()+$params['expires_in']);
saveVariable('code'.$userid, $code);
} elseif (isset($params['access_token']) && isset($params['refresh_token'])){
$access_token = $params['access_token'];
saveVariable('access_token'.$userid, $access_token);
saveVariable('refresh_token'.$userid, $params['refresh_token']);
saveVariable('expire_time'.$userid, time()+$params['expires_in']);
if ($code != '') {saveVariable('code'.$userid, $code);}
} elseif ($access_token == '') {sdk_abort(2);}
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><?
$userid = $params['userid'];
// sauvegarde pour l'utilisateur donné
saveVariable('access_token'.$userid, $access_token);
if ($params['refresh_token'] != '') {saveVariable('refresh_token'.$userid, $params['refresh_token']);}
saveVariable('expire_time'.$userid, time()+$params['expires_in']);
if ($code != '') {saveVariable('code'.$userid, $code);}
echo "<img width='64' src='https://secure.eedomus.com/img/mdm/01/check.png' align='absmiddle'> Votre box eedomus est maintenant autorisée à consulter vos données Withings !";
echo '<br><br>';
echo "Votre <b>Code utilisateur</b> Withings est : ".'<input onclick="this.select();" type="text" size="10" readonly="readonly" value="'.$userid .'" />, vous pouvez le copier-coller dans votre périphérique Withings eedomus.';
die();
}
}
//******** Programme de lecture des données *********
$userid = getArg('userid');
$lastupdate = loadVariable('lastupdate'.$userid);
sdk_header('text/xml');
echo '<?xml version="1.0" encoding="utf8" ?>'."\n";
if (($mode_selection == 'measure') && ($action_selection == 'getmeas'))
{
define('PERIOD',7);//Période par défaut (7 jours)//opa95
define('DELTATIME',59);//Validité du XML (59 minutes)//opa95
$period = getArg('period',false,PERIOD);
$delta_Time = getArg('deltat',false,DELTATIME);
$use_last_xml = ( ( (loadVariable('last_xml_time_'.$userid)+$delta_Time*60)>time()) || $last_update=0);
if ($use_last_xml) {$new_xml = $last_xml = loadVariable('last_xml_'.$userid);}
else {
if ( ($lastupdate == '') || ($period == 0) ) {
$lastupdate = 0;// tout l'historique//opa95
$url = "https://wbsapi.withings.net/measure?action=getmeas&access_token=$access_token&lastupdate=$lastupdate";
} else {
$startdate -= 86400*($period-1);
$url = "https://wbsapi.withings.net/measure?action=getmeas&access_token=$access_token&startdate=$startdate&enddate=$enddate";
}
//$info=array();
// $response = httpQuery($url, 'GET',NULL,NULL,NULL,false, false, $info);
$response = httpQuery($url, 'GET');
// var_dump($info); die();
if ($debug) {echo "<--\n";var_dump($url, $response);echo "-->\n";}
$json = sdk_json_decode($response);
if ($json['error'] != '') {
if ($json['status'] == '401') // XRequestID: Not provided invalid_token: The access token provided is invalid
{
// force the use of the refresh token for next access
saveVariable('expire_time'.$userid, 0);
}
sdk_abort("$mode_selection : $action_selection");
}
if ($_GET['print'] == 'json') {
echo "<!--\n$response\n";
var_dump($json);
echo "-->\n";
}
$has_measures = false;
$new_xml = "<root>";
for($i = 0; $i < sizeof($json['body']['measuregrps']); $i++) {
if ($i == 0 || $json['body']['measuregrps'][$i]['date'] != $json['body']['measuregrps'][$i-1]['date']) {
$has_weight = false;
$has_heart = false;
$height = getArg('height',false,0);
$has_height = $height>0;
$new_xml .= "<measure>";
$last_date = $json['body']['measuregrps'][$i]['date']*1;
$new_xml .= "<Date>".date('Y-m-d H:i:s', $last_date)."</Date>";
}
for($j = 0; $j < sizeof($json['body']['measuregrps'][$i]['measures']); $j++){
$type = $measure_type[$json['body']['measuregrps'][$i]['measures'][$j]['type']*1];
if ($type == '') {
$type = "unknown_type_".$json['body']['measuregrps'][$i]['measures'][$j]['type'];
}
if ($type != '') {
$measures[$type] = $json['body']['measuregrps'][$i]['measures'][$j]['value']*pow(10, $json['body']['measuregrps'][$i]['measures'][$j]['unit']);
$new_xml .= "<$type>".$measures[$type]."</$type>";
$has_measures = true;
switch ($type) {
case 'Weight' : $has_weight = ($measures[$type]>0);break;
case 'Height' : $has_height = true;break;
case 'Diastolic_Blood_Pressure' :
case 'Systolic_Blood_Pressure' : $has_heart = true;break;
}
}
}
if ($has_weight) {
foreach ($measures as $type => $measure){
switch ($type) {
case 'Fat_Free_Mass' : $new_xml .= "<Fat_Free_Ratio>".round(100*$measure/$measures['Weight'],2)."</Fat_Free_Ratio>";break;
case 'Muscle_Mass' : $new_xml .= "<Muscle_Mass_Ratio>".round(100*$measure/$measures['Weight'],2)."</Muscle_Mass_Ratio>";break;
case 'Hydration' : $new_xml .= "<Hydration_Ratio>".round(100*$measure/$measures['Weight'],2)."</Hydration_Ratio>";break;
case 'Bone_Mass' : $new_xml .= "<Bone_Mass_Ratio>".round(100*$measure/$measures['Weight'],2)."</Bone_Mass_Ratio>";break;
case 'Muscle_Mass_Segments' : $new_xml .= "<Muscle_Mass_Segments_Ratio>".round(100*$measure/$measures['weight'],2)."</Muscle_Mass_Segments_Ratio>";break;
}
}
if ($has_height) $new_xml .= "<Body_Mass_Index>".round($measures['Weight']/$height/$height,2)."</Body_Mass_Index>";
}
if ($has_heart) $new_xml .= "<heart>".$measures['Systolic_Blood_Pressure']."/".$measures['Diastolic_Blood_Pressure']." (".$measures['Heart_Pulse'].")"."</heart>";
if ($json['body']['measuregrps'][$i+1]['date'] != $json['body']['measuregrps'][$i]['date']) {$new_xml .= "</measure>";}
}
$new_xml .= "<token>".$access_token."</token>";
$new_xml .= "<Rtoken>".$refresh_token."</Rtoken>";
$new_xml .= "<userid>".$userid."</userid>";
$new_xml .= "<new>new</new>";
$new_xml .= "<expire>".date('Y-m-d H:i:s',$expire_time)."</expire>";
$new_xml .= "</root>";
if (!$has_measures) {saveVariable('lastupdate'.$userid, 0);}
}
echo $new_xml;
$last_xml = loadVariable('last_xml_'.$userid);
$last_xml_time = loadVariable('last_xml_time_'.$userid);
if ($last_xml != $new_xml) {
saveVariable('last_xml_time_'.$userid, time());
$new_xml = str_replace("<new>new</new>","<new>old</new>",$new_xml);
saveVariable('last_xml_'.$userid, $new_xml);
if ($last_date != '') {saveVariable('lastupdate'.$userid, $last_date);}
}
}
?>
Utilisateurs parcourant ce forum : Google [Bot] et 4 invité(s)