From 110082358565433bb5dc718b393bc16667a16a54 Mon Sep 17 00:00:00 2001
From: jmartinez-silabs <67972863+jmartinez-silabs@users.noreply.github.com>
Date: Tue, 15 Nov 2022 02:20:57 +0100
Subject: [PATCH] [Silabs] Update the efr32 Thermostat app (#23408)

* Update the efr32 Thermostat app, Use the temperature sensor when available, add a LCD UI for thermostat

* Address PR comments, Cleanup rebase and regen
---
 examples/platform/efr32/TemperatureSensor.cpp |  49 ++++
 examples/platform/efr32/TemperatureSensor.h   |  28 ++
 examples/platform/efr32/display/lcd.cpp       |  16 +-
 examples/platform/efr32/display/lcd.h         |   7 +-
 examples/thermostat/efr32/BUILD.gn            |  34 +++
 examples/thermostat/efr32/include/AppEvent.h  |   6 -
 examples/thermostat/efr32/include/AppTask.h   |  17 +-
 .../efr32/include/CHIPProjectConfig.h         |  10 +-
 .../thermostat/efr32/include/SensorManager.h  |  48 ++++
 .../efr32/include/TemperatureManager.h        |  69 +++++
 .../efr32/include/ThermostatIcons.h           | 218 +++++++++++++++
 .../thermostat/efr32/include/ThermostatUI.h   |  52 ++++
 examples/thermostat/efr32/src/AppTask.cpp     |  66 +++--
 .../thermostat/efr32/src/SensorManager.cpp    | 133 +++++++++
 .../efr32/src/TemperatureManager.cpp          | 149 ++++++++++
 .../thermostat/efr32/src/ThermostatUI.cpp     | 255 ++++++++++++++++++
 .../thermostat/efr32/src/ZclCallbacks.cpp     |  25 +-
 .../thermostat-common/thermostat.matter       |  54 ++--
 .../thermostat-common/thermostat.zap          | 211 ++++++++++++++-
 .../thermostat/zap-generated/access.h         |   6 +
 .../zap-generated/callback-stub.cpp           |   8 +
 .../zap-generated/endpoint_config.h           | 116 ++++----
 .../thermostat/zap-generated/gen_config.h     |  10 +-
 23 files changed, 1435 insertions(+), 152 deletions(-)
 create mode 100644 examples/platform/efr32/TemperatureSensor.cpp
 create mode 100644 examples/platform/efr32/TemperatureSensor.h
 create mode 100644 examples/thermostat/efr32/include/SensorManager.h
 create mode 100644 examples/thermostat/efr32/include/TemperatureManager.h
 create mode 100644 examples/thermostat/efr32/include/ThermostatIcons.h
 create mode 100644 examples/thermostat/efr32/include/ThermostatUI.h
 create mode 100644 examples/thermostat/efr32/src/SensorManager.cpp
 create mode 100644 examples/thermostat/efr32/src/TemperatureManager.cpp
 create mode 100644 examples/thermostat/efr32/src/ThermostatUI.cpp

diff --git a/examples/platform/efr32/TemperatureSensor.cpp b/examples/platform/efr32/TemperatureSensor.cpp
new file mode 100644
index 00000000000000..69ba106fd69872
--- /dev/null
+++ b/examples/platform/efr32/TemperatureSensor.cpp
@@ -0,0 +1,49 @@
+/*
+ *
+ *    Copyright (c) 2020 Project CHIP Authors
+ *    Copyright (c) 2019 Google LLC.
+ *    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 "TemperatureSensor.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+// This is a C implementation. Need the ifdef __cplusplus else we get linking issues
+#include "sl_sensor_rht.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+namespace TemperatureSensor {
+constexpr uint16_t kSensorTemperatureOffset = 800;
+
+sl_status_t Init()
+{
+    return sl_sensor_rht_init();
+}
+
+sl_status_t GetTemp(uint32_t * relativeHumidity, int16_t * temperature)
+{
+    // Sensor resolution 0.001 C
+    // DataModel resolution 0.01 C
+    int32_t temp;
+    sl_status_t status = sl_sensor_rht_get(relativeHumidity, &temp);
+    *temperature       = static_cast<int16_t>(temp / 10) - kSensorTemperatureOffset;
+    return status;
+}
+}; // namespace TemperatureSensor
diff --git a/examples/platform/efr32/TemperatureSensor.h b/examples/platform/efr32/TemperatureSensor.h
new file mode 100644
index 00000000000000..116287e9a37155
--- /dev/null
+++ b/examples/platform/efr32/TemperatureSensor.h
@@ -0,0 +1,28 @@
+/*
+ *
+ *    Copyright (c) 2020 Project CHIP Authors
+ *    Copyright (c) 2019 Google LLC.
+ *    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 "sl_status.h"
+#include <stdint.h>
+
+namespace TemperatureSensor {
+sl_status_t Init();
+sl_status_t GetTemp(uint32_t * relativeHumidity, int16_t * temperature);
+}; // namespace TemperatureSensor
diff --git a/examples/platform/efr32/display/lcd.cpp b/examples/platform/efr32/display/lcd.cpp
index e73770259358e8..8e6b38eb4ca0a8 100644
--- a/examples/platform/efr32/display/lcd.cpp
+++ b/examples/platform/efr32/display/lcd.cpp
@@ -135,8 +135,20 @@ void SilabsLCD::WriteDemoUI(bool state)
 void SilabsLCD::WriteDemoUI()
 {
     Clear();
-    demoUIClearMainScreen(mName);
-    demoUIDisplayApp(dState.mainState);
+    if (customUI != nullptr)
+    {
+        customUI(&glibContext);
+    }
+    else
+    {
+        demoUIClearMainScreen(mName);
+        demoUIDisplayApp(dState.mainState);
+    }
+}
+
+void SilabsLCD::SetCustomUI(customUICB cb)
+{
+    customUI = cb;
 }
 
 #ifdef QR_CODE_ENABLED
diff --git a/examples/platform/efr32/display/lcd.h b/examples/platform/efr32/display/lcd.h
index c9729e15d05de4..d375b7a133c9aa 100644
--- a/examples/platform/efr32/display/lcd.h
+++ b/examples/platform/efr32/display/lcd.h
@@ -33,12 +33,15 @@ class SilabsLCD
 {
 
 public:
+    typedef void (*customUICB)(GLIB_Context_t * context);
     CHIP_ERROR Init(uint8_t * name = nullptr, bool initialState = false);
     void * Context();
     int Clear(void);
     int DrawPixel(void * pContext, int32_t x, int32_t y);
     int Update(void);
     void WriteDemoUI(bool state);
+    void SetCustomUI(customUICB cb);
+
 #ifdef QR_CODE_ENABLED
     void SetQRCode(uint8_t * str, uint32_t size);
     void ShowQRCode(bool show, bool forceRefresh = false);
@@ -66,6 +69,6 @@ class SilabsLCD
 #else
     uint8_t mName[APP_NAME_MAX_LENGTH + 1];
 #endif
-
-        DemoState_t dState;
+        customUICB customUI = nullptr;
+    DemoState_t dState;
 };
diff --git a/examples/thermostat/efr32/BUILD.gn b/examples/thermostat/efr32/BUILD.gn
index da732a26122b1d..690023d185c835 100644
--- a/examples/thermostat/efr32/BUILD.gn
+++ b/examples/thermostat/efr32/BUILD.gn
@@ -33,6 +33,7 @@ assert(current_os == "freertos")
 
 efr32_project_dir = "${chip_root}/examples/thermostat/efr32"
 examples_plat_dir = "${chip_root}/examples/platform/efr32"
+efr32_sdk_root = "${chip_root}/third_party/silabs/gecko_sdk"
 
 declare_args() {
   # Dump memory usage at link time.
@@ -59,6 +60,10 @@ declare_args() {
 
   # Argument to Disable IPv4 for wifi(rs911)
   chip_enable_wifi_ipv4 = false
+
+  # Enable the temperature sensor
+  # Some boards do not have a temperature sensor
+  use_temp_sensor = silabs_board != "BRD2703A" && silabs_board != "BRD4319A"
 }
 
 declare_args() {
@@ -133,6 +138,7 @@ efr32_sdk("sdk") {
     "${efr32_project_dir}/include",
     "${examples_plat_dir}",
     "${chip_root}/src/lib",
+    "${efr32_sdk_root}/app/common/util/app_assert",
   ]
 
   defines = [
@@ -172,6 +178,18 @@ efr32_sdk("sdk") {
       defines += [ "SL_WFX_CONFIG_SCAN" ]
     }
   }
+  if (use_temp_sensor) {
+    include_dirs += [
+      "${efr32_sdk_root}/platform/driver/i2cspm/inc",
+      "${efr32_sdk_root}/app/bluetooth/common/sensor_rht",
+      "${efr32_sdk_root}/app/bluetooth/common/sensor_rht/config",
+      "${efr32_sdk_root}/hardware/driver/si70xx/inc",
+      "${efr32_sdk_root}/app/bluetooth/common/sensor_select",
+      "${efr32_sdk_root}/platform/common/config",
+    ]
+
+    defines += [ "USE_TEMP_SENSOR" ]
+  }
 }
 
 efr32_executable("thermostat_app") {
@@ -186,6 +204,8 @@ efr32_executable("thermostat_app") {
     "${examples_plat_dir}/init_efrPlatform.cpp",
     "${examples_plat_dir}/matter_config.cpp",
     "src/AppTask.cpp",
+    "src/SensorManager.cpp",
+    "src/TemperatureManager.cpp",
     "src/ZclCallbacks.cpp",
     "src/main.cpp",
   ]
@@ -194,6 +214,19 @@ efr32_executable("thermostat_app") {
     sources += [ "${examples_plat_dir}/LEDWidget.cpp" ]
   }
 
+  if (use_temp_sensor) {
+    sources += [
+      "${efr32_sdk_root}/app/bluetooth/common/sensor_rht/sl_sensor_rht.c",
+      "${efr32_sdk_root}/app/bluetooth/common/sensor_select/sl_sensor_select.c",
+      "${efr32_sdk_root}/hardware/driver/si70xx/src/sl_si70xx.c",
+      "${efr32_sdk_root}/platform/common/src/sl_status.c",
+      "${efr32_sdk_root}/platform/driver/i2cspm/src/sl_i2cspm.c",
+      "${efr32_sdk_root}/platform/emlib/src/em_i2c.c",
+      "${examples_plat_dir}/TemperatureSensor.cpp",
+      "${sdk_support_root}/matter/efr32/${silabs_family}/${silabs_board}/autogen/sl_i2cspm_init.c",
+    ]
+  }
+
   if (chip_enable_pw_rpc || chip_build_libshell || enable_openthread_cli ||
       use_wf200 || use_rs911x) {
     sources += [ "${examples_plat_dir}/uart.cpp" ]
@@ -268,6 +301,7 @@ efr32_executable("thermostat_app") {
     sources += [
       "${examples_plat_dir}/display/demo-ui.c",
       "${examples_plat_dir}/display/lcd.cpp",
+      "src/ThermostatUI.cpp",
     ]
     include_dirs += [ "${examples_plat_dir}/display" ]
     defines += [
diff --git a/examples/thermostat/efr32/include/AppEvent.h b/examples/thermostat/efr32/include/AppEvent.h
index 7a19b719edad25..d8d7de44079886 100644
--- a/examples/thermostat/efr32/include/AppEvent.h
+++ b/examples/thermostat/efr32/include/AppEvent.h
@@ -28,7 +28,6 @@ struct AppEvent
     {
         kEventType_Button = 0,
         kEventType_Timer,
-        kEventType_Light,
         kEventType_Install,
     };
 
@@ -44,11 +43,6 @@ struct AppEvent
         {
             void * Context;
         } TimerEvent;
-        struct
-        {
-            uint8_t Action;
-            int32_t Actor;
-        } LightEvent;
     };
 
     EventHandler Handler;
diff --git a/examples/thermostat/efr32/include/AppTask.h b/examples/thermostat/efr32/include/AppTask.h
index 800dda99ad37ac..ce4fa6f0fef43c 100644
--- a/examples/thermostat/efr32/include/AppTask.h
+++ b/examples/thermostat/efr32/include/AppTask.h
@@ -26,9 +26,15 @@
 #include <stdbool.h>
 #include <stdint.h>
 
+#ifdef DISPLAY_ENABLED
+#include "ThermostatUI.h"
+#endif
+
 #include "AppEvent.h"
 #include "BaseApplication.h"
 #include "FreeRTOS.h"
+#include "SensorManager.h"
+#include "TemperatureManager.h"
 #include "sl_simple_button_instances.h"
 #include "timers.h" // provides FreeRTOS timer support
 #include <app/clusters/identify-server/identify-server.h>
@@ -69,6 +75,11 @@ class AppTask : public BaseApplication
 
     CHIP_ERROR StartAppTask();
 
+    /**
+     * @brief Request an update of the Thermostat LCD UI
+     */
+    void UpdateThermoStatUI();
+
     /**
      * @brief Event handler when a button is pressed
      * Function posts an event for button processing
@@ -112,11 +123,5 @@ class AppTask : public BaseApplication
      */
     static void ButtonHandler(AppEvent * aEvent);
 
-    /**
-     * @brief PB1 Button event processing function
-     *        Function triggers a thermostat action sent to the CHIP task
-     *
-     * @param aEvent button event being processed
-     */
     static void ThermostatActionEventHandler(AppEvent * aEvent);
 };
