From 9d053d3cb16f052870eaa6432bdbde49be89aba8 Mon Sep 17 00:00:00 2001 From: crlonxp <88241281+crlonxp@users.noreply.github.com> Date: Sat, 22 Jul 2023 23:02:30 +0800 Subject: [PATCH] Add laundry-washer-controls-cluster server implementation (#27503) * Add laundry-washer-controls-cluster server implementation Signed-off-by: Chin-Ran Lo * Restyled by clang-format * Refine the definition Signed-off-by: Chin-Ran Lo * Restyled by clang-format * * Remove unnecessary code to read the attribute * Remove the deleget * Change the implementation to accept the attribute from the example Signed-off-by: Chin-Ran Lo * Restyled by clang-format * * Add "const" to the read-only attribute * Remove the empty emberAfLaundryWasherControlsClusterInitCallback() that app-level can implement it Signed-off-by: Chin-Ran Lo * * Add LaundryWasherServer get/set API to access the attributes Signed-off-by: Chin-Ran Lo * * Add the API to get/set the SpinSpeeds and SupportedRinses attribute of LaundryWasherControl cluster * Save/Load the SpinSpeeds and SupportedRinses attribute to/from the flash Signed-off-by: Chin-Ran Lo * Restyled by whitespace * Restyled by clang-format * * Move the release / clean member functions to public - ReleaseSpinSpeedList / ClearSpinSpeedList - ReleaseSupportedRinsesList / ClearSupportedRinsesList Signed-off-by: Chin-Ran Lo * Restyled by clang-format * * Add back the delegate interface and report the items one by one * Remove the data provider Signed-off-by: Chin-Ran Lo * Restyled by whitespace * Restyled by clang-format * * Remove the unused definition for storage-key-alloc Signed-off-by: Chin-Ran Lo * Update src/app/clusters/laundry-washer-controls-server/laundry-washer-controls-server.cpp Co-authored-by: Boris Zbarsky * Update src/app/clusters/laundry-washer-controls-server/laundry-washer-controls-server.h Co-authored-by: Boris Zbarsky * Update src/app/clusters/laundry-washer-controls-server/laundry-washer-controls-server.h Co-authored-by: Boris Zbarsky * Update src/app/clusters/laundry-washer-controls-server/laundry-washer-controls-server.cpp Co-authored-by: Boris Zbarsky * Update src/app/clusters/laundry-washer-controls-server/laundry-washer-controls-server.cpp Co-authored-by: Boris Zbarsky * * Use MutableCharSpan to replace CharSpan * Add to calculate the delegate id from endpoint Signed-off-by: Chin-Ran Lo * Restyled by clang-format * * Refine the comment Signed-off-by: Chin-Ran Lo * Update src/app/clusters/laundry-washer-controls-server/laundry-washer-controls-server.h Co-authored-by: Boris Zbarsky * Update src/app/clusters/laundry-washer-controls-server/laundry-washer-controls-server.h Co-authored-by: Boris Zbarsky * Update src/app/clusters/laundry-washer-controls-server/laundry-washer-controls-server.h Co-authored-by: Boris Zbarsky * Restyled by clang-format --------- Signed-off-by: Chin-Ran Lo Co-authored-by: Restyled.io Co-authored-by: Boris Zbarsky --- .../laundry-washer-controls-delegate.h | 59 ++++++ .../laundry-washer-controls-server.cpp | 195 ++++++++++++++++++ .../laundry-washer-controls-server.h | 103 +++++++++ src/app/zap_cluster_list.json | 1 + 4 files changed, 358 insertions(+) create mode 100644 src/app/clusters/laundry-washer-controls-server/laundry-washer-controls-delegate.h create mode 100644 src/app/clusters/laundry-washer-controls-server/laundry-washer-controls-server.cpp create mode 100644 src/app/clusters/laundry-washer-controls-server/laundry-washer-controls-server.h diff --git a/src/app/clusters/laundry-washer-controls-server/laundry-washer-controls-delegate.h b/src/app/clusters/laundry-washer-controls-server/laundry-washer-controls-delegate.h new file mode 100644 index 00000000000000..5529413a40cb88 --- /dev/null +++ b/src/app/clusters/laundry-washer-controls-server/laundry-washer-controls-delegate.h @@ -0,0 +1,59 @@ +/* + * + * 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 LaundryWasherControls { + +/** @brief + * Defines methods for implementing application-specific logic for the laundry washer controls cluster. + */ +class Delegate +{ +public: + Delegate() = default; + virtual ~Delegate() = default; + + /** + * Get the list of supported spin_speed list. + * Fills in the provided spin_speed at index `index` if there is one, + * or returns CHIP_ERROR_PROVIDER_LIST_EXHAUSTED if the index is out of range for the list of spin_speed. + * @param index The index of the spin_speed, with 0 representing the first one. + * @param spinSpeed The spin speed is filled. + */ + virtual CHIP_ERROR GetSpinSpeedAtIndex(size_t index, MutableCharSpan & spinSpeed) = 0; + + /** + * Get the list of supported rinses list. + * Fills in the provided rinses at index `index` if there is one, + * or returns CHIP_ERROR_PROVIDER_LIST_EXHAUSTED if the index is out of range for the list of rinses. + * @param index The index of the supported rinses with 0 representing the first one. + * @param supportedRinse The supported rinse is filled. + */ + virtual CHIP_ERROR GetSupportedRinseAtIndex(size_t index, NumberOfRinsesEnum & supportedRinse) = 0; +}; + +} // namespace LaundryWasherControls +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/laundry-washer-controls-server/laundry-washer-controls-server.cpp b/src/app/clusters/laundry-washer-controls-server/laundry-washer-controls-server.cpp new file mode 100644 index 00000000000000..76832e4c091eb8 --- /dev/null +++ b/src/app/clusters/laundry-washer-controls-server/laundry-washer-controls-server.cpp @@ -0,0 +1,195 @@ +/** + * + * 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-washer-controls-delegate.h" +#include "laundry-washer-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::LaundryWasherControls; +using namespace chip::app::Clusters::LaundryWasherControls::Attributes; +using chip::Protocols::InteractionModel::Status; + +static constexpr size_t kLaundryWasherControlsDelegateTableSize = + EMBER_AF_LAUNDRY_WASHER_CONTROLS_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; + +// ----------------------------------------------------------------------------- +// Delegate Implementation +// +namespace { +Delegate * gDelegateTable[kLaundryWasherControlsDelegateTableSize] = { nullptr }; +} + +namespace { +Delegate * GetDelegate(EndpointId endpoint) +{ + uint16_t ep = emberAfGetClusterServerEndpointIndex(endpoint, LaundryWasherControls::Id, + EMBER_AF_LAUNDRY_WASHER_CONTROLS_CLUSTER_SERVER_ENDPOINT_COUNT); + return (ep >= kLaundryWasherControlsDelegateTableSize ? nullptr : gDelegateTable[ep]); +} + +} // namespace + +LaundryWasherControlsServer LaundryWasherControlsServer::sInstance; + +/********************************************************** + * LaundryWasherControlsServer public methods + *********************************************************/ +void LaundryWasherControlsServer::SetDefaultDelegate(EndpointId endpoint, Delegate * delegate) +{ + uint16_t ep = emberAfGetClusterServerEndpointIndex(endpoint, LaundryWasherControls::Id, + EMBER_AF_LAUNDRY_WASHER_CONTROLS_CLUSTER_SERVER_ENDPOINT_COUNT); + // if endpoint is found + if (ep < kLaundryWasherControlsDelegateTableSize) + { + gDelegateTable[ep] = delegate; + } +} + +LaundryWasherControlsServer & LaundryWasherControlsServer::Instance() +{ + return sInstance; +} + +EmberAfStatus LaundryWasherControlsServer::SetSpinSpeedCurrent(EndpointId endpointId, + DataModel::Nullable newSpinSpeedCurrent) +{ + DataModel::Nullable spinSpeedCurrent; + EmberAfStatus res = SpinSpeedCurrent::Get(endpointId, spinSpeedCurrent); + if ((res == EMBER_ZCL_STATUS_SUCCESS) && (spinSpeedCurrent != newSpinSpeedCurrent)) + { + res = SpinSpeedCurrent::Set(endpointId, newSpinSpeedCurrent); + } + + return res; +} + +EmberAfStatus LaundryWasherControlsServer::GetSpinSpeedCurrent(EndpointId endpointId, + DataModel::Nullable & spinSpeedCurrent) +{ + return SpinSpeedCurrent::Get(endpointId, spinSpeedCurrent); +} + +EmberAfStatus LaundryWasherControlsServer::SetNumberOfRinses(EndpointId endpointId, NumberOfRinsesEnum newNumberOfRinses) +{ + NumberOfRinsesEnum numberOfRinses; + EmberAfStatus res = NumberOfRinses::Get(endpointId, &numberOfRinses); + + if ((res == EMBER_ZCL_STATUS_SUCCESS) && (numberOfRinses != newNumberOfRinses)) + { + res = NumberOfRinses::Set(endpointId, newNumberOfRinses); + } + + return res; +} + +EmberAfStatus LaundryWasherControlsServer::GetNumberOfRinses(EndpointId endpointId, NumberOfRinsesEnum & numberOfRinses) +{ + return NumberOfRinses::Get(endpointId, &numberOfRinses); +} + +/********************************************************** + * LaundryWasherControlsServer private methods + *********************************************************/ +CHIP_ERROR LaundryWasherControlsServer::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) +{ + if (aPath.mClusterId != LaundryWasherControls::Id) + { + // We shouldn't have been called at all. + return CHIP_ERROR_INVALID_ARGUMENT; + } + switch (aPath.mAttributeId) + { + case Attributes::SpinSpeeds::Id: + return ReadSpinSpeeds(aPath, aEncoder); + case Attributes::SupportedRinses::Id: + return ReadSupportedRinses(aPath, aEncoder); + default: + break; + } + return CHIP_NO_ERROR; +} + +CHIP_ERROR LaundryWasherControlsServer::ReadSpinSpeeds(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++) + { + char buffer[kMaxSpinSpeedLength]; + MutableCharSpan spinSpeed(buffer); + auto err = delegate->GetSpinSpeedAtIndex(i, spinSpeed); + if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) + { + return CHIP_NO_ERROR; + } + ReturnErrorOnFailure(err); + ReturnErrorOnFailure(encoder.Encode(spinSpeed)); + } + }); +} + +CHIP_ERROR LaundryWasherControlsServer::ReadSupportedRinses(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++) + { + NumberOfRinsesEnum supportedRinse; + auto err = delegate->GetSupportedRinseAtIndex(i, supportedRinse); + if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) + { + return CHIP_NO_ERROR; + } + ReturnErrorOnFailure(err); + ReturnErrorOnFailure(encoder.Encode(supportedRinse)); + } + }); +} + +/********************************************************** + * Register LaundryWasherControlsServer + *********************************************************/ + +void MatterLaundryWasherControlsPluginServerInitCallback() +{ + LaundryWasherControlsServer & laundryWasherControlsServer = LaundryWasherControlsServer::Instance(); + registerAttributeAccessOverride(&laundryWasherControlsServer); +} diff --git a/src/app/clusters/laundry-washer-controls-server/laundry-washer-controls-server.h b/src/app/clusters/laundry-washer-controls-server/laundry-washer-controls-server.h new file mode 100644 index 00000000000000..ac9b4ca0b7f209 --- /dev/null +++ b/src/app/clusters/laundry-washer-controls-server/laundry-washer-controls-server.h @@ -0,0 +1,103 @@ +/** + * + * 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-washer-controls-delegate.h" +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace LaundryWasherControls { + +/** + * @brief LaundryWasherControls Server Plugin class + */ +class LaundryWasherControlsServer : public AttributeAccessInterface +{ +public: + LaundryWasherControlsServer() : AttributeAccessInterface(Optional::Missing(), LaundryWasherControls::Id) {} + static LaundryWasherControlsServer & Instance(); + + static constexpr uint8_t kMaxSpinSpeedLength = 64; + + /** + * Set the default delegate of laundry washer server at endpoint x + * @param endpoint ID of the endpoint + * @param delegate The default delegate at the endpoint + * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error code. + */ + static void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate); + + /** + * Init the laundry washer server. + * @param void + * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error code. + */ + // CHIP_ERROR Init(); + + /** + * @brief Set the attribute newSpinSpeedCurrent + * + * @param endpointId ID of the endpoint + * @param newSpinSpeedCurrent attribute SpinSpeedCurrent + * @return true on success, false on failure + */ + EmberAfStatus SetSpinSpeedCurrent(EndpointId endpointId, DataModel::Nullable newSpinSpeedCurrent); + + /** + * @brief Get the attribute newSpinSpeedCurrent + * + * @param endpointId ID of the endpoint + * @param SpinSpeedCurrent attribute SpinSpeedCurrent + * @return true on success, false on failure + */ + EmberAfStatus GetSpinSpeedCurrent(EndpointId endpointId, DataModel::Nullable & spinSpeedCurrent); + + /** + * @brief Set the attribute NumberOfRinses + * + * @param endpointId ID of the endpoint + * @param newNumberOfRinses attribute NumberOfRinses + * @return true on success, false on failure + */ + EmberAfStatus SetNumberOfRinses(EndpointId endpointId, NumberOfRinsesEnum newNumberOfRinses); + + /** + * @brief Get the attribute NumberOfRinses + * + * @param endpointId ID of the endpoint + * @param NumberOfRinses attribute NumberOfRinses + * @return true on success, false on failure + */ + EmberAfStatus GetNumberOfRinses(EndpointId endpointId, NumberOfRinsesEnum & numberOfRinses); + +private: + CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override; + CHIP_ERROR ReadSpinSpeeds(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder); + CHIP_ERROR ReadSupportedRinses(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder); + + static LaundryWasherControlsServer sInstance; +}; + +} // namespace LaundryWasherControls +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/zap_cluster_list.json b/src/app/zap_cluster_list.json index e405b924737a7d..f88948ef7d7c5a 100644 --- a/src/app/zap_cluster_list.json +++ b/src/app/zap_cluster_list.json @@ -236,6 +236,7 @@ "UNIT_TESTING_CLUSTER": ["test-cluster-server"], "USER_LABEL_CLUSTER": ["user-label-server"], "WAKE_ON_LAN_CLUSTER": ["wake-on-lan-server"], + "LAUNDRY_WASHER_CONTROLS_CLUSTER": ["laundry-washer-controls-server"], "WIFI_NETWORK_DIAGNOSTICS_CLUSTER": ["wifi-network-diagnostics-server"], "WINDOW_COVERING_CLUSTER": ["window-covering-server"], "ZLL_COMMISSIONING_CLUSTER": []