Skip to content

Commit

Permalink
Use seperate timers to control lift and tilt window coverings
Browse files Browse the repository at this point in the history
  • Loading branch information
yufengwangca committed Sep 19, 2022
1 parent 0cf7694 commit 695b4bb
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 31 deletions.
103 changes: 75 additions & 28 deletions examples/all-clusters-app/linux/WindowCoveringManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<WindowCoveringManager *>(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<uint16_t>(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<uint16_t>(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<WindowCoveringManager *>(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));
}
}

Expand All @@ -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)
Expand All @@ -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;
}
3 changes: 2 additions & 1 deletion examples/all-clusters-app/linux/WindowCoveringManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
Expand Down Expand Up @@ -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));
}
Expand Down

0 comments on commit 695b4bb

Please sign in to comment.