Domoticz. Comment envoyer des données via l'API/JSON depuis un IoT ESP8266 • Domotique et objets connectés à faire soi-même

Dans ce tutoriel, nous allons utiliser les librairies ESP8266Client et ESP8266HTTPClient pour mettre en place une communication TCP/IP entre et un module ESP8266 NodeMCU et l’interface API/JSON de Domoticz. Nous utiliserons un capteur de température et d’humidité DHT22 ainsi qu’un capteur de pression atmosphérique BMP180 pour publier des mesures réelles sur des capteurs virtuels du serveur domotique.

Lectures conseillées

Si vous débutez en domotique et en programmation Arduino, je vous conseille de débutez avec le firmware ESP Easy (tous les tutoriels sur le sujet) qui permet de créer des objets connectés sans aucune programmation.

Matériel utilisé

Nous allons commencer par créer un petit montage qui vous nous permettre d’interagir entre Domoticz et l’ESP8266. Pour la partie sonde, vous pouvez utiliser un DHT11 ou un DHT22. Rapide à mettre en oeuvre grace à la librairie DHT.h Adafruit. J’ai également ajouté un BMP180 permettant de créer un baromètre sur Domoticz. Pour le pilotage du GPIO, vous pouvez utiliser une simple LED ou un relai.

Circuit

Composant Broches Repérage Arduino Broche ESP8266 (LoLin D1 mini)
DHT22 (shield Wemos D1 Mini) VCC 3V3 3V3
GND GND G
Data GPIO2 D4
BMP180 VCC 3V3 3V3
GND GND G
SDA GPIO4 D2
SCK GPIO5 D1
Led GPIO D7 Pole + GPIO13 D7
Pole – GND G

Interface de communication Domoticz (API et URL JSON)

Domoticz met à disposition une interface de communication (API) qui permet d’envoyer des données (mesure, état…) depuis un objet connecté vers Domoticz. En retour Domoticz. Cette interface est très puissante. Non seulement il est possible d’envoyer des données à Domoticz, mais il est également possible de réaliser toutes les opérations d’administration directement depuis le programme Arduino. En voici quelques unes :

  • Créer un appareil virtuel (param=addhardware)
  • Créer un capteur virtuel (param=createvirtualsensor)
  • Ajouter, supprimer une scène
  • Ajouter, supprimer un groupe
  • Arrêter, redémarrer le système

Il est également possible de récupérer l’état et les valeurs des différents appareils et capteurs (param=getlightswitches). En retour Domoticz renvoi un fichier au format JSON.

Pour connaître en détail le fonctionnement de toutes les commandes disponibles, vous pouvez aller sur le wiki officiel. Je vous conseille également de lire cette excellente traduction française faite par easydomoticz.com

Ce qui va surtout nous intéresser dans ce tutoriel, c’est comment envoyer des données à l’API Domoticz. C’est assez simple à mettre en oeuvre. Domoticz récupère les données encodées dans l’URL. Par exemple pour envoyer la température (26°C) au device (IDX 111), il suffit d’envoyer au serveur la requête HTTP suivante.

http://#IP_SERVER#/json.htm?type=command&param=udevice&idx=111&nvalue=0&svalue=26

Capteur virtuel (température + humidité + baromètre)

Avant d’entamer le code Arduino, nous allons créer un capteur virtuel qui va recevoir les mesures en provenance du DHT22 et du BMP180 connectés à l’ESP8266. Allez dans les Réglages puis Matériel. Créez un nouveau matériel de type Dummy. Désactivez le délai d’attente des données puis Ajouter.

Un nouveau matériel a été créé. Cliquez sur le bouton Créer capteurs virtuels.

Donnez un nom au capteur et choisissez le type qui correspond. Ici Temp+Humidité+Baromètre

Une fois créé, le capteur virtuel est ajouté à la liste des dispositifs. Il a également automatiquement été ajouté dans les onglets Température et Météo. Ce qui est important, c’est de repérer son identifiant (IDX). Ici, c’est le 12.

Envoyer des données depuis l’ESP8266 vers Domoticz (exemple avec DHT22 et BMP180)

Passons au choses sérieuses maintenant. Ouvrez l’IDE Arduino, créez un nouveau sketch et collez le code complet du projet. Modifiez les variables ssid, password ainsi que l’adresse IP du serveur Domoticz (variable host).

#include 
#include 
#include 
#include 

#define DHTTYPE   DHT22       // DHT type (DHT11, DHT22)
#define DHTPIN    D4          // Broche du DHT / DHT Pin

const char* ssid     = "XXXXXXXX";
const char* password = "XXXXXXXX";
const char* host = "XXX.XXX.XXX.XXX";
const int   port = 8080;
const int   watchdog = 60000; // Fréquence d'envoi des données à Domoticz - Frequency of sending data to Domoticz
unsigned long previousMillis = millis(); 

DHT dht(DHTPIN, DHTTYPE);
Adafruit_BMP085 bmp;
HTTPClient http;

void setup() {
  Serial.begin(115200);
  delay(10);
  
  if ( !bmp.begin() ) {
    Serial.println("BMP180 KO!");
    while (1);
  } else {
    Serial.println("BMP180 OK");
  }
  
  Serial.setDebugOutput(true);  
  Serial.println("Connecting Wifi...");

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
   
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.print(WiFi.localIP()); 
}

