Using mqtt from ESP to Openhab2

Guys, Is it possible to merge this code that i got from https://github.com/OLIMEX/ESP8266 with the one that @robb01published to read the temperature? I want to have a NodeMCU that can read the temperature and switch a relay on the same device. What should i move? Thank you for your help.

/*
 *  This code switches a relay connected to port 5 (GPIO5) on an ESP8266.
 *
 *  It will connect to MQTT and listens on topic house/2/attic/cv/thermostat/relay
 *  for 'on' and 'off' commands. Every 60 seconds, it will publishes te current
 *  state on house/2/attic/cv/thermostat/relay_state
 *
 *  Dimitar Manovski
 *  support@smart-republic.com
 *
 * 
 *
 */


#include <ESP8266WiFi.h>
#include <PubSubClient.h>

int RelayPin = 5;    // RELAY connected to digital pin 5

const char* ssid     = "comhem_D64E3F";
const char* password = "b7at87t6";

//change with your MQTT server IP address
const char* mqtt_server = "192.168.0.10";


WiFiClient espClient;
PubSubClient client(espClient);


void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print(topic);
  Serial.print(" => ");

char* payload_str;
  payload_str = (char*) malloc(length + 1);
  memcpy(payload_str, payload, length);
  payload_str[length] = '\0';
Serial.println(String(payload_str));
  
  if ( String(topic) == "house/2/attic/cv/thermostat/relay" ) {
    if (String(payload_str) == "on" ) {
      digitalWrite(RelayPin, HIGH);   // turn the RELAY on
      client.publish("house/2/attic/cv/thermostat/relay_state","on");
    } else if ( String(payload_str) == "off" ) {
      digitalWrite(RelayPin, LOW);    // turn the RELAY off
      client.publish("house/2/attic/cv/thermostat/relay_state","off");
    } else {
      Serial.print("I do not know what to do with ");
      Serial.print(String(payload_str));
      Serial.print(" on topic ");
      Serial.println( String(topic));
    }
  }
}

void connect_to_MQTT() {
 client.setServer(mqtt_server, 1883);
  client.setCallback(callback);

  if (client.connect("thermostat_relay")) {
    Serial.println("(re)-connected to MQTT");
    client.subscribe("house/2/attic/cv/thermostat/relay");
  } else {
    Serial.println("Could not connect to MQTT");
  }
}

void setup() {
  Serial.begin(115200);
  delay(10);

  // Connecting to our WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  connect_to_MQTT();

  // initialize pin 5, where the relay is connected to.
  pinMode(RelayPin, OUTPUT);
}

int tellstate = 0;

void loop() {
  client.loop();

  if (! client.connected()) {
    Serial.println("Not connected to MQTT....");
    connect_to_MQTT();
    delay(5000);
  }

  // Tell the current state every 60 seconds
  if ( (millis() - tellstate) > 60000 ) {
    if ( digitalRead(RelayPin) ) {
       client.publish("house/2/attic/cv/thermostat/relay_state","on");
    } else {
      client.publish("house/2/attic/cv/thermostat/relay_state","off");
    }
    tellstate = millis();
  }
}

It must be possible, but I’ve not dealt hands on with INO and ESP etc so this comes with out a guarantee!

You need to deal with a couple of main changes:

  1. subscribe to MQTT messages
  2. callback to handle the MQTT subscribed messages
  3. setup and initialise the relay pins

The subscription is easy, the above code is doing it here:

    client.subscribe("house/2/attic/cv/thermostat/relay");

change to suit your own path/message preferences.

Re the callback you can copy the whole ‘callback’ rountine and again in set up just after client.setServer he is registering the callback with MQTT:

  client.setCallback(callback);

take and change the PIN number to suit your deployment:

int RelayPin = 5;    // RELAY connected to digital pin 5

and finally in your setup rountine ensure it is initialised:

  // initialize pin 5, where the relay is connected to.
  pinMode(RelayPin, OUTPUT);

You need to change some code in the callback based again on the paths of the MQTT messages you subscribe to. Hmm looking at the callback it looks like it’s got a memory leak, malloc with no free.