diff --git a/examples/thermostat/efr32/include/CHIPProjectConfig.h b/examples/thermostat/efr32/include/CHIPProjectConfig.h
index 94c82dcbb0281d..35f6d54e785c70 100644
--- a/examples/thermostat/efr32/include/CHIPProjectConfig.h
+++ b/examples/thermostat/efr32/include/CHIPProjectConfig.h
@@ -57,7 +57,7 @@
  *
  * 0x8005: example lighting app
  */
-#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0x8004
+#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0x800E
 
 /**
  * CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION
@@ -97,6 +97,14 @@
  */
 #define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE 1
 
+/**
+ * CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC
+ *
+ * Enables synchronizing the device's real time clock with a remote Chip Time service
+ * using the Chip Time Sync protocol.
+ */
+#define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 0
+
 /**
  * CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER
  *
diff --git a/examples/thermostat/efr32/include/SensorManager.h b/examples/thermostat/efr32/include/SensorManager.h
new file mode 100644
index 00000000000000..9c910abb35881e
--- /dev/null
+++ b/examples/thermostat/efr32/include/SensorManager.h
@@ -0,0 +1,48 @@
+/*
+ *
+ *    Copyright (c) 2019 Google LLC.
+ *    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 <stdbool.h>
+#include <stdint.h>
+
+#include "AppEvent.h"
+
+#include "FreeRTOS.h"
+#include "timers.h" // provides FreeRTOS timer support
+#include <app-common/zap-generated/attributes/Accessors.h>
+#include <lib/core/CHIPError.h>
+
+class SensorManager
+{
+public:
+    CHIP_ERROR Init();
+
+private:
+    friend SensorManager & SensorMgr();
+
+    // Reads new generated sensor value, stores it, and updates local temperature attribute
+    static void SensorTimerEventHandler(TimerHandle_t xTimer);
+
+    static SensorManager sSensorManager;
+};
+
+inline SensorManager & SensorMgr()
+{
+    return SensorManager::sSensorManager;
+}
diff --git a/examples/thermostat/efr32/include/TemperatureManager.h b/examples/thermostat/efr32/include/TemperatureManager.h
new file mode 100644
index 00000000000000..1005a6753fe450
--- /dev/null
+++ b/examples/thermostat/efr32/include/TemperatureManager.h
@@ -0,0 +1,69 @@
+/*
+ *
+ *    Copyright (c) 2019 Google LLC.
+ *    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 <stdbool.h>
+#include <stdint.h>
+
+#include "AppEvent.h"
+
+#include "FreeRTOS.h"
+#include "timers.h" // provides FreeRTOS timer support
+#include <app-common/zap-generated/attributes/Accessors.h>
+
+#include <lib/core/CHIPError.h>
+
+using namespace chip;
+
+// AppCluster Spec Table 85.
+enum ThermMode
+{
+    OFF = 0,
+    AUTO,
+    NOT_USED,
+    COOL,
+    HEAT,
+};
+
+class TemperatureManager
+{
+public:
+    CHIP_ERROR Init();
+    void AttributeChangeHandler(EndpointId endpointId, AttributeId attributeId, uint8_t * value, uint16_t size);
+    uint8_t GetMode();
+    int8_t GetCurrentTemp();
+    int8_t GetHeatingSetPoint();
+    int8_t GetCoolingSetPoint();
+
+private:
+    friend TemperatureManager & TempMgr();
+
+    int8_t mCurrentTempCelsius;
+    int8_t mCoolingCelsiusSetPoint;
+    int8_t mHeatingCelsiusSetPoint;
+    uint8_t mThermMode;
+
+    int8_t ConvertToPrintableTemp(int16_t temperature);
+    static TemperatureManager sTempMgr;
+};
+
+inline TemperatureManager & TempMgr()
+{
+    return TemperatureManager::sTempMgr;
+}
diff --git a/examples/thermostat/efr32/include/ThermostatIcons.h b/examples/thermostat/efr32/include/ThermostatIcons.h
new file mode 100644
index 00000000000000..094775fa9f2141
--- /dev/null
+++ b/examples/thermostat/efr32/include/ThermostatIcons.h
@@ -0,0 +1,218 @@
+/*
+ *
+ *    Copyright (c) 2020 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
+
+#define SILABS_LOGO_WIDTH 47
+#define SILABS_LOGO_HEIGHT 18
+#define BLUETOOTH_ICON_SIZE 18
+
+// Status Icon defines
+#define STATUS_ICON_LINE 0
+#define SILABS_ICON_POSITION_X 0
+#define BLE_ICON_POSITION_X 72
+#define NETWORK_ICON_POSITION_X 90
+#define MATTER_ICON_POSITION_X 108
+
+// Heating/Cooling position
+#define HEATING_COOLING_X 90
+#define HEATING_COOLING_Y 40
+
+#define BLUETOOTH_ICON_SMALL                                                                                                       \
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0x7F, 0xFE, 0xEF, 0xF1, 0x7F, 0x9F, 0xFF, 0x7B, 0xFF, 0x1F, 0xFE, 0xFF, 0xFC, 0xFF,  \
+        0xF3, 0xFF, 0x87, 0xFF, 0xEF, 0xFD, 0xDF, 0xE7, 0xBF, 0xC7, 0xFF, 0x9F, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F
+
+#define SILABS_LOGO_SMALL                                                                                                          \
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F,  \
+        0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x80, 0x3F, 0xFF, 0xFF, 0xFF, 0x00, 0xE0, 0x9F, 0xFF, 0xE7, 0x3F, 0xE0, 0xF1, 0x83,    \
+        0xFF, 0xF9, 0xEF, 0xFF, 0x3F, 0xE0, 0x3F, 0xFC, 0xFF, 0xFF, 0x7F, 0xF8, 0x0F, 0xFC, 0xFF, 0xFF, 0x3F, 0xFE, 0x03, 0xFC,    \
+        0xFF, 0xF7, 0x9F, 0xFF, 0x81, 0x07, 0x02, 0xF8, 0xFF, 0xFF, 0xE0, 0x07, 0x00, 0xFE, 0xFF, 0xFF, 0xF8, 0x03, 0xC0, 0xFF,    \
+        0xFF, 0xFF, 0xFE, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0x3F
+
+#define HEATING_BITMAP                                                                                                             \
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF,  \
+        0x3F, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFE, 0x7F, 0xFC, 0x1F,    \
+        0x1F, 0xF8, 0xF8, 0x3F, 0x07, 0xE0, 0xFC, 0xBF, 0xC7, 0xE3, 0xFD, 0xFF, 0xE3, 0xC7, 0xFF, 0xFF, 0xF3, 0xCF, 0xFF, 0xFF,    \
+        0xF3, 0xCF, 0xFF, 0xFF, 0xF3, 0xCF, 0xFF, 0xFF, 0xF3, 0xCF, 0xFF, 0xFF, 0xE3, 0xC7, 0xFF, 0xBF, 0xC7, 0xE3, 0xFD, 0x3F,    \
+        0x07, 0xE0, 0xFC, 0x1F, 0x1F, 0xF8, 0xF8, 0x3F, 0xFE, 0x7F, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xBF, 0xFD, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+
+#define HEATING_WIDTH 32
+#define HEATING_HEIGHT 32
+
+#define COOLING_BITMAP                                                                                                             \
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0xFD, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF,  \
+        0x3F, 0xFC, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0x3F, 0x7F, 0xFE, 0xFC, 0x3F, 0x7F, 0xFE, 0xFC, 0x3F,    \
+        0x3E, 0x7C, 0xFC, 0x0F, 0x0C, 0x30, 0xF0, 0xCF, 0x80, 0x01, 0xF3, 0xFF, 0xE3, 0xC7, 0xFF, 0xFF, 0xF3, 0xCF, 0xFF, 0xFF,    \
+        0xF3, 0xCF, 0xFF, 0xFF, 0xF3, 0xCF, 0xFF, 0xFF, 0xF3, 0xCF, 0xFF, 0xFF, 0xE3, 0xC7, 0xFF, 0xCF, 0x80, 0x01, 0xF3, 0x0F,    \
+        0x0C, 0x30, 0xF0, 0x3F, 0x3E, 0x7C, 0xFC, 0x3F, 0x7F, 0xFE, 0xFC, 0x3F, 0x7F, 0xFE, 0xFC, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF,    \
+        0x7F, 0xFE, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0xBF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+
+#define HEATING_COOLING_BITMAP                                                                                                     \
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFC, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF,  \
+        0xFC, 0xE0, 0xFF, 0xFF, 0xFC, 0xF9, 0xF7, 0x7F, 0xFC, 0xF8, 0xF3, 0x1F, 0xFC, 0xFC, 0xF9, 0x1F, 0x78, 0xFC, 0xFC, 0xFF,    \
+        0x01, 0x7C, 0xFE, 0xFF, 0x03, 0x3C, 0xFF, 0xFF, 0xE3, 0x9F, 0xFF, 0xFF, 0xF3, 0x8F, 0xF3, 0xFF, 0xF3, 0x87, 0xE3, 0xFF,    \
+        0xF3, 0x83, 0xF7, 0xC7, 0xF0, 0x01, 0xF7, 0x07, 0xF0, 0x00, 0xFF, 0x0F, 0x7F, 0x00, 0xFF, 0xCF, 0x3F, 0x80, 0xFF, 0xCF,    \
+        0x1F, 0x80, 0xFF, 0xFF, 0x0F, 0xC0, 0xFF, 0xFF, 0x07, 0xE0, 0xFD, 0xFF, 0xF3, 0xF8, 0xFD, 0xFF, 0xF9, 0xFF, 0xFC, 0xFF,    \
+        0xFC, 0x3F, 0xFC, 0x7F, 0xDE, 0xFF, 0xFF, 0x3F, 0x1F, 0xFE, 0xFF, 0xFF, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+
+#define COOLING_WIDTH 32
+#define COOLING_HEIGHT 32
+
+// Font for temperature
+#define CELSIUS_INDEX 2320
+#define FAHRENHEIT_INDEX 2370
+#define DEGREE_INDEX 2420
+
+#define MONACO_FONT_WIDTH 29
+#define MONACO_FONT_NB_LENGTH 232
+#define MONACO_FONT_CH_LENGTH 50
+
+#define MONACO_48PT                                                                                                                \
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFC, 0xFF, 0xFF,    \
+        0x00, 0xF0, 0xFF, 0x7F, 0x00, 0xC0, 0xFF, 0x3F, 0x00, 0x80, 0xFF, 0x1F, 0x60, 0x00, 0xFF, 0x1F, 0xF8, 0x03, 0xFF, 0x0F,    \
+        0xFC, 0x07, 0xFE, 0x07, 0xFE, 0x07, 0xFE, 0x07, 0xFE, 0x07, 0xFC, 0x07, 0xFF, 0x03, 0xFC, 0x03, 0xFF, 0x03, 0xFC, 0x03,    \
+        0xFF, 0x01, 0xF8, 0x83, 0xFF, 0x00, 0xF8, 0x83, 0xFF, 0x00, 0xF8, 0x83, 0x7F, 0x30, 0xF8, 0x83, 0x3F, 0x30, 0xF8, 0x83,    \
+        0x3F, 0x38, 0xF8, 0x81, 0x1F, 0x3C, 0xF8, 0x81, 0x0F, 0x3C, 0xF8, 0x81, 0x0F, 0x3E, 0xF8, 0x81, 0x07, 0x3E, 0xF8, 0x81,    \
+        0x07, 0x3F, 0xF8, 0x83, 0x83, 0x3F, 0xF8, 0x83, 0x81, 0x3F, 0xF8, 0x83, 0xC1, 0x3F, 0xF8, 0x83, 0xE0, 0x1F, 0xF8, 0x03,    \
+        0xE0, 0x1F, 0xF8, 0x03, 0xF0, 0x1F, 0xF8, 0x03, 0xF8, 0x1F, 0xFC, 0x07, 0xF8, 0x0F, 0xFC, 0x07, 0xFC, 0x0F, 0xFC, 0x07,    \
+        0xFC, 0x07, 0xFE, 0x0F, 0xFC, 0x07, 0xFE, 0x0F, 0xF8, 0x03, 0xFF, 0x1F, 0xE0, 0x00, 0xFF, 0x3F, 0x00, 0x80, 0xFF, 0x7F,    \
+        0x00, 0xC0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x03, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* Character 0x30 (48: '0')*/                            \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0x0F, 0xFC, 0xFF, 0xFF, 0x07, 0xFC, 0xFF, 0xFF, 0x03, 0xFC, 0xFF, 0xFF, 0x00, 0xFC, 0xFF, 0x3F, 0x00, 0xFC, 0xFF,    \
+        0x1F, 0x00, 0xFC, 0xFF, 0x0F, 0x10, 0xFC, 0xFF, 0x0F, 0x1C, 0xFC, 0xFF, 0x0F, 0x1E, 0xFC, 0xFF, 0xCF, 0x1F, 0xFC, 0xFF,    \
+        0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF,    \
+        0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF,    \
+        0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF,    \
+        0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF,    \
+        0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0x0F, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xF8,    \
+        0x0F, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* Character 0x31 (49: '1')*/                      \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xF8, 0xFF,    \
+        0x3F, 0x00, 0xC0, 0xFF, 0x0F, 0x00, 0x80, 0xFF, 0x0F, 0x00, 0x00, 0xFF, 0x0F, 0xF8, 0x00, 0xFF, 0x0F, 0xFF, 0x03, 0xFE,    \
+        0xEF, 0xFF, 0x07, 0xFE, 0xFF, 0xFF, 0x0F, 0xFE, 0xFF, 0xFF, 0x0F, 0xFE, 0xFF, 0xFF, 0x0F, 0xFE, 0xFF, 0xFF, 0x0F, 0xFE,    \
+        0xFF, 0xFF, 0x07, 0xFE, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF,    \
+        0xFF, 0x7F, 0xC0, 0xFF, 0xFF, 0x3F, 0xE0, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF, 0x07, 0xFC, 0xFF,    \
+        0xFF, 0x03, 0xFE, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0x7F, 0xE0, 0xFF, 0xFF,    \
+        0x3F, 0xF0, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0x0F, 0xFC, 0xFF, 0xFF, 0x0F, 0xFE, 0xFF, 0xFF,    \
+        0x0F, 0xFE, 0xFF, 0xFF, 0x07, 0xFE, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x00, 0xFC, 0x07, 0x00, 0x00, 0xFC,    \
+        0x07, 0x00, 0x00, 0xFC, 0x07, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* Character 0x32 (50: '2')*/                      \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFE, 0xFF,    \
+        0x0F, 0x00, 0xF0, 0xFF, 0x0F, 0x00, 0xC0, 0xFF, 0x0F, 0x00, 0xC0, 0xFF, 0x0F, 0x7C, 0x80, 0xFF, 0x8F, 0xFF, 0x01, 0xFF,    \
+        0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0x07, 0xFF,    \
+        0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0x7F, 0xC0, 0xFF, 0xFF, 0x07, 0xE0, 0xFF,    \
+        0x7F, 0x00, 0xF0, 0xFF, 0x7F, 0x00, 0xF8, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x80, 0xFF, 0xFF, 0x7F, 0x00, 0xFF,    \
+        0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0x07, 0xFE, 0xFF, 0xFF, 0x07, 0xFE, 0xFF, 0xFF, 0x0F, 0xFC, 0xFF, 0xFF, 0x0F, 0xFC,    \
+        0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0x0F, 0xFC, 0xFF, 0xFF, 0x0F, 0xFC, 0xFF, 0xFF, 0x0F, 0xFC,    \
+        0xFF, 0xFF, 0x07, 0xFE, 0xF7, 0xFF, 0x07, 0xFE, 0x87, 0xFF, 0x01, 0xFF, 0x07, 0x7C, 0x80, 0xFF, 0x07, 0x00, 0xC0, 0xFF,    \
+        0x07, 0x00, 0xE0, 0xFF, 0x0F, 0x00, 0xF0, 0xFF, 0x7F, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* Character 0x33 (51: '3')*/                      \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0x7F, 0xE0, 0xFF, 0xFF, 0x7F, 0xE0, 0xFF, 0xFF, 0x3F, 0xE0, 0xFF, 0xFF, 0x1F, 0xE0, 0xFF,    \
+        0xFF, 0x1F, 0xE0, 0xFF, 0xFF, 0x0F, 0xE0, 0xFF, 0xFF, 0x07, 0xE0, 0xFF, 0xFF, 0x07, 0xE0, 0xFF, 0xFF, 0x83, 0xE0, 0xFF,    \
+        0xFF, 0x81, 0xE0, 0xFF, 0xFF, 0xC0, 0xE0, 0xFF, 0xFF, 0xE0, 0xE0, 0xFF, 0x7F, 0xE0, 0xE0, 0xFF, 0x3F, 0xF0, 0xE0, 0xFF,    \
+        0x3F, 0xF8, 0xE0, 0xFF, 0x1F, 0xF8, 0xE0, 0xFF, 0x0F, 0xFC, 0xE0, 0xFF, 0x0F, 0xFE, 0xE0, 0xFF, 0x07, 0xFE, 0xE0, 0xFF,    \
+        0x03, 0xFF, 0xE0, 0xFF, 0x83, 0xFF, 0xE0, 0xFF, 0x81, 0xFF, 0xC0, 0xFF, 0x01, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0xF0,    \
+        0x01, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0xF0, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF,    \
+        0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF,    \
+        0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* Character 0x34 (52: '4')*/                      \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0x0F, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x00, 0xFE,    \
+        0x0F, 0xFE, 0xFF, 0xFF, 0x0F, 0xFE, 0xFF, 0xFF, 0x0F, 0xFE, 0xFF, 0xFF, 0x0F, 0xFE, 0xFF, 0xFF, 0x0F, 0xFE, 0xFF, 0xFF,    \
+        0x0F, 0xFE, 0xFF, 0xFF, 0x0F, 0xFE, 0xFF, 0xFF, 0x0F, 0xFE, 0xFF, 0xFF, 0x0F, 0xC0, 0xFF, 0xFF, 0x0F, 0x00, 0xFC, 0xFF,    \
+        0x0F, 0x00, 0xF0, 0xFF, 0x0F, 0x00, 0xC0, 0xFF, 0x0F, 0x00, 0x80, 0xFF, 0xFF, 0x0F, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFE,    \
+        0xFF, 0xFF, 0x03, 0xFE, 0xFF, 0xFF, 0x07, 0xFE, 0xFF, 0xFF, 0x07, 0xFC, 0xFF, 0xFF, 0x0F, 0xFC, 0xFF, 0xFF, 0x0F, 0xFC,    \
+        0xFF, 0xFF, 0x0F, 0xFC, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0x0F, 0xFC, 0xFF, 0xFF, 0x0F, 0xFC, 0xFF, 0xFF, 0x0F, 0xFC,    \
+        0xFF, 0xFF, 0x07, 0xFE, 0xEF, 0xFF, 0x03, 0xFE, 0x07, 0xFF, 0x00, 0xFF, 0x07, 0x00, 0x80, 0xFF, 0x07, 0x00, 0xC0, 0xFF,    \
+        0x07, 0x00, 0xE0, 0xFF, 0x0F, 0x00, 0xF0, 0xFF, 0xFF, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* Character 0x35 (53: '5')*/                      \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xC0, 0xFF,    \
+        0xFF, 0x07, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0xFE, 0xFF, 0x00, 0x00, 0xFE, 0x7F, 0x80, 0x07, 0xFE, 0x3F, 0xE0, 0x7F, 0xFE,    \
+        0x1F, 0xF0, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x0F, 0xFC, 0xFF, 0xFF, 0x0F, 0xFE, 0xFF, 0xFF, 0x07, 0xFE, 0xFF, 0xFF,    \
+        0x07, 0xFE, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0x03, 0x0F, 0xE0, 0xFF,    \
+        0x83, 0x03, 0x80, 0xFF, 0x83, 0x01, 0x00, 0xFF, 0x83, 0x00, 0x00, 0xFE, 0x03, 0xC0, 0x07, 0xFC, 0x03, 0xF0, 0x0F, 0xFC,    \
+        0x03, 0xF8, 0x1F, 0xF8, 0x03, 0xFC, 0x3F, 0xF8, 0x03, 0xFC, 0x3F, 0xF8, 0x07, 0xFE, 0x3F, 0xF8, 0x07, 0xFE, 0x3F, 0xF8,    \
+        0x07, 0xFE, 0x3F, 0xF8, 0x07, 0xFE, 0x3F, 0xF8, 0x07, 0xFE, 0x3F, 0xF8, 0x0F, 0xFE, 0x3F, 0xF8, 0x0F, 0xFC, 0x1F, 0xF8,    \
+        0x0F, 0xFC, 0x1F, 0xFC, 0x1F, 0xF8, 0x0F, 0xFC, 0x1F, 0xF0, 0x07, 0xFE, 0x3F, 0xC0, 0x01, 0xFE, 0x7F, 0x00, 0x00, 0xFF,    \
+        0xFF, 0x00, 0x80, 0xFF, 0xFF, 0x01, 0xE0, 0xFF, 0xFF, 0x07, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* Character 0x36 (54: '6')*/                      \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0x0F, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xF8,    \
+        0xFF, 0xFF, 0x3F, 0xF8, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0x0F, 0xFE, 0xFF, 0xFF, 0x0F, 0xFE,    \
+        0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF,    \
+        0xFF, 0x7F, 0xE0, 0xFF, 0xFF, 0x3F, 0xF0, 0xFF, 0xFF, 0x3F, 0xF8, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0x0F, 0xFC, 0xFF,    \
+        0xFF, 0x07, 0xFE, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xFF, 0x81, 0xFF, 0xFF,    \
+        0xFF, 0xC1, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0x7F, 0xE0, 0xFF, 0xFF,    \
+        0x7F, 0xE0, 0xFF, 0xFF, 0x7F, 0xE0, 0xFF, 0xFF, 0x7F, 0xE0, 0xFF, 0xFF, 0x7F, 0xE0, 0xFF, 0xFF, 0x7F, 0xF0, 0xFF, 0xFF,    \
+        0x7F, 0xF0, 0xFF, 0xFF, 0x7F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* Character 0x37 (55: '7')*/                      \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF,    \
+        0xFF, 0x01, 0xE0, 0xFF, 0xFF, 0x00, 0x80, 0xFF, 0x7F, 0x00, 0x80, 0xFF, 0x3F, 0xE0, 0x00, 0xFF, 0x3F, 0xF8, 0x03, 0xFF,    \
+        0x1F, 0xFC, 0x07, 0xFE, 0x1F, 0xFC, 0x0F, 0xFE, 0x1F, 0xFC, 0x0F, 0xFE, 0x1F, 0xFC, 0x0F, 0xFE, 0x1F, 0xFC, 0x07, 0xFE,    \
+        0x1F, 0xF8, 0x07, 0xFF, 0x3F, 0xF0, 0x03, 0xFF, 0x3F, 0xE0, 0x81, 0xFF, 0x7F, 0xC0, 0x80, 0xFF, 0x7F, 0x00, 0xC0, 0xFF,    \
+        0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x01, 0xF0, 0xFF, 0xFF, 0x03, 0xF8, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xC0, 0xFF,    \
+        0x3F, 0x60, 0x80, 0xFF, 0x1F, 0xF0, 0x00, 0xFF, 0x1F, 0xF8, 0x01, 0xFE, 0x0F, 0xFC, 0x03, 0xFE, 0x0F, 0xFC, 0x07, 0xFC,    \
+        0x07, 0xFE, 0x0F, 0xFC, 0x07, 0xFE, 0x0F, 0xFC, 0x07, 0xFF, 0x1F, 0xFC, 0x07, 0xFF, 0x1F, 0xFC, 0x07, 0xFF, 0x1F, 0xFC,    \
+        0x07, 0xFE, 0x0F, 0xFC, 0x07, 0xFC, 0x0F, 0xFC, 0x0F, 0xF8, 0x07, 0xFE, 0x0F, 0xE0, 0x01, 0xFE, 0x1F, 0x00, 0x00, 0xFF,    \
+        0x3F, 0x00, 0x80, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x03, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* Character 0x38 (56: '8')*/                      \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xFE, 0xFF,    \
+        0xFF, 0x00, 0xF0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0xC0, 0xFF, 0x0F, 0x70, 0x80, 0xFF, 0x07, 0xFC, 0x01, 0xFF,    \
+        0x07, 0xFE, 0x03, 0xFF, 0x03, 0xFF, 0x03, 0xFF, 0x83, 0xFF, 0x07, 0xFE, 0x83, 0xFF, 0x07, 0xFE, 0x83, 0xFF, 0x0F, 0xFC,    \
+        0xC1, 0xFF, 0x0F, 0xFC, 0xC1, 0xFF, 0x0F, 0xFC, 0xC1, 0xFF, 0x0F, 0xFC, 0x83, 0xFF, 0x07, 0xFC, 0x83, 0xFF, 0x07, 0xFC,    \
+        0x83, 0xFF, 0x07, 0xFC, 0x03, 0xFF, 0x03, 0xF8, 0x03, 0xFE, 0x01, 0xF8, 0x07, 0x7C, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xF8,    \
+        0x1F, 0x00, 0x10, 0xF8, 0x3F, 0x00, 0x1C, 0xFC, 0xFF, 0x00, 0x1F, 0xFC, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0x1F, 0xFC,    \
+        0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0x0F, 0xFC, 0xFF, 0xFF, 0x0F, 0xFE, 0xFF, 0xFF, 0x07, 0xFE, 0xFF, 0xFF, 0x07, 0xFE,    \
+        0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0x81, 0xFF, 0xCF, 0xFF, 0x80, 0xFF, 0x0F, 0x3E, 0xC0, 0xFF, 0x0F, 0x00, 0xE0, 0xFF,    \
+        0x0F, 0x00, 0xF0, 0xFF, 0x0F, 0x00, 0xFC, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* Character 0x39 (57: '9')*/                      \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFC, 0x1F, 0xE0, 0x0F, 0xE3, 0xC7, 0xFF,    \
+        0xE3, 0xFF, 0xE3, 0xFF, 0xE3, 0xFF, 0xE3, 0xFF, 0xE3, 0xFF, 0xE3, 0xFF, 0xC3, 0xFF, 0x87, 0xEF, 0x0F, 0xE0, 0x1F, 0xE0,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* Character 0x63 (99: 'c')*/                                  \
+        0xFF, 0xFB, 0x7F, 0xC0, 0x3F, 0xC0, 0x1F, 0xFF, 0x1F, 0xFF, 0x9F, 0xFF, 0x9F, 0xFF, 0x9F, 0xFF, 0x03, 0xF0, 0x03, 0xF0,    \
+        0x9F, 0xFF, 0x9F, 0xFF, 0x9F, 0xFF, 0x9F, 0xFF, 0x9F, 0xFF, 0x9F, 0xFF, 0x9F, 0xFF, 0x9F, 0xFF, 0x9F, 0xFF, 0x9F, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* Character 0x66 (102: 'f')*/                                 \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0xFF, 0xDD, 0xFF, 0xDD, 0xFF, 0xDD, 0xFF, 0xE3, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    \
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* Character 0x20 (32: 'degree')*/
diff --git a/examples/thermostat/efr32/include/ThermostatUI.h b/examples/thermostat/efr32/include/ThermostatUI.h
new file mode 100644
index 00000000000000..671bbf8605952b
--- /dev/null
+++ b/examples/thermostat/efr32/include/ThermostatUI.h
@@ -0,0 +1,52 @@
+/*
+ *
+ *    Copyright (c) 2020 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 "ThermostatIcons.h"
+#include "glib.h"
+#include "lcd.h"
+
+class ThermostatUI
+{
+
+public:
+    // AppCluster Spec Table 85.
+    enum HVACMode
+    {
+        MODE_OFF = 0,
+        HEATING_COOLING,
+        NOT_USED,
+        COOLING,
+        HEATING,
+    };
+
+    static void DrawUI(GLIB_Context_t * glibContext);
+    static void SetHeatingSetPoint(int8_t temp);
+    static void SetCoolingSetPoint(int8_t temp);
+    static void SetCurrentTemp(int8_t temp);
+    static void SetMode(uint8_t mode);
+
+private:
+    static void DrawHeader(GLIB_Context_t * glibContext);
+    static void DrawFooter(GLIB_Context_t * glibContext, bool autoMode = true);
+    static void DrawCurrentTemp(GLIB_Context_t * glibContext, int8_t temp, bool isCelsius = true);
+    static void DrawFont(GLIB_Context_t * glibContext, uint8_t initial_x, uint8_t initial_y, uint8_t width, uint8_t * data,
+                         uint32_t size);
+    static void DrawSetPoint(GLIB_Context_t * glibContext, int8_t setPoint, bool secondLine);
+};
diff --git a/examples/thermostat/efr32/src/AppTask.cpp b/examples/thermostat/efr32/src/AppTask.cpp
index 37ab028045fe35..64af0859e887c3 100644
--- a/examples/thermostat/efr32/src/AppTask.cpp
+++ b/examples/thermostat/efr32/src/AppTask.cpp
@@ -31,6 +31,7 @@
 #endif // ENABLE_WSTK_LEDS
 
 #ifdef DISPLAY_ENABLED
+#include "ThermostatUI.h"
 #include "lcd.h"
 #ifdef QR_CODE_ENABLED
 #include "qrcodegen.h"
@@ -39,7 +40,13 @@
 
 #include <app-common/zap-generated/attribute-id.h>
 #include <app-common/zap-generated/attribute-type.h>
+#include <app-common/zap-generated/attributes/Accessors.h>
+#include <app-common/zap-generated/callback.h>
 #include <app-common/zap-generated/cluster-id.h>
+#include <app-common/zap-generated/cluster-objects.h>
+#include <app-common/zap-generated/command-id.h>
+#include <app-common/zap-generated/enums.h>
+#include <app-common/zap-generated/ids/Attributes.h>
 #include <app/server/OnboardingCodesUtil.h>
 #include <app/server/Server.h>
 #include <app/util/attribute-storage.h>
@@ -56,7 +63,10 @@
 #define APP_FUNCTION_BUTTON &sl_button_btn0
 #define APP_THERMOSTAT &sl_button_btn1
 
+#define MODE_TIMER 1000 // 1s timer period
+
 using namespace chip;
+using namespace chip::TLV;
 using namespace ::chip::DeviceLayer;
 
 /**********************************************************
@@ -129,9 +139,6 @@ Identify gIdentify = {
 
 } // namespace
 
-using namespace chip::TLV;
-using namespace ::chip::DeviceLayer;
-
 /**********************************************************
  * AppTask Definitions
  *********************************************************/
