From 29f4e482cd5acfe40f73ca0b58ba206ccac6a4d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Thu, 6 Nov 2025 12:39:48 +0100 Subject: [PATCH 1/8] feat(zibgee): Add requestIASZoneEnroll + error check fixes --- .../Zigbee_Contact_Switch.ino | 17 +++++++- .../Zigbee_Vibration_Sensor.ino | 16 +++++++- .../Zigbee/src/ep/ZigbeeContactSwitch.cpp | 39 ++++++++++++------- libraries/Zigbee/src/ep/ZigbeeContactSwitch.h | 7 ++++ .../Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp | 22 +++++++++-- .../Zigbee/src/ep/ZigbeeDoorWindowHandle.h | 7 ++++ .../Zigbee/src/ep/ZigbeeVibrationSensor.cpp | 27 ++++++++++--- .../Zigbee/src/ep/ZigbeeVibrationSensor.h | 9 ++++- 8 files changed, 118 insertions(+), 26 deletions(-) diff --git a/libraries/Zigbee/examples/Zigbee_Contact_Switch/Zigbee_Contact_Switch.ino b/libraries/Zigbee/examples/Zigbee_Contact_Switch/Zigbee_Contact_Switch.ino index ce9eedb683d..a017ae6582a 100644 --- a/libraries/Zigbee/examples/Zigbee_Contact_Switch/Zigbee_Contact_Switch.ino +++ b/libraries/Zigbee/examples/Zigbee_Contact_Switch/Zigbee_Contact_Switch.ino @@ -33,7 +33,7 @@ #include "Zigbee.h" /* Zigbee contact sensor configuration */ -#define CONTACT_SWITCH_ENDPOINT_NUMBER 10 +#define CONTACT_SWITCH_ENDPOINT_NUMBER 1 uint8_t button = BOOT_PIN; uint8_t sensor_pin = 4; @@ -67,6 +67,21 @@ void setup() { delay(100); } Serial.println(); + + // Request IAS Zone enroll + if (!zbContactSwitch.requestIASZoneEnroll()) { + Serial.println("Failed to request IAS Zone enroll!"); + Serial.println("Rebooting..."); + ESP.restart(); + } else { + Serial.println("IAS Zone enroll requested successfully!"); + } + while (!zbContactSwitch.enrolled()) { + Serial.print("."); + delay(100); + } + Serial.println(); + Serial.println("Zigbee enrolled successfully!"); } void loop() { diff --git a/libraries/Zigbee/examples/Zigbee_Vibration_Sensor/Zigbee_Vibration_Sensor.ino b/libraries/Zigbee/examples/Zigbee_Vibration_Sensor/Zigbee_Vibration_Sensor.ino index d9ac7b6e241..2c3f55d09a9 100644 --- a/libraries/Zigbee/examples/Zigbee_Vibration_Sensor/Zigbee_Vibration_Sensor.ino +++ b/libraries/Zigbee/examples/Zigbee_Vibration_Sensor/Zigbee_Vibration_Sensor.ino @@ -33,7 +33,7 @@ #include "Zigbee.h" /* Zigbee vibration sensor configuration */ -#define VIBRATION_SENSOR_ENDPOINT_NUMBER 10 +#define VIBRATION_SENSOR_ENDPOINT_NUMBER 1 uint8_t button = BOOT_PIN; uint8_t sensor_pin = 4; @@ -67,6 +67,20 @@ void setup() { delay(100); } Serial.println(); + // Request IAS Zone enroll + if (!zbVibrationSensor.requestIASZoneEnroll()) { + Serial.println("Failed to request IAS Zone enroll!"); + Serial.println("Rebooting..."); + ESP.restart(); + } else { + Serial.println("IAS Zone enroll requested successfully!"); + } + while (!zbVibrationSensor.enrolled()) { + Serial.print("."); + delay(100); + } + Serial.println(); + Serial.println("Zigbee enrolled successfully!"); } void loop() { diff --git a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp index 4142f87fe16..758c5cc207f 100644 --- a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp @@ -31,6 +31,7 @@ ZigbeeContactSwitch::ZigbeeContactSwitch(uint8_t endpoint) : ZigbeeEP(endpoint) _zone_status = 0; _zone_id = 0xff; _ias_cie_endpoint = 1; + _enrolled = false; //Create custom contact switch configuration zigbee_contact_switch_cfg_t contact_switch_cfg = ZIGBEE_DEFAULT_CONTACT_SWITCH_CONFIG(); @@ -44,15 +45,16 @@ void ZigbeeContactSwitch::setIASClientEndpoint(uint8_t ep_number) { } bool ZigbeeContactSwitch::setClosed() { + esp_zb_zcl_status_t ret = ESP_ZB_ZCL_STATUS_SUCCESS; log_v("Setting Contact switch to closed"); uint8_t closed = 0; // ALARM1 = 0, ALARM2 = 0 esp_zb_lock_acquire(portMAX_DELAY); - esp_err_t ret = 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_OK) { - log_e("Failed to set contact switch to closed: 0x%x: %s", ret, esp_err_to_name(ret)); + if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) { + log_e("Failed to set contact switch to closed: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret)); return false; } _zone_status = closed; @@ -60,15 +62,16 @@ bool ZigbeeContactSwitch::setClosed() { } bool ZigbeeContactSwitch::setOpen() { + esp_zb_zcl_status_t ret = ESP_ZB_ZCL_STATUS_SUCCESS; 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_err_t ret = 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, &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)); + if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) { + log_e("Failed to set contact switch to open: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret)); return false; } _zone_status = open; @@ -90,13 +93,9 @@ bool ZigbeeContactSwitch::report() { status_change_notif_cmd.delay = 0; esp_zb_lock_acquire(portMAX_DELAY); - esp_err_t ret = esp_zb_zcl_ias_zone_status_change_notif_cmd_req(&status_change_notif_cmd); + uint8_t tsn = 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"); + log_v("IAS Zone status changed notification sent with transaction sequence number: %u", tsn); return true; } @@ -115,11 +114,25 @@ void ZigbeeContactSwitch::zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enro ); esp_zb_lock_release(); _zone_id = message->zone_id; + _enrolled = true; } - } else { log_w("Received message ignored. Cluster ID: %d not supported for On/Off Light", message->info.cluster); } } +bool ZigbeeContactSwitch::requestIASZoneEnroll() { + esp_zb_zcl_ias_zone_enroll_request_cmd_t enroll_request; + enroll_request.zcl_basic_cmd.src_endpoint = _endpoint; + enroll_request.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; + enroll_request.zone_type = ESP_ZB_ZCL_IAS_ZONE_ZONETYPE_CONTACT_SWITCH; + enroll_request.manuf_code = 0; + + esp_zb_lock_acquire(portMAX_DELAY); + uint8_t tsn = esp_zb_zcl_ias_zone_enroll_cmd_req(&enroll_request); + esp_zb_lock_release(); + log_v("IAS Zone enroll request send with transaction sequence number: %u", tsn); + return true; +} + #endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.h b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.h index b3be38c3eb4..c317a9ddac2 100644 --- a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.h +++ b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.h @@ -70,12 +70,19 @@ class ZigbeeContactSwitch : public ZigbeeEP { // Report the contact switch value, done automatically after setting the position bool report(); + // Request a new IAS zone enroll, needed to be called after rebooting already configured device + bool requestIASZoneEnroll(); + + // Check if the device is enrolled in the IAS Zone + bool enrolled() { return _enrolled; } + private: void zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) override; uint8_t _zone_status; uint8_t _zone_id; esp_zb_ieee_addr_t _ias_cie_addr; uint8_t _ias_cie_endpoint; + bool _enrolled; }; #endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp index 2ca032b01e5..ec51f205cea 100644 --- a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp @@ -31,6 +31,7 @@ ZigbeeDoorWindowHandle::ZigbeeDoorWindowHandle(uint8_t endpoint) : ZigbeeEP(endp _zone_status = 0; _zone_id = 0xff; _ias_cie_endpoint = 1; + _enrolled = false; //Create custom door window handle configuration zigbee_door_window_handle_cfg_t door_window_handle_cfg = ZIGBEE_DEFAULT_DOOR_WINDOW_HANDLE_CONFIG(); @@ -108,11 +109,10 @@ bool 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); + uint8_t tsn = 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"); + log_v("IAS Zone status changed notification sent with transaction sequence number: %u", tsn); return true; } @@ -131,11 +131,25 @@ void ZigbeeDoorWindowHandle::zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_e ); esp_zb_lock_release(); _zone_id = message->zone_id; + _enrolled = true; } - } else { log_w("Received message ignored. Cluster ID: %d not supported for On/Off Light", message->info.cluster); } } +bool ZigbeeDoorWindowHandle::requestIASZoneEnroll() { + esp_zb_zcl_ias_zone_enroll_request_cmd_t enroll_request; + enroll_request.zcl_basic_cmd.src_endpoint = _endpoint; + enroll_request.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; + enroll_request.zone_type = ESP_ZB_ZCL_IAS_ZONE_ZONETYPE_DOOR_WINDOW_HANDLE; + enroll_request.manuf_code = 0; + + esp_zb_lock_acquire(portMAX_DELAY); + uint8_t tsn = esp_zb_zcl_ias_zone_enroll_cmd_req(&enroll_request); + esp_zb_lock_release(); + log_v("IAS Zone enroll request send with transaction sequence number: %u", tsn); + return true; +} + #endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h index d4a2d81eb39..cb58c251f1a 100644 --- a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h +++ b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h @@ -74,12 +74,19 @@ class ZigbeeDoorWindowHandle : public ZigbeeEP { // Report the door/window handle value, done automatically after setting the position bool report(); + // Request a new IAS zone enroll, needed to be called after rebooting already configured device + bool requestIASZoneEnroll(); + + // Check if the device is enrolled in the IAS Zone + bool enrolled() { return _enrolled; } + private: void zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) override; uint8_t _zone_status; uint8_t _zone_id; esp_zb_ieee_addr_t _ias_cie_addr; uint8_t _ias_cie_endpoint; + bool _enrolled; }; #endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp index 218638ed3cb..7906a935659 100644 --- a/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp @@ -31,6 +31,7 @@ ZigbeeVibrationSensor::ZigbeeVibrationSensor(uint8_t endpoint) : ZigbeeEP(endpoi _zone_status = 0; _zone_id = 0xff; _ias_cie_endpoint = 1; + _enrolled = false; //Create custom vibration sensor configuration zigbee_vibration_sensor_cfg_t vibration_sensor_cfg = ZIGBEE_DEFAULT_VIBRATION_SENSOR_CONFIG(); @@ -57,11 +58,10 @@ bool ZigbeeVibrationSensor::setVibration(bool sensed) { return false; } _zone_status = vibration; - report(); - return true; + return report(); } -void ZigbeeVibrationSensor::report() { +bool ZigbeeVibrationSensor::report() { /* Send IAS Zone status changed notification command */ esp_zb_zcl_ias_zone_status_change_notif_cmd_t status_change_notif_cmd; @@ -75,9 +75,10 @@ void ZigbeeVibrationSensor::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); + uint8_t tsn = 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"); + log_v("IAS Zone status changed notification sent with transaction sequence number: %u", tsn); + return true; } void ZigbeeVibrationSensor::zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) { @@ -95,11 +96,25 @@ void ZigbeeVibrationSensor::zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_en ); esp_zb_lock_release(); _zone_id = message->zone_id; + _enrolled = true; } - } else { log_w("Received message ignored. Cluster ID: %d not supported for On/Off Light", message->info.cluster); } } +bool ZigbeeVibrationSensor::requestIASZoneEnroll() { + esp_zb_zcl_ias_zone_enroll_request_cmd_t enroll_request; + enroll_request.zcl_basic_cmd.src_endpoint = _endpoint; + enroll_request.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; + enroll_request.zone_type = ESP_ZB_ZCL_IAS_ZONE_ZONETYPE_VIBRATION_MOVEMENT; + enroll_request.manuf_code = 0; + + esp_zb_lock_acquire(portMAX_DELAY); + uint8_t tsn = esp_zb_zcl_ias_zone_enroll_cmd_req(&enroll_request); + esp_zb_lock_release(); + log_v("IAS Zone enroll request send with transaction sequence number: %u", tsn); + return true; +} + #endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.h b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.h index 9757257b5c1..02ec5573ca6 100644 --- a/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.h +++ b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.h @@ -65,7 +65,13 @@ class ZigbeeVibrationSensor : public ZigbeeEP { bool setVibration(bool sensed); // Report the vibration sensor value, done automatically after setting the sensed value - void report(); + bool report(); + + // Request a new IAS zone enroll, needed to be called after rebooting already configured device + bool requestIASZoneEnroll(); + + // Check if the device is enrolled in the IAS Zone + bool enrolled() { return _enrolled; } private: void zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) override; @@ -73,6 +79,7 @@ class ZigbeeVibrationSensor : public ZigbeeEP { uint8_t _zone_id; esp_zb_ieee_addr_t _ias_cie_addr; uint8_t _ias_cie_endpoint; + bool _enrolled; }; #endif // CONFIG_ZB_ENABLED From 8ae3d7053e330b47af1a06c88d4bccf4c625c7e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Thu, 6 Nov 2025 12:51:07 +0100 Subject: [PATCH 2/8] fix: Spelling Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp | 2 +- libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp | 2 +- libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp index 758c5cc207f..ca47ecddf85 100644 --- a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp @@ -131,7 +131,7 @@ bool ZigbeeContactSwitch::requestIASZoneEnroll() { esp_zb_lock_acquire(portMAX_DELAY); uint8_t tsn = esp_zb_zcl_ias_zone_enroll_cmd_req(&enroll_request); esp_zb_lock_release(); - log_v("IAS Zone enroll request send with transaction sequence number: %u", tsn); + log_v("IAS Zone enroll request sent with transaction sequence number: %u", tsn); return true; } diff --git a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp index ec51f205cea..72ce2ef6b55 100644 --- a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp @@ -148,7 +148,7 @@ bool ZigbeeDoorWindowHandle::requestIASZoneEnroll() { esp_zb_lock_acquire(portMAX_DELAY); uint8_t tsn = esp_zb_zcl_ias_zone_enroll_cmd_req(&enroll_request); esp_zb_lock_release(); - log_v("IAS Zone enroll request send with transaction sequence number: %u", tsn); + log_v("IAS Zone enroll request sent with transaction sequence number: %u", tsn); return true; } diff --git a/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp index 7906a935659..c20961b5263 100644 --- a/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp @@ -113,7 +113,7 @@ bool ZigbeeVibrationSensor::requestIASZoneEnroll() { esp_zb_lock_acquire(portMAX_DELAY); uint8_t tsn = esp_zb_zcl_ias_zone_enroll_cmd_req(&enroll_request); esp_zb_lock_release(); - log_v("IAS Zone enroll request send with transaction sequence number: %u", tsn); + log_v("IAS Zone enroll request sent with transaction sequence number: %u", tsn); return true; } From de5fe0aa39ccfdc7304e68129c50047f00baba6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Thu, 6 Nov 2025 13:02:22 +0100 Subject: [PATCH 3/8] fix(zigbee): Remove transaction sequence logging --- libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp | 8 ++++---- libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp | 8 ++++---- libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp index 758c5cc207f..5adcb45c49c 100644 --- a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp @@ -93,9 +93,9 @@ bool ZigbeeContactSwitch::report() { status_change_notif_cmd.delay = 0; esp_zb_lock_acquire(portMAX_DELAY); - uint8_t tsn = esp_zb_zcl_ias_zone_status_change_notif_cmd_req(&status_change_notif_cmd); + esp_zb_zcl_ias_zone_status_change_notif_cmd_req(&status_change_notif_cmd); //return transaction sequence number, ignore it esp_zb_lock_release(); - log_v("IAS Zone status changed notification sent with transaction sequence number: %u", tsn); + log_v("IAS Zone status changed notification sent"); return true; } @@ -129,9 +129,9 @@ bool ZigbeeContactSwitch::requestIASZoneEnroll() { enroll_request.manuf_code = 0; esp_zb_lock_acquire(portMAX_DELAY); - uint8_t tsn = esp_zb_zcl_ias_zone_enroll_cmd_req(&enroll_request); + esp_zb_zcl_ias_zone_enroll_cmd_req(&enroll_request); //return transaction sequence number, ignore it esp_zb_lock_release(); - log_v("IAS Zone enroll request send with transaction sequence number: %u", tsn); + log_v("IAS Zone enroll request sent"); return true; } diff --git a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp index ec51f205cea..28ad76bb5a7 100644 --- a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp @@ -110,9 +110,9 @@ bool ZigbeeDoorWindowHandle::report() { status_change_notif_cmd.delay = 0; esp_zb_lock_acquire(portMAX_DELAY); - uint8_t tsn = esp_zb_zcl_ias_zone_status_change_notif_cmd_req(&status_change_notif_cmd); + esp_zb_zcl_ias_zone_status_change_notif_cmd_req(&status_change_notif_cmd); //return transaction sequence number, ignore it esp_zb_lock_release(); - log_v("IAS Zone status changed notification sent with transaction sequence number: %u", tsn); + log_v("IAS Zone status changed notification sent"); return true; } @@ -146,9 +146,9 @@ bool ZigbeeDoorWindowHandle::requestIASZoneEnroll() { enroll_request.manuf_code = 0; esp_zb_lock_acquire(portMAX_DELAY); - uint8_t tsn = esp_zb_zcl_ias_zone_enroll_cmd_req(&enroll_request); + esp_zb_zcl_ias_zone_enroll_cmd_req(&enroll_request); //return transaction sequence number, ignore it esp_zb_lock_release(); - log_v("IAS Zone enroll request send with transaction sequence number: %u", tsn); + log_v("IAS Zone enroll request sent"); return true; } diff --git a/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp index 7906a935659..fb75a262a9a 100644 --- a/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp @@ -75,9 +75,9 @@ bool ZigbeeVibrationSensor::report() { status_change_notif_cmd.delay = 0; esp_zb_lock_acquire(portMAX_DELAY); - uint8_t tsn = esp_zb_zcl_ias_zone_status_change_notif_cmd_req(&status_change_notif_cmd); + esp_zb_zcl_ias_zone_status_change_notif_cmd_req(&status_change_notif_cmd); //return transaction sequence number, ignore it esp_zb_lock_release(); - log_v("IAS Zone status changed notification sent with transaction sequence number: %u", tsn); + log_v("IAS Zone status changed notification sent"); return true; } @@ -111,9 +111,9 @@ bool ZigbeeVibrationSensor::requestIASZoneEnroll() { enroll_request.manuf_code = 0; esp_zb_lock_acquire(portMAX_DELAY); - uint8_t tsn = esp_zb_zcl_ias_zone_enroll_cmd_req(&enroll_request); + esp_zb_zcl_ias_zone_enroll_cmd_req(&enroll_request); //return transaction sequence number, ignore it esp_zb_lock_release(); - log_v("IAS Zone enroll request send with transaction sequence number: %u", tsn); + log_v("IAS Zone enroll request sent"); return true; } From 89103205d8896112724a8b45a8f3696056c55d17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Thu, 6 Nov 2025 20:23:49 +0100 Subject: [PATCH 4/8] feat(zigbee): Add restoreIASZone from flash method --- .../Zigbee_Contact_Switch.ino | 35 ++++++++++++++---- .../Zigbee_Vibration_Sensor.ino | 36 +++++++++++++++---- libraries/Zigbee/keywords.txt | 3 ++ .../Zigbee/src/ep/ZigbeeContactSwitch.cpp | 28 +++++++++++++++ libraries/Zigbee/src/ep/ZigbeeContactSwitch.h | 5 ++- .../Zigbee/src/ep/ZigbeeVibrationSensor.cpp | 28 +++++++++++++++ .../Zigbee/src/ep/ZigbeeVibrationSensor.h | 5 ++- 7 files changed, 126 insertions(+), 14 deletions(-) diff --git a/libraries/Zigbee/examples/Zigbee_Contact_Switch/Zigbee_Contact_Switch.ino b/libraries/Zigbee/examples/Zigbee_Contact_Switch/Zigbee_Contact_Switch.ino index a017ae6582a..eec1c3b1c05 100644 --- a/libraries/Zigbee/examples/Zigbee_Contact_Switch/Zigbee_Contact_Switch.ino +++ b/libraries/Zigbee/examples/Zigbee_Contact_Switch/Zigbee_Contact_Switch.ino @@ -31,6 +31,7 @@ #endif #include "Zigbee.h" +#include /* Zigbee contact sensor configuration */ #define CONTACT_SWITCH_ENDPOINT_NUMBER 1 @@ -39,9 +40,16 @@ uint8_t sensor_pin = 4; ZigbeeContactSwitch zbContactSwitch = ZigbeeContactSwitch(CONTACT_SWITCH_ENDPOINT_NUMBER); +/* Preferences for storing ENROLLED flag to persist across reboots */ +Preferences preferences; + void setup() { Serial.begin(115200); + preferences.begin("Zigbee", false); // Save ENROLLED flag in flash so it persists across reboots + bool enrolled = preferences.getBool("ENROLLED"); // Get ENROLLED flag from preferences + preferences.end(); + // Init button + switch pinMode(button, INPUT_PULLUP); pinMode(sensor_pin, INPUT_PULLUP); @@ -68,20 +76,30 @@ void setup() { } Serial.println(); - // Request IAS Zone enroll - if (!zbContactSwitch.requestIASZoneEnroll()) { - Serial.println("Failed to request IAS Zone enroll!"); - Serial.println("Rebooting..."); - ESP.restart(); + // Check if device has been enrolled before restarting - if so, restore IAS Zone enroll, otherwise request new IAS Zone enroll + if (enrolled) { + Serial.println("Device has been enrolled before - restoring IAS Zone enrollment"); + zbContactSwitch.restoreIASZoneEnroll(); } else { - Serial.println("IAS Zone enroll requested successfully!"); + Serial.println("Device is factory new - first time joining network - requesting new IAS Zone enrollment"); + zbContactSwitch.requestIASZoneEnroll(); } + while (!zbContactSwitch.enrolled()) { Serial.print("."); delay(100); } Serial.println(); Serial.println("Zigbee enrolled successfully!"); + + // Store ENROLLED flag only if this was a new enrollment (previous flag was false) + // Skip writing if we just restored enrollment (flag was already true) + if (!enrolled) { + preferences.begin("Zigbee", false); + preferences.putBool("ENROLLED", true); // set ENROLLED flag to true + preferences.end(); + Serial.println("ENROLLED flag saved to preferences"); + } } void loop() { @@ -106,6 +124,11 @@ void loop() { if ((millis() - startTime) > 3000) { // If key pressed for more than 3secs, factory reset Zigbee and reboot Serial.println("Resetting Zigbee to factory and rebooting in 1s."); + // Clear the ENROLLED flag from preferences + preferences.begin("Zigbee", false); + preferences.putBool("ENROLLED", false); // set ENROLLED flag to false + preferences.end(); + Serial.println("ENROLLED flag cleared from preferences"); delay(1000); Zigbee.factoryReset(); } diff --git a/libraries/Zigbee/examples/Zigbee_Vibration_Sensor/Zigbee_Vibration_Sensor.ino b/libraries/Zigbee/examples/Zigbee_Vibration_Sensor/Zigbee_Vibration_Sensor.ino index 2c3f55d09a9..b7797290161 100644 --- a/libraries/Zigbee/examples/Zigbee_Vibration_Sensor/Zigbee_Vibration_Sensor.ino +++ b/libraries/Zigbee/examples/Zigbee_Vibration_Sensor/Zigbee_Vibration_Sensor.ino @@ -31,6 +31,7 @@ #endif #include "Zigbee.h" +#include /* Zigbee vibration sensor configuration */ #define VIBRATION_SENSOR_ENDPOINT_NUMBER 1 @@ -39,9 +40,16 @@ uint8_t sensor_pin = 4; ZigbeeVibrationSensor zbVibrationSensor = ZigbeeVibrationSensor(VIBRATION_SENSOR_ENDPOINT_NUMBER); +/* Preferences for storing ENROLLED flag to persist across reboots */ +Preferences preferences; + void setup() { Serial.begin(115200); + preferences.begin("Zigbee", false); // Save ENROLLED flag in flash so it persists across reboots + bool enrolled = preferences.getBool("ENROLLED"); // Get ENROLLED flag from preferences + preferences.end(); + // Init button + sensor pinMode(button, INPUT_PULLUP); pinMode(sensor_pin, INPUT); @@ -67,20 +75,31 @@ void setup() { delay(100); } Serial.println(); - // Request IAS Zone enroll - if (!zbVibrationSensor.requestIASZoneEnroll()) { - Serial.println("Failed to request IAS Zone enroll!"); - Serial.println("Rebooting..."); - ESP.restart(); + + // Check if device has been enrolled before restarting - if so, restore IAS Zone enroll, otherwise request new IAS Zone enroll + if (enrolled) { + Serial.println("Device has been enrolled before - restoring IAS Zone enrollment"); + zbVibrationSensor.restoreIASZoneEnroll(); } else { - Serial.println("IAS Zone enroll requested successfully!"); + Serial.println("Device is factory new - first time joining network - requesting new IAS Zone enrollment"); + zbVibrationSensor.requestIASZoneEnroll(); } + while (!zbVibrationSensor.enrolled()) { Serial.print("."); delay(100); } Serial.println(); Serial.println("Zigbee enrolled successfully!"); + + // Store ENROLLED flag only if this was a new enrollment (previous flag was false) + // Skip writing if we just restored enrollment (flag was already true) + if (!enrolled) { + preferences.begin("Zigbee", false); + preferences.putBool("ENROLLED", true); // set ENROLLED flag to true + preferences.end(); + Serial.println("ENROLLED flag saved to preferences"); + } } void loop() { @@ -109,6 +128,11 @@ void loop() { if ((millis() - startTime) > 3000) { // If key pressed for more than 3secs, factory reset Zigbee and reboot Serial.println("Resetting Zigbee to factory and rebooting in 1s."); + // Clear the ENROLLED flag from preferences + preferences.begin("Zigbee", false); + preferences.putBool("ENROLLED", false); // set ENROLLED flag to false + preferences.end(); + Serial.println("ENROLLED flag cleared from preferences"); delay(1000); Zigbee.factoryReset(); } diff --git a/libraries/Zigbee/keywords.txt b/libraries/Zigbee/keywords.txt index 44067fc4886..c940d85d4d1 100644 --- a/libraries/Zigbee/keywords.txt +++ b/libraries/Zigbee/keywords.txt @@ -209,6 +209,9 @@ setIASClientEndpoint KEYWORD2 setClosed KEYWORD2 setOpen KEYWORD2 setTilted KEYWORD2 +requestIASZoneEnroll KEYWORD2 +restoreIASZoneEnroll KEYWORD2 +enrolled KEYWORD2 # ZigbeeVibrationSensor setVibration KEYWORD2 diff --git a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp index 5adcb45c49c..00d93bad5bb 100644 --- a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp @@ -135,4 +135,32 @@ bool ZigbeeContactSwitch::requestIASZoneEnroll() { return true; } +bool ZigbeeContactSwitch::restoreIASZoneEnroll() { + esp_zb_lock_acquire(portMAX_DELAY); + memcpy( + _ias_cie_addr, + (*(esp_zb_ieee_addr_t *) + esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_IAS_CIE_ADDRESS_ID) + ->data_p), + sizeof(esp_zb_ieee_addr_t) + ); + _zone_id = (*(uint8_t *) + esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONEID_ID) + ->data_p); + esp_zb_lock_release(); + + log_d("Restored IAS Zone enroll: zone id(%d), ias cie address(%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X)", _zone_id, _ias_cie_addr[0], _ias_cie_addr[1], _ias_cie_addr[2], _ias_cie_addr[3], _ias_cie_addr[4], _ias_cie_addr[5], _ias_cie_addr[6], _ias_cie_addr[7]); + + if (_zone_id == 0xFF) { + log_e("Failed to restore IAS Zone enroll: zone id not found"); + return false; + } + if (_ias_cie_addr == NULL) { + log_e("Failed to restore IAS Zone enroll: ias cie address not found"); + return false; + } + _enrolled = true; + return true; +} + #endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.h b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.h index c317a9ddac2..c558a1c009c 100644 --- a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.h +++ b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.h @@ -70,9 +70,12 @@ class ZigbeeContactSwitch : public ZigbeeEP { // Report the contact switch value, done automatically after setting the position bool report(); - // Request a new IAS zone enroll, needed to be called after rebooting already configured device + // Request a new IAS zone enroll, can be called to enroll a new device or to re-enroll an already enrolled device bool requestIASZoneEnroll(); + // Restore IAS Zone enroll, needed to be called after rebooting already enrolled device - restored from flash memory (faster for sleepy devices) + bool restoreIASZoneEnroll(); + // Check if the device is enrolled in the IAS Zone bool enrolled() { return _enrolled; } diff --git a/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp index fb75a262a9a..f6e0183ffac 100644 --- a/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp @@ -117,4 +117,32 @@ bool ZigbeeVibrationSensor::requestIASZoneEnroll() { return true; } +bool ZigbeeVibrationSensor::restoreIASZoneEnroll() { + esp_zb_lock_acquire(portMAX_DELAY); + memcpy( + _ias_cie_addr, + (*(esp_zb_ieee_addr_t *) + esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_IAS_CIE_ADDRESS_ID) + ->data_p), + sizeof(esp_zb_ieee_addr_t) + ); + _zone_id = (*(uint8_t *) + esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONEID_ID) + ->data_p); + esp_zb_lock_release(); + + log_d("Restored IAS Zone enroll: zone id(%d), ias cie address(%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X)", _zone_id, _ias_cie_addr[0], _ias_cie_addr[1], _ias_cie_addr[2], _ias_cie_addr[3], _ias_cie_addr[4], _ias_cie_addr[5], _ias_cie_addr[6], _ias_cie_addr[7]); + + if (_zone_id == 0xFF) { + log_e("Failed to restore IAS Zone enroll: zone id not found"); + return false; + } + if (_ias_cie_addr == NULL) { + log_e("Failed to restore IAS Zone enroll: ias cie address not found"); + return false; + } + _enrolled = true; + return true; +} + #endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.h b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.h index 02ec5573ca6..1cad6af7a08 100644 --- a/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.h +++ b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.h @@ -67,9 +67,12 @@ class ZigbeeVibrationSensor : public ZigbeeEP { // Report the vibration sensor value, done automatically after setting the sensed value bool report(); - // Request a new IAS zone enroll, needed to be called after rebooting already configured device + // Request a new IAS zone enroll, can be called to enroll a new device or to re-enroll an already enrolled device bool requestIASZoneEnroll(); + // Restore IAS Zone enroll, needed to be called after rebooting already enrolled device - restored from flash memory (faster for sleepy devices) + bool restoreIASZoneEnroll(); + // Check if the device is enrolled in the IAS Zone bool enrolled() { return _enrolled; } From c38a689b838b94a45fb722b0716b3cfa76a91851 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Thu, 6 Nov 2025 20:30:37 +0100 Subject: [PATCH 5/8] docs(zigbee): Add docs for new methods --- docs/en/zigbee/ep_contact_switch.rst | 43 +++++++++++++++++++++--- docs/en/zigbee/ep_door_window_handle.rst | 43 +++++++++++++++++++++--- docs/en/zigbee/ep_vibration_sensor.rst | 37 ++++++++++++++++++-- 3 files changed, 111 insertions(+), 12 deletions(-) diff --git a/docs/en/zigbee/ep_contact_switch.rst b/docs/en/zigbee/ep_contact_switch.rst index f7f6dc15c66..d9780632c22 100644 --- a/docs/en/zigbee/ep_contact_switch.rst +++ b/docs/en/zigbee/ep_contact_switch.rst @@ -63,6 +63,17 @@ Sets the contact switch to open state. This function will return ``true`` if successful, ``false`` otherwise. +report +^^^^^^ + +Manually reports the current contact state. + +.. code-block:: arduino + + bool report(); + +This function will return ``true`` if successful, ``false`` otherwise. + setIASClientEndpoint ^^^^^^^^^^^^^^^^^^^^ @@ -74,16 +85,38 @@ Sets the IAS Client endpoint number (default is 1). * ``ep_number`` - IAS Client endpoint number -report -^^^^^^ +requestIASZoneEnroll +^^^^^^^^^^^^^^^^^^^^ -Manually reports the current contact state. +Requests a new IAS Zone enrollment. Can be called to enroll a new device or to re-enroll an already enrolled device. .. code-block:: arduino - bool report(); + bool requestIASZoneEnroll(); -This function will return ``true`` if successful, ``false`` otherwise. +This function will return ``true`` if the enrollment request was sent successfully, ``false`` otherwise. The actual enrollment status should be checked using the ``enrolled()`` method after waiting for the enrollment response. + +restoreIASZoneEnroll +^^^^^^^^^^^^^^^^^^^^ + +Restores IAS Zone enrollment from stored attributes. This method should be called after rebooting an already enrolled device. It restores the enrollment information from flash memory, which is faster for sleepy devices compared to requesting a new enrollment. + +.. code-block:: arduino + + bool restoreIASZoneEnroll(); + +This function will return ``true`` if the enrollment was successfully restored, ``false`` otherwise. The enrollment information (zone ID and IAS CIE address) must be available in the device's stored attributes for this to succeed. + +enrolled +^^^^^^^^ + +Checks if the device is currently enrolled in the IAS Zone. + +.. code-block:: arduino + + bool enrolled(); + +This function returns ``true`` if the device is enrolled, ``false`` otherwise. Use this method to check the enrollment status after calling ``requestIASZoneEnroll()`` or ``restoreIASZoneEnroll()``. Example ------- diff --git a/docs/en/zigbee/ep_door_window_handle.rst b/docs/en/zigbee/ep_door_window_handle.rst index 53203f463dd..3ca932e4df7 100644 --- a/docs/en/zigbee/ep_door_window_handle.rst +++ b/docs/en/zigbee/ep_door_window_handle.rst @@ -67,6 +67,17 @@ Sets the door/window handle to tilted position. This function will return ``true`` if successful, ``false`` otherwise. +report +^^^^^^ + +Manually reports the current handle position. + +.. code-block:: arduino + + bool report(); + +This function will return ``true`` if successful, ``false`` otherwise. + setIASClientEndpoint ^^^^^^^^^^^^^^^^^^^^ @@ -78,16 +89,38 @@ Sets the IAS Client endpoint number (default is 1). * ``ep_number`` - IAS Client endpoint number -report -^^^^^^ +requestIASZoneEnroll +^^^^^^^^^^^^^^^^^^^^ -Manually reports the current handle position. +Requests a new IAS Zone enrollment. Can be called to enroll a new device or to re-enroll an already enrolled device. .. code-block:: arduino - bool report(); + bool requestIASZoneEnroll(); -This function will return ``true`` if successful, ``false`` otherwise. +This function will return ``true`` if the enrollment request was sent successfully, ``false`` otherwise. The actual enrollment status should be checked using the ``enrolled()`` method after waiting for the enrollment response. + +restoreIASZoneEnroll +^^^^^^^^^^^^^^^^^^^^ + +Restores IAS Zone enrollment from stored attributes. This method should be called after rebooting an already enrolled device. It restores the enrollment information from flash memory, which is faster for sleepy devices compared to requesting a new enrollment. + +.. code-block:: arduino + + bool restoreIASZoneEnroll(); + +This function will return ``true`` if the enrollment was successfully restored, ``false`` otherwise. The enrollment information (zone ID and IAS CIE address) must be available in the device's stored attributes for this to succeed. + +enrolled +^^^^^^^^ + +Checks if the device is currently enrolled in the IAS Zone. + +.. code-block:: arduino + + bool enrolled(); + +This function returns ``true`` if the device is enrolled, ``false`` otherwise. Use this method to check the enrollment status after calling ``requestIASZoneEnroll()``. Example ------- diff --git a/docs/en/zigbee/ep_vibration_sensor.rst b/docs/en/zigbee/ep_vibration_sensor.rst index 896c4672c6d..d8ca3fdd5f4 100644 --- a/docs/en/zigbee/ep_vibration_sensor.rst +++ b/docs/en/zigbee/ep_vibration_sensor.rst @@ -73,9 +73,42 @@ Manually reports the current vibration state. .. code-block:: arduino - void report(); + bool report(); -This function does not return a value. +This function will return ``true`` if successful, ``false`` otherwise. + +requestIASZoneEnroll +^^^^^^^^^^^^^^^^^^^^ + +Requests a new IAS Zone enrollment. Can be called to enroll a new device or to re-enroll an already enrolled device. + +.. code-block:: arduino + + bool requestIASZoneEnroll(); + +This function will return ``true`` if the enrollment request was sent successfully, ``false`` otherwise. The actual enrollment status should be checked using the ``enrolled()`` method after waiting for the enrollment response. + +restoreIASZoneEnroll +^^^^^^^^^^^^^^^^^^^^ + +Restores IAS Zone enrollment from stored attributes. This method should be called after rebooting an already enrolled device. It restores the enrollment information from flash memory, which is faster for sleepy devices compared to requesting a new enrollment. + +.. code-block:: arduino + + bool restoreIASZoneEnroll(); + +This function will return ``true`` if the enrollment was successfully restored, ``false`` otherwise. The enrollment information (zone ID and IAS CIE address) must be available in the device's stored attributes for this to succeed. + +enrolled +^^^^^^^^ + +Checks if the device is currently enrolled in the IAS Zone. + +.. code-block:: arduino + + bool enrolled(); + +This function returns ``true`` if the device is enrolled, ``false`` otherwise. Use this method to check the enrollment status after calling ``requestIASZoneEnroll()`` or ``restoreIASZoneEnroll()``. Example ------- From 082313dd562710c8c839d5d150c692b62576bcc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Thu, 6 Nov 2025 20:37:00 +0100 Subject: [PATCH 6/8] feat(zigbee): Update checking logic --- .../Zigbee/src/ep/ZigbeeContactSwitch.cpp | 30 +++++++++---------- .../Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp | 28 +++++++++++++++++ .../Zigbee/src/ep/ZigbeeDoorWindowHandle.h | 5 +++- .../Zigbee/src/ep/ZigbeeVibrationSensor.cpp | 30 +++++++++---------- 4 files changed, 62 insertions(+), 31 deletions(-) diff --git a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp index 00d93bad5bb..8127366efbc 100644 --- a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp @@ -137,26 +137,26 @@ bool ZigbeeContactSwitch::requestIASZoneEnroll() { bool ZigbeeContactSwitch::restoreIASZoneEnroll() { esp_zb_lock_acquire(portMAX_DELAY); - memcpy( - _ias_cie_addr, - (*(esp_zb_ieee_addr_t *) - esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_IAS_CIE_ADDRESS_ID) - ->data_p), - sizeof(esp_zb_ieee_addr_t) - ); - _zone_id = (*(uint8_t *) - esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONEID_ID) - ->data_p); + esp_zb_zcl_attr_t *ias_cie_attr = esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_IAS_CIE_ADDRESS_ID); + esp_zb_zcl_attr_t *zone_id_attr = esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONEID_ID); esp_zb_lock_release(); + if (ias_cie_attr == NULL || ias_cie_attr->data_p == NULL) { + log_e("Failed to restore IAS Zone enroll: ias cie address attribute not found"); + return false; + } + if (zone_id_attr == NULL || zone_id_attr->data_p == NULL) { + log_e("Failed to restore IAS Zone enroll: zone id attribute not found"); + return false; + } + + memcpy(_ias_cie_addr, (*(esp_zb_ieee_addr_t *)ias_cie_attr->data_p), sizeof(esp_zb_ieee_addr_t)); + _zone_id = (*(uint8_t *)zone_id_attr->data_p); + log_d("Restored IAS Zone enroll: zone id(%d), ias cie address(%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X)", _zone_id, _ias_cie_addr[0], _ias_cie_addr[1], _ias_cie_addr[2], _ias_cie_addr[3], _ias_cie_addr[4], _ias_cie_addr[5], _ias_cie_addr[6], _ias_cie_addr[7]); if (_zone_id == 0xFF) { - log_e("Failed to restore IAS Zone enroll: zone id not found"); - return false; - } - if (_ias_cie_addr == NULL) { - log_e("Failed to restore IAS Zone enroll: ias cie address not found"); + log_e("Failed to restore IAS Zone enroll: zone id not valid"); return false; } _enrolled = true; diff --git a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp index 28ad76bb5a7..8ee4f5c1406 100644 --- a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp @@ -152,4 +152,32 @@ bool ZigbeeDoorWindowHandle::requestIASZoneEnroll() { return true; } +bool ZigbeeDoorWindowHandle::restoreIASZoneEnroll() { + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_attr_t *ias_cie_attr = esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_IAS_CIE_ADDRESS_ID); + esp_zb_zcl_attr_t *zone_id_attr = esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONEID_ID); + esp_zb_lock_release(); + + if (ias_cie_attr == NULL || ias_cie_attr->data_p == NULL) { + log_e("Failed to restore IAS Zone enroll: ias cie address attribute not found"); + return false; + } + if (zone_id_attr == NULL || zone_id_attr->data_p == NULL) { + log_e("Failed to restore IAS Zone enroll: zone id attribute not found"); + return false; + } + + memcpy(_ias_cie_addr, (*(esp_zb_ieee_addr_t *)ias_cie_attr->data_p), sizeof(esp_zb_ieee_addr_t)); + _zone_id = (*(uint8_t *)zone_id_attr->data_p); + + log_d("Restored IAS Zone enroll: zone id(%d), ias cie address(%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X)", _zone_id, _ias_cie_addr[0], _ias_cie_addr[1], _ias_cie_addr[2], _ias_cie_addr[3], _ias_cie_addr[4], _ias_cie_addr[5], _ias_cie_addr[6], _ias_cie_addr[7]); + + if (_zone_id == 0xFF) { + log_e("Failed to restore IAS Zone enroll: zone id not valid"); + return false; + } + _enrolled = true; + return true; +} + #endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h index cb58c251f1a..106b5d48f7a 100644 --- a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h +++ b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h @@ -74,9 +74,12 @@ class ZigbeeDoorWindowHandle : public ZigbeeEP { // Report the door/window handle value, done automatically after setting the position bool report(); - // Request a new IAS zone enroll, needed to be called after rebooting already configured device + // Request a new IAS zone enroll, can be called to enroll a new device or to re-enroll an already enrolled device bool requestIASZoneEnroll(); + // Restore IAS Zone enroll, needed to be called after rebooting already enrolled device - restored from flash memory (faster for sleepy devices) + bool restoreIASZoneEnroll(); + // Check if the device is enrolled in the IAS Zone bool enrolled() { return _enrolled; } diff --git a/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp index f6e0183ffac..4e9368fdea2 100644 --- a/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp @@ -119,26 +119,26 @@ bool ZigbeeVibrationSensor::requestIASZoneEnroll() { bool ZigbeeVibrationSensor::restoreIASZoneEnroll() { esp_zb_lock_acquire(portMAX_DELAY); - memcpy( - _ias_cie_addr, - (*(esp_zb_ieee_addr_t *) - esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_IAS_CIE_ADDRESS_ID) - ->data_p), - sizeof(esp_zb_ieee_addr_t) - ); - _zone_id = (*(uint8_t *) - esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONEID_ID) - ->data_p); + esp_zb_zcl_attr_t *ias_cie_attr = esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_IAS_CIE_ADDRESS_ID); + esp_zb_zcl_attr_t *zone_id_attr = esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONEID_ID); esp_zb_lock_release(); + if (ias_cie_attr == NULL || ias_cie_attr->data_p == NULL) { + log_e("Failed to restore IAS Zone enroll: ias cie address attribute not found"); + return false; + } + if (zone_id_attr == NULL || zone_id_attr->data_p == NULL) { + log_e("Failed to restore IAS Zone enroll: zone id attribute not found"); + return false; + } + + memcpy(_ias_cie_addr, (*(esp_zb_ieee_addr_t *)ias_cie_attr->data_p), sizeof(esp_zb_ieee_addr_t)); + _zone_id = (*(uint8_t *)zone_id_attr->data_p); + log_d("Restored IAS Zone enroll: zone id(%d), ias cie address(%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X)", _zone_id, _ias_cie_addr[0], _ias_cie_addr[1], _ias_cie_addr[2], _ias_cie_addr[3], _ias_cie_addr[4], _ias_cie_addr[5], _ias_cie_addr[6], _ias_cie_addr[7]); if (_zone_id == 0xFF) { - log_e("Failed to restore IAS Zone enroll: zone id not found"); - return false; - } - if (_ias_cie_addr == NULL) { - log_e("Failed to restore IAS Zone enroll: ias cie address not found"); + log_e("Failed to restore IAS Zone enroll: zone id not valid"); return false; } _enrolled = true; From 80b1592d862af7c2f6390b09f267d9610d53e4eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Thu, 6 Nov 2025 20:47:36 +0100 Subject: [PATCH 7/8] fix: Fix memcpy and update docs --- docs/en/zigbee/ep_door_window_handle.rst | 2 +- libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp | 2 +- libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp | 2 +- libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/en/zigbee/ep_door_window_handle.rst b/docs/en/zigbee/ep_door_window_handle.rst index 3ca932e4df7..b2339d681a5 100644 --- a/docs/en/zigbee/ep_door_window_handle.rst +++ b/docs/en/zigbee/ep_door_window_handle.rst @@ -120,7 +120,7 @@ Checks if the device is currently enrolled in the IAS Zone. bool enrolled(); -This function returns ``true`` if the device is enrolled, ``false`` otherwise. Use this method to check the enrollment status after calling ``requestIASZoneEnroll()``. +This function returns ``true`` if the device is enrolled, ``false`` otherwise. Use this method to check the enrollment status after calling ``requestIASZoneEnroll()`` or ``restoreIASZoneEnroll()``. Example ------- diff --git a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp index 8127366efbc..60c41487225 100644 --- a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp @@ -150,7 +150,7 @@ bool ZigbeeContactSwitch::restoreIASZoneEnroll() { return false; } - memcpy(_ias_cie_addr, (*(esp_zb_ieee_addr_t *)ias_cie_attr->data_p), sizeof(esp_zb_ieee_addr_t)); + memcpy(_ias_cie_addr, (esp_zb_ieee_addr_t *)ias_cie_attr->data_p, sizeof(esp_zb_ieee_addr_t)); _zone_id = (*(uint8_t *)zone_id_attr->data_p); log_d("Restored IAS Zone enroll: zone id(%d), ias cie address(%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X)", _zone_id, _ias_cie_addr[0], _ias_cie_addr[1], _ias_cie_addr[2], _ias_cie_addr[3], _ias_cie_addr[4], _ias_cie_addr[5], _ias_cie_addr[6], _ias_cie_addr[7]); diff --git a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp index 8ee4f5c1406..c2dbc97bc9e 100644 --- a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp @@ -167,7 +167,7 @@ bool ZigbeeDoorWindowHandle::restoreIASZoneEnroll() { return false; } - memcpy(_ias_cie_addr, (*(esp_zb_ieee_addr_t *)ias_cie_attr->data_p), sizeof(esp_zb_ieee_addr_t)); + memcpy(_ias_cie_addr, (esp_zb_ieee_addr_t *)ias_cie_attr->data_p, sizeof(esp_zb_ieee_addr_t)); _zone_id = (*(uint8_t *)zone_id_attr->data_p); log_d("Restored IAS Zone enroll: zone id(%d), ias cie address(%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X)", _zone_id, _ias_cie_addr[0], _ias_cie_addr[1], _ias_cie_addr[2], _ias_cie_addr[3], _ias_cie_addr[4], _ias_cie_addr[5], _ias_cie_addr[6], _ias_cie_addr[7]); diff --git a/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp index 4e9368fdea2..106ce1645c5 100644 --- a/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp @@ -132,7 +132,7 @@ bool ZigbeeVibrationSensor::restoreIASZoneEnroll() { return false; } - memcpy(_ias_cie_addr, (*(esp_zb_ieee_addr_t *)ias_cie_attr->data_p), sizeof(esp_zb_ieee_addr_t)); + memcpy(_ias_cie_addr, (esp_zb_ieee_addr_t *)ias_cie_attr->data_p, sizeof(esp_zb_ieee_addr_t)); _zone_id = (*(uint8_t *)zone_id_attr->data_p); log_d("Restored IAS Zone enroll: zone id(%d), ias cie address(%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X)", _zone_id, _ias_cie_addr[0], _ias_cie_addr[1], _ias_cie_addr[2], _ias_cie_addr[3], _ias_cie_addr[4], _ias_cie_addr[5], _ias_cie_addr[6], _ias_cie_addr[7]); From d2c4c73c6760acd089d95637101ba415a319ce32 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Fri, 7 Nov 2025 09:30:22 +0000 Subject: [PATCH 8/8] ci(pre-commit): Apply automatic fixes --- docs/en/zigbee/ep_contact_switch.rst | 2 +- .../Zigbee_Contact_Switch.ino | 8 ++++---- .../Zigbee_Vibration_Sensor.ino | 8 ++++---- .../Zigbee/src/ep/ZigbeeContactSwitch.cpp | 19 ++++++++++++------- libraries/Zigbee/src/ep/ZigbeeContactSwitch.h | 4 +++- .../Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp | 19 ++++++++++++------- .../Zigbee/src/ep/ZigbeeDoorWindowHandle.h | 4 +++- .../Zigbee/src/ep/ZigbeeVibrationSensor.cpp | 19 ++++++++++++------- .../Zigbee/src/ep/ZigbeeVibrationSensor.h | 4 +++- 9 files changed, 54 insertions(+), 33 deletions(-) diff --git a/docs/en/zigbee/ep_contact_switch.rst b/docs/en/zigbee/ep_contact_switch.rst index d9780632c22..50844cdd180 100644 --- a/docs/en/zigbee/ep_contact_switch.rst +++ b/docs/en/zigbee/ep_contact_switch.rst @@ -88,7 +88,7 @@ Sets the IAS Client endpoint number (default is 1). requestIASZoneEnroll ^^^^^^^^^^^^^^^^^^^^ -Requests a new IAS Zone enrollment. Can be called to enroll a new device or to re-enroll an already enrolled device. +Requests a new IAS Zone enrollment. Can be called to enroll a new device or to re-enroll an already enrolled device. .. code-block:: arduino diff --git a/libraries/Zigbee/examples/Zigbee_Contact_Switch/Zigbee_Contact_Switch.ino b/libraries/Zigbee/examples/Zigbee_Contact_Switch/Zigbee_Contact_Switch.ino index eec1c3b1c05..1a84c4d7471 100644 --- a/libraries/Zigbee/examples/Zigbee_Contact_Switch/Zigbee_Contact_Switch.ino +++ b/libraries/Zigbee/examples/Zigbee_Contact_Switch/Zigbee_Contact_Switch.ino @@ -46,8 +46,8 @@ Preferences preferences; void setup() { Serial.begin(115200); - preferences.begin("Zigbee", false); // Save ENROLLED flag in flash so it persists across reboots - bool enrolled = preferences.getBool("ENROLLED"); // Get ENROLLED flag from preferences + preferences.begin("Zigbee", false); // Save ENROLLED flag in flash so it persists across reboots + bool enrolled = preferences.getBool("ENROLLED"); // Get ENROLLED flag from preferences preferences.end(); // Init button + switch @@ -96,7 +96,7 @@ void setup() { // Skip writing if we just restored enrollment (flag was already true) if (!enrolled) { preferences.begin("Zigbee", false); - preferences.putBool("ENROLLED", true); // set ENROLLED flag to true + preferences.putBool("ENROLLED", true); // set ENROLLED flag to true preferences.end(); Serial.println("ENROLLED flag saved to preferences"); } @@ -126,7 +126,7 @@ void loop() { Serial.println("Resetting Zigbee to factory and rebooting in 1s."); // Clear the ENROLLED flag from preferences preferences.begin("Zigbee", false); - preferences.putBool("ENROLLED", false); // set ENROLLED flag to false + preferences.putBool("ENROLLED", false); // set ENROLLED flag to false preferences.end(); Serial.println("ENROLLED flag cleared from preferences"); delay(1000); diff --git a/libraries/Zigbee/examples/Zigbee_Vibration_Sensor/Zigbee_Vibration_Sensor.ino b/libraries/Zigbee/examples/Zigbee_Vibration_Sensor/Zigbee_Vibration_Sensor.ino index b7797290161..b3fc6b9d18b 100644 --- a/libraries/Zigbee/examples/Zigbee_Vibration_Sensor/Zigbee_Vibration_Sensor.ino +++ b/libraries/Zigbee/examples/Zigbee_Vibration_Sensor/Zigbee_Vibration_Sensor.ino @@ -46,8 +46,8 @@ Preferences preferences; void setup() { Serial.begin(115200); - preferences.begin("Zigbee", false); // Save ENROLLED flag in flash so it persists across reboots - bool enrolled = preferences.getBool("ENROLLED"); // Get ENROLLED flag from preferences + preferences.begin("Zigbee", false); // Save ENROLLED flag in flash so it persists across reboots + bool enrolled = preferences.getBool("ENROLLED"); // Get ENROLLED flag from preferences preferences.end(); // Init button + sensor @@ -96,7 +96,7 @@ void setup() { // Skip writing if we just restored enrollment (flag was already true) if (!enrolled) { preferences.begin("Zigbee", false); - preferences.putBool("ENROLLED", true); // set ENROLLED flag to true + preferences.putBool("ENROLLED", true); // set ENROLLED flag to true preferences.end(); Serial.println("ENROLLED flag saved to preferences"); } @@ -130,7 +130,7 @@ void loop() { Serial.println("Resetting Zigbee to factory and rebooting in 1s."); // Clear the ENROLLED flag from preferences preferences.begin("Zigbee", false); - preferences.putBool("ENROLLED", false); // set ENROLLED flag to false + preferences.putBool("ENROLLED", false); // set ENROLLED flag to false preferences.end(); Serial.println("ENROLLED flag cleared from preferences"); delay(1000); diff --git a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp index 60c41487225..35e05afb290 100644 --- a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp @@ -137,10 +137,12 @@ bool ZigbeeContactSwitch::requestIASZoneEnroll() { bool ZigbeeContactSwitch::restoreIASZoneEnroll() { esp_zb_lock_acquire(portMAX_DELAY); - esp_zb_zcl_attr_t *ias_cie_attr = esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_IAS_CIE_ADDRESS_ID); - esp_zb_zcl_attr_t *zone_id_attr = esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONEID_ID); + esp_zb_zcl_attr_t *ias_cie_attr = + esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_IAS_CIE_ADDRESS_ID); + esp_zb_zcl_attr_t *zone_id_attr = + esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONEID_ID); esp_zb_lock_release(); - + if (ias_cie_attr == NULL || ias_cie_attr->data_p == NULL) { log_e("Failed to restore IAS Zone enroll: ias cie address attribute not found"); return false; @@ -149,12 +151,15 @@ bool ZigbeeContactSwitch::restoreIASZoneEnroll() { log_e("Failed to restore IAS Zone enroll: zone id attribute not found"); return false; } - + memcpy(_ias_cie_addr, (esp_zb_ieee_addr_t *)ias_cie_attr->data_p, sizeof(esp_zb_ieee_addr_t)); _zone_id = (*(uint8_t *)zone_id_attr->data_p); - - log_d("Restored IAS Zone enroll: zone id(%d), ias cie address(%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X)", _zone_id, _ias_cie_addr[0], _ias_cie_addr[1], _ias_cie_addr[2], _ias_cie_addr[3], _ias_cie_addr[4], _ias_cie_addr[5], _ias_cie_addr[6], _ias_cie_addr[7]); - + + log_d( + "Restored IAS Zone enroll: zone id(%d), ias cie address(%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X)", _zone_id, _ias_cie_addr[0], _ias_cie_addr[1], + _ias_cie_addr[2], _ias_cie_addr[3], _ias_cie_addr[4], _ias_cie_addr[5], _ias_cie_addr[6], _ias_cie_addr[7] + ); + if (_zone_id == 0xFF) { log_e("Failed to restore IAS Zone enroll: zone id not valid"); return false; diff --git a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.h b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.h index c558a1c009c..002ed722d78 100644 --- a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.h +++ b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.h @@ -77,7 +77,9 @@ class ZigbeeContactSwitch : public ZigbeeEP { bool restoreIASZoneEnroll(); // Check if the device is enrolled in the IAS Zone - bool enrolled() { return _enrolled; } + bool enrolled() { + return _enrolled; + } private: void zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) override; diff --git a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp index c2dbc97bc9e..2a3a5c80498 100644 --- a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp @@ -154,10 +154,12 @@ bool ZigbeeDoorWindowHandle::requestIASZoneEnroll() { bool ZigbeeDoorWindowHandle::restoreIASZoneEnroll() { esp_zb_lock_acquire(portMAX_DELAY); - esp_zb_zcl_attr_t *ias_cie_attr = esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_IAS_CIE_ADDRESS_ID); - esp_zb_zcl_attr_t *zone_id_attr = esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONEID_ID); + esp_zb_zcl_attr_t *ias_cie_attr = + esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_IAS_CIE_ADDRESS_ID); + esp_zb_zcl_attr_t *zone_id_attr = + esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONEID_ID); esp_zb_lock_release(); - + if (ias_cie_attr == NULL || ias_cie_attr->data_p == NULL) { log_e("Failed to restore IAS Zone enroll: ias cie address attribute not found"); return false; @@ -166,12 +168,15 @@ bool ZigbeeDoorWindowHandle::restoreIASZoneEnroll() { log_e("Failed to restore IAS Zone enroll: zone id attribute not found"); return false; } - + memcpy(_ias_cie_addr, (esp_zb_ieee_addr_t *)ias_cie_attr->data_p, sizeof(esp_zb_ieee_addr_t)); _zone_id = (*(uint8_t *)zone_id_attr->data_p); - - log_d("Restored IAS Zone enroll: zone id(%d), ias cie address(%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X)", _zone_id, _ias_cie_addr[0], _ias_cie_addr[1], _ias_cie_addr[2], _ias_cie_addr[3], _ias_cie_addr[4], _ias_cie_addr[5], _ias_cie_addr[6], _ias_cie_addr[7]); - + + log_d( + "Restored IAS Zone enroll: zone id(%d), ias cie address(%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X)", _zone_id, _ias_cie_addr[0], _ias_cie_addr[1], + _ias_cie_addr[2], _ias_cie_addr[3], _ias_cie_addr[4], _ias_cie_addr[5], _ias_cie_addr[6], _ias_cie_addr[7] + ); + if (_zone_id == 0xFF) { log_e("Failed to restore IAS Zone enroll: zone id not valid"); return false; diff --git a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h index 106b5d48f7a..cfaf7e772a0 100644 --- a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h +++ b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h @@ -81,7 +81,9 @@ class ZigbeeDoorWindowHandle : public ZigbeeEP { bool restoreIASZoneEnroll(); // Check if the device is enrolled in the IAS Zone - bool enrolled() { return _enrolled; } + bool enrolled() { + return _enrolled; + } private: void zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) override; diff --git a/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp index 106ce1645c5..a9fd437a2c6 100644 --- a/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp @@ -119,10 +119,12 @@ bool ZigbeeVibrationSensor::requestIASZoneEnroll() { bool ZigbeeVibrationSensor::restoreIASZoneEnroll() { esp_zb_lock_acquire(portMAX_DELAY); - esp_zb_zcl_attr_t *ias_cie_attr = esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_IAS_CIE_ADDRESS_ID); - esp_zb_zcl_attr_t *zone_id_attr = esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONEID_ID); + esp_zb_zcl_attr_t *ias_cie_attr = + esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_IAS_CIE_ADDRESS_ID); + esp_zb_zcl_attr_t *zone_id_attr = + esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONEID_ID); esp_zb_lock_release(); - + if (ias_cie_attr == NULL || ias_cie_attr->data_p == NULL) { log_e("Failed to restore IAS Zone enroll: ias cie address attribute not found"); return false; @@ -131,12 +133,15 @@ bool ZigbeeVibrationSensor::restoreIASZoneEnroll() { log_e("Failed to restore IAS Zone enroll: zone id attribute not found"); return false; } - + memcpy(_ias_cie_addr, (esp_zb_ieee_addr_t *)ias_cie_attr->data_p, sizeof(esp_zb_ieee_addr_t)); _zone_id = (*(uint8_t *)zone_id_attr->data_p); - - log_d("Restored IAS Zone enroll: zone id(%d), ias cie address(%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X)", _zone_id, _ias_cie_addr[0], _ias_cie_addr[1], _ias_cie_addr[2], _ias_cie_addr[3], _ias_cie_addr[4], _ias_cie_addr[5], _ias_cie_addr[6], _ias_cie_addr[7]); - + + log_d( + "Restored IAS Zone enroll: zone id(%d), ias cie address(%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X)", _zone_id, _ias_cie_addr[0], _ias_cie_addr[1], + _ias_cie_addr[2], _ias_cie_addr[3], _ias_cie_addr[4], _ias_cie_addr[5], _ias_cie_addr[6], _ias_cie_addr[7] + ); + if (_zone_id == 0xFF) { log_e("Failed to restore IAS Zone enroll: zone id not valid"); return false; diff --git a/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.h b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.h index 1cad6af7a08..a819be0ba8f 100644 --- a/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.h +++ b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.h @@ -74,7 +74,9 @@ class ZigbeeVibrationSensor : public ZigbeeEP { bool restoreIASZoneEnroll(); // Check if the device is enrolled in the IAS Zone - bool enrolled() { return _enrolled; } + bool enrolled() { + return _enrolled; + } private: void zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) override;