From 226f964f1520a8febf1314fd6713d830692a3e65 Mon Sep 17 00:00:00 2001 From: Sting Chang <33673360+stingchang@users.noreply.github.com> Date: Fri, 30 Aug 2024 19:26:37 +0800 Subject: [PATCH] Add state transition feature (#35271) * add state transition feature * device running cycle dont deduct pause time * Restyled by clang-format * update countdown time --------- Co-authored-by: Restyled.io --- .../chef-rvc-operational-state-delegate.cpp | 99 ++++++++++++++++--- .../chef-rvc-operational-state-delegate.h | 3 +- 2 files changed, 85 insertions(+), 17 deletions(-) diff --git a/examples/chef/common/chef-rvc-operational-state-delegate.cpp b/examples/chef/common/chef-rvc-operational-state-delegate.cpp index 36ff3e88fcd181..9b4118732ee165 100644 --- a/examples/chef/common/chef-rvc-operational-state-delegate.cpp +++ b/examples/chef/common/chef-rvc-operational-state-delegate.cpp @@ -35,10 +35,10 @@ static void onOperationalStateTimerTick(System::Layer * systemLayer, void * data DataModel::Nullable RvcOperationalStateDelegate::GetCountdownTime() { - if (mRunningTime > mPhaseDuration.Value()) + if (mCountdownTime.IsNull() || mRunningTime > mCountdownTime.Value()) return DataModel::NullNullable; - return DataModel::MakeNullable((uint32_t) (mPhaseDuration.Value() - mRunningTime)); + return DataModel::MakeNullable((uint32_t) (mCountdownTime.Value() - mRunningTime)); } CHIP_ERROR RvcOperationalStateDelegate::GetOperationalStateAtIndex(size_t index, GenericOperationalState & operationalState) @@ -62,10 +62,27 @@ CHIP_ERROR RvcOperationalStateDelegate::GetOperationalPhaseAtIndex(size_t index, void RvcOperationalStateDelegate::HandlePauseStateCallback(GenericOperationalError & err) { + OperationalState::OperationalStateEnum state = + static_cast(gRvcOperationalStateInstance->GetCurrentOperationalState()); + + if (state == OperationalState::OperationalStateEnum::kPaused) + { + err.Set(to_underlying(OperationalState::ErrorStateEnum::kNoError)); + return; + } + + if (state == OperationalState::OperationalStateEnum::kStopped || state == OperationalState::OperationalStateEnum::kError) + { + err.Set(to_underlying(OperationalState::ErrorStateEnum::kCommandInvalidInState)); + return; + } + // placeholder implementation - auto error = GetInstance()->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kPaused)); + auto error = gRvcOperationalStateInstance->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kPaused)); if (error == CHIP_NO_ERROR) { + (void) DeviceLayer::SystemLayer().StartTimer(System::Clock::Seconds16(1), onOperationalStateTimerTick, GetInstance()); + GetInstance()->UpdateCountdownTimeFromDelegate(); err.Set(to_underlying(OperationalState::ErrorStateEnum::kNoError)); } else @@ -76,10 +93,21 @@ void RvcOperationalStateDelegate::HandlePauseStateCallback(GenericOperationalErr void RvcOperationalStateDelegate::HandleResumeStateCallback(GenericOperationalError & err) { + OperationalState::OperationalStateEnum state = + static_cast(gRvcOperationalStateInstance->GetCurrentOperationalState()); + + if (state == OperationalState::OperationalStateEnum::kStopped || state == OperationalState::OperationalStateEnum::kError) + { + err.Set(to_underlying(OperationalState::ErrorStateEnum::kUnableToStartOrResume)); + return; + } + // placeholder implementation - auto error = GetInstance()->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kRunning)); + auto error = gRvcOperationalStateInstance->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kRunning)); if (error == CHIP_NO_ERROR) { + (void) DeviceLayer::SystemLayer().StartTimer(System::Clock::Seconds16(1), onOperationalStateTimerTick, GetInstance()); + GetInstance()->UpdateCountdownTimeFromDelegate(); err.Set(to_underlying(OperationalState::ErrorStateEnum::kNoError)); } else @@ -103,7 +131,8 @@ void RvcOperationalStateDelegate::HandleStartStateCallback(GenericOperationalErr auto error = GetInstance()->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kRunning)); if (error == CHIP_NO_ERROR) { - (void) DeviceLayer::SystemLayer().StartTimer(System::Clock::Seconds16(1), onOperationalStateTimerTick, this); + (void) DeviceLayer::SystemLayer().StartTimer(System::Clock::Seconds16(1), onOperationalStateTimerTick, GetInstance()); + GetInstance()->UpdateCountdownTimeFromDelegate(); err.Set(to_underlying(OperationalState::ErrorStateEnum::kNoError)); } else @@ -119,6 +148,7 @@ void RvcOperationalStateDelegate::HandleStopStateCallback(GenericOperationalErro if (error == CHIP_NO_ERROR) { (void) DeviceLayer::SystemLayer().CancelTimer(onOperationalStateTimerTick, this); + GetInstance()->UpdateCountdownTimeFromDelegate(); OperationalState::GenericOperationalError current_err(to_underlying(OperationalState::ErrorStateEnum::kNoError)); GetInstance()->GetCurrentOperationalError(current_err); @@ -130,6 +160,7 @@ void RvcOperationalStateDelegate::HandleStopStateCallback(GenericOperationalErro mRunningTime = 0; mPausedTime = 0; + mCountdownTime.SetNull(); err.Set(to_underlying(OperationalState::ErrorStateEnum::kNoError)); } else @@ -145,27 +176,54 @@ static void onOperationalStateTimerTick(System::Layer * systemLayer, void * data OperationalState::OperationalStateEnum state = static_cast(instance->GetCurrentOperationalState()); - auto countdown_time = delegate->GetCountdownTime(); - - if (countdown_time.ValueOr(1) > 0) + if (gRvcOperationalStateDelegate->mCountdownTime.IsNull()) { if (state == OperationalState::OperationalStateEnum::kRunning) { - delegate->mRunningTime++; - } - else if (state == OperationalState::OperationalStateEnum::kPaused) - { - delegate->mPausedTime++; + gRvcOperationalStateDelegate->mCountdownTime.SetNonNull( + static_cast(gRvcOperationalStateDelegate->kExampleCountDown)); + gRvcOperationalStateDelegate->mRunningTime = 0; + gRvcOperationalStateDelegate->mPausedTime = 0; } } - if (state == OperationalState::OperationalStateEnum::kRunning || state == OperationalState::OperationalStateEnum::kPaused) + if (state == OperationalState::OperationalStateEnum::kRunning) + { + gRvcOperationalStateDelegate->mRunningTime++; + } + else if (state == OperationalState::OperationalStateEnum::kPaused) + { + gRvcOperationalStateDelegate->mPausedTime++; + } + + uint32_t mPausedTime = gRvcOperationalStateDelegate->mPausedTime; + uint32_t mRunningTime = gRvcOperationalStateDelegate->mRunningTime; + + if (gRvcOperationalStateDelegate->mCountdownTime.Value() > mRunningTime) { (void) DeviceLayer::SystemLayer().StartTimer(System::Clock::Seconds16(1), onOperationalStateTimerTick, delegate); } else { (void) DeviceLayer::SystemLayer().CancelTimer(onOperationalStateTimerTick, delegate); + + CHIP_ERROR err = + gRvcOperationalStateInstance->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kStopped)); + if (err == CHIP_NO_ERROR) + { + OperationalState::GenericOperationalError current_err(to_underlying(OperationalState::ErrorStateEnum::kNoError)); + gRvcOperationalStateInstance->GetCurrentOperationalError(current_err); + + Optional> totalTime((DataModel::Nullable(mPausedTime + mRunningTime))); + Optional> pausedTime((DataModel::Nullable(mPausedTime))); + + gRvcOperationalStateInstance->OnOperationCompletionDetected(static_cast(current_err.errorStateID), totalTime, + pausedTime); + + gRvcOperationalStateDelegate->mRunningTime = 0; + gRvcOperationalStateDelegate->mPausedTime = 0; + gRvcOperationalStateDelegate->mCountdownTime.SetNull(); + } } } @@ -200,8 +258,17 @@ chip::Protocols::InteractionModel::Status chefRvcOperationalStateWriteCallback(c } break; case chip::app::Clusters::RvcOperationalState::Attributes::OperationalState::Id: { - uint8_t m = static_cast(buffer[0]); - CHIP_ERROR err = gRvcOperationalStateInstance->SetOperationalState(m); + uint8_t currentState = gRvcOperationalStateInstance->GetCurrentOperationalState(); + uint8_t m = static_cast(buffer[0]); + CHIP_ERROR err = gRvcOperationalStateInstance->SetOperationalState(m); + + if (currentState == to_underlying(OperationalState::OperationalStateEnum::kStopped) && + m == to_underlying(OperationalState::OperationalStateEnum::kRunning)) + { + gRvcOperationalStateDelegate->mCountdownTime.SetNonNull( + static_cast(gRvcOperationalStateDelegate->kExampleCountDown)); + } + if (CHIP_NO_ERROR == err) { break; diff --git a/examples/chef/common/chef-rvc-operational-state-delegate.h b/examples/chef/common/chef-rvc-operational-state-delegate.h index 33b01d55201466..7aca1a86ed95fa 100644 --- a/examples/chef/common/chef-rvc-operational-state-delegate.h +++ b/examples/chef/common/chef-rvc-operational-state-delegate.h @@ -95,7 +95,8 @@ class RvcOperationalStateDelegate : public RvcOperationalState::Delegate uint32_t mRunningTime = 0; uint32_t mPausedTime = 0; - app::DataModel::Nullable mPhaseDuration; + app::DataModel::Nullable mCountdownTime; + const uint32_t kExampleCountDown = 30; private: Span mOperationalStateList;