diff --git a/boards.txt b/boards.txt
index 26ec251ecfe..e1f18e50157 100644
--- a/boards.txt
+++ b/boards.txt
@@ -453,6 +453,9 @@ esp32h2.menu.PartitionScheme.app3M_fat9M_16MB.upload.maximum_size=3145728
 esp32h2.menu.PartitionScheme.zigbee=Zigbee 4MB with spiffs
 esp32h2.menu.PartitionScheme.zigbee.build.partitions=zigbee
 esp32h2.menu.PartitionScheme.zigbee.upload.maximum_size=1310720
+esp32h2.menu.PartitionScheme.zigbee_2MB=Zigbee 2MB with spiffs
+esp32h2.menu.PartitionScheme.zigbee_2MB.build.partitions=zigbee_2MB
+esp32h2.menu.PartitionScheme.zigbee_2MB.upload.maximum_size=1310720
 esp32h2.menu.PartitionScheme.zigbee_zczr=Zigbee ZCZR 4MB with spiffs
 esp32h2.menu.PartitionScheme.zigbee_zczr.build.partitions=zigbee_zczr
 esp32h2.menu.PartitionScheme.zigbee_zczr.upload.maximum_size=1310720
@@ -645,6 +648,9 @@ esp32c6.menu.PartitionScheme.rainmaker_8MB.upload.maximum_size=4116480
 esp32c6.menu.PartitionScheme.zigbee=Zigbee 4MB with spiffs
 esp32c6.menu.PartitionScheme.zigbee.build.partitions=zigbee
 esp32c6.menu.PartitionScheme.zigbee.upload.maximum_size=1310720
+esp32c6.menu.PartitionScheme.zigbee_2MB=Zigbee 2MB with spiffs
+esp32c6.menu.PartitionScheme.zigbee_2MB.build.partitions=zigbee_2MB
+esp32c6.menu.PartitionScheme.zigbee_2MB.upload.maximum_size=1310720
 esp32c6.menu.PartitionScheme.zigbee_zczr=Zigbee ZCZR 4MB with spiffs
 esp32c6.menu.PartitionScheme.zigbee_zczr.build.partitions=zigbee_zczr
 esp32c6.menu.PartitionScheme.zigbee_zczr.upload.maximum_size=1310720
diff --git a/libraries/Zigbee/examples/Zigbee_On_Off_Switch/Zigbee_On_Off_Switch.ino b/libraries/Zigbee/examples/Zigbee_On_Off_Switch/Zigbee_On_Off_Switch.ino
index 56d23cdc95f..0721371ce0e 100644
--- a/libraries/Zigbee/examples/Zigbee_On_Off_Switch/Zigbee_On_Off_Switch.ino
+++ b/libraries/Zigbee/examples/Zigbee_On_Off_Switch/Zigbee_On_Off_Switch.ino
@@ -143,8 +143,14 @@ void setup() {
       "IEEE Address: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\r\n", device->ieee_addr[7], device->ieee_addr[6], device->ieee_addr[5], device->ieee_addr[4],
       device->ieee_addr[3], device->ieee_addr[2], device->ieee_addr[1], device->ieee_addr[0]
     );
-    Serial.printf("Light manufacturer: %s\r\n", zbSwitch.readManufacturer(device->endpoint, device->short_addr, device->ieee_addr));
-    Serial.printf("Light model: %s\r\n", zbSwitch.readModel(device->endpoint, device->short_addr, device->ieee_addr));
+    char *manufacturer = zbSwitch.readManufacturer(device->endpoint, device->short_addr, device->ieee_addr);
+    char *model = zbSwitch.readModel(device->endpoint, device->short_addr, device->ieee_addr);
+    if (manufacturer != nullptr) {
+      Serial.printf("Light manufacturer: %s\r\n", manufacturer);
+    }
+    if (model != nullptr) {
+      Serial.printf("Light model: %s\r\n", model);
+    }
   }
 
   Serial.println();
