Domotique et Intelligence : la communication

lacommunication

Quelques mois plus tôt, j’avais évoqué la nécessité de la connaissance pour un environnement domotique (cf. http://blog.guiguiabloc.fr/index.php/2014/01/04/domotique-et-intelligence-la-connaissance/)

J’aimerais maintenant aborder avec vous la deuxième partie, la communication.

A suivre l’actualité des constructeurs et les retours ou discussions des utilisateurs de domotique sur les blogs ou forums divers, j’ai l’impression assez désagréable de vivre à nouveau le même scénario qu’il y a plusieurs années quand l’informatique personnelle s’est généralisée auprès du grand public.

Tout le monde y va de son interface, de son protocole de communication, de sa box révolutionnaire, de ses structures http etc.. Bref, « c’est moi qui ait la bonne solution et les autres n’ont qu’a s’adapter ».

king

Alors heureusement, un peu d’intelligence à effleurer ce microcosme car la plupart des solutions « tout-en-un » intègre des api permettant d’interagir via des requêtes http.Ne vous réjouissez tout de même pas trop vite, chaque API est différente (REST (ou pas), SOAP (ou pas), LUA_API_QUEJESUISSEULEACOMPRENDRE(c), etc..)
Parce que s’il vous prend l’idée saugrenue (ou pas…) de faire discuter votre box Fibaro avec un RFXtrx branché sur votre VeraLite ou votre PC, vous allez y passer un peu de temps…

Ne soyez pas médisant, j’ai pris la solution la plus simple :D et ce n’est qu’un exemple très basique, j’aurais pu pousser le concept jusqu’à exiger que je puisse communiquer via mon smartphone avec Tasker qui appelle ma centrale MyFox, qui interroge le module fibaro relié à mon eedomus en fonction des sondes de températures dont les données remontent sur mon RFXCOM Lan en supposant que le module X10 relié à mon CM15 soit « on ».

why_trollcat

C’est complètement idiot, j’avoue, mais c’était un exemple un peu capillotracté du travail à fournir pour pouvoir faire discuter tout ses équipements entre eux.

Ne croyez pas que cela se borne à vos box domotiques, tout ceux qui ont un jour ajouter un serveur Asterisk pour gérer leur téléphonie a la maison se sont demandé « et comment que je discute entre ce serveur et ma box ???? »
Car oui mon bon monsieur, c’est la génération des objets connectés !!! Connectés, oui, mais à moi tout seul parce que le dialogue avec les autres, très peu pour moi !

Nous sommes tout les jours submergés de ces nouveaux objets qui doivent nous rendrent la vie plus facile, mais ne croyez pas qu’il va vous être facile de l’intégrer à votre monde, chacun parle sa propre langue et dans le terme « connecté » largement usité par les médias et les constructeurs, on parle rarement de communication, la faute à qui ?…

lol cat

Pour sauver ce petit monde de passionnés de domotique perdu dans les méandres d’un univers sourd et aveugle, il existe quand même des projets qui cherche à unifier ou interagir avec tout cela.

Nul besoin de vous présenter Imperihome qui risque fortement de devenir « LA » solution Android pour faire causer ensemble tout ça.

En protocole « natif », xPL (dont je suis un fervent défenseur :p (mais ça vous le savais déjà si vous êtes habitué de ce blog)), a du mal a se faire sa place malgré un concept simple et plutôt efficace.

Plus récemment, xAAL, prometteur, une grosse évolution de ce que l’on peut faire dans la communication des objets connectés et de la domotique en générale (quand on peut parler des copains :p  @jkxathome )

Bref, vous l’avez compris, quand on veut discuter simplement avec toutes nos passerelles domotiques ou nos objets connectés, cela devient vite très problématique parce qu’il faut tout changer selon avec qui vous souhaitez communiquer.

Dans mon billet précédent de cette « série », j’avais évoquer le fait que mon serveur domotique était une sorte de centralisateur des informations remontées par tout ce qui gravitait autout de lui.
Pour la communication, je suis partie du même constat.
Je ne veux pas m’adresser dans des langues différentes à chacun des périphériques, mais uniquement à une « porte d’entrée » et dans un langage compréhensible.

Un des exemples les plus démonstratifs est le dernier projet dont je vous avais fait part, api.domogeek.fr.
Vous envoyez une requête simple pour connaître une information basique et publique sans vous soucier des méthodes différentes d’appels uniques à chacune de ses informations (les dates de vacances scolaires, la vigilance météo etc…).

Dans votre environnement domotique, cela doit être la même chose.
Un point d’entrée unique, structuré, défini, qui se chargera de discuter ensuite dans le langage de chaque périphérique.

La meilleure façon de mettre cela en place est une API de type REST.

La mise en oeuvre est simple et à la portée de tous (surtout si vous avez décider d’utiliser un vrai langage comme python (troll inside).

Une fois déployé, il devient facile pour tout vos scripts, applications smartphones, etc… de faire appel à cette API pour communiquer avec vos équipements sans vous souciez de vous rappeler comment doit s’écrire la requête http vers tel ou tel module.

Prenons l’exemple du lancement d’une scène sur une VeraLite.

Si je dois interroger directement la VeraLite par http, ma requête ressemblera à cela :

http://vera:3480/data_request?id=lu_action&serviceId=urn:micasaverde-com:serviceId:HomeAutomationGateway1&action=RunScene&SceneNum=1

(facile à retenir, hein ? :p)

Imaginons maintenant que l’on écrive une simple fonction en python pour cela :

def setscene(device):
  url = 'http://vera:3480/data_request?'
  values = {'output_format' : 'text', 'id' : 'lu_action','serviceId': 'urn:micasaverde-com:serviceId:HomeAutomationGateway1', 'action' : 'RunScene', 'SceneNum' : device }
  try:
    data = urllib.urlencode(values)
    req = urllib2.Request(url+data)
    sendrequest = urllib2.urlopen(req)
    responsefromvera = sendrequest.read()
    if responsefromvera != "OK":
      return web.notfound()
      return "200 SUCCESS"
  except Exception, detail:
    print "Error ", detail

Maintenant, codons une API Rest toute bête (attention c’est du brut de fonderie bien crado) :

#!/usr/bin/python
# Gruik coded by GuiguiAbloc
import urllib, urllib2, web, re
def scenevera(device):
  url = 'http://vera.styx.net:3480/data_request?'
  values = {'output_format' : 'text', 'id' : 'lu_action', 'serviceId' : 'urn:micasaverde-com:serviceId:HomeAutomationGateway1', 'action' : 'RunScene','SceneNum' : device }
  try:
    data = urllib.urlencode(values)
    req = urllib2.Request(url+data)
    sendrequest = urllib2.urlopen(req)
    responsefromvera = sendrequest.read()
    if responsefromvera != "OK":
      return web.notfound()
      return "200 SUCCESS"
  except Exception, detail:
    print "Error ", detail
 
web.config.debug = False
 
urls = (
'/scene/(.*)', 'scenes'
)
 
render = web.template.render('templates/', globals={'re':re})
app = web.application(urls, globals())
 
class scenes:
  def POST(self,uri):
    request = uri.split('/')
    if request == ['']:
      return web.badrequest()
    if request[0]:
      device = request[0]
      try:
        result = scenevera(device)
        return "200 SUCCESS\n"
      except:
        web.notfound()
 
if __name__ == '__main__':
app.run()

Démarrez votre script (python monscript.py), il écoutera par défaut sur le port 8080 et lancer une requête http de type « POST » (avec surement le meilleur outil sous linux pour contruire des appels http de toutes sortes, cURL) :

curl -XPOST http://localhost:8080/scene/13

Et hop, magique, la scène 13 est lancée :)

Maintenant, vous avez une base de données MySQL (par exemple) dans laquelle vous stockez amoureusement toutes les valeurs de températures de vos sondes Oregon.
Interrogeons simplement la dernière valeur dans votre BDD de la même façon.

D’abord la fonction, on va imaginer que votre table « sensor » contient les colonnes « sensorRoom » qui défini le nom de votre sonde et « sensorValue », la valeur enregistrée :

...
import MySQLdb
...
def tempdb(ID):
  try:
    if ID == "salon":
      ID = "TempSalon"
    if ID == "exterieur" or ID == "dehors" or ID == "ext":
      ID = "TempExt"
    conn = MySQLdb.connect('localhost', 'mabase', 'login', 'motdepasse')
    cur = conn.cursor()
    cur.execute("SELECT sensorValue from sensor where sensorRoom='%s' ORDER BY idx DESC limit 1" % ID )
    result = cur.fetchone()
    return result[0]
 
  except MySQLdb.Error, e:
    print "Error %d: %s" % (e.args[0], e.args[1])
    return None
  conn.close()

On l’inclut dans notre API Python et l’on rajoute les appels :

...urls = (
'/scene/(.*)', 'scenes',
'/temp/(.*)', 'temp'
)
...
class temp:
  def GET(self,uri):
    request = uri.split('/')
    if request == ['']:
      return web.badrequest()
    if request[0]:
      room = request[0]
      try:
        result = tempdb(room)
        return result
      except:
        web.notfound()

On lance le tout et on fait un appel :

curl http://localhost:8080/temp/exterieur
16.5

C’est quand même plus simple, non ?

Voici 2 exemples basiques qui nous permettent de communiquer simplement via un point d’entrée à divers équipements de notre domotique.

Gardez le contrôle, toujours, de votre environnement. Quelque soit les objets, périphériques, modules communicants qui seront et feront la vie de votre domotique, il vous appartient de maîtriser la communication avec eux. Établissez un point d’entrée unique dont vous détiendrez la syntaxe et le langage sans devoir dépendre du bon vouloir d’un constructeur.
Changer de fournisseur ou de technos ne doit pas être plus dur que modifier quelques lignes de votre interface de communication sans revoir l’intégralité de votre interface web ou de votre application smartphone.

Et puisque je suis dans ma période lolcats sur ce billet…

161432646-1161414097812Amusez vous bien :D

Ce billet a été posté dans domotique et taggé , , . Bookmark ce permalink.

12 commentaires sur “Domotique et Intelligence : la communication

  1. Y a un truc que je me demande, pourquoi du xpl et pas du m2m la différence pour tout c’est quoi ?

    Encore un bon article !!

  2. Le m2m est un concept général (plus marketing qu’autre chose puisque TCP/IP est du m2m…)
    xPL est un protocole de communication défini et standardisé (on peut même dire que c’est du m2m puisqu’il permet de faire discuter 2 machines ensemble).
    Bref, le m2m n’est qu’une vision du fait de faire communiquer des périphériques ensemble en utilisant un protocole de communication défini (la plupart du temps, des sockets tcp).
    merci :)

  3. Salut Guigui,

    Article très intéressant je partages ton avis sur la question et tu me retire les mots de la bouche c’est exactement ce que j’en pensais.

    Tu parles un moment du xPL (dont on avais un peu discuté ensemble la dernière fois sur IRC) qui pourrais peut être fédérer un peu tout ça selon toi (c’est du moins ce que j’interprètes), je serais curieux d’avoir ton avis sur thread le nouveau protocol (dont j’ai pas encore réussi à récupérer les specs d’ailleurs) ou de Jabber qui pourrait être pertinent également ?

    Concernant Asterisk, j’ai pas fait de tests pour l’intégrer à de la domotique mais le système d’AGI et les dialplans permettent quand même de faire pas mal de choses assez simplement je ne penses pas que ça soit si complexe que ça du coup mais je me trompe peut être.

    Je vais finir avec le script que tu proposes, ça fait longtemps que je réfléchis à un système similaire sans m’être réellement lancé dans le dev mais je penses qu’il serait intéressant de créer une passerelle agnostique (et modulaire) en python permettant de se dispenser de ces protocoles, le but serait du coup de faire un langage d’abstraction un peu comme tu le fait mais en plus poussé et plus généralisé. J’ai légèrement réfléchis à la conception mais mon manque de connaissances en python me fait peut être défaut en l’état mais ya vraiment moyen de faire quelque choses de bien (peut être en combinant un système de queue ou en utilisant du twisted).

    Très bon article encore une fois en tout cas !

    Romain.

  4. Merci Romain pour ton commentaire :)
    Je ne connais pas Thread donc je ne pourrais pas te donner mon avis, je vais regardé. Concernant Jabber (ou plus précisément xmpp), il est déjà inclus dans certains équipements réseau (je pense a Arista par exemple) et donc oui, cela peut être une piste intéressante.
    Non Asterisk n’est pas difficile a implémenter, c’est juste que les AGI, bah ca discute qu’avec Asterisk, c’est le but de ce billet. D’ailleurs, j’ai développé un module xPL pour Asterisk qui se base sur ses AGI (https://github.com/guiguiabloc/xPL-PyHAL/blob/master/tools/Asterisk2xPL.agi)

  5. Et concernant ton systeme agnostique et modulaire, c’est ce que j’ai développé chez moi. C’est la version lourde de ce que j’explique ici, plus le centralisateur et du Redis entre autre pour le cache et les messages Push (et plein de bonne chose bien sympa, mais il me faudrait beaucoup de billets pour tout expliquer :D )

  6. Ah oui exact xmpp est plus juste j’avais zappé le nom j’ai fait un petit raccourcis avec Jabber :) Merci pour tes réponses compte tu publier ton centralisateur ou c’est beaucoup trop spécifique à ton installation, je serais curieux de voir comment tu l’as implémenter du coup (à moins que ça correspond à ton repo xPL-PyHAL que j’ai pas encore eu trop le temps de regarder ?). Il y a également les alliances qui se forme en (comme la AllSeenAlliance par exemple) et qui risque de se battre pour un « framework ».

  7. xPL-PyHAL est effectivement une version allégée de mon centralisateur. Ce n’est pas évident de le publier entièrement car il est assez spécifique à mon environnement et la partie système de procédure de raisonnement est plutot complexe.
    Mais je distille de ci de là des briques :)

  8. Comme d hab, un article pour lequel je suis a 100% ok sur la forme et dont je ne comprend rien sur le fond ^^. Si je suis contre l uniformité en general, un language commun est, je pense et l ecris depuis longtemps, le seul moyen de faire decoller un projet et pas ce tirage de bourre perpetuel dont seul lactionnaire est gagnant mais ni le client a court terme ou meme l entreprise a long terme. Les exemples economiques sont legions.

  9. Merci de focaliser tant d’idées pour homogénéiser la domotique.
    Je ne suis pas dans la domotique généraliste, mais spécialisé dans la gestion d’énergie renouvelable thermique avec l’automate programmable UVR1611 de ta.co.at et j’en ai marre de leur système de modules fonctionnels blindés. Ils vont sortir un nouveau modèle avec écran tactile couleur mais je crains que le système soit aussi bridé que le précédent: interface ethernet en option trop chère, communication inter-modules propriétaire sur bus CAN, programmation graphique à base de modules précompilés non modifiables… alors que tous les bâtiments/bureaux d’études/plombiers-chauffagistes/geeks n’ont pas les mêmes besoins et façons de travailler.
    Alors j’ai très envie d’écrire une bibliothèque de ces fonctions de gestion thermique et fluidique de bâtiments.
    Mais quel(s) langage(s) apprendre (Python, Erlang…) ?
    Merci pour tout conseil.

  10. Le choix d’un langage est surtout lié à la facilité avec laquelle tu es à l’aise avec, mais aussi à sa portabilité et son usage.
    Python est un excellent langage, portable et facilement abordable.
    Erlang est très puissant en temps réel et en performance (c’est pour cela qu’on le trouve beaucoup dans l’embarqué) mais il est beaucoup plus difficile à appréhender que python.
    Bref, ce n’est pas un choix facile et je n’ai pas la réponse toute prête mais si je devais donner mon avis, pour de l’automatisme plus industriel, je pencherais pour Erlang.