This is also publishing the state of the relay back to MQTT during idle loops but you can choose to take that or not.

Oh the danger of sketching this out on the fly you will also need to change the main loop. MQTT needs to be given processing time to receive and trigger callbacks which is what this is doing:

  client.loop();

Because the temperature stuff is only publishing the main loop looks to sleep and exit every 60 seconds. Interesting does the ESP module stuff just rerun the main loop for you, how frequently and does it retain global states?
Whatever way that works you’ll need to change the main loop to ensure you call the “client.loop()” on the MQTT object frequently so no 60 second sleeping. So take the princinple of the main loop from this example without the sleep so you move the existing publishing to here like:

  // Tell the current state every 60 seconds
  if ( (millis() - tellstate) > 60000 ) {
     getTemperature();
     getVoltage();
     tellstate = millis();
  }

Hope that all makes sense!

I have an ESP2866 with connected relay arriving sometime in the next month so may be back then when I get real hands on with compiling it all although I wont have the temperature publishing need so still wont be exactly the same. This stuff will all be good for me to build from so thanks to all.

1 Like

ESPEasy makes this all very simple.

The Temperature/Humidity can be read and sent via MQTT, with a specified delay between readings (ie every 60 seconds)

It is also very easy to publish an MQTT topic from OpenHAB for a GPIO to be toggled.

https://www.letscontrolit.com/wiki/index.php/Tutorial_OpenHAB_Switch

1 Like

Can it do both at the same time @Confused?

I tried to create a sketch which could do both but failed miserably. I’ll try again some time. @RayMYP’s post above is extremely good

Cool and this does look ‘Easy’. Will add to my list to investigate when I have some toys to play with…thanks

Thank you very much @RayMYP. Very much appreciated. I will try it and will come back with the results. Thanks.

@Rob_Pope I think your “issue” was that you are Sleeping for 60 seconds - so nothing can be done during this time.

The approach that @RayMYP looks similar to what I have done in another sketch - subscribe to a topic, set a callback, and then do the DHT stuff once every X seconds, but let the loop continue to run as quickly as possible.

You won’t get good time on battery (which I know was one of your goals) but if you wanted the “roll your own” approach, then this should work - but likewise ESPEasy will also work very well, and has quite a bit of functionality.

1 Like

There are always trade offs :slight_smile:

As I said still picking up on the real world implementation of ESP but if the mainloop executes full speed like thousands of times a second then I’d re-add a sleep anyway. My requirements on the response time of my relay aren’t going to be mission critical so I’d probably stick a 5 second sleep back in to balance battery/power against response times. Some MQTT libraries have a loop(delay) option but can’t see it here unless I’m looking at the wrong code base which is entirely possible.

My existing deployment is on a PiZero using Python which makes life easy as it provides nice background threading out of the box. Don’t need to change it really but a full debian OS stack strapped to a relay handling MQTT seems over kill and it’s fun to try these things.

I tried to merge both of the codes and I ended up with this piece of code that you can read below. The problem is that I doesnt connect to the MQTT broker. It does show temperature, humidity and voltage in the Serial Monitor, but it doesnt say that it was successfuly connected to the broker and I dont get any messages at all in the MQTT.fx that Im using to monitor the network. Can somebody take a look at it because I only understand pieces of it. I bought my first Arduino yesterday morning.
Thank you in advance.

//Required for VCC
ADC_MODE(ADC_VCC);

//Import Libraries
#include <ESP8266WiFi.h>
#include <DHT.h>
#include <PubSubClient.h>

// WiFi parameters
const char* ssid = "comhem_D64E3F";
const char* password = "b7at87t6";

//Create client
WiFiClient client;

// DHT11 Temperature chip i/o
#define DHTPIN 2
#define DHTTYPE DHT11
DHT dht(DHTPIN,DHTTYPE);

// Realy module i/o
int RelayPin = 5;

//MQTT Configuration
PubSubClient mosq(client);
char tmp[50];
char hum[50];

