Add server implementation of temperature-control cluster. (#26566)

* Add server implementation of temperature-control cluster

* restyle and fixed typo

* Zap generated for all-clusters-app with temperature control server cluster

* Addressed review comments

* Addressed review comments and added supported-temperature-levels implemeatation

* Addressed review comments

* Create iterator to iterate over the supported-temperature-levels

* Restructure server implementation to match spec

* Addressed review comments

* Fix CI

* Restyled by gn

* restyle and fixed typo

* Zap generated for all-clusters-app with temperature control server cluster

* Addressed review comments

* Addressed review comments and added supported-temperature-levels implemeatation

* Addressed review comments

* Create iterator to iterate over the supported-temperature-levels

* Restructure server implementation to match spec

* Addressed review comments

* Fix CI

* Restyled by gn

* Apply suggestions from code review

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>

* Fix darwin and Linux REPL tests CI

---------

Co-authored-by: Restyled.io <commits@restyled.io>
Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>
diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter
index d743a03..b768860 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
@@ -2492,6 +2492,31 @@
   command ChangeToMode(ChangeToModeRequest): DefaultSuccess = 0;
 }
 
+/** Attributes and commands for configuring the temperature control, and reporting temperature. */
+server cluster TemperatureControl = 86 {
+  bitmap Feature : BITMAP32 {
+    kTemperatureNumber = 0x1;
+    kTemperatureLevel = 0x2;
+    kTemperatureStep = 0x4;
+  }
+
+  readonly attribute int8u selectedTemperatureLevel = 4;
+  readonly attribute char_string supportedTemperatureLevels[] = 5;
+  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 SetTemperatureRequest {
+    optional temperature targetTemperature = 0;
+    optional INT8U targetTemperatureLevel = 1;
+  }
+
+  command SetTemperature(SetTemperatureRequest): DefaultSuccess = 0;
+}
+
 /** Attributes and commands for configuring the Refrigerator alarm. */
 server cluster RefrigeratorAlarm = 87 {
   bitmap AlarmMap : BITMAP32 {
@@ -6645,6 +6670,17 @@
     ram      attribute manufacturerExtension default = 255;
   }
 
+  server cluster TemperatureControl {
+    ram      attribute selectedTemperatureLevel default = 0;
+    callback attribute supportedTemperatureLevels;
+    callback attribute generatedCommandList;
+    callback attribute acceptedCommandList;
+    callback attribute eventList;
+    callback attribute attributeList;
+    ram      attribute featureMap default = 2;
+    ram      attribute clusterRevision default = 1;
+  }
+
   server cluster RefrigeratorAlarm {
     emits event Notify;
     ram      attribute mask default = 1;
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 d4998f4..01261ac 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
@@ -18,17 +18,17 @@
   "package": [
     {
       "pathRelativity": "relativeToZap",
-      "path": "../../../src/app/zap-templates/app-templates.json",
-      "type": "gen-templates-json",
-      "version": "chip-v1"
-    },
-    {
-      "pathRelativity": "relativeToZap",
       "path": "../../../src/app/zap-templates/zcl/zcl-with-test-extensions.json",
       "type": "zcl-properties",
       "category": "matter",
       "version": 1,
       "description": "Matter SDK ZCL data with some extensions"
+    },
+    {
+      "pathRelativity": "relativeToZap",
+      "path": "../../../src/app/zap-templates/app-templates.json",
+      "type": "gen-templates-json",
+      "version": "chip-v1"
     }
   ],
   "endpointTypes": [
@@ -13522,12 +13522,22 @@
           ]
         },
         {
-          "name": "Refrigerator Alarm",
-          "code": 87,
+          "name": "Temperature Control",
+          "code": 86,
           "mfgCode": null,
-          "define": "REFRIGERATOR_ALARM_CLUSTER",
+          "define": "TEMPERATURE_CONTROL_CLUSTER",
           "side": "client",
           "enabled": 0,
+          "commands": [
+            {
+              "name": "SetTemperature",
+              "code": 0,
+              "mfgCode": null,
+              "source": "client",
+              "incoming": 1,
+              "outgoing": 1
+            }
+          ],
           "attributes": [
             {
               "name": "FeatureMap",
@@ -13564,6 +13574,208 @@
           ]
         },
         {
+          "name": "Temperature Control",
+          "code": 86,
+          "mfgCode": null,
+          "define": "TEMPERATURE_CONTROL_CLUSTER",
+          "side": "server",
+          "enabled": 1,
+          "attributes": [
+            {
+              "name": "TemperatureSetpoint",
+              "code": 0,
+              "mfgCode": null,
+              "side": "server",
+              "type": "temperature",
+              "included": 0,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "MinTemperature",
+              "code": 1,
+              "mfgCode": null,
+              "side": "server",
+              "type": "temperature",
+              "included": 0,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "MaxTemperature",
+              "code": 2,
+              "mfgCode": null,
+              "side": "server",
+              "type": "temperature",
+              "included": 0,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "Step",
+              "code": 3,
+              "mfgCode": null,
+              "side": "server",
+              "type": "temperature",
+              "included": 0,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "SelectedTemperatureLevel",
+              "code": 4,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int8u",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "0",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "SupportedTemperatureLevels",
+              "code": 5,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "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": "2",
+              "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 Alarm",
           "code": 87,
           "mfgCode": null,
diff --git a/examples/all-clusters-app/all-clusters-common/include/static-supported-temperature-levels.h b/examples/all-clusters-app/all-clusters-common/include/static-supported-temperature-levels.h
new file mode 100644
index 0000000..1ef9f1d
--- /dev/null
+++ b/examples/all-clusters-app/all-clusters-common/include/static-supported-temperature-levels.h
@@ -0,0 +1,64 @@
+/*
+ *
+ *    Copyright (c) 2023 Project CHIP Authors
+ *    All rights reserved.
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#pragma once
+
+#include <app/clusters/temperature-control-server/supported-temperature-levels-manager.h>
+#include <app/util/af.h>
+#include <zap-generated/gen_config.h>
+
+namespace chip {
+namespace app {
+namespace Clusters {
+namespace TemperatureControl {
+
+/**
+ * This implementation statically defines the options.
+ */
+
+class AppSupportedTemperatureLevelsDelegate : public SupportedTemperatureLevelsIteratorDelegate
+{
+    struct EndpointPair
+    {
+        EndpointId mEndpointId;
+        CharSpan * mTemperatureLevels;
+        uint8_t mSize;
+
+        EndpointPair(EndpointId aEndpointId, CharSpan * aTemperatureLevels, uint8_t aSize) :
+            mEndpointId(aEndpointId), mTemperatureLevels(aTemperatureLevels), mSize(aSize)
+        {}
+
+        ~EndpointPair() {}
+    };
+
+    static CharSpan temperatureLevelOptions[3];
+
+public:
+    static const EndpointPair supportedOptionsByEndpoints[EMBER_AF_TEMPERATURE_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT];
+
+    uint8_t Size() override;
+
+    CHIP_ERROR Next(MutableCharSpan & item) override;
+
+    ~AppSupportedTemperatureLevelsDelegate() {}
+};
+
+} // namespace TemperatureControl
+} // namespace Clusters
+} // namespace app
+} // namespace chip
diff --git a/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp b/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp
new file mode 100644
index 0000000..d5352ee
--- /dev/null
+++ b/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp
@@ -0,0 +1,69 @@
+/*
+ *
+ *    Copyright (c) 2023 Project CHIP Authors
+ *    All rights reserved.
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#include <static-supported-temperature-levels.h>
+#include <zap-generated/gen_config.h>
+
+using namespace std;
+using namespace chip;
+using namespace chip::app::Clusters;
+using namespace chip::app::Clusters::TemperatureControl;
+using chip::Protocols::InteractionModel::Status;
+
+// TODO: Configure your options for each endpoint
+CharSpan AppSupportedTemperatureLevelsDelegate::temperatureLevelOptions[] = { CharSpan("Hot", 3), CharSpan("Warm", 4),
+                                                                              CharSpan("Freezing", 8) };
+
+const AppSupportedTemperatureLevelsDelegate::EndpointPair AppSupportedTemperatureLevelsDelegate::supportedOptionsByEndpoints
+    [EMBER_AF_TEMPERATURE_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT] = {
+        EndpointPair(1, AppSupportedTemperatureLevelsDelegate::temperatureLevelOptions, 3) // Options for Endpoint 1
+    };
+
+uint8_t AppSupportedTemperatureLevelsDelegate::Size()
+{
+    for (auto & endpointPair : AppSupportedTemperatureLevelsDelegate::supportedOptionsByEndpoints)
+    {
+        if (endpointPair.mEndpointId == mEndpoint)
+        {
+            return endpointPair.mSize;
+        }
+    }
+    return 0;
+}
+
+CHIP_ERROR AppSupportedTemperatureLevelsDelegate::Next(MutableCharSpan & item)
+{
+    for (auto & endpointPair : AppSupportedTemperatureLevelsDelegate::supportedOptionsByEndpoints)
+    {
+        if (endpointPair.mEndpointId == mEndpoint)
+        {
+            if (endpointPair.mSize > mIndex)
+            {
+                CHIP_ERROR err = CopyCharSpanToMutableCharSpan(endpointPair.mTemperatureLevels[mIndex], item);
+                if (err != CHIP_NO_ERROR)
+                {
+                    ChipLogError(Zcl, "Error copying char span to mutable char span %s", ErrorStr(err));
+                    return err;
+                }
+                mIndex++;
+                return CHIP_NO_ERROR;
+            }
+        }
+    }
+    return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED;
+}
diff --git a/examples/all-clusters-app/ameba/chip_main.cmake b/examples/all-clusters-app/ameba/chip_main.cmake
index cbb4da6..7d6cecf 100755
--- a/examples/all-clusters-app/ameba/chip_main.cmake
+++ b/examples/all-clusters-app/ameba/chip_main.cmake
@@ -156,7 +156,7 @@
     ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp
     ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp
     ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp
-
+    ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp
     ${chip_dir}/examples/all-clusters-app/ameba/main/chipinterface.cpp
     ${chip_dir}/examples/all-clusters-app/ameba/main/BindingHandler.cpp
     ${chip_dir}/examples/all-clusters-app/ameba/main/DeviceCallbacks.cpp
diff --git a/examples/all-clusters-app/ameba/main/chipinterface.cpp b/examples/all-clusters-app/ameba/main/chipinterface.cpp
index 8f32c8d..55107d3 100644
--- a/examples/all-clusters-app/ameba/main/chipinterface.cpp
+++ b/examples/all-clusters-app/ameba/main/chipinterface.cpp
@@ -37,6 +37,7 @@
 #include <platform/CHIPDeviceLayer.h>
 #include <setup_payload/ManualSetupPayloadGenerator.h>
 #include <setup_payload/QRCodeSetupPayloadGenerator.h>
+#include <static-supported-temperature-levels.h>
 #include <support/CHIPMem.h>
 
 #if CONFIG_ENABLE_PW_RPC
@@ -60,6 +61,8 @@
 app::Clusters::NetworkCommissioning::Instance
     sWiFiNetworkCommissioningInstance(kNetworkCommissioningEndpointMain /* Endpoint Id */,
                                       &(NetworkCommissioning::AmebaWiFiDriver::GetInstance()));
