| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- /**
- *
- * Copyright (c) 2022 Project CHIP Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #include "WindowCoveringManager.h"
- #include <app-common/zap-generated/attributes/Accessors.h>
- #include <platform/internal/CHIPDeviceLayerInternal.h>
- #include <system/SystemClock.h>
- using namespace chip;
- using namespace chip::app;
- using namespace chip::app::Clusters::WindowCovering;
- using namespace chip::System::Clock::Literals;
- namespace {
- constexpr const System::Clock::Milliseconds32 kIncrementMovementTimeout = 700_ms32;
- constexpr const uint16_t kDefaultMovementStep = 2000;
- } // namespace
- void WindowCoveringManager::Init(EndpointId endpoint)
- {
- mState = OperationalState::Stall;
- mCurrentLiftPosition.SetNonNull(static_cast<uint16_t>(0));
- mTargetLiftPosition.SetNonNull(static_cast<uint16_t>(0));
- mCurrentTiltPosition.SetNonNull(static_cast<uint16_t>(0));
- mTargetTiltPosition.SetNonNull(static_cast<uint16_t>(0));
- SetEndpoint(endpoint);
- }
- void WindowCoveringManager::HandleLiftMovementTimer(System::Layer * layer, void * aAppState)
- {
- WindowCoveringManager * manager = reinterpret_cast<WindowCoveringManager *>(aAppState);
- VerifyOrReturn(manager->mState != OperationalState::Stall);
- Percent100ths currentPosition = manager->mCurrentLiftPosition.Value();
- Percent100ths targetPosition = manager->mTargetLiftPosition.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;
- }
- Percent100ths tempPosition =
- ComputePercent100thsStep(OperationalState::MovingUpOrOpen, currentPosition, kDefaultMovementStep);
- currentPosition = tempPosition > targetPosition ? tempPosition : targetPosition;
- manager->mCurrentLiftPosition.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->mCurrentLiftPosition.SetNonNull(currentPosition);
- }
- LiftPositionSet(manager->mEndpoint, manager->mCurrentLiftPosition);
- if (manager->mCurrentLiftPosition != manager->mTargetLiftPosition)
- {
- 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->mCurrentTiltPosition.Value();
- Percent100ths targetPosition = manager->mTargetTiltPosition.Value();
- ChipLogProgress(NotSpecified, "HandleTiltMovementTimer:currentPosition:%u, targetPosition:%u", currentPosition, targetPosition);
- if (OperationalState::MovingUpOrOpen == manager->mState)
- {
- 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->mCurrentTiltPosition.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->mCurrentTiltPosition.SetNonNull(currentPosition);
- }
- TiltPositionSet(manager->mEndpoint, manager->mCurrentTiltPosition);
- if (manager->mCurrentTiltPosition != manager->mTargetTiltPosition)
- {
- LogErrorOnFailure(DeviceLayer::SystemLayer().StartTimer(kIncrementMovementTimeout, HandleTiltMovementTimer, aAppState));
- }
- }
- CHIP_ERROR WindowCoveringManager::HandleMovement(WindowCoveringType type)
- {
- if (type == WindowCoveringType::Lift)
- {
- mState = OperationalStateGet(mEndpoint, OperationalStatus::kLift);
- }
- else
- {
- mState = OperationalStateGet(mEndpoint, OperationalStatus::kTilt);
- }
- if (OperationalState::Stall == mState)
- {
- ChipLogProgress(NotSpecified, "Covering is currently not moving");
- return CHIP_NO_ERROR;
- }
- CHIP_ERROR err = CHIP_NO_ERROR;
- // At least one of the Lift and Tilt features SHALL be supported.
- if (type == WindowCoveringType::Lift)
- {
- // Cancel ongoing window covering movement timer if any.
- DeviceLayer::SystemLayer().CancelTimer(HandleLiftMovementTimer, this);
- Attributes::CurrentPositionLiftPercent100ths::Get(mEndpoint, mCurrentLiftPosition);
- Attributes::TargetPositionLiftPercent100ths::Get(mEndpoint, mTargetLiftPosition);
- VerifyOrReturnError(!mCurrentLiftPosition.IsNull(), CHIP_ERROR_INCORRECT_STATE);
- VerifyOrReturnError(!mTargetLiftPosition.IsNull(), CHIP_ERROR_INCORRECT_STATE);
- VerifyOrReturnError(mCurrentLiftPosition != mTargetLiftPosition, CHIP_ERROR_INCORRECT_STATE);
- err = DeviceLayer::SystemLayer().StartTimer(kIncrementMovementTimeout, HandleLiftMovementTimer, this);
- }
- else
- {
- // Cancel ongoing window covering movement timer if any.
- DeviceLayer::SystemLayer().CancelTimer(HandleTiltMovementTimer, this);
- Attributes::CurrentPositionTiltPercent100ths::Get(mEndpoint, mCurrentTiltPosition);
- Attributes::TargetPositionTiltPercent100ths::Get(mEndpoint, mTargetTiltPosition);
- VerifyOrReturnError(!mCurrentTiltPosition.IsNull(), CHIP_ERROR_INCORRECT_STATE);
- VerifyOrReturnError(!mTargetTiltPosition.IsNull(), CHIP_ERROR_INCORRECT_STATE);
- VerifyOrReturnError(mCurrentTiltPosition != mTargetTiltPosition, CHIP_ERROR_INCORRECT_STATE);
- err = DeviceLayer::SystemLayer().StartTimer(kIncrementMovementTimeout, HandleTiltMovementTimer, this);
- }
- return err;
- }
- CHIP_ERROR WindowCoveringManager::HandleStopMotion()
- {
- DeviceLayer::SystemLayer().CancelTimer(HandleLiftMovementTimer, this);
- DeviceLayer::SystemLayer().CancelTimer(HandleTiltMovementTimer, this);
- return CHIP_NO_ERROR;
- }
|