mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2026-07-28 17:42:45 +00:00
Compare commits
27 Commits
9cb2455af2
...
c55655c0c5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c55655c0c5 | ||
|
|
55a0e4b2b5 | ||
|
|
eceb097cc7 | ||
|
|
0e18645ba5 | ||
|
|
63f49a347b | ||
|
|
943048a920 | ||
|
|
2b8a0bd8b7 | ||
|
|
d83b56a13c | ||
|
|
1f34a41d27 | ||
|
|
343ac5880c | ||
|
|
855edace20 | ||
|
|
aabc4f021c | ||
|
|
0aaa566e73 | ||
|
|
20e3d6a19b | ||
|
|
67953fccd6 | ||
|
|
0c910bc822 | ||
|
|
b6a7fb0bf0 | ||
|
|
95f475ab6f | ||
|
|
f8fa092ac3 | ||
|
|
5aadf7234f | ||
|
|
b8a63aeac6 | ||
|
|
908a9ebbfc | ||
|
|
dbf970d869 | ||
|
|
33602f65f3 | ||
|
|
1ae547a710 | ||
|
|
70cfbd96e2 | ||
|
|
b441fd83dd |
@@ -12,5 +12,11 @@ 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)
|
||||
- prevent system crash during WiFi network discovery on ESP32-S3 hardware [#3128](https://github.com/emsesp/EMS-ESP32/pull/3128)
|
||||
- fix setting date/time on Junkers thermostats
|
||||
|
||||
## 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)
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -88,34 +88,6 @@ def bin_copy(source, target, env):
|
||||
print(f"MD5: {md5_hash}")
|
||||
md5_file.write_text(md5_hash)
|
||||
|
||||
# Make a copy using the old 3.6.x filename format for backwards compatibility
|
||||
# Note: there is a chance newer E32V2s (which use the 16MB partition table and PSRAM)
|
||||
# are running a custom build of the 3.6.5 firmware as 3.6.5 was released before
|
||||
# production of the gateway board. Updating via the WebUI will break the system
|
||||
# and require a manual update.
|
||||
|
||||
pio_env = env.get('PIOENV', '')
|
||||
extra_variant = None
|
||||
|
||||
if pio_env == "s3_16M_P":
|
||||
extra_variant = f"EMS-ESP-{app_version.replace('.', '_')}-ESP32_S3"
|
||||
elif pio_env == "s_4M":
|
||||
extra_variant = f"EMS-ESP-{app_version.replace('.', '_')}-ESP32"
|
||||
|
||||
if extra_variant:
|
||||
extra_bin_file = firmware_dir / f"{extra_variant}.bin"
|
||||
extra_md5_file = firmware_dir / f"{extra_variant}.md5"
|
||||
|
||||
# Remove existing files if they exist
|
||||
for file_path in [extra_bin_file, extra_md5_file]:
|
||||
if file_path.exists():
|
||||
file_path.unlink()
|
||||
|
||||
# Copy files
|
||||
shutil.copy2(str(bin_file), str(extra_bin_file))
|
||||
shutil.copy2(str(md5_file), str(extra_md5_file))
|
||||
print(f"Filename copy for 3.6.x: {extra_bin_file}")
|
||||
|
||||
print("=" * 90)
|
||||
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ void WiFiScanner::scanNetworks(AsyncWebServerRequest * request) {
|
||||
|
||||
if (WiFi.scanComplete() != -1) {
|
||||
WiFi.scanDelete();
|
||||
WiFi.scanNetworks(true);
|
||||
WiFi.scanNetworks(true, false, true, 250);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,10 @@ void WiFiScanner::listNetworks(AsyncWebServerRequest * request) {
|
||||
} else if (numNetworks == -1) {
|
||||
request->send(202); // special code to indicate scan in progress
|
||||
} else {
|
||||
scanNetworks(request);
|
||||
auto * response = new AsyncJsonResponse(false);
|
||||
JsonObject root = response->getRoot();
|
||||
root["networks"].to<JsonArray>();
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,19 +377,23 @@ void Roomctrl::temperature(uint8_t addr, uint8_t dst, uint8_t hc) {
|
||||
|
||||
// send telegram 0x047B only for RC100H
|
||||
void Roomctrl::humidity(uint8_t addr, uint8_t dst, uint8_t hc) {
|
||||
int16_t dew = calc_dew(remotetemp_[hc], remotehum_[hc]);
|
||||
int8_t dew8 = EMS_VALUE_INT8_NOTSET;
|
||||
if (dew != EMS_VALUE_INT16_NOTSET) {
|
||||
dew8 = static_cast<int8_t>((dew >= 0 ? dew + 5 : dew - 5) / 10);
|
||||
}
|
||||
uint8_t data[11];
|
||||
data[0] = addr | EMSbus::ems_mask();
|
||||
data[1] = dst & 0x7F;
|
||||
uint16_t dew = calc_dew(remotetemp_[hc], remotehum_[hc]);
|
||||
data[2] = 0xFF;
|
||||
data[3] = 0;
|
||||
data[4] = 3;
|
||||
data[5] = 0x7B + hc;
|
||||
data[6] = dew == EMS_VALUE_INT16_NOTSET ? EMS_VALUE_INT8_NOTSET : (uint8_t)((dew + 5) / 10);
|
||||
data[7] = remotehum_[hc];
|
||||
data[8] = (uint8_t)(dew << 8);
|
||||
data[9] = (uint8_t)(dew & 0xFF);
|
||||
data[10] = EMSbus::calculate_crc(data, 10); // append CRC
|
||||
data[0] = addr | EMSbus::ems_mask();
|
||||
data[1] = dst & 0x7F;
|
||||
data[2] = 0xFF;
|
||||
data[3] = 0;
|
||||
data[4] = 3;
|
||||
data[5] = 0x7B + hc;
|
||||
data[6] = static_cast<uint8_t>(dew8);
|
||||
data[7] = remotehum_[hc];
|
||||
data[8] = static_cast<uint8_t>(static_cast<uint16_t>(dew) >> 8);
|
||||
data[9] = static_cast<uint8_t>(static_cast<uint16_t>(dew) & 0xFF);
|
||||
data[10] = EMSbus::calculate_crc(data, 10); // append CRC
|
||||
EMSuart::transmit(data, 11);
|
||||
}
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -333,7 +333,10 @@ std::deque<Token> shuntingYard(const std::deque<Token> & 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]) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -810,16 +810,15 @@ void Thermostat::process_RemoteTemp(std::shared_ptr<const Telegram> telegram) {
|
||||
// e.g. "38 10 FF 00 03 7B 08 24 00 4B"
|
||||
void Thermostat::process_RemoteHumidity(std::shared_ptr<const Telegram> 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_));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3071,7 +3070,6 @@ bool Thermostat::set_datetime(const char * value, const int8_t id) {
|
||||
data[6] = (tm_->tm_wday + 6) % 7; // Bosch counts from Mo, time from Su
|
||||
data[7] = (id == 0) ? 2 : tm_->tm_isdst + 2; // set DST and flag for ext. clock
|
||||
if (model() == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) {
|
||||
data[6]++; // Junkers use 1-7;
|
||||
data[7] = 0;
|
||||
}
|
||||
} else if (dt.length() == 23) {
|
||||
@@ -3095,6 +3093,10 @@ bool Thermostat::set_datetime(const char * value, const int8_t id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (model() == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) {
|
||||
data[6]++; // Junkers use 1-7 for day of the week
|
||||
}
|
||||
|
||||
// LOG_INFO("Setting date and time: %02d.%02d.2%03d-%02d:%02d:%02d-%d-%d", data[3], data[1], data[0], data[2], data[4], data[5], data[6], data[7]);
|
||||
write_command(EMS_TYPE_time, 0, data, 8, EMS_TYPE_time);
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define EMSESP_APP_VERSION "3.8.3-dev.5"
|
||||
#define EMSESP_APP_VERSION "3.8.3-dev.8"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -89,9 +89,7 @@ class WebSchedulerService : public StatefulService<WebScheduler> {
|
||||
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();
|
||||
|
||||
Reference in New Issue
Block a user