Gérer la présence grâce à son téléphone.

Si vous vous êtes lancé dans la domotique, il y a fort à parier qu’un jour ou l’autre vous ayez était confronté au problème de la présence. En effet comment est-il possible de déterminer de manière efficace si quelqu’un est présent ou non dans le domicile ? Cette notion devient vite primordiale dès lors que vous concevez vos scénarios. J’avais déjà fait un article qui traitait de toutes les subtilités de la présence, je ne vais donc pas revenir là-dessus. Aujourd’hui nous allons nous intéresser à la mise en pratique, au côté technique quoi 🙂

Objectif.

Le but est on ne peut plus simple :
Je veux que ma box domotique (Jeedom) soit informée en temps réel (à 5 minutes près en fait) si je suis présent au domicile ou pas. Et idem pour ma copine ! Cette condition est très pratique dans bon nombre de scénarios (chauffage, lumière, volet…). Je n’aurais même pas besoin de l’afficher sur le dashboard car l’info visuelle ne me sera pas utile (a priori j’arrive encore à savoir si je suis chez moi et si je suis seul ou pas…:p).

Principe.

Dans mon cas, se baser sur la connexion wifi des téléphones portables est ce qui m’a semblé le plus logique. Nous avons chacun un téléphone que nous avons en permanence avec nous, pas d’enfants, et pas spécialement adepte des bracelets connectés (qui sont une bonne alternative si vous êtes un utilisateur assidu). Donc :

  • Si le téléphone est connecté au wifi du domicile : Présent.
  • Si le téléphone est déconnecté du wifi du comicile : Absent.

La vérification sera faite toutes les 5 minutes.

Quand votre téléphone est connecté au réseau wifi, il obtient une adresse IP qui « appartient » à votre réseau et qui sert d’identifiant logique sur ce même réseau. En général, elle est choisie de manière automatique mais on peut très bien la définir manuellement (vu qu’elle est logique…).
Exemple d’adresse IP : 192.168.1.5
Mais la carte wifi de votre téléphone dispose également d’une adresse MAC, qui elle est physique et ne peut être changée.
Exemple d’adresse MAC : 0A:B3:DD:C4:87:3D

Il existe une commande de diagnostique bien connu des administrateurs réseau qui permet d’interroger une adresse IP et en cas de réponse d’en déduire que l’équipement est bien présent : la commande PING.

On pourrait basiquement penser qu’il suffirait de récupérer l’adresse IP de notre téléphone et de la « pinguer » toutes les 5 minutes mais ce n’est pas si simple car si sur le papier cette solution convient parfaitement, elle montre vite ses limites car certains téléphones n’autorisent pas la réponse au ping ou, pour préserver votre batterie, coupent l’interface wifi pendant une durée plus ou moins longue dès lors que votre smartphone est en veille.

Je lisais un article qui préconisait l’utilisation de arp-scan plutôt que ping. Pourquoi ? Car arp-scan utilise les requêtes ARP là ou ping va utiliser le protocole ICMP. Concrètement ARP ne sera pas soumis aux mêmes contraintes car il opère sur une couche plus basse (cf. modèle OSI-TCP/IP). Arp-scan va scanner l’ensemble du réseau local et va comparer les réponses avec l’adresse MAC qu’on lui aura demander de vérifier pour en déduire si le téléphone est bien connecter au wifi ou non.

Vous trouverez les informations d’adresse IP et MAC dans les paramètres wifi de votre téléphone :

 

Vous aurez besoin de récupérer l’adresse MAC de votre téléphone.

Comment qu’on fait ?

La mise en place se fera en 2 étapes :

  • Création du script qui va mettre à jour les états.
  • Création du module de présence et automatisation de l’exécution du script dans Jeedom.

Le Script:

J’ai développé le script en python mais si vous êtes plus à l’aise en bash (ou autre), libre à vous de l’adapter. L’idée en tout cas est assez simple. Tester si les équipements sont présents ou pas et en fonction du résultat, exécuter l’URL de mise à jour du statut.

Voilà le script avec les commentaires :

#!/usr/bin/python
# -*- coding: utf-8 -*-

# IMPORTS 
import urllib
import time
import commands

# FONCTIONS
def maj_status(id): # Fonction qui sera appelée pour mettre à jour le status. On lui donne l'id a mettre à jour
   # On instancie une variable pour reexecuter l'url en cas d'echec
   retry = 0
   # On execute l'url de l'API avec l'id envoye et on reessaye 3 fois tant que le code retourné n'est pas 200 (OK en HTTP)
   while urllib.urlopen("http://<IP SERVEUR JEEDOM>/core/api/jeeApi.php?apikey=<VOTRE CLE API>&type=cmd&id="+id).getcode() != 200 and retry <= 2:
      time.sleep(2)
      retry += 1

