From 3ff3e8a8cf9a415d8e1d0dca5b9d6956341355ba Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 21 Jun 2024 11:03:33 +0200 Subject: [PATCH] system commands case independend, logic checks, small fixes --- interface/src/i18n/de/index.ts | 2 +- src/command.cpp | 5 ++--- src/system.cpp | 25 ++++++++++++++++++++----- src/web/shuntingYard.hpp | 17 ++++++++++++++--- 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/interface/src/i18n/de/index.ts b/interface/src/i18n/de/index.ts index d59f7e195..7d2206ee4 100644 --- a/interface/src/i18n/de/index.ts +++ b/interface/src/i18n/de/index.ts @@ -121,7 +121,7 @@ const de: Translation = { READONLY: 'Nur-Lese-Modus aktivieren (blockiert alle ausgehenden EMS Tx Write-Befehle)', UNDERCLOCK_CPU: 'CPU-Geschwindigkeit untertakten', REMOTE_TIMEOUT: 'Timeout', - REMOTE_TIMEOUT_EN: 'Deaktitiere Remote bei fehender Temperatur', + REMOTE_TIMEOUT_EN: 'Deaktitiere Remote bei fehlender Temperatur', HEATINGOFF: 'Heizen ausschalten beim EMS-ESP Start', MIN_DURATION: 'Dauer bis die Dusche erkannt wrid', ENABLE_SHOWER_TIMER: 'Duschtimer aktivieren', diff --git a/src/command.cpp b/src/command.cpp index fbd132a8f..afdbdaa8d 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -320,8 +320,7 @@ uint8_t Command::call(const uint8_t device_type, const char * cmd, const char * // for example info, values, commands, etc bool single_command = (!value || !strlen(value)); if (single_command) { - // exception 1: anything that is from System - // exception 2: boiler coldshot command + // exception: boiler coldshot command bool get_attributes = (!cf || !cf->cmdfunction_json_) && (strcmp(cmd, F_(coldshot)) != 0); if (get_attributes) { @@ -444,7 +443,7 @@ void Command::erase_device_commands(const uint8_t device_type) { auto it = cmdfunctions_.end(); do { int i = it - cmdfunctions_.begin(); - if (cmdfunctions_[i].device_type_==device_type) { + if (cmdfunctions_[i].device_type_ == device_type) { cmdfunctions_.erase(it); } } while (it-- > cmdfunctions_.begin()); diff --git a/src/system.cpp b/src/system.cpp index d01ea90e0..9ee69cb31 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -1290,10 +1290,25 @@ bool System::get_value_info(JsonObject root, const char * command) { } if (command_info("", 0, root)) { std::string s; - if (dash && root[cmd].containsKey(dash)) { - s = root[cmd][dash].as(); - } else if (root.containsKey(cmd)) { - s = root[cmd].as(); + // Loop through all the key-value pairs in root to find the key case independent + if (dash) { // search the nest first + for (JsonPair p : root) { + if (p.value().is() && Helpers::toLower(p.key().c_str()) == cmd) { + for (JsonPair p1 : p.value().as()) { + if (Helpers::toLower(p1.key().c_str()) == dash && !p1.value().is()) { + s = p1.value().as(); + break; + } + } + } + } + } else { + for (JsonPair p : root) { + if (Helpers::toLower(p.key().c_str()) == cmd && !p.value().is()) { + s = p.value().as(); + break; + } + } } if (!s.empty()) { root.clear(); @@ -1306,7 +1321,7 @@ bool System::get_value_info(JsonObject root, const char * command) { } } root.clear(); - LOG_ERROR("system command not found: %s from %s", cmd, command); + LOG_ERROR("system command '%s' not found", command); return false; } diff --git a/src/web/shuntingYard.hpp b/src/web/shuntingYard.hpp index 10e2fa08e..0db7cf897 100644 --- a/src/web/shuntingYard.hpp +++ b/src/web/shuntingYard.hpp @@ -56,6 +56,7 @@ class Token { const bool rightAssociative; }; +// find tokens std::deque exprToTokens(const std::string & expr) { std::deque tokens; @@ -204,7 +205,7 @@ std::deque exprToTokens(const std::string & expr) { return tokens; } - +// sort tokens to RPN form std::deque shuntingYard(const std::deque & tokens) { std::deque queue; std::vector stack; @@ -303,6 +304,7 @@ std::deque shuntingYard(const std::deque & tokens) { return queue; } +// check if string is a number bool isnum(const std::string & s) { if (s.find_first_not_of("0123456789.") == std::string::npos || (s[0] == '-' && s.find_first_not_of("0123456789.", 1) == std::string::npos)) { return true; @@ -356,6 +358,7 @@ std::string commands(std::string & expr) { return expr; } +// checks for logic value int to_logic(const std::string & s) { if (s[0] == '1' || s == "on" || s == "ON" || s == "true") { return 1; @@ -363,9 +366,10 @@ int to_logic(const std::string & s) { if (s[0] == '0' || s == "off" || s == "OFF" || s == "false") { return 0; } - return 0; + return -1; } +// number to string std::string to_string(double d) { if (d == static_cast(d)) { return std::to_string(static_cast(d)); @@ -373,8 +377,9 @@ std::string to_string(double d) { return std::to_string(d); } +// RPN calculator std::string compute(const std::string & expr) { - auto expr_new = expr; //emsesp::Helpers::toLower(expr); + auto expr_new = emsesp::Helpers::toLower(expr); // emsesp::EMSESP::logger().info("calculate: %s", expr_new.c_str()); commands(expr_new); // emsesp::EMSESP::logger().info("calculate: %s", expr_new.c_str()); @@ -413,6 +418,9 @@ std::string compute(const std::string & expr) { stack.push_back(to_string(-1 * std::stod(rhs))); break; case '!': + if (to_logic(rhs) < 0) { + return ""; + } stack.push_back(to_logic(rhs) == 0 ? "1" : "0"); break; } @@ -483,6 +491,9 @@ std::string compute(const std::string & expr) { stack.pop_back(); const auto lhs = to_logic(stack.back()); stack.pop_back(); + if (rhs < 0 || lhs < 0) { + return ""; + } switch (token.str[0]) { default: return "";