From 0bcf1538dd6ee9b464ac936d043b6737243d3315 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, 30 Jan 2025 14:26:00 +0100 Subject: [PATCH 1/3] feat(zigbee): Add IAS Zone endpoints --- CMakeLists.txt | 2 + .../examples/Zigbee_Contact_Switch/README.md | 58 ++++++++++ .../Zigbee_Contact_Switch.ino | 100 +++++++++++++++++ .../examples/Zigbee_Contact_Switch/ci.json | 6 + libraries/Zigbee/src/Zigbee.h | 2 + libraries/Zigbee/src/ZigbeeEP.h | 1 + libraries/Zigbee/src/ZigbeeHandlers.cpp | 20 ++++ .../Zigbee/src/ep/ZigbeeContactSwitch.cpp | 92 ++++++++++++++++ libraries/Zigbee/src/ep/ZigbeeContactSwitch.h | 66 +++++++++++ .../Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp | 104 ++++++++++++++++++ .../Zigbee/src/ep/ZigbeeDoorWindowHandle.h | 70 ++++++++++++ 11 files changed, 521 insertions(+) create mode 100644 libraries/Zigbee/examples/Zigbee_Contact_Switch/README.md create mode 100644 libraries/Zigbee/examples/Zigbee_Contact_Switch/Zigbee_Contact_Switch.ino create mode 100644 libraries/Zigbee/examples/Zigbee_Contact_Switch/ci.json create mode 100644 libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp create mode 100644 libraries/Zigbee/src/ep/ZigbeeContactSwitch.h create mode 100644 libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp create mode 100644 libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 9fd23d14d77..b3cb6c06cdc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -290,6 +290,8 @@ set(ARDUINO_LIBRARY_Zigbee_SRCS libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp libraries/Zigbee/src/ep/ZigbeeOccupancySensor.cpp libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp + libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp + libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp ) set(ARDUINO_LIBRARY_BLE_SRCS diff --git a/libraries/Zigbee/examples/Zigbee_Contact_Switch/README.md b/libraries/Zigbee/examples/Zigbee_Contact_Switch/README.md new file mode 100644 index 00000000000..486b3b2a1aa --- /dev/null +++ b/libraries/Zigbee/examples/Zigbee_Contact_Switch/README.md @@ -0,0 +1,58 @@ +# Arduino-ESP32 Zigbee Contact Switch Example + +This example shows how to configure the Zigbee end device and use it as a Home Automation (HA) contact switch (IAS Zone), +that can be used for example as window/door sensor having 2 states - closed/open. + +# Supported Targets + +Currently, this example supports the following targets. + +| Supported Targets | ESP32-C6 | ESP32-H2 | +| ----------------- | -------- | -------- | + +## Hardware Required + +* A USB cable for power supply and programming + +### Configure the Project + +Set the Button GPIO by changing the `button` variable. By default, it's the pin `BOOT_PIN` (BOOT button on ESP32-C6 and ESP32-H2). +Set the Sensor GPIO by changing the `sensor_pin` variable. + +#### Using Arduino IDE + +To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). + +* Before Compile/Verify, select the correct board: `Tools -> Board`. +* Select the End device Zigbee mode: `Tools -> Zigbee mode: Zigbee ED (end device)` +* Select Partition Scheme for Zigbee: `Tools -> Partition Scheme: Zigbee 4MB with spiffs` +* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. +* Optional: Set debug level to verbose to see all logs from Zigbee stack: `Tools -> Core Debug Level: Verbose`. + +## Troubleshooting + +If the End device flashed with this example is not connecting to the coordinator, erase the flash of the End device before flashing the example to the board. + +***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** + +* **LED not blinking:** Check the wiring connection and the IO selection. +* **Programming Fail:** If the programming/flash procedure fails, try reducing the serial connection speed. +* **COM port not detected:** Check the USB cable and the USB to Serial driver installation. + +If the error persists, you can ask for help at the official [ESP32 forum](https://esp32.com) or see [Contribute](#contribute). + +## Contribute + +To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) + +If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! + +Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. + +## Resources + +* Official ESP32 Forum: [Link](https://esp32.com) +* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) +* ESP32-C6 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c6_datasheet_en.pdf) +* ESP32-H2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-h2_datasheet_en.pdf) +* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) diff --git a/libraries/Zigbee/examples/Zigbee_Contact_Switch/Zigbee_Contact_Switch.ino b/libraries/Zigbee/examples/Zigbee_Contact_Switch/Zigbee_Contact_Switch.ino new file mode 100644 index 00000000000..ce9eedb683d --- /dev/null +++ b/libraries/Zigbee/examples/Zigbee_Contact_Switch/Zigbee_Contact_Switch.ino @@ -0,0 +1,100 @@ +// Copyright 2024 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @brief This example demonstrates Zigbee contact switch (IAS Zone). + * + * The example demonstrates how to use Zigbee library to create a end device contact switch. + * The contact switch is a Zigbee end device, which is reporting data to the Zigbee network. + * + * Proper Zigbee mode must be selected in Tools->Zigbee mode + * and also the correct partition scheme must be selected in Tools->Partition Scheme. + * + * Please check the README.md for instructions and more detailed description. + * + * Created by Jan Procházka (https://github.com/P-R-O-C-H-Y/) + */ + +#ifndef ZIGBEE_MODE_ED +#error "Zigbee end device mode is not selected in Tools->Zigbee mode" +#endif + +#include "Zigbee.h" + +/* Zigbee contact sensor configuration */ +#define CONTACT_SWITCH_ENDPOINT_NUMBER 10 +uint8_t button = BOOT_PIN; +uint8_t sensor_pin = 4; + +ZigbeeContactSwitch zbContactSwitch = ZigbeeContactSwitch(CONTACT_SWITCH_ENDPOINT_NUMBER); + +void setup() { + Serial.begin(115200); + + // Init button + switch + pinMode(button, INPUT_PULLUP); + pinMode(sensor_pin, INPUT_PULLUP); + + // Optional: set Zigbee device name and model + zbContactSwitch.setManufacturerAndModel("Espressif", "ZigbeeContactSwitch"); + + // Add endpoint to Zigbee Core + Zigbee.addEndpoint(&zbContactSwitch); + + Serial.println("Starting Zigbee..."); + // When all EPs are registered, start Zigbee in End Device mode + if (!Zigbee.begin()) { + Serial.println("Zigbee failed to start!"); + Serial.println("Rebooting..."); + ESP.restart(); + } else { + Serial.println("Zigbee started successfully!"); + } + Serial.println("Connecting to network"); + while (!Zigbee.connected()) { + Serial.print("."); + delay(100); + } + Serial.println(); +} + +void loop() { + // Checking pin for contact change + static bool contact = false; + if (digitalRead(sensor_pin) == HIGH && !contact) { + // Update contact sensor value + zbContactSwitch.setOpen(); + contact = true; + } else if (digitalRead(sensor_pin) == LOW && contact) { + zbContactSwitch.setClosed(); + contact = false; + } + + // Checking button for factory reset + if (digitalRead(button) == LOW) { // Push button pressed + // Key debounce handling + delay(100); + int startTime = millis(); + while (digitalRead(button) == LOW) { + delay(50); + 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."); + delay(1000); + Zigbee.factoryReset(); + } + } + } + delay(100); +} diff --git a/libraries/Zigbee/examples/Zigbee_Contact_Switch/ci.json b/libraries/Zigbee/examples/Zigbee_Contact_Switch/ci.json new file mode 100644 index 00000000000..7b7ccef8ed7 --- /dev/null +++ b/libraries/Zigbee/examples/Zigbee_Contact_Switch/ci.json @@ -0,0 +1,6 @@ +{ + "fqbn_append": "PartitionScheme=zigbee,ZigbeeMode=ed", + "requires": [ + "CONFIG_SOC_IEEE802154_SUPPORTED=y" + ] +} diff --git a/libraries/Zigbee/src/Zigbee.h b/libraries/Zigbee/src/Zigbee.h index cf58dc8d5d8..c97be9378a8 100644 --- a/libraries/Zigbee/src/Zigbee.h +++ b/libraries/Zigbee/src/Zigbee.h @@ -18,3 +18,5 @@ #include "ep/ZigbeeFlowSensor.h" #include "ep/ZigbeeOccupancySensor.h" #include "ep/ZigbeeCarbonDioxideSensor.h" +#include "ep/ZigbeeContactSwitch.h" +#include "ep/ZigbeeDoorWindowHandle.h" diff --git a/libraries/Zigbee/src/ZigbeeEP.h b/libraries/Zigbee/src/ZigbeeEP.h index ac22143c4d7..d12194f59f2 100644 --- a/libraries/Zigbee/src/ZigbeeEP.h +++ b/libraries/Zigbee/src/ZigbeeEP.h @@ -106,6 +106,7 @@ class ZigbeeEP { virtual void zbIdentify(const esp_zb_zcl_set_attr_value_message_t *message); virtual void zbIASZoneStatusChangeNotification(const esp_zb_zcl_ias_zone_status_change_notification_message_t *message) {}; + virtual void zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) {}; virtual void addBoundDevice(zb_device_params_t *device) { _bound_devices.push_back(device); diff --git a/libraries/Zigbee/src/ZigbeeHandlers.cpp b/libraries/Zigbee/src/ZigbeeHandlers.cpp index bccb27da7f8..07ad5fec137 100644 --- a/libraries/Zigbee/src/ZigbeeHandlers.cpp +++ b/libraries/Zigbee/src/ZigbeeHandlers.cpp @@ -10,6 +10,7 @@ static esp_err_t zb_attribute_reporting_handler(const esp_zb_zcl_report_attr_mes static esp_err_t zb_cmd_read_attr_resp_handler(const esp_zb_zcl_cmd_read_attr_resp_message_t *message); static esp_err_t zb_configure_report_resp_handler(const esp_zb_zcl_cmd_config_report_resp_message_t *message); static esp_err_t zb_cmd_ias_zone_status_change_handler(const esp_zb_zcl_ias_zone_status_change_notification_message_t *message); +static esp_err_t zb_cmd_ias_zone_enroll_response_handler(const esp_zb_zcl_ias_zone_enroll_response_message_t *message); static esp_err_t zb_cmd_default_resp_handler(const esp_zb_zcl_cmd_default_resp_message_t *message); // Zigbee action handlers @@ -24,6 +25,7 @@ static esp_err_t zb_action_handler(esp_zb_core_action_callback_id_t callback_id, case ESP_ZB_CORE_CMD_IAS_ZONE_ZONE_STATUS_CHANGE_NOT_ID: ret = zb_cmd_ias_zone_status_change_handler((esp_zb_zcl_ias_zone_status_change_notification_message_t *)message); break; + case ESP_ZB_CORE_IAS_ZONE_ENROLL_RESPONSE_VALUE_CB_ID: ret = zb_cmd_ias_zone_enroll_response_handler((esp_zb_zcl_ias_zone_enroll_response_message_t *)message); break; case ESP_ZB_CORE_CMD_DEFAULT_RESP_CB_ID: ret = zb_cmd_default_resp_handler((esp_zb_zcl_cmd_default_resp_message_t *)message); break; default: log_w("Receive unhandled Zigbee action(0x%x) callback", callback_id); break; } @@ -158,6 +160,24 @@ static esp_err_t zb_cmd_ias_zone_status_change_handler(const esp_zb_zcl_ias_zone return ESP_OK; } +static esp_err_t zb_cmd_ias_zone_enroll_response_handler(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) { + if (!message) { + log_e("Empty message"); + return ESP_FAIL; + } + if (message->info.status != ESP_ZB_ZCL_STATUS_SUCCESS) { + log_e("Received message: error status(%d)", message->info.status); + return ESP_ERR_INVALID_ARG; + } + log_v("IAS Zone Enroll Response recieved"); + for (std::list::iterator it = Zigbee.ep_objects.begin(); it != Zigbee.ep_objects.end(); ++it) { + if (message->info.dst_endpoint == (*it)->getEndpoint()) { + (*it)->zbIASZoneEnrollResponse(message); + } + } + return ESP_OK; +} + static esp_err_t zb_cmd_default_resp_handler(const esp_zb_zcl_cmd_default_resp_message_t *message) { if (!message) { log_e("Empty message"); diff --git a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp new file mode 100644 index 00000000000..d2a15670557 --- /dev/null +++ b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp @@ -0,0 +1,92 @@ +#include "ZigbeeContactSwitch.h" +#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED + +esp_zb_cluster_list_t *zigbee_contact_switch_clusters_create(zigbee_contact_switch_cfg_t *contact_switch) { + esp_zb_basic_cluster_cfg_t *basic_cfg = contact_switch ? &(contact_switch->basic_cfg) : NULL; + esp_zb_identify_cluster_cfg_t *identify_cfg = contact_switch ? &(contact_switch->identify_cfg) : NULL; + esp_zb_ias_zone_cluster_cfg_t *ias_zone_cfg = contact_switch ? &(contact_switch->ias_zone_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); + esp_zb_cluster_list_add_ias_zone_cluster(cluster_list, esp_zb_ias_zone_cluster_create(ias_zone_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + return cluster_list; +} + +ZigbeeContactSwitch::ZigbeeContactSwitch(uint8_t endpoint) : ZigbeeEP(endpoint) { + _device_id = ESP_ZB_HA_IAS_ZONE_ID; + _zone_status = 0; + _zone_id = 0xff; + _ias_cie_endpoint = 1; + + //Create custom contact switch configuration + zigbee_contact_switch_cfg_t contact_switch_cfg = ZIGBEE_DEFAULT_CONTACT_SWITCH_CONFIG(); + _cluster_list = zigbee_contact_switch_clusters_create(&contact_switch_cfg); + + _ep_config = {.endpoint = _endpoint, .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, .app_device_id = ESP_ZB_HA_IAS_ZONE_ID, .app_device_version = 0}; +} + +void ZigbeeContactSwitch::setIASClientEndpoint(uint8_t ep_number) { + _ias_cie_endpoint = ep_number; +} + +void 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( + _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(); + _zone_status = closed; + report(); +} + +void 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_zb_lock_release(); + _zone_status = open; + report(); +} + +void ZigbeeContactSwitch::report() { + /* Send IAS Zone status changed notification command */ + + esp_zb_zcl_ias_zone_status_change_notif_cmd_t status_change_notif_cmd; + status_change_notif_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT; + 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; + 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_zb_lock_release(); + log_v("IAS Zone status changed notification sent"); +} + +void ZigbeeContactSwitch::zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) { + if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE) { + log_v("IAS Zone Enroll Response: zone id(%d), status(%d)", message->zone_id, message->response_code); + if(message->response_code == ESP_ZB_ZCL_IAS_ZONE_ENROLL_RESPONSE_CODE_SUCCESS) { + log_v("IAS Zone Enroll Response: success"); + 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)); + esp_zb_lock_release(); + _zone_id = message->zone_id; + } + + } else { + log_w("Received message ignored. Cluster ID: %d not supported for On/Off Light", message->info.cluster); + } +} + +#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.h b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.h new file mode 100644 index 00000000000..ebb410b7dbd --- /dev/null +++ b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.h @@ -0,0 +1,66 @@ +/* Class of Zigbee contact switch (IAS Zone) endpoint inherited from common EP class */ + +#pragma once + +#include "soc/soc_caps.h" +#include "sdkconfig.h" +#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED + +#include "ZigbeeEP.h" +#include "ha/esp_zigbee_ha_standard.h" + +// clang-format off +#define ZIGBEE_DEFAULT_CONTACT_SWITCH_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, \ + }, \ + .ias_zone_cfg = \ + { \ + .zone_state = ESP_ZB_ZCL_IAS_ZONE_ZONESTATE_NOT_ENROLLED, \ + .zone_type = ESP_ZB_ZCL_IAS_ZONE_ZONETYPE_CONTACT_SWITCH, \ + .zone_status = 0, \ + .ias_cie_addr = ESP_ZB_ZCL_ZONE_IAS_CIE_ADDR_DEFAULT, \ + .zone_id = 0xff, \ + .zone_ctx = {0, 0, 0, 0}, \ + }, \ + } +// clang-format on + +typedef struct zigbee_contact_switch_cfg_s { + esp_zb_basic_cluster_cfg_t basic_cfg; + esp_zb_identify_cluster_cfg_t identify_cfg; + esp_zb_ias_zone_cluster_cfg_t ias_zone_cfg; +} zigbee_contact_switch_cfg_t; + +class ZigbeeContactSwitch : public ZigbeeEP { +public: + ZigbeeContactSwitch(uint8_t endpoint); + ~ZigbeeContactSwitch() {} + + // Set the IAS Client endpoint number (default is 1) + void setIASClientEndpoint(uint8_t ep_number); + + // Set the contact switch value to closed + void setClosed(); + + // Set the contact switch value to open + void setOpen(); + + // Report the contact switch value, done automatically after setting the position + void report(); +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; +}; + +#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp new file mode 100644 index 00000000000..6ab3ac855c7 --- /dev/null +++ b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp @@ -0,0 +1,104 @@ +#include "ZigbeeDoorWindowHandle.h" +#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED + +esp_zb_cluster_list_t *zigbee_door_window_handle_clusters_create(zigbee_door_window_handle_cfg_t *door_window_handle) { + esp_zb_basic_cluster_cfg_t *basic_cfg = door_window_handle ? &(door_window_handle->basic_cfg) : NULL; + esp_zb_identify_cluster_cfg_t *identify_cfg = door_window_handle ? &(door_window_handle->identify_cfg) : NULL; + esp_zb_ias_zone_cluster_cfg_t *ias_zone_cfg = door_window_handle ? &(door_window_handle->ias_zone_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); + esp_zb_cluster_list_add_ias_zone_cluster(cluster_list, esp_zb_ias_zone_cluster_create(ias_zone_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + return cluster_list; +} + +ZigbeeDoorWindowHandle::ZigbeeDoorWindowHandle(uint8_t endpoint) : ZigbeeEP(endpoint) { + _device_id = ESP_ZB_HA_IAS_ZONE_ID; + _zone_status = 0; + _zone_id = 0xff; + _ias_cie_endpoint = 1; + + //Create custom door window handle configuration + zigbee_door_window_handle_cfg_t door_window_handle_cfg = ZIGBEE_DEFAULT_DOOR_WINDOW_HANDLE_CONFIG(); + _cluster_list = zigbee_door_window_handle_clusters_create(&door_window_handle_cfg); + + _ep_config = {.endpoint = _endpoint, .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, .app_device_id = ESP_ZB_HA_IAS_ZONE_ID, .app_device_version = 0}; +} + +void ZigbeeDoorWindowHandle::setIASClientEndpoint(uint8_t ep_number) { + _ias_cie_endpoint = ep_number; +} + +void ZigbeeDoorWindowHandle::setClosed() { + 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( + _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(); + _zone_status = closed; + report(); +} + +void ZigbeeDoorWindowHandle::setOpen() { + 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 + ); + esp_zb_lock_release(); + _zone_status = open; + report(); +} + +void ZigbeeDoorWindowHandle::setTilted() { + 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( + _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(); + _zone_status = tilted; + report(); +} + +void ZigbeeDoorWindowHandle::report() { + /* Send IAS Zone status changed notification command */ + + esp_zb_zcl_ias_zone_status_change_notif_cmd_t status_change_notif_cmd; + status_change_notif_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT; + 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; + 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_zb_lock_release(); + log_v("IAS Zone status changed notification sent"); +} + +void ZigbeeDoorWindowHandle::zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) { + if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE) { + log_v("IAS Zone Enroll Response: zone id(%d), status(%d)", message->zone_id, message->response_code); + if(message->response_code == ESP_ZB_ZCL_IAS_ZONE_ENROLL_RESPONSE_CODE_SUCCESS) { + log_v("IAS Zone Enroll Response: success"); + 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)); + esp_zb_lock_release(); + _zone_id = message->zone_id; + } + + } else { + log_w("Received message ignored. Cluster ID: %d not supported for On/Off Light", message->info.cluster); + } +} + +#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h new file mode 100644 index 00000000000..84ec4e71d8d --- /dev/null +++ b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h @@ -0,0 +1,70 @@ +/* Class of Zigbee door window handle (IAS Zone) endpoint inherited from common EP class */ + +#pragma once + +#include "soc/soc_caps.h" +#include "sdkconfig.h" +#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED + +#include "ZigbeeEP.h" +#include "ha/esp_zigbee_ha_standard.h" + +#define ESP_ZB_ZCL_IAS_ZONE_ZONETYPE_DOOR_WINDOW_HANDLE 0x0016 +// clang-format off +#define ZIGBEE_DEFAULT_DOOR_WINDOW_HANDLE_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, \ + }, \ + .ias_zone_cfg = \ + { \ + .zone_state = ESP_ZB_ZCL_IAS_ZONE_ZONESTATE_NOT_ENROLLED, \ + .zone_type = ESP_ZB_ZCL_IAS_ZONE_ZONETYPE_DOOR_WINDOW_HANDLE, \ + .zone_status = 0, \ + .ias_cie_addr = ESP_ZB_ZCL_ZONE_IAS_CIE_ADDR_DEFAULT, \ + .zone_id = 0xff, \ + .zone_ctx = {0, 0, 0, 0}, \ + }, \ + } +// clang-format on + +typedef struct zigbee_door_window_handle_cfg_s { + esp_zb_basic_cluster_cfg_t basic_cfg; + esp_zb_identify_cluster_cfg_t identify_cfg; + esp_zb_ias_zone_cluster_cfg_t ias_zone_cfg; +} zigbee_door_window_handle_cfg_t; + +class ZigbeeDoorWindowHandle : public ZigbeeEP { +public: + ZigbeeDoorWindowHandle(uint8_t endpoint); + ~ZigbeeDoorWindowHandle() {} + + // Set the IAS Client endpoint number (default is 1) + void setIASClientEndpoint(uint8_t ep_number); + + // Set the door/window handle value to closed + void setClosed(); + + // Set the door/window handle value to open + void setOpen(); + + // Set the door/window handle value to tilted + void setTilted(); + + // Report the door/window handle value, done automatically after setting the position + void report(); +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; +}; + +#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED From 9db296323973bf06ac888641931b9812264ce540 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Thu, 30 Jan 2025 15:33:51 +0000 Subject: [PATCH 2/3] ci(pre-commit): Apply automatic fixes --- .../examples/Zigbee_Contact_Switch/README.md | 2 +- libraries/Zigbee/src/ZigbeeHandlers.cpp | 4 ++- .../Zigbee/src/ep/ZigbeeContactSwitch.cpp | 24 ++++++++++------- libraries/Zigbee/src/ep/ZigbeeContactSwitch.h | 1 + .../Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp | 26 +++++++++++-------- .../Zigbee/src/ep/ZigbeeDoorWindowHandle.h | 1 + 6 files changed, 35 insertions(+), 23 deletions(-) diff --git a/libraries/Zigbee/examples/Zigbee_Contact_Switch/README.md b/libraries/Zigbee/examples/Zigbee_Contact_Switch/README.md index 486b3b2a1aa..a5a32358a7c 100644 --- a/libraries/Zigbee/examples/Zigbee_Contact_Switch/README.md +++ b/libraries/Zigbee/examples/Zigbee_Contact_Switch/README.md @@ -1,6 +1,6 @@ # Arduino-ESP32 Zigbee Contact Switch Example -This example shows how to configure the Zigbee end device and use it as a Home Automation (HA) contact switch (IAS Zone), +This example shows how to configure the Zigbee end device and use it as a Home Automation (HA) contact switch (IAS Zone), that can be used for example as window/door sensor having 2 states - closed/open. # Supported Targets diff --git a/libraries/Zigbee/src/ZigbeeHandlers.cpp b/libraries/Zigbee/src/ZigbeeHandlers.cpp index 07ad5fec137..be7ae1adb68 100644 --- a/libraries/Zigbee/src/ZigbeeHandlers.cpp +++ b/libraries/Zigbee/src/ZigbeeHandlers.cpp @@ -25,7 +25,9 @@ static esp_err_t zb_action_handler(esp_zb_core_action_callback_id_t callback_id, case ESP_ZB_CORE_CMD_IAS_ZONE_ZONE_STATUS_CHANGE_NOT_ID: ret = zb_cmd_ias_zone_status_change_handler((esp_zb_zcl_ias_zone_status_change_notification_message_t *)message); break; - case ESP_ZB_CORE_IAS_ZONE_ENROLL_RESPONSE_VALUE_CB_ID: ret = zb_cmd_ias_zone_enroll_response_handler((esp_zb_zcl_ias_zone_enroll_response_message_t *)message); break; + case ESP_ZB_CORE_IAS_ZONE_ENROLL_RESPONSE_VALUE_CB_ID: + ret = zb_cmd_ias_zone_enroll_response_handler((esp_zb_zcl_ias_zone_enroll_response_message_t *)message); + break; case ESP_ZB_CORE_CMD_DEFAULT_RESP_CB_ID: ret = zb_cmd_default_resp_handler((esp_zb_zcl_cmd_default_resp_message_t *)message); break; default: log_w("Receive unhandled Zigbee action(0x%x) callback", callback_id); break; } diff --git a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp index d2a15670557..9a3551b0581 100644 --- a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp @@ -31,7 +31,7 @@ void ZigbeeContactSwitch::setIASClientEndpoint(uint8_t ep_number) { void ZigbeeContactSwitch::setClosed() { log_v("Setting Contact switch to closed"); - uint8_t closed = 0; // ALARM1 = 0, ALARM2 = 0 + uint8_t closed = 0; // ALARM1 = 0, ALARM2 = 0 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, &closed, false @@ -43,11 +43,9 @@ void ZigbeeContactSwitch::setClosed() { void 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 + 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_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(); _zone_status = open; report(); @@ -59,7 +57,7 @@ void ZigbeeContactSwitch::report() { esp_zb_zcl_ias_zone_status_change_notif_cmd_t status_change_notif_cmd; status_change_notif_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT; 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 + 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; @@ -76,14 +74,20 @@ void ZigbeeContactSwitch::report() { void ZigbeeContactSwitch::zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) { if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE) { log_v("IAS Zone Enroll Response: zone id(%d), status(%d)", message->zone_id, message->response_code); - if(message->response_code == ESP_ZB_ZCL_IAS_ZONE_ENROLL_RESPONSE_CODE_SUCCESS) { + if (message->response_code == ESP_ZB_ZCL_IAS_ZONE_ENROLL_RESPONSE_CODE_SUCCESS) { log_v("IAS Zone Enroll Response: success"); 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)); + 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) + ); esp_zb_lock_release(); _zone_id = message->zone_id; - } - + } + } else { log_w("Received message ignored. Cluster ID: %d not supported for On/Off Light", message->info.cluster); } diff --git a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.h b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.h index ebb410b7dbd..692caf092ba 100644 --- a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.h +++ b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.h @@ -55,6 +55,7 @@ class ZigbeeContactSwitch : public ZigbeeEP { // Report the contact switch value, done automatically after setting the position void report(); + private: void zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) override; uint8_t _zone_status; diff --git a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp index 6ab3ac855c7..364b3ef6d9d 100644 --- a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp @@ -31,7 +31,7 @@ void ZigbeeDoorWindowHandle::setIASClientEndpoint(uint8_t ep_number) { void ZigbeeDoorWindowHandle::setClosed() { log_v("Setting Door/Window handle to closed"); - uint8_t closed = 0; // ALARM1 = 0, ALARM2 = 0 + uint8_t closed = 0; // ALARM1 = 0, ALARM2 = 0 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, &closed, false @@ -43,11 +43,9 @@ void ZigbeeDoorWindowHandle::setClosed() { void ZigbeeDoorWindowHandle::setOpen() { 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 + 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_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(); _zone_status = open; report(); @@ -55,7 +53,7 @@ void ZigbeeDoorWindowHandle::setOpen() { void ZigbeeDoorWindowHandle::setTilted() { log_v("Setting Door/Window handle to tilted"); - uint8_t tilted = ESP_ZB_ZCL_IAS_ZONE_ZONE_STATUS_ALARM1; // ALARM1 = 1, ALARM2 = 0 + 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( _endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONESTATUS_ID, &tilted, false @@ -71,7 +69,7 @@ void ZigbeeDoorWindowHandle::report() { esp_zb_zcl_ias_zone_status_change_notif_cmd_t status_change_notif_cmd; status_change_notif_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT; 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 + 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; @@ -88,14 +86,20 @@ void ZigbeeDoorWindowHandle::report() { void ZigbeeDoorWindowHandle::zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) { if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE) { log_v("IAS Zone Enroll Response: zone id(%d), status(%d)", message->zone_id, message->response_code); - if(message->response_code == ESP_ZB_ZCL_IAS_ZONE_ENROLL_RESPONSE_CODE_SUCCESS) { + if (message->response_code == ESP_ZB_ZCL_IAS_ZONE_ENROLL_RESPONSE_CODE_SUCCESS) { log_v("IAS Zone Enroll Response: success"); 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)); + 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) + ); esp_zb_lock_release(); _zone_id = message->zone_id; - } - + } + } else { log_w("Received message ignored. Cluster ID: %d not supported for On/Off Light", message->info.cluster); } diff --git a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h index 84ec4e71d8d..e60316f8764 100644 --- a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h +++ b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h @@ -59,6 +59,7 @@ class ZigbeeDoorWindowHandle : public ZigbeeEP { // Report the door/window handle value, done automatically after setting the position void report(); + private: void zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) override; uint8_t _zone_status; From 6698fb990840390d8da35219e06ec19794895f80 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: Tue, 4 Feb 2025 10:13:42 +0100 Subject: [PATCH 3/3] fix(ci): Typo fixes --- libraries/Zigbee/src/ZigbeeHandlers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/Zigbee/src/ZigbeeHandlers.cpp b/libraries/Zigbee/src/ZigbeeHandlers.cpp index be7ae1adb68..3f7578fd275 100644 --- a/libraries/Zigbee/src/ZigbeeHandlers.cpp +++ b/libraries/Zigbee/src/ZigbeeHandlers.cpp @@ -171,7 +171,7 @@ static esp_err_t zb_cmd_ias_zone_enroll_response_handler(const esp_zb_zcl_ias_zo log_e("Received message: error status(%d)", message->info.status); return ESP_ERR_INVALID_ARG; } - log_v("IAS Zone Enroll Response recieved"); + log_v("IAS Zone Enroll Response received"); for (std::list::iterator it = Zigbee.ep_objects.begin(); it != Zigbee.ep_objects.end(); ++it) { if (message->info.dst_endpoint == (*it)->getEndpoint()) { (*it)->zbIASZoneEnrollResponse(message);