Feature/dishwasher alarm impl (#27748)
* init disdwasher alarm
* add dishwasher alarm zap
* format file
* Restyled by whitespace
* Restyled by clang-format
* init disdwasher alarm
* add dishwasher alarm zap
* format file
* Restyled by whitespace
* Restyled by clang-format
* modify dishwasheralarm Supported
* revert
* Restyled by clang-format
* modify dishwasher alarm
* modify dishwasher alarm latch support
* add all cluster zap
* modify dishwasher alarm latch support
* modify all cluster zap
* Restyled by whitespace
* Restyled by clang-format
* Add TestDishwasherAlarm
* Modify dishwasher cluster definition in all-cluster-app
* add dishwasher alarm cluster
* Restyled by whitespace and Tab
* Optimize the dishwasher alarm cluster
* Optimize the alarm dishwasher alarm server
* Using namespace to optimize the head file
* Add dishwasher alarm cluster delegate
* optimize TestDishwasherAlarm
* init DishwasherAlarmServer instance in all-cluster-app
* Move the dishwasher alarm plugin server init
* Restyled by whitespace
* Restyled by clang-format
* Restyled by gn
* Restyled by prettier-yaml
* optimize the note for dishwasher alarm server and delegate
* optimize the note in ciTest
* rename and note the function.
* use static to modify variable
* Fix some bug not match with dishwasher alarm cluster's spec
* modify the init value of attribute in dishwasher alarm cluster in all-cluster-app
* optimize the TestDishwasherAlarm
* take off prefix of variable chip::
* Optimize SetStateByLatch api
* fix CI build error
* optimize document of function in dishwasher alarm cluster
* modify with review advice
* Optimize StateStateValue and ResetStateValue function
* fix SetStateValue function error
* Restyled by whitespace
* Restyled by clang-format
* fix zap error
* modify the State attribute in Dishwasher alarm in zap
* fix CI build error
* Remove function.
* Update src/app/clusters/dishwasher-alarm-server/dishwasher-alarm-server.cpp
Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>
* Update src/app/clusters/dishwasher-alarm-server/dishwasher-alarm-server.h
Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>
* Update src/app/clusters/dishwasher-alarm-server/dishwasher-alarm-server.h
Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>
* Update src/app/clusters/dishwasher-alarm-server/dishwasher-alarm-server.cpp
Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>
* Updates per review
* Update src/app/clusters/dishwasher-alarm-server/dishwasher-alarm-server.h
Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>
* fix TestScript error in TestDishwasherAlarm
* zap regen all
* fix the document
* Restyled by whitespace
* Restyled by gn
---------
Co-authored-by: Restyled.io <commits@restyled.io>
Co-authored-by: mideayanghui <yanghui65@midea.com>
Co-authored-by: Rob Bultman <rob.bultman@gmail.com>
Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>
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 9381838..32c8d1f 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
@@ -2919,6 +2919,47 @@
command SelfTestRequest(): DefaultSuccess = 0;
}
+/** Attributes and commands for configuring the Dishwasher alarm. */
+server cluster DishwasherAlarm = 93 {
+ bitmap AlarmMap : BITMAP32 {
+ kInflowError = 0x1;
+ kDrainError = 0x2;
+ kDoorError = 0x4;
+ kTempTooLow = 0x8;
+ kTempTooHigh = 0x10;
+ kWaterLevelError = 0x20;
+ }
+
+ info event Notify = 0 {
+ AlarmMap active = 0;
+ AlarmMap inactive = 1;
+ AlarmMap state = 2;
+ AlarmMap mask = 3;
+ }
+
+ readonly attribute AlarmMap mask = 0;
+ readonly attribute AlarmMap latch = 1;
+ readonly attribute AlarmMap state = 2;
+ readonly attribute AlarmMap supported = 3;
+ 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;
+
+ request struct ResetRequest {
+ AlarmMap alarms = 0;
+ }
+
+ request struct ModifyEnabledAlarmsRequest {
+ AlarmMap mask = 0;
+ }
+
+ command Reset(ResetRequest): DefaultSuccess = 0;
+ command ModifyEnabledAlarms(ModifyEnabledAlarmsRequest): DefaultSuccess = 1;
+}
+
/** This cluster supports remotely monitoring and, where supported, changing the operational state of any device where a state machine is a part of the operation. */
server cluster OperationalState = 96 {
enum ErrorStateEnum : ENUM8 {
@@ -6676,6 +6717,20 @@
ram attribute clusterRevision default = 1;
}
+ server cluster DishwasherAlarm {
+ emits event Notify;
+ ram attribute mask default = 1;
+ ram attribute latch default = 1;
+ ram attribute state default = 0;
+ ram attribute supported default = 15;
+ callback attribute generatedCommandList;
+ callback attribute acceptedCommandList;
+ callback attribute eventList;
+ callback attribute attributeList;
+ ram attribute featureMap default = 1;
+ ram attribute clusterRevision default = 1;
+ }
+
server cluster OperationalState {
emits event OperationalError;
emits event OperationCompletion;
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 9e7e08f..3653378 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
@@ -15740,6 +15740,245 @@
]
},
{
+ "name": "Dishwasher Alarm",
+ "code": 93,
+ "mfgCode": null,
+ "define": "DISHWASHER_ALARM_CLUSTER",
+ "side": "client",
+ "enabled": 0,
+ "commands": [
+ {
+ "name": "Reset",
+ "code": 0,
+ "mfgCode": null,
+ "source": "client",
+ "incoming": 1,
+ "outgoing": 0
+ },
+ {
+ "name": "ModifyEnabledAlarms",
+ "code": 1,
+ "mfgCode": null,
+ "source": "client",
+ "incoming": 1,
+ "outgoing": 0
+ }
+ ],
+ "attributes": [
+ {
+ "name": "FeatureMap",
+ "code": 65532,
+ "mfgCode": null,
+ "side": "client",
+ "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": "client",
+ "type": "int16u",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "1",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ }
+ ]
+ },
+ {
+ "name": "Dishwasher Alarm",
+ "code": 93,
+ "mfgCode": null,
+ "define": "DISHWASHER_ALARM_CLUSTER",
+ "side": "server",
+ "enabled": 1,
+ "attributes": [
+ {
+ "name": "Mask",
+ "code": 0,
+ "mfgCode": null,
+ "side": "server",
+ "type": "AlarmMap",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "1",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "Latch",
+ "code": 1,
+ "mfgCode": null,
+ "side": "server",
+ "type": "AlarmMap",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "1",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "State",
+ "code": 2,
+ "mfgCode": null,
+ "side": "server",
+ "type": "AlarmMap",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "0",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "Supported",
+ "code": 3,
+ "mfgCode": null,
+ "side": "server",
+ "type": "AlarmMap",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "15",
+ "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": "1",
+ "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
+ }
+ ],
+ "events": [
+ {
+ "name": "Notify",
+ "code": 0,
+ "mfgCode": null,
+ "side": "server",
+ "included": 1
+ }
+ ]
+ },
+ {
"name": "Operational State",
"code": 96,
"mfgCode": null,
diff --git a/examples/all-clusters-app/all-clusters-common/src/dishwasher-alarm-stub.cpp b/examples/all-clusters-app/all-clusters-common/src/dishwasher-alarm-stub.cpp
new file mode 100644
index 0000000..58d3937
--- /dev/null
+++ b/examples/all-clusters-app/all-clusters-common/src/dishwasher-alarm-stub.cpp
@@ -0,0 +1,142 @@
+/*
+ *
+ * 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 <app-common/zap-generated/cluster-objects.h>
+#include <app/clusters/dishwasher-alarm-server/dishwasher-alarm-server.h>
+#include <app/util/af-enums.h>
+
+using namespace chip;
+
+namespace chip {
+namespace app {
+namespace Clusters {
+namespace DishwasherAlarm {
+
+class DishwasherAlarmDelegate : public Delegate
+{
+public:
+ /**
+ * @brief
+ * A notification that the Mask attribute will be changed. When this happens, some previously suppressed
+ * alarms may need to be enabled, and previously enabled alarms may need to be suppressed.
+ * @param[in] mask The new value of the Mask attribute.
+ * @return The cluster will do this update if ModifyEnabledAlarmsCallback() returns true.
+ * The cluster will not do this update if ModifyEnabledAlarmsCallback() returns false.
+ */
+ bool ModifyEnabledAlarmsCallback(const BitMask<AlarmMap> mask) override;
+
+ /**
+ * @brief
+ * A notification that resets active alarms (if possible)
+ * @param[in] alarms The value of reset alarms
+ * @return The cluster will reset active alarms if ResetAlarmsCallback() returns true.
+ * The cluster will not reset active alarms if ResetAlarmsCallback() returns false.
+ */
+ bool ResetAlarmsCallback(const BitMask<AlarmMap> alarms) override;
+
+ ~DishwasherAlarmDelegate() = default;
+};
+
+bool DishwasherAlarmDelegate::ModifyEnabledAlarmsCallback(const BitMask<AlarmMap> mask)
+{
+ // placeholder implementation
+ return true;
+}
+
+bool DishwasherAlarmDelegate::ResetAlarmsCallback(const BitMask<AlarmMap> alarms)
+{
+ // placeholder implementation
+ return true;
+}
+
+} // namespace DishwasherAlarm
+} // namespace Clusters
+} // namespace app
+} // namespace chip
+
+/*
+ * An example to present device's endpointId
+ */
+static constexpr EndpointId kDemoEndpointId = 1;
+
+void MatterDishwasherAlarmServerInit()
+{
+ using namespace app::Clusters;
+ using namespace app::Clusters::DishwasherAlarm;
+
+ static DishwasherAlarm::DishwasherAlarmDelegate delegate;
+ DishwasherAlarm::SetDefaultDelegate(kDemoEndpointId, &delegate);
+
+ // Set Supported attribute = 0x2F = 47
+ // Bit Name Value
+ // 0 InflowError 1
+ // 1 DrainError 1
+ // 2 DoorError 1
+ // 3 TempTooLow 1
+ // 4 TempTooHigh 0
+ // 5 WaterLevelError 1
+ BitMask<AlarmMap> supported;
+ supported.SetField(AlarmMap::kInflowError, 1);
+ supported.SetField(AlarmMap::kDrainError, 1);
+ supported.SetField(AlarmMap::kDoorError, 1);
+ supported.SetField(AlarmMap::kTempTooLow, 1);
+ supported.SetField(AlarmMap::kWaterLevelError, 1);
+ DishwasherAlarmServer::Instance().SetSupportedValue(kDemoEndpointId, supported);
+
+ // Set Mask attribute = 0x2F = 47
+ // Bit Name Value
+ // 0 InflowError 1
+ // 1 DrainError 1
+ // 2 DoorError 1
+ // 3 TempTooLow 1
+ // 4 TempTooHigh 0
+ // 5 WaterLevelError 1
+ BitMask<AlarmMap> mask;
+ mask.SetField(AlarmMap::kInflowError, 1);
+ mask.SetField(AlarmMap::kDrainError, 1);
+ mask.SetField(AlarmMap::kDoorError, 1);
+ mask.SetField(AlarmMap::kTempTooLow, 1);
+ mask.SetField(AlarmMap::kWaterLevelError, 1);
+ DishwasherAlarmServer::Instance().SetMaskValue(kDemoEndpointId, mask);
+
+ // Set Latch attribute = 0x03
+ // Bit Name Value
+ // 0 InflowError 1
+ // 1 DrainError 1
+ // 2 DoorError 0
+ // 3 TempTooLow 0
+ // 4 TempTooHigh 0
+ // 5 WaterLevelError 0
+ BitMask<AlarmMap> latch;
+ latch.SetField(AlarmMap::kInflowError, 1);
+ latch.SetField(AlarmMap::kDrainError, 1);
+ DishwasherAlarmServer::Instance().SetLatchValue(kDemoEndpointId, latch);
+
+ // Set State attribute = 0x07
+ // Bit Name Value
+ // 0 InflowError 1
+ // 1 DrainError 1
+ // 2 DoorError 1
+ // 3 TempTooLow 0
+ // 4 TempTooHigh 0
+ // 5 WaterLevelError 0
+ BitMask<AlarmMap> state;
+ state.SetField(AlarmMap::kInflowError, 1);
+ state.SetField(AlarmMap::kDrainError, 1);
+ state.SetField(AlarmMap::kDoorError, 1);
+ DishwasherAlarmServer::Instance().SetStateValue(kDemoEndpointId, state);
+}
diff --git a/examples/all-clusters-app/esp32/main/CMakeLists.txt b/examples/all-clusters-app/esp32/main/CMakeLists.txt
index 90ba706..1401533 100644
--- a/examples/all-clusters-app/esp32/main/CMakeLists.txt
+++ b/examples/all-clusters-app/esp32/main/CMakeLists.txt
@@ -95,6 +95,7 @@
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/resource-monitoring-server"
"${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/examples/all-clusters-app/all-clusters-common/src"
)
diff --git a/examples/all-clusters-app/linux/BUILD.gn b/examples/all-clusters-app/linux/BUILD.gn
index bdaf494..72cd65b 100644
--- a/examples/all-clusters-app/linux/BUILD.gn
+++ b/examples/all-clusters-app/linux/BUILD.gn
@@ -23,6 +23,7 @@
sources = [
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/binding-handler.cpp",
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp",
+ "${chip_root}/examples/all-clusters-app/all-clusters-common/src/dishwasher-alarm-stub.cpp",
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/dishwasher-mode.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-washer-mode.cpp",
diff --git a/examples/all-clusters-app/linux/main-common.cpp b/examples/all-clusters-app/linux/main-common.cpp
index 7894a78..0ebeff4 100644
--- a/examples/all-clusters-app/linux/main-common.cpp
+++ b/examples/all-clusters-app/linux/main-common.cpp
@@ -61,6 +61,9 @@
#ifdef EMBER_AF_PLUGIN_OPERATIONAL_STATE_SERVER
extern void MatterOperationalStateServerInit();
#endif
+#ifdef EMBER_AF_PLUGIN_DISHWASHER_ALARM_SERVER
+extern void MatterDishwasherAlarmServerInit();
+#endif
void OnIdentifyStart(::Identify *)
{
@@ -181,6 +184,10 @@
#ifdef EMBER_AF_PLUGIN_OPERATIONAL_STATE_SERVER
MatterOperationalStateServerInit();
#endif
+
+#ifdef EMBER_AF_PLUGIN_DISHWASHER_ALARM_SERVER
+ MatterDishwasherAlarmServerInit();
+#endif
app::Clusters::TemperatureControl::SetInstance(&sAppSupportedTemperatureLevelsDelegate);
}
diff --git a/src/app/chip_data_model.gni b/src/app/chip_data_model.gni
index 8eae0fc..1724d10 100644
--- a/src/app/chip_data_model.gni
+++ b/src/app/chip_data_model.gni
@@ -270,6 +270,12 @@
"${_app_root}/clusters/${cluster}/${cluster}.h",
"${_app_root}/clusters/${cluster}/operational-state-delegate.h",
]
+ } else if (cluster == "dishwasher-alarm-server") {
+ sources += [
+ "${_app_root}/clusters/${cluster}/${cluster}.cpp",
+ "${_app_root}/clusters/${cluster}/${cluster}.h",
+ "${_app_root}/clusters/${cluster}/dishwasher-alarm-delegate.h",
+ ]
} else if (cluster == "icd-management-server") {
sources += [ "${_app_root}/clusters/${cluster}/${cluster}.cpp" ]
diff --git a/src/app/clusters/dishwasher-alarm-server/dishwasher-alarm-delegate.h b/src/app/clusters/dishwasher-alarm-server/dishwasher-alarm-delegate.h
new file mode 100644
index 0000000..5f4e772
--- /dev/null
+++ b/src/app/clusters/dishwasher-alarm-server/dishwasher-alarm-delegate.h
@@ -0,0 +1,69 @@
+/*
+ *
+ * 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>
+#include <app/CommandResponseHelper.h>
+#include <app/util/af.h>
+
+namespace chip {
+namespace app {
+namespace Clusters {
+namespace DishwasherAlarm {
+
+/** @brief
+ * Defines methods for implementing application-specific logic for the DishwasherAlarm Cluster.
+ */
+class Delegate
+{
+public:
+ /**
+ * @brief
+ * A notification that the Mask attribute will be changed. When this happens, some previously suppressed
+ * alarms may need to be enabled, and previously enabled alarms may need to be suppressed.
+ * @param[in] mask The new value of the Mask attribute.
+ * @return The cluster will do this update if ModifyEnabledAlarmsCallback() returns true.
+ * the cluster will not do this update if ModifyEnabledAlarmsCallback() returns false.
+ */
+ virtual bool ModifyEnabledAlarmsCallback(const BitMask<AlarmMap> mask) = 0;
+
+ /**
+ * @brief
+ * A notification that resets active alarms (if possible)
+ * @param[in] alarms The value of reset alarms
+ * @return The cluster will reset active alarms if ResetAlarmsCallback() returns true.
+ * The cluster will not reset active alarms if ResetAlarmsCallback() returns false.
+ */
+ virtual bool ResetAlarmsCallback(const BitMask<AlarmMap> alarms) = 0;
+
+ Delegate(EndpointId endpoint) : mEndpoint(endpoint) {}
+
+ Delegate() = default;
+
+ virtual ~Delegate() = default;
+
+protected:
+ EndpointId mEndpoint = 0;
+};
+
+} // namespace DishwasherAlarm
+} // namespace Clusters
+} // namespace app
+} // namespace chip
diff --git a/src/app/clusters/dishwasher-alarm-server/dishwasher-alarm-server.cpp b/src/app/clusters/dishwasher-alarm-server/dishwasher-alarm-server.cpp
new file mode 100644
index 0000000..c0d167f
--- /dev/null
+++ b/src/app/clusters/dishwasher-alarm-server/dishwasher-alarm-server.cpp
@@ -0,0 +1,398 @@
+/**
+ *
+ * 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 "dishwasher-alarm-server.h"
+
+#include <app-common/zap-generated/attributes/Accessors.h>
+#include <app-common/zap-generated/cluster-enums.h>
+#include <app-common/zap-generated/cluster-objects.h>
+#include <app/EventLogging.h>
+#include <app/InteractionModelEngine.h>
+#include <app/util/attribute-storage.h>
+#include <app/util/error-mapping.h>
+#include <lib/support/BitFlags.h>
+
+using namespace chip;
+using namespace chip::app;
+using namespace chip::app::Clusters;
+using namespace chip::app::Clusters::DishwasherAlarm;
+using namespace chip::app::Clusters::DishwasherAlarm::Attributes;
+using namespace chip::DeviceLayer;
+using chip::Protocols::InteractionModel::Status;
+using namespace std;
+
+static constexpr size_t kDishwasherAlarmDelegateTableSize =
+ EMBER_AF_DISHWASHER_ALARM_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT;
+
+static_assert(kDishwasherAlarmDelegateTableSize <= kEmberInvalidEndpointIndex, "Dishwasher Alarm Delegate table size error");
+
+namespace chip {
+namespace app {
+namespace Clusters {
+namespace DishwasherAlarm {
+
+Delegate * gDelegateTable[kDishwasherAlarmDelegateTableSize] = { nullptr };
+
+Delegate * GetDelegate(EndpointId endpoint)
+{
+ uint16_t ep = emberAfGetClusterServerEndpointIndex(endpoint, DishwasherAlarm::Id,
+ EMBER_AF_DISHWASHER_ALARM_CLUSTER_SERVER_ENDPOINT_COUNT);
+ return (ep >= kDishwasherAlarmDelegateTableSize ? nullptr : gDelegateTable[ep]);
+}
+
+void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate)
+{
+ uint16_t ep = emberAfGetClusterServerEndpointIndex(endpoint, DishwasherAlarm::Id,
+ EMBER_AF_DISHWASHER_ALARM_CLUSTER_SERVER_ENDPOINT_COUNT);
+ // if endpoint is found
+ if (ep < kDishwasherAlarmDelegateTableSize)
+ {
+ gDelegateTable[ep] = delegate;
+ }
+}
+
+} // namespace DishwasherAlarm
+} // namespace Clusters
+} // namespace app
+} // namespace chip
+
+DishwasherAlarmServer DishwasherAlarmServer::instance;
+
+DishwasherAlarmServer & DishwasherAlarmServer::Instance()
+{
+ return instance;
+}
+
+EmberAfStatus DishwasherAlarmServer::GetMaskValue(EndpointId endpoint, BitMask<AlarmMap> * mask)
+{
+ EmberAfStatus status = Attributes::Mask::Get(endpoint, mask);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ ChipLogProgress(Zcl, "Dishwasher Alarm: ERR: reading mask, err:0x%x", status);
+ return status;
+ }
+ return status;
+}
+
+EmberAfStatus DishwasherAlarmServer::GetLatchValue(EndpointId endpoint, BitMask<AlarmMap> * latch)
+{
+ if (!HasResetFeature(endpoint))
+ {
+ ChipLogProgress(Zcl, "Dishwasher Alarm feature: Unsupport Latch attribute");
+ return EMBER_ZCL_STATUS_UNSUPPORTED_ATTRIBUTE;
+ }
+
+ EmberAfStatus status = Attributes::Latch::Get(endpoint, latch);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ ChipLogProgress(Zcl, "Dishwasher Alarm: ERR: reading latch, err:0x%x", status);
+ return status;
+ }
+ return status;
+}
+
+EmberAfStatus DishwasherAlarmServer::GetStateValue(EndpointId endpoint, BitMask<AlarmMap> * state)
+{
+ EmberAfStatus status = Attributes::State::Get(endpoint, state);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ ChipLogProgress(Zcl, "Dishwasher Alarm: ERR: get state, err:0x%x", status);
+ return status;
+ }
+ return status;
+}
+
+EmberAfStatus DishwasherAlarmServer::GetSupportedValue(EndpointId endpoint, BitMask<AlarmMap> * supported)
+{
+ EmberAfStatus status = Attributes::Supported::Get(endpoint, supported);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ ChipLogProgress(Zcl, "Dishwasher Alarm: ERR: reading supported, err:0x%x", status);
+ }
+ return status;
+}
+
+EmberAfStatus DishwasherAlarmServer::SetSupportedValue(EndpointId endpoint, const BitMask<AlarmMap> supported)
+{
+ EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS;
+ ;
+ if ((status = Attributes::Supported::Set(endpoint, supported)) != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ ChipLogProgress(Zcl, "Dishwasher Alarm: ERR: writing supported, err:0x%x", status);
+ return status;
+ }
+ // Whenever there is change in Supported attribute, Latch should change accordingly (if possible).
+ BitMask<AlarmMap> latch;
+ if (GetLatchValue(endpoint, &latch) == EMBER_ZCL_STATUS_SUCCESS && !supported.HasAll(latch))
+ {
+ latch = latch & supported;
+ status = SetLatchValue(endpoint, latch);
+ }
+
+ // Whenever there is change in Supported attribute, Mask, State should change accordingly.
+ BitMask<AlarmMap> mask;
+ if ((status = GetMaskValue(endpoint, &mask)) != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ return status;
+ }
+
+ if (!supported.HasAll(mask))
+ {
+ mask = supported & mask;
+ status = SetMaskValue(endpoint, mask);
+ }
+ return status;
+}
+
+EmberAfStatus DishwasherAlarmServer::SetMaskValue(EndpointId endpoint, const BitMask<AlarmMap> mask)
+{
+ BitMask<AlarmMap> supported;
+ if (GetSupportedValue(endpoint, &supported) || !supported.HasAll(mask))
+ {
+ ChipLogProgress(Zcl, "Dishwasher Alarm: ERR: Mask is not supported");
+ return EMBER_ZCL_STATUS_FAILURE;
+ }
+
+ EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS;
+ if ((status = Attributes::Mask::Set(endpoint, mask)) != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ ChipLogProgress(Zcl, "Dishwasher Alarm: ERR: writing mask, err:0x%x", status);
+ return status;
+ }
+
+ // Whenever there is change in Mask, State should change accordingly.
+ BitMask<AlarmMap> state;
+ status = GetStateValue(endpoint, &state);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ return status;
+ }
+
+ if (!mask.HasAll(state))
+ {
+ state = mask & state;
+ status = SetStateValue(endpoint, state, true);
+ }
+ return status;
+}
+
+EmberAfStatus DishwasherAlarmServer::SetLatchValue(EndpointId endpoint, const BitMask<AlarmMap> latch)
+{
+ if (!HasResetFeature(endpoint))
+ {
+ ChipLogProgress(Zcl, "Dishwasher Alarm feature: Unsupport Latch attribute");
+ return EMBER_ZCL_STATUS_UNSUPPORTED_ATTRIBUTE;
+ }
+
+ BitMask<AlarmMap> supported;
+ if (GetSupportedValue(endpoint, &supported) || !supported.HasAll(latch))
+ {
+ ChipLogProgress(Zcl, "Dishwasher Alarm: ERR: Latch is not supported");
+ return EMBER_ZCL_STATUS_FAILURE;
+ }
+
+ EmberAfStatus status = Attributes::Latch::Set(endpoint, latch);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ ChipLogProgress(Zcl, "Dishwasher Alarm: ERR: writing latch, err:0x%x", status);
+ return status;
+ }
+
+ return status;
+}
+
+EmberAfStatus DishwasherAlarmServer::SetStateValue(EndpointId endpoint, const BitMask<AlarmMap> newState, bool ignoreLatchState)
+{
+ BitMask<AlarmMap> supported;
+ BitMask<AlarmMap> finalNewState;
+ finalNewState.Set(newState);
+
+ if (GetSupportedValue(endpoint, &supported) || !supported.HasAll(finalNewState))
+ {
+ ChipLogProgress(Zcl, "Dishwasher Alarm: ERR: Alarm is not supported");
+ return EMBER_ZCL_STATUS_FAILURE;
+ }
+
+ BitMask<AlarmMap> mask;
+ if (GetMaskValue(endpoint, &mask) || !mask.HasAll(finalNewState))
+ {
+ ChipLogProgress(Zcl, "Dishwasher Alarm: ERR: Alarm is suppressed");
+ return EMBER_ZCL_STATUS_FAILURE;
+ }
+
+ EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS;
+ BitMask<AlarmMap> currentState;
+ status = Attributes::State::Get(endpoint, ¤tState);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ ChipLogProgress(Zcl, "Dishwasher Alarm: ERR: reading state, err:0x%x", status);
+ return status;
+ }
+
+ BitMask<AlarmMap> latch;
+ if (!ignoreLatchState && (GetLatchValue(endpoint, &latch) == EMBER_ZCL_STATUS_SUCCESS))
+ {
+ // Restore bits that have their Latch bit set.
+ auto bitsToKeep = latch & currentState;
+ finalNewState.Set(bitsToKeep);
+ }
+
+ // Store the new value of the State attribute.
+ status = Attributes::State::Set(endpoint, finalNewState);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ ChipLogProgress(Zcl, "Dishwasher Alarm: ERR: writing state, err:0x%x", status);
+ return status;
+ }
+
+ // Generate Notify event.
+ BitMask<AlarmMap> becameActive;
+ becameActive.Set(finalNewState).Clear(currentState);
+ BitMask<AlarmMap> becameInactive;
+ becameInactive.Set(currentState).Clear(finalNewState);
+
+ SendNotifyEvent(endpoint, becameActive, becameInactive, finalNewState, mask);
+ return status;
+}
+
+EmberAfStatus DishwasherAlarmServer::ResetLatchedAlarms(EndpointId endpoint, const BitMask<AlarmMap> alarms)
+{
+ BitMask<AlarmMap> supported;
+ if (GetSupportedValue(endpoint, &supported) || !supported.HasAll(alarms))
+ {
+ ChipLogProgress(Zcl, "Dishwasher Alarm: ERR: Alarm is not supported");
+ return EMBER_ZCL_STATUS_FAILURE;
+ }
+
+ BitMask<AlarmMap> state;
+ if (GetStateValue(endpoint, &state) != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ return EMBER_ZCL_STATUS_FAILURE;
+ }
+
+ state.Clear(alarms);
+ return SetStateValue(endpoint, state, true);
+}
+
+bool DishwasherAlarmServer::HasResetFeature(EndpointId endpoint)
+{
+ uint32_t featureMap = 0;
+ if (Attributes::FeatureMap::Get(endpoint, &featureMap) != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ return false;
+ }
+
+ if (featureMap & 1)
+ {
+ return true;
+ }
+ return false;
+}
+
+void DishwasherAlarmServer::SendNotifyEvent(EndpointId endpointId, BitMask<AlarmMap> becameActive, BitMask<AlarmMap> becameInactive,
+ BitMask<AlarmMap> newState, BitMask<AlarmMap> mask)
+{
+ Events::Notify::Type event{ .active = becameActive, .inactive = becameInactive, .state = newState, .mask = mask };
+ EventNumber eventNumber;
+ CHIP_ERROR error = LogEvent(event, endpointId, eventNumber);
+ if (CHIP_NO_ERROR != error)
+ {
+ ChipLogError(Zcl, "[Notify] Unable to send notify event: %s [endpointId=%d]", error.AsString(), endpointId);
+ }
+}
+
+static Status ModifyEnabledHandler(const app::ConcreteCommandPath & commandPath, const BitMask<AlarmMap> mask)
+{
+ EndpointId endpoint = commandPath.mEndpointId;
+ BitMask<AlarmMap> supported;
+
+ if (DishwasherAlarmServer::Instance().GetSupportedValue(endpoint, &supported) != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ return Status::Failure;
+ }
+
+ // receives this command with a Mask that includes bits that are set for alarms which are not supported
+ if (!supported.HasAll(mask))
+ {
+ return Status::InvalidCommand;
+ }
+
+ // A server that is unable to enable a currently suppressed alarm,
+ // or is unable to suppress a currently enabled alarm SHALL respond
+ // with a status code of FAILURE
+ Delegate * delegate = DishwasherAlarm::GetDelegate(endpoint);
+ if (delegate && !(delegate->ModifyEnabledAlarmsCallback(mask)))
+ {
+ ChipLogProgress(Zcl, "Unable to modify enabled alarms");
+ return Status::Failure;
+ }
+ // The cluster will do this update if delegate.ModifyEnabledAlarmsCallback() returns true.
+ if (DishwasherAlarmServer::Instance().SetMaskValue(endpoint, mask) != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ return Status::Failure;
+ }
+ return Status::Success;
+}
+
+static Status ResetHandler(const app::ConcreteCommandPath & commandPath, const BitMask<AlarmMap> alarms)
+{
+ EndpointId endpoint = commandPath.mEndpointId;
+
+ if (!DishwasherAlarmServer::Instance().HasResetFeature(endpoint))
+ {
+ ChipLogProgress(Zcl, "Dishwasher Alarm feature: Unsupport Reset Command");
+ return app::ToInteractionModelStatus(EMBER_ZCL_STATUS_UNSUPPORTED_COMMAND);
+ }
+
+ // A server that is unable to reset alarms SHALL respond with a status code of FAILURE
+ Delegate * delegate = DishwasherAlarm::GetDelegate(endpoint);
+ if (delegate && !(delegate->ResetAlarmsCallback(alarms)))
+ {
+ ChipLogProgress(Zcl, "Unable to reset alarms");
+ return Status::Failure;
+ }
+
+ // The cluster will do this update if delegate.ResetAlarmsCallback() returns true.
+ if (DishwasherAlarmServer::Instance().ResetLatchedAlarms(endpoint, alarms) != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ ChipLogProgress(Zcl, "reset alarms fail");
+ return Status::Failure;
+ }
+ return Status::Success;
+}
+
+bool emberAfDishwasherAlarmClusterResetCallback(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath,
+ const Commands::Reset::DecodableType & commandData)
+{
+ auto & alarms = commandData.alarms;
+
+ Status status = ResetHandler(commandPath, alarms);
+ commandObj->AddStatus(commandPath, status);
+
+ return true;
+}
+
+bool emberAfDishwasherAlarmClusterModifyEnabledAlarmsCallback(app::CommandHandler * commandObj,
+ const app::ConcreteCommandPath & commandPath,
+ const Commands::ModifyEnabledAlarms::DecodableType & commandData)
+{
+ auto & mask = commandData.mask;
+ Status status = ModifyEnabledHandler(commandPath, mask);
+ commandObj->AddStatus(commandPath, status);
+
+ return true;
+}
diff --git a/src/app/clusters/dishwasher-alarm-server/dishwasher-alarm-server.h b/src/app/clusters/dishwasher-alarm-server/dishwasher-alarm-server.h
new file mode 100644
index 0000000..d03662f
--- /dev/null
+++ b/src/app/clusters/dishwasher-alarm-server/dishwasher-alarm-server.h
@@ -0,0 +1,89 @@
+/*
+ *
+ * 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 "dishwasher-alarm-delegate.h"
+#include <app-common/zap-generated/cluster-objects.h>
+#include <app/CommandHandler.h>
+#include <app/ConcreteCommandPath.h>
+#include <app/util/af-types.h>
+#include <app/util/basic-types.h>
+#include <platform/CHIPDeviceConfig.h>
+
+namespace chip {
+namespace app {
+namespace Clusters {
+namespace DishwasherAlarm {
+
+class DishwasherAlarmServer
+{
+public:
+ static DishwasherAlarmServer & Instance();
+
+ EmberAfStatus GetMaskValue(EndpointId endpoint, BitMask<AlarmMap> * mask);
+ EmberAfStatus GetStateValue(EndpointId endpoint, BitMask<AlarmMap> * state);
+ EmberAfStatus GetLatchValue(EndpointId endpoint, BitMask<AlarmMap> * latch);
+ EmberAfStatus GetSupportedValue(EndpointId endpoint, BitMask<AlarmMap> * suppported);
+
+ // Whenever there is change on Mask we should change State accordingly.
+ EmberAfStatus SetMaskValue(EndpointId endpoint, const BitMask<AlarmMap> mask);
+ EmberAfStatus SetLatchValue(EndpointId endpoint, const BitMask<AlarmMap> latch);
+ // A change in supported value will result in a corresponding change in mask and state.
+ EmberAfStatus SetSupportedValue(EndpointId endpoint, const BitMask<AlarmMap> supported);
+
+ /**
+ * @brief Set the value of the State attribute
+ * This method sets the State attribute to the value in newState, if allowed by the Mask
+ * and Supported attributes. When the State attribute changes, a Notify event will be
+ * generated.
+ * @param[in] endpoint The endpoint corresponding to the Dishwasher Alarm cluster.
+ * @param[in] newState The desired new value for the State attribute.
+ * @param[in] ignoreLatchState If false, the Latch attribute will be honored and the
+ * method will not reset any bits in the State attribute which have their
+ * associated Latch bit set. If true, the Latch attribute is ignored and the value of
+ * the State attribute will be set to the value of the newState parameter while
+ * honoring the Mask and Supported attributes.
+ * The default value for the ignoreLatchState parameter is false.
+ */
+ EmberAfStatus SetStateValue(EndpointId endpoint, const BitMask<AlarmMap> newState, bool ignoreLatchState = false);
+
+ /**
+ * @brief Reset the value of latched alarms in the State attribute.
+ * When the State attribute changes a Notify event is generated.
+ * @param[in] endpoint The endpoint corresponding to the Dishwasher Alarm cluster.
+ * @param[in] alarms Each bit set to a 1 in this parameter corresponds to a bit in the
+ * State attribute will SHALL be reset to false.
+ */
+ EmberAfStatus ResetLatchedAlarms(EndpointId endpoint, const BitMask<AlarmMap> alarms);
+
+ // check whether the Alarm featureMap has enabled Reset feature.
+ bool HasResetFeature(EndpointId endpoint);
+
+private:
+ static DishwasherAlarmServer instance;
+
+ void SendNotifyEvent(EndpointId endpointId, BitMask<AlarmMap> becameActive, BitMask<AlarmMap> becameInactive,
+ BitMask<AlarmMap> newState, BitMask<AlarmMap> mask);
+};
+
+void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate);
+
+} // namespace DishwasherAlarm
+} // namespace Clusters
+} // namespace app
+} // namespace chip
diff --git a/src/app/tests/suites/TestDishwasherAlarm.yaml b/src/app/tests/suites/TestDishwasherAlarm.yaml
new file mode 100644
index 0000000..94af332
--- /dev/null
+++ b/src/app/tests/suites/TestDishwasherAlarm.yaml
@@ -0,0 +1,190 @@
+# 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.
+
+name: Dishwasher Alarm Tests
+
+config:
+ nodeId: 0x12344321
+ cluster: "Dishwasher Alarm"
+ endpoint: 1
+
+tests:
+ - label: "Wait for the commissioned device to be retrieved"
+ cluster: "DelayCommands"
+ command: "WaitForCommissionee"
+ arguments:
+ values:
+ - name: "nodeId"
+ value: nodeId
+ #Init
+ #Support 10 1111 (47) (0x2F)
+ #Mask 10 1111 (47) (0x2F)
+ #Latch 00 0011 (3) (0x03)
+ #State 00 0111 (7) (0x07)
+ #FeatureMap 1
+ - label: "Read Supported Attribute"
+ command: "readAttribute"
+ attribute: "Supported"
+ response:
+ value: 47
+
+ - label: "Read Mask Attribute"
+ command: "readAttribute"
+ attribute: "Mask"
+ response:
+ value: 47
+
+ - label: "Read Latch Attribute"
+ command: "readAttribute"
+ attribute: "Latch"
+ response:
+ value: 3
+
+ - label: "Read State Attribute"
+ command: "readAttribute"
+ attribute: "State"
+ response:
+ value: 7
+
+ - label: "Read feature map Attribute"
+ command: "readAttribute"
+ attribute: "FeatureMap"
+ response:
+ constraints:
+ type: bitmap32
+ hasMasksSet: [0x1]
+
+ #After Modify Enabled Alarm (Valid)
+ #Support 10 1111 (47) (0x2F)
+ #Mask 10 1001 (41) (0x29)
+ #Latch 00 0011 (3) (0x03)
+ #State 00 0001 (1) (0x01)
+ - label: "Modify enabled alarms Command"
+ command: "ModifyEnabledAlarms"
+ arguments:
+ values:
+ - name: "Mask"
+ value: 41
+
+ - label: "Read Mask Attribute"
+ command: "readAttribute"
+ attribute: "Mask"
+ response:
+ value: 41
+
+ - label: "Read Latch Attribute"
+ command: "readAttribute"
+ attribute: "Latch"
+ response:
+ value: 3
+
+ - label: "Read State Attribute"
+ command: "readAttribute"
+ attribute: "State"
+ response:
+ value: 1
+
+ #After Modify Enabled Alarm (Invalid, set for unknown alarms)
+ #Support 10 1111 (47) (0x2F)
+ #Mask 110 1001 (105) (0x69)
+ #Latch 00 0011 (3) (0x03)
+ #State 00 0001 (1) (0x01)
+ - label: "Modify enabled alarms Command"
+ command: "ModifyEnabledAlarms"
+ arguments:
+ values:
+ - name: "Mask"
+ value: 105
+ response:
+ error: INVALID_COMMAND
+
+ - label: "Read Mask Attribute"
+ command: "readAttribute"
+ attribute: "Mask"
+ response:
+ value: 41
+
+ - label: "Read Latch Attribute"
+ command: "readAttribute"
+ attribute: "Latch"
+ response:
+ value: 3
+
+ - label: "Read State Attribute"
+ command: "readAttribute"
+ attribute: "State"
+ response:
+ value: 1
+
+ #After Modify Enabled Alarm (Invalid, set for alarms which are not supported)
+ #Support 10 1111 (47) (0x2F)
+ #Mask 11 1011 (59) (0x3B)
+ #Latch 00 0011 (3) (0x03)
+ #State 00 0001 (1) (0x01)
+ - label: "Modify enabled alarms Command"
+ command: "ModifyEnabledAlarms"
+ arguments:
+ values:
+ - name: "Mask"
+ value: 59
+ response:
+ error: INVALID_COMMAND
+
+ - label: "Read Mask Attribute"
+ command: "readAttribute"
+ attribute: "Mask"
+ response:
+ value: 41
+
+ - label: "Read Latch Attribute"
+ command: "readAttribute"
+ attribute: "Latch"
+ response:
+ value: 3
+
+ - label: "Read State Attribute"
+ command: "readAttribute"
+ attribute: "State"
+ response:
+ value: 1
+
+ #After Reset alarms bit 0
+ #Support 10 1111 (47) (0x2F)
+ #Mask 10 1001 (41) (0x29)
+ #Latch 00 0011 (3) (0x03)
+ #State 00 0000 (0) (0x00)
+ - label: "Reset Command"
+ command: "Reset"
+ arguments:
+ values:
+ - name: "Alarms"
+ value: 1
+
+ - label: "Read Mask Attribute"
+ command: "readAttribute"
+ attribute: "Mask"
+ response:
+ value: 41
+
+ - label: "Read Latch Attribute"
+ command: "readAttribute"
+ attribute: "Latch"
+ response:
+ value: 3
+
+ - label: "Read State Attribute"
+ command: "readAttribute"
+ attribute: "State"
+ response:
+ value: 0
diff --git a/src/app/tests/suites/ciTests.json b/src/app/tests/suites/ciTests.json
index fbb8340..377dd56 100644
--- a/src/app/tests/suites/ciTests.json
+++ b/src/app/tests/suites/ciTests.json
@@ -270,7 +270,8 @@
"TestCommissionerNodeId",
"TestTimeSynchronization",
"TestOperationalState",
- "TestRVCOperationalState"
+ "TestRVCOperationalState",
+ "TestDishwasherAlarm"
],
"MultiAdmin": ["TestMultiAdmin"],
"SoftwareDiagnostics": ["Test_TC_DGSW_1_1"],
diff --git a/src/app/util/util.cpp b/src/app/util/util.cpp
index 116ed03..dd2085a 100644
--- a/src/app/util/util.cpp
+++ b/src/app/util/util.cpp
@@ -156,6 +156,7 @@
void MatterRefrigeratorAndTemperatureControlledCabinetModePluginServerInitCallback() {}
void MatterOperationalStatePluginServerInitCallback() {}
void MatterRvcOperationalStatePluginServerInitCallback() {}
+void MatterDishwasherAlarmPluginServerInitCallback() {}
// ****************************************
// Print out information about each cluster
// ****************************************
diff --git a/zzz_generated/chip-tool/zap-generated/test/Commands.h b/zzz_generated/chip-tool/zap-generated/test/Commands.h
index 2ede952..ce0c3be 100644
--- a/zzz_generated/chip-tool/zap-generated/test/Commands.h
+++ b/zzz_generated/chip-tool/zap-generated/test/Commands.h
@@ -299,6 +299,7 @@
printf("TestTimeSynchronization\n");
printf("TestOperationalState\n");
printf("TestRVCOperationalState\n");
+ printf("TestDishwasherAlarm\n");
printf("TestMultiAdmin\n");
printf("Test_TC_DGSW_1_1\n");
printf("TestSubscribe_OnOff\n");
@@ -96813,6 +96814,348 @@
}
};
+class TestDishwasherAlarmSuite : public TestCommand
+{
+public:
+ TestDishwasherAlarmSuite(CredentialIssuerCommands * credsIssuerConfig) :
+ TestCommand("TestDishwasherAlarm", 22, credsIssuerConfig)
+ {
+ AddArgument("nodeId", 0, UINT64_MAX, &mNodeId);
+ AddArgument("cluster", &mCluster);
+ AddArgument("endpoint", 0, UINT16_MAX, &mEndpoint);
+ AddArgument("timeout", 0, UINT16_MAX, &mTimeout);
+ }
+
+ ~TestDishwasherAlarmSuite() {}
+
+ chip::System::Clock::Timeout GetWaitDuration() const override
+ {
+ return chip::System::Clock::Seconds16(mTimeout.ValueOr(kTimeoutInSeconds));
+ }
+
+private:
+ chip::Optional<chip::NodeId> mNodeId;
+ chip::Optional<chip::CharSpan> mCluster;
+ chip::Optional<chip::EndpointId> mEndpoint;
+ chip::Optional<uint16_t> mTimeout;
+
+ chip::EndpointId GetEndpoint(chip::EndpointId endpoint) { return mEndpoint.HasValue() ? mEndpoint.Value() : endpoint; }
+
+ //
+ // Tests methods
+ //
+
+ void OnResponse(const chip::app::StatusIB & status, chip::TLV::TLVReader * data) override
+ {
+ bool shouldContinue = false;
+
+ switch (mTestIndex - 1)
+ {
+ case 0:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ shouldContinue = true;
+ break;
+ case 1:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ {
+ chip::BitMask<chip::app::Clusters::DishwasherAlarm::AlarmMap> value;
+ VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value)));
+ VerifyOrReturn(CheckValue("supported", value, 47UL));
+ }
+ break;
+ case 2:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ {
+ chip::BitMask<chip::app::Clusters::DishwasherAlarm::AlarmMap> value;
+ VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value)));
+ VerifyOrReturn(CheckValue("mask", value, 47UL));
+ }
+ break;
+ case 3:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ {
+ chip::BitMask<chip::app::Clusters::DishwasherAlarm::AlarmMap> value;
+ VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value)));
+ VerifyOrReturn(CheckValue("latch", value, 3UL));
+ }
+ break;
+ case 4:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ {
+ chip::BitMask<chip::app::Clusters::DishwasherAlarm::AlarmMap> value;
+ VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value)));
+ VerifyOrReturn(CheckValue("state", value, 7UL));
+ }
+ break;
+ case 5:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ {
+ uint32_t value;
+ VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value)));
+ VerifyOrReturn(CheckConstraintType("value", "bitmap32", "bitmap32"));
+ VerifyOrReturn(CheckConstraintHasMasksSet("value", value, 1UL));
+ }
+ break;
+ case 6:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ break;
+ case 7:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ {
+ chip::BitMask<chip::app::Clusters::DishwasherAlarm::AlarmMap> value;
+ VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value)));
+ VerifyOrReturn(CheckValue("mask", value, 41UL));
+ }
+ break;
+ case 8:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ {
+ chip::BitMask<chip::app::Clusters::DishwasherAlarm::AlarmMap> value;
+ VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value)));
+ VerifyOrReturn(CheckValue("latch", value, 3UL));
+ }
+ break;
+ case 9:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ {
+ chip::BitMask<chip::app::Clusters::DishwasherAlarm::AlarmMap> value;
+ VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value)));
+ VerifyOrReturn(CheckValue("state", value, 1UL));
+ }
+ break;
+ case 10:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), EMBER_ZCL_STATUS_INVALID_COMMAND));
+ break;
+ case 11:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ {
+ chip::BitMask<chip::app::Clusters::DishwasherAlarm::AlarmMap> value;
+ VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value)));
+ VerifyOrReturn(CheckValue("mask", value, 41UL));
+ }
+ break;
+ case 12:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ {
+ chip::BitMask<chip::app::Clusters::DishwasherAlarm::AlarmMap> value;
+ VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value)));
+ VerifyOrReturn(CheckValue("latch", value, 3UL));
+ }
+ break;
+ case 13:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ {
+ chip::BitMask<chip::app::Clusters::DishwasherAlarm::AlarmMap> value;
+ VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value)));
+ VerifyOrReturn(CheckValue("state", value, 1UL));
+ }
+ break;
+ case 14:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), EMBER_ZCL_STATUS_INVALID_COMMAND));
+ break;
+ case 15:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ {
+ chip::BitMask<chip::app::Clusters::DishwasherAlarm::AlarmMap> value;
+ VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value)));
+ VerifyOrReturn(CheckValue("mask", value, 41UL));
+ }
+ break;
+ case 16:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ {
+ chip::BitMask<chip::app::Clusters::DishwasherAlarm::AlarmMap> value;
+ VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value)));
+ VerifyOrReturn(CheckValue("latch", value, 3UL));
+ }
+ break;
+ case 17:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ {
+ chip::BitMask<chip::app::Clusters::DishwasherAlarm::AlarmMap> value;
+ VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value)));
+ VerifyOrReturn(CheckValue("state", value, 1UL));
+ }
+ break;
+ case 18:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ break;
+ case 19:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ {
+ chip::BitMask<chip::app::Clusters::DishwasherAlarm::AlarmMap> value;
+ VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value)));
+ VerifyOrReturn(CheckValue("mask", value, 41UL));
+ }
+ break;
+ case 20:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ {
+ chip::BitMask<chip::app::Clusters::DishwasherAlarm::AlarmMap> value;
+ VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value)));
+ VerifyOrReturn(CheckValue("latch", value, 3UL));
+ }
+ break;
+ case 21:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ {
+ chip::BitMask<chip::app::Clusters::DishwasherAlarm::AlarmMap> value;
+ VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value)));
+ VerifyOrReturn(CheckValue("state", value, 0UL));
+ }
+ break;
+ default:
+ LogErrorOnFailure(ContinueOnChipMainThread(CHIP_ERROR_INVALID_ARGUMENT));
+ }
+
+ if (shouldContinue)
+ {
+ ContinueOnChipMainThread(CHIP_NO_ERROR);
+ }
+ }
+
+ CHIP_ERROR DoTestStep(uint16_t testIndex) override
+ {
+ using namespace chip::app::Clusters;
+ switch (testIndex)
+ {
+ case 0: {
+ LogStep(0, "Wait for the commissioned device to be retrieved");
+ ListFreer listFreer;
+ chip::app::Clusters::DelayCommands::Commands::WaitForCommissionee::Type value;
+ value.nodeId = mNodeId.HasValue() ? mNodeId.Value() : 305414945ULL;
+ return WaitForCommissionee(kIdentityAlpha, value);
+ }
+ case 1: {
+ LogStep(1, "Read Supported Attribute");
+ return ReadAttribute(kIdentityAlpha, GetEndpoint(1), DishwasherAlarm::Id, DishwasherAlarm::Attributes::Supported::Id,
+ true, chip::NullOptional);
+ }
+ case 2: {
+ LogStep(2, "Read Mask Attribute");
+ return ReadAttribute(kIdentityAlpha, GetEndpoint(1), DishwasherAlarm::Id, DishwasherAlarm::Attributes::Mask::Id, true,
+ chip::NullOptional);
+ }
+ case 3: {
+ LogStep(3, "Read Latch Attribute");
+ return ReadAttribute(kIdentityAlpha, GetEndpoint(1), DishwasherAlarm::Id, DishwasherAlarm::Attributes::Latch::Id, true,
+ chip::NullOptional);
+ }
+ case 4: {
+ LogStep(4, "Read State Attribute");
+ return ReadAttribute(kIdentityAlpha, GetEndpoint(1), DishwasherAlarm::Id, DishwasherAlarm::Attributes::State::Id, true,
+ chip::NullOptional);
+ }
+ case 5: {
+ LogStep(5, "Read feature map Attribute");
+ return ReadAttribute(kIdentityAlpha, GetEndpoint(1), DishwasherAlarm::Id, DishwasherAlarm::Attributes::FeatureMap::Id,
+ true, chip::NullOptional);
+ }
+ case 6: {
+ LogStep(6, "Modify enabled alarms Command");
+ ListFreer listFreer;
+ chip::app::Clusters::DishwasherAlarm::Commands::ModifyEnabledAlarms::Type value;
+ value.mask = static_cast<chip::BitMask<chip::app::Clusters::DishwasherAlarm::AlarmMap>>(41UL);
+ return SendCommand(kIdentityAlpha, GetEndpoint(1), DishwasherAlarm::Id,
+ DishwasherAlarm::Commands::ModifyEnabledAlarms::Id, value, chip::NullOptional
+
+ );
+ }
+ case 7: {
+ LogStep(7, "Read Mask Attribute");
+ return ReadAttribute(kIdentityAlpha, GetEndpoint(1), DishwasherAlarm::Id, DishwasherAlarm::Attributes::Mask::Id, true,
+ chip::NullOptional);
+ }
+ case 8: {
+ LogStep(8, "Read Latch Attribute");
+ return ReadAttribute(kIdentityAlpha, GetEndpoint(1), DishwasherAlarm::Id, DishwasherAlarm::Attributes::Latch::Id, true,
+ chip::NullOptional);
+ }
+ case 9: {
+ LogStep(9, "Read State Attribute");
+ return ReadAttribute(kIdentityAlpha, GetEndpoint(1), DishwasherAlarm::Id, DishwasherAlarm::Attributes::State::Id, true,
+ chip::NullOptional);
+ }
+ case 10: {
+ LogStep(10, "Modify enabled alarms Command");
+ ListFreer listFreer;
+ chip::app::Clusters::DishwasherAlarm::Commands::ModifyEnabledAlarms::Type value;
+ value.mask = static_cast<chip::BitMask<chip::app::Clusters::DishwasherAlarm::AlarmMap>>(105UL);
+ return SendCommand(kIdentityAlpha, GetEndpoint(1), DishwasherAlarm::Id,
+ DishwasherAlarm::Commands::ModifyEnabledAlarms::Id, value, chip::NullOptional
+
+ );
+ }
+ case 11: {
+ LogStep(11, "Read Mask Attribute");
+ return ReadAttribute(kIdentityAlpha, GetEndpoint(1), DishwasherAlarm::Id, DishwasherAlarm::Attributes::Mask::Id, true,
+ chip::NullOptional);
+ }
+ case 12: {
+ LogStep(12, "Read Latch Attribute");
+ return ReadAttribute(kIdentityAlpha, GetEndpoint(1), DishwasherAlarm::Id, DishwasherAlarm::Attributes::Latch::Id, true,
+ chip::NullOptional);
+ }
+ case 13: {
+ LogStep(13, "Read State Attribute");
+ return ReadAttribute(kIdentityAlpha, GetEndpoint(1), DishwasherAlarm::Id, DishwasherAlarm::Attributes::State::Id, true,
+ chip::NullOptional);
+ }
+ case 14: {
+ LogStep(14, "Modify enabled alarms Command");
+ ListFreer listFreer;
+ chip::app::Clusters::DishwasherAlarm::Commands::ModifyEnabledAlarms::Type value;
+ value.mask = static_cast<chip::BitMask<chip::app::Clusters::DishwasherAlarm::AlarmMap>>(59UL);
+ return SendCommand(kIdentityAlpha, GetEndpoint(1), DishwasherAlarm::Id,
+ DishwasherAlarm::Commands::ModifyEnabledAlarms::Id, value, chip::NullOptional
+
+ );
+ }
+ case 15: {
+ LogStep(15, "Read Mask Attribute");
+ return ReadAttribute(kIdentityAlpha, GetEndpoint(1), DishwasherAlarm::Id, DishwasherAlarm::Attributes::Mask::Id, true,
+ chip::NullOptional);
+ }
+ case 16: {
+ LogStep(16, "Read Latch Attribute");
+ return ReadAttribute(kIdentityAlpha, GetEndpoint(1), DishwasherAlarm::Id, DishwasherAlarm::Attributes::Latch::Id, true,
+ chip::NullOptional);
+ }
+ case 17: {
+ LogStep(17, "Read State Attribute");
+ return ReadAttribute(kIdentityAlpha, GetEndpoint(1), DishwasherAlarm::Id, DishwasherAlarm::Attributes::State::Id, true,
+ chip::NullOptional);
+ }
+ case 18: {
+ LogStep(18, "Reset Command");
+ ListFreer listFreer;
+ chip::app::Clusters::DishwasherAlarm::Commands::Reset::Type value;
+ value.alarms = static_cast<chip::BitMask<chip::app::Clusters::DishwasherAlarm::AlarmMap>>(1UL);
+ return SendCommand(kIdentityAlpha, GetEndpoint(1), DishwasherAlarm::Id, DishwasherAlarm::Commands::Reset::Id, value,
+ chip::NullOptional
+
+ );
+ }
+ case 19: {
+ LogStep(19, "Read Mask Attribute");
+ return ReadAttribute(kIdentityAlpha, GetEndpoint(1), DishwasherAlarm::Id, DishwasherAlarm::Attributes::Mask::Id, true,
+ chip::NullOptional);
+ }
+ case 20: {
+ LogStep(20, "Read Latch Attribute");
+ return ReadAttribute(kIdentityAlpha, GetEndpoint(1), DishwasherAlarm::Id, DishwasherAlarm::Attributes::Latch::Id, true,
+ chip::NullOptional);
+ }
+ case 21: {
+ LogStep(21, "Read State Attribute");
+ return ReadAttribute(kIdentityAlpha, GetEndpoint(1), DishwasherAlarm::Id, DishwasherAlarm::Attributes::State::Id, true,
+ chip::NullOptional);
+ }
+ }
+ return CHIP_NO_ERROR;
+ }
+};
+
class TestMultiAdminSuite : public TestCommand
{
public:
@@ -144580,6 +144923,7 @@
make_unique<TestTimeSynchronizationSuite>(credsIssuerConfig),
make_unique<TestOperationalStateSuite>(credsIssuerConfig),
make_unique<TestRVCOperationalStateSuite>(credsIssuerConfig),
+ make_unique<TestDishwasherAlarmSuite>(credsIssuerConfig),
make_unique<TestMultiAdminSuite>(credsIssuerConfig),
make_unique<Test_TC_DGSW_1_1Suite>(credsIssuerConfig),
make_unique<TestSubscribe_OnOffSuite>(credsIssuerConfig),
diff --git a/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h b/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h
index 2dc568d..3d69b11 100644
--- a/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h
+++ b/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h
@@ -266,6 +266,7 @@
printf("TestTimeSynchronization\n");
printf("TestOperationalState\n");
printf("TestRVCOperationalState\n");
+ printf("TestDishwasherAlarm\n");
printf("TestMultiAdmin\n");
printf("Test_TC_DGSW_1_1\n");
printf("TestSubscribe_OnOff\n");
@@ -143027,6 +143028,717 @@
}
};
+class TestDishwasherAlarm : public TestCommandBridge {
+public:
+ // NOLINTBEGIN(clang-analyzer-nullability.NullPassedToNonnull): Test constructor nullability not enforced
+ TestDishwasherAlarm()
+ : TestCommandBridge("TestDishwasherAlarm")
+ , mTestIndex(0)
+ {
+ AddArgument("nodeId", 0, UINT64_MAX, &mNodeId);
+ AddArgument("cluster", &mCluster);
+ AddArgument("endpoint", 0, UINT16_MAX, &mEndpoint);
+ AddArgument("timeout", 0, UINT16_MAX, &mTimeout);
+ }
+ // NOLINTEND(clang-analyzer-nullability.NullPassedToNonnull)
+
+ ~TestDishwasherAlarm() {}
+
+ /////////// TestCommand Interface /////////
+ void NextTest() override
+ {
+ CHIP_ERROR err = CHIP_NO_ERROR;
+
+ if (0 == mTestIndex) {
+ ChipLogProgress(chipTool, " **** Test Start: TestDishwasherAlarm\n");
+ }
+
+ if (mTestCount == mTestIndex) {
+ ChipLogProgress(chipTool, " **** Test Complete: TestDishwasherAlarm\n");
+ SetCommandExitStatus(CHIP_NO_ERROR);
+ return;
+ }
+
+ Wait();
+
+ // Ensure we increment mTestIndex before we start running the relevant
+ // command. That way if we lose the timeslice after we send the message
+ // but before our function call returns, we won't end up with an
+ // incorrect mTestIndex value observed when we get the response.
+ switch (mTestIndex++) {
+ case 0:
+ ChipLogProgress(chipTool, " ***** Test Step 0 : Wait for the commissioned device to be retrieved\n");
+ err = TestWaitForTheCommissionedDeviceToBeRetrieved_0();
+ break;
+ case 1:
+ ChipLogProgress(chipTool, " ***** Test Step 1 : Read Supported Attribute\n");
+ err = TestReadSupportedAttribute_1();
+ break;
+ case 2:
+ ChipLogProgress(chipTool, " ***** Test Step 2 : Read Mask Attribute\n");
+ err = TestReadMaskAttribute_2();
+ break;
+ case 3:
+ ChipLogProgress(chipTool, " ***** Test Step 3 : Read Latch Attribute\n");
+ err = TestReadLatchAttribute_3();
+ break;
+ case 4:
+ ChipLogProgress(chipTool, " ***** Test Step 4 : Read State Attribute\n");
+ err = TestReadStateAttribute_4();
+ break;
+ case 5:
+ ChipLogProgress(chipTool, " ***** Test Step 5 : Read feature map Attribute\n");
+ err = TestReadFeatureMapAttribute_5();
+ break;
+ case 6:
+ ChipLogProgress(chipTool, " ***** Test Step 6 : Modify enabled alarms Command\n");
+ err = TestModifyEnabledAlarmsCommand_6();
+ break;
+ case 7:
+ ChipLogProgress(chipTool, " ***** Test Step 7 : Read Mask Attribute\n");
+ err = TestReadMaskAttribute_7();
+ break;
+ case 8:
+ ChipLogProgress(chipTool, " ***** Test Step 8 : Read Latch Attribute\n");
+ err = TestReadLatchAttribute_8();
+ break;
+ case 9:
+ ChipLogProgress(chipTool, " ***** Test Step 9 : Read State Attribute\n");
+ err = TestReadStateAttribute_9();
+ break;
+ case 10:
+ ChipLogProgress(chipTool, " ***** Test Step 10 : Modify enabled alarms Command\n");
+ err = TestModifyEnabledAlarmsCommand_10();
+ break;
+ case 11:
+ ChipLogProgress(chipTool, " ***** Test Step 11 : Read Mask Attribute\n");
+ err = TestReadMaskAttribute_11();
+ break;
+ case 12:
+ ChipLogProgress(chipTool, " ***** Test Step 12 : Read Latch Attribute\n");
+ err = TestReadLatchAttribute_12();
+ break;
+ case 13:
+ ChipLogProgress(chipTool, " ***** Test Step 13 : Read State Attribute\n");
+ err = TestReadStateAttribute_13();
+ break;
+ case 14:
+ ChipLogProgress(chipTool, " ***** Test Step 14 : Modify enabled alarms Command\n");
+ err = TestModifyEnabledAlarmsCommand_14();
+ break;
+ case 15:
+ ChipLogProgress(chipTool, " ***** Test Step 15 : Read Mask Attribute\n");
+ err = TestReadMaskAttribute_15();
+ break;
+ case 16:
+ ChipLogProgress(chipTool, " ***** Test Step 16 : Read Latch Attribute\n");
+ err = TestReadLatchAttribute_16();
+ break;
+ case 17:
+ ChipLogProgress(chipTool, " ***** Test Step 17 : Read State Attribute\n");
+ err = TestReadStateAttribute_17();
+ break;
+ case 18:
+ ChipLogProgress(chipTool, " ***** Test Step 18 : Reset Command\n");
+ err = TestResetCommand_18();
+ break;
+ case 19:
+ ChipLogProgress(chipTool, " ***** Test Step 19 : Read Mask Attribute\n");
+ err = TestReadMaskAttribute_19();
+ break;
+ case 20:
+ ChipLogProgress(chipTool, " ***** Test Step 20 : Read Latch Attribute\n");
+ err = TestReadLatchAttribute_20();
+ break;
+ case 21:
+ ChipLogProgress(chipTool, " ***** Test Step 21 : Read State Attribute\n");
+ err = TestReadStateAttribute_21();
+ break;
+ }
+
+ if (CHIP_NO_ERROR != err) {
+ ChipLogError(chipTool, " ***** Test Failure: %s\n", chip::ErrorStr(err));
+ SetCommandExitStatus(err);
+ }
+ }
+
+ void OnStatusUpdate(const chip::app::StatusIB & status) override
+ {
+ switch (mTestIndex - 1) {
+ case 0:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ break;
+ case 1:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ break;
+ case 2:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ break;
+ case 3:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ break;
+ case 4:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ break;
+ case 5:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ break;
+ case 6:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ break;
+ case 7:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ break;
+ case 8:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ break;
+ case 9:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ break;
+ case 10:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), EMBER_ZCL_STATUS_INVALID_COMMAND));
+ break;
+ case 11:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ break;
+ case 12:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ break;
+ case 13:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ break;
+ case 14:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), EMBER_ZCL_STATUS_INVALID_COMMAND));
+ break;
+ case 15:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ break;
+ case 16:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ break;
+ case 17:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ break;
+ case 18:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ break;
+ case 19:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ break;
+ case 20:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ break;
+ case 21:
+ VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+ break;
+ }
+
+ // Go on to the next test.
+ ContinueOnChipMainThread(CHIP_NO_ERROR);
+ }
+
+ chip::System::Clock::Timeout GetWaitDuration() const override
+ {
+ return chip::System::Clock::Seconds16(mTimeout.ValueOr(kTimeoutInSeconds));
+ }
+
+private:
+ std::atomic_uint16_t mTestIndex;
+ const uint16_t mTestCount = 22;
+
+ chip::Optional<chip::NodeId> mNodeId;
+ chip::Optional<chip::CharSpan> mCluster;
+ chip::Optional<chip::EndpointId> mEndpoint;
+ chip::Optional<uint16_t> mTimeout;
+
+ CHIP_ERROR TestWaitForTheCommissionedDeviceToBeRetrieved_0()
+ {
+
+ chip::app::Clusters::DelayCommands::Commands::WaitForCommissionee::Type value;
+ value.nodeId = mNodeId.HasValue() ? mNodeId.Value() : 305414945ULL;
+ return WaitForCommissionee("alpha", value);
+ }
+
+ CHIP_ERROR TestReadSupportedAttribute_1()
+ {
+
+ MTRBaseDevice * device = GetDevice("alpha");
+ __auto_type * cluster = [[MTRBaseClusterDishwasherAlarm alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue];
+ VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE);
+
+ [cluster readAttributeSupportedWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) {
+ NSLog(@"Read Supported Attribute Error: %@", err);
+
+ VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0));
+
+ {
+ id actualValue = value;
+ VerifyOrReturn(CheckValue("Supported", actualValue, 47UL));
+ }
+
+ NextTest();
+ }];
+
+ return CHIP_NO_ERROR;
+ }
+
+ CHIP_ERROR TestReadMaskAttribute_2()
+ {
+
+ MTRBaseDevice * device = GetDevice("alpha");
+ __auto_type * cluster = [[MTRBaseClusterDishwasherAlarm alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue];
+ VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE);
+
+ [cluster readAttributeMaskWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) {
+ NSLog(@"Read Mask Attribute Error: %@", err);
+
+ VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0));
+
+ {
+ id actualValue = value;
+ VerifyOrReturn(CheckValue("Mask", actualValue, 47UL));
+ }
+
+ NextTest();
+ }];
+
+ return CHIP_NO_ERROR;
+ }
+
+ CHIP_ERROR TestReadLatchAttribute_3()
+ {
+
+ MTRBaseDevice * device = GetDevice("alpha");
+ __auto_type * cluster = [[MTRBaseClusterDishwasherAlarm alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue];
+ VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE);
+
+ [cluster readAttributeLatchWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) {
+ NSLog(@"Read Latch Attribute Error: %@", err);
+
+ VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0));
+
+ {
+ id actualValue = value;
+ VerifyOrReturn(CheckValue("Latch", actualValue, 3UL));
+ }
+
+ NextTest();
+ }];
+
+ return CHIP_NO_ERROR;
+ }
+
+ CHIP_ERROR TestReadStateAttribute_4()
+ {
+
+ MTRBaseDevice * device = GetDevice("alpha");
+ __auto_type * cluster = [[MTRBaseClusterDishwasherAlarm alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue];
+ VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE);
+
+ [cluster readAttributeStateWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) {
+ NSLog(@"Read State Attribute Error: %@", err);
+
+ VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0));
+
+ {
+ id actualValue = value;
+ VerifyOrReturn(CheckValue("State", actualValue, 7UL));
+ }
+
+ NextTest();
+ }];
+
+ return CHIP_NO_ERROR;
+ }
+
+ CHIP_ERROR TestReadFeatureMapAttribute_5()
+ {
+
+ MTRBaseDevice * device = GetDevice("alpha");
+ __auto_type * cluster = [[MTRBaseClusterDishwasherAlarm alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue];
+ VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE);
+
+ [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) {
+ NSLog(@"Read feature map Attribute Error: %@", err);
+
+ VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0));
+
+ VerifyOrReturn(CheckConstraintType("featureMap", "bitmap32", "bitmap32"));
+ NextTest();
+ }];
+
+ return CHIP_NO_ERROR;
+ }
+
+ CHIP_ERROR TestModifyEnabledAlarmsCommand_6()
+ {
+
+ MTRBaseDevice * device = GetDevice("alpha");
+ __auto_type * cluster = [[MTRBaseClusterDishwasherAlarm alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue];
+ VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE);
+
+ __auto_type * params = [[MTRDishwasherAlarmClusterModifyEnabledAlarmsParams alloc] init];
+ params.mask = [NSNumber numberWithUnsignedInt:41UL];
+ [cluster modifyEnabledAlarmsWithParams:params
+ completion:^(NSError * _Nullable err) {
+ NSLog(@"Modify enabled alarms Command Error: %@", err);
+
+ VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0));
+
+ NextTest();
+ }];
+
+ return CHIP_NO_ERROR;
+ }
+
+ CHIP_ERROR TestReadMaskAttribute_7()
+ {
+
+ MTRBaseDevice * device = GetDevice("alpha");
+ __auto_type * cluster = [[MTRBaseClusterDishwasherAlarm alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue];
+ VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE);
+
+ [cluster readAttributeMaskWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) {
+ NSLog(@"Read Mask Attribute Error: %@", err);
+
+ VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0));
+
+ {
+ id actualValue = value;
+ VerifyOrReturn(CheckValue("Mask", actualValue, 41UL));
+ }
+
+ NextTest();
+ }];
+
+ return CHIP_NO_ERROR;
+ }
+
+ CHIP_ERROR TestReadLatchAttribute_8()
+ {
+
+ MTRBaseDevice * device = GetDevice("alpha");
+ __auto_type * cluster = [[MTRBaseClusterDishwasherAlarm alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue];
+ VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE);
+
+ [cluster readAttributeLatchWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) {
+ NSLog(@"Read Latch Attribute Error: %@", err);
+
+ VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0));
+
+ {
+ id actualValue = value;
+ VerifyOrReturn(CheckValue("Latch", actualValue, 3UL));
+ }
+
+ NextTest();
+ }];
+
+ return CHIP_NO_ERROR;
+ }
+
+ CHIP_ERROR TestReadStateAttribute_9()
+ {
+
+ MTRBaseDevice * device = GetDevice("alpha");
+ __auto_type * cluster = [[MTRBaseClusterDishwasherAlarm alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue];
+ VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE);
+
+ [cluster readAttributeStateWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) {
+ NSLog(@"Read State Attribute Error: %@", err);
+
+ VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0));
+
+ {
+ id actualValue = value;
+ VerifyOrReturn(CheckValue("State", actualValue, 1UL));
+ }
+
+ NextTest();
+ }];
+
+ return CHIP_NO_ERROR;
+ }
+
+ CHIP_ERROR TestModifyEnabledAlarmsCommand_10()
+ {
+
+ MTRBaseDevice * device = GetDevice("alpha");
+ __auto_type * cluster = [[MTRBaseClusterDishwasherAlarm alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue];
+ VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE);
+
+ __auto_type * params = [[MTRDishwasherAlarmClusterModifyEnabledAlarmsParams alloc] init];
+ params.mask = [NSNumber numberWithUnsignedInt:105UL];
+ [cluster
+ modifyEnabledAlarmsWithParams:params
+ completion:^(NSError * _Nullable err) {
+ NSLog(@"Modify enabled alarms Command Error: %@", err);
+
+ VerifyOrReturn(CheckValue("status",
+ err ? ([err.domain isEqualToString:MTRInteractionErrorDomain] ? err.code
+ : EMBER_ZCL_STATUS_FAILURE)
+ : 0,
+ EMBER_ZCL_STATUS_INVALID_COMMAND));
+ NextTest();
+ }];
+
+ return CHIP_NO_ERROR;
+ }
+
+ CHIP_ERROR TestReadMaskAttribute_11()
+ {
+
+ MTRBaseDevice * device = GetDevice("alpha");
+ __auto_type * cluster = [[MTRBaseClusterDishwasherAlarm alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue];
+ VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE);
+
+ [cluster readAttributeMaskWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) {
+ NSLog(@"Read Mask Attribute Error: %@", err);
+
+ VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0));
+
+ {
+ id actualValue = value;
+ VerifyOrReturn(CheckValue("Mask", actualValue, 41UL));
+ }
+
+ NextTest();
+ }];
+
+ return CHIP_NO_ERROR;
+ }
+
+ CHIP_ERROR TestReadLatchAttribute_12()
+ {
+
+ MTRBaseDevice * device = GetDevice("alpha");
+ __auto_type * cluster = [[MTRBaseClusterDishwasherAlarm alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue];
+ VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE);
+
+ [cluster readAttributeLatchWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) {
+ NSLog(@"Read Latch Attribute Error: %@", err);
+
+ VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0));
+
+ {
+ id actualValue = value;
+ VerifyOrReturn(CheckValue("Latch", actualValue, 3UL));
+ }
+
+ NextTest();
+ }];
+
+ return CHIP_NO_ERROR;
+ }
+
+ CHIP_ERROR TestReadStateAttribute_13()
+ {
+
+ MTRBaseDevice * device = GetDevice("alpha");
+ __auto_type * cluster = [[MTRBaseClusterDishwasherAlarm alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue];
+ VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE);
+
+ [cluster readAttributeStateWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) {
+ NSLog(@"Read State Attribute Error: %@", err);
+
+ VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0));
+
+ {
+ id actualValue = value;
+ VerifyOrReturn(CheckValue("State", actualValue, 1UL));
+ }
+
+ NextTest();
+ }];
+
+ return CHIP_NO_ERROR;
+ }
+
+ CHIP_ERROR TestModifyEnabledAlarmsCommand_14()
+ {
+
+ MTRBaseDevice * device = GetDevice("alpha");
+ __auto_type * cluster = [[MTRBaseClusterDishwasherAlarm alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue];
+ VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE);
+
+ __auto_type * params = [[MTRDishwasherAlarmClusterModifyEnabledAlarmsParams alloc] init];
+ params.mask = [NSNumber numberWithUnsignedInt:59UL];
+ [cluster
+ modifyEnabledAlarmsWithParams:params
+ completion:^(NSError * _Nullable err) {
+ NSLog(@"Modify enabled alarms Command Error: %@", err);
+
+ VerifyOrReturn(CheckValue("status",
+ err ? ([err.domain isEqualToString:MTRInteractionErrorDomain] ? err.code
+ : EMBER_ZCL_STATUS_FAILURE)
+ : 0,
+ EMBER_ZCL_STATUS_INVALID_COMMAND));
+ NextTest();
+ }];
+
+ return CHIP_NO_ERROR;
+ }
+
+ CHIP_ERROR TestReadMaskAttribute_15()
+ {
+
+ MTRBaseDevice * device = GetDevice("alpha");
+ __auto_type * cluster = [[MTRBaseClusterDishwasherAlarm alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue];
+ VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE);
+
+ [cluster readAttributeMaskWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) {
+ NSLog(@"Read Mask Attribute Error: %@", err);
+
+ VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0));
+
+ {
+ id actualValue = value;
+ VerifyOrReturn(CheckValue("Mask", actualValue, 41UL));
+ }
+
+ NextTest();
+ }];
+
+ return CHIP_NO_ERROR;
+ }
+
+ CHIP_ERROR TestReadLatchAttribute_16()
+ {
+
+ MTRBaseDevice * device = GetDevice("alpha");
+ __auto_type * cluster = [[MTRBaseClusterDishwasherAlarm alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue];
+ VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE);
+
+ [cluster readAttributeLatchWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) {
+ NSLog(@"Read Latch Attribute Error: %@", err);
+
+ VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0));
+
+ {
+ id actualValue = value;
+ VerifyOrReturn(CheckValue("Latch", actualValue, 3UL));
+ }
+
+ NextTest();
+ }];
+
+ return CHIP_NO_ERROR;
+ }
+
+ CHIP_ERROR TestReadStateAttribute_17()
+ {
+
+ MTRBaseDevice * device = GetDevice("alpha");
+ __auto_type * cluster = [[MTRBaseClusterDishwasherAlarm alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue];
+ VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE);
+
+ [cluster readAttributeStateWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) {
+ NSLog(@"Read State Attribute Error: %@", err);
+
+ VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0));
+
+ {
+ id actualValue = value;
+ VerifyOrReturn(CheckValue("State", actualValue, 1UL));
+ }
+
+ NextTest();
+ }];
+
+ return CHIP_NO_ERROR;
+ }
+
+ CHIP_ERROR TestResetCommand_18()
+ {
+
+ MTRBaseDevice * device = GetDevice("alpha");
+ __auto_type * cluster = [[MTRBaseClusterDishwasherAlarm alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue];
+ VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE);
+
+ __auto_type * params = [[MTRDishwasherAlarmClusterResetParams alloc] init];
+ params.alarms = [NSNumber numberWithUnsignedInt:1UL];
+ [cluster resetWithParams:params
+ completion:^(NSError * _Nullable err) {
+ NSLog(@"Reset Command Error: %@", err);
+
+ VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0));
+
+ NextTest();
+ }];
+
+ return CHIP_NO_ERROR;
+ }
+
+ CHIP_ERROR TestReadMaskAttribute_19()
+ {
+
+ MTRBaseDevice * device = GetDevice("alpha");
+ __auto_type * cluster = [[MTRBaseClusterDishwasherAlarm alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue];
+ VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE);
+
+ [cluster readAttributeMaskWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) {
+ NSLog(@"Read Mask Attribute Error: %@", err);
+
+ VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0));
+
+ {
+ id actualValue = value;
+ VerifyOrReturn(CheckValue("Mask", actualValue, 41UL));
+ }
+
+ NextTest();
+ }];
+
+ return CHIP_NO_ERROR;
+ }
+
+ CHIP_ERROR TestReadLatchAttribute_20()
+ {
+
+ MTRBaseDevice * device = GetDevice("alpha");
+ __auto_type * cluster = [[MTRBaseClusterDishwasherAlarm alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue];
+ VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE);
+
+ [cluster readAttributeLatchWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) {
+ NSLog(@"Read Latch Attribute Error: %@", err);
+
+ VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0));
+
+ {
+ id actualValue = value;
+ VerifyOrReturn(CheckValue("Latch", actualValue, 3UL));
+ }
+
+ NextTest();
+ }];
+
+ return CHIP_NO_ERROR;
+ }
+
+ CHIP_ERROR TestReadStateAttribute_21()
+ {
+
+ MTRBaseDevice * device = GetDevice("alpha");
+ __auto_type * cluster = [[MTRBaseClusterDishwasherAlarm alloc] initWithDevice:device endpointID:@(1) queue:mCallbackQueue];
+ VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE);
+
+ [cluster readAttributeStateWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable err) {
+ NSLog(@"Read State Attribute Error: %@", err);
+
+ VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0));
+
+ {
+ id actualValue = value;
+ VerifyOrReturn(CheckValue("State", actualValue, 0UL));
+ }
+
+ NextTest();
+ }];
+
+ return CHIP_NO_ERROR;
+ }
+};
+
class TestMultiAdmin : public TestCommandBridge {
public:
// NOLINTBEGIN(clang-analyzer-nullability.NullPassedToNonnull): Test constructor nullability not enforced
@@ -173739,6 +174451,7 @@
make_unique<TestTimeSynchronization>(),
make_unique<TestOperationalState>(),
make_unique<TestRVCOperationalState>(),
+ make_unique<TestDishwasherAlarm>(),
make_unique<TestMultiAdmin>(),
make_unique<Test_TC_DGSW_1_1>(),
make_unique<TestSubscribe_OnOff>(),