Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Chef] Fix Read/Write Attributes of AirPurifier's clusters. #33848

Merged
merged 10 commits into from
Jun 17, 2024
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
*
* Copyright (c) 2023 Project CHIP Authors
* Copyright (c) 2024 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.
Expand All @@ -19,7 +19,9 @@
#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>
#include <lib/core/TLVReader.h>
#include <resource-monitoring/chef-resource-monitoring-delegates.h>
#include <utility>

using namespace chip;
using namespace chip::app;
Expand All @@ -37,10 +39,10 @@ const chip::BitMask<ResourceMonitoring::Feature> gActivatedCarbonFeatureMap(Reso
ResourceMonitoring::Feature::kReplacementProductList);

static std::unique_ptr<ActivatedCarbonFilterMonitoringDelegate> gActivatedCarbonFilterDelegate;
static std::unique_ptr<ResourceMonitoring::Instance> gActivatedCarbonFilterInstance;
static std::unique_ptr<ResourceMonitoring::ChefResourceMonitorInstance> gActivatedCarbonFilterInstance;

static std::unique_ptr<HepaFilterMonitoringDelegate> gHepaFilterDelegate;
static std::unique_ptr<ResourceMonitoring::Instance> gHepaFilterInstance;
static std::unique_ptr<ResourceMonitoring::ChefResourceMonitorInstance> gHepaFilterInstance;

static ImmutableReplacementProductListManager sReplacementProductListManager;

Expand Down Expand Up @@ -96,25 +98,161 @@ void HepaFilterMonitoring::Shutdown()
gHepaFilterDelegate.reset();
}

chip::Protocols::InteractionModel::Status
ChefResourceMonitorInstance::ExternalAttributeWrite(const EmberAfAttributeMetadata * attributeMetadata, uint8_t * buffer)
{
Protocols::InteractionModel::Status ret = Protocols::InteractionModel::Status::Success;
AttributeId attributeId = attributeMetadata->attributeId;

switch (attributeId)
{
case HepaFilterMonitoring::Attributes::Condition::Id: {
uint8_t newCondition = *(uint8_t *) buffer;
ret = UpdateCondition(newCondition);
}
break;
case HepaFilterMonitoring::Attributes::ChangeIndication::Id: {
ResourceMonitoring::ChangeIndicationEnum newIndication =
static_cast<ResourceMonitoring::ChangeIndicationEnum>(*(uint8_t *) buffer);
ret = UpdateChangeIndication(newIndication);
}
break;
case HepaFilterMonitoring::Attributes::InPlaceIndicator::Id: {
bool newInPlaceIndicator = *(bool *) buffer;
ret = UpdateInPlaceIndicator(newInPlaceIndicator);
}
break;
case HepaFilterMonitoring::Attributes::LastChangedTime::Id: {
uint32_t newValue = 0;
uint16_t tlvLen = *(uint16_t *) buffer;
chip::TLV::TLVReader reader;
reader.Init(buffer + sizeof(uint16_t), tlvLen);
reader.Next();
reader.Get(newValue);
DataModel::Nullable<uint32_t> newLastChangedTime = DataModel::MakeNullable(newValue);
ret = UpdateLastChangedTime(newLastChangedTime);
}
break;
case HepaFilterMonitoring::Attributes::DegradationDirection::Id:
default: {
ChipLogError(Zcl, "Unsupported External Attribute Read: %d", static_cast<int>(attributeId));
ret = Protocols::InteractionModel::Status::UnsupportedWrite;
}
break;
}

return ret;
}

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 = std::make_unique<ActivatedCarbonFilterMonitoringDelegate>();
gActivatedCarbonFilterInstance = std::make_unique<ResourceMonitoring::ChefResourceMonitorInstance>(
gActivatedCarbonFilterDelegate.get(), endpoint, ActivatedCarbonFilterMonitoring::Id,
static_cast<uint32_t>(gActivatedCarbonFeatureMap.Raw()), ResourceMonitoring::DegradationDirectionEnum::kDown,
bResetConditionCommandSupported);
gActivatedCarbonFilterInstance->Init();
}

