Les batteries en Z-Wave

La version de Domoticz v2152 généralise la récupération par Domoticz de l’état des batteries des périphériques Z-Wave.

Certains de nos équipements étant relativement inaccessibles,

Voyons comment récupérer le % de batteries restant et se faire avertir en dessous d’un seuil, histoire d’avoir le temps de changer les piles.

Ce pourcentage est visible depuis le menu de configuration des dispositifs.

Batt_levelC’est celui ci que nous récupérerons grâce à un script python qui alimente un widget « Pourcentage » auquel nous pourrons associer des notifications.

N.B les versions récentes de Domoticz (>2563 de Juin 2015) incluent nativement ce contrôle automatique, utilisez cet article pour en savoir plus.

 I – Domoticz

Commençons par créer un virtual sensor Pourcentage

Comme d’habitude dans « Matériel » et « Create virtual sensor » créons un capteur « Pourcentage »

virtual sensorPuis dans l’onglet des dispositifs, utiliser la flèche verte pour le nommer et le « pousser » dans l’onglet. Noter son Idx (38 ici)

idx_domoticz

Récupérons l ‘IDX du périphérique Z-wave pour lequel l’etat des batteries m’intéresse , ici 105.2014-12-11 13_11_55

2 – Prérequis

L’idée est d’interroger Domoticz pour récupérer l’information sur la batterie de ce composant z-wave.

On utilise l’API Json de Domoticz qui renvoie l’état d’un périphérique et comme depuis la version 2152 on a le % de batterie on peut traiter cela facilement.

L’url interrogée est celle ci : avec IDX qui est la valeur du périphérique Z-Wave

Donc si dans votre navigateur vous lancez un

http://ip:port/json.htm?type=devices&rid=IDX_ZWave_quivabien

Vous obtenez cela :

On voit que c’est le terme « BatteryLevel » qui contient le niveau des batteries et qu’il y a un guillemet,espace,deux point avant la valeur.

Bien,

3 – Le script de récupération

Le script python nécessite la bibliothèque requests  un sudo pip install requests fera l’affaire. Si le module pip n’est pas présent : sudo apt-get install python-pip

Dans le script on peut placer debug=1 pour voir ce que l’on reçoit de Domoticz.

On y définit :

  • l’adresse et le port Domoticz, l’Idx du Z-wave a interroger,
  • l’idx du virtual sensor, le terme a rechercher dans la chaine envoyée par Domoticz (BatteryLevel) attention aux majuscules/minuscules.
  • N.B ce script doit pouvoir extraire n’importe quoi de n’importe quelle url JSON Domoticz dans le bloc JSON ‘result’.
#!/usr/bin/python
# -*- coding: utf-8 -*-


# la 2eme version du script python pour les batteries
# utilise le dict JSON que renvoie Domoticz
# Domoticz renvoie 2 pavés de données ,1 pave concernant les géneralités (long/lat, status ...)
# on peut aller chercher ces données par un r[terme] si les données sont dans la partie haute (avant le result[
# 1 autre pavé qui content les datas spécifiques au capteur en question , ces valeurs sont dans la liste result
# on utilise alors r['result'][0][terme] pour aller chercher dans le dict de la liste result

# il faut le module requests
# sudo pip install requests

import time
import requests
from requests.auth import HTTPBasicAuth

############# Parametres #################################


#debug = 1 on affiche les chaines de caracteres recues
debug=1


#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# les parametres de Domoticz
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

domoticz_ip='192.168.1.81'
domoticz_port='8080'
user=''
password=''

# l'idx du peripherique ZWave a interroger pour batterie (cf Idx Domoticz)
periph_zwave_idx='105'


#terme a rechercher
terme='BatteryLevel'

# ici l'idx Domoticz du widget a alimenter avec la valeur lue
# un widget pourcentage est adatpté pour les capacité des batteries
idx_widget_pourcent='28'

# fin du parametrage #


###############  fin des parametres #############################
###############  ce qui suit est repute fonctionner ############

def maj_widget(valeur_batterie):
    requete='http://'+domoticz_ip+':'+domoticz_port+json_url_text1+idx_widget_pourcent+json_url_text2+valeur_batterie
    r=requests.get(requete,auth=HTTPBasicAuth(user,password))
# l URL Domoticz a interroger pour recuperer les infos est type=devices&rid=XXX

json_url1='/json.htm?type=devices&rid='
requete='http://'+domoticz_ip+':'+domoticz_port+json_url1+periph_zwave_idx


# l URL Domoticz pour le widget virtuel
json_url_text1='/json.htm?type=command&param=udevice&idx='
json_url_text2='&nvalue=0&svalue='
#http://IP:PORT/json.htm?type=command&param=udevice&idx=mon_idx&nvalue=0svalue=POURCENTAGE

##### main ##