@@ -144,6 +151,7 @@ CHIP_ERROR AppTask::Init()
 
 #ifdef DISPLAY_ENABLED
     GetLCD().Init((uint8_t *) "Thermostat-App");
+    GetLCD().SetCustomUI(ThermostatUI::DrawUI);
 #endif
 
     err = BaseApplication::Init(&gIdentify);
@@ -152,6 +160,18 @@ CHIP_ERROR AppTask::Init()
         EFR32_LOG("BaseApplication::Init() failed");
         appError(err);
     }
+    err = SensorMgr().Init();
+    if (err != CHIP_NO_ERROR)
+    {
+        EFR32_LOG("SensorMgr::Init() failed");
+        appError(err);
+    }
+    err = TempMgr().Init();
+    if (err != CHIP_NO_ERROR)
+    {
+        EFR32_LOG("TempMgr::Init() failed");
+        appError(err);
+    }
 
     return err;
 }
@@ -207,34 +227,42 @@ void AppTask::OnIdentifyStop(Identify * identify)
 #endif
 }
 
-void AppTask::ThermostatActionEventHandler(AppEvent * aEvent)
+void AppTask::UpdateThermoStatUI()
 {
-    if (aEvent->Type == AppEvent::kEventType_Button)
+#ifdef DISPLAY_ENABLED
+    ThermostatUI::SetMode(TempMgr().GetMode());
+    ThermostatUI::SetHeatingSetPoint(TempMgr().GetHeatingSetPoint());
+    ThermostatUI::SetCoolingSetPoint(TempMgr().GetCoolingSetPoint());
+    ThermostatUI::SetCurrentTemp(TempMgr().GetCurrentTemp());
+
+#ifdef SL_WIFI
+    if (ConnectivityMgr().IsWiFiStationProvisioned())
+#else
+    if (ConnectivityMgr().IsThreadProvisioned())
+#endif /* !SL_WIFI */
     {
-        EFR32_LOG("App Button was pressed!");
-        // TODO: Implement button functionnality
+        AppTask::GetAppTask().GetLCD().WriteDemoUI(false); // State doesn't Matter
     }
+#else
+    EFR32_LOG("Thermostat Status - M:%d T:%d'C H:%d'C C:%d'C", TempMgr().GetMode(), TempMgr().GetCurrentTemp(),
+              TempMgr().GetHeatingSetPoint(), TempMgr().GetCoolingSetPoint());
+#endif // DISPLAY_ENABLED
 }
 
 void AppTask::ButtonEventHandler(const sl_button_t * buttonHandle, uint8_t btnAction)
 {
-    if (buttonHandle == NULL)
+    if (buttonHandle == nullptr)
     {
         return;
     }
 
-    AppEvent button_event           = {};
-    button_event.Type               = AppEvent::kEventType_Button;
-    button_event.ButtonEvent.Action = btnAction;
+    AppEvent aEvent           = {};
+    aEvent.Type               = AppEvent::kEventType_Button;
+    aEvent.ButtonEvent.Action = btnAction;
 
-    if (buttonHandle == APP_THERMOSTAT && btnAction == SL_SIMPLE_BUTTON_PRESSED)
-    {
-        button_event.Handler = ThermostatActionEventHandler;
-        sAppTask.PostEvent(&button_event);
-    }
-    else if (buttonHandle == APP_FUNCTION_BUTTON)
+    if (buttonHandle == APP_FUNCTION_BUTTON)
     {
-        button_event.Handler = BaseApplication::ButtonHandler;
-        sAppTask.PostEvent(&button_event);
+        aEvent.Handler = BaseApplication::ButtonHandler;
+        sAppTask.PostEvent(&aEvent);
     }
 }