+
+app::Clusters::TemperatureControl::AppSupportedTemperatureLevelsDelegate sAppSupportedTemperatureLevelsDelegate;
 } // namespace
 
 void NetWorkCommissioningInstInit()
@@ -141,6 +144,7 @@
 #if CONFIG_ENABLE_CHIP_SHELL
     InitBindingHandler();
 #endif
+    app::Clusters::TemperatureControl::SetInstance(&sAppSupportedTemperatureLevelsDelegate);
 }
 
 extern "C" void ChipTest(void)
diff --git a/examples/all-clusters-app/asr/BUILD.gn b/examples/all-clusters-app/asr/BUILD.gn
index 612c02d..a701ccf 100755
--- a/examples/all-clusters-app/asr/BUILD.gn
+++ b/examples/all-clusters-app/asr/BUILD.gn
@@ -74,6 +74,7 @@
     "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.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",
     "${examples_plat_dir}/ButtonHandler.cpp",
     "${examples_plat_dir}/CHIPDeviceManager.cpp",
     "${examples_plat_dir}/LEDWidget.cpp",
diff --git a/examples/all-clusters-app/asr/src/AppTask.cpp b/examples/all-clusters-app/asr/src/AppTask.cpp
index 3efb22f..3f16789 100755
--- a/examples/all-clusters-app/asr/src/AppTask.cpp
+++ b/examples/all-clusters-app/asr/src/AppTask.cpp
@@ -40,6 +40,7 @@
 #include <platform/CHIPDeviceLayer.h>
 #include <setup_payload/QRCodeSetupPayloadGenerator.h>
 #include <setup_payload/SetupPayload.h>
+#include <static-supported-temperature-levels.h>
 
 using namespace ::chip;
 using namespace ::chip::Credentials;
@@ -60,6 +61,7 @@
 app::Clusters::NetworkCommissioning::Instance
     sWiFiNetworkCommissioningInstance(kNetworkCommissioningEndpointMain /* Endpoint Id */,
                                       &(NetworkCommissioning::ASRWiFiDriver::GetInstance()));
+app::Clusters::TemperatureControl::AppSupportedTemperatureLevelsDelegate sAppSupportedTemperatureLevelsDelegate;
 } // namespace
 
 AppTask AppTask::sAppTask;
@@ -124,6 +126,8 @@
     PrintOnboardingCodes(chip::RendezvousInformationFlag(chip::RendezvousInformationFlag::kOnNetwork));
 #endif /* CONFIG_NETWORK_LAYER_BLE */
 
+    app::Clusters::TemperatureControl::SetInstance(&sAppSupportedTemperatureLevelsDelegate);
+
     return CHIP_NO_ERROR;
 }
 
diff --git a/examples/all-clusters-app/cc13x2x7_26x2x7/BUILD.gn b/examples/all-clusters-app/cc13x2x7_26x2x7/BUILD.gn
index c48a332..ff3cc6b 100644
--- a/examples/all-clusters-app/cc13x2x7_26x2x7/BUILD.gn
+++ b/examples/all-clusters-app/cc13x2x7_26x2x7/BUILD.gn
@@ -79,6 +79,7 @@
     "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.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/providers/DeviceInfoProviderImpl.cpp",
     "${project_dir}/main/AppTask.cpp",
     "${project_dir}/main/ClusterManager.cpp",
diff --git a/examples/all-clusters-app/cc13x2x7_26x2x7/main/AppTask.cpp b/examples/all-clusters-app/cc13x2x7_26x2x7/main/AppTask.cpp
index 871a5f7..2d5896a 100644
--- a/examples/all-clusters-app/cc13x2x7_26x2x7/main/AppTask.cpp
+++ b/examples/all-clusters-app/cc13x2x7_26x2x7/main/AppTask.cpp
@@ -30,6 +30,7 @@
 
 #include <DeviceInfoProviderImpl.h>
 #include <platform/CHIPDeviceLayer.h>
+#include <static-supported-temperature-levels.h>
 
 #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR
 #include <app/clusters/ota-requestor/BDXDownloader.h>
@@ -71,6 +72,10 @@
 
 constexpr EndpointId kNetworkCommissioningEndpointSecondary = 0xFFFE;
 
+namespace {
+app::Clusters::TemperatureControl::AppSupportedTemperatureLevelsDelegate sAppSupportedTemperatureLevelsDelegate;
+}
+
 #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR
 static DefaultOTARequestor sRequestorCore;
 static DefaultOTARequestorStorage sRequestorStorage;
@@ -270,6 +275,7 @@
     // QR code will be used with CHIP Tool
     PrintOnboardingCodes(RendezvousInformationFlags(RendezvousInformationFlag::kBLE));
 
+    app::Clusters::TemperatureControl::SetInstance(&sAppSupportedTemperatureLevelsDelegate);
     return 0;
 }
 
diff --git a/examples/all-clusters-app/cc13x4_26x4/BUILD.gn b/examples/all-clusters-app/cc13x4_26x4/BUILD.gn
index 4b15639..377ecad 100644
--- a/examples/all-clusters-app/cc13x4_26x4/BUILD.gn
+++ b/examples/all-clusters-app/cc13x4_26x4/BUILD.gn
@@ -79,6 +79,7 @@
     "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.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/providers/DeviceInfoProviderImpl.cpp",
     "${project_dir}/main/AppTask.cpp",
     "${project_dir}/main/ClusterManager.cpp",
