Capteurs de température avec Domoticz sur un Raspberry Pi
2017-06-25
Mise à jour: 2018-01-02
Temperature Sensors - Take 2 (en anglais)

S'informer avant d'acheter est peut-être une bonne idée. Le capteur de température et d'humidité DHT11 fonctionne de 0°C à 50°C, ce qui n'est pas acceptable pour une installation dans un garage non chauffé où les températures en hiver plongent souvent sous le point de congélation. Ainsi, le DHT11 que j'ai acheté pour un moniteur de porte de garage intelligent sera remplacé par un DHT22 (AM2302) qui a une plage de température beaucoup plus large de -40°C à 80°C.

Ce serait un gaspillage de jeter un capteur de 1,25$ CDN. Pourquoi ne pas l'installer sur le Raspberry Pi qui héberge mon système de domotique? Il sera alors possible d'afficher les données dans Domoticz et éventuellement de garder un journal de la température et de l'humidité ambiante dans la maison.

Il existe de nombreuses descriptions sur le Web sur la façon de le faire. Mais la plupart supposent que la broche GPIO One-Wire par défaut sera utilisée. Malheureusement, elle est recouverte (mais pas utilisée!) par l'horloge en temps réel installée sur le même Raspberry Pi (voir Horloge en temps réel, DS3231, pour Domoticz sur le Raspberry Pi). D'autres recherches sur le Web ont révélé que le problème est facilement résolu sans recours à une modification matérielle.

J'ai aussi décidé de surveiller la température de Raspberry Pi. Cela semble particulièrement utile lors qu'on accélère la cadence du système.