diff --git a/examples/thermostat/efr32/src/SensorManager.cpp b/examples/thermostat/efr32/src/SensorManager.cpp
new file mode 100644
index 00000000000000..4a60846fae950c
--- /dev/null
+++ b/examples/thermostat/efr32/src/SensorManager.cpp
@@ -0,0 +1,133 @@
+/*
+ *
+ *    Copyright (c) 2020 Project CHIP Authors
+ *    Copyright (c) 2019 Google LLC.
+ *    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.
+ */
+
+/**********************************************************
+ * Includes
+ *********************************************************/
+
+#include "SensorManager.h"
+#include "AppConfig.h"
+#include "AppEvent.h"
+#include "AppTask.h"
+
+#ifdef USE_TEMP_SENSOR
+#include "TemperatureSensor.h"
+#endif
+/**********************************************************
+ * Defines and Constants
+ *********************************************************/
+
+using namespace chip;
+using namespace ::chip::DeviceLayer;
+
+constexpr EndpointId kThermostatEndpoint = 1;
+constexpr uint16_t kSensorTImerPeriodMs  = 30000; // 30s timer period
+constexpr uint16_t kMinTemperatureDelta  = 50;    // 0.5 degree Celcius
+
+/**********************************************************
+ * Variable declarations
+ *********************************************************/
+
+TimerHandle_t sSensorTimer;
+StaticTimer_t sStaticSensorTimerStruct;
+
+SensorManager SensorManager::sSensorManager;
+
+#ifndef USE_TEMP_SENSOR
+constexpr uint16_t kSimulatedReadingFrequency = (60000 / kSensorTImerPeriodMs); // Change Simulated number at each minutes
+static int16_t mSimulatedTemp[]               = { 2300, 2400, 2800, 2550, 2200, 2125, 2100, 2600, 1800, 2700 };
+#endif
+
+CHIP_ERROR SensorManager::Init()
+{
+    // Create FreeRTOS sw timer for temp sensor timer.
+    sSensorTimer = xTimerCreateStatic("sensorTmr", pdMS_TO_TICKS(kSensorTImerPeriodMs), true, nullptr, SensorTimerEventHandler,
+                                      &sStaticSensorTimerStruct);
+
+    if (sSensorTimer == NULL)
+    {
+        EFR32_LOG("sSensorTimer timer create failed");
+        return APP_ERROR_CREATE_TIMER_FAILED;
+    }
+
+#ifdef USE_TEMP_SENSOR
+    if (SL_STATUS_OK != TemperatureSensor::Init())
+    {
+        EFR32_LOG("Failed to Init Sensor");
+        return CHIP_ERROR_INTERNAL;
+    }
+#endif
+
+    // Update Temp immediatly at bootup
+    SensorTimerEventHandler(sSensorTimer);
+
+    // Trigger periodic update
+    xTimerStart(sSensorTimer, portMAX_DELAY);
+
+    return CHIP_NO_ERROR;
+}
+
+void SensorManager::SensorTimerEventHandler(TimerHandle_t xTimer)
+{
+    int16_t temperature            = 0;
+    static int16_t lastTemperature = 0;
+
+#ifdef USE_TEMP_SENSOR
+    int32_t tempSum   = 0;
+    uint32_t humidity = 0;
+
+    for (uint8_t i = 0; i < 100; i++)
+    {
+        if (SL_STATUS_OK != TemperatureSensor::GetTemp(&humidity, &temperature))
+        {
+            EFR32_LOG("Failed to read Temperature !!!");
+        }
+        tempSum += temperature;
+    }
+    temperature = static_cast<int16_t>(tempSum / 100);
+#else
+    static uint8_t nbOfRepetition = 0;
+    static uint8_t simulatedIndex = 0;
+    if (simulatedIndex >= sizeof(mSimulatedTemp))
+    {
+        simulatedIndex = 0;
+    }
+    temperature = mSimulatedTemp[simulatedIndex];
+
+    nbOfRepetition++;
+    if (nbOfRepetition >= kSimulatedReadingFrequency)
+    {
+        simulatedIndex++;
+        nbOfRepetition = 0;
+    }
+#endif // USE_TEMP_SENSOR
+
+    EFR32_LOG("Sensor Temp is : %d", temperature);
+
+    if ((temperature >= (lastTemperature + kMinTemperatureDelta)) || temperature <= (lastTemperature - kMinTemperatureDelta))
+    {
+        lastTemperature = temperature;
+        PlatformMgr().LockChipStack();
+        // The SensorMagager shouldn't be aware of the Endpoint ID TODO Fix this.
+        // TODO Per Spec we should also apply the Offset stored in the same cluster before saving the temp
+
+        app::Clusters::Thermostat::Attributes::LocalTemperature::Set(kThermostatEndpoint, temperature);
+        PlatformMgr().UnlockChipStack();
+    }
+}
diff --git a/examples/thermostat/efr32/src/TemperatureManager.cpp b/examples/thermostat/efr32/src/TemperatureManager.cpp
new file mode 100644
index 00000000000000..8b0d6c7f8413cc
--- /dev/null
+++ b/examples/thermostat/efr32/src/TemperatureManager.cpp
@@ -0,0 +1,149 @@
+/*
+ *
+ *    Copyright (c) 2020 Project CHIP Authors
+ *    Copyright (c) 2019 Google LLC.
+ *    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.
+ */
+
+/**********************************************************
+ * Includes
+ *********************************************************/
+
+#include "TemperatureManager.h"
+#include "AppConfig.h"
+#include "AppEvent.h"
+#include "AppTask.h"
+#include "semphr.h"
+
+/**********************************************************
+ * Defines and Constants
+ *********************************************************/
+
+using namespace chip;
+using namespace ::chip::DeviceLayer;
+
+constexpr EndpointId kThermostatEndpoint = 1;
+
+namespace ThermAttr = chip::app::Clusters::Thermostat::Attributes;
+/**********************************************************
+ * Variable declarations
+ *********************************************************/
+
+TemperatureManager TemperatureManager::sTempMgr;
+
+CHIP_ERROR TemperatureManager::Init()
+{
+    app::DataModel::Nullable<int16_t> temp;
+    int16_t heatingSetpoint, coolingSetpoint;
+    uint8_t systemMode;
+
+    PlatformMgr().LockChipStack();
+    ThermAttr::LocalTemperature::Get(kThermostatEndpoint, temp);
+    ThermAttr::OccupiedCoolingSetpoint::Get(kThermostatEndpoint, &coolingSetpoint);
+    ThermAttr::OccupiedHeatingSetpoint::Get(kThermostatEndpoint, &heatingSetpoint);
+    ThermAttr::SystemMode::Get(kThermostatEndpoint, &systemMode);
+    PlatformMgr().UnlockChipStack();
+
+    mCurrentTempCelsius     = ConvertToPrintableTemp(temp.Value());
+    mHeatingCelsiusSetPoint = ConvertToPrintableTemp(coolingSetpoint);
+    mCoolingCelsiusSetPoint = ConvertToPrintableTemp(heatingSetpoint);
+    mThermMode              = systemMode;
+
+    AppTask::GetAppTask().UpdateThermoStatUI();
+
+    return CHIP_NO_ERROR;
+}
+
+int8_t TemperatureManager::ConvertToPrintableTemp(int16_t temperature)
+{
+    constexpr uint8_t kRoundUpValue = 50;
+
+    // Round up the temperature as we won't print decimals on LCD
+    // Is it a negative temperature
+    if (temperature < 0)
+    {
+        temperature -= kRoundUpValue;
+    }
+    else
+    {
+        temperature += kRoundUpValue;
+    }
+
+    return static_cast<int8_t>(temperature / 100);
+}
+
+void TemperatureManager::AttributeChangeHandler(EndpointId endpointId, AttributeId attributeId, uint8_t * value, uint16_t size)
+{
+    switch (attributeId)
+    {
+    case ThermAttr::LocalTemperature::Id: {
+        int8_t Temp = ConvertToPrintableTemp(*((int16_t *) value));
+        EFR32_LOG("Local temp %d", Temp);
+        mCurrentTempCelsius = Temp;
+    }
+    break;
+
+    case ThermAttr::OccupiedCoolingSetpoint::Id: {
+        int8_t coolingTemp = ConvertToPrintableTemp(*((int16_t *) value));
+        EFR32_LOG("CoolingSetpoint %d", coolingTemp);
+        mCoolingCelsiusSetPoint = coolingTemp;
+    }
+    break;
+
+    case ThermAttr::OccupiedHeatingSetpoint::Id: {
+        int8_t heatingTemp = ConvertToPrintableTemp(*((int16_t *) value));
+        EFR32_LOG("HeatingSetpoint %d", heatingTemp);
+        mHeatingCelsiusSetPoint = heatingTemp;
+    }
+    break;
+
+    case ThermAttr::SystemMode::Id: {
+        EFR32_LOG("SystemMode %d", static_cast<uint8_t>(*value));
+        uint8_t mode = static_cast<uint8_t>(*value);
+        if (mThermMode != mode)
+        {
+            mThermMode = mode;
+        }
+    }
+    break;
+
+    default: {
+        EFR32_LOG("Unhandled thermostat attribute %x", attributeId);
+        return;
+    }
+    break;
+    }
+
+    AppTask::GetAppTask().UpdateThermoStatUI();
+}
+
+uint8_t TemperatureManager::GetMode()
+{
+    return mThermMode;
+}
+
+int8_t TemperatureManager::GetCurrentTemp()
+{
+    return mCurrentTempCelsius;
+}
+int8_t TemperatureManager::GetHeatingSetPoint()
+{
+    return mHeatingCelsiusSetPoint;
+}
+
+int8_t TemperatureManager::GetCoolingSetPoint()
+{
+    return mCoolingCelsiusSetPoint;
+}
diff --git a/examples/thermostat/efr32/src/ThermostatUI.cpp b/examples/thermostat/efr32/src/ThermostatUI.cpp
new file mode 100644
index 00000000000000..9336d356770d48
--- /dev/null
+++ b/examples/thermostat/efr32/src/ThermostatUI.cpp
@@ -0,0 +1,255 @@
+/*
+ *
+ *    Copyright (c) 2020 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 <stdio.h>
+#include <string.h>
+
+#include "ThermostatUI.h"
+#include "demo-ui-bitmaps.h"
+#include "dmd.h"
+#include "glib.h"
+#include "lcd.h"
+
+// LCD line define
+constexpr uint8_t kTempLcdInitialX = 30;
+
+// Bitmap
+static const uint8_t silabsLogo[]       = { SILABS_LOGO_SMALL };
+static const uint8_t matterLogoBitmap[] = { MATTER_LOGO_BITMAP };
+
+static const uint8_t wifiLogo[]   = { WIFI_BITMAP };
+static const uint8_t threadLogo[] = { THREAD_BITMAP };
+static const uint8_t bleLogo[]    = { BLUETOOTH_ICON_SMALL };
+
+static const unsigned char monaco_48pt[]          = { MONACO_48PT };
+static const unsigned char heating_bits[]         = { HEATING_BITMAP };
+static const unsigned char cooling_bits[]         = { COOLING_BITMAP };
+static const unsigned char heating_cooling_bits[] = { HEATING_COOLING_BITMAP };
+
+static int8_t mHeatingCelsiusSetPoint;
+static int8_t mCoolingCelsiusSetPoint;
+static int8_t mCurrentTempCelsius;
+static uint8_t mMode;
+
+#ifdef SL_WIFI
+#define UI_WIFI 1
+#else
+#define UI_WIFI 0
+#endif
+
+void ThermostatUI::DrawUI(GLIB_Context_t * glibContext)
+{
+    if (glibContext == nullptr)
+    {
+        EFR32_LOG("Context is null");
+        return;
+    }
+
+    GLIB_clear(glibContext);
+    DrawHeader(glibContext);
+    DrawCurrentTemp(glibContext, mCurrentTempCelsius);
+    DrawFooter(glibContext, false);
+
+    DMD_updateDisplay();
+}
+
+void ThermostatUI::SetHeatingSetPoint(int8_t temp)
+{
+    mHeatingCelsiusSetPoint = temp;
+}
+
+void ThermostatUI::SetCoolingSetPoint(int8_t temp)
+{
+    mCoolingCelsiusSetPoint = temp;
+}
+
+void ThermostatUI::SetCurrentTemp(int8_t temp)
+{
+    mCurrentTempCelsius = temp;
+}
+void ThermostatUI::SetMode(uint8_t mode)
+{
+    mMode = mode;
+}
+
+void ThermostatUI::DrawHeader(GLIB_Context_t * glibContext)
+{
+    // Draw Silabs Corner icon
+    GLIB_drawBitmap(glibContext, SILABS_ICON_POSITION_X, STATUS_ICON_LINE, SILABS_LOGO_WIDTH, SILABS_LOGO_HEIGHT, silabsLogo);
+    // Draw BLE Icon
+    GLIB_drawBitmap(glibContext, BLE_ICON_POSITION_X, STATUS_ICON_LINE, BLUETOOTH_ICON_SIZE, BLUETOOTH_ICON_SIZE, bleLogo);
+    // Draw WiFi/OpenThread Icon
+    GLIB_drawBitmap(glibContext, NETWORK_ICON_POSITION_X, STATUS_ICON_LINE, (UI_WIFI) ? WIFI_BITMAP_HEIGHT : THREAD_BITMAP_WIDTH,
+                    WIFI_BITMAP_HEIGHT, (UI_WIFI) ? wifiLogo : threadLogo);
+    // Draw Matter Icon
+    GLIB_drawBitmap(glibContext, MATTER_ICON_POSITION_X, STATUS_ICON_LINE, MATTER_LOGO_WIDTH, MATTER_LOGO_HEIGHT, matterLogoBitmap);
+    DMD_updateDisplay();
+}
+
+void ThermostatUI::DrawFooter(GLIB_Context_t * glibContext, bool autoMode)
+{
+    switch (static_cast<ThermostatUI::HVACMode>(mMode))
+    {
+    case HVACMode::HEATING:
+        GLIB_drawStringOnLine(glibContext, "Mode : Heating", 11, GLIB_ALIGN_LEFT, 0, 0, true);
+        GLIB_drawBitmap(glibContext, HEATING_COOLING_X, HEATING_COOLING_Y, COOLING_WIDTH, COOLING_HEIGHT, heating_bits);
+        DrawSetPoint(glibContext, mHeatingCelsiusSetPoint, false);
+        break;
+    case HVACMode::COOLING:
+        GLIB_drawStringOnLine(glibContext, "Mode : Cooling", 11, GLIB_ALIGN_LEFT, 0, 0, true);
+        GLIB_drawBitmap(glibContext, HEATING_COOLING_X, HEATING_COOLING_Y, COOLING_WIDTH, COOLING_HEIGHT, cooling_bits);
+        DrawSetPoint(glibContext, mCoolingCelsiusSetPoint, false);
+        break;
+    case HVACMode::HEATING_COOLING:
+        GLIB_drawStringOnLine(glibContext, "Mode : Auto", 11, GLIB_ALIGN_LEFT, 0, 0, true);
+        GLIB_drawBitmap(glibContext, HEATING_COOLING_X, HEATING_COOLING_Y, COOLING_WIDTH, COOLING_HEIGHT, heating_cooling_bits);
+        DrawSetPoint(glibContext, mHeatingCelsiusSetPoint, false);
+        DrawSetPoint(glibContext, mCoolingCelsiusSetPoint, true);
+        break;
+    case HVACMode::MODE_OFF:
+        DrawSetPoint(glibContext, 0, false);
+        GLIB_drawStringOnLine(glibContext, "Mode : OFF", 11, GLIB_ALIGN_LEFT, 0, 0, true);
+        break;
+    default:
+        break;
+    }
+
+    DMD_updateDisplay();
+}
+
+/**
+ * @brief Draw a 2 digit Temp of screen. Because of this Celsius is used by default
+ * @param GLIB_Context_t * pointer to the context for the GLIB library
+ * @param int8_t current Temperature in Celsius
+ * @param int8_t setPoint in Celsius
+ * @param bool isCelsius By default set to True. For future development
+ */
+void ThermostatUI::DrawCurrentTemp(GLIB_Context_t * glibContext, int8_t temp, bool isCelsius)
+{
+    uint8_t tempArray[2];
+    uint8_t position_x = 10;
+    uint8_t * data;
+
+    if (temp > 99 || temp < -99)
+    {
+        // Invalid temp for a house thermostat
+        return;
+    }
+
+    if (temp < 0)
+    {
+        for (uint8_t y = 60; y < 64; y++)
+        {
+            for (uint8_t x = 1; x < 10; x++)
+            {
+                GLIB_drawPixel(glibContext, x, y);
+            }
+        }
+
+        temp = temp * -1;
+    }
+
+    // Draw Unit
+    if (isCelsius)
+    {
+        data = (uint8_t *) &monaco_48pt[DEGREE_INDEX];
+        DrawFont(glibContext, 65, kTempLcdInitialX, 15, data, MONACO_FONT_CH_LENGTH);
+        data = (uint8_t *) &monaco_48pt[CELSIUS_INDEX];
+        DrawFont(glibContext, 70, kTempLcdInitialX, 15, data, MONACO_FONT_CH_LENGTH);
+    }
+    else
+    {
+        data = (uint8_t *) &monaco_48pt[DEGREE_INDEX];
+        DrawFont(glibContext, 65, 25, 15, data, MONACO_FONT_CH_LENGTH); // 25 to fit with f of fahrenheint
+        data = (uint8_t *) &monaco_48pt[FAHRENHEIT_INDEX];
+        DrawFont(glibContext, 70, kTempLcdInitialX, 15, data, MONACO_FONT_CH_LENGTH);
+    }
+
+    // Print Current temp
+    tempArray[0] = (uint8_t)((temp / 10));
+    tempArray[1] = (uint8_t)((temp % 10));
+
+    for (uint8_t ch = 0; ch < 2; ch++)
+    {
+        data = (uint8_t *) &monaco_48pt[tempArray[ch] * MONACO_FONT_NB_LENGTH];
+        DrawFont(glibContext, position_x, kTempLcdInitialX, MONACO_FONT_WIDTH, data, MONACO_FONT_NB_LENGTH);
+        position_x += MONACO_FONT_WIDTH;
+    }
+}
+
+void ThermostatUI::DrawFont(GLIB_Context_t * glibContext, uint8_t initial_x, uint8_t initial_y, uint8_t width, uint8_t * data,
+                            uint32_t size)
+{
+    uint8_t x = initial_x, y = initial_y;
+    for (uint16_t i = 0; i < size; i++)
+    {
+        for (uint8_t mask = 0; mask < 8; mask++)
+        {
+            if (!(data[i] & (0x01 << mask)))
+            {
+                GLIB_drawPixel(glibContext, x, y);
+            }
+            // Check line changes
+            if (((x - initial_x) % width) == 0 && x != initial_x)
+            {
+                x = initial_x;
+                y++;
+                // Font is 8 bit align with paddings bits;
+                mask = 8;
+            }
+            else
+            {
+                x++;
+            }
+        }
+    }
+}
+
+void ThermostatUI::DrawSetPoint(GLIB_Context_t * glibContext, int8_t setPoint, bool secondLine)
+{
+    char setPointLine[] = { '-', 'X', 'X', '\0' };
+
+    if (setPoint > 99 || setPoint < -99)
+    {
+        return;
+    }
+
+    // Update SetPoint string
+    if (static_cast<ThermostatUI::HVACMode>(mMode) == ThermostatUI::HVACMode::MODE_OFF)
+    {
+        setPointLine[0] = '-';
+        setPointLine[1] = '-';
+        setPointLine[2] = '\0';
+    }
+    else if (setPoint < 0)
+    {
+        setPointLine[0] = (setPoint < 0) ? '-' : ' ';
+        setPoint *= -1;
+        setPointLine[1] = ((setPoint / 10) + 0x30);
+        setPointLine[2] = ((setPoint % 10) + 0x30);
+    }
+    else
+    {
+        setPointLine[0] = ((setPoint / 10) + 0x30);
+        setPointLine[1] = ((setPoint % 10) + 0x30);
+        setPointLine[2] = '\0';
+    }
+
+    // Print SetPoint
+    GLIB_drawStringOnLine(glibContext, setPointLine, (secondLine) ? 8 : 7, GLIB_ALIGN_LEFT, 67, 0, true);
+}
diff --git a/examples/thermostat/efr32/src/ZclCallbacks.cpp b/examples/thermostat/efr32/src/ZclCallbacks.cpp
index f89d4aaa8cd581..734637d91be401 100644
--- a/examples/thermostat/efr32/src/ZclCallbacks.cpp
+++ b/examples/thermostat/efr32/src/ZclCallbacks.cpp
@@ -22,6 +22,7 @@
 
 #include "AppConfig.h"
 
