Jeedom. Publier en MQTT des commandes virtuelles vers ESP8266 ou ESP32 (interrupteur, poussoir, dimmer) • Domotique et objets connectés à faire soi-même

Depuis Jeedom, il est assez facile de renvoyer chaque action sur une commande à l’aide de messages MQTT pour piloter des accessoires domotiques développés à l’aide d’ESP32, ESP8266 ou Raspberry Pi par exemple. Dans cet article, nous utiliserons des commandes virtuelles pour créer un interrupteur, un bouton poussoir (inversion d’état) et un variateur (dimmer). Après l’exécution de chaque action, l’état de la commande est publiée à l’aide d’un équipement MQTT qui jouera le rôle de simple répéteur. On verra également comment récupérer le retour d’état depuis l’accessoire domotique. Ce retour d’état pourra être utilisé pour piloter les équipements Jeedom (ou un scénario) depuis une commande externe.

Dans un premier temps, nous allons apprendre comment créer un interrupteur virtuel et publier chaque changement d’état vers un broker MQTT. On verra également comment récupérer le retour d’état ou comment changer l’état de l’interrupteur virtuel Jeedom depuis une commande externe. On ferra la même chose avec un bouton poussoir qui inverse simplement l’état de la commande avec un seul bouton. Enfin, nous verrons comment réaliser un variateur (dimmer) à l’aide d’un curseur. On pourra s’en servir pour piloter un éclairage, la vitesse d’un ventilateur…

Configuration nécessaire

Pour ce projet, vous aurez besoin des éléments suivants

  • Un broker MQTT. Mosquitto par exemple
  • Eventuellement un client MQTT, plus simple à utiliser que les lignes de commande. Je vous conseille MQTTfx. MQTTfx est gratuit et disponible pour Windows, macOS et Linux
  • Eventuellement un ESP32 ou ESP8266 pour tester le code Arduino proposé à la fin du projet

Installation du plugin jMQTT pour Jeedom

Il existe 2 plugins pour communiquer avec un broker MQTT pour Jeedom. Le plugin jMQTT développé par Domotruc est le plus documenté actuellement. A vous de choisir en fonction de vos habitudes. Quelque soit le plugin installé, le principe restera le même.

Allez sur le Market, installez le plugin MQTT de votre choix et activez le.

wdryyrypazxajtqibnb0-2373919

Configurer un broker à jMQTT

Laissez le plugin installer les dépendances nécessaires et démarrer. Ouvrez ensuite le panneau d’accueil du plugin depuis le menu Plugin -> Protocole Domotique -> jMQTT

qdwt4gjlgvuweq8v1vrg-5850605

Contrairement au plugin officiel, jMQTT permet de se connecter à plusieurs Brokers. Cliquez sur ajouter un broker.

Indiquez les informations de base :

  • Nom de l’équipement
  • Objet parent
  • Activer
  • Visible pour voir l’état de la connexion dans le Dashboard Jeedom
  • Optionnel :

Ouvrez ensuite le panneau Broker pour renseigner les paramètres de connexion

  • IP ou nom de domaine (Obligatoire)
  • Optionnel (paramètres par défaut déjà indiqués)
    • Port (1883 par défaut)
    • Utilisateur et mot de passe
    • Topic de souscription (laissez vide par défaut).

9qudfd6ahvpmcmykqhxl-9737590

Sauvegardez et relancez le broker. Si tout est correct, configuration et statut doivent passer au vert.

cfm8mobaoxtqt0lzmcco-6313774

Installer le plugin Virtuel pour Jeedom

Il est possible de déclencher la publication d’une commande MQTT depuis n’importe quelle action. Pour ce tutoriel, nous allons créer des commandes virtuelles. Allez dans le Market, cherchez le plugin Virtuel (officiel et gratuit), installez-le et activez-le.

leokgvrocdkp0p5brypk-7736917

Interrupteur virtuel pour commander éclairage, relais, LED depuis un ESP32 ou ESP8266

Avant de rentrer dans le vif du sujet, voyons le principe de l’interrupteur. Bien évidemment, il y a probablement d’autres architectures (certainement plus simples), l’idée étant de pouvoir récupérer l’état du relai ou la commande d’un interrupteur physique depuis l’ESP32 ou l’ESP8266.