diff --git a/libraries/Zigbee/src/ZigbeeCore.cpp b/libraries/Zigbee/src/ZigbeeCore.cpp
index cc0111f2644..0a3177919da 100644
--- a/libraries/Zigbee/src/ZigbeeCore.cpp
+++ b/libraries/Zigbee/src/ZigbeeCore.cpp
@@ -314,7 +314,20 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct) {
         // for each endpoint in the list call the findEndpoint function if not bounded or allowed to bind multiple devices
         for (std::list<ZigbeeEP *>::iterator it = Zigbee.ep_objects.begin(); it != Zigbee.ep_objects.end(); ++it) {
           if (!(*it)->bound() || (*it)->epAllowMultipleBinding()) {
-            (*it)->findEndpoint(&cmd_req);
+            // Check if the device is already bound
+            bool found = false;
+            // Get the list of devices bound to the EP
+            std::list<zb_device_params_t *> bound_devices = (*it)->getBoundDevices();
+            for (std::list<zb_device_params_t *>::iterator device = bound_devices.begin(); device != bound_devices.end(); ++device) {
+              if (((*device)->short_addr == dev_annce_params->device_short_addr) || (memcmp((*device)->ieee_addr, dev_annce_params->ieee_addr, 8) == 0)) {
+                found = true;
+                log_d("Device already bound to endpoint %d", (*it)->getEndpoint());
+                break;
+              }
+            }
+            if (!found) {
+              (*it)->findEndpoint(&cmd_req);
+            }
           }
         }
       }
diff --git a/libraries/Zigbee/src/ZigbeeEP.cpp b/libraries/Zigbee/src/ZigbeeEP.cpp
index dbfe8596268..61f2fa8d2de 100644
--- a/libraries/Zigbee/src/ZigbeeEP.cpp
+++ b/libraries/Zigbee/src/ZigbeeEP.cpp
@@ -7,8 +7,6 @@
 #include "esp_zigbee_cluster.h"
 #include "zcl/esp_zigbee_zcl_power_config.h"
 
-#define ZB_CMD_TIMEOUT 10000  // 10 seconds
-
 bool ZigbeeEP::_is_bound = false;
 bool ZigbeeEP::_allow_multiple_binding = false;
 
diff --git a/libraries/Zigbee/src/ZigbeeEP.h b/libraries/Zigbee/src/ZigbeeEP.h
index 522c84620ff..a5e9efa4283 100644
--- a/libraries/Zigbee/src/ZigbeeEP.h
+++ b/libraries/Zigbee/src/ZigbeeEP.h
@@ -8,6 +8,8 @@
 #include <Arduino.h>
 
 /* Useful defines */
