system commands case independend, logic checks, small fixes

This commit is contained in:
MichaelDvP
2024-06-21 11:03:33 +02:00
parent fb8deb41f9
commit 3ff3e8a8cf
4 changed files with 37 additions and 12 deletions

View File

@@ -121,7 +121,7 @@ const de: Translation = {
READONLY: 'Nur-Lese-Modus aktivieren (blockiert alle ausgehenden EMS Tx Write-Befehle)', READONLY: 'Nur-Lese-Modus aktivieren (blockiert alle ausgehenden EMS Tx Write-Befehle)',
UNDERCLOCK_CPU: 'CPU-Geschwindigkeit untertakten', UNDERCLOCK_CPU: 'CPU-Geschwindigkeit untertakten',
REMOTE_TIMEOUT: 'Timeout', 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', HEATINGOFF: 'Heizen ausschalten beim EMS-ESP Start',
MIN_DURATION: 'Dauer bis die Dusche erkannt wrid', MIN_DURATION: 'Dauer bis die Dusche erkannt wrid',
ENABLE_SHOWER_TIMER: 'Duschtimer aktivieren', ENABLE_SHOWER_TIMER: 'Duschtimer aktivieren',

View File

@@ -320,8 +320,7 @@ uint8_t Command::call(const uint8_t device_type, const char * cmd, const char *
// for example info, values, commands, etc // for example info, values, commands, etc
bool single_command = (!value || !strlen(value)); bool single_command = (!value || !strlen(value));
if (single_command) { if (single_command) {
// exception 1: anything that is from System // exception: boiler coldshot command
// exception 2: boiler coldshot command
bool get_attributes = (!cf || !cf->cmdfunction_json_) && (strcmp(cmd, F_(coldshot)) != 0); bool get_attributes = (!cf || !cf->cmdfunction_json_) && (strcmp(cmd, F_(coldshot)) != 0);
if (get_attributes) { if (get_attributes) {

View File

@@ -1290,10 +1290,25 @@ bool System::get_value_info(JsonObject root, const char * command) {
} }
if (command_info("", 0, root)) { if (command_info("", 0, root)) {
std::string s; std::string s;
if (dash && root[cmd].containsKey(dash)) { // Loop through all the key-value pairs in root to find the key case independent
s = root[cmd][dash].as<std::string>(); if (dash) { // search the nest first
} else if (root.containsKey(cmd)) { for (JsonPair p : root) {
s = root[cmd].as<std::string>(); if (p.value().is<JsonObject>() && Helpers::toLower(p.key().c_str()) == cmd) {
for (JsonPair p1 : p.value().as<JsonObject>()) {
if (Helpers::toLower(p1.key().c_str()) == dash && !p1.value().is<JsonObject>()) {
s = p1.value().as<std::string>();
break;
}
}
}
}
} else {
for (JsonPair p : root) {
if (Helpers::toLower(p.key().c_str()) == cmd && !p.value().is<JsonObject>()) {
s = p.value().as<std::string>();
break;
}
}
} }
if (!s.empty()) { if (!s.empty()) {
root.clear(); root.clear();
@@ -1306,7 +1321,7 @@ bool System::get_value_info(JsonObject root, const char * command) {
} }
} }
root.clear(); root.clear();
LOG_ERROR("system command not found: %s from %s", cmd, command); LOG_ERROR("system command '%s' not found", command);
return false; return false;
} }

View File

@@ -56,6 +56,7 @@ class Token {
const bool rightAssociative; const bool rightAssociative;
}; };
// find tokens
std::deque<Token> exprToTokens(const std::string & expr) { std::deque<Token> exprToTokens(const std::string & expr) {
std::deque<Token> tokens; std::deque<Token> tokens;
@@ -204,7 +205,7 @@ std::deque<Token> exprToTokens(const std::string & expr) {
return tokens; return tokens;
} }
// sort tokens to RPN form
std::deque<Token> shuntingYard(const std::deque<Token> & tokens) { std::deque<Token> shuntingYard(const std::deque<Token> & tokens) {
std::deque<Token> queue; std::deque<Token> queue;
std::vector<Token> stack; std::vector<Token> stack;
@@ -303,6 +304,7 @@ std::deque<Token> shuntingYard(const std::deque<Token> & tokens) {
return queue; return queue;
} }
// check if string is a number
bool isnum(const std::string & s) { 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)) { if (s.find_first_not_of("0123456789.") == std::string::npos || (s[0] == '-' && s.find_first_not_of("0123456789.", 1) == std::string::npos)) {
return true; return true;
@@ -356,6 +358,7 @@ std::string commands(std::string & expr) {
return expr; return expr;
} }
// checks for logic value
int to_logic(const std::string & s) { int to_logic(const std::string & s) {
if (s[0] == '1' || s == "on" || s == "ON" || s == "true") { if (s[0] == '1' || s == "on" || s == "ON" || s == "true") {
return 1; return 1;
@@ -363,9 +366,10 @@ int to_logic(const std::string & s) {
if (s[0] == '0' || s == "off" || s == "OFF" || s == "false") { if (s[0] == '0' || s == "off" || s == "OFF" || s == "false") {
return 0; return 0;
} }
return 0; return -1;
} }
// number to string
std::string to_string(double d) { std::string to_string(double d) {
if (d == static_cast<int>(d)) { if (d == static_cast<int>(d)) {
return std::to_string(static_cast<int>(d)); return std::to_string(static_cast<int>(d));
@@ -373,8 +377,9 @@ std::string to_string(double d) {
return std::to_string(d); return std::to_string(d);
} }
// RPN calculator
std::string compute(const std::string & expr) { 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()); // emsesp::EMSESP::logger().info("calculate: %s", expr_new.c_str());
commands(expr_new); commands(expr_new);
// emsesp::EMSESP::logger().info("calculate: %s", expr_new.c_str()); // 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))); stack.push_back(to_string(-1 * std::stod(rhs)));
break; break;
case '!': case '!':
if (to_logic(rhs) < 0) {
return "";
}
stack.push_back(to_logic(rhs) == 0 ? "1" : "0"); stack.push_back(to_logic(rhs) == 0 ? "1" : "0");
break; break;
} }
@@ -483,6 +491,9 @@ std::string compute(const std::string & expr) {
stack.pop_back(); stack.pop_back();
const auto lhs = to_logic(stack.back()); const auto lhs = to_logic(stack.back());
stack.pop_back(); stack.pop_back();
if (rhs < 0 || lhs < 0) {
return "";
}
switch (token.str[0]) { switch (token.str[0]) {
default: default:
return ""; return "";