Connectez votre voiture a votre Domotique avec XeeConnect

XeeConnect

Présentation

La société française Eliocity nous propose aujourd’hui de connecter notre voiture grâce a un petit boitier XeeConnect qui se branche facilement sur la prise diagnostique (ODB) de votre véhicule. Il vous permet d’afficher sur votre smartphone tout un tas d’informations utiles (localisation, niveau de carburant, verrouillage, phares allumés ou non, vitesse de déplacement…). Le boîtier est livré avec un câble adapté et s’installe facilement sur la plupart de véhicules. Pour cela, il vous faudra tout d’abord localiser la prise ODB, pour vous y aider, le site web de Xee vous donne des indications en fonction du modèle de votre voiture. Voici une petite vidéo de présentation:

 

Fonctionnalités

– Recevez des alertes si votre voiture a atteint un seuil minimum de carburant
Xee_carburant
– Localisez votre voiture en temps réel
Xee_localisation
– Recevez des alertes si votre voiture est mobile
Xee_deplacement
– Recevez des alertes si votre voiture sort d’un périmètre d’utilisation
Xee_Sortie_perimetre
– Recevez des alertes si votre voiture est utilisée en dehors d’une plage horaire
– Recevez des alertes si votre voiture dépasse une vitesse maximale
Xee_vitesse
– Recevez des alertes si votre voiture a ses feux allumés
Xee_Phares
– Partagez par SMS la position de votre véhicule

– Alertez par SMS vos contacts avec votre position géographique
Xee_alertes
– Alertez automatiquement par SMS vos contacts avec votre position géographique en cas de chocs violents
Xee_panne

Intégration Domotique

Ce qui nous intéresse le plus bien sur c’est de pouvoir intégrer et traiter les données de Xee avec notre système domotique. Domotique-Home vous présentes quelques exemples d’intégration:

Jeedom

