From 26522cb061bbf9b18c51c7e88c90c1c9db7b78e1 Mon Sep 17 00:00:00 2001 From: Proddy Date: Sun, 29 Jan 2023 12:16:14 +0100 Subject: [PATCH 1/5] package update --- interface/package-lock.json | 60 ++++++++++++++++++------------------- interface/package.json | 10 +++---- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/interface/package-lock.json b/interface/package-lock.json index ec93d897c..1048f0168 100644 --- a/interface/package-lock.json +++ b/interface/package-lock.json @@ -12,7 +12,7 @@ "@emotion/styled": "^11.10.5", "@msgpack/msgpack": "^2.8.0", "@mui/icons-material": "^5.11.0", - "@mui/material": "^5.11.5", + "@mui/material": "^5.11.6", "@table-library/react-table-library": "4.0.23", "@types/lodash": "^4.14.191", "@types/node": "^18.11.18", @@ -20,8 +20,7 @@ "@types/react-dom": "^18.0.10", "@types/react-router-dom": "^5.3.3", "async-validator": "^4.2.5", - "axios": "^1.2.3", - "http-proxy-middleware": "^2.0.6", + "axios": "^1.2.6", "jwt-decode": "^3.1.2", "lodash": "^4.17.21", "notistack": "^2.0.8", @@ -30,13 +29,14 @@ "react-dom": "^18.2.0", "react-dropzone": "^14.2.3", "react-icons": "^4.7.1", - "react-router-dom": "^6.7.0", + "react-router-dom": "^6.8.0", "react-scripts": "5.0.1", "sockette": "^2.0.6", "typesafe-i18n": "^5.20.0", "typescript": "^4.9.4" }, "devDependencies": { + "http-proxy-middleware": "^2.0.6", "nodemon": "^2.0.20", "npm-run-all": "^4.1.5" } @@ -3082,9 +3082,9 @@ } }, "node_modules/@mui/base": { - "version": "5.0.0-alpha.114", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.114.tgz", - "integrity": "sha512-ZpsG2I+zTOAnVTj3Un7TxD2zKRA2OhEPGMcWs/9ylPlS6VuGQSXowPooZiqarjT7TZ0+1bOe8titk/t8dLFiGw==", + "version": "5.0.0-alpha.115", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.115.tgz", + "integrity": "sha512-OGQ84whT/yNYd6xKCGGS6MxqEfjVjk5esXM7HP6bB2Rim7QICUapxZt4nm8q39fpT08rNDkv3xPVqDDwRdRg1g==", "dependencies": { "@babel/runtime": "^7.20.7", "@emotion/is-prop-valid": "^1.2.0", @@ -3114,9 +3114,9 @@ } }, "node_modules/@mui/core-downloads-tracker": { - "version": "5.11.5", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.11.5.tgz", - "integrity": "sha512-MIuWGjitOsugpRhp64CQY3ZEVMIu9M/L9ioql6QLSkz73+bGIlC9FEhfi670/GZ8pQIIGmtiGGwofYzlwEWjig==", + "version": "5.11.6", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.11.6.tgz", + "integrity": "sha512-lbD3qdafBOf2dlqKhOcVRxaPAujX+9UlPC6v8iMugMeAXe0TCgU3QbGXY3zrJsu6ex64WYDpH4y1+WOOBmWMuA==", "funding": { "type": "opencollective", "url": "https://opencollective.com/mui" @@ -3148,13 +3148,13 @@ } }, "node_modules/@mui/material": { - "version": "5.11.5", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.11.5.tgz", - "integrity": "sha512-5fzjBbRYaB5MoEpvA32oalAWltOZ3/kSyuovuVmPc6UF6AG42lTtbdMLpdCygurFSGUMZYTg4Cjij52fKlDDgg==", + "version": "5.11.6", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.11.6.tgz", + "integrity": "sha512-MzkkL5KC2PCkFiv8cLpkzgLUPXSrAtnvJBR0emV7mLVWbkwV3n5832vjBx154B6R032fHjFTziTh7YEb50nK6Q==", "dependencies": { "@babel/runtime": "^7.20.7", - "@mui/base": "5.0.0-alpha.114", - "@mui/core-downloads-tracker": "^5.11.5", + "@mui/base": "5.0.0-alpha.115", + "@mui/core-downloads-tracker": "^5.11.6", "@mui/system": "^5.11.5", "@mui/types": "^7.2.3", "@mui/utils": "^5.11.2", @@ -3449,9 +3449,9 @@ } }, "node_modules/@remix-run/router": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.3.0.tgz", - "integrity": "sha512-nwQoYb3m4DDpHTeOwpJEuDt8lWVcujhYYSFGLluC+9es2PyLjm+jjq3IeRBQbwBtPLJE/lkuHuGHr8uQLgmJRA==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.3.1.tgz", + "integrity": "sha512-+eun1Wtf72RNRSqgU7qM2AMX/oHp+dnx7BHk1qhK5ZHzdHTUU4LA1mGG1vT+jMc8sbhG3orvsfOmryjzx2PzQw==", "engines": { "node": ">=14" } @@ -5076,9 +5076,9 @@ } }, "node_modules/axios": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.2.3.tgz", - "integrity": "sha512-pdDkMYJeuXLZ6Xj/Q5J3Phpe+jbGdsSzlQaFVkMQzRUL05+6+tetX8TV3p4HrU4kzuO9bt+io/yGQxuyxA/xcw==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.2.6.tgz", + "integrity": "sha512-rC/7F08XxZwjMV4iuWv+JpD3E0Ksqg9nac4IIg6RwNuF0JTeWoCo/mBNG54+tNhhI11G3/VDRbdDQTs9hGp4pQ==", "dependencies": { "follow-redirects": "^1.15.0", "form-data": "^4.0.0", @@ -14884,11 +14884,11 @@ } }, "node_modules/react-router": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.7.0.tgz", - "integrity": "sha512-KNWlG622ddq29MAM159uUsNMdbX8USruoKnwMMQcs/QWZgFUayICSn2oB7reHce1zPj6CG18kfkZIunSSRyGHg==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.8.0.tgz", + "integrity": "sha512-760bk7y3QwabduExtudhWbd88IBbuD1YfwzpuDUAlJUJ7laIIcqhMvdhSVh1Fur1PE8cGl84L0dxhR3/gvHF7A==", "dependencies": { - "@remix-run/router": "1.3.0" + "@remix-run/router": "1.3.1" }, "engines": { "node": ">=14" @@ -14898,12 +14898,12 @@ } }, "node_modules/react-router-dom": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.7.0.tgz", - "integrity": "sha512-jQtXUJyhso3kFw430+0SPCbmCmY1/kJv8iRffGHwHy3CkoomGxeYzMkmeSPYo6Egzh3FKJZRAL22yg5p2tXtfg==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.8.0.tgz", + "integrity": "sha512-hQouduSTywGJndE86CXJ2h7YEy4HYC6C/uh19etM+79FfQ6cFFFHnHyDlzO4Pq0eBUI96E4qVE5yUjA00yJZGQ==", "dependencies": { - "@remix-run/router": "1.3.0", - "react-router": "6.7.0" + "@remix-run/router": "1.3.1", + "react-router": "6.8.0" }, "engines": { "node": ">=14" diff --git a/interface/package.json b/interface/package.json index 6b4e5ae83..ddb8481ea 100644 --- a/interface/package.json +++ b/interface/package.json @@ -8,7 +8,7 @@ "@emotion/styled": "^11.10.5", "@msgpack/msgpack": "^2.8.0", "@mui/icons-material": "^5.11.0", - "@mui/material": "^5.11.5", + "@mui/material": "^5.11.6", "@table-library/react-table-library": "4.0.23", "@types/lodash": "^4.14.191", "@types/node": "^18.11.18", @@ -16,8 +16,7 @@ "@types/react-dom": "^18.0.10", "@types/react-router-dom": "^5.3.3", "async-validator": "^4.2.5", - "axios": "^1.2.3", - "http-proxy-middleware": "^2.0.6", + "axios": "^1.2.6", "jwt-decode": "^3.1.2", "lodash": "^4.17.21", "notistack": "^2.0.8", @@ -26,7 +25,7 @@ "react-dom": "^18.2.0", "react-dropzone": "^14.2.3", "react-icons": "^4.7.1", - "react-router-dom": "^6.7.0", + "react-router-dom": "^6.8.0", "react-scripts": "5.0.1", "sockette": "^2.0.6", "typesafe-i18n": "^5.20.0", @@ -99,6 +98,7 @@ }, "devDependencies": { "nodemon": "^2.0.20", - "npm-run-all": "^4.1.5" + "npm-run-all": "^4.1.5", + "http-proxy-middleware": "^2.0.6" } } From e4358ba489cbde62d3c1820f8d8b72003f186743 Mon Sep 17 00:00:00 2001 From: Proddy Date: Sun, 29 Jan 2023 12:16:34 +0100 Subject: [PATCH 2/5] uptime in HA should be a string --- src/mqtt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 079834ba5..a876b4619 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -643,7 +643,7 @@ void Mqtt::ha_status() { } publish_system_ha_sensor_config(DeviceValueType::STRING, "EMS Bus", "bus_status", DeviceValueUOM::NONE); - publish_system_ha_sensor_config(DeviceValueType::INT, "Uptime", "uptime", DeviceValueUOM::NONE); + publish_system_ha_sensor_config(DeviceValueType::STRING, "Uptime", "uptime", DeviceValueUOM::NONE); publish_system_ha_sensor_config(DeviceValueType::INT, "Uptime (sec)", "uptime_sec", DeviceValueUOM::SECONDS); publish_system_ha_sensor_config(DeviceValueType::BOOL, "NTP status", "ntp_status", DeviceValueUOM::CONNECTIVITY); publish_system_ha_sensor_config(DeviceValueType::INT, "Free memory", "freemem", DeviceValueUOM::KB); 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 3/5] 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 4/5] 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) { From 1603eafbb257fe575df4a5d6525595e0ed7e8645 Mon Sep 17 00:00:00 2001 From: Proddy Date: Mon, 30 Jan 2023 09:22:03 +0100 Subject: [PATCH 5/5] fix dump_value_info() --- src/emsdevice.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index da6e337e5..48e1eb7d2 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -1109,7 +1109,7 @@ void EMSdevice::dump_value_info() { if (dv.fullname != nullptr) { Serial.print(name_); Serial.print(','); - Serial.print(device_type_name().c_str()); + Serial.print(device_type_name()); Serial.print(','); Serial.print(product_id_);