Nous continuons notre série d’articles sur l’échange de données par requêtes HTTP (TCP/IP) entre un ESP8266 et le serveur domotique Jeedom. Jeedom met à disposition une API au standard JSON RPC (presque) aussi complète que celle de Domoticz. Nous irons un peu plus vite que pour Domoticz, le principe général étant le même.
Sommaire
Lectures recommandées
ESP8266 (Client Web) : envoyer des données à Domoticz en TCP/IP sans fil (API/JSON)
ESP Easy : utiliser des objets connectés DIY avec Jeedom
Documentation API JSON RPC de Jeedom
Matériel utilisé
Le circuit reste le même, à savoir un ESP8266 LoLin D1 Mini (WeMos), un capteur de température et d’humidité (DHT22), un capteur de pression atmosphérique (BMP180) ainsi qu’un shield relai pour piloter l’allumage d’un appareil depuis l’interface de Jeedom.
Circuit d’une mini station météo connectée
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 |
Récupérer votre clé API Jeedom
Pour pouvoir transmettre des données à Jeedom, il est nécessaire de récupérer la clé API depuis l’interface d’administration. Connectez vous à votre serveur et allez dans la configuration (roues crantées). Elle se trouve dans le champ clef API. Vous aurez besoin de cette clé pour le code Arduino.
Préparer un instrument virtuel
Nous allons maintenant créer un instrument qui va recevoir les données. Allez dans les plugins et vérifiez que le plugin Instrument Virtuel est installé. Si ce n’est pas le cas, faites-le.
Rendez-vous dans plugins -> Programmation -> Virtuel et cliquer sur + pour créer un nouveau instrument :
- Donnez lui un nom
- Un objet
- Un type (optionnel)
- Cochez Activer et Visible
Allez ensuite à l’onglet Commandes et ajoutez 3 infos virtuelles : température, humidité, baromètre. Vous pouvez en profiter pour attribuer une étiquette pour l’unité ainsi qu’une valeur mini et maxi pur l’échelle. Sauvegardez. Après la sauvegarde, un identifiant (#) est attribué pour chaque information virtuelle. Ici, température (#78), humidité (#79) et baromètre (#80). Nous en aurons besoin dans le code Arduino.
Code Arduino compatible ESP8266
C’est exactement le même que celui développé pour Domoticz, il n’y a que la construction de la requête HTTP qui change. Contrairement à Domoticz, on doit envoyer les données séparément, c’est à dire celle qui correspond à l’instrument virtuel.
La requête HTTP prend la forme suivante
http://#IP_JEEDOM#/core/api/jeeApi.php?apikey=#APIKEY#&type=virtual&id=#ID#&value=#value#
Pour faciliter le travail, vous trouverez au début du programme les variables suivantes qu’il vous reste à modifier par vos valeurs :
const char* apiKey = "mVuQikcXm69l2mDMYZiCsLj0wamT0HsCcrBCuXRxntJDO1kn";
const char* idTemp = "78";
const char* idHumi = "79";
const char* idPA = "80";
On va donc devoir envoyer une requête HTTP pour chaque mesure et l’envoyer à l’instrument virtuel correspondant. La fonction SendToJeedom() utilise la librairie ESP8266HTTPClient pour envoyer la requête de type Get (les données étant encodées dans l’URL). En retour Jeedom, renvoi le code 200 si tout s’est bien passé.
Si la clé API est mauvaise, la librairie ESP8266HTTPClient renvoi l’erreur -11 (HTTPC_ERROR_READ_TIMEOUT). Jeedom reste muet tout simplement.
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();
Serial.println("closing connection");
http.end();
}
La requête reste un simple chaine de caractère que l’on assemble avec les différentes variables, par exemple pour la température
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);
Ce qui donne par exemple la requête suivante
/core/api/jeeApi.php?apikey=mVuQikcXm69l2mDMYZiCsLj0wamT0HsCcrBCuXRxntJDO1kn&type=virtual&id=78&value=19.8
Il suffit ensuite de reprendre la base de l’url (baseurl) qui est toujours identique et l’assembler avec l’identifiant et sa valeur. J’ai ajouté un délai de 1s entre chaque publication. Pour optimiser le code, on pourrait vérifier que l’envoi précédent a été correct avant de poursuivre.
Ouvrez l’IDE Arduino et collez le code suivant. Modifiez les variables et téléversez-le.
/*
* 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();
Serial.println("closing connection");
http.end();
}
De retour sur l’interface Jeedom, vous pouvez visualiser les mesures qui remontent de l’ESP8266 sur l’instrument virtuel.
Avez-vous aimé cet article ?