In this tutorial, we will use the ESP8266Client and ESP8266HTTPClient libraries to implement TCP/IP communication between and an ESP8266 NodeMCU module and the Domoticz API/JSON interface. We will use a temperature and humidity sensor DHT22 as well as a BMP180 atmospheric pressure sensor to publish real measurements on virtual sensors of the home automation server.
Recommended readings
If you are a beginner in home automation and Arduino programming, I advise you to start with the firmware ESP Easy (all the tutorials on the subject) which allows to create connected objects without any programming.
ESP8266 (Web Client – Part 1): TCP/IP communication (examples ESP8266WiFi and ESP866HTTPClient)
Equipment used
We will start by creating a small montage that allows you to interact between Domoticz and ESP8266. For the probe part, you can use a DHT11 or a DHT22. Quick to implement thanks to the library DHT.h Adafruit. I also added a BMP180 to create a barometer on Domoticz. For controlling the GPIO, you can use a simple LED or a relay.
Any ESP8266 ESP-12 module, for example Wemos D1 Mini | |
Power supply 5/3A micro-usb | |
|
Atmospheric pressure |
Temperature and humidity sensor | |
Shield DHT22 or DHT11 for Wemos D1 Mini.
The sensor is connected to pin D4 (GPIO2) |
|
Jumper Dupont | |
Breadboard | |
Led (optional, follow the WiFi activity) | |
Resistor 220Ω (optional) |
Circuit
Composant | Pin | Arduino Pin | ESP8266 Pin (Wemos 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 on GPIO (D7) | Pole + | GPIO13 | D7 |
Pole – | GND | G |
Domoticz communication interface (API and JSON URL)
Domoticz provides a communication interface (API) for sending data (measurement, status, etc.) from a connected object to Domoticz. In return Domoticz. This interface is very powerful. Not only is it possible to send data to Domoticz, but it is also possible to perform all administrative operations directly from the Arduino program. Here are a few :
- Create a virtual device (param = addhardware)
- Create a virtual sensor (param = createvirtualsensor)
- Add, delete a scene
- Add, delete a group
- Stop, restart the system
- …
It is also possible to retrieve the status and values of the different devices and sensors (param=getlightswitches). In return Domoticz returns a file in JSON format.
To know in detail the operation of all available commands, you can go to the official wiki.
What will be most interesting in this tutorial is how to send data to the Domoticz API. It is quite simple to implement. Domoticz retrieves the data encoded in the URL. For example, to send the temperature (26 ° C) to the device (IDX 111), it is sufficient to send to the server the following HTTP request.
http://#IP_SERVER#/json.htm?type=command¶m=udevice&idx=111&nvalue=0&svalue=26
Virtual sensor (temperature + humidity + barometer)
Before starting the Arduino code, we will create a virtual sensor that will receive measurements from the DHT22 and BMP180 connected to the ESP8266. Go to Settings and then Hardware. Create a new Dummy material. Disable the timeout and then Add.
A new material has been created. Click the Create Virtual Sensors button.
Give the sensor a name and choose the corresponding type. Here Temp+Humidity+Barometer
Once created, the virtual sensor is added to the device list. It has also been automatically added to the Temperature and Weather tabs. What is important is to identify its identifier (IDX). This is 12.
Send data from ESP8266 to Domoticz (example with DHT22 and BMP180)
Let’s move on to serious things now. Open the Arduino IDE, create a new skit and paste the complete project code. Modify the ssid, password variables and the IP address of the Domoticz server (variable host).
#include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h> #include <DHT.h> #include <Adafruit_BMP085.h> #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 ) { hum_stat = 0; } else if ( h > 45 & h <= 70 ) { hum_stat = 1; } if ( pa > 1030 ) { bar_for = 1; } else if ( pa > 1010 & pa <= 1030 ) { bar_for = 2; } else if ( pa > 990 & pa <= 1010 ) { bar_for = 3; } else if ( pa > 970 & pa < 990 ) { bar_for = 4; } String url = "/json.htm?type=command¶m=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(); }
The program is not very complicated. It should be ensured that valid measurements of the DHT22 (and BMP180) have been retrieved before sending the measurements to the server. Indeed, Domoticz does not check any incoming values. He trusts blindly. Unfortunately, the DHT.h library returns if no action is returned by the DHT. In this case, all the displays will disappear from the various tabs. No panic however, as soon as valid values are sent, the displays will be restored.
Let’s look more ready to send the measurements. If we look more closely at the wiki (here), we must send a query of the form
/json.htm?type=command¶m=udevice&idx=IDX&nvalue=0&svalue=TEMP;HUM;HUM_STAT;BAR;BAR_FOR
We already know our IDX. Here it is the 12. We will have to build a chain including the measurements of temperature, humidity and atmospheric pressure. Domoticz is also able to manage 2 other information
HUM_STAT (Humidity Status)
It is defined a little higher in the wiki but it is up to us to calculate it
- 0 = Normal (normal): 30 to 45%
- 1 = Comfortable (comfortable): from 45 to 70%
- 2 = Dry (dry): <30%
- 3 = Wet (wet)> 70%
BAR_FOR (Barometer Forecast, barometric prediction).
It is also up to us to do the work. In the absence of wind speed and direction, the forecast will be very random. We could go for information on openweatherboard.org for example. Without going so far, one can have an idea based only on the atmospheric pressure for precise beaches. Outside, we will return 0 (no info). The classification is a bit confusing, it lacks snow, thunderstorms … we will have to settle for that while waiting for an evolution.
- 0 = No info (no forecast)
- 1 = Sunny (Sunny):> 1030hPa
- 2 = Partly cloudy (partly cloudy) 1010 to 1030hPa
- 3 = Cloudy (cloudy) from 990 to 1010hPa
- 4 = Rain (from 970 to 990hPa)
This gives, for example, the following query
/json.htm?type=command¶m=udevice&idx=IDX&nvalue=0&svalue=27.10;31.10;0;981.03;4
It only remains to make a GET request. A post is not really suitable in this case because all data has been encoded in a URL. There is no other data to send to the server.
http.begin(host,port,url); int httpCode = http.GET();
It is possible to perform other verification processes by testing the code returned by the GET function.
Obtained result
Once the Arduino code is uploaded, return to the Domoticz interface. As soon as Domoticz receives the first measurements, the display will be updated.
In the next tutorial we will see how to drive the GPIO of the ESP8266 directly from Domoticz using a Dummy Device. Finally we will learn how to secure (in part) exchanges between the ESP8266 and Domoticz.
- Temperature measurement with several DS18B20 probes, Arduino code compatible ESP8266 and ESP32, publication on Domoticz in HTTP
- ESP8266. How to use WiFiManager library to manage WiFi connections
- ESP8266 (Web Client): Sending Data to Jeedom in TCP / IP Wireless (JSON API) – Part 1
- ESP8266 (Web Client): Sending Data to Domoticz in TCP/IP Wireless (API/JSON) – Part 1