[Feature]Microwave oven mode cluster implementation (#30441)
* [Feature]Microwave oven mode cluster implementation
* Restyled by clang-format
* Restyled by gn
* remove the restriction that limits usage only to endpoint 1 for microwave oven cluster
* use static delegate instead of new
* Restyled by clang-format
* to shutdown the microwave oven mode cluster instance
* use dynamic allocate to new deleget and use endpoint
* Restyled by clang-format
* sync all-clusters-app.matter
* return fail status when receiving command ChangeToMode by microwave mode
* remove supported command interface from mode base
---------
Co-authored-by: Restyled.io <commits@restyled.io>
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 799391e..0557d67 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
@@ -3116,6 +3116,40 @@
command ModifyEnabledAlarms(ModifyEnabledAlarmsRequest): DefaultSuccess = 1;
}
+/** Attributes and commands for selecting a mode from a list of supported options. */
+provisional server cluster MicrowaveOvenMode = 94 {
+ revision 1;
+
+ enum ModeTag : enum16 {
+ kNormal = 16384;
+ kDefrost = 16385;
+ }
+
+ bitmap Feature : bitmap32 {
+ kOnOff = 0x1;
+ }
+
+ struct ModeTagStruct {
+ optional vendor_id mfgCode = 0;
+ enum16 value = 1;
+ }
+
+ struct ModeOptionStruct {
+ char_string<64> label = 0;
+ int8u mode = 1;
+ ModeTagStruct modeTags[] = 2;
+ }
+
+ readonly attribute ModeOptionStruct supportedModes[] = 0;
+ readonly attribute int8u currentMode = 1;
+ readonly attribute command_id generatedCommandList[] = 65528;
+ readonly attribute command_id acceptedCommandList[] = 65529;
+ readonly attribute event_id eventList[] = 65530;
+ readonly attribute attrib_id attributeList[] = 65531;
+ readonly attribute bitmap32 featureMap = 65532;
+ readonly attribute int16u clusterRevision = 65533;
+}
+
/** 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 {
revision 1; // NOTE: Default/not specifically set
@@ -6189,6 +6223,17 @@
handle command ModifyEnabledAlarms;
}
+ server cluster MicrowaveOvenMode {
+ callback attribute supportedModes;
+ callback attribute currentMode;
+ callback attribute generatedCommandList;
+ callback attribute acceptedCommandList;
+ callback attribute eventList;
+ callback attribute attributeList;
+ callback attribute featureMap default = 0;
+ 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 fe400ec..08a758e 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
@@ -10522,6 +10522,145 @@
]
},
{
+ "name": "Microwave Oven Mode",
+ "code": 94,
+ "mfgCode": null,
+ "define": "MICROWAVE_OVEN_MODE_CLUSTER",
+ "side": "server",
+ "enabled": 1,
+ "apiMaturity": "provisional",
+ "attributes": [
+ {
+ "name": "SupportedModes",
+ "code": 0,
+ "mfgCode": null,
+ "side": "server",
+ "type": "array",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "CurrentMode",
+ "code": 1,
+ "mfgCode": null,
+ "side": "server",
+ "type": "int8u",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "GeneratedCommandList",
+ "code": 65528,
+ "mfgCode": null,
+ "side": "server",
+ "type": "array",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "AcceptedCommandList",
+ "code": 65529,
+ "mfgCode": null,
+ "side": "server",
+ "type": "array",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "EventList",
+ "code": 65530,
+ "mfgCode": null,
+ "side": "server",
+ "type": "array",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "AttributeList",
+ "code": 65531,
+ "mfgCode": null,
+ "side": "server",
+ "type": "array",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "FeatureMap",
+ "code": 65532,
+ "mfgCode": null,
+ "side": "server",
+ "type": "bitmap32",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "0",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "ClusterRevision",
+ "code": 65533,
+ "mfgCode": null,
+ "side": "server",
+ "type": "int16u",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "1",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ }
+ ]
+ },
+ {
"name": "Operational State",
"code": 96,
"mfgCode": null,
diff --git a/examples/all-clusters-app/all-clusters-common/include/microwave-oven-mode.h b/examples/all-clusters-app/all-clusters-common/include/microwave-oven-mode.h
new file mode 100644
index 0000000..dd5d5b4
--- /dev/null
+++ b/examples/all-clusters-app/all-clusters-common/include/microwave-oven-mode.h
@@ -0,0 +1,72 @@
+/*
+ *
+ * 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/clusters/mode-base-server/mode-base-server.h>
+#include <app/util/af.h>
+#include <app/util/config.h>
+#include <cstring>
+#include <utility>
+
+namespace chip {
+namespace app {
+namespace Clusters {
+
+namespace MicrowaveOvenMode {
+
+const uint8_t ModeNormal = 0;
+const uint8_t ModeDefrost = 1;
+
+/// This is an application level delegate to handle MicrowaveOvenMode commands according to the specific business logic.
+class ExampleMicrowaveOvenModeDelegate : public ModeBase::Delegate
+{
+private:
+ using ModeTagStructType = detail::Structs::ModeTagStruct::Type;
+ ModeTagStructType modeTagsNormal[1] = { { .value = to_underlying(ModeTag::kNormal) } };
+ ModeTagStructType modeTagsDefrost[1] = { { .value = to_underlying(ModeTag::kDefrost) } };
+
+ const detail::Structs::ModeOptionStruct::Type kModeOptions[2] = {
+ detail::Structs::ModeOptionStruct::Type{ .label = CharSpan::fromCharString("Normal"),
+ .mode = ModeNormal,
+ .modeTags = DataModel::List<const ModeTagStructType>(modeTagsNormal) },
+ detail::Structs::ModeOptionStruct::Type{ .label = CharSpan::fromCharString("Defrost"),
+ .mode = ModeDefrost,
+ .modeTags = DataModel::List<const ModeTagStructType>(modeTagsDefrost) }
+ };
+
+ CHIP_ERROR Init() override;
+ void HandleChangeToMode(uint8_t mode, ModeBase::Commands::ChangeToModeResponse::Type & response) override;
+
+ CHIP_ERROR GetModeLabelByIndex(uint8_t modeIndex, MutableCharSpan & label) override;
+ CHIP_ERROR GetModeValueByIndex(uint8_t modeIndex, uint8_t & value) override;
+ CHIP_ERROR GetModeTagsByIndex(uint8_t modeIndex, DataModel::List<ModeTagStructType> & tags) override;
+
+public:
+ ~ExampleMicrowaveOvenModeDelegate() override = default;
+};
+
+ModeBase::Instance * Instance();
+
+void Shutdown();
+
+} // namespace MicrowaveOvenMode
+
+} // namespace Clusters
+} // namespace app
+} // namespace chip
diff --git a/examples/all-clusters-app/all-clusters-common/src/microwave-oven-mode.cpp b/examples/all-clusters-app/all-clusters-common/src/microwave-oven-mode.cpp
new file mode 100644
index 0000000..a7ab998
--- /dev/null
+++ b/examples/all-clusters-app/all-clusters-common/src/microwave-oven-mode.cpp
@@ -0,0 +1,106 @@
+/*
+ *
+ * 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/attributes/Accessors.h>
+#include <microwave-oven-mode.h>
+
+using namespace chip::app::Clusters;
+using namespace chip::app::Clusters::MicrowaveOvenMode;
+using chip::Protocols::InteractionModel::Status;
+template <typename T>
+using List = chip::app::DataModel::List<T>;
+using ModeTagStructType = chip::app::Clusters::detail::Structs::ModeTagStruct::Type;
+
+static ExampleMicrowaveOvenModeDelegate * gMicrowaveOvenModeDelegate = nullptr;
+static ModeBase::Instance * gMicrowaveOvenModeInstance = nullptr;
+
+CHIP_ERROR ExampleMicrowaveOvenModeDelegate::Init()
+{
+ return CHIP_NO_ERROR;
+}
+
+// todo refactor code by making a parent class for all ModeInstance classes to reduce flash usage.
+void ExampleMicrowaveOvenModeDelegate::HandleChangeToMode(uint8_t NewMode,
+ ModeBase::Commands::ChangeToModeResponse::Type & response)
+{
+ response.status = to_underlying(ModeBase::StatusCode::kGenericFailure);
+}
+
+CHIP_ERROR ExampleMicrowaveOvenModeDelegate::GetModeLabelByIndex(uint8_t modeIndex, chip::MutableCharSpan & label)
+{
+ if (modeIndex >= ArraySize(kModeOptions))
+ {
+ return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED;
+ }
+ return chip::CopyCharSpanToMutableCharSpan(kModeOptions[modeIndex].label, label);
+}
+
+CHIP_ERROR ExampleMicrowaveOvenModeDelegate::GetModeValueByIndex(uint8_t modeIndex, uint8_t & value)
+{
+ if (modeIndex >= ArraySize(kModeOptions))
+ {
+ return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED;
+ }
+ value = kModeOptions[modeIndex].mode;
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR ExampleMicrowaveOvenModeDelegate::GetModeTagsByIndex(uint8_t modeIndex, List<ModeTagStructType> & tags)
+{
+ if (modeIndex >= ArraySize(kModeOptions))
+ {
+ return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED;
+ }
+
+ if (tags.size() < kModeOptions[modeIndex].modeTags.size())
+ {
+ return CHIP_ERROR_INVALID_ARGUMENT;
+ }
+
+ std::copy(kModeOptions[modeIndex].modeTags.begin(), kModeOptions[modeIndex].modeTags.end(), tags.begin());
+ tags.reduce_size(kModeOptions[modeIndex].modeTags.size());
+
+ return CHIP_NO_ERROR;
+}
+
+ModeBase::Instance * MicrowaveOvenMode::Instance()
+{
+ return gMicrowaveOvenModeInstance;
+}
+
+void MicrowaveOvenMode::Shutdown()
+{
+ if (gMicrowaveOvenModeInstance != nullptr)
+ {
+ delete gMicrowaveOvenModeInstance;
+ gMicrowaveOvenModeInstance = nullptr;
+ }
+ if (gMicrowaveOvenModeDelegate != nullptr)
+ {
+ delete gMicrowaveOvenModeDelegate;
+ gMicrowaveOvenModeDelegate = nullptr;
+ }
+}
+
+void emberAfMicrowaveOvenModeClusterInitCallback(chip::EndpointId endpointId)
+{
+ VerifyOrDie(gMicrowaveOvenModeDelegate == nullptr && gMicrowaveOvenModeInstance == nullptr);
+ gMicrowaveOvenModeDelegate = new MicrowaveOvenMode::ExampleMicrowaveOvenModeDelegate;
+ gMicrowaveOvenModeInstance =
+ new ModeBase::Instance(gMicrowaveOvenModeDelegate, endpointId, MicrowaveOvenMode::Id, chip::to_underlying(Feature::kOnOff));
+ gMicrowaveOvenModeInstance->Init();
+}
diff --git a/examples/all-clusters-app/linux/BUILD.gn b/examples/all-clusters-app/linux/BUILD.gn
index 215f79f..cfe028c 100644
--- a/examples/all-clusters-app/linux/BUILD.gn
+++ b/examples/all-clusters-app/linux/BUILD.gn
@@ -30,6 +30,7 @@
"${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-controls-delegate-impl.cpp",
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/laundry-washer-mode.cpp",
+ "${chip_root}/examples/all-clusters-app/all-clusters-common/src/microwave-oven-mode.cpp",
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/operational-state-delegate-impl.cpp",
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/resource-monitoring-delegates.cpp",
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/rvc-modes.cpp",
diff --git a/examples/all-clusters-app/linux/main-common.cpp b/examples/all-clusters-app/linux/main-common.cpp
index b477555..004827d 100644
--- a/examples/all-clusters-app/linux/main-common.cpp
+++ b/examples/all-clusters-app/linux/main-common.cpp
@@ -23,6 +23,7 @@
#include "include/tv-callbacks.h"
#include "laundry-washer-controls-delegate-impl.h"
#include "laundry-washer-mode.h"
+#include "microwave-oven-mode.h"
#include "operational-state-delegate-impl.h"
#include "resource-monitoring-delegates.h"
#include "rvc-modes.h"
@@ -226,6 +227,7 @@
Clusters::LaundryWasherMode::Shutdown();
Clusters::RvcCleanMode::Shutdown();
Clusters::RvcRunMode::Shutdown();
+ Clusters::MicrowaveOvenMode::Shutdown();
Clusters::RefrigeratorAndTemperatureControlledCabinetMode::Shutdown();
Clusters::HepaFilterMonitoring::Shutdown();
Clusters::ActivatedCarbonFilterMonitoring::Shutdown();
diff --git a/src/app/clusters/mode-base-server/mode-base-server.cpp b/src/app/clusters/mode-base-server/mode-base-server.cpp
index 2b9cc23..2a86f1e 100644
--- a/src/app/clusters/mode-base-server/mode-base-server.cpp
+++ b/src/app/clusters/mode-base-server/mode-base-server.cpp
@@ -51,6 +51,15 @@
Instance::~Instance()
{
+ Shutdown();
+}
+
+void Instance::Shutdown()
+{
+ if (!IsInList())
+ {
+ return;
+ }
UnregisterThisInstance();
chip::app::InteractionModelEngine::GetInstance()->UnregisterCommandHandler(this);
unregisterAttributeAccessOverride(this);
@@ -289,21 +298,6 @@
}
}
-// List the commands supported by this instance.
-CHIP_ERROR Instance::EnumerateAcceptedCommands(const ConcreteClusterPath & cluster,
- CommandHandlerInterface::CommandIdCallback callback, void * context)
-{
- callback(ModeBase::Commands::ChangeToMode::Id, context);
- return CHIP_NO_ERROR;
-}
-
-// List the commands generated by this instance.
-CHIP_ERROR Instance::EnumerateGeneratedCommands(const ConcreteClusterPath & cluster, CommandIdCallback callback, void * context)
-{
- callback(ModeBase::Commands::ChangeToModeResponse::Id, context);
- return CHIP_NO_ERROR;
-}
-
// Implements the read functionality for complex attributes.
CHIP_ERROR Instance::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder)
{
diff --git a/src/app/clusters/mode-base-server/mode-base-server.h b/src/app/clusters/mode-base-server/mode-base-server.h
index ef88ee8..256670d 100644
--- a/src/app/clusters/mode-base-server/mode-base-server.h
+++ b/src/app/clusters/mode-base-server/mode-base-server.h
@@ -121,6 +121,9 @@
*/
bool IsSupportedMode(uint8_t mode);
+ // Unregisters this instance if already registered.
+ void Shutdown();
+
private:
Delegate * mDelegate;
@@ -139,8 +142,6 @@
// CommandHandlerInterface
void InvokeCommand(HandlerContext & ctx) override;
- CHIP_ERROR EnumerateAcceptedCommands(const ConcreteClusterPath & cluster, CommandIdCallback callback, void * context) override;
- CHIP_ERROR EnumerateGeneratedCommands(const ConcreteClusterPath & cluster, CommandIdCallback callback, void * context) override;
// AttributeAccessInterface
CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override;
diff --git a/src/app/util/util.cpp b/src/app/util/util.cpp
index 1add789..9d618dc 100644
--- a/src/app/util/util.cpp
+++ b/src/app/util/util.cpp
@@ -160,6 +160,7 @@
void MatterDishwasherAlarmPluginServerInitCallback() {}
void MatterBooleanSensorConfigurationPluginServerInitCallback() {}
void MatterValveConfigurationAndControlPluginServerInitCallback() {}
+void MatterMicrowaveOvenModePluginServerInitCallback() {}
// ****************************************
// Print out information about each cluster
// ****************************************