+#include "TemperatureManager.h"
 #include <app-common/zap-generated/ids/Attributes.h>
 #include <app-common/zap-generated/ids/Clusters.h>
 #include <app/ConcreteAttributePath.h>
@@ -42,24 +43,8 @@ void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath &
         ChipLogProgress(Zcl, "Identify attribute ID: " ChipLogFormatMEI " Type: %u Value: %u, length %u",
                         ChipLogValueMEI(attributeId), type, *value, size);
     }
-}
-
-/** @brief OnOff Cluster Init
- *
- * This function is called when a specific cluster is initialized. It gives the
- * application an opportunity to take care of cluster initialization procedures.
- * It is called exactly once for each endpoint where cluster is present.
- *
- * @param endpoint   Ver.: always
- *
- * TODO Issue #3841
- * emberAfOnOffClusterInitCallback happens before the stack initialize the cluster
- * attributes to the default value.
- * The logic here expects something similar to the deprecated Plugins callback
- * emberAfPluginOnOffClusterServerPostInitCallback.
- *
- */
-void emberAfOnOffClusterInitCallback(EndpointId endpoint)
-{
-    // TODO: implement any additional Cluster Server init actions
+    else if (clusterId == Thermostat::Id)
+    {
+        TempMgr().AttributeChangeHandler(attributePath.mEndpointId, attributeId, value, size);
+    }
 }
