-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Chef] Add AirPurifier device in Chef example (#31226)
* After finish Chef fan control manager * Add Step command to chef airpurifier * Add chef resource monitoring delegates * Support Chef AirPurfier for nRFConnect * Restyled by clang-format * Enable LocalizationConfigurate / TimeFormatLocalization * Remove TimeFormatLocalization and LocalizationConfiguration * Use std::unique_ptr and ValueOr in AirPurifier sample Use std::unique_ptr to manage the pointer in chef-resource-monitoring-delegates.cpp Add ValueOr to chip::Nullable and simplify the code based on it * Restyled by clang-format * Use ValueOr instead of check IsNull() * Fix typo * Replacing with chip::BitMask<ResourceMonitoring::Feature> * Fix typo * Restyled by clang-format * Remove comments * Remove unused comment * Use unique_ptr.reset() instead of unique_ptr = nullptr * Remove unused comment * Not using nullptr when using unique_ptr * Add comments to std::make_unique<ResourceMonitoring::Instance> * Restyled by clang-format * Use chip:BitMask(args...) instead of static_cast * Remove comments cause confusion * Fix speedSetting 1. Simplify the code by a new kLowest vriable 2. Return error when Attribute Read error * Restyled by clang-format * Make mFanControlManager a std::unique_ptr * Rename kLowest to kLowestSpeed * Restyled by clang-format * When decrease, we don't need to check speedMax * Using std::invoke & lambda to return the step * Restyled by clang-format --------- Co-authored-by: Restyled.io <commits@restyled.io>
- Loading branch information
Showing
8 changed files
with
5,357 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
/* | ||
* | ||
* 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 <app-common/zap-generated/attributes/Accessors.h> | ||
#include <app-common/zap-generated/cluster-objects.h> | ||
#include <app-common/zap-generated/ids/Attributes.h> | ||
#include <app-common/zap-generated/ids/Clusters.h> | ||
#include <app/AttributeAccessInterface.h> | ||
#include <app/clusters/fan-control-server/fan-control-server.h> | ||
#include <app/util/attribute-storage.h> | ||
#include <app/util/error-mapping.h> | ||
#include <lib/support/CodeUtils.h> | ||
#include <lib/support/logging/CHIPLogging.h> | ||
|
||
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 ChefFanControlManager : public AttributeAccessInterface, public Delegate | ||
{ | ||
public: | ||
ChefFanControlManager(EndpointId aEndpointId) : | ||
AttributeAccessInterface(Optional<EndpointId>(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<ChefFanControlManager> mFanControlManager; | ||
|
||
CHIP_ERROR ChefFanControlManager::ReadPercentCurrent(AttributeValueEncoder & aEncoder) | ||
{ | ||
// Return PercentSetting attribute value for now | ||
DataModel::Nullable<Percent> percentSetting; | ||
EmberAfStatus status = PercentSetting::Get(mEndpoint, percentSetting); | ||
|
||
VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, CHIP_ERROR_READ_FAILED); | ||
|
||
return aEncoder.Encode(percentSetting.ValueOr(0)); | ||
} | ||
|
||
CHIP_ERROR ChefFanControlManager::ReadSpeedCurrent(AttributeValueEncoder & aEncoder) | ||
{ | ||
// Return SpeedCurrent attribute value for now | ||
DataModel::Nullable<uint8_t> speedSetting; | ||
EmberAfStatus status = SpeedSetting::Get(mEndpoint, speedSetting); | ||
|
||
VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, CHIP_ERROR_READ_FAILED); | ||
|
||
return aEncoder.Encode(speedSetting.ValueOr(0)); | ||
} | ||
|
||
Status ChefFanControlManager::HandleStep(StepDirectionEnum aDirection, bool aWrap, bool aLowestOff) | ||
{ | ||
ChipLogProgress(NotSpecified, "ChefFanControlManager::HandleStep aDirection %d, aWrap %d, aLowestOff %d", | ||
to_underlying(aDirection), aWrap, aLowestOff); | ||
|
||
VerifyOrReturnError(aDirection != StepDirectionEnum::kUnknownEnumValue, Status::InvalidCommand); | ||
|
||
EmberAfStatus status; | ||
|
||
uint8_t speedMax; | ||
status = SpeedMax::Get(mEndpoint, &speedMax); | ||
VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, Status::InvalidCommand); | ||
|
||
uint8_t speedCurrent; | ||
status = SpeedCurrent::Get(mEndpoint, &speedCurrent); | ||
VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, Status::InvalidCommand); | ||
|
||
DataModel::Nullable<uint8_t> speedSetting; | ||
status = SpeedSetting::Get(mEndpoint, speedSetting); | ||
VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, Status::InvalidCommand); | ||
|
||
uint8_t newSpeedSetting; | ||
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<uint8_t>(speedValue + 1); | ||
}); | ||
} | ||
else if (aDirection == StepDirectionEnum::kDecrease) | ||
{ | ||
newSpeedSetting = std::invoke([&]() -> uint8_t { | ||
VerifyOrReturnValue(speedValue > kLowestSpeed, aWrap ? speedMax : kLowestSpeed); | ||
return static_cast<uint8_t>(speedValue - 1); | ||
}); | ||
} | ||
|
||
return ToInteractionModelStatus(SpeedSetting::Set(mEndpoint, newSpeedSetting)); | ||
} | ||
|
||
CHIP_ERROR ChefFanControlManager::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<ChefFanControlManager>(endpoint); | ||
registerAttributeAccessOverride(mFanControlManager.get()); | ||
FanControl::SetDefaultDelegate(endpoint, mFanControlManager.get()); | ||
} |
157 changes: 157 additions & 0 deletions
157
examples/chef/common/chef-resource-monitoring-delegates.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
/* | ||
* | ||
* 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 <app-common/zap-generated/ids/Attributes.h> | ||
#include <app-common/zap-generated/ids/Clusters.h> | ||
#include <app/clusters/resource-monitoring-server/resource-monitoring-cluster-objects.h> | ||
#include <app/clusters/resource-monitoring-server/resource-monitoring-server.h> | ||
#include <chef-resource-monitoring-delegates.h> | ||
|
||
using namespace chip; | ||
using namespace chip::app; | ||
using namespace chip::app::Clusters; | ||
using namespace chip::app::Clusters::ResourceMonitoring; | ||
using namespace chip::app::Clusters::ActivatedCarbonFilterMonitoring; | ||
using namespace chip::app::Clusters::HepaFilterMonitoring; | ||
using chip::Protocols::InteractionModel::Status; | ||
|
||
const chip::BitMask<ResourceMonitoring::Feature> gHepaFilterFeatureMap(ResourceMonitoring::Feature::kCondition, | ||
ResourceMonitoring::Feature::kWarning, | ||
ResourceMonitoring::Feature::kReplacementProductList); | ||
const chip::BitMask<ResourceMonitoring::Feature> gActivatedCarbonFeatureMap(ResourceMonitoring::Feature::kCondition, | ||
ResourceMonitoring::Feature::kWarning, | ||
ResourceMonitoring::Feature::kReplacementProductList); | ||
|
||
static std::unique_ptr<ActivatedCarbonFilterMonitoringDelegate> gActivatedCarbonFilterDelegate; | ||
static std::unique_ptr<ResourceMonitoring::Instance> gActivatedCarbonFilterInstance; | ||
|
||
static std::unique_ptr<HepaFilterMonitoringDelegate> gHepaFilterDelegate; | ||
static std::unique_ptr<ResourceMonitoring::Instance> gHepaFilterInstance; | ||
|
||
static ImmutableReplacementProductListManager sReplacementProductListManager; | ||
|
||
//-- Activated Carbon Filter Monitoring delegate methods | ||
CHIP_ERROR ActivatedCarbonFilterMonitoringDelegate::Init() | ||
{ | ||
ChipLogDetail(Zcl, "ActivatedCarbonFilterMonitoringDelegate::Init()"); | ||
GetInstance()->SetReplacementProductListManagerInstance(&sReplacementProductListManager); | ||
return CHIP_NO_ERROR; | ||
} | ||
|
||
Status ActivatedCarbonFilterMonitoringDelegate::PreResetCondition() | ||
{ | ||
ChipLogDetail(Zcl, "ActivatedCarbonFilterMonitoringDelegate::PreResetCondition()"); | ||
return Status::Success; | ||
} | ||
|
||
Status ActivatedCarbonFilterMonitoringDelegate::PostResetCondition() | ||
{ | ||
ChipLogDetail(Zcl, "ActivatedCarbonFilterMonitoringDelegate::PostResetCondition()"); | ||
return Status::Success; | ||
} | ||
|
||
void ActivatedCarbonFilterMonitoring::Shutdown() | ||
{ | ||
gActivatedCarbonFilterInstance.reset(); | ||
gActivatedCarbonFilterDelegate.reset(); | ||
} | ||
|
||
//-- Hepa Filter Monitoring delegate methods | ||
CHIP_ERROR HepaFilterMonitoringDelegate::Init() | ||
{ | ||
ChipLogDetail(Zcl, "HepaFilterMonitoringDelegate::Init()"); | ||
GetInstance()->SetReplacementProductListManagerInstance(&sReplacementProductListManager); | ||
return CHIP_NO_ERROR; | ||
} | ||
|
||
Status HepaFilterMonitoringDelegate::PreResetCondition() | ||
{ | ||
ChipLogDetail(Zcl, "HepaFilterMonitoringDelegate::PreResetCondition()"); | ||
return Status::Success; | ||
} | ||
|
||
Status HepaFilterMonitoringDelegate::PostResetCondition() | ||
{ | ||
ChipLogDetail(Zcl, "HepaFilterMonitoringDelegate::PostResetCondition()"); | ||
return Status::Success; | ||
} | ||
|
||
void HepaFilterMonitoring::Shutdown() | ||
{ | ||
gHepaFilterInstance.reset(); | ||
gHepaFilterDelegate.reset(); | ||
} | ||
|
||
void emberAfActivatedCarbonFilterMonitoringClusterInitCallback(chip::EndpointId endpoint) | ||
{ | ||
VerifyOrDie(!gActivatedCarbonFilterInstance && !gActivatedCarbonFilterDelegate); | ||
gActivatedCarbonFilterDelegate = std::make_unique<ActivatedCarbonFilterMonitoringDelegate>(); | ||
bool bResetConditionCommandSupported = true; // The ResetCondition command is supported by the ResourceMonitor cluster | ||
gActivatedCarbonFilterInstance = std::make_unique<ResourceMonitoring::Instance>( | ||
gActivatedCarbonFilterDelegate.get(), endpoint, ActivatedCarbonFilterMonitoring::Id, | ||
static_cast<uint32_t>(gActivatedCarbonFeatureMap.Raw()), ResourceMonitoring::DegradationDirectionEnum::kDown, | ||
bResetConditionCommandSupported); | ||
gActivatedCarbonFilterInstance->Init(); | ||
} | ||
|
||
void emberAfHepaFilterMonitoringClusterInitCallback(chip::EndpointId endpoint) | ||
{ | ||
VerifyOrDie(!gHepaFilterInstance && !gHepaFilterDelegate); | ||
|
||
gHepaFilterDelegate = std::make_unique<HepaFilterMonitoringDelegate>(); | ||
bool bResetConditionCommandSupported = true; // The ResetCondition command is supported by the ResourceMonitor cluster | ||
gHepaFilterInstance = std::make_unique<ResourceMonitoring::Instance>( | ||
gHepaFilterDelegate.get(), endpoint, HepaFilterMonitoring::Id, static_cast<uint32_t>(gHepaFilterFeatureMap.Raw()), | ||
ResourceMonitoring::DegradationDirectionEnum::kDown, bResetConditionCommandSupported); | ||
gHepaFilterInstance->Init(); | ||
} | ||
|
||
CHIP_ERROR ImmutableReplacementProductListManager::Next(ReplacementProductStruct & item) | ||
{ | ||
if (mIndex >= kReplacementProductListMaxSize) | ||
{ | ||
return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; | ||
} | ||
|
||
switch (mIndex) | ||
{ | ||
case 0: | ||
item.SetProductIdentifierType(ResourceMonitoring::ProductIdentifierTypeEnum::kUpc); | ||
item.SetProductIdentifierValue(CharSpan::fromCharString("111112222233")); | ||
break; | ||
case 1: | ||
item.SetProductIdentifierType(ResourceMonitoring::ProductIdentifierTypeEnum::kGtin8); | ||
item.SetProductIdentifierValue(CharSpan::fromCharString("gtin8xxx")); | ||
break; | ||
case 2: | ||
item.SetProductIdentifierType(ResourceMonitoring::ProductIdentifierTypeEnum::kEan); | ||
item.SetProductIdentifierValue(CharSpan::fromCharString("4444455555666")); | ||
break; | ||
case 3: | ||
item.SetProductIdentifierType(ResourceMonitoring::ProductIdentifierTypeEnum::kGtin14); | ||
item.SetProductIdentifierValue(CharSpan::fromCharString("gtin14xxxxxxxx")); | ||
break; | ||
case 4: | ||
item.SetProductIdentifierType(ResourceMonitoring::ProductIdentifierTypeEnum::kOem); | ||
item.SetProductIdentifierValue(CharSpan::fromCharString("oem20xxxxxxxxxxxxxxx")); | ||
break; | ||
default: | ||
return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; | ||
} | ||
mIndex++; | ||
return CHIP_NO_ERROR; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/* | ||
* | ||
* 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 <app-common/zap-generated/ids/Attributes.h> | ||
#include <app-common/zap-generated/ids/Clusters.h> | ||
#include <app/clusters/resource-monitoring-server/resource-monitoring-cluster-objects.h> | ||
#include <app/clusters/resource-monitoring-server/resource-monitoring-server.h> | ||
|
||
namespace chip { | ||
namespace app { | ||
namespace Clusters { | ||
|
||
namespace ActivatedCarbonFilterMonitoring { | ||
class ActivatedCarbonFilterMonitoringDelegate : public ResourceMonitoring::Delegate | ||
{ | ||
private: | ||
CHIP_ERROR Init() override; | ||
chip::Protocols::InteractionModel::Status PreResetCondition() override; | ||
chip::Protocols::InteractionModel::Status PostResetCondition() override; | ||
|
||
public: | ||
~ActivatedCarbonFilterMonitoringDelegate() override = default; | ||
}; | ||
|
||
void Shutdown(); | ||
|
||
} // namespace ActivatedCarbonFilterMonitoring | ||
|
||
namespace HepaFilterMonitoring { | ||
class HepaFilterMonitoringDelegate : public ResourceMonitoring::Delegate | ||
{ | ||
private: | ||
CHIP_ERROR Init() override; | ||
chip::Protocols::InteractionModel::Status PreResetCondition() override; | ||
chip::Protocols::InteractionModel::Status PostResetCondition() override; | ||
|
||
public: | ||
~HepaFilterMonitoringDelegate() override = default; | ||
}; | ||
|
||
class ImmutableReplacementProductListManager : public ResourceMonitoring::ReplacementProductListManager | ||
{ | ||
public: | ||
CHIP_ERROR | ||
Next(chip::app::Clusters::ResourceMonitoring::ReplacementProductStruct & item) override; | ||
}; | ||
|
||
void Shutdown(); | ||
|
||
} // namespace HepaFilterMonitoring | ||
|
||
} // namespace Clusters | ||
} // namespace app | ||
} // namespace chip |
Oops, something went wrong.