diff --git a/src/app/clusters/on-off-server/on-off-server.cpp b/src/app/clusters/on-off-server/on-off-server.cpp index c0006c70c25134..b24ee63efe9042 100644 --- a/src/app/clusters/on-off-server/on-off-server.cpp +++ b/src/app/clusters/on-off-server/on-off-server.cpp @@ -452,6 +452,26 @@ bool OnOffServer::OnWithRecallGlobalSceneCommand(app::CommandHandler * commandOb return true; } +uint32_t OnOffServer::calculateNextWaitTimeMS(void) +{ + const chip::System::Clock::Timestamp currentTime = chip::System::SystemClock().GetMonotonicTimestamp(); + chip::System::Clock::Timestamp waitTime = UPDATE_TIME_MS; + chip::System::Clock::Timestamp latency; + + if (currentTime > nextDesiredOnWithTimedOffTimestamp) + { + latency = currentTime - nextDesiredOnWithTimedOffTimestamp; + if (latency >= UPDATE_TIME_MS) + waitTime = chip::System::Clock::Milliseconds32(1); + else + waitTime -= latency; + } + + nextDesiredOnWithTimedOffTimestamp += UPDATE_TIME_MS; + + return (uint32_t) waitTime.count(); +} + bool OnOffServer::OnWithTimedOffCommand(const app::ConcreteCommandPath & commandPath, const Commands::OnWithTimedOff::DecodableType & commandData) { @@ -503,7 +523,8 @@ bool OnOffServer::OnWithTimedOffCommand(const app::ConcreteCommandPath & command if (currentOnTime < MAX_TIME_VALUE && currentOffWaitTime < MAX_TIME_VALUE) { - emberEventControlSetDelayMS(configureEventControl(endpoint), UPDATE_TIME_MS); + nextDesiredOnWithTimedOffTimestamp = chip::System::SystemClock().GetMonotonicTimestamp() + UPDATE_TIME_MS; + emberEventControlSetDelayMS(configureEventControl(endpoint), (uint32_t) UPDATE_TIME_MS.count()); } exit: @@ -526,7 +547,7 @@ void OnOffServer::updateOnOffTimeCommand(chip::EndpointId endpoint) if (isOn) // OnOff On case { // Restart Timer - emberEventControlSetDelayMS(configureEventControl(endpoint), UPDATE_TIME_MS); + emberEventControlSetDelayMS(configureEventControl(endpoint), calculateNextWaitTimeMS()); // Update onTime values uint16_t onTime = MIN_TIME_VALUE; @@ -565,7 +586,7 @@ void OnOffServer::updateOnOffTimeCommand(chip::EndpointId endpoint) if (offWaitTime > 0) { // Restart Timer - emberEventControlSetDelayMS(configureEventControl(endpoint), UPDATE_TIME_MS); + emberEventControlSetDelayMS(configureEventControl(endpoint), calculateNextWaitTimeMS()); } else { diff --git a/src/app/clusters/on-off-server/on-off-server.h b/src/app/clusters/on-off-server/on-off-server.h index a91588015bca9a..61c95278c58387 100644 --- a/src/app/clusters/on-off-server/on-off-server.h +++ b/src/app/clusters/on-off-server/on-off-server.h @@ -29,8 +29,8 @@ using chip::app::Clusters::OnOff::OnOffFeature; * Defines and Macros *********************************************************/ -static constexpr uint8_t UPDATE_TIME_MS = 100; -static constexpr uint16_t TRANSITION_TIME_1S = 10; +static constexpr chip::System::Clock::Milliseconds32 UPDATE_TIME_MS = chip::System::Clock::Milliseconds32(100); +static constexpr uint16_t TRANSITION_TIME_1S = 10; static constexpr uint16_t MAX_TIME_VALUE = 0xFFFF; static constexpr uint8_t MIN_TIME_VALUE = 1; @@ -79,12 +79,14 @@ class OnOffServer EmberEventControl * getEventControl(chip::EndpointId endpoint); EmberEventControl * configureEventControl(chip::EndpointId endpoint); + uint32_t calculateNextWaitTimeMS(void); /********************************************************** * Attributes Declaration *********************************************************/ static OnOffServer instance; EmberEventControl eventControls[EMBER_AF_ON_OFF_CLUSTER_SERVER_ENDPOINT_COUNT]; + chip::System::Clock::Timestamp nextDesiredOnWithTimedOffTimestamp; }; struct OnOffEffect