XeeCloud

  • Téléchargez le Plugin sur le MerketJeedom
  • S’inscrire sur developer.xee.com (https://developer.xee.com) et ajouter une application pour obtenir client_id et client_secret. !!! l’accès a jeedom doit être possible de l’extérieur (à partir d’internet)
  • Saisir le client_id et client_secret dans la page de configuration du plugin.
  • Ajouter vos véhicules

XeeCloud_screenshot1

ImperiHome

Xee_ImperiHome

Les utilisateurs de ImperiHome peuvent nativement intégrer XeeConnect dans leurs système. Pour cela il suffit de vous rendre dans « Mes systèmes » et l’ajouter. Personnellement je consulte les infos de mes véhicules directement sur ma tablette murale.

Xee_ImperiHome

HC2 de Fibaro

Pour pouvoir intégrer notre boitier connecté dans la HC2 de Fibaro il faut utiliser un serveur PHP. Le XeeConnect  peut communiquer avec des APIs et récupérer ainsi des infos dans un fichier JSON. Nous savons bien que la HC2 comprend très bien ce « language ». Alors nous pouvons l’exploiter facilement. Je ne vais pas réinventer la roue puisque tibahut il nous a deja fait un excellent script de connexion en PHP et en prime un VD (module virtuel) pour votre HC2. Voici le lien vers l’article de thibahut sur le forum dédier aux box Fibaro (domotique-fibaro.fr)

Script php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
<?php
 
define('XEE_API_CLIENT_ID', 'votreclientid');
define('XEE_API_SECRET_ID', 'votresecretid');
define('XEE_API_REDIRECT_URI', 'http://votre-serveur.com/le/chemin/de/votre/script/php');
 
define('XEE_API_DEFAULT_URL', 'https://cloud.xee.com/v3/');
 
/**
 * get data from the web service
 * @return array agreggation from all results
 */
function getData()
{
    $totalResults              = array();
    $totalResults['token']     = getAccessToken();
    $totalResults['user']      = getUserData($totalResults['token']['access_token']);
    $totalResults['car']       = getCarData($totalResults['token']['access_token'], $totalResults['user']['id']);
    $totalResults['carStatus'] = getCarStatusData($totalResults['token']['access_token'], $totalResults['car']['id']);
 
    return $totalResults;
}
 
/**
 * get connected user data
 * @param  string $accessToken access token
 * 
 * @return array all informations about me
 */
function getUserData($accessToken)
{
    return getRequest(
        XEE_API_DEFAULT_URL . 'users/me', 
        $httpHeaders = array(
            'authorization: Bearer ' . $accessToken,
            'cache-control: no-cache'
        )
    );
}
 
/**
 * get user's car data
 * @param  string $accessToken access token
 * @param  int    $userId      car's owner
 * 
 * @return array all informations about the first car
 */
function getCarData($accessToken, $userId)
{
    $carData = getRequest(
        XEE_API_DEFAULT_URL . 'users/' . $userId . '/cars', 
        $httpHeaders = array(
            'authorization: Bearer ' . $accessToken,
            'cache-control: no-cache'
        )
    );
    //get only the first car
    return $carData[0];
}
 
/**
 * get car status
 * @param  string $accessToken access token
 * @param  int    $carId       car id
 * 
 * @return array all informations about car status
 */
function getCarStatusData($accessToken, $carId)
{
    $carStatusData = getRequest(
        XEE_API_DEFAULT_URL . 'cars/' . $carId . '/status', 
        $httpHeaders = array(
            'authorization: Bearer ' . $accessToken,
            'cache-control: no-cache'
        )
    );
 
    return $carStatusData;
}
 
/**
 * automatic switch to get the first token from first connection
 * or to get a fresh token from the web service
 * @return array access token, refresh token and expiration date
 */
function getAccessToken()
{
    if (isset($_GET['token']) && !empty($_GET['token'])) {
        return getFreshToken($_GET['token']);
    } elseif (isset($_GET['code']) && !empty($_GET['code'])) {
        return getToken($_GET['code']);
    }
 
    firstConnection();
}
 
/**
 * get an access token and a new refresh token from a refresh token
 * @param  string $refreshToken current refresh token
 * @return array access token, refresh token and expiration date 
 */
function getFreshToken($refreshToken)
{
    return getToken($refreshToken, 'refresh_token');
}
 
/**
 * generic function to get a token
 * @param  string $key  authorization code or refresh token
 * @param  string $type grant type 
 * 
 * @return array access token, refresh token and expiration date
 */
function getToken($key, $type = '')
{
    switch ($type) {
        case 'refresh_token':
            $parameters = 'grant_type=refresh_token&refresh_token=' . $key;
            break;
 
        default:
            $parameters = 'grant_type=authorization_code&code=' . $key;
            break;
    }
 
    return postRequest(
        XEE_API_DEFAULT_URL . 'auth/access_token', 
        $parameters, 
        $httpHeaders = array(
            'authorization: Basic ' . base64_encode(XEE_API_CLIENT_ID . ':' . XEE_API_SECRET_ID),
            'cache-control: no-cache',
            'content-type: application/x-www-form-urlencoded'
        )
    );
}
 
/**
 * first Connection to the webservice with an Oauth authentification
 */
function firstConnection()
{
    $urlParams = array(
        'client_id'    => XEE_API_CLIENT_ID,
        'scope'        => 'users_read cars_read trips_read signals_read locations_read status_read',
        'redirect_uri' => XEE_API_REDIRECT_URI
    );
 
    header('Location: ' . XEE_API_DEFAULT_URL . 'auth/auth?' . http_build_query($urlParams));
    die;
}
 
/**
 * do a request with POST method
 * @param  string $url         url do do the request
 * @param  string $postFields  keys/values to POST
 * @param  array  $httpHeaders additionnal HTTP headers
 * 
 * @return array json decoded request result
 */
function postRequest($url, $postFields, $httpHeaders = array())
{
    return sendRequest($url, $requestType = 'POST', $postFields, $httpHeaders);
}
 
/**
 * do a request with GET method
 * @param  string $url         url do do the request
 * @param  array  $httpHeaders additionnal HTTP headers
 * 
 * @return array json decoded request result 
 */
function getRequest($url, $httpHeaders = array())
{
    return sendRequest($url, $requestType = 'GET', $postFields = '', $httpHeaders);
}
 
/**
 * generic function to make curl request
 * @param  string $url         url do do the request
 * @param  string $requestType request type : GET or POST
 * @param  string $postFields  keys/values urlencoded for POST method
 * @param  array  $httpHeaders additionnal HTTP headers
 * 
 * @return array json decoded request result
 */
function sendRequest($url, $requestType = 'GET', $postFields = '', $httpHeaders = array())
{
    $curl = curl_init();
 
    curl_setopt_array($curl, 
        array(
            CURLOPT_URL            => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING       => '',
            CURLOPT_MAXREDIRS      => 10,
            CURLOPT_TIMEOUT        => 30,
            CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST  => $requestType,
            CURLOPT_POSTFIELDS     => $postFields,
            CURLOPT_HTTPHEADER     => $httpHeaders,
        )
    );
 
    $response = curl_exec($curl);
    $err      = curl_error($curl);
 
    curl_close($curl);
 
    if ($err) {
      die('cURL Error #:' . $err);
    } else {
        return json_decode($response, true);
    }
}
 
// display json encoded data
echo json_encode(getData());
exit;
?>
<?php
 
define('XEE_API_CLIENT_ID', 'votreclientid');
define('XEE_API_SECRET_ID', 'votresecretid');
define('XEE_API_REDIRECT_URI', 'http://votre-serveur.com/le/chemin/de/votre/script/php');
 
define('XEE_API_DEFAULT_URL', 'https://cloud.xee.com/v3/');
 
/**
 * get data from the web service
 * @return array agreggation from all results
 */
function getData()
{
    $totalResults              = array();
    $totalResults['token']     = getAccessToken();
    $totalResults['user']      = getUserData($totalResults['token']['access_token']);
    $totalResults['car']       = getCarData($totalResults['token']['access_token'], $totalResults['user']['id']);
    $totalResults['carStatus'] = getCarStatusData($totalResults['token']['access_token'], $totalResults['car']['id']);
 
    return $totalResults;
}
 
/**
 * get connected user data
 * @param  string $accessToken access token
 * 
 * @return array all informations about me
 */
function getUserData($accessToken)
{
    return getRequest(
        XEE_API_DEFAULT_URL . 'users/me', 
        $httpHeaders = array(
            'authorization: Bearer ' . $accessToken,
            'cache-control: no-cache'
        )
    );
}
 
/**
 * get user's car data
 * @param  string $accessToken access token
 * @param  int    $userId      car's owner
 * 
 * @return array all informations about the first car
 */
function getCarData($accessToken, $userId)
{
    $carData = getRequest(
        XEE_API_DEFAULT_URL . 'users/' . $userId . '/cars', 
        $httpHeaders = array(
            'authorization: Bearer ' . $accessToken,
            'cache-control: no-cache'
        )
    );
    //get only the first car
    return $carData[0];
}
 
/**
 * get car status
 * @param  string $accessToken access token
 * @param  int    $carId       car id
 * 
 * @return array all informations about car status
 */
function getCarStatusData($accessToken, $carId)
{
    $carStatusData = getRequest(
        XEE_API_DEFAULT_URL . 'cars/' . $carId . '/status', 
        $httpHeaders = array(
            'authorization: Bearer ' . $accessToken,
            'cache-control: no-cache'
        )
    );
 
    return $carStatusData;
}
 
/**
 * automatic switch to get the first token from first connection
 * or to get a fresh token from the web service
 * @return array access token, refresh token and expiration date
 */
function getAccessToken()
{
    if (isset($_GET['token']) && !empty($_GET['token'])) {
        return getFreshToken($_GET['token']);
    } elseif (isset($_GET['code']) && !empty($_GET['code'])) {
        return getToken($_GET['code']);
    }
 
    firstConnection();
}
 
/**
 * get an access token and a new refresh token from a refresh token
 * @param  string $refreshToken current refresh token
 * @return array access token, refresh token and expiration date 
 */
function getFreshToken($refreshToken)
{
    return getToken($refreshToken, 'refresh_token');
}
 
/**
 * generic function to get a token
 * @param  string $key  authorization code or refresh token
 * @param  string $type grant type 
 * 
 * @return array access token, refresh token and expiration date
 */
function getToken($key, $type = '')
{
    switch ($type) {
        case 'refresh_token':
            $parameters = 'grant_type=refresh_token&refresh_token=' . $key;
            break;
 
        default:
            $parameters = 'grant_type=authorization_code&code=' . $key;
            break;
    }
 
    return postRequest(
        XEE_API_DEFAULT_URL . 'auth/access_token', 
        $parameters, 
        $httpHeaders = array(
            'authorization: Basic ' . base64_encode(XEE_API_CLIENT_ID . ':' . XEE_API_SECRET_ID),
            'cache-control: no-cache',
            'content-type: application/x-www-form-urlencoded'
        )
    );
}
 
/**
 * first Connection to the webservice with an Oauth authentification
 */
function firstConnection()
{
    $urlParams = array(
        'client_id'    => XEE_API_CLIENT_ID,
        'scope'        => 'users_read cars_read trips_read signals_read locations_read status_read',
        'redirect_uri' => XEE_API_REDIRECT_URI
    );
 
    header('Location: ' . XEE_API_DEFAULT_URL . 'auth/auth?' . http_build_query($urlParams));
    die;
}
 
/**
 * do a request with POST method
 * @param  string $url         url do do the request
 * @param  string $postFields  keys/values to POST
 * @param  array  $httpHeaders additionnal HTTP headers
 * 
 * @return array json decoded request result
 */
function postRequest($url, $postFields, $httpHeaders = array())
{
    return sendRequest($url, $requestType = 'POST', $postFields, $httpHeaders);
}
 
/**
 * do a request with GET method
 * @param  string $url         url do do the request
 * @param  array  $httpHeaders additionnal HTTP headers
 * 
 * @return array json decoded request result 
 */
function getRequest($url, $httpHeaders = array())
{
    return sendRequest($url, $requestType = 'GET', $postFields = '', $httpHeaders);
}
 
/**
 * generic function to make curl request
 * @param  string $url         url do do the request
 * @param  string $requestType request type : GET or POST
 * @param  string $postFields  keys/values urlencoded for POST method
 * @param  array  $httpHeaders additionnal HTTP headers
 * 
 * @return array json decoded request result
 */
function sendRequest($url, $requestType = 'GET', $postFields = '', $httpHeaders = array())
{
    $curl = curl_init();
 
    curl_setopt_array($curl, 
        array(
            CURLOPT_URL            => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING       => '',
            CURLOPT_MAXREDIRS      => 10,
            CURLOPT_TIMEOUT        => 30,
            CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST  => $requestType,
            CURLOPT_POSTFIELDS     => $postFields,
            CURLOPT_HTTPHEADER     => $httpHeaders,
        )
    );
 
    $response = curl_exec($curl);
    $err      = curl_error($curl);
 
    curl_close($curl);
 
    if ($err) {
      die('cURL Error #:' . $err);
    } else {
        return json_decode($response, true);
    }
}
 
// display json encoded data
echo json_encode(getData());
exit;
?>

Module virtuel

xee_fibaro

 

Je vous prépare un article d’utilisation de XeeConnect avec Tasker, il sera bientôt disponible et téléchargeable. Et si le temps me permet j’ai en projet également de développer une application Android qui va facilité l’échange d’infos avec la HC2 de Fibaro 😉