void setup() {
  // Start Serial
  Serial.begin(115200);
  
  // Connect to WiFi  
  Serial.print("Connecting to WiFi");
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  // Print the IP address
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print(topic);
  Serial.print(" => ");

char* payload_str;
  payload_str = (char*) malloc(length + 1);
  memcpy(payload_str, payload, length);
  payload_str[length] = '\0';
Serial.println(String(payload_str));
  
  if ( String(topic) == "sensor/relay" ) {
    if (String(payload_str) == "on" ) {
      digitalWrite(RelayPin, HIGH);   // turn the RELAY on
      mosq.publish("sensor/relay_state","on");
    } else if ( String(payload_str) == "off" ) {
      digitalWrite(RelayPin, LOW);    // turn the RELAY off
      mosq.publish("sensor/relay_state","off");
    } else {
      Serial.print("I do not know what to do with ");
      Serial.print(String(payload_str));
      Serial.print(" on topic ");
      Serial.println( String(topic));
    }
  }
  //Connect to Mosquitto Server
  mosq.setServer("192.168.0.10",1883);
    mosq.setCallback(callback);
    mosq.subscribe("sensor/relay");
    Serial.print(String(payload_str));

  //Initialize pin 5
  pinMode(RelayPin, OUTPUT);
}

void loop() {
    if(!mosq.connected()){
      mosq.connect("client2");
      getTemperature();
      getVoltage();
    }
    
    delay(60000);
}

void getTemperature() {
  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  //Temp as string
  itoa(t,tmp,10);
  mosq.publish("sensor/temperature",tmp);
  Serial.println(tmp);

  //Humidity as string
  itoa(h,hum,10);
  mosq.publish("sensor/humidity",hum);
  Serial.println(hum);
}

void getVoltage() {
  int iVcc = ESP.getVcc();
  float fVcc = (float)ESP.getVcc() / 1000;
  char cVcc[5];
  dtostrf(fVcc,5, 3, cVcc);
  
  mosq.publish("sensor/voltage",cVcc);
  Serial.println(cVcc);
}

You’ve somehow moved these lines in side of the ‘callback’ rountine, they should be put in at the end of ‘setup’ once the WiFi is connected.

I’ve highlighted the Serial.print line as that should be left in ‘callback’

I was hoping that it could print the status of the relay (“on” or “off”)

You also need to add:

mosq.loop();

inside the main loop. You’ve left the timing as was so it could be a maximum of 60 seconds before you’re relay triggers (assuming there aren’t lots more bugs)

Uf @RayMYP, no idea where to put it. I already put a void loop() Where should I put the mosq.loop();? and what should it contains? I modified it now. It looks like this:

  //Connect to Mosquitto Server
  mosq.setServer("192.168.0.10",1883);
    mosq.setCallback(callback);

    if (mosq.connect("thermostat_relay")) {
    Serial.println("(re)-connected to MQTT");
    mosq.subscribe("sensor/relay");
  } else {
    Serial.println("Could not connect to MQTT");
  }

  //Initialize pin 5
  pinMode(RelayPin, OUTPUT);
}

void loop() {
    if(!mosq.connected()){
      mosq.connect("client2");
      getTemperature();
      getVoltage();
    }
    
    delay(60000);
}

Doesn’t look like you’ve moved the block of code I mentioned. It has to go in setup otherwise nothing will ever happen on your subscribe because you’re trying to register ‘callback’ from within the ‘callback’ routine.

I’ve swapped the ‘setup’ and ‘callback’ rountine around in the file as I would guess the compiler will complain otherwise something like ‘setup’ using undefined function ‘callback’.

Seriously can’t do much more for you than that as it’s late and time for some sleep before back to the grind stone tomorrow.

//Required for VCC
ADC_MODE(ADC_VCC);

//Import Libraries
#include <ESP8266WiFi.h>
#include <DHT.h>
#include <PubSubClient.h>

// WiFi parameters
const char* ssid = "comhem_D64E3F";
const char* password = "b7at87t6";

//Create client
WiFiClient client;

// DHT11 Temperature chip i/o
#define DHTPIN 2
#define DHTTYPE DHT11
DHT dht(DHTPIN,DHTTYPE);

// Realy module i/o
int RelayPin = 5;

