From e62fc14b6dc9d9a1a99d1fb91e6af4ac85e43b87 Mon Sep 17 00:00:00 2001 From: Proddy Date: Thu, 4 Jan 2024 18:10:53 +0100 Subject: [PATCH] support domoticz - MQTT autodiscovery in Domoticz not working #1360 --- src/mqtt.cpp | 39 +++++++++++++++++------------- src/mqtt.h | 4 +-- src/web/WebCustomEntityService.cpp | 2 +- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 0a96f0cea..6a5a24edf 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -863,8 +863,8 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev case DeviceValueType::USHORT: case DeviceValueType::ULONG: // number - https://www.home-assistant.io/integrations/number.mqtt - // Domoticz does not support number, use sensor - if (discovery_type() == discoveryType::HOMEASSISTANT) { + // older Domoticz does not support number, use sensor + if (discovery_type() == discoveryType::HOMEASSISTANT || discovery_type() == discoveryType::DOMOTICZ_LATEST) { snprintf(topic, sizeof(topic), "number/%s", config_topic); readonly_sensors = false; } else { @@ -1296,39 +1296,44 @@ void Mqtt::add_ha_sections_to_doc(const std::string & name, } // adds "availability" section to HA Discovery config - // but not for Domoticz + JsonArray avty = config.createNestedArray("avty"); + StaticJsonDocument avty_json; + + const char * tpl_draft = "{{'online' if %s else 'offline'}}"; + + // EMS-ESP status check + char tpl[150]; + snprintf(tpl, sizeof(tpl), "%s/status", Mqtt::base().c_str()); + avty_json["t"] = tpl; + snprintf(tpl, sizeof(tpl), tpl_draft, "value == 'online'"); + avty_json["val_tpl"] = tpl; + avty.add(avty_json); // returns 0 if no mem + + // skip conditional Jinja2 templates if not home assistant if (discovery_type() == discoveryType::HOMEASSISTANT) { - const char * tpl_draft = "{{'online' if %s else 'offline'}}"; - char tpl[150]; - JsonArray avty = config.createNestedArray("avty"); - - StaticJsonDocument<512> avty_json; - - snprintf(tpl, sizeof(tpl), "%s/status", Mqtt::base().c_str()); - avty_json["t"] = tpl; - snprintf(tpl, sizeof(tpl), tpl_draft, "value == 'online'"); - avty_json["val_tpl"] = tpl; - avty.add(avty_json); + // condition 1 avty_json.clear(); avty_json["t"] = state_t; snprintf(tpl, sizeof(tpl), tpl_draft, cond1 == nullptr ? "value is defined" : cond1); avty_json["val_tpl"] = tpl; - avty.add(avty_json); + avty.add(avty_json); // returns 0 if no mem + // condition 2 if (cond2 != nullptr) { avty_json.clear(); avty_json["t"] = state_t; snprintf(tpl, sizeof(tpl), tpl_draft, cond2); avty_json["val_tpl"] = tpl; - avty.add(avty_json); + avty.add(avty_json); // returns 0 if no mem } + // negative condition if (negcond != nullptr) { avty_json.clear(); avty_json["t"] = state_t; snprintf(tpl, sizeof(tpl), "{{'offline' if %s else 'online'}}", negcond); avty_json["val_tpl"] = tpl; - avty.add(avty_json); + avty.add(avty_json); // returns 0 if no mem } config["avty_mode"] = "all"; diff --git a/src/mqtt.h b/src/mqtt.h index 6854cc334..c965e0e51 100644 --- a/src/mqtt.h +++ b/src/mqtt.h @@ -35,7 +35,7 @@ using mqtt_sub_function_p = std::function; class Mqtt { public: - enum discoveryType : uint8_t { HOMEASSISTANT, DOMOTICZ }; + enum discoveryType : uint8_t { HOMEASSISTANT, DOMOTICZ, DOMOTICZ_LATEST }; enum entityFormat : uint8_t { SINGLE_LONG, SINGLE_SHORT, MULTI_SHORT }; void loop(); @@ -219,7 +219,7 @@ class Mqtt { static void add_ha_sections_to_doc(const std::string & name, const char * state_t, - const JsonObject & doc, + const JsonObject & config, const bool is_first = false, const char * cond1 = nullptr, const char * cond2 = nullptr, diff --git a/src/web/WebCustomEntityService.cpp b/src/web/WebCustomEntityService.cpp index 4f318a07f..7eaed6026 100644 --- a/src/web/WebCustomEntityService.cpp +++ b/src/web/WebCustomEntityService.cpp @@ -397,7 +397,7 @@ void WebCustomEntityService::publish(const bool force) { snprintf(topic, sizeof(topic), "switch/%s/custom_%s/config", Mqtt::basename().c_str(), entityItem.name.c_str()); } else if (entityItem.value_type == DeviceValueType::STRING) { snprintf(topic, sizeof(topic), "sensor/%s/custom_%s/config", Mqtt::basename().c_str(), entityItem.name.c_str()); - } else if (Mqtt::discovery_type() == Mqtt::discoveryType::HOMEASSISTANT) { + } else if (Mqtt::discovery_type() == Mqtt::discoveryType::HOMEASSISTANT || Mqtt::discovery_type() == Mqtt::discoveryType::DOMOTICZ_LATEST) { snprintf(topic, sizeof(topic), "number/%s/custom_%s/config", Mqtt::basename().c_str(), entityItem.name.c_str()); } else { snprintf(topic, sizeof(topic), "sensor/%s/custom_%s/config", Mqtt::basename().c_str(), entityItem.name.c_str());