From b95873169ea1d4ff0dc1bc2d12d47d930f58d1aa Mon Sep 17 00:00:00 2001 From: proddy Date: Tue, 20 Oct 2026 12:38:44 +0200 Subject: [PATCH] more EMSESP_GATEWAY_TX_HOLD tests --- src/core/emsesp.cpp | 52 ++++++++++++++++++++++----------------------- src/core/emsesp.h | 9 ++++---- 2 files changed, 30 insertions(+), 31 deletions(-) diff --git a/src/core/emsesp.cpp b/src/core/emsesp.cpp index 75ef88c52..50615226d 100644 --- a/src/core/emsesp.cpp +++ b/src/core/emsesp.cpp @@ -52,7 +52,7 @@ uint32_t EMSESP::last_fetch_ = 0; #ifdef EMSESP_GATEWAY_TX_HOLD uint32_t EMSESP::gateway_hold_until_ = 0; uint32_t EMSESP::gateway_hold_start_ = 0; -uint32_t EMSESP::gateway_cooldown_until_ = 0; +uint32_t EMSESP::gateway_hold_max_log_ = 0; uint32_t EMSESP::gateway_window_start_ = 0; uint8_t EMSESP::gateway_window_count_ = 0; uint32_t EMSESP::gateway_fast_start_ = 0; @@ -1803,9 +1803,12 @@ void EMSESP::incoming_telegram(uint8_t * data, const uint8_t length) { #endif // check for poll to us, if so send top message from Tx queue immediately and quit #ifdef EMSESP_GATEWAY_TX_HOLD - if (poll_id == EMSbus::ems_bus_id() && gateway_tx_hold()) { - // still ack the poll, otherwise the master drops us from 0x07 and the gateway sees the device list change - txservice_.send_poll(); + // while the gateway is syncing, don't Tx anything (including Roomctrl) β€” only ack our own poll + // so the master keeps us in 0x07 and the gateway doesn't see the device list change + if (gateway_tx_hold()) { + if (poll_id == EMSbus::ems_bus_id()) { + txservice_.send_poll(); + } return; } #endif @@ -1867,13 +1870,10 @@ void EMSESP::scheduled_fetch_values() { 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)); + 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_start_ = now; + gateway_hold_max_log_ = 0; } gateway_hold_until_ = (now + GATEWAY_HOLD_TIME) | 1; } @@ -1921,16 +1921,10 @@ void EMSESP::gateway_rx_check(const uint8_t * data, const uint8_t length) { void EMSESP::gateway_tx_hold_start() { uint32_t now = uuid::get_uptime(); - if (gateway_cooldown_until_) { - if ((int32_t)(now - gateway_cooldown_until_) < 0) { - return; - } - - gateway_cooldown_until_ = 0; - } if (!gateway_hold_until_) { - gateway_hold_start_ = now; + gateway_hold_start_ = now; + gateway_hold_max_log_ = 0; LOG_INFO("Gateway 0x%02X is busy, holding Tx", EMSdevice::EMS_DEVICE_ID_GATEWAY1); } @@ -1943,17 +1937,23 @@ bool EMSESP::gateway_tx_hold() { } uint32_t now = uuid::get_uptime(); - if (now - gateway_hold_start_ > GATEWAY_HOLD_MAX) { - gateway_hold_until_ = 0; - gateway_cooldown_until_ = (now + GATEWAY_HOLD_COOLDOWN) | 1; - LOG_WARNING("Gateway 0x%02X still busy after %lu s, resuming Tx", EMSdevice::EMS_DEVICE_ID_GATEWAY1, (unsigned long)(GATEWAY_HOLD_MAX / 1000)); + + // only resume when the gateway has been quiet for GATEWAY_HOLD_TIME β€” never force-resume + // while bursts keep extending the hold (that 10‑min flap prolonged A21 storm on #3094) + if ((int32_t)(now - gateway_hold_until_) >= 0) { + uint32_t held_s = (now - gateway_hold_start_) / 1000; + gateway_hold_until_ = 0; + gateway_hold_max_log_ = 0; + LOG_INFO("Gateway 0x%02X is quiet, resuming Tx after %lu s", EMSdevice::EMS_DEVICE_ID_GATEWAY1, (unsigned long)held_s); return false; } - if ((int32_t)(now - gateway_hold_until_) >= 0) { - gateway_hold_until_ = 0; - LOG_INFO("Gateway 0x%02X is quiet, resuming Tx after %lu s", EMSdevice::EMS_DEVICE_ID_GATEWAY1, (unsigned long)((now - gateway_hold_start_) / 1000)); - return false; + // still busy past HOLD_MAX β€” stay muted, just log periodically + if (now - gateway_hold_start_ > GATEWAY_HOLD_MAX && (!gateway_hold_max_log_ || now - gateway_hold_max_log_ > GATEWAY_HOLD_MAX)) { + gateway_hold_max_log_ = now; + LOG_WARNING("Gateway 0x%02X still busy after %lu s, continuing to hold Tx", + EMSdevice::EMS_DEVICE_ID_GATEWAY1, + (unsigned long)((now - gateway_hold_start_) / 1000)); } return true; diff --git a/src/core/emsesp.h b/src/core/emsesp.h index f1fd94652..9ee532eee 100644 --- a/src/core/emsesp.h +++ b/src/core/emsesp.h @@ -308,14 +308,13 @@ class EMSESP { static constexpr uint8_t GATEWAY_BURST_THRESHOLD = 15; // read requests within window to treat gateway as busy static constexpr uint32_t GATEWAY_FAST_WINDOW = 5000; // short window to catch the start of a burst quickly static constexpr uint8_t GATEWAY_FAST_THRESHOLD = 8; // normal polling is ~1 read per 2s, a sync starts at >10/s - 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 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; // log every 10 minutes while still busy; do not force-resume (see #3094) + 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_; - static uint32_t gateway_cooldown_until_; + static uint32_t gateway_hold_max_log_; // last time we logged a HOLD_MAX "still busy" warning static uint32_t gateway_window_start_; static uint8_t gateway_window_count_; static uint32_t gateway_fast_start_;