diff --git a/examples/all-clusters-app/esp32/main/CMakeLists.txt b/examples/all-clusters-app/esp32/main/CMakeLists.txt
index af8eed1..ad90393 100644
--- a/examples/all-clusters-app/esp32/main/CMakeLists.txt
+++ b/examples/all-clusters-app/esp32/main/CMakeLists.txt
@@ -92,6 +92,7 @@
                       "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/pump-configuration-and-control-server"
                       "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/power-source-configuration-server"
                       "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/power-source-server"
+                      "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/temperature-control-server"
                       "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/time-synchronization-server"
                       "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/all-clusters-app/all-clusters-common/src"
 )
diff --git a/examples/all-clusters-app/esp32/main/main.cpp b/examples/all-clusters-app/esp32/main/main.cpp
index f3a593c..4ace2fb 100644
--- a/examples/all-clusters-app/esp32/main/main.cpp
+++ b/examples/all-clusters-app/esp32/main/main.cpp
@@ -42,6 +42,7 @@
 #include <credentials/examples/DeviceAttestationCredsExample.h>
 #include <examples/platform/esp32/mode-support/static-supported-modes-manager.h>
 #include <platform/ESP32/ESP32Utils.h>
+#include <static-supported-temperature-levels.h>
 
 #if CONFIG_HAVE_DISPLAY
 #include "DeviceWithDisplay.h"
@@ -96,6 +97,8 @@
 
 AppCallbacks sCallbacks;
 
+app::Clusters::TemperatureControl::AppSupportedTemperatureLevelsDelegate sAppSupportedTemperatureLevelsDelegate;
+
 constexpr EndpointId kNetworkCommissioningEndpointSecondary = 0xFFFE;
 
 #if CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
@@ -134,6 +137,8 @@
     {
         ESP_LOGE(TAG, "Failed to initialize endpoint array for supported-modes, err:%" CHIP_ERROR_FORMAT, err.Format());
     }
+
+    app::Clusters::TemperatureControl::SetInstance(&sAppSupportedTemperatureLevelsDelegate);
 }
 
 extern "C" void app_main()
diff --git a/examples/all-clusters-app/infineon/psoc6/BUILD.gn b/examples/all-clusters-app/infineon/psoc6/BUILD.gn
index b8cbc85..2e0da5d 100644
--- a/examples/all-clusters-app/infineon/psoc6/BUILD.gn
+++ b/examples/all-clusters-app/infineon/psoc6/BUILD.gn
@@ -110,6 +110,7 @@
     "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.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",
     "${examples_plat_dir}/LEDWidget.cpp",
     "${examples_plat_dir}/init_psoc6Platform.cpp",
     "src/AppTask.cpp",
diff --git a/examples/all-clusters-app/infineon/psoc6/src/AppTask.cpp b/examples/all-clusters-app/infineon/psoc6/src/AppTask.cpp
index 49a95ec..3fde24f 100644
--- a/examples/all-clusters-app/infineon/psoc6/src/AppTask.cpp
+++ b/examples/all-clusters-app/infineon/psoc6/src/AppTask.cpp
@@ -40,6 +40,7 @@
 #include <DeviceInfoProviderImpl.h>
 #include <app/clusters/network-commissioning/network-commissioning.h>
 #include <platform/Infineon/PSOC6/NetworkCommissioningDriver.h>
+#include <static-supported-temperature-levels.h>
 
 /* OTA related includes */
 #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR
@@ -95,6 +96,7 @@
 OTAImageProcessorImpl gImageProcessor;
 #endif
 
+chip::app::Clusters::TemperatureControl::AppSupportedTemperatureLevelsDelegate sAppSupportedTemperatureLevelsDelegate;
 } // namespace
 
 using namespace ::chip;
@@ -137,6 +139,7 @@
 #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR
     GetAppTask().InitOTARequestor();
 #endif
+    chip::app::Clusters::TemperatureControl::SetInstance(&sAppSupportedTemperatureLevelsDelegate);
 }
 
 CHIP_ERROR AppTask::StartAppTask()
diff --git a/examples/all-clusters-app/linux/BUILD.gn b/examples/all-clusters-app/linux/BUILD.gn
index 38f40b8..3e2f9c4 100644
--- a/examples/all-clusters-app/linux/BUILD.gn
+++ b/examples/all-clusters-app/linux/BUILD.gn
@@ -28,6 +28,7 @@
     "${chip_root}/examples/all-clusters-app/all-clusters-common/src/operational-state-delegates.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",
     "AllClustersCommandDelegate.cpp",
     "AppOptions.cpp",
     "WindowCoveringManager.cpp",
diff --git a/examples/all-clusters-app/linux/main-common.cpp b/examples/all-clusters-app/linux/main-common.cpp
index 48e8157..1616d98 100644
--- a/examples/all-clusters-app/linux/main-common.cpp
+++ b/examples/all-clusters-app/linux/main-common.cpp
@@ -31,6 +31,7 @@
 #include <platform/DeviceInstanceInfoProvider.h>
 #include <platform/DiagnosticDataProvider.h>
 #include <platform/PlatformManager.h>
+#include <static-supported-temperature-levels.h>
 #include <system/SystemPacketBuffer.h>
 #include <transport/SessionManager.h>
 #include <transport/raw/PeerAddress.h>
@@ -49,6 +50,7 @@
 AllClustersCommandDelegate sAllClustersCommandDelegate;
 chip::app::Clusters::WindowCovering::WindowCoveringManager sWindowCoveringManager;
 
+app::Clusters::TemperatureControl::AppSupportedTemperatureLevelsDelegate sAppSupportedTemperatureLevelsDelegate;
 } // namespace
 
 #ifdef EMBER_AF_PLUGIN_OPERATIONAL_STATE_SERVER
@@ -174,6 +176,7 @@
 #ifdef EMBER_AF_PLUGIN_OPERATIONAL_STATE_SERVER
     MatterOperationalStateServerInit();
 #endif
+    app::Clusters::TemperatureControl::SetInstance(&sAppSupportedTemperatureLevelsDelegate);
 }
 
 void ApplicationExit()
diff --git a/examples/all-clusters-app/mbed/CMakeLists.txt b/examples/all-clusters-app/mbed/CMakeLists.txt
index 32efe99..3b5e605 100644
--- a/examples/all-clusters-app/mbed/CMakeLists.txt
+++ b/examples/all-clusters-app/mbed/CMakeLists.txt
@@ -62,6 +62,7 @@
                ${ALL_CLUSTERS_COMMON}/src/bridged-actions-stub.cpp
                ${ALL_CLUSTERS_COMMON}/src/smco-stub.cpp
                ${ALL_CLUSTERS_COMMON}/src/static-supported-modes-manager.cpp
+               ${ALL_CLUSTERS_COMMON}/src/static-supported-temperature-levels.cpp
 )
 
 chip_configure_data_model(${APP_TARGET}
diff --git a/examples/all-clusters-app/mbed/main/AppTask.cpp b/examples/all-clusters-app/mbed/main/AppTask.cpp
index 53628a0..b497ea7 100644
--- a/examples/all-clusters-app/mbed/main/AppTask.cpp
+++ b/examples/all-clusters-app/mbed/main/AppTask.cpp
@@ -25,6 +25,7 @@
 #include <app/server/Server.h>
 #include <credentials/DeviceAttestationCredsProvider.h>
 #include <credentials/examples/DeviceAttestationCredsExample.h>
+#include <static-supported-temperature-levels.h>
 
 #include <lib/support/logging/CHIPLogging.h>
 
@@ -42,6 +43,10 @@
 using namespace ::chip::DeviceLayer;
 using namespace ::chip::Credentials;
 
+namespace {
+app::Clusters::TemperatureControl::AppSupportedTemperatureLevelsDelegate sAppSupportedTemperatureLevelsDelegate;
+}
+
 AppTask AppTask::sAppTask;
 
 int AppTask::Init()
@@ -84,7 +89,7 @@
         ChipLogError(NotSpecified, "DFU manager initialization failed: %s", error.AsString());
         return EXIT_FAILURE;
     }