//MQTT Configuration
PubSubClient mosq(client);
char tmp[50];
char hum[50];

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print(topic);
  Serial.print(" => ");

char* payload_str;
  payload_str = (char*) malloc(length + 1);
  memcpy(payload_str, payload, length);
  payload_str[length] = '\0';
Serial.println(String(payload_str));

  if ( String(topic) == "sensor/relay" ) {
    if (String(payload_str) == "on" ) {
      digitalWrite(RelayPin, HIGH);   // turn the RELAY on
      mosq.publish("sensor/relay_state","on");
    } else if ( String(payload_str) == "off" ) {
      digitalWrite(RelayPin, LOW);    // turn the RELAY off
      mosq.publish("sensor/relay_state","off");
    } else {
      Serial.print("I do not know what to do with ");
      Serial.print(String(payload_str));
      Serial.print(" on topic ");
      Serial.println( String(topic));
    }
  }
    Serial.print(String(payload_str));
}

void setup() {
  // Start Serial
  Serial.begin(115200);

  // Connect to WiFi  
  Serial.print("Connecting to WiFi");
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  // Print the IP address
  Serial.println(WiFi.localIP());

  //Connect to Mosquitto Server
  mosq.setServer("192.168.0.10",1883);
    mosq.setCallback(callback);
    mosq.subscribe("sensor/relay");

  //Initialize pin 5
  pinMode(RelayPin, OUTPUT);
}

void loop() {
    if(!mosq.connected()){
      mosq.connect("client2");
      getTemperature();
      getVoltage();
    }
   mosq.loop()

    delay(10000);
}

void getTemperature() {
  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  //Temp as string
  itoa(t,tmp,10);
  mosq.publish("sensor/temperature",tmp);
  Serial.println(tmp);

  //Humidity as string
  itoa(h,hum,10);
  mosq.publish("sensor/humidity",hum);
  Serial.println(hum);
}

void getVoltage() {
  int iVcc = ESP.getVcc();
  float fVcc = (float)ESP.getVcc() / 1000;
  char cVcc[5];
  dtostrf(fVcc,5, 3, cVcc);

  mosq.publish("sensor/voltage",cVcc);
  Serial.println(cVcc);
}

Thank you for your help. I will also continue tomorrow.

New Update. I print out both of the codes, I analysed every int, char and void, I red about arduino syntaxis, I red the documentation related to the PubSubClient library and after long hours of study I came up with this:

//Import Libraries
#include <ESP8266WiFi.h>
#include <DHT.h>
#include <PubSubClient.h>

// DHT11 Temperature chip i/o
#define DHTPIN 2 //NodeMCU pin D4
#define DHTTYPE DHT11
DHT dht(DHTPIN,DHTTYPE);
char tmp[50];
char hum[50];

int RelayPin = 5; //Set Relay to be connected to digital pin 5 (NodeMCU pin D1)

//Wifi/Broker parameters
const char* ssid = "comhem_D64E3F"; //Wifi network SSID
const char* password = "b7at87t6"; //Wifi network PASSWORD
const char* mqtt_server = "192.168.0.10"; //Broker IP Address

//MQTT Configuration
WiFiClient espClient; //Creates a partially initialised client instance.
PubSubClient client(espClient); //Before it can be used, the server details must be configured

void connect_to_MQTT() {
 client.setServer(mqtt_server, 1883);//Set the MQTT server details
  client.setCallback(callback);

  if (client.connect("temperature_sensor_relay")) {
    Serial.println("Connected to MQTT Server");
    client.subscribe("sensor/relay");
  } else {
    Serial.println("Could not connect to MQTT");
  }
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print(topic);
  Serial.print(" => ");

char* payload_str;
  payload_str = (char*) malloc(length + 1);
  memcpy(payload_str, payload, length);
  payload_str[length] = '\0';
Serial.println(String(payload_str));
  
  if ( String(topic) == "sensor/relay" ) {
    if (String(payload_str) == "on" ) {
      digitalWrite(RelayPin, HIGH);   // turn the RELAY on
      client.publish("sensor/relay_state","on");
    } else if ( String(payload_str) == "off" ) {
      digitalWrite(RelayPin, LOW);    // turn the RELAY off
      client.publish("sensor/relay_state","off");
    } else {
      Serial.print("I cannot process ");
      Serial.print(String(payload_str));
      Serial.print(" on topic ");
      Serial.println( String(topic));
    }
  }
}

