Friday, November 6, 2020

Sending data from ESP to Domoticz part II

For an index to all my stories click this text

In the first part of this series I showed you how to switch your lights on and off by having an ESP 8266 sending commands to Domoticz. You can re-read that story here: http://lucstechblog.blogspot.com/2020/01/sending-data-from-esp-to-domoticz.html

In this part I am going to show you how to build a thermometer with an ESP8266 and have it send it's data to Domoticz. Naturally the thermometer can be used as an example to send any information you like to Domoticz and display it on the Dashboard.

Domoticz part

First step is to build a Virtual sensor in Domoticz. This is a sensor that is not physically connected to Domoticz. So start with opening your web-browser and open your Domoticz dashboard.




Go to the settings tab in Domoticz and choose hardware.



Fill in the name, I choose Virtual 2 as I already have another ESP running as a thermometer. Feel free to use a meaningfull name for yourself.
As type select Dummy, and choose add.




As you can see in the list Virtual 2 has been added. This device has been given an IDX which is not important for us now.



Now on the line with Virtual 2 click on the blue button that mentions: Create virtual sensors. A small screen opens in which you can give your sensor a name and you can select a type from the drop-down list. Choose a meaningfull name and as type choose temperature.

Briefly a popup screen appears mentioning that a new sensor has been created which is visible in the devices menu.


In the devices menu you will find your new designed thermometer. In my particular case it has IDX 5223. This is important as you will need this jnumber in the ESP8266 program later on.


Now move over to the Temperature tab and there your new thermometer is visible. The temperature is set at 0 degrees Celsius as no data has been received yet.

ESP8266 part

Building a thermometer with an ESP8266 is actually quite easy. You will only need an ESP8266,  a Dallas DS18B20 thermometer chip and a 4k7 pull up resistor.
You can find a detailed description on how to build one here: http://lucstechblog.blogspot.com/2017/11/oh-no-not-another-wifi-thermometer.html

This time we are going to do things differently. I am going to use an ESP8266 and the software will be in Arduino IDE (C++) and NOT in ESPBasic.


As you can see the breadboard setup is very straightforward. As mentioned just an ESP8266 (Wemos Mini D1 clone), a DS18B20 and a 4k7 pull-up resistor attached to D4 (GPIO 2).

Testing The DS18B20

Before we will send data to Domoticz we have to make sure that the Dallas DS18B20 works like it should.

This is one of the most usefull things I learned during all my years as tinkerer. Do everything step by step. This makes searching for errors much easier. If we directly started with software that send data to Domoticz, and it did not work we could not be sure wether the hardware of the software was the faulty part. So lets do this step by step.



// Test program for Dallas DS18B20
// Adapted by Luc Volders

// Include the libraries we need
#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is connected to GPIO 2 (D4) on the Wemos D1 mini
#define dallasiopin 2

// Setup a oneWire instance
OneWire oneWire(dallasiopin);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);


void setup()
{
  // start serial port
  Serial.begin(9600);
  Serial.println("Dallas Temperature Demo");

  // Start the library
  sensors.begin();
}


void loop()
{ 
  Serial.print("Requesting temperatures...");
  sensors.requestTemperatures();
  Serial.println("DONE");
  // When we got the temperatures, we can print it here.
  // Use the temperature from the first sensor only.
  Serial.print("Temperature for the device 1 (index 0) is: ");
  Serial.println(sensors.getTempCByIndex(0));  
  delay (2000);
}


A quick look at the program.

First two libraries are loaded: OneWire and DallasTemperature. The first one takes care of the communication between the ESP and the DS18B20 over the one wire. The second library reads  and interprets the received data.

We define that the OneWire library is connected to dallasiopin which is IO pin 2 (D4)

In the setup we open the Serialport so we can see what happens, and start the DallasTemperature library with the attached command sensors.begin()

In the loop the actual reading from the sensor is done.

sensors.requestTemperatures();

This is the line that gets the temperature from one (or more attached) sensor(s).

Serial.println(sensors.getTempCByIndex(0));

And this line prints the temperature fetched from sensor (0) in Celsius.

You can alter this line in:

Serial.println(sensors.getTempFByIndex(0));

to get the temperature in Fahrenheit.

Compile and upload the code with the Arduino IDE and open the Serial Monitor.



This is what you will see as the temperature in your case will undoubtedly be different. As you can see it is rather cold in my mancave.

As the test is successfull we can now be sure that the hardware is working ok.

Domoticz API

To send data to Domoticz we have to use the API. So let's visit the Domoticz documentation again. In the previous story I showed you where to find it. Here is the link again:
https://www.domoticz.com/wiki/Domoticz_API/JSON_URL's

Scroll a bit down the list and in the index you can see that Chapter 7 part 7.1 gives you details about using a temperature sensor. So move to that part:
https://www.domoticz.com/wiki/Domoticz_API/JSON_URL's#Temperature

