diff --git a/libraries/Zigbee/examples/Zigbee_Temp_Hum_Sensor_Sleepy/Zigbee_Temp_Hum_Sensor_Sleepy.ino b/libraries/Zigbee/examples/Zigbee_Temp_Hum_Sensor_Sleepy/Zigbee_Temp_Hum_Sensor_Sleepy.ino
index 0bfbad1fe95..3eefd973dd2 100644
--- a/libraries/Zigbee/examples/Zigbee_Temp_Hum_Sensor_Sleepy/Zigbee_Temp_Hum_Sensor_Sleepy.ino
+++ b/libraries/Zigbee/examples/Zigbee_Temp_Hum_Sensor_Sleepy/Zigbee_Temp_Hum_Sensor_Sleepy.ino
@@ -133,7 +133,11 @@ void loop() {
         // If key pressed for more than 10secs, factory reset Zigbee and reboot
         Serial.println("Resetting Zigbee to factory and rebooting in 1s.");
         delay(1000);
-        Zigbee.factoryReset();
+        // Optional set reset in factoryReset to false, to not restart device after erasing nvram, but set it to endless sleep manually instead
+        Zigbee.factoryReset(false);
+        Serial.println("Going to endless sleep, press RESET button or power off/on the device to wake up");
+        esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER);
+        esp_deep_sleep_start();
       }
     }
   }
diff --git a/libraries/Zigbee/src/ZigbeeCore.cpp b/libraries/Zigbee/src/ZigbeeCore.cpp
index 2200aec2662..b93542159a6 100644
--- a/libraries/Zigbee/src/ZigbeeCore.cpp
+++ b/libraries/Zigbee/src/ZigbeeCore.cpp
@@ -91,21 +91,26 @@ bool ZigbeeCore::begin(zigbee_role_t role, bool erase_nvs) {
   return started();
 }
 
