Issu d’un article du wiki de Domoticz et comme le sujet court sur le forum depuis quelque jours, je vous propose ma traduction de l’article en question concernant la détection de présence basée sur une IP.
Objectif
Ce script activera un switch virtuel lorsque un périphérique IP sera présent dans votre réseau et l’inactivera dès que ce périphérique IP aura disparu du réseau. Vous pouvez utiliser cela pour savoir si une personne (et surtout son téléphone) arrive dans votre réseau (cela nécessite une IP fixe sur le smartphone)
Cela est utilisable également pour savoir si votre NAS, Serveur … est up ou down.
Bien sur on pourra déclencher les événements classiques (action on , action off,scripts ..)
Prérequis
Ce mécanisme ne fonctionne que pour des périphériques ayant une IP fixe ou un bail DHCP statique.
Utilisez la configuration de vos équipements, de votre routeur ou celle de vos smartphones dans les paramètres wifi pour assigner des ip fixes .
Exemple d’un routeur 788 technicolor OVH
Domoticz – Matériel et switches virtuels
Nous avons besoin d’un interrupteur dont l’état basculera en fonction de la présence d’une IP. Créons un interrupteur virtuel.
Il faut avoir activé auparavant un matériel de type « Dummy ».
Cette manip n’est à faire qu’une seule fois dans Domoticz pour activer les matériels virtuels et y accrocher tous nos interrupteurs (ou autres périphériques) virtuels.
- Dans l’onglet « Matériel » , donnez un nom à votre matériel virtuel ‘Dummy dev’ pour moi.
- Choisissez ‘Dummy (Does nothing, use for virtual switches only)’ dans la liste déroulante.
- Laissez ‘Délai d’attente des données’ à « Désactivé. Cliquez sur « Ajouter »
Créons l’interrupteur virtuel
Rendez vous dans l’onglet des interrupteurs, puis « Ajout Manuel » en haut à gauche.
- Choisissez le matériel virtuel crée plus haut
- Donnez un nom explicite
- Switch type sera ‘On/Off’
- Le Type ‘X10’. Pourr ‘House code’ and ‘Unit code’, choisissez n’importe quoi
- Laissez ‘Main Device’.
- Validez, il se rajoute dans la liste des interrupteurs
- En cliquant sur « Editer » ,on peut aussi cocher la case « Protégé » pour éviter les clicks manuels dans l’interface et ainsi n’autoriser que les scripts à agir sur ce switch.
Nous avons besoin du numéro de ce périphérique Domoticz.
Allez dans ‘Configuration’ puis ‘Dispositifs », retrouvez l’équipement en question en notez son ID.
Bien sur si il y a plusieurs smartphones refaites cette creation autant que nécessaire. Notez chaque fois le bon ID.
LE script
Pourquoi ce script ci plutôt que d’autres ?
Au lancement il vérifie que l’état actuel du périphérique est le même (ou pas) que l’état indiqué dans Domoticz puis il reste actif en permanence pour scruter le changement d’état.
L’intérêt de celui ci est qu’il prend 4 paramètres qui sont bien commodes :
./checkip.py 192.168.1.76 93 20 300
- L’adresse IP du périphérique à interroger (Ici ‘192.168.1.76’)
- L’ID du virtual switch (’93’)
- L’intervalle en secondes pendant lequel on interroge pour savoir si le périphérique est présent ou non (20).
- La ‘cool-down’ period (secondes). C’est le délai de non réponse du périphérique, si il ne répond pas dans ce délai, alors on décide qu’il est OFF (300).
- Si au bout de 300 secondes il ne réponds pas alors OFF
Copiez ce script dans le dossier \home\pi\domoticz\scripts\ sous le nom que vous voulez (checkip.py pour moi)
Changez juste l’adresse de votre Domoticz dans les settings et l’éventuel user/ motdepasse
# Settings for the domoticz server domoticzserver="192.168.2.1:8080" domoticzusername = "" domoticzpassword = ""
[codesyntax lang="python"]
#!/usr/bin/python # Title: check_device_online.py # Author: Chopper_Rob # Date: 27-10-2014 # Info: Checks the presence of the given device on the network and reports back to domoticz # URL : https://www.chopperrob.nl/domoticz/5-report-devices-online-status-to-domoticz # Version : 1.4 import sys import datetime import time import os import subprocess import urllib2 import json import base64 # Settings for the domoticz server domoticzserver="192.168.1.81:8080" domoticzusername = "" domoticzpassword = "" # DO NOT CHANGE BEYOND THIS LINE if len(sys.argv) != 5 : print ("Not enough parameters. Needs %Host %Switchid %Interval %Cooldownperiod.") sys.exit(0) device=sys.argv[1] switchid=sys.argv[2] interval=sys.argv[3] cooldownperiod=sys.argv[4] previousstate=-1 lastsuccess=datetime.datetime.now() lastreported=-1 base64string = base64.encodestring('%s:%s' % (domoticzusername, domoticzpassword)).replace('\n', '') domoticzurl = 'http://'+domoticzserver+'/json.htm?type=devices&filter=all&used=true&order=Name' if int(subprocess.check_output('ps x | grep \'' + sys.argv[0] + ' ' + sys.argv[1] + '\' | grep -cv grep', shell=True)) > 2 : print (datetime.datetime.now().strftime("%H:%M:%S") + "- script already running. exiting.") sys.exit(0) def domoticzstatus (): json_object = json.loads(domoticzrequest(domoticzurl)) if json_object["status"] == "OK": for i, v in enumerate(json_object["result"]): if json_object["result"][i]["idx"] == switchid and "Lighting" in json_object["result"][i]["Type"] : if json_object["result"][i]["Status"] == "On": status = 1 if json_object["result"][i]["Status"] == "Off": status = 0 return status def domoticzrequest (url): request = urllib2.Request(url) request.add_header("Authorization", "Basic %s" % base64string) response = urllib2.urlopen(request) return response.read() print (datetime.datetime.now().strftime("%H:%M:%S") + "- script started.") lastreported = domoticzstatus() if lastreported == 1 : print (datetime.datetime.now().strftime("%H:%M:%S") + "- according to domoticz, " + device + " is online") if lastreported == 0 : print (datetime.datetime.now().strftime("%H:%M:%S") + "- according to domoticz, " + device + " is offline") while 1==1: currentstate = subprocess.call('ping -q -c1 -W 1 '+ device + ' > /dev/null', shell=True) if currentstate == 0 : lastsuccess=datetime.datetime.now() if currentstate == 0 and currentstate != previousstate and lastreported == 1 : print (datetime.datetime.now().strftime("%H:%M:%S") + "- " + device + " online, no need to tell domoticz") if currentstate == 0 and currentstate != previousstate and lastreported != 1 : if domoticzstatus() == 0 : print (datetime.datetime.now().strftime("%H:%M:%S") + "- " + device + " online, tell domoticz it's back") domoticzrequest("http://" + domoticzserver + "/json.htm?type=command¶m=switchlight&idx=" + switchid + "&switchcmd=On&level=0") else: print (datetime.datetime.now().strftime("%H:%M:%S") + "- " + device + " online, but domoticz already knew") lastreported=1 if currentstate == 1 and currentstate != previousstate : print (datetime.datetime.now().strftime("%H:%M:%S") + "- " + device + " offline, waiting for it to come back") if currentstate == 1 and (datetime.datetime.now()-lastsuccess).total_seconds() > float(cooldownperiod) and lastreported != 0 : if domoticzstatus() == 1 : print (datetime.datetime.now().strftime("%H:%M:%S") + "- " + device + " offline, tell domoticz it's gone") domoticzrequest("http://" + domoticzserver + "/json.htm?type=command¶m=switchlight&idx=" + switchid + "&switchcmd=Off&level=0") else: print (datetime.datetime.now().strftime("%H:%M:%S") + "- " + device + " offline, but domoticz already knew") lastreported=0 time.sleep (float(interval)) previousstate=currentstate
[/codesyntax]
Dans un terminal dans le dossier \home\pi\domoticz\scripts , faites un chmod +x checkip.py.
Lancer ce script au boot de la machine
Dans un terminal,lancez crontab -e.
Dans l’écran ajoutez une ligne pour chaque périphérique à interroger
@reboot sudo /home/pi/domoticz/scripts/checkip.py 192.168.1.76 93 10 120 @reboot sudo /home/pi/domoticz/scripts/checkip.py 192.168.1.70 94 10 900
Faites CTRL O (pas zéro) puis entrée
Expérimentons
Tous les pc,serveurs, smartphones (android, ios) ne se comportement pas de la même façon , il faut ajuster la cool-down period (4eme valeur) en fonction de chaque matériel.
Car par exemple sur Ios , le Wifi est coupé quand l’écran est en veille, alors que sur Android non , le wifi est toujours ON, bref bricolez …
Ensuite déclenchez vos événements par les dispositifs esclaves, les action on/off, scripts,….
Bon jeu
salut,
D’abord bravo pour ce site !
J’ai essayé la méthode décrite ci-dessus et ça ne marche pas, du coup pour investiquer j’ai lancé la commande cron dans le terminal et celle-ci se solde par une erreur : local variable ‘status’ referenced before assignment. sur le site de chopper rob quelqu’un évoque le même problème mais je n’ai pas trouvé la solution !! si quelqu’un a une piste je suis preneur !
Par avance merci,
Bonjour,
Merci pour les compliments !
Pour l’erreur une idée me vient en relisant le script cherche la ligne
if json_object[« status »] == « OK »:
et remplace par
if json_object[« Status »] == « OK »:
le status avec un S majuscule et dis moi si c’est OK
Bonjour,
Je débute dans l’univers de la domotique. Je parcours donc les forums pour apprendre et voir les possibilités.
Tout d’abord, félicitation pour ton engagement et ton partage. Ce topic est particulièrement intéressant.
J’essaye de le mettre en place et je me pose 2 questions :
– A quoi sert le mode « protégé » que tu as défini dans l’interrupteur virtuel ?
– Le script est en place sur ma framboise. Il réponds bien au changement d’état de mon smartphone lorsque je coupe le wifi de ce dernier.
Cependant, l’info ne remonte pas dans domoticz.
Et effectivement, je ne vois pas par quel biais elle est censée remonter ??? (C’est précisément ma deuxième question)
Le script a beau être présent dans le dossier script de l’installation de domoticz, ne faut il pas le « brancher » à l’interrupteur virtuel et éventuellement déclarer des variables pour interfacer le script avec domoticz ?
Merci pour ton aide
J’
Merci pour les compliments.
Concernant le mode protégé il est dit dans l’article
Quand à la liaison entre le script et Domoticz, tu remarqueras que
1- dans le script tu as un bloc
ou tu dois placer IP, port, usr/password de ton Domoticz
2- Tu dois appeler le script avec 4 arguments : tels que précisés dans l’article
l’adresse IP du serveur que l’on veut tester,
numéro d’idx du virtual switch
nombre de secondes d’interrogation du peripherique IP
delai de non reponse
Voila j’espère que cela roulera comme cela sinon reviens faire un tour ici
Bonne soirée
Salut patrice,
je prends la suite de Sam
=> en remplaçant status par Status, d’autre soucis dans le script :
20:57:39- script started.
Traceback (most recent call last):
File « ./checkip.py », line 65, in <module>
lastreported = domoticzstatus()
File « ./checkip.py », line 46, in domoticzstatus
if json_object[« Status »] == « OK »:
KeyError: ‘Status’
Merci d’avance!
Bonsoir
L’erreur signifie qu’il n’a pas pu trouver ton Domoticz donc une erreur ici
# Settings for the domoticz server
domoticzserver= »192.168.1.81:8080″
domoticzusername = « »
domoticzpassword = « »
tu as oublie de changer, l’ip , le port , tu as mis un mot de passe …
Bonsoir
Merci pour ce script et ce tutoriel
Le script est copié, il fonctionne mais pas moyen de faire remonter l’info sur les interrupteurs
il reste toujours sur OFF
Merci d’avance
Bonjour
As tu changé les adreses IP de mon domoticz pourle tien ?
as tu mis des user et password dans ton domoticz?
que se passe t’il lorsque tu tapes directement en mode console le nom de ton script : des erreurs, rien ?
Bonjour
j’ai changé l’ IP et le compte domoticz
voici le retour de la commande
root@raspberrypi:/home/pi/domoticz/scripts# ./checkip.py 192.168.0.100 47 60 120
13:17:23- script started.
13:17:23- according to domoticz, 192.168.0.100 is online
13:17:24- 192.168.0.100 offline, waiting for it to come back
^CTraceback (most recent call last):
File « ./checkip.py », line 95, in <module>
time.sleep (float(interval))
KeyboardInterrupt
Merci pour ta réponse
et le crontab
*/10 * * * * /home/pi/domoticz/scripts/checkip.py 192.168.0.100 47 60 120
*/10 * * * * /home/pi/domoticz/scripts/checkip.py 192.168.0.104 48 60 120
Donc on est d’accord dans le script tu as modifie la ligne
– domoticzserver= »192.168.1.81:8080″ par l’adresse ip de TON domoticz
– 192.18.0.100 est l’adresse ip du telephone ou materiel dont tu testes la présence
– 47 est l’index du widget interrupteur qui devra basculer à ON
C’est ca ?
Ensuite tu n’a pas répondu à ma question de mot de passe et user de protection de Domoticz , il y en a ?
hello
oui, j’ai remplacé l’adresse ip par celle de mon domoticz, ajouté mon compte et mon mot de passe, je n’ai pas de user protection de domoticz
192.18.0.100 est l’adresse ip materiel et 47 est l’index du widget de l’interrupteur qui doit passer à on
voici le résultat de la commande :
pi@raspberrypi:~/domoticz/scripts$ ./checkip.py 192.168.0.100 47 60 120
19:29:32- script started.
19:29:32- according to domoticz, 192.168.0.100 is offline
19:29:32- 192.168.0.100 online, tell domoticz it’s back
^CTraceback (most recent call last):
File « ./checkip.py », line 95, in <module>
time.sleep (float(interval))
Merci
Laurent
Bonjour
oui c’est bizarre ici ça marche correctement et ça bascule bien l’interrupteur en question
je teste la présence de 192.168.1.93 , j’active l(interuupteur 112 au bout de 20 sec et 10 sec de delai de grace
j’ai joue a connecter/deconnecter mon telephone et tout se passe bien
pi@domoticz ~/domoticz/scripts $ ./checkip.py 192.168.1.93 112 20 10
10:13:56- script started.
10:13:56- according to domoticz, 192.168.1.93 is offline
10:13:56- 192.168.1.93 online, tell domoticz it's back
10:14:37- 192.168.1.93 offline, waiting for it to come back
10:14:38- 192.168.1.93 offline, tell domoticz it's gone
10:15:40- 192.168.1.93 online, tell domoticz it's back
essaie de mettre des print dans le programme python pour voir d’ou ca vient
hello
Maintenant, j’ai mis en place un script Lua et tout fonctionne correctement.
je continuerai à tester ton script plus tard, il doit marcher !!!
Merci pour ton aide
Bonjour,
Je viens pour donner la solution toute simple pour ceux qui quand il run dans le terminal ./checkip.py 192.168.0.100 47 60 120 et que tout ce passe à merveille à ce moment là et une fois le terminal fermé plus rien !
La solution uniquement dans le crontab -e à la place de
faites comme ceci
Vérifiez quand même que checkip.py a les bonnes permissions 755
Salut,
tout fonctionnait bien jusqu’à maintenant.
Je ne sais pas ce qu’il s’est passé, mais maintenant le script ne fonctionne plus.
Et quand je le lance à la main dans un terminal, j’obtiens tous ces messages d’erreurs… Et j’y comprends rien…
Une idée?
23:10:57- pid file exists
23:10:57- Seems to be an old file, ignoring.
23:10:57- script started.
Traceback (most recent call last):
File « ./presence_IP.py », line 102, in <module>
lastreported = domoticzstatus()
File « ./presence_IP.py », line 80, in domoticzstatus
json_object = json.loads(domoticzrequest(domoticzurl))
File « ./presence_IP.py », line 97, in domoticzrequest
response = urllib2.urlopen(request)
File « /usr/lib/python2.7/urllib2.py », line 154, in urlopen
return opener.open(url, data, timeout)
File « /usr/lib/python2.7/urllib2.py », line 437, in open
response = meth(req, response)
File « /usr/lib/python2.7/urllib2.py », line 550, in http_response
‘http’, request, response, code, msg, hdrs)
File « /usr/lib/python2.7/urllib2.py », line 475, in error
return self._call_chain(*args)
File « /usr/lib/python2.7/urllib2.py », line 409, in _call_chain
result = func(*args)
File « /usr/lib/python2.7/urllib2.py », line 558, in http_error_default
raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
urllib2.HTTPError: HTTP Error 401: Unauthorized
Bonjour,
ce message vous dit-il quelque chose ?
./checkip.py: 1: ./checkip.py: import: not found
./checkip.py: 2: ./checkip.py: import: not found
./checkip.py: 3: ./checkip.py: import: not found
./checkip.py: 4: ./checkip.py: import: not found
./checkip.py: 5: ./checkip.py: import: not found
./checkip.py: 6: ./checkip.py: import: not found
./checkip.py: 7: ./checkip.py: import: not found
./checkip.py: 8: ./checkip.py: import: not found
./checkip.py: 12: ./checkip.py: domoticzusername: not found
./checkip.py: 13: ./checkip.py: domoticzpassword: not found
./checkip.py: 16: ./checkip.py: Syntax error: word unexpected (expecting « ) »)
Merci de votre réponse éclairé 😉
Bonjour
Essaies de reprendre le script d’origine depuis cette page anglaise dans un nouveau fichier pour voir si cela ne vient pas de l’encodage du fichier
http://www.domoticz.com/wiki/Presence_detection
Merci pour cet article très intéressant!
Il y a cependant un truc que j’ai pas compris. A l’aide du crontab, tu semble lancer le script très fréquement. Or dans le script, il y a une boucle infini (1 ==1) donc le script ne va jamais se terminer. Mais alors pourquoi le lancer plusieurs fois? Dans l’état actuel, la raspberry doit alors lancer un nouveau script à chaque fois de manière infini, et donc augmentation des scripts qui tournent en parrallèle pour faire la même chose.
Bonjour
Oui tu as raison, j’avais oubliè de modifier l’article en question pour faire executer le script juste au reboot en utilisant le @reboot du crontab.
J’ai corrigè,
Merci de ta lecture attentive.
Bonjour,
Voici les messages d’erreurs lorsque je lance le script à la main.
Une idée?
Merci et merci pour ce tuto
pi@domoticz:~ $ /home/pi/domoticz/scripts/Perso/check_ip.py 192.168.0.203 15 60 300
23:06:23- script started.
Traceback (most recent call last):
File « /home/pi/domoticz/scripts/Perso/check_ip.py », line 64, in
lastreported = domoticzstatus()
File « /home/pi/domoticz/scripts/Perso/check_ip.py », line 52, in domoticzstatus
return status
UnboundLocalError: local variable ‘status’ referenced before assignment