Arduino sketch for auto dsicovery of ESP32

Hello,

I was searching a day…

Can anyone guide me for autodiscovery in openhab passing by MQTT ? Tutorial ? Example Code ?

I have been able to auto-integrate a ESP32 code for controlling a HeatPump (F1p on github) using HA autodiscovery. It has also auto-integrate HomeAssistant…. Without much control from me.

I wanted to come back to understand what happens and I erase these integrations. And it is no more recognize :(:::

I tried this simple example to understand but it is not recognize either :

Please help me

/**************************************************************************************************************************************************
* File name     : ESP32_HA_Discovery.c
* Compiler      : 
* Autor         : VIGASAN   
* Created       : 27/01/2023
* Modified      : 
* Last modified :
*
*
* Description   : 
*
* Other info    : Discovery MQTT Device Example
**************************************************************************************************************************************************/


/*-----------------------------------------------------------------------------------------------------------------------------------------------*/
/*------------------------------------Include Files----------------------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------------------------------------------------------------------*/
#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
//#include "DHT.h"


/*-----------------------------------------------------------------------------------------------------------------------------------------------*/
/*------------------------------------Local definitions------------------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------------------------------------------------------------------*/
#define PERIOD_MILLSEC_1000    1000
#define PERIOD_MILLSEC_500     500
#define PERIOD_MILLSEC_250     250

#define DHTTYPE             DHT22

/*-----------------------------------------------------------------------------------------------------------------------------------------------*/
/*------------------------------------I/O Definitions--------------------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------------------------------------------------------------------*/
const int IN_DETECT = 5; 
const int DHTPIN = 22;

/*-----------------------------------------------------------------------------------------------------------------------------------------------*/
/*------------------------------------ Configuration --------------------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------------------------------------------------------------------*/
const char*         g_ssid = "NicoBrez";
const char*         g_password = "ecole2vaumeilh";
const char*         g_mqtt_server = "192.168.1.13";                           // MQTT Server IP, same of Home Assistant
const char*         g_mqttUser = "nico";                                 // MQTT Server User Name
const char*         g_mqttPsw = "nicouille";                                   // MQTT Server password
int                 g_mqttPort = 1883;                                        // MQTT Server Port

// Variable used for MQTT Discovery
const char*         g_deviceModel = "ESP32C3";                            // Hardware Model
const char*         g_swVersion = "1.0";                                      // Firmware Version
const char*         g_manufacturer = "Vigasan";                               // Manufacturer Name
String              g_deviceName = "CustomSensor";                            // Device Name
String              g_mqttStatusTopic = "esp32iotsensor/" + g_deviceName;     // MQTT Topic
            

/*-----------------------------------------------------------------------------------------------------------------------------------------------*/
/*------------------------------------Public variables-------------------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------------------------------------------------------------------*/
WiFiClient          g_WiFiClient;
PubSubClient        g_mqttPubSub(g_WiFiClient);
unsigned long       g_Time = 0;
int                 g_count = 0;
int                 g_input_Door; 
int                 g_old_input_Door = 0;
String              g_strDoorStatus;
int                 g_mqttCounterConn = 0;
float               g_Humidity = 0.0;
float               g_Temperature = 0.0;
bool                g_InitSystem = true;
String              g_UniqueId;
bool                g_SendMqttData = false;
//uDHT                 g_dht(DHTPIN, DHTTYPE);
             
/*-----------------------------------------------------------------------------------------------------------------------------------------------*/
/*------------------------------------ SETUP ----------------------------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------------------------------------------------------------------*/
void setup() 
{
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Input output Pin definitions
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    pinMode(IN_DETECT, INPUT);

    //g_dht.begin();

    Serial.begin(115200);
    delay(500);

    Serial.println("");
    Serial.println("");
    Serial.println("----------------------------------------------");
    Serial.print("MODEL: ");
    Serial.println(g_deviceModel);
    Serial.print("DEVICE: ");
    Serial.println(g_deviceName);
    Serial.print("SW Rev: ");
    Serial.println(g_swVersion);
    Serial.println("----------------------------------------------");
   
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Wifi Init
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    setup_wifi();

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // MQTT Init
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    g_mqttPubSub.setServer(g_mqtt_server, g_mqttPort);
    g_mqttPubSub.setCallback(MqttReceiverCallback);
}


/*-----------------------------------------------------------------------------------------------------------------------------------------------*/
/*------------------------------------ LOOP -----------------------------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------------------------------------------------------------------*/
void loop() 
{
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // MQTT Connection
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    if(WiFi.status() == WL_CONNECTED)
    {
        if(!g_mqttPubSub.connected())
            MqttReconnect();
        else
            g_mqttPubSub.loop();
    }

    if(g_InitSystem)
    {
        delay(100);
        g_InitSystem = false;
        Serial.println("INIT SYSTEM...");
        MqttHomeAssistantDiscovery();     // Send Discovery Data
    }

    if(millis() - g_Time > PERIOD_MILLSEC_1000)  
    {
        g_Time = millis();

        ////////////////////////////////////////////////////////////////
        // DIGITAL INPUTS
        ////////////////////////////////////////////////////////////////
        g_input_Door = digitalRead(IN_DETECT); 
        
        if(g_input_Door == 0) 
            g_strDoorStatus = "ON";
        else
            g_strDoorStatus = "OFF";

        if(g_old_input_Door != g_input_Door)
        {
            g_old_input_Door = g_input_Door;
            g_SendMqttData = true;
            Serial.print("Door Status: ");
            Serial.println(g_strDoorStatus);
        }
        
            ////////////////////////////////////////////////////////////////
            // TEMPERATURE HUMIDITY
            ////////////////////////////////////////////////////////////////
            //g_Temperature = g_dht.readTemperature();
            //g_Humidity = g_dht.readHumidity();

            g_Temperature += 0.1;
            g_Humidity += 0.2;


            Serial.print("Temperature: ");
            Serial.print(g_Temperature);
            Serial.println(" °C");

            Serial.print("Humidity: ");
            Serial.print(g_Humidity);
            Serial.println(" %");
            
            g_SendMqttData = true;

        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // SEND MQTT DATA
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
        if(g_SendMqttData == true)        
        {
            StaticJsonDocument<200> payload;  
            payload["temp"] = g_Temperature;
            payload["hum"] = g_Humidity;
            payload["inputstatus"] = g_strDoorStatus;

            String strPayload;
            serializeJson(payload, strPayload);

            if(g_mqttPubSub.connected())
            {
                g_mqttPubSub.publish(g_mqttStatusTopic.c_str(), strPayload.c_str()); 
                Serial.println("MQTT: Send Data!!!");
                Serial.println(" ");
                Serial.println(" ");
                g_SendMqttData = false;
            }
        }
    }
}


/*-----------------------------------------------------------------------------------------------------------------------------------------------*/
/*------------------------------------ Public Functions -----------------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------------------------------------------------------------------*/
void setup_wifi() 
{
    int counter = 0;
    byte mac[6];
    delay(10);
    // We start by connecting to a WiFi network
    Serial.print("Connecting to ");
    Serial.println(g_ssid);

    WiFi.begin(g_ssid, g_password);

    WiFi.macAddress(mac);
    g_UniqueId =  String(mac[0],HEX) +String(mac[1],HEX) +String(mac[2],HEX) +String(mac[3],HEX) + String(mac[4],HEX) + String(mac[5],HEX);

    Serial.print("Unique ID: ");
    Serial.println(g_UniqueId);    
   
    while(WiFi.status() != WL_CONNECTED && counter++ < 8) 
    {
        delay(1000);
        Serial.print(".");
    }
    Serial.println("");

    if(WiFi.status() == WL_CONNECTED)
    {
        Serial.println("WiFi connected");
        Serial.print("IP address: ");
        Serial.println(WiFi.localIP());
    } else
    {
        Serial.println("WiFi NOT connected!!!");
    }
}

void MqttReconnect() 
{
    // Loop until we're reconnected
    while (!g_mqttPubSub.connected()  && (g_mqttCounterConn++ < 4))
    {
        Serial.print("Attempting MQTT connection...");
        // Attempt to connect
        if (g_mqttPubSub.connect(g_deviceName.c_str(), g_mqttUser, g_mqttPsw)) 
        {
            Serial.println("connected");
            // Subscribe
            g_mqttPubSub.subscribe("homeassistant/status");
            delay(100);
        } else 
        {
            Serial.print("failed, rc=");
            Serial.print(g_mqttPubSub.state());
            Serial.println(" try again in 1 seconds");
            delay(1000);
        }
    }  
    g_mqttCounterConn = 0;
}

void MqttHomeAssistantDiscovery()
{
    String discoveryTopic;
    String payload;
    String strPayload;
    if(g_mqttPubSub.connected())
    {
        Serial.println("SEND HOME ASSISTANT DISCOVERY!!!");
        StaticJsonDocument<600> payload;
        JsonObject device;
        JsonArray identifiers;

        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // Temperature
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        discoveryTopic = "homeassistant/sensor/esp32iotsensor/" + g_deviceName + "_temp" + "/config";
        
        payload["name"] = g_deviceName + ".temp";
        payload["uniq_id"] = g_UniqueId + "_temp";
        payload["stat_t"] = g_mqttStatusTopic;
        payload["dev_cla"] = "temperature";
        payload["val_tpl"] = "{{ value_json.temp | is_defined }}";
        payload["unit_of_meas"] = "°C";
        device = payload.createNestedObject("device");
        device["name"] = g_deviceName;
        device["model"] = g_deviceModel;
        device["sw_version"] = g_swVersion;
        device["manufacturer"] = g_manufacturer;
        identifiers = device.createNestedArray("identifiers");
        identifiers.add(g_UniqueId);

        serializeJsonPretty(payload, Serial);
        Serial.println(" ");
        serializeJson(payload, strPayload);

        g_mqttPubSub.publish(discoveryTopic.c_str(), strPayload.c_str());



        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // Humidity
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        discoveryTopic = "homeassistant/sensor/esp32iotsensor/" + g_deviceName + "_hum" + "/config";
        
        payload["name"] = g_deviceName + ".hum";
        payload["uniq_id"] = g_UniqueId + "_hum";
        payload["stat_t"] = g_mqttStatusTopic;
        payload["dev_cla"] = "humidity";
        payload["val_tpl"] = "{{ value_json.hum | is_defined }}";
        payload["unit_of_meas"] = "%";
        device = payload.createNestedObject("device");
        device["name"] = g_deviceName;
        device["model"] = g_deviceModel;
        device["sw_version"] = g_swVersion;
        device["manufacturer"] = g_manufacturer;
        identifiers = device.createNestedArray("identifiers");
        identifiers.add(g_UniqueId);

        serializeJsonPretty(payload, Serial);
        Serial.println(" ");
        serializeJson(payload, strPayload);

        g_mqttPubSub.publish(discoveryTopic.c_str(), strPayload.c_str());


        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // Binary Door
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    

        discoveryTopic = "homeassistant/binary_sensor/esp32iotsensor/" + g_deviceName + "_door" + "/config";
        
        payload["name"] = g_deviceName + ".door";
        payload["uniq_id"] = g_UniqueId + "_door";
        payload["stat_t"] = g_mqttStatusTopic;
        payload["dev_cla"] = "door";
        payload["val_tpl"] = "{{ value_json.inputstatus | is_defined }}";
        device = payload.createNestedObject("device");
        device["name"] = g_deviceName;
        device["model"] = g_deviceModel;
        device["sw_version"] = g_swVersion;
        device["manufacturer"] = g_manufacturer;
        identifiers = device.createNestedArray("identifiers");
        identifiers.add(g_UniqueId);

        serializeJsonPretty(payload, Serial);
        Serial.println(" ");
        serializeJson(payload, strPayload);

        g_mqttPubSub.publish(discoveryTopic.c_str(), strPayload.c_str());


    }
}

void MqttReceiverCallback(char* topic, byte* inFrame, unsigned int length) 
{
    Serial.print("Message arrived on topic: ");
    Serial.print(topic);
    Serial.print(". Message: ");
    byte state = 0;
    String messageTemp;
    
    for (int i = 0; i < length; i++) 
    {
        Serial.print((char)inFrame[i]);
        messageTemp += (char)inFrame[i];
    }
    Serial.println();
  
    if(String(topic) == String("homeassistant/status")) 
    {
        if(messageTemp == "online")
            MqttHomeAssistantDiscovery();
    }
}

The last script is a Arduino Script.

I am able to receive its MQTT messages on a linux terminal.

Ultimate precision :

I can listen at message from the topic “esp32iotsensor/CustomSensor” (topic where the states are send)

but not from : homeassistant/sensor/esp32iotsensor/CustomSensor_hum/config (the subscription topic for auto discovery at start)

Try the Homie autodescovery

Thanks for your answer. I tried your library but there is too much dependancies and I prefer to continue with HA integration because the code I found on Github.

Finally I use my code for my heatpump, subscribe to the dicovery topic : homeassistant/sensor/HP_Id/ac/config/

and I success to listen at the publication :

{“device”:{“identifiers”:“EcodanBridge-HP_Id”},

“origin”:{“name”:“Nico”},

“unique_id”:“ashp_bridge_rssi_HP_Id”,

“name”:“Bridge WiFi Signal”,

“stat_t”:“Ecodan/ASHP/Status/WiFiStatus”,

“unit_of_meas”:“dBm”,

“dev_cla”:“signal_strength”,

“stat_cla”:“measurement”,

“val_tpl”:“{{ value_json.RSSI }}”}

The most weird is that HomeAssistant don’t recognize it either, nor OH.

Thks for help

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.