-void ZigbeeCore::addEndpoint(ZigbeeEP *ep) {
+bool ZigbeeCore::addEndpoint(ZigbeeEP *ep) {
   ep_objects.push_back(ep);
 
   log_d("Endpoint: %d, Device ID: 0x%04x", ep->_endpoint, ep->_device_id);
   //Register clusters and ep_list to the ZigbeeCore class's ep_list
   if (ep->_ep_config.endpoint == 0 || ep->_cluster_list == nullptr) {
     log_e("Endpoint config or Cluster list is not initialized, EP not added to ZigbeeCore's EP list");
-    return;
+    return false;
   }
-
+  esp_err_t ret = ESP_OK;
   if (ep->_device_id == ESP_ZB_HA_HOME_GATEWAY_DEVICE_ID) {
-    esp_zb_ep_list_add_gateway_ep(_zb_ep_list, ep->_cluster_list, ep->_ep_config);
+    ret = esp_zb_ep_list_add_gateway_ep(_zb_ep_list, ep->_cluster_list, ep->_ep_config);
   } else {
-    esp_zb_ep_list_add_ep(_zb_ep_list, ep->_cluster_list, ep->_ep_config);
+    ret = esp_zb_ep_list_add_ep(_zb_ep_list, ep->_cluster_list, ep->_ep_config);
+  }
+  if (ret != ESP_OK) {
+    log_e("Failed to add endpoint: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
   }
+  return true;
 }
 
 static void esp_zb_task(void *pvParameters) {
@@ -368,16 +373,22 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct) {
     case ESP_ZB_ZDO_SIGNAL_LEAVE:  // End Device + Router
       // Device was removed from the network, factory reset the device
       if ((zigbee_role_t)Zigbee.getRole() != ZIGBEE_COORDINATOR) {
-        Zigbee.factoryReset();
+        Zigbee.factoryReset(true);
       }
       break;
     default: log_v("ZDO signal: %s (0x%x), status: %s", esp_zb_zdo_signal_to_string(sig_type), sig_type, esp_err_to_name(err_status)); break;
   }
 }
 
-void ZigbeeCore::factoryReset() {
-  log_v("Factory resetting Zigbee stack, device will reboot");
-  esp_zb_factory_reset();
+void ZigbeeCore::factoryReset(bool restart) {
+  if (restart) {
+    log_v("Factory resetting Zigbee stack, device will reboot");
+    esp_zb_factory_reset();
+  } else {
+    log_v("Factory resetting Zigbee NVRAM to factory default");
+    log_w("The device will not reboot, to take effect please reboot the device manually");
+    esp_zb_zcl_reset_nvram_to_factory_default();
+  }
 }
 
 void ZigbeeCore::scanCompleteCallback(esp_zb_zdp_status_t zdo_status, uint8_t count, esp_zb_network_descriptor_t *nwk_descriptor) {
diff --git a/libraries/Zigbee/src/ZigbeeCore.h b/libraries/Zigbee/src/ZigbeeCore.h
index 018f701d6e0..06c3ec4551a 100644
--- a/libraries/Zigbee/src/ZigbeeCore.h
+++ b/libraries/Zigbee/src/ZigbeeCore.h
@@ -129,7 +129,7 @@ class ZigbeeCore {
     return _role;
   }
 
-  void addEndpoint(ZigbeeEP *ep);
+  bool addEndpoint(ZigbeeEP *ep);
   //void removeEndpoint(ZigbeeEP *ep);
 
   void setRadioConfig(esp_zb_radio_config_t config);
@@ -164,7 +164,7 @@ class ZigbeeCore {
   zigbee_scan_result_t *getScanResult();
   void scanDelete();
 
-  void factoryReset();
+  void factoryReset(bool restart = true);
 
   // Friend function declaration to allow access to private members
   friend void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct);
diff --git a/libraries/Zigbee/src/ZigbeeEP.cpp b/libraries/Zigbee/src/ZigbeeEP.cpp
index 7052a558192..e7d507dc441 100644
--- a/libraries/Zigbee/src/ZigbeeEP.cpp
+++ b/libraries/Zigbee/src/ZigbeeEP.cpp
@@ -32,71 +32,95 @@ void ZigbeeEP::setVersion(uint8_t version) {
   _ep_config.app_device_version = version;
 }
 
-void ZigbeeEP::setManufacturerAndModel(const char *name, const char *model) {
+bool ZigbeeEP::setManufacturerAndModel(const char *name, const char *model) {
   // Convert manufacturer to ZCL string
-  size_t length = strlen(name);
-  if (length > 32) {
-    log_e("Manufacturer name is too long");
-    return;
+  size_t name_length = strlen(name);
+  size_t model_length = strlen(model);
+  if (name_length > 32 || model_length > 32) {
+    log_e("Manufacturer or model name is too long");
+    return false;
   }
   // Allocate a new array of size length + 2 (1 for the length, 1 for null terminator)
-  char *zb_name = new char[length + 2];
+  char *zb_name = new char[name_length + 2];
+  char *zb_model = new char[model_length + 2];
   // Store the length as the first element
-  zb_name[0] = static_cast<char>(length);  // Cast size_t to char
+  zb_name[0] = static_cast<char>(name_length);  // Cast size_t to char
+  zb_model[0] = static_cast<char>(model_length);
   // Use memcpy to copy the characters to the result array
-  memcpy(zb_name + 1, name, length);
+  memcpy(zb_name + 1, name, name_length);
+  memcpy(zb_model + 1, model, model_length);
   // Null-terminate the array
-  zb_name[length + 1] = '\0';
-
-  // Convert model to ZCL string
-  length = strlen(model);
-  if (length > 32) {
-    log_e("Model name is too long");
-    delete[] zb_name;
-    return;
-  }
-  char *zb_model = new char[length + 2];
-  zb_model[0] = static_cast<char>(length);
-  memcpy(zb_model + 1, model, length);
-  zb_model[length + 1] = '\0';
+  zb_name[name_length + 1] = '\0';
+  zb_model[model_length + 1] = '\0';
 
   // Get the basic cluster and update the manufacturer and model attributes
   esp_zb_attribute_list_t *basic_cluster = esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_BASIC, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
-  esp_zb_basic_cluster_add_attr(basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MANUFACTURER_NAME_ID, (void *)zb_name);
-  esp_zb_basic_cluster_add_attr(basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MODEL_IDENTIFIER_ID, (void *)zb_model);
+  esp_err_t ret_name = esp_zb_basic_cluster_add_attr(basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MANUFACTURER_NAME_ID, (void *)zb_name);
+  if (ret_name != ESP_OK) {
+    log_e("Failed to set manufacturer: 0x%x: %s", ret_name, esp_err_to_name(ret_name));
+  }
+  esp_err_t ret_model = esp_zb_basic_cluster_add_attr(basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MODEL_IDENTIFIER_ID, (void *)zb_model);
+  if (ret_model != ESP_OK) {
+    log_e("Failed to set model: 0x%x: %s", ret_model, esp_err_to_name(ret_model));
+  }
+  delete[] zb_name;
+  delete[] zb_model;
+  return ret_name == ESP_OK && ret_model == ESP_OK;
 }
 
-void ZigbeeEP::setPowerSource(zb_power_source_t power_source, uint8_t battery_percentage) {
+bool ZigbeeEP::setPowerSource(zb_power_source_t power_source, uint8_t battery_percentage) {
   esp_zb_attribute_list_t *basic_cluster = esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_BASIC, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
-  esp_zb_cluster_update_attr(basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_POWER_SOURCE_ID, (void *)&power_source);
+  esp_err_t ret = esp_zb_cluster_update_attr(basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_POWER_SOURCE_ID, (void *)&power_source);
+  if (ret != ESP_OK) {
+    log_e("Failed to set power source: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
 
   if (power_source == ZB_POWER_SOURCE_BATTERY) {
     // Add power config cluster and battery percentage attribute
+    if (battery_percentage > 100) {
+      battery_percentage = 100;
+    }
     battery_percentage = battery_percentage * 2;
     esp_zb_attribute_list_t *power_config_cluster = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_POWER_CONFIG);
-    esp_zb_power_config_cluster_add_attr(power_config_cluster, ESP_ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_PERCENTAGE_REMAINING_ID, (void *)&battery_percentage);
-    esp_zb_cluster_list_add_power_config_cluster(_cluster_list, power_config_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
+    ret = esp_zb_power_config_cluster_add_attr(power_config_cluster, ESP_ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_PERCENTAGE_REMAINING_ID, (void *)&battery_percentage);
+    if (ret != ESP_OK) {
+      log_e("Failed to add battery percentage attribute: 0x%x: %s", ret, esp_err_to_name(ret));
+      return false;
+    }
+    ret = esp_zb_cluster_list_add_power_config_cluster(_cluster_list, power_config_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
+    if (ret != ESP_OK) {
+      log_e("Failed to add power config cluster: 0x%x: %s", ret, esp_err_to_name(ret));
+      return false;
+    }
   }
   _power_source = power_source;
+  return true;
 }
 
-void ZigbeeEP::setBatteryPercentage(uint8_t percentage) {
+bool ZigbeeEP::setBatteryPercentage(uint8_t percentage) {
   // 100% = 200 in decimal, 0% = 0
   // Convert percentage to 0-200 range
+  esp_zb_zcl_status_t ret = ESP_ZB_ZCL_STATUS_SUCCESS;
   if (percentage > 100) {
     percentage = 100;
   }
   percentage = percentage * 2;
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_set_attribute_val(
+  ret = esp_zb_zcl_set_attribute_val(
     _endpoint, ESP_ZB_ZCL_CLUSTER_ID_POWER_CONFIG, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_PERCENTAGE_REMAINING_ID, &percentage,
     false
   );
   esp_zb_lock_release();
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set battery percentage: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    return false;
+  }
   log_v("Battery percentage updated");
+  return true;
 }
 
-void ZigbeeEP::reportBatteryPercentage() {
+bool ZigbeeEP::reportBatteryPercentage() {
   /* Send report attributes command */
   esp_zb_zcl_report_attr_cmd_t report_attr_cmd;
   report_attr_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
@@ -107,9 +131,14 @@ void ZigbeeEP::reportBatteryPercentage() {
   report_attr_cmd.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC;
 
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd);
+  esp_err_t ret = esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd);
   esp_zb_lock_release();
+  if (ret != ESP_OK) {
+    log_e("Failed to report battery percentage: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
   log_v("Battery percentage reported");
+  return true;
 }
 
 char *ZigbeeEP::readManufacturer(uint8_t endpoint, uint16_t short_addr, esp_zb_ieee_addr_t ieee_addr) {
@@ -134,7 +163,9 @@ char *ZigbeeEP::readManufacturer(uint8_t endpoint, uint16_t short_addr, esp_zb_i
   read_req.attr_number = ZB_ARRAY_LENTH(attributes);
   read_req.attr_field = attributes;
 
-  // clear read manufacturer
+  if (_read_manufacturer != nullptr) {
+    free(_read_manufacturer);
+  }
   _read_manufacturer = nullptr;
 
   esp_zb_lock_acquire(portMAX_DELAY);
@@ -170,7 +201,9 @@ char *ZigbeeEP::readModel(uint8_t endpoint, uint16_t short_addr, esp_zb_ieee_add
   read_req.attr_number = ZB_ARRAY_LENTH(attributes);
   read_req.attr_field = attributes;
 
-  // clear read model
+  if (_read_model != nullptr) {
+    free(_read_model);
+  }
   _read_model = nullptr;
 
   esp_zb_lock_acquire(portMAX_DELAY);
@@ -240,7 +273,7 @@ void ZigbeeEP::zbIdentify(const esp_zb_zcl_set_attr_value_message_t *message) {
   }
 }
 
-void ZigbeeEP::addTimeCluster(tm time, int32_t gmt_offset) {
+bool ZigbeeEP::addTimeCluster(tm time, int32_t gmt_offset) {
   time_t utc_time = 0;
   // Check if time is set
   if (time.tm_year > 0) {
@@ -250,28 +283,63 @@ void ZigbeeEP::addTimeCluster(tm time, int32_t gmt_offset) {
 
   // Create time cluster server attributes
   esp_zb_attribute_list_t *time_cluster_server = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_TIME);
-  esp_zb_time_cluster_add_attr(time_cluster_server, ESP_ZB_ZCL_ATTR_TIME_TIME_ZONE_ID, (void *)&gmt_offset);
-  esp_zb_time_cluster_add_attr(time_cluster_server, ESP_ZB_ZCL_ATTR_TIME_TIME_ID, (void *)&utc_time);
-  esp_zb_time_cluster_add_attr(time_cluster_server, ESP_ZB_ZCL_ATTR_TIME_TIME_STATUS_ID, (void *)&_time_status);
+  esp_err_t ret = esp_zb_time_cluster_add_attr(time_cluster_server, ESP_ZB_ZCL_ATTR_TIME_TIME_ZONE_ID, (void *)&gmt_offset);
+  if (ret != ESP_OK) {
+    log_e("Failed to add time zone attribute: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  ret = esp_zb_time_cluster_add_attr(time_cluster_server, ESP_ZB_ZCL_ATTR_TIME_TIME_ID, (void *)&utc_time);
+  if (ret != ESP_OK) {
+    log_e("Failed to add time attribute: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  ret = esp_zb_time_cluster_add_attr(time_cluster_server, ESP_ZB_ZCL_ATTR_TIME_TIME_STATUS_ID, (void *)&_time_status);
+  if (ret != ESP_OK) {
+    log_e("Failed to add time status attribute: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
   // Create time cluster client attributes
   esp_zb_attribute_list_t *time_cluster_client = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_TIME);
   // Add time clusters to cluster list
-  esp_zb_cluster_list_add_time_cluster(_cluster_list, time_cluster_server, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
-  esp_zb_cluster_list_add_time_cluster(_cluster_list, time_cluster_client, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);
+  ret = esp_zb_cluster_list_add_time_cluster(_cluster_list, time_cluster_server, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
+  if (ret != ESP_OK) {
+    log_e("Failed to add time cluster (server role): 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  ret = esp_zb_cluster_list_add_time_cluster(_cluster_list, time_cluster_client, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);
+  if (ret != ESP_OK) {
+    log_e("Failed to add time cluster (client role): 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeeEP::setTime(tm time) {
+bool ZigbeeEP::setTime(tm time) {
+  esp_zb_zcl_status_t ret = ESP_ZB_ZCL_STATUS_SUCCESS;
   time_t utc_time = mktime(&time);
   log_d("Setting time to %lld", utc_time);
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_set_attribute_val(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_TIME, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_TIME_TIME_ID, &utc_time, false);
+  ret = esp_zb_zcl_set_attribute_val(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_TIME, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_TIME_TIME_ID, &utc_time, false);
   esp_zb_lock_release();
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set time: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeeEP::setTimezone(int32_t gmt_offset) {
+bool ZigbeeEP::setTimezone(int32_t gmt_offset) {
+  esp_zb_zcl_status_t ret = ESP_ZB_ZCL_STATUS_SUCCESS;
+  log_d("Setting timezone to %d", gmt_offset);
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_set_attribute_val(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_TIME, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_TIME_TIME_ZONE_ID, &gmt_offset, false);
+  ret =
+    esp_zb_zcl_set_attribute_val(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_TIME, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_TIME_TIME_ZONE_ID, &gmt_offset, false);
   esp_zb_lock_release();
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set timezone: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
 tm ZigbeeEP::getTime(uint8_t endpoint, int32_t short_addr, esp_zb_ieee_addr_t ieee_addr) {
@@ -390,7 +458,7 @@ void ZigbeeEP::zbReadTimeCluster(const esp_zb_zcl_attribute_t *attribute) {
 //     uint8_t max_data_size; /*!< The maximum size of OTA data */
 // } esp_zb_zcl_ota_upgrade_client_variable_t;
 
-void ZigbeeEP::addOTAClient(
+bool ZigbeeEP::addOTAClient(
   uint32_t file_version, uint32_t downloaded_file_ver, uint16_t hw_version, uint16_t manufacturer, uint16_t image_type, uint8_t max_data_size
 ) {
 
@@ -410,11 +478,27 @@ void ZigbeeEP::addOTAClient(
   uint16_t ota_upgrade_server_addr = 0xffff;
   uint8_t ota_upgrade_server_ep = 0xff;
 
-  ESP_ERROR_CHECK(esp_zb_ota_cluster_add_attr(ota_cluster, ESP_ZB_ZCL_ATTR_OTA_UPGRADE_CLIENT_DATA_ID, (void *)&variable_config));
-  ESP_ERROR_CHECK(esp_zb_ota_cluster_add_attr(ota_cluster, ESP_ZB_ZCL_ATTR_OTA_UPGRADE_SERVER_ADDR_ID, (void *)&ota_upgrade_server_addr));
-  ESP_ERROR_CHECK(esp_zb_ota_cluster_add_attr(ota_cluster, ESP_ZB_ZCL_ATTR_OTA_UPGRADE_SERVER_ENDPOINT_ID, (void *)&ota_upgrade_server_ep));
-
-  ESP_ERROR_CHECK(esp_zb_cluster_list_add_ota_cluster(_cluster_list, ota_cluster, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE));
+  esp_err_t ret = esp_zb_ota_cluster_add_attr(ota_cluster, ESP_ZB_ZCL_ATTR_OTA_UPGRADE_CLIENT_DATA_ID, (void *)&variable_config);
+  if (ret != ESP_OK) {
+    log_e("Failed to add OTA client data: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  ret = esp_zb_ota_cluster_add_attr(ota_cluster, ESP_ZB_ZCL_ATTR_OTA_UPGRADE_SERVER_ADDR_ID, (void *)&ota_upgrade_server_addr);
+  if (ret != ESP_OK) {
+    log_e("Failed to add OTA server address: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  ret = esp_zb_ota_cluster_add_attr(ota_cluster, ESP_ZB_ZCL_ATTR_OTA_UPGRADE_SERVER_ENDPOINT_ID, (void *)&ota_upgrade_server_ep);
+  if (ret != ESP_OK) {
+    log_e("Failed to add OTA server endpoint: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  ret = esp_zb_cluster_list_add_ota_cluster(_cluster_list, ota_cluster, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);
+  if (ret != ESP_OK) {
+    log_e("Failed to add OTA cluster: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
 static void findOTAServer(esp_zb_zdp_status_t zdo_status, uint16_t addr, uint8_t endpoint, void *user_ctx) {
@@ -445,4 +529,42 @@ void ZigbeeEP::requestOTAUpdate() {
   esp_zb_lock_release();
 }
 
+const char *ZigbeeEP::esp_zb_zcl_status_to_name(esp_zb_zcl_status_t status) {
+  switch (status) {
+    case ESP_ZB_ZCL_STATUS_SUCCESS:               return "Success";
+    case ESP_ZB_ZCL_STATUS_FAIL:                  return "Fail";
+    case ESP_ZB_ZCL_STATUS_NOT_AUTHORIZED:        return "Not authorized";
+    case ESP_ZB_ZCL_STATUS_MALFORMED_CMD:         return "Malformed command";
+    case ESP_ZB_ZCL_STATUS_UNSUP_CLUST_CMD:       return "Unsupported cluster command";
+    case ESP_ZB_ZCL_STATUS_UNSUP_GEN_CMD:         return "Unsupported general command";
+    case ESP_ZB_ZCL_STATUS_UNSUP_MANUF_CLUST_CMD: return "Unsupported manufacturer cluster command";
+    case ESP_ZB_ZCL_STATUS_UNSUP_MANUF_GEN_CMD:   return "Unsupported manufacturer general command";
+    case ESP_ZB_ZCL_STATUS_INVALID_FIELD:         return "Invalid field";
+    case ESP_ZB_ZCL_STATUS_UNSUP_ATTRIB:          return "Unsupported attribute";
+    case ESP_ZB_ZCL_STATUS_INVALID_VALUE:         return "Invalid value";
+    case ESP_ZB_ZCL_STATUS_READ_ONLY:             return "Read only";
+    case ESP_ZB_ZCL_STATUS_INSUFF_SPACE:          return "Insufficient space";
+    case ESP_ZB_ZCL_STATUS_DUPE_EXISTS:           return "Duplicate exists";
+    case ESP_ZB_ZCL_STATUS_NOT_FOUND:             return "Not found";
+    case ESP_ZB_ZCL_STATUS_UNREPORTABLE_ATTRIB:   return "Unreportable attribute";
+    case ESP_ZB_ZCL_STATUS_INVALID_TYPE:          return "Invalid type";
+    case ESP_ZB_ZCL_STATUS_WRITE_ONLY:            return "Write only";
+    case ESP_ZB_ZCL_STATUS_INCONSISTENT:          return "Inconsistent";
+    case ESP_ZB_ZCL_STATUS_ACTION_DENIED:         return "Action denied";
+    case ESP_ZB_ZCL_STATUS_TIMEOUT:               return "Timeout";
+    case ESP_ZB_ZCL_STATUS_ABORT:                 return "Abort";
+    case ESP_ZB_ZCL_STATUS_INVALID_IMAGE:         return "Invalid OTA upgrade image";
+    case ESP_ZB_ZCL_STATUS_WAIT_FOR_DATA:         return "Server does not have data block available yet";
+    case ESP_ZB_ZCL_STATUS_NO_IMAGE_AVAILABLE:    return "No image available";
+    case ESP_ZB_ZCL_STATUS_REQUIRE_MORE_IMAGE:    return "Require more image";
+    case ESP_ZB_ZCL_STATUS_NOTIFICATION_PENDING:  return "Notification pending";
+    case ESP_ZB_ZCL_STATUS_HW_FAIL:               return "Hardware failure";
+    case ESP_ZB_ZCL_STATUS_SW_FAIL:               return "Software failure";
+    case ESP_ZB_ZCL_STATUS_CALIB_ERR:             return "Calibration error";
+    case ESP_ZB_ZCL_STATUS_UNSUP_CLUST:           return "Cluster is not found on the target endpoint";
+    case ESP_ZB_ZCL_STATUS_LIMIT_REACHED:         return "Limit reached";
+    default:                                      return "Unknown status";
+  }
+}
+
 #endif  // CONFIG_ZB_ENABLED
diff --git a/libraries/Zigbee/src/ZigbeeEP.h b/libraries/Zigbee/src/ZigbeeEP.h
index 0a4e3e9d252..bd142344929 100644
--- a/libraries/Zigbee/src/ZigbeeEP.h
+++ b/libraries/Zigbee/src/ZigbeeEP.h
@@ -70,21 +70,21 @@ class ZigbeeEP {
   }
 
   // Set Manufacturer name and model
-  void setManufacturerAndModel(const char *name, const char *model);
+  bool setManufacturerAndModel(const char *name, const char *model);
 
   // Methods to read manufacturer and model name from selected endpoint and short address
   char *readManufacturer(uint8_t endpoint, uint16_t short_addr, esp_zb_ieee_addr_t ieee_addr);
   char *readModel(uint8_t endpoint, uint16_t short_addr, esp_zb_ieee_addr_t ieee_addr);
 
   // Set Power source and battery percentage for battery powered devices
-  void setPowerSource(zb_power_source_t power_source, uint8_t percentage = 255);
-  void setBatteryPercentage(uint8_t percentage);
-  void reportBatteryPercentage();
+  bool setPowerSource(zb_power_source_t power_source, uint8_t percentage = 255);
+  bool setBatteryPercentage(uint8_t percentage);
+  bool reportBatteryPercentage();
 
   // Set time
-  void addTimeCluster(tm time = {}, int32_t gmt_offset = 0);  // gmt offset in seconds
-  void setTime(tm time);
-  void setTimezone(int32_t gmt_offset);
+  bool addTimeCluster(tm time = {}, int32_t gmt_offset = 0);  // gmt offset in seconds
+  bool setTime(tm time);
+  bool setTimezone(int32_t gmt_offset);
 
   // Get time from Coordinator or specific endpoint (blocking until response)
   struct tm getTime(uint8_t endpoint = 1, int32_t short_addr = 0x0000, esp_zb_ieee_addr_t ieee_addr = {0});
@@ -104,8 +104,9 @@ class ZigbeeEP {
    * @param manufacturer The manufacturer code (default: 0x1001).
    * @param image_type The image type code (default: 0x1011).
    * @param max_data_size The maximum data size for OTA transfer (default and recommended: 223).
+   * @return true if the OTA client was added successfully, false otherwise.
    */
-  void addOTAClient(
+  bool addOTAClient(
     uint32_t file_version, uint32_t downloaded_file_ver, uint16_t hw_version, uint16_t manufacturer = 0x1001, uint16_t image_type = 0x1011,
     uint8_t max_data_size = 223
   );
@@ -114,10 +115,10 @@ class ZigbeeEP {
   */
   void requestOTAUpdate();
 
-  // findEndpoind may be implemented by EPs to find and bind devices
+  // findEndpoint may be implemented by EPs to find and bind devices
   virtual void findEndpoint(esp_zb_zdo_match_desc_req_param_t *cmd_req) {};
 
-  //list of all handlers function calls, to be override by EPs implementation
+  // list of all handlers function calls, to be override by EPs implementation
   virtual void zbAttributeSet(const esp_zb_zcl_set_attr_value_message_t *message) {};
   virtual void zbAttributeRead(uint16_t cluster_id, const esp_zb_zcl_attribute_t *attribute) {};
   virtual void zbReadBasicCluster(const esp_zb_zcl_attribute_t *attribute);  //already implemented
@@ -144,6 +145,9 @@ class ZigbeeEP {
   int32_t _read_timezone;
 
 protected:
+  // Convert ZCL status to name
+  const char *esp_zb_zcl_status_to_name(esp_zb_zcl_status_t status);
+
   uint8_t _endpoint;
   esp_zb_ha_standard_devices_t _device_id;
   esp_zb_endpoint_config_t _ep_config;
diff --git a/libraries/Zigbee/src/ep/ZigbeeAnalog.cpp b/libraries/Zigbee/src/ep/ZigbeeAnalog.cpp
index 417eeb6d98c..a95668b7afe 100644
--- a/libraries/Zigbee/src/ep/ZigbeeAnalog.cpp
+++ b/libraries/Zigbee/src/ep/ZigbeeAnalog.cpp
@@ -1,38 +1,35 @@
 #include "ZigbeeAnalog.h"
 #if CONFIG_ZB_ENABLED
 
-esp_zb_cluster_list_t *zigbee_analog_clusters_create(zigbee_analog_cfg_t *analog_sensor) {
-  esp_zb_basic_cluster_cfg_t *basic_cfg = analog_sensor ? &(analog_sensor->basic_cfg) : NULL;
-  esp_zb_identify_cluster_cfg_t *identify_cfg = analog_sensor ? &(analog_sensor->identify_cfg) : NULL;
-  esp_zb_cluster_list_t *cluster_list = esp_zb_zcl_cluster_list_create();
-  esp_zb_cluster_list_add_basic_cluster(cluster_list, esp_zb_basic_cluster_create(basic_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
-  esp_zb_cluster_list_add_identify_cluster(cluster_list, esp_zb_identify_cluster_create(identify_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
-  return cluster_list;
-}
-
 ZigbeeAnalog::ZigbeeAnalog(uint8_t endpoint) : ZigbeeEP(endpoint) {
   _device_id = ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID;
 
-  //Create custom analog sensor configuration
-  zigbee_analog_cfg_t analog_cfg = ZIGBEE_DEFAULT_ANALOG_CONFIG();
-  _cluster_list = zigbee_analog_clusters_create(&analog_cfg);
+  //Create basic analog sensor clusters without configuration
+  _cluster_list = esp_zb_zcl_cluster_list_create();
+  esp_zb_cluster_list_add_basic_cluster(_cluster_list, esp_zb_basic_cluster_create(NULL), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
+  esp_zb_cluster_list_add_identify_cluster(_cluster_list, esp_zb_identify_cluster_create(NULL), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
 
   _ep_config = {.endpoint = _endpoint, .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, .app_device_id = ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID, .app_device_version = 0};
 }
 
-void ZigbeeAnalog::addAnalogValue() {
-  esp_zb_cluster_list_add_analog_value_cluster(_cluster_list, esp_zb_analog_value_cluster_create(NULL), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
-  _analog_clusters |= ANALOG_VALUE;
-}
-
-void ZigbeeAnalog::addAnalogInput() {
-  esp_zb_cluster_list_add_analog_input_cluster(_cluster_list, esp_zb_analog_input_cluster_create(NULL), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
+bool ZigbeeAnalog::addAnalogInput() {
+  esp_err_t ret = esp_zb_cluster_list_add_analog_input_cluster(_cluster_list, esp_zb_analog_input_cluster_create(NULL), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
+  if (ret != ESP_OK) {
+    log_e("Failed to add Analog Input cluster: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
   _analog_clusters |= ANALOG_INPUT;
+  return true;
 }
 
-void ZigbeeAnalog::addAnalogOutput() {
-  esp_zb_cluster_list_add_analog_output_cluster(_cluster_list, esp_zb_analog_output_cluster_create(NULL), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
+bool ZigbeeAnalog::addAnalogOutput() {
+  esp_err_t ret = esp_zb_cluster_list_add_analog_output_cluster(_cluster_list, esp_zb_analog_output_cluster_create(NULL), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
+  if (ret != ESP_OK) {
+    log_e("Failed to add Analog Output cluster: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
   _analog_clusters |= ANALOG_OUTPUT;
+  return true;
 }
 
 //set attribute method -> method overridden in child class
@@ -57,35 +54,26 @@ void ZigbeeAnalog::analogOutputChanged(float analog_output) {
   }
 }
 
-void ZigbeeAnalog::setAnalogValue(float analog) {
-  if (!(_analog_clusters & ANALOG_VALUE)) {
-    log_e("Analog Value cluster not added");
-    return;
-  }
-  // float zb_analog = analog;
-  log_d("Setting analog value to %.1f", analog);
-  esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_set_attribute_val(
-    _endpoint, ESP_ZB_ZCL_CLUSTER_ID_ANALOG_VALUE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_ANALOG_VALUE_PRESENT_VALUE_ID, &analog, false
-  );
-  esp_zb_lock_release();
-}
-
-void ZigbeeAnalog::setAnalogInput(float analog) {
+bool ZigbeeAnalog::setAnalogInput(float analog) {
+  esp_zb_zcl_status_t ret = ESP_ZB_ZCL_STATUS_SUCCESS;
   if (!(_analog_clusters & ANALOG_INPUT)) {
     log_e("Analog Input cluster not added");
-    return;
+    return false;
   }
-  // float zb_analog = analog;
   log_d("Setting analog input to %.1f", analog);
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_set_attribute_val(
+  ret = esp_zb_zcl_set_attribute_val(
     _endpoint, ESP_ZB_ZCL_CLUSTER_ID_ANALOG_INPUT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_ANALOG_INPUT_PRESENT_VALUE_ID, &analog, false
   );
   esp_zb_lock_release();
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set analog input: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeeAnalog::reportAnalogInput() {
+bool ZigbeeAnalog::reportAnalogInput() {
   /* Send report attributes command */
   esp_zb_zcl_report_attr_cmd_t report_attr_cmd;
   report_attr_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
@@ -96,12 +84,17 @@ void ZigbeeAnalog::reportAnalogInput() {
   report_attr_cmd.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC;
 
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd);
+  esp_err_t ret = esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd);
   esp_zb_lock_release();
+  if (ret != ESP_OK) {
+    log_e("Failed to send Analog Input report: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
   log_v("Analog Input report sent");
+  return true;
 }
 
-void ZigbeeAnalog::setAnalogInputReporting(uint16_t min_interval, uint16_t max_interval, float delta) {
+bool ZigbeeAnalog::setAnalogInputReporting(uint16_t min_interval, uint16_t max_interval, float delta) {
   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;
@@ -118,8 +111,13 @@ void ZigbeeAnalog::setAnalogInputReporting(uint16_t min_interval, uint16_t max_i
   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_err_t ret = esp_zb_zcl_update_reporting_info(&reporting_info);
   esp_zb_lock_release();
+  if (ret != ESP_OK) {
+    log_e("Failed to set Analog Input reporting: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
 #endif  // CONFIG_ZB_ENABLED
diff --git a/libraries/Zigbee/src/ep/ZigbeeAnalog.h b/libraries/Zigbee/src/ep/ZigbeeAnalog.h
index 8993c6ea1a4..03fbc678b6e 100644
--- a/libraries/Zigbee/src/ep/ZigbeeAnalog.h
+++ b/libraries/Zigbee/src/ep/ZigbeeAnalog.h
@@ -9,32 +9,15 @@
 #include "ZigbeeEP.h"
 #include "ha/esp_zigbee_ha_standard.h"
 
-// clang-format off
-#define ZIGBEE_DEFAULT_ANALOG_CONFIG()                                    \
-  {                                                                       \
-    .basic_cfg =                                                          \
-      {                                                                   \
-        .zcl_version = ESP_ZB_ZCL_BASIC_ZCL_VERSION_DEFAULT_VALUE,        \
-        .power_source = ESP_ZB_ZCL_BASIC_POWER_SOURCE_DEFAULT_VALUE,      \
-      },                                                                  \
-    .identify_cfg =                                                       \
-      {                                                                   \
-        .identify_time = ESP_ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE, \
-      },                                                                  \
-  }
-// clang-format on
-
 //enum for bits set to check what analog cluster were added
 enum zigbee_analog_clusters {
-  ANALOG_VALUE = 1,
-  ANALOG_INPUT = 2,
-  ANALOG_OUTPUT = 4
+  ANALOG_INPUT = 1,
+  ANALOG_OUTPUT = 2
 };
 
 typedef struct zigbee_analog_cfg_s {
   esp_zb_basic_cluster_cfg_t basic_cfg;
   esp_zb_identify_cluster_cfg_t identify_cfg;
-  esp_zb_analog_value_cluster_cfg_t analog_value_cfg;
   esp_zb_analog_output_cluster_cfg_t analog_output_cfg;
   esp_zb_analog_input_cluster_cfg_t analog_input_cfg;
 } zigbee_analog_cfg_t;
@@ -45,24 +28,22 @@ class ZigbeeAnalog : public ZigbeeEP {
   ~ZigbeeAnalog() {}
 
   // Add analog clusters
-  void addAnalogValue();
-  void addAnalogInput();
-  void addAnalogOutput();
+  bool addAnalogInput();
+  bool addAnalogOutput();
 
   // Use to set a cb function to be called on analog output change
   void onAnalogOutputChange(void (*callback)(float analog)) {
     _on_analog_output_change = callback;
   }
 
-  // Set the analog value / input
-  void setAnalogValue(float analog);
-  void setAnalogInput(float analog);
+  // Set the analog input value
+  bool setAnalogInput(float analog);
 
-  // Report Analog Input
-  void reportAnalogInput();
+  // Report Analog Input value
+  bool reportAnalogInput();
 
   // Set reporting for Analog Input
-  void setAnalogInputReporting(uint16_t min_interval, uint16_t max_interval, float delta);
+  bool setAnalogInputReporting(uint16_t min_interval, uint16_t max_interval, float delta);
 
 private:
   void zbAttributeSet(const esp_zb_zcl_set_attr_value_message_t *message) override;
diff --git a/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp
index 2718d9275c2..2b8271f09a9 100644
--- a/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp
+++ b/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp
@@ -24,25 +24,39 @@ ZigbeeCarbonDioxideSensor::ZigbeeCarbonDioxideSensor(uint8_t endpoint) : ZigbeeE
   _ep_config = {.endpoint = _endpoint, .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, .app_device_id = ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID, .app_device_version = 0};
 }
 
-void ZigbeeCarbonDioxideSensor::setMinMaxValue(float min, float max) {
+bool ZigbeeCarbonDioxideSensor::setMinMaxValue(float min, float max) {
   float zb_min = min / 1000000.0f;
   float zb_max = max / 1000000.0f;
   esp_zb_attribute_list_t *carbon_dioxide_measure_cluster =
     esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_CARBON_DIOXIDE_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
-  esp_zb_cluster_update_attr(carbon_dioxide_measure_cluster, ESP_ZB_ZCL_ATTR_CARBON_DIOXIDE_MEASUREMENT_MIN_MEASURED_VALUE_ID, (void *)&zb_min);
-  esp_zb_cluster_update_attr(carbon_dioxide_measure_cluster, ESP_ZB_ZCL_ATTR_CARBON_DIOXIDE_MEASUREMENT_MAX_MEASURED_VALUE_ID, (void *)&zb_max);
+  esp_err_t ret = esp_zb_cluster_update_attr(carbon_dioxide_measure_cluster, ESP_ZB_ZCL_ATTR_CARBON_DIOXIDE_MEASUREMENT_MIN_MEASURED_VALUE_ID, (void *)&zb_min);
+  if (ret != ESP_OK) {
+    log_e("Failed to set min value: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  ret = esp_zb_cluster_update_attr(carbon_dioxide_measure_cluster, ESP_ZB_ZCL_ATTR_CARBON_DIOXIDE_MEASUREMENT_MAX_MEASURED_VALUE_ID, (void *)&zb_max);
+  if (ret != ESP_OK) {
+    log_e("Failed to set max value: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeeCarbonDioxideSensor::setTolerance(float tolerance) {
+bool ZigbeeCarbonDioxideSensor::setTolerance(float tolerance) {
   float zb_tolerance = tolerance / 1000000.0f;
   esp_zb_attribute_list_t *carbon_dioxide_measure_cluster =
     esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_CARBON_DIOXIDE_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
-  esp_zb_carbon_dioxide_measurement_cluster_add_attr(
+  esp_err_t ret = esp_zb_carbon_dioxide_measurement_cluster_add_attr(
     carbon_dioxide_measure_cluster, ESP_ZB_ZCL_ATTR_CARBON_DIOXIDE_MEASUREMENT_TOLERANCE_ID, (void *)&zb_tolerance
   );
+  if (ret != ESP_OK) {
+    log_e("Failed to set tolerance: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeeCarbonDioxideSensor::setReporting(uint16_t min_interval, uint16_t max_interval, uint16_t delta) {
+bool ZigbeeCarbonDioxideSensor::setReporting(uint16_t min_interval, uint16_t max_interval, uint16_t delta) {
   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;
@@ -60,24 +74,35 @@ void ZigbeeCarbonDioxideSensor::setReporting(uint16_t min_interval, uint16_t max
   memcpy(&reporting_info.u.send_info.delta.s32, &delta_f, sizeof(float));
 
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_update_reporting_info(&reporting_info);
+  esp_err_t ret = esp_zb_zcl_update_reporting_info(&reporting_info);
   esp_zb_lock_release();
+  if (ret != ESP_OK) {
+    log_e("Failed to set reporting: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeeCarbonDioxideSensor::setCarbonDioxide(float carbon_dioxide) {
+bool ZigbeeCarbonDioxideSensor::setCarbonDioxide(float carbon_dioxide) {
+  esp_zb_zcl_status_t ret = ESP_ZB_ZCL_STATUS_SUCCESS;
   float zb_carbon_dioxide = carbon_dioxide / 1000000.0f;
   log_v("Updating carbon dioxide sensor value...");
   /* Update carbon dioxide sensor measured value */
   log_d("Setting carbon dioxide to %0.1f", carbon_dioxide);
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_set_attribute_val(
+  ret = esp_zb_zcl_set_attribute_val(
     _endpoint, ESP_ZB_ZCL_CLUSTER_ID_CARBON_DIOXIDE_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_CARBON_DIOXIDE_MEASUREMENT_MEASURED_VALUE_ID,
     &zb_carbon_dioxide, false
   );
   esp_zb_lock_release();
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set carbon dioxide: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeeCarbonDioxideSensor::report() {
+bool ZigbeeCarbonDioxideSensor::report() {
   /* Send report attributes command */
   esp_zb_zcl_report_attr_cmd_t report_attr_cmd;
   report_attr_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
@@ -88,9 +113,14 @@ void ZigbeeCarbonDioxideSensor::report() {
   report_attr_cmd.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC;
 
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd);
+  esp_err_t ret = esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd);
   esp_zb_lock_release();
+  if (ret != ESP_OK) {
+    log_e("Failed to send carbon dioxide report: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
   log_v("Carbon dioxide report sent");
+  return true;
 }
 
 #endif  // CONFIG_ZB_ENABLED
diff --git a/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.h b/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.h
index 41a9a4fb355..e0a6de48648 100644
--- a/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.h
+++ b/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.h
@@ -42,20 +42,20 @@ class ZigbeeCarbonDioxideSensor : public ZigbeeEP {
   ~ZigbeeCarbonDioxideSensor() {}
 
   // Set the carbon dioxide value in ppm
-  void setCarbonDioxide(float carbon_dioxide);
+  bool setCarbonDioxide(float carbon_dioxide);
 
   // Set the min and max value for the carbon dioxide sensor in ppm
-  void setMinMaxValue(float min, float max);
+  bool setMinMaxValue(float min, float max);
 
   // Set the tolerance value for the carbon dioxide sensor in ppm
-  void setTolerance(float tolerance);
+  bool setTolerance(float tolerance);
 
   // Set the reporting interval for carbon dioxide measurement in seconds and delta (carbon dioxide change in ppm)
   // NOTE: Delta reporting is currently not supported by the carbon dioxide sensor
-  void setReporting(uint16_t min_interval, uint16_t max_interval, uint16_t delta);
+  bool setReporting(uint16_t min_interval, uint16_t max_interval, uint16_t delta);
 
   // Report the carbon dioxide value
-  void report();
+  bool report();
 };
 
 #endif  // CONFIG_ZB_ENABLED
diff --git a/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.cpp b/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.cpp
index 585b1549816..caac73b5c68 100644
--- a/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.cpp
+++ b/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.cpp
@@ -117,7 +117,8 @@ void ZigbeeColorDimmableLight::lightChanged() {
   }
 }
 
-void ZigbeeColorDimmableLight::setLight(bool state, uint8_t level, uint8_t red, uint8_t green, uint8_t blue) {
+bool ZigbeeColorDimmableLight::setLight(bool state, uint8_t level, uint8_t red, uint8_t green, uint8_t blue) {
+  esp_zb_zcl_status_t ret = ESP_ZB_ZCL_STATUS_SUCCESS;
   //Update all attributes
   _current_state = state;
   _current_level = level;
@@ -126,55 +127,83 @@ void ZigbeeColorDimmableLight::setLight(bool state, uint8_t level, uint8_t red,
 
   espXyColor_t xy_color = espRgbColorToXYColor(_current_color);
   espHsvColor_t hsv_color = espRgbColorToHsvColor(_current_color);
+  uint8_t hue = (uint8_t)hsv_color.h;
 
   log_v("Updating light state: %d, level: %d, color: %d, %d, %d", state, level, red, green, blue);
   /* Update light clusters */
   esp_zb_lock_acquire(portMAX_DELAY);
   //set on/off state
-  esp_zb_zcl_set_attribute_val(
+  ret = esp_zb_zcl_set_attribute_val(
     _endpoint, ESP_ZB_ZCL_CLUSTER_ID_ON_OFF, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID, &_current_state, false
   );
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set light state: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    goto unlock_and_return;
+  }
   //set level
-  esp_zb_zcl_set_attribute_val(
+  ret = esp_zb_zcl_set_attribute_val(
     _endpoint, ESP_ZB_ZCL_CLUSTER_ID_LEVEL_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_LEVEL_CONTROL_CURRENT_LEVEL_ID, &_current_level, false
   );
-  //set xy color
-  esp_zb_zcl_set_attribute_val(
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set light level: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    goto unlock_and_return;
+  }
+  //set x color
+  ret = esp_zb_zcl_set_attribute_val(
     _endpoint, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_X_ID, &xy_color.x, false
   );
-  esp_zb_zcl_set_attribute_val(
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set light xy color: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    goto unlock_and_return;
+  }
+  //set y color
+  ret = esp_zb_zcl_set_attribute_val(
     _endpoint, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_Y_ID, &xy_color.y, false
   );
-  //set hsv color
-  uint8_t hue = (uint8_t)hsv_color.h;
-  esp_zb_zcl_set_attribute_val(
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set light y color: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    goto unlock_and_return;
+  }
+  //set hue
+  ret = esp_zb_zcl_set_attribute_val(
     _endpoint, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_HUE_ID, &hue, false
   );
-  esp_zb_zcl_set_attribute_val(
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set light hue: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    goto unlock_and_return;
+  }
+  //set saturation
+  ret = esp_zb_zcl_set_attribute_val(
     _endpoint, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_SATURATION_ID, &hsv_color.s, false
   );
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set light saturation: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    goto unlock_and_return;
+  }
+unlock_and_return:
   esp_zb_lock_release();
+  return ret == ESP_ZB_ZCL_STATUS_SUCCESS;
 }
 
-void ZigbeeColorDimmableLight::setLightState(bool state) {
-  setLight(state, _current_level, _current_color.r, _current_color.g, _current_color.b);
+bool ZigbeeColorDimmableLight::setLightState(bool state) {
+  return setLight(state, _current_level, _current_color.r, _current_color.g, _current_color.b);
 }
 
-void ZigbeeColorDimmableLight::setLightLevel(uint8_t level) {
-  setLight(_current_state, level, _current_color.r, _current_color.g, _current_color.b);
+bool ZigbeeColorDimmableLight::setLightLevel(uint8_t level) {
+  return setLight(_current_state, level, _current_color.r, _current_color.g, _current_color.b);
 }
 
-void ZigbeeColorDimmableLight::setLightColor(uint8_t red, uint8_t green, uint8_t blue) {
-  setLight(_current_state, _current_level, red, green, blue);
+bool ZigbeeColorDimmableLight::setLightColor(uint8_t red, uint8_t green, uint8_t blue) {
+  return setLight(_current_state, _current_level, red, green, blue);
 }
 
-void ZigbeeColorDimmableLight::setLightColor(espRgbColor_t rgb_color) {
-  setLight(_current_state, _current_level, rgb_color.r, rgb_color.g, rgb_color.b);
+bool ZigbeeColorDimmableLight::setLightColor(espRgbColor_t rgb_color) {
+  return setLight(_current_state, _current_level, rgb_color.r, rgb_color.g, rgb_color.b);
 }
 
-void ZigbeeColorDimmableLight::setLightColor(espHsvColor_t hsv_color) {
+bool ZigbeeColorDimmableLight::setLightColor(espHsvColor_t hsv_color) {
   espRgbColor_t rgb_color = espHsvColorToRgbColor(hsv_color);
-  setLight(_current_state, _current_level, rgb_color.r, rgb_color.g, rgb_color.b);
+  return setLight(_current_state, _current_level, rgb_color.r, rgb_color.g, rgb_color.b);
 }
 
 #endif  // CONFIG_ZB_ENABLED
diff --git a/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.h b/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.h
index 64df3565793..6681f213ad0 100644
--- a/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.h
+++ b/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.h
@@ -62,12 +62,12 @@ class ZigbeeColorDimmableLight : public ZigbeeEP {
     lightChanged();
   }
 
-  void setLightState(bool state);
-  void setLightLevel(uint8_t level);
-  void setLightColor(uint8_t red, uint8_t green, uint8_t blue);
-  void setLightColor(espRgbColor_t rgb_color);
-  void setLightColor(espHsvColor_t hsv_color);
-  void setLight(bool state, uint8_t level, uint8_t red, uint8_t green, uint8_t blue);
+  bool setLightState(bool state);
+  bool setLightLevel(uint8_t level);
+  bool setLightColor(uint8_t red, uint8_t green, uint8_t blue);
+  bool setLightColor(espRgbColor_t rgb_color);
+  bool setLightColor(espHsvColor_t hsv_color);
+  bool setLight(bool state, uint8_t level, uint8_t red, uint8_t green, uint8_t blue);
 
   bool getLightState() {
     return _current_state;
diff --git a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp
index 6237315d5d9..ced8e43d6ea 100644
--- a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp
+++ b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp
@@ -29,29 +29,39 @@ void ZigbeeContactSwitch::setIASClientEndpoint(uint8_t ep_number) {
   _ias_cie_endpoint = ep_number;
 }
 
-void ZigbeeContactSwitch::setClosed() {
+bool ZigbeeContactSwitch::setClosed() {
   log_v("Setting Contact switch to closed");
   uint8_t closed = 0;  // ALARM1 = 0, ALARM2 = 0
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_set_attribute_val(
+  esp_err_t ret = esp_zb_zcl_set_attribute_val(
     _endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONESTATUS_ID, &closed, false
   );
   esp_zb_lock_release();
+  if (ret != ESP_OK) {
+    log_e("Failed to set contact switch to closed: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
   _zone_status = closed;
-  report();
+  return report();
 }
 
-void ZigbeeContactSwitch::setOpen() {
+bool ZigbeeContactSwitch::setOpen() {
   log_v("Setting Contact switch to open");
   uint8_t open = ESP_ZB_ZCL_IAS_ZONE_ZONE_STATUS_ALARM1 | ESP_ZB_ZCL_IAS_ZONE_ZONE_STATUS_ALARM2;  // ALARM1 = 1, ALARM2 = 1
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_set_attribute_val(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONESTATUS_ID, &open, false);
+  esp_err_t ret = esp_zb_zcl_set_attribute_val(
+    _endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONESTATUS_ID, &open, false
+  );
   esp_zb_lock_release();
+  if (ret != ESP_OK) {
+    log_e("Failed to set contact switch to open: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
   _zone_status = open;
-  report();
+  return report();
 }
 
-void ZigbeeContactSwitch::report() {
+bool ZigbeeContactSwitch::report() {
   /* Send IAS Zone status changed notification command */
 
   esp_zb_zcl_ias_zone_status_change_notif_cmd_t status_change_notif_cmd;
@@ -66,9 +76,14 @@ void ZigbeeContactSwitch::report() {
   status_change_notif_cmd.delay = 0;
 
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_ias_zone_status_change_notif_cmd_req(&status_change_notif_cmd);
+  esp_err_t ret = esp_zb_zcl_ias_zone_status_change_notif_cmd_req(&status_change_notif_cmd);
   esp_zb_lock_release();
+  if (ret != ESP_OK) {
+    log_e("Failed to send IAS Zone status changed notification: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
   log_v("IAS Zone status changed notification sent");
+  return true;
 }
 
 void ZigbeeContactSwitch::zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) {
diff --git a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.h b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.h
index f44ce1cec40..b33effd8dfc 100644
--- a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.h
+++ b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.h
@@ -48,13 +48,13 @@ class ZigbeeContactSwitch : public ZigbeeEP {
   void setIASClientEndpoint(uint8_t ep_number);
 
   // Set the contact switch value to closed
-  void setClosed();
+  bool setClosed();
 
   // Set the contact switch value to open
-  void setOpen();
+  bool setOpen();
 
   // Report the contact switch value, done automatically after setting the position
-  void report();
+  bool report();
 
 private:
   void zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) override;
diff --git a/libraries/Zigbee/src/ep/ZigbeeDimmableLight.cpp b/libraries/Zigbee/src/ep/ZigbeeDimmableLight.cpp
index 34622d1d2db..05a7e5ad6c1 100644
--- a/libraries/Zigbee/src/ep/ZigbeeDimmableLight.cpp
+++ b/libraries/Zigbee/src/ep/ZigbeeDimmableLight.cpp
@@ -1,4 +1,3 @@
-
 #include "ZigbeeDimmableLight.h"
 #if CONFIG_ZB_ENABLED
 
@@ -52,7 +51,8 @@ void ZigbeeDimmableLight::lightChanged() {
   }
 }
 
-void ZigbeeDimmableLight::setLight(bool state, uint8_t level) {
+bool ZigbeeDimmableLight::setLight(bool state, uint8_t level) {
+  esp_zb_zcl_status_t ret = ESP_ZB_ZCL_STATUS_SUCCESS;
   // Update all attributes
   _current_state = state;
   _current_level = level;
@@ -62,22 +62,32 @@ void ZigbeeDimmableLight::setLight(bool state, uint8_t level) {
   /* Update light clusters */
   esp_zb_lock_acquire(portMAX_DELAY);
   // set on/off state
-  esp_zb_zcl_set_attribute_val(
+  ret = esp_zb_zcl_set_attribute_val(
     _endpoint, ESP_ZB_ZCL_CLUSTER_ID_ON_OFF, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID, &_current_state, false
   );
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set light state: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    goto unlock_and_return;
+  }
   // set level
-  esp_zb_zcl_set_attribute_val(
+  ret = esp_zb_zcl_set_attribute_val(
     _endpoint, ESP_ZB_ZCL_CLUSTER_ID_LEVEL_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_LEVEL_CONTROL_CURRENT_LEVEL_ID, &_current_level, false
   );
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set light level: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    goto unlock_and_return;
+  }
+unlock_and_return:
   esp_zb_lock_release();
+  return ret == ESP_ZB_ZCL_STATUS_SUCCESS;
 }
 
-void ZigbeeDimmableLight::setLightState(bool state) {
-  setLight(state, _current_level);
+bool ZigbeeDimmableLight::setLightState(bool state) {
+  return setLight(state, _current_level);
 }
 
-void ZigbeeDimmableLight::setLightLevel(uint8_t level) {
-  setLight(_current_state, level);
+bool ZigbeeDimmableLight::setLightLevel(uint8_t level) {
+  return setLight(_current_state, level);
 }
 
 esp_zb_cluster_list_t *ZigbeeDimmableLight::zigbee_dimmable_light_clusters_create(zigbee_dimmable_light_cfg_t *light_cfg) {
diff --git a/libraries/Zigbee/src/ep/ZigbeeDimmableLight.h b/libraries/Zigbee/src/ep/ZigbeeDimmableLight.h
index 45c3e97c00b..747fdbafaef 100644
--- a/libraries/Zigbee/src/ep/ZigbeeDimmableLight.h
+++ b/libraries/Zigbee/src/ep/ZigbeeDimmableLight.h
@@ -76,9 +76,9 @@ class ZigbeeDimmableLight : public ZigbeeEP {
     lightChanged();
   }
 
-  void setLightState(bool state);
-  void setLightLevel(uint8_t level);
-  void setLight(bool state, uint8_t level);
+  bool setLightState(bool state);
+  bool setLightLevel(uint8_t level);
+  bool setLight(bool state, uint8_t level);
 
   bool getLightState() {
     return _current_state;
@@ -89,7 +89,6 @@ class ZigbeeDimmableLight : public ZigbeeEP {
 
 private:
   void zbAttributeSet(const esp_zb_zcl_set_attr_value_message_t *message) override;
-
   void lightChanged();
   // callback function to be called on light change (State, Level)
   void (*_on_light_change)(bool, uint8_t);
diff --git a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp
index 70008fbab10..c5b62ee2b75 100644
--- a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp
+++ b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp
@@ -29,41 +29,58 @@ void ZigbeeDoorWindowHandle::setIASClientEndpoint(uint8_t ep_number) {
   _ias_cie_endpoint = ep_number;
 }
 
-void ZigbeeDoorWindowHandle::setClosed() {
+bool ZigbeeDoorWindowHandle::setClosed() {
+  esp_zb_zcl_status_t ret = ESP_ZB_ZCL_STATUS_SUCCESS;
   log_v("Setting Door/Window handle to closed");
   uint8_t closed = 0;  // ALARM1 = 0, ALARM2 = 0
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_set_attribute_val(
+  ret = esp_zb_zcl_set_attribute_val(
     _endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONESTATUS_ID, &closed, false
   );
   esp_zb_lock_release();
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set door/window handle to closed: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    return false;
+  }
   _zone_status = closed;
-  report();
+  return report();
 }
 
-void ZigbeeDoorWindowHandle::setOpen() {
+bool ZigbeeDoorWindowHandle::setOpen() {
+  esp_zb_zcl_status_t ret = ESP_ZB_ZCL_STATUS_SUCCESS;
   log_v("Setting Door/Window handle to open");
   uint8_t open = ESP_ZB_ZCL_IAS_ZONE_ZONE_STATUS_ALARM1 | ESP_ZB_ZCL_IAS_ZONE_ZONE_STATUS_ALARM2;  // ALARM1 = 1, ALARM2 = 1
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_set_attribute_val(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONESTATUS_ID, &open, false);
+  ret = esp_zb_zcl_set_attribute_val(
+    _endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONESTATUS_ID, &open, false
+  );
   esp_zb_lock_release();
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set door/window handle to open: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    return false;
+  }
   _zone_status = open;
-  report();
+  return report();
 }
 
-void ZigbeeDoorWindowHandle::setTilted() {
+bool ZigbeeDoorWindowHandle::setTilted() {
+  esp_zb_zcl_status_t ret = ESP_ZB_ZCL_STATUS_SUCCESS;
   log_v("Setting Door/Window handle to tilted");
   uint8_t tilted = ESP_ZB_ZCL_IAS_ZONE_ZONE_STATUS_ALARM1;  // ALARM1 = 1, ALARM2 = 0
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_set_attribute_val(
+  ret = esp_zb_zcl_set_attribute_val(
     _endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONESTATUS_ID, &tilted, false
   );
   esp_zb_lock_release();
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set door/window handle to tilted: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    return false;
+  }
   _zone_status = tilted;
-  report();
+  return report();
 }
 
-void ZigbeeDoorWindowHandle::report() {
+bool ZigbeeDoorWindowHandle::report() {
   /* Send IAS Zone status changed notification command */
 
   esp_zb_zcl_ias_zone_status_change_notif_cmd_t status_change_notif_cmd;
@@ -77,10 +94,12 @@ void ZigbeeDoorWindowHandle::report() {
   status_change_notif_cmd.zone_id = _zone_id;
   status_change_notif_cmd.delay = 0;
 
+  //NOTE: Check result of esp_zb_zcl_ias_zone_status_change_notif_cmd_req() and return true if success, false if failure
   esp_zb_lock_acquire(portMAX_DELAY);
   esp_zb_zcl_ias_zone_status_change_notif_cmd_req(&status_change_notif_cmd);
   esp_zb_lock_release();
   log_v("IAS Zone status changed notification sent");
+  return true;
 }
 
 void ZigbeeDoorWindowHandle::zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) {
diff --git a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h
index 8d4eff9e45a..efffd34b12f 100644
--- a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h
+++ b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h
@@ -49,16 +49,16 @@ class ZigbeeDoorWindowHandle : public ZigbeeEP {
   void setIASClientEndpoint(uint8_t ep_number);
 
   // Set the door/window handle value to closed
-  void setClosed();
+  bool setClosed();
 
   // Set the door/window handle value to open
-  void setOpen();
+  bool setOpen();
 
   // Set the door/window handle value to tilted
-  void setTilted();
+  bool setTilted();
 
   // Report the door/window handle value, done automatically after setting the position
-  void report();
+  bool report();
 
 private:
   void zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) override;
diff --git a/libraries/Zigbee/src/ep/ZigbeeFlowSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeFlowSensor.cpp
index 11fbf7c906b..8a60af5a8e1 100644
--- a/libraries/Zigbee/src/ep/ZigbeeFlowSensor.cpp
+++ b/libraries/Zigbee/src/ep/ZigbeeFlowSensor.cpp
@@ -22,24 +22,37 @@ ZigbeeFlowSensor::ZigbeeFlowSensor(uint8_t endpoint) : ZigbeeEP(endpoint) {
   _ep_config = {.endpoint = _endpoint, .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, .app_device_id = ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID, .app_device_version = 0};
 }
 
-void ZigbeeFlowSensor::setMinMaxValue(float min, float max) {
+bool ZigbeeFlowSensor::setMinMaxValue(float min, float max) {
   uint16_t zb_min = (uint16_t)(min * 10);
   uint16_t zb_max = (uint16_t)(max * 10);
   esp_zb_attribute_list_t *flow_measure_cluster =
     esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_FLOW_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
-  esp_zb_cluster_update_attr(flow_measure_cluster, ESP_ZB_ZCL_ATTR_FLOW_MEASUREMENT_MIN_VALUE_ID, (void *)&zb_min);
-  esp_zb_cluster_update_attr(flow_measure_cluster, ESP_ZB_ZCL_ATTR_FLOW_MEASUREMENT_MAX_VALUE_ID, (void *)&zb_max);
+  esp_err_t ret = esp_zb_cluster_update_attr(flow_measure_cluster, ESP_ZB_ZCL_ATTR_FLOW_MEASUREMENT_MIN_VALUE_ID, (void *)&zb_min);
+  if (ret != ESP_OK) {
+    log_e("Failed to set min value: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  ret = esp_zb_cluster_update_attr(flow_measure_cluster, ESP_ZB_ZCL_ATTR_FLOW_MEASUREMENT_MAX_VALUE_ID, (void *)&zb_max);
+  if (ret != ESP_OK) {
+    log_e("Failed to set max value: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeeFlowSensor::setTolerance(float tolerance) {
-  // Convert tolerance to ZCL uint16_t
+bool ZigbeeFlowSensor::setTolerance(float tolerance) {
   uint16_t zb_tolerance = (uint16_t)(tolerance * 10);
   esp_zb_attribute_list_t *flow_measure_cluster =
     esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_FLOW_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
-  esp_zb_flow_meas_cluster_add_attr(flow_measure_cluster, ESP_ZB_ZCL_ATTR_FLOW_MEASUREMENT_TOLERANCE_ID, (void *)&zb_tolerance);
+  esp_err_t ret = esp_zb_flow_meas_cluster_add_attr(flow_measure_cluster, ESP_ZB_ZCL_ATTR_FLOW_MEASUREMENT_TOLERANCE_ID, (void *)&zb_tolerance);
+  if (ret != ESP_OK) {
+    log_e("Failed to set tolerance: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeeFlowSensor::setReporting(uint16_t min_interval, uint16_t max_interval, float delta) {
+bool ZigbeeFlowSensor::setReporting(uint16_t min_interval, uint16_t max_interval, float delta) {
   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;
@@ -54,24 +67,39 @@ void ZigbeeFlowSensor::setReporting(uint16_t min_interval, uint16_t 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_err_t ret = esp_zb_zcl_update_reporting_info(&reporting_info);
   esp_zb_lock_release();
+
+  if (ret != ESP_OK) {
+    log_e("Failed to set reporting: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeeFlowSensor::setFlow(float flow) {
+bool ZigbeeFlowSensor::setFlow(float flow) {
+  esp_zb_zcl_status_t ret = ESP_ZB_ZCL_STATUS_SUCCESS;
   uint16_t zb_flow = (uint16_t)(flow * 10);
   log_v("Updating flow sensor value...");
   /* Update temperature sensor measured value */
   log_d("Setting flow to %d", zb_flow);
+
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_set_attribute_val(
+  ret = esp_zb_zcl_set_attribute_val(
     _endpoint, ESP_ZB_ZCL_CLUSTER_ID_FLOW_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_FLOW_MEASUREMENT_VALUE_ID, &zb_flow, false
   );
   esp_zb_lock_release();
+
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set flow value: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeeFlowSensor::report() {
+bool ZigbeeFlowSensor::report() {
   /* Send report attributes command */
   esp_zb_zcl_report_attr_cmd_t report_attr_cmd;
   report_attr_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
@@ -82,9 +110,15 @@ void ZigbeeFlowSensor::report() {
   report_attr_cmd.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC;
 
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd);
+  esp_err_t ret = esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd);
   esp_zb_lock_release();
+
+  if (ret != ESP_OK) {
+    log_e("Failed to send flow report: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
   log_v("Flow report sent");
+  return true;
 }
 
 #endif  // CONFIG_ZB_ENABLED
diff --git a/libraries/Zigbee/src/ep/ZigbeeFlowSensor.h b/libraries/Zigbee/src/ep/ZigbeeFlowSensor.h
index 5e9e20e4d1a..fa16b4a5636 100644
--- a/libraries/Zigbee/src/ep/ZigbeeFlowSensor.h
+++ b/libraries/Zigbee/src/ep/ZigbeeFlowSensor.h
@@ -42,19 +42,19 @@ class ZigbeeFlowSensor : public ZigbeeEP {
   ~ZigbeeFlowSensor() {}
 
   // Set the flow value in 0,1 m3/h
-  void setFlow(float value);
+  bool setFlow(float value);
 
   // Set the min and max value for the flow sensor in 0,1 m3/h
-  void setMinMaxValue(float min, float max);
+  bool setMinMaxValue(float min, float max);
 
   // Set the tolerance value for the flow sensor in 0,01 m3/h
-  void setTolerance(float tolerance);
+  bool setTolerance(float tolerance);
 
   // Set the reporting interval for flow measurement in seconds and delta (temp change in 0,1 m3/h)
-  void setReporting(uint16_t min_interval, uint16_t max_interval, float delta);
+  bool setReporting(uint16_t min_interval, uint16_t max_interval, float delta);
 
   // Report the flow value
-  void report();
+  bool report();
 };
 
 #endif  // CONFIG_ZB_ENABLED
diff --git a/libraries/Zigbee/src/ep/ZigbeeIlluminanceSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeIlluminanceSensor.cpp
index d38e9b1065f..f1661c3a026 100644
--- a/libraries/Zigbee/src/ep/ZigbeeIlluminanceSensor.cpp
+++ b/libraries/Zigbee/src/ep/ZigbeeIlluminanceSensor.cpp
@@ -10,20 +10,34 @@ ZigbeeIlluminanceSensor::ZigbeeIlluminanceSensor(uint8_t endpoint) : ZigbeeEP(en
   _ep_config = {.endpoint = _endpoint, .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, .app_device_id = ESP_ZB_HA_LIGHT_SENSOR_DEVICE_ID, .app_device_version = 0};
 }
 
-void ZigbeeIlluminanceSensor::setMinMaxValue(uint16_t min, uint16_t max) {
+bool ZigbeeIlluminanceSensor::setMinMaxValue(uint16_t min, uint16_t max) {
   esp_zb_attribute_list_t *light_measure_cluster =
     esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_ILLUMINANCE_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
-  esp_zb_cluster_update_attr(light_measure_cluster, ESP_ZB_ZCL_ATTR_ILLUMINANCE_MEASUREMENT_MIN_MEASURED_VALUE_ID, (void *)&min);
-  esp_zb_cluster_update_attr(light_measure_cluster, ESP_ZB_ZCL_ATTR_ILLUMINANCE_MEASUREMENT_MAX_MEASURED_VALUE_ID, (void *)&max);
+  esp_err_t ret = esp_zb_cluster_update_attr(light_measure_cluster, ESP_ZB_ZCL_ATTR_ILLUMINANCE_MEASUREMENT_MIN_MEASURED_VALUE_ID, (void *)&min);
+  if (ret != ESP_OK) {
+    log_e("Failed to set min value: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  ret = esp_zb_cluster_update_attr(light_measure_cluster, ESP_ZB_ZCL_ATTR_ILLUMINANCE_MEASUREMENT_MAX_MEASURED_VALUE_ID, (void *)&max);
+  if (ret != ESP_OK) {
+    log_e("Failed to set max value: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeeIlluminanceSensor::setTolerance(uint16_t tolerance) {
+bool ZigbeeIlluminanceSensor::setTolerance(uint16_t tolerance) {
   esp_zb_attribute_list_t *light_measure_cluster =
     esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_ILLUMINANCE_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
-  esp_zb_illuminance_meas_cluster_add_attr(light_measure_cluster, ESP_ZB_ZCL_ATTR_ILLUMINANCE_MEASUREMENT_TOLERANCE_ID, (void *)&tolerance);
+  esp_err_t ret = esp_zb_illuminance_meas_cluster_add_attr(light_measure_cluster, ESP_ZB_ZCL_ATTR_ILLUMINANCE_MEASUREMENT_TOLERANCE_ID, (void *)&tolerance);
+  if (ret != ESP_OK) {
+    log_e("Failed to set tolerance: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeeIlluminanceSensor::setReporting(uint16_t min_interval, uint16_t max_interval, uint16_t delta) {
+bool ZigbeeIlluminanceSensor::setReporting(uint16_t min_interval, uint16_t max_interval, uint16_t delta) {
   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;
@@ -38,24 +52,37 @@ void ZigbeeIlluminanceSensor::setReporting(uint16_t min_interval, uint16_t max_i
   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_err_t ret = esp_zb_zcl_update_reporting_info(&reporting_info);
   esp_zb_lock_release();
+
+  if (ret != ESP_OK) {
+    log_e("Failed to set reporting: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeeIlluminanceSensor::setIlluminance(uint16_t illuminanceValue) {
+bool ZigbeeIlluminanceSensor::setIlluminance(uint16_t illuminanceValue) {
+  esp_zb_zcl_status_t ret = ESP_ZB_ZCL_STATUS_SUCCESS;
   log_v("Updating Illuminance...");
   /* Update illuminance sensor measured illuminance */
   log_d("Setting Illuminance to %d", illuminanceValue);
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_set_attribute_val(
+  ret = esp_zb_zcl_set_attribute_val(
     _endpoint, ESP_ZB_ZCL_CLUSTER_ID_ILLUMINANCE_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_ILLUMINANCE_MEASUREMENT_MEASURED_VALUE_ID,
     &illuminanceValue, false
   );
   esp_zb_lock_release();
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set illuminance: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeeIlluminanceSensor::report() {
+bool ZigbeeIlluminanceSensor::report() {
   /* Send report attributes command */
   esp_zb_zcl_report_attr_cmd_t report_attr_cmd;
   report_attr_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
@@ -66,9 +93,14 @@ void ZigbeeIlluminanceSensor::report() {
   report_attr_cmd.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC;
 
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd);
+  esp_err_t ret = esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd);
   esp_zb_lock_release();
+  if (ret != ESP_OK) {
+    log_e("Failed to send illuminance report: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
   log_v("Illuminance report sent");
+  return true;
 }
 
 #endif  // CONFIG_ZB_ENABLED
diff --git a/libraries/Zigbee/src/ep/ZigbeeIlluminanceSensor.h b/libraries/Zigbee/src/ep/ZigbeeIlluminanceSensor.h
index 9c9d9e3fcaf..133dfc315db 100644
--- a/libraries/Zigbee/src/ep/ZigbeeIlluminanceSensor.h
+++ b/libraries/Zigbee/src/ep/ZigbeeIlluminanceSensor.h
@@ -33,19 +33,19 @@ class ZigbeeIlluminanceSensor : public ZigbeeEP {
   ~ZigbeeIlluminanceSensor() {}
 
   // Set the illuminance value
-  void setIlluminance(uint16_t value);
+  bool setIlluminance(uint16_t value);
 
   // Set the min and max value for the illuminance sensor
-  void setMinMaxValue(uint16_t min, uint16_t max);
+  bool setMinMaxValue(uint16_t min, uint16_t max);
 
   // Set the tolerance value for the illuminance sensor
-  void setTolerance(uint16_t tolerance);
+  bool setTolerance(uint16_t tolerance);
 
   // Set the reporting interval for illuminance measurement in seconds and delta
-  void setReporting(uint16_t min_interval, uint16_t max_interval, uint16_t delta);
+  bool setReporting(uint16_t min_interval, uint16_t max_interval, uint16_t delta);
 
   // Report the illuminance value
-  void report();
+  bool report();
 };
 
 #endif  // CONFIG_ZB_ENABLED
diff --git a/libraries/Zigbee/src/ep/ZigbeeLight.cpp b/libraries/Zigbee/src/ep/ZigbeeLight.cpp
index 2a87db71287..edfac04fcdf 100644
--- a/libraries/Zigbee/src/ep/ZigbeeLight.cpp
+++ b/libraries/Zigbee/src/ep/ZigbeeLight.cpp
@@ -33,17 +33,24 @@ void ZigbeeLight::lightChanged() {
   }
 }
 
-void ZigbeeLight::setLight(bool state) {
+bool ZigbeeLight::setLight(bool state) {
+  esp_zb_zcl_status_t ret = ESP_ZB_ZCL_STATUS_SUCCESS;
   _current_state = state;
   lightChanged();
 
   log_v("Updating on/off light state to %d", state);
   /* Update on/off light state */
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_set_attribute_val(
+  ret = esp_zb_zcl_set_attribute_val(
     _endpoint, ESP_ZB_ZCL_CLUSTER_ID_ON_OFF, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID, &_current_state, false
   );
   esp_zb_lock_release();
+
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set light state: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
 #endif  // CONFIG_ZB_ENABLED
diff --git a/libraries/Zigbee/src/ep/ZigbeeLight.h b/libraries/Zigbee/src/ep/ZigbeeLight.h
index 807802be9b3..773fbb14ec5 100644
--- a/libraries/Zigbee/src/ep/ZigbeeLight.h
+++ b/libraries/Zigbee/src/ep/ZigbeeLight.h
@@ -23,7 +23,7 @@ class ZigbeeLight : public ZigbeeEP {
     lightChanged();
   }
   // Use to control light state
-  void setLight(bool state);
+  bool setLight(bool state);
   // Use to get light state
   bool getLightState() {
     return _current_state;
diff --git a/libraries/Zigbee/src/ep/ZigbeeOccupancySensor.cpp b/libraries/Zigbee/src/ep/ZigbeeOccupancySensor.cpp
index 31a1f7e90e1..b8f88fed4a4 100644
--- a/libraries/Zigbee/src/ep/ZigbeeOccupancySensor.cpp
+++ b/libraries/Zigbee/src/ep/ZigbeeOccupancySensor.cpp
@@ -22,26 +22,41 @@ ZigbeeOccupancySensor::ZigbeeOccupancySensor(uint8_t endpoint) : ZigbeeEP(endpoi
   _ep_config = {.endpoint = _endpoint, .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, .app_device_id = ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID, .app_device_version = 0};
 }
 
-void ZigbeeOccupancySensor::setSensorType(uint8_t sensor_type) {
+bool ZigbeeOccupancySensor::setSensorType(uint8_t sensor_type) {
   uint8_t sensor_type_bitmap = 1 << sensor_type;
   esp_zb_attribute_list_t *occupancy_sens_cluster =
     esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_OCCUPANCY_SENSING, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
-  esp_zb_cluster_update_attr(occupancy_sens_cluster, ESP_ZB_ZCL_ATTR_OCCUPANCY_SENSING_OCCUPANCY_SENSOR_TYPE_ID, (void *)&sensor_type);
-  esp_zb_cluster_update_attr(occupancy_sens_cluster, ESP_ZB_ZCL_ATTR_OCCUPANCY_SENSING_OCCUPANCY_SENSOR_TYPE_BITMAP_ID, (void *)&sensor_type_bitmap);
+  esp_err_t ret = esp_zb_cluster_update_attr(occupancy_sens_cluster, ESP_ZB_ZCL_ATTR_OCCUPANCY_SENSING_OCCUPANCY_SENSOR_TYPE_ID, (void *)&sensor_type);
+  if (ret != ESP_OK) {
+    log_e("Failed to set sensor type: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  ret = esp_zb_cluster_update_attr(occupancy_sens_cluster, ESP_ZB_ZCL_ATTR_OCCUPANCY_SENSING_OCCUPANCY_SENSOR_TYPE_BITMAP_ID, (void *)&sensor_type_bitmap);
+  if (ret != ESP_OK) {
+    log_e("Failed to set sensor type bitmap: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeeOccupancySensor::setOccupancy(bool occupied) {
+bool ZigbeeOccupancySensor::setOccupancy(bool occupied) {
+  esp_zb_zcl_status_t ret = ESP_ZB_ZCL_STATUS_SUCCESS;
   log_v("Updating occupancy sensor value...");
   /* Update occupancy sensor value */
   log_d("Setting occupancy to %d", occupied);
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_set_attribute_val(
+  ret = esp_zb_zcl_set_attribute_val(
     _endpoint, ESP_ZB_ZCL_CLUSTER_ID_OCCUPANCY_SENSING, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_OCCUPANCY_SENSING_OCCUPANCY_ID, &occupied, false
   );
   esp_zb_lock_release();
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set occupancy: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeeOccupancySensor::report() {
+bool ZigbeeOccupancySensor::report() {
   /* Send report attributes command */
   esp_zb_zcl_report_attr_cmd_t report_attr_cmd;
   report_attr_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
@@ -52,9 +67,14 @@ void ZigbeeOccupancySensor::report() {
   report_attr_cmd.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC;
 
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd);
+  esp_err_t ret = esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd);
   esp_zb_lock_release();
+  if (ret != ESP_OK) {
+    log_e("Failed to send occupancy report: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
   log_v("Occupancy report sent");
+  return true;
 }
 
 #endif  // CONFIG_ZB_ENABLED
diff --git a/libraries/Zigbee/src/ep/ZigbeeOccupancySensor.h b/libraries/Zigbee/src/ep/ZigbeeOccupancySensor.h
index fa622d5a707..7408e10a76b 100644
--- a/libraries/Zigbee/src/ep/ZigbeeOccupancySensor.h
+++ b/libraries/Zigbee/src/ep/ZigbeeOccupancySensor.h
@@ -42,13 +42,13 @@ class ZigbeeOccupancySensor : public ZigbeeEP {
   ~ZigbeeOccupancySensor() {}
 
   // Set the occupancy value. True for occupied, false for unoccupied
-  void setOccupancy(bool occupied);
+  bool setOccupancy(bool occupied);
 
   // Set the sensor type, see esp_zb_zcl_occupancy_sensing_occupancy_sensor_type_t
-  void setSensorType(uint8_t sensor_type);
+  bool setSensorType(uint8_t sensor_type);
 
   // Report the occupancy value
-  void report();
+  bool report();
 };
 
 #endif  // CONFIG_ZB_ENABLED
diff --git a/libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp b/libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp
index 21456a51511..bca06a35d0c 100644
--- a/libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp
+++ b/libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp
@@ -22,21 +22,33 @@ ZigbeePressureSensor::ZigbeePressureSensor(uint8_t endpoint) : ZigbeeEP(endpoint
   _ep_config = {.endpoint = _endpoint, .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, .app_device_id = ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID, .app_device_version = 0};
 }
 
-void ZigbeePressureSensor::setMinMaxValue(int16_t min, int16_t max) {
-
+bool ZigbeePressureSensor::setMinMaxValue(int16_t min, int16_t max) {
   esp_zb_attribute_list_t *pressure_measure_cluster =
     esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_PRESSURE_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
-  esp_zb_cluster_update_attr(pressure_measure_cluster, ESP_ZB_ZCL_ATTR_PRESSURE_MEASUREMENT_MIN_VALUE_ID, (void *)&min);
-  esp_zb_cluster_update_attr(pressure_measure_cluster, ESP_ZB_ZCL_ATTR_PRESSURE_MEASUREMENT_MAX_VALUE_ID, (void *)&max);
+  esp_err_t ret = esp_zb_cluster_update_attr(pressure_measure_cluster, ESP_ZB_ZCL_ATTR_PRESSURE_MEASUREMENT_MIN_VALUE_ID, (void *)&min);
+  if (ret != ESP_OK) {
+    log_e("Failed to set min value: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  ret = esp_zb_cluster_update_attr(pressure_measure_cluster, ESP_ZB_ZCL_ATTR_PRESSURE_MEASUREMENT_MAX_VALUE_ID, (void *)&max);
+  if (ret != ESP_OK) {
+    log_e("Failed to set max value: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeePressureSensor::setTolerance(uint16_t tolerance) {
+bool ZigbeePressureSensor::setTolerance(uint16_t tolerance) {
   esp_zb_attribute_list_t *pressure_measure_cluster =
     esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_PRESSURE_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
-  esp_zb_pressure_meas_cluster_add_attr(pressure_measure_cluster, ESP_ZB_ZCL_ATTR_PRESSURE_MEASUREMENT_TOLERANCE_ID, (void *)&tolerance);
+  esp_err_t ret = esp_zb_pressure_meas_cluster_add_attr(pressure_measure_cluster, ESP_ZB_ZCL_ATTR_PRESSURE_MEASUREMENT_TOLERANCE_ID, (void *)&tolerance);
+  if (ret != ESP_OK) {
+    log_e("Failed to set tolerance: 0x%x: %s", ret, esp_err_to_name(ret));
+  }
+  return ret == ESP_OK;
 }
 
-void ZigbeePressureSensor::setReporting(uint16_t min_interval, uint16_t max_interval, uint16_t delta) {
+bool ZigbeePressureSensor::setReporting(uint16_t min_interval, uint16_t max_interval, uint16_t delta) {
   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;
@@ -52,22 +64,33 @@ void ZigbeePressureSensor::setReporting(uint16_t min_interval, uint16_t max_inte
   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_err_t ret = esp_zb_zcl_update_reporting_info(&reporting_info);
   esp_zb_lock_release();
+  if (ret != ESP_OK) {
+    log_e("Failed to set reporting: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeePressureSensor::setPressure(int16_t pressure) {
+bool ZigbeePressureSensor::setPressure(int16_t pressure) {
+  esp_zb_zcl_status_t ret = ESP_ZB_ZCL_STATUS_SUCCESS;
   log_v("Updating pressure sensor value...");
   /* Update pressure sensor measured value */
   log_d("Setting pressure to %d hPa", pressure);
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_set_attribute_val(
+  ret = esp_zb_zcl_set_attribute_val(
     _endpoint, ESP_ZB_ZCL_CLUSTER_ID_PRESSURE_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_PRESSURE_MEASUREMENT_VALUE_ID, &pressure, false
   );
   esp_zb_lock_release();
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set pressure: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeePressureSensor::report() {
+bool ZigbeePressureSensor::report() {
   /* Send report attributes command */
   esp_zb_zcl_report_attr_cmd_t report_attr_cmd;
   report_attr_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
@@ -78,9 +101,14 @@ void ZigbeePressureSensor::report() {
   report_attr_cmd.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC;
 
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd);
+  esp_err_t ret = esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd);
   esp_zb_lock_release();
+  if (ret != ESP_OK) {
+    log_e("Failed to send pressure report: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
   log_v("Pressure report sent");
+  return true;
 }
 
 #endif  // CONFIG_ZB_ENABLED
diff --git a/libraries/Zigbee/src/ep/ZigbeePressureSensor.h b/libraries/Zigbee/src/ep/ZigbeePressureSensor.h
index db14dd1c341..f93df7a7411 100644
--- a/libraries/Zigbee/src/ep/ZigbeePressureSensor.h
+++ b/libraries/Zigbee/src/ep/ZigbeePressureSensor.h
@@ -42,19 +42,19 @@ class ZigbeePressureSensor : public ZigbeeEP {
   ~ZigbeePressureSensor() {}
 
   // Set the pressure value in 1 hPa
-  void setPressure(int16_t value);
+  bool setPressure(int16_t value);
 
   // Set the min and max value for the pressure sensor in 1 hPa
-  void setMinMaxValue(int16_t min, int16_t max);
+  bool setMinMaxValue(int16_t min, int16_t max);
 
   // Set the tolerance value for the pressure sensor in 1 hPa
-  void setTolerance(uint16_t tolerance);
+  bool setTolerance(uint16_t tolerance);
 
   // Set the reporting interval for pressure measurement in seconds and delta (pressure change in 1 hPa)
-  void setReporting(uint16_t min_interval, uint16_t max_interval, uint16_t delta);
+  bool setReporting(uint16_t min_interval, uint16_t max_interval, uint16_t delta);
 
   // Report the pressure value
-  void report();
+  bool report();
 };
 
 #endif  // CONFIG_ZB_ENABLED
diff --git a/libraries/Zigbee/src/ep/ZigbeeTempSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeTempSensor.cpp
index b3ff03f0a6b..7126dae15cf 100644
--- a/libraries/Zigbee/src/ep/ZigbeeTempSensor.cpp
+++ b/libraries/Zigbee/src/ep/ZigbeeTempSensor.cpp
@@ -17,24 +17,38 @@ static int16_t zb_float_to_s16(float temp) {
   return (int16_t)(temp * 100);
 }
 
-void ZigbeeTempSensor::setMinMaxValue(float min, float max) {
+bool ZigbeeTempSensor::setMinMaxValue(float min, float max) {
   int16_t zb_min = zb_float_to_s16(min);
   int16_t zb_max = zb_float_to_s16(max);
   esp_zb_attribute_list_t *temp_measure_cluster =
     esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
-  esp_zb_cluster_update_attr(temp_measure_cluster, ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_MIN_VALUE_ID, (void *)&zb_min);
-  esp_zb_cluster_update_attr(temp_measure_cluster, ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_MAX_VALUE_ID, (void *)&zb_max);
+  esp_err_t ret = esp_zb_cluster_update_attr(temp_measure_cluster, ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_MIN_VALUE_ID, (void *)&zb_min);
+  if (ret != ESP_OK) {
+    log_e("Failed to set min value: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  ret = esp_zb_cluster_update_attr(temp_measure_cluster, ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_MAX_VALUE_ID, (void *)&zb_max);
+  if (ret != ESP_OK) {
+    log_e("Failed to set max value: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeeTempSensor::setTolerance(float tolerance) {
+bool ZigbeeTempSensor::setTolerance(float tolerance) {
   // Convert tolerance to ZCL uint16_t
   uint16_t zb_tolerance = (uint16_t)(tolerance * 100);
   esp_zb_attribute_list_t *temp_measure_cluster =
     esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
-  esp_zb_temperature_meas_cluster_add_attr(temp_measure_cluster, ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_TOLERANCE_ID, (void *)&zb_tolerance);
+  esp_err_t ret = esp_zb_temperature_meas_cluster_add_attr(temp_measure_cluster, ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_TOLERANCE_ID, (void *)&zb_tolerance);
+  if (ret != ESP_OK) {
+    log_e("Failed to set tolerance: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeeTempSensor::setReporting(uint16_t min_interval, uint16_t max_interval, float delta) {
+bool ZigbeeTempSensor::setReporting(uint16_t min_interval, uint16_t max_interval, float delta) {
   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;
@@ -50,23 +64,34 @@ void ZigbeeTempSensor::setReporting(uint16_t min_interval, uint16_t max_interval
   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_err_t ret = esp_zb_zcl_update_reporting_info(&reporting_info);
   esp_zb_lock_release();
+  if (ret != ESP_OK) {
+    log_e("Failed to set reporting: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeeTempSensor::setTemperature(float temperature) {
+bool ZigbeeTempSensor::setTemperature(float temperature) {
+  esp_zb_zcl_status_t ret = ESP_ZB_ZCL_STATUS_SUCCESS;
   int16_t zb_temperature = zb_float_to_s16(temperature);
   log_v("Updating temperature sensor value...");
   /* Update temperature sensor measured value */
   log_d("Setting temperature to %d", zb_temperature);
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_set_attribute_val(
+  ret = esp_zb_zcl_set_attribute_val(
     _endpoint, ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID, &zb_temperature, false
   );
   esp_zb_lock_release();
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set temperature: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeeTempSensor::reportTemperature() {
+bool ZigbeeTempSensor::reportTemperature() {
   /* Send report attributes command */
   esp_zb_zcl_report_attr_cmd_t report_attr_cmd;
   report_attr_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
@@ -77,9 +102,14 @@ void ZigbeeTempSensor::reportTemperature() {
   report_attr_cmd.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC;
 
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd);
+  esp_err_t ret = esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd);
   esp_zb_lock_release();
+  if (ret != ESP_OK) {
+    log_e("Failed to send temperature report: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
   log_v("Temperature report sent");
+  return true;
 }
 
 void ZigbeeTempSensor::addHumiditySensor(float min, float max, float tolerance) {
@@ -96,20 +126,26 @@ void ZigbeeTempSensor::addHumiditySensor(float min, float max, float tolerance)
   _humidity_sensor = true;
 }
 
-void ZigbeeTempSensor::setHumidity(float humidity) {
+bool ZigbeeTempSensor::setHumidity(float humidity) {
+  esp_zb_zcl_status_t ret = ESP_ZB_ZCL_STATUS_SUCCESS;
   int16_t zb_humidity = zb_float_to_s16(humidity);
   log_v("Updating humidity sensor value...");
   /* Update humidity sensor measured value */
   log_d("Setting humidity to %d", zb_humidity);
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_set_attribute_val(
+  ret = esp_zb_zcl_set_attribute_val(
     _endpoint, ESP_ZB_ZCL_CLUSTER_ID_REL_HUMIDITY_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_REL_HUMIDITY_MEASUREMENT_VALUE_ID, &zb_humidity,
     false
   );
   esp_zb_lock_release();
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set humidity: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeeTempSensor::reportHumidity() {
+bool ZigbeeTempSensor::reportHumidity() {
   /* Send report attributes command */
   esp_zb_zcl_report_attr_cmd_t report_attr_cmd;
   report_attr_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
@@ -120,12 +156,17 @@ void ZigbeeTempSensor::reportHumidity() {
   report_attr_cmd.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC;
 
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd);
+  esp_err_t ret = esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd);
   esp_zb_lock_release();
+  if (ret != ESP_OK) {
+    log_e("Failed to send humidity report: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
   log_v("Humidity report sent");
+  return true;
 }
 
-void ZigbeeTempSensor::setHumidityReporting(uint16_t min_interval, uint16_t max_interval, float delta) {
+bool ZigbeeTempSensor::setHumidityReporting(uint16_t min_interval, uint16_t max_interval, float delta) {
   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;
@@ -141,15 +182,22 @@ void ZigbeeTempSensor::setHumidityReporting(uint16_t min_interval, uint16_t max_
   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_err_t ret = esp_zb_zcl_update_reporting_info(&reporting_info);
   esp_zb_lock_release();
+  if (ret != ESP_OK) {
+    log_e("Failed to set humidity reporting: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeeTempSensor::report() {
-  reportTemperature();
+bool ZigbeeTempSensor::report() {
+  bool temp_ret = reportTemperature();
+  bool hum_ret = true;
   if (_humidity_sensor) {
-    reportHumidity();
+    hum_ret = reportHumidity();
   }
+  return temp_ret && hum_ret;
 }
 
 #endif  // CONFIG_ZB_ENABLED
diff --git a/libraries/Zigbee/src/ep/ZigbeeTempSensor.h b/libraries/Zigbee/src/ep/ZigbeeTempSensor.h
index 41da03d9db8..bc769b32de6 100644
--- a/libraries/Zigbee/src/ep/ZigbeeTempSensor.h
+++ b/libraries/Zigbee/src/ep/ZigbeeTempSensor.h
@@ -15,34 +15,34 @@ class ZigbeeTempSensor : public ZigbeeEP {
   ~ZigbeeTempSensor() {}
 
   // Set the temperature value in 0,01°C
-  void setTemperature(float value);
+  bool setTemperature(float value);
 
   // Set the min and max value for the temperature sensor in 0,01°C
-  void setMinMaxValue(float min, float max);
+  bool setMinMaxValue(float min, float max);
 
   // Set the tolerance value for the temperature sensor in 0,01°C
-  void setTolerance(float tolerance);
+  bool setTolerance(float tolerance);
 
   // Set the reporting interval for temperature measurement in seconds and delta (temp change in 0,01 °C)
-  void setReporting(uint16_t min_interval, uint16_t max_interval, float delta);
+  bool setReporting(uint16_t min_interval, uint16_t max_interval, float delta);
 
   // Report the temperature value
-  void reportTemperature();
+  bool reportTemperature();
 
   // Add humidity cluster to the temperature sensor device
   void addHumiditySensor(float min, float max, float tolerance);
 
   // Set the humidity value in 0,01%
-  void setHumidity(float value);
+  bool setHumidity(float value);
 
   // Set the reporting interval for humidity measurement in seconds and delta (humidity change in 0,01%)
-  void setHumidityReporting(uint16_t min_interval, uint16_t max_interval, float delta);
+  bool setHumidityReporting(uint16_t min_interval, uint16_t max_interval, float delta);
 
   // Report the humidity value
-  void reportHumidity();
+  bool reportHumidity();
 
   // Report the temperature and humidity values if humidity sensor is added
-  void report();
+  bool report();
 
 private:
   bool _humidity_sensor;
diff --git a/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp
index 9fc75297262..6be457c389a 100644
--- a/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp
+++ b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp
@@ -29,16 +29,22 @@ void ZigbeeVibrationSensor::setIASClientEndpoint(uint8_t ep_number) {
   _ias_cie_endpoint = ep_number;
 }
 
-void ZigbeeVibrationSensor::setVibration(bool sensed) {
+bool ZigbeeVibrationSensor::setVibration(bool sensed) {
+  esp_zb_zcl_status_t ret = ESP_ZB_ZCL_STATUS_SUCCESS;
   log_v("Setting Vibration sensor to %s", sensed ? "sensed" : "not sensed");
   uint8_t vibration = (uint8_t)sensed;
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_set_attribute_val(
+  ret = esp_zb_zcl_set_attribute_val(
     _endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONESTATUS_ID, &vibration, false
   );
   esp_zb_lock_release();
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set vibration status: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    return false;
+  }
   _zone_status = vibration;
   report();
+  return true;
 }
 
 void ZigbeeVibrationSensor::report() {
@@ -49,7 +55,6 @@ void ZigbeeVibrationSensor::report() {
   status_change_notif_cmd.zcl_basic_cmd.src_endpoint = _endpoint;
   status_change_notif_cmd.zcl_basic_cmd.dst_endpoint = _ias_cie_endpoint;  //default is 1
   memcpy(status_change_notif_cmd.zcl_basic_cmd.dst_addr_u.addr_long, _ias_cie_addr, sizeof(esp_zb_ieee_addr_t));
-
   status_change_notif_cmd.zone_status = _zone_status;
   status_change_notif_cmd.extend_status = 0;
   status_change_notif_cmd.zone_id = _zone_id;
diff --git a/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.h b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.h
index 1ee3740dcc3..2f67c7bb6b4 100644
--- a/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.h
+++ b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.h
@@ -48,7 +48,7 @@ class ZigbeeVibrationSensor : public ZigbeeEP {
   void setIASClientEndpoint(uint8_t ep_number);
 
   // Set the vibration sensor value (true = sensed, false = not sensed)
-  void setVibration(bool sensed);
+  bool setVibration(bool sensed);
 
   // Report the vibration sensor value, done automatically after setting the sensed value
   void report();
diff --git a/libraries/Zigbee/src/ep/ZigbeeWindSpeedSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeWindSpeedSensor.cpp
index d93b02adbc3..72184927d4d 100644
--- a/libraries/Zigbee/src/ep/ZigbeeWindSpeedSensor.cpp
+++ b/libraries/Zigbee/src/ep/ZigbeeWindSpeedSensor.cpp
@@ -28,25 +28,39 @@ static uint16_t zb_windspeed_to_u16(float windspeed) {
   return (uint16_t)(windspeed * 100);
 }
 
-void ZigbeeWindSpeedSensor::setMinMaxValue(float min, float max) {
+bool ZigbeeWindSpeedSensor::setMinMaxValue(float min, float max) {
   uint16_t zb_min = zb_windspeed_to_u16(min);
   uint16_t zb_max = zb_windspeed_to_u16(max);
   esp_zb_attribute_list_t *windspeed_measure_cluster =
     esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_WIND_SPEED_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
-  //
-  esp_zb_cluster_update_attr(windspeed_measure_cluster, ESP_ZB_ZCL_ATTR_WIND_SPEED_MEASUREMENT_MIN_MEASURED_VALUE_ID, (void *)&zb_min);
-  esp_zb_cluster_update_attr(windspeed_measure_cluster, ESP_ZB_ZCL_ATTR_WIND_SPEED_MEASUREMENT_MAX_MEASURED_VALUE_ID, (void *)&zb_max);
+  esp_err_t ret = esp_zb_cluster_update_attr(windspeed_measure_cluster, ESP_ZB_ZCL_ATTR_WIND_SPEED_MEASUREMENT_MIN_MEASURED_VALUE_ID, (void *)&zb_min);
+  if (ret != ESP_OK) {
+    log_e("Failed to set min value: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  ret = esp_zb_cluster_update_attr(windspeed_measure_cluster, ESP_ZB_ZCL_ATTR_WIND_SPEED_MEASUREMENT_MAX_MEASURED_VALUE_ID, (void *)&zb_max);
+  if (ret != ESP_OK) {
+    log_e("Failed to set max value: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeeWindSpeedSensor::setTolerance(float tolerance) {
+bool ZigbeeWindSpeedSensor::setTolerance(float tolerance) {
   // Convert tolerance to ZCL uint16_t
   uint16_t zb_tolerance = zb_windspeed_to_u16(tolerance);
   esp_zb_attribute_list_t *windspeed_measure_cluster =
     esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_WIND_SPEED_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
-  esp_zb_wind_speed_measurement_cluster_add_attr(windspeed_measure_cluster, ESP_ZB_ZCL_ATTR_WIND_SPEED_MEASUREMENT_TOLERANCE_ID, (void *)&zb_tolerance);
+  esp_err_t ret =
+    esp_zb_wind_speed_measurement_cluster_add_attr(windspeed_measure_cluster, ESP_ZB_ZCL_ATTR_WIND_SPEED_MEASUREMENT_TOLERANCE_ID, (void *)&zb_tolerance);
+  if (ret != ESP_OK) {
+    log_e("Failed to set tolerance: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeeWindSpeedSensor::setReporting(uint16_t min_interval, uint16_t max_interval, float delta) {
+bool ZigbeeWindSpeedSensor::setReporting(uint16_t min_interval, uint16_t max_interval, float delta) {
   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;
@@ -62,24 +76,35 @@ void ZigbeeWindSpeedSensor::setReporting(uint16_t min_interval, uint16_t max_int
   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_err_t ret = esp_zb_zcl_update_reporting_info(&reporting_info);
   esp_zb_lock_release();
+  if (ret != ESP_OK) {
+    log_e("Failed to set reporting: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeeWindSpeedSensor::setWindSpeed(float windspeed) {
+bool ZigbeeWindSpeedSensor::setWindSpeed(float windspeed) {
+  esp_zb_zcl_status_t ret = ESP_ZB_ZCL_STATUS_SUCCESS;
   uint16_t zb_windspeed = zb_windspeed_to_u16(windspeed);
   log_v("Updating windspeed sensor value...");
   /* Update windspeed sensor measured value */
   log_d("Setting windspeed to %d", zb_windspeed);
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_set_attribute_val(
+  ret = esp_zb_zcl_set_attribute_val(
     _endpoint, ESP_ZB_ZCL_CLUSTER_ID_WIND_SPEED_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_WIND_SPEED_MEASUREMENT_MEASURED_VALUE_ID,
     &zb_windspeed, false
   );
   esp_zb_lock_release();
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set wind speed: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeeWindSpeedSensor::reportWindSpeed() {
+bool ZigbeeWindSpeedSensor::reportWindSpeed() {
   /* Send report attributes command */
   esp_zb_zcl_report_attr_cmd_t report_attr_cmd;
   report_attr_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
@@ -90,9 +115,14 @@ void ZigbeeWindSpeedSensor::reportWindSpeed() {
   report_attr_cmd.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC;
 
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd);
+  esp_err_t ret = esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd);
   esp_zb_lock_release();
+  if (ret != ESP_OK) {
+    log_e("Failed to send wind speed report: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
   log_v("Wind speed measurement report sent");
+  return true;
 }
 
 #endif  //CONFIG_ZB_ENABLED
diff --git a/libraries/Zigbee/src/ep/ZigbeeWindSpeedSensor.h b/libraries/Zigbee/src/ep/ZigbeeWindSpeedSensor.h
index e091d3ae548..641c1d84780 100644
--- a/libraries/Zigbee/src/ep/ZigbeeWindSpeedSensor.h
+++ b/libraries/Zigbee/src/ep/ZigbeeWindSpeedSensor.h
@@ -40,17 +40,17 @@ class ZigbeeWindSpeedSensor : public ZigbeeEP {
   ~ZigbeeWindSpeedSensor() {}
 
   // Set the WindSpeed value in 0,01 m/s
-  void setWindSpeed(float value);
+  bool setWindSpeed(float value);
 
   // Set the min and max value for the WindSpeed sensor
-  void setMinMaxValue(float min, float max);
+  bool setMinMaxValue(float min, float max);
 
   // Set the tolerance value for the WindSpeed sensor
-  void setTolerance(float tolerance);
+  bool setTolerance(float tolerance);
 
   // Set the reporting interval for WindSpeed measurement in seconds and delta
-  void setReporting(uint16_t min_interval, uint16_t max_interval, float delta);
-  void reportWindSpeed();
+  bool setReporting(uint16_t min_interval, uint16_t max_interval, float delta);
+  bool reportWindSpeed();
 };
 
 #endif  //CONFIG_ZB_ENABLED
diff --git a/libraries/Zigbee/src/ep/ZigbeeWindowCovering.cpp b/libraries/Zigbee/src/ep/ZigbeeWindowCovering.cpp
index f6d6ec268ea..7c7889dbbf7 100644
--- a/libraries/Zigbee/src/ep/ZigbeeWindowCovering.cpp
+++ b/libraries/Zigbee/src/ep/ZigbeeWindowCovering.cpp
@@ -1,4 +1,3 @@
-
 #include "ZigbeeWindowCovering.h"
 #if CONFIG_ZB_ENABLED
 
@@ -72,13 +71,18 @@ ZigbeeWindowCovering::ZigbeeWindowCovering(uint8_t endpoint) : ZigbeeEP(endpoint
 }
 
 // Configuration methods for window covering
-void ZigbeeWindowCovering::setCoveringType(ZigbeeWindowCoveringType covering_type) {
+bool ZigbeeWindowCovering::setCoveringType(ZigbeeWindowCoveringType covering_type) {
   esp_zb_attribute_list_t *window_covering_cluster =
     esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_WINDOW_COVERING, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
-  esp_zb_cluster_update_attr(window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_WINDOW_COVERING_TYPE_ID, (void *)&covering_type);
+  esp_err_t ret = esp_zb_cluster_update_attr(window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_WINDOW_COVERING_TYPE_ID, (void *)&covering_type);
+  if (ret != ESP_OK) {
+    log_e("Failed to set covering type: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeeWindowCovering::setConfigStatus(
+bool ZigbeeWindowCovering::setConfigStatus(
   bool operational, bool online, bool commands_reversed, bool lift_closed_loop, bool tilt_closed_loop, bool lift_encoder_controlled,
   bool tilt_encoder_controlled
 ) {
@@ -93,10 +97,15 @@ void ZigbeeWindowCovering::setConfigStatus(
 
   esp_zb_attribute_list_t *window_covering_cluster =
     esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_WINDOW_COVERING, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
-  esp_zb_cluster_update_attr(window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CONFIG_STATUS_ID, (void *)&config_status);
+  esp_err_t ret = esp_zb_cluster_update_attr(window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CONFIG_STATUS_ID, (void *)&config_status);
+  if (ret != ESP_OK) {
+    log_e("Failed to set config status: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeeWindowCovering::setMode(bool motor_reversed, bool calibration_mode, bool maintenance_mode, bool leds_on) {
+bool ZigbeeWindowCovering::setMode(bool motor_reversed, bool calibration_mode, bool maintenance_mode, bool leds_on) {
   uint8_t mode = (motor_reversed ? ESP_ZB_ZCL_ATTR_WINDOW_COVERING_TYPE_REVERSED_MOTOR_DIRECTION : 0)
                  | (calibration_mode ? ESP_ZB_ZCL_ATTR_WINDOW_COVERING_TYPE_RUN_IN_CALIBRATION_MODE : 0)
                  | (maintenance_mode ? ESP_ZB_ZCL_ATTR_WINDOW_COVERING_TYPE_MOTOR_IS_RUNNING_IN_MAINTENANCE_MODE : 0)
@@ -106,10 +115,15 @@ void ZigbeeWindowCovering::setMode(bool motor_reversed, bool calibration_mode, b
 
   esp_zb_attribute_list_t *window_covering_cluster =
     esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_WINDOW_COVERING, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
-  esp_zb_cluster_update_attr(window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_MODE_ID, (void *)&mode);
+  esp_err_t ret = esp_zb_cluster_update_attr(window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_MODE_ID, (void *)&mode);
+  if (ret != ESP_OK) {
+    log_e("Failed to set mode: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
-void ZigbeeWindowCovering::setLimits(
+bool ZigbeeWindowCovering::setLimits(
   uint16_t installed_open_limit_lift, uint16_t installed_closed_limit_lift, uint16_t installed_open_limit_tilt, uint16_t installed_closed_limit_tilt
 ) {
   _installed_open_limit_lift = installed_open_limit_lift;
@@ -121,12 +135,41 @@ void ZigbeeWindowCovering::setLimits(
 
   esp_zb_attribute_list_t *window_covering_cluster =
     esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_WINDOW_COVERING, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
-  esp_zb_cluster_update_attr(window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_INSTALLED_OPEN_LIMIT_LIFT_ID, (void *)&_installed_open_limit_lift);
-  esp_zb_cluster_update_attr(window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_INSTALLED_CLOSED_LIMIT_LIFT_ID, (void *)&_installed_closed_limit_lift);
-  esp_zb_cluster_update_attr(window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_INSTALLED_OPEN_LIMIT_TILT_ID, (void *)&_installed_open_limit_tilt);
-  esp_zb_cluster_update_attr(window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_INSTALLED_CLOSED_LIMIT_TILT_ID, (void *)&_installed_closed_limit_tilt);
-  esp_zb_cluster_update_attr(window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_PHYSICAL_CLOSED_LIMIT_LIFT_ID, (void *)&_physical_closed_limit_lift);
-  esp_zb_cluster_update_attr(window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_PHY_CLOSED_LIMIT_TILT_ID, (void *)&_physical_closed_limit_tilt);
+  esp_err_t ret =
+    esp_zb_cluster_update_attr(window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_INSTALLED_OPEN_LIMIT_LIFT_ID, (void *)&_installed_open_limit_lift);
+  if (ret != ESP_OK) {
+    log_e("Failed to set installed open limit lift: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  ret =
+    esp_zb_cluster_update_attr(window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_INSTALLED_CLOSED_LIMIT_LIFT_ID, (void *)&_installed_closed_limit_lift);
+  if (ret != ESP_OK) {
+    log_e("Failed to set installed closed limit lift: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  ret = esp_zb_cluster_update_attr(window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_INSTALLED_OPEN_LIMIT_TILT_ID, (void *)&_installed_open_limit_tilt);
+  if (ret != ESP_OK) {
+    log_e("Failed to set installed open limit tilt: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  ret =
+    esp_zb_cluster_update_attr(window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_INSTALLED_CLOSED_LIMIT_TILT_ID, (void *)&_installed_closed_limit_tilt);
+  if (ret != ESP_OK) {
+    log_e("Failed to set installed closed limit tilt: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  ret =
+    esp_zb_cluster_update_attr(window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_PHYSICAL_CLOSED_LIMIT_LIFT_ID, (void *)&_physical_closed_limit_lift);
+  if (ret != ESP_OK) {
+    log_e("Failed to set physical closed limit lift: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  ret = esp_zb_cluster_update_attr(window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_PHY_CLOSED_LIMIT_TILT_ID, (void *)&_physical_closed_limit_tilt);
+  if (ret != ESP_OK) {
+    log_e("Failed to set physical closed limit tilt: 0x%x: %s", ret, esp_err_to_name(ret));
+    return false;
+  }
+  return true;
 }
 
 // Callback for handling incoming messages and commands
@@ -183,12 +226,13 @@ void ZigbeeWindowCovering::zbWindowCoveringMovementCmd(const esp_zb_zcl_window_c
       if (_current_lift_percentage != message->payload.percentage_lift_value) {
         _current_lift_percentage = message->payload.percentage_lift_value;
         goToLiftPercentage(_current_lift_percentage);
+        return;
       }
-      return;
     } else if (message->command == ESP_ZB_ZCL_CMD_WINDOW_COVERING_GO_TO_TILT_PERCENTAGE) {
       if (_current_tilt_percentage != message->payload.percentage_tilt_value) {
         _current_tilt_percentage = message->payload.percentage_tilt_value;
         goToTiltPercentage(_current_tilt_percentage);
+        return;
       }
     } else {
       log_w("Received message ignored. Command: %d not supported for Window Covering", message->command);
@@ -229,80 +273,122 @@ void ZigbeeWindowCovering::stop() {
 }
 
 // Methods to control window covering from user application
-void ZigbeeWindowCovering::setLiftPosition(uint16_t lift_position) {
+bool ZigbeeWindowCovering::setLiftPosition(uint16_t lift_position) {
+  esp_zb_zcl_status_t ret = ESP_ZB_ZCL_STATUS_SUCCESS;
   // Update both lift attributes
   _current_lift_position = lift_position;
   _current_lift_percentage = ((lift_position - _installed_open_limit_lift) * 100) / (_installed_closed_limit_lift - _installed_open_limit_lift);
-
   log_v("Updating window covering lift position to %d (%d%)", _current_lift_position, _current_lift_percentage);
-  // set lift state
+
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_set_attribute_val(
+  ret = esp_zb_zcl_set_attribute_val(
     _endpoint, ESP_ZB_ZCL_CLUSTER_ID_WINDOW_COVERING, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CURRENT_POSITION_LIFT_ID,
     &_current_lift_position, false
   );
-  esp_zb_zcl_set_attribute_val(
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set lift position: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    goto unlock_and_return;
+  }
+  ret = esp_zb_zcl_set_attribute_val(
     _endpoint, ESP_ZB_ZCL_CLUSTER_ID_WINDOW_COVERING, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CURRENT_POSITION_LIFT_PERCENTAGE_ID,
     &_current_lift_percentage, false
   );
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set lift percentage: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    goto unlock_and_return;
+  }
+unlock_and_return:
   esp_zb_lock_release();
+  return ret == ESP_ZB_ZCL_STATUS_SUCCESS;
 }
 
-void ZigbeeWindowCovering::setLiftPercentage(uint8_t lift_percentage) {
+bool ZigbeeWindowCovering::setLiftPercentage(uint8_t lift_percentage) {
+  esp_zb_zcl_status_t ret = ESP_ZB_ZCL_STATUS_SUCCESS;
   // Update both lift attributes
   _current_lift_percentage = lift_percentage;
   _current_lift_position = _installed_open_limit_lift + ((_installed_closed_limit_lift - _installed_open_limit_lift) * lift_percentage) / 100;
+  log_v("Updating window covering lift percentage to %d%% (%d)", _current_lift_percentage, _current_lift_position);
 
-  log_v("Updating window covering lift position to %d (%d%)", _current_lift_position, _current_lift_percentage);
-  // set lift state
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_set_attribute_val(
+  ret = esp_zb_zcl_set_attribute_val(
     _endpoint, ESP_ZB_ZCL_CLUSTER_ID_WINDOW_COVERING, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CURRENT_POSITION_LIFT_ID,
     &_current_lift_position, false
   );
-  esp_zb_zcl_set_attribute_val(
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set lift position: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    goto unlock_and_return;
+  }
+  ret = esp_zb_zcl_set_attribute_val(
     _endpoint, ESP_ZB_ZCL_CLUSTER_ID_WINDOW_COVERING, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CURRENT_POSITION_LIFT_PERCENTAGE_ID,
     &_current_lift_percentage, false
   );
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set lift percentage: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    goto unlock_and_return;
+  }
+unlock_and_return:
   esp_zb_lock_release();
+  return ret == ESP_ZB_ZCL_STATUS_SUCCESS;
 }
 
-void ZigbeeWindowCovering::setTiltPosition(uint16_t tilt_position) {
+bool ZigbeeWindowCovering::setTiltPosition(uint16_t tilt_position) {
+  esp_zb_zcl_status_t ret = ESP_ZB_ZCL_STATUS_SUCCESS;
   // Update both tilt attributes
   _current_tilt_position = tilt_position;
   _current_tilt_percentage = ((tilt_position - _installed_open_limit_tilt) * 100) / (_installed_closed_limit_tilt - _installed_open_limit_tilt);
 
   log_v("Updating window covering tilt position to %d (%d%)", _current_tilt_position, _current_tilt_percentage);
-  // set lift state
+
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_set_attribute_val(
+  ret = esp_zb_zcl_set_attribute_val(
     _endpoint, ESP_ZB_ZCL_CLUSTER_ID_WINDOW_COVERING, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CURRENT_POSITION_TILT_ID,
     &_current_tilt_position, false
   );
-  esp_zb_zcl_set_attribute_val(
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set tilt position: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    goto unlock_and_return;
+  }
+  ret = esp_zb_zcl_set_attribute_val(
     _endpoint, ESP_ZB_ZCL_CLUSTER_ID_WINDOW_COVERING, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CURRENT_POSITION_TILT_PERCENTAGE_ID,
     &_current_tilt_percentage, false
   );
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set tilt percentage: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    goto unlock_and_return;
+  }
+unlock_and_return:
   esp_zb_lock_release();
+  return ret == ESP_ZB_ZCL_STATUS_SUCCESS;
 }
 
-void ZigbeeWindowCovering::setTiltPercentage(uint8_t tilt_percentage) {
+bool ZigbeeWindowCovering::setTiltPercentage(uint8_t tilt_percentage) {
+  esp_zb_zcl_status_t ret = ESP_ZB_ZCL_STATUS_SUCCESS;
   // Update both tilt attributes
   _current_tilt_percentage = tilt_percentage;
-  _current_tilt_position = _installed_open_limit_lift + ((_installed_closed_limit_tilt - _installed_open_limit_tilt) * tilt_percentage) / 100;
+  _current_tilt_position = _installed_open_limit_tilt + ((_installed_closed_limit_tilt - _installed_open_limit_tilt) * tilt_percentage) / 100;
+
+  log_v("Updating window covering tilt percentage to %d%% (%d)", _current_tilt_percentage, _current_tilt_position);
 
-  log_v("Updating window covering tilt position to %d (%d%)", _current_tilt_position, _current_tilt_percentage);
-  // set lift state
   esp_zb_lock_acquire(portMAX_DELAY);
-  esp_zb_zcl_set_attribute_val(
+  ret = esp_zb_zcl_set_attribute_val(
     _endpoint, ESP_ZB_ZCL_CLUSTER_ID_WINDOW_COVERING, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CURRENT_POSITION_TILT_ID,
     &_current_tilt_position, false
   );
-  esp_zb_zcl_set_attribute_val(
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set tilt position: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    goto unlock_and_return;
+  }
+  ret = esp_zb_zcl_set_attribute_val(
     _endpoint, ESP_ZB_ZCL_CLUSTER_ID_WINDOW_COVERING, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CURRENT_POSITION_TILT_PERCENTAGE_ID,
     &_current_tilt_percentage, false
   );
+  if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
+    log_e("Failed to set tilt percentage: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
+    goto unlock_and_return;
+  }
+unlock_and_return:
   esp_zb_lock_release();
+  return ret == ESP_ZB_ZCL_STATUS_SUCCESS;
 }
 
 #endif  // CONFIG_ZB_ENABLED
diff --git a/libraries/Zigbee/src/ep/ZigbeeWindowCovering.h b/libraries/Zigbee/src/ep/ZigbeeWindowCovering.h
index f3a368370c4..288d92c5765 100644
--- a/libraries/Zigbee/src/ep/ZigbeeWindowCovering.h
+++ b/libraries/Zigbee/src/ep/ZigbeeWindowCovering.h
@@ -87,25 +87,25 @@ class ZigbeeWindowCovering : public ZigbeeEP {
   }
 
   // Set the window covering position in centimeters or percentage (0-100)
-  void setLiftPosition(uint16_t lift_position);
-  void setLiftPercentage(uint8_t lift_percentage);
-  void setTiltPosition(uint16_t tilt_position);
-  void setTiltPercentage(uint8_t tilt_percentage);
+  bool setLiftPosition(uint16_t lift_position);
+  bool setLiftPercentage(uint8_t lift_percentage);
+  bool setTiltPosition(uint16_t tilt_position);
+  bool setTiltPercentage(uint8_t tilt_percentage);
 
   // Set the window covering type (see ZigbeeWindowCoveringType)
-  void setCoveringType(ZigbeeWindowCoveringType covering_type);
+  bool setCoveringType(ZigbeeWindowCoveringType covering_type);
 
   // Set window covering config/status, for more info see esp_zb_zcl_window_covering_config_status_t
-  void setConfigStatus(
+  bool setConfigStatus(
     bool operational, bool online, bool commands_reversed, bool lift_closed_loop, bool tilt_closed_loop, bool lift_encoder_controlled,
     bool tilt_encoder_controlled
   );
 
   // Set configuration mode of window covering, for more info see esp_zb_zcl_window_covering_mode_t
-  void setMode(bool motor_reversed, bool calibration_mode, bool maintenance_mode, bool leds_on);
+  bool setMode(bool motor_reversed, bool calibration_mode, bool maintenance_mode, bool leds_on);
 
   // Set limits of motion, for more info see esp_zb_zcl_window_covering_info_attr_t
-  void setLimits(
+  bool setLimits(
     uint16_t installed_open_limit_lift, uint16_t installed_closed_limit_lift, uint16_t installed_open_limit_tilt, uint16_t installed_closed_limit_tilt
   );