On a deux flux de commandes

  • Orange c’est le flux des commandes depuis l’interrupteur virtuel de Jeedom. Le topic se terminera par set (pour set value, valeur attribuée en français). Ce topic permet uniquement d’allumer / éteindre l’accessoire depuis Jeedom
  • Bleu C’est l’état ou une commande externe qui remonte vers Jeedom. Ca pourra être un interrupteur par exemple. Le topic MQTT se terminera par act (pour actual value). Peu importe le nom, c’est juste pour récupérer un changement d’état. Pour actualiser l’état du bouton virtuel, on utilisera simplement l’API interne de jeedom.

Nous allons créer un équipement MQTT qui va renvoyer les actions (allumer, éteindre) depuis un interrupteur.

j1aaneyy3iyxbcypcfhr-5647564

Flux des commandes virtuelles et des messages MQTT depuis et vers Jeedom. L’interrupteur pourra également être piloté depuis un bouton physique. En orange, de jeedom vers l’extérieur. En bleu,  de l’extérieur vers Jeedom.

Création de interrupteur virtuel

La première chose à faire est de créer un interrupteur virtuel. Si vous disposez déjà d’un interrupteur (un switch Xiaomi par exemple), vous pouvez passer à l’étape suivante

Ouvrez le panneau du plugin virtuel en allant dans le menu Plugin -> Programmation -> Virtuel. Cliquez sur Ajouter

hhcuxgycyfzgzlmdig9i-7751652

On va créer une commande virtuelle pour chaque état de l’interrupteur (allumé | on – éteint | off). Cliquez deux fois sur Ajouter une commande virtuelle et configurez les deux commandes comme ceci :

  • Nom on | off
  • Nom Information etat
  • Valeur on | off
  • Afficher cocher pour rendre visible les deux commandes

Sauvegarder

bmnicerq316j4wnbpjtl-1483226

Jeedom créé automatiquement l’info virtuelle. Celle-ci prendra le nom etat. Vous pouvez en plus

  • Sous-type binaire pour avoir l’état de l’interrupteur sous la forme d’une icône.
  • Historiser pratique pour suivre les actions sur les interrupteurs
  • Inverser la commande

Sauvegarder

Voici à quoi ressemble l’interrupteur sur le Dashboard

7zw55cpfff0chxfw63hl-2435374

Création du répéteur MQTT

On va maintenant créer un accessoire MQTT qui sera appelé à chaque fois qu’une commande virtuelle est déclenchée. Ca pourra être depuis le Dashboard, l’application mobile ou un scénario.

Configurez comme ceci

  • Nom de l’équipement attribuez un nom sans espace. Ce sera la racine du topic MQTT
  • Objet parent conseillé
  • Activer
  • Broker associé choisissez le broker MQTT qui doit être utilisé pour cet équipement
  • Inscrit au Topic le nom de l’équipement/# pour récupérer tous les enfants
  • Catégorie conseillé
  • Optionnel : ajout automatique des commandes, Qos (1 par défaut)

Sauvegarder

xax4dvoihd7nz52bwcs7-6659336

Ouvrez l’ongle commandes et créer une commande action et configurez comme ceci

  • Nom de préférence un dérivé d’état, par exemple renvoi_etat
  • Topic de la forme nom_equipement/commande/argument. Ici on suit le chemin orange, donc le Topic doit se terminer par set, ce qui nous donne Interrupteur_renvoi_MQTT/switch/act
  • Valeur on recopie ici simplement l’état de l’interrupteur. Utilisez la recherche d’équipement pour trouver son chemin. N’oubliez d’encadrer par # le chemin

Sauvegarder

wd0hznozj9auwcptpm6i-6594304

Connecter les commandes virtuelles à répéteur MQTT

Ouvrez la commande virtuelle et cliquez sur les roues crantées (engrenages !) de la commande on

apj5mfo5wlx0sqlu08xl-1418924

Depuis l’onglet Configuration, ajouter une action après l’execution de la commande (impératif pour renvoyer le nouvel état de la commande vers MQTT !). Chercher la commande du répéteur MQTT créée précédemment.

Sauvegardez et faites la même chose pour la commande off.

b9ka5r8yqrgz4vf9lkqx-7919619