diff --git a/examples/thermostat/thermostat-common/thermostat.matter b/examples/thermostat/thermostat-common/thermostat.matter
index 9b104b990f3159..15933ed93c52d3 100644
--- a/examples/thermostat/thermostat-common/thermostat.matter
+++ b/examples/thermostat/thermostat-common/thermostat.matter
@@ -1436,6 +1436,16 @@ server cluster Thermostat = 513 {
   command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0;
 }
 
+server cluster ThermostatUserInterfaceConfiguration = 516 {
+  attribute enum8 temperatureDisplayMode = 0;
+  attribute access(write: manage) enum8 keypadLockout = 1;
+  readonly attribute command_id generatedCommandList[] = 65528;
+  readonly attribute command_id acceptedCommandList[] = 65529;
+  readonly attribute attrib_id attributeList[] = 65531;
+  readonly attribute bitmap32 featureMap = 65532;
+  readonly attribute int16u clusterRevision = 65533;
+}
+
 endpoint 0 {
   device type rootdevice = 22;
   binding cluster OtaSoftwareUpdateProvider;
@@ -1743,29 +1753,13 @@ endpoint 1 {
     ram      attribute clusterRevision default = 4;
   }
 
-  server cluster Basic {
-    callback attribute dataModelRevision default = 10;
-    callback attribute vendorName;
-    callback attribute vendorID;
-    callback attribute productName;
-    callback attribute productID;
-    persist  attribute nodeLabel;
-    callback attribute location default = "XX";
-    callback attribute hardwareVersion;
-    callback attribute hardwareVersionString;
-    callback attribute softwareVersion;
-    callback attribute softwareVersionString;
-    callback attribute manufacturingDate default = "20210614123456ZZ";
-    callback attribute partNumber;
-    callback attribute productURL;
-    callback attribute productLabel;
-    callback attribute serialNumber;
-    persist  attribute localConfigDisabled;
-    ram      attribute reachable default = 1;
-    callback attribute uniqueID;
-    callback attribute capabilityMinima;
+  server cluster Descriptor {
+    callback attribute deviceTypeList;
+    callback attribute serverList;
+    callback attribute clientList;
+    callback attribute partsList;
     ram      attribute featureMap;
-    ram      attribute clusterRevision default = 1;
+    callback attribute clusterRevision default = 1;
   }
 
   server cluster Thermostat {
@@ -1774,21 +1768,31 @@ endpoint 1 {
     ram      attribute absMaxHeatSetpointLimit default = 3000;
     ram      attribute absMinCoolSetpointLimit default = 1600;
     ram      attribute absMaxCoolSetpointLimit default = 3200;
-    ram      attribute occupiedCoolingSetpoint default = 0x0A28;
-    ram      attribute occupiedHeatingSetpoint default = 0x07D0;
+    persist  attribute occupiedCoolingSetpoint default = 0x0A28;
+    persist  attribute occupiedHeatingSetpoint default = 0x07D0;
     ram      attribute minHeatSetpointLimit default = 700;
     ram      attribute maxHeatSetpointLimit default = 3000;
     ram      attribute minCoolSetpointLimit default = 1600;
     ram      attribute maxCoolSetpointLimit default = 3200;
     ram      attribute minSetpointDeadBand default = 0x19;
     ram      attribute controlSequenceOfOperation default = 0x04;
-    ram      attribute systemMode default = 0x01;
+    persist  attribute systemMode default = 0x01;
     callback attribute generatedCommandList;
     callback attribute acceptedCommandList;
     callback attribute attributeList;
     ram      attribute featureMap default = 0x23;
     ram      attribute clusterRevision default = 5;
   }
+
+  server cluster ThermostatUserInterfaceConfiguration {
+    ram      attribute temperatureDisplayMode;
+    ram      attribute keypadLockout;
+    callback attribute generatedCommandList;
+    callback attribute acceptedCommandList;
+    callback attribute attributeList;
+    ram      attribute featureMap;
+    ram      attribute clusterRevision default = 1;
+  }
 }
 
 
diff --git a/examples/thermostat/thermostat-common/thermostat.zap b/examples/thermostat/thermostat-common/thermostat.zap
index 601a871112cf16..ca91d4a2332a90 100644
--- a/examples/thermostat/thermostat-common/thermostat.zap
+++ b/examples/thermostat/thermostat-common/thermostat.zap
@@ -1,5 +1,5 @@
 {
-  "featureLevel": 81,
+  "featureLevel": 85,
   "creator": "zap",
   "keyValuePairs": [
     {
@@ -8592,7 +8592,7 @@
           "mfgCode": null,
           "define": "DESCRIPTOR_CLUSTER",
           "side": "server",
-          "enabled": 0,
+          "enabled": 1,
           "attributes": [
             {
               "name": "DeviceTypeList",
@@ -8658,6 +8658,22 @@
               "maxInterval": 65344,
               "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,
@@ -8776,7 +8792,7 @@
           "mfgCode": null,
           "define": "BASIC_CLUSTER",
           "side": "server",
-          "enabled": 1,
+          "enabled": 0,
           "attributes": [
             {
               "name": "DataModelRevision",
@@ -11119,7 +11135,7 @@
               "side": "server",
               "type": "int16s",
               "included": 1,
-              "storageOption": "RAM",
+              "storageOption": "NVM",
               "singleton": 0,
               "bounded": 0,
               "defaultValue": "0x0A28",
@@ -11135,7 +11151,7 @@
               "side": "server",
               "type": "int16s",
               "included": 1,
-              "storageOption": "RAM",
+              "storageOption": "NVM",
               "singleton": 0,
               "bounded": 0,
               "defaultValue": "0x07D0",
@@ -11247,7 +11263,7 @@
               "side": "server",
               "type": "enum8",
               "included": 1,
-              "storageOption": "RAM",
+              "storageOption": "NVM",
               "singleton": 0,
               "bounded": 0,
               "defaultValue": "0x01",
@@ -11386,6 +11402,186 @@
             }
           ]
         },
+        {
+          "name": "Thermostat User Interface Configuration",
+          "code": 516,
+          "mfgCode": null,
+          "define": "THERMOSTAT_USER_INTERFACE_CONFIGURATION_CLUSTER",
+          "side": "client",
+          "enabled": 0,
+          "attributes": [
+            {
+              "name": "FeatureMap",
+              "code": 65532,
+              "mfgCode": null,
+              "side": "client",
+              "type": "bitmap32",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "0",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "ClusterRevision",
+              "code": 65533,
+              "mfgCode": null,
+              "side": "client",
+              "type": "int16u",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "1",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            }
+          ]
+        },
+        {
+          "name": "Thermostat User Interface Configuration",
+          "code": 516,
+          "mfgCode": null,
+          "define": "THERMOSTAT_USER_INTERFACE_CONFIGURATION_CLUSTER",
+          "side": "server",
+          "enabled": 1,
+          "attributes": [
+            {
+              "name": "temperature display mode",
+              "code": 0,
+              "mfgCode": null,
+              "side": "server",
+              "type": "enum8",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "0x00",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "keypad lockout",
+              "code": 1,
+              "mfgCode": null,
+              "side": "server",
+              "type": "enum8",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "0x00",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "schedule programming visibility",
+              "code": 2,
+              "mfgCode": null,
+              "side": "server",
+              "type": "enum8",
+              "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": "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": "Color Control",
           "code": 768,
@@ -14354,5 +14550,6 @@
       "endpointVersion": 1,
       "deviceIdentifier": 769
     }
-  ]
+  ],
+  "log": []
 }
\ No newline at end of file
diff --git a/zzz_generated/thermostat/zap-generated/access.h b/zzz_generated/thermostat/zap-generated/access.h
index 8babb2f23818a1..794789b5c57838 100644
--- a/zzz_generated/thermostat/zap-generated/access.h
+++ b/zzz_generated/thermostat/zap-generated/access.h
@@ -54,6 +54,7 @@
     /* Cluster: Thermostat, Attribute: MinSetpointDeadBand, Privilege: view */ \
     /* Cluster: Thermostat, Attribute: ControlSequenceOfOperation, Privilege: view */ \
     /* Cluster: Thermostat, Attribute: SystemMode, Privilege: view */ \
+    /* Cluster: Thermostat User Interface Configuration, Attribute: keypad lockout, Privilege: view */ \
 }
 
 // Parallel array data (cluster, *attribute*, privilege) for read attribute
@@ -83,6 +84,7 @@
     /* Cluster: Thermostat, Attribute: MinSetpointDeadBand, Privilege: view */ \
     /* Cluster: Thermostat, Attribute: ControlSequenceOfOperation, Privilege: view */ \
     /* Cluster: Thermostat, Attribute: SystemMode, Privilege: view */ \
+    /* Cluster: Thermostat User Interface Configuration, Attribute: keypad lockout, Privilege: view */ \
 }
 
 // Parallel array data (cluster, attribute, *privilege*) for read attribute
@@ -112,6 +114,7 @@
     /* Cluster: Thermostat, Attribute: MinSetpointDeadBand, Privilege: view */ \
     /* Cluster: Thermostat, Attribute: ControlSequenceOfOperation, Privilege: view */ \
     /* Cluster: Thermostat, Attribute: SystemMode, Privilege: view */ \
+    /* Cluster: Thermostat User Interface Configuration, Attribute: keypad lockout, Privilege: view */ \
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -134,6 +137,7 @@
     513, /* Cluster: Thermostat, Attribute: MinSetpointDeadBand, Privilege: manage */ \
     513, /* Cluster: Thermostat, Attribute: ControlSequenceOfOperation, Privilege: manage */ \
     513, /* Cluster: Thermostat, Attribute: SystemMode, Privilege: manage */ \
+    516, /* Cluster: Thermostat User Interface Configuration, Attribute: keypad lockout, Privilege: manage */ \
 }
 
 // Parallel array data (cluster, *attribute*, privilege) for write attribute
@@ -154,6 +158,7 @@
     25, /* Cluster: Thermostat, Attribute: MinSetpointDeadBand, Privilege: manage */ \
     27, /* Cluster: Thermostat, Attribute: ControlSequenceOfOperation, Privilege: manage */ \
     28, /* Cluster: Thermostat, Attribute: SystemMode, Privilege: manage */ \
+    1, /* Cluster: Thermostat User Interface Configuration, Attribute: keypad lockout, Privilege: manage */ \
 }
 
 // Parallel array data (cluster, attribute, *privilege*) for write attribute
@@ -174,6 +179,7 @@
     kMatterAccessPrivilegeManage, /* Cluster: Thermostat, Attribute: MinSetpointDeadBand, Privilege: manage */ \
     kMatterAccessPrivilegeManage, /* Cluster: Thermostat, Attribute: ControlSequenceOfOperation, Privilege: manage */ \
     kMatterAccessPrivilegeManage, /* Cluster: Thermostat, Attribute: SystemMode, Privilege: manage */ \
+    kMatterAccessPrivilegeManage, /* Cluster: Thermostat User Interface Configuration, Attribute: keypad lockout, Privilege: manage */ \
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/zzz_generated/thermostat/zap-generated/callback-stub.cpp b/zzz_generated/thermostat/zap-generated/callback-stub.cpp
index 9e6402a1003382..d000ee8a6cd453 100644
--- a/zzz_generated/thermostat/zap-generated/callback-stub.cpp
+++ b/zzz_generated/thermostat/zap-generated/callback-stub.cpp
@@ -92,6 +92,9 @@ void emberAfClusterInitCallback(EndpointId endpoint, ClusterId clusterId)
     case ZCL_THERMOSTAT_CLUSTER_ID:
         emberAfThermostatClusterInitCallback(endpoint);
         break;
+    case ZCL_THERMOSTAT_USER_INTERFACE_CONFIGURATION_CLUSTER_ID:
+        emberAfThermostatUserInterfaceConfigurationClusterInitCallback(endpoint);
+        break;
     case ZCL_THREAD_NETWORK_DIAGNOSTICS_CLUSTER_ID:
         emberAfThreadNetworkDiagnosticsClusterInitCallback(endpoint);
         break;
@@ -218,6 +221,11 @@ void __attribute__((weak)) emberAfThermostatClusterInitCallback(EndpointId endpo
     // To prevent warning
     (void) endpoint;
 }
+void __attribute__((weak)) emberAfThermostatUserInterfaceConfigurationClusterInitCallback(EndpointId endpoint)
+{
+    // To prevent warning
+    (void) endpoint;
+}
 void __attribute__((weak)) emberAfThreadNetworkDiagnosticsClusterInitCallback(EndpointId endpoint)
 {
     // To prevent warning
diff --git a/zzz_generated/thermostat/zap-generated/endpoint_config.h b/zzz_generated/thermostat/zap-generated/endpoint_config.h
index 6205237faed904..083e077e91e35a 100644
--- a/zzz_generated/thermostat/zap-generated/endpoint_config.h
+++ b/zzz_generated/thermostat/zap-generated/endpoint_config.h
@@ -78,7 +78,7 @@
     }
 
 // This is an array of EmberAfAttributeMinMaxValue structures.
-#define GENERATED_MIN_MAX_DEFAULT_COUNT 11
+#define GENERATED_MIN_MAX_DEFAULT_COUNT 13
 #define GENERATED_MIN_MAX_DEFAULTS                                                                                                 \
     {                                                                                                                              \
                                                                                                                                    \
@@ -97,14 +97,18 @@
             { (uint16_t) 0xC80, (uint16_t) -0x6AB3, (uint16_t) 0x7FFF }, /* MaxCoolSetpointLimit */                                \
             { (uint16_t) 0x19, (uint16_t) 0x0, (uint16_t) 0x19 },        /* MinSetpointDeadBand */                                 \
             { (uint16_t) 0x4, (uint16_t) 0x0, (uint16_t) 0x5 },          /* ControlSequenceOfOperation */                          \
+            { (uint16_t) 0x1, (uint16_t) 0x0, (uint16_t) 0x7 },          /* SystemMode */                                          \
+                                                                                                                                   \
+            /* Endpoint: 1, Cluster: Thermostat User Interface Configuration (server) */                                           \
+            { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0x1 }, /* temperature display mode */                                     \
         {                                                                                                                          \
-            (uint16_t) 0x1, (uint16_t) 0x0, (uint16_t) 0x7                                                                         \
-        } /* SystemMode */                                                                                                         \
+            (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0x5                                                                         \
+        } /* keypad lockout */                                                                                                     \
     }
 
 #define ZAP_ATTRIBUTE_MASK(mask) ATTRIBUTE_MASK_##mask
 // This is an array of EmberAfAttributeMetadata structures.
-#define GENERATED_ATTRIBUTE_COUNT 261
+#define GENERATED_ATTRIBUTE_COUNT 249
 #define GENERATED_ATTRIBUTES                                                                                                       \
     {                                                                                                                              \
                                                                                                                                    \
@@ -483,50 +487,13 @@
             { 0x0000FFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_SIMPLE_DEFAULT(0) },      /* FeatureMap */                                 \
             { 0x0000FFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(4) },        /* ClusterRevision */                            \
                                                                                                                                    \
-            /* Endpoint: 1, Cluster: Basic (server) */                                                                             \
-            { 0x00000000, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON),               \
-              ZAP_EMPTY_DEFAULT() }, /* DataModelRevision */                                                                       \
-            { 0x00000001, ZAP_TYPE(CHAR_STRING), 33, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON),         \
-              ZAP_EMPTY_DEFAULT() }, /* VendorName */                                                                              \
-            { 0x00000002, ZAP_TYPE(VENDOR_ID), 2, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON),            \
-              ZAP_EMPTY_DEFAULT() }, /* VendorID */                                                                                \
-            { 0x00000003, ZAP_TYPE(CHAR_STRING), 33, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON),         \
-              ZAP_EMPTY_DEFAULT() }, /* ProductName */                                                                             \
-            { 0x00000004, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON),               \
-              ZAP_EMPTY_DEFAULT() }, /* ProductID */                                                                               \
-            { 0x00000005, ZAP_TYPE(CHAR_STRING), 33,                                                                               \
-              ZAP_ATTRIBUTE_MASK(TOKENIZE) | ZAP_ATTRIBUTE_MASK(SINGLETON) | ZAP_ATTRIBUTE_MASK(WRITABLE),                         \
-              ZAP_EMPTY_DEFAULT() }, /* NodeLabel */                                                                               \
-            { 0x00000006, ZAP_TYPE(CHAR_STRING), 3,                                                                                \
-              ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON) | ZAP_ATTRIBUTE_MASK(WRITABLE),                 \
-              ZAP_EMPTY_DEFAULT() }, /* Location */                                                                                \
-            { 0x00000007, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON),               \
-              ZAP_EMPTY_DEFAULT() }, /* HardwareVersion */                                                                         \
-            { 0x00000008, ZAP_TYPE(CHAR_STRING), 65, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON),         \
-              ZAP_EMPTY_DEFAULT() }, /* HardwareVersionString */                                                                   \
-            { 0x00000009, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON),               \
-              ZAP_EMPTY_DEFAULT() }, /* SoftwareVersion */                                                                         \
-            { 0x0000000A, ZAP_TYPE(CHAR_STRING), 65, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON),         \
-              ZAP_EMPTY_DEFAULT() }, /* SoftwareVersionString */                                                                   \
-            { 0x0000000B, ZAP_TYPE(CHAR_STRING), 17, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON),         \
-              ZAP_EMPTY_DEFAULT() }, /* ManufacturingDate */                                                                       \
-            { 0x0000000C, ZAP_TYPE(CHAR_STRING), 33, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON),         \
-              ZAP_EMPTY_DEFAULT() }, /* PartNumber */                                                                              \
-            { 0x0000000D, ZAP_TYPE(LONG_CHAR_STRING), 258, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON),   \
-              ZAP_EMPTY_DEFAULT() }, /* ProductURL */                                                                              \
-            { 0x0000000E, ZAP_TYPE(CHAR_STRING), 65, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON),         \
-              ZAP_EMPTY_DEFAULT() }, /* ProductLabel */                                                                            \
-            { 0x0000000F, ZAP_TYPE(CHAR_STRING), 33, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON),         \
-              ZAP_EMPTY_DEFAULT() }, /* SerialNumber */                                                                            \
-            { 0x00000010, ZAP_TYPE(BOOLEAN), 1,                                                                                    \
-              ZAP_ATTRIBUTE_MASK(TOKENIZE) | ZAP_ATTRIBUTE_MASK(SINGLETON) | ZAP_ATTRIBUTE_MASK(WRITABLE),                         \
-              ZAP_SIMPLE_DEFAULT(0) },                                                                  /* LocalConfigDisabled */  \
-            { 0x00000011, ZAP_TYPE(BOOLEAN), 1, ZAP_ATTRIBUTE_MASK(SINGLETON), ZAP_SIMPLE_DEFAULT(1) }, /* Reachable */            \
-            { 0x00000012, ZAP_TYPE(CHAR_STRING), 33, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON),         \
-              ZAP_EMPTY_DEFAULT() },                                                                        /* UniqueID */         \
-            { 0x00000013, ZAP_TYPE(STRUCT), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* CapabilityMinima */ \
+            /* Endpoint: 1, Cluster: Descriptor (server) */                                                                        \
+            { 0x00000000, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() },  /* DeviceTypeList */   \
+            { 0x00000001, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() },  /* ServerList */       \
+            { 0x00000002, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() },  /* ClientList */       \
+            { 0x00000003, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() },  /* PartsList */        \
             { 0x0000FFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_SIMPLE_DEFAULT(0) },                                /* FeatureMap */       \
-            { 0x0000FFFD, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(SINGLETON), ZAP_SIMPLE_DEFAULT(1) },      /* ClusterRevision */  \
+            { 0x0000FFFD, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* ClusterRevision */  \
                                                                                                                                    \
             /* Endpoint: 1, Cluster: Thermostat (server) */                                                                        \
             { 0x00000000, ZAP_TYPE(INT16S), 2, ZAP_ATTRIBUTE_MASK(NULLABLE), ZAP_EMPTY_DEFAULT() }, /* LocalTemperature */         \
@@ -534,9 +501,11 @@
             { 0x00000004, ZAP_TYPE(INT16S), 2, 0, ZAP_SIMPLE_DEFAULT(3000) },                       /* AbsMaxHeatSetpointLimit */  \
             { 0x00000005, ZAP_TYPE(INT16S), 2, 0, ZAP_SIMPLE_DEFAULT(1600) },                       /* AbsMinCoolSetpointLimit */  \
             { 0x00000006, ZAP_TYPE(INT16S), 2, 0, ZAP_SIMPLE_DEFAULT(3200) },                       /* AbsMaxCoolSetpointLimit */  \
-            { 0x00000011, ZAP_TYPE(INT16S), 2, ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE),                         \
+            { 0x00000011, ZAP_TYPE(INT16S), 2,                                                                                     \
+              ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(TOKENIZE) | ZAP_ATTRIBUTE_MASK(WRITABLE),                           \
               ZAP_MIN_MAX_DEFAULTS_INDEX(2) }, /* OccupiedCoolingSetpoint */                                                       \
-            { 0x00000012, ZAP_TYPE(INT16S), 2, ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE),                         \
+            { 0x00000012, ZAP_TYPE(INT16S), 2,                                                                                     \
+              ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(TOKENIZE) | ZAP_ATTRIBUTE_MASK(WRITABLE),                           \
               ZAP_MIN_MAX_DEFAULTS_INDEX(3) }, /* OccupiedHeatingSetpoint */                                                       \
             { 0x00000015, ZAP_TYPE(INT16S), 2, ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE),                         \
               ZAP_MIN_MAX_DEFAULTS_INDEX(4) }, /* MinHeatSetpointLimit */                                                          \
@@ -550,10 +519,19 @@
               ZAP_MIN_MAX_DEFAULTS_INDEX(8) }, /* MinSetpointDeadBand */                                                           \
             { 0x0000001B, ZAP_TYPE(ENUM8), 1, ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE),                          \
               ZAP_MIN_MAX_DEFAULTS_INDEX(9) }, /* ControlSequenceOfOperation */                                                    \
