From 226c1fd6c52662f1c9a3e7871b123875eb714a47 Mon Sep 17 00:00:00 2001 From: pswid <78219494+pswid@users.noreply.github.com> Date: Sun, 29 Jan 2023 18:52:13 +0100 Subject: [PATCH 1/2] fixed 1/0 and true/false MQTT/API format options with HA enabled (#931) furthermore variable names in the HA discovery payload has been abbreviated according to: https://www.home-assistant.io/integrations/mqtt/#discovery-payload --- src/emsdevice.cpp | 5 +--- src/mqtt.cpp | 43 ++++++++++++++++++++-------------- src/shower.cpp | 15 ++++++++---- src/web/WebSettingsService.cpp | 21 ++++++++++++----- 4 files changed, 52 insertions(+), 32 deletions(-) diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index af8318077..da6e337e5 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -1525,10 +1525,7 @@ bool EMSdevice::generate_values(JsonObject & output, const uint8_t tag_filter, c if (dv.type == DeviceValueType::BOOL && Helpers::hasValue(*(uint8_t *)(dv.value_p), EMS_VALUE_BOOL)) { // see how to render the value depending on the setting auto value_b = (bool)*(uint8_t *)(dv.value_p); - if (Mqtt::ha_enabled() && (output_target == OUTPUT_TARGET::MQTT)) { - char s[12]; - json[name] = Helpers::render_boolean(s, value_b); // for HA always render as string - } else if (output_target == OUTPUT_TARGET::CONSOLE) { + if (output_target == OUTPUT_TARGET::CONSOLE) { char s[12]; json[name] = Helpers::render_boolean(s, value_b, true); // console use web settings } else if (EMSESP::system_.bool_format() == BOOL_FORMAT_TRUEFALSE) { diff --git a/src/mqtt.cpp b/src/mqtt.cpp index a876b4619..147e8fb3d 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -610,15 +610,15 @@ void Mqtt::ha_status() { strcpy(uniq, "system_status"); } - doc["uniq_id"] = uniq; - doc["object_id"] = uniq; + doc["uniq_id"] = uniq; + doc["obj_id"] = uniq; - doc["stat_t"] = mqtt_base_ + "/status"; - doc["name"] = "EMS-ESP status"; - doc["payload_on"] = "online"; - doc["payload_off"] = "offline"; - doc["state_class"] = "measurement"; - doc["device_class"] = "connectivity"; + doc["stat_t"] = mqtt_base_ + "/status"; + doc["name"] = "EMS-ESP status"; + doc["pl_on"] = "online"; + doc["pl_off"] = "offline"; + doc["stat_cla"] = "measurement"; + doc["dev_cla"] = "connectivity"; // doc["avty_t"] = "~/status"; // commented out, as it causes errors in HA sometimes // doc["json_attr_t"] = "~/heartbeat"; // store also as HA attributes @@ -1062,8 +1062,8 @@ void Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev // build the payload DynamicJsonDocument doc(EMSESP_JSON_SIZE_HA_CONFIG); - doc["uniq_id"] = uniq_id; - doc["object_id"] = uniq_id; // same as unique_id + doc["uniq_id"] = uniq_id; + doc["obj_id"] = uniq_id; // same as unique_id const char * ic_ha = "ic"; // icon - only set this if there is no device class const char * sc_ha = "state_class"; // state class @@ -1080,7 +1080,7 @@ void Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev } else { snprintf(command_topic, sizeof(command_topic), "%s/%s/%s", mqtt_basename_.c_str(), device_name, entity); } - doc["command_topic"] = command_topic; + doc["cmd_t"] = command_topic; // for enums, add options if (type == DeviceValueType::ENUM) { @@ -1155,13 +1155,20 @@ void Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev // special case to handle booleans // applies to both Binary Sensor (read only) and a Switch (for a command) - // always render boolean as strings true & false - // and has no unit of measure or icon + // has no unit of measure or icon if (type == DeviceValueType::BOOL) { - char result[12]; - doc["payload_on"] = Helpers::render_boolean(result, true); - doc["payload_off"] = Helpers::render_boolean(result, false); - doc[sc_ha] = F_(measurement); + if (EMSESP::system_.bool_format() == BOOL_FORMAT_TRUEFALSE) { + doc["pl_on"] = true; + doc["pl_off"] = false; + } else if (EMSESP::system_.bool_format() == BOOL_FORMAT_10) { + doc["pl_on"] = 1; + doc["pl_off"] = 0; + } else { + char result[12]; + doc["pl_on"] = Helpers::render_boolean(result, true); + doc["pl_off"] = Helpers::render_boolean(result, false); + } + doc[sc_ha] = F_(measurement); //do we want this??? } else { // always set the uom, using the standards except for hours/minutes/seconds // using HA specific codes from https://github.com/home-assistant/core/blob/dev/homeassistant/const.py @@ -1333,7 +1340,7 @@ void Mqtt::publish_ha_climate_config(const uint8_t tag, const bool has_roomtemp, doc["~"] = mqtt_base_; doc["uniq_id"] = uniq_id_s; - doc["object_id"] = uniq_id_s; // same as uniq_id + doc["obj_id"] = uniq_id_s; // same as uniq_id doc["name"] = name_s; doc["mode_stat_t"] = topic_t; doc["mode_stat_tpl"] = mode_str_tpl; diff --git a/src/shower.cpp b/src/shower.cpp index c8b6e6430..4f3d1fa5e 100644 --- a/src/shower.cpp +++ b/src/shower.cpp @@ -167,10 +167,17 @@ void Shower::set_shower_state(bool state, bool force) { snprintf(stat_t, sizeof(stat_t), "%s/shower_active", Mqtt::base().c_str()); // use base path doc["stat_t"] = stat_t; - // always render boolean as strings for HA - char result[12]; - doc[("payload_on")] = Helpers::render_boolean(result, true); - doc[("payload_off")] = Helpers::render_boolean(result, false); + if (EMSESP::system_.bool_format() == BOOL_FORMAT_TRUEFALSE) { + doc["pl_on"] = true; + doc["pl_off"] = false; + } else if (EMSESP::system_.bool_format() == BOOL_FORMAT_10) { + doc["pl_on"] = 1; + doc["pl_off"] = 0; + } else { + char result[12]; + doc["pl_on"] = Helpers::render_boolean(result, true); + doc["pl_off"] = Helpers::render_boolean(result, false); + } JsonObject dev = doc.createNestedObject("dev"); JsonArray ids = dev.createNestedArray("ids"); diff --git a/src/web/WebSettingsService.cpp b/src/web/WebSettingsService.cpp index 1d9e33e5b..0321b4d06 100644 --- a/src/web/WebSettingsService.cpp +++ b/src/web/WebSettingsService.cpp @@ -249,6 +249,21 @@ StateUpdateResult WebSettings::update(JsonObject & root, WebSettings & settings) } #endif + // + // these may need mqtt restart to rebuild HA discovery topics + // + prev = settings.bool_format; + settings.bool_format = root["bool_format"] | EMSESP_DEFAULT_BOOL_FORMAT; + EMSESP::system_.bool_format(settings.bool_format); + if (Mqtt::ha_enabled()) + check_flag(prev, settings.bool_format, ChangeFlags::MQTT); + + prev = settings.enum_format; + settings.enum_format = root["enum_format"] | EMSESP_DEFAULT_ENUM_FORMAT; + EMSESP::system_.enum_format(settings.enum_format); + if (Mqtt::ha_enabled()) + check_flag(prev, settings.enum_format, ChangeFlags::MQTT); + // // without checks or necessary restarts... // @@ -264,15 +279,9 @@ StateUpdateResult WebSettings::update(JsonObject & root, WebSettings & settings) settings.readonly_mode = root["readonly_mode"] | false; EMSESP::system_.readonly_mode(settings.readonly_mode); - settings.bool_format = root["bool_format"] | EMSESP_DEFAULT_BOOL_FORMAT; - EMSESP::system_.bool_format(settings.bool_format); - settings.bool_dashboard = root["bool_dashboard"] | EMSESP_DEFAULT_BOOL_FORMAT; EMSESP::system_.bool_dashboard(settings.bool_dashboard); - settings.enum_format = root["enum_format"] | EMSESP_DEFAULT_ENUM_FORMAT; - EMSESP::system_.enum_format(settings.enum_format); - settings.weblog_level = root["weblog_level"] | EMSESP_DEFAULT_WEBLOG_LEVEL; settings.weblog_buffer = root["weblog_buffer"] | EMSESP_DEFAULT_WEBLOG_BUFFER; settings.weblog_compact = root["weblog_compact"] | EMSESP_DEFAULT_WEBLOG_COMPACT; From d36f87707a77f4099036f96eaff35f1f7a7991ad Mon Sep 17 00:00:00 2001 From: pswid <78219494+pswid@users.noreply.github.com> Date: Sun, 29 Jan 2023 19:08:17 +0100 Subject: [PATCH 2/2] removed "mode"+"step" in HA discovery for BOOL type entities --- src/mqtt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 147e8fb3d..7f000fe58 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -1088,7 +1088,7 @@ void Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev for (uint8_t i = 0; i < options_size; i++) { option_list.add(Helpers::translated_word(options[i])); } - } else if (type != DeviceValueType::STRING) { + } else if (type != DeviceValueType::STRING && type != DeviceValueType::BOOL) { // Must be Numeric.... doc["mode"] = "box"; // auto, slider or box if (num_op > 0) {