Skip to content

Commit 6971f61

Browse files
OliverFan1restyled-commitsbzbarsky-apple
authored andcommitted
[occupancy-sensing]Updated occupancy sensing cluster SDK & Sample app(all-clusters-app) implementation to Rev 5 (Matter 1.4) (project-chip#34293)
* [occupancy-sensing]Updated occupancy sensing cluster SDK & Sample app(all-clusters-app) implementation to Rev 5 (Matter 1.4) Signed-off-by: Oliver Fan <oliver.fan@nxp.com> * Restyled by whitespace * Restyled by clang-format * Apply suggestions from code review Update Copyright suggestions Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * Apply suggestions from code review, remove some dead code. Signed-off-by: Oliver Fan <oliver.fan@nxp.com> * Restyled by clang-format * Apply suggestions from code review * Avoid mixing code-backed and Attribute-store-backed attributes * Avoid global singletons to maintain state * Initialize the cluster from the application * Report features based on code, not on ZAP-configured values Signed-off-by: Oliver Fan <oliver.fan@nxp.com> * Restyled by whitespace * Restyled by clang-format * Restyled by clang-format * Restyled by clang-format * Restyled by clang-format * Update examples/all-clusters-app/all-clusters-common/src/occupancy-sensing-stub.cpp Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * Apply suggestions from code review change mHoldTimeLimitsStructs and mHoldTime to sHoldTimeLimitsStructs and sHoldTime put above two variables in an anonymous namespace Signed-off-by: Oliver Fan <oliver.fan@nxp.com> * Restyled by clang-format --------- Signed-off-by: Oliver Fan <oliver.fan@nxp.com> Co-authored-by: Restyled.io <commits@restyled.io> Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>
1 parent 3d9ada2 commit 6971f61

File tree

7 files changed

+327
-26
lines changed

7 files changed

+327
-26
lines changed

examples/all-clusters-app/all-clusters-common/all-clusters-app.matter

+8-4
Original file line numberDiff line numberDiff line change
@@ -8869,8 +8869,10 @@ endpoint 1 {
88698869
ram attribute occupancy;
88708870
ram attribute occupancySensorType;
88718871
ram attribute occupancySensorTypeBitmap;
8872-
ram attribute featureMap default = 0;
8873-
ram attribute clusterRevision default = 4;
8872+
ram attribute holdTime default = 10;
8873+
callback attribute holdTimeLimits;
8874+
ram attribute featureMap default = 0x01;
8875+
ram attribute clusterRevision default = 5;
88748876
}
88758877

88768878
server cluster CarbonMonoxideConcentrationMeasurement {
@@ -9338,8 +9340,10 @@ endpoint 2 {
93389340
ram attribute occupancy;
93399341
ram attribute occupancySensorType;
93409342
ram attribute occupancySensorTypeBitmap;
9341-
ram attribute featureMap default = 0;
9342-
ram attribute clusterRevision default = 4;
9343+
ram attribute holdTime default = 20;
9344+
callback attribute holdTimeLimits;
9345+
ram attribute featureMap default = 0x01;
9346+
ram attribute clusterRevision default = 5;
93439347
}
93449348
}
93459349
endpoint 3 {

examples/all-clusters-app/all-clusters-common/all-clusters-app.zap

+68-4
Original file line numberDiff line numberDiff line change
@@ -18984,6 +18984,38 @@
1898418984
"maxInterval": 65344,
1898518985
"reportableChange": 0
1898618986
},
18987+
{
18988+
"name": "HoldTime",
18989+
"code": 3,
18990+
"mfgCode": null,
18991+
"side": "server",
18992+
"type": "int16u",
18993+
"included": 1,
18994+
"storageOption": "RAM",
18995+
"singleton": 0,
18996+
"bounded": 0,
18997+
"defaultValue": "10",
18998+
"reportable": 1,
18999+
"minInterval": 1,
19000+
"maxInterval": 65534,
19001+
"reportableChange": 0
19002+
},
19003+
{
19004+
"name": "HoldTimeLimits",
19005+
"code": 4,
19006+
"mfgCode": null,
19007+
"side": "server",
19008+
"type": "HoldTimeLimitsStruct",
19009+
"included": 1,
19010+
"storageOption": "External",
19011+
"singleton": 0,
19012+
"bounded": 0,
19013+
"defaultValue": null,
19014+
"reportable": 1,
19015+
"minInterval": 1,
19016+
"maxInterval": 65534,
19017+
"reportableChange": 0
19018+
},
1898719019
{
1898819020
"name": "FeatureMap",
1898919021
"code": 65532,
@@ -18994,7 +19026,7 @@
1899419026
"storageOption": "RAM",
1899519027
"singleton": 0,
1899619028
"bounded": 0,
18997-
"defaultValue": "0",
19029+
"defaultValue": "0x01",
1899819030
"reportable": 1,
1899919031
"minInterval": 1,
1900019032
"maxInterval": 65534,
@@ -19010,7 +19042,7 @@
1901019042
"storageOption": "RAM",
1901119043
"singleton": 0,
1901219044
"bounded": 0,
19013-
"defaultValue": "4",
19045+
"defaultValue": "5",
1901419046
"reportable": 1,
1901519047
"minInterval": 0,
1901619048
"maxInterval": 65344,
@@ -25013,6 +25045,38 @@
2501325045
"maxInterval": 65344,
2501425046
"reportableChange": 0
2501525047
},
25048+
{
25049+
"name": "HoldTime",
25050+
"code": 3,
25051+
"mfgCode": null,
25052+
"side": "server",
25053+
"type": "int16u",
25054+
"included": 1,
25055+
"storageOption": "RAM",
25056+
"singleton": 0,
25057+
"bounded": 0,
25058+
"defaultValue": "20",
25059+
"reportable": 1,
25060+
"minInterval": 1,
25061+
"maxInterval": 65534,
25062+
"reportableChange": 0
25063+
},
25064+
{
25065+
"name": "HoldTimeLimits",
25066+
"code": 4,
25067+
"mfgCode": null,
25068+
"side": "server",
25069+
"type": "HoldTimeLimitsStruct",
25070+
"included": 1,
25071+
"storageOption": "External",
25072+
"singleton": 0,
25073+
"bounded": 0,
25074+
"defaultValue": null,
25075+
"reportable": 1,
25076+
"minInterval": 1,
25077+
"maxInterval": 65534,
25078+
"reportableChange": 0
25079+
},
2501625080
{
2501725081
"name": "FeatureMap",
2501825082
"code": 65532,
@@ -25023,7 +25087,7 @@
2502325087
"storageOption": "RAM",
2502425088
"singleton": 0,
2502525089
"bounded": 0,
25026-
"defaultValue": "0",
25090+
"defaultValue": "0x01",
2502725091
"reportable": 1,
2502825092
"minInterval": 1,
2502925093
"maxInterval": 65534,
@@ -25039,7 +25103,7 @@
2503925103
"storageOption": "RAM",
2504025104
"singleton": 0,
2504125105
"bounded": 0,
25042-
"defaultValue": "4",
25106+
"defaultValue": "5",
2504325107
"reportable": 1,
2504425108
"minInterval": 0,
2504525109
"maxInterval": 65344,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
*
3+
* Copyright (c) 2024 Project CHIP Authors
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#include <app/CommandHandler.h>
19+
#include <app/clusters/occupancy-sensor-server/occupancy-hal.h>
20+
#include <app/clusters/occupancy-sensor-server/occupancy-sensor-server.h>
21+
#include <platform/CHIPDeviceLayer.h>
22+
23+
using namespace chip;
24+
using namespace chip::app::Clusters;
25+
using namespace chip::app::Clusters::OccupancySensing;
26+
using namespace chip::app::Clusters::OccupancySensing::Structs;
27+
using namespace chip::DeviceLayer;
28+
29+
using chip::Protocols::InteractionModel::Status;
30+
31+
static std::unique_ptr<OccupancySensingAttrAccess>
32+
gAttrAccess[MATTER_DM_OCCUPANCY_SENSING_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT];
33+
34+
void emberAfOccupancySensingClusterInitCallback(EndpointId endpointId)
35+
{
36+
VerifyOrDie(!gAttrAccess[endpointId]);
37+
38+
gAttrAccess[endpointId] = std::make_unique<OccupancySensingAttrAccess>(
39+
BitMask<OccupancySensing::Feature, uint32_t>(OccupancySensing::Feature::kOther));
40+
41+
OccupancySensing::Structs::HoldTimeLimitsStruct::Type holdTimeLimits = {
42+
.holdTimeMin = 1,
43+
.holdTimeMax = 300,
44+
.holdTimeDefault = 10,
45+
};
46+
47+
uint16_t holdTime = 10;
48+
49+
if (gAttrAccess[endpointId])
50+
{
51+
gAttrAccess[endpointId]->Init();
52+
53+
SetHoldTimeLimits(endpointId, holdTimeLimits);
54+
55+
SetHoldTime(endpointId, holdTime);
56+
}
57+
}

examples/all-clusters-app/linux/BUILD.gn

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ source_set("chip-all-clusters-common") {
4646
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/laundry-washer-controls-delegate-impl.cpp",
4747
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/laundry-washer-mode.cpp",
4848
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/microwave-oven-mode.cpp",
49+
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/occupancy-sensing-stub.cpp",
4950
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/operational-state-delegate-impl.cpp",
5051
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/oven-modes.cpp",
5152
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/oven-operational-state-delegate.cpp",

src/app/clusters/occupancy-sensor-server/occupancy-sensor-server.cpp

+149-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
*
3-
* Copyright (c) 2020 Project CHIP Authors
3+
* Copyright (c) 2020-2024 Project CHIP Authors
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
66
* you may not use this file except in compliance with the License.
@@ -16,12 +16,158 @@
1616
*/
1717

1818
#include "occupancy-sensor-server.h"
19+
#include "occupancy-hal.h"
1920

20-
#include <app-common/zap-generated/attributes/Accessors.h>
21+
#include <app/AttributeAccessInterfaceRegistry.h>
22+
#include <app/EventLogging.h>
23+
#include <app/data-model/Encode.h>
24+
#include <app/reporting/reporting.h>
25+
#include <app/util/attribute-storage.h>
26+
#include <lib/core/CHIPError.h>
2127

22-
#include "occupancy-hal.h"
28+
using chip::Protocols::InteractionModel::Status;
29+
30+
namespace chip {
31+
namespace app {
32+
namespace Clusters {
33+
namespace OccupancySensing {
34+
35+
namespace {
36+
Structs::HoldTimeLimitsStruct::Type
37+
sHoldTimeLimitsStructs[MATTER_DM_OCCUPANCY_SENSING_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT];
38+
39+
uint16_t sHoldTime[MATTER_DM_OCCUPANCY_SENSING_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT];
40+
} // namespace
41+
42+
CHIP_ERROR OccupancySensingAttrAccess::Init()
43+
{
44+
VerifyOrReturnError(registerAttributeAccessOverride(this), CHIP_ERROR_INCORRECT_STATE);
45+
return CHIP_NO_ERROR;
46+
}
47+
48+
void OccupancySensingAttrAccess::Shutdown()
49+
{
50+
unregisterAttributeAccessOverride(this);
51+
}
52+
53+
CHIP_ERROR OccupancySensingAttrAccess::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder)
54+
{
55+
VerifyOrDie(aPath.mClusterId == app::Clusters::OccupancySensing::Id);
56+
57+
switch (aPath.mAttributeId)
58+
{
59+
case Attributes::FeatureMap::Id:
60+
ReturnErrorOnFailure(aEncoder.Encode(mFeature));
61+
break;
62+
case Attributes::HoldTime::Id: {
63+
64+
uint16_t * holdTime = GetHoldTimeForEndpoint(aPath.mEndpointId);
65+
66+
if (holdTime == nullptr)
67+
{
68+
return CHIP_ERROR_NOT_FOUND;
69+
}
70+
71+
return aEncoder.Encode(*holdTime);
72+
}
73+
case Attributes::HoldTimeLimits::Id: {
74+
75+
Structs::HoldTimeLimitsStruct::Type * holdTimeLimitsStruct = GetHoldTimeLimitsForEndpoint(aPath.mEndpointId);
76+
77+
if (holdTimeLimitsStruct == nullptr)
78+
{
79+
return CHIP_ERROR_NOT_FOUND;
80+
}
81+
82+
return aEncoder.Encode(*holdTimeLimitsStruct);
83+
}
84+
default:
85+
return CHIP_NO_ERROR;
86+
}
87+
88+
return CHIP_NO_ERROR;
89+
}
90+
91+
bool OccupancySensingAttrAccess::HasFeature(Feature aFeature) const
92+
{
93+
return mFeature.Has(aFeature);
94+
}
95+
96+
Structs::HoldTimeLimitsStruct::Type * GetHoldTimeLimitsForEndpoint(EndpointId endpoint)
97+
{
98+
auto index = emberAfGetClusterServerEndpointIndex(endpoint, app::Clusters::OccupancySensing::Id,
99+
MATTER_DM_OCCUPANCY_SENSING_CLUSTER_SERVER_ENDPOINT_COUNT);
100+
101+
if (index == kEmberInvalidEndpointIndex)
102+
{
103+
return nullptr;
104+
}
105+
106+
if (index >= ArraySize(sHoldTimeLimitsStructs))
107+
{
108+
ChipLogError(NotSpecified, "Internal error: invalid/unexpected hold time limits index.");
109+
return nullptr;
110+
}
111+
return &sHoldTimeLimitsStructs[index];
112+
}
113+
114+
CHIP_ERROR SetHoldTimeLimits(EndpointId endpointId, const Structs::HoldTimeLimitsStruct::Type & holdTimeLimits)
115+
{
116+
117+
VerifyOrReturnError(kInvalidEndpointId != endpointId, CHIP_ERROR_INVALID_ARGUMENT);
118+
119+
Structs::HoldTimeLimitsStruct::Type * holdTimeLimitsForEndpoint = GetHoldTimeLimitsForEndpoint(endpointId);
120+
VerifyOrReturnError(holdTimeLimitsForEndpoint != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
121+
122+
holdTimeLimitsForEndpoint->holdTimeMin = holdTimeLimits.holdTimeMin;
123+
holdTimeLimitsForEndpoint->holdTimeMax = holdTimeLimits.holdTimeMax;
124+
holdTimeLimitsForEndpoint->holdTimeDefault = holdTimeLimits.holdTimeDefault;
125+
126+
MatterReportingAttributeChangeCallback(endpointId, OccupancySensing::Id, Attributes::HoldTimeLimits::Id);
127+
128+
return CHIP_NO_ERROR;
129+
}
130+
131+
uint16_t * GetHoldTimeForEndpoint(EndpointId endpoint)
132+
{
133+
auto index = emberAfGetClusterServerEndpointIndex(endpoint, app::Clusters::OccupancySensing::Id,
134+
MATTER_DM_OCCUPANCY_SENSING_CLUSTER_SERVER_ENDPOINT_COUNT);
135+
136+
if (index == kEmberInvalidEndpointIndex)
137+
{
138+
return nullptr;
139+
}
140+
141+
if (index >= ArraySize(sHoldTimeLimitsStructs))
142+
{
143+
ChipLogError(NotSpecified, "Internal error: invalid/unexpected hold time index.");
144+
return nullptr;
145+
}
146+
return &sHoldTime[index];
147+
}
148+
149+
CHIP_ERROR SetHoldTime(EndpointId endpointId, const uint16_t & holdTime)
150+
{
151+
VerifyOrReturnError(kInvalidEndpointId != endpointId, CHIP_ERROR_INVALID_ARGUMENT);
152+
153+
uint16_t * holdTimeForEndpoint = GetHoldTimeForEndpoint(endpointId);
154+
VerifyOrReturnError(holdTimeForEndpoint != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
155+
156+
*holdTimeForEndpoint = holdTime;
157+
158+
MatterReportingAttributeChangeCallback(endpointId, OccupancySensing::Id, Attributes::HoldTime::Id);
159+
160+
return CHIP_NO_ERROR;
161+
}
162+
163+
} // namespace OccupancySensing
164+
} // namespace Clusters
165+
} // namespace app
166+
} // namespace chip
23167

24168
using namespace chip;
169+
using namespace chip::app;
170+
using namespace chip::app::Clusters;
25171
using namespace chip::app::Clusters::OccupancySensing;
26172

27173
//******************************************************************************
@@ -59,8 +205,6 @@ void emberAfOccupancySensingClusterServerInitCallback(EndpointId endpoint)
59205
break;
60206
}
61207
Attributes::OccupancySensorTypeBitmap::Set(endpoint, deviceTypeBitmap);
62-
63-
emberAfPluginOccupancyClusterServerPostInitCallback(endpoint);
64208
}
65209

66210
//******************************************************************************
@@ -82,8 +226,6 @@ void halOccupancyStateChangedCallback(EndpointId endpoint, HalOccupancyState occ
82226
Attributes::Occupancy::Set(endpoint, occupancyState);
83227
}
84228

85-
void emberAfPluginOccupancyClusterServerPostInitCallback(EndpointId endpoint) {}
86-
87229
HalOccupancySensorType __attribute__((weak)) halOccupancyGetSensorType(EndpointId endpoint)
88230
{
89231
return HAL_OCCUPANCY_SENSOR_TYPE_PIR;

0 commit comments

Comments
 (0)