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(length); // Cast size_t to char + zb_name[0] = static_cast(name_length); // Cast size_t to char + zb_model[0] = static_cast(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(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 );