Allez sur le Dashboard et connectez vous au broker MQTT. Je vous conseille d’utiliser MQTTfx, une application gratuite disponible pour Windows, macOS et Linux.

Si vous avez bien travaillé, vous devriez recevoir un message à chaque changement d’état de l’interrupteur virtuel 😉

z2ntcq0csbsn0ahmnqdw-7156122

Renvoi d’état ou commande externe

On va maintenant ajouter un retour d’état que l’on pourra aussi utiliser comme commande externe pour piloter l’interrupteur virtuel de Jeedom.

Ouvrez le panneau de configuration de l’interrupteur virtuel et récupérez l’URL de retour. Elle est de la forme

http://jeedom/core/api/jeeApi.php?plugin=virtual&apikey=#cle_api#&type=virtual&id=#cmd_id#&value=#value#

tuwvh18jo3ykaf4ttylt-3735522

Récupérez ensuite l’IDentifiant de la commande d’information depuis l’onglet Commandes.

Remplacez #cmd_id# dans l’URL de retour pour l’identifiant de la commande qui donne l’état de l’interrupteur.

ll11adqqntex3says781-3357626

Ouvrez le répéteur MQTT et ajoutez une commande d’information. Configurez comme ceci :

  • Nom je vous conseille de donner un nom sous la forme renvoi_nomdelacommandeliee, par exemple renvoi_etat.
  • Topic Ici on suit le chemin bleu, donc le Topic doit se terminer par act, ce qui nous donnera par exemple Interrupteur_renvoi_MQTT/switch/act

Sauvegarder

wd0hznozj9auwcptpm6i-6594304

Cliquez sur la roue crantée de la commande d’information.

lvjrhuarkzcojtl60by0-7431277

Sauvegarder

Actualisez l’état de l’interrupteur en publiant un message MQTT à l’aide de MQTTfx par exemple.

Voilà. Vous pouvez maintenant piloter très simplement un éclairage, un relais de puissance, une prise connectée directement depuis Jeedom. Vous disposez également d’un retour d’état ou d’une commande externe à Jeedom.

Bouton poussoir (toggle)

Voici comment transformer un interrupteur on/off en simple bouton poussoir. L’état sera inversé à chaque appui sur le bouton.

Le flux des informations est identique à l’interrupteur précédent.

Créer le bouton poussoir virtuel

Si vous disposez déjà d’un bouton poussoir, vous pouvez passer à l’étape suivante.

Créez un nouvel équipement virtuel et ajoutez une seule commande d’action en la configurant comme ceci :

  • Nom qui vous convient. Ici toggle
  • Nom Information qui vous convient. Ici etat

Sauvegarder

Profitez-en pour récupérer l’URL de retour de l’équipement

Jeedom créé automatiquement la commande d’information correspondante. Attribuer le sous-type binaire pour l’info virtuelle afin d’avoir un affichage sous la forme d’une icône.

Pour inverser la commande, il suffit d’inverser l’état de l’info virtuelle en la faisant précéder la not, ce qui donne par exemple

