From 1102716f8b04030453b80c2b61d03745fd8c174b Mon Sep 17 00:00:00 2001 From: William Date: Fri, 21 Jul 2023 13:15:35 +0100 Subject: [PATCH] Mode base sdk implementation (#27504) * Added first draft of the ModeBase SDK implementation. * Fixed build files and mode base source files from mode select references. * Fixed final errors. * Removed global accessor functions in place instance attributes. * Renamed internal members to mX. Replaced the use the zap Feature map with and internally managed variable. * Added Command Types and DecodableTypes to the SDK implementation to bypass the limitations of the the current zap generation. * Added ModeBase attributes to the list of attributeAccessInterfaceAttributes to ensure that not RAM memory is allocated for these attibutes. * Merged the mode base delegate into the mode base instance due to attribute accessability following management of attributes by the mode base instance. * Added documentation and readme for the ModeBase alias. * Added the dishwasher mode cluster to the all-clusters-app example. * Added the laundry washer mode cluster to the all-clusters-app example. * Added the refrigerator and temperature controlled cabinet mode cluster to the all-clusters-app example. * Renamed the mode base alias all-clusters-app examples to the correct naming. * Implemented interaction between the ModeBase and OnOff servers. Added ModeBase attribute type infos. Updated documentation. * Restyled by whitespace * Restyled by clang-format * Restyled by gn * Restyled by prettier-markdown * Fixed copy paste issues in the mode base cluster objects. * Moved the ModeBaseAliasesInstanceMap into the ModeBase namespace and added a getter for it. * Moved OnOff server common behavior in a top-level anonymous namespace method. * Apply suggestions from code review Accepted readme suggestions. Co-authored-by: Tennessee Carmel-Veilleux * Renamed the readme * Added doc to ModeBase instance init. Removed the use of using in made-base-server.h * Added validity checking when updating attributes. * Made ModeBase functions that are required to be implemented by the user pure virtural. * Renamed constants according to the convention. * Made persistant attributes persistant. Experimented with helper accessor functions for persistent attributes. * Fixed code after merge * Regenerats all-clusters-app.matter after merge * Restyled by clang-format * Restyled by prettier-markdown * Simplified IsSupportedMode to make it more readable. * Removed the use of using from header files. * Removed the use of using from mode-base-server.h. * Enabled UpdateModeBaseCurrentModeToOnMode only when the ModeBase plugin is enabled. * Restyled by clang-format * In the OnOff server, include mode-base only when the ModeBase plugin is enabled. * Fixed AliasedCluster's type * Changed to calling of Update sttribute functions when loading persistent attributes on init. * Moved the ChangeToModeResponse command from the accepted commands to the generated commands list. * Renamed isAliasedCluster to isDerivedCluster. * Refactored the supported modes encoding to make the Read switch statement more readable. * Fixed typos in the ModeBase readme. Co-authored-by: Boris Zbarsky * Simplified the encoding function and some comments. * Fixed var naming and GetModeLabelByIndex return. * Fixed incorrect version number in some ModeBase derived clusters. * Made mode base derived cluster code more readble with using * Removed unneccissary namespace paths. * Removed unneccissary size checking. * Refactored GetModeTagsByIndex to make it more readable. * Added new StatusCode. * Used chip::CharSpan::fromCharString to avoid setting the length. * Added missing function nampspace. * Made the mode-base-cluster-objects.h more readable by removing unneccessery namespace specifications. * Made the mode-base-cluster-objects.h more readable by simplifying the DecodableArgType definition. * Removed redundant processing in the Read function. * Added cluster constants to make the code more readabel. * Changed attribute write errors. * Added attribute getters and setters documentaton. * Added FeatureMap to the list of attributeAccessInterfaceAttributes. * Used std::set instead of std::map to hold the ModeBase Instances. * Removed the BuildModeOptionStruct helper function to avoid giving incorroct expectations to the SDK consumers. * Changed the Delegate's API to remove the need for the GetNumberOfModes method. * Changed checks for essetion setup in the ModeBase init to VerifyOrDie. * Moved the setting of the CurrentMode based on the StartUpMode, OnMode and OnOff cluster values to the ModeBase init function. Added some TODOs from the reviews. * Added documentation about the required lifetime of the ModeBase Instance object. * Refoctored ModeBase to separate out the Delegate functionality into a separate class. * Added generated code after merge * Restyled by clang-format * Restyled by gn * Restyled by prettier-markdown * Added ModeBase to the spellcheck. Allowed the use of set in mode-base-server.h * Removed the ModeBase constraint that the cluster ID given should be of an actual ModeBase derived cluster. * Changed the ModeBase derived cluster's instatiation in the all-clusters-app to make it easier to include for all platforms. * Defined EMBER_AF_PLUGIN_MODE_BASE for the linux all-clustres-app to enable OfOff cluster related code. * Restyled by whitespace * Restyled by clang-format * Restyled by prettier-markdown * Fixed the lock app gni argument chip_project_config_include_dirs as it was pointing to the all-clusters-app's include dir. * Fixed ModeBase derived clusters version numbers in zap. * Apply suggestions from code review Co-authored-by: Boris Zbarsky * Updated the Mode Base readme afther review. * Removed ModeBase from the .github/.wordlist.txt Co-authored-by: Boris Zbarsky * Unregister the AttributeAccessOverride when deconstructing a Mode Base instance. * Added // nogncheck to the Mode Base includes in the OnOff server code. * Updated Mode Base function documentatio. * Added read case for the Feature Map. * Restyled by clang-format * Restyled by prettier-markdown * used the feature map's enum instead of a literal number in the Mode Bease examples. * Restyled by clang-format * Fixed return bug in the Mode Base RVC examples. * Update .github/workflows/build.yaml Co-authored-by: Boris Zbarsky * Fixed attribute get issue in the Mode Base RVC example. Co-authored-by: Petru Lauric <81822411+plauric@users.noreply.github.com> * Checkedout out-of-sync third-party repos to match what is on master. * Restyled by clang-format --------- Co-authored-by: Restyled.io Co-authored-by: Tennessee Carmel-Veilleux Co-authored-by: Boris Zbarsky Co-authored-by: Petru Lauric <81822411+plauric@users.noreply.github.com> --- .../all-clusters-app.matter | 309 +++++ .../all-clusters-common/all-clusters-app.zap | 1160 +++++++++++++++++ .../include/dishwasher-mode.h | 76 ++ .../include/laundry-washer-mode.h | 81 ++ .../all-clusters-common/include/rvc-modes.h | 114 ++ .../all-clusters-common/include/tcc-mode.h | 74 ++ .../src/dishwasher-mode.cpp | 88 ++ .../src/laundry-washer-mode.cpp | 86 ++ .../all-clusters-common/src/rvc-modes.cpp | 169 +++ .../all-clusters-common/src/tcc-mode.cpp | 86 ++ examples/all-clusters-app/linux/BUILD.gn | 4 + .../linux/include/CHIPProjectAppConfig.h | 3 + .../all-clusters-app/linux/main-common.cpp | 5 + examples/lock-app/linux/args.gni | 2 +- scripts/tools/check_includes_config.py | 5 +- src/app/chip_data_model.gni | 7 + src/app/clusters/mode-base-server/README.md | 41 + .../mode-base-cluster-objects.cpp | 113 ++ .../mode-base-cluster-objects.h | 216 +++ .../mode-base-server/mode-base-server.cpp | 492 +++++++ .../mode-base-server/mode-base-server.h | 239 ++++ .../clusters/on-off-server/on-off-server.cpp | 51 + src/app/common/templates/config-data.yaml | 5 + src/app/util/util.cpp | 5 + .../chip/laundry-washer-mode-cluster.xml | 1 - .../zcl/data-model/chip/mode-base-cluster.xml | 14 +- ...rature-controlled-cabinet-mode-cluster.xml | 1 - .../chip/rvc-clean-mode-cluster.xml | 1 - .../data-model/chip/rvc-run-mode-cluster.xml | 1 - .../zcl/zcl-with-test-extensions.json | 35 + src/app/zap-templates/zcl/zcl.json | 35 + src/app/zap_cluster_list.json | 8 +- .../data_model/controller-clusters.zap | 232 ++++ .../zap-generated/attributes/Accessors.cpp | 753 +---------- .../zap-generated/attributes/Accessors.h | 95 -- .../app-common/zap-generated/callback.h | 31 - 36 files changed, 3774 insertions(+), 864 deletions(-) create mode 100644 examples/all-clusters-app/all-clusters-common/include/dishwasher-mode.h create mode 100644 examples/all-clusters-app/all-clusters-common/include/laundry-washer-mode.h create mode 100644 examples/all-clusters-app/all-clusters-common/include/rvc-modes.h create mode 100644 examples/all-clusters-app/all-clusters-common/include/tcc-mode.h create mode 100644 examples/all-clusters-app/all-clusters-common/src/dishwasher-mode.cpp create mode 100644 examples/all-clusters-app/all-clusters-common/src/laundry-washer-mode.cpp create mode 100644 examples/all-clusters-app/all-clusters-common/src/rvc-modes.cpp create mode 100644 examples/all-clusters-app/all-clusters-common/src/tcc-mode.cpp create mode 100644 src/app/clusters/mode-base-server/README.md create mode 100644 src/app/clusters/mode-base-server/mode-base-cluster-objects.cpp create mode 100644 src/app/clusters/mode-base-server/mode-base-cluster-objects.h create mode 100644 src/app/clusters/mode-base-server/mode-base-server.cpp create mode 100644 src/app/clusters/mode-base-server/mode-base-server.h 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 4b5d51f442205f..43e71115a827ea 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 @@ -2489,6 +2489,204 @@ server cluster ModeSelect = 80 { command ChangeToMode(ChangeToModeRequest): DefaultSuccess = 0; } +/** Attributes and commands for selecting a mode from a list of supported options. */ +server cluster LaundryWasherMode = 81 { + enum ModeTag : ENUM16 { + kNormal = 16384; + kDelicate = 16385; + kHeavy = 16386; + kWhites = 16387; + } + + 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; + attribute nullable int8u startUpMode = 2; + attribute nullable int8u onMode = 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 ChangeToModeRequest { + INT8U newMode = 0; + } + + response struct ChangeToModeResponse = 1 { + ENUM8 status = 0; + optional CHAR_STRING statusText = 1; + } + + command ChangeToMode(ChangeToModeRequest): ChangeToModeResponse = 0; +} + +/** Attributes and commands for selecting a mode from a list of supported options. */ +server cluster RefrigeratorAndTemperatureControlledCabinetMode = 82 { + enum ModeTag : ENUM16 { + kRapidCool = 16384; + kRapidFreeze = 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; + attribute nullable int8u startUpMode = 2; + attribute nullable int8u onMode = 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 ChangeToModeRequest { + INT8U newMode = 0; + } + + response struct ChangeToModeResponse = 1 { + ENUM8 status = 0; + optional CHAR_STRING statusText = 1; + } + + command ChangeToMode(ChangeToModeRequest): ChangeToModeResponse = 0; +} + +/** Attributes and commands for selecting a mode from a list of supported options. */ +server cluster RvcRunMode = 84 { + enum ModeTag : ENUM16 { + kIdle = 16384; + kCleaning = 16385; + } + + enum StatusCode : ENUM8 { + kStuck = 65; + kDustBinMissing = 66; + kDustBinFull = 67; + kWaterTankEmpty = 68; + kWaterTankMissing = 69; + kWaterTankLidOpen = 70; + kMopCleaningPadMissing = 71; + kBatteryLow = 72; + } + + 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; + attribute nullable int8u startUpMode = 2; + attribute nullable int8u onMode = 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 ChangeToModeRequest { + INT8U newMode = 0; + } + + response struct ChangeToModeResponse = 1 { + ENUM8 status = 0; + optional CHAR_STRING statusText = 1; + } + + command ChangeToMode(ChangeToModeRequest): ChangeToModeResponse = 0; +} + +/** Attributes and commands for selecting a mode from a list of supported options. */ +server cluster RvcCleanMode = 85 { + enum ModeTag : ENUM16 { + kDeepClean = 16384; + kVacuum = 16385; + kMop = 16386; + } + + enum StatusCode : ENUM8 { + kCleaningInProgress = 64; + } + + 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; + attribute nullable int8u startUpMode = 2; + attribute nullable int8u onMode = 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 ChangeToModeRequest { + INT8U newMode = 0; + } + + response struct ChangeToModeResponse = 1 { + ENUM8 status = 0; + optional CHAR_STRING statusText = 1; + } + + command ChangeToMode(ChangeToModeRequest): ChangeToModeResponse = 0; +} + /** Attributes and commands for configuring the temperature control, and reporting temperature. */ server cluster TemperatureControl = 86 { bitmap Feature : BITMAP32 { @@ -2538,6 +2736,52 @@ server cluster RefrigeratorAlarm = 87 { readonly attribute int16u clusterRevision = 65533; } +/** Attributes and commands for selecting a mode from a list of supported options. */ +server cluster DishwasherMode = 89 { + enum ModeTag : ENUM16 { + kNormal = 16384; + kHeavy = 16385; + kLight = 16386; + } + + 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; + attribute nullable int8u startUpMode = 2; + attribute nullable int8u onMode = 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 ChangeToModeRequest { + INT8U newMode = 0; + } + + response struct ChangeToModeResponse = 1 { + ENUM8 status = 0; + optional CHAR_STRING statusText = 1; + } + + command ChangeToMode(ChangeToModeRequest): ChangeToModeResponse = 0; +} + /** Attributes for reporting air quality classification */ server cluster AirQuality = 91 { enum AirQualityEnum : ENUM8 { @@ -6243,6 +6487,58 @@ endpoint 1 { ram attribute manufacturerExtension default = 255; } + server cluster LaundryWasherMode { + callback attribute supportedModes; + callback attribute currentMode; + callback attribute startUpMode; + callback attribute onMode; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + + server cluster RefrigeratorAndTemperatureControlledCabinetMode { + callback attribute supportedModes; + callback attribute currentMode; + callback attribute startUpMode; + callback attribute onMode; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + + server cluster RvcRunMode { + callback attribute supportedModes; + callback attribute currentMode; + callback attribute startUpMode; + callback attribute onMode; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + + server cluster RvcCleanMode { + callback attribute supportedModes; + callback attribute currentMode; + callback attribute startUpMode; + callback attribute onMode; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + server cluster TemperatureControl { ram attribute selectedTemperatureLevel default = 0; callback attribute supportedTemperatureLevels; @@ -6267,6 +6563,19 @@ endpoint 1 { ram attribute clusterRevision default = 1; } + server cluster DishwasherMode { + callback attribute supportedModes; + callback attribute currentMode; + callback attribute startUpMode; + callback attribute onMode; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + server cluster AirQuality { ram attribute airQuality default = 0; callback attribute generatedCommandList; 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 1fb87b6b560309..54f2e2fe532e15 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 @@ -13970,6 +13970,1166 @@ } ] }, + { + "name": "Laundry Washer Mode", + "code": 81, + "mfgCode": null, + "define": "LAUNDRY_WASHER_MODE_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "ChangeToMode", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + } + ], + "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": "Laundry Washer Mode", + "code": 81, + "mfgCode": null, + "define": "LAUNDRY_WASHER_MODE_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ChangeToModeResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "SupportedModes", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "RAM", + "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": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "StartUpMode", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "OnMode", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "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": "RAM", + "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": "RAM", + "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": "RAM", + "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": "RAM", + "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": "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": "Refrigerator And Temperature Controlled Cabinet Mode", + "code": 82, + "mfgCode": null, + "define": "REFRIGERATOR_AND_TEMPERATURE_CONTROLLED_CABINET_MODE_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "ChangeToMode", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + } + ], + "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": "Refrigerator And Temperature Controlled Cabinet Mode", + "code": 82, + "mfgCode": null, + "define": "REFRIGERATOR_AND_TEMPERATURE_CONTROLLED_CABINET_MODE_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ChangeToModeResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "SupportedModes", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "RAM", + "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": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "StartUpMode", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "OnMode", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "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": "RAM", + "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": "RAM", + "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": "RAM", + "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": "RAM", + "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": "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": "RVC Run Mode", + "code": 84, + "mfgCode": null, + "define": "RVC_RUN_MODE_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "ChangeToMode", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + } + ], + "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": "RVC Run Mode", + "code": 84, + "mfgCode": null, + "define": "RVC_RUN_MODE_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ChangeToModeResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 1 + } + ], + "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": "StartUpMode", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "OnMode", + "code": 3, + "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": "RAM", + "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": "RVC Clean Mode", + "code": 85, + "mfgCode": null, + "define": "RVC_CLEAN_MODE_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "ChangeToMode", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + } + ], + "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": "RVC Clean Mode", + "code": 85, + "mfgCode": null, + "define": "RVC_CLEAN_MODE_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ChangeToModeResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 1 + } + ], + "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": "StartUpMode", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "OnMode", + "code": 3, + "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": "RAM", + "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": "Dishwasher Mode", + "code": 89, + "mfgCode": null, + "define": "DISHWASHER_MODE_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "ChangeToMode", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + } + ], + "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 Mode", + "code": 89, + "mfgCode": null, + "define": "DISHWASHER_MODE_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ChangeToModeResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "SupportedModes", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "RAM", + "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": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "StartUpMode", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "OnMode", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "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": "RAM", + "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": "RAM", + "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": "RAM", + "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": "RAM", + "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": "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": "Air Quality", "code": 91, diff --git a/examples/all-clusters-app/all-clusters-common/include/dishwasher-mode.h b/examples/all-clusters-app/all-clusters-common/include/dishwasher-mode.h new file mode 100644 index 00000000000000..51a5ab5d0d80d8 --- /dev/null +++ b/examples/all-clusters-app/all-clusters-common/include/dishwasher-mode.h @@ -0,0 +1,76 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { + +namespace DishwasherMode { + +const uint8_t ModeNormal = 0; +const uint8_t ModeHeavy = 1; +const uint8_t ModeLight = 2; + +/// This is an application level delegate to handle DishwasherMode commands according to the specific business logic. +class DishwasherModeDelegate : public ModeBase::Delegate +{ +private: + using ModeTagStructType = detail::Structs::ModeTagStruct::Type; + ModeTagStructType modeTagsNormal[1] = { { .value = to_underlying(ModeTag::kNormal) } }; + ModeTagStructType modeTagsHeavy[2] = { { .value = to_underlying(ModeBase::ModeTag::kMax) }, + { .value = to_underlying(ModeTag::kHeavy) } }; + ModeTagStructType modeTagsLight[3] = { { .value = to_underlying(ModeTag::kLight) }, + { .value = to_underlying(ModeBase::ModeTag::kNight) }, + { .value = to_underlying(ModeBase::ModeTag::kQuiet) } }; + + const detail::Structs::ModeOptionStruct::Type kModeOptions[3] = { + detail::Structs::ModeOptionStruct::Type{ .label = CharSpan::fromCharString("Normal"), + .mode = ModeNormal, + .modeTags = DataModel::List(modeTagsNormal) }, + detail::Structs::ModeOptionStruct::Type{ .label = CharSpan::fromCharString("Heavy"), + .mode = ModeHeavy, + .modeTags = DataModel::List(modeTagsHeavy) }, + detail::Structs::ModeOptionStruct::Type{ .label = CharSpan::fromCharString("Light"), + .mode = ModeLight, + .modeTags = DataModel::List(modeTagsLight) } + }; + + 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 & tags) override; + +public: + ~DishwasherModeDelegate() override = default; +}; + +} // namespace DishwasherMode + +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/all-clusters-app/all-clusters-common/include/laundry-washer-mode.h b/examples/all-clusters-app/all-clusters-common/include/laundry-washer-mode.h new file mode 100644 index 00000000000000..06fffda82d99b1 --- /dev/null +++ b/examples/all-clusters-app/all-clusters-common/include/laundry-washer-mode.h @@ -0,0 +1,81 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { + +namespace LaundryWasherMode { + +const uint8_t ModeNormal = 0; +const uint8_t ModeDelicate = 1; +const uint8_t ModeHeavy = 2; +const uint8_t ModeWhites = 3; + +/// This is an application level delegate to handle LaundryWasherMode commands according to the specific business logic. +class LaundryWasherModeDelegate : public ModeBase::Delegate +{ +private: + using ModeTagStructType = detail::Structs::ModeTagStruct::Type; + ModeTagStructType modeTagsNormal[1] = { { .value = to_underlying(ModeTag::kNormal) } }; + ModeTagStructType modeTagsDelicate[3] = { { .value = to_underlying(ModeTag::kDelicate) }, + { .value = to_underlying(ModeBase::ModeTag::kNight) }, + { .value = to_underlying(ModeBase::ModeTag::kQuiet) } }; + ModeTagStructType modeTagsHeavy[2] = { { .value = to_underlying(ModeBase::ModeTag::kMax) }, + { .value = to_underlying(ModeTag::kHeavy) } }; + ModeTagStructType modeTagsWhites[1] = { { .value = to_underlying(ModeTag::kWhites) } }; + + const detail::Structs::ModeOptionStruct::Type kModeOptions[4] = { + detail::Structs::ModeOptionStruct::Type{ .label = CharSpan::fromCharString("Normal"), + .mode = ModeNormal, + .modeTags = DataModel::List(modeTagsNormal) }, + detail::Structs::ModeOptionStruct::Type{ .label = CharSpan::fromCharString("Delicate"), + .mode = ModeDelicate, + .modeTags = DataModel::List(modeTagsDelicate) }, + detail::Structs::ModeOptionStruct::Type{ .label = CharSpan::fromCharString("Heavy"), + .mode = ModeHeavy, + .modeTags = DataModel::List(modeTagsHeavy) }, + detail::Structs::ModeOptionStruct::Type{ .label = CharSpan::fromCharString("Whites"), + .mode = ModeWhites, + .modeTags = DataModel::List(modeTagsWhites) }, + }; + + 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 & tags) override; + +public: + ~LaundryWasherModeDelegate() override = default; +}; + +} // namespace LaundryWasherMode + +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/all-clusters-app/all-clusters-common/include/rvc-modes.h b/examples/all-clusters-app/all-clusters-common/include/rvc-modes.h new file mode 100644 index 00000000000000..3e2841654fb5e5 --- /dev/null +++ b/examples/all-clusters-app/all-clusters-common/include/rvc-modes.h @@ -0,0 +1,114 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { + +namespace RvcRunMode { + +const uint8_t ModeIdle = 0; +const uint8_t ModeCleaning = 1; +const uint8_t ModeMapping = 2; + +/// This is an application level delegate to handle RvcRun commands according to the specific business logic. +class RvcRunModeDelegate : public ModeBase::Delegate +{ +private: + using ModeTagStructType = detail::Structs::ModeTagStruct::Type; + ModeTagStructType ModeTagsIdle[1] = { { .value = to_underlying(ModeTag::kIdle) } }; + ModeTagStructType ModeTagsCleaning[1] = { { .value = to_underlying(ModeTag::kCleaning) } }; + + const detail::Structs::ModeOptionStruct::Type kModeOptions[3] = { + detail::Structs::ModeOptionStruct::Type{ .label = CharSpan::fromCharString("Idle"), + .mode = ModeIdle, + .modeTags = DataModel::List(ModeTagsIdle) }, + detail::Structs::ModeOptionStruct::Type{ .label = CharSpan::fromCharString("Cleaning"), + .mode = ModeCleaning, + .modeTags = DataModel::List(ModeTagsCleaning) }, + detail::Structs::ModeOptionStruct::Type{ + .label = CharSpan::fromCharString("Mapping"), + .mode = ModeMapping, + .modeTags = DataModel::List(ModeTagsIdle) }, // todo set to no mode tags + }; + + 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 & tags) override; + +public: + ~RvcRunModeDelegate() override = default; +}; + +} // namespace RvcRunMode + +namespace RvcCleanMode { + +const uint8_t ModeVacuum = 0; +const uint8_t ModeWash = 1; +const uint8_t ModeDeepClean = 2; + +/// This is an application level delegate to handle RvcClean commands according to the specific business logic. +class RvcCleanModeDelegate : public ModeBase::Delegate +{ +private: + using ModeTagStructType = detail::Structs::ModeTagStruct::Type; + ModeTagStructType modeTagsVac[1] = { { .value = to_underlying(ModeTag::kVacuum) } }; + ModeTagStructType modeTagsMop[1] = { { .value = to_underlying(ModeTag::kMop) } }; + ModeTagStructType modeTagsBoost[2] = { { .value = to_underlying(ModeBase::ModeTag::kMax) }, + { .value = to_underlying(ModeTag::kDeepClean) } }; + + const detail::Structs::ModeOptionStruct::Type kModeOptions[3] = { + detail::Structs::ModeOptionStruct::Type{ .label = CharSpan::fromCharString("Vacuum"), + .mode = ModeVacuum, + .modeTags = DataModel::List(modeTagsVac) }, + detail::Structs::ModeOptionStruct::Type{ .label = CharSpan::fromCharString("Wash"), + .mode = ModeWash, + .modeTags = DataModel::List(modeTagsMop) }, + detail::Structs::ModeOptionStruct::Type{ .label = CharSpan::fromCharString("Deep clean"), + .mode = ModeDeepClean, + .modeTags = DataModel::List(modeTagsBoost) }, + }; + + 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 & tags) override; + +public: + ~RvcCleanModeDelegate() override = default; +}; + +} // namespace RvcCleanMode + +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/all-clusters-app/all-clusters-common/include/tcc-mode.h b/examples/all-clusters-app/all-clusters-common/include/tcc-mode.h new file mode 100644 index 00000000000000..7294fac8cbccd8 --- /dev/null +++ b/examples/all-clusters-app/all-clusters-common/include/tcc-mode.h @@ -0,0 +1,74 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { + +namespace RefrigeratorAndTemperatureControlledCabinetMode { + +const uint8_t ModeNormal = 0; +const uint8_t ModeRapidCool = 1; +const uint8_t ModeRapidFreeze = 2; + +/// This is an application level delegate to handle RefrigeratorAndTemperatureControlledCabinet commands according to the specific +/// business logic. +class TccModeDelegate : public ModeBase::Delegate +{ +private: + using ModeTagStructType = detail::Structs::ModeTagStruct::Type; + ModeTagStructType modeTagsTccNormal[1] = { { .value = to_underlying(ModeBase::ModeTag::kAuto) } }; + ModeTagStructType modeTagsTccRapidCool[1] = { { .value = to_underlying(ModeTag::kRapidCool) } }; + ModeTagStructType modeTagsTccRapidFreeze[1] = { { .value = to_underlying(ModeTag::kRapidFreeze) } }; + + const detail::Structs::ModeOptionStruct::Type kModeOptions[3] = { + detail::Structs::ModeOptionStruct::Type{ .label = CharSpan::fromCharString("Normal"), + .mode = ModeNormal, + .modeTags = DataModel::List(modeTagsTccNormal) }, + detail::Structs::ModeOptionStruct::Type{ .label = CharSpan::fromCharString("Rapid Cool"), + .mode = ModeRapidCool, + .modeTags = DataModel::List(modeTagsTccRapidCool) }, + detail::Structs::ModeOptionStruct::Type{ .label = CharSpan::fromCharString("Rapid Freeze"), + .mode = ModeRapidFreeze, + .modeTags = DataModel::List(modeTagsTccRapidFreeze) }, + }; + + 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 & tags) override; + +public: + ~TccModeDelegate() override = default; +}; + +} // namespace RefrigeratorAndTemperatureControlledCabinetMode + +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/all-clusters-app/all-clusters-common/src/dishwasher-mode.cpp b/examples/all-clusters-app/all-clusters-common/src/dishwasher-mode.cpp new file mode 100644 index 00000000000000..845ecb6d32a8a9 --- /dev/null +++ b/examples/all-clusters-app/all-clusters-common/src/dishwasher-mode.cpp @@ -0,0 +1,88 @@ +/* + * + * 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 +#include + +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::DishwasherMode; +using chip::Protocols::InteractionModel::Status; +template +using List = chip::app::DataModel::List; +using ModeTagStructType = chip::app::Clusters::detail::Structs::ModeTagStruct::Type; + +static DishwasherModeDelegate * gDishwasherModeDelegate = nullptr; +static ModeBase::Instance * gDishwasherModeInstance = nullptr; + +CHIP_ERROR DishwasherModeDelegate::Init() +{ + return CHIP_NO_ERROR; +} + +// todo refactor code by making a parent class for all ModeInstance classes to reduce flash usage. +void DishwasherModeDelegate::HandleChangeToMode(uint8_t NewMode, ModeBase::Commands::ChangeToModeResponse::Type & response) +{ + response.status = to_underlying(ModeBase::StatusCode::kSuccess); +} + +CHIP_ERROR DishwasherModeDelegate::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 DishwasherModeDelegate::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 DishwasherModeDelegate::GetModeTagsByIndex(uint8_t modeIndex, List & 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; +} + +void emberAfDishwasherModeClusterInitCallback(chip::EndpointId endpointId) +{ + VerifyOrDie(endpointId == 1); // this cluster is only enabled for endpoint 1. + VerifyOrDie(gDishwasherModeDelegate == nullptr && gDishwasherModeInstance == nullptr); + gDishwasherModeDelegate = new DishwasherMode::DishwasherModeDelegate; + // todo use Clusters::XxxMode::Feature::kXxxx to set features. + gDishwasherModeInstance = + new ModeBase::Instance(gDishwasherModeDelegate, 0x1, DishwasherMode::Id, chip::to_underlying(Feature::kOnOff)); + gDishwasherModeInstance->Init(); +} diff --git a/examples/all-clusters-app/all-clusters-common/src/laundry-washer-mode.cpp b/examples/all-clusters-app/all-clusters-common/src/laundry-washer-mode.cpp new file mode 100644 index 00000000000000..3cc44deee84878 --- /dev/null +++ b/examples/all-clusters-app/all-clusters-common/src/laundry-washer-mode.cpp @@ -0,0 +1,86 @@ +/* + * + * 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 +#include + +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::LaundryWasherMode; +using chip::Protocols::InteractionModel::Status; +template +using List = chip::app::DataModel::List; +using ModeTagStructType = chip::app::Clusters::detail::Structs::ModeTagStruct::Type; + +static LaundryWasherModeDelegate * gLaundryWasherModeDelegate = nullptr; +static ModeBase::Instance * gLaundryWasherModeInstance = nullptr; + +CHIP_ERROR LaundryWasherModeDelegate::Init() +{ + return CHIP_NO_ERROR; +} + +void LaundryWasherModeDelegate::HandleChangeToMode(uint8_t NewMode, ModeBase::Commands::ChangeToModeResponse::Type & response) +{ + response.status = to_underlying(ModeBase::StatusCode::kSuccess); +} + +CHIP_ERROR LaundryWasherModeDelegate::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 LaundryWasherModeDelegate::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 LaundryWasherModeDelegate::GetModeTagsByIndex(uint8_t modeIndex, List & 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; +} + +void emberAfLaundryWasherModeClusterInitCallback(chip::EndpointId endpointId) +{ + VerifyOrDie(endpointId == 1); // this cluster is only enabled for endpoint 1. + VerifyOrDie(gLaundryWasherModeDelegate == nullptr && gLaundryWasherModeInstance == nullptr); + gLaundryWasherModeDelegate = new LaundryWasherMode::LaundryWasherModeDelegate; + gLaundryWasherModeInstance = + new ModeBase::Instance(gLaundryWasherModeDelegate, 0x1, LaundryWasherMode::Id, chip::to_underlying(Feature::kOnOff)); + gLaundryWasherModeInstance->Init(); +} diff --git a/examples/all-clusters-app/all-clusters-common/src/rvc-modes.cpp b/examples/all-clusters-app/all-clusters-common/src/rvc-modes.cpp new file mode 100644 index 00000000000000..36a2fd7204a77c --- /dev/null +++ b/examples/all-clusters-app/all-clusters-common/src/rvc-modes.cpp @@ -0,0 +1,169 @@ +/* + * + * 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 +#include + +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::RvcRunMode; +using namespace chip::app::Clusters::RvcCleanMode; +using chip::Protocols::InteractionModel::Status; +template +using List = chip::app::DataModel::List; +using ModeTagStructType = chip::app::Clusters::detail::Structs::ModeTagStruct::Type; + +// RVC Run + +static RvcRunModeDelegate * gRvcRunModeDelegate = nullptr; +static ModeBase::Instance * gRvcRunModeInstance = nullptr; + +CHIP_ERROR RvcRunModeDelegate::Init() +{ + return CHIP_NO_ERROR; +} + +void RvcRunModeDelegate::HandleChangeToMode(uint8_t NewMode, ModeBase::Commands::ChangeToModeResponse::Type & response) +{ + uint8_t currentMode = mInstance->GetCurrentMode(); + + // Our business logic states that we can only switch into the mapping state from the idle state. + if (NewMode == RvcRunMode::ModeMapping && currentMode != RvcRunMode::ModeIdle) + { + response.status = to_underlying(ModeBase::StatusCode::kGenericFailure); + response.statusText.SetValue(chip::CharSpan::fromCharString("Change to the mapping mode is only allowed from idle")); + return; + } + + response.status = to_underlying(ModeBase::StatusCode::kSuccess); +} + +CHIP_ERROR RvcRunModeDelegate::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 RvcRunModeDelegate::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 RvcRunModeDelegate::GetModeTagsByIndex(uint8_t modeIndex, List & 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; +} + +void emberAfRvcRunModeClusterInitCallback(chip::EndpointId endpointId) +{ + VerifyOrDie(endpointId == 1); // this cluster is only enabled for endpoint 1. + VerifyOrDie(gRvcRunModeDelegate == nullptr && gRvcRunModeInstance == nullptr); + gRvcRunModeDelegate = new RvcRunMode::RvcRunModeDelegate; + gRvcRunModeInstance = + new ModeBase::Instance(gRvcRunModeDelegate, 0x1, RvcRunMode::Id, chip::to_underlying(RvcRunMode::Feature::kOnOff)); + gRvcRunModeInstance->Init(); +} + +// RVC Clean +static RvcCleanModeDelegate * gRvcCleanModeDelegate = nullptr; +static ModeBase::Instance * gRvcCleanModeInstance = nullptr; + +CHIP_ERROR RvcCleanModeDelegate::Init() +{ + return CHIP_NO_ERROR; +} + +void RvcCleanModeDelegate::HandleChangeToMode(uint8_t NewMode, ModeBase::Commands::ChangeToModeResponse::Type & response) +{ + uint8_t rvcRunCurrentMode = gRvcRunModeInstance->GetCurrentMode(); + + if (rvcRunCurrentMode == RvcRunMode::ModeCleaning) + { + response.status = to_underlying(RvcCleanMode::StatusCode::kCleaningInProgress); + response.statusText.SetValue(chip::CharSpan::fromCharString("Cannot change the cleaning mode during a clean")); + return; + } + + response.status = to_underlying(ModeBase::StatusCode::kSuccess); +} + +CHIP_ERROR RvcCleanModeDelegate::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 RvcCleanModeDelegate::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 RvcCleanModeDelegate::GetModeTagsByIndex(uint8_t modeIndex, List & 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; +} + +void emberAfRvcCleanModeClusterInitCallback(chip::EndpointId endpointId) +{ + VerifyOrDie(endpointId == 1); // this cluster is only enabled for endpoint 1. + VerifyOrDie(gRvcCleanModeDelegate == nullptr && gRvcCleanModeInstance == nullptr); + gRvcCleanModeDelegate = new RvcCleanMode::RvcCleanModeDelegate; + gRvcCleanModeInstance = + new ModeBase::Instance(gRvcCleanModeDelegate, 0x1, RvcCleanMode::Id, chip::to_underlying(RvcCleanMode::Feature::kOnOff)); + gRvcCleanModeInstance->Init(); +} diff --git a/examples/all-clusters-app/all-clusters-common/src/tcc-mode.cpp b/examples/all-clusters-app/all-clusters-common/src/tcc-mode.cpp new file mode 100644 index 00000000000000..704e5b17be22cb --- /dev/null +++ b/examples/all-clusters-app/all-clusters-common/src/tcc-mode.cpp @@ -0,0 +1,86 @@ +/* + * + * 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 +#include + +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::RefrigeratorAndTemperatureControlledCabinetMode; +using chip::Protocols::InteractionModel::Status; +template +using List = chip::app::DataModel::List; +using ModeTagStructType = chip::app::Clusters::detail::Structs::ModeTagStruct::Type; + +static TccModeDelegate * gTccModeDelegate = nullptr; +static ModeBase::Instance * gTccModeInstance = nullptr; + +CHIP_ERROR TccModeDelegate::Init() +{ + return CHIP_NO_ERROR; +} + +void TccModeDelegate::HandleChangeToMode(uint8_t NewMode, ModeBase::Commands::ChangeToModeResponse::Type & response) +{ + response.status = to_underlying(ModeBase::StatusCode::kSuccess); +} + +CHIP_ERROR TccModeDelegate::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 TccModeDelegate::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 TccModeDelegate::GetModeTagsByIndex(uint8_t modeIndex, List & 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; +} + +void emberAfRefrigeratorAndTemperatureControlledCabinetModeClusterInitCallback(chip::EndpointId endpointId) +{ + VerifyOrDie(endpointId == 1); // this cluster is only enabled for endpoint 1. + VerifyOrDie(gTccModeDelegate == nullptr && gTccModeInstance == nullptr); + gTccModeDelegate = new RefrigeratorAndTemperatureControlledCabinetMode::TccModeDelegate; + gTccModeInstance = new ModeBase::Instance(gTccModeDelegate, 0x1, RefrigeratorAndTemperatureControlledCabinetMode::Id, + chip::to_underlying(Feature::kOnOff)); + gTccModeInstance->Init(); +} diff --git a/examples/all-clusters-app/linux/BUILD.gn b/examples/all-clusters-app/linux/BUILD.gn index 6b7fa388c11970..bdaf4945e3ae4f 100644 --- a/examples/all-clusters-app/linux/BUILD.gn +++ b/examples/all-clusters-app/linux/BUILD.gn @@ -23,13 +23,17 @@ source_set("chip-all-clusters-common") { 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-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", "${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/operational-state-delegates.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/resource-monitoring-instances.cpp", + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/rvc-modes.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp", + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/tcc-mode.cpp", "AllClustersCommandDelegate.cpp", "AppOptions.cpp", "WindowCoveringManager.cpp", diff --git a/examples/all-clusters-app/linux/include/CHIPProjectAppConfig.h b/examples/all-clusters-app/linux/include/CHIPProjectAppConfig.h index 34cb4b56fd0ce8..7346ebd2807bfb 100644 --- a/examples/all-clusters-app/linux/include/CHIPProjectAppConfig.h +++ b/examples/all-clusters-app/linux/include/CHIPProjectAppConfig.h @@ -39,3 +39,6 @@ // Expose the device type in the advertisement for CI testing. #define CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONABLE_DEVICE_TYPE 1 + +// Marks that a ModeBase Derived cluster is being used. +#define EMBER_AF_PLUGIN_MODE_BASE diff --git a/examples/all-clusters-app/linux/main-common.cpp b/examples/all-clusters-app/linux/main-common.cpp index a2f5b31c161833..7894a781a6f278 100644 --- a/examples/all-clusters-app/linux/main-common.cpp +++ b/examples/all-clusters-app/linux/main-common.cpp @@ -19,11 +19,16 @@ #include "main-common.h" #include "AllClustersCommandDelegate.h" #include "WindowCoveringManager.h" +#include "dishwasher-mode.h" #include "include/tv-callbacks.h" +#include "laundry-washer-mode.h" +#include "rvc-modes.h" +#include "tcc-mode.h" #include #include #include #include +#include #include #include #include diff --git a/examples/lock-app/linux/args.gni b/examples/lock-app/linux/args.gni index e01c49ddbbdf34..db4d2e8c274da4 100644 --- a/examples/lock-app/linux/args.gni +++ b/examples/lock-app/linux/args.gni @@ -21,7 +21,7 @@ chip_project_config_include = "" chip_system_project_config_include = "" chip_project_config_include_dirs = - [ "${chip_root}/examples/all-clusters-app/linux/include" ] + [ "${chip_root}/examples/lock-app/linux/include" ] chip_project_config_include_dirs += [ "${chip_root}/config/standalone" ] matter_enable_tracing_support = true diff --git a/scripts/tools/check_includes_config.py b/scripts/tools/check_includes_config.py index c632eb34d12af4..fba3a095e74a6d 100644 --- a/scripts/tools/check_includes_config.py +++ b/scripts/tools/check_includes_config.py @@ -157,5 +157,8 @@ # Library meant for non-embedded 'src/tracing/json/json_tracing.cpp': {'string', 'sstream'}, - 'src/tracing/json/json_tracing.h': {'fstream'} + 'src/tracing/json/json_tracing.h': {'fstream'}, + + # Temporary solution util the OnOff server can provide a callback API for state change. + 'src/app/clusters/mode-base-server/mode-base-server.h': {'set'} } diff --git a/src/app/chip_data_model.gni b/src/app/chip_data_model.gni index 51bee460f09346..8eae0fcf8c0c6c 100644 --- a/src/app/chip_data_model.gni +++ b/src/app/chip_data_model.gni @@ -215,6 +215,13 @@ template("chip_data_model") { "${_app_root}/clusters/${cluster}/${cluster}.cpp", "${_app_root}/clusters/${cluster}/supported-temperature-levels-manager.h", ] + } else if (cluster == "mode-base-server") { + sources += [ + "${_app_root}/clusters/mode-base-server/mode-base-cluster-objects.cpp", + "${_app_root}/clusters/mode-base-server/mode-base-cluster-objects.h", + "${_app_root}/clusters/mode-base-server/mode-base-server.cpp", + "${_app_root}/clusters/mode-base-server/mode-base-server.h", + ] } else if (cluster == "application-launcher-server") { sources += [ "${_app_root}/app-platform/ContentApp.cpp", diff --git a/src/app/clusters/mode-base-server/README.md b/src/app/clusters/mode-base-server/README.md new file mode 100644 index 00000000000000..432091f041d31c --- /dev/null +++ b/src/app/clusters/mode-base-server/README.md @@ -0,0 +1,41 @@ +# Mode Base and its aliases + +Mode Base is a pseudo cluster. It has no cluster ID. It exists only to be +derived from by other clusters. + +# How to use a Mode Base derived cluster + +To use a Mode Base derived cluster, you need to + +- Create a class that inherits the `ModeBase::Delegate` class. For simple + examples that store all their data in memory, look at the + `-mode.*` files in the `src` and `include` directories in + `examples/all-clusters-app/all-clusters-common`. +- For this class implement the `GetModeLabelByIndex`, `GetModeValueByIndex`, + `GetModeTagsByIndex` and `HandleChangeToMode` methods. Look at the + documentation in `mode-base-server.h` for more information about these + methods. Cluster-specific enums can be accessed from the cluster namespace. +- Optionally implement the `Init` function. +- In some translation unit (.c or .cpp file), instantiate your + `ModeBase::Instance` inherited class. See the constructor documentation in + `mode-base-server.h`. +- Call the `.Init()` function of your instance after the root + `Server::Init()`. +- Alternatively, the last two steps can be done in the + `emberAfClusterInitCallback` function. +- Add `#define EMBER_AF_PLUGIN_MODE_BASE` to your + `chip_device_project_config_include` file. In the examples, this file is + `CHIPProjectAppConfig.h`. + +**Note** Zap accessor functions for these clusters do not exist. Use the +instance's `Update...` and `Get...` functions to access the attributes. + +# How to add new derived clusters + +Once a Mode Base derived cluster has been defined in the spec, add the +implementation using the following steps + +1. Translate the spec as an XML in `src/app/zap-templates/zcl/data-model/chip`. + You can look at similar files on how to do this. +2. Regenerate the zap code. +3. Extend the all-clusters-app example to include your new cluster. diff --git a/src/app/clusters/mode-base-server/mode-base-cluster-objects.cpp b/src/app/clusters/mode-base-server/mode-base-cluster-objects.cpp new file mode 100644 index 00000000000000..ee91338693a13c --- /dev/null +++ b/src/app/clusters/mode-base-server/mode-base-cluster-objects.cpp @@ -0,0 +1,113 @@ +/* + * + * 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 "mode-base-cluster-objects.h" + +namespace chip { +namespace app { +namespace Clusters { +namespace ModeBase { + +namespace Commands { + +namespace ChangeToMode { +CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const +{ + TLV::TLVType outer; + ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer)); + ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(Fields::kNewMode), newMode)); + ReturnErrorOnFailure(writer.EndContainer(outer)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + TLV::TLVType outer; + VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE); + ReturnErrorOnFailure(reader.EnterContainer(outer)); + while ((err = reader.Next()) == CHIP_NO_ERROR) + { + if (!TLV::IsContextTag(reader.GetTag())) + { + continue; + } + switch (TLV::TagNumFromTag(reader.GetTag())) + { + case to_underlying(Fields::kNewMode): + ReturnErrorOnFailure(DataModel::Decode(reader, newMode)); + break; + default: + break; + } + } + + VerifyOrReturnError(err == CHIP_END_OF_TLV, err); + ReturnErrorOnFailure(reader.ExitContainer(outer)); + return CHIP_NO_ERROR; +} +} // namespace ChangeToMode. +namespace ChangeToModeResponse { +CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const +{ + TLV::TLVType outer; + ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer)); + ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(Fields::kStatus), status)); + ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(Fields::kStatusText), statusText)); + ReturnErrorOnFailure(writer.EndContainer(outer)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + TLV::TLVType outer; + VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE); + ReturnErrorOnFailure(reader.EnterContainer(outer)); + while ((err = reader.Next()) == CHIP_NO_ERROR) + { + if (!TLV::IsContextTag(reader.GetTag())) + { + continue; + } + switch (TLV::TagNumFromTag(reader.GetTag())) + { + case to_underlying(Fields::kStatus): + ReturnErrorOnFailure(DataModel::Decode(reader, status)); + break; + case to_underlying(Fields::kStatusText): + ReturnErrorOnFailure(DataModel::Decode(reader, statusText)); + break; + default: + break; + } + } + + VerifyOrReturnError(err == CHIP_END_OF_TLV, err); + ReturnErrorOnFailure(reader.ExitContainer(outer)); + return CHIP_NO_ERROR; +} + +} // namespace ChangeToModeResponse. + +} // namespace Commands + +} // namespace ModeBase +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/mode-base-server/mode-base-cluster-objects.h b/src/app/clusters/mode-base-server/mode-base-cluster-objects.h new file mode 100644 index 00000000000000..5d450c671408d5 --- /dev/null +++ b/src/app/clusters/mode-base-server/mode-base-cluster-objects.h @@ -0,0 +1,216 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace ModeBase { + +namespace Attributes { + +namespace SupportedModes { +static constexpr AttributeId Id = 0x00000000; +struct TypeInfo +{ + using Type = DataModel::List; + using DecodableType = DataModel::DecodableList; + using DecodableArgType = DecodableType &; + + static constexpr AttributeId GetAttributeId() { return Attributes::SupportedModes::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace SupportedModes + +namespace CurrentMode { +static constexpr AttributeId Id = 0x00000001; +struct TypeInfo +{ + using Type = uint8_t; + using DecodableType = uint8_t; + using DecodableArgType = uint8_t; + + static constexpr AttributeId GetAttributeId() { return Attributes::CurrentMode::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace CurrentMode + +namespace StartUpMode { +static constexpr AttributeId Id = 0x00000002; +struct TypeInfo +{ + using Type = DataModel::Nullable; + using DecodableType = DataModel::Nullable; + using DecodableArgType = const DecodableType &; + + static constexpr AttributeId GetAttributeId() { return Attributes::StartUpMode::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace StartUpMode + +namespace OnMode { +static constexpr AttributeId Id = 0x00000003; +struct TypeInfo +{ + using Type = DataModel::Nullable; + using DecodableType = DataModel::Nullable; + using DecodableArgType = const DecodableType &; + + static constexpr AttributeId GetAttributeId() { return Attributes::OnMode::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace OnMode + +namespace GeneratedCommandList { +static constexpr AttributeId Id = Globals::Attributes::GeneratedCommandList::Id; +} // namespace GeneratedCommandList + +namespace AcceptedCommandList { +static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; +} // namespace AcceptedCommandList + +namespace EventList { +static constexpr AttributeId Id = Globals::Attributes::EventList::Id; +} // namespace EventList + +namespace AttributeList { +static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; +} // namespace AttributeList + +namespace FeatureMap { +static constexpr AttributeId Id = Globals::Attributes::FeatureMap::Id; +} // namespace FeatureMap + +namespace ClusterRevision { +static constexpr AttributeId Id = Globals::Attributes::ClusterRevision::Id; +} // namespace ClusterRevision + +} // namespace Attributes + +enum class Feature : uint32_t +{ + kOnOff = 0x1, +}; + +namespace Commands { + +namespace ChangeToModeResponse { + +static constexpr CommandId Id = 0x00000001; + +enum class Fields : uint8_t +{ + kStatus = 0, + kStatusText = 1, +}; + +struct Type +{ +public: + static constexpr CommandId GetCommandId() { return Commands::ChangeToModeResponse::Id; } + + uint8_t status = static_cast(0); + Optional statusText; + + CHIP_ERROR Encode(TLV::TLVWriter & writer, TLV::Tag tag) const; + + using ResponseType = DataModel::NullObjectType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::ChangeToModeResponse::Id; } + + uint8_t status = static_cast(0); + Optional statusText; + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace ChangeToModeResponse + +namespace ChangeToMode { + +static constexpr CommandId Id = 0x00000000; + +enum class Fields : uint8_t +{ + kNewMode = 0, +}; + +struct Type +{ +public: + static constexpr CommandId GetCommandId() { return Commands::ChangeToMode::Id; } + + uint8_t newMode = static_cast(0); + + CHIP_ERROR Encode(TLV::TLVWriter & writer, TLV::Tag tag) const; + + using ResponseType = Clusters::ModeBase::Commands::ChangeToModeResponse::DecodableType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::ChangeToMode::Id; } + uint8_t newMode = static_cast(0); + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace ChangeToMode + +} // namespace Commands + +// enums +// Enum for ModeTag +enum class ModeTag : uint16_t +{ + kAuto = 0x0, + kQuick = 0x1, + kQuiet = 0x2, + kLowNoise = 0x3, + kLowEnergy = 0x4, + kVacation = 0x5, + kMin = 0x6, + kMax = 0x7, + kNight = 0x8, + kDay = 0x9, +}; + +// Enum for StatusCode +enum class StatusCode : uint8_t +{ + kSuccess = 0x0, + kUnsupportedMode = 0x1, + kGenericFailure = 0x2, + kInvalidInMode = 0x3, +}; + +} // namespace ModeBase +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/mode-base-server/mode-base-server.cpp b/src/app/clusters/mode-base-server/mode-base-server.cpp new file mode 100644 index 00000000000000..ac85ccb9941ec9 --- /dev/null +++ b/src/app/clusters/mode-base-server/mode-base-server.cpp @@ -0,0 +1,492 @@ +/* + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; +using chip::Protocols::InteractionModel::Status; +using BootReasonType = GeneralDiagnostics::BootReasonEnum; +using ModeOptionStructType = chip::app::Clusters::detail::Structs::ModeOptionStruct::Type; +using ModeTagStructType = chip::app::Clusters::detail::Structs::ModeTagStruct::Type; + +namespace chip { +namespace app { +namespace Clusters { +namespace ModeBase { + +bool Instance::HasFeature(Feature feature) const +{ + return (mFeature & to_underlying(feature)) != 0; +} + +void Instance::LoadPersistentAttributes() +{ + // Load Current Mode + uint8_t tempCurrentMode; + CHIP_ERROR err = GetAttributePersistenceProvider()->ReadScalarValue( + ConcreteAttributePath(mEndpointId, mClusterId, Attributes::CurrentMode::Id), tempCurrentMode); + if (err == CHIP_NO_ERROR) + { + Status status = UpdateCurrentMode(tempCurrentMode); + if (status == Status::Success) + { + ChipLogDetail(Zcl, "ModeBase: Loaded CurrentMode as %u", GetCurrentMode()); + } + else + { + ChipLogError(Zcl, "ModeBase: Could not update CurrentMode to %u: %u", tempCurrentMode, to_underlying(status)); + } + } + else + { + // If we cannot find the previous CurrentMode, we will assume it to be the first mode in the + // list, as was initialised in the constructor. + ChipLogDetail(Zcl, "ModeBase: Unable to load the CurrentMode from the KVS. Assuming %u", GetCurrentMode()); + } + + // Load Start-Up Mode + DataModel::Nullable tempStartUpMode; + err = GetAttributePersistenceProvider()->ReadScalarValue( + ConcreteAttributePath(mEndpointId, mClusterId, Attributes::StartUpMode::Id), tempStartUpMode); + if (err == CHIP_NO_ERROR) + { + Status status = UpdateStartUpMode(tempStartUpMode); + if (status == Status::Success) + { + if (GetStartUpMode().IsNull()) + { + ChipLogDetail(Zcl, "ModeBase: Loaded StartUpMode as null"); + } + else + { + ChipLogDetail(Zcl, "ModeBase: Loaded StartUpMode as %u", GetStartUpMode().Value()); + } + } + else + { + ChipLogError(Zcl, "ModeBase: Could not update StartUpMode: %u", to_underlying(status)); + } + } + else + { + ChipLogDetail(Zcl, "ModeBase: Unable to load the StartUpMode from the KVS. Assuming null"); + } + + // Load On Mode + DataModel::Nullable tempOnMode; + err = GetAttributePersistenceProvider()->ReadScalarValue(ConcreteAttributePath(mEndpointId, mClusterId, Attributes::OnMode::Id), + tempOnMode); + if (err == CHIP_NO_ERROR) + { + Status status = UpdateOnMode(tempOnMode); + if (status == Status::Success) + { + if (GetOnMode().IsNull()) + { + ChipLogDetail(Zcl, "ModeBase: Loaded OnMode as null"); + } + else + { + ChipLogDetail(Zcl, "ModeBase: Loaded OnMode as %u", GetOnMode().Value()); + } + } + else + { + ChipLogError(Zcl, "ModeBase: Could not update OnMode: %u", to_underlying(status)); + } + } + else + { + ChipLogDetail(Zcl, "ModeBase: Unable to load the OnMode from the KVS. Assuming null"); + } +} + +CHIP_ERROR Instance::Init() +{ + // Initialise the current mode with the value of the first mode. This ensures that it is representing a valid mode. + ReturnErrorOnFailure(mDelegate->GetModeValueByIndex(0, mCurrentMode)); + + // Check if the cluster has been selected in zap + VerifyOrDie(emberAfContainsServer(mEndpointId, mClusterId) == true); + + LoadPersistentAttributes(); + + ReturnErrorOnFailure(chip::app::InteractionModelEngine::GetInstance()->RegisterCommandHandler(this)); + VerifyOrReturnError(registerAttributeAccessOverride(this), CHIP_ERROR_INCORRECT_STATE); + ReturnErrorOnFailure(mDelegate->Init()); + + ModeBaseAliasesInstances.insert(this); + + // If the StartUpMode is set, the CurrentMode attribute SHALL be set to the StartUpMode value, when the server is powered up. + if (!mStartUpMode.IsNull()) + { + // This behavior does not apply to reboots associated with OTA. + // After an OTA restart, the CurrentMode attribute SHALL return to its value prior to the restart. + // todo this only works for matter OTAs. According to the spec, this should also work for general OTAs. + BootReasonType bootReason = BootReasonType::kUnspecified; + CHIP_ERROR error = DeviceLayer::GetDiagnosticDataProvider().GetBootReason(bootReason); + + if (error != CHIP_NO_ERROR) + { + ChipLogError( + Zcl, "Unable to retrieve boot reason: %" CHIP_ERROR_FORMAT ". Assuming that we did not reboot because of an OTA", + error.Format()); + bootReason = BootReasonType::kUnspecified; + } + + if (bootReason == BootReasonType::kSoftwareUpdateCompleted) + { + ChipLogDetail(Zcl, "ModeBase: StartUpMode is ignored for OTA reboot."); + } + else + { + // Set CurrentMode to StartUpMode + if (mStartUpMode.Value() != mCurrentMode) + { + ChipLogProgress(Zcl, "ModeBase: Changing CurrentMode to the StartUpMode value."); + Status status = UpdateCurrentMode(mStartUpMode.Value()); + if (status != Status::Success) + { + ChipLogError(Zcl, "ModeBase: Failed to change the CurrentMode to the StartUpMode value: %u", + to_underlying(status)); + return StatusIB(status).ToChipError(); + } + + ChipLogProgress(Zcl, "ModeBase: Successfully initialized CurrentMode to the StartUpMode value %u", + mStartUpMode.Value()); + } + } + } + + // OnMode with Power Up + // If the On/Off feature is supported and the On/Off cluster attribute StartUpOnOff is present, with a + // value of On (turn on at power up), then the CurrentMode attribute SHALL be set to the OnMode attribute + // value when the server is supplied with power, except if the OnMode attribute is null. + if (emberAfContainsServer(mEndpointId, OnOff::Id) && + emberAfContainsAttribute(mEndpointId, OnOff::Id, OnOff::Attributes::StartUpOnOff::Id) && + emberAfContainsAttribute(mEndpointId, mClusterId, ModeBase::Attributes::OnMode::Id) && + HasFeature(ModeBase::Feature::kOnOff)) + { + DataModel::Nullable onMode = GetOnMode(); + bool onOffValueForStartUp = false; + if (!emberAfIsKnownVolatileAttribute(mEndpointId, OnOff::Id, OnOff::Attributes::StartUpOnOff::Id) && + OnOffServer::Instance().getOnOffValueForStartUp(mEndpointId, onOffValueForStartUp) == EMBER_ZCL_STATUS_SUCCESS) + { + if (onOffValueForStartUp && !onMode.IsNull()) + { + // Set CurrentMode to OnMode + if (mOnMode.Value() != mCurrentMode) + { + ChipLogProgress(Zcl, "ModeBase: Changing CurrentMode to the OnMode value."); + Status status = UpdateCurrentMode(mOnMode.Value()); + if (status != Status::Success) + { + ChipLogError(Zcl, "ModeBase: Failed to change the CurrentMode to the OnMode value: %u", + to_underlying(status)); + return StatusIB(status).ToChipError(); + } + + ChipLogProgress(Zcl, "ModeBase: Successfully initialized CurrentMode to the OnMode value %u", mOnMode.Value()); + } + } + } + } + + return CHIP_NO_ERROR; +} + +template +void Instance::HandleCommand(HandlerContext & handlerContext, FuncT func) +{ + if (!handlerContext.mCommandHandled && (handlerContext.mRequestPath.mCommandId == RequestT::GetCommandId())) + { + RequestT requestPayload; + + // If the command matches what the caller is looking for, let's mark this as being handled + // even if errors happen after this. This ensures that we don't execute any fall-back strategies + // to handle this command since at this point, the caller is taking responsibility for handling + // the command in its entirety, warts and all. + // + handlerContext.SetCommandHandled(); + + if (DataModel::Decode(handlerContext.mPayload, requestPayload) != CHIP_NO_ERROR) + { + handlerContext.mCommandHandler.AddStatus(handlerContext.mRequestPath, + Protocols::InteractionModel::Status::InvalidCommand); + return; + } + + func(handlerContext, requestPayload); + } +} + +void Instance::HandleChangeToMode(HandlerContext & ctx, const Commands::ChangeToMode::DecodableType & commandData) +{ + uint8_t newMode = commandData.newMode; + + Commands::ChangeToModeResponse::Type response; + + if (!IsSupportedMode(newMode)) + { + ChipLogError(Zcl, "ModeBase: Failed to find the option with mode %u", newMode); + response.status = to_underlying(StatusCode::kUnsupportedMode); + ctx.mCommandHandler.AddResponse(ctx.mRequestPath, response); + return; + } + + mDelegate->HandleChangeToMode(newMode, response); + + if (response.status == to_underlying(StatusCode::kSuccess)) + { + UpdateCurrentMode(newMode); + ChipLogProgress(Zcl, "ModeBase: HandleChangeToMode changed to mode %u", newMode); + } + + ctx.mCommandHandler.AddResponse(ctx.mRequestPath, response); +} + +// This function is called by the interaction model engine when a command destined for this instance is received. +void Instance::InvokeCommand(HandlerContext & handlerContext) +{ + switch (handlerContext.mRequestPath.mCommandId) + { + case ModeBase::Commands::ChangeToMode::Id: + ChipLogDetail(Zcl, "ModeBase: Entering handling ChangeToModeWithStatus"); + + HandleCommand( + handlerContext, [this](HandlerContext & ctx, const auto & commandData) { HandleChangeToMode(ctx, commandData); }); + } +} + +// 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; +} + +CHIP_ERROR Instance::EncodeSupportedModes(const AttributeValueEncoder::ListEncodeHelper & encoder) +{ + for (uint8_t i = 0; true; i++) + { + ModeOptionStructType mode; + + // Get the mode label + char buffer[kMaxModeLabelSize]; + MutableCharSpan label(buffer); + auto err = mDelegate->GetModeLabelByIndex(i, label); + if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) + { + return CHIP_NO_ERROR; + } + ReturnErrorOnFailure(err); + + mode.label = label; + + // Get the mode value + ReturnErrorOnFailure(mDelegate->GetModeValueByIndex(i, mode.mode)); + + // Get the mode tags + ModeTagStructType tagsBuffer[kMaxNumOfModeTags]; + DataModel::List tags(tagsBuffer); + ReturnErrorOnFailure(mDelegate->GetModeTagsByIndex(i, tags)); + mode.modeTags = tags; + + ReturnErrorOnFailure(encoder.Encode(mode)); + } + return CHIP_NO_ERROR; +} + +// Implements the read functionality for complex attributes. +CHIP_ERROR Instance::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) +{ + switch (aPath.mAttributeId) + { + case Attributes::CurrentMode::Id: + ReturnErrorOnFailure(aEncoder.Encode(mCurrentMode)); + break; + case Attributes::StartUpMode::Id: + ReturnErrorOnFailure(aEncoder.Encode(mStartUpMode)); + break; + case Attributes::OnMode::Id: + ReturnErrorOnFailure(aEncoder.Encode(mOnMode)); + break; + case Attributes::FeatureMap::Id: + ReturnErrorOnFailure(aEncoder.Encode(mFeature)); + break; + case Attributes::SupportedModes::Id: + Instance * d = this; + CHIP_ERROR err = aEncoder.EncodeList([d](const auto & encoder) -> CHIP_ERROR { return d->EncodeSupportedModes(encoder); }); + return err; + } + return CHIP_NO_ERROR; +} + +// Implements checking before attribute writes. +CHIP_ERROR Instance::Write(const ConcreteDataAttributePath & attributePath, AttributeValueDecoder & aDecoder) +{ + DataModel::Nullable newMode; + ReturnErrorOnFailure(aDecoder.Decode(newMode)); + Status status; + + switch (attributePath.mAttributeId) + { + case ModeBase::Attributes::StartUpMode::Id: + status = UpdateStartUpMode(newMode); + return StatusIB(status).ToChipError(); + case ModeBase::Attributes::OnMode::Id: + status = UpdateOnMode(newMode); + return StatusIB(status).ToChipError(); + } + + return CHIP_ERROR_INCORRECT_STATE; +} + +Status Instance::UpdateCurrentMode(uint8_t aNewMode) +{ + if (!IsSupportedMode(aNewMode)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + uint8_t oldMode = mCurrentMode; + mCurrentMode = aNewMode; + if (mCurrentMode != oldMode) + { + // Write new value to persistent storage. + ConcreteAttributePath path = ConcreteAttributePath(mEndpointId, mClusterId, Attributes::CurrentMode::Id); + GetAttributePersistenceProvider()->WriteScalarValue(path, mCurrentMode); + MatterReportingAttributeChangeCallback(path); + } + return Protocols::InteractionModel::Status::Success; +} + +Status Instance::UpdateStartUpMode(DataModel::Nullable aNewStartUpMode) +{ + if (!aNewStartUpMode.IsNull()) + { + if (!IsSupportedMode(aNewStartUpMode.Value())) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + } + DataModel::Nullable oldStartUpMode = mStartUpMode; + mStartUpMode = aNewStartUpMode; + if (mStartUpMode != oldStartUpMode) + { + // Write new value to persistent storage. + ConcreteAttributePath path = ConcreteAttributePath(mEndpointId, mClusterId, Attributes::StartUpMode::Id); + GetAttributePersistenceProvider()->WriteScalarValue(path, mStartUpMode); + MatterReportingAttributeChangeCallback(path); + } + return Protocols::InteractionModel::Status::Success; +} + +Status Instance::UpdateOnMode(DataModel::Nullable aNewOnMode) +{ + if (!aNewOnMode.IsNull()) + { + if (!IsSupportedMode(aNewOnMode.Value())) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + } + DataModel::Nullable oldOnMode = mOnMode; + mOnMode = aNewOnMode; + if (mOnMode != oldOnMode) + { + // Write new value to persistent storage. + ConcreteAttributePath path = ConcreteAttributePath(mEndpointId, mClusterId, Attributes::OnMode::Id); + GetAttributePersistenceProvider()->WriteScalarValue(path, mOnMode); + MatterReportingAttributeChangeCallback(path); + } + return Protocols::InteractionModel::Status::Success; +} + +DataModel::Nullable Instance::GetStartUpMode() const +{ + return mStartUpMode; +} + +DataModel::Nullable Instance::GetOnMode() const +{ + return mOnMode; +} + +uint8_t Instance::GetCurrentMode() const +{ + return mCurrentMode; +} + +bool Instance::IsSupportedMode(uint8_t modeValue) +{ + uint8_t value; + for (uint8_t i = 0; mDelegate->GetModeValueByIndex(i, value) != CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; i++) + { + if (value == modeValue) + { + return true; + } + } + ChipLogDetail(Zcl, "Cannot find a mode with value %u", modeValue); + return false; +} + +Instance::Instance(Delegate * aDelegate, EndpointId aEndpointId, ClusterId aClusterId, uint32_t aFeature) : + CommandHandlerInterface(Optional(aEndpointId), aClusterId), + AttributeAccessInterface(Optional(aEndpointId), aClusterId), mDelegate(aDelegate), mEndpointId(aEndpointId), + mClusterId(aClusterId), + mCurrentMode(0), // This is a temporary value and may not be valid. We will change this to the value of the first + // mode in the list at the start of the Init function to ensure that it represents a valid mode. + mFeature(aFeature) +{ + mDelegate->SetInstance(this); +} + +Instance::~Instance() +{ + ModeBaseAliasesInstances.erase(this); + chip::app::InteractionModelEngine::GetInstance()->UnregisterCommandHandler(this); + unregisterAttributeAccessOverride(this); +} + +std::set * GetModeBaseInstances() +{ + return &ModeBaseAliasesInstances; +} + +} // namespace ModeBase +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/mode-base-server/mode-base-server.h b/src/app/clusters/mode-base-server/mode-base-server.h new file mode 100644 index 00000000000000..617fd262ba8515 --- /dev/null +++ b/src/app/clusters/mode-base-server/mode-base-server.h @@ -0,0 +1,239 @@ +/* + * + * 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 "mode-base-cluster-objects.h" +#include +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace ModeBase { + +class Delegate; + +class Instance : public CommandHandlerInterface, public AttributeAccessInterface +{ +private: + Delegate * mDelegate; + + EndpointId mEndpointId{}; + ClusterId mClusterId{}; + + // Attribute data store + uint8_t mCurrentMode; + DataModel::Nullable mStartUpMode; + DataModel::Nullable mOnMode; + uint32_t mFeature; + + // 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; + CHIP_ERROR Write(const ConcreteDataAttributePath & aPath, AttributeValueDecoder & aDecoder) override; + + /** + * Internal change-to-mode command handler function. + */ + void HandleChangeToMode(HandlerContext & ctx, const Commands::ChangeToMode::DecodableType & req); + + /** + * Helper function that loads all the persistent attributes from the KVS. These attributes are CurrentMode, + * StartUpMode and OnMode. + */ + void LoadPersistentAttributes(); + + /** + * Helper function that encodes the supported modes. + * @param encoder The encoder to encode the supported modes into. + */ + CHIP_ERROR EncodeSupportedModes(const AttributeValueEncoder::ListEncodeHelper & encoder); + +public: + /** + * Initialise the ModeBase server instance. + * @return Returns an error if the given endpoint and cluster ID have not been enabled in zap, if the + * CommandHandler or AttributeHandler registration fails or if the Delegate::Init() returns an error. + */ + CHIP_ERROR Init(); + + // Attribute setters + /** + * Sets the Start-Up attribute. Note, this also handles writing the new value into non-volatile storage. + * @param aNewStartUpMode The value to which the Start-Up mode is to be set. + * @return Returns a ConstraintError if the aNewStartUpMode value is not valid. Returns Success otherwise. + */ + Protocols::InteractionModel::Status UpdateStartUpMode(DataModel::Nullable aNewStartUpMode); + + /** + * Sets the On-Mode attribute. Note, this also handles writing the new value into non-volatile storage. + * @param aNewOnMode The value to which the On-Mode mode is to be set. + * @return Returns a ConstraintError if the aNewOnMode value is not valid. Returns Success otherwise. + */ + Protocols::InteractionModel::Status UpdateOnMode(DataModel::Nullable aNewOnMode); + + /** + * Sets the Current-Mode attribute. Note, this also handles writing the new value into non-volatile storage. + * @param aNewMode The value to which the Current-Mode mode is to be set. + * @return Returns a ConstraintError if the aNewMode value is not valid. Returns Success otherwise. + */ + Protocols::InteractionModel::Status UpdateCurrentMode(uint8_t aNewMode); + + // Attribute getters. + /** + * @return The Start-Up mode. + */ + DataModel::Nullable GetStartUpMode() const; + + /** + * @return The On mode. + */ + DataModel::Nullable GetOnMode() const; + + /** + * @return The Current mode. + */ + uint8_t GetCurrentMode() const; + + /** + * @return The endpoint ID. + */ + EndpointId GetEndpointId() const { return mEndpointId; } + + // Cluster constants, from the spec. + static constexpr uint8_t kMaxModeLabelSize = 64; + static constexpr uint8_t kMaxNumOfModeTags = 8; + + /** + * Returns true if the feature is supported. + * @param feature the feature to check. + */ + bool HasFeature(Feature feature) const; + + /** + * This function returns true if the mode value given matches one of the supported modes, otherwise it returns false. + * @param mode + */ + bool IsSupportedMode(uint8_t mode); + + /** + * Creates a mode base cluster instance. The Init() function needs to be called for this instance to be registered and + * called by the interaction model at the appropriate times. + * @param aEndpointId The endpoint on which this cluster exists. This must match the zap configuration. + * @param aClusterId The ID of the ModeBase aliased cluster to be instantiated. + * @param aFeature The bitmask value that identifies which features are supported by this instance. + */ + Instance(Delegate * aDelegate, EndpointId aEndpointId, ClusterId aClusterId, uint32_t aFeature); + + ~Instance() override; + + template + void HandleCommand(HandlerContext & handlerContext, FuncT func); +}; + +class Delegate +{ +protected: + Instance * mInstance = nullptr; + +public: + Delegate() = default; + + virtual ~Delegate() = default; + + /** + * This method is used by the SDK to set the instance pointer. This is done during the instantiation of an Instance object. + * @param aInstance A pointer to the Instance object related to this delegate object. + */ + void SetInstance(Instance * aInstance) { mInstance = aInstance; } + + // The following functions should be overridden by the SDK user to implement the business logic of their application. + /** + * This init function will be called during the ModeBase server initialization after the Instance information has been + * validated and the Instance has been registered. This can be used to initialise app logic. + */ + virtual CHIP_ERROR Init() = 0; + + /** + * Get the mode label of the Nth mode in the list of modes. + * @param modeIndex The index of the mode to be returned. It is assumed that modes are indexable from 0 and with no gaps. + * @param label A reference to the mutable char span which will be mutated to receive the label on success. Use + * CopyCharSpanToMutableCharSpan to copy into the MutableCharSpan. + * @return Returns a CHIP_NO_ERROR if there was no error and the label was returned successfully. + * CHIP_ERROR_PROVIDER_LIST_EXHAUSTED if the modeIndex in beyond the list of available labels. + */ + virtual CHIP_ERROR GetModeLabelByIndex(uint8_t modeIndex, MutableCharSpan & label) = 0; + + /** + * Get the mode value of the Nth mode in the list of modes. + * @param modeIndex The index of the mode to be returned. It is assumed that modes are indexable from 0 and with no gaps. + * @param value a reference to the uint8_t variable that is to contain the mode value. + * @return Returns a CHIP_NO_ERROR if there was no error and the value was returned successfully. + * CHIP_ERROR_PROVIDER_LIST_EXHAUSTED if the modeIndex in beyond the list of available values. + */ + virtual CHIP_ERROR GetModeValueByIndex(uint8_t modeIndex, uint8_t & value) = 0; + + /** + * Get the mode tags of the Nth mode in the list of modes. + * The caller will make sure the List points to an existing buffer of sufficient size to hold the spec-required number + * of tags, and the size of the List is the size of the buffer. + * + * The implementation must place its desired ModeTagStructType instances in that buffer and call tags.reduce_size + * on the list to indicate how many entries were initialized. + * @param modeIndex The index of the mode to be returned. It is assumed that modes are indexable from 0 and with no gaps. + * @param tags a reference to an existing and initialised buffer that is to contain the mode tags. std::copy can be used + * to copy into the buffer. + * @return Returns a CHIP_NO_ERROR if there was no error and the mode tags were returned successfully. + * CHIP_ERROR_PROVIDER_LIST_EXHAUSTED if the modeIndex in beyond the list of available mode tags. + */ + virtual CHIP_ERROR GetModeTagsByIndex(uint8_t modeIndex, DataModel::List & modeTags) = 0; + + /** + * When a ChangeToMode command is received, if the NewMode value is a supported mode, this method is called to 1) decide if + * we should go ahead with transitioning to this mode and 2) formulate the ChangeToModeResponse that will be sent back to the + * client. If this function returns a response.status of StatusCode::kSuccess, the change request is accepted + * and the CurrentMode is set to the NewMode. Else, the CurrentMode is left untouched. The response is sent as a + * ChangeToModeResponse command. + * + * This function is to be overridden by a user implemented function that makes this decision based on the application logic. + * @param NewMode The new made that the device is requested to transition to. + * @param response A reference to a response that will be sent to the client. The contents of which con be modified by the + * application. + * + */ + virtual void HandleChangeToMode(uint8_t NewMode, ModeBase::Commands::ChangeToModeResponse::Type & response) = 0; +}; + +// A set of pointers to all initialised ModeBase instances. It provides a way to access all ModeBase derived clusters. +// todo change once there is a clear public interface for the OnOff cluster data dependencies (#27508) +static std::set ModeBaseAliasesInstances; + +std::set * GetModeBaseInstances(); + +} // namespace ModeBase +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/on-off-server/on-off-server.cpp b/src/app/clusters/on-off-server/on-off-server.cpp index 46e161a752b221..eb1c320b800da6 100644 --- a/src/app/clusters/on-off-server/on-off-server.cpp +++ b/src/app/clusters/on-off-server/on-off-server.cpp @@ -33,6 +33,14 @@ #include #endif // EMBER_AF_PLUGIN_LEVEL_CONTROL +#ifdef EMBER_AF_PLUGIN_MODE_BASE +// nogncheck because the gn dependency checker does not understand +// conditional includes, so will fail in an application that has an On/Off +// cluster but no ModeBase-derived cluster. +#include // nogncheck +#include // nogncheck +#endif // EMBER_AF_PLUGIN_MODE_BASE + #include #include @@ -41,6 +49,45 @@ using namespace chip::app::Clusters; using namespace chip::app::Clusters::OnOff; using chip::Protocols::InteractionModel::Status; +namespace { + +#ifdef EMBER_AF_PLUGIN_MODE_BASE + +/** + * For all ModeBase alias clusters on the given endpoint, if the OnOff feature is supported and + * the OnMode attribute is set, update the CurrentMode attribute value to the OnMode value. + * @param endpoint + */ +void UpdateModeBaseCurrentModeToOnMode(EndpointId endpoint) +{ + for (const auto & modeBaseInstance : *ModeBase::GetModeBaseInstances()) + { + if (modeBaseInstance->GetEndpointId() == endpoint) + { + if (modeBaseInstance->HasFeature(ModeBase::Feature::kOnOff)) + { + ModeBase::Attributes::OnMode::TypeInfo::Type onMode = modeBaseInstance->GetOnMode(); + if (!onMode.IsNull()) + { + Status status = modeBaseInstance->UpdateCurrentMode(onMode.Value()); + if (status == Status::Success) + { + ChipLogProgress(Zcl, "Changed the Current Mode to %x", onMode.Value()); + } + else + { + ChipLogError(Zcl, "Failed to Changed the Current Mode to %x: %u", onMode.Value(), to_underlying(status)); + } + } + } + } + } +} + +#endif // EMBER_AF_PLUGIN_MODE_BASE + +} // namespace + #ifdef EMBER_AF_PLUGIN_LEVEL_CONTROL static bool LevelControlWithOnOffFeaturePresent(EndpointId endpoint) { @@ -465,6 +512,10 @@ EmberAfStatus OnOffServer::setOnOffValue(chip::EndpointId endpoint, chip::Comman status = ModeSelect::Attributes::CurrentMode::Set(endpoint, onMode.Value()); } } +#endif +#ifdef EMBER_AF_PLUGIN_MODE_BASE + // If OnMode is not a null value, then change the current mode to it. + UpdateModeBaseCurrentModeToOnMode(endpoint); #endif } else // Set Off diff --git a/src/app/common/templates/config-data.yaml b/src/app/common/templates/config-data.yaml index 1f341047fa9921..d31acdb01ce998 100644 --- a/src/app/common/templates/config-data.yaml +++ b/src/app/common/templates/config-data.yaml @@ -24,6 +24,11 @@ CommandHandlerInterfaceOnlyClusters: # This uses asUpperCamelCase versions of the cluster name. - NetworkCommissioning - Scenes + - RvcRunMode + - RvcCleanMode + - DishwasherMode + - LaundryWasherMode + - RefrigeratorAndTemperatureControlledCabinetMode - OperationalState - ActivatedCarbonFilterMonitoring - HepaFilterMonitoring diff --git a/src/app/util/util.cpp b/src/app/util/util.cpp index b134b6db589994..8e42e4e277ab30 100644 --- a/src/app/util/util.cpp +++ b/src/app/util/util.cpp @@ -149,6 +149,11 @@ void MatterPm1ConcentrationMeasurementPluginServerInitCallback() {} void MatterPm25ConcentrationMeasurementPluginServerInitCallback() {} void MatterRadonConcentrationMeasurementPluginServerInitCallback() {} void MatterTotalVolatileOrganicCompoundsConcentrationMeasurementPluginServerInitCallback() {} +void MatterRvcRunModePluginServerInitCallback() {} +void MatterRvcCleanModePluginServerInitCallback() {} +void MatterDishwasherModePluginServerInitCallback() {} +void MatterLaundryWasherModePluginServerInitCallback() {} +void MatterRefrigeratorAndTemperatureControlledCabinetModePluginServerInitCallback() {} void MatterOperationalStatePluginServerInitCallback() {} // **************************************** // Print out information about each cluster diff --git a/src/app/zap-templates/zcl/data-model/chip/laundry-washer-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/laundry-washer-mode-cluster.xml index 3bea0e59d015ef..95eb512618f274 100644 --- a/src/app/zap-templates/zcl/data-model/chip/laundry-washer-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/laundry-washer-mode-cluster.xml @@ -33,7 +33,6 @@ limitations under the License. true true Attributes and commands for selecting a mode from a list of supported options. - SupportedModes CurrentMode diff --git a/src/app/zap-templates/zcl/data-model/chip/mode-base-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/mode-base-cluster.xml index f0bb878ce09b7a..6b3355542713bb 100644 --- a/src/app/zap-templates/zcl/data-model/chip/mode-base-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/mode-base-cluster.xml @@ -22,12 +22,15 @@ Due to the ModeBase cluster not having a clustre ID, these enems will need to be These enems can be used once the zap generation tool supports aliased and derived clusters. --> + + + @@ -65,16 +68,17 @@ These enems can be used once the zap generation tool supports aliased and derive + - - - - + + + + @@ -92,10 +96,10 @@ These enems can be used once the zap generation tool supports aliased and derive - + diff --git a/src/app/zap-templates/zcl/data-model/chip/refrigerator-and-temperature-controlled-cabinet-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/refrigerator-and-temperature-controlled-cabinet-mode-cluster.xml index aafc4f36af53f4..c55109379e5aa2 100644 --- a/src/app/zap-templates/zcl/data-model/chip/refrigerator-and-temperature-controlled-cabinet-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/refrigerator-and-temperature-controlled-cabinet-mode-cluster.xml @@ -31,7 +31,6 @@ limitations under the License. true true Attributes and commands for selecting a mode from a list of supported options. - SupportedModes CurrentMode diff --git a/src/app/zap-templates/zcl/data-model/chip/rvc-clean-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/rvc-clean-mode-cluster.xml index 9ae08bb6cb6a3a..1baf10841b9672 100644 --- a/src/app/zap-templates/zcl/data-model/chip/rvc-clean-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/rvc-clean-mode-cluster.xml @@ -37,7 +37,6 @@ limitations under the License. true true Attributes and commands for selecting a mode from a list of supported options. - SupportedModes CurrentMode diff --git a/src/app/zap-templates/zcl/data-model/chip/rvc-run-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/rvc-run-mode-cluster.xml index ae5cc2163cc786..dd7905ce9891d7 100644 --- a/src/app/zap-templates/zcl/data-model/chip/rvc-run-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/rvc-run-mode-cluster.xml @@ -43,7 +43,6 @@ limitations under the License. true true Attributes and commands for selecting a mode from a list of supported options. - SupportedModes CurrentMode diff --git a/src/app/zap-templates/zcl/zcl-with-test-extensions.json b/src/app/zap-templates/zcl/zcl-with-test-extensions.json index 59d5ba3e1a03f1..7a7c992d6f3084 100644 --- a/src/app/zap-templates/zcl/zcl-with-test-extensions.json +++ b/src/app/zap-templates/zcl/zcl-with-test-extensions.json @@ -314,6 +314,41 @@ "DSTOffsetListMaxSize" ], "Temperature Control": ["SupportedTemperatureLevels"], + "Dishwasher Mode": [ + "SupportedModes", + "CurrentMode", + "StartUpMode", + "OnMode", + "FeatureMap" + ], + "Laundry Washer Mode": [ + "SupportedModes", + "CurrentMode", + "StartUpMode", + "OnMode", + "FeatureMap" + ], + "Refrigerator And Temperature Controlled Cabinet Mode": [ + "SupportedModes", + "CurrentMode", + "StartUpMode", + "OnMode", + "FeatureMap" + ], + "RVC Clean Mode": [ + "SupportedModes", + "CurrentMode", + "StartUpMode", + "OnMode", + "FeatureMap" + ], + "RVC Run Mode": [ + "SupportedModes", + "CurrentMode", + "StartUpMode", + "OnMode", + "FeatureMap" + ], "Operational State": [ "OperationalState", "OperationalError", diff --git a/src/app/zap-templates/zcl/zcl.json b/src/app/zap-templates/zcl/zcl.json index 7d4d89ec6b4107..73475a6196662f 100644 --- a/src/app/zap-templates/zcl/zcl.json +++ b/src/app/zap-templates/zcl/zcl.json @@ -312,6 +312,41 @@ "DSTOffsetListMaxSize" ], "Temperature Control": ["SupportedTemperatureLevels"], + "Dishwasher Mode": [ + "SupportedModes", + "CurrentMode", + "StartUpMode", + "OnMode", + "FeatureMap" + ], + "Laundry Washer Mode": [ + "SupportedModes", + "CurrentMode", + "StartUpMode", + "OnMode", + "FeatureMap" + ], + "Refrigerator And Temperature Controlled Cabinet Mode": [ + "SupportedModes", + "CurrentMode", + "StartUpMode", + "OnMode", + "FeatureMap" + ], + "RVC Clean Mode": [ + "SupportedModes", + "CurrentMode", + "StartUpMode", + "OnMode", + "FeatureMap" + ], + "RVC Run Mode": [ + "SupportedModes", + "CurrentMode", + "StartUpMode", + "OnMode", + "FeatureMap" + ], "Operational State": [ "OperationalState", "OperationalError", diff --git a/src/app/zap_cluster_list.json b/src/app/zap_cluster_list.json index 717d39f7faeca4..4c3b0ff941ce3e 100644 --- a/src/app/zap_cluster_list.json +++ b/src/app/zap_cluster_list.json @@ -167,7 +167,7 @@ "IDENTIFY_CLUSTER": ["identify-server"], "ILLUMINANCE_MEASUREMENT_CLUSTER": [], "KEYPAD_INPUT_CLUSTER": ["keypad-input-server"], - "LAUNDRY_WASHER_MODE_CLUSTER": ["mode-select-server"], + "LAUNDRY_WASHER_MODE_CLUSTER": ["mode-base-server"], "LEVEL_CONTROL_CLUSTER": ["level-control"], "LOCALIZATION_CONFIGURATION_CLUSTER": [ "localization-configuration-server" @@ -208,11 +208,11 @@ "RADON_CONCENTRATION_MEASUREMENT_CLUSTER": [], "REFRIGERATOR_ALARM_CLUSTER": ["refrigerator-alarm-server"], "REFRIGERATOR_AND_TEMPERATURE_CONTROLLED_CABINET_MODE_CLUSTER": [ - "mode-select-server" + "mode-base-server" ], "RELATIVE_HUMIDITY_MEASUREMENT_CLUSTER": [], - "RVC_CLEAN_MODE_CLUSTER": ["mode-select-server"], - "RVC_RUN_MODE_CLUSTER": ["mode-select-server"], + "RVC_CLEAN_MODE_CLUSTER": ["mode-base-server"], + "RVC_RUN_MODE_CLUSTER": ["mode-base-server"], "SCENES_CLUSTER": ["scenes-server"], "SMOKE_CO_ALARM_CLUSTER": ["smoke-co-alarm-server"], "SOFTWARE_DIAGNOSTICS_CLUSTER": ["software-diagnostics-server"], diff --git a/src/controller/data_model/controller-clusters.zap b/src/controller/data_model/controller-clusters.zap index 266851580d9068..637f8d4e6bd5d6 100644 --- a/src/controller/data_model/controller-clusters.zap +++ b/src/controller/data_model/controller-clusters.zap @@ -26937,6 +26937,238 @@ } ] }, + { + "name": "Mode Base", + "code": 61731, + "mfgCode": null, + "define": "MODE_BASE_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "ChangeToMode", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 0, + "outgoing": 1 + } + ], + "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": "2", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Mode Base", + "code": 61731, + "mfgCode": null, + "define": "MODE_BASE_CLUSTER", + "side": "server", + "enabled": 0, + "commands": [ + { + "name": "ChangeToModeResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 0 + } + ], + "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": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "StartUpMode", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "OnMode", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 0, + "storageOption": "RAM", + "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": "RAM", + "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": "2", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, { "name": "Unit Testing", "code": 4294048773, diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp index 618969f82de5b2..df0f618f25c559 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp @@ -6989,143 +6989,6 @@ EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value) namespace LaundryWasherMode { namespace Attributes { -namespace CurrentMode { - -EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::LaundryWasherMode::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status); - if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) - { - return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; - } - *value = Traits::StorageToWorking(temp); - return status; -} -EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::LaundryWasherMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -} // namespace CurrentMode - -namespace StartUpMode { - -EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable & value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::LaundryWasherMode::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status); - if (Traits::IsNullValue(temp)) - { - value.SetNull(); - } - else - { - value.SetNonNull() = Traits::StorageToWorking(temp); - } - return status; -} -EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) - { - return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::LaundryWasherMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -EmberAfStatus SetNull(chip::EndpointId endpoint) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType value; - Traits::SetNull(value); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::LaundryWasherMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value) -{ - if (value.IsNull()) - { - return SetNull(endpoint); - } - - return Set(endpoint, value.Value()); -} - -} // namespace StartUpMode - -namespace OnMode { - -EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable & value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::LaundryWasherMode::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status); - if (Traits::IsNullValue(temp)) - { - value.SetNull(); - } - else - { - value.SetNonNull() = Traits::StorageToWorking(temp); - } - return status; -} -EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) - { - return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::LaundryWasherMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -EmberAfStatus SetNull(chip::EndpointId endpoint) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType value; - Traits::SetNull(value); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::LaundryWasherMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value) -{ - if (value.IsNull()) - { - return SetNull(endpoint); - } - - return Set(endpoint, value.Value()); -} - -} // namespace OnMode - namespace FeatureMap { EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value) @@ -7194,151 +7057,6 @@ EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value) namespace RefrigeratorAndTemperatureControlledCabinetMode { namespace Attributes { -namespace CurrentMode { - -EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - EmberAfStatus status = - emberAfReadAttribute(endpoint, Clusters::RefrigeratorAndTemperatureControlledCabinetMode::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status); - if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) - { - return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; - } - *value = Traits::StorageToWorking(temp); - return status; -} -EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::RefrigeratorAndTemperatureControlledCabinetMode::Id, Id, writable, - ZCL_INT8U_ATTRIBUTE_TYPE); -} - -} // namespace CurrentMode - -namespace StartUpMode { - -EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable & value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - EmberAfStatus status = - emberAfReadAttribute(endpoint, Clusters::RefrigeratorAndTemperatureControlledCabinetMode::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status); - if (Traits::IsNullValue(temp)) - { - value.SetNull(); - } - else - { - value.SetNonNull() = Traits::StorageToWorking(temp); - } - return status; -} -EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) - { - return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::RefrigeratorAndTemperatureControlledCabinetMode::Id, Id, writable, - ZCL_INT8U_ATTRIBUTE_TYPE); -} - -EmberAfStatus SetNull(chip::EndpointId endpoint) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType value; - Traits::SetNull(value); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::RefrigeratorAndTemperatureControlledCabinetMode::Id, Id, writable, - ZCL_INT8U_ATTRIBUTE_TYPE); -} - -EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value) -{ - if (value.IsNull()) - { - return SetNull(endpoint); - } - - return Set(endpoint, value.Value()); -} - -} // namespace StartUpMode - -namespace OnMode { - -EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable & value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - EmberAfStatus status = - emberAfReadAttribute(endpoint, Clusters::RefrigeratorAndTemperatureControlledCabinetMode::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status); - if (Traits::IsNullValue(temp)) - { - value.SetNull(); - } - else - { - value.SetNonNull() = Traits::StorageToWorking(temp); - } - return status; -} -EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) - { - return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::RefrigeratorAndTemperatureControlledCabinetMode::Id, Id, writable, - ZCL_INT8U_ATTRIBUTE_TYPE); -} - -EmberAfStatus SetNull(chip::EndpointId endpoint) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType value; - Traits::SetNull(value); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::RefrigeratorAndTemperatureControlledCabinetMode::Id, Id, writable, - ZCL_INT8U_ATTRIBUTE_TYPE); -} - -EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value) -{ - if (value.IsNull()) - { - return SetNull(endpoint); - } - - return Set(endpoint, value.Value()); -} - -} // namespace OnMode - namespace FeatureMap { EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value) @@ -7493,212 +7211,7 @@ EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::LaundryWasherC return emberAfWriteAttribute(endpoint, Clusters::LaundryWasherControls::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE); } -} // namespace NumberOfRinses - -namespace FeatureMap { - -EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::LaundryWasherControls::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status); - if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) - { - return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; - } - *value = Traits::StorageToWorking(temp); - return status; -} -EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::LaundryWasherControls::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); -} - -} // namespace FeatureMap - -namespace ClusterRevision { - -EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::LaundryWasherControls::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status); - if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) - { - return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; - } - *value = Traits::StorageToWorking(temp); - return status; -} -EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::LaundryWasherControls::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); -} - -} // namespace ClusterRevision - -} // namespace Attributes -} // namespace LaundryWasherControls - -namespace RvcRunMode { -namespace Attributes { - -namespace CurrentMode { - -EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::RvcRunMode::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status); - if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) - { - return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; - } - *value = Traits::StorageToWorking(temp); - return status; -} -EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::RvcRunMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -} // namespace CurrentMode - -namespace StartUpMode { - -EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable & value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::RvcRunMode::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status); - if (Traits::IsNullValue(temp)) - { - value.SetNull(); - } - else - { - value.SetNonNull() = Traits::StorageToWorking(temp); - } - return status; -} -EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) - { - return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::RvcRunMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -EmberAfStatus SetNull(chip::EndpointId endpoint) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType value; - Traits::SetNull(value); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::RvcRunMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value) -{ - if (value.IsNull()) - { - return SetNull(endpoint); - } - - return Set(endpoint, value.Value()); -} - -} // namespace StartUpMode - -namespace OnMode { - -EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable & value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::RvcRunMode::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status); - if (Traits::IsNullValue(temp)) - { - value.SetNull(); - } - else - { - value.SetNonNull() = Traits::StorageToWorking(temp); - } - return status; -} -EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) - { - return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::RvcRunMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -EmberAfStatus SetNull(chip::EndpointId endpoint) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType value; - Traits::SetNull(value); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::RvcRunMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value) -{ - if (value.IsNull()) - { - return SetNull(endpoint); - } - - return Set(endpoint, value.Value()); -} - -} // namespace OnMode +} // namespace NumberOfRinses namespace FeatureMap { @@ -7707,7 +7220,7 @@ EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value) using Traits = NumericAttributeTraits; Traits::StorageType temp; uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::RvcRunMode::Id, Id, readable, sizeof(temp)); + EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::LaundryWasherControls::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -7726,7 +7239,7 @@ EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value) Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::RvcRunMode::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::LaundryWasherControls::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); } } // namespace FeatureMap @@ -7738,7 +7251,7 @@ EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value) using Traits = NumericAttributeTraits; Traits::StorageType temp; uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::RvcRunMode::Id, Id, readable, sizeof(temp)); + EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::LaundryWasherControls::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -7757,25 +7270,25 @@ EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value) Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::RvcRunMode::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::LaundryWasherControls::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } } // namespace ClusterRevision } // namespace Attributes -} // namespace RvcRunMode +} // namespace LaundryWasherControls -namespace RvcCleanMode { +namespace RvcRunMode { namespace Attributes { -namespace CurrentMode { +namespace FeatureMap { -EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value) +EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType temp; uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::RvcCleanMode::Id, Id, readable, sizeof(temp)); + EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::RvcRunMode::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -7784,9 +7297,9 @@ EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value) *value = Traits::StorageToWorking(temp); return status; } -EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value) +EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; @@ -7794,116 +7307,47 @@ EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value) Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::RvcCleanMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::RvcRunMode::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); } -} // namespace CurrentMode +} // namespace FeatureMap -namespace StartUpMode { +namespace ClusterRevision { -EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable & value) +EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType temp; uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::RvcCleanMode::Id, Id, readable, sizeof(temp)); + EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::RvcRunMode::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status); - if (Traits::IsNullValue(temp)) - { - value.SetNull(); - } - else - { - value.SetNonNull() = Traits::StorageToWorking(temp); - } - return status; -} -EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::RvcCleanMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -EmberAfStatus SetNull(chip::EndpointId endpoint) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType value; - Traits::SetNull(value); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::RvcCleanMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value) -{ - if (value.IsNull()) - { - return SetNull(endpoint); - } - - return Set(endpoint, value.Value()); -} - -} // namespace StartUpMode - -namespace OnMode { - -EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable & value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::RvcCleanMode::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status); - if (Traits::IsNullValue(temp)) - { - value.SetNull(); - } - else - { - value.SetNonNull() = Traits::StorageToWorking(temp); - } + *value = Traits::StorageToWorking(temp); return status; } -EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value) +EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value) { - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; } Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::RvcCleanMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -EmberAfStatus SetNull(chip::EndpointId endpoint) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType value; - Traits::SetNull(value); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::RvcCleanMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::RvcRunMode::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } -EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value) -{ - if (value.IsNull()) - { - return SetNull(endpoint); - } +} // namespace ClusterRevision - return Set(endpoint, value.Value()); -} +} // namespace Attributes +} // namespace RvcRunMode -} // namespace OnMode +namespace RvcCleanMode { +namespace Attributes { namespace FeatureMap { @@ -8357,143 +7801,6 @@ EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value) namespace DishwasherMode { namespace Attributes { -namespace CurrentMode { - -EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::DishwasherMode::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status); - if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) - { - return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; - } - *value = Traits::StorageToWorking(temp); - return status; -} -EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::DishwasherMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -} // namespace CurrentMode - -namespace StartUpMode { - -EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable & value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::DishwasherMode::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status); - if (Traits::IsNullValue(temp)) - { - value.SetNull(); - } - else - { - value.SetNonNull() = Traits::StorageToWorking(temp); - } - return status; -} -EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) - { - return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::DishwasherMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -EmberAfStatus SetNull(chip::EndpointId endpoint) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType value; - Traits::SetNull(value); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::DishwasherMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value) -{ - if (value.IsNull()) - { - return SetNull(endpoint); - } - - return Set(endpoint, value.Value()); -} - -} // namespace StartUpMode - -namespace OnMode { - -EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable & value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::DishwasherMode::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status); - if (Traits::IsNullValue(temp)) - { - value.SetNull(); - } - else - { - value.SetNonNull() = Traits::StorageToWorking(temp); - } - return status; -} -EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) - { - return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::DishwasherMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -EmberAfStatus SetNull(chip::EndpointId endpoint) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType value; - Traits::SetNull(value); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::DishwasherMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value) -{ - if (value.IsNull()) - { - return SetNull(endpoint); - } - - return Set(endpoint, value.Value()); -} - -} // namespace OnMode - namespace FeatureMap { EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value) diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h index badfc61960da7d..db0d78a387c052 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h @@ -1345,25 +1345,6 @@ EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value); namespace LaundryWasherMode { namespace Attributes { -namespace CurrentMode { -EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value); // int8u -EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value); -} // namespace CurrentMode - -namespace StartUpMode { -EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable & value); // int8u -EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value); -EmberAfStatus SetNull(chip::EndpointId endpoint); -EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value); -} // namespace StartUpMode - -namespace OnMode { -EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable & value); // int8u -EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value); -EmberAfStatus SetNull(chip::EndpointId endpoint); -EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value); -} // namespace OnMode - namespace FeatureMap { EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value); // bitmap32 EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value); @@ -1380,25 +1361,6 @@ EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value); namespace RefrigeratorAndTemperatureControlledCabinetMode { namespace Attributes { -namespace CurrentMode { -EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value); // int8u -EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value); -} // namespace CurrentMode - -namespace StartUpMode { -EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable & value); // int8u -EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value); -EmberAfStatus SetNull(chip::EndpointId endpoint); -EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value); -} // namespace StartUpMode - -namespace OnMode { -EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable & value); // int8u -EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value); -EmberAfStatus SetNull(chip::EndpointId endpoint); -EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value); -} // namespace OnMode - namespace FeatureMap { EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value); // bitmap32 EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value); @@ -1444,25 +1406,6 @@ EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value); namespace RvcRunMode { namespace Attributes { -namespace CurrentMode { -EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value); // int8u -EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value); -} // namespace CurrentMode - -namespace StartUpMode { -EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable & value); // int8u -EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value); -EmberAfStatus SetNull(chip::EndpointId endpoint); -EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value); -} // namespace StartUpMode - -namespace OnMode { -EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable & value); // int8u -EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value); -EmberAfStatus SetNull(chip::EndpointId endpoint); -EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value); -} // namespace OnMode - namespace FeatureMap { EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value); // bitmap32 EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value); @@ -1479,25 +1422,6 @@ EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value); namespace RvcCleanMode { namespace Attributes { -namespace CurrentMode { -EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value); // int8u -EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value); -} // namespace CurrentMode - -namespace StartUpMode { -EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable & value); // int8u -EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value); -EmberAfStatus SetNull(chip::EndpointId endpoint); -EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value); -} // namespace StartUpMode - -namespace OnMode { -EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable & value); // int8u -EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value); -EmberAfStatus SetNull(chip::EndpointId endpoint); -EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value); -} // namespace OnMode - namespace FeatureMap { EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value); // bitmap32 EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value); @@ -1586,25 +1510,6 @@ EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value); namespace DishwasherMode { namespace Attributes { -namespace CurrentMode { -EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value); // int8u -EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value); -} // namespace CurrentMode - -namespace StartUpMode { -EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable & value); // int8u -EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value); -EmberAfStatus SetNull(chip::EndpointId endpoint); -EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value); -} // namespace StartUpMode - -namespace OnMode { -EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable & value); // int8u -EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value); -EmberAfStatus SetNull(chip::EndpointId endpoint); -EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value); -} // namespace OnMode - namespace FeatureMap { EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value); // bitmap32 EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value); diff --git a/zzz_generated/app-common/app-common/zap-generated/callback.h b/zzz_generated/app-common/app-common/zap-generated/callback.h index 8c4d6baf4b51e3..3a0809697a120f 100644 --- a/zzz_generated/app-common/app-common/zap-generated/callback.h +++ b/zzz_generated/app-common/app-common/zap-generated/callback.h @@ -8741,43 +8741,12 @@ bool emberAfIcdManagementClusterStayActiveRequestCallback( bool emberAfModeSelectClusterChangeToModeCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::ModeSelect::Commands::ChangeToMode::DecodableType & commandData); -/** - * @brief Laundry Washer Mode Cluster ChangeToMode Command callback (from client) - */ -bool emberAfLaundryWasherModeClusterChangeToModeCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::LaundryWasherMode::Commands::ChangeToMode::DecodableType & commandData); -/** - * @brief Refrigerator And Temperature Controlled Cabinet Mode Cluster ChangeToMode Command callback (from client) - */ -bool emberAfRefrigeratorAndTemperatureControlledCabinetModeClusterChangeToModeCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::RefrigeratorAndTemperatureControlledCabinetMode::Commands::ChangeToMode::DecodableType & - commandData); -/** - * @brief RVC Run Mode Cluster ChangeToMode Command callback (from client) - */ -bool emberAfRvcRunModeClusterChangeToModeCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::RvcRunMode::Commands::ChangeToMode::DecodableType & commandData); -/** - * @brief RVC Clean Mode Cluster ChangeToMode Command callback (from client) - */ -bool emberAfRvcCleanModeClusterChangeToModeCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::RvcCleanMode::Commands::ChangeToMode::DecodableType & commandData); /** * @brief Temperature Control Cluster SetTemperature Command callback (from client) */ bool emberAfTemperatureControlClusterSetTemperatureCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::TemperatureControl::Commands::SetTemperature::DecodableType & commandData); -/** - * @brief Dishwasher Mode Cluster ChangeToMode Command callback (from client) - */ -bool emberAfDishwasherModeClusterChangeToModeCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::DishwasherMode::Commands::ChangeToMode::DecodableType & commandData); /** * @brief Smoke CO Alarm Cluster SelfTestRequest Command callback (from client) */