Skip to content

Commit 2e4f0ff

Browse files
committed
Valve: Disco ball - Access and command interfaces
1 parent 8bf5e5a commit 2e4f0ff

7 files changed

+267
-4
lines changed

src/app/chip_data_model.gni

+2
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,8 @@ template("chip_data_model") {
451451
"${_app_root}/clusters/${cluster}/valve-configuration-and-control-delegate.h",
452452
"${_app_root}/clusters/${cluster}/valve-configuration-and-control-matter-context.cpp",
453453
"${_app_root}/clusters/${cluster}/valve-configuration-and-control-matter-context.h",
454+
"${_app_root}/clusters/${cluster}/valve-configuration-and-control-server-disco.cpp",
455+
"${_app_root}/clusters/${cluster}/valve-configuration-and-control-server-disco.h",
454456
]
455457
cflags += [ "-Wno-unused-private-field" ]
456458
} else {

src/app/clusters/valve-configuration-and-control-server/valve-configuration-and-control-cluster-logic.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ class ClusterLogic
129129
// CHIP_ERROR HandleClose();
130130

131131
// All Get functions:
132-
// Return CHIP_ERROR_INVALID_STATE if the class has not been initialized.
132+
// Return CHIP_ERROR_INCORRECT_STATE if the class has not been initialized.
133133
// Return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE if the attribute is not supported by the conformance.
134134
// Otherwise return CHIP_NO_ERROR and set the input parameter value to the current cluster state value
135135
CHIP_ERROR GetOpenDuration(DataModel::Nullable<ElapsedS> & openDuration);

src/app/clusters/valve-configuration-and-control-server/valve-configuration-and-control-matter-context.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
#include "valve-configuration-and-control-matter-context.h"
2020

21+
#include <app-common/zap-generated/ids/Clusters.h>
22+
#include <app/reporting/reporting.h>
2123
#include <lib/support/DefaultStorageKeyAllocator.h>
2224

2325
namespace chip {
@@ -59,9 +61,9 @@ CHIP_ERROR MatterContext::GetDefaultOpenLevel(uint8_t & returnVal)
5961
&returnVal, size);
6062
}
6163

62-
void MatterContext::MarkDirty(const AttributeId id)
64+
void MatterContext::MarkDirty(const AttributeId attributeId)
6365
{
64-
// Uh...how do we do this?
66+
MatterReportingAttributeChangeCallback(mEndpoint, Id, attributeId);
6567
}
6668

6769
} // namespace ValveConfigurationAndControl

src/app/clusters/valve-configuration-and-control-server/valve-configuration-and-control-matter-context.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class MatterContext
5353
CHIP_ERROR GetDefaultOpenLevel(uint8_t & returnVal);
5454

5555
// MarkDirty
56-
virtual void MarkDirty(AttributeId id);
56+
virtual void MarkDirty(AttributeId attributeId);
5757

