Piloter le GPIO de l'ESP8266 (Serveur Web) depuis Jeedom en TCP/IP sans fil – Partie 2 • Domotique et objets connectés à faire soi-même

Voici la seconde partie de l’article pour faire communiquer un ESP8266 en TCP/IP avec Jeedom. Dans ce tutoriel, nous allons voir comment piloter le GPIO d’un ESP8266 depuis Jeedom à l’aide de requêtes HTTP (TCP/IP). Le principe est le même que pour Domoticz (article), on démarre un petit serveur Web sur l’ESP8266 qui lancera un fonction à chaque fois qu’une requête est reçue sur un point d’entrée (ici /gpio). La mise en oeuvre coté Jeedom est un peu plus compliquée que pour Domoticz. Il va falloir créer un script capable d’exécuter des requêtes HTTP puis appeler ce script dans un instrument virtuel (ce que nous allons faire) ou un scénario.

Article précédent : ESP8266 (Client Web) : envoyer des données à Jeedom en TCP/IP sans fil (API JSON) – Partie 1

Matériel utilisé

Le matériel et le montage reste identique aux tutoriels précédents.

Circuit

Composant Broches Broche ESP8266 (Wemos D1 mini)
DHT22 (shield Wemos D1 Mini) VCC 3V3
GND G
Data D4
BMP180 VCC 3V3
GND G
SDA D2
SCK D3
Shield relai Wemos D1 Mini D1

7vgypaxie5v45e0s8rsf-8907942

Changer les broches du bus I2C de l’ESP8266

Si vous utilisez un capteur fonctionnant sur le bus I2C, vous allez devoir modifier une ou deux broches du bus I2C. Pour cela, on utilise la librairie Wire.h

Déclarez la librairie en début de programme

#include 

Dans le setup() ; mais avant le d’initialiser l’objet BMP180 avec la commande bmp.begin() par exemple; on déclare la initialise le bus I2C en indiquant les nouvelles broches. Ici, j’ai déplacé par broche D1 (SCK) sur la broche D3, ce qui donne

Wire.begin(D2,D3);

Vous pouvez maintenant déplacer le bus I2C sur les broches que vous voulez.

Piloter le GPIO de l’ESP8266 depuis Jeedom

Pour ce tutoriel, j’ai donc utilisé le shield relai pour Wemos D1 mini qui vient s’empiler au dessus la l’ESP8266 pour former un ensemble compact (et économique, moins de 8€).

Créer un script pour piloter le GPIO par requête HTTP

Allez dans plugins -> Programmation -> Script (installez le plugin script si le menu n’existe pas) puis ajoutez un nouveau script :

  • Donnez lui un nom en commençant par script_xxxx. Cela vous permettra de distinguer les scripts des autres équipement et de les retrouver plus facilement dans les listes de choix.
  • Attribuez lu un objet parent (optionnel),
  • Activez le
  • Ne cochez pas visible

Allez dans l’onglet Commandes puis cliquez sur Ajouter une commande script :

  • Donnez lui le nom ON
  • Type de script : HTTP
  • Type : action
  • Requête : remplacez l’adresse IP, l’id du GPIO et le token
    • http://#IP_ESP8266#/gpio?id=#ID#&etat=1&token=#token#
  • La requête doit contenir :
    • saisissez success:1 (ou un autre retour qu’il faudra modifier dans le code Arduino)
  • Un délai maximum de réponse de l’ESP8266 (timeout). Par exemple 2 secondes
  • Nombre de tentatives maximum : 5 (au choix)
  • Décocher Afficher

Dupliquez la commande en appuyant sur l’icône (documents superposés) à coté du bouton tester. Modifiez état=1 par état=0. Sauvegardez.

Créer un bouton (équipement) virtuel

Allez dans plugins -> Programmation -> Virtuel (installez le plugin Virtuel si le menu n’existe pas) puis ajoutez un nouveau équipement. Donnez luis un nom, un objet parent et cochez activer et visible. Allez ensuite à l’onglet Commandes et ajoutez 2 commandes virtuelles

Pour la première commande :

  • Donnez lui le nom On
  • Cliquez sur Rechercher équipement. Recherchez le script puis la commande ON de ce dernier

Faites la même chose pour la commande Off. Sauvegardez.

La configuration de Jeedom est terminée.

