-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Add laundry-washer-controls-cluster server implementation #27503
Changes from 17 commits
4f7ee38
440f57b
ef282db
6ae46e2
665b2e3
bb9b0b1
45fde9d
3998529
b92715f
9e98b96
59934be
14f1ed7
845d1ea
461d6e3
21fa5ee
7bef9a0
bbe0590
72d6279
9f38b00
f619a52
b4f1b01
402da53
db5a449
550253f
cc8b13f
de033f2
1da8c1a
866b712
3703648
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/* | ||
* | ||
* 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 <app-common/zap-generated/cluster-objects.h> | ||
#include <app/AttributeAccessInterface.h> | ||
|
||
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. | ||
* @param index The index of the spin_speed, with 0 representing the first one. | ||
* @param spinSpeed The spin speed is filled. | ||
crlonxp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
*/ | ||
virtual CHIP_ERROR GetSpinSpeedAtIndex(size_t index, CharSpan & spinSpeed) = 0; | ||
crlonxp marked this conversation as resolved.
Show resolved
Hide resolved
crlonxp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/** | ||
* Get the list of supported rinses list. | ||
crlonxp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* @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; | ||
crlonxp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}; | ||
|
||
} // namespace LaundryWasherControls | ||
} // namespace Clusters | ||
} // namespace app | ||
} // namespace chip |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,191 @@ | ||
/** | ||
* | ||
* 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 <app/util/af.h> | ||
#include <app/util/attribute-storage.h> | ||
#include <app/util/config.h> | ||
|
||
#include "laundry-washer-controls-delegate.h" | ||
#include "laundry-washer-controls-server.h" | ||
#include <app-common/zap-generated/attributes/Accessors.h> | ||
#include <app-common/zap-generated/callback.h> | ||
#include <app-common/zap-generated/cluster-objects.h> | ||
#include <app-common/zap-generated/enums.h> | ||
#include <app-common/zap-generated/ids/Attributes.h> | ||
#include <app-common/zap-generated/ids/Clusters.h> | ||
#include <app/AttributeAccessInterface.h> | ||
#include <app/CommandHandler.h> | ||
#include <app/ConcreteAttributePath.h> | ||
#include <app/ConcreteCommandPath.h> | ||
#include <app/server/Server.h> | ||
#include <app/util/error-mapping.h> | ||
#include <lib/core/CHIPEncoding.h> | ||
|
||
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) | ||
{ | ||
return (endpoint > kLaundryWasherControlsDelegateTableSize ? nullptr : gDelegateTable[endpoint]); | ||
crlonxp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
} // namespace | ||
|
||
LaundryWasherControlsServer LaundryWasherControlsServer::sInstance; | ||
|
||
/********************************************************** | ||
* LaundryWasherControlsServer public methods | ||
*********************************************************/ | ||
void LaundryWasherControlsServer::SetDefaultDelegate(EndpointId endpoint, Delegate * delegate) | ||
{ | ||
if (endpoint < kLaundryWasherControlsDelegateTableSize) | ||
crlonxp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
gDelegateTable[endpoint] = delegate; | ||
} | ||
} | ||
|
||
LaundryWasherControlsServer & LaundryWasherControlsServer::Instance() | ||
{ | ||
return sInstance; | ||
} | ||
|
||
EmberAfStatus LaundryWasherControlsServer::SetSpinSpeedCurrent(EndpointId endpointId, | ||
DataModel::Nullable<uint8_t> newSpinSpeedCurrent) | ||
{ | ||
DataModel::Nullable<uint8_t> 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<uint8_t> & 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) | ||
{ | ||
aEncoder.EncodeEmptyList(); | ||
crlonxp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Delegate * delegate = GetDelegate(aPath.mEndpointId); | ||
VerifyOrReturnError(delegate != nullptr, CHIP_ERROR_INCORRECT_STATE, ChipLogError(Zcl, "Delegate is nullptr")); | ||
|
||
return aEncoder.EncodeList([&](const auto & encoder) -> CHIP_ERROR { | ||
crlonxp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
for (uint8_t i = 0; true; i++) | ||
{ | ||
CharSpan spinSpeed; | ||
crlonxp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
auto err = delegate->GetSpinSpeedAtIndex(i, spinSpeed); | ||
if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) | ||
crlonxp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
return CHIP_NO_ERROR; | ||
} | ||
ReturnErrorOnFailure(err); | ||
ReturnErrorOnFailure(encoder.Encode(spinSpeed)); | ||
} | ||
}); | ||
} | ||
|
||
CHIP_ERROR LaundryWasherControlsServer::ReadSupportedRinses(const ConcreteReadAttributePath & aPath, | ||
AttributeValueEncoder & aEncoder) | ||
{ | ||
aEncoder.EncodeEmptyList(); | ||
crlonxp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Delegate * delegate = GetDelegate(aPath.mEndpointId); | ||
VerifyOrReturnError(delegate != nullptr, CHIP_ERROR_INCORRECT_STATE, ChipLogError(Zcl, "Delegate is nullptr")); | ||
|
||
return aEncoder.EncodeList([&](const auto & encoder) -> CHIP_ERROR { | ||
crlonxp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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); | ||
} |
crlonxp marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
/** | ||
* | ||
* 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 <app-common/zap-generated/cluster-objects.h> | ||
#include <app/AttributeAccessInterface.h> | ||
#include <app/util/af.h> | ||
|
||
namespace chip { | ||
namespace app { | ||
namespace Clusters { | ||
namespace LaundryWasherControls { | ||
|
||
/** | ||
* @brief LaundryWasherControls Server Plugin class | ||
*/ | ||
class LaundryWasherControlsServer : public AttributeAccessInterface | ||
{ | ||
public: | ||
LaundryWasherControlsServer() : AttributeAccessInterface(Optional<EndpointId>::Missing(), LaundryWasherControls::Id) {} | ||
static LaundryWasherControlsServer & Instance(); | ||
|
||
using SpinSpeedList = DataModel::List<const chip::CharSpan>; | ||
using SupportedRinsesList = DataModel::List<const NumberOfRinsesEnum>; | ||
crlonxp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/** | ||
* 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(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this commented-out thing here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I registered the LaundryWasherControlServer instance to registerAttributeAccessOverride() before. But it's moved to MatterLaundryWasherControlsPluginServerInitCallback() that it's no specific behavior needed for now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would just remove it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you for the suggestion. |
||
|
||
/** | ||
* @brief Set the attribute newSpinSpeedCurrent | ||
* | ||
* @param endpointId ID of the endpoint | ||
* @param newSpinSpeedCurrent attribute SpinSpeedCurrent | ||
* @return true on success, false on failure | ||
*/ | ||
EmberAfStatus SetSpinSpeedCurrent(chip::EndpointId endpointId, DataModel::Nullable<uint8_t> newSpinSpeedCurrent); | ||
crlonxp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/** | ||
* @brief Get the attribute newSpinSpeedCurrent | ||
* | ||
* @param endpointId ID of the endpoint | ||
* @param SpinSpeedCurrent attribute SpinSpeedCurrent | ||
* @return true on success, false on failure | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. commenting post merge, so I do not block the PR: these return EmberAfStatus, so probably not true on success/false on failure. Also the comment seems redundant - when something returns CHIP_ERROR or EmberAfStatus the return is reasonably clear. Overall we can save vertical space a lot (it is obvious There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you for the suggestions. I will change these in the next PR. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I add the change in #28264 |
||
*/ | ||
EmberAfStatus GetSpinSpeedCurrent(chip::EndpointId endpointId, DataModel::Nullable<uint8_t> & spinSpeedCurrent); | ||
crlonxp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/** | ||
* @brief Set the attribute NumberOfRinses | ||
* | ||
* @param endpointId ID of the endpoint | ||
* @param newNumberOfRinses attribute NumberOfRinses | ||
* @return true on success, false on failure | ||
*/ | ||
EmberAfStatus SetNumberOfRinses(chip::EndpointId endpointId, NumberOfRinsesEnum newNumberOfRinses); | ||
crlonxp marked this conversation as resolved.
Show resolved
Hide resolved
crlonxp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/** | ||
* @brief Get the attribute NumberOfRinses | ||
* | ||
* @param endpointId ID of the endpoint | ||
* @param NumberOfRinses attribute NumberOfRinses | ||
* @return true on success, false on failure | ||
*/ | ||
EmberAfStatus GetNumberOfRinses(chip::EndpointId endpointId, NumberOfRinsesEnum & numberOfRinses); | ||
crlonxp marked this conversation as resolved.
Show resolved
Hide resolved
crlonxp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@crlonxp This was merged without addressing review comments (e.g. #27503 (comment)), even though those comments got marked resolved.
I am sorry, but I will no longer be marking your PRs as "approved if you address these comments". All comments will need to be addressed before I can approve.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should I create another PR to address these remaining comments? Or should I keep modify the code I have and push?
Thank you
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, please, since this PR is now merged...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I add the change in #28264
Please review. Thank you