From 783ea7901c266c6462ff653478e3310000f37c0e Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 17 Dec 2022 19:20:31 +0100 Subject: [PATCH 1/3] support 3 types of MQTT discovery entity id --- .../src/framework/mqtt/MqttSettingsForm.tsx | 9 ++-- interface/src/i18n/de/index.ts | 5 +- interface/src/i18n/en/index.ts | 5 +- interface/src/i18n/fr/index.ts | 5 +- interface/src/i18n/nl/index.ts | 5 +- interface/src/i18n/no/index.ts | 5 +- interface/src/i18n/pl/index.ts | 5 +- interface/src/i18n/se/index.ts | 5 +- interface/src/types/mqtt.ts | 2 +- lib/framework/MqttSettingsService.cpp | 46 +++++++++---------- lib/framework/MqttSettingsService.h | 6 +-- lib_standalone/ESP8266React.h | 2 +- mock-api/server.js | 2 +- src/analogsensor.cpp | 2 +- src/dallassensor.cpp | 2 +- src/mqtt.cpp | 14 ++++-- src/mqtt.h | 6 +-- src/shower.cpp | 2 +- src/system.cpp | 2 +- 19 files changed, 71 insertions(+), 59 deletions(-) diff --git a/interface/src/framework/mqtt/MqttSettingsForm.tsx b/interface/src/framework/mqtt/MqttSettingsForm.tsx index ef78c8436..ebe7151f8 100644 --- a/interface/src/framework/mqtt/MqttSettingsForm.tsx +++ b/interface/src/framework/mqtt/MqttSettingsForm.tsx @@ -236,17 +236,18 @@ const MqttSettingsForm: FC = () => { - {LL.MQTT_ENTITY_FORMAT_0()} - {LL.MQTT_ENTITY_FORMAT_1()} + {LL.MQTT_ENTITY_FORMAT_0()} + {LL.MQTT_ENTITY_FORMAT_1()} + {LL.MQTT_ENTITY_FORMAT_2()} diff --git a/interface/src/i18n/de/index.ts b/interface/src/i18n/de/index.ts index 5ee053fca..179596123 100644 --- a/interface/src/i18n/de/index.ts +++ b/interface/src/i18n/de/index.ts @@ -250,8 +250,9 @@ const de: Translation = { MQTT_QUEUE: 'MQTT Queue', DEFAULT: 'Standard', MQTT_ENTITY_FORMAT: 'Entity ID format', - MQTT_ENTITY_FORMAT_0: 'Single instance, long name (depreciated)', - MQTT_ENTITY_FORMAT_1: 'Multiple instances, short name', + MQTT_ENTITY_FORMAT_0: 'Single instance, long name (v3.4)', + MQTT_ENTITY_FORMAT_1: 'Single instance, short name', + MQTT_ENTITY_FORMAT_2: 'Multiple instances, short name', 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 95f386a5f..570230c53 100644 --- a/interface/src/i18n/en/index.ts +++ b/interface/src/i18n/en/index.ts @@ -249,8 +249,9 @@ const en: Translation = { MQTT_QUEUE: 'MQTT Queue', DEFAULT: 'Default', MQTT_ENTITY_FORMAT: 'Entity ID format', - MQTT_ENTITY_FORMAT_0: 'Single instance, long name (depreciated)', - MQTT_ENTITY_FORMAT_1: 'Multiple instances, short name', + MQTT_ENTITY_FORMAT_0: 'Single instance, long name (v3.4)', + MQTT_ENTITY_FORMAT_1: 'Single instance, short name', + MQTT_ENTITY_FORMAT_2: 'Multiple instances, short name', MQTT_CLEAN_SESSION: 'Set Clean Session', MQTT_RETAIN_FLAG: 'Always set Retain flag', INACTIVE: 'Inactive', diff --git a/interface/src/i18n/fr/index.ts b/interface/src/i18n/fr/index.ts index 8665ddb2a..a1494ccf4 100644 --- a/interface/src/i18n/fr/index.ts +++ b/interface/src/i18n/fr/index.ts @@ -249,8 +249,9 @@ const fr: Translation = { MQTT_QUEUE: 'Queue MQTT', DEFAULT: 'Défaut', MQTT_ENTITY_FORMAT: 'Entity ID format', - MQTT_ENTITY_FORMAT_0: 'Single instance, long name (depreciated)', - MQTT_ENTITY_FORMAT_1: 'Multiple instances, short name', + MQTT_ENTITY_FORMAT_0: 'Single instance, long name (v3.4)', + MQTT_ENTITY_FORMAT_1: 'Single instance, short name', + MQTT_ENTITY_FORMAT_2: 'Multiple instances, short name', MQTT_CLEAN_SESSION: 'Flag Clean Session', MQTT_RETAIN_FLAG: 'Toujours activer le Retain Flag', INACTIVE: 'Inactif', diff --git a/interface/src/i18n/nl/index.ts b/interface/src/i18n/nl/index.ts index 41cfe4bae..d62467551 100644 --- a/interface/src/i18n/nl/index.ts +++ b/interface/src/i18n/nl/index.ts @@ -249,8 +249,9 @@ const nl: Translation = { MQTT_QUEUE: 'MQTT Queue', DEFAULT: 'Default', MQTT_ENTITY_FORMAT: 'Entity ID format', - MQTT_ENTITY_FORMAT_0: 'Single instance, long name (depreciated)', - MQTT_ENTITY_FORMAT_1: 'Multiple instances, short name', + MQTT_ENTITY_FORMAT_0: 'Single instance, long name (v3.4)', + MQTT_ENTITY_FORMAT_1: 'Single instance, short name', + MQTT_ENTITY_FORMAT_2: 'Multiple instances, short name', 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 2eaf3e2fd..eec20dd21 100644 --- a/interface/src/i18n/no/index.ts +++ b/interface/src/i18n/no/index.ts @@ -249,8 +249,9 @@ const no: Translation = { MQTT_QUEUE: 'MQTT Queue', DEFAULT: 'Standard', MQTT_ENTITY_FORMAT: 'Entity ID format', - MQTT_ENTITY_FORMAT_0: 'Single instance, long name (depreciated)', - MQTT_ENTITY_FORMAT_1: 'Multiple instances, short name', + MQTT_ENTITY_FORMAT_0: 'Single instance, long name (v3.4)', + MQTT_ENTITY_FORMAT_1: 'Single instance, short name', + MQTT_ENTITY_FORMAT_2: 'Multiple instances, short name', 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 8e023ed85..40b983ac4 100644 --- a/interface/src/i18n/pl/index.ts +++ b/interface/src/i18n/pl/index.ts @@ -249,8 +249,9 @@ const pl: BaseTranslation = { MQTT_QUEUE: 'Kolejka MQTT', DEFAULT: '{{Pozostałe|Domyślna|}}', MQTT_ENTITY_FORMAT: 'Entity ID format', - MQTT_ENTITY_FORMAT_0: 'Single instance, long name (depreciated)', - MQTT_ENTITY_FORMAT_1: 'Multiple instances, short name', + MQTT_ENTITY_FORMAT_0: 'Single instance, long name (v3.4)', + MQTT_ENTITY_FORMAT_1: 'Single instance, short name', + MQTT_ENTITY_FORMAT_2: 'Multiple instances, short name', 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 74a2898c2..446150b09 100644 --- a/interface/src/i18n/se/index.ts +++ b/interface/src/i18n/se/index.ts @@ -249,8 +249,9 @@ const se: Translation = { MQTT_QUEUE: 'MQTT Queue', DEFAULT: 'Standard', MQTT_ENTITY_FORMAT: 'Entity ID format', - MQTT_ENTITY_FORMAT_0: 'Single instance, long name (depreciated)', - MQTT_ENTITY_FORMAT_1: 'Multiple instances, short name', + MQTT_ENTITY_FORMAT_0: 'Single instance, long name (v3.4)', + MQTT_ENTITY_FORMAT_1: 'Single instance, short name', + MQTT_ENTITY_FORMAT_2: 'Multiple instances, short name', 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 ee69da5b5..8636039eb 100644 --- a/interface/src/types/mqtt.ts +++ b/interface/src/types/mqtt.ts @@ -29,7 +29,7 @@ export interface MqttSettings { client_id: string; keep_alive: number; clean_session: boolean; - multiple_instances: boolean; + entity_format: number; 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 a52af34f6..f54372578 100644 --- a/lib/framework/MqttSettingsService.cpp +++ b/lib/framework/MqttSettingsService.cpp @@ -145,16 +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["multiple_instances"] = settings.multiple_instances; + 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["entity_format"] = settings.entity_format; // added by proddy for EMS-ESP root["publish_time_boiler"] = settings.publish_time_boiler; @@ -178,18 +178,18 @@ 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.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.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.entity_format = root["entity_format"] | FACTORY_MQTT_ENTITY_FORMAT; + 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; @@ -223,7 +223,7 @@ StateUpdateResult MqttSettings::update(JsonObject & root, MqttSettings & setting changed = true; } - if (newSettings.multiple_instances != settings.multiple_instances) { + if (newSettings.entity_format != settings.entity_format) { changed = true; } diff --git a/lib/framework/MqttSettingsService.h b/lib/framework/MqttSettingsService.h index cac21aa86..eb7907a58 100644 --- a/lib/framework/MqttSettingsService.h +++ b/lib/framework/MqttSettingsService.h @@ -57,8 +57,8 @@ static String generateClientId() { #define FACTORY_MQTT_MAX_TOPIC_LENGTH 128 #endif -#ifndef FACTORY_MQTT_MULTIPLE_INSTANCES -#define FACTORY_MQTT_MULTIPLE_INSTANCES true +#ifndef FACTORY_MQTT_ENTITY_FORMAT +#define FACTORY_MQTT_ENTITY_FORMAT 1 // use shortnames #endif class MqttSettings { @@ -80,7 +80,7 @@ class MqttSettings { bool cleanSession; // multiple instances - bool multiple_instances; + bool entity_format; // proddy EMS-ESP specific String base; diff --git a/lib_standalone/ESP8266React.h b/lib_standalone/ESP8266React.h index f0e8b3817..b8c599862 100644 --- a/lib_standalone/ESP8266React.h +++ b/lib_standalone/ESP8266React.h @@ -81,7 +81,7 @@ class DummySettings { String username = ""; uint16_t keepAlive = 60; bool cleanSession = false; - bool multiple_instances = false; + uint8_t entity_format = 1; 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 e2d06fef9..f94b8290e 100644 --- a/mock-api/server.js +++ b/mock-api/server.js @@ -223,7 +223,7 @@ mqtt_settings = { client_id: 'ems-esp', keep_alive: 60, clean_session: true, - multiple_instances: true, + entity_format: 1, publish_time_boiler: 10, publish_time_thermostat: 10, publish_time_solar: 10, diff --git a/src/analogsensor.cpp b/src/analogsensor.cpp index da7c350f3..fccaf23a5 100644 --- a/src/analogsensor.cpp +++ b/src/analogsensor.cpp @@ -452,7 +452,7 @@ void AnalogSensor::publish_values(const bool force) { config["val_tpl"] = str; char uniq_s[70]; - if (Mqtt::multiple_instances()) { + if (Mqtt::entity_format() == 2) { snprintf(uniq_s, sizeof(uniq_s), "%s_analogsensor_%d", Mqtt::basename().c_str(), sensor.gpio()); } else { snprintf(uniq_s, sizeof(uniq_s), "analogsensor_%d", sensor.gpio()); diff --git a/src/dallassensor.cpp b/src/dallassensor.cpp index 59607909b..9d9db08f1 100644 --- a/src/dallassensor.cpp +++ b/src/dallassensor.cpp @@ -519,7 +519,7 @@ void DallasSensor::publish_values(const bool force) { config["val_tpl"] = str; char uniq_s[70]; - if (Mqtt::multiple_instances()) { + if (Mqtt::entity_format() == 2) { snprintf(uniq_s, sizeof(uniq_s), "%s_dallassensor_%s", Mqtt::basename().c_str(), sensor.id().c_str()); } else { snprintf(uniq_s, sizeof(uniq_s), "dallassensor_%s", sensor.id().c_str()); diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 38817bdce..8a1d7ef07 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -38,7 +38,7 @@ uint32_t Mqtt::publish_time_sensor_; uint32_t Mqtt::publish_time_other_; uint32_t Mqtt::publish_time_heartbeat_; bool Mqtt::mqtt_enabled_; -bool Mqtt::multiple_instances_; +uint8_t Mqtt::entity_format_; bool Mqtt::ha_enabled_; uint8_t Mqtt::nested_format_; std::string Mqtt::discovery_prefix_; @@ -430,7 +430,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; + entity_format_ = mqttSettings.entity_format; // convert to milliseconds publish_time_boiler_ = mqttSettings.publish_time_boiler * 1000; @@ -609,7 +609,7 @@ void Mqtt::ha_status() { StaticJsonDocument doc; char uniq[70]; - if (Mqtt::multiple_instances()) { + if (Mqtt::entity_format() == 2) { snprintf(uniq, sizeof(uniq), "%s_system_status", mqtt_basename_.c_str()); } else { strcpy(uniq, "system_status"); @@ -991,10 +991,14 @@ void Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev // build unique identifier also used as object_id and becomes the Entity ID in HA char uniq_id[70]; - if (Mqtt::multiple_instances()) { + if (Mqtt::entity_format() == 2) { // prefix base name to each uniq_id and use the shortname snprintf(uniq_id, sizeof(uniq_id), "%s_%s_%s", mqtt_basename_.c_str(), device_name, entity_with_tag); + } else if (Mqtt::entity_format() == 1) { + // shortname, no mqtt base + snprintf(uniq_id, sizeof(uniq_id), "%s_%s", device_name, entity_with_tag); } else { + // entity_format is 0 // old v3.4 style // take en_name and replace all spaces and lowercase it char uniq_s[40]; @@ -1308,7 +1312,7 @@ void Mqtt::publish_ha_climate_config(const uint8_t tag, const bool has_roomtemp, snprintf(name_s, sizeof(name_s), "Hc%d", hc_num); - if (Mqtt::multiple_instances()) { + if (Mqtt::entity_format() == 2) { 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 diff --git a/src/mqtt.h b/src/mqtt.h index e2de8bba4..cf19d6c8e 100644 --- a/src/mqtt.h +++ b/src/mqtt.h @@ -181,8 +181,8 @@ class Mqtt { return nested_format_ == NestedFormat::NESTED; } - static bool multiple_instances() { - return multiple_instances_; + static uint8_t entity_format() { + return entity_format_; } static void nested_format(uint8_t nested_format) { @@ -322,7 +322,7 @@ class Mqtt { static bool mqtt_enabled_; static bool ha_enabled_; static uint8_t nested_format_; - static bool multiple_instances_; + static uint8_t entity_format_; static std::string discovery_prefix_; static bool publish_single_; static bool publish_single2cmd_; diff --git a/src/shower.cpp b/src/shower.cpp index 61c5f9ab6..c8b6e6430 100644 --- a/src/shower.cpp +++ b/src/shower.cpp @@ -155,7 +155,7 @@ void Shower::set_shower_state(bool state, bool force) { doc["name"] = "Shower Active"; char str[70]; - if (Mqtt::multiple_instances()) { + if (Mqtt::entity_format() == 2) { snprintf(str, sizeof(str), "%s_shower_active", Mqtt::basename().c_str()); } else { snprintf(str, sizeof(str), "shower_active"); // v3.4 compatible diff --git a/src/system.cpp b/src/system.cpp index b7e23086d..bfba78c6e 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -1152,7 +1152,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["entity format"] = settings.entity_format; node["base"] = settings.base; node["discovery prefix"] = settings.discovery_prefix; node["nested format"] = settings.nested_format; From dc27a44c0cc8e8315181b0517d95263334e7a351 Mon Sep 17 00:00:00 2001 From: Proddy Date: Sat, 17 Dec 2022 20:50:29 +0100 Subject: [PATCH 2/3] fix typo --- interface/src/i18n/de/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/i18n/de/index.ts b/interface/src/i18n/de/index.ts index 2c91e6941..05b09d7b3 100644 --- a/interface/src/i18n/de/index.ts +++ b/interface/src/i18n/de/index.ts @@ -252,7 +252,7 @@ const de: Translation = { MQTT_ENTITY_FORMAT: 'Entitäts-ID Format', MQTT_ENTITY_FORMAT_0: 'Einzelinstanz, Langname (v3.4)', MQTT_ENTITY_FORMAT_1: 'Einzelinstanz, MQTT-Namen', - MQTT_ENTITY_FORMAT_1: 'Mehrfachinstanzen, MQTT-Namen', + MQTT_ENTITY_FORMAT_2: 'Mehrfachinstanzen, MQTT-Namen', MQTT_CLEAN_SESSION: 'Setze `Clean Session`', MQTT_RETAIN_FLAG: 'Setze `Retain flag` immer', INACTIVE: 'Inaktiv', From 17cbd2623f982f090ae8e1d3dffa9d76284d5ee7 Mon Sep 17 00:00:00 2001 From: Proddy Date: Sat, 17 Dec 2022 21:17:57 +0100 Subject: [PATCH 3/3] fix another silly mistake --- lib/framework/MqttSettingsService.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/framework/MqttSettingsService.h b/lib/framework/MqttSettingsService.h index eb7907a58..ab6766b35 100644 --- a/lib/framework/MqttSettingsService.h +++ b/lib/framework/MqttSettingsService.h @@ -80,7 +80,7 @@ class MqttSettings { bool cleanSession; // multiple instances - bool entity_format; + uint8_t entity_format; // proddy EMS-ESP specific String base;