chip::Protocols::InteractionModel::Status
chefResourceMonitoringExternalWriteCallback(chip::EndpointId endpoint, chip::ClusterId clusterId,
const EmberAfAttributeMetadata * attributeMetadata, uint8_t * buffer)
{
Protocols::InteractionModel::Status ret = Protocols::InteractionModel::Status::Success;
AttributeId attributeId = attributeMetadata->attributeId;
ChipLogProgress(Zcl, "chefResourceMonitoringExternalWriteCallback EP: %d, Cluster: %d, Att: %d", static_cast<int>(endpoint),
static_cast<int>(clusterId), static_cast<int>(attributeId));

switch (clusterId)
{
case HepaFilterMonitoring::Id:
ret = gHepaFilterInstance->ExternalAttributeWrite(attributeMetadata, buffer);
break;
case ActivatedCarbonFilterMonitoring::Id:
ret = gActivatedCarbonFilterInstance->ExternalAttributeWrite(attributeMetadata, buffer);
break;
default:
ret = Protocols::InteractionModel::Status::UnsupportedWrite;
break;
}

return ret;
}

chip::Protocols::InteractionModel::Status
chefResourceMonitoringExternalReadCallback(chip::EndpointId endpoint, chip::ClusterId clusterId,
const EmberAfAttributeMetadata * attributeMetadata, uint8_t * buffer,
uint16_t maxReadLength)
{
Protocols::InteractionModel::Status ret = Protocols::InteractionModel::Status::Success;
AttributeId attributeId = attributeMetadata->attributeId;
ChipLogProgress(Zcl, "chefResourceMonitoringExternalReadCallback EP: %d, Cluster: %d, Att: %d", static_cast<int>(endpoint),
static_cast<int>(clusterId), static_cast<int>(attributeId));

switch (clusterId)
{
case HepaFilterMonitoring::Id:
ret = gHepaFilterInstance->ExternalAttributeRead(attributeMetadata, buffer, maxReadLength);
break;
case ActivatedCarbonFilterMonitoring::Id:
ret = gActivatedCarbonFilterInstance->ExternalAttributeRead(attributeMetadata, buffer, maxReadLength);
break;
default:
ret = Protocols::InteractionModel::Status::UnsupportedRead;
break;
}

return ret;
}

chip::Protocols::InteractionModel::Status
ChefResourceMonitorInstance::ExternalAttributeRead(const EmberAfAttributeMetadata * attributeMetadata, uint8_t * buffer,
uint16_t maxReadLength)
{
Protocols::InteractionModel::Status ret = Protocols::InteractionModel::Status::Success;
AttributeId attributeId = attributeMetadata->attributeId;

switch (attributeId)
{
case HepaFilterMonitoring::Attributes::Condition::Id: {
*buffer = GetCondition();
}
break;
case HepaFilterMonitoring::Attributes::ChangeIndication::Id: {
ResourceMonitoring::ChangeIndicationEnum changeIndication = GetChangeIndication();
// The underlying type of ResourceMonitoring::ChangeIndicationEnum is uint8_t
*buffer = to_underlying(changeIndication);
}
break;
case HepaFilterMonitoring::Attributes::InPlaceIndicator::Id: {
*(bool *) buffer = GetInPlaceIndicator();
}
break;
case HepaFilterMonitoring::Attributes::LastChangedTime::Id: {
DataModel::Nullable<uint32_t> lastChangedTime = GetLastChangedTime();
*(uint32_t *) buffer = lastChangedTime.IsNull() ? 0 : lastChangedTime.Value();
}
break;
case HepaFilterMonitoring::Attributes::DegradationDirection::Id:
default:
ChipLogError(Zcl, "Unsupported External Attribute Read: %d", static_cast<int>(attributeId));
ret = Protocols::InteractionModel::Status::UnsupportedRead;
break;
}

return ret;
}

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 = std::make_unique<HepaFilterMonitoringDelegate>();
gHepaFilterInstance = std::make_unique<ResourceMonitoring::ChefResourceMonitorInstance>(
gHepaFilterDelegate.get(), endpoint, HepaFilterMonitoring::Id, static_cast<uint32_t>(gHepaFilterFeatureMap.Raw()),
ResourceMonitoring::DegradationDirectionEnum::kDown, bResetConditionCommandSupported);
gHepaFilterInstance->Init();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
*
* Copyright (c) 2023 Project CHIP Authors
* Copyright (c) 2024 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.
Expand All @@ -24,21 +24,25 @@ 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;
namespace ResourceMonitoring {

// Inherit ResourceMonitoring class to able to write external attributes
class ChefResourceMonitorInstance : public ResourceMonitoring::Instance
{
public:
~ActivatedCarbonFilterMonitoringDelegate() override = default;
};
ChefResourceMonitorInstance(Delegate * aDelegate, EndpointId aEndpointId, ClusterId aClusterId, uint32_t aFeatureMap,
ResourceMonitoring::Attributes::DegradationDirection::TypeInfo::Type aDegradationDirection,
bool aResetConditionCommandSupported) :
ResourceMonitoring::Instance(aDelegate, aEndpointId, aClusterId, aFeatureMap, aDegradationDirection,
aResetConditionCommandSupported){};

void Shutdown();
chip::Protocols::InteractionModel::Status ExternalAttributeWrite(const EmberAfAttributeMetadata * attributeMetadata,
uint8_t * buffer);
chip::Protocols::InteractionModel::Status ExternalAttributeRead(const EmberAfAttributeMetadata * attributeMetadata,
uint8_t * buffer, uint16_t maxReadLength);
};

} // namespace ActivatedCarbonFilterMonitoring
} // namespace ResourceMonitoring