-            { 0x0000001C, ZAP_TYPE(ENUM8), 1, ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE),                          \
+            { 0x0000001C, ZAP_TYPE(ENUM8), 1,                                                                                      \
+              ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(TOKENIZE) | ZAP_ATTRIBUTE_MASK(WRITABLE),                           \
               ZAP_MIN_MAX_DEFAULTS_INDEX(10) },                                 /* SystemMode */                                   \
             { 0x0000FFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_SIMPLE_DEFAULT(0x23) }, /* FeatureMap */                                   \
             { 0x0000FFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(5) },      /* ClusterRevision */                              \
+                                                                                                                                   \
+            /* Endpoint: 1, Cluster: Thermostat User Interface Configuration (server) */                                           \
+            { 0x00000000, ZAP_TYPE(ENUM8), 1, ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE),                          \
+              ZAP_MIN_MAX_DEFAULTS_INDEX(11) }, /* temperature display mode */                                                     \
+            { 0x00000001, ZAP_TYPE(ENUM8), 1, ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE),                          \
+              ZAP_MIN_MAX_DEFAULTS_INDEX(12) },                              /* keypad lockout */                                  \
+            { 0x0000FFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_SIMPLE_DEFAULT(0) }, /* FeatureMap */                                      \
+            { 0x0000FFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(1) },   /* ClusterRevision */                                 \
     }
 
 // This is an array of EmberAfCluster structures.