int value = 0;

void loop() {
  unsigned long currentMillis = millis();

  if ( currentMillis - previousMillis > watchdog ) {
    previousMillis = currentMillis;

    if(WiFi.status() != WL_CONNECTED) {
      Serial.println("WiFi not connected !");
    } else {  
      Serial.println("Send data to Domoticz");
      
      float t = dht.readTemperature();
      float h = dht.readHumidity();
      float pa = bmp.readPressure() / 100.0F;
      
      if ( isnan(t) || isnan(h) ) {
        Serial.println("DHT KO");
      } else {
        int hum_stat;
        int bar_for = 0;
        if ( h > 70 ) {
          hum_stat = 3;
        } else if ( h < 30 ) {
          hum_stat = 2; 
        } else if ( h >= 30 & h  45 & h  1030 ) {
          bar_for = 1;  
        } else if ( pa > 1010 & pa  990 & pa  970 & pa < 990 ) {
          bar_for = 4;
        }
        
        String url = "/json.htm?type=command&param=udevice&idx=12&nvalue=0&svalue=";
        url += String(t); url += ";";
        url += String(h); url += ";";
        url += String(hum_stat); url += ";";
        url += String(pa);url += ";";
        url += String(bar_for);
     
        sendDomoticz(url);
      }
    }
  }
}

void sendDomoticz(String url){
  Serial.print("connecting to ");
  Serial.println(host);
  Serial.print("Requesting URL: ");
  Serial.println(url);
  http.begin(host,port,url);
  int httpCode = http.GET();
    if (httpCode) {
      if (httpCode == 200) {
        String payload = http.getString();
        Serial.println("Domoticz response "); 
        Serial.println(payload);
      }
    }
  Serial.println("closing connection");
  http.end();
}

Le programme n’a rien de bien compliqué. Il faut simplement s’assurer que l’on a bien récupéré des mesures valides du DHT22 (et du BMP180) avant d’envoyer les mesures au serveur. En effet, Domoticz ne fait aucune vérification des valeurs entrantes. Il fait une confiance aveugle. Malheureusement, la librairie DHT.h renvoi nan si aucun mesure n’est renvoyée par le DHT. Dans ce cas, tous les afficheurs vont disparaître des différents onglets. Pas de panique toutefois, dès que des valeurs valides seront envoyées, les affichages seront rétablis.

Regardons de plus prêts comment envoyer les mesures. Si on regarde de plus près sur le wiki (ici), on doit envoyer une requête de la forme

/json.htm?type=command&param=udevice&idx=IDX&nvalue=0&svalue=TEMP;HUM;HUM_STAT;BAR;BAR_FOR

On connait déjà notre IDX. Ici c’est le 12. On va devoir construire une chaine en y incluant les mesures de température, humidité et pression atmosphérique. Domoticz est capable également de gérer 2 autres informations

  • HUM_STAT (Humidity Status). Il est définit un peu plus haut dans le wiki mais c’est à nous de le calculer
    • 0=Normal (normal) : de 30 à 45%
    • 1=Comfortable (confortable) : de 45 à 70%
    • 2=Dry (sec) : < 30%
    • 3=Wet (humide) > 70%
  • BAR_FOR (Barometer Forecast, prévision barométrique). C’est également à nous de faire le travail. En l’absence de la vitesse et de la direction du vent, la prévision sera très aléatoire. On pourrait aller chercher ses infos sur openweathermap.org par exemple. Sans aller si loin, on peut avoir une petite idée en nous basant uniquement sur la pression atmosphérique pour des plages précises. En dehors, on renverra 0 (no info). La classification est un peu déroutante, il manque la neige, les orages… il faudra se contenter de ça en attendant une évolution.
    • 0 = No info (aucune prévision)
    • 1 = Sunny (ensoleillé) : > 1030hPa
    • 2 = Partly cloudy (partiellement nuageux) de 1010 à 1030hPa
    • 3 = Cloudy (nuageux) de 990 à 1010hPa
    • 4 = Rain (Pluie) : de 970 à 990hPa

Cela donne par exemple la requête suivante

/json.htm?type=command&param=udevice&idx=IDX&nvalue=0&svalue=27.10;31.10;0;981.03;4

Il ne reste plus qu’à faire une requête GET. Un post ne convient pas vraiment dans ce cas car toutes les données ont été encodées dans une URL. Il n’y a aucunes autres données à envoyer au serveur.

http.begin(host,port,url);
int httpCode = http.GET();

Il est possible de réaliser d’autres traitements de vérification en testant le code renvoyé par la fonction GET.

Résultat obtenu

Une fois le code Arduino téléversé, retournez sur l’interface de Domoticz. Dès que Domoticz aura reçu les premières mesures, l’afficheur sera actualisé.

Vous pouvez continuer par la lecture de ce tutoriel qui explique comment afficher d’autres types de données ou piloter un relais ou une prise connectée à l’aide de l’équipement virtuel Dummy Device de Domoticz.

Avez-vous aimé cet article ?

[Total: 3 Moyenne: 5]