Envoyer des SMS depuis la Nissan Leaf

La solution proposée ici est un Proof of Concept, le code doit être amélioré pour une utilisation quotidienne

Lorsqu’il a fallu changer de voiture, il y a deux ans, avec les minis, nous avons craqué pour la Nissan Leaf. Rien de plus Geek qu’une voiture électrique avec laquelle on peut lancer la climatisation depuis son smartphone. Depuis, d’autres marques ont fait mieux puisque sur certains modèles il est possible de gérer la fermeture des portes, l’allumage des feux, ouvrir le toit ouvrant, etc… Dans ce domaine, le best-of semble venir de chez Tesla. Surtout que maintenant, il est possible de faire ça avec sa montre, et ça c’est LA fonctionnalité ultime pour tout Geek qui a grandi avec « K2000 ». Mais revenons au sujet de ce post.

La Leaf, comme dit précédemment, est une voiture électrique, « full électrique », sans pot d’échappement ou trappe à essence, qui permet de parcourir 160km de moyenne. Elle est plutôt spacieuse et très agréable à conduire, dans un silence confortable. Les modèles Acenta et Tekna comprennent, entre autres, l’ordinateur de bord Carwings. Ce dernier permet de gérer tous les paramètres du véhicule, d’avoir le GPS avec l’information Traffic, de connaitre les emplacements régulièrement actualisés pour la recharge ou pour les POI (Point Of Interrest – Restaurant, supermarché, station-essence :(, … ). Mais malheureusement, Carwings ne permet pas, d’origine, d’envoyer des SMS. Par contre, fonctionnalité assez rare dans une voiture, Carwings permet de lire du flux RSS. Cela permet de demander à la Leaf de lire les news provenant de site de notre choix, au démarrage du véhicule. Et c’est justement sur cela que l’on va s’appuyer pour notre système de SMS.

Pour expliquer grossièrement le système :

  1. L’utilisateur entre, via l’interface Web de Carwings, l’adresse Internet où sera hébergé notre script. Il est possible d’en enregistrer plusieurs, qui deviendront des « canaux d’informations ».
  2. Au démarrage, la Leaf synchronise la liste des canaux préférés avec le serveur Carwings.
  3. L’utilisateur sélectionne le canal correspondant au message qu’il souhaite envoyer.
  4. La Leaf, en passant par les serveurs de Carwings, interroge notre serveur pour connaître les informations à remonter à la voiture. En réalité, sur notre serveur, cela va enclencher différentes actions lancées par notre script (dont l’envoi d’un SMS). Carwings pense interroger un flux RSS classique, il faut donc tout mettre en oeuvre pour qu’il continue de le croire.
  5. Le script envoie ainsi, soit un SMS directement depuis un téléphone portable relié à notre serveur (en utilisant un utilitaire comme Gammu), soit la fonctionnalité de Free Mobile permettant d’envoyer des SMS à son propre numéro par une requête HTTP.
  6. Carwings lit le message qui a été renvoyé par notre script, et qui nous sert de confirmation de réception (acquittement).

Alors, vous l’aurez compris par vous-même, on triche un peu sur l’utilisation première de la fonctionnalité initiale, c’est ce qui s’appelle communément du « Hacking » (Wikipedia : « Dans un sens large, le bidouillage ou hacking concerne les activités visant à détourner un objet de sa fonction première »), rien à voir, donc, avec du piratage. De plus, on ne peut pas envoyer n’importe quel message, les SMS sont pré-enregistrés ainsi que leur destinataire. Mais il est possible d’en enregistrer 20 dans l’ordinateur de bord (depuis l’interface Web de la Leaf).
Et pour ceux qui voient encore plus loin, on peut bien évidemment utiliser ce script pour faire d’autres choses : gérer sa domotique, ouvrir son portail, déclencher le chauffage chez vous avant votre arrivée au domicile, allumer la TV (si c’est une SmartTV), éteindre tous les éclairages en partant, etc… Les possibilités ne sont limitées que par votre imagination et vos moyens financiers.

Pour ce projet, les dépenses se limitent à :

  • un Raspberry avec son alimentation et son boitier : 50€
  • un dongle USB/3G : j’avais acheté le mien une dizaine d’euros lors d’une offre Orange, il m’a fallu ensuite le désimlocker.
  • un abonnement Free Mobile à 2€ par mois.

Les deux derniers éléments sont nécessaires en utilisant la méthode avec Gammu, dans le cas où notre carte SIM habituelle est chez Free Mobile, ils ne sont pas indispensables
Passons maintenant au concret !

Le Script

#!/usr/bin/env python
# -*- coding: utf8 -*-

# chargement de tous les modules Python nécessaires
from BaseHTTPServer import HTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler
import cgi
import sys
from time import gmtime, strftime
import urllib2

# enregistrement du port dans une variable
PORT = 80

# on créé un fichier de log qui retracera les demandes
logfile = '/data/PiSim/PiSim.log'
log = open(logfile,'a')

# on indique ici les paramètres liés au compte Free Mobile
free_sms_user = '123456789'
free_sms_pass = 'AzErTyUiOp123456'

# il s'agit ici des en-têtes nécessaires pour se faire passer pour un serveur RSS
rss_begin = '<rss version="2.0"><channel><title>PiSim - monClavier.fr</title><link>https://www.monclavier.fr</link><description>Système d\'envoi de SMS depuis la Leaf</description>'
rss_end =  '</channel></rss>'

class HTTPHandler (SimpleHTTPRequestHandler):
    server_version = "MonServeurHTTP/0.1"
    def do_GET(self):
        log.write('\n---------------------------------------------------------\n')
        # on récupère ici les arguments présents dans l'URL
        for field in self.headers:
            log.write(field + ' : ' + self.headers[field] + '\n')
        self.path, self.requete = self.path.split('?', 1)
        self.reponse()
    def do_POST(self):
        self.requete = self.rfile.read(int(self.headers['Content-Length']))
        self.reponse()
    def reponse(self):
        self.args = dict(cgi.parse_qsl(self.requete))
        self.send_response(200, 'OK')
        log.write(self.client_address[0] + " - - [" + self.log_date_time_string() + '] "' + self.command + ' ' + self.path + self.requete + ' ' + self.request_version +'" 200 - \n')
        self.send_header('Content-type', 'text/html')
        self.end_headers()
        # On définit ici les différents paramètres des messages à envoyer
        if self.args['message']== 'depart' :
            destinataire_user = free_sms_user
            destinataire_pass = free_sms_pass
            # Message qui sera envoyé par SMS
            message = 'Départ du boulot.'
        elif self.args['message']== 'bouchon' :
            destinataire_user = free_sms_user
            destinataire_pass = free_sms_pass
            message = 'J\'ai des bouchons sur la route.'
        elif self.args['message']== 'test' :
            destinataire_user = free_sms_user
            destinataire_pass = free_sms_pass
            # le '%0D' permet de faire un saut de ligne, le '\n' n'est pas interprété
            message = 'Salut. C\'est un message de test pour un super système de notification créé par Rekk%0Dhttps://www.monclavier.fr'

        # Ajout d'un footer
        message = message + '%0DEnvoyé depuis la Leaf.'
        message_html = message.replace(' ', '%20')
        titre = "Envoi d\'un SMS"
        lien = "https://www.monclavier.fr/"
        date = strftime("%a, %d %b %Y %H:%M:%S GMT", gmtime())
        description = 'Le message "' + message + '" est envoyé'

        rss_contain = "<item><title>%s</title><link>%s</link><pubDate>%s</pubDate><description><![CDATA[ %s ]]></description></item>" %(titre, lien, date, description)
        self.wfile.write(rss_begin + rss_contain + rss_end)

        urllib2.urlopen('https://smsapi.free-mobile.fr/sendmsg?user=' + destinataire_user + '&pass=' + destinataire_pass + '&msg=' + message)

if __name__ == '__main__':
    try:
        httpd = HTTPServer(('', PORT), HTTPHandler)
        print "serving at port", PORT
        httpd.serve_forever()

    except KeyboardInterrupt:
        print('Fermeture du programme')
        log.close()
        sys.exit(0)

L'envoi du SMS

Deux méthodes peuvent être employées pour envoyer ce SMS. Soit vous êtes chez Free Mobile et vous pouvez utiliser la fonction « Notification par SMS » qui permet d’envoyer un SMS depuis, et vers, votre numéro de téléphone, soit vous utilisez un système qui permet d’envoyer un SMS depuis un ordinateur (cette partie, qui utilisera Gammu, est en cours de rédaction).
L’option proposée par Free Mobile peut servir, par exemple, pour des notifications d’alarme. L’option est gratuite et il n’y a pas, à ma connaissance, de limitation de nombre de SMS. En même temps, ils ne prennent pas trop de risque, puisqu’avec cette méthode, vous n’envoyez pas des SMS à tous les numéros que vous souhaitez, vous ne pouvez, par exemple, pas vous en servir pour faire un SMS proxy ; l’expéditeur et le destinataire ne sont qu’un seul et même numéro, le vôtre.

Pour utiliser cette méthode, il faut vous rendre sur votre interface de gestion Free Mobile à l’adresse http://mobile.free.fr. Sur la page des options, celle qui nous intéresse se trouve, généralement, sur le bas de la page. La méthode d’utilisation est suffisamment bien expliquée, je ne reviens pas dessus. Il ne vous reste plus qu’à activer l’option et à récupérer les deux clés données par Free sur l’interface. Ces deux clés sont ensuite à coller dans le script Python présent ci-dessus (variables free_sms_user et free_sms_pass).

Un article sur Gammu devrait arriver prochainement, suite à cela, cette section sera mise à jour


L'accessibilité du serveur Web

Pour que ce sytème fonctionne, il faut que notre Rasbperry soit accessible depuis Internet. Si cela n’est pas fait correctement, cela peut être un point d’entrée vers votre « réseau informatique » depuis l’extérieur et peut donc poser un problème de Sécurité Informatique ; il faut donc faire très attention sur la manière utilisée pour faire ça. Personnellement, mon Raspberry Pi (qui, pour l’instant, ne me sert qu’à ça), est branché sur la patte DMZ de mon Firewall, et une seule adresse IP peut y accéder depuis l’extérieur, celle du serveur Carwings. Par un jeu de règles Firewall, le reste de mon réseau n’est pas visible depuis ce Raspberry Pi. Avec une Freebox, ou toute autre box, cela fonctionne en redirigeant tout le flux provenant d’Internet vers une IP interne (faussement appelée DMZ par Free), mais cela est plus risqué parce qu’il n’a plus de protection entre votre réseau local et le réseau Internet.

Une fois que vous aurez terminé la configuration réseau, il ne vous reste plus qu’à tester en vous rendant à l’adresse suivante depuis votre navigateur :

http://IP_publique_de_votre_ligne/?message=test

Vous devriez avoir votre lecteur RSS qui se lance, ou l’affichage du flux directement dans votre navigateur (Firefox).

NB : Je ne communiquerai pas ici l’adresse IP utilisée par Carwings, mais si vous avez les compétences pour mettre en place ce hack, nous n’aurez aucune difficulté à retrouver cette IP. D’ailleurs, il arrive que Nissan change cette adresse IP, si votre script ne fonctionne plus, pensez à vérifier que l’adresse n’ait pas changé. 


Paramétrage de Carwings

Maintenant qu’on sait que notre script fonctionne correctement, on va pouvoir configurer Carwings. Pour cela, il faut aller dans les paramètres de Carwings disponibles à cette adresse, puis cliquer sur le lien « Canaux d’information favoris » :

https://www.nissan.fr/FR/fr/YouPlus/welcome_pack_leaf/how_to_register.html
Carwings

Page d’accueil de Carwings

Après avoir cliqué sur l’un des boutons (+), on indique l’adresse de notre script, en n’oubliant pas le titre du message à envoyer, puis on clique sur « Utiliser le titre prédéfini ». À partir de là, on comprend pourquoi on est obligé de faire tout ça, et pas uniquement un site Web classique : Carwings vérifie qu’il s’agit bien d’un flux RSS avant de l’enregistrer. Sans cette validation, il serait impossible d’utiliser le système dans la Leaf. Vous devriez retrouver une trace de cet essai dans vos logs, ou en recevant le SMS, comme dans son fonctionnement normal. Une fois la validation terminée, il ne vous reste plus qu’à entrer un titre pour différencier chaque message ou action.

Canaux d'information enregistrés sur Carwings

Canaux d’information enregistrés sur Carwings


Résultat final

Au démarrage de la Leaf, il faut patienter quelques minutes pour que la liste des canaux d’information se mette à jour, et finalement, vous retrouvez vos canaux RSS créés (Bouchon, Départ et TEST).

Carwings_canaux_Leaf

Canaux disponibles de la Leaf


Envoi du SMS en cours

Envoi du SMS en cours

Durant l’envoi du SMS, la voix de synthèse de la Leaf lit ce qui, pour elle correspond au contenu du flux RSS, qui correspond aux variables titre et description de notre programme. Quelques secondes plus tard, nous recevons le SMS sur le téléphone.

Carwings_sms_recu

SMS reçu sur mon téléphone

Voir plus loin...

Maintenant que vous voyez comment faire et par quels moyens on est passé, on peut revenir aux possibilités de ce système. Parce qu’en modifiant quelques lignes du script Python, on peut faire bien plus de choses que de simplement envoyer des SMS. La plupart des box de domotique autorisent l’appel d’un scénario depuis une requête HTTP. Il serait donc possible d’ouvrir votre portail sans avoir à sortir de la voiture, d’allumer vos éclairages extérieurs et/ou intérieurs à votre arrivée, ou bien tout éteindre à votre départ, prévenir votre conjoint(e) de votre retard à un rendez-vous, etc… et tout ça en trois clics sur l’ordinateur de bord de votre Leaf, sans quitter les yeux de la route.

N’hésitez pas à partager toutes idées dans les commentaires.  🙂

6 Commentaires

  1. 1
  2. 2

    Bonjour,
    Bravo pour ce tuto rekk, ça fait plaisir de trouver des geeks sur la leaf, qui plus est francophone!

    J’ai enfin réussi à paramétrer mes flux RSS sur Nissan (leur lien est mort il faut passer par une URL directe: voir site ci dessous).
    Par contre je ne comprends pas dans votre tuto où doit on placer le script python? Comment le serveur Apache le sert il au client?
    Merci de tes lumières,

    Willily

    • 3

      Bonjour Willily,
      Merci pour ton lien. J’ai changé récemment de Leaf et je me retrouve donc sur le nouveau site, l’ancien (Carwings) restait fonctionnel et je ne savais pas qu’ils avaient tout changé depuis. J’ai passé du temps à retrouver comment remettre mes flux RSS sur la nouvelle Leaf et j’avais (provisoirement) lâcher l’affaire… Du coup, je vais tester ça d’ici peu, puis mettre à jour l’article avec ton astuce.
      Pour serveur Web, en fait, le script contient son propre serveur Web, il n’utilise donc pas Apache. Du coup, il faut d’assurer que le port d’écoute ne soit pas utilisé par un autre programme. Pour tester, tu déclenches le lancement du script depuis une console et tu cherches à y accéder depuis Firefox, ou tout autre navigateur qui gère les flux RSS. N’hésite pas à reposter un message ou m’envoyer un mail à rekk@monclavier.fr si tu as besoin d’aide.
      Rekk.

      • 4

        Salut Rekk

        Ok je comprends merci!
        Du coup, j’ai utilisé un combiné serveur Apache/php pour simuler le retour RSS.
        En paramétrant l’url http://mondyndns.org/?action=1 avec le nom « Ouvrir le portail » mon code PHP est le suivant:


        <?php

        /*
        ** Fichier permettant la simulation d'un flux RSS via un script PHP
        **
        ** On récupère la variable 'action' pour savoir ce qu'il faut faire
        ** puis on retourne le texte associé à la commande reçue
        **
        ** script fonctionnant avec la Nissan Leaf
        */

        // on traite la variable action passée en paramètre
        if(isset($_GET["action"]))
        {
        switch($_GET["action"]){
        case 0: exec('./spot.sh');
        $message = "Les spots viennent d'être actionnés";
        break;
        case 1: exec('./portail.sh');
        $message = "Le portail de la maison vient d'être actionné";
        break;
        case 2: exec('./open1.sh');
        $message = "Stores de la maison ouverts";
        break;
        case 3: exec('./close1.sh');
        $message = "Stores de la maison fermés";
        break;
        }

        $xml = "

        Portail
        Domotique maison

        Gestion domotique maison

        fr
        Copyright Willily

        <![CDATA[
        Bonne route
        ]]>

        ";

        print $xml;

        ?>

        • 5

          Effectivement, il est possible d’utiliser Apache avec PHP pour avoir la même fonctionnalité. Je suppose que tu n’affiches ici qu’une portion du code. Car, comme je l’indique dans l’article, le système de Nissan vérifie qu’il s’agit bien un flux RSS, au moins lors de la première connexion (pour l’enregistrement du site dans You+Nissan, anciennement CARWINGS), avec par exemple la date de publication, etc…
          Est-ce que ça fonctionne comme tu veux?
          Par contre, en terme de sécurité, fais attention à filtrer les flux qui arrivent sur ton serveur. Il ne faudrait pas que quelqu’un puisse ouvrir tes stores, portail et autres « barrières » pour accéder à ton domicile en ton absence. En regardant un peu les logs d’Apache, tu constateras que les flux provenant de la Leaf ont toutes la même adresse IP d’origine. Ça apportera un minimum de sécu si tu filtres uniquement cette IP pour accéder au service ; même si ce n’est pas parfait car une IP d’origine est falsifiable.
          Par curiosité, tu utilises quoi comme solution de domotique ?

          Merci pour le lien. J’ai effectivement pu rentrer mes flux RSS et retrouver le fonctionnement de mon hack! Je mets le lien ici pour ceux que ça intéresse : https://speakev.com/threads/how-to-setup-rss-feed-to-nissanconnect-ev.20255/. (le lien laissé dans le formulaire est accessible en cliquant sur le nom du posteur). Est-ce que NISSAN a été informé de ce problème?

  3. 6

    En fait le PHP que tu vois génère un flux RSS qui contient le texte de la commande envoyée, donc pour le client web, c’est vraiment comme un flux xml standard. Juste que la « news » retrounée est conditionnée par l’action envoyée. Du coup le site nissan n’y voit que du feu.
    Après je suis développeur PHP, d’où mon choix de cette solution.
    Pour la sécurité, oui j’ai pensé à carrément passer une clé en paramètre, comme ça le script ne se déclenche que si la clé match. Le problème avec l’IP source c’est que le smartphone ou même la leaf n’ont pas d’IP fixe.
    Pour la solution domotique, je viens de me mettre à Raspberry Pi et je dois dire que c’est fantastique. Pouvoir passer du développement abstrait au concret de piloter des volets, éclairage ou portail c’est excellent!
    En plus le coût est dérisoire: 35€ pour le raspberry, 2 x 5€ pour des relais et hop, je pilote mes volets roulants, mon éclairage de l’allée et le portail de la maison.

    Et grâce à toi, je peux utiliser la leaf pour piloter tous ça: merci 🙂
    Une petite question quand même, y a t il un moyen de raccourcir l’accès aux flux rss? pour l’instant j’ai juste ajouté l’icone « Canaux préférés » sur la deuxième page du menu Nissan: du coup il faut cliquer sur menu, puis canaux préférés, puis ouvrir le portail.
    L’idéal serait d’avoir sur la page principale le flux: Ouvrir le portail.

    Pour Nissan, avant de trouver la page cachée, je les avais appelé et ils m’avaient dit que mon abonnement ne permettait pas de modifier les flux RSS. Je pense que c’est une réponse bateau pour ne pas avoir à chercher. Si on leur parle de cette solution, j’ai peur qu’ils sécurisent la page ou désactive le lien. Vu que le problème a aussi lieu sur la version anglaise (speakev.com), je ne pense pas que ce soit quelque chose qu’ils veuillent rétablir. Après ce ne sont que des suppositions.

Laisser un commentaire

Votre adresse mail ne sera pas publiée. Champs requis *

Vous pouvez utiliser ces balises HTML et attributs: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.

Vous pourriez être intéressé par