From 0903b31fcfe7110b618bebd5b1d0982518a5284e Mon Sep 17 00:00:00 2001 From: Proddy Date: Mon, 5 Dec 2022 10:06:50 +0100 Subject: [PATCH 1/4] highlight breaking changes --- CHANGELOG_LATEST.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 73b2939e3..5eeeaa02b 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -2,6 +2,11 @@ # [3.5.0] +## **IMPORTANT! BREAKING CHANGES** + +- When upgrading to v3.5 for the first time from v3.4 on a BBQKees Gateway board you will need to use the [EMS-EPS Flasher](https://github.com/emsesp/EMS-ESP-Flasher/releases) to correctly re-partition the flash. Make sure you backup the settings and customizations from the WebUI (System->Upload/Download) and restore after the upgrade. +- Since 3.5.0b11 we added support for multiple EMS-ESPs [#759] so they can co-exist with MQTT Discovery. The mqtt base is now included in each of the entity names to make them unique. Unfortunately this means in Home Assistant the entity IDs have also been renamed (for example from `number.boiler_burnminperiod` to `number.ems_esp_boiler_burnminperiod`) and any dashboards and automation scripts need to be adjusted accordingly. + ## Added - Translations in Web UI and all device entity names (DE, NL, SE, PL, NO) [#22](https://github.com/emsesp/EMS-ESP32/issues/22) @@ -35,8 +40,3 @@ - analog/dallas values command as list like ems-devices - analog/dallas HA-entities based on id - MQTT Base is a mandatory field. Removed MQTT topic length from settings. - -## **BREAKING CHANGES:** - -- When upgrading for the first time from 3.4.x on a BBQKees Gateway board you will need to use the [EMS-EPS Flasher](https://github.com/emsesp/EMS-ESP-Flasher/releases). Make sure you make a backup of the settings and customizations via the WebUI (System->Upload/Download). -- Because of #759 the Home Assistant entity IDs have been renamed From fd04f8be5ad96316e102af7fb2b26339d389678c Mon Sep 17 00:00:00 2001 From: proddy Date: Mon, 5 Dec 2022 20:35:04 +0100 Subject: [PATCH 2/4] add multiple_sessions --- .../src/framework/mqtt/MqttSettingsForm.tsx | 4 ++ interface/src/i18n/de/index.ts | 1 + interface/src/i18n/en/index.ts | 1 + interface/src/i18n/nl/index.ts | 1 + interface/src/i18n/no/index.ts | 1 + interface/src/i18n/pl/index.ts | 1 + interface/src/i18n/se/index.ts | 1 + interface/src/types/mqtt.ts | 1 + lib/framework/MqttSettingsService.cpp | 43 ++++++++++--------- lib/framework/MqttSettingsService.h | 7 +++ lib_standalone/ESP8266React.h | 1 + mock-api/server.js | 1 + src/system.cpp | 1 + 13 files changed, 44 insertions(+), 20 deletions(-) diff --git a/interface/src/framework/mqtt/MqttSettingsForm.tsx b/interface/src/framework/mqtt/MqttSettingsForm.tsx index b5956b034..984f23e7d 100644 --- a/interface/src/framework/mqtt/MqttSettingsForm.tsx +++ b/interface/src/framework/mqtt/MqttSettingsForm.tsx @@ -162,6 +162,10 @@ const MqttSettingsForm: FC = () => { + } + label={LL.MQTT_MULTIPLE_INSTANCES()} + /> } label={LL.MQTT_CLEAN_SESSION()} diff --git a/interface/src/i18n/de/index.ts b/interface/src/i18n/de/index.ts index 5837fac56..fe6c05740 100644 --- a/interface/src/i18n/de/index.ts +++ b/interface/src/i18n/de/index.ts @@ -247,6 +247,7 @@ const de: Translation = { MQTT_INT_MIXER: 'Mischermodule', MQTT_QUEUE: 'MQTT Queue', DEFAULT: 'Standard', + MQTT_MULTIPLE_INSTANCES: 'Enable Multiple Instances of EMS-ESP', MQTT_CLEAN_SESSION: 'Setze `Clean Session`', MQTT_RETAIN_FLAG: 'Setze `Retain flag` immer', INACTIVE: 'Inaktiv', diff --git a/interface/src/i18n/en/index.ts b/interface/src/i18n/en/index.ts index 4cd5e69ec..0abaf6d97 100644 --- a/interface/src/i18n/en/index.ts +++ b/interface/src/i18n/en/index.ts @@ -247,6 +247,7 @@ const en: Translation = { MQTT_INT_MIXER: 'Mixer Modules', MQTT_QUEUE: 'MQTT Queue', DEFAULT: 'Default', + MQTT_MULTIPLE_INSTANCES: 'Enable Multiple Instances of EMS-ESP', MQTT_CLEAN_SESSION: 'Set Clean Session', MQTT_RETAIN_FLAG: 'Always set Retain flag', INACTIVE: 'Inactive', diff --git a/interface/src/i18n/nl/index.ts b/interface/src/i18n/nl/index.ts index cbd1cd400..5363adcbf 100644 --- a/interface/src/i18n/nl/index.ts +++ b/interface/src/i18n/nl/index.ts @@ -247,6 +247,7 @@ const nl: Translation = { MQTT_INT_MIXER: 'Mixer Modules', MQTT_QUEUE: 'MQTT Queue', DEFAULT: 'Default', + MQTT_MULTIPLE_INSTANCES: 'Enable Multiple Instances of EMS-ESP', MQTT_CLEAN_SESSION: 'Clean Session aan', MQTT_RETAIN_FLAG: 'Retain flag aan', INACTIVE: 'Inactief', diff --git a/interface/src/i18n/no/index.ts b/interface/src/i18n/no/index.ts index 851876219..04df90fc2 100644 --- a/interface/src/i18n/no/index.ts +++ b/interface/src/i18n/no/index.ts @@ -247,6 +247,7 @@ const no: Translation = { MQTT_INT_MIXER: 'Blandeventil', MQTT_QUEUE: 'MQTT Queue', DEFAULT: 'Standard', + MQTT_MULTIPLE_INSTANCES: 'Enable Multiple Instances of EMS-ESP', MQTT_CLEAN_SESSION: 'Benytt Clean Session', MQTT_RETAIN_FLAG: 'Alltid sett Retain flag', INACTIVE: 'Innaktiv', diff --git a/interface/src/i18n/pl/index.ts b/interface/src/i18n/pl/index.ts index 413d21c66..06f58bbd9 100644 --- a/interface/src/i18n/pl/index.ts +++ b/interface/src/i18n/pl/index.ts @@ -247,6 +247,7 @@ const pl: BaseTranslation = { MQTT_INT_MIXER: 'Mieszacze', MQTT_QUEUE: 'Kolejka MQTT', DEFAULT: '{{Pozostałe|Domyślna|}}', + MQTT_MULTIPLE_INSTANCES: 'Enable Multiple Instances of EMS-ESP', MQTT_CLEAN_SESSION: 'Ustawiaj flagę "Clean session"', MQTT_RETAIN_FLAG: 'Ustawiaj flagę "Retain"', INACTIVE: 'nieaktywny', diff --git a/interface/src/i18n/se/index.ts b/interface/src/i18n/se/index.ts index 923c9617e..cddcc243d 100644 --- a/interface/src/i18n/se/index.ts +++ b/interface/src/i18n/se/index.ts @@ -247,6 +247,7 @@ const se: Translation = { MQTT_INT_MIXER: 'Blandarventiler', MQTT_QUEUE: 'MQTT Queue', DEFAULT: 'Standard', + MQTT_MULTIPLE_INSTANCES: 'Enable Multiple Instances of EMS-ESP', MQTT_CLEAN_SESSION: 'Använd "Clean Session"-flaggan', MQTT_RETAIN_FLAG: 'Använd "Always Retain"-flaggan', INACTIVE: 'Inaktiv', diff --git a/interface/src/types/mqtt.ts b/interface/src/types/mqtt.ts index 7ecf694ca..65d0a444a 100644 --- a/interface/src/types/mqtt.ts +++ b/interface/src/types/mqtt.ts @@ -29,6 +29,7 @@ export interface MqttSettings { client_id: string; keep_alive: number; clean_session: boolean; + multiple_instances: boolean; publish_time_boiler: number; publish_time_thermostat: number; publish_time_solar: number; diff --git a/lib/framework/MqttSettingsService.cpp b/lib/framework/MqttSettingsService.cpp index 952724606..9a9bfa487 100644 --- a/lib/framework/MqttSettingsService.cpp +++ b/lib/framework/MqttSettingsService.cpp @@ -145,15 +145,16 @@ void MqttSettingsService::configureMqtt() { } void MqttSettings::read(MqttSettings & settings, JsonObject & root) { - root["enabled"] = settings.enabled; - root["host"] = settings.host; - root["port"] = settings.port; - root["base"] = settings.base; - root["username"] = settings.username; - root["password"] = settings.password; - root["client_id"] = settings.clientId; - root["keep_alive"] = settings.keepAlive; - root["clean_session"] = settings.cleanSession; + root["enabled"] = settings.enabled; + root["host"] = settings.host; + root["port"] = settings.port; + root["base"] = settings.base; + root["username"] = settings.username; + root["password"] = settings.password; + root["client_id"] = settings.clientId; + root["keep_alive"] = settings.keepAlive; + root["clean_session"] = settings.cleanSession; + root["multiple_instances"] = settings.multiple_instances; // added by proddy for EMS-ESP root["publish_time_boiler"] = settings.publish_time_boiler; @@ -176,17 +177,19 @@ StateUpdateResult MqttSettings::update(JsonObject & root, MqttSettings & setting MqttSettings newSettings = {}; bool changed = false; - newSettings.enabled = root["enabled"] | FACTORY_MQTT_ENABLED; - newSettings.host = root["host"] | FACTORY_MQTT_HOST; - newSettings.port = root["port"] | FACTORY_MQTT_PORT; - newSettings.base = root["base"] | FACTORY_MQTT_BASE; - newSettings.username = root["username"] | FACTORY_MQTT_USERNAME; - newSettings.password = root["password"] | FACTORY_MQTT_PASSWORD; - newSettings.clientId = root["client_id"] | FACTORY_MQTT_CLIENT_ID; - newSettings.keepAlive = root["keep_alive"] | FACTORY_MQTT_KEEP_ALIVE; - newSettings.cleanSession = root["clean_session"] | FACTORY_MQTT_CLEAN_SESSION; - newSettings.mqtt_qos = root["mqtt_qos"] | EMSESP_DEFAULT_MQTT_QOS; - newSettings.mqtt_retain = root["mqtt_retain"] | EMSESP_DEFAULT_MQTT_RETAIN; + newSettings.enabled = root["enabled"] | FACTORY_MQTT_ENABLED; + newSettings.host = root["host"] | FACTORY_MQTT_HOST; + newSettings.port = root["port"] | FACTORY_MQTT_PORT; + newSettings.base = root["base"] | FACTORY_MQTT_BASE; + newSettings.username = root["username"] | FACTORY_MQTT_USERNAME; + newSettings.password = root["password"] | FACTORY_MQTT_PASSWORD; + newSettings.clientId = root["client_id"] | FACTORY_MQTT_CLIENT_ID; + newSettings.keepAlive = root["keep_alive"] | FACTORY_MQTT_KEEP_ALIVE; + newSettings.cleanSession = root["clean_session"] | FACTORY_MQTT_CLEAN_SESSION; + newSettings.multiple_instances = root["multiple_instances"] | FACTORY_MQTT_MULTIPLE_INSTANCES; + + newSettings.mqtt_qos = root["mqtt_qos"] | EMSESP_DEFAULT_MQTT_QOS; + newSettings.mqtt_retain = root["mqtt_retain"] | EMSESP_DEFAULT_MQTT_RETAIN; newSettings.publish_time_boiler = root["publish_time_boiler"] | EMSESP_DEFAULT_PUBLISH_TIME; newSettings.publish_time_thermostat = root["publish_time_thermostat"] | EMSESP_DEFAULT_PUBLISH_TIME; diff --git a/lib/framework/MqttSettingsService.h b/lib/framework/MqttSettingsService.h index 199c7379b..0a976ac21 100644 --- a/lib/framework/MqttSettingsService.h +++ b/lib/framework/MqttSettingsService.h @@ -57,6 +57,10 @@ static String generateClientId() { #define FACTORY_MQTT_MAX_TOPIC_LENGTH 128 #endif +#ifndef FACTORY_MQTT_MULTIPLE_INSTANCES +#define FACTORY_MQTT_MULTIPLE_INSTANCES false +#endif + class MqttSettings { public: // host and port - if enabled @@ -75,6 +79,9 @@ class MqttSettings { uint16_t keepAlive; bool cleanSession; + // multiple instances + bool multiple_instances; + // proddy EMS-ESP specific String base; uint16_t publish_time_boiler; diff --git a/lib_standalone/ESP8266React.h b/lib_standalone/ESP8266React.h index 96590bef2..4587c8817 100644 --- a/lib_standalone/ESP8266React.h +++ b/lib_standalone/ESP8266React.h @@ -81,6 +81,7 @@ class DummySettings { String username = ""; uint16_t keepAlive = 60; bool cleanSession = false; + bool multiple_instances = false; uint16_t publish_time_boiler = 10; uint16_t publish_time_thermostat = 10; diff --git a/mock-api/server.js b/mock-api/server.js index f37697551..28315dfbc 100644 --- a/mock-api/server.js +++ b/mock-api/server.js @@ -219,6 +219,7 @@ mqtt_settings = { client_id: 'ems-esp', keep_alive: 60, clean_session: true, + multiple_instances: false, publish_time_boiler: 10, publish_time_thermostat: 10, publish_time_solar: 10, diff --git a/src/system.cpp b/src/system.cpp index 1fbfe9aa9..47b439759 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -1153,6 +1153,7 @@ bool System::command_info(const char * value, const int8_t id, JsonObject & outp node["client id"] = settings.clientId; node["keep alive"] = settings.keepAlive; node["clean session"] = settings.cleanSession; + node["multiple instances"] = settings.multiple_instances; node["base"] = settings.base; node["discovery prefix"] = settings.discovery_prefix; node["nested format"] = settings.nested_format; From 1af1a1863a4b848fceb634017ff4f47b710c1c13 Mon Sep 17 00:00:00 2001 From: proddy Date: Mon, 5 Dec 2022 21:33:10 +0100 Subject: [PATCH 3/4] #759 add option to enable multiple instances to keep backward compatibllity with v3.4 --- interface/package-lock.json | 28 ++++++++++++++-------------- interface/package.json | 4 ++-- src/analogsensor.cpp | 7 ++++++- src/dallassensor.cpp | 11 ++++++++--- src/mqtt.cpp | 22 ++++++++++++++++++---- src/mqtt.h | 5 +++++ 6 files changed, 53 insertions(+), 24 deletions(-) diff --git a/interface/package-lock.json b/interface/package-lock.json index a29315980..9b1f3f369 100644 --- a/interface/package-lock.json +++ b/interface/package-lock.json @@ -15,12 +15,12 @@ "@mui/material": "^5.10.16", "@table-library/react-table-library": "4.0.23", "@types/lodash": "^4.14.191", - "@types/node": "^18.11.10", + "@types/node": "^18.11.11", "@types/react": "^18.0.26", "@types/react-dom": "^18.0.9", "@types/react-router-dom": "^5.3.3", "async-validator": "^4.2.5", - "axios": "^1.2.0", + "axios": "^1.2.1", "http-proxy-middleware": "^2.0.6", "jwt-decode": "^3.1.2", "lodash": "^4.17.21", @@ -4017,9 +4017,9 @@ "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==" }, "node_modules/@types/node": { - "version": "18.11.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.10.tgz", - "integrity": "sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ==" + "version": "18.11.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.11.tgz", + "integrity": "sha512-KJ021B1nlQUBLopzZmPBVuGU9un7WJd/W4ya7Ih02B4Uwky5Nja0yGYav2EfYIk0RR2Q9oVhf60S2XR1BCWJ2g==" }, "node_modules/@types/parse-json": { "version": "4.0.0", @@ -5030,9 +5030,9 @@ } }, "node_modules/axios": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.2.0.tgz", - "integrity": "sha512-zT7wZyNYu3N5Bu0wuZ6QccIf93Qk1eV8LOewxgjOZFd2DenOs98cJ7+Y6703d0wkaXGY6/nZd4EweJaHz9uzQw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.2.1.tgz", + "integrity": "sha512-I88cFiGu9ryt/tfVEi4kX2SITsvDddTajXTOFmt2uK1ZVA8LytjtdeyefdQWEf5PU8w+4SSJDoYnggflB5tW4A==", "dependencies": { "follow-redirects": "^1.15.0", "form-data": "^4.0.0", @@ -20230,9 +20230,9 @@ "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==" }, "@types/node": { - "version": "18.11.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.10.tgz", - "integrity": "sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ==" + "version": "18.11.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.11.tgz", + "integrity": "sha512-KJ021B1nlQUBLopzZmPBVuGU9un7WJd/W4ya7Ih02B4Uwky5Nja0yGYav2EfYIk0RR2Q9oVhf60S2XR1BCWJ2g==" }, "@types/parse-json": { "version": "4.0.0", @@ -20998,9 +20998,9 @@ "integrity": "sha512-u2MVsXfew5HBvjsczCv+xlwdNnB1oQR9HlAcsejZttNjKKSkeDNVwB1vMThIUIFI9GoT57Vtk8iQLwqOfAkboA==" }, "axios": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.2.0.tgz", - "integrity": "sha512-zT7wZyNYu3N5Bu0wuZ6QccIf93Qk1eV8LOewxgjOZFd2DenOs98cJ7+Y6703d0wkaXGY6/nZd4EweJaHz9uzQw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.2.1.tgz", + "integrity": "sha512-I88cFiGu9ryt/tfVEi4kX2SITsvDddTajXTOFmt2uK1ZVA8LytjtdeyefdQWEf5PU8w+4SSJDoYnggflB5tW4A==", "requires": { "follow-redirects": "^1.15.0", "form-data": "^4.0.0", diff --git a/interface/package.json b/interface/package.json index c727c1dc4..91afdb57e 100644 --- a/interface/package.json +++ b/interface/package.json @@ -11,12 +11,12 @@ "@mui/material": "^5.10.16", "@table-library/react-table-library": "4.0.23", "@types/lodash": "^4.14.191", - "@types/node": "^18.11.10", + "@types/node": "^18.11.11", "@types/react": "^18.0.26", "@types/react-dom": "^18.0.9", "@types/react-router-dom": "^5.3.3", "async-validator": "^4.2.5", - "axios": "^1.2.0", + "axios": "^1.2.1", "http-proxy-middleware": "^2.0.6", "jwt-decode": "^3.1.2", "lodash": "^4.17.21", diff --git a/src/analogsensor.cpp b/src/analogsensor.cpp index 1b805b460..a90e7219f 100644 --- a/src/analogsensor.cpp +++ b/src/analogsensor.cpp @@ -451,7 +451,12 @@ void AnalogSensor::publish_values(const bool force) { } config["val_tpl"] = str; - snprintf(str, sizeof(str), "%s_analogsensor_%d", Mqtt::basename().c_str(), sensor.gpio()); + if (Mqtt::multiple_instances()) { + snprintf(str, sizeof(str), "%s_analogsensor_%d", Mqtt::basename().c_str(), sensor.gpio()); + } else { + snprintf(str, sizeof(str), "analogsensor_%d", sensor.gpio()); + } + config["object_id"] = str; config["uniq_id"] = str; // same as object_id diff --git a/src/dallassensor.cpp b/src/dallassensor.cpp index eb1aeab74..15b55ddad 100644 --- a/src/dallassensor.cpp +++ b/src/dallassensor.cpp @@ -518,15 +518,20 @@ void DallasSensor::publish_values(const bool force) { } config["val_tpl"] = str; - snprintf(str, sizeof(str), "%s_dallassensor_%s", Mqtt::basename().c_str(), sensor.id().c_str()); + if (Mqtt::multiple_instances()) { + snprintf(str, sizeof(str), "%s_dallassensor_%s", Mqtt::basename().c_str(), sensor.id().c_str()); + } else { + snprintf(str, sizeof(str), "dallassensor_%s", sensor.id().c_str()); + } + config["object_id"] = str; config["uniq_id"] = str; // same as object_id snprintf(str, sizeof(str), "%s", sensor.name().c_str()); config["name"] = str; - JsonObject dev = config.createNestedObject("dev"); - JsonArray ids = dev.createNestedArray("ids"); + JsonObject dev = config.createNestedObject("dev"); + JsonArray ids = dev.createNestedArray("ids"); ids.add("ems-esp"); char topic[Mqtt::MQTT_TOPIC_MAX_SIZE]; diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 404b8878b..bc11f6a10 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -37,6 +37,7 @@ uint32_t Mqtt::publish_time_mixer_; uint32_t Mqtt::publish_time_sensor_; uint32_t Mqtt::publish_time_other_; bool Mqtt::mqtt_enabled_; +bool Mqtt::multiple_instances_; bool Mqtt::ha_enabled_; uint8_t Mqtt::nested_format_; std::string Mqtt::discovery_prefix_; @@ -422,6 +423,7 @@ void Mqtt::load_settings() { publish_single2cmd_ = mqttSettings.publish_single2cmd; send_response_ = mqttSettings.send_response; discovery_prefix_ = mqttSettings.discovery_prefix.c_str(); + multiple_instances_ = mqttSettings.multiple_instances; // convert to milliseconds publish_time_boiler_ = mqttSettings.publish_time_boiler * 1000; @@ -594,10 +596,10 @@ void Mqtt::ha_status() { StaticJsonDocument doc; char uniq[70]; - snprintf(uniq, sizeof(uniq), "%s_status", mqtt_basename_.c_str()); + snprintf(uniq, sizeof(uniq), "%s_status", mqtt_basename_.c_str()); // always use basename doc["uniq_id"] = uniq; doc["object_id"] = uniq; - doc["~"] = mqtt_base_; // default ems-esp + doc["~"] = mqtt_base_; // doc["avty_t"] = "~/status"; // commented out, as it causes errors in HA sometimes // doc["json_attr_t"] = "~/heartbeat"; // store also as HA attributes doc["stat_t"] = "~/status"; @@ -784,6 +786,7 @@ void Mqtt::process_queue() { if (message->topic.find(discovery_prefix_) == 0) { strlcpy(topic, message->topic.c_str(), sizeof(topic)); // leave topic as it is } else { + // it's a discovery topic, added the mqtt base to the topic path snprintf(topic, MQTT_TOPIC_MAX_SIZE, "%s/%s", mqtt_base_.c_str(), message->topic.c_str()); // uses base } @@ -965,7 +968,12 @@ void Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev // build unique identifier which will be used in the topic, also used as object_id char uniq_id[70]; - snprintf(uniq_id, sizeof(uniq_id), "%s_%s_%s", mqtt_basename_.c_str(), device_name, entity_with_tag); + if (multiple_instances_) { + // prefix base name to each uniq_id + snprintf(uniq_id, sizeof(uniq_id), "%s_%s_%s", mqtt_basename_.c_str(), device_name, entity_with_tag); + } else { + snprintf(uniq_id, sizeof(uniq_id), "%s_%s", device_name, entity_with_tag); + } // build a config topic that will be prefix onto a HA type (e.g. number, switch) // e.g. homeassistant/number/ems-esp/thermostat_hc1_manualtemp @@ -1267,7 +1275,13 @@ void Mqtt::publish_ha_climate_config(const uint8_t tag, const bool has_roomtemp, hc_mode_s); snprintf(name_s, sizeof(name_s), "Hc%d", hc_num); - snprintf(uniq_id_s, sizeof(uniq_id_s), "%s_thermostat_hc%d", mqtt_basename_.c_str(), hc_num); // add basename + + if (Mqtt::multiple_instances()) { + snprintf(uniq_id_s, sizeof(uniq_id_s), "%s_thermostat_hc%d", mqtt_basename_.c_str(), hc_num); // add basename + } else { + snprintf(uniq_id_s, sizeof(uniq_id_s), "thermostat_hc%d", hc_num); // backward compatible with v3.4 + } + snprintf(temp_cmd_s, sizeof(temp_cmd_s), "~/thermostat/hc%d/seltemp", hc_num); snprintf(mode_cmd_s, sizeof(temp_cmd_s), "~/thermostat/hc%d/mode", hc_num); diff --git a/src/mqtt.h b/src/mqtt.h index 65e4fcad7..1fcebb217 100644 --- a/src/mqtt.h +++ b/src/mqtt.h @@ -179,6 +179,10 @@ class Mqtt { return nested_format_ == NestedFormat::NESTED; } + static bool multiple_instances() { + return multiple_instances_; + } + static void nested_format(uint8_t nested_format) { nested_format_ = nested_format; } @@ -314,6 +318,7 @@ class Mqtt { static bool mqtt_enabled_; static bool ha_enabled_; static uint8_t nested_format_; + static bool multiple_instances_; static std::string discovery_prefix_; static bool publish_single_; static bool publish_single2cmd_; From 995420354e04d6db1dc2600f09eededab54693d8 Mon Sep 17 00:00:00 2001 From: Proddy Date: Tue, 6 Dec 2022 11:15:14 +0100 Subject: [PATCH 4/4] remove breaking change note about MQTT discovery --- CHANGELOG_LATEST.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 5eeeaa02b..64ecba199 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -5,7 +5,6 @@ ## **IMPORTANT! BREAKING CHANGES** - When upgrading to v3.5 for the first time from v3.4 on a BBQKees Gateway board you will need to use the [EMS-EPS Flasher](https://github.com/emsesp/EMS-ESP-Flasher/releases) to correctly re-partition the flash. Make sure you backup the settings and customizations from the WebUI (System->Upload/Download) and restore after the upgrade. -- Since 3.5.0b11 we added support for multiple EMS-ESPs [#759] so they can co-exist with MQTT Discovery. The mqtt base is now included in each of the entity names to make them unique. Unfortunately this means in Home Assistant the entity IDs have also been renamed (for example from `number.boiler_burnminperiod` to `number.ems_esp_boiler_burnminperiod`) and any dashboards and automation scripts need to be adjusted accordingly. ## Added