-
+    app::Clusters::TemperatureControl::SetInstance(&sAppSupportedTemperatureLevelsDelegate);
     return 0;
 }
 
diff --git a/examples/all-clusters-app/nrfconnect/CMakeLists.txt b/examples/all-clusters-app/nrfconnect/CMakeLists.txt
index 7958228..7d38fe7 100644
--- a/examples/all-clusters-app/nrfconnect/CMakeLists.txt
+++ b/examples/all-clusters-app/nrfconnect/CMakeLists.txt
@@ -59,6 +59,7 @@
                main/ZclDoorLockCallbacks.cpp
                ${ALL_CLUSTERS_COMMON_DIR}/src/smco-stub.cpp
                ${ALL_CLUSTERS_COMMON_DIR}/src/static-supported-modes-manager.cpp
+               ${ALL_CLUSTERS_COMMON_DIR}/src/static-supported-temperature-levels.cpp
                ${ALL_CLUSTERS_COMMON_DIR}/src/bridged-actions-stub.cpp
                ${ALL_CLUSTERS_COMMON_DIR}/src/binding-handler.cpp
                ${NRFCONNECT_COMMON}/util/LEDWidget.cpp)
diff --git a/examples/all-clusters-app/nrfconnect/main/AppTask.cpp b/examples/all-clusters-app/nrfconnect/main/AppTask.cpp
index cb30872..4b837e0 100644
--- a/examples/all-clusters-app/nrfconnect/main/AppTask.cpp
+++ b/examples/all-clusters-app/nrfconnect/main/AppTask.cpp
@@ -32,6 +32,7 @@
 
 #include <credentials/DeviceAttestationCredsProvider.h>
 #include <credentials/examples/DeviceAttestationCredsExample.h>
+#include <static-supported-temperature-levels.h>
 
 #ifdef CONFIG_CHIP_WIFI
 #include <app/clusters/network-commissioning/network-commissioning.h>
@@ -83,6 +84,8 @@
 bool sIsNetworkEnabled     = false;
 bool sHaveBLEConnections   = false;
 
+app::Clusters::TemperatureControl::AppSupportedTemperatureLevelsDelegate sAppSupportedTemperatureLevelsDelegate;
+
 } // namespace
 
 namespace LedConsts {
@@ -218,6 +221,7 @@
         LOG_ERR("PlatformMgr().StartEventLoopTask() failed");
     }
 
+    app::Clusters::TemperatureControl::SetInstance(&sAppSupportedTemperatureLevelsDelegate);
     return err;
 }
 
diff --git a/examples/all-clusters-app/nxp/mw320/BUILD.gn b/examples/all-clusters-app/nxp/mw320/BUILD.gn
index da940a4..bd40e0f 100644
--- a/examples/all-clusters-app/nxp/mw320/BUILD.gn
+++ b/examples/all-clusters-app/nxp/mw320/BUILD.gn
@@ -68,6 +68,7 @@
   include_dirs = [
     "${chip_root}/src/platform/nxp/mw320",
     "${examples_plat_dir}/app/project_include",
+    "${chip_root}/src",
     "${chip_root}/src/app/util",
     "${chip_root}/examples/all-clusters-app/all-clusters-common/include",
     "${chip_root}/examples/all-clusters-app/nxp/mw320/include",
@@ -76,6 +77,7 @@
     "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.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}/src/lib/shell/streamer_mw320.cpp",
     "binding-handler.cpp",
     "include/CHIPProjectConfig.h",
diff --git a/examples/all-clusters-app/nxp/mw320/main.cpp b/examples/all-clusters-app/nxp/mw320/main.cpp
index b8b1fe8..8344be7 100644
--- a/examples/all-clusters-app/nxp/mw320/main.cpp
+++ b/examples/all-clusters-app/nxp/mw320/main.cpp
@@ -41,6 +41,7 @@
 #include <lib/support/logging/CHIPLogging.h>
 #include <platform/CHIPDeviceLayer.h>
 #include <setup_payload/QRCodeSetupPayloadGenerator.h>
+#include <static-supported-temperature-levels.h>
 
 #include <app/InteractionModelEngine.h>
 
@@ -119,6 +120,8 @@
 static struct wlan_network sta_network;
 static struct wlan_network uap_network;
 
+chip::app::Clusters::TemperatureControl::AppSupportedTemperatureLevelsDelegate sAppSupportedTemperatureLevelsDelegate;
+
 const int TASK_MAIN_PRIO         = OS_PRIO_3;
 const int TASK_MAIN_STACK_SIZE   = 800;
 portSTACK_TYPE * task_main_stack = NULL;
@@ -1079,6 +1082,8 @@
     InitBindingHandlers();
     // binding --
 
+    chip::app::Clusters::TemperatureControl::SetInstance(&sAppSupportedTemperatureLevelsDelegate);
+
     return;
 }
 
diff --git a/examples/all-clusters-app/telink/CMakeLists.txt b/examples/all-clusters-app/telink/CMakeLists.txt
index b05baa8..a3844c5 100644
--- a/examples/all-clusters-app/telink/CMakeLists.txt
+++ b/examples/all-clusters-app/telink/CMakeLists.txt
@@ -73,6 +73,7 @@
                src/ZclDoorLockCallbacks.cpp
                ${ALL_CLUSTERS_COMMON_DIR}/src/smco-stub.cpp
                ${ALL_CLUSTERS_COMMON_DIR}/src/static-supported-modes-manager.cpp
+               ${ALL_CLUSTERS_COMMON_DIR}/src/static-supported-temperature-levels.cpp
                ${ALL_CLUSTERS_COMMON_DIR}/src/bridged-actions-stub.cpp
                ${ALL_CLUSTERS_COMMON_DIR}/src/binding-handler.cpp
                ${TELINK_COMMON}/common/src/mainCommon.cpp
diff --git a/examples/all-clusters-app/tizen/BUILD.gn b/examples/all-clusters-app/tizen/BUILD.gn
index 3e7f1ed..94e841d 100644
--- a/examples/all-clusters-app/tizen/BUILD.gn
+++ b/examples/all-clusters-app/tizen/BUILD.gn
@@ -27,6 +27,7 @@
     "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.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",
   ]
 
   deps = [
diff --git a/examples/all-clusters-app/tizen/src/main.cpp b/examples/all-clusters-app/tizen/src/main.cpp
index adeb873..b7e3a50 100644
--- a/examples/all-clusters-app/tizen/src/main.cpp
+++ b/examples/all-clusters-app/tizen/src/main.cpp
@@ -22,6 +22,7 @@
 #include <app/clusters/network-commissioning/network-commissioning.h>
 #include <app/util/af.h>
 #include <platform/Tizen/NetworkCommissioningDriver.h>
+#include <static-supported-temperature-levels.h>
 
 #include <TizenServiceAppMain.h>
 #include <binding-handler.h>
@@ -37,6 +38,8 @@
 
 NetworkCommissioning::TizenEthernetDriver sEthernetDriver;
 Clusters::NetworkCommissioning::Instance sEthernetNetworkCommissioningInstance(kNetworkCommissioningEndpointMain, &sEthernetDriver);
+
+app::Clusters::TemperatureControl::AppSupportedTemperatureLevelsDelegate sAppSupportedTemperatureLevelsDelegate;
 } // namespace
 
 void ApplicationInit()
@@ -45,6 +48,7 @@
     emberAfEndpointEnableDisable(kNetworkCommissioningEndpointSecondary, false);
 
     sEthernetNetworkCommissioningInstance.Init();
+    app::Clusters::TemperatureControl::SetInstance(&sAppSupportedTemperatureLevelsDelegate);
 }
 
 int main(int argc, char * argv[])
diff --git a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter
index 9e5f678..fd0cb14 100644
--- a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter
+++ b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter
@@ -2081,6 +2081,31 @@
   command ChangeToMode(ChangeToModeRequest): DefaultSuccess = 0;
 }
 
