Skip to content

Instantly share code, notes, and snippets.

@Resinchem
Last active July 12, 2025 10:54
Show Gist options
  • Select an option

  • Save Resinchem/ecd86dfb52bd699c79acfa80cd348d7b to your computer and use it in GitHub Desktop.

Select an option

Save Resinchem/ecd86dfb52bd699c79acfa80cd348d7b to your computer and use it in GitHub Desktop.

Revisions

  1. Resinchem revised this gist May 23, 2025. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion mqtt_discovery.cpp
    Original file line number Diff line number Diff line change
    @@ -160,7 +160,6 @@ void haDiscovery() {
    doc["ent_cat"] = "diagnostic";
    doc["stat_t"] = "stat/mydevice/ipaddress";
    JsonObject deviceI = doc.createNestedObject("device");
    deviceI = doc.createNestedObject("device");
    deviceI["ids"] = "mymqttdevice01";
    deviceI["name"] = "My MQTT Device";
    serializeJson(doc, buffer4);
  2. Resinchem revised this gist Feb 29, 2024. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions mqtt_discovery.cpp
    Original file line number Diff line number Diff line change
    @@ -118,7 +118,7 @@ void haDiscovery() {
    deviceS["name"] = "My MQTT Device";
    serializeJson(doc, buffer2);
    //Publish discovery topic and payload (with retained flag)
    client.publish(topic, buffer1, true);
    client.publish(topic, buffer2, true);

    //Temperature Sensor
    Serial.println("Adding Temp Sensor...");
    @@ -142,7 +142,7 @@ void haDiscovery() {
    deviceT["name"] = "My MQTT Device";
    serializeJson(doc, buffer3);
    //Publish discovery topic and payload (with retained flag)
    client.publish(topic, buffer1, true);
    client.publish(topic, buffer3, true);

    //IP Address Diagnostic
    Serial.println("Adding IP Diagnostic Sensor...");
    @@ -165,7 +165,7 @@ void haDiscovery() {
    deviceI["name"] = "My MQTT Device";
    serializeJson(doc, buffer4);
    //Publish discovery topic and payload (with retained flag)
    client.publish(topic, buffer1, true);
    client.publish(topic, buffer4, true);

    Serial.println("All devices added!");

  3. Resinchem revised this gist Jan 5, 2024. No changes.
  4. Resinchem revised this gist Jan 5, 2024. No changes.
  5. Resinchem revised this gist Jan 5, 2024. No changes.
  6. Resinchem revised this gist Dec 30, 2023. 1 changed file with 17 additions and 1 deletion.
    18 changes: 17 additions & 1 deletion mqtt_discovery.cpp
    Original file line number Diff line number Diff line change
    @@ -18,6 +18,7 @@
    //Partial list of libaries - also need Wifi, ESP8266/ESP32 libraries, etc.
    #include <PubSubClient.h>
    #include <ArduinoJson.h>
    #include <ESP8266WebServer.h> //Used for HTTP callback to enable/disable discovery

    //Auto-discover enable/disable option
    bool auto_discovery = false; //default to false and provide end-user interface to allow toggling
    @@ -214,5 +215,20 @@ void Setup() {

    //Call routing (or embed here) to create initial Unique ID
    createDiscoveryUniqueID();


    //Handle web callbacks for enabling or disabling discovery (using this method is just one of many ways to do this)
    server.on("/discovery_on",[]() {
    server.send(200, "text/html", "<h1>Discovery ON...<h1><h3>Home Assistant MQTT Discovery enabled</h3>");
    delay(200);
    auto_discovery = true;
    haDiscovery();
    });
    server.on("/discovery_off",[]() {
    server.send(200, "text/html", "<h1>Discovery OFF...<h1><h3>Home Assistant MQTT Discovery disabled. Previous entities removed.</h3>");
    delay(200);
    auto_discovery = false;
    haDiscovery();
    });
    server.begin();

    }
  7. Resinchem revised this gist Dec 28, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion mqtt_discovery.cpp
    Original file line number Diff line number Diff line change
    @@ -4,7 +4,7 @@
    for topic/entity publishing based on the device MAC address.
    It also includes sample code for creating a Home Assistant device with four
    entities via MQTT Discovery, as shown here:
    Video: LINK
    Video: https://youtu.be/VHiCtZqllU8
    Blog: https://resinchemtech.blogspot.com/2023/12/mqtt-auto-discovery.html
    It is highly recommended that you include some sort of end-user accessible setting to
  8. Resinchem created this gist Dec 28, 2023.
    218 changes: 218 additions & 0 deletions mqtt_discovery.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,218 @@
    /* ===================================================================
    SAMPLE CODE Segments for Home Assistant MQTT Discovery
    This is NOT complete code but shows an example of generating a unique ID
    for topic/entity publishing based on the device MAC address.
    It also includes sample code for creating a Home Assistant device with four
    entities via MQTT Discovery, as shown here:
    Video: LINK
    Blog: https://resinchemtech.blogspot.com/2023/12/mqtt-auto-discovery.html
    It is highly recommended that you include some sort of end-user accessible setting to
    enable/disable Home Assistant discovery as some users may not want your device auto-discovered
    and Home Assistant currently doesn't provide any prompting... devices/entities are immediately
    added as soon as a valid topic/payload are received.
    THIS IS AN INCOMPLETE EXAMPLE ONLY!!!!
    ===================================================================== */

    //Partial list of libaries - also need Wifi, ESP8266/ESP32 libraries, etc.
    #include <PubSubClient.h>
    #include <ArduinoJson.h>

    //Auto-discover enable/disable option
    bool auto_discovery = false; //default to false and provide end-user interface to allow toggling

    //Variables for creating unique entity IDs and topics
    byte macAddr[6]; //Device MAC address
    char uidPrefix[] = "rctdev"; //Prefix for unique ID generation (limit to 20 chars)
    char devUniqueID[30]; //Generated Unique ID for this device (uidPrefix + last 6 MAC characters)

    // =====================================
    // Create Unique ID for topics/entities
    // =====================================
    void createDiscoveryUniqueID() {
    //Generate UniqueID from uidPrefix + last 6 chars of device MAC address
    //This should insure that even multiple devices installed in same HA instance are unique

    strcpy(devUniqueID, uidPrefix);
    int preSizeBytes = sizeof(uidPrefix);
    int preSizeElements = (sizeof(uidPrefix) / sizeof(uidPrefix[0]));
    //Now add last 6 chars from MAC address (these are 'reversed' in the array)
    int j = 0;
    for (int i = 2; i >= 0; i--) {
    sprintf(&devUniqueID[(preSizeBytes - 1) + (j)], "%02X", macAddr[i]); //preSizeBytes indicates num of bytes in prefix - null terminator, plus 2 (j) bytes for each hex segment of MAC
    j = j + 2;
    }
    // End result is a unique ID for this device (e.g. rctdevE350CA)
    Serial.print("Unique ID: ");
    Serial.println(devUniqueID);
    }
    // ===============================
    // Main HA MQTT Discover Function
    // This creates a single fictional device with four entities:
    // - A dimmer switch with light level, temperature and IP address
    // ===============================
    void haDiscovery() {
    char topic[128];
    if (auto_discovery) {
    char buffer1[512];
    char buffer2[512];
    char buffer3[512];
    char buffer4[512];
    char uid[128];
    DynamicJsonDocument doc(512);
    doc.clear();
    Serial.println("Discovering new devices...");


    Serial.println("Adding light switch...");
    //Create unique topic based on devUniqueID
    strcpy(topic, "homeassistant/light/");
    strcat(topic, devUniqueID);
    strcat(topic, "S/config");
    //Create unique_id based on devUniqueID
    strcpy(uid, devUniqueID);
    strcat(uid, "S");
    //Create JSON payload per HA documentation
    doc["name"] = "My MQTT Light";
    doc["obj_id"] = "mqtt_light";
    doc["uniq_id"] = uid;
    doc["stat_t"] = "stat/mydevice/switch";
    doc["cmd_t"] = "cmnd/mydevice/switch";
    doc["brightness"] = "true";
    doc["bri_scl"] = "100";
    doc["bri_stat_t"] = "stat/mydevice/brightness";
    doc["bri_cmd_t"] = "cmnd/mydevice/brightness";
    JsonObject device = doc.createNestedObject("device");
    device["ids"] = "mymqttdevice01";
    device["name"] = "My MQTT Device";
    device["mf"] = "Resinchem Tech";
    device["mdl"] = "ESP8266";
    device["sw"] = "1.24";
    device["hw"] = "0.45";
    device["cu"] = "http://192.168.1.226/config"; //web interface for device, with discovery toggle
    serializeJson(doc, buffer1);
    //Publish discovery topic and payload (with retained flag)
    client.publish(topic, buffer1, true);

    //Lux Sensor
    Serial.println("Adding light sensor...");
    //Create unique Topic based on devUniqueID
    strcpy(topic, "homeassistant/sensor/");
    strcat(topic, devUniqueID);
    strcat(topic, "L/config");
    //Create unique_id based on decUniqueID
    strcpy(uid, devUniqueID);
    strcat(uid, "L");
    //Create JSON payload per HA documentation
    doc.clear();
    doc["name"] = "Light Level";
    doc["obj_id"] = "mqtt_light_level";
    doc["dev_cla"] = "illuminance";
    doc["uniq_id"] = uid;
    doc["stat_t"] = "stat/mydevice/lightlevel";
    doc["unit_of_meas"] = "lx";
    JsonObject deviceS = doc.createNestedObject("device");
    deviceS["ids"] = "mymqttdevice01";
    deviceS["name"] = "My MQTT Device";
    serializeJson(doc, buffer2);
    //Publish discovery topic and payload (with retained flag)
    client.publish(topic, buffer1, true);

    //Temperature Sensor
    Serial.println("Adding Temp Sensor...");
    //Create unique Topic based on devUniqueID
    strcpy(topic, "homeassistant/sensor/");
    strcat(topic, devUniqueID);
    strcat(topic, "T/config");
    //Create unique_id based on decUniqueID
    strcpy(uid, devUniqueID);
    strcat(uid, "T");
    //Create JSON payload per HA documentation
    doc.clear();
    doc["name"] = "Temperature";
    doc["obj_id"] = "mqtt_temperature";
    doc["deve_cla"] = "temperature";
    doc["uniq_id"] = uid;
    doc["stat_t"] = "stat/mydevice/temperature";
    doc["unit_of_meas"] = "°F";
    JsonObject deviceT = doc.createNestedObject("device");
    deviceT["ids"] = "mymqttdevice01";
    deviceT["name"] = "My MQTT Device";
    serializeJson(doc, buffer3);
    //Publish discovery topic and payload (with retained flag)
    client.publish(topic, buffer1, true);

    //IP Address Diagnostic
    Serial.println("Adding IP Diagnostic Sensor...");
    //Create unique Topic based on devUniqueID
    strcpy(topic, "homeassistant/sensor/");
    strcat(topic, devUniqueID);
    strcat(topic, "I/config");
    //Create unique_id based on decUniqueID
    strcpy(uid, devUniqueID);
    strcat(uid, "I");
    //Create JSON payload per HA documentation
    doc.clear();
    doc["name"] = "IP Address";
    doc["uniq_id"] = uid;
    doc["ent_cat"] = "diagnostic";
    doc["stat_t"] = "stat/mydevice/ipaddress";
    JsonObject deviceI = doc.createNestedObject("device");
    deviceI = doc.createNestedObject("device");
    deviceI["ids"] = "mymqttdevice01";
    deviceI["name"] = "My MQTT Device";
    serializeJson(doc, buffer4);
    //Publish discovery topic and payload (with retained flag)
    client.publish(topic, buffer1, true);

    Serial.println("All devices added!");

    } else {

    //Remove all entities by publishing empty payloads
    //Must use original topic, so recreate from original Unique ID
    //This will immediately remove/delete the device/entities from HA
    Serial.println("Removing discovered devices...");

    //Lux Sensor
    strcpy(topic, "homeassistant/sensor/");
    strcat(topic, devUniqueID);
    strcat(topic, "L/config");
    client.publish(topic, "");

    //Temperature Sensor
    strcpy(topic, "homeassistant/sensor/");
    strcat(topic, devUniqueID);
    strcat(topic, "T/config");
    client.publish(topic, "");

    //IP Address Sensor
    strcpy(topic, "homeassistant/sensor/");
    strcat(topic, devUniqueID);
    strcat(topic, "I/config");
    client.publish(topic, "");

    //Light (switch)
    strcpy(topic, "homeassistant/light/");
    strcat(topic, devUniqueID);
    strcat(topic, "S/config");
    client.publish(topic, "");

    Serial.println("Devices Removed...");
    }
    }

    // =====================
    // MAIN SETUP
    // =====================
    void Setup() {
    // The following should be included in (or called from) the main setup routine

    //Get MAC address when joining wifi and place into char array
    WiFi.macAddress(macAddr);

    //Call routing (or embed here) to create initial Unique ID
    createDiscoveryUniqueID();

    }