From 1442568790e79701a49698216d9014e20f7045f1 Mon Sep 17 00:00:00 2001 From: Proddy Date: Sun, 12 Nov 2023 15:58:06 +0100 Subject: [PATCH 01/14] uppercase ems --- src/locale_translations.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/locale_translations.h b/src/locale_translations.h index e8add620b..7df48201e 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -55,7 +55,6 @@ MAKE_WORD_TRANSLATION(custom_device_name, "User defined entities", "Nutzer dekla MAKE_WORD_TRANSLATION(ventilation_device, "Ventilation", "Lüftung", "Ventilatie", "", "", "", "", "Havalandırma", "Ventilazione") // TODO translate // commands -// TODO translate MAKE_WORD_TRANSLATION(info_cmd, "lists all values", "Liste aller Werte", "lijst van alle waardes", "", "wyświetl wszystkie wartości", "Viser alle verdier", "", "Tüm değerleri listele", "elenca tutti i valori") // TODO translate MAKE_WORD_TRANSLATION(commands_cmd, "lists all commands", "Liste aller Kommandos", "lijst van alle commando's", "", "wyświetl wszystkie komendy", "Viser alle kommandoer", "", "Tüm komutları listele", "elencaa tutti i comandi") // TODO translate MAKE_WORD_TRANSLATION(entities_cmd, "lists all entities", "Liste aller Entitäten", "lijst van alle entiteiten", "", "wyświetl wszsytkie encje", "Viser alle enheter", "", "Tüm varlıkları listele", "elenca tutte le entità") // TODO translate @@ -68,9 +67,10 @@ MAKE_WORD_TRANSLATION(watch_cmd, "watch incoming telegrams", "Watch auf eingehen MAKE_WORD_TRANSLATION(publish_cmd, "publish all to MQTT", "Publiziere MQTT", "publiceer alles naar MQTT", "", "opublikuj wszystko na MQTT", "Publiser alt til MQTT", "", "Hepsini MQTTye gönder", "pubblica tutto su MQTT") // TODO translate MAKE_WORD_TRANSLATION(system_info_cmd, "show system status", "Zeige System-Status", "toon systeemstatus", "", "pokaż status systemu", "vis system status", "", "Sistem Durumunu Göster", "visualizza stati di sistema") // TODO translate MAKE_WORD_TRANSLATION(schedule_cmd, "enable schedule item", "Aktiviere Zeitplan", "activeer tijdschema item", "", "aktywuj wybrany harmonogram", "", "", "program öğesini etkinleştir", "abilitare l'elemento programmato") // TODO translate -MAKE_WORD_TRANSLATION(entity_cmd, "set custom value on ems", "Sende eigene Entitäten zu EMS", "verstuur custom waarde naar EMS", "", "wyślij własną wartość na EMS", "", "", "emp üzerinde özel değer ayarla", "imposta valori personalizzati su EMS") // TODO translate +MAKE_WORD_TRANSLATION(entity_cmd, "set custom value on EMS", "Sende eigene Entitäten zu EMS", "verstuur custom waarde naar EMS", "", "wyślij własną wartość na EMS", "", "", "emp üzerinde özel değer ayarla", "imposta valori personalizzati su EMS") // TODO translate MAKE_WORD_TRANSLATION(commands_response, "get response","Hole Antwort","Verzoek om antwoord", "", "", "", "gelen cevap", "") // TODO translate MAKE_WORD_TRANSLATION(coldshot_cmd, "send a cold shot of water", "", "", "", "", "", "", "soğuk su gönder", "") // TODO translate +MAKE_WORD_TRANSLATION(values_cmd, "show all values", "", "", "", "", "", "", "", "") // TODO translate // tags MAKE_WORD_TRANSLATION(tag_boiler_data_ww, "dhw", "WW", "dhw", "VV", "CWU", "dhw", "ecs", "SKS", "dhw") From 101159b9f663c843080e6fa49f99e210f256bc71 Mon Sep 17 00:00:00 2001 From: Proddy Date: Sun, 12 Nov 2023 15:58:22 +0100 Subject: [PATCH 02/14] add sensors to generic test --- src/test/test.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/test/test.cpp b/src/test/test.cpp index 0ba654b85..51427919f 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -275,11 +275,17 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const bool ok = false; if (command == "general") { - shell.printfln("Testing adding a general boiler & thermostat..."); + shell.printfln("Testing adding a boiler, thermostat and sensors..."); run_test("general"); + + // add sensors + emsesp::EMSESP::analogsensor_.test(); + emsesp::EMSESP::temperaturesensor_.test(); + // shell.invoke_command("show devices"); shell.invoke_command("show values"); - shell.invoke_command("call system publish"); + shell.invoke_command("call system values"); + // shell.invoke_command("call system publish"); // shell.invoke_command("show mqtt"); ok = true; } From 2079b7e602e38e04986a32ab0215ba40e3e25ef8 Mon Sep 17 00:00:00 2001 From: Proddy Date: Sun, 12 Nov 2023 15:58:35 +0100 Subject: [PATCH 03/14] formatting --- src/web/WebCustomEntityService.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/web/WebCustomEntityService.cpp b/src/web/WebCustomEntityService.cpp index 653c8a74e..36fb5ac9c 100644 --- a/src/web/WebCustomEntityService.cpp +++ b/src/web/WebCustomEntityService.cpp @@ -247,11 +247,13 @@ bool WebCustomEntityService::get_value_info(JsonObject & output, const char * cm } return true; } + // if no entries, return empty json // https://github.com/emsesp/EMS-ESP32/issues/1297 if (customEntityItems->size() == 0) { return true; } + if (strlen(cmd) == 0 || Helpers::toLower(cmd) == F_(values) || Helpers::toLower(cmd) == F_(info)) { // list all names for (const CustomEntityItem & entity : *customEntityItems) { From ea380110859438279b296c9f96f0dca446fa2f0b Mon Sep 17 00:00:00 2001 From: Proddy Date: Sun, 12 Nov 2023 15:59:02 +0100 Subject: [PATCH 04/14] add text to remind people about su command --- src/console.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/console.cpp b/src/console.cpp index 363457785..c60f0d7e7 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -597,12 +597,13 @@ void EMSESPShell::stopped() { // show welcome banner void EMSESPShell::display_banner() { println(); - printfln("┌────────────────────────────────────────┐"); - printfln("│ %sEMS-ESP version %-12s%s │", COLOR_BOLD_ON, EMSESP_APP_VERSION, COLOR_BOLD_OFF); - printfln("│ %s%shttps://github.com/emsesp/EMS-ESP32%s │", COLOR_BRIGHT_GREEN, COLOR_UNDERLINE, COLOR_RESET); - printfln("│ │"); - printfln("│ type %shelp%s to show available commands │", COLOR_UNDERLINE, COLOR_RESET); - printfln("└────────────────────────────────────────┘"); + printfln("┌───────────────────────────────────────┐"); + printfln("│ %sEMS-ESP version %-12s%s │", COLOR_BOLD_ON, EMSESP_APP_VERSION, COLOR_BOLD_OFF); + printfln("│ %s%shttps://github.com/emsesp/EMS-ESP32%s │", COLOR_BRIGHT_GREEN, COLOR_UNDERLINE, COLOR_RESET); + printfln("│ │"); + printfln("│ type %shelp%s to show available commands │", COLOR_UNDERLINE, COLOR_RESET); + printfln("│ use %ssu%s to access Admin commands │", COLOR_UNDERLINE, COLOR_RESET); + printfln("└───────────────────────────────────────┘"); println(); // set console name From 9993a7c7397dc9797abb75731f14eda54509daaf Mon Sep 17 00:00:00 2001 From: Proddy Date: Sun, 12 Nov 2023 15:59:29 +0100 Subject: [PATCH 05/14] fix UOM not showing in console - and added new command 'system values' --- src/analogsensor.h | 4 ++- src/emsdevice.cpp | 61 ++++++++++++++++++++++++++--------------- src/emsdevice.h | 12 ++++---- src/emsesp.cpp | 56 ++++++++++--------------------------- src/emsesp.h | 1 - src/system.cpp | 32 +++++++++++++++++++++ src/system.h | 2 ++ src/temperaturesensor.h | 3 +- 8 files changed, 99 insertions(+), 72 deletions(-) diff --git a/src/analogsensor.h b/src/analogsensor.h index 132b20e50..b33fb1137 100644 --- a/src/analogsensor.h +++ b/src/analogsensor.h @@ -156,6 +156,9 @@ class AnalogSensor { bool get_value_info(JsonObject & output, const char * cmd, const int8_t id) const; void store_counters(); + bool command_info(const char * value, const int8_t id, JsonObject & output) const; + + #if defined(EMSESP_TEST) void test(); #endif @@ -169,7 +172,6 @@ class AnalogSensor { void remove_ha_topic(const int8_t type, const uint8_t id) const; bool command_setvalue(const char * value, const int8_t gpio); void measure(); - bool command_info(const char * value, const int8_t id, JsonObject & output) const; bool command_commands(const char * value, const int8_t id, JsonObject & output); std::vector sensors_; // our list of sensors diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index 7ce2b602f..ae80ffcb2 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -803,29 +803,9 @@ void EMSdevice::publish_value(void * value_p) const { } // looks up the UOM for a given key from the device value table -// key is the fullname -std::string EMSdevice::get_value_uom(const char * key) const { - // the key may have a TAG string prefixed at the beginning. If so, remove it - char new_key[80]; - strlcpy(new_key, key, sizeof(new_key)); - char * key_p = new_key; - - for (uint8_t i = 0; i < DeviceValue::NUM_TAGS; i++) { - auto tag = Helpers::translated_word(DeviceValue::DeviceValueTAG_s[i]); - if (tag) { - std::string key2 = key; // copy string to a std::string so we can use the find function - uint8_t length = strlen(tag); - if ((key2.find(tag) != std::string::npos) && (key[length] == ' ')) { - key_p += length + 1; // remove the tag - break; - } - } - } - - // look up key in our device value list +std::string EMSdevice::get_value_uom(const std::string & shortname) const { for (const auto & dv : devicevalues_) { - auto fullname = dv.get_fullname(); - if ((!dv.has_state(DeviceValueState::DV_WEB_EXCLUDE) && !fullname.empty()) && (fullname == key_p)) { + if ((!dv.has_state(DeviceValueState::DV_WEB_EXCLUDE)) && (dv.short_name == shortname)) { // ignore TIME since "minutes" is already added to the string value if ((dv.uom == DeviceValueUOM::NONE) || (dv.uom == DeviceValueUOM::MINUTES)) { break; @@ -837,6 +817,43 @@ std::string EMSdevice::get_value_uom(const char * key) const { return std::string{}; // not found } +bool EMSdevice::export_values(uint8_t device_type, JsonObject & output, const int8_t id, const uint8_t output_target) { + bool has_value = false; + uint8_t tag; + if (id >= 1 && id <= (1 + DeviceValueTAG::TAG_HS16 - DeviceValueTAG::TAG_HC1)) { + tag = DeviceValueTAG::TAG_HC1 + id - 1; // this sets also WWC and HS + } else if (id == -1 || id == 0) { + tag = DeviceValueTAG::TAG_NONE; + } else { + return false; + } + + if (id > 0 || output_target == EMSdevice::OUTPUT_TARGET::API_VERBOSE) { + for (const auto & emsdevice : EMSESP::emsdevices) { + if (emsdevice && (emsdevice->device_type() == device_type)) { + has_value |= emsdevice->generate_values(output, tag, (id < 1), output_target); // use nested for id -1 and 0 + } + } + return has_value; + } + + // for nested output add for each tag + for (tag = DeviceValueTAG::TAG_BOILER_DATA_WW; tag <= DeviceValueTAG::TAG_HS16; tag++) { + JsonObject output_hc = output; + bool nest_created = false; + for (const auto & emsdevice : EMSESP::emsdevices) { + if (emsdevice && (emsdevice->device_type() == device_type)) { + if (!nest_created && emsdevice->has_tags(tag)) { + output_hc = output.createNestedObject(EMSdevice::tag_to_mqtt(tag)); + nest_created = true; + } + has_value |= emsdevice->generate_values(output_hc, tag, true, output_target); // use nested for id -1 and 0 + } + } + } + return has_value; +} + // prepare array of device values used for the WebUI // this is loosely based of the function generate_values used for the MQTT and Console // except additional data is stored in the JSON document needed for the Web UI like the UOM and command diff --git a/src/emsdevice.h b/src/emsdevice.h index 62810471e..3a05ecb54 100644 --- a/src/emsdevice.h +++ b/src/emsdevice.h @@ -47,12 +47,13 @@ class EMSdevice { // static functions, used outside the class like in console.cpp, command.cpp, emsesp.cpp, mqtt.cpp static const char * device_type_2_device_name(const uint8_t device_type); static uint8_t device_name_2_device_type(const char * topic); - static const char * tag_to_string(uint8_t tag, const bool translate = true); static const char * uom_to_string(uint8_t uom); static const char * tag_to_mqtt(uint8_t tag); + static uint8_t decode_brand(uint8_t value); + static bool export_values(uint8_t device_type, JsonObject & output, const int8_t id, const uint8_t output_target); - static uint8_t decode_brand(uint8_t value); + // non static const char * device_type_name(); // returns short non-translated device type name const char * device_type_2_device_name_translated(); // returns translated device type name @@ -213,9 +214,10 @@ class EMSdevice { void register_telegram_type(const uint16_t telegram_type_id, const char * telegram_type_name, bool fetch, const process_function_p cb); bool handle_telegram(std::shared_ptr telegram); - std::string get_value_uom(const char * key) const; - bool get_value_info(JsonObject & root, const char * cmd, const int8_t id); - void get_dv_info(JsonObject & json); + std::string get_value_uom(const std::string & shortname) const; + + bool get_value_info(JsonObject & root, const char * cmd, const int8_t id); + void get_dv_info(JsonObject & json); enum OUTPUT_TARGET : uint8_t { API_VERBOSE, API_SHORTNAMES, MQTT, CONSOLE }; bool generate_values(JsonObject & output, const uint8_t tag_filter, const bool nested, const uint8_t output_target); diff --git a/src/emsesp.cpp b/src/emsesp.cpp index 3e2a8982d..21a8b19d5 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -386,13 +386,19 @@ void EMSESP::show_device_values(uuid::console::Shell & shell) { // print line for (JsonPair p : json) { - const char * key = p.key().c_str(); - shell.printf(" %s: ", key); + std::string key = p.key().c_str(); // this will be fullname and the shortname in brackets + shell.printf(" %s: ", key.c_str()); JsonVariant data = p.value(); shell.print(COLOR_BRIGHT_GREEN); shell.print(data.as()); + + // extract the shortname from the key, which is in brackets + std::size_t first_bracket = key.find_first_of('('); + std::size_t last_bracket = key.find_last_of(')'); + std::string shortname = key.substr(first_bracket + 1, last_bracket - first_bracket - 1); + // if there is a uom print it - std::string uom = emsdevice->get_value_uom(key); + std::string uom = emsdevice->get_value_uom(shortname); if (uom == "°C" && EMSESP::system_.fahrenheit()) { uom = "°F"; } @@ -1169,14 +1175,17 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, const device_type, F_(info), [device_type](const char * value, const int8_t id, JsonObject & output) { - return command_info(device_type, output, id, EMSdevice::OUTPUT_TARGET::API_VERBOSE); + return EMSdevice::export_values(device_type, output, id, EMSdevice::OUTPUT_TARGET::API_VERBOSE); }, FL_(info_cmd)); Command::add( device_type, F_(values), [device_type](const char * value, const int8_t id, JsonObject & output) { - return command_info(device_type, output, id, EMSdevice::OUTPUT_TARGET::API_SHORTNAMES); // HIDDEN command showing short names, used in e.g. /api/boiler + return EMSdevice::export_values(device_type, + output, + id, + EMSdevice::OUTPUT_TARGET::API_SHORTNAMES); // HIDDEN command showing short names, used in e.g. /api/boiler }, nullptr, CommandFlag::HIDDEN); // this command is hidden @@ -1217,43 +1226,6 @@ bool EMSESP::command_commands(uint8_t device_type, JsonObject & output, const in return Command::list(device_type, output); } -// export all values for a specific device -bool EMSESP::command_info(uint8_t device_type, JsonObject & output, const int8_t id, const uint8_t output_target) { - bool has_value = false; - uint8_t tag; - if (id >= 1 && id <= (1 + DeviceValueTAG::TAG_HS16 - DeviceValueTAG::TAG_HC1)) { - tag = DeviceValueTAG::TAG_HC1 + id - 1; // this sets also WWC and HS - } else if (id == -1 || id == 0) { - tag = DeviceValueTAG::TAG_NONE; - } else { - return false; - } - - if (id > 0 || output_target == EMSdevice::OUTPUT_TARGET::API_VERBOSE) { - for (const auto & emsdevice : emsdevices) { - if (emsdevice && (emsdevice->device_type() == device_type)) { - has_value |= emsdevice->generate_values(output, tag, (id < 1), output_target); // use nested for id -1 and 0 - } - } - return has_value; - } - // for nested output add for each tag - for (tag = DeviceValueTAG::TAG_BOILER_DATA_WW; tag <= DeviceValueTAG::TAG_HS16; tag++) { - JsonObject output_hc = output; - bool nest_created = false; - for (const auto & emsdevice : emsdevices) { - if (emsdevice && (emsdevice->device_type() == device_type)) { - if (!nest_created && emsdevice->has_tags(tag)) { - output_hc = output.createNestedObject(EMSdevice::tag_to_mqtt(tag)); - nest_created = true; - } - has_value |= emsdevice->generate_values(output_hc, tag, true, output_target); // use nested for id -1 and 0 - } - } - } - return has_value; -} - // send a read request, passing it into to the Tx Service, with optional offset and length void EMSESP::send_read_request(const uint16_t type_id, const uint8_t dest, const uint8_t offset, const uint8_t length, const bool front) { txservice_.read_request(type_id, dest, offset, length, front); diff --git a/src/emsesp.h b/src/emsesp.h index 30634c103..e5d074460 100644 --- a/src/emsesp.h +++ b/src/emsesp.h @@ -245,7 +245,6 @@ class EMSESP { static void process_version(std::shared_ptr telegram); static void publish_response(std::shared_ptr telegram); static void publish_all_loop(); - static bool command_info(uint8_t device_type, JsonObject & output, const int8_t id, const uint8_t output_target); static bool command_commands(uint8_t device_type, JsonObject & output, const int8_t id); static bool command_entities(uint8_t device_type, JsonObject & output, const int8_t id); diff --git a/src/system.cpp b/src/system.cpp index be47f261a..f4cd90302 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -106,6 +106,35 @@ bool System::command_response(const char * value, const int8_t id, JsonObject & return true; } +// output all the EMS devices and their values, plus the sensors and any custom things +// basically dump everything we know about +bool System::command_values(const char * value, const int8_t id, JsonObject & output) { + DynamicJsonDocument doc(EMSESP_JSON_SIZE_XXXLARGE); + JsonObject device_output; + + for (const auto & device_class : EMSFactory::device_handlers()) { + for (const auto & emsdevice : EMSESP::emsdevices) { + if (emsdevice->device_type() == device_class.first) { + std::string title = emsdevice->device_type_2_device_name_translated() + std::string(" ") + emsdevice->to_string(); + device_output = output.createNestedObject(title); + emsesp::EMSdevice::export_values(emsdevice->device_type(), device_output, id, EMSdevice::OUTPUT_TARGET::API_VERBOSE); + } + } + } + + // Custom entities + device_output = output.createNestedObject("Custom Entities"); + EMSESP::webCustomEntityService.get_value_info(device_output, ""); + + // Sensors + device_output = output.createNestedObject("Analog Sensors"); + EMSESP::analogsensor_.command_info(nullptr, 0, device_output); + device_output = output.createNestedObject("Temperature Sensors"); + EMSESP::temperaturesensor_.command_info(nullptr, 0, device_output); + + return true; +} + // fetch device values bool System::command_fetch(const char * value, const int8_t id) { std::string value_s; @@ -756,6 +785,7 @@ void System::commands_init() { // restart and watch (and test) are also exposed as Console commands Command::add(EMSdevice::DeviceType::SYSTEM, F_(restart), System::command_restart, FL_(restart_cmd), CommandFlag::ADMIN_ONLY); Command::add(EMSdevice::DeviceType::SYSTEM, F_(watch), System::command_watch, FL_(watch_cmd)); + #if defined(EMSESP_TEST) Command::add(EMSdevice::DeviceType::SYSTEM, ("test"), System::command_test, FL_(test_cmd)); #endif @@ -764,6 +794,8 @@ void System::commands_init() { Command::add(EMSdevice::DeviceType::SYSTEM, F_(info), System::command_info, FL_(system_info_cmd)); Command::add(EMSdevice::DeviceType::SYSTEM, F_(commands), System::command_commands, FL_(commands_cmd)); Command::add(EMSdevice::DeviceType::SYSTEM, F("response"), System::command_response, FL_(commands_response)); + Command::add(EMSdevice::DeviceType::SYSTEM, F_(values), System::command_values, FL_(values_cmd)); + // MQTT subscribe "ems-esp/system/#" Mqtt::subscribe(EMSdevice::DeviceType::SYSTEM, "system/#", nullptr); // use empty function callback diff --git a/src/system.h b/src/system.h index a4cb6d5f6..d4826bb60 100644 --- a/src/system.h +++ b/src/system.h @@ -60,6 +60,8 @@ class System { static bool command_info(const char * value, const int8_t id, JsonObject & output); static bool command_commands(const char * value, const int8_t id, JsonObject & output); static bool command_response(const char * value, const int8_t id, JsonObject & output); + static bool command_values(const char * value, const int8_t id, JsonObject & output); + #if defined(EMSESP_TEST) static bool command_test(const char * value, const int8_t id); #endif diff --git a/src/temperaturesensor.h b/src/temperaturesensor.h index 353b8f8fa..3d7363054 100644 --- a/src/temperaturesensor.h +++ b/src/temperaturesensor.h @@ -111,6 +111,8 @@ class TemperatureSensor { bool update(const std::string & id, const std::string & name, int16_t offset); + bool command_info(const char * value, const int8_t id, JsonObject & output); + #if defined(EMSESP_TEST) void test(); #endif @@ -152,7 +154,6 @@ class TemperatureSensor { uint64_t get_id(const uint8_t addr[]); void remove_ha_topic(const std::string & id); - bool command_info(const char * value, const int8_t id, JsonObject & output); bool command_commands(const char * value, const int8_t id, JsonObject & output); std::vector sensors_; // our list of active sensors From fd81299da18f06a9d78186be727dddc7aaef3ae4 Mon Sep 17 00:00:00 2001 From: Proddy Date: Sun, 12 Nov 2023 16:00:52 +0100 Subject: [PATCH 06/14] 3.6.3-dev.8 --- CHANGELOG_LATEST.md | 1 + src/version.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 67c22fc3e..64624c549 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -14,6 +14,7 @@ Writeable Text entities have moved from type `sensor` to `text` in Home Assistan - option for `forceheatingoff` [#1262](https://github.com/emsesp/EMS-ESP32/issues/1262) - shower_data MQTT payload contains the timestamp [#1329](https://github.com/emsesp/EMS-ESP32/issues/1329) - HA discovery for writeable text entities [#1337](https://github.com/emsesp/EMS-ESP32/pull/1377) +- Added 'system values' command that dumps all the EMS device values, plus sensors and any custom entities ## Fixed diff --git a/src/version.h b/src/version.h index 27f386c60..3cfe27471 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.6.3-dev.7" +#define EMSESP_APP_VERSION "3.6.3-dev.8" From fc027218159ae19e60caa7f04c01298207c477a9 Mon Sep 17 00:00:00 2001 From: Proddy Date: Mon, 13 Nov 2023 16:55:10 +0100 Subject: [PATCH 07/14] package update --- interface/package.json | 2 +- interface/yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/interface/package.json b/interface/package.json index d9ffc23db..c97f68fd0 100644 --- a/interface/package.json +++ b/interface/package.json @@ -66,7 +66,7 @@ "eslint-plugin-react": "^7.33.2", "eslint-plugin-react-hooks": "^4.6.0", "preact": "^10.19.1", - "prettier": "^3.0.3", + "prettier": "^3.1.0", "rollup-plugin-visualizer": "^5.9.2", "terser": "^5.24.0", "vite": "^4.5.0", diff --git a/interface/yarn.lock b/interface/yarn.lock index 9f20d6982..b9c69217a 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -1679,7 +1679,7 @@ __metadata: lodash-es: "npm:^4.17.21" mime-types: "npm:^2.1.35" preact: "npm:^10.19.1" - prettier: "npm:^3.0.3" + prettier: "npm:^3.1.0" react: "npm:latest" react-dom: "npm:latest" react-dropzone: "npm:^14.2.3" @@ -6795,12 +6795,12 @@ __metadata: languageName: node linkType: hard -"prettier@npm:^3.0.3": - version: 3.0.3 - resolution: "prettier@npm:3.0.3" +"prettier@npm:^3.1.0": + version: 3.1.0 + resolution: "prettier@npm:3.1.0" bin: prettier: bin/prettier.cjs - checksum: ccf1ead9794b017be6b42d0873f459070beef2069eb393c8b4c0d11aa3430acefc54f6d5f44a5b7ce9af05ad8daf694b912f0aa2808d1c22dfa86e61e9d563f8 + checksum: e95e8f93c6b9aea2ac1e86bebe329bee90c8c50d9a23d1f593eba8d7f39b33b3641eb28785001505b6723c47895a5322ad12a2fb855b289cb7bae450ffc34425 languageName: node linkType: hard From 386082b747ca59c2aeaa2f6802cd232f3edccdcd Mon Sep 17 00:00:00 2001 From: Proddy Date: Mon, 13 Nov 2023 16:55:52 +0100 Subject: [PATCH 08/14] update for vscode --- .vscode/settings.json | 46 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 5b4f0b9d6..7039a6101 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -26,7 +26,51 @@ "type_traits": "cpp", "utility": "cpp", "string": "cpp", - "string_view": "cpp" + "string_view": "cpp", + "atomic": "cpp", + "bitset": "cpp", + "cctype": "cpp", + "chrono": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "condition_variable": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "list": "cpp", + "unordered_map": "cpp", + "unordered_set": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "iterator": "cpp", + "map": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "random": "cpp", + "set": "cpp", + "fstream": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "thread": "cpp", + "cinttypes": "cpp", + "typeinfo": "cpp" }, "todo-tree.filtering.excludeGlobs": [ "**/vendor/**", From 1a9cf4ebdc58b58262d127dbcf9d7fb4b43c09c4 Mon Sep 17 00:00:00 2001 From: Proddy Date: Mon, 13 Nov 2023 16:56:25 +0100 Subject: [PATCH 09/14] added more space for longer names --- src/command.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/command.cpp b/src/command.cpp index fd6325f0b..40c7096e5 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -504,7 +504,7 @@ void Command::show(uuid::console::Shell & shell, uint8_t device_type, bool verbo } shell.print(cl); // pad with spaces - while (i++ < 22) { + while (i++ < 30) { shell.print(' '); } shell.print(COLOR_BRIGHT_CYAN); @@ -515,7 +515,7 @@ void Command::show(uuid::console::Shell & shell, uint8_t device_type, bool verbo shell.print(Helpers::translated_word(cf.description_)); if (!cf.has_flags(CommandFlag::ADMIN_ONLY)) { shell.print(' '); - shell.print(COLOR_BRIGHT_RED); + shell.print(COLOR_BRIGHT_GREEN); shell.print('*'); } shell.print(COLOR_RESET); @@ -595,7 +595,7 @@ void Command::show_devices(uuid::console::Shell & shell) { // output list of all commands to console // calls show with verbose mode set void Command::show_all(uuid::console::Shell & shell) { - shell.println("Available commands (*=authorization not required): "); + shell.printfln("Showing all available commands (%s*%s=authentication not required):", COLOR_BRIGHT_GREEN, COLOR_RESET); // show system first shell.print(COLOR_BOLD_ON); @@ -609,9 +609,9 @@ void Command::show_all(uuid::console::Shell & shell) { shell.print(COLOR_YELLOW); shell.printf(" %s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::CUSTOM)); shell.println(COLOR_RESET); - shell.printf(" info: %slists all values %s*", COLOR_BRIGHT_CYAN, COLOR_BRIGHT_RED); + shell.printf(" info:\t\t\t\t%slists all values %s*", COLOR_BRIGHT_CYAN, COLOR_BRIGHT_GREEN); shell.println(COLOR_RESET); - shell.printf(" commands: %slists all commands %s*", COLOR_BRIGHT_CYAN, COLOR_BRIGHT_RED); + shell.printf(" commands:\t\t\t%slists all commands %s*", COLOR_BRIGHT_CYAN, COLOR_BRIGHT_GREEN); shell.print(COLOR_RESET); show(shell, EMSdevice::DeviceType::CUSTOM, true); @@ -620,9 +620,9 @@ void Command::show_all(uuid::console::Shell & shell) { shell.print(COLOR_YELLOW); shell.printf(" %s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::SCHEDULER)); shell.println(COLOR_RESET); - shell.printf(" info: %slists all values %s*", COLOR_BRIGHT_CYAN, COLOR_BRIGHT_RED); + shell.printf(" info:\t\t\t\t%slists all values %s*", COLOR_BRIGHT_CYAN, COLOR_BRIGHT_GREEN); shell.println(COLOR_RESET); - shell.printf(" commands: %slists all commands %s*", COLOR_BRIGHT_CYAN, COLOR_BRIGHT_RED); + shell.printf(" commands:\t\t\t%slists all commands %s*", COLOR_BRIGHT_CYAN, COLOR_BRIGHT_GREEN); shell.print(COLOR_RESET); show(shell, EMSdevice::DeviceType::SCHEDULER, true); From ae0599d13dd41b99cb900091f517d0ccca966b3d Mon Sep 17 00:00:00 2001 From: Proddy Date: Mon, 13 Nov 2023 16:56:48 +0100 Subject: [PATCH 10/14] optionally render with UOM attached --- src/web/WebCustomEntityService.cpp | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/web/WebCustomEntityService.cpp b/src/web/WebCustomEntityService.cpp index 36fb5ac9c..f8b18ff80 100644 --- a/src/web/WebCustomEntityService.cpp +++ b/src/web/WebCustomEntityService.cpp @@ -182,7 +182,8 @@ bool WebCustomEntityService::command_setvalue(const char * value, const std::str } // output of a single value -void WebCustomEntityService::render_value(JsonObject & output, CustomEntityItem entity, const bool useVal, const bool web) { +// if add_uom is true it will add the UOM string to the value +void WebCustomEntityService::render_value(JsonObject & output, CustomEntityItem entity, const bool useVal, const bool web, const bool add_uom) { char payload[12]; std::string name = useVal ? "value" : entity.name; switch (entity.value_type) { @@ -201,28 +202,33 @@ void WebCustomEntityService::render_value(JsonObject & output, CustomEntityItem break; case DeviceValueType::INT: if ((int8_t)entity.value != EMS_VALUE_INT_NOTSET) { - output[name] = serialized(Helpers::render_value(payload, entity.factor * (int8_t)entity.value, 2)); + std::string v = Helpers::render_value(payload, entity.factor * (int8_t)entity.value, 2); + output[name] = add_uom ? serialized(v + ' ' + EMSdevice::uom_to_string(entity.uom)) : serialized(v); } break; case DeviceValueType::UINT: if ((uint8_t)entity.value != EMS_VALUE_UINT_NOTSET) { - output[name] = serialized(Helpers::render_value(payload, entity.factor * (uint8_t)entity.value, 2)); + std::string v = Helpers::render_value(payload, entity.factor * (uint8_t)entity.value, 2); + output[name] = add_uom ? serialized(v + ' ' + EMSdevice::uom_to_string(entity.uom)) : serialized(v); } break; case DeviceValueType::SHORT: if ((int16_t)entity.value != EMS_VALUE_SHORT_NOTSET) { - output[name] = serialized(Helpers::render_value(payload, entity.factor * (int16_t)entity.value, 2)); + std::string v = Helpers::render_value(payload, entity.factor * (int16_t)entity.value, 2); + output[name] = add_uom ? serialized(v + ' ' + EMSdevice::uom_to_string(entity.uom)) : serialized(v); } break; case DeviceValueType::USHORT: if ((uint16_t)entity.value != EMS_VALUE_USHORT_NOTSET) { - output[name] = serialized(Helpers::render_value(payload, entity.factor * (uint16_t)entity.value, 2)); + std::string v = Helpers::render_value(payload, entity.factor * (uint16_t)entity.value, 2); + output[name] = add_uom ? serialized(v + ' ' + EMSdevice::uom_to_string(entity.uom)) : serialized(v); } break; case DeviceValueType::ULONG: case DeviceValueType::TIME: if (entity.value != EMS_VALUE_ULONG_NOTSET) { - output[name] = serialized(Helpers::render_value(payload, entity.factor * entity.value, 2)); + std::string v = Helpers::render_value(payload, entity.factor * entity.value, 2); + output[name] = add_uom ? serialized(v + ' ' + EMSdevice::uom_to_string(entity.uom)) : serialized(v); } break; case DeviceValueType::STRING: @@ -236,6 +242,15 @@ void WebCustomEntityService::render_value(JsonObject & output, CustomEntityItem } } +// display all custom entities +// adding each one, with UOM to a json object string +void WebCustomEntityService::show_values(JsonObject & output) { + for (const CustomEntityItem & entity : *customEntityItems) { + render_value(output, entity, false, false, true); // with add_uom + } +} + + // process json output for info/commands and value_info bool WebCustomEntityService::get_value_info(JsonObject & output, const char * cmd) { EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); From 499ff0d31e6c2ea294b1f676d9a2e72c8a8ec805 Mon Sep 17 00:00:00 2001 From: Proddy Date: Mon, 13 Nov 2023 16:57:20 +0100 Subject: [PATCH 11/14] include (HS1) for standalone testing --- src/web/WebCustomizationService.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/web/WebCustomizationService.cpp b/src/web/WebCustomizationService.cpp index 6f1e9f711..2a812a7e3 100644 --- a/src/web/WebCustomizationService.cpp +++ b/src/web/WebCustomizationService.cpp @@ -97,7 +97,7 @@ StateUpdateResult WebCustomization::update(JsonObject & root, WebCustomization & #ifdef EMSESP_STANDALONE // invoke some fake data for testing const char * json = "{\"ts\":[],\"as\":[],\"masked_entities\":[{\"product_id\":123,\"device_id\":8,\"entity_ids\":[\"08heatingactive|my custom " - "name for heating active\",\"08tapwateractive\"]}]}"; + "name for heating active (HS1)\",\"08tapwateractive\"]}]}"; StaticJsonDocument<500> doc; deserializeJson(doc, json); root = doc.as(); From eccece72073559bb974092b73f7dc44b764e5086 Mon Sep 17 00:00:00 2001 From: Proddy Date: Mon, 13 Nov 2023 16:57:35 +0100 Subject: [PATCH 12/14] minor code optimization --- src/emsesp.cpp | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/src/emsesp.cpp b/src/emsesp.cpp index 21a8b19d5..d378ef274 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -387,33 +387,31 @@ void EMSESP::show_device_values(uuid::console::Shell & shell) { // print line for (JsonPair p : json) { std::string key = p.key().c_str(); // this will be fullname and the shortname in brackets - shell.printf(" %s: ", key.c_str()); - JsonVariant data = p.value(); - shell.print(COLOR_BRIGHT_GREEN); - shell.print(data.as()); // extract the shortname from the key, which is in brackets - std::size_t first_bracket = key.find_first_of('('); + std::size_t first_bracket = key.find_last_of('('); std::size_t last_bracket = key.find_last_of(')'); std::string shortname = key.substr(first_bracket + 1, last_bracket - first_bracket - 1); + std::string uom = emsdevice->get_value_uom(key.substr(first_bracket + 1, last_bracket - first_bracket - 1)); - // if there is a uom print it - std::string uom = emsdevice->get_value_uom(shortname); - if (uom == "°C" && EMSESP::system_.fahrenheit()) { - uom = "°F"; - } - if (!uom.empty()) { - shell.print(' '); - shell.print(uom); - } - - shell.print(COLOR_RESET); - shell.println(); + shell.printfln(" %s: %s%s %s%s", key.c_str(), COLOR_BRIGHT_GREEN, p.value().as().c_str(), uom.c_str(), COLOR_RESET); } shell.println(); } } } + + // show any custom entities + if (webCustomEntityService.count_entities() > 0) { + shell.printfln("Custom entities:"); + StaticJsonDocument custom_doc; // use max size + JsonObject custom_output = custom_doc.to(); + webCustomEntityService.show_values(custom_output); + for (JsonPair p : custom_output) { + shell.printfln(" %s: %s%s%s", p.key().c_str(), COLOR_BRIGHT_GREEN, p.value().as().c_str(), COLOR_RESET); + } + shell.println(); + } } // show temperature sensors and Analog sensors From d717b72a9e7474507c85a6d0df2b34ba065b721b Mon Sep 17 00:00:00 2001 From: Proddy Date: Mon, 13 Nov 2023 16:58:20 +0100 Subject: [PATCH 13/14] have its own show_values function --- src/web/WebCustomEntityService.h | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/web/WebCustomEntityService.h b/src/web/WebCustomEntityService.h index 816b1bdb5..1b18e2073 100644 --- a/src/web/WebCustomEntityService.h +++ b/src/web/WebCustomEntityService.h @@ -52,22 +52,23 @@ class WebCustomEntityService : public StatefulService { public: WebCustomEntityService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager); - void begin(); - void publish_single(const CustomEntityItem & entity); - void publish(const bool force = false); - bool command_setvalue(const char * value, const std::string name); - bool get_value_info(JsonObject & output, const char * cmd); - bool get_value(std::shared_ptr telegram); - void fetch(); - void render_value(JsonObject & output, CustomEntityItem entity, const bool useVal = false, const bool web = false); + void begin(); + void publish_single(const CustomEntityItem & entity); + void publish(const bool force = false); + bool command_setvalue(const char * value, const std::string name); + bool get_value_info(JsonObject & output, const char * cmd); + bool get_value(std::shared_ptr telegram); + void fetch(); + void render_value(JsonObject & output, CustomEntityItem entity, const bool useVal = false, const bool web = false, const bool add_uom = false); + void show_values(JsonObject & output); + void generate_value_web(JsonObject & output); + uint8_t count_entities(); uint8_t has_commands(); - void generate_value_web(JsonObject & output); void ha_reset() { ha_registered_ = false; } - private: HttpEndpoint _httpEndpoint; FSPersistence _fsPersistence; From a0f1f51cca4da29064f876cd0e61641c76e63715 Mon Sep 17 00:00:00 2001 From: Proddy Date: Mon, 13 Nov 2023 16:58:32 +0100 Subject: [PATCH 14/14] rename system values -> allvalues --- CHANGELOG_LATEST.md | 4 ++-- src/locale_translations.h | 2 +- src/system.cpp | 8 ++++---- src/system.h | 2 +- src/test/test.cpp | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 64624c549..2bb37d471 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -4,7 +4,7 @@ ## **IMPORTANT! BREAKING CHANGES** -Writeable Text entities have moved from type `sensor` to `text` in Home Assistant to make them also editable within an HA dashboard. Examples are `datetime`, `holidays`, `switchtime`, `vacations`, `maintenancedate`...). You will need to manually remove any old discovery topics from your MQTT broker using an application like MQTT Explorer. +Writeable Text entities have moved from type `sensor` to `text` in Home Assistant to make them also editable within an HA dashboard. Examples are `datetime`, `holidays`, `switchtime`, `vacations`, `maintenancedate`... You will need to manually remove any old discovery topics from your MQTT broker using an application like MQTT Explorer. ## Added @@ -14,7 +14,7 @@ Writeable Text entities have moved from type `sensor` to `text` in Home Assistan - option for `forceheatingoff` [#1262](https://github.com/emsesp/EMS-ESP32/issues/1262) - shower_data MQTT payload contains the timestamp [#1329](https://github.com/emsesp/EMS-ESP32/issues/1329) - HA discovery for writeable text entities [#1337](https://github.com/emsesp/EMS-ESP32/pull/1377) -- Added 'system values' command that dumps all the EMS device values, plus sensors and any custom entities +- Added 'system allvalues' command that dumps all the EMS device values, plus sensors and any custom entities ## Fixed diff --git a/src/locale_translations.h b/src/locale_translations.h index 7df48201e..8b32724b6 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -70,7 +70,7 @@ MAKE_WORD_TRANSLATION(schedule_cmd, "enable schedule item", "Aktiviere Zeitplan" MAKE_WORD_TRANSLATION(entity_cmd, "set custom value on EMS", "Sende eigene Entitäten zu EMS", "verstuur custom waarde naar EMS", "", "wyślij własną wartość na EMS", "", "", "emp üzerinde özel değer ayarla", "imposta valori personalizzati su EMS") // TODO translate MAKE_WORD_TRANSLATION(commands_response, "get response","Hole Antwort","Verzoek om antwoord", "", "", "", "gelen cevap", "") // TODO translate MAKE_WORD_TRANSLATION(coldshot_cmd, "send a cold shot of water", "", "", "", "", "", "", "soğuk su gönder", "") // TODO translate -MAKE_WORD_TRANSLATION(values_cmd, "show all values", "", "", "", "", "", "", "", "") // TODO translate +MAKE_WORD_TRANSLATION(allvalues_cmd, "output all values", "", "", "", "", "", "", "", "") // TODO translate // tags MAKE_WORD_TRANSLATION(tag_boiler_data_ww, "dhw", "WW", "dhw", "VV", "CWU", "dhw", "ecs", "SKS", "dhw") diff --git a/src/system.cpp b/src/system.cpp index f4cd90302..6e2759f7d 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -106,9 +106,9 @@ bool System::command_response(const char * value, const int8_t id, JsonObject & return true; } -// output all the EMS devices and their values, plus the sensors and any custom things -// basically dump everything we know about -bool System::command_values(const char * value, const int8_t id, JsonObject & output) { +// output all the EMS devices and their values, plus the sensors and any custom entities +// not scheduler as these are records with no output data +bool System::command_allvalues(const char * value, const int8_t id, JsonObject & output) { DynamicJsonDocument doc(EMSESP_JSON_SIZE_XXXLARGE); JsonObject device_output; @@ -794,7 +794,7 @@ void System::commands_init() { Command::add(EMSdevice::DeviceType::SYSTEM, F_(info), System::command_info, FL_(system_info_cmd)); Command::add(EMSdevice::DeviceType::SYSTEM, F_(commands), System::command_commands, FL_(commands_cmd)); Command::add(EMSdevice::DeviceType::SYSTEM, F("response"), System::command_response, FL_(commands_response)); - Command::add(EMSdevice::DeviceType::SYSTEM, F_(values), System::command_values, FL_(values_cmd)); + Command::add(EMSdevice::DeviceType::SYSTEM, F("allvalues"), System::command_allvalues, FL_(allvalues_cmd)); // MQTT subscribe "ems-esp/system/#" diff --git a/src/system.h b/src/system.h index d4826bb60..d75dd247d 100644 --- a/src/system.h +++ b/src/system.h @@ -60,7 +60,7 @@ class System { static bool command_info(const char * value, const int8_t id, JsonObject & output); static bool command_commands(const char * value, const int8_t id, JsonObject & output); static bool command_response(const char * value, const int8_t id, JsonObject & output); - static bool command_values(const char * value, const int8_t id, JsonObject & output); + static bool command_allvalues(const char * value, const int8_t id, JsonObject & output); #if defined(EMSESP_TEST) static bool command_test(const char * value, const int8_t id); diff --git a/src/test/test.cpp b/src/test/test.cpp index 51427919f..f993854a2 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -284,7 +284,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const // shell.invoke_command("show devices"); shell.invoke_command("show values"); - shell.invoke_command("call system values"); + shell.invoke_command("call system allvalues"); // shell.invoke_command("call system publish"); // shell.invoke_command("show mqtt"); ok = true;