+/** Attributes and commands for configuring the temperature control, and reporting temperature. */
+server cluster TemperatureControl = 86 {
+  bitmap Feature : BITMAP32 {
+    kTemperatureNumber = 0x1;
+    kTemperatureLevel = 0x2;
+    kTemperatureStep = 0x4;
+  }
+
+  readonly attribute int8u selectedTemperatureLevel = 4;
+  readonly attribute char_string supportedTemperatureLevels[] = 5;
+  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 SetTemperatureRequest {
+    optional temperature targetTemperature = 0;
+    optional INT8U targetTemperatureLevel = 1;
+  }
+
+  command SetTemperature(SetTemperatureRequest): DefaultSuccess = 0;
+}
+
 /** An interface to a generic way to secure a door */
 server cluster DoorLock = 257 {
   enum AlarmCodeEnum : ENUM8 {
@@ -4288,6 +4313,17 @@
     ram      attribute clusterRevision default = 1;
   }
 
+  server cluster TemperatureControl {
+    ram      attribute selectedTemperatureLevel default = 0;
+    callback attribute supportedTemperatureLevels;
+    callback attribute generatedCommandList;
+    callback attribute acceptedCommandList;
+    callback attribute eventList;
+    callback attribute attributeList;
+    ram      attribute featureMap default = 2;
+    ram      attribute clusterRevision default = 1;
+  }
+
   server cluster DoorLock {
     emits event DoorLockAlarm;
     emits event LockOperation;
diff --git a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.zap b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.zap
index 1ad1394..187c83d 100644
--- a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.zap
+++ b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.zap
@@ -18,17 +18,17 @@
   "package": [
     {
       "pathRelativity": "relativeToZap",
+      "path": "../../../src/app/zap-templates/app-templates.json",
+      "type": "gen-templates-json",
+      "version": "chip-v1"
+    },
+    {
+      "pathRelativity": "relativeToZap",
       "path": "../../../src/app/zap-templates/zcl/zcl.json",
       "type": "zcl-properties",
       "category": "matter",
       "version": 1,
       "description": "Matter SDK ZCL data"
-    },
-    {
-      "pathRelativity": "relativeToZap",
-      "path": "../../../src/app/zap-templates/app-templates.json",
-      "type": "gen-templates-json",
-      "version": "chip-v1"
     }
   ],
   "endpointTypes": [
@@ -12514,6 +12514,260 @@
           ]
         },
         {
+          "name": "Temperature Control",
+          "code": 86,
+          "mfgCode": null,
+          "define": "TEMPERATURE_CONTROL_CLUSTER",
+          "side": "client",
+          "enabled": 0,
+          "commands": [
+            {
+              "name": "SetTemperature",
+              "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": "Temperature Control",
+          "code": 86,
+          "mfgCode": null,
+          "define": "TEMPERATURE_CONTROL_CLUSTER",
+          "side": "server",
+          "enabled": 1,
+          "attributes": [
+            {
+              "name": "TemperatureSetpoint",
+              "code": 0,
+              "mfgCode": null,
+              "side": "server",
+              "type": "temperature",
+              "included": 0,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "1",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "MinTemperature",
+              "code": 1,
+              "mfgCode": null,
+              "side": "server",
+              "type": "temperature",
+              "included": 0,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "0",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "MaxTemperature",
+              "code": 2,
+              "mfgCode": null,
+              "side": "server",
+              "type": "temperature",
+              "included": 0,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "100",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "Step",
+              "code": 3,
+              "mfgCode": null,
+              "side": "server",
+              "type": "temperature",
+              "included": 0,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "SelectedTemperatureLevel",
+              "code": 4,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int8u",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "0",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "SupportedTemperatureLevels",
+              "code": 5,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "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": "2",
+              "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": "Door Lock",
           "code": 257,
           "mfgCode": null,
@@ -14869,7 +15123,7 @@
               "code": 0,
               "mfgCode": null,
               "side": "server",
-              "type": "FanModeType",
+              "type": "FanModeEnum",
               "included": 1,
               "storageOption": "RAM",
               "singleton": 0,
@@ -14885,7 +15139,7 @@
               "code": 1,
               "mfgCode": null,
               "side": "server",
-              "type": "FanModeSequenceType",
+              "type": "FanModeSequenceEnum",
               "included": 1,
               "storageOption": "RAM",
               "singleton": 0,
@@ -14901,7 +15155,7 @@
               "code": 2,
               "mfgCode": null,
               "side": "server",
-              "type": "int8u",
+              "type": "Percent",
               "included": 1,
               "storageOption": "RAM",
               "singleton": 0,
@@ -14917,7 +15171,7 @@
               "code": 3,
               "mfgCode": null,
               "side": "server",
-              "type": "int8u",
+              "type": "Percent",
               "included": 1,
               "storageOption": "RAM",
               "singleton": 0,
@@ -14981,7 +15235,7 @@
               "code": 7,
               "mfgCode": null,
               "side": "server",
-              "type": "bitmap8",
+              "type": "RockBitmap",
               "included": 0,
               "storageOption": "RAM",
               "singleton": 0,
@@ -14997,7 +15251,7 @@
               "code": 8,
               "mfgCode": null,
               "side": "server",
-              "type": "bitmap8",
+              "type": "RockBitmap",
               "included": 0,
               "storageOption": "RAM",
               "singleton": 0,
@@ -15013,7 +15267,7 @@
               "code": 9,
               "mfgCode": null,
               "side": "server",
-              "type": "bitmap8",
+              "type": "WindBitmap",
               "included": 0,
               "storageOption": "RAM",
               "singleton": 0,
@@ -15029,7 +15283,7 @@
               "code": 10,
               "mfgCode": null,
               "side": "server",
-              "type": "bitmap8",
+              "type": "WindBitmap",
               "included": 0,
               "storageOption": "RAM",
               "singleton": 0,
@@ -25132,5 +25386,6 @@
       "endpointVersion": 1,
       "deviceIdentifier": 61442
     }
-  ]
+  ],
+  "log": []
 }
\ No newline at end of file
diff --git a/examples/all-clusters-minimal-app/esp32/main/CMakeLists.txt b/examples/all-clusters-minimal-app/esp32/main/CMakeLists.txt
index 147719a9..e457bf2 100644
--- a/examples/all-clusters-minimal-app/esp32/main/CMakeLists.txt
+++ b/examples/all-clusters-minimal-app/esp32/main/CMakeLists.txt
@@ -64,6 +64,7 @@
                       "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/media-playback-server"
                       "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/ota-requestor"
                       "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/target-navigator-server"
+                      "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/temperature-control-server"
                       "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/thermostat-server"
                       "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/thermostat-user-interface-configuration-server"
                       "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/thread-network-diagnostics-server"
diff --git a/examples/darwin-framework-tool/templates/tests/ciTests.json b/examples/darwin-framework-tool/templates/tests/ciTests.json
index 6bbdca3..44d2eec 100644
--- a/examples/darwin-framework-tool/templates/tests/ciTests.json
+++ b/examples/darwin-framework-tool/templates/tests/ciTests.json
@@ -33,6 +33,8 @@
         "DL_LockUnlock",
         "Disabled due to OperationalState not being enabled in Matter.framework for now:",
         "TestOperationalState",
+        "Disabled due to TemperatureControl not being enabled in Matter.framework for now:",
+        "TestTemperatureControl",
         "Disabled due to using ICD Management (ICDManagement) cluster, which is provisional on Darwin for now:",
         "TestIcdManagementCluster",
         "Test_TC_ICDM_1_1",
diff --git a/examples/placeholder/linux/include/static-supported-temperature-levels.h b/examples/placeholder/linux/include/static-supported-temperature-levels.h
new file mode 100644
index 0000000..50739de
--- /dev/null
+++ b/examples/placeholder/linux/include/static-supported-temperature-levels.h
@@ -0,0 +1,64 @@
+/*
+ *
+ *    Copyright (c) 2023 Project CHIP Authors
+ *    All rights reserved.
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#pragma once
+
+#include <app/clusters/temperature-control-server/supported-temperature-levels-manager.h>
+#include <app/util/af.h>
+#include <app/util/config.h>
+
+namespace chip {
+namespace app {
+namespace Clusters {
+namespace TemperatureControl {
+
+/**
+ * This implementation statically defines the options.
+ */
+
+class AppSupportedTemperatureLevelsDelegate : public SupportedTemperatureLevelsIteratorDelegate
+{
+    struct EndpointPair
+    {
+        EndpointId mEndpointId;
+        CharSpan * mTemperatureLevels;
+        uint8_t mSize;
+
+        EndpointPair(EndpointId aEndpointId, CharSpan * aTemperatureLevels, uint8_t aSize) :
+            mEndpointId(aEndpointId), mTemperatureLevels(aTemperatureLevels), mSize(aSize)
+        {}
+
+        ~EndpointPair() {}
+    };
+
+    static CharSpan temperatureLevelOptions[3];
+
+public:
+    static const EndpointPair supportedOptionsByEndpoints[EMBER_AF_TEMPERATURE_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT];
+
+    uint8_t Size() override;
+
+    CHIP_ERROR Next(MutableCharSpan & item) override;
+
+    ~AppSupportedTemperatureLevelsDelegate() {}
+};
+
+} // namespace TemperatureControl
+} // namespace Clusters
+} // namespace app
+} // namespace chip
diff --git a/examples/placeholder/linux/static-supported-temperature-levels.cpp b/examples/placeholder/linux/static-supported-temperature-levels.cpp
new file mode 100644
index 0000000..38a560e
--- /dev/null
+++ b/examples/placeholder/linux/static-supported-temperature-levels.cpp
@@ -0,0 +1,70 @@
+/*
+ *
+ *    Copyright (c) 2023 Project CHIP Authors
+ *    All rights reserved.
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#include <app/util/config.h>
+#include <static-supported-temperature-levels.h>
+#include <zap-generated/gen_config.h>
+
+using namespace std;
+using namespace chip;
+using namespace chip::app::Clusters;
+using namespace chip::app::Clusters::TemperatureControl;
+using chip::Protocols::InteractionModel::Status;
+
+// TODO: Configure your options for each endpoint
+CharSpan AppSupportedTemperatureLevelsDelegate::temperatureLevelOptions[] = { CharSpan("Hot", 3), CharSpan("Warm", 4),
+                                                                              CharSpan("Cold", 4) };
+
+const AppSupportedTemperatureLevelsDelegate::EndpointPair AppSupportedTemperatureLevelsDelegate::supportedOptionsByEndpoints
+    [EMBER_AF_TEMPERATURE_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT] = {
+        EndpointPair(1, AppSupportedTemperatureLevelsDelegate::temperatureLevelOptions, 3) // Options for Endpoint 1
+    };
+
+uint8_t AppSupportedTemperatureLevelsDelegate::Size()
+{
+    for (auto & endpointPair : AppSupportedTemperatureLevelsDelegate::supportedOptionsByEndpoints)
+    {
+        if (endpointPair.mEndpointId == mEndpoint)
+        {
+            return endpointPair.mSize;
+        }
+    }
+    return 0;
+}
+
+CHIP_ERROR AppSupportedTemperatureLevelsDelegate::Next(MutableCharSpan & item)
+{
+    for (auto & endpointPair : AppSupportedTemperatureLevelsDelegate::supportedOptionsByEndpoints)
+    {
+        if (endpointPair.mEndpointId == mEndpoint)
+        {
+            if (endpointPair.mSize > mIndex)
+            {
+                CHIP_ERROR err = CopyCharSpanToMutableCharSpan(endpointPair.mTemperatureLevels[mIndex], item);
+                if (err != CHIP_NO_ERROR)
+                {
+                    ChipLogError(Zcl, "Error copying char span to mutable char span %s", ErrorStr(err));
+                    return err;
+                }
+                mIndex++;
+                return CHIP_NO_ERROR;
+            }
+        }
+    }
+    return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED;
+}
diff --git a/examples/shell/shell_common/BUILD.gn b/examples/shell/shell_common/BUILD.gn
index 67aaeb9..2cbc890 100644
--- a/examples/shell/shell_common/BUILD.gn
+++ b/examples/shell/shell_common/BUILD.gn
@@ -67,6 +67,7 @@
       "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.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",
     ]
 
     include_dirs =
diff --git a/src/app/chip_data_model.gni b/src/app/chip_data_model.gni
index b6aa8f6..7092359 100644
--- a/src/app/chip_data_model.gni
+++ b/src/app/chip_data_model.gni
@@ -210,6 +210,11 @@
           "${_app_root}/clusters/${cluster}/${cluster}.cpp",
           "${_app_root}/clusters/${cluster}/supported-modes-manager.h",
         ]
+      } else if (cluster == "temperature-control-server") {
+        sources += [
+          "${_app_root}/clusters/${cluster}/${cluster}.cpp",
+          "${_app_root}/clusters/${cluster}/supported-temperature-levels-manager.h",
+        ]
       } else if (cluster == "application-launcher-server") {
         sources += [
           "${_app_root}/app-platform/ContentApp.cpp",
diff --git a/src/app/clusters/temperature-control-server/supported-temperature-levels-manager.h b/src/app/clusters/temperature-control-server/supported-temperature-levels-manager.h
new file mode 100644
index 0000000..754be57
--- /dev/null
+++ b/src/app/clusters/temperature-control-server/supported-temperature-levels-manager.h
@@ -0,0 +1,63 @@
+/*
+ *
+ *    Copyright (c) 2023 Project CHIP Authors
+ *    All rights reserved.
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#pragma once
+
+#include <app-common/zap-generated/cluster-objects.h>
+#include <app/util/af-enums.h>
+#include <protocols/interaction_model/StatusCode.h>
+
+namespace chip {
+namespace app {
+namespace Clusters {
+namespace TemperatureControl {
+
+/**
+ * Interface to help manage the supported temperature levels of the Temperature Control Cluster.
+ */
+class SupportedTemperatureLevelsIteratorDelegate
+{
+public:
+    virtual ~SupportedTemperatureLevelsIteratorDelegate() = default;
+
+    SupportedTemperatureLevelsIteratorDelegate() {}
+
+    void Reset(EndpointId endpoint)
+    {
+        mEndpoint = endpoint;
+        mIndex    = 0;
+    }
+
+    // Returns total size of SupportedTemperatureLevels list.
+    virtual uint8_t Size() = 0;
+
+    virtual CHIP_ERROR Next(MutableCharSpan & item) = 0;
+
+protected:
+    EndpointId mEndpoint;
+    uint8_t mIndex;
+};
+
+SupportedTemperatureLevelsIteratorDelegate * GetInstance();
+
+void SetInstance(SupportedTemperatureLevelsIteratorDelegate * instance);
+
+} // namespace TemperatureControl
+} // namespace Clusters
+} // namespace app
+} // namespace chip
diff --git a/src/app/clusters/temperature-control-server/temperature-control-server.cpp b/src/app/clusters/temperature-control-server/temperature-control-server.cpp
new file mode 100644
index 0000000..16e2124
--- /dev/null
+++ b/src/app/clusters/temperature-control-server/temperature-control-server.cpp
@@ -0,0 +1,227 @@
+/**
+ *
+ *    Copyright (c) 2023 Project CHIP Authors
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ *
+ */
+
+#include <app-common/zap-generated/attributes/Accessors.h>
+#include <app-common/zap-generated/cluster-objects.h>
+#include <app/InteractionModelEngine.h>
+#include <app/clusters/temperature-control-server/supported-temperature-levels-manager.h>
+#include <app/util/attribute-storage.h>
+#include <app/util/error-mapping.h>
+
+using namespace chip;
+using namespace chip::app;
+using namespace chip::app::Clusters;
+using namespace chip::app::Clusters::TemperatureControl;
+using namespace chip::app::Clusters::TemperatureControl::Attributes;
+using namespace chip::DeviceLayer;
+using chip::Protocols::InteractionModel::Status;
+
+namespace {
+
+const uint8_t kMaxTemperatureLevelStringSize = 32;
+
+static SupportedTemperatureLevelsIteratorDelegate * sInstance = nullptr;
+
+class TemperatureControlAttrAccess : public AttributeAccessInterface
+{
+public:
+    // Register for the TemperatureControl cluster on all endpoints.
+    TemperatureControlAttrAccess() : AttributeAccessInterface(Optional<EndpointId>::Missing(), TemperatureControl::Id) {}
+
+    CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override;
+};
+
+} // namespace
+TemperatureControlAttrAccess gAttrAccess;
+
+namespace chip {
+namespace app {
+namespace Clusters {
+namespace TemperatureControl {
+
+SupportedTemperatureLevelsIteratorDelegate * GetInstance()
+{
+    return sInstance;
+}
+
+void SetInstance(SupportedTemperatureLevelsIteratorDelegate * instance)
+{
+    sInstance = instance;
+}
+
+} // namespace TemperatureControl
+} // namespace Clusters
+} // namespace app
+} // namespace chip
+
+CHIP_ERROR TemperatureControlAttrAccess::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder)
+{
+    CHIP_ERROR err = CHIP_NO_ERROR;
+    VerifyOrDie(aPath.mClusterId == TemperatureControl::Id);
+    if (TemperatureControl::Attributes::SupportedTemperatureLevels::Id == aPath.mAttributeId)
+    {
+        TemperatureControl::SupportedTemperatureLevelsIteratorDelegate * instance = TemperatureControl::GetInstance();
+        if (instance == nullptr)
+        {
+            aEncoder.EncodeEmptyList();
+            return CHIP_NO_ERROR;
+        }
+        instance->Reset(aPath.mEndpointId);
+        err = aEncoder.EncodeList([&](const auto & encoder) -> CHIP_ERROR {
+            char buffer[kMaxTemperatureLevelStringSize];
+            MutableCharSpan item(buffer);
+            while (instance->Next(item) == CHIP_NO_ERROR)
+            {
+                ReturnErrorOnFailure(encoder.Encode(item));
+                item = MutableCharSpan(buffer);
+            }
+            return CHIP_NO_ERROR;
+        });
+    }
+    return err;
+}
+
+bool TemperatureControlHasFeature(EndpointId endpoint, TemperatureControl::Feature feature)
+{
+    bool success;
+    uint32_t featureMap;
+    success = (Attributes::FeatureMap::Get(endpoint, &featureMap) == EMBER_ZCL_STATUS_SUCCESS);
+
+    return success ? ((featureMap & to_underlying(feature)) != 0) : false;
+}
+
+/**********************************************************
+ * Callbacks Implementation
+ *********************************************************/
+
+bool emberAfTemperatureControlClusterSetTemperatureCallback(app::CommandHandler * commandObj,
+                                                            const app::ConcreteCommandPath & commandPath,
+                                                            const Commands::SetTemperature::DecodableType & commandData)
+{
+    auto & targetTemperature      = commandData.targetTemperature;
+    auto & targetTemperatureLevel = commandData.targetTemperatureLevel;
+    EndpointId endpoint           = commandPath.mEndpointId;
+    Status status                 = Status::Success;
+    EmberAfStatus emberAfStatus   = EMBER_ZCL_STATUS_SUCCESS;
+
+    if (TemperatureControlHasFeature(endpoint, Feature::kTemperatureNumber) &&
+        TemperatureControlHasFeature(endpoint, Feature::kTemperatureLevel))
+    {
+        commandObj->AddStatus(commandPath, Status::Failure);
+        return false;
+    }
+    if (TemperatureControlHasFeature(endpoint, TemperatureControl::Feature::kTemperatureNumber))
+    {
+        if (targetTemperature.HasValue())
+        {
+            int16_t minTemperature = 0;
+            int16_t maxTemperature = 0;
+            emberAfStatus          = MinTemperature::Get(endpoint, &minTemperature);
+            if (emberAfStatus != EMBER_ZCL_STATUS_SUCCESS)
+            {
+                status = app::ToInteractionModelStatus(emberAfStatus);
+                goto exit;
+            }
+
+            emberAfStatus = MaxTemperature::Get(endpoint, &maxTemperature);
+            if (emberAfStatus != EMBER_ZCL_STATUS_SUCCESS)
+            {
+                status = app::ToInteractionModelStatus(emberAfStatus);
+                goto exit;
+            }
+
+            if (TemperatureControlHasFeature(endpoint, TemperatureControl::Feature::kTemperatureStep))
+            {
+                int16_t step  = 0;
+                emberAfStatus = Step::Get(endpoint, &step);
+                if (emberAfStatus != EMBER_ZCL_STATUS_SUCCESS)
+                {
+                    status = app::ToInteractionModelStatus(emberAfStatus);
+                    goto exit;
+                }
+
+                if ((targetTemperature.Value() - minTemperature) % step != 0)
+                {
+                    status = Status::ConstraintError;
+                    goto exit;
+                }
+            }
+            else
+            {
+                if (targetTemperature.Value() < minTemperature || targetTemperature.Value() > maxTemperature)
+                {
+                    status = Status::ConstraintError;
+                    goto exit;
+                }
+            }
+            emberAfStatus = TemperatureSetpoint::Set(endpoint, targetTemperature.Value());
+            if (emberAfStatus != EMBER_ZCL_STATUS_SUCCESS)
+            {
+                status = app::ToInteractionModelStatus(emberAfStatus);
+            }
+        }
+        else
+        {
+            status = Status::InvalidCommand;
+        }
+    }
+    if (TemperatureControlHasFeature(endpoint, TemperatureControl::Feature::kTemperatureLevel))
+    {
+        if (targetTemperatureLevel.HasValue())
+        {
+            TemperatureControl::SupportedTemperatureLevelsIteratorDelegate * instance = TemperatureControl::GetInstance();
+            if (instance == nullptr)
+            {
+                status = Status::NotFound;
+                goto exit;
+            }
+
+            instance->Reset(endpoint);
+
+            uint8_t size = instance->Size();
+
+            if (targetTemperatureLevel.Value() < size)
+            {
+                emberAfStatus = SelectedTemperatureLevel::Set(endpoint, targetTemperatureLevel.Value());
+                if (emberAfStatus != EMBER_ZCL_STATUS_SUCCESS)
+                {
+                    status = app::ToInteractionModelStatus(emberAfStatus);
+                }
+            }
+            else
+            {
+                status = Status::ConstraintError;
+            }
+        }
+        else
+        {
+            status = Status::InvalidCommand;
+        }
+    }
+exit:
+    commandObj->AddStatus(commandPath, status);
+
+    return true;
+}
+
+void emberAfTemperatureControlClusterServerInitCallback(EndpointId endpoint) {}
+
+void MatterTemperatureControlPluginServerInitCallback()
+{
+    registerAttributeAccessOverride(&gAttrAccess);
+}
diff --git a/src/app/tests/suites/TestTemperatureControl.yaml b/src/app/tests/suites/TestTemperatureControl.yaml
new file mode 100644
index 0000000..b7c2844
--- /dev/null
+++ b/src/app/tests/suites/TestTemperatureControl.yaml
@@ -0,0 +1,69 @@
+# Copyright (c) 2021 Project CHIP Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+name: Temperature Control Cluster Tests
+
+config:
+    nodeId: 0x12344321
+    cluster: "Temperature Control"
+    endpoint: 1
+
+tests:
+    - label: "Wait for the commissioned device to be retrieved"
+      cluster: "DelayCommands"
+      command: "WaitForCommissionee"
+      arguments:
+          values:
+              - name: "nodeId"
+                value: nodeId
+
+    - label: "Read supported temperature levels"
+      command: "readAttribute"
+      attribute: "SupportedTemperatureLevels"
+      response:
+          value: ["Hot", "Warm", "Freezing"]
+
+    - label: "Read selected temperature level"
+      command: "readAttribute"
+      attribute: "SelectedTemperatureLevel"
+      response:
+          value: 0
+
+    - label: "Set temperature level to different level"
+      command: "SetTemperature"
+      arguments:
+          values:
+              - name: "TargetTemperatureLevel"
+                value: 1
+
+    - label: "Read back selected temperature level"
+      command: "readAttribute"
+      attribute: "SelectedTemperatureLevel"
+      response:
+          value: 1
+
+    - label: "Set temperature level to different level"
+      command: "SetTemperature"
+      arguments:
+          values:
+              - name: "TargetTemperatureLevel"
+                value: 3
+      response:
+          error: CONSTRAINT_ERROR
+
+    - label: "Read back selected temperature level"
+      command: "readAttribute"
+      attribute: "SelectedTemperatureLevel"
+      response:
+          value: 1
diff --git a/src/app/tests/suites/ciTests.json b/src/app/tests/suites/ciTests.json
index 54cc604..d261ad0 100644
--- a/src/app/tests/suites/ciTests.json
+++ b/src/app/tests/suites/ciTests.json
@@ -244,6 +244,7 @@
         "TestIdentifyCluster",
         "TestOperationalCredentialsCluster",
         "TestModeSelectCluster",
