diff --git a/CMakeLists.txt b/CMakeLists.txt
index eba1a3fd824..ed9ae23f83f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -176,6 +176,7 @@ set(ARDUINO_LIBRARY_Matter_SRCS
   libraries/Matter/src/MatterEndpoints/MatterEnhancedColorLight.cpp
   libraries/Matter/src/MatterEndpoints/MatterFan.cpp
   libraries/Matter/src/MatterEndpoints/MatterTemperatureSensor.cpp
+  libraries/Matter/src/MatterEndpoints/MatterHumiditySensor.cpp
   libraries/Matter/src/Matter.cpp)
 
 set(ARDUINO_LIBRARY_PPP_SRCS
diff --git a/libraries/Matter/examples/MatterHumiditySensor/MatterHumiditySensor.ino b/libraries/Matter/examples/MatterHumiditySensor/MatterHumiditySensor.ino
new file mode 100644
index 00000000000..c4977772c1b
--- /dev/null
+++ b/libraries/Matter/examples/MatterHumiditySensor/MatterHumiditySensor.ino
@@ -0,0 +1,130 @@
+// Copyright 2024 Espressif Systems (Shanghai) PTE LTD
+//
+// 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.
+
+/*
+ * This example is an example code that will create a Matter Device which can be
+ * commissioned and controlled from a Matter Environment APP.
+ * Additionally the ESP32 will send debug messages indicating the Matter activity.
+ * Turning DEBUG Level ON may be useful to following Matter Accessory and Controller messages.
+ */
+
+// Matter Manager
+#include <Matter.h>
+#include <WiFi.h>
+
+// List of Matter Endpoints for this Node
+// Matter Humidity Sensor Endpoint
+MatterHumiditySensor SimulatedHumiditySensor;
+
+// set your board USER BUTTON pin here - decommissioning button
+const uint8_t buttonPin = BOOT_PIN;  // Set your pin here. Using BOOT Button.
+
+// WiFi is manually set and started
+const char *ssid = "your-ssid";          // Change this to your WiFi SSID
+const char *password = "your-password";  // Change this to your WiFi password
+
+// Button control - decommision the Matter Node
+uint32_t button_time_stamp = 0;                // debouncing control
+bool button_state = false;                     // false = released | true = pressed
+const uint32_t decommissioningTimeout = 5000;  // keep the button pressed for 5s, or longer, to decommission
+
+// Simulate a humidity sensor - add your preferred humidity sensor library code here
+float getSimulatedHumidity() {
+  // The Endpoint implementation keeps an uint16_t as internal value information,
+  // which stores data in 1/100th of humidity percent
+  static float simulatedHumidityHWSensor = 10.0;
+
+  // it will increase from 10% to 30% in 0.5% steps to simulate a humidity sensor
+  simulatedHumidityHWSensor = simulatedHumidityHWSensor + 0.5;
+  if (simulatedHumidityHWSensor > 30) {
+    simulatedHumidityHWSensor = 10;
+  }
+
+  return simulatedHumidityHWSensor;
+}
+
+void setup() {
+  // Initialize the USER BUTTON (Boot button) that will be used to decommission the Matter Node
+  pinMode(buttonPin, INPUT_PULLUP);
+
+  Serial.begin(115200);
+
+  // Manually connect to WiFi
+  WiFi.begin(ssid, password);
+  // Wait for connection
+  while (WiFi.status() != WL_CONNECTED) {
+    delay(500);
+    Serial.print(".");
+  }
+  Serial.println();
+
+  // set initial humidity sensor measurement
+  // Simulated Sensor - it shall initially print 95% and then move to the 10% to 30% humidity range
+  SimulatedHumiditySensor.begin(95.00);
+
+  // Matter beginning - Last step, after all EndPoints are initialized
+  Matter.begin();
+
+  // Check Matter Accessory Commissioning state, which may change during execution of loop()
+  if (!Matter.isDeviceCommissioned()) {
+    Serial.println("");
+    Serial.println("Matter Node is not commissioned yet.");
+    Serial.println("Initiate the device discovery in your Matter environment.");
+    Serial.println("Commission it to your Matter hub with the manual pairing code or QR code");
+    Serial.printf("Manual pairing code: %s\r\n", Matter.getManualPairingCode().c_str());
+    Serial.printf("QR code URL: %s\r\n", Matter.getOnboardingQRCodeUrl().c_str());
+    // waits for Matter Humidity Sensor Commissioning.
+    uint32_t timeCount = 0;
+    while (!Matter.isDeviceCommissioned()) {
+      delay(100);
+      if ((timeCount++ % 50) == 0) {  // 50*100ms = 5 sec
+        Serial.println("Matter Node not commissioned yet. Waiting for commissioning.");
+      }
+    }
+    Serial.println("Matter Node is commissioned and connected to Wi-Fi. Ready for use.");
+  }
+}
+
+void loop() {
+  static uint32_t timeCounter = 0;
+
+  // Print the current humidity value every 5s
+  if (!(timeCounter++ % 10)) {  // delaying for 500ms x 10 = 5s
+    // Print the current humidity value
+    Serial.printf("Current Humidity is %.02f%%\r\n", SimulatedHumiditySensor.getHumidity());
+    // Update Humidity from the (Simulated) Hardware Sensor
+    // Matter APP shall display the updated humidity percent
+    SimulatedHumiditySensor.setHumidity(getSimulatedHumidity());
+  }
+
+  // Check if the button has been pressed
+  if (digitalRead(buttonPin) == LOW && !button_state) {
+    // deals with button debouncing
+    button_time_stamp = millis();  // record the time while the button is pressed.
+    button_state = true;           // pressed.
+  }
+
+  if (digitalRead(buttonPin) == HIGH && button_state) {
+    button_state = false;  // released
+  }
+
+  // Onboard User Button is kept pressed for longer than 5 seconds in order to decommission matter node
+  uint32_t time_diff = millis() - button_time_stamp;
+  if (button_state && time_diff > decommissioningTimeout) {
+    Serial.println("Decommissioning the Light Matter Accessory. It shall be commissioned again.");
+    Matter.decommission();
+  }
+
+  delay(500);
+}
diff --git a/libraries/Matter/examples/MatterHumiditySensor/ci.json b/libraries/Matter/examples/MatterHumiditySensor/ci.json
new file mode 100644
index 00000000000..556a8a9ee6b
--- /dev/null
+++ b/libraries/Matter/examples/MatterHumiditySensor/ci.json
@@ -0,0 +1,7 @@
+{
+  "fqbn_append": "PartitionScheme=huge_app",
+  "requires": [
+    "CONFIG_SOC_WIFI_SUPPORTED=y",
+    "CONFIG_ESP_MATTER_ENABLE_DATA_MODEL=y"
+  ]
+}
diff --git a/libraries/Matter/keywords.txt b/libraries/Matter/keywords.txt
index 60ffc546bd6..c54b040d94b 100644
--- a/libraries/Matter/keywords.txt
+++ b/libraries/Matter/keywords.txt
@@ -19,6 +19,7 @@ MatterFan	KEYWORD1
 FanMode_t	KEYWORD1
 FanModeSequence_t	KEYWORD1
 MatterTemperatureSensor	KEYWORD1
+MatterHumiditySensor	KEYWORD1
 
 #######################################
 # Methods and Functions (KEYWORD2)
@@ -65,6 +66,8 @@ onChangeMode	KEYWORD2
 onChangeSpeedPercent	KEYWORD2
 setTemperature	KEYWORD2
 getTemperature	KEYWORD2
+setHumidity	KEYWORD2
+getHumidity	KEYWORD2
 
 #######################################
 # Constants (LITERAL1)
diff --git a/libraries/Matter/src/Matter.h b/libraries/Matter/src/Matter.h
index 1b35d876705..4b7804d61df 100644
--- a/libraries/Matter/src/Matter.h
+++ b/libraries/Matter/src/Matter.h
@@ -27,6 +27,7 @@
 #include <MatterEndpoints/MatterEnhancedColorLight.h>
 #include <MatterEndpoints/MatterFan.h>
 #include <MatterEndpoints/MatterTemperatureSensor.h>
+#include <MatterEndpoints/MatterHumiditySensor.h>
 
 using namespace esp_matter;
 
@@ -60,6 +61,7 @@ class ArduinoMatter {
   friend class MatterEnhancedColorLight;
   friend class MatterFan;
   friend class MatterTemperatureSensor;
+  friend class MatterHumiditySensor;
 
 protected:
   static void _init();
diff --git a/libraries/Matter/src/MatterEndpoints/MatterHumiditySensor.cpp b/libraries/Matter/src/MatterEndpoints/MatterHumiditySensor.cpp
new file mode 100644
index 00000000000..3e911606074
--- /dev/null
+++ b/libraries/Matter/src/MatterEndpoints/MatterHumiditySensor.cpp
@@ -0,0 +1,111 @@
+// Copyright 2024 Espressif Systems (Shanghai) PTE LTD
+//
+// 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 <sdkconfig.h>
+#ifdef CONFIG_ESP_MATTER_ENABLE_DATA_MODEL
+
+#include <Matter.h>
+#include <app/server/Server.h>
+#include <MatterEndpoints/MatterHumiditySensor.h>
+
+using namespace esp_matter;
+using namespace esp_matter::endpoint;
+using namespace chip::app::Clusters;
+
+bool MatterHumiditySensor::attributeChangeCB(uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_id, esp_matter_attr_val_t *val) {
+  bool ret = true;
+  if (!started) {
+    log_e("Matter Humidity Sensor device has not begun.");
+    return false;
+  }
+
+  log_d("Humidity Sensor Attr update callback: endpoint: %u, cluster: %u, attribute: %u, val: %u", endpoint_id, cluster_id, attribute_id, val->val.u32);
+  return ret;
+}
+
+MatterHumiditySensor::MatterHumiditySensor() {}
+
+MatterHumiditySensor::~MatterHumiditySensor() {
+  end();
+}
+
+bool MatterHumiditySensor::begin(uint16_t _rawHumidity) {
+  ArduinoMatter::_init();
+
+  // is it a valid percentage value?
+  if (_rawHumidity > 10000) {
+    log_e("Humidity Sensor Percentage value out of range [0..100].");
+    return false;
+  }
+
+  humidity_sensor::config_t humidity_sensor_config;
+  humidity_sensor_config.relative_humidity_measurement.measured_value = _rawHumidity;
+  humidity_sensor_config.relative_humidity_measurement.min_measured_value = nullptr;
+  humidity_sensor_config.relative_humidity_measurement.max_measured_value = nullptr;
+
+  // endpoint handles can be used to add/modify clusters.
+  endpoint_t *endpoint = humidity_sensor::create(node::get(), &humidity_sensor_config, ENDPOINT_FLAG_NONE, (void *)this);
+  if (endpoint == nullptr) {
+    log_e("Failed to create Humidity Sensor endpoint");
+    return false;
+  }
+  rawHumidity = _rawHumidity;
+  setEndPointId(endpoint::get_id(endpoint));
+  log_i("Humidity Sensor created with endpoint_id %d", getEndPointId());
+  started = true;
+  return true;
+}
+
+void MatterHumiditySensor::end() {
+  started = false;
+}
+
+bool MatterHumiditySensor::setRawHumidity(uint16_t _rawHumidity) {
+  if (!started) {
+    log_e("Matter Humidity Sensor device has not begun.");
+    return false;
+  }
+  // is it a valid percentage value?
+  if (_rawHumidity > 10000) {
+    log_e("Humidity Sensor Percentage value out of range [0..100].");
+    return false;
+  }
+
+  // avoid processing the a "no-change"
+  if (rawHumidity == _rawHumidity) {
+    return true;
+  }
+
+  esp_matter_attr_val_t humidityVal = esp_matter_invalid(NULL);
+
+  if (!getAttributeVal(RelativeHumidityMeasurement::Id, RelativeHumidityMeasurement::Attributes::MeasuredValue::Id, &humidityVal)) {
+    log_e("Failed to get Humidity Sensor Attribute.");
+    return false;
+  }
+  if (humidityVal.val.u16 != _rawHumidity) {
+    humidityVal.val.u16 = _rawHumidity;
+    bool ret;
+    ret = updateAttributeVal(RelativeHumidityMeasurement::Id, RelativeHumidityMeasurement::Attributes::MeasuredValue::Id, &humidityVal);
+    if (!ret) {
+      log_e("Failed to update Fan Speed Percent Attribute.");
+      return false;
+    }
+    rawHumidity = _rawHumidity;
+  }
+  log_v("Humidity Sensor set to %.02f Percent", (float)_rawHumidity / 100.00);
+
+  return true;
+}
+
+#endif /* CONFIG_ESP_MATTER_ENABLE_DATA_MODEL */
diff --git a/libraries/Matter/src/MatterEndpoints/MatterHumiditySensor.h b/libraries/Matter/src/MatterEndpoints/MatterHumiditySensor.h
new file mode 100644
index 00000000000..aed758b7b7a
--- /dev/null
+++ b/libraries/Matter/src/MatterEndpoints/MatterHumiditySensor.h
@@ -0,0 +1,69 @@
+// Copyright 2024 Espressif Systems (Shanghai) PTE LTD
+//
+// 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 <sdkconfig.h>
+#ifdef CONFIG_ESP_MATTER_ENABLE_DATA_MODEL
+
+#include <Matter.h>
+#include <MatterEndPoint.h>
+
+class MatterHumiditySensor : public MatterEndPoint {
+public:
+  MatterHumiditySensor();
+  ~MatterHumiditySensor();
+  // begin Matter Humidity Sensor endpoint with initial float humidity percent
+  bool begin(double humidityPercent = 0.00) {
+    if (humidityPercent < 0.0 || humidityPercent > 100.0) {
+      log_e("Humidity Sensor Percentage value out of range [0..100].");
+      return false;
+    }
+    return begin(static_cast<uint16_t>(humidityPercent * 100.0f));
+  }
+  // this will just stop processing Humidity Sensor Matter events
+  void end();
+
+  // set the humidity percent with 1/100th of a percent precision
+  bool setHumidity(double humidityPercent) {
+    if (humidityPercent < 0.0 || humidityPercent > 100.0) {
+      log_e("Humidity Sensor Percentage value out of range [0..100].");
+      return false;
+    }
+    return setRawHumidity(static_cast<uint16_t>(humidityPercent * 100.0f));
+  }
+  // returns the reported float humidity percent with 1/100th of precision
+  double getHumidity() {
+    return (double)rawHumidity / 100.0;
+  }
+  // double conversion operator
+  void operator=(double humidityPercent) {
+    setHumidity(humidityPercent);
+  }
+  // double conversion operator
+  operator double() {
+    return (double)getHumidity();
+  }
+
+  // this function is called by Matter internal event processor. It could be overwritten by the application, if necessary.
+  bool attributeChangeCB(uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_id, esp_matter_attr_val_t *val);
+
+protected:
+  bool started = false;
+  // implementation keeps humidity relative percentage with 1/100th of a percent precision
+  uint16_t rawHumidity = 0;
+  // internal function to set the raw humidity value (Matter Cluster)
+  bool begin(uint16_t _rawHumidity);
+  bool setRawHumidity(uint16_t _rawHumidity);
+};
+#endif /* CONFIG_ESP_MATTER_ENABLE_DATA_MODEL */