From 01012ccc895085f7f1160051d030359aba2e9525 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Thu, 21 Mar 2024 21:39:06 +0100 Subject: [PATCH] Create fan-control-manager.cpp --- .../linux/fan-control-manager.cpp | 145 ++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 examples/all-clusters-app/linux/fan-control-manager.cpp diff --git a/examples/all-clusters-app/linux/fan-control-manager.cpp b/examples/all-clusters-app/linux/fan-control-manager.cpp new file mode 100644 index 00000000000000..5a1656315799eb --- /dev/null +++ b/examples/all-clusters-app/linux/fan-control-manager.cpp @@ -0,0 +1,145 @@ +/* + * + * Copyright (c) 2023 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::FanControl; +using namespace chip::app::Clusters::FanControl::Attributes; +using Protocols::InteractionModel::Status; + +namespace { +class FanControlManager : public AttributeAccessInterface, public Delegate +{ +public: + FanControlManager(EndpointId aEndpointId) : + AttributeAccessInterface(Optional(aEndpointId), FanControl::Id), Delegate(aEndpointId) + {} + + CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override; + Status HandleStep(StepDirectionEnum aDirection, bool aWrap, bool aLowestOff) override; + +private: + CHIP_ERROR ReadPercentCurrent(AttributeValueEncoder & aEncoder); + CHIP_ERROR ReadSpeedCurrent(AttributeValueEncoder & aEncoder); +}; + +static std::unique_ptr mFanControlManager; + +CHIP_ERROR FanControlManager::ReadPercentCurrent(AttributeValueEncoder & aEncoder) +{ + // Return PercentSetting attribute value for now + DataModel::Nullable percentSetting; + Protocols::InteractionModel::Status status = PercentSetting::Get(mEndpoint, percentSetting); + + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, CHIP_ERROR_READ_FAILED); + + return aEncoder.Encode(percentSetting.ValueOr(0)); +} + +CHIP_ERROR FanControlManager::ReadSpeedCurrent(AttributeValueEncoder & aEncoder) +{ + // Return SpeedCurrent attribute value for now + DataModel::Nullable speedSetting; + Protocols::InteractionModel::Status status = SpeedSetting::Get(mEndpoint, speedSetting); + + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, CHIP_ERROR_READ_FAILED); + + return aEncoder.Encode(speedSetting.ValueOr(0)); +} + +Status FanControlManager::HandleStep(StepDirectionEnum aDirection, bool aWrap, bool aLowestOff) +{ + ChipLogProgress(NotSpecified, "FanControlManager::HandleStep aDirection %d, aWrap %d, aLowestOff %d", + to_underlying(aDirection), aWrap, aLowestOff); + + VerifyOrReturnError(aDirection != StepDirectionEnum::kUnknownEnumValue, Status::InvalidCommand); + + Protocols::InteractionModel::Status status; + + uint8_t speedMax; + status = SpeedMax::Get(mEndpoint, &speedMax); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, Status::InvalidCommand); + + uint8_t speedCurrent; + status = SpeedCurrent::Get(mEndpoint, &speedCurrent); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, Status::InvalidCommand); + + DataModel::Nullable speedSetting; + status = SpeedSetting::Get(mEndpoint, speedSetting); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, Status::InvalidCommand); + + uint8_t newSpeedSetting = speedSetting.ValueOr(0); + uint8_t speedValue = speedSetting.ValueOr(speedCurrent); + const uint8_t kLowestSpeed = aLowestOff ? 0 : 1; + + if (aDirection == StepDirectionEnum::kIncrease) + { + newSpeedSetting = std::invoke([&]() -> uint8_t { + VerifyOrReturnValue(speedValue < speedMax, (aWrap ? kLowestSpeed : speedMax)); + return static_cast(speedValue + 1); + }); + } + else if (aDirection == StepDirectionEnum::kDecrease) + { + newSpeedSetting = std::invoke([&]() -> uint8_t { + VerifyOrReturnValue(speedValue > kLowestSpeed, aWrap ? speedMax : kLowestSpeed); + return static_cast(speedValue - 1); + }); + } + + return SpeedSetting::Set(mEndpoint, newSpeedSetting); +} + +CHIP_ERROR FanControlManager::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) +{ + VerifyOrDie(aPath.mClusterId == FanControl::Id); + VerifyOrDie(aPath.mEndpointId == mEndpoint); + + switch (aPath.mAttributeId) + { + case SpeedCurrent::Id: + return ReadSpeedCurrent(aEncoder); + case PercentCurrent::Id: + return ReadPercentCurrent(aEncoder); + default: + break; + } + return CHIP_NO_ERROR; +} + +} // anonymous namespace + +void emberAfFanControlClusterInitCallback(EndpointId endpoint) +{ + VerifyOrDie(!mFanControlManager); + mFanControlManager = std::make_unique(endpoint); + registerAttributeAccessOverride(mFanControlManager.get()); + FanControl::SetDefaultDelegate(endpoint, mFanControlManager.get()); +}