+        "TestTemperatureControl",
         "TestSelfFabricRemoval",
         "TestSystemCommands",
         "TestBinding",
diff --git a/zzz_generated/chip-tool/zap-generated/test/Commands.h b/zzz_generated/chip-tool/zap-generated/test/Commands.h
index 5d4963b..6e36240 100644
--- a/zzz_generated/chip-tool/zap-generated/test/Commands.h
+++ b/zzz_generated/chip-tool/zap-generated/test/Commands.h
@@ -274,6 +274,7 @@
         printf("TestIdentifyCluster\n");
         printf("TestOperationalCredentialsCluster\n");
         printf("TestModeSelectCluster\n");
+        printf("TestTemperatureControl\n");
         printf("TestSelfFabricRemoval\n");
         printf("TestSystemCommands\n");
         printf("TestBinding\n");
@@ -85857,6 +85858,166 @@
     }
 };
 
+class TestTemperatureControlSuite : public TestCommand
+{
+public:
+    TestTemperatureControlSuite(CredentialIssuerCommands * credsIssuerConfig) :
+        TestCommand("TestTemperatureControl", 7, credsIssuerConfig)
+    {
+        AddArgument("nodeId", 0, UINT64_MAX, &mNodeId);
+        AddArgument("cluster", &mCluster);
+        AddArgument("endpoint", 0, UINT16_MAX, &mEndpoint);
+        AddArgument("timeout", 0, UINT16_MAX, &mTimeout);
+    }
+
+    ~TestTemperatureControlSuite() {}
+
+    chip::System::Clock::Timeout GetWaitDuration() const override
+    {
+        return chip::System::Clock::Seconds16(mTimeout.ValueOr(kTimeoutInSeconds));
+    }
+
+private:
+    chip::Optional<chip::NodeId> mNodeId;
+    chip::Optional<chip::CharSpan> mCluster;
+    chip::Optional<chip::EndpointId> mEndpoint;
+    chip::Optional<uint16_t> mTimeout;
+
+    chip::EndpointId GetEndpoint(chip::EndpointId endpoint) { return mEndpoint.HasValue() ? mEndpoint.Value() : endpoint; }
+
+    //
+    // Tests methods
+    //
+
+    void OnResponse(const chip::app::StatusIB & status, chip::TLV::TLVReader * data) override
+    {
+        bool shouldContinue = false;
+
+        switch (mTestIndex - 1)
+        {
+        case 0:
+            VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+            shouldContinue = true;
+            break;
+        case 1:
+            VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+            {
+                chip::app::DataModel::DecodableList<chip::CharSpan> value;
+                VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value)));
+                {
+                    auto iter_0 = value.begin();
+                    VerifyOrReturn(CheckNextListItemDecodes<decltype(value)>("supportedTemperatureLevels", iter_0, 0));
+                    VerifyOrReturn(
+                        CheckValueAsString("supportedTemperatureLevels[0]", iter_0.GetValue(), chip::CharSpan("Hot", 3)));
+                    VerifyOrReturn(CheckNextListItemDecodes<decltype(value)>("supportedTemperatureLevels", iter_0, 1));
+                    VerifyOrReturn(
+                        CheckValueAsString("supportedTemperatureLevels[1]", iter_0.GetValue(), chip::CharSpan("Warm", 4)));
+                    VerifyOrReturn(CheckNextListItemDecodes<decltype(value)>("supportedTemperatureLevels", iter_0, 2));
+                    VerifyOrReturn(
+                        CheckValueAsString("supportedTemperatureLevels[2]", iter_0.GetValue(), chip::CharSpan("Freezing", 8)));
+                    VerifyOrReturn(CheckNoMoreListItems<decltype(value)>("supportedTemperatureLevels", iter_0, 3));
+                }
+            }
+            break;
+        case 2:
+            VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+            {
+                uint8_t value;
+                VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value)));
+                VerifyOrReturn(CheckValue("selectedTemperatureLevel", value, 0U));
+            }
+            break;
+        case 3:
+            VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+            break;
+        case 4:
+            VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+            {
+                uint8_t value;
+                VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value)));
+                VerifyOrReturn(CheckValue("selectedTemperatureLevel", value, 1U));
+            }
+            break;
+        case 5:
+            VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), EMBER_ZCL_STATUS_CONSTRAINT_ERROR));
+            break;
+        case 6:
+            VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0));
+            {
+                uint8_t value;
+                VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value)));
+                VerifyOrReturn(CheckValue("selectedTemperatureLevel", value, 1U));
+            }
+            break;
+        default:
+            LogErrorOnFailure(ContinueOnChipMainThread(CHIP_ERROR_INVALID_ARGUMENT));
+        }
+
+        if (shouldContinue)
+        {
+            ContinueOnChipMainThread(CHIP_NO_ERROR);
+        }
+    }
+
+    CHIP_ERROR DoTestStep(uint16_t testIndex) override
+    {
+        using namespace chip::app::Clusters;
+        switch (testIndex)
+        {
+        case 0: {
+            LogStep(0, "Wait for the commissioned device to be retrieved");
+            ListFreer listFreer;
+            chip::app::Clusters::DelayCommands::Commands::WaitForCommissionee::Type value;
+            value.nodeId = mNodeId.HasValue() ? mNodeId.Value() : 305414945ULL;
+            return WaitForCommissionee(kIdentityAlpha, value);
+        }
+        case 1: {
+            LogStep(1, "Read supported temperature levels");
+            return ReadAttribute(kIdentityAlpha, GetEndpoint(1), TemperatureControl::Id,
+                                 TemperatureControl::Attributes::SupportedTemperatureLevels::Id, true, chip::NullOptional);
+        }
+        case 2: {
+            LogStep(2, "Read selected temperature level");
+            return ReadAttribute(kIdentityAlpha, GetEndpoint(1), TemperatureControl::Id,
+                                 TemperatureControl::Attributes::SelectedTemperatureLevel::Id, true, chip::NullOptional);
+        }
+        case 3: {
+            LogStep(3, "Set temperature level to different level");
+            ListFreer listFreer;
+            chip::app::Clusters::TemperatureControl::Commands::SetTemperature::Type value;
+            value.targetTemperatureLevel.Emplace();
+            value.targetTemperatureLevel.Value() = 1U;
+            return SendCommand(kIdentityAlpha, GetEndpoint(1), TemperatureControl::Id,
+                               TemperatureControl::Commands::SetTemperature::Id, value, chip::NullOptional
+
+            );
+        }
+        case 4: {
+            LogStep(4, "Read back selected temperature level");
+            return ReadAttribute(kIdentityAlpha, GetEndpoint(1), TemperatureControl::Id,
+                                 TemperatureControl::Attributes::SelectedTemperatureLevel::Id, true, chip::NullOptional);
+        }
+        case 5: {
+            LogStep(5, "Set temperature level to different level");
+            ListFreer listFreer;
+            chip::app::Clusters::TemperatureControl::Commands::SetTemperature::Type value;
+            value.targetTemperatureLevel.Emplace();
+            value.targetTemperatureLevel.Value() = 3U;
+            return SendCommand(kIdentityAlpha, GetEndpoint(1), TemperatureControl::Id,
+                               TemperatureControl::Commands::SetTemperature::Id, value, chip::NullOptional
+
+            );
+        }
+        case 6: {
+            LogStep(6, "Read back selected temperature level");
+            return ReadAttribute(kIdentityAlpha, GetEndpoint(1), TemperatureControl::Id,
+                                 TemperatureControl::Attributes::SelectedTemperatureLevel::Id, true, chip::NullOptional);
+        }
+        }
+        return CHIP_NO_ERROR;
+    }
+};
+
 class TestSelfFabricRemovalSuite : public TestCommand
 {
 public:
@@ -137875,6 +138036,7 @@
         make_unique<TestIdentifyClusterSuite>(credsIssuerConfig),
         make_unique<TestOperationalCredentialsClusterSuite>(credsIssuerConfig),
         make_unique<TestModeSelectClusterSuite>(credsIssuerConfig),
+        make_unique<TestTemperatureControlSuite>(credsIssuerConfig),
         make_unique<TestSelfFabricRemovalSuite>(credsIssuerConfig),
         make_unique<TestSystemCommandsSuite>(credsIssuerConfig),
         make_unique<TestBindingSuite>(credsIssuerConfig),