Table des matières

  1. Activation de l'interface 1-Wire
  2. Installation de la bibliothèque DHTxx Python de Adafruit
  3. Installation d'un capteur de température dans Domoticz
  4. Python Script
  5. Température du processeur
  6. Surveillance de la température

  1. Activation de l'interface 1-Wire
  2. Les capteurs de température et d'humidité DHT11 et DHT22/AM2302 communiquent à l'aide du bus de communication 1-Wire. Il s'agit en fait d'une connexion à trois fils, la mise à terre et le courant sont nécessaires en plus de la ligne de données.

    Il semble qu'il ne soit plus nécessaire de modifier le fichier /boot/config.txt. Voir mon dernier billet lié à ce sujet, qui n'est disponible qu'en anglais: Removing Nuisance Messages in Raspberry Pi Syslog (Suppression des messages de nuisance du journal système de Raspberry Pi). Il n'est même pas certain que raspi-config devrait être invoqué.
    2018-01-02

    L'interface 1-Wire peut être activée avec l'utilitaire raspi-config. Cependant, il active l'interface 1-Wire uniquement sur la broche BCM 4 (broche physique 7). Il est nécessaire d'éditer le fichier config.txt dans le répertoire /boot pour utiliser une broche GPIO différente. Ajoutez une ligne à la fin du fichier ou modifiez la ligne dtoverlay=w1-gpio si 1-Wire est déjà activé. J'ai décidé d'utiliser la broche BCM 24 (broche physique 18) pour les données 1-Wire.

    pi@domo:~ $ sudo nano /boot/config.txt
    ... dtoverlay=w1-gpio, gpiopin=24

    J'ai choisi BCM 24 parce que les broches adjacentes sont 3,3V et la mise à terre ce qui simplifie la connexion.

               3v3 [17][18] BCM 24 - 1-wire
     BCM 10 (MOSI) [19][20] Mise à terre 0v

    Comme il s'agit d'une modification de config.txt, 1-Wire sera activé lors du prochain démarrage. Les impatients peuvent l'activer immédiatement

    pi@domo:~ $ sudo modprobe w1-gpio gpiopin=24
    Mais il s'agit d'une situation temporaire et 1-Wire ne sera pas activé sur BCM 24 automatiquement lors du prochain démarrage sans la modification de config.txt décrite ci-dessus.

    Note: Bien que la série de capteurs DHT utilise le protocole de communication à 1 fil, ils ne sont pas compatibles avec le protocole One Wire de Dallas qui permet à plusieurs dispositifs One Wire d'être connectés en parallèle. En fait, cela n'est pas possible avec les capteurs DHT, chacun doit disposer d'une broche de données dédiée.

    Reference: W1-GPIO - One-Wire Interface.

  3. Installation de la bibliothèque DHTxx Python de Adafruit
  4. Adafruit a créé quatre bibliothèques pour communiquer avec les capteurs de type DHTxx. J'ai utilisé la bibliothèque en Python. Git et le paquet de développement Python sont nécessaires pour l'installer. Le logiciel de contrôle de versions, Git était déjà installé sur mon Raspberry Pi; Je pense que c'est toujours le cas avec Raspbian.

    pi@domo:~ $ sudo apt-get install build-essential python-dev pi@domo:~ $ git clone https://github.com/adafruit/Adafruit_Python_DHT.git pi@domo:~ $ cd Adafruit_Pyt* pi@domo:~/Adafruit_Python_DHT $ sudo python setup.py install

    Une fois la bibliothèque installée, il est possible de tester que tout fonctionne de manière interactive. Voici un exemple.

    pi@domo:~ $ python Python 2.7.9 (default, Sep 17 2016, 20:26:04) [GCC 4.9.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import Adafruit_DHT >>> print(Adafruit_DHT.read(11, 24)) (None, None) >>> print(Adafruit_DHT.read(11, 24)) (None, None) >>> print(Adafruit_DHT.read(11, 24)) (50.0, 24.0) >>> print(Adafruit_DHT.read(11, 24)) (None, None) >>> exit() pi@domo:~ $

    Comme on peut le voir, la fonction de lecture peut retourner (None, None). Une explication possible de cette défaillance est qu'on n'a pas attendu les 2 secondes minimums requises entre lectures successives du DHT11. La bibliothèque fournit une fonction, read_retry, qui tentera jusqu'à 15 fois de lire les données du cap en attendant 2 secondes entre chaque essai. Ces valeurs par défaut peuvent être modifiées.

    Reference: How to Set Up the DHT11 Humidity Sensor on the Raspberry Pi.

  5. Installation d'un capteur de température dans Domoticz
  6. Il est maintenant temps de créer une température virtuelle + capteur d'humidité dans Domoticz. La première étape, si elle n'est pas déjà faite, est de créer un matériel "fictif". Ensuite, un capteur virtuel sera ajouté au matériel. Enfin, les valeurs du capteur seront modifiées avec l'API JSON pour s'assurer que tout fonctionne.

    Ajouter du matériel virtuel

    1. Cliquez sur l'onglet Réglages (Setup).
    2. Sélectionnez Matériel (Hardware) dans le menu déroulant.
    3. Entrez un nom pour le matériel; J'ai choisi Virtual.
    4. Pour le type, sélectionnez Dummy (Does nothing, use for virtual switches only) dans la liste déroulante.
    5. Cliquer sur le bouton Ajouter (Add). Le nouveau matériel, Virtual, sera ajouté dans le tableau au haut de la page:
      On ajoute ce matériel virtuel qu'une seule fois.

    Ajouter un capteur virtuel

    1. Cliquez sur le bouton Créer capteur virtuels (Create Virtual Sensors) dans le matériel virtuel nouvellement créé.
    2. Complétez les champs Nom (votre choix) et Type de capteur en sélectionnant Temp+Hum dans la fenêtre intitulée Create Virtual Sensor:
      Un message apparaîtra confirmant la création du capteur et indiquant qu'il peut être trouvé dans l'onglet des dispositifs.
    3. Pour voir cet onglet, cliquez sur l'onglet Réglages (Setup) puis sélectionnez Dispositifs (Devices) dans le menu déroulant.

      Notez le numéro de l'index (idx) du capteur virtuel qu'on doit utiliser plus loin.

    Vérification

    1. Afficher le capteur nouvellement créé en cliquant sur l'onglet Température . Si cet onglet n'est pas visible sur la page HTML, alors
      1. Cliquez sur l'onglet Réglage.
      2. Cliquez sur Paramètres dans la liste déroulante.
      3. Faites défiler la page  Système  vers le bas pour voir le groupe Onglets activés:
      4. Cochez Température.
      5. Faites défiler la page vers le haut et cliquez sur  Appliquer les paramètres .
      6. Cliquez sur l'onglet Température qui devrait être visible maintenant.
    2. L'image du capteur, telle qu'on peut voir à gauche ci-dessous, sera visible.
    3. Ouvrez un navigateur Web et entrez l'adresse suivante et la chaîne JSON
      http://192.168.0.22:8080/json.htm?type=command&param=udevice&idx=35&nvalue=0&svalue=21.2;76.7;1 S'il n'y a pas de problème, le statut sur la page retournée devrait être "OK".

      Puis, après un court délai, l'image du capteur devrait maintenant refléter les nouvelles valeurs pour la température, l'humidité et le niveau d'humidité.

      Au lieu d'utiliser un navigateur Web, un message MQTT peut être envoyé en supposant que le matériel MQTT a été installé dans Domoticiz.

      michel@hp:~$ mosquitto_pub -h 192.168.0.22-t "domoticz/in" -m '{ "idx" : 35, "nvalue" : 1, "svalue" : "21.2;76.7;1"}'

  7. Script Python
  8. A python script can read the sensor data using the Adafruit python DHT library and send on the values to Domoticz.

    pi@domo:~ $ mkdir pythons pi@domo:~ $ cd pythons pi@domo:~/pythons $ nano dht11.py
    #!/usr/bin/python import sys import Adafruit_DHT import urllib # parameters DHT_type = 11 OneWire_pin = 24 sensor_idx = 35 url_json = "http://192.168.0.22:8080/json.htm?type=command&param=udevice&idx=" verbose = 1 # set to 1 to print out information to the console # read dht11 temperature and humidity humidity, temperature = Adafruit_DHT.read_retry(DHT_type, OneWire_pin) # use Domoticz JSON url to update cmd = url_json + str(sensor_idx) + "&nvalue=0&svalue=" + str(temperature) + ";" + str(humidity) + ";0" hf = urllib.urlopen(cmd) if verbose > 0: print 'Sensor data: temperature = {0:0.1f}C, humidity = {1:0.1f}%'.format(temperature, humidity) print 'Uploaded to Pi: ' + cmd print 'Response: ' + hf.read() hf.close
    Téléchargez le fichier en cliquant sur le lien dht11.py avec le bouton droit de la souris.

    Ceci n'est qu'un premier brouillon, donc nous ne prendrons pas la peine de le rendre exécutable. Toutefois, il peut être testé facilement.

    pi@domo:~/pythons $ python dht11.py Sensor data: temperature = 24.0C, humidity = 48.0% Uploaded to Pi: http://192.168.0.45:9071/json.htm?type=command&param=udevice&idx=35&nvalue=0&svalue=24.0;48.0;0 Response: { "status" : "OK", "title" : "Update Device" }

    Notez le « ;0 » de fin dans l'URL JSON. C'est la valeur du paramètre HUM_STAT (niveau d'humidité?). Ses valeurs possibles sont de 0 à 3.

        0 = Normal
        1 = Agréable
        2 = Sec
        3 = Humide
    À droite de chaque valeur se trouve la chaîne affichée dans la première ligne du capteur sur l'onglet Température.

    En regardant sur le Web pour voir ce que d'autres ont fait, il semble que la plupart du temps, soit HUM_STAT est fixé à 0 comme dans le script ci-dessus, soit que l'on calcule une valeur en utilisant l'humidité relative:

    if humidity > 70: HUM_STAT = 3 elif humidity > 30: HUM_STAT = 1 else: HUM_STAT = 2

    Cette dernière approche n'est pas la meilleure. Selon le National Weather Service de la National Oceanic and Atmospheric Administration « si vous voulez une estimation juste de comment sec ou humide on se sent dehors, regarder le point de rosée au lieu de l'humidité relative ». Sans doute la NOAA a raison de préférer l'utilisation du point de rosée au lieu de l'humidité relative pour qualifier la perception de la sécheresse. Je reprendrai cette question plus tard.

  9. Température du processeur
  10. Le Raspberry Pi possède un capteur thermique intégré qui signale régulièrement la température du processeur. La mesure est écrite dans un fichier; un examen de son contenu montre que la température est rapportée en millièmes de degrés Celsius.

    pi@domo:~ $ cat /sys/class/thermal/thermal_zone0/temp 42236

    La température du processeur est donc 42.236°C.

    On peut aussi demander à l'utilitaire vcgencmd d'afficher la températur en degrés.

    pi@domo:~ $ vcgencmd measure_temp temp=42.2'C

    Il est assez facile d'écrire un script Python pour lire cette valeur et la transmettre à Domoticz pour affichage dans un capteur de température. Créer ce capteur de température revient à créer le capteur de la température et de l'humidité tel que décrit ci-dessus sauf pour le type de capteur.

    #!/usr/bin/python import sys import urllib # parameters cpu_idx = 36 url_json = "http://192.168.0.22:8080/json.htm?type=command&param=udevice&idx=" verbose = 1 # set to 1 to print out information to the console # read cpu temperature # replace 1000.0 with 1000 to round to nearest degree cpuTemp = int(open('/sys/class/thermal/thermal_zone0/temp').read()) / 1000.0 # use Domoticz JSON url to update cmd = url_json + str(sensor_idx) + "&nvalue=0&svalue=" + str(cpuTemp) hf = urllib.urlopen(cmd) if verbose > 0: print 'Sensor data: temperature = {0:0.1f}C'.format(cpuTemp) print 'Uploaded to Pi: ' + cmd print 'Response: ' + hf.read() hf.close
    Téléchargez le fichier en cliquant sur le lien soc_temp.py avec le bouton droit de la souris.

    Référence:
    [Tutorial] Show RPI's Temperature with a command.
    RPI vcgencmd usage.

  11. Surveillance de la température
  12. Les deux scripts présentés ci-dessus sont facilement fusionnés en un seul script Python qui sera exécuté à intervalles réguliers par cron. Voici ce script.

    #!/usr/bin/python # coding: utf-8 import sys import Adafruit_DHT import urllib # parameters DHT_type = 11 OneWire_pin = 24 room_temp_idx = 35 cpu_temp_idx = 36 url_json = "http://192.168.0.22:8080/json.htm?type=command&param=udevice&idx=" verbose = 1 # 1 to print out information to the console, 0 for silence # read and report dht11 temperature and humidity humidity, temperature = Adafruit_DHT.read_retry(DHT_type, OneWire_pin) cmd = url_json + str(room_temp_idx) + "&nvalue=0&svalue=" + str(temperature) + ";" + str(humidity) + ";0" hf = urllib.urlopen(cmd) if verbose > 0: print 'Données lues: température ambiante {0:0.1f}°C, humidité {1:0.1f}%'.format(temperature, humidity) print 'URL JSON pour Domoticz: ' + cmd print 'Réponse: ' + hf.read() hf.close # read and report cpu temperature cpuTemp = int(open('/sys/class/thermal/thermal_zone0/temp').read()) / 1e3 cmd = url_json + str(cpu_temp_idx) + "&nvalue=0&svalue=" + str(cpuTemp) hf = urllib.urlopen(cmd) if verbose > 0: print 'Donnée lue: température du Raspberry Pi: {0:0.1f}°C'.format(cpuTemp) print 'URL JSON pour Domoticz: ' + cmd print 'Réponse: ' + hf.read() hf.close
    Téléchargez le fichier en cliquant sur le lien soc_temp.py avec le bouton droit de la souris. (Il y a eu une mise à jour du script le 4 juillet 2017).

    La deuxième ligne, # coding: utf-8 est le seul changement significatif. Elle est nécessaire en vertu des messages en français, contenant des caractères Unicode, imprimés sur la console quand verbose vaut 1. Cette deuxième ligne peut être supprimée si seulement des caractères ASCII sont utilisés dans un script Python.

    J'ai sauvegardé le script sous le nom temps.py et vérifié qu'il fonctionne.

    pi@domo:~/pythons $ python temps.py Données lues: température ambiante 23.0°C, humidité 53.0% URL JSON pour Domoticz: http://192.168.0.45:9071/json.htm?type=command¶m=udevice&idx=35&nvalue=0&svalue=23.0;53.0;0 Réponse: { "status" : "OK", "title" : "Update Device" } Donnée lue: température du Raspberry Pi: 42.8°C URL JSON pour Domoticz: http://192.168.0.45:9071/json.htm?type=command¶m=udevice&idx=36&nvalue=0&svalue=42.774 Réponse: { "status" : "OK", "title" : "Update Device" }

    J'ai aussi vérifié que les capteurs dans Domoticz ont été mis à jour.

    Comme tout fonctionnait, j'ai changé la valeur de verbose à 0, j'ai modifié les permissions du fichier contenant le script pour qu'il soit exécutable et j'ai ajouté une entrée dans l'horaire de cron.

    pi@domo:~/pythons $ sudo chmod +x temps.py pi@domo:~/pythons $ crontab -e
    # m h dom mon dow command # update Domoticz temperature and humidty sensors every 5 minutes */5 * * * * /home/pi/pythons/temps.py quitter l'éditeur en sauvegardant l'ajout crontab: installing new crontab

    Ainsi le script sera exécuté à toutes les cinq minutes. Après un certain temps, les données accumulées par Domoticz peuvent être visualisées dans un graphique et enregistrées dans un fichier. Cliquez sur le Log du capteur de température.

    Inutile de spéculer sur les causes du coup de froid précipité qui s'est produit au début de l'été. Les grandes fluctuations des niveaux de température et d'humidité dans la soirée du 27 sont de « fausses nouvelles » que j'ai créé pour voir comment le calcul du point de rosée changeait en réponse.

    Ce billet est déjà long; j'examinerai le sujet de nouveau dans un prochain article.

Temperature Sensors - Take 2 (en anglais)