diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 5cf6be35d..f47f825d9 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -12,6 +12,10 @@ For more details go to [emsesp.org](https://emsesp.org/). - signed value for solarInfuence [#3077](https://github.com/emsesp/EMS-ESP32/issues/3077) - set bin file upload limit to 1M again [3086](https://github.com/emsesp/EMS-ESP32/issues/3086) +- check arithmetric operations on strings [#3127](https://github.com/emsesp/EMS-ESP32/discussions/3127) - Fix: Prevent system crash during WiFi network discovery on ESP32-S3 hardware [#3128](https://github.com/emsesp/EMS-ESP32/pull/3128) ## Changed + +- call compute value direct, enlarge TCP stack [#3127](https://github.com/emsesp/EMS-ESP32/discussions/3127) +- Dewtemperature for Easycontrol calculated by ems-esp [3135](https://github.com/emsesp/EMS-ESP32/issues/3135) diff --git a/mock-api/restServer.ts b/mock-api/restServer.ts index 1e3a7afae..355d4ae9b 100644 --- a/mock-api/restServer.ts +++ b/mock-api/restServer.ts @@ -4139,7 +4139,7 @@ let emsesp_schedule = { id: 5, active: false, flags: 130, - time: 'system/network info/rssi < -70', + time: 'system/network/rssi < -70', cmd: 'system/restart', value: '', name: 'bad_wifi' diff --git a/platformio.ini b/platformio.ini index 241af2c71..40e5057ef 100644 --- a/platformio.ini +++ b/platformio.ini @@ -39,7 +39,7 @@ build_flags = -D CONFIG_ASYNC_TCP_PRIORITY=10 ; default -D CONFIG_ASYNC_TCP_QUEUE_SIZE=64 ; default -D CONFIG_ASYNC_TCP_RUNNING_CORE=1 ; force async_tcp task to be on same core as Arduino app (default is any core) - -D CONFIG_ASYNC_TCP_STACK_SIZE=6144 ; default is 16KB/8192*2 + -D CONFIG_ASYNC_TCP_STACK_SIZE=8192 ; default is 16KB/8192*2 ; ESPAsyncWebServer ; -D WS_MAX_QUEUED_MESSAGES=0 ; not used, default 8 ; -D SSE_MAX_QUEUED_MESSAGES=1 ; for log messages, default 32 diff --git a/src/core/roomcontrol.h b/src/core/roomcontrol.h index 5b361cfe3..2bc61c1e5 100644 --- a/src/core/roomcontrol.h +++ b/src/core/roomcontrol.h @@ -34,7 +34,8 @@ class Roomctrl { static bool is_remote(const uint8_t hc) { return (hc < 4 && remotetemp_[hc] != EMS_VALUE_INT16_NOTSET); } - static void set_timeout(uint8_t t); + static void set_timeout(uint8_t t); + static int16_t calc_dew(int16_t temp, uint8_t hum); private: static constexpr uint32_t SEND_INTERVAL = 15000; // 15 sec @@ -50,7 +51,6 @@ class Roomctrl { static void nack_write(); static void ack_write(); static void replyF7(uint8_t addr, uint8_t dst, uint8_t offset, uint8_t typehh, uint8_t typeh, uint8_t typel, uint8_t hc); - static int16_t calc_dew(int16_t temp, uint8_t hum); static bool switch_off_[HCS]; static uint32_t send_time_[HCS]; diff --git a/src/core/shuntingYard.cpp b/src/core/shuntingYard.cpp index 0e8da02c2..fd51bbf5e 100644 --- a/src/core/shuntingYard.cpp +++ b/src/core/shuntingYard.cpp @@ -333,7 +333,10 @@ std::deque shuntingYard(const std::deque & tokens) { // check if string is a number bool isnum(const std::string & s) { - if (!s.empty() && (s.find_first_not_of("0123456789.") == std::string::npos || (s[0] == '-' && s.find_first_not_of("0123456789.", 1) == std::string::npos))) { + if (s.empty() || s.find_first_of("0123456789") == std::string::npos) { + return false; + } + 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 false; @@ -636,6 +639,10 @@ std::string calculate(const std::string & expr) { stack.push_back(lhs + rhs); break; } + if (!isnum(rhs) || !isnum(lhs)) { + stack.push_back(lhs + token.str + rhs); + break; + } auto lhd = std::stod(lhs); auto rhd = std::stod(rhs); switch (token.str[0]) { diff --git a/src/core/system.cpp b/src/core/system.cpp index f27ba427a..6cd6a6680 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -222,22 +222,10 @@ bool System::command_message(const char * value, const int8_t id, JsonObject out LOG_WARNING("Message is empty"); return false; // must have a string value } - - EMSESP::webSchedulerService.computed_value.clear(); - EMSESP::webSchedulerService.raw_value = value; - for (uint16_t wait = 0; wait < 2000 && !EMSESP::webSchedulerService.raw_value.empty(); wait++) { - delay(1); - } - - if (EMSESP::webSchedulerService.computed_value.empty()) { - LOG_WARNING("Message result is empty"); - return false; - } - - LOG_INFO("Message: %s", EMSESP::webSchedulerService.computed_value.c_str()); // send to log - Mqtt::queue_publish(F_(message), EMSESP::webSchedulerService.computed_value); // send to MQTT if enabled - output["api_data"] = EMSESP::webSchedulerService.computed_value; // send to API - + std::string computed_value = EMSESP::webSchedulerService.compute_value(value); + LOG_INFO("Message: %s", computed_value.c_str()); // send to log + Mqtt::queue_publish(F_(message), computed_value); // send to MQTT if enabled + output["api_data"] = computed_value; // send to API return true; } diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index eb9b2ef01..8f5441cc3 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -810,16 +810,15 @@ void Thermostat::process_RemoteTemp(std::shared_ptr telegram) { // e.g. "38 10 FF 00 03 7B 08 24 00 4B" void Thermostat::process_RemoteHumidity(std::shared_ptr telegram) { // has_update(telegram, dewtemperature_, 0); // this is int8 - has_update(telegram, humidity_, 1); - has_update(telegram, dewtemperature_, 2); // this is int16 // some thermostats use short telegram with int8 dewpoint, https://github.com/emsesp/EMS-ESP32/issues/1491 - if (telegram->offset == 0 && telegram->message_length < 4) { - int8_t dew = dewtemperature_ / 10; - telegram->read_value(dew, 0); - if (dew != EMS_VALUE_INT8_NOTSET && dewtemperature_ != dew * 10) { - dewtemperature_ = dew * 10; - has_update(dewtemperature_); - } + // but it's not a dewpoint in offset 0, removed, see https://github.com/emsesp/EMS-ESP32/issues/3135 + has_update(telegram, humidity_, 1); + // has_update(telegram, dewtemperature_, 2); // this is int16 + int16_t dew = EMS_VALUE_INT16_NOTSET; + if (telegram->read_value(dew, 2)) { + has_update(dewtemperature_, dew); + } else if (telegram->offset == 0 && telegram->message_length < 4) { + has_update(dewtemperature_, Roomctrl::calc_dew(tempsensor1_, humidity_)); } } diff --git a/src/emsesp_version.h b/src/emsesp_version.h index 340c555c0..74e1e397b 100644 --- a/src/emsesp_version.h +++ b/src/emsesp_version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.8.3-dev.6" +#define EMSESP_APP_VERSION "3.8.3-dev.7" diff --git a/src/web/WebSchedulerService.cpp b/src/web/WebSchedulerService.cpp index 4bb53c3bd..45d6354c6 100644 --- a/src/web/WebSchedulerService.cpp +++ b/src/web/WebSchedulerService.cpp @@ -472,6 +472,10 @@ void WebSchedulerService::condition() { } } +std::string WebSchedulerService::compute_value(const char * value) { + return compute(value); +} + // process any scheduled jobs void WebSchedulerService::loop() { // initialize static value on startup @@ -479,11 +483,6 @@ void WebSchedulerService::loop() { static uint32_t last_uptime_min = 0; static uint32_t last_uptime_sec = 0; - if (!raw_value.empty()) { // process a value from system/message command - computed_value = compute(raw_value); - raw_value.clear(); - } - // get list of scheduler events and exit if it's empty if (scheduleItems_->empty()) { return; diff --git a/src/web/WebSchedulerService.h b/src/web/WebSchedulerService.h index 0d1ad2fa6..fabfd44bd 100644 --- a/src/web/WebSchedulerService.h +++ b/src/web/WebSchedulerService.h @@ -89,9 +89,7 @@ class WebSchedulerService : public StatefulService { bool onChange(const char * cmd); std::string get_metrics_prometheus(); - - std::string raw_value; - std::string computed_value; + std::string compute_value(const char * value); #if defined(EMSESP_TEST) void load_test_data();