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

[occupancy-sensing] Follow up improvements for Occupancy Sensing Cluster updates for Matter 1.4 #34658

Merged
merged 10 commits into from
Aug 8, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -8998,9 +8998,9 @@ endpoint 1 {
ram attribute occupancy;
ram attribute occupancySensorType;
ram attribute occupancySensorTypeBitmap;
ram attribute holdTime default = 10;
callback attribute holdTime;
callback attribute holdTimeLimits;
ram attribute featureMap default = 0x01;
callback attribute featureMap;
ram attribute clusterRevision default = 5;
}

Expand Down Expand Up @@ -9469,9 +9469,9 @@ endpoint 2 {
ram attribute occupancy;
ram attribute occupancySensorType;
ram attribute occupancySensorTypeBitmap;
ram attribute holdTime default = 20;
callback attribute holdTime;
callback attribute holdTimeLimits;
ram attribute featureMap default = 0x01;
callback attribute featureMap;
ram attribute clusterRevision default = 5;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <app/CommandHandler.h>
#include <app/clusters/occupancy-sensor-server/occupancy-hal.h>
#include <app/clusters/occupancy-sensor-server/occupancy-sensor-server.h>
#include <app/util/attribute-storage.h>
#include <platform/CHIPDeviceLayer.h>

using namespace chip;
Expand All @@ -28,30 +29,48 @@ using namespace chip::DeviceLayer;

using chip::Protocols::InteractionModel::Status;

static std::unique_ptr<OccupancySensingAttrAccess>
gAttrAccess[MATTER_DM_OCCUPANCY_SENSING_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT];
namespace {

static constexpr size_t kOccupancySensingClusterTableSize =
MATTER_DM_OCCUPANCY_SENSING_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT;

static_assert(kOccupancySensingClusterTableSize <= kEmberInvalidEndpointIndex, "Occupancy Sensing Cluster table size error");

static std::unique_ptr<Instance> gOccupancySensingClusterInstances[kOccupancySensingClusterTableSize];

} // namespace

void emberAfOccupancySensingClusterInitCallback(EndpointId endpointId)
{
VerifyOrDie(!gAttrAccess[endpointId]);
uint16_t epIndex = emberAfGetClusterServerEndpointIndex(endpointId, chip::app::Clusters::OccupancySensing::Id,
MATTER_DM_OCCUPANCY_SENSING_CLUSTER_SERVER_ENDPOINT_COUNT);

gAttrAccess[endpointId] = std::make_unique<OccupancySensingAttrAccess>(
BitMask<OccupancySensing::Feature, uint32_t>(OccupancySensing::Feature::kOther));
if (epIndex < kOccupancySensingClusterTableSize)
{
VerifyOrDie(!gOccupancySensingClusterInstances[epIndex]);

OccupancySensing::Structs::HoldTimeLimitsStruct::Type holdTimeLimits = {
.holdTimeMin = 1,
.holdTimeMax = 300,
.holdTimeDefault = 10,
};
gOccupancySensingClusterInstances[epIndex] =
std::make_unique<Instance>(BitMask<OccupancySensing::Feature, uint32_t>(OccupancySensing::Feature::kOther));

uint16_t holdTime = 10;
OccupancySensing::Structs::HoldTimeLimitsStruct::Type holdTimeLimits = {
.holdTimeMin = 1,
.holdTimeMax = 300,
.holdTimeDefault = 10,
};

if (gAttrAccess[endpointId])
{
gAttrAccess[endpointId]->Init();
uint16_t holdTime = 10;

if (gOccupancySensingClusterInstances[epIndex])
{
gOccupancySensingClusterInstances[epIndex]->Init();

SetHoldTimeLimits(endpointId, holdTimeLimits);
SetHoldTimeLimits(endpointId, holdTimeLimits);

SetHoldTime(endpointId, holdTime);
SetHoldTime(endpointId, holdTime);
}
}
else
{
jadhavrohit924 marked this conversation as resolved.
Show resolved Hide resolved
ChipLogError(AppServer, "Error: invalid/unexpected OccupancySensing Cluster endpoint index.");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6682,7 +6682,7 @@ endpoint 1 {
ram attribute occupancy;
ram attribute occupancySensorType;
ram attribute occupancySensorTypeBitmap;
ram attribute featureMap default = 0;
callback attribute featureMap;
ram attribute clusterRevision default = 4;
}

Expand Down Expand Up @@ -7029,7 +7029,7 @@ endpoint 2 {
ram attribute occupancy;
ram attribute occupancySensorType;
ram attribute occupancySensorTypeBitmap;
ram attribute featureMap default = 0;
callback attribute featureMap;
ram attribute clusterRevision default = 4;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1716,7 +1716,7 @@ endpoint 1 {
callback attribute generatedCommandList;
callback attribute acceptedCommandList;
callback attribute attributeList;
ram attribute featureMap default = 0;
callback attribute featureMap;
ram attribute clusterRevision default = 2;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2153,7 +2153,7 @@ endpoint 1 {
ram attribute occupancy;
ram attribute occupancySensorType;
ram attribute occupancySensorTypeBitmap;
ram attribute featureMap default = 0;
callback attribute featureMap;
ram attribute clusterRevision default = 4;
}
}
Expand Down
2 changes: 1 addition & 1 deletion examples/lighting-app/lighting-common/lighting-app.matter
Original file line number Diff line number Diff line change
Expand Up @@ -2977,7 +2977,7 @@ endpoint 1 {
ram attribute occupancy;
ram attribute occupancySensorType;
ram attribute occupancySensorTypeBitmap;
ram attribute featureMap default = 0;
callback attribute featureMap;
ram attribute clusterRevision default = 4;
}
}
Expand Down
2 changes: 1 addition & 1 deletion examples/placeholder/linux/apps/app1/config.matter
Original file line number Diff line number Diff line change
Expand Up @@ -9362,7 +9362,7 @@ endpoint 1 {
ram attribute physicalContactOccupiedToUnoccupiedDelay default = 0x00;
ram attribute physicalContactUnoccupiedToOccupiedDelay default = 0x00;
ram attribute physicalContactUnoccupiedToOccupiedThreshold default = 1;
ram attribute featureMap default = 0;
callback attribute featureMap;
callback attribute clusterRevision default = 4;
}
}
Expand Down
2 changes: 1 addition & 1 deletion examples/placeholder/linux/apps/app2/config.matter
Original file line number Diff line number Diff line change
Expand Up @@ -9301,7 +9301,7 @@ endpoint 1 {
ram attribute physicalContactOccupiedToUnoccupiedDelay default = 0x00;
ram attribute physicalContactUnoccupiedToOccupiedDelay default = 0x00;
ram attribute physicalContactUnoccupiedToOccupiedThreshold default = 1;
ram attribute featureMap default = 0;
callback attribute featureMap;
callback attribute clusterRevision default = 4;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1576,11 +1576,11 @@
{ ZAP_SIMPLE_DEFAULT(3), 0x0000FFFD, 2, ZAP_TYPE(INT16U), 0 }, /* ClusterRevision */ \
\
/* Endpoint: 1, Cluster: Occupancy Sensing (server) */ \
{ ZAP_EMPTY_DEFAULT(), 0x00000000, 1, ZAP_TYPE(BITMAP8), 0 }, /* Occupancy */ \
{ ZAP_EMPTY_DEFAULT(), 0x00000001, 1, ZAP_TYPE(ENUM8), 0 }, /* OccupancySensorType */ \
{ ZAP_EMPTY_DEFAULT(), 0x00000002, 1, ZAP_TYPE(BITMAP8), 0 }, /* OccupancySensorTypeBitmap */ \
{ ZAP_SIMPLE_DEFAULT(0), 0x0000FFFC, 4, ZAP_TYPE(BITMAP32), 0 }, /* FeatureMap */ \
{ ZAP_SIMPLE_DEFAULT(4), 0x0000FFFD, 2, ZAP_TYPE(INT16U), 0 }, /* ClusterRevision */ \
{ ZAP_EMPTY_DEFAULT(), 0x00000000, 1, ZAP_TYPE(BITMAP8), 0 }, /* Occupancy */ \
{ ZAP_EMPTY_DEFAULT(), 0x00000001, 1, ZAP_TYPE(ENUM8), 0 }, /* OccupancySensorType */ \
{ ZAP_EMPTY_DEFAULT(), 0x00000002, 1, ZAP_TYPE(BITMAP8), 0 }, /* OccupancySensorTypeBitmap */ \
{ ZAP_EMPTY_DEFAULT(), 0x0000FFFC, 4, ZAP_TYPE(BITMAP32), ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) }, /* FeatureMap */ \
{ ZAP_SIMPLE_DEFAULT(4), 0x0000FFFD, 2, ZAP_TYPE(INT16U), 0 }, /* ClusterRevision */ \
\
/* Endpoint: 1, Cluster: Carbon Monoxide Concentration Measurement (server) */ \
{ ZAP_EMPTY_DEFAULT(), 0x00000000, 4, ZAP_TYPE(SINGLE), \
Expand Down Expand Up @@ -2017,11 +2017,11 @@
{ ZAP_SIMPLE_DEFAULT(1), 0x0000FFFD, 2, ZAP_TYPE(INT16U), 0 }, /* ClusterRevision */ \
\
/* Endpoint: 2, Cluster: Occupancy Sensing (server) */ \
{ ZAP_EMPTY_DEFAULT(), 0x00000000, 1, ZAP_TYPE(BITMAP8), 0 }, /* Occupancy */ \
{ ZAP_EMPTY_DEFAULT(), 0x00000001, 1, ZAP_TYPE(ENUM8), 0 }, /* OccupancySensorType */ \
{ ZAP_EMPTY_DEFAULT(), 0x00000002, 1, ZAP_TYPE(BITMAP8), 0 }, /* OccupancySensorTypeBitmap */ \
{ ZAP_SIMPLE_DEFAULT(0), 0x0000FFFC, 4, ZAP_TYPE(BITMAP32), 0 }, /* FeatureMap */ \
{ ZAP_SIMPLE_DEFAULT(4), 0x0000FFFD, 2, ZAP_TYPE(INT16U), 0 }, /* ClusterRevision */ \
{ ZAP_EMPTY_DEFAULT(), 0x00000000, 1, ZAP_TYPE(BITMAP8), 0 }, /* Occupancy */ \
{ ZAP_EMPTY_DEFAULT(), 0x00000001, 1, ZAP_TYPE(ENUM8), 0 }, /* OccupancySensorType */ \
{ ZAP_EMPTY_DEFAULT(), 0x00000002, 1, ZAP_TYPE(BITMAP8), 0 }, /* OccupancySensorTypeBitmap */ \
{ ZAP_EMPTY_DEFAULT(), 0x0000FFFC, 4, ZAP_TYPE(BITMAP32), ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) }, /* FeatureMap */ \
{ ZAP_SIMPLE_DEFAULT(4), 0x0000FFFD, 2, ZAP_TYPE(INT16U), 0 }, /* ClusterRevision */ \
\
/* Endpoint: 65534, Cluster: Descriptor (server) */ \
{ ZAP_EMPTY_DEFAULT(), 0x00000000, 0, ZAP_TYPE(ARRAY), ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) }, /* DeviceTypeList */ \
Expand Down Expand Up @@ -3879,7 +3879,7 @@
.clusterId = 0x00000406, \
.attributes = ZAP_ATTRIBUTE_INDEX(762), \
.attributeCount = 5, \
.clusterSize = 9, \
.clusterSize = 5, \
.mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \
.functions = chipFuncArrayOccupancySensingServer, \
.acceptedCommandList = nullptr, \
Expand Down Expand Up @@ -4152,7 +4152,7 @@
.clusterId = 0x00000406, \
.attributes = ZAP_ATTRIBUTE_INDEX(1034), \
.attributeCount = 5, \
.clusterSize = 9, \
.clusterSize = 5, \
.mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \
.functions = chipFuncArrayOccupancySensingServer, \
.acceptedCommandList = nullptr, \
Expand Down Expand Up @@ -4195,7 +4195,7 @@
// This is an array of EmberAfEndpointType structures.
#define GENERATED_ENDPOINT_TYPES \
{ \
{ ZAP_CLUSTER_INDEX(0), 29, 349 }, { ZAP_CLUSTER_INDEX(29), 74, 3522 }, { ZAP_CLUSTER_INDEX(103), 7, 126 }, \
{ ZAP_CLUSTER_INDEX(0), 29, 349 }, { ZAP_CLUSTER_INDEX(29), 74, 3518 }, { ZAP_CLUSTER_INDEX(103), 7, 122 }, \
{ ZAP_CLUSTER_INDEX(110), 2, 0 }, \
}

Expand All @@ -4208,7 +4208,7 @@ static_assert(ATTRIBUTE_LARGEST <= CHIP_CONFIG_MAX_ATTRIBUTE_STORE_ELEMENT_SIZE,
#define ATTRIBUTE_SINGLETONS_SIZE (36)

// Total size of attribute storage
#define ATTRIBUTE_MAX_SIZE (3997)
#define ATTRIBUTE_MAX_SIZE (3989)

// Number of fixed endpoints
#define FIXED_ENDPOINT_COUNT (4)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -536,11 +536,11 @@
{ ZAP_SIMPLE_DEFAULT(7), 0x0000FFFD, 2, ZAP_TYPE(INT16U), 0 }, /* ClusterRevision */ \
\
/* Endpoint: 1, Cluster: Occupancy Sensing (server) */ \
{ ZAP_EMPTY_DEFAULT(), 0x00000000, 1, ZAP_TYPE(BITMAP8), 0 }, /* Occupancy */ \
{ ZAP_EMPTY_DEFAULT(), 0x00000001, 1, ZAP_TYPE(ENUM8), 0 }, /* OccupancySensorType */ \
{ ZAP_EMPTY_DEFAULT(), 0x00000002, 1, ZAP_TYPE(BITMAP8), 0 }, /* OccupancySensorTypeBitmap */ \
{ ZAP_SIMPLE_DEFAULT(0), 0x0000FFFC, 4, ZAP_TYPE(BITMAP32), 0 }, /* FeatureMap */ \
{ ZAP_SIMPLE_DEFAULT(4), 0x0000FFFD, 2, ZAP_TYPE(INT16U), 0 }, /* ClusterRevision */ \
{ ZAP_EMPTY_DEFAULT(), 0x00000000, 1, ZAP_TYPE(BITMAP8), 0 }, /* Occupancy */ \
{ ZAP_EMPTY_DEFAULT(), 0x00000001, 1, ZAP_TYPE(ENUM8), 0 }, /* OccupancySensorType */ \
{ ZAP_EMPTY_DEFAULT(), 0x00000002, 1, ZAP_TYPE(BITMAP8), 0 }, /* OccupancySensorTypeBitmap */ \
{ ZAP_EMPTY_DEFAULT(), 0x0000FFFC, 4, ZAP_TYPE(BITMAP32), ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) }, /* FeatureMap */ \
{ ZAP_SIMPLE_DEFAULT(4), 0x0000FFFD, 2, ZAP_TYPE(INT16U), 0 }, /* ClusterRevision */ \
}

// clang-format off
Expand Down Expand Up @@ -1170,7 +1170,7 @@
.clusterId = 0x00000406, \
.attributes = ZAP_ATTRIBUTE_INDEX(271), \
.attributeCount = 5, \
.clusterSize = 9, \
.clusterSize = 5, \
.mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \
.functions = chipFuncArrayOccupancySensingServer, \
.acceptedCommandList = nullptr, \
Expand All @@ -1187,7 +1187,7 @@
// This is an array of EmberAfEndpointType structures.
#define GENERATED_ENDPOINT_TYPES \
{ \
{ ZAP_CLUSTER_INDEX(0), 21, 223 }, { ZAP_CLUSTER_INDEX(21), 8, 121 }, \
{ ZAP_CLUSTER_INDEX(0), 21, 223 }, { ZAP_CLUSTER_INDEX(21), 8, 117 }, \
}

// Largest attribute size is needed for various buffers
Expand All @@ -1199,7 +1199,7 @@ static_assert(ATTRIBUTE_LARGEST <= CHIP_CONFIG_MAX_ATTRIBUTE_STORE_ELEMENT_SIZE,
#define ATTRIBUTE_SINGLETONS_SIZE (36)

// Total size of attribute storage
#define ATTRIBUTE_MAX_SIZE (344)
#define ATTRIBUTE_MAX_SIZE (340)

// Number of fixed endpoints
#define FIXED_ENDPOINT_COUNT (2)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,18 @@ Structs::HoldTimeLimitsStruct::Type
uint16_t sHoldTime[MATTER_DM_OCCUPANCY_SENSING_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT];
} // namespace

CHIP_ERROR OccupancySensingAttrAccess::Init()
CHIP_ERROR Instance::Init()
{
VerifyOrReturnError(registerAttributeAccessOverride(this), CHIP_ERROR_INCORRECT_STATE);
return CHIP_NO_ERROR;
}

void OccupancySensingAttrAccess::Shutdown()
void Instance::Shutdown()
{
unregisterAttributeAccessOverride(this);
}

CHIP_ERROR OccupancySensingAttrAccess::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder)
CHIP_ERROR Instance::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder)
{
VerifyOrDie(aPath.mClusterId == app::Clusters::OccupancySensing::Id);

Expand Down Expand Up @@ -88,7 +88,34 @@ CHIP_ERROR OccupancySensingAttrAccess::Read(const ConcreteReadAttributePath & aP
return CHIP_NO_ERROR;
}

bool OccupancySensingAttrAccess::HasFeature(Feature aFeature) const
CHIP_ERROR Instance::Write(const ConcreteDataAttributePath & aPath, AttributeValueDecoder & aDecoder)
{
VerifyOrDie(aPath.mClusterId == app::Clusters::OccupancySensing::Id);

switch (aPath.mAttributeId)
{
case Attributes::HoldTime::Id: {

uint16_t newHoldTime;

ReturnErrorOnFailure(aDecoder.Decode(newHoldTime));

Structs::HoldTimeLimitsStruct::Type * currHoldTimeLimits = GetHoldTimeLimitsForEndpoint(aPath.mEndpointId);
VerifyOrReturnError(currHoldTimeLimits != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(newHoldTime >= currHoldTimeLimits->holdTimeMin, CHIP_IM_GLOBAL_STATUS(ConstraintError));
VerifyOrReturnError(newHoldTime <= currHoldTimeLimits->holdTimeMax, CHIP_IM_GLOBAL_STATUS(ConstraintError));

return SetHoldTime(aPath.mEndpointId, newHoldTime);
}
default: {
break;
}
}

return CHIP_NO_ERROR;
}

bool Instance::HasFeature(Feature aFeature) const
{
return mFeature.Has(aFeature);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,22 @@ namespace app {
namespace Clusters {
namespace OccupancySensing {

class OccupancySensingAttrAccess : public AttributeAccessInterface
class Instance : public AttributeAccessInterface
{
public:
OccupancySensingAttrAccess(BitMask<Feature> aFeature) :
Instance(BitMask<Feature> aFeature) :
app::AttributeAccessInterface(Optional<EndpointId>::Missing(), app::Clusters::OccupancySensing::Id), mFeature(aFeature)
{}

~OccupancySensingAttrAccess() { Shutdown(); }
~Instance() { Shutdown(); }

CHIP_ERROR Init();
void Shutdown();

CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override;

CHIP_ERROR Write(const ConcreteDataAttributePath & aPath, AttributeValueDecoder & aDecoder) override;

bool HasFeature(Feature aFeature) const;

private:
Expand Down
2 changes: 1 addition & 1 deletion src/app/zap-templates/zcl/zcl-with-test-extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@
"ClientsSupportedPerFabric",
"MaximumCheckInBackOff"
],
"Occupancy Sensing": ["HoldTimeLimits"],
"Occupancy Sensing": ["HoldTimeLimits", "HoldTime", "FeatureMap"],
"Operational Credentials": [
"SupportedFabrics",
"CommissionedFabrics",
Expand Down
2 changes: 1 addition & 1 deletion src/app/zap-templates/zcl/zcl.json
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@
"ClientsSupportedPerFabric",
"MaximumCheckInBackOff"
],
"Occupancy Sensing": ["HoldTimeLimits"],
"Occupancy Sensing": ["HoldTimeLimits", "HoldTime", "FeatureMap"],
"Operational Credentials": [
"SupportedFabrics",
"CommissionedFabrics",
Expand Down
Loading
Loading