# MAIN
# On definit la liste qui va inclure les equipements a tester. Ici 2 téléphones en indiquant l'adresse MAC de chacun (l'ip ne me sert pas pour le moment). Ainsi que les id jeedom.
liste={}
liste["arnaud"]={"ip":"192.168.1.5","mac":"78:f8:82:a1:a4:2b","present":"918","absent":"919"} # Adapter avec vos ID/MAC/IP
liste["jen"]={"ip":"192.168.1.4","mac":"CC:20:E8:AA:80:35","present":"921","absent":"922"} # Adapter avec vos ID/MAC/IP

# On fait une boucle pour chaque entrée de la liste
for prenom,info in liste.items():
   # On exécute la commande arp-scan             
   # On grep sur la MAC pour voir si on a un résultat et on compte (wc -l) le nombre de ligne (si 1 ligne alors il y a bien une entrée et on mets le status à jour avec l'id présent, sinon on mets à jour avec l'id absent).      
   # On exécute la fonction de mise à jour du status
   result= commands.getoutput("sudo arp-scan -l -g -T " + info["mac"] + " -t 800 | grep -i " + info["mac"] + " | wc -l")
   if result == '1':
      maj_status(info["present"])
      time.sleep(3)
   else:
      maj_status(info["absent"])
      time.sleep(3)

Pensez à remplacer :

  • L’IP du serveur Jeedom dans l’URL.
  • Votre clé API (ici si vous ne savez pas la récupérer).
  • L’adresse IP/MAC de vos téléphones à tester.
  • Les ID de présence et absence (on verra après comment les récupérer).

Maintenant pour créer le script :

Connectez vous en SSH sur votre serveur Jeedom. On installe arp-scan :

$ sudo apt-get install arp-scan

On crée notre script (vous pouvez choisir un autre endroit) :

$ sudo nano /var/www/html/plugins/script/core/ressources/arp-scan_jeedom.py

On indique que c’est www-data le propriétaire du fichier :

$ sudo chown www-data:www-data /var/www/html/plugins/script/core/ressources/arp-scan_jeedom.py

On rend le fichier exécutable par le propriétaire :

$ sudo chmod u+x /var/www/html/plugins/script/core/ressources/arp-scan_jeedom.py

Le fichier est maintenant exécutable par www-data (l’utilisateur système qui exécutera le script depuis Jeedom), en revanche le script fait appel à la commande « arp-scan » qui elle n’est pas autorisée a être executée par www-data.

On édite les paramètres sudo pour valider que www-data peut bien exécuter des commandes en tant que root :

$ sudo visudo -s

On ajoute la ligne si elle n’y est pas déjà :

www-data ALL=(ALL) NOPASSWD: ALL

Voilà on devrait être prêt a executer notre script depuis Jeedom. Il faudra juste qu’on édite le script à la fin quand on aura récupéré les ID de présence et d’absence.

Côté Jeedom.

Avant tout, vous aurez besoin du plugin gratuit « Script » et « Virtuel ». Donc installez les si besoin.

On commence par créer un objet virtuel (Menu Plugins >> Programmation >> Virtuel). Je l’ai appelé « Présence ». L’onglet « Equipement » n’a pas d’importance :

Et maintenant les commandes !

Il faut créer 2 commandes « infos » qui correspondront aux états présent ou absent (1 ou 0) pour chaque téléphone (Je vous conseille de les historiser). Et 4 commandes « d’actions » qui permettent de mettre à jour les commande d’états. Attention à bien faire référence à la commande d’état dans les commandes d’actions.

Les ID des commandes sont ceux indiqués dans la colonne de gauche. C’est ceux là qu’il faudra reporter dans le script que l’on a crée plus tôt.

Maintenant, il ne nous reste plus qu’à faire en sorte que le script s’exécute de manière récurrente. Pour cela on va utiliser le plugin « Script » (menu Plugins >> Programmation >> Script) et créer un nouvel objet. C’est la partie « auto-actualisation » qui va nous permettre de le rendre récurent. La syntaxe est simplement celle utilisée par crontab donc pour une exécution toutes les 5 minutes il faut définir « */5 * * * * » :

Pour la commande, il faut indiquer le chemin absolue du script et c’est tout :

Vous pouvez vérifier que tout fonctionne bien en activant/désactivant le wifi sur votre téléphone et en allant dans « Analyse >> Historique« , récupérer le graphe d’état et voir si les valeurs se mettent bien à jour !

Je peux maintenant utiliser la notion de présence dans les scénarios. Les valeurs à tester sont bien évidemment « 0 » pour absent et « 1 » pour présent.
Voilà un scénario qui ne sert strictement à rien mais juste pour que vous voyez à quoi ça ressemble dans l’utilisation :

A bientôt 🙂

6 commentaires

  1. Parfait. A noter qu’il existe également un plugin « Networks » qui permet aujourd’hui de faire cela de manière native sous Jeedom (fixer l’adresse IP du téléphone et c’est parti)

  2. Merci beaucoup pour ce tuto ! Encore une fois tout fonctionne à merveille ! Ca ouvre encore plus de perspective sur Jeedom 🙂

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

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