void setup() {
  Serial.begin(115200); //Sets the data rate in bits per second (baud) for serial data transmission.

// Connecting to our WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  // initialize pin 5, where the relay is connected to.
  pinMode(RelayPin, OUTPUT);

  connect_to_MQTT();
}

int tellstate = 0;

void getTemperature() {
  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  //Temp as string
  itoa(t,tmp,10);
  client.publish("sensor/temperature",tmp);
  Serial.println(tmp);

  //Humidity as string
  itoa(h,hum,10);
  client.publish("sensor/humidity",hum);
  Serial.println(hum);
}

void getVoltage() {
  int iVcc = ESP.getVcc();
  float fVcc = (float)ESP.getVcc() / 1000;
  char cVcc[5];
  dtostrf(fVcc,5, 3, cVcc);
  
  client.publish("sensor/voltage",cVcc);
  Serial.println(cVcc);
}
  
void loop() {
  client.loop();

  if (! client.connected()) {
    Serial.println("Not connected to MQTT....");
    connect_to_MQTT();
    delay(5000);
    getTemperature();
    getVoltage();
  }
 
 // Tell relay the current state every 60 seconds
  if ( (millis() - tellstate) > 60000 ) {
    if ( digitalRead(RelayPin) ) {
       client.publish("sensor/relay_state","on");
    } else {
      client.publish("sensor/relay_state","off");
    }
    tellstate = millis();
  }
}
 

The relay publishes the status as it should. Im connected to the Wifi and to MQTT server but the temperature sensor does not publishes anything. My guess is I should put:

    getTemperature();
    getVoltage();

Inside the callback function. Can anybody explain me how can i merge void getTemperature(); and void getVoltage(); inside void callback();?

I have 3 questions:
What does: “char tmp[50];” and “char hum[50];” means?
What does “char* payload_str;” actually do?
What does “int tellstate = 0;” means?

Thank you for your help. I will be here…waiting. Thanks.

It is declaring an array of char, or as some people understand it a string with space for 50 characters.

It’s declaring a pointer to a char. Probably not enough space here to go over what pointers are so could only recommend searching for something like “C and pointers”. The line following it uses malloc to allocate memory for a string that the pointer is pointing to, that’s where the memory leak is as it doesn’t get freed. Welcome to the power of C and also its challenges.

It’s a global number variable initialised to zero, personally I’d move it up to the top with the other global variable declarations. The main loop uses it to count out the 60 seconds between updates.

I very much doubt you want getTemperature and getVoltage in the callback function. MQTT will only trigger that when your subscribed messages are received, so you’d only get temperature and voltage updates when you switched the relay if you put it in callback.

Try this change on the main loop:

void loop() {
  client.loop();

  if (! client.connected()) {
    Serial.println("Not connected to MQTT....");
    connect_to_MQTT();
  }
 
 // Tell relay the current state every 60 seconds
  if ( (millis() - tellstate) > 60000 ) {
    getTemperature();
    getVoltage();
    if ( digitalRead(RelayPin) ) {
      client.publish("sensor/relay_state","on");
    } else {
      client.publish("sensor/relay_state","off");
    }
    tellstate = millis();
  }
}

Thank you very much to everyone!. It is a success! Now the hole code is working to declare temperature/humidity and to operate the switch!.

This is the complete code:

//Import Libraries
#include <ESP8266WiFi.h>
#include <DHT.h>
#include <PubSubClient.h>

// DHT11 Temperature chip i/o
#define DHTPIN 2 //NodeMCU pin D4
#define DHTTYPE DHT11
DHT dht(DHTPIN,DHTTYPE);
char tmp[50];
char hum[50];
int tellstate = 0;

int RelayPin = 5; //Set Relay to be connected to digital pin 5 (NodeMCU pin D1)

