From d85c1dc8e8441115b014edf7a19fe0802f1172ae Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 18 May 2026 07:40:02 +0200 Subject: [PATCH 1/4] telegram buffers --- src/core/telegram.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/core/telegram.cpp b/src/core/telegram.cpp index 46f0cdd30..4052dd061 100644 --- a/src/core/telegram.cpp +++ b/src/core/telegram.cpp @@ -403,7 +403,7 @@ void TxService::send_telegram(const QueuedTxTelegram & tx_telegram) { } LOG_DEBUG("Sending %s Tx [#%d], telegram: %s", - (telegram->operation != Telegram::Operation::TX_READ) ? ("write") : ("read"), + (telegram->operation != Telegram::Operation::TX_READ) ? "write" : "read", tx_telegram.id_, Helpers::data_to_hex(telegram_raw, length - 1).c_str()); // exclude the last CRC byte @@ -573,11 +573,10 @@ bool TxService::send_raw(const char * telegram_data) { } // since the telegram data is a const, make a copy. add 1 to grab the \0 EOS - char telegram[strlen(telegram_data) + 1]; - strlcpy(telegram, telegram_data, sizeof(telegram)); + char * telegram = strdup(telegram_data); uint8_t count = 0; - uint8_t data[2 + strlen(telegram) / 3]; + uint8_t data[256]; // get values char * p = strtok(telegram, " ,"); // delimiter @@ -585,7 +584,7 @@ bool TxService::send_raw(const char * telegram_data) { data[count++] = (uint8_t)strtol(p, 0, 16); p = strtok(nullptr, " ,"); } - + free(telegram); // check valid length if (count < 4) { return false; @@ -628,7 +627,7 @@ void TxService::retry_tx(const uint8_t operation, const uint8_t * data, const ui } LOG_DEBUG("Last Tx %s operation failed. Retry #%d. sent message: %s, received: %s", - (operation == Telegram::Operation::TX_WRITE) ? ("Write") : ("Read"), + (operation == Telegram::Operation::TX_WRITE) ? "Write" : "Read", retry_count_, telegram_last_->to_string().c_str(), Helpers::data_to_hex(data, length - 1).c_str()); From 31166794dd7c97e4bc592a7005ac0b2f9577a148 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 24 May 2026 16:54:04 +0200 Subject: [PATCH 2/4] network fallback, fixes #3090 --- CHANGELOG_LATEST.md | 1 + platformio.ini | 2 +- src/core/network.cpp | 39 ++++++++++++++++++--------------------- src/core/network.h | 5 +++-- src/emsesp_version.h | 2 +- 5 files changed, 24 insertions(+), 25 deletions(-) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 07a443148..0d5d853d2 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -45,3 +45,4 @@ For more details go to [emsesp.org](https://emsesp.org/). - refactored network code into a single class [#3052](https://github.com/emsesp/EMS-ESP32/pull/3052) - check and read 0x470 as summer2_typeids[0] only if received [#2686](https://github.com/emsesp/EMS-ESP32/issues/2686), [#3055](https://github.com/emsesp/EMS-ESP32/issues/3055) - default bus-id: gateway1(0x49), tx-mode: auto +- network fallback to AP only after start [#3090](https://github.com/emsesp/EMS-ESP32/issues/3090) \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index d526fbd8c..92fcddb7d 100644 --- a/platformio.ini +++ b/platformio.ini @@ -93,7 +93,7 @@ lib_deps = bblanchon/ArduinoJson @ 7.4.3 ESP32Async/AsyncTCP @ 3.4.10 ESP32Async/ESPAsyncWebServer @ 3.11.0 - https://github.com/mobizt/ReadyMail.git @ 0.4.0 + https://github.com/mobizt/ReadyMail.git @ 0.4.2 https://github.com/mobizt/ESP_SSLClient.git @ 3.1.3 ; https://github.com/emsesp/EMS-ESP-Modules.git @ 1.0.8 diff --git a/src/core/network.cpp b/src/core/network.cpp index 210800c97..9dd23fbc9 100644 --- a/src/core/network.cpp +++ b/src/core/network.cpp @@ -82,7 +82,8 @@ void Network::begin() { WiFi.persistent(false); WiFi.setAutoReconnect(false); WiFi.mode(WIFI_STA); - WiFi.disconnect(true); // wipe old settings in NVS + WiFi.disconnect(true, true); // wipe old settings in NVS + WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN); WiFi.setHostname(hostname_.c_str()); // updates shared default_hostname buffer WiFi.enableSTA(true); // creates the STA netif WiFi.STA.setHostname(hostname_.c_str()); // pushes to esp_netif_set_hostname @@ -235,7 +236,6 @@ void Network::reconnect() { last_disconnect_reason_ = 0; connect_retry_ = 0; reconnect_count_ = 0; - phase_ = NetPhase::ETHERNET; // begin() will refine this once settings are reloaded // reload the network settings and apply them begin(); @@ -304,23 +304,15 @@ void Network::checkConnection() { } if (!still_up) { - if (network_iface_ == NetIface::WIFI) { - uint8_t reason = last_disconnect_reason_; - if (reason == 0) { - reason = WIFI_REASON_UNSPECIFIED; // event hasn't fired yet (or was cleared); avoid logging "0" - } - LOG_INFO("WiFi connection lost (reason %u: %s)", reason, disconnectReason(reason)); - wifi_connect_pending_ = false; - } else if (network_iface_ == NetIface::ETHERNET) { - LOG_INFO("Ethernet connection lost"); - ethernet_connect_pending_ = false; - } juststopped_ = true; - network_iface_ = NetIface::NONE; network_ip_ = 0; has_ipv6_ = false; connect_retry_ = 0; - phase_ = initialPhase(); + if (network_iface_ == NetIface::ETHERNET) { + LOG_WARNING("Ethernet connection lost"); + return; + } + begin(); } #endif } @@ -659,7 +651,9 @@ void Network::findNetworks() { } else if (network_iface_ == NetIface::AP) { phase_ = NetPhase::AP; } - + if (network_iface_ == NetIface::ETHERNET && network_ip_ != 0) { + ethernet_ever_connected_ = true; + } LOG_INFO("Network connected via %s (IP: " IPSTR ")", network_iface_ == NetIface::ETHERNET ? "Ethernet" : network_iface_ == NetIface::WIFI ? "WiFi" @@ -705,18 +699,21 @@ void Network::findNetworks() { if (connect_retry_ >= MAX_NETWORK_RECONNECTION_ATTEMPTS && phase_ != NetPhase::AP) { if (phase_ == NetPhase::ETHERNET) { if (ssid_.isEmpty()) { - LOG_WARNING("Ethernet failed to connect after %u attempts, falling back to AP", connect_retry_); - phase_ = NetPhase::AP; + if (!ethernet_ever_connected_) { + LOG_WARNING("Ethernet failed to connect after %u attempts, falling back to AP", connect_retry_); + phase_ = NetPhase::AP; + } } else { LOG_WARNING("Ethernet failed to connect after %u attempts, switching to WiFi", connect_retry_); phase_ = NetPhase::WIFI; } ethernet_connect_pending_ = false; } else if (phase_ == NetPhase::WIFI) { - LOG_WARNING("WiFi failed to connect after %u attempts, falling back to AP", connect_retry_); - phase_ = NetPhase::AP; + if (!wifi_ever_connected_) { + LOG_WARNING("WiFi failed to connect after %u attempts, falling back to AP", connect_retry_); + phase_ = NetPhase::AP; + } wifi_connect_pending_ = false; - WiFi.disconnect(true); } connect_retry_ = 0; } diff --git a/src/core/network.h b/src/core/network.h index abfe3750d..92da60be3 100644 --- a/src/core/network.h +++ b/src/core/network.h @@ -204,8 +204,9 @@ class Network { NetPhase phase_ = NetPhase::ETHERNET; - bool wifi_events_registered_ = false; // ensure WiFi.onEvent() handlers are registered only once across begin()/reconnect() cycles - bool wifi_ever_connected_ = false; // set true once we've successfully obtained an IP + bool wifi_events_registered_ = false; // ensure WiFi.onEvent() handlers are registered only once across begin()/reconnect() cycles + bool wifi_ever_connected_ = false; // set true once we've successfully obtained an IP + bool ethernet_ever_connected_ = false; // set true once we've successfully obtained an IP // Network and AP settings bool enableMDNS_; diff --git a/src/emsesp_version.h b/src/emsesp_version.h index be3d8d15d..4750696f3 100644 --- a/src/emsesp_version.h +++ b/src/emsesp_version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.9.0-dev.8" +#define EMSESP_APP_VERSION "3.9.0-dev.9" From 04934c6bcaeed8016f8c2f6538b319b72820eaf2 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 25 May 2026 08:59:09 +0200 Subject: [PATCH 3/4] remove trailing comma --- src/core/device_library.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/device_library.h b/src/core/device_library.h index 00dceb6fd..486b91521 100644 --- a/src/core/device_library.h +++ b/src/core/device_library.h @@ -189,7 +189,7 @@ // Gateways - 0x48 {17, DeviceType::GATEWAY, "MX400", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x48, 0x4B, or 0x50 as wireless base {189, DeviceType::GATEWAY, "KM200, MB LAN 2", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x48 -{222, DeviceType::GATEWAY, "KM300,", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x4A +{222, DeviceType::GATEWAY, "KM300", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x4A {252, DeviceType::GATEWAY, "K30RF, MX300", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // Generic - 0x40 or other with no product-id and no version From ba7d9b33d862eaf7b0a6b4f025e66d77d446e902 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 25 May 2026 08:59:37 +0200 Subject: [PATCH 4/4] allow E32 gateway to connect eth --- src/core/network.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/core/network.cpp b/src/core/network.cpp index cfefacad3..423b1d11e 100644 --- a/src/core/network.cpp +++ b/src/core/network.cpp @@ -535,12 +535,6 @@ void Network::startEthernet() { return; } - // disabled Ethernet for boards with only 4MB flash and no PSRAM - if (ESP.getFlashChipSize() < 4194304 && !ESP.getPsramSize()) { // 4MB - LOG_NOTICE("Ethernet disabled for boards with only 4MB flash"); - return; - } - // reset power and add a delay as ETH doesn't not always start up correctly after a warm boot if (eth_power_ != -1) { pinMode(eth_power_, OUTPUT); @@ -649,7 +643,7 @@ void Network::findNetworks() { } else if (network_iface_ == NetIface::AP) { phase_ = NetPhase::AP; } - if (network_iface_ == NetIface::ETHERNET && network_ip_ != 0) { + if (!ethernet_ever_connected && ethernet_connected()) { ethernet_ever_connected_ = true; } LOG_INFO("Network connected via %s (IP: " IPSTR ")",