diff --git a/examples/lock-app/silabs/include/LockManager.h b/examples/lock-app/silabs/include/LockManager.h index 9adcc863f0aec7..1654c393685e80 100644 --- a/examples/lock-app/silabs/include/LockManager.h +++ b/examples/lock-app/silabs/include/LockManager.h @@ -121,6 +121,7 @@ class LockManager { LOCK_ACTION = 0, UNLOCK_ACTION, + UNLATCH_ACTION, INVALID_ACTION } Action; @@ -130,7 +131,9 @@ class LockManager kState_LockInitiated = 0, kState_LockCompleted, kState_UnlockInitiated, + kState_UnlatchInitiated, kState_UnlockCompleted, + kState_UnlatchCompleted, } State; CHIP_ERROR Init(chip::app::DataModel::Nullable state, @@ -194,6 +197,8 @@ class LockManager bool ReadConfigValues(); private: + chip::EndpointId mCurrentEndpointId; + friend LockManager & LockMgr(); State_t mState; @@ -206,6 +211,7 @@ class LockManager static void TimerEventHandler(TimerHandle_t xTimer); static void AutoLockTimerEventHandler(AppEvent * aEvent); static void ActuatorMovementTimerEventHandler(AppEvent * aEvent); + static void UpdateClusterStateAfterUnlatch(intptr_t context); EmberAfPluginDoorLockUserInfo mLockUsers[kMaxUsers]; EmberAfPluginDoorLockCredentialInfo mLockCredentials[kNumCredentialTypes][kMaxCredentials]; diff --git a/examples/lock-app/silabs/src/AppTask.cpp b/examples/lock-app/silabs/src/AppTask.cpp index 4e8527f4f4fa1a..96930db8b5f9f0 100644 --- a/examples/lock-app/silabs/src/AppTask.cpp +++ b/examples/lock-app/silabs/src/AppTask.cpp @@ -309,6 +309,10 @@ void AppTask::ActionInitiated(LockManager::Action_t aAction, int32_t aActor) sAppTask.GetLCD().WriteDemoUI(locked); #endif // DISPLAY_ENABLED } + else if (aAction == LockManager::UNLATCH_ACTION) + { + SILABS_LOG("Unlatch Action has been initiated"); + } if (aActor == AppEvent::kEventType_Button) { @@ -325,6 +329,11 @@ void AppTask::ActionCompleted(LockManager::Action_t aAction) { SILABS_LOG("Lock Action has been completed") } + else if (aAction == LockManager::UNLATCH_ACTION) + { + SILABS_LOG("Unlatch Action has been completed") + LockMgr().InitiateAction(AppEvent::kEventType_Lock, LockManager::UNLOCK_ACTION); + } else if (aAction == LockManager::UNLOCK_ACTION) { SILABS_LOG("Unlock Action has been completed") diff --git a/examples/lock-app/silabs/src/LockManager.cpp b/examples/lock-app/silabs/src/LockManager.cpp index 3cd0fa4ee56fe4..82965cbc95348f 100644 --- a/examples/lock-app/silabs/src/LockManager.cpp +++ b/examples/lock-app/silabs/src/LockManager.cpp @@ -36,7 +36,8 @@ using namespace EFR32DoorLock::LockInitParams; CHIP_ERROR LockManager::Init(chip::app::DataModel::Nullable state, LockParam lockParam) { - LockParams = lockParam; + LockParams = lockParam; + mCurrentEndpointId = kInvalidEndpointId; if (LockParams.numberOfUsers > kMaxUsers) { @@ -190,12 +191,18 @@ bool LockManager::InitiateAction(int32_t aActor, Action_t aAction) State_t new_state; // Initiate Turn Lock/Unlock Action only when the previous one is complete. - if (mState == kState_LockCompleted && aAction == UNLOCK_ACTION) + if ((mState == kState_LockCompleted || mState == kState_UnlatchCompleted) && (aAction == UNLOCK_ACTION)) { action_initiated = true; new_state = kState_UnlockInitiated; } + else if ((mState == kState_LockCompleted || mState == kState_UnlockCompleted) && (aAction == UNLATCH_ACTION)) + { + action_initiated = true; + + new_state = kState_UnlatchInitiated; + } else if (mState == kState_UnlockCompleted && aAction == LOCK_ACTION) { action_initiated = true; @@ -262,6 +269,22 @@ void LockManager::TimerEventHandler(TimerHandle_t xTimer) AppTask::GetAppTask().PostEvent(&event); } +void LockManager::UpdateClusterStateAfterUnlatch(intptr_t context) +{ + EndpointId endpointId = *reinterpret_cast(context); + // write the new lock value + bool succes = false; + if (endpointId != kInvalidEndpointId) + { + succes = DoorLockServer::Instance().SetLockState(endpointId, DlLockState::kUnlocked); + } + + if (!succes) + { + SILABS_LOG("Failed to update the lock state after Unlatch"); + } +} + void LockManager::ActuatorMovementTimerEventHandler(AppEvent * aEvent) { Action_t actionCompleted = INVALID_ACTION; @@ -273,6 +296,13 @@ void LockManager::ActuatorMovementTimerEventHandler(AppEvent * aEvent) lock->mState = kState_LockCompleted; actionCompleted = LOCK_ACTION; } + else if (lock->mState == kState_UnlatchInitiated) + { + chip::DeviceLayer::PlatformMgr().ScheduleWork(UpdateClusterStateAfterUnlatch, + reinterpret_cast(&lock->mCurrentEndpointId)); + lock->mState = kState_UnlatchCompleted; + actionCompleted = UNLATCH_ACTION; + } else if (lock->mState == kState_UnlockInitiated) { lock->mState = kState_UnlockCompleted; @@ -299,7 +329,26 @@ bool LockManager::Unlock(chip::EndpointId endpointId, const Nullable