From 1af1a1863a4b848fceb634017ff4f47b710c1c13 Mon Sep 17 00:00:00 2001 From: proddy Date: Mon, 5 Dec 2022 21:33:10 +0100 Subject: [PATCH] #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_;