//Wifi/Broker parameters
const char* ssid = "comhem_D64E3F"; //Wifi network SSID
const char* password = "b7at87t6"; //Wifi network PASSWORD
const char* mqtt_server = "192.168.0.10"; //Broker IP Address

//MQTT Configuration
WiFiClient espClient; //Creates a partially initialised client instance.
PubSubClient client(espClient); //Before it can be used, the server details must be configured

void connect_to_MQTT() {
 client.setServer(mqtt_server, 1883);//Set the MQTT server details
  client.setCallback(callback);

  if (client.connect("temperature_sensor_relay")) {
    Serial.println("Connected to MQTT Server");
    client.subscribe("sensor/relay");
  } else {
    Serial.println("Could not connect to MQTT");
  }
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print(topic);
  Serial.print(" => ");

char* payload_str;
  payload_str = (char*) malloc(length + 1);
  memcpy(payload_str, payload, length);
  payload_str[length] = '\0';
Serial.println(String(payload_str));
  
  if ( String(topic) == "sensor/relay" ) {
    if (String(payload_str) == "on" ) {
      digitalWrite(RelayPin, HIGH);   // turn the RELAY on
      client.publish("sensor/relay_state","on");
    } else if ( String(payload_str) == "off" ) {
      digitalWrite(RelayPin, LOW);    // turn the RELAY off
      client.publish("sensor/relay_state","off");
    } else {
      Serial.print("I cannot process ");
      Serial.print(String(payload_str));
      Serial.print(" on topic ");
      Serial.println( String(topic));
    }
  }
}

void setup() {
  Serial.begin(115200); //Sets the data rate in bits per second (baud) for serial data transmission.

// Connecting to our WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  // initialize pin 5, where the relay is connected to.
  pinMode(RelayPin, OUTPUT);

  connect_to_MQTT();
}

void getTemperature() {
  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  //Temp as string
  itoa(t,tmp,10);
  client.publish("sensor/temperature",tmp);
  Serial.println(tmp);

  //Humidity as string
  itoa(h,hum,10);
  client.publish("sensor/humidity",hum);
  Serial.println(hum);
}

void getVoltage() {
  int iVcc = ESP.getVcc();
  float fVcc = (float)ESP.getVcc() / 1000;
  char cVcc[5];
  dtostrf(fVcc,5, 3, cVcc);
  
  client.publish("sensor/voltage",cVcc);
  Serial.println(cVcc);
}
  
void loop() {
  client.loop();

  if (! client.connected()) {
    Serial.println("Not connected to MQTT....");
    connect_to_MQTT();
  }

 //Every 60 seconds read the temperature, humidity and relay state
  if ( (millis() - tellstate) > 60000 ) {
    getTemperature();
    getVoltage();
    if ( digitalRead(RelayPin) ) {
       client.publish("sensor/relay_state","on");
    } else {
      client.publish("sensor/relay_state","off");
    }
    tellstate = millis();
  }
}
 

Now I will work on that memory leak. I will come back. Thank you.

Glad it’s working. It would be helpful for others if you also shared any of your relevant Items definitions, guessing you don’t have any related Things.

Also just remembered about adding in a slight delay to the main loop, probably last line. At the moment the ESP unit will be running at 100% speed, an issue for batteries but also unnecessary really so you can pick a number to suit your own preference of how fast you want the relay to respond i.e. 500, 1000, 5000 or 10000

For the memory leak add as the last line of the callback rountine:

free(payload_str)

Of course. This is my home.items:


//Temperature Sensors
Number Temperature "Temperature [%.1f °C]" {mqtt="<[broker:sensor/temperature:state:default]"}
Number Humidity "Humidity [%.1f%%]" {mqtt="<[broker:sensor/humidity:state:default]"}

Switch Relay "Channel 1" {mqtt=">[broker:sensor/relay:command:ON:on],>[broker:sensor/relay:command:OFF:off]"}

Im trying to make the HomeKit binding to work, but everytime I add [ “Lighting” ] , the switch stop working. I don´t know if its possible to use HomeKit on devices connected to an MQTT network. If anybody knows something please let me know. Thanks.