From b096c88aab8ad3bf1165222ec947aaa333ef7bbb Mon Sep 17 00:00:00 2001 From: eahove Date: Fri, 22 Dec 2023 09:06:41 -0600 Subject: [PATCH] Laundry dryer controls cluster sdk (#30285) * Steps 1.1, 1.2 * update cluster list and build.gn This reverts commit feabe0b2fe2fafbd9dcd0a1a1f2d6cd6c2d5c9dd. run zap and update build, clusters list zap_regen_all & build chip-tool regen zap updated zap and regen updated zap and regen zap_regen_all & build chip-tool Revert "regen zap" This reverts commit f259abfaf960804273ff45a6ab3c16aaaae0622e. * controller-clusters.zap and regen_all * setting optional=false for clusters * zap_regen_all * run zap and update build, clusters list * zap_regen_all & build chip-tool * Fisrt Pass at SDK code * SDK is building and running * now registers laundry controls delegate added function definitions to override weak definitions that do nothing. * adding the cluster to preAttributeChange list * Restyled by clang-format * Restyled by gn * regenerated all zap * reverting submodule changes * regenerate_zap_all * update all-clusters zap * Updated cluster-enums.h path * Revert "run zap and update build, clusters list" This reverts commit 17642c9951b85d230ee5b1a9b4f4c7988d5b71e2. * Restyled by clang-format * update zap * Attribute fix for SelectedDrynessLevel * Added Attribute in zcl.json * Revert "Added Attribute in zcl.json" This reverts commit 4ee377fa04fb0ea942d244fcaff92a699bb398c0. * adding SupportedDrynessLevels to JSON bits * Updated zcl test json * Fix Dryer delegate init on Linux all-clusters * Restyled by clang-format * Added static assert for Enum and removed dryer from .json bits --------- Co-authored-by: Restyled.io Co-authored-by: OmAmbalkar <36728913+OmAmbalkar@users.noreply.github.com> Co-authored-by: tennessee.carmelveilleux@gmail.com --- .../all-clusters-app.matter | 33 ++++ .../all-clusters-common/all-clusters-app.zap | 141 ++++++++++++- .../laundry-dryer-controls-delegate-impl.h | 53 +++++ .../laundry-dryer-controls-delegate-impl.cpp | 40 ++++ .../esp32/main/CMakeLists.txt | 3 +- examples/all-clusters-app/esp32/main/main.cpp | 18 ++ examples/all-clusters-app/linux/BUILD.gn | 1 + .../all-clusters-app/linux/main-common.cpp | 8 + .../laundry-dryer-controls-delegate.h | 49 +++++ .../laundry-dryer-controls-server.cpp | 187 ++++++++++++++++++ .../laundry-dryer-controls-server.h | 62 ++++++ src/app/common/templates/config-data.yaml | 1 + src/app/zap_cluster_list.json | 1 + 13 files changed, 595 insertions(+), 2 deletions(-) create mode 100644 examples/all-clusters-app/all-clusters-common/include/laundry-dryer-controls-delegate-impl.h create mode 100644 examples/all-clusters-app/all-clusters-common/src/laundry-dryer-controls-delegate-impl.cpp create mode 100644 src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-delegate.h create mode 100644 src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-server.cpp create mode 100644 src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-server.h diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter index 59090b662d6486..71bb489e6a3c21 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter @@ -2785,6 +2785,28 @@ cluster BooleanState = 69 { readonly attribute int16u clusterRevision = 65533; } +/** This cluster supports remotely monitoring and controling the different typs of + functionality available to a drying device, such as a laundry dryer. */ +cluster LaundryDryerControls = 74 { + revision 1; // NOTE: Default/not specifically set + + enum DrynessLevelEnum : enum8 { + kLow = 0; + kNormal = 1; + kExtra = 2; + kMax = 3; + } + + readonly attribute DrynessLevelEnum supportedDrynessLevels[] = 0; + attribute nullable DrynessLevelEnum selectedDrynessLevel = 1; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + /** Attributes and commands for selecting a mode from a list of supported options. */ cluster ModeSelect = 80 { revision 2; @@ -7038,6 +7060,17 @@ endpoint 1 { ram attribute clusterRevision default = 1; } + server cluster LaundryDryerControls { + callback attribute supportedDrynessLevels; + ram attribute selectedDrynessLevel; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + server cluster ModeSelect { ram attribute description default = "Coffee"; ram attribute standardNamespace default = 0; diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap index 6f35331ee14640..8f1d73386c7465 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap @@ -8408,6 +8408,144 @@ } ] }, + { + "name": "Laundry Dryer Controls", + "code": 74, + "mfgCode": null, + "define": "LAUNDRY_DRYER_CONTROLS_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "SupportedDrynessLevels", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SelectedDrynessLevel", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "DrynessLevelEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, { "name": "Mode Select", "code": 80, @@ -22522,4 +22660,5 @@ } ], "log": [] -} \ No newline at end of file +} + diff --git a/examples/all-clusters-app/all-clusters-common/include/laundry-dryer-controls-delegate-impl.h b/examples/all-clusters-app/all-clusters-common/include/laundry-dryer-controls-delegate-impl.h new file mode 100644 index 00000000000000..898cf8806f4111 --- /dev/null +++ b/examples/all-clusters-app/all-clusters-common/include/laundry-dryer-controls-delegate-impl.h @@ -0,0 +1,53 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * 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. + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace LaundryDryerControls { + +/** + * The application delegate to statically define the options. + */ + +class LaundryDryerControlDelegate : public Delegate +{ + static const DrynessLevelEnum supportedDrynessLevelOptions[]; + static LaundryDryerControlDelegate instance; + +public: + CHIP_ERROR GetSupportedDrynessLevelAtIndex(size_t index, DrynessLevelEnum & supportedDrynessLevel); + + LaundryDryerControlDelegate() = default; + ~LaundryDryerControlDelegate() = default; + + static inline LaundryDryerControlDelegate & getLaundryDryerControlDelegate() { return instance; } +}; + +} // namespace LaundryDryerControls +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/all-clusters-app/all-clusters-common/src/laundry-dryer-controls-delegate-impl.cpp b/examples/all-clusters-app/all-clusters-common/src/laundry-dryer-controls-delegate-impl.cpp new file mode 100644 index 00000000000000..d404680f2a87d2 --- /dev/null +++ b/examples/all-clusters-app/all-clusters-common/src/laundry-dryer-controls-delegate-impl.cpp @@ -0,0 +1,40 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * 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 +#include +#include + +using namespace chip; +using namespace chip::app::Clusters::LaundryDryerControls; + +const DrynessLevelEnum LaundryDryerControlDelegate::supportedDrynessLevelOptions[] = { DrynessLevelEnum::kLow, + DrynessLevelEnum::kNormal, + DrynessLevelEnum::kMax }; + +LaundryDryerControlDelegate LaundryDryerControlDelegate::instance; + +// TODO: Add EndpointId to the API so that different values per endpoint may be possible in some implementations. +CHIP_ERROR LaundryDryerControlDelegate::GetSupportedDrynessLevelAtIndex(size_t index, DrynessLevelEnum & supportedDrynessLevel) +{ + if (index >= ArraySize(supportedDrynessLevelOptions)) + { + return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; + } + supportedDrynessLevel = supportedDrynessLevelOptions[index]; + return CHIP_NO_ERROR; +} diff --git a/examples/all-clusters-app/esp32/main/CMakeLists.txt b/examples/all-clusters-app/esp32/main/CMakeLists.txt index e8851aa5a4d3d5..d1b795e47d1e99 100644 --- a/examples/all-clusters-app/esp32/main/CMakeLists.txt +++ b/examples/all-clusters-app/esp32/main/CMakeLists.txt @@ -86,7 +86,8 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/temperature-control-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/time-synchronization-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/dishwasher-alarm-server" - "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/laundry-washer-controls-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/laundry-washer-controls-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/laundry-dryer-controls-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/all-clusters-app/all-clusters-common/src" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/electrical-energy-measurement-server" ) diff --git a/examples/all-clusters-app/esp32/main/main.cpp b/examples/all-clusters-app/esp32/main/main.cpp index 9972f95b95f546..4893cf1b8f1475 100644 --- a/examples/all-clusters-app/esp32/main/main.cpp +++ b/examples/all-clusters-app/esp32/main/main.cpp @@ -133,6 +133,24 @@ static void InitServer(intptr_t context) app::Clusters::TemperatureControl::SetInstance(&sAppSupportedTemperatureLevelsDelegate); } +// #include +#include +#include + +using namespace chip::app::Clusters::LaundryWasherControls; +void emberAfLaundryWasherControlsClusterInitCallback(EndpointId endpoint) +{ + LaundryWasherControlsServer::SetDefaultDelegate(1, &LaundryWasherControlDelegate::getLaundryWasherControlDelegate()); +} + +#include +#include +using namespace chip::app::Clusters::LaundryDryerControls; +void emberAfLaundryDryerControlsClusterInitCallback(EndpointId endpoint) +{ + LaundryDryerControlsServer::SetDefaultDelegate(endpoint, &LaundryDryerControlDelegate::getLaundryDryerControlDelegate()); +} + extern "C" void app_main() { // Initialize the ESP NVS layer. diff --git a/examples/all-clusters-app/linux/BUILD.gn b/examples/all-clusters-app/linux/BUILD.gn index af9414529ca76e..6feba8becbe31b 100644 --- a/examples/all-clusters-app/linux/BUILD.gn +++ b/examples/all-clusters-app/linux/BUILD.gn @@ -29,6 +29,7 @@ source_set("chip-all-clusters-common") { "${chip_root}/examples/all-clusters-app/all-clusters-common/src/dishwasher-mode.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/energy-evse-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/fan-stub.cpp", + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/laundry-dryer-controls-delegate-impl.cpp", "${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", diff --git a/examples/all-clusters-app/linux/main-common.cpp b/examples/all-clusters-app/linux/main-common.cpp index f53b6aa68c8057..bf47dae4646b4b 100644 --- a/examples/all-clusters-app/linux/main-common.cpp +++ b/examples/all-clusters-app/linux/main-common.cpp @@ -21,6 +21,7 @@ #include "air-quality-instance.h" #include "dishwasher-mode.h" #include "include/tv-callbacks.h" +#include "laundry-dryer-controls-delegate-impl.h" #include "laundry-washer-controls-delegate-impl.h" #include "laundry-washer-mode.h" #include "microwave-oven-mode.h" @@ -33,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -248,6 +250,12 @@ void emberAfLaundryWasherControlsClusterInitCallback(EndpointId endpoint) LaundryWasherControlsServer::SetDefaultDelegate(endpoint, &LaundryWasherControlDelegate::getLaundryWasherControlDelegate()); } +using namespace chip::app::Clusters::LaundryDryerControls; +void emberAfLaundryDryerControlsClusterInitCallback(EndpointId endpoint) +{ + LaundryDryerControlsServer::SetDefaultDelegate(endpoint, &LaundryDryerControlDelegate::getLaundryDryerControlDelegate()); +} + void emberAfLowPowerClusterInitCallback(EndpointId endpoint) { ChipLogProgress(NotSpecified, "Setting LowPower default delegate to global manager"); diff --git a/src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-delegate.h b/src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-delegate.h new file mode 100644 index 00000000000000..253ad62ca549fe --- /dev/null +++ b/src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-delegate.h @@ -0,0 +1,49 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * 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. + */ + +#pragma once +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace LaundryDryerControls { + +/** @brief + * Defines methods for implementing application-specific logic for the laundry dryer controls cluster. + */ +class Delegate +{ +public: + Delegate() = default; + virtual ~Delegate() = default; + + /** + * Get the supported dryness value at the given index in the list. + * @param index The index of the supported dryness with 0 representing the first one. + * @param supportedDryness The supported dryness at the given index + * @return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED if the index is out of range for the list of supported dryness. + */ + virtual CHIP_ERROR GetSupportedDrynessLevelAtIndex(size_t index, DrynessLevelEnum & supportedDryness) = 0; +}; + +} // namespace LaundryDryerControls +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-server.cpp b/src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-server.cpp new file mode 100644 index 00000000000000..3f9e1646f1ec11 --- /dev/null +++ b/src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-server.cpp @@ -0,0 +1,187 @@ +/** + * + * 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 +#include +#include + +#include "laundry-dryer-controls-delegate.h" +#include "laundry-dryer-controls-server.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::LaundryDryerControls; +using namespace chip::app::Clusters::LaundryDryerControls::Attributes; +using chip::Protocols::InteractionModel::Status; + +static constexpr size_t kLaundryDryerControlsDelegateTableSize = + EMBER_AF_LAUNDRY_DRYER_CONTROLS_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; + +// ----------------------------------------------------------------------------- +// Delegate Implementation +// +namespace { +Delegate * gDelegateTable[kLaundryDryerControlsDelegateTableSize] = { nullptr }; +} + +namespace { +Delegate * GetDelegate(EndpointId endpoint) +{ + uint16_t ep = emberAfGetClusterServerEndpointIndex(endpoint, LaundryDryerControls::Id, + EMBER_AF_LAUNDRY_DRYER_CONTROLS_CLUSTER_SERVER_ENDPOINT_COUNT); + return (ep >= kLaundryDryerControlsDelegateTableSize ? nullptr : gDelegateTable[ep]); +} + +} // namespace + +LaundryDryerControlsServer LaundryDryerControlsServer::sInstance; + +/********************************************************** + * LaundryDryerControlsServer public methods + *********************************************************/ +void LaundryDryerControlsServer::SetDefaultDelegate(EndpointId endpoint, Delegate * delegate) +{ + uint16_t ep = emberAfGetClusterServerEndpointIndex(endpoint, LaundryDryerControls::Id, + EMBER_AF_LAUNDRY_DRYER_CONTROLS_CLUSTER_SERVER_ENDPOINT_COUNT); + // if endpoint is found + if (ep < kLaundryDryerControlsDelegateTableSize) + { + gDelegateTable[ep] = delegate; + } +} + +LaundryDryerControlsServer & LaundryDryerControlsServer::Instance() +{ + return sInstance; +} + +EmberAfStatus LaundryDryerControlsServer::SetSelectedDrynessLevel(EndpointId endpointId, DrynessLevelEnum newSelectedDrynessLevel) +{ + DataModel::Nullable selectedDrynessLevel; + EmberAfStatus res = SelectedDrynessLevel::Get(endpointId, selectedDrynessLevel); + + if ((res == EMBER_ZCL_STATUS_SUCCESS) && (selectedDrynessLevel != newSelectedDrynessLevel)) + { + res = SelectedDrynessLevel::Set(endpointId, newSelectedDrynessLevel); + } + + return res; +} + +EmberAfStatus LaundryDryerControlsServer::GetSelectedDrynessLevel(EndpointId endpointId, + DataModel::Nullable & selectedDrynessLevel) +{ + return SelectedDrynessLevel::Get(endpointId, selectedDrynessLevel); +} + +/********************************************************** + * LaundryDryerControlsServer private methods + *********************************************************/ +CHIP_ERROR LaundryDryerControlsServer::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) +{ + if (aPath.mClusterId != LaundryDryerControls::Id) + { + // We shouldn't have been called at all. + return CHIP_ERROR_INVALID_ARGUMENT; + } + switch (aPath.mAttributeId) + { + case Attributes::SupportedDrynessLevels::Id: + return ReadSupportedDrynessLevels(aPath, aEncoder); + default: + break; + } + return CHIP_NO_ERROR; +} + +CHIP_ERROR LaundryDryerControlsServer::ReadSupportedDrynessLevels(const ConcreteReadAttributePath & aPath, + AttributeValueEncoder & aEncoder) +{ + Delegate * delegate = GetDelegate(aPath.mEndpointId); + VerifyOrReturnError(delegate != nullptr, CHIP_ERROR_INCORRECT_STATE, ChipLogError(Zcl, "Delegate is nullptr")); + + return aEncoder.EncodeList([delegate](const auto & encoder) -> CHIP_ERROR { + for (uint8_t i = 0; true; i++) + { + DrynessLevelEnum supportedDrynessLevel; + auto err = delegate->GetSupportedDrynessLevelAtIndex(i, supportedDrynessLevel); + if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) + { + return CHIP_NO_ERROR; + } + ReturnErrorOnFailure(err); + ReturnErrorOnFailure(encoder.Encode(supportedDrynessLevel)); + } + }); +} + +/********************************************************** + * Register LaundryDryerControlsServer + *********************************************************/ + +void MatterLaundryDryerControlsPluginServerInitCallback() +{ + LaundryDryerControlsServer & laundryDryerControlsServer = LaundryDryerControlsServer::Instance(); + registerAttributeAccessOverride(&laundryDryerControlsServer); +} + +Status MatterLaundryDryerControlsClusterServerPreAttributeChangedCallback(const chip::app::ConcreteAttributePath & attributePath, + EmberAfAttributeType attributeType, uint16_t size, + uint8_t * value) +{ + Delegate * delegate = GetDelegate(attributePath.mEndpointId); + VerifyOrDie((delegate != nullptr) && "Dryer Controls implementation requires a registered delegate for validation."); + switch (attributePath.mAttributeId) + { + case Attributes::SelectedDrynessLevel::Id: { + uint8_t drynessLevelIdx = 0; + while (true) + { + DrynessLevelEnum supportedDryness; + auto err = delegate->GetSupportedDrynessLevelAtIndex(drynessLevelIdx, supportedDryness); + if (err != CHIP_NO_ERROR) + { + // Can't find the attribute to be written in the supported list (CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) + // Or can't get the correct supported list + return Status::InvalidInState; + } + static_assert(sizeof(DrynessLevelEnum) == sizeof(*value), "Enum size doesn't match parameter size"); + if (supportedDryness == static_cast(*value)) + { + // The written attribute is one of the supported item + return Status::Success; + } + drynessLevelIdx++; + } + } + } + return Status::Success; +} diff --git a/src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-server.h b/src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-server.h new file mode 100644 index 00000000000000..454c029e21fc52 --- /dev/null +++ b/src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-server.h @@ -0,0 +1,62 @@ +/** + * + * 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. + */ + +#pragma once + +#include "laundry-dryer-controls-delegate.h" +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace LaundryDryerControls { + +/** + * @brief LaundryDryerControls Server Plugin class + */ +class LaundryDryerControlsServer : public AttributeAccessInterface +{ +public: + LaundryDryerControlsServer() : AttributeAccessInterface(Optional::Missing(), LaundryDryerControls::Id) {} + static LaundryDryerControlsServer & Instance(); + + /** + * Set the default delegate of laundry dryer server at endpoint x + * @param endpoint ID of the endpoint + * @param delegate The default delegate at the endpoint + */ + static void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate); + + /** + * API to set/get the SelectedDrynessLevel attribute + */ + EmberAfStatus SetSelectedDrynessLevel(EndpointId endpointId, DrynessLevelEnum newSelectedDrynessLevel); + EmberAfStatus GetSelectedDrynessLevel(EndpointId endpointId, DataModel::Nullable & selectedDrynessLevel); + +private: + CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override; + CHIP_ERROR ReadSupportedDrynessLevels(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder); + + static LaundryDryerControlsServer sInstance; +}; + +} // namespace LaundryDryerControls +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/common/templates/config-data.yaml b/src/app/common/templates/config-data.yaml index 5586614c6d7186..8c8300d9c20e4a 100644 --- a/src/app/common/templates/config-data.yaml +++ b/src/app/common/templates/config-data.yaml @@ -77,3 +77,4 @@ ClustersWithPreAttributeChangeFunctions: - Fan Control - Thermostat - Laundry Washer Controls + - Laundry Dryer Controls diff --git a/src/app/zap_cluster_list.json b/src/app/zap_cluster_list.json index 15df401e161d4f..a7f1c8e58dca6f 100644 --- a/src/app/zap_cluster_list.json +++ b/src/app/zap_cluster_list.json @@ -288,6 +288,7 @@ "VALVE_CONFIGURATION_AND_CONTROL_CLUSTER": [], "WAKE_ON_LAN_CLUSTER": ["wake-on-lan-server"], "LAUNDRY_WASHER_CONTROLS_CLUSTER": ["laundry-washer-controls-server"], + "LAUNDRY_DRYER_CONTROLS_CLUSTER": ["laundry-dryer-controls-server"], "WIFI_NETWORK_DIAGNOSTICS_CLUSTER": ["wifi-network-diagnostics-server"], "WINDOW_COVERING_CLUSTER": ["window-covering-server"], "ZLL_COMMISSIONING_CLUSTER": []