@@ -587,6 +565,9 @@
     const EmberAfGenericClusterFunction chipFuncArrayThermostatServer[] = {                                                        \
         (EmberAfGenericClusterFunction) emberAfThermostatClusterServerInitCallback,                                                \
         (EmberAfGenericClusterFunction) MatterThermostatClusterServerPreAttributeChangedCallback,                                  \
+    };                                                                                                                             \
+    const EmberAfGenericClusterFunction chipFuncArrayThermostatUserInterfaceConfigurationServer[] = {                              \
+        (EmberAfGenericClusterFunction) MatterThermostatUserInterfaceConfigurationClusterServerPreAttributeChangedCallback,        \
     };
 
 // clang-format off
@@ -704,7 +685,7 @@
 // clang-format on
 
 #define ZAP_CLUSTER_MASK(mask) CLUSTER_MASK_##mask
-#define GENERATED_CLUSTER_COUNT 29
+#define GENERATED_CLUSTER_COUNT 30
 
 // clang-format off
 #define GENERATED_CLUSTERS { \
@@ -1006,20 +987,20 @@
       .generatedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 69 ) ,\
     },\
   { \
-      /* Endpoint: 1, Cluster: Basic (server) */ \
-      .clusterId = 0x00000028,  \
+      /* Endpoint: 1, Cluster: Descriptor (server) */ \
+      .clusterId = 0x0000001D,  \
       .attributes = ZAP_ATTRIBUTE_INDEX(223), \
-      .attributeCount = 22, \
-      .clusterSize = 41, \
-      .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \
-      .functions = chipFuncArrayBasicServer, \
+      .attributeCount = 6, \
+      .clusterSize = 4, \
+      .mask = ZAP_CLUSTER_MASK(SERVER), \
+      .functions = NULL, \
       .acceptedCommandList = nullptr ,\
       .generatedCommandList = nullptr ,\
     },\
   { \
       /* Endpoint: 1, Cluster: Thermostat (server) */ \
       .clusterId = 0x00000201,  \
-      .attributes = ZAP_ATTRIBUTE_INDEX(245), \
+      .attributes = ZAP_ATTRIBUTE_INDEX(229), \
       .attributeCount = 16, \
       .clusterSize = 31, \
       .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION) | ZAP_CLUSTER_MASK(PRE_ATTRIBUTE_CHANGED_FUNCTION), \
@@ -1027,18 +1008,29 @@
       .acceptedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 76 ) ,\
       .generatedCommandList = nullptr ,\
     },\
+  { \
+      /* Endpoint: 1, Cluster: Thermostat User Interface Configuration (server) */ \
+      .clusterId = 0x00000204,  \
+      .attributes = ZAP_ATTRIBUTE_INDEX(245), \
+      .attributeCount = 4, \
+      .clusterSize = 8, \
+      .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(PRE_ATTRIBUTE_CHANGED_FUNCTION), \
+      .functions = chipFuncArrayThermostatUserInterfaceConfigurationServer, \
+      .acceptedCommandList = nullptr ,\
+      .generatedCommandList = nullptr ,\
+    },\
 }
 
 // clang-format on
 
 #define ZAP_CLUSTER_INDEX(index) (&generatedClusters[index])
 
-#define ZAP_FIXED_ENDPOINT_DATA_VERSION_COUNT 27
+#define ZAP_FIXED_ENDPOINT_DATA_VERSION_COUNT 28
 
 // This is an array of EmberAfEndpointType structures.
 #define GENERATED_ENDPOINT_TYPES                                                                                                   \
     {                                                                                                                              \
-        { ZAP_CLUSTER_INDEX(0), 23, 259 }, { ZAP_CLUSTER_INDEX(23), 6, 100 },                                                      \
+        { ZAP_CLUSTER_INDEX(0), 23, 259 }, { ZAP_CLUSTER_INDEX(23), 7, 71 },                                                       \
     }
 
 // Largest attribute size is needed for various buffers
@@ -1047,10 +1039,10 @@
 static_assert(ATTRIBUTE_LARGEST <= CHIP_CONFIG_MAX_ATTRIBUTE_STORE_ELEMENT_SIZE, "ATTRIBUTE_LARGEST larger than expected");
 
 // Total size of singleton attributes
-#define ATTRIBUTE_SINGLETONS_SIZE (74)
+#define ATTRIBUTE_SINGLETONS_SIZE (37)
 
 // Total size of attribute storage
-#define ATTRIBUTE_MAX_SIZE (359)
+#define ATTRIBUTE_MAX_SIZE (330)
 
 // Number of fixed endpoints
 #define FIXED_ENDPOINT_COUNT (2)
diff --git a/zzz_generated/thermostat/zap-generated/gen_config.h b/zzz_generated/thermostat/zap-generated/gen_config.h
index 0f3fd1f8c1698d..86a851c2c39483 100644
--- a/zzz_generated/thermostat/zap-generated/gen_config.h
+++ b/zzz_generated/thermostat/zap-generated/gen_config.h
@@ -33,10 +33,10 @@
 #define EMBER_AF_IDENTIFY_CLUSTER_SERVER_ENDPOINT_COUNT (2)
 #define EMBER_AF_GROUPS_CLUSTER_SERVER_ENDPOINT_COUNT (1)
 #define EMBER_AF_SCENES_CLUSTER_SERVER_ENDPOINT_COUNT (1)
-#define EMBER_AF_DESCRIPTOR_CLUSTER_SERVER_ENDPOINT_COUNT (1)
+#define EMBER_AF_DESCRIPTOR_CLUSTER_SERVER_ENDPOINT_COUNT (2)
 #define EMBER_AF_BINDING_CLUSTER_SERVER_ENDPOINT_COUNT (1)
 #define EMBER_AF_ACCESS_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT (1)
-#define EMBER_AF_BASIC_CLUSTER_SERVER_ENDPOINT_COUNT (2)
+#define EMBER_AF_BASIC_CLUSTER_SERVER_ENDPOINT_COUNT (1)
 #define EMBER_AF_OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER_CLIENT_ENDPOINT_COUNT (1)
 #define EMBER_AF_OTA_SOFTWARE_UPDATE_REQUESTOR_CLUSTER_SERVER_ENDPOINT_COUNT (1)
 #define EMBER_AF_LOCALIZATION_CONFIGURATION_CLUSTER_SERVER_ENDPOINT_COUNT (1)
@@ -56,6 +56,7 @@
 #define EMBER_AF_FIXED_LABEL_CLUSTER_SERVER_ENDPOINT_COUNT (1)
 #define EMBER_AF_USER_LABEL_CLUSTER_SERVER_ENDPOINT_COUNT (1)
 #define EMBER_AF_THERMOSTAT_CLUSTER_SERVER_ENDPOINT_COUNT (1)
+#define EMBER_AF_THERMOSTAT_USER_INTERFACE_CONFIGURATION_CLUSTER_SERVER_ENDPOINT_COUNT (1)
 
 /**** Cluster Plugins ****/
 
@@ -203,3 +204,8 @@
 #define ZCL_USING_THERMOSTAT_CLUSTER_SERVER
 #define EMBER_AF_PLUGIN_THERMOSTAT_SERVER
 #define EMBER_AF_PLUGIN_THERMOSTAT
+
+// Use this macro to check if the server side of the Thermostat User Interface Configuration cluster is included
+#define ZCL_USING_THERMOSTAT_USER_INTERFACE_CONFIGURATION_CLUSTER_SERVER
+#define EMBER_AF_PLUGIN_THERMOSTAT_USER_INTERFACE_CONFIGURATION_SERVER
+#define EMBER_AF_PLUGIN_THERMOSTAT_USER_INTERFACE_CONFIGURATION