Domotique et objets connectés à faire soi-même

Jeedom. Publier en MQTT des commandes virtuelles vers ESP8266 ou ESP32 (interrupteur, poussoir, dimmer)

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

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.

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

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

Indiquez les informations de base :

 

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

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

 

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.

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

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

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

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 :

Sauvegarder

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

Sauvegarder

Voici à quoi ressemble l’interrupteur sur le Dashboard

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

Sauvegarder

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

Sauvegarder

Connecter les commandes virtuelles à répéteur MQTT

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

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.

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 😉

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#

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.

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

Sauvegarder

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

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 :

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

Sauvegarder

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

Créer une commande info  et configurer comme ceci

Sauvegarder

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

Sauvegarder

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.

Sauvegarder

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

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 :

Sauvegarder

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

 

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.

Sauvegarder

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)

Sauvegarder

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

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

/*
  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<length; i++) {
    message_buff[i] = payload[i];
  }
  message_buff[i] = '';
  
  String msgString = String(message_buff);
  if ( debug ) {
    Serial.println(" | Payload: " + msgString);
  }

  if ( String(topic) == dimmer_topic ) {
   if ( debug ) { Serial.print("Dimmer to "); Serial.println(msgString.toInt()); }
   // Attention, ne fonctionne pas sur ESP32 | Warning, ne fonctionne pas avec ESP32
   analogWrite(PIN_LED, msgString.toInt());
  } else if ( String(topic) == switch_topic ) {
    if ( debug ) { Serial.print("Switch relay to "); Serial.println(msgString.toInt()); }
    if ( msgString == "ON" || msgString == "1" ) {
      digitalWrite(PIN_RELAI,HIGH);  
    } else {
      digitalWrite(PIN_RELAI,LOW);  
    }
  }  
}

Mises à jour

23/07/2020 Première publication du projet

Avez-vous aimé cet article ?
[Total: 3 Moyenne: 5]
Exit mobile version