Code Arduino / ESP8266

Le code Arduino est parfaitement identique à la version Domoticz. Pour en savoir plus sur le fonctionnement, je vous invite à lire le tutoriel précédent. La seule différence réside dans le retour de la fonction updateGpio(). Alors que Domoticz n’attend rien de l’ESP8266, il est nécessaire de répondre à Jeedom. Cela ne gêne en rien le fonctionnement du serveur domotique mais Jeedom va afficher une notification et ajouter une erreur dans le journal d’événement. Autant bien faire les choses. On va juste renvoyer une chaine de caractère (success:1) qui sera testée par le script. C’est tout.

server.send(200, "application/json","success:1");

Créez un nouveau sketch depuis l’IDE Arduino. Modifiez les variables avant de téléverser le programme.

/*
 * HTTP communication between ESP8266 and Jeedom Smart Home Server
 * Communication HTTP (TCP/IP) entre ESP8266 et le serveur domotique Jeedom
 * Copyright (C) 2017 http://www.projetsdiy.fr - http://www.diyprojects.io
 *   
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 */
#include 
#include 
#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     = 80;
const char* apiKey   = "mVuQikcXm69l2mDMYZiCsLj0wamT0HsCcrBCuXRxntJDO1kn";
const char* idTemp   = "78";
const char* idHumi   = "79";
const char* idPA     = "80";
const int   watchdog = 60000;
unsigned long previousMillis = millis(); 
const uint8_t GPIOPIN[5] = {D1,D5,D6,D7,D8};  // Led

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

void updateGpio(){
  Serial.println("Update GPIO command from Jeedom : ");
  for ( int i = 0 ; i < server.args(); i++ ) {
    Serial.print(server.argName(i)); Serial.println(server.arg(i));
  }
  String gpio = server.arg("id"); 
  String token = server.arg("token");
  // Vérifie si le serveur est autorisé - Check if server is authorized
  if ( token != "123abCde" ) {
    Serial.println("Not authentified ");
    return;
  }
  int etat = server.arg("etat").toInt();
  int pin = D1;
  if ( gpio == "D1" ) {
    pin = D1;
  } else if ( gpio == "D7" ) {
    pin = D7;
  } else if ( gpio == "D8" ) {
    pin = D8;  
  } else {   
    pin = D1;
  }
  Serial.print("Update GPIO "); Serial.println(pin);
  if ( etat == 1 ) {
    digitalWrite(pin, HIGH);
    Serial.println("GPIO updated : On");
    server.send(200, "application/json","success:1");
  } else if ( etat == 0 ) {
    digitalWrite(pin, LOW);
    Serial.println("GPIO updated : Off");
    server.send(200, "application/json","success:1");
  } else {
    Serial.println("Bad state Value !");
    server.send(200, "application/json","success:0");
  }
}

void setup() {
  Serial.begin(115200);
  delay(10);
  
  Wire.begin(D2,D3);            // Modifie les broches du bus I2C - Change I2C Pins
  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(".");
  }
  
  for ( int x = 0 ; x < 5 ; x++ ) {
    pinMode(GPIOPIN[x], OUTPUT);
  }
  
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.print(WiFi.localIP()); 
  
  server.on("/gpio", updateGpio);
  server.begin();
}

int value = 0;

void loop() {
  server.handleClient();
  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 Jeedom");
      
      float t = dht.readTemperature();
      float h = dht.readHumidity();
      float pa = bmp.readPressure() / 100.0F;
      
      if ( isnan(t) || isnan(h) ) {
        Serial.println("DHT KO");
      } else {
        String baseurl = "/core/api/jeeApi.php?apikey="; 
        baseurl += apiKey;
        baseurl += "&type=virtual&id="; 
        String url = baseurl + idTemp;
        url += url + "&value="; url += String(t); 
        sendToJeedom(url);
        delay(1000);
        
        url = baseurl + idHumi;
        url += url + "&value="; url += String(h);
        sendToJeedom(url);
        delay(1000);

        url = baseurl + idPA;
        url += url + "&value="; url += String(pa);
        sendToJeedom(url);
        delay(1000);
      }
    }
  }
}

boolean sendToJeedom(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();
  http.end();
}

Vous pouvez maintenant piloter le GPIO de n’importe quel ESP8266.

Avez-vous aimé cet article ?