namespace HepaFilterMonitoring {
class HepaFilterMonitoringDelegate : public ResourceMonitoring::Delegate
Expand All @@ -63,6 +67,31 @@ void Shutdown();

} // namespace HepaFilterMonitoring

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 Clusters
} // namespace app
} // namespace chip

chip::Protocols::InteractionModel::Status
chefResourceMonitoringExternalWriteCallback(chip::EndpointId endpoint, chip::ClusterId clusterId,
const EmberAfAttributeMetadata * attributeMetadata, uint8_t * buffer);

chip::Protocols::InteractionModel::Status
chefResourceMonitoringExternalReadCallback(chip::EndpointId endpoint, chip::ClusterId clusterId,
const EmberAfAttributeMetadata * attributeMetadata, uint8_t * buffer,
uint16_t maxReadLength);
13 changes: 13 additions & 0 deletions examples/chef/common/stubs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
defined(MATTER_DM_PLUGIN_RADON_CONCENTRATION_MEASUREMENT_SERVER)
#include "chef-concentration-measurement.h"
#endif
#if defined(MATTER_DM_PLUGIN_HEPA_FILTER_MONITORING_SERVER) || defined(MATTER_DM_PLUGIN_ACTIVATED_CARBON_FILTER_MONITORING_SERVER)
#include "resource-monitoring/chef-resource-monitoring-delegates.h"
#endif

#if defined(MATTER_DM_PLUGIN_RVC_RUN_MODE_SERVER) || defined(MATTER_DM_PLUGIN_RVC_CLEAN_MODE_SERVER)
#include "chef-rvc-mode-delegate.h"
Expand Down Expand Up @@ -65,6 +68,11 @@ Protocols::InteractionModel::Status emberAfExternalAttributeReadCallback(Endpoin
case chip::app::Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Id:
return chefConcentrationMeasurementReadCallback(endpoint, clusterId, attributeMetadata, buffer, maxReadLength);
#endif
#if defined(MATTER_DM_PLUGIN_HEPA_FILTER_MONITORING_SERVER) || defined(MATTER_DM_PLUGIN_ACTIVATED_CARBON_FILTER_MONITORING_SERVER)
case chip::app::Clusters::HepaFilterMonitoring::Id:
case chip::app::Clusters::ActivatedCarbonFilterMonitoring::Id:
return chefResourceMonitoringExternalReadCallback(endpoint, clusterId, attributeMetadata, buffer, maxReadLength);
#endif
#ifdef MATTER_DM_PLUGIN_RVC_RUN_MODE_SERVER
case chip::app::Clusters::RvcRunMode::Id:
return chefRvcRunModeReadCallback(endpoint, clusterId, attributeMetadata, buffer, maxReadLength);
Expand Down Expand Up @@ -125,6 +133,11 @@ Protocols::InteractionModel::Status emberAfExternalAttributeWriteCallback(Endpoi
case chip::app::Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Id:
return chefConcentrationMeasurementWriteCallback(endpoint, clusterId, attributeMetadata, buffer);
#endif
#if defined(MATTER_DM_PLUGIN_HEPA_FILTER_MONITORING_SERVER) || defined(MATTER_DM_PLUGIN_ACTIVATED_CARBON_FILTER_MONITORING_SERVER)
case chip::app::Clusters::HepaFilterMonitoring::Id:
case chip::app::Clusters::ActivatedCarbonFilterMonitoring::Id:
return chefResourceMonitoringExternalWriteCallback(endpoint, clusterId, attributeMetadata, buffer);
#endif
#ifdef MATTER_DM_PLUGIN_RVC_RUN_MODE_SERVER
case chip::app::Clusters::RvcRunMode::Id:
return chefRvcRunModeWriteCallback(endpoint, clusterId, attributeMetadata, buffer);
Expand Down
Loading
Loading