Skip to content

Commit

Permalink
[occupancy-sensing]Updated occupancy sensing cluster SDK & Sample app…
Browse files Browse the repository at this point in the history
…(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 <[email protected]>

* Restyled by whitespace

* Restyled by clang-format

* Apply suggestions from code review

Update Copyright suggestions

Co-authored-by: Boris Zbarsky <[email protected]>

* Apply suggestions from code review, remove some dead code.

Signed-off-by: Oliver Fan <[email protected]>

* 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 <[email protected]>

* 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 <[email protected]>

* 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 <[email protected]>

* Restyled by clang-format

---------

Signed-off-by: Oliver Fan <[email protected]>
Co-authored-by: Restyled.io <[email protected]>
Co-authored-by: Boris Zbarsky <[email protected]>
  • Loading branch information
3 people authored and j-ororke committed Jul 31, 2024
1 parent 0878757 commit 6046f1e
Show file tree
Hide file tree
Showing 7 changed files with 327 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8869,8 +8869,10 @@ endpoint 1 {
ram attribute occupancy;
ram attribute occupancySensorType;
ram attribute occupancySensorTypeBitmap;
ram attribute featureMap default = 0;
ram attribute clusterRevision default = 4;
ram attribute holdTime default = 10;
callback attribute holdTimeLimits;
ram attribute featureMap default = 0x01;
ram attribute clusterRevision default = 5;
}

server cluster CarbonMonoxideConcentrationMeasurement {
Expand Down Expand Up @@ -9338,8 +9340,10 @@ endpoint 2 {
ram attribute occupancy;
ram attribute occupancySensorType;
ram attribute occupancySensorTypeBitmap;
ram attribute featureMap default = 0;
ram attribute clusterRevision default = 4;
ram attribute holdTime default = 20;
callback attribute holdTimeLimits;
ram attribute featureMap default = 0x01;
ram attribute clusterRevision default = 5;
}
}
endpoint 3 {
Expand Down
72 changes: 68 additions & 4 deletions examples/all-clusters-app/all-clusters-common/all-clusters-app.zap
Original file line number Diff line number Diff line change
Expand Up @@ -18984,6 +18984,38 @@
"maxInterval": 65344,
"reportableChange": 0
},
{
"name": "HoldTime",
"code": 3,
"mfgCode": null,
"side": "server",
"type": "int16u",
"included": 1,
"storageOption": "RAM",
"singleton": 0,
"bounded": 0,
"defaultValue": "10",
"reportable": 1,
"minInterval": 1,
"maxInterval": 65534,
"reportableChange": 0
},
{
"name": "HoldTimeLimits",
"code": 4,
"mfgCode": null,
"side": "server",
"type": "HoldTimeLimitsStruct",
"included": 1,
"storageOption": "External",
"singleton": 0,
"bounded": 0,
"defaultValue": null,
"reportable": 1,
"minInterval": 1,
"maxInterval": 65534,
"reportableChange": 0
},
{
"name": "FeatureMap",
"code": 65532,
Expand All @@ -18994,7 +19026,7 @@
"storageOption": "RAM",
"singleton": 0,
"bounded": 0,
"defaultValue": "0",
"defaultValue": "0x01",
"reportable": 1,
"minInterval": 1,
"maxInterval": 65534,
Expand All @@ -19010,7 +19042,7 @@
"storageOption": "RAM",
"singleton": 0,
"bounded": 0,
"defaultValue": "4",
"defaultValue": "5",
"reportable": 1,
"minInterval": 0,
"maxInterval": 65344,
Expand Down Expand Up @@ -25013,6 +25045,38 @@
"maxInterval": 65344,
"reportableChange": 0
},
{
"name": "HoldTime",
"code": 3,
"mfgCode": null,
"side": "server",
"type": "int16u",
"included": 1,
"storageOption": "RAM",
"singleton": 0,
"bounded": 0,
"defaultValue": "20",
"reportable": 1,
"minInterval": 1,
"maxInterval": 65534,
"reportableChange": 0
},
{
"name": "HoldTimeLimits",
"code": 4,
"mfgCode": null,
"side": "server",
"type": "HoldTimeLimitsStruct",
"included": 1,
"storageOption": "External",
"singleton": 0,
"bounded": 0,
"defaultValue": null,
"reportable": 1,
"minInterval": 1,
"maxInterval": 65534,
"reportableChange": 0
},
{
"name": "FeatureMap",
"code": 65532,
Expand All @@ -25023,7 +25087,7 @@
"storageOption": "RAM",
"singleton": 0,
"bounded": 0,
"defaultValue": "0",
"defaultValue": "0x01",
"reportable": 1,
"minInterval": 1,
"maxInterval": 65534,
Expand All @@ -25039,7 +25103,7 @@
"storageOption": "RAM",
"singleton": 0,
"bounded": 0,
"defaultValue": "4",
"defaultValue": "5",
"reportable": 1,
"minInterval": 0,
"maxInterval": 65344,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
*
* 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.
* 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/CommandHandler.h>
#include <app/clusters/occupancy-sensor-server/occupancy-hal.h>
#include <app/clusters/occupancy-sensor-server/occupancy-sensor-server.h>
#include <platform/CHIPDeviceLayer.h>

using namespace chip;
using namespace chip::app::Clusters;
using namespace chip::app::Clusters::OccupancySensing;
using namespace chip::app::Clusters::OccupancySensing::Structs;
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];

void emberAfOccupancySensingClusterInitCallback(EndpointId endpointId)
{
VerifyOrDie(!gAttrAccess[endpointId]);

gAttrAccess[endpointId] = std::make_unique<OccupancySensingAttrAccess>(
BitMask<OccupancySensing::Feature, uint32_t>(OccupancySensing::Feature::kOther));

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

uint16_t holdTime = 10;

if (gAttrAccess[endpointId])
{
gAttrAccess[endpointId]->Init();

SetHoldTimeLimits(endpointId, holdTimeLimits);

SetHoldTime(endpointId, holdTime);
}
}
1 change: 1 addition & 0 deletions examples/all-clusters-app/linux/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ source_set("chip-all-clusters-common") {
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/laundry-washer-controls-delegate-impl.cpp",
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/laundry-washer-mode.cpp",
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/microwave-oven-mode.cpp",
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/occupancy-sensing-stub.cpp",
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/operational-state-delegate-impl.cpp",
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/oven-modes.cpp",
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/oven-operational-state-delegate.cpp",
Expand Down
156 changes: 149 additions & 7 deletions src/app/clusters/occupancy-sensor-server/occupancy-sensor-server.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
*
* Copyright (c) 2020 Project CHIP Authors
* Copyright (c) 2020-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 @@ -16,12 +16,158 @@
*/

#include "occupancy-sensor-server.h"
#include "occupancy-hal.h"

#include <app-common/zap-generated/attributes/Accessors.h>
#include <app/AttributeAccessInterfaceRegistry.h>
#include <app/EventLogging.h>
#include <app/data-model/Encode.h>
#include <app/reporting/reporting.h>
#include <app/util/attribute-storage.h>
#include <lib/core/CHIPError.h>

#include "occupancy-hal.h"
using chip::Protocols::InteractionModel::Status;

namespace chip {
namespace app {
namespace Clusters {
namespace OccupancySensing {

namespace {
Structs::HoldTimeLimitsStruct::Type
sHoldTimeLimitsStructs[MATTER_DM_OCCUPANCY_SENSING_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT];

uint16_t sHoldTime[MATTER_DM_OCCUPANCY_SENSING_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT];
} // namespace

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

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

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

switch (aPath.mAttributeId)
{
case Attributes::FeatureMap::Id:
ReturnErrorOnFailure(aEncoder.Encode(mFeature));
break;
case Attributes::HoldTime::Id: {

uint16_t * holdTime = GetHoldTimeForEndpoint(aPath.mEndpointId);

if (holdTime == nullptr)
{
return CHIP_ERROR_NOT_FOUND;
}

return aEncoder.Encode(*holdTime);
}
case Attributes::HoldTimeLimits::Id: {

Structs::HoldTimeLimitsStruct::Type * holdTimeLimitsStruct = GetHoldTimeLimitsForEndpoint(aPath.mEndpointId);

if (holdTimeLimitsStruct == nullptr)
{
return CHIP_ERROR_NOT_FOUND;
}

return aEncoder.Encode(*holdTimeLimitsStruct);
}
default:
return CHIP_NO_ERROR;
}

return CHIP_NO_ERROR;
}

bool OccupancySensingAttrAccess::HasFeature(Feature aFeature) const
{
return mFeature.Has(aFeature);
}

Structs::HoldTimeLimitsStruct::Type * GetHoldTimeLimitsForEndpoint(EndpointId endpoint)
{
auto index = emberAfGetClusterServerEndpointIndex(endpoint, app::Clusters::OccupancySensing::Id,
MATTER_DM_OCCUPANCY_SENSING_CLUSTER_SERVER_ENDPOINT_COUNT);

if (index == kEmberInvalidEndpointIndex)
{
return nullptr;
}

if (index >= ArraySize(sHoldTimeLimitsStructs))
{
ChipLogError(NotSpecified, "Internal error: invalid/unexpected hold time limits index.");
return nullptr;
}
return &sHoldTimeLimitsStructs[index];
}

CHIP_ERROR SetHoldTimeLimits(EndpointId endpointId, const Structs::HoldTimeLimitsStruct::Type & holdTimeLimits)
{

VerifyOrReturnError(kInvalidEndpointId != endpointId, CHIP_ERROR_INVALID_ARGUMENT);

Structs::HoldTimeLimitsStruct::Type * holdTimeLimitsForEndpoint = GetHoldTimeLimitsForEndpoint(endpointId);
VerifyOrReturnError(holdTimeLimitsForEndpoint != nullptr, CHIP_ERROR_INVALID_ARGUMENT);

holdTimeLimitsForEndpoint->holdTimeMin = holdTimeLimits.holdTimeMin;
holdTimeLimitsForEndpoint->holdTimeMax = holdTimeLimits.holdTimeMax;
holdTimeLimitsForEndpoint->holdTimeDefault = holdTimeLimits.holdTimeDefault;

MatterReportingAttributeChangeCallback(endpointId, OccupancySensing::Id, Attributes::HoldTimeLimits::Id);

return CHIP_NO_ERROR;
}

uint16_t * GetHoldTimeForEndpoint(EndpointId endpoint)
{
auto index = emberAfGetClusterServerEndpointIndex(endpoint, app::Clusters::OccupancySensing::Id,
MATTER_DM_OCCUPANCY_SENSING_CLUSTER_SERVER_ENDPOINT_COUNT);

if (index == kEmberInvalidEndpointIndex)
{
return nullptr;
}

if (index >= ArraySize(sHoldTimeLimitsStructs))
{
ChipLogError(NotSpecified, "Internal error: invalid/unexpected hold time index.");
return nullptr;
}
return &sHoldTime[index];
}

CHIP_ERROR SetHoldTime(EndpointId endpointId, const uint16_t & holdTime)
{
VerifyOrReturnError(kInvalidEndpointId != endpointId, CHIP_ERROR_INVALID_ARGUMENT);

uint16_t * holdTimeForEndpoint = GetHoldTimeForEndpoint(endpointId);
VerifyOrReturnError(holdTimeForEndpoint != nullptr, CHIP_ERROR_INVALID_ARGUMENT);

*holdTimeForEndpoint = holdTime;

MatterReportingAttributeChangeCallback(endpointId, OccupancySensing::Id, Attributes::HoldTime::Id);

return CHIP_NO_ERROR;
}

} // namespace OccupancySensing
} // namespace Clusters
} // namespace app
} // namespace chip

using namespace chip;
using namespace chip::app;
using namespace chip::app::Clusters;
using namespace chip::app::Clusters::OccupancySensing;

//******************************************************************************
Expand Down Expand Up @@ -59,8 +205,6 @@ void emberAfOccupancySensingClusterServerInitCallback(EndpointId endpoint)
break;
}
Attributes::OccupancySensorTypeBitmap::Set(endpoint, deviceTypeBitmap);

emberAfPluginOccupancyClusterServerPostInitCallback(endpoint);
}

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

void emberAfPluginOccupancyClusterServerPostInitCallback(EndpointId endpoint) {}

HalOccupancySensorType __attribute__((weak)) halOccupancyGetSensorType(EndpointId endpoint)
{
return HAL_OCCUPANCY_SENSOR_TYPE_PIR;
Expand Down
Loading

0 comments on commit 6046f1e

Please sign in to comment.