not(#[info][virtuelle][etat]#)

Sauvegarder

Créer le renvoi MQTT

Comme précédemment, on va créer un équipement MQTT qui va renvoyer l’état du bouton poussoir à chaque fois qu’on appuie sur le bouton. On pourra également actualiser le bouton virtuel depuis un bouton extérieur.

Voici un exemple de configuration d’équipement MQTT

  • Nom de l’équipement sans espaces, ce sera la racine du Topic MQTT
  • Activer
  • Broker associé utilisé pour communiquer avec cet équipement
  • Inscrit au Topic de la forme nom_equipement/#
  • Catégorie du topic

Sauvegarder

Dans l’onglet commandes, créer une commande action et configurer comme ceci

  • Nom de préférence etat
  • Topic sous la forme nom_equipement/commande/set chemin orange
  • Valeur sélection l’état du bouton poussoir virtuel

Créer une commande info  et configurer comme ceci

  • Nom sous la forme commande:argument, ce qui donne toggle:act
  • Topic sous la forme nom_equipement/commande/act chemin bleu

Sauvegarder

vwri8qxx7onl4b0crnkt-9466083

Cliquer sur la roue crantée de la commande info et ajouter l’URL de retour sans oublier

  • Ajouter http://jeedom ou http://IP_JEEDOM au début de l’URL
  • Remplacer #cmd_id# par l’identifiant de l’état du bouton poussoir récupéré précédemment

Sauvegarder

jsap2mze3wxu8ugsgvan-3092787

Lier le bouton poussoir virtuel au renvoi MQTT

Ouvrez le panneau de configuration de la commande action du bouton poussoir et ajouter une action après exécution de la commande. Sélectionner la commande etat de l’équipement MQTT que l’on vient de créer.

s0m3khoiogpbjxwbaytt-7216900

Sauvegarder

Depuis le Dashboard, vous pouvez maintenant tester le bouton poussoir. Vous devriez recevoir un message MQTT à chaque action sur le bouton poussoir.

hskw8pl2hibwbkuht1xs-6436757 z4854gbkqngklpxv8aaz-8792617

Variateur de lumière MQTT

La dernière commande que je vous propose de créer est un variateur que l’on pourra utiliser pour piloter divers accessoires domotiques. Eclairage, niveau du rétro-éclairage d’un écran, vitesse de ventilateur…

Contrairement aux deux exemples précédent, on ne récupèrera pas l’état du variateur. Si toutefois vous en avez besoin, il suffira d’appliquer le même principe et créant une commande info dans le répéteur MQTT et la lier l’état de l’équipement virtuel à l’aide de l’URL de retour.

Créer un nouvel équipement virtuel de type Dimmer (variateur) en suivant ce modèle

Créer le curseur (slider) virtuel Jeedom

Créer un nouvel équipement virtuel avec une commande de type curseur (slider en anglais) et configurer comme ceci :

  • Nom slider par exemple
  • Valeur variateur par exemple
  • Sous-type curseur
  • Cocher Afficher
  • Optionnel : valeur mini et maxi du curseur

Sauvegarder

Jeedom créé automatiquement la commande info qui est affichée par défaut sur le Widget. Modifier les paramètres comme ceci :

  • Sous-Type numérique
  • Bornes Mini et Maxi de l’affichage
  • Afficher ou pas

6hekpitgekwm4wd9oqum-9468177

Créer le répéteur MQTT pour le dimmer

Créer un équipement MQTT et ajoutez une commande action en suivant ce modèle.

  • Topic en suivant le chemin orange, de la forme nom_equipement/commande/set
  • Valeur recherchez l’équipement et liez son état (la valeur du variateur) qui sera publiée sur MQTT
  • Vous pouvez modifier le type mais c’est optionnel

Sauvegarder

hvyqgrcwwxikkylblobx-9233593

Lier le variateur virtuel au répéteur MQTT

Retournez sur l’équipement du variateur virtuel et déclenchez une action après exécution en cliquant sur la roue crantée de la commande action du variateur (slider)

cdqb3kk74yemc8uqctio-1503972

Sauvegarder

Allez sur le dashboard et actionnez le curseur. Vous devriez recevoir le nouveau niveau du variateur au niveau du broker MQTT

44noonntktxdnjixt4hl-5941809

Code Arduino compatible ESP32 et ESP8266

Pour conclure cet article, voici un exemple de code Arduino que vous pouvez utiliser comme base pour vos projets d’accessoires domotiques. Le code est compatible ESP32 et ESP8266 et permet

  • De se connecter au réseau WiFi local
  • De se connecter à n’importe quel Broker MQTT dès que la connexion WiFi est établie
  • De récupérer la connexion au broker MQTT en cas de coupure
  • De publier toutes les 60 secondes les mesures de température et d’humidité à l’aide d’un capteur DHT22
  • De piloter un relais
  • De simuler le variateur de lumière sur une LED (uniquement avec un ESP8266)
/*
  Simple IoT projects using MQTT broker to communicate with Home Automation server
  Code compatible with ESP32 and ESP8266
  
  Projet simple d'objet connecté communique avec un serveur domotique à l'aide de messages MQTT
  Code compatible ESP32 et ESP8266
  
  https://projetsdiy.fr | https://diyprojects.io 
  
  2020
  Licence : MIT
*/
// Libraries
// ESP8266
//#include 
// ESP32
#include 
#include 
#include "DHT.h"          //DHT

// Configuration WiFi | WiFi settings
#define wifi_ssid     "SSID"
#define wifi_password "WIFI_PASSWORD"

/*
 * Paramètres MQTT - MQTT Settings  
 */
#define mqtt_server   "MQTT_IP"
// Optionnel | Optional
#define mqtt_port     1883
#define mqtt_user     "guest"       //Identifiant | user
#define mqtt_password "guest"       //Mot de passe | Password

/*
 * Topics
 */
#define dimmer_topic      "Variateur_renvoi_MQTT/dimmer/set"
#define switch_topic      "Interrupteur_renvoi_MQTT/switch/set"
#define temperature_topic "sensor/dht22/temperature"  //Temperature
#define humidity_topic    "sensor/dht22/humidity"     //Humidité | Humidity

//Buffer qui permet de décoder les messages MQTT reçus | Buffer to receive MQTT messages
char message_buff[100];

long lastMsg = 0;   //Horodatage du dernier message publié sur MQTT
long lastRecu = 0;
#define debug true  //Affiche sur la console si True

/*
 * Configuration des broches | Pin settings
 * Attention, par défaut pour ESP8266 | Warning, by default for ESP8266
 */
#define PIN_DHT           D4   
#define PIN_RELAI         D1    
#define PIN_LED           D8

// Dé-commentez la sonde DHT | un-comment DHT sensor 
//#define DHTTYPE DHT11       // DHT 11 
#define DHTTYPE DHT22         // DHT 22  (AM2302)

//Création des objets C++ | Create C++ objects
DHT dht(PIN_DHT, DHTTYPE);     
WiFiClient espClient;
PubSubClient client(espClient);

void setup() {
  Serial.begin(115200);    
  
  pinMode(PIN_RELAI,OUTPUT);// Relais
  pinMode(PIN_LED, OUTPUT);  // LED
  
  setup_wifi();             //On se connecte au réseau wifi | Launch WiFi connexion
  client.setServer(mqtt_server, 1883);    //Configuration de la connexion au serveur MQTT
  client.setCallback(callback);  //La fonction de callback qui est executée à chaque réception de message   
  dht.begin();
}

//Connexion au réseau WiFi
void setup_wifi() {
  delay(10);
  Serial.println(); Serial.print("Connecting to "); Serial.println(wifi_ssid);

  WiFi.begin(wifi_ssid, wifi_password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println(""); Serial.print("Successfully connected with IP "); Serial.println(WiFi.localIP());
}

//Reconnexion
void reconnect() {
  //Boucle jusqu'à obtenur une reconnexion
  while (!client.connected()) {
    Serial.print("Connecting to MQTT Broker...");
    if (client.connect("ESP8266Client", mqtt_user, mqtt_password)) {
      Serial.println("OK");
    } else {
      Serial.print("KO ");
      Serial.print(client.state());
      Serial.println(" wait 5 seconds before retry");  // On attend 5s avant de tenter une nouvelle connexion
      delay(5000);
    }
  }
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  long now = millis();
  // Publie temp + hum chaque minute | publish temp+hum every minute
  if (now - lastMsg > 1000 * 60) {
    lastMsg = now;
    
    float h = dht.readHumidity();
    float t = dht.readTemperature();

    // Un problème avec le capteur DHT ! | A problem with DHT sensor !
    if ( isnan(t) || isnan(h)) {
      Serial.println("Please check DHT sensor");
      return;
    }
  
    if ( debug ) {
      Serial.print("Temp: "); Serial.print(t); Serial.print(" | Hum: "); Serial.println(h);
    }  
    client.publish(temperature_topic, String(t).c_str(), true);   // Publie la température | publish temperature
    client.publish(humidity_topic, String(h).c_str(), true);      // Publie l'humidité | publish humidity
  }
  if (now - lastRecu > 100 ) {
    lastRecu = now;
    client.subscribe(dimmer_topic);
    client.subscribe(switch_topic);
  }
}

// Déclenche les actions à la réception d'un message | Execute action when new MQTT message arrive
void callback(char* topic, byte* payload, unsigned int length) {
  int i = 0;
  if ( debug ) {
    Serial.println(""); Serial.print("MQTT message received on topic: " + String(topic));
    Serial.print(" | length: " + String(length,DEC)); 
  }
  // create character buffer with ending null terminator (string)
  for(i=0; i