+#define ZB_CMD_TIMEOUT 10000  // 10 seconds
+
 #define ZB_ARRAY_LENTH(arr) (sizeof(arr) / sizeof(arr[0]))
 #define XYZ_TO_RGB(X, Y, Z, r, g, b)                                \
   {                                                                 \
diff --git a/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp
index 89454c057e3..eabc3c7c194 100644
--- a/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp
+++ b/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp
@@ -45,34 +45,20 @@ void ZigbeeCarbonDioxideSensor::setReporting(uint16_t min_interval, uint16_t max
   if (delta > 0) {
     log_e("Delta reporting is currently not supported by the carbon dioxide sensor");
   }
-  // clang-format off
-  esp_zb_zcl_reporting_info_t reporting_info = {
-    .direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_SRV,
-    .ep = _endpoint,
-    .cluster_id = ESP_ZB_ZCL_CLUSTER_ID_CARBON_DIOXIDE_MEASUREMENT,
-    .cluster_role = ESP_ZB_ZCL_CLUSTER_SERVER_ROLE,
-    .attr_id = ESP_ZB_ZCL_ATTR_CARBON_DIOXIDE_MEASUREMENT_MEASURED_VALUE_ID,
-    .u =
-      {
-        .send_info =
-          {
-            .min_interval = min_interval,
-            .max_interval = max_interval,
-            .delta =
-              {
-                .u16 = delta,
-              },
-            .def_min_interval = min_interval,
-            .def_max_interval = max_interval,
-          },
-      },
-    .dst =
-      {
-        .profile_id = ESP_ZB_AF_HA_PROFILE_ID,
-      },
-    .manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC,
-  };
-  // clang-format on
+  esp_zb_zcl_reporting_info_t reporting_info;
+  memset(&reporting_info, 0, sizeof(esp_zb_zcl_reporting_info_t));
+  reporting_info.direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_SRV;
+  reporting_info.ep = _endpoint;
+  reporting_info.cluster_id = ESP_ZB_ZCL_CLUSTER_ID_CARBON_DIOXIDE_MEASUREMENT;
+  reporting_info.cluster_role = ESP_ZB_ZCL_CLUSTER_SERVER_ROLE;
+  reporting_info.attr_id = ESP_ZB_ZCL_ATTR_CARBON_DIOXIDE_MEASUREMENT_MEASURED_VALUE_ID;
+  reporting_info.u.send_info.min_interval = min_interval;
+  reporting_info.u.send_info.max_interval = max_interval;
+  reporting_info.u.send_info.def_min_interval = min_interval;
+  reporting_info.u.send_info.def_max_interval = max_interval;
+  reporting_info.u.send_info.delta.u16 = delta;
+  reporting_info.dst.profile_id = ESP_ZB_AF_HA_PROFILE_ID;
+  reporting_info.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC;
   esp_zb_lock_acquire(portMAX_DELAY);
   esp_zb_zcl_update_reporting_info(&reporting_info);
   esp_zb_lock_release();
diff --git a/libraries/Zigbee/src/ep/ZigbeeFlowSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeFlowSensor.cpp
index 6adf8172194..75196e78543 100644
--- a/libraries/Zigbee/src/ep/ZigbeeFlowSensor.cpp
+++ b/libraries/Zigbee/src/ep/ZigbeeFlowSensor.cpp
@@ -41,34 +41,20 @@ void ZigbeeFlowSensor::setTolerance(float tolerance) {
 }
 
 void ZigbeeFlowSensor::setReporting(uint16_t min_interval, uint16_t max_interval, float delta) {
-  // clang-format off
-  esp_zb_zcl_reporting_info_t reporting_info = {
-    .direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_SRV,
-    .ep = _endpoint,
-    .cluster_id = ESP_ZB_ZCL_CLUSTER_ID_FLOW_MEASUREMENT,
-    .cluster_role = ESP_ZB_ZCL_CLUSTER_SERVER_ROLE,
-    .attr_id = ESP_ZB_ZCL_ATTR_FLOW_MEASUREMENT_VALUE_ID,
-    .u =
-      {
-        .send_info =
-          {
-            .min_interval = min_interval,
-            .max_interval = max_interval,
-            .delta =
-              {
-                .u16 = (uint16_t)(delta * 10),  // Convert delta to ZCL uint16_t
-              },
-            .def_min_interval = min_interval,
-            .def_max_interval = max_interval,
-          },
-      },
-    .dst =
-      {
-        .profile_id = ESP_ZB_AF_HA_PROFILE_ID,
-      },
-    .manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC,
-  };
-  // clang-format on
+  esp_zb_zcl_reporting_info_t reporting_info;
+  memset(&reporting_info, 0, sizeof(esp_zb_zcl_reporting_info_t));
+  reporting_info.direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_SRV;
+  reporting_info.ep = _endpoint;
+  reporting_info.cluster_id = ESP_ZB_ZCL_CLUSTER_ID_FLOW_MEASUREMENT;
+  reporting_info.cluster_role = ESP_ZB_ZCL_CLUSTER_SERVER_ROLE;
+  reporting_info.attr_id = ESP_ZB_ZCL_ATTR_FLOW_MEASUREMENT_VALUE_ID;
+  reporting_info.u.send_info.min_interval = min_interval;
+  reporting_info.u.send_info.max_interval = max_interval;
+  reporting_info.u.send_info.def_min_interval = min_interval;
+  reporting_info.u.send_info.def_max_interval = max_interval;
+  reporting_info.u.send_info.delta.u16 = (uint16_t)(delta * 10);  // Convert delta to ZCL uint16_t
+  reporting_info.dst.profile_id = ESP_ZB_AF_HA_PROFILE_ID;
+  reporting_info.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC;
   esp_zb_lock_acquire(portMAX_DELAY);
   esp_zb_zcl_update_reporting_info(&reporting_info);
   esp_zb_lock_release();
diff --git a/libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp b/libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp
index 9415502215d..24b4efb127e 100644
--- a/libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp
+++ b/libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp
@@ -38,34 +38,20 @@ void ZigbeePressureSensor::setTolerance(uint16_t tolerance) {
 }
 
 void ZigbeePressureSensor::setReporting(uint16_t min_interval, uint16_t max_interval, uint16_t delta) {
-  // clang-format off
-  esp_zb_zcl_reporting_info_t reporting_info = {
-    .direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_SRV,
-    .ep = _endpoint,
-    .cluster_id = ESP_ZB_ZCL_CLUSTER_ID_PRESSURE_MEASUREMENT,
-    .cluster_role = ESP_ZB_ZCL_CLUSTER_SERVER_ROLE,
-    .attr_id = ESP_ZB_ZCL_ATTR_PRESSURE_MEASUREMENT_VALUE_ID,
-    .u =
-      {
-        .send_info =
-          {
-            .min_interval = min_interval,
-            .max_interval = max_interval,
-            .delta =
-              {
-                .u16 = delta, // x hPa
-              },
-            .def_min_interval = min_interval,
-            .def_max_interval = max_interval,
-          },
-      },
-    .dst =
-      {
-        .profile_id = ESP_ZB_AF_HA_PROFILE_ID,
-      },
-    .manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC,
-  };
-  // clang-format on
+  esp_zb_zcl_reporting_info_t reporting_info;
+  memset(&reporting_info, 0, sizeof(esp_zb_zcl_reporting_info_t));
+  reporting_info.direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_SRV;
+  reporting_info.ep = _endpoint;
+  reporting_info.cluster_id = ESP_ZB_ZCL_CLUSTER_ID_PRESSURE_MEASUREMENT;
+  reporting_info.cluster_role = ESP_ZB_ZCL_CLUSTER_SERVER_ROLE;
+  reporting_info.attr_id = ESP_ZB_ZCL_ATTR_PRESSURE_MEASUREMENT_VALUE_ID;
+  reporting_info.u.send_info.min_interval = min_interval;
+  reporting_info.u.send_info.max_interval = max_interval;
+  reporting_info.u.send_info.def_min_interval = min_interval;
+  reporting_info.u.send_info.def_max_interval = max_interval;
+  reporting_info.u.send_info.delta.u16 = delta;  // x hPa
+  reporting_info.dst.profile_id = ESP_ZB_AF_HA_PROFILE_ID;
+  reporting_info.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC;
   esp_zb_lock_acquire(portMAX_DELAY);
   esp_zb_zcl_update_reporting_info(&reporting_info);
   esp_zb_lock_release();
diff --git a/libraries/Zigbee/src/ep/ZigbeeTempSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeTempSensor.cpp
index 98a3793fbad..d419fb14adc 100644
--- a/libraries/Zigbee/src/ep/ZigbeeTempSensor.cpp
+++ b/libraries/Zigbee/src/ep/ZigbeeTempSensor.cpp
@@ -35,33 +35,20 @@ void ZigbeeTempSensor::setTolerance(float tolerance) {
 }
 
 void ZigbeeTempSensor::setReporting(uint16_t min_interval, uint16_t max_interval, float delta) {
-  esp_zb_zcl_reporting_info_t reporting_info = {
-    .direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_SRV,
-    .ep = _endpoint,
-    .cluster_id = ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT,
-    .cluster_role = ESP_ZB_ZCL_CLUSTER_SERVER_ROLE,
-    .attr_id = ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID,
-    .u =
-      {
-        .send_info =
-          {
-            .min_interval = min_interval,
-            .max_interval = max_interval,
-            .delta =
-              {
-                .u16 = (uint16_t)(delta * 100),  // Convert delta to ZCL uint16_t
-              },
-            .def_min_interval = min_interval,
-            .def_max_interval = max_interval,
-          },
-      },
-    .dst =
-      {
-        .profile_id = ESP_ZB_AF_HA_PROFILE_ID,
-      },
-    .manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC,
-  };
-  esp_zb_lock_acquire(portMAX_DELAY);
+  esp_zb_zcl_reporting_info_t reporting_info;
+  memset(&reporting_info, 0, sizeof(esp_zb_zcl_reporting_info_t));
+  reporting_info.direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_SRV;
+  reporting_info.ep = _endpoint;
+  reporting_info.cluster_id = ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT;
+  reporting_info.cluster_role = ESP_ZB_ZCL_CLUSTER_SERVER_ROLE;
+  reporting_info.attr_id = ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID;
+  reporting_info.u.send_info.min_interval = min_interval;
+  reporting_info.u.send_info.max_interval = max_interval;
+  reporting_info.u.send_info.def_min_interval = min_interval;
+  reporting_info.u.send_info.def_max_interval = max_interval;
+  reporting_info.u.send_info.delta.u16 = (uint16_t)(delta * 100);  // Convert delta to ZCL uint16_t
+  reporting_info.dst.profile_id = ESP_ZB_AF_HA_PROFILE_ID;
+  reporting_info.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC, esp_zb_lock_acquire(portMAX_DELAY);
   esp_zb_zcl_update_reporting_info(&reporting_info);
   esp_zb_lock_release();
 }
@@ -136,32 +123,20 @@ void ZigbeeTempSensor::reportHumidity() {
 }
 
 void ZigbeeTempSensor::setHumidityReporting(uint16_t min_interval, uint16_t max_interval, float delta) {
-  esp_zb_zcl_reporting_info_t reporting_info = {
-    .direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_SRV,
-    .ep = _endpoint,
-    .cluster_id = ESP_ZB_ZCL_CLUSTER_ID_REL_HUMIDITY_MEASUREMENT,
-    .cluster_role = ESP_ZB_ZCL_CLUSTER_SERVER_ROLE,
-    .attr_id = ESP_ZB_ZCL_ATTR_REL_HUMIDITY_MEASUREMENT_VALUE_ID,
-    .u =
-      {
-        .send_info =
-          {
-            .min_interval = min_interval,
-            .max_interval = max_interval,
-            .delta =
-              {
-                .u16 = (uint16_t)(delta * 100),  // Convert delta to ZCL uint16_t
-              },
-            .def_min_interval = min_interval,
-            .def_max_interval = max_interval,
-          },
-      },
-    .dst =
-      {
-        .profile_id = ESP_ZB_AF_HA_PROFILE_ID,
-      },
-    .manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC,
-  };
+  esp_zb_zcl_reporting_info_t reporting_info;
+  memset(&reporting_info, 0, sizeof(esp_zb_zcl_reporting_info_t));
+  reporting_info.direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_SRV;
+  reporting_info.ep = _endpoint;
+  reporting_info.cluster_id = ESP_ZB_ZCL_CLUSTER_ID_REL_HUMIDITY_MEASUREMENT;
+  reporting_info.cluster_role = ESP_ZB_ZCL_CLUSTER_SERVER_ROLE;
+  reporting_info.attr_id = ESP_ZB_ZCL_ATTR_REL_HUMIDITY_MEASUREMENT_VALUE_ID;
+  reporting_info.u.send_info.min_interval = min_interval;
+  reporting_info.u.send_info.max_interval = max_interval;
+  reporting_info.u.send_info.def_min_interval = min_interval;
+  reporting_info.u.send_info.def_max_interval = max_interval;
+  reporting_info.u.send_info.delta.u16 = (uint16_t)(delta * 100);  // Convert delta to ZCL uint16_t
+  reporting_info.dst.profile_id = ESP_ZB_AF_HA_PROFILE_ID;
+  reporting_info.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC;
   esp_zb_lock_acquire(portMAX_DELAY);
   esp_zb_zcl_update_reporting_info(&reporting_info);
   esp_zb_lock_release();
diff --git a/libraries/Zigbee/src/ep/ZigbeeThermostat.cpp b/libraries/Zigbee/src/ep/ZigbeeThermostat.cpp
index 4610e087563..f8957f073a5 100644
--- a/libraries/Zigbee/src/ep/ZigbeeThermostat.cpp
+++ b/libraries/Zigbee/src/ep/ZigbeeThermostat.cpp
@@ -166,7 +166,7 @@ void ZigbeeThermostat::getSensorSettings() {
   esp_zb_lock_release();
 
   //Take semaphore to wait for response of all attributes
-  if (xSemaphoreTake(lock, portMAX_DELAY) != pdTRUE) {
+  if (xSemaphoreTake(lock, ZB_CMD_TIMEOUT) != pdTRUE) {
     log_e("Error while reading attributes");
     return;
   } else {
diff --git a/tools/partitions/zigbee_2MB.csv b/tools/partitions/zigbee_2MB.csv
new file mode 100644
index 00000000000..18adb6358bd
--- /dev/null
+++ b/tools/partitions/zigbee_2MB.csv
@@ -0,0 +1,7 @@
+# Name,     Type, SubType, Offset,  Size, Flags
+nvs,        data, nvs,     0x9000,  0x5000,
+factory,    app,  factory, 0x10000,  0x140000,
+spiffs,     data, spiffs,  0x150000,0x9B000,
+zb_storage, data, fat,     0x1EB000,0x4000,
+zb_fct,     data, fat,     0x1EF000,0x1000,
+coredump,   data, coredump,0x1F0000,0x10000,