result={}
r=requests.get (requete).json()
valeur_batterie=str(r['result'][0][terme])

if debug==1:
    print r
    print valeur_batterie

maj_widget(valeur_batterie)

adaptez ce qui est nécessaire, puis un chmod +x sur le script pour le rendre exécutable.

Utilisez l’option debug=1 pour consulter les messages envoyés par Domoticz et ce que le script décode.

N.B : En  python 3 pensez à parenthèser les print en bas et à modifier la ligne

r=requests.get (requete).json()

en

r=requests.get (requete).json

 4 – Les notifications

Il suffit maintenant d’établir une notification sur ce composant pour être averti à bon escient.

Dupliquez et adaptez ce script pour chaque capteur dont vous voulez suivre la consommation.

5 – Déclenchement régulier

Utiliser crontab -e pour déclencher votre script une fois par jour.

Pour toute question technique concernant cet article, veuillez utiliser les forum situés à https://easydomoticz.com/forum/
Posted in domoticz, python, scripts and tagged , , , , .

10 Comments

  1. Bonjour,

    Merci pour ce tuto, mais quand j’essaie j’ai l’erreur suivante:

    Traceback (most recent call last):
    File « ./niv_bat.py », line 71, in <module>
    r=requests.get (requete).json()
    File « /usr/local/lib/python2.7/dist-packages/requests/models.py », line 805, in json
    return complexjson.loads(self.text, **kwargs)
    File « /usr/lib/python2.7/json/__init__.py », line 326, in loads
    return _default_decoder.decode(s)
    File « /usr/lib/python2.7/json/decoder.py », line 365, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
    File « /usr/lib/python2.7/json/decoder.py », line 383, in raw_decode
    raise ValueError(« No JSON object could be decoded »)
    ValueError: No JSON object could be decoded

    Avez-vous une idée de ce qui ne va pas ?

    Merci d’avance

  2. Bonsoir
    Tu n’as pas indiqué correctement l adresse ip , le port de Domoticz ou tu n’as pas indiqué le bon idx de ton matériel

  3. Bonsoir Patrice,

    Merci de ta réponse mais à priori, tous les paramètres sont corrects (IP du raspi Domiticz, le port, l’idx du périph zWave, l’idx du widget, le terme recherché). J’ai testé l’url générée (en la récupérant avec un print) dans mon navigateur et je récupère bien le pavé de données json…

    D’autres idées ?

    Merci d’avance

     

  4. Bonjour
    L’erreur renvoyée dit que le JSON est mal formé, je pensais vraiment à une erreur d’idx

    Si tu modifie la partie basse du script comme cela

    ##### main ##

    result={}
    print result
    r=requests.get (requete).json()
    print r
    #valeur_batterie=str(r['result'][0][terme])
    #if debug==1:
    # print r
    # print valeur_batterie
    # ma=raw_input ('entrez valeur')

    #maj_widget(valeur_batterie)

    Que s’affiche t’il ?

    sinon :
    Quelle version de python
    quelle version de Domoticz
    Windows ou Raspberry

  5. Bonsoir Patrice,

    Avec la modif, voici ce qui s’affiche :

    (‘requete 2 = ‘, ‘http://192.168.0.26:8080/json.htm?type=devices&rid=72’)
    {}
    Traceback (most recent call last):
    File « ./niv_bat.py », line 84, in <module>
    r=requests.get (requete).json()
    File « /usr/local/lib/python2.7/dist-packages/requests/models.py », line 805, in json
    return complexjson.loads(self.text, **kwargs)
    File « /usr/lib/python2.7/json/__init__.py », line 326, in loads
    return _default_decoder.decode(s)
    File « /usr/lib/python2.7/json/decoder.py », line 365, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
    File « /usr/lib/python2.7/json/decoder.py », line 383, in raw_decode
    raise ValueError(« No JSON object could be decoded »)
    ValueError: No JSON object could be decoded

    Quand je copie http://192.168.0.26:8080/json.htm?type=devices&rid=72 dans un navigateur, j’obtiens bien

    {
       "ActTime" : 1447105989,
       "ServerTime" : "Nov 09 2015 22:53:09",
       "Sunrise" : "07:52:00",
       "Sunset" : "17:19:00",
       "result" : [
          {
             "AddjMulti" : 1.0,
             "AddjValue" : 0.0,
             "BatteryLevel" : 0,
             "CustomImage" : 0,
             "Data" : "18.9 C",
             "Favorite" : 1,
             "HardwareID" : 8,
             "HardwareName" : "RaZberry",
             "HaveTimeout" : false,
             "ID" : "0401",
             "LastUpdate" : "2015-11-09 20:06:30",
             "Name" : "Température Entrée",
             "Notifications" : "false",
             "PlanID" : "0",
             "Protected" : false,
             "ShowNotifications" : true,
             "SignalLevel" : 12,
             "SubType" : "TFA 30.3133",
             "Temp" : 18.90,
             "Timers" : "false",
             "Type" : "Temp",
             "TypeImg" : "temperature",
             "Unit" : 1,
             "Used" : 1,
             "XOffset" : "0",
             "YOffset" : "0",
             "idx" : "72"
          }
       ],
       "status" : "OK",
       "title" : "Devices"
    }
    
    Sinon, j'utilise un Raspi :
    - Version Python : 2.7.3
    - Version Domoticz : 2.2563
    
    
  6. Bonsoir Patrice,

    Et voici (j’ai laissé les dernières modifications demandées et plein de print pour débugger) :

     

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

    # la 2eme version du script python pour les batteries
    # utilise le dict JSON que renvoie Domoticz
    # Domoticz renvoie 2 pavés de données ,1 pave concernant les géneralités (long/lat, status …)
    # on peut aller chercher ces données par un r[terme] si les données sont dans la partie haute (avant le result[
    # 1 autre pavé qui content les datas spécifiques au capteur en question , ces valeurs sont dans la liste result
    # on utilise alors r[‘result’][0][terme] pour aller chercher dans le dict de la liste result

    # il faut le module requests
    # sudo pip install requests

    import time
    import requests

    ############# Parametres #################################

    #debug = 1 on affiche les chaines de caracteres recues
    #debug=0
    debug=1

    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # les parametres de Domoticz
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    domoticz_ip=’192.168.0.26′
    domoticz_port=’8080′

    # l’idx du peripherique ZWave a interroger pour batterie (cf Idx Domoticz)
    periph_zwave_idx=’72’

    #terme a rechercher
    terme=’BatteryLevel’

    # ici l’idx Domoticz du widget a alimenter avec la valeur lue
    # un widget pourcentage est adatpté pour les capacité des batteries
    idx_widget_texte=’82’

    # fin du parametrage #

    ###############  fin des parametres #############################

    def maj_widget(valeur_batterie):
    requete=’http://’+domoticz_ip+’:’+domoticz_port+json_url_text1+idx_widget_texte+json_url_text2+valeur_batterie

    if debug==1:
    print(‘valeur_batterie = ‘, valeur_batterie)
    print(‘requete 1 = ‘, requete)

    r=requests.get (requete)

    # l URL Domoticz a interroger pour recuperer les infos est type=devices&rid=XXX

    json_url1=’/json.htm?type=devices&rid=’
    requete=’http://’+domoticz_ip+’:’+domoticz_port+json_url1+periph_zwave_idx

    if debug==1:
    print(‘requete 2 = ‘,requete)

    # l URL Domoticz pour le widget virtuel
    json_url_text1=’/json.htm?type=command&param=udevice&idx=’
    json_url_text2=’&svalue=’
    #http://IP:PORT/json.htm?type=command&param=udevice&idx=mon_idx&svalue=POURCENTAGE

    ##### main ##

    result={}
    print result

    #if debug==1:
    #    print(‘requete 3 = ‘,requete)

    r=requests.get (requete).json()
    print r
    #valeur_batterie=str(r[‘result’][0][terme])

    #if debug==1:
    #    print r
    #    print valeur_batterie
    #    ma=raw_input (‘entrez valeur’)

    #maj_widget(valeur_batterie)

     

    Merci de ton aide.

  7. Bonjour,

    J’ai remis ici à jour une version modifiée du script python , j’ai testé chez moi et cela fonctionne correctement
    supprime le contenu de ton fichier python et colles y le script ci -dessus

    Fais attention de créer un widget Pourcentage et non pas texte comme il était marque dans le script python
    J’attends de tes nouvelles

  8. Bonsoir Patrice,

    Après modification du script avec ta mise à jour, j’avais toujours la même erreur !

    En débuggant, je me suis aperçu que la requète « requests.get (requete) » retournait « <Response [401]> ».

    Après quelques recherches sur internet, j’ai trouvé que « <Response [401]> » était lié à un problème d’autorisation/d’identification. Et là TILT, je me suis rappelé que j’avais activé la sécurité de Domoticz avec un identifiant et mot de passe (dans Réglages \ Paramètres \ Sécurité).

    Pour résoudre ce problème j’ai juste rajouté l’adresse IP de mon raspi Domoticz dans  « Réseaux locaux (pas d’identifiant/mot de passe à fournir): » dans Réglages \ Paramètres. Et là BINGO, ça a fonctionné !

    Bref, j’espère que le problème que j’ai rencontré et sa résolution serviront à d’autres.

    En tout cas, un GRAND merci Patrice pour ton aide et ta persévérance.

     

  9. Bonjour
    Bien que je ne pense pas que cela soit cela qui ai fait des erreurs de decodage JSON , j’ai ajouté dans le script la partie identification que, en general , je n’oublie pas
    Merci du retour

Comments are closed.