5858
virtual ~MatterContext() = default;
5959

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
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+
19+
#include "valve-configuration-and-control-server-disco.h"
20+
21+
#include <app-common/zap-generated/cluster-objects.h>
22+
#include <app-common/zap-generated/ids/Attributes.h>
23+
#include <app-common/zap-generated/ids/Clusters.h>
24+
#include <app/AttributeAccessInterface.h>
25+
#include <app/AttributeAccessInterfaceRegistry.h>
26+
#include <app/CommandHandlerInterface.h>
27+
#include <app/CommandHandlerInterfaceRegistry.h>
28+
#include <app/ConcreteCommandPath.h>
29+
#include <app/clusters/valve-configuration-and-control-server/valve-configuration-and-control-cluster-logic.h>
30+
#include <app/data-model/Encode.h>
31+
#include <app/util/config.h>
32+
#include <lib/core/CHIPError.h>
33+
34+
namespace chip {
35+
namespace app {
36+
namespace Clusters {
37+
namespace ValveConfigurationAndControl {
38+
39+
using namespace Attributes;
40+
using namespace Commands;
41+
using namespace Protocols::InteractionModel;
42+
namespace {
43+
44+
template <typename T, typename F>
45+
CHIP_ERROR EncodeRead(AttributeValueEncoder & aEncoder, const F & getter)
46+
{
47+
T ret;
48+
CHIP_ERROR err = getter(ret);
49+
if (err == CHIP_NO_ERROR)
50+
{
51+
err = aEncoder.Encode(ret);
52+
}
53+
54+
// TODO: Should the logic return these directly? I didn't want to mix the IM layer into there, but this is annoying.
55+
if (err == CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE)
56+
{
57+
return CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute);
58+
}
59+
if (err == CHIP_ERROR_INCORRECT_STATE)
60+
{
61+
// what actually gets returned here? This is really an internal error, so failure seems perhaps correct.
62+
return CHIP_IM_GLOBAL_STATUS(Failure);
63+
}
64+
return err;
65+
}
66+
67+
} // namespace
68+
69+
CHIP_ERROR Interface::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder)
70+
{
71+
switch (aPath.mAttributeId)
72+
{
73+
case OpenDuration::Id: {
74+
typedef OpenDuration::TypeInfo::Type T;
75+
return EncodeRead<T>(aEncoder, [&logic = mClusterLogic](T & ret) -> CHIP_ERROR { return logic.GetOpenDuration(ret); });
76+
}
77+
case DefaultOpenDuration::Id: {
78+
typedef DefaultOpenDuration::TypeInfo::Type T;
79+
return EncodeRead<T>(aEncoder,
80+
[&logic = mClusterLogic](T & ret) -> CHIP_ERROR { return logic.GetDefaultOpenDuration(ret); });
81+
}
82+
case AutoCloseTime::Id: {
83+
typedef AutoCloseTime::TypeInfo::Type T;
84+
return EncodeRead<T>(aEncoder, [&logic = mClusterLogic](T & ret) -> CHIP_ERROR { return logic.GetAutoCloseTime(ret); });
85+
}
86+
case RemainingDuration::Id: {
87+
typedef RemainingDuration::TypeInfo::Type T;
88+
return EncodeRead<T>(aEncoder, [&logic = mClusterLogic](T & ret) -> CHIP_ERROR { return logic.GetRemainingDuration(ret); });
89+
}
90+
case CurrentState::Id: {
91+
typedef CurrentState::TypeInfo::Type T;
92+
return EncodeRead<T>(aEncoder, [&logic = mClusterLogic](T & ret) -> CHIP_ERROR { return logic.GetCurrentState(ret); });
93+
}
94+
case TargetState::Id: {
95+
typedef TargetState::TypeInfo::Type T;
96+
return EncodeRead<T>(aEncoder, [&logic = mClusterLogic](T & ret) -> CHIP_ERROR { return logic.GetTargetState(ret); });
97+
}
98+
case CurrentLevel::Id: {
99+
typedef CurrentLevel::TypeInfo::Type T;
100+
return EncodeRead<T>(aEncoder, [&logic = mClusterLogic](T & ret) -> CHIP_ERROR { return logic.GetCurrentLevel(ret); });
101+
}
102+
case TargetLevel::Id: {
103+
typedef TargetLevel::TypeInfo::Type T;
104+
return EncodeRead<T>(aEncoder, [&logic = mClusterLogic](T & ret) -> CHIP_ERROR { return logic.GetTargetLevel(ret); });
105+
}
106+
case DefaultOpenLevel::Id: {
107+
typedef DefaultOpenLevel::TypeInfo::Type T;
108+
return EncodeRead<T>(aEncoder, [&logic = mClusterLogic](T & ret) -> CHIP_ERROR { return logic.GetDefaultOpenLevel(ret); });
109+
}
110+
case ValveFault::Id: {
111+
typedef ValveFault::TypeInfo::Type T;
112+
return EncodeRead<T>(aEncoder, [&logic = mClusterLogic](T & ret) -> CHIP_ERROR { return logic.GetValveFault(ret); });
113+
}
114+
case LevelStep::Id: {
115+
typedef LevelStep::TypeInfo::Type T;
116+
return EncodeRead<T>(aEncoder, [&logic = mClusterLogic](T & ret) -> CHIP_ERROR { return logic.GetLevelStep(ret); });
117+
}
118+
default:
119+
return CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute);
120+
}
121+
}
122+
123+
CHIP_ERROR Interface::Write(const ConcreteDataAttributePath & aPath, AttributeValueDecoder & aDecoder)
124+
{
125+
switch (aPath.mAttributeId)
126+
{
127+
case DefaultOpenDuration::Id: {
128+
DefaultOpenDuration::TypeInfo::Type val;
129+
ReturnErrorOnFailure(aDecoder.Decode(val));
130+
return mClusterLogic.SetDefaultOpenDuration(val);
131+
}
132+
case DefaultOpenLevel::Id: {
133+
DefaultOpenLevel::TypeInfo::Type val;
134+
ReturnErrorOnFailure(aDecoder.Decode(val));
135+
return mClusterLogic.SetDefaultOpenLevel(val);
136+
}
137+
default:
138+
return CHIP_IM_GLOBAL_STATUS(UnsupportedWrite);
139+
}
140+
}
141+
142+
// CommandHandlerInterface
143+
void Interface::InvokeCommand(HandlerContext & handlerContext)
144+
{
145+
switch (handlerContext.mRequestPath.mCommandId)
146+
{
147+
case Open::Id:
148+
HandleCommand<Open::DecodableType>(
149+
handlerContext, [&logic = mClusterLogic](HandlerContext & ctx, const auto & commandData) {
150+
// TODO: I used optional in the lower layers because I think we want to move to std::optional in general
151+
// So here, I need to change over. But I can also change the Logic cluster to use Optional
152+
CHIP_ERROR err =
153+
logic.HandleOpenCommand(commandData.openDuration.std_optional(), commandData.targetLevel.std_optional());
154+
Status status = Status::Success;
155+
if (err == CHIP_ERROR_INVALID_ARGUMENT)
156+
{
157+
status = Status::ConstraintError;
158+
}
159+
if (err != CHIP_NO_ERROR)
160+
{
161+
status = Status::Failure;
162+
}
163+
ctx.mCommandHandler.AddStatus(ctx.mRequestPath, status);
164+
});
165+
return;
166+
case Close::Id:
167+
HandleCommand<Close::DecodableType>(handlerContext,
168+
[&logic = mClusterLogic](HandlerContext & ctx, const auto & commandData) {
169+
CHIP_ERROR err = logic.HandleCloseCommand();
170+
Status status = Status::Success;
171+
if (err == CHIP_ERROR_INVALID_ARGUMENT)
172+
{
173+
status = Status::ConstraintError;
174+
}
175+
if (err != CHIP_NO_ERROR)
176+
{
177+
status = Status::Failure;
178+
}
179+
ctx.mCommandHandler.AddStatus(ctx.mRequestPath, status);
180+
});
181+
return;
182+
}
183+
}
184+
185+
CHIP_ERROR Interface::Init()
186+
{
187+
AttributeAccessInterfaceRegistry::Instance().Register(this);
188+
CommandHandlerInterfaceRegistry::Instance().RegisterCommandHandler(this);
189+
return CHIP_NO_ERROR;
190+
}
191+
192+
} // namespace ValveConfigurationAndControl
193+
} // namespace Clusters
194+
} // namespace app
195+
} // namespace chip
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
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+
#pragma once
19+
20+
#include <app-common/zap-generated/ids/Clusters.h>
21+
#include <app/AttributeAccessInterface.h>
22+
#include <app/AttributeAccessInterfaceRegistry.h>
23+
#include <app/CommandHandlerInterface.h>
24+
#include <app/ConcreteCommandPath.h>
25+
#include <app/clusters/valve-configuration-and-control-server/valve-configuration-and-control-cluster-logic.h>
26+
#include <app/data-model/Encode.h>
27+
#include <app/util/config.h>
28+
#include <lib/core/CHIPError.h>
29+
30+
namespace chip {
31+
namespace app {
32+
namespace Clusters {
33+
namespace ValveConfigurationAndControl {
34+
35+
// App should instantiate and init one Interface per endpoint
36+
class Interface : public AttributeAccessInterface, public CommandHandlerInterface
37+
{
38+
public:
39+
Interface(EndpointId endpoint, ClusterLogic & clusterLogic) :
40+
AttributeAccessInterface(Optional<EndpointId>(endpoint), Id), CommandHandlerInterface(Optional<EndpointId>(endpoint), Id),
41+
mClusterLogic(clusterLogic)
42+
{}
43+
// AttributeAccessInterface
44+
CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override;
45+
CHIP_ERROR Write(const ConcreteDataAttributePath & aPath, AttributeValueDecoder & aDecoder) override;
46+
47+
// CommandHandlerInterface
48+
void InvokeCommand(HandlerContext & handlerContext) override;
49+
50+
// Registers this handler.
51+
CHIP_ERROR Init();
52+
53+
// TODO: Shutdown - is there a way to unregister?
54+
55+
private:
56+
// This is owned by the caller and passed to the interface for its use.
57+
ClusterLogic & mClusterLogic;
58+
};
59+
60+
} // namespace ValveConfigurationAndControl
61+
} // namespace Clusters
62+
} // namespace app
63+
} // namespace chip

src/app/tests/BUILD.gn

+1
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ source_set("valve-configuration-and-control-test-srcs") {
164164
"${chip_root}/src/app/clusters/valve-configuration-and-control-server/valve-configuration-and-control-matter-context.h",
165165
]
166166
public_deps = [
167+
"${chip_root}/src/app:interaction-model",
167168
"${chip_root}/src/app/common:cluster-objects",
168169
"${chip_root}/src/lib/core",
169170
"${chip_root}/src/lib/support",

0 commit comments

Comments
 (0)