From 695b4bbf83d1fd666956f0a677d8d0443da90baa Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Mon, 19 Sep 2022 08:58:43 -0700 Subject: [PATCH] Use seperate timers to control lift and tilt window coverings --- .../linux/WindowCoveringManager.cpp | 103 +++++++++++++----- .../linux/WindowCoveringManager.h | 3 +- .../window-covering-server.cpp | 6 +- 3 files changed, 81 insertions(+), 31 deletions(-) diff --git a/examples/all-clusters-app/linux/WindowCoveringManager.cpp b/examples/all-clusters-app/linux/WindowCoveringManager.cpp index 0418d7f1cde7f5..ce3c6cb502d5a0 100644 --- a/examples/all-clusters-app/linux/WindowCoveringManager.cpp +++ b/examples/all-clusters-app/linux/WindowCoveringManager.cpp @@ -40,61 +40,96 @@ void WindowCoveringManager::Init(EndpointId endpoint) SetEndpoint(endpoint); } -void WindowCoveringManager::HandleMovementTimer(System::Layer * layer, void * aAppState) +void WindowCoveringManager::HandleLiftMovementTimer(System::Layer * layer, void * aAppState) { WindowCoveringManager * manager = reinterpret_cast(aAppState); VerifyOrReturn(manager->mState != OperationalState::Stall); - uint16_t currentPosition = manager->mCurrentPosition.Value(); - uint16_t targetPosition = manager->mTargetPosition.Value(); + Percent100ths currentPosition = manager->mCurrentPosition.Value(); + Percent100ths targetPosition = manager->mTargetPosition.Value(); - ChipLogProgress(NotSpecified, "HandleMovementTimer:currentPosition:%u, targetPosition:%u", currentPosition, targetPosition); + ChipLogProgress(NotSpecified, "yujuan: HandleLiftMovementTimer:currentPosition:%u, targetPosition:%u", currentPosition, + targetPosition); if (OperationalState::MovingUpOrOpen == manager->mState) { - if (currentPosition > targetPosition) - { - uint16_t tempPosition = - currentPosition > kDefaultMovementStep ? static_cast(currentPosition - kDefaultMovementStep) : 0; - currentPosition = tempPosition > targetPosition ? tempPosition : targetPosition; - - manager->mCurrentPosition.SetNonNull(currentPosition); - } - else + if (ComputeOperationalState(targetPosition, currentPosition) != OperationalState::MovingUpOrOpen) { ChipLogProgress(NotSpecified, "Reached the target position"); return; } + + Percent100ths tempPosition = + ComputePercent100thsStep(OperationalState::MovingUpOrOpen, currentPosition, kDefaultMovementStep); + currentPosition = tempPosition > targetPosition ? tempPosition : targetPosition; + manager->mCurrentPosition.SetNonNull(currentPosition); } else { - if (currentPosition < targetPosition) - { - uint16_t tempPosition = static_cast(currentPosition + kDefaultMovementStep); - currentPosition = tempPosition < targetPosition ? tempPosition : targetPosition; - manager->mCurrentPosition.SetNonNull(currentPosition); - } - else + if (ComputeOperationalState(targetPosition, currentPosition) != OperationalState::MovingDownOrClose) { ChipLogProgress(NotSpecified, "Reached the target position"); return; } + + Percent100ths tempPosition = + ComputePercent100thsStep(OperationalState::MovingDownOrClose, currentPosition, kDefaultMovementStep); + currentPosition = tempPosition < targetPosition ? tempPosition : targetPosition; + manager->mCurrentPosition.SetNonNull(currentPosition); } - if (HasFeature(manager->mEndpoint, Feature::kPositionAwareLift)) + LiftPositionSet(manager->mEndpoint, manager->mCurrentPosition); + + if (manager->mCurrentPosition != manager->mTargetPosition) { - LiftPositionSet(manager->mEndpoint, manager->mCurrentPosition); + LogErrorOnFailure(DeviceLayer::SystemLayer().StartTimer(kIncrementMovementTimeout, HandleLiftMovementTimer, aAppState)); } +} + +void WindowCoveringManager::HandleTiltMovementTimer(System::Layer * layer, void * aAppState) +{ + WindowCoveringManager * manager = reinterpret_cast(aAppState); + + VerifyOrReturn(manager->mState != OperationalState::Stall); + + Percent100ths currentPosition = manager->mCurrentPosition.Value(); + Percent100ths targetPosition = manager->mTargetPosition.Value(); + + ChipLogProgress(NotSpecified, "HandleLiftMovementTimer:currentPosition:%u, targetPosition:%u", currentPosition, targetPosition); + + if (OperationalState::MovingUpOrOpen == manager->mState) + { + if (ComputeOperationalState(targetPosition, currentPosition) != OperationalState::MovingUpOrOpen) + { + ChipLogProgress(NotSpecified, "Reached the target position"); + return; + } - if (HasFeature(manager->mEndpoint, Feature::kPositionAwareTilt)) + Percent100ths tempPosition = + ComputePercent100thsStep(OperationalState::MovingUpOrOpen, currentPosition, kDefaultMovementStep); + currentPosition = tempPosition > targetPosition ? tempPosition : targetPosition; + manager->mCurrentPosition.SetNonNull(currentPosition); + } + else { - TiltPositionSet(manager->mEndpoint, manager->mCurrentPosition); + if (ComputeOperationalState(targetPosition, currentPosition) != OperationalState::MovingDownOrClose) + { + ChipLogProgress(NotSpecified, "Reached the target position"); + return; + } + + Percent100ths tempPosition = + ComputePercent100thsStep(OperationalState::MovingDownOrClose, currentPosition, kDefaultMovementStep); + currentPosition = tempPosition < targetPosition ? tempPosition : targetPosition; + manager->mCurrentPosition.SetNonNull(currentPosition); } + TiltPositionSet(manager->mEndpoint, manager->mCurrentPosition); + if (manager->mCurrentPosition != manager->mTargetPosition) { - LogErrorOnFailure(DeviceLayer::SystemLayer().StartTimer(kIncrementMovementTimeout, HandleMovementTimer, aAppState)); + LogErrorOnFailure(DeviceLayer::SystemLayer().StartTimer(kIncrementMovementTimeout, HandleTiltMovementTimer, aAppState)); } } @@ -109,7 +144,7 @@ CHIP_ERROR WindowCoveringManager::HandleMovement(WindowCoveringType type) } // Cancel ongoing window covering movement timer if any. - DeviceLayer::SystemLayer().CancelTimer(HandleMovementTimer, this); + DeviceLayer::SystemLayer().CancelTimer(HandleLiftMovementTimer, this); // At least one of the Lift and Tilt features SHALL be supported. if (type == WindowCoveringType::Lift) @@ -127,12 +162,24 @@ CHIP_ERROR WindowCoveringManager::HandleMovement(WindowCoveringType type) VerifyOrReturnError(!mTargetPosition.IsNull(), CHIP_ERROR_INCORRECT_STATE); VerifyOrReturnError(mCurrentPosition != mTargetPosition, CHIP_ERROR_INCORRECT_STATE); - return DeviceLayer::SystemLayer().StartTimer(kIncrementMovementTimeout, HandleMovementTimer, this); + CHIP_ERROR err = CHIP_NO_ERROR; + + if (type == WindowCoveringType::Lift) + { + err = DeviceLayer::SystemLayer().StartTimer(kIncrementMovementTimeout, HandleLiftMovementTimer, this); + } + else + { + err = DeviceLayer::SystemLayer().StartTimer(kIncrementMovementTimeout, HandleTiltMovementTimer, this); + } + + return err; } CHIP_ERROR WindowCoveringManager::HandleStopMotion() { - DeviceLayer::SystemLayer().CancelTimer(HandleMovementTimer, this); + DeviceLayer::SystemLayer().CancelTimer(HandleLiftMovementTimer, this); + DeviceLayer::SystemLayer().CancelTimer(HandleTiltMovementTimer, this); return CHIP_NO_ERROR; } diff --git a/examples/all-clusters-app/linux/WindowCoveringManager.h b/examples/all-clusters-app/linux/WindowCoveringManager.h index 8687329e1ec717..400e76e61618a5 100644 --- a/examples/all-clusters-app/linux/WindowCoveringManager.h +++ b/examples/all-clusters-app/linux/WindowCoveringManager.h @@ -40,7 +40,8 @@ class WindowCoveringManager : public Delegate * @brief * The callback function to be called when "movement timer" expires. */ - static void HandleMovementTimer(chip::System::Layer * layer, void * aAppState); + static void HandleLiftMovementTimer(chip::System::Layer * layer, void * aAppState); + static void HandleTiltMovementTimer(chip::System::Layer * layer, void * aAppState); }; } // namespace WindowCovering diff --git a/src/app/clusters/window-covering-server/window-covering-server.cpp b/src/app/clusters/window-covering-server/window-covering-server.cpp index 0f7562853bf770..65237ba9b1211f 100644 --- a/src/app/clusters/window-covering-server/window-covering-server.cpp +++ b/src/app/clusters/window-covering-server/window-covering-server.cpp @@ -652,7 +652,8 @@ bool emberAfWindowCoveringClusterUpOrOpenCallback(app::CommandHandler * commandO { LogErrorOnFailure(delegate->HandleMovement(WindowCoveringType::Lift)); } - else if (HasFeature(endpoint, Feature::kPositionAwareTilt)) + + if (HasFeature(endpoint, Feature::kPositionAwareTilt)) { LogErrorOnFailure(delegate->HandleMovement(WindowCoveringType::Tilt)); } @@ -702,7 +703,8 @@ bool emberAfWindowCoveringClusterDownOrCloseCallback(app::CommandHandler * comma { LogErrorOnFailure(delegate->HandleMovement(WindowCoveringType::Lift)); } - else if (HasFeature(endpoint, Feature::kPositionAwareTilt)) + + if (HasFeature(endpoint, Feature::kPositionAwareTilt)) { LogErrorOnFailure(delegate->HandleMovement(WindowCoveringType::Tilt)); }