Here we can see that the API for uploading temperature to Domoticz is as follows:

/json.htm?type=command&param=udevice&idx=IDX&nvalue=0&svalue=TEMP

IDX is the number of your device in Domoticz
TEMP is the temperature.

We have to incorporate this in our program.

We will use the same program as in the previous story but make alterations for the Dallas DS18B20 and the different API call.


// Program to send Temperature data from a
// Dallas DS18B20 with an ESP8266 to Domoticz
// adapted by Luc Volders

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into GPIO 2 (D4) on the Wemos D1 mini
#define dallasiopin 2

// Setup a oneWire instance
OneWire oneWire(dallasiopin);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

// WiFi settings
#define wifi_ssid "XXXXXXXXXXXXX"
#define wifi_password "YYYYYYYYYYY"

// HTTP Domoticz settings
const char* host = "192.168.1.66";
const int   port = 8080;

HTTPClient http;

void setup() 
{
  Serial.begin(115200);
  setup_wifi();   

  // Start up the library
  sensors.begin();
}

void settemp()
{
  Serial.print("Requesting temperatures...");
  sensors.requestTemperatures();
  Serial.println("DONE");
  // After we got the temperatures, we can print them here.
  // Get the temperature from the first sensor only.
  Serial.print("Temperature for the device 1 (index 0) is: ");
  int TEMP = (sensors.getTempCByIndex(0));
  Serial.println(TEMP);
  // Here is the Json format that Domoticz expects
  // /json.htm?type=command&param=udevice&idx=IDX&nvalue=0&svalue=TEMP
  String url = "/json.htm?type=command&param=udevice&idx=";
  url += String(5223);
  url += "&nvalue=0&svalue="; 
  url += String(TEMP);

  sendToDomoticz(url);
}  

void loop() 
{
  settemp();
  delay (300000);
}

//Connect to 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.println("WiFi connection Established");
  Serial.print("IP Adress : ");
  Serial.print(WiFi.localIP());
}


void sendToDomoticz(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();
}


As you can see this software is adapted from the software we used in the previous story. A close examination of the most important parts will help you adapt it for your own purposes.

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>

The program starts with importing the necessary libraries. After that the DallasTemperature and OneWire setup is done as described above in our test program.

// WiFi settings
#define wifi_ssid "XXXXXXXXXXXXX"
#define wifi_password "YYYYYYYYYYY"

// HTTP Domoticz settings
const char* host = "192.168.1.66";
const int   port = 8080;

Here you have to fill in your own credentials and IP number of your Domoticz system.

Move over to the setup part.

sensors.begin();

This command starts the reading of the DS18B20 sensor

setup_wifi();

This calls our Wifi setup routine. In that routine a connection is established with your router and the program displays the IP number of the ESP in the serial monitor. Then automatically the void loop() is called.
In the loop the settemp() routine is called every 5 minutes. This is achieved by the delay(300000). Five minutes is 5 x 60 (seconds) x 1000 (milis) = 300000. This value is ok for testing purposes. Sending temperature every 5 minutes is a totall overkill for Domoticz. So adapt this to your own needs. Every half hour would be more appropriate. Therefore change the delay value to 30 * 60 *1000 = 18000000

In the settemp() routine all the elements of the API call are assembled in the variable url. In the documentation we saw that the API call was as follows:

/json.htm?type=command&param=udevice&idx=IDX&nvalue=0&svalue=TEMP

So this is build step by step into the variable url.

String url = "/json.htm?type=command&param=udevice&idx=";

Here the first part of the call is put into the variable.

url += String(5223);

This line adds the IDX. Replace this with your own IDX.

url += "&nvalue=0&svalue=";
url += String(TEMP);

These lines add the last part of the API call. TEMP is a figure and converted to a string with STRING(TEMP) The value TEMP is the temperature collected by this statement:

int TEMP = (sensors.getTempCByIndex(0));

That's all.

Again compile and upload the code with the Arduino IDE and open the Serial Monitor. In the serial monitor you can see, just as with our teswt program,

Back to Domoticz

First wrap your fingers around the DS18B20 and make sure this makes the temperature go up.

Now open Domoticz in your webbrowser and go to the temperature tab. There you will see something similar to this:


As you can see the ESP8266 indeed send the temperature from the DS18B20 straight to Domoticz. The icecube has been replaced with the actual value.

This story and the previous one showed you how to control light switches through Domoticz with an ESP8266 and send a sensor value to Domoticz.

Next time we are going to expand the program to build a webpage that contains buttons for switching the light switches and displays the temperature that is send to Domoticz.

For now you will have enough documentation to control switches and send all kinds of data from various sensors to Domoticz. Just adapt the program to using the right API call which can be found in the Domoticz documentation.

Till next time
have fun

Luc Volders