From 4d779cd972dadc0d30ef223929fb75d936bd9059 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 17 Oct 2026 13:49:11 +0200 Subject: [PATCH] more tests for #3094 --- src/core/emsesp.cpp | 35 ++++++++++++++++++++++++++++++++++- src/core/emsesp.h | 3 +++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/core/emsesp.cpp b/src/core/emsesp.cpp index 5e5b7db0b..75ef88c52 100644 --- a/src/core/emsesp.cpp +++ b/src/core/emsesp.cpp @@ -57,6 +57,7 @@ uint32_t EMSESP::gateway_window_start_ = 0; uint8_t EMSESP::gateway_window_count_ = 0; uint32_t EMSESP::gateway_fast_start_ = 0; uint8_t EMSESP::gateway_fast_count_ = 0; +uint32_t EMSESP::gateway_last_seen_ = 0; uint8_t EMSESP::last_version_request_src_ = 0; uint32_t EMSESP::last_version_request_time_ = 0; #endif @@ -1598,6 +1599,8 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, const #ifdef EMSESP_GATEWAY_TX_HOLD // a gateway appearing while we're running is most likely starting up and about to sync if (device_id == EMSdevice::EMS_DEVICE_ID_GATEWAY1) { + uint32_t now = uuid::get_uptime(); + gateway_last_seen_ = now ? now : 1; gateway_tx_hold_start(); } #endif @@ -1781,6 +1784,13 @@ void EMSESP::incoming_telegram(uint8_t * data, const uint8_t length) { wait_km_ = false; // KM200 is polled, from now on it is safe to send } +#ifdef EMSESP_GATEWAY_TX_HOLD + // master polling 0x48 again after a gap means the gateway (or heat pump) came back + if (poll_id == EMSdevice::EMS_DEVICE_ID_GATEWAY1) { + gateway_note_activity(); + } +#endif + #ifdef EMSESP_UART_DEBUG char s[4]; if (first_value & 0x80) { @@ -1853,9 +1863,32 @@ void EMSESP::scheduled_fetch_values() { } #ifdef EMSESP_GATEWAY_TX_HOLD +// any poll of or telegram from 0x48 — if it was silent (HP/K30RF restart) re-arm the Tx hold +void EMSESP::gateway_note_activity() { + uint32_t now = uuid::get_uptime(); + if (gateway_last_seen_ && (now - gateway_last_seen_ > GATEWAY_SILENCE_MS)) { + // a real reconnect: allow hold even if we were in the post-max cooldown + gateway_cooldown_until_ = 0; + LOG_INFO("Gateway 0x%02X returned after %lu s silence, holding Tx", + EMSdevice::EMS_DEVICE_ID_GATEWAY1, + (unsigned long)((now - gateway_last_seen_) / 1000)); + if (!gateway_hold_until_) { + gateway_hold_start_ = now; + } + gateway_hold_until_ = (now + GATEWAY_HOLD_TIME) | 1; + } + gateway_last_seen_ = now ? now : 1; // keep 0 as "never seen" +} + // count read requests from the gateway to other devices, a high rate means it's doing its startup sync void EMSESP::gateway_rx_check(const uint8_t * data, const uint8_t length) { - if (length < 4 || (data[0] & 0x7F) != EMSdevice::EMS_DEVICE_ID_GATEWAY1 || !(data[1] & 0x80)) { + if (length < 2 || (data[0] & 0x7F) != EMSdevice::EMS_DEVICE_ID_GATEWAY1) { + return; + } + + gateway_note_activity(); + + if (length < 4 || !(data[1] & 0x80)) { return; } diff --git a/src/core/emsesp.h b/src/core/emsesp.h index 6ffcff21d..f1fd94652 100644 --- a/src/core/emsesp.h +++ b/src/core/emsesp.h @@ -300,6 +300,7 @@ class EMSESP { // hold our Tx while a gateway (K30RF/KM200 on 0x48) is doing its startup sync, see issue #3094 // a startup sync is 55-250 read requests/min to other devices, normal operation is <10/min static void gateway_rx_check(const uint8_t * data, const uint8_t length); + static void gateway_note_activity(); // poll or telegram from 0x48 — re-arm hold if it was silent static bool gateway_tx_hold(); static void gateway_tx_hold_start(); @@ -310,6 +311,7 @@ class EMSESP { static constexpr uint32_t GATEWAY_HOLD_TIME = 60000; // keep holding Tx this long after the last busy window static constexpr uint32_t GATEWAY_HOLD_MAX = 600000; // never hold longer than 10 minutes in one go static constexpr uint32_t GATEWAY_HOLD_COOLDOWN = 600000; // after hitting the max, don't hold again for 10 minutes + static constexpr uint32_t GATEWAY_SILENCE_MS = 60000; // no 0x48 traffic for this long = gone; next sighting re-arms hold static uint32_t gateway_hold_until_; static uint32_t gateway_hold_start_; @@ -318,6 +320,7 @@ class EMSESP { static uint8_t gateway_window_count_; static uint32_t gateway_fast_start_; static uint8_t gateway_fast_count_; + static uint32_t gateway_last_seen_; // last poll or telegram from 0x48 static uint8_t last_version_request_src_; static uint32_t last_version_request_time_; #endif