diff --git a/libraries/Zigbee/examples/Zigbee_Color_Dimmable_Light/Zigbee_Color_Dimmable_Light.ino b/libraries/Zigbee/examples/Zigbee_Color_Dimmable_Light/Zigbee_Color_Dimmable_Light.ino index 7a68b830b2f..c12ecadbd64 100644 --- a/libraries/Zigbee/examples/Zigbee_Color_Dimmable_Light/Zigbee_Color_Dimmable_Light.ino +++ b/libraries/Zigbee/examples/Zigbee_Color_Dimmable_Light/Zigbee_Color_Dimmable_Light.ino @@ -15,7 +15,7 @@ /** * @brief This example demonstrates Zigbee Color Dimmable light bulb. * - * The example demonstrates how to use Zigbee library to create an end device with + * The example demonstrates how to use Zigbee library to create an end device with * color dimmable light end point. * The light bulb is a Zigbee end device, which is controlled by a Zigbee coordinator. * @@ -23,7 +23,7 @@ * 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/) */ @@ -34,9 +34,9 @@ #include "ZigbeeCore.h" #include "ep/ZigbeeColorDimmableLight.h" -#define LED_PIN RGB_BUILTIN -#define BUTTON_PIN 9 // C6/H2 Boot button -#define ZIGBEE_LIGHT_ENDPOINT 10 +#define LED_PIN RGB_BUILTIN +#define BUTTON_PIN 9 // C6/H2 Boot button +#define ZIGBEE_LIGHT_ENDPOINT 10 ZigbeeColorDimmableLight zbColorLight = ZigbeeColorDimmableLight(ZIGBEE_LIGHT_ENDPOINT); @@ -52,7 +52,7 @@ void identify(uint16_t time) { log_d("Identify called for %d seconds", time); if (time == 0) { // If identify time is 0, stop blinking and restore light as it was used for identify - zbColorLight.restoreLight(); + zbColorLight.restoreLight(); return; } rgbLedWrite(LED_PIN, 255 * blink, 255 * blink, 255 * blink); @@ -79,7 +79,7 @@ void setup() { // Add endpoint to Zigbee Core log_d("Adding ZigbeeLight endpoint to Zigbee Core"); Zigbee.addEndpoint(&zbColorLight); - + // When all EPs are registered, start Zigbee. By default acts as ZIGBEE_END_DEVICE log_d("Calling Zigbee.begin()"); Zigbee.begin(); @@ -93,7 +93,7 @@ void loop() { int startTime = millis(); while (digitalRead(BUTTON_PIN) == LOW) { delay(50); - if((millis() - startTime) > 3000) { + if ((millis() - startTime) > 3000) { // If key pressed for more than 3secs, factory reset Zigbee and reboot Serial.printf("Reseting Zigbee to factory settings, reboot.\n"); Zigbee.factoryReset(); @@ -101,4 +101,4 @@ void loop() { } } delay(100); -} \ No newline at end of file +} diff --git a/libraries/Zigbee/examples/Zigbee_Color_Dimmable_Light/ci.json b/libraries/Zigbee/examples/Zigbee_Color_Dimmable_Light/ci.json index 83af1395ee6..3aaf44eb376 100644 --- a/libraries/Zigbee/examples/Zigbee_Color_Dimmable_Light/ci.json +++ b/libraries/Zigbee/examples/Zigbee_Color_Dimmable_Light/ci.json @@ -1,16 +1,16 @@ { - "targets": { - "esp32": false, - "esp32c3": false, - "esp32s2": false, - "esp32s3": false - }, - "fqbn": { + "fqbn": { "esp32c6": [ "espressif:esp32:esp32c6:PartitionScheme=zigbee,ZigbeeMode=ed" ], "esp32h2": [ "espressif:esp32:esp32h2:PartitionScheme=zigbee,ZigbeeMode=ed" ] + }, + "targets": { + "esp32": false, + "esp32c3": false, + "esp32s2": false, + "esp32s3": false } } diff --git a/libraries/Zigbee/examples/Zigbee_Color_Dimmer_Switch/Zigbee_Color_Dimmer_Switch.ino b/libraries/Zigbee/examples/Zigbee_Color_Dimmer_Switch/Zigbee_Color_Dimmer_Switch.ino index b8cb061a91c..fac0a92316f 100644 --- a/libraries/Zigbee/examples/Zigbee_Color_Dimmer_Switch/Zigbee_Color_Dimmer_Switch.ino +++ b/libraries/Zigbee/examples/Zigbee_Color_Dimmer_Switch/Zigbee_Color_Dimmer_Switch.ino @@ -19,7 +19,7 @@ * The RGB light bulb is a Zigbee end device, which is controlled by a Zigbee coordinator (Switch). * To turn on/off the light, push the button on the switch. * To change the color or level of the light, send serial commands to the switch. - * + * * By setting the switch to allow multiple binding, so it can bind to multiple lights. * Also every 30 seconds, all bound lights are printed to the serial console. * @@ -27,7 +27,7 @@ * 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/) */ @@ -39,7 +39,7 @@ #include "ep/ZigbeeColorDimmerSwitch.h" /* Switch configuration */ -#define SWITCH_PIN 9 // ESP32-C6/H2 Boot button +#define SWITCH_PIN 9 // ESP32-C6/H2 Boot button #define SWITCH_ENDPOINT_NUMBER 5 /* Zigbee switch */ @@ -47,7 +47,7 @@ ZigbeeColorDimmerSwitch zbSwitch = ZigbeeColorDimmerSwitch(SWITCH_ENDPOINT_NUMBE /********************* Arduino functions **************************/ void setup() { - + Serial.begin(115200); while (!Serial) { delay(10); @@ -67,14 +67,13 @@ void setup() { //Open network for 180 seconds after boot Zigbee.setRebootOpenNetwork(180); - + //When all EPs are registered, start Zigbee with ZIGBEE_COORDINATOR mode Zigbee.begin(ZIGBEE_COORDINATOR); - + Serial.println("Waiting for Light to bound to the switch"); //Wait for switch to bound to a light: - while(!zbSwitch.isBound()) - { + while (!zbSwitch.isBound()) { Serial.printf("."); delay(500); } diff --git a/libraries/Zigbee/examples/Zigbee_Color_Dimmer_Switch/ci.json b/libraries/Zigbee/examples/Zigbee_Color_Dimmer_Switch/ci.json index 203fce34b38..c916121b991 100644 --- a/libraries/Zigbee/examples/Zigbee_Color_Dimmer_Switch/ci.json +++ b/libraries/Zigbee/examples/Zigbee_Color_Dimmer_Switch/ci.json @@ -1,16 +1,16 @@ { - "targets": { - "esp32": false, - "esp32c3": false, - "esp32s2": false, - "esp32s3": false - }, - "fqbn": { + "fqbn": { "esp32c6": [ "espressif:esp32:esp32c6:PartitionScheme=zigbee_zczr,ZigbeeMode=zczr" ], "esp32h2": [ "espressif:esp32:esp32h2:PartitionScheme=zigbee_zczr,ZigbeeMode=zczr" ] + }, + "targets": { + "esp32": false, + "esp32c3": false, + "esp32s2": false, + "esp32s3": false } } diff --git a/libraries/Zigbee/examples/Zigbee_On_Off_Light/Zigbee_On_Off_Light.ino b/libraries/Zigbee/examples/Zigbee_On_Off_Light/Zigbee_On_Off_Light.ino index 2bbe5ba3e7b..576623e990a 100644 --- a/libraries/Zigbee/examples/Zigbee_On_Off_Light/Zigbee_On_Off_Light.ino +++ b/libraries/Zigbee/examples/Zigbee_On_Off_Light/Zigbee_On_Off_Light.ino @@ -22,7 +22,7 @@ * 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/) */ @@ -33,8 +33,8 @@ #include "ZigbeeCore.h" #include "ep/ZigbeeLight.h" -#define LED_PIN RGB_BUILTIN -#define BUTTON_PIN 9 // ESP32-C6/H2 Boot button +#define LED_PIN RGB_BUILTIN +#define BUTTON_PIN 9 // ESP32-C6/H2 Boot button #define ZIGBEE_LIGHT_ENDPOINT 10 ZigbeeLight zbLight = ZigbeeLight(ZIGBEE_LIGHT_ENDPOINT); @@ -62,7 +62,7 @@ void setup() { //Add endpoint to Zigbee Core log_d("Adding ZigbeeLight endpoint to Zigbee Core"); Zigbee.addEndpoint(&zbLight); - + // When all EPs are registered, start Zigbee. By default acts as ZIGBEE_END_DEVICE log_d("Calling Zigbee.begin()"); Zigbee.begin(); @@ -76,7 +76,7 @@ void loop() { int startTime = millis(); while (digitalRead(BUTTON_PIN) == LOW) { delay(50); - if((millis() - startTime) > 3000) { + if ((millis() - startTime) > 3000) { // If key pressed for more than 3secs, factory reset Zigbee and reboot Serial.printf("Reseting Zigbee to factory settings, reboot.\n"); Zigbee.factoryReset(); @@ -84,4 +84,4 @@ void loop() { } } delay(100); -} \ No newline at end of file +} diff --git a/libraries/Zigbee/examples/Zigbee_On_Off_Light/ci.json b/libraries/Zigbee/examples/Zigbee_On_Off_Light/ci.json index 83af1395ee6..3aaf44eb376 100644 --- a/libraries/Zigbee/examples/Zigbee_On_Off_Light/ci.json +++ b/libraries/Zigbee/examples/Zigbee_On_Off_Light/ci.json @@ -1,16 +1,16 @@ { - "targets": { - "esp32": false, - "esp32c3": false, - "esp32s2": false, - "esp32s3": false - }, - "fqbn": { + "fqbn": { "esp32c6": [ "espressif:esp32:esp32c6:PartitionScheme=zigbee,ZigbeeMode=ed" ], "esp32h2": [ "espressif:esp32:esp32h2:PartitionScheme=zigbee,ZigbeeMode=ed" ] + }, + "targets": { + "esp32": false, + "esp32c3": false, + "esp32s2": false, + "esp32s3": false } } diff --git a/libraries/Zigbee/examples/Zigbee_On_Off_Switch/Zigbee_On_Off_Switch.ino b/libraries/Zigbee/examples/Zigbee_On_Off_Switch/Zigbee_On_Off_Switch.ino index f9f7c9a711d..09487dea05d 100644 --- a/libraries/Zigbee/examples/Zigbee_On_Off_Switch/Zigbee_On_Off_Switch.ino +++ b/libraries/Zigbee/examples/Zigbee_On_Off_Switch/Zigbee_On_Off_Switch.ino @@ -23,7 +23,7 @@ * 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/) */ @@ -94,7 +94,7 @@ static void enableGpioInterrupt(bool enabled) { /********************* Arduino functions **************************/ void setup() { - + Serial.begin(115200); while (!Serial) { delay(10); @@ -112,7 +112,7 @@ void setup() { //Open network for 180 seconds after boot Zigbee.setRebootOpenNetwork(180); - + // Init button switch for (int i = 0; i < PAIR_SIZE(buttonFunctionPair); i++) { pinMode(buttonFunctionPair[i].pin, INPUT_PULLUP); @@ -128,21 +128,23 @@ void setup() { // When all EPs are registered, start Zigbee with ZIGBEE_COORDINATOR mode log_d("Calling Zigbee.begin()"); Zigbee.begin(ZIGBEE_COORDINATOR); - + Serial.println("Waiting for Light to bound to the switch"); //Wait for switch to bound to a light: - while(!zbSwitch.isBound()) - { + while (!zbSwitch.isBound()) { Serial.printf("."); delay(500); } // Optional: read manufacturer and model name from the bound light - std::list boundLights = zbSwitch.getBoundDevices(); + std::list boundLights = zbSwitch.getBoundDevices(); //List all bound lights - for (const auto& device : boundLights) { + for (const auto &device : boundLights) { Serial.printf("Device on endpoint %d, short address: 0x%x\n", device->endpoint, device->short_addr); - Serial.printf("IEEE Address: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n", device->ieee_addr[0], device->ieee_addr[1], device->ieee_addr[2], device->ieee_addr[3], device->ieee_addr[4], device->ieee_addr[5], device->ieee_addr[6], device->ieee_addr[7]); + Serial.printf( + "IEEE Address: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n", device->ieee_addr[0], device->ieee_addr[1], device->ieee_addr[2], device->ieee_addr[3], + device->ieee_addr[4], device->ieee_addr[5], device->ieee_addr[6], device->ieee_addr[7] + ); Serial.printf("Light manufacturer: %s", zbSwitch.readManufacturer(device->endpoint, device->short_addr)); Serial.printf("Light model: %s", zbSwitch.readModel(device->endpoint, device->short_addr)); } @@ -156,7 +158,6 @@ void loop() { SwitchData buttonSwitch; static SwitchState buttonState = SWITCH_IDLE; bool eventFlag = false; - /* check if there is any queue received, if yes read out the buttonSwitch */ if (xQueueReceive(gpio_evt_queue, &buttonSwitch, portMAX_DELAY)) { diff --git a/libraries/Zigbee/examples/Zigbee_On_Off_Switch/ci.json b/libraries/Zigbee/examples/Zigbee_On_Off_Switch/ci.json index 203fce34b38..c916121b991 100644 --- a/libraries/Zigbee/examples/Zigbee_On_Off_Switch/ci.json +++ b/libraries/Zigbee/examples/Zigbee_On_Off_Switch/ci.json @@ -1,16 +1,16 @@ { - "targets": { - "esp32": false, - "esp32c3": false, - "esp32s2": false, - "esp32s3": false - }, - "fqbn": { + "fqbn": { "esp32c6": [ "espressif:esp32:esp32c6:PartitionScheme=zigbee_zczr,ZigbeeMode=zczr" ], "esp32h2": [ "espressif:esp32:esp32h2:PartitionScheme=zigbee_zczr,ZigbeeMode=zczr" ] + }, + "targets": { + "esp32": false, + "esp32c3": false, + "esp32s2": false, + "esp32s3": false } } diff --git a/libraries/Zigbee/examples/Zigbee_Scan_Networks/Zigbee_Scan_Networks.ino b/libraries/Zigbee/examples/Zigbee_Scan_Networks/Zigbee_Scan_Networks.ino index 3d67d74c8fe..a72ade201ae 100644 --- a/libraries/Zigbee/examples/Zigbee_Scan_Networks/Zigbee_Scan_Networks.ino +++ b/libraries/Zigbee/examples/Zigbee_Scan_Networks/Zigbee_Scan_Networks.ino @@ -21,7 +21,7 @@ * with proper Zigbee partition scheme 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/) */ @@ -32,9 +32,9 @@ #include "ZigbeeCore.h" #ifdef ZIGBEE_MODE_ZCZR -zigbee_role_t role = ZIGBEE_ROUTER; // or can be ZIGBEE_COORDINATOR, but it wont scan itself +zigbee_role_t role = ZIGBEE_ROUTER; // or can be ZIGBEE_COORDINATOR, but it wont scan itself #else -zigbee_role_t role = ZIGBEE_END_DEVICE; +zigbee_role_t role = ZIGBEE_END_DEVICE; #endif void printScannedNetworks(uint16_t networksFound) { @@ -60,10 +60,11 @@ void printScannedNetworks(uint16_t networksFound) { Serial.print(" | "); Serial.printf("%-19.19s", scan_result[i].end_device_capacity ? "Yes" : "No"); Serial.print(" | "); - Serial.printf("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", scan_result[i].extended_pan_id[7], scan_result[i].extended_pan_id[6], - scan_result[i].extended_pan_id[5], scan_result[i].extended_pan_id[4], - scan_result[i].extended_pan_id[3], scan_result[i].extended_pan_id[2], - scan_result[i].extended_pan_id[1], scan_result[i].extended_pan_id[0]); + Serial.printf( + "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", scan_result[i].extended_pan_id[7], scan_result[i].extended_pan_id[6], scan_result[i].extended_pan_id[5], + scan_result[i].extended_pan_id[4], scan_result[i].extended_pan_id[3], scan_result[i].extended_pan_id[2], scan_result[i].extended_pan_id[1], + scan_result[i].extended_pan_id[0] + ); Serial.println(); delay(10); } diff --git a/libraries/Zigbee/examples/Zigbee_Scan_Networks/ci.json b/libraries/Zigbee/examples/Zigbee_Scan_Networks/ci.json index 83af1395ee6..3aaf44eb376 100644 --- a/libraries/Zigbee/examples/Zigbee_Scan_Networks/ci.json +++ b/libraries/Zigbee/examples/Zigbee_Scan_Networks/ci.json @@ -1,16 +1,16 @@ { - "targets": { - "esp32": false, - "esp32c3": false, - "esp32s2": false, - "esp32s3": false - }, - "fqbn": { + "fqbn": { "esp32c6": [ "espressif:esp32:esp32c6:PartitionScheme=zigbee,ZigbeeMode=ed" ], "esp32h2": [ "espressif:esp32:esp32h2:PartitionScheme=zigbee,ZigbeeMode=ed" ] + }, + "targets": { + "esp32": false, + "esp32c3": false, + "esp32s2": false, + "esp32s3": false } } diff --git a/libraries/Zigbee/examples/Zigbee_Temperature_Sensor/Zigbee_Temperature_Sensor.ino b/libraries/Zigbee/examples/Zigbee_Temperature_Sensor/Zigbee_Temperature_Sensor.ino index 7a25319c983..bfb578663db 100644 --- a/libraries/Zigbee/examples/Zigbee_Temperature_Sensor/Zigbee_Temperature_Sensor.ino +++ b/libraries/Zigbee/examples/Zigbee_Temperature_Sensor/Zigbee_Temperature_Sensor.ino @@ -33,7 +33,7 @@ #include "ZigbeeCore.h" #include "ep/ZigbeeTempSensor.h" -#define BUTTON_PIN 9 //Boot button for C6/H2 +#define BUTTON_PIN 9 //Boot button for C6/H2 #define TEMP_SENSOR_ENDPOINT_NUMBER 10 ZigbeeTempSensor zbTempSensor = ZigbeeTempSensor(TEMP_SENSOR_ENDPOINT_NUMBER); @@ -52,7 +52,7 @@ static void temp_sensor_value_update(void *arg) { /********************* Arduino functions **************************/ void setup() { - + Serial.begin(115200); while (!Serial) { delay(10); @@ -65,7 +65,7 @@ void setup() { zbTempSensor.setManufacturerAndModel("Espressif", "ZigbeeTempSensor"); // Set minimum and maximum temperature measurement value (10-50°C is default range for chip temperature measurement) - zbTempSensor.setMinMaxValue(10,50); + zbTempSensor.setMinMaxValue(10, 50); // Set tolerance for temperature measurement in °C (lowest possible value is 0.01°C) zbTempSensor.setTolerance(1); @@ -95,7 +95,7 @@ void loop() { int startTime = millis(); while (digitalRead(BUTTON_PIN) == LOW) { delay(50); - if((millis() - startTime) > 3000) { + if ((millis() - startTime) > 3000) { // If key pressed for more than 3secs, factory reset Zigbee and reboot Serial.printf("Reseting Zigbee to factory settings, reboot.\n"); Zigbee.factoryReset(); diff --git a/libraries/Zigbee/examples/Zigbee_Temperature_Sensor/ci.json b/libraries/Zigbee/examples/Zigbee_Temperature_Sensor/ci.json index 83af1395ee6..3aaf44eb376 100644 --- a/libraries/Zigbee/examples/Zigbee_Temperature_Sensor/ci.json +++ b/libraries/Zigbee/examples/Zigbee_Temperature_Sensor/ci.json @@ -1,16 +1,16 @@ { - "targets": { - "esp32": false, - "esp32c3": false, - "esp32s2": false, - "esp32s3": false - }, - "fqbn": { + "fqbn": { "esp32c6": [ "espressif:esp32:esp32c6:PartitionScheme=zigbee,ZigbeeMode=ed" ], "esp32h2": [ "espressif:esp32:esp32h2:PartitionScheme=zigbee,ZigbeeMode=ed" ] + }, + "targets": { + "esp32": false, + "esp32c3": false, + "esp32s2": false, + "esp32s3": false } } diff --git a/libraries/Zigbee/examples/Zigbee_Thermostat/Zigbee_Thermostat.ino b/libraries/Zigbee/examples/Zigbee_Thermostat/Zigbee_Thermostat.ino index 94f7a1aba4e..0fef83f0ad7 100644 --- a/libraries/Zigbee/examples/Zigbee_Thermostat/Zigbee_Thermostat.ino +++ b/libraries/Zigbee/examples/Zigbee_Thermostat/Zigbee_Thermostat.ino @@ -23,7 +23,7 @@ * 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/) */ @@ -34,7 +34,7 @@ #include "ZigbeeCore.h" #include "ep/ZigbeeThermostat.h" -#define BUTTON_PIN 9 // Boot button for C6/H2 +#define BUTTON_PIN 9 // Boot button for C6/H2 #define THERMOSTAT_ENDPOINT_NUMBER 5 ZigbeeThermostat zbThermostat = ZigbeeThermostat(THERMOSTAT_ENDPOINT_NUMBER); @@ -79,15 +79,14 @@ void setup() { //Open network for 180 seconds after boot Zigbee.setRebootOpenNetwork(180); - + // When all EPs are registered, start Zigbee with ZIGBEE_COORDINATOR mode Zigbee.begin(ZIGBEE_COORDINATOR); - + Serial.println("Waiting for Temperature sensor to bound to the switch"); //Wait for switch to bound to a light: - while(!zbThermostat.isBound()) - { + while (!zbThermostat.isBound()) { Serial.printf("."); delay(500); } @@ -109,7 +108,7 @@ void loop() { // Set reporting interval for temperature sensor zbThermostat.setTemperatureReporting(0, 10, 2); } - + // Print temperature sensor data each 10 seconds static uint32_t last_print = 0; if (millis() - last_print > 10000) { diff --git a/libraries/Zigbee/examples/Zigbee_Thermostat/ci.json b/libraries/Zigbee/examples/Zigbee_Thermostat/ci.json index 203fce34b38..c916121b991 100644 --- a/libraries/Zigbee/examples/Zigbee_Thermostat/ci.json +++ b/libraries/Zigbee/examples/Zigbee_Thermostat/ci.json @@ -1,16 +1,16 @@ { - "targets": { - "esp32": false, - "esp32c3": false, - "esp32s2": false, - "esp32s3": false - }, - "fqbn": { + "fqbn": { "esp32c6": [ "espressif:esp32:esp32c6:PartitionScheme=zigbee_zczr,ZigbeeMode=zczr" ], "esp32h2": [ "espressif:esp32:esp32h2:PartitionScheme=zigbee_zczr,ZigbeeMode=zczr" ] + }, + "targets": { + "esp32": false, + "esp32c3": false, + "esp32s2": false, + "esp32s3": false } } diff --git a/libraries/Zigbee/src/ZigbeeCore.cpp b/libraries/Zigbee/src/ZigbeeCore.cpp index 737f2459368..2b089cf03ec 100644 --- a/libraries/Zigbee/src/ZigbeeCore.cpp +++ b/libraries/Zigbee/src/ZigbeeCore.cpp @@ -7,8 +7,8 @@ #include "Arduino.h" ZigbeeCore::ZigbeeCore() { - _radio_config.radio_mode = ZB_RADIO_MODE_NATIVE; // Use the native 15.4 radio - _host_config.host_connection_mode = ZB_HOST_CONNECTION_MODE_NONE; // Disable host connection + _radio_config.radio_mode = ZB_RADIO_MODE_NATIVE; // Use the native 15.4 radio + _host_config.host_connection_mode = ZB_HOST_CONNECTION_MODE_NONE; // Disable host connection _zb_ep_list = esp_zb_ep_list_create(); _primary_channel_mask = ESP_ZB_TRANSCEIVER_ALL_CHANNELS_MASK; _open_network = 0; @@ -21,7 +21,7 @@ ZigbeeCore::~ZigbeeCore() {} static esp_err_t zb_action_handler(esp_zb_core_action_callback_id_t callback_id, const void *message); bool ZigbeeCore::begin(esp_zb_cfg_t *role_cfg, bool erase_nvs) { - if (!zigbeeInit(role_cfg, erase_nvs)){ + if (!zigbeeInit(role_cfg, erase_nvs)) { return false; } _role = (zigbee_role_t)role_cfg->esp_zb_role; @@ -30,36 +30,36 @@ bool ZigbeeCore::begin(esp_zb_cfg_t *role_cfg, bool erase_nvs) { bool ZigbeeCore::begin(zigbee_role_t role, bool erase_nvs) { bool status = true; - switch (role) - { - case ZIGBEE_COORDINATOR: { + switch (role) { + case ZIGBEE_COORDINATOR: + { _role = ZIGBEE_COORDINATOR; esp_zb_cfg_t zb_nwk_cfg = ZIGBEE_DEFAULT_COORDINATOR_CONFIG(); status = zigbeeInit(&zb_nwk_cfg, erase_nvs); break; } - case ZIGBEE_ROUTER: { + case ZIGBEE_ROUTER: + { _role = ZIGBEE_ROUTER; esp_zb_cfg_t zb_nwk_cfg = ZIGBEE_DEFAULT_ROUTER_CONFIG(); status = zigbeeInit(&zb_nwk_cfg, erase_nvs); break; } - case ZIGBEE_END_DEVICE: { + case ZIGBEE_END_DEVICE: + { _role = ZIGBEE_END_DEVICE; esp_zb_cfg_t zb_nwk_cfg = ZIGBEE_DEFAULT_ED_CONFIG(); status = zigbeeInit(&zb_nwk_cfg, erase_nvs); break; } - default: - log_e("Invalid Zigbee Role"); - return false; + default: log_e("Invalid Zigbee Role"); return false; } return status; } void ZigbeeCore::addEndpoint(ZigbeeEP *ep) { ep_objects.push_back(ep); - + log_d("Endpoint: %d, Device ID: 0x%04x", ep->_endpoint, ep->_device_id); //Register clusters and ep_list to the ZigbeeCore class's ep_list if (ep->_ep_config.endpoint == 0 || ep->_cluster_list == nullptr) { @@ -84,7 +84,7 @@ bool ZigbeeCore::zigbeeInit(esp_zb_cfg_t *zb_cfg, bool erase_nvs) { .host_config = _host_config, }; - esp_err_t err = esp_zb_platform_config(&platform_config); + esp_err_t err = esp_zb_platform_config(&platform_config); if (err != ESP_OK) { log_e("Failed to configure Zigbee platform"); return false; @@ -94,8 +94,8 @@ bool ZigbeeCore::zigbeeInit(esp_zb_cfg_t *zb_cfg, bool erase_nvs) { log_d("Initialize Zigbee stack"); esp_zb_init(zb_cfg); - // Register all Zigbee EPs in list - if(ep_objects.empty()) { + // Register all Zigbee EPs in list + if (ep_objects.empty()) { log_w("No Zigbee EPs to register"); } else { log_d("Register all Zigbee EPs in list"); @@ -104,10 +104,10 @@ bool ZigbeeCore::zigbeeInit(esp_zb_cfg_t *zb_cfg, bool erase_nvs) { log_e("Failed to register Zigbee EPs"); return false; } - + //print the list of Zigbee EPs from ep_objects log_i("List of registered Zigbee EPs:"); - for (std::list::iterator it = ep_objects.begin(); it != ep_objects.end(); ++it) { + for (std::list::iterator it = ep_objects.begin(); it != ep_objects.end(); ++it) { log_i("Device type: %s, Endpoint: %d, Device ID: 0x%04x", getDeviceTypeString((*it)->_device_id), (*it)->_endpoint, (*it)->_device_id); } } @@ -175,12 +175,12 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct) { //main switch switch (sig_type) { - case ESP_ZB_ZDO_SIGNAL_SKIP_STARTUP: // Common + case ESP_ZB_ZDO_SIGNAL_SKIP_STARTUP: // Common log_i("Zigbee stack initialized"); esp_zb_bdb_start_top_level_commissioning(ESP_ZB_BDB_MODE_INITIALIZATION); break; - case ESP_ZB_BDB_SIGNAL_DEVICE_FIRST_START: // Common - case ESP_ZB_BDB_SIGNAL_DEVICE_REBOOT: // Common + case ESP_ZB_BDB_SIGNAL_DEVICE_FIRST_START: // Common + case ESP_ZB_BDB_SIGNAL_DEVICE_REBOOT: // Common if (err_status == ESP_OK) { log_i("Device started up in %s factory-reset mode", esp_zb_bdb_is_factory_new() ? "" : "non"); if (esp_zb_bdb_is_factory_new()) { @@ -207,7 +207,7 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct) { log_e("Failed to initialize Zigbee stack (status: %s)", esp_err_to_name(err_status)); } break; - case ESP_ZB_BDB_SIGNAL_FORMATION: // Coordinator + case ESP_ZB_BDB_SIGNAL_FORMATION: // Coordinator if ((zigbee_role_t)Zigbee.getRole() == ZIGBEE_COORDINATOR) { if (err_status == ESP_OK) { esp_zb_ieee_addr_t extended_pan_id; @@ -224,14 +224,13 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct) { } } break; - case ESP_ZB_BDB_SIGNAL_STEERING: // Router and End Device + case ESP_ZB_BDB_SIGNAL_STEERING: // Router and End Device Zigbee._started = true; if ((zigbee_role_t)Zigbee.getRole() == ZIGBEE_COORDINATOR) { if (err_status == ESP_OK) { log_i("Network steering started"); } - } - else { + } else { if (err_status == ESP_OK) { esp_zb_ieee_addr_t extended_pan_id; esp_zb_get_extended_pan_id(extended_pan_id); @@ -246,7 +245,7 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct) { } } break; - case ESP_ZB_ZDO_SIGNAL_DEVICE_ANNCE: // Coordinator + case ESP_ZB_ZDO_SIGNAL_DEVICE_ANNCE: // Coordinator if ((zigbee_role_t)Zigbee.getRole() == ZIGBEE_COORDINATOR) { dev_annce_params = (esp_zb_zdo_signal_device_annce_params_t *)esp_zb_app_signal_get_params(p_sg_p); log_i("New device commissioned or rejoined (short: 0x%04hx)", dev_annce_params->device_short_addr); @@ -255,26 +254,26 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct) { cmd_req.addr_of_interest = dev_annce_params->device_short_addr; log_v("Device capabilities: 0x%02x", dev_annce_params->capability); /* - capability: + capability: Bit 0 – Alternate PAN Coordinator Bit 1 – Device type: 1- ZigBee Router; 0 – End Device - Bit 2 – Power Source: 1 Main powered + Bit 2 – Power Source: 1 Main powered Bit 3 – Receiver on when Idle - Bit 4 – Reserved - Bit 5 – Reserved + Bit 4 – Reserved + Bit 5 – Reserved Bit 6 – Security capability Bit 7 – Reserved */ // for each endpoint in the list call the findEndpoint function if not bounded or allowed to bind multiple devices - for (std::list::iterator it = Zigbee.ep_objects.begin(); it != Zigbee.ep_objects.end(); ++it) { + for (std::list::iterator it = Zigbee.ep_objects.begin(); it != Zigbee.ep_objects.end(); ++it) { if (!(*it)->isBound() || (*it)->epAllowMultipleBinding()) { (*it)->findEndpoint(&cmd_req); } } } break; - case ESP_ZB_NWK_SIGNAL_PERMIT_JOIN_STATUS: // Coordinator + case ESP_ZB_NWK_SIGNAL_PERMIT_JOIN_STATUS: // Coordinator if ((zigbee_role_t)Zigbee.getRole() == ZIGBEE_COORDINATOR) { if (err_status == ESP_OK) { if (*(uint8_t *)esp_zb_app_signal_get_params(p_sg_p)) { @@ -294,14 +293,20 @@ void ZigbeeCore::factoryReset() { esp_zb_factory_reset(); } -void ZigbeeCore::scanCompleteCallback(esp_zb_zdp_status_t zdo_status, uint8_t count, esp_zb_network_descriptor_t *nwk_descriptor){ +void ZigbeeCore::scanCompleteCallback(esp_zb_zdp_status_t zdo_status, uint8_t count, esp_zb_network_descriptor_t *nwk_descriptor) { log_v("Zigbee network scan complete"); - if(zdo_status == ESP_ZB_ZDP_STATUS_SUCCESS) { + if (zdo_status == ESP_ZB_ZDP_STATUS_SUCCESS) { log_v("Found %d networks", count); //print Zigbee networks for (int i = 0; i < count; i++) { - log_v("Network %d: PAN ID: 0x%04hx, Permit Joining: %s, Extended PAN ID: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, Channel: %d, Router Capacity: %s, End Device Capacity: %s", - i, nwk_descriptor[i].short_pan_id, nwk_descriptor[i].permit_joining ? "Yes" : "No", nwk_descriptor[i].extended_pan_id[7], nwk_descriptor[i].extended_pan_id[6], nwk_descriptor[i].extended_pan_id[5], nwk_descriptor[i].extended_pan_id[4], nwk_descriptor[i].extended_pan_id[3], nwk_descriptor[i].extended_pan_id[2], nwk_descriptor[i].extended_pan_id[1], nwk_descriptor[i].extended_pan_id[0], nwk_descriptor[i].logic_channel, nwk_descriptor[i].router_capacity ? "Yes" : "No", nwk_descriptor[i].end_device_capacity ? "Yes" : "No"); + log_v( + "Network %d: PAN ID: 0x%04hx, Permit Joining: %s, Extended PAN ID: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, Channel: %d, Router Capacity: %s, End " + "Device Capacity: %s", + i, nwk_descriptor[i].short_pan_id, nwk_descriptor[i].permit_joining ? "Yes" : "No", nwk_descriptor[i].extended_pan_id[7], + nwk_descriptor[i].extended_pan_id[6], nwk_descriptor[i].extended_pan_id[5], nwk_descriptor[i].extended_pan_id[4], nwk_descriptor[i].extended_pan_id[3], + nwk_descriptor[i].extended_pan_id[2], nwk_descriptor[i].extended_pan_id[1], nwk_descriptor[i].extended_pan_id[0], nwk_descriptor[i].logic_channel, + nwk_descriptor[i].router_capacity ? "Yes" : "No", nwk_descriptor[i].end_device_capacity ? "Yes" : "No" + ); } //save scan result and update scan status //copy network descriptor to _scan_result to keep the data after the callback @@ -316,7 +321,7 @@ void ZigbeeCore::scanCompleteCallback(esp_zb_zdp_status_t zdo_status, uint8_t co } void ZigbeeCore::scanNetworks(u_int32_t channel_mask, u_int8_t scan_duration) { - if(!_started) { + if (!_started) { log_e("Zigbee stack is not started, cannot scan networks"); return; } @@ -325,11 +330,11 @@ void ZigbeeCore::scanNetworks(u_int32_t channel_mask, u_int8_t scan_duration) { _scan_status = ZB_SCAN_RUNNING; } -int16_t ZigbeeCore::scanComplete(){ +int16_t ZigbeeCore::scanComplete() { return _scan_status; } -zigbee_scan_result_t* ZigbeeCore::getScanResult() { +zigbee_scan_result_t *ZigbeeCore::getScanResult() { return _scan_result; } @@ -342,50 +347,50 @@ void ZigbeeCore::scanDelete() { } // Function to convert enum value to string -const char* ZigbeeCore::getDeviceTypeString(esp_zb_ha_standard_devices_t deviceId) { - switch (deviceId) { - case ESP_ZB_HA_ON_OFF_SWITCH_DEVICE_ID: return "General On/Off switch"; - case ESP_ZB_HA_LEVEL_CONTROL_SWITCH_DEVICE_ID: return "Level Control Switch"; - case ESP_ZB_HA_ON_OFF_OUTPUT_DEVICE_ID: return "General On/Off output"; - case ESP_ZB_HA_LEVEL_CONTROLLABLE_OUTPUT_DEVICE_ID: return "Level Controllable Output"; - case ESP_ZB_HA_SCENE_SELECTOR_DEVICE_ID: return "Scene Selector"; - case ESP_ZB_HA_CONFIGURATION_TOOL_DEVICE_ID: return "Configuration Tool"; - case ESP_ZB_HA_REMOTE_CONTROL_DEVICE_ID: return "Remote Control"; - case ESP_ZB_HA_COMBINED_INTERFACE_DEVICE_ID: return "Combined Interface"; - case ESP_ZB_HA_RANGE_EXTENDER_DEVICE_ID: return "Range Extender"; - case ESP_ZB_HA_MAINS_POWER_OUTLET_DEVICE_ID: return "Mains Power Outlet"; - case ESP_ZB_HA_DOOR_LOCK_DEVICE_ID: return "Door lock client"; - case ESP_ZB_HA_DOOR_LOCK_CONTROLLER_DEVICE_ID: return "Door lock controller"; - case ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID: return "Simple Sensor device"; - case ESP_ZB_HA_CONSUMPTION_AWARENESS_DEVICE_ID: return "Consumption Awareness Device"; - case ESP_ZB_HA_HOME_GATEWAY_DEVICE_ID: return "Home Gateway"; - case ESP_ZB_HA_SMART_PLUG_DEVICE_ID: return "Smart plug"; - case ESP_ZB_HA_WHITE_GOODS_DEVICE_ID: return "White Goods"; - case ESP_ZB_HA_METER_INTERFACE_DEVICE_ID: return "Meter Interface"; - case ESP_ZB_HA_ON_OFF_LIGHT_DEVICE_ID: return "On/Off Light Device"; - case ESP_ZB_HA_DIMMABLE_LIGHT_DEVICE_ID: return "Dimmable Light Device"; - case ESP_ZB_HA_COLOR_DIMMABLE_LIGHT_DEVICE_ID: return "Color Dimmable Light Device"; - case ESP_ZB_HA_DIMMER_SWITCH_DEVICE_ID: return "Dimmer Switch Device"; - case ESP_ZB_HA_COLOR_DIMMER_SWITCH_DEVICE_ID: return "Color Dimmer Switch Device"; - case ESP_ZB_HA_LIGHT_SENSOR_DEVICE_ID: return "Light Sensor"; - case ESP_ZB_HA_SHADE_DEVICE_ID: return "Shade"; - case ESP_ZB_HA_SHADE_CONTROLLER_DEVICE_ID: return "Shade controller"; - case ESP_ZB_HA_WINDOW_COVERING_DEVICE_ID: return "Window Covering client"; - case ESP_ZB_HA_WINDOW_COVERING_CONTROLLER_DEVICE_ID: return "Window Covering controller"; - case ESP_ZB_HA_HEATING_COOLING_UNIT_DEVICE_ID: return "Heating/Cooling Unit device"; - case ESP_ZB_HA_THERMOSTAT_DEVICE_ID: return "Thermostat Device"; - case ESP_ZB_HA_TEMPERATURE_SENSOR_DEVICE_ID: return "Temperature Sensor"; - case ESP_ZB_HA_IAS_CONTROL_INDICATING_EQUIPMENT_ID: return "IAS Control and Indicating Equipment"; - case ESP_ZB_HA_IAS_ANCILLARY_CONTROL_EQUIPMENT_ID: return "IAS Ancillary Control Equipment"; - case ESP_ZB_HA_IAS_ZONE_ID: return "IAS Zone"; - case ESP_ZB_HA_IAS_WARNING_DEVICE_ID: return "IAS Warning Device"; - case ESP_ZB_HA_TEST_DEVICE_ID: return "Custom HA device for test"; - case ESP_ZB_HA_CUSTOM_TUNNEL_DEVICE_ID: return "Custom Tunnel device"; - case ESP_ZB_HA_CUSTOM_ATTR_DEVICE_ID: return "Custom Attributes Device"; - default: return "Unknown device type"; - } +const char *ZigbeeCore::getDeviceTypeString(esp_zb_ha_standard_devices_t deviceId) { + switch (deviceId) { + case ESP_ZB_HA_ON_OFF_SWITCH_DEVICE_ID: return "General On/Off switch"; + case ESP_ZB_HA_LEVEL_CONTROL_SWITCH_DEVICE_ID: return "Level Control Switch"; + case ESP_ZB_HA_ON_OFF_OUTPUT_DEVICE_ID: return "General On/Off output"; + case ESP_ZB_HA_LEVEL_CONTROLLABLE_OUTPUT_DEVICE_ID: return "Level Controllable Output"; + case ESP_ZB_HA_SCENE_SELECTOR_DEVICE_ID: return "Scene Selector"; + case ESP_ZB_HA_CONFIGURATION_TOOL_DEVICE_ID: return "Configuration Tool"; + case ESP_ZB_HA_REMOTE_CONTROL_DEVICE_ID: return "Remote Control"; + case ESP_ZB_HA_COMBINED_INTERFACE_DEVICE_ID: return "Combined Interface"; + case ESP_ZB_HA_RANGE_EXTENDER_DEVICE_ID: return "Range Extender"; + case ESP_ZB_HA_MAINS_POWER_OUTLET_DEVICE_ID: return "Mains Power Outlet"; + case ESP_ZB_HA_DOOR_LOCK_DEVICE_ID: return "Door lock client"; + case ESP_ZB_HA_DOOR_LOCK_CONTROLLER_DEVICE_ID: return "Door lock controller"; + case ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID: return "Simple Sensor device"; + case ESP_ZB_HA_CONSUMPTION_AWARENESS_DEVICE_ID: return "Consumption Awareness Device"; + case ESP_ZB_HA_HOME_GATEWAY_DEVICE_ID: return "Home Gateway"; + case ESP_ZB_HA_SMART_PLUG_DEVICE_ID: return "Smart plug"; + case ESP_ZB_HA_WHITE_GOODS_DEVICE_ID: return "White Goods"; + case ESP_ZB_HA_METER_INTERFACE_DEVICE_ID: return "Meter Interface"; + case ESP_ZB_HA_ON_OFF_LIGHT_DEVICE_ID: return "On/Off Light Device"; + case ESP_ZB_HA_DIMMABLE_LIGHT_DEVICE_ID: return "Dimmable Light Device"; + case ESP_ZB_HA_COLOR_DIMMABLE_LIGHT_DEVICE_ID: return "Color Dimmable Light Device"; + case ESP_ZB_HA_DIMMER_SWITCH_DEVICE_ID: return "Dimmer Switch Device"; + case ESP_ZB_HA_COLOR_DIMMER_SWITCH_DEVICE_ID: return "Color Dimmer Switch Device"; + case ESP_ZB_HA_LIGHT_SENSOR_DEVICE_ID: return "Light Sensor"; + case ESP_ZB_HA_SHADE_DEVICE_ID: return "Shade"; + case ESP_ZB_HA_SHADE_CONTROLLER_DEVICE_ID: return "Shade controller"; + case ESP_ZB_HA_WINDOW_COVERING_DEVICE_ID: return "Window Covering client"; + case ESP_ZB_HA_WINDOW_COVERING_CONTROLLER_DEVICE_ID: return "Window Covering controller"; + case ESP_ZB_HA_HEATING_COOLING_UNIT_DEVICE_ID: return "Heating/Cooling Unit device"; + case ESP_ZB_HA_THERMOSTAT_DEVICE_ID: return "Thermostat Device"; + case ESP_ZB_HA_TEMPERATURE_SENSOR_DEVICE_ID: return "Temperature Sensor"; + case ESP_ZB_HA_IAS_CONTROL_INDICATING_EQUIPMENT_ID: return "IAS Control and Indicating Equipment"; + case ESP_ZB_HA_IAS_ANCILLARY_CONTROL_EQUIPMENT_ID: return "IAS Ancillary Control Equipment"; + case ESP_ZB_HA_IAS_ZONE_ID: return "IAS Zone"; + case ESP_ZB_HA_IAS_WARNING_DEVICE_ID: return "IAS Warning Device"; + case ESP_ZB_HA_TEST_DEVICE_ID: return "Custom HA device for test"; + case ESP_ZB_HA_CUSTOM_TUNNEL_DEVICE_ID: return "Custom Tunnel device"; + case ESP_ZB_HA_CUSTOM_ATTR_DEVICE_ID: return "Custom Attributes Device"; + default: return "Unknown device type"; + } } ZigbeeCore Zigbee = ZigbeeCore(); -#endif //SOC_IEEE802154_SUPPORTED +#endif //SOC_IEEE802154_SUPPORTED diff --git a/libraries/Zigbee/src/ZigbeeCore.h b/libraries/Zigbee/src/ZigbeeCore.h index 0a7f52e1b42..1044a9c737c 100644 --- a/libraries/Zigbee/src/ZigbeeCore.h +++ b/libraries/Zigbee/src/ZigbeeCore.h @@ -19,110 +19,107 @@ typedef esp_zb_network_descriptor_t zigbee_scan_result_t; // enum of Zigbee Roles typedef enum { - ZIGBEE_COORDINATOR = 0, - ZIGBEE_ROUTER = 1, - ZIGBEE_END_DEVICE = 2 + ZIGBEE_COORDINATOR = 0, + ZIGBEE_ROUTER = 1, + ZIGBEE_END_DEVICE = 2 } zigbee_role_t; #define ZB_SCAN_RUNNING (-1) #define ZB_SCAN_FAILED (-2) -#define ZIGBEE_DEFAULT_ED_CONFIG() \ - { \ - .esp_zb_role = ESP_ZB_DEVICE_TYPE_ED, \ - .install_code_policy = false, \ - .nwk_cfg = { \ - .zed_cfg = \ - { \ - .ed_timeout = ESP_ZB_ED_AGING_TIMEOUT_64MIN, \ - .keep_alive = 3000, \ - }, \ - }, \ +#define ZIGBEE_DEFAULT_ED_CONFIG() \ + { \ + .esp_zb_role = ESP_ZB_DEVICE_TYPE_ED, .install_code_policy = false, \ + .nwk_cfg = { \ + .zed_cfg = \ + { \ + .ed_timeout = ESP_ZB_ED_AGING_TIMEOUT_64MIN, \ + .keep_alive = 3000, \ + }, \ + }, \ } -#define ZIGBEE_DEFAULT_ROUTER_CONFIG() \ - { \ - .esp_zb_role = ESP_ZB_DEVICE_TYPE_ROUTER, \ - .install_code_policy = false, \ - .nwk_cfg = { \ - .zczr_cfg = \ - { \ - .max_children = 10, \ - }, \ - } \ +#define ZIGBEE_DEFAULT_ROUTER_CONFIG() \ + { \ + .esp_zb_role = ESP_ZB_DEVICE_TYPE_ROUTER, .install_code_policy = false, .nwk_cfg = { \ + .zczr_cfg = \ + { \ + .max_children = 10, \ + }, \ + } \ } - -#define ZIGBEE_DEFAULT_COORDINATOR_CONFIG() \ - { \ - .esp_zb_role = ESP_ZB_DEVICE_TYPE_COORDINATOR, \ - .install_code_policy = false, \ - .nwk_cfg = { \ - .zczr_cfg = \ - { \ - .max_children = 10, \ - }, \ - } \ +#define ZIGBEE_DEFAULT_COORDINATOR_CONFIG() \ + { \ + .esp_zb_role = ESP_ZB_DEVICE_TYPE_COORDINATOR, .install_code_policy = false, .nwk_cfg = { \ + .zczr_cfg = \ + { \ + .max_children = 10, \ + }, \ + } \ } class ZigbeeCore { - private: - esp_zb_radio_config_t _radio_config; - esp_zb_host_config_t _host_config; - uint32_t _primary_channel_mask; - int16_t _scan_status; - - esp_zb_ep_list_t *_zb_ep_list; - zigbee_role_t _role; - bool _started; +private: + esp_zb_radio_config_t _radio_config; + esp_zb_host_config_t _host_config; + uint32_t _primary_channel_mask; + int16_t _scan_status; - uint8_t _open_network; - zigbee_scan_result_t *_scan_result; + esp_zb_ep_list_t *_zb_ep_list; + zigbee_role_t _role; + bool _started; - bool zigbeeInit(esp_zb_cfg_t *zb_cfg, bool erase_nvs); - static void scanCompleteCallback(esp_zb_zdp_status_t zdo_status, uint8_t count, esp_zb_network_descriptor_t *nwk_descriptor); - const char* getDeviceTypeString(esp_zb_ha_standard_devices_t deviceId); + uint8_t _open_network; + zigbee_scan_result_t *_scan_result; - public: - ZigbeeCore(); - ~ZigbeeCore(); + bool zigbeeInit(esp_zb_cfg_t *zb_cfg, bool erase_nvs); + static void scanCompleteCallback(esp_zb_zdp_status_t zdo_status, uint8_t count, esp_zb_network_descriptor_t *nwk_descriptor); + const char *getDeviceTypeString(esp_zb_ha_standard_devices_t deviceId); - std::list ep_objects; +public: + ZigbeeCore(); + ~ZigbeeCore(); - bool begin(zigbee_role_t role = ZIGBEE_END_DEVICE, bool erase_nvs = false); - bool begin(esp_zb_cfg_t *role_cfg, bool erase_nvs = false); - // bool end(); + std::list ep_objects; - bool isStarted() { return _started; } - zigbee_role_t getRole() { return _role; } + bool begin(zigbee_role_t role = ZIGBEE_END_DEVICE, bool erase_nvs = false); + bool begin(esp_zb_cfg_t *role_cfg, bool erase_nvs = false); + // bool end(); - void addEndpoint(ZigbeeEP *ep); - //void removeEndpoint(ZigbeeEP *ep); + bool isStarted() { + return _started; + } + zigbee_role_t getRole() { + return _role; + } - void setRadioConfig(esp_zb_radio_config_t config); - esp_zb_radio_config_t getRadioConfig(); + void addEndpoint(ZigbeeEP *ep); + //void removeEndpoint(ZigbeeEP *ep); - void setHostConfig(esp_zb_host_config_t config); - esp_zb_host_config_t getHostConfig(); + void setRadioConfig(esp_zb_radio_config_t config); + esp_zb_radio_config_t getRadioConfig(); - void setPrimaryChannelMask(uint32_t mask); - void setRebootOpenNetwork(uint8_t time); - void openNetwork(uint8_t time); + void setHostConfig(esp_zb_host_config_t config); + esp_zb_host_config_t getHostConfig(); - //scan_duration Time spent scanning each channel, in units of ((1 << scan_duration) + 1) * a beacon time. (15.36 microseconds) - void scanNetworks(uint32_t channel_mask = ESP_ZB_TRANSCEIVER_ALL_CHANNELS_MASK, uint8_t scan_duration = 5); - // Zigbee scan complete status check, -2: failed or not started, -1: running, 0: no networks found, >0: number of networks found - int16_t scanComplete(); - zigbee_scan_result_t* getScanResult(); - void scanDelete(); + void setPrimaryChannelMask(uint32_t mask); + void setRebootOpenNetwork(uint8_t time); + void openNetwork(uint8_t time); - void factoryReset(); + //scan_duration Time spent scanning each channel, in units of ((1 << scan_duration) + 1) * a beacon time. (15.36 microseconds) + void scanNetworks(uint32_t channel_mask = ESP_ZB_TRANSCEIVER_ALL_CHANNELS_MASK, uint8_t scan_duration = 5); + // Zigbee scan complete status check, -2: failed or not started, -1: running, 0: no networks found, >0: number of networks found + int16_t scanComplete(); + zigbee_scan_result_t *getScanResult(); + void scanDelete(); - // Friend function declaration to allow access to private members - friend void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct); + void factoryReset(); + // Friend function declaration to allow access to private members + friend void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct); }; extern ZigbeeCore Zigbee; -#endif //SOC_IEEE802154_SUPPORTED +#endif //SOC_IEEE802154_SUPPORTED diff --git a/libraries/Zigbee/src/ZigbeeEP.cpp b/libraries/Zigbee/src/ZigbeeEP.cpp index 1f5823a7bfd..af237739327 100644 --- a/libraries/Zigbee/src/ZigbeeEP.cpp +++ b/libraries/Zigbee/src/ZigbeeEP.cpp @@ -12,154 +12,151 @@ bool ZigbeeEP::_allow_multiple_binding = false; /* Zigbee End Device Class */ ZigbeeEP::ZigbeeEP(uint8_t endpoint) { - _endpoint = endpoint; - _ep_config.endpoint = 0; - _cluster_list = nullptr; + _endpoint = endpoint; + _ep_config.endpoint = 0; + _cluster_list = nullptr; #if !CONFIG_DISABLE_HAL_LOCKS - if (!lock) { - lock = xSemaphoreCreateBinary(); - if (lock == NULL) { - log_e("Semaphore creation failed"); - } + if (!lock) { + lock = xSemaphoreCreateBinary(); + if (lock == NULL) { + log_e("Semaphore creation failed"); } + } #endif } -ZigbeeEP::~ZigbeeEP() { - -} +ZigbeeEP::~ZigbeeEP() {} void ZigbeeEP::setVersion(uint8_t version) { - _ep_config.app_device_version = version; + _ep_config.app_device_version = version; } void ZigbeeEP::setManufacturerAndModel(const char *name, const char *model) { - // Convert manufacturer to ZCL string - size_t length = strlen(name); - if (length > 32) { - log_e("Manufacturer name is too long"); - return; - } - // Allocate a new array of size length + 2 (1 for the length, 1 for null terminator) - char* zb_name = new char[length + 2]; - // Store the length as the first element - zb_name[0] = static_cast(length); // Cast size_t to char - // Use memcpy to copy the characters to the result array - memcpy(zb_name + 1, name, length); - // Null-terminate the array - zb_name[length + 1] = '\0'; - - // Convert model to ZCL string - length = strlen(model); - if (length > 32) { - log_e("Model name is too long"); - delete[] zb_name; - return; - } - char* zb_model = new char[length + 2]; - zb_model[0] = static_cast(length); - memcpy(zb_model + 1, model, length); - zb_model[length + 1] = '\0'; - - // Get the basic cluster and update the manufacturer and model attributes - esp_zb_attribute_list_t *basic_cluster = esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_BASIC, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); - esp_zb_basic_cluster_add_attr(basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MANUFACTURER_NAME_ID, (void *)zb_name); - esp_zb_basic_cluster_add_attr(basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MODEL_IDENTIFIER_ID, (void *)zb_model); + // Convert manufacturer to ZCL string + size_t length = strlen(name); + if (length > 32) { + log_e("Manufacturer name is too long"); + return; + } + // Allocate a new array of size length + 2 (1 for the length, 1 for null terminator) + char *zb_name = new char[length + 2]; + // Store the length as the first element + zb_name[0] = static_cast(length); // Cast size_t to char + // Use memcpy to copy the characters to the result array + memcpy(zb_name + 1, name, length); + // Null-terminate the array + zb_name[length + 1] = '\0'; + + // Convert model to ZCL string + length = strlen(model); + if (length > 32) { + log_e("Model name is too long"); + delete[] zb_name; + return; + } + char *zb_model = new char[length + 2]; + zb_model[0] = static_cast(length); + memcpy(zb_model + 1, model, length); + zb_model[length + 1] = '\0'; + + // Get the basic cluster and update the manufacturer and model attributes + esp_zb_attribute_list_t *basic_cluster = esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_BASIC, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_zb_basic_cluster_add_attr(basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MANUFACTURER_NAME_ID, (void *)zb_name); + esp_zb_basic_cluster_add_attr(basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MODEL_IDENTIFIER_ID, (void *)zb_model); } -char* ZigbeeEP::readManufacturer(uint8_t endpoint, uint16_t short_addr) { - /* Read peer Manufacture Name & Model Identifier */ - esp_zb_zcl_read_attr_cmd_t read_req; - read_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT; - read_req.zcl_basic_cmd.src_endpoint = _endpoint; - read_req.zcl_basic_cmd.dst_endpoint = endpoint; - read_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr; - read_req.clusterID = ESP_ZB_ZCL_CLUSTER_ID_BASIC; +char *ZigbeeEP::readManufacturer(uint8_t endpoint, uint16_t short_addr) { + /* Read peer Manufacture Name & Model Identifier */ + esp_zb_zcl_read_attr_cmd_t read_req; + read_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT; + read_req.zcl_basic_cmd.src_endpoint = _endpoint; + read_req.zcl_basic_cmd.dst_endpoint = endpoint; + read_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr; + read_req.clusterID = ESP_ZB_ZCL_CLUSTER_ID_BASIC; - uint16_t attributes[] = { + uint16_t attributes[] = { ESP_ZB_ZCL_ATTR_BASIC_MANUFACTURER_NAME_ID, - }; - read_req.attr_number = ZB_ARRAY_LENTH(attributes); - read_req.attr_field = attributes; + }; + read_req.attr_number = ZB_ARRAY_LENTH(attributes); + read_req.attr_field = attributes; + // clear read manufacturer + _read_manufacturer = nullptr; - // clear read manufacturer - _read_manufacturer = nullptr; - - esp_zb_zcl_read_attr_cmd_req(&read_req); - - //Wait for response or timeout - if(xSemaphoreTake(lock, portMAX_DELAY) != pdTRUE){ - log_e("Error while reading manufacturer"); - } - return _read_manufacturer; + esp_zb_zcl_read_attr_cmd_req(&read_req); + //Wait for response or timeout + if (xSemaphoreTake(lock, portMAX_DELAY) != pdTRUE) { + log_e("Error while reading manufacturer"); + } + return _read_manufacturer; } -char* ZigbeeEP::readModel(uint8_t endpoint, uint16_t short_addr) { - /* Read peer Manufacture Name & Model Identifier */ - esp_zb_zcl_read_attr_cmd_t read_req; - read_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT; - read_req.zcl_basic_cmd.src_endpoint = _endpoint; - read_req.zcl_basic_cmd.dst_endpoint = endpoint; - read_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr; - read_req.clusterID = ESP_ZB_ZCL_CLUSTER_ID_BASIC; +char *ZigbeeEP::readModel(uint8_t endpoint, uint16_t short_addr) { + /* Read peer Manufacture Name & Model Identifier */ + esp_zb_zcl_read_attr_cmd_t read_req; + read_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT; + read_req.zcl_basic_cmd.src_endpoint = _endpoint; + read_req.zcl_basic_cmd.dst_endpoint = endpoint; + read_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr; + read_req.clusterID = ESP_ZB_ZCL_CLUSTER_ID_BASIC; - uint16_t attributes[] = { + uint16_t attributes[] = { ESP_ZB_ZCL_ATTR_BASIC_MODEL_IDENTIFIER_ID, - }; - read_req.attr_number = ZB_ARRAY_LENTH(attributes); - read_req.attr_field = attributes; + }; + read_req.attr_number = ZB_ARRAY_LENTH(attributes); + read_req.attr_field = attributes; - // clear read model - _read_model = nullptr; + // clear read model + _read_model = nullptr; - esp_zb_zcl_read_attr_cmd_req(&read_req); + esp_zb_zcl_read_attr_cmd_req(&read_req); - //Wait for response or timeout - //Semaphore take - if(xSemaphoreTake(lock, portMAX_DELAY) != pdTRUE){ - log_e("Error while reading model"); - } - return _read_model; + //Wait for response or timeout + //Semaphore take + if (xSemaphoreTake(lock, portMAX_DELAY) != pdTRUE) { + log_e("Error while reading model"); + } + return _read_model; } void ZigbeeEP::printBoundDevices() { - log_i("Bound devices:"); - for( [[maybe_unused]] const auto& device : _bound_devices) { - log_i("Device on endpoint %d, short address: 0x%x", device->endpoint, device->short_addr); - print_ieee_addr(device->ieee_addr); - } + log_i("Bound devices:"); + for ([[maybe_unused]] + const auto &device : _bound_devices) { + log_i("Device on endpoint %d, short address: 0x%x", device->endpoint, device->short_addr); + print_ieee_addr(device->ieee_addr); + } } void ZigbeeEP::zbReadBasicCluster(const esp_zb_zcl_attribute_t *attribute) { - /* Basic cluster attributes */ - if (attribute->id == ESP_ZB_ZCL_ATTR_BASIC_MANUFACTURER_NAME_ID && attribute->data.type == ESP_ZB_ZCL_ATTR_TYPE_CHAR_STRING && attribute->data.value) { - zbstring_t *zbstr = (zbstring_t *)attribute->data.value; - char *string = (char *)malloc(zbstr->len + 1); - memcpy(string, zbstr->data, zbstr->len); - string[zbstr->len] = '\0'; - log_i("Peer Manufacturer is \"%s\"", string); - _read_manufacturer = string; - xSemaphoreGive(lock); - } - if (attribute->id == ESP_ZB_ZCL_ATTR_BASIC_MODEL_IDENTIFIER_ID && attribute->data.type == ESP_ZB_ZCL_ATTR_TYPE_CHAR_STRING && attribute->data.value) { - zbstring_t *zbstr = (zbstring_t *)attribute->data.value; - char *string = (char *)malloc(zbstr->len + 1); - memcpy(string, zbstr->data, zbstr->len); - string[zbstr->len] = '\0'; - log_i("Peer Model is \"%s\"", string); - _read_model = string; - xSemaphoreGive(lock); - } + /* Basic cluster attributes */ + if (attribute->id == ESP_ZB_ZCL_ATTR_BASIC_MANUFACTURER_NAME_ID && attribute->data.type == ESP_ZB_ZCL_ATTR_TYPE_CHAR_STRING && attribute->data.value) { + zbstring_t *zbstr = (zbstring_t *)attribute->data.value; + char *string = (char *)malloc(zbstr->len + 1); + memcpy(string, zbstr->data, zbstr->len); + string[zbstr->len] = '\0'; + log_i("Peer Manufacturer is \"%s\"", string); + _read_manufacturer = string; + xSemaphoreGive(lock); + } + if (attribute->id == ESP_ZB_ZCL_ATTR_BASIC_MODEL_IDENTIFIER_ID && attribute->data.type == ESP_ZB_ZCL_ATTR_TYPE_CHAR_STRING && attribute->data.value) { + zbstring_t *zbstr = (zbstring_t *)attribute->data.value; + char *string = (char *)malloc(zbstr->len + 1); + memcpy(string, zbstr->data, zbstr->len); + string[zbstr->len] = '\0'; + log_i("Peer Model is \"%s\"", string); + _read_model = string; + xSemaphoreGive(lock); + } } void ZigbeeEP::zbIdentify(const esp_zb_zcl_set_attr_value_message_t *message) { - if (message->attribute.id == ESP_ZB_ZCL_CMD_IDENTIFY_IDENTIFY_ID && message->attribute.data.type == ESP_ZB_ZCL_ATTR_TYPE_U16) { - _on_identify(*(uint16_t *)message->attribute.data.value); - } else { - log_w("Other identify commands are not implemented yet."); - } -} + if (message->attribute.id == ESP_ZB_ZCL_CMD_IDENTIFY_IDENTIFY_ID && message->attribute.data.type == ESP_ZB_ZCL_ATTR_TYPE_U16) { + _on_identify(*(uint16_t *)message->attribute.data.value); + } else { + log_w("Other identify commands are not implemented yet."); + } +} -#endif //SOC_IEEE802154_SUPPORTED +#endif //SOC_IEEE802154_SUPPORTED diff --git a/libraries/Zigbee/src/ZigbeeEP.h b/libraries/Zigbee/src/ZigbeeEP.h index cdd52fbcd78..beb045559b3 100644 --- a/libraries/Zigbee/src/ZigbeeEP.h +++ b/libraries/Zigbee/src/ZigbeeEP.h @@ -8,30 +8,36 @@ #include /* Usefull defines */ -#define ZB_ARRAY_LENTH(arr) (sizeof(arr)/ sizeof(arr[0])) -#define print_ieee_addr(addr) log_i("IEEE Address: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7]) -#define XYZ_TO_RGB(X, Y, Z, r, g, b) \ -{ \ - r = (float)( 3.240479*(X) -1.537150*(Y) -0.498535*(Z)); \ - g = (float)(-0.969256*(X) +1.875992*(Y) +0.041556*(Z)); \ - b = (float)( 0.055648*(X) -0.204043*(Y) +1.057311*(Z)); \ - if(r > 1){r = 1;} \ - if(g > 1){g = 1;} \ - if(b > 1){b = 1;} \ -} - -#define RGB_TO_XYZ(r, g, b, X, Y, Z) \ -{ \ - X = (float)(0.412453*(r) + 0.357580*(g) + 0.180423*(b)); \ - Y = (float)(0.212671*(r) + 0.715160*(g) + 0.072169*(b)); \ - Z = (float)(0.019334*(r) + 0.119193*(g) + 0.950227*(b)); \ -} +#define ZB_ARRAY_LENTH(arr) (sizeof(arr) / sizeof(arr[0])) +#define print_ieee_addr(addr) \ + log_i("IEEE Address: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7]) +#define XYZ_TO_RGB(X, Y, Z, r, g, b) \ + { \ + r = (float)(3.240479 * (X) - 1.537150 * (Y) - 0.498535 * (Z)); \ + g = (float)(-0.969256 * (X) + 1.875992 * (Y) + 0.041556 * (Z)); \ + b = (float)(0.055648 * (X) - 0.204043 * (Y) + 1.057311 * (Z)); \ + if (r > 1) { \ + r = 1; \ + } \ + if (g > 1) { \ + g = 1; \ + } \ + if (b > 1) { \ + b = 1; \ + } \ + } + +#define RGB_TO_XYZ(r, g, b, X, Y, Z) \ + { \ + X = (float)(0.412453 * (r) + 0.357580 * (g) + 0.180423 * (b)); \ + Y = (float)(0.212671 * (r) + 0.715160 * (g) + 0.072169 * (b)); \ + Z = (float)(0.019334 * (r) + 0.119193 * (g) + 0.950227 * (b)); \ + } typedef struct zbstring_s { - uint8_t len; - char data[]; -} ESP_ZB_PACKED_STRUCT -zbstring_t; + uint8_t len; + char data[]; +} ESP_ZB_PACKED_STRUCT zbstring_t; typedef struct zb_device_params_s { esp_zb_ieee_addr_t ieee_addr; @@ -40,67 +46,79 @@ typedef struct zb_device_params_s { } zb_device_params_t; typedef enum { - SINGLE_COLOR = 0, - RGB = 1 + SINGLE_COLOR = 0, + RGB = 1 } zb_identify_led_type_t; /* Zigbee End Device Class */ class ZigbeeEP { - public: - ZigbeeEP(uint8_t endpoint = 10); - ~ZigbeeEP(); - - // Set ep config and cluster list - void setEpConfig(esp_zb_endpoint_config_t ep_config, esp_zb_cluster_list_t *cluster_list) { - _ep_config = ep_config; - _cluster_list = cluster_list; - } - - void setVersion(uint8_t version); - uint8_t getEndpoint() { return _endpoint; } - - void printBoundDevices(); - std::list getBoundDevices() const { return _bound_devices;} - - static bool isBound() { return _is_bound; } - static void allowMultipleBinding(bool bind) { _allow_multiple_binding = bind; } - - // Manufacturer name and model implemented - void setManufacturerAndModel(const char *name, const char *model); - - // Methods to read manufacturer and model name from selected endpoint and short address - char* readManufacturer(uint8_t endpoint, uint16_t short_addr); - char* readModel(uint8_t endpoint, uint16_t short_addr); - - bool epAllowMultipleBinding() { return _allow_multiple_binding; } - - // findEndpoind may be implemented by EPs to find and bind devices - virtual void findEndpoint(esp_zb_zdo_match_desc_req_param_t *cmd_req) {}; - - //list of all handlers function calls, to be overide by EPs implementation - virtual void zbAttributeSet(const esp_zb_zcl_set_attr_value_message_t *message) {}; - virtual void zbAttributeRead(uint16_t cluster_id, const esp_zb_zcl_attribute_t *attribute) {}; - virtual void zbReadBasicCluster(const esp_zb_zcl_attribute_t *attribute); //already implemented - virtual void zbIdentify(const esp_zb_zcl_set_attr_value_message_t *message); - - void onIdentify(void (*callback)(uint16_t)) { _on_identify = callback; } - - private: - static bool _allow_multiple_binding; - char* _read_manufacturer; - char* _read_model; - void (*_on_identify)(uint16_t time); - - protected: - static uint8_t _endpoint; - esp_zb_ha_standard_devices_t _device_id; - esp_zb_endpoint_config_t _ep_config; - esp_zb_cluster_list_t *_cluster_list; - static bool _is_bound; - std::list _bound_devices; - SemaphoreHandle_t lock; +public: + ZigbeeEP(uint8_t endpoint = 10); + ~ZigbeeEP(); + + // Set ep config and cluster list + void setEpConfig(esp_zb_endpoint_config_t ep_config, esp_zb_cluster_list_t *cluster_list) { + _ep_config = ep_config; + _cluster_list = cluster_list; + } + + void setVersion(uint8_t version); + uint8_t getEndpoint() { + return _endpoint; + } + + void printBoundDevices(); + std::list getBoundDevices() const { + return _bound_devices; + } + + static bool isBound() { + return _is_bound; + } + static void allowMultipleBinding(bool bind) { + _allow_multiple_binding = bind; + } + + // Manufacturer name and model implemented + void setManufacturerAndModel(const char *name, const char *model); + + // Methods to read manufacturer and model name from selected endpoint and short address + char *readManufacturer(uint8_t endpoint, uint16_t short_addr); + char *readModel(uint8_t endpoint, uint16_t short_addr); + + bool epAllowMultipleBinding() { + return _allow_multiple_binding; + } + + // findEndpoind may be implemented by EPs to find and bind devices + virtual void findEndpoint(esp_zb_zdo_match_desc_req_param_t *cmd_req) {}; + + //list of all handlers function calls, to be overide by EPs implementation + virtual void zbAttributeSet(const esp_zb_zcl_set_attr_value_message_t *message) {}; + virtual void zbAttributeRead(uint16_t cluster_id, const esp_zb_zcl_attribute_t *attribute) {}; + virtual void zbReadBasicCluster(const esp_zb_zcl_attribute_t *attribute); //already implemented + virtual void zbIdentify(const esp_zb_zcl_set_attr_value_message_t *message); + + void onIdentify(void (*callback)(uint16_t)) { + _on_identify = callback; + } + +private: + static bool _allow_multiple_binding; + char *_read_manufacturer; + char *_read_model; + void (*_on_identify)(uint16_t time); + +protected: + static uint8_t _endpoint; + esp_zb_ha_standard_devices_t _device_id; + esp_zb_endpoint_config_t _ep_config; + esp_zb_cluster_list_t *_cluster_list; + static bool _is_bound; + std::list _bound_devices; + SemaphoreHandle_t lock; friend class ZigbeeCore; }; -#endif //SOC_IEEE802154_SUPPORTED +#endif //SOC_IEEE802154_SUPPORTED diff --git a/libraries/Zigbee/src/ZigbeeHandlers.cpp b/libraries/Zigbee/src/ZigbeeHandlers.cpp index 692103709c8..9522b0ba1a8 100644 --- a/libraries/Zigbee/src/ZigbeeHandlers.cpp +++ b/libraries/Zigbee/src/ZigbeeHandlers.cpp @@ -12,15 +12,16 @@ static esp_err_t zb_configure_report_resp_handler(const esp_zb_zcl_cmd_config_re static esp_err_t zb_cmd_default_resp_handler(const esp_zb_zcl_cmd_default_resp_message_t *message); // Zigbee action handlers -[[maybe_unused]] static esp_err_t zb_action_handler(esp_zb_core_action_callback_id_t callback_id, const void *message) { +[[maybe_unused]] +static esp_err_t zb_action_handler(esp_zb_core_action_callback_id_t callback_id, const void *message) { esp_err_t ret = ESP_OK; switch (callback_id) { - case ESP_ZB_CORE_SET_ATTR_VALUE_CB_ID: ret = zb_attribute_set_handler((esp_zb_zcl_set_attr_value_message_t *)message); break; - case ESP_ZB_CORE_REPORT_ATTR_CB_ID: ret = zb_attribute_reporting_handler((esp_zb_zcl_report_attr_message_t *)message); break; - case ESP_ZB_CORE_CMD_READ_ATTR_RESP_CB_ID: ret = zb_cmd_read_attr_resp_handler((esp_zb_zcl_cmd_read_attr_resp_message_t *)message); break; - case ESP_ZB_CORE_CMD_REPORT_CONFIG_RESP_CB_ID: ret = zb_configure_report_resp_handler((esp_zb_zcl_cmd_config_report_resp_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; + case ESP_ZB_CORE_SET_ATTR_VALUE_CB_ID: ret = zb_attribute_set_handler((esp_zb_zcl_set_attr_value_message_t *)message); break; + case ESP_ZB_CORE_REPORT_ATTR_CB_ID: ret = zb_attribute_reporting_handler((esp_zb_zcl_report_attr_message_t *)message); break; + case ESP_ZB_CORE_CMD_READ_ATTR_RESP_CB_ID: ret = zb_cmd_read_attr_resp_handler((esp_zb_zcl_cmd_read_attr_resp_message_t *)message); break; + case ESP_ZB_CORE_CMD_REPORT_CONFIG_RESP_CB_ID: ret = zb_configure_report_resp_handler((esp_zb_zcl_cmd_config_report_resp_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; } return ret; } @@ -39,13 +40,12 @@ static esp_err_t zb_attribute_set_handler(const esp_zb_zcl_set_attr_value_messag ); // List through all Zigbee EPs and call the callback function, with the message - for (std::list::iterator it = Zigbee.ep_objects.begin(); it != Zigbee.ep_objects.end(); ++it) { - if (message->info.dst_endpoint == (*it)->getEndpoint()){ - if(message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_IDENTIFY){ - (*it)->zbIdentify(message); //method zbIdentify implemented in the common EP class - } - else { - (*it)->zbAttributeSet(message); //method zbAttributeSet must be implemented in specific EP class + for (std::list::iterator it = Zigbee.ep_objects.begin(); it != Zigbee.ep_objects.end(); ++it) { + if (message->info.dst_endpoint == (*it)->getEndpoint()) { + if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_IDENTIFY) { + (*it)->zbIdentify(message); //method zbIdentify implemented in the common EP class + } else { + (*it)->zbAttributeSet(message); //method zbAttributeSet must be implemented in specific EP class } } } @@ -63,10 +63,10 @@ static esp_err_t zb_attribute_reporting_handler(const esp_zb_zcl_report_attr_mes "Received report from address(0x%x) src endpoint(%d) to dst endpoint(%d) cluster(0x%x)", message->src_address.u.short_addr, message->src_endpoint, message->dst_endpoint, message->cluster ); - // List through all Zigbee EPs and call the callback function, with the message - for (std::list::iterator it = Zigbee.ep_objects.begin(); it != Zigbee.ep_objects.end(); ++it) { + // List through all Zigbee EPs and call the callback function, with the message + for (std::list::iterator it = Zigbee.ep_objects.begin(); it != Zigbee.ep_objects.end(); ++it) { if (message->dst_endpoint == (*it)->getEndpoint()) { - (*it)->zbAttributeRead(message->cluster, &message->attribute); //method zbAttributeRead must be implemented in specific EP class + (*it)->zbAttributeRead(message->cluster, &message->attribute); //method zbAttributeRead must be implemented in specific EP class } } return ESP_OK; @@ -84,7 +84,7 @@ static esp_err_t zb_cmd_read_attr_resp_handler(const esp_zb_zcl_cmd_read_attr_re message->info.src_endpoint, message->info.dst_endpoint, message->info.cluster ); - for (std::list::iterator it = Zigbee.ep_objects.begin(); it != Zigbee.ep_objects.end(); ++it) { + for (std::list::iterator it = Zigbee.ep_objects.begin(); it != Zigbee.ep_objects.end(); ++it) { if (message->info.dst_endpoint == (*it)->getEndpoint()) { esp_zb_zcl_read_attr_resp_variable_t *variable = message->variables; while (variable) { @@ -94,10 +94,9 @@ static esp_err_t zb_cmd_read_attr_resp_handler(const esp_zb_zcl_cmd_read_attr_re ); if (variable->status == ESP_ZB_ZCL_STATUS_SUCCESS) { if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_BASIC) { - (*it)->zbReadBasicCluster(&variable->attribute); //method zbReadBasicCluster implemented in the common EP class - } - else { - (*it)->zbAttributeRead(message->info.cluster, &variable->attribute); //method zbAttributeRead must be implemented in specific EP class + (*it)->zbReadBasicCluster(&variable->attribute); //method zbReadBasicCluster implemented in the common EP class + } else { + (*it)->zbAttributeRead(message->info.cluster, &variable->attribute); //method zbAttributeRead must be implemented in specific EP class } } variable = variable->next; @@ -133,10 +132,10 @@ static esp_err_t zb_cmd_default_resp_handler(const esp_zb_zcl_cmd_default_resp_m log_e("Received message: error status(%d)", message->info.status); } log_v( - "Received default response: from address(0x%x), src_endpoint(%d) to dst_endpoint(%d), cluster(0x%x) with status 0x%x", message->info.src_address.u.short_addr, - message->info.src_endpoint, message->info.dst_endpoint, message->info.cluster, message->status_code + "Received default response: from address(0x%x), src_endpoint(%d) to dst_endpoint(%d), cluster(0x%x) with status 0x%x", + message->info.src_address.u.short_addr, message->info.src_endpoint, message->info.dst_endpoint, message->info.cluster, message->status_code ); return ESP_OK; } -#endif //SOC_IEEE802154_SUPPORTED +#endif //SOC_IEEE802154_SUPPORTED diff --git a/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.cpp b/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.cpp index 745b022ea82..b823d3879d1 100644 --- a/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.cpp @@ -2,115 +2,111 @@ #if SOC_IEEE802154_SUPPORTED ZigbeeColorDimmableLight::ZigbeeColorDimmableLight(uint8_t endpoint) : ZigbeeEP(endpoint) { - _device_id = ESP_ZB_HA_COLOR_DIMMABLE_LIGHT_DEVICE_ID; + _device_id = ESP_ZB_HA_COLOR_DIMMABLE_LIGHT_DEVICE_ID; - esp_zb_color_dimmable_light_cfg_t light_cfg = ESP_ZB_DEFAULT_COLOR_DIMMABLE_LIGHT_CONFIG(); - _cluster_list = esp_zb_color_dimmable_light_clusters_create(&light_cfg); - _ep_config = { - .endpoint = _endpoint, - .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, - .app_device_id = ESP_ZB_HA_COLOR_DIMMABLE_LIGHT_DEVICE_ID, - .app_device_version = 0 - }; + esp_zb_color_dimmable_light_cfg_t light_cfg = ESP_ZB_DEFAULT_COLOR_DIMMABLE_LIGHT_CONFIG(); + _cluster_list = esp_zb_color_dimmable_light_clusters_create(&light_cfg); + _ep_config = { + .endpoint = _endpoint, .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, .app_device_id = ESP_ZB_HA_COLOR_DIMMABLE_LIGHT_DEVICE_ID, .app_device_version = 0 + }; - //set default values - _current_state = false; - _current_level = 255; - _current_red = 255; - _current_green = 255; - _current_blue = 255; + //set default values + _current_state = false; + _current_level = 255; + _current_red = 255; + _current_green = 255; + _current_blue = 255; } -uint16_t ZigbeeColorDimmableLight::getCurrentColorX(){ - return (*(uint16_t *)esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_X_ID)->data_p); +uint16_t ZigbeeColorDimmableLight::getCurrentColorX() { + return (*(uint16_t *)esp_zb_zcl_get_attribute( + _endpoint, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_X_ID + ) + ->data_p); } -uint16_t ZigbeeColorDimmableLight::getCurrentColorY(){ - return (*(uint16_t *)esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_Y_ID)->data_p); +uint16_t ZigbeeColorDimmableLight::getCurrentColorY() { + return (*(uint16_t *)esp_zb_zcl_get_attribute( + _endpoint, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_Y_ID + ) + ->data_p); } -void ZigbeeColorDimmableLight::calculateRGB( uint16_t x, uint16_t y, uint8_t &red, uint8_t &green, uint8_t &blue){ - float r, g, b, color_x, color_y; - color_x = (float)x / 65535; - color_y = (float)y / 65535; - - float color_X = color_x / color_y; - float color_Z = (1 - color_x - color_y) / color_y; +void ZigbeeColorDimmableLight::calculateRGB(uint16_t x, uint16_t y, uint8_t &red, uint8_t &green, uint8_t &blue) { + float r, g, b, color_x, color_y; + color_x = (float)x / 65535; + color_y = (float)y / 65535; - XYZ_TO_RGB(color_X, 1, color_Z, r, g, b); + float color_X = color_x / color_y; + float color_Z = (1 - color_x - color_y) / color_y; - red = (uint8_t)(r * (float)255); - green = (uint8_t)(g * (float)255); - blue = (uint8_t)(b * (float)255); + XYZ_TO_RGB(color_X, 1, color_Z, r, g, b); + + red = (uint8_t)(r * (float)255); + green = (uint8_t)(g * (float)255); + blue = (uint8_t)(b * (float)255); } //set attribude method -> methon overriden in child class void ZigbeeColorDimmableLight::zbAttributeSet(const esp_zb_zcl_set_attr_value_message_t *message) { - //check the data and call right method - if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_ON_OFF) { - if (message->attribute.id == ESP_ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID && message->attribute.data.type == ESP_ZB_ZCL_ATTR_TYPE_BOOL) { - if(_current_state != *(bool *)message->attribute.data.value) { - _current_state = *(bool *)message->attribute.data.value; - lightChanged(); - } - return; - } - else { - log_w("Recieved message ignored. Attribute ID: %d not supported for On/Off Light", message->attribute.id); - } + //check the data and call right method + if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_ON_OFF) { + if (message->attribute.id == ESP_ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID && message->attribute.data.type == ESP_ZB_ZCL_ATTR_TYPE_BOOL) { + if (_current_state != *(bool *)message->attribute.data.value) { + _current_state = *(bool *)message->attribute.data.value; + lightChanged(); + } + return; + } else { + log_w("Recieved message ignored. Attribute ID: %d not supported for On/Off Light", message->attribute.id); } - else if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_LEVEL_CONTROL) { - if (message->attribute.id == ESP_ZB_ZCL_ATTR_LEVEL_CONTROL_CURRENT_LEVEL_ID && message->attribute.data.type == ESP_ZB_ZCL_ATTR_TYPE_U8) { - if (_current_level != *(uint8_t *)message->attribute.data.value) { - _current_level = *(uint8_t *)message->attribute.data.value; - lightChanged(); - } - return; - } - else { - log_w("Recieved message ignored. Attribute ID: %d not supported for Level Control", message->attribute.id); - //TODO: implement more attributes -> includes/zcl/esp_zigbee_zcl_level.h - } + } else if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_LEVEL_CONTROL) { + if (message->attribute.id == ESP_ZB_ZCL_ATTR_LEVEL_CONTROL_CURRENT_LEVEL_ID && message->attribute.data.type == ESP_ZB_ZCL_ATTR_TYPE_U8) { + if (_current_level != *(uint8_t *)message->attribute.data.value) { + _current_level = *(uint8_t *)message->attribute.data.value; + lightChanged(); + } + return; + } else { + log_w("Recieved message ignored. Attribute ID: %d not supported for Level Control", message->attribute.id); + //TODO: implement more attributes -> includes/zcl/esp_zigbee_zcl_level.h } - else if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL) { - if (message->attribute.id == ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_X_ID && message->attribute.data.type == ESP_ZB_ZCL_ATTR_TYPE_U16) { - uint16_t light_color_x = (*(uint16_t *)message->attribute.data.value); - uint16_t light_color_y = getCurrentColorY(); - //calculate RGB from XY and call setColor() - uint8_t red, green, blue; - calculateRGB(light_color_x, light_color_y, red, green, blue); - _current_blue = blue; - _current_green = green; - _current_red = red; - lightChanged(); - return; + } else if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL) { + if (message->attribute.id == ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_X_ID && message->attribute.data.type == ESP_ZB_ZCL_ATTR_TYPE_U16) { + uint16_t light_color_x = (*(uint16_t *)message->attribute.data.value); + uint16_t light_color_y = getCurrentColorY(); + //calculate RGB from XY and call setColor() + uint8_t red, green, blue; + calculateRGB(light_color_x, light_color_y, red, green, blue); + _current_blue = blue; + _current_green = green; + _current_red = red; + lightChanged(); + return; - } - else if (message->attribute.id == ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_Y_ID && message->attribute.data.type == ESP_ZB_ZCL_ATTR_TYPE_U16) { - uint16_t light_color_x = getCurrentColorX(); - uint16_t light_color_y = (*(uint16_t *)message->attribute.data.value); - //calculate RGB from XY and call setColor() - uint8_t red, green, blue; - calculateRGB(light_color_x, light_color_y, red, green, blue); - _current_blue = blue; - _current_green = green; - _current_red = red; - lightChanged(); - return; - } - else { - log_w("Recieved message ignored. Attribute ID: %d not supported for Color Control", message->attribute.id); - } - } - else { - log_w("Recieved message ignored. Cluster ID: %d not supported for Color dimmable Light", message->info.cluster); + } else if (message->attribute.id == ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_Y_ID && message->attribute.data.type == ESP_ZB_ZCL_ATTR_TYPE_U16) { + uint16_t light_color_x = getCurrentColorX(); + uint16_t light_color_y = (*(uint16_t *)message->attribute.data.value); + //calculate RGB from XY and call setColor() + uint8_t red, green, blue; + calculateRGB(light_color_x, light_color_y, red, green, blue); + _current_blue = blue; + _current_green = green; + _current_red = red; + lightChanged(); + return; + } else { + log_w("Recieved message ignored. Attribute ID: %d not supported for Color Control", message->attribute.id); } + } else { + log_w("Recieved message ignored. Cluster ID: %d not supported for Color dimmable Light", message->info.cluster); + } } void ZigbeeColorDimmableLight::lightChanged() { - if(_on_light_change) { - _on_light_change(_current_state, _current_red, _current_green, _current_blue, _current_level); - } + if (_on_light_change) { + _on_light_change(_current_state, _current_red, _current_green, _current_blue, _current_level); + } } -#endif //SOC_IEEE802154_SUPPORTED +#endif //SOC_IEEE802154_SUPPORTED diff --git a/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.h b/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.h index b46aff75bee..992c2573654 100644 --- a/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.h +++ b/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.h @@ -9,29 +9,33 @@ #include "ha/esp_zigbee_ha_standard.h" class ZigbeeColorDimmableLight : public ZigbeeEP { - public: - ZigbeeColorDimmableLight(uint8_t endpoint); - ~ZigbeeColorDimmableLight(); - - void onLightChange(void (*callback)(bool, uint8_t, uint8_t, uint8_t, uint8_t)) { _on_light_change = callback; } - void restoreLight() { lightChanged(); } - - private: - void zbAttributeSet(const esp_zb_zcl_set_attr_value_message_t *message) override; - void calculateRGB(uint16_t x, uint16_t y, uint8_t &red, uint8_t &green, uint8_t &blue); - - uint16_t getCurrentColorX(); - uint16_t getCurrentColorY(); - - void lightChanged(); - //callback function to be called on light change (State, R, G, B, Level) - void (*_on_light_change)(bool, uint8_t, uint8_t, uint8_t, uint8_t); - - bool _current_state; - uint8_t _current_level; - uint16_t _current_red; - uint16_t _current_green; - uint16_t _current_blue; +public: + ZigbeeColorDimmableLight(uint8_t endpoint); + ~ZigbeeColorDimmableLight(); + + void onLightChange(void (*callback)(bool, uint8_t, uint8_t, uint8_t, uint8_t)) { + _on_light_change = callback; + } + void restoreLight() { + lightChanged(); + } + +private: + void zbAttributeSet(const esp_zb_zcl_set_attr_value_message_t *message) override; + void calculateRGB(uint16_t x, uint16_t y, uint8_t &red, uint8_t &green, uint8_t &blue); + + uint16_t getCurrentColorX(); + uint16_t getCurrentColorY(); + + void lightChanged(); + //callback function to be called on light change (State, R, G, B, Level) + void (*_on_light_change)(bool, uint8_t, uint8_t, uint8_t, uint8_t); + + bool _current_state; + uint8_t _current_level; + uint16_t _current_red; + uint16_t _current_green; + uint16_t _current_blue; }; -#endif //SOC_IEEE802154_SUPPORTED +#endif //SOC_IEEE802154_SUPPORTED diff --git a/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.cpp b/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.cpp index 76a97d8e84c..c30599aadac 100644 --- a/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.cpp @@ -2,405 +2,402 @@ #if SOC_IEEE802154_SUPPORTED // Initialize the static instance pointer -ZigbeeColorDimmerSwitch* ZigbeeColorDimmerSwitch::_instance = nullptr; +ZigbeeColorDimmerSwitch *ZigbeeColorDimmerSwitch::_instance = nullptr; ZigbeeColorDimmerSwitch::ZigbeeColorDimmerSwitch(uint8_t endpoint) : ZigbeeEP(endpoint) { - _device_id = ESP_ZB_HA_COLOR_DIMMER_SWITCH_DEVICE_ID; - _instance = this; // Set the static pointer to this instance - - esp_zb_color_dimmable_switch_cfg_t switch_cfg = ESP_ZB_DEFAULT_COLOR_DIMMABLE_SWITCH_CONFIG(); - _cluster_list = esp_zb_color_dimmable_switch_clusters_create(&switch_cfg); - - _ep_config = { - .endpoint = _endpoint, - .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, - .app_device_id = ESP_ZB_HA_COLOR_DIMMER_SWITCH_DEVICE_ID, - .app_device_version = 0 - }; + _device_id = ESP_ZB_HA_COLOR_DIMMER_SWITCH_DEVICE_ID; + _instance = this; // Set the static pointer to this instance + + esp_zb_color_dimmable_switch_cfg_t switch_cfg = ESP_ZB_DEFAULT_COLOR_DIMMABLE_SWITCH_CONFIG(); + _cluster_list = esp_zb_color_dimmable_switch_clusters_create(&switch_cfg); + + _ep_config = { + .endpoint = _endpoint, .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, .app_device_id = ESP_ZB_HA_COLOR_DIMMER_SWITCH_DEVICE_ID, .app_device_version = 0 + }; } void ZigbeeColorDimmerSwitch::calculateXY(uint8_t red, uint8_t green, uint8_t blue, uint16_t &x, uint16_t &y) { - // Convert RGB to XYZ - float r = (float)red / 255.0f; - float g = (float)green / 255.0f; - float b = (float)blue / 255.0f; + // Convert RGB to XYZ + float r = (float)red / 255.0f; + float g = (float)green / 255.0f; + float b = (float)blue / 255.0f; - float X, Y, Z; - RGB_TO_XYZ(r, g, b, X, Y, Z); + float X, Y, Z; + RGB_TO_XYZ(r, g, b, X, Y, Z); - // Convert XYZ to xy chromaticity coordinates - float color_x = X / (X + Y + Z); - float color_y = Y / (X + Y + Z); + // Convert XYZ to xy chromaticity coordinates + float color_x = X / (X + Y + Z); + float color_y = Y / (X + Y + Z); - // Convert normalized xy to 16-bit values - x = (uint16_t)(color_x * 65535.0f); - y = (uint16_t)(color_y * 65535.0f); + // Convert normalized xy to 16-bit values + x = (uint16_t)(color_x * 65535.0f); + y = (uint16_t)(color_y * 65535.0f); } void ZigbeeColorDimmerSwitch::bindCb(esp_zb_zdp_status_t zdo_status, void *user_ctx) { - if (zdo_status == ESP_ZB_ZDP_STATUS_SUCCESS) { - log_i("Bound successfully!"); - if (user_ctx) { - zb_device_params_t *light = (zb_device_params_t *)user_ctx; - log_i("The light originating from address(0x%x) on endpoint(%d)", light->short_addr, light->endpoint); - _instance->_bound_devices.push_back(light); - } - _is_bound = true; - } else { - log_e("Binding failed!"); + if (zdo_status == ESP_ZB_ZDP_STATUS_SUCCESS) { + log_i("Bound successfully!"); + if (user_ctx) { + zb_device_params_t *light = (zb_device_params_t *)user_ctx; + log_i("The light originating from address(0x%x) on endpoint(%d)", light->short_addr, light->endpoint); + _instance->_bound_devices.push_back(light); } + _is_bound = true; + } else { + log_e("Binding failed!"); + } } void ZigbeeColorDimmerSwitch::findCb(esp_zb_zdp_status_t zdo_status, uint16_t addr, uint8_t endpoint, void *user_ctx) { - if (zdo_status == ESP_ZB_ZDP_STATUS_SUCCESS) { - log_d("Found light endpoint"); - esp_zb_zdo_bind_req_param_t bind_req; - zb_device_params_t *light = (zb_device_params_t *)malloc(sizeof(zb_device_params_t)); - light->endpoint = endpoint; - light->short_addr = addr; - esp_zb_ieee_address_by_short(light->short_addr, light->ieee_addr); - esp_zb_get_long_address(bind_req.src_address); - bind_req.src_endp = _endpoint; - bind_req.cluster_id = ESP_ZB_ZCL_CLUSTER_ID_ON_OFF; - bind_req.dst_addr_mode = ESP_ZB_ZDO_BIND_DST_ADDR_MODE_64_BIT_EXTENDED; - memcpy(bind_req.dst_address_u.addr_long, light->ieee_addr, sizeof(esp_zb_ieee_addr_t)); - bind_req.dst_endp = endpoint; - bind_req.req_dst_addr = esp_zb_get_short_address(); - log_v("Try to bind on/off control of dimmable light"); - esp_zb_zdo_device_bind_req(&bind_req, bindCb, NULL); - bind_req.cluster_id = ESP_ZB_ZCL_CLUSTER_ID_LEVEL_CONTROL; - log_v("Try to bind level control of dimmable light"); - esp_zb_zdo_device_bind_req(&bind_req, bindCb, NULL); - bind_req.cluster_id = ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL; - log_v("Try to bind color control of dimmable light"); - esp_zb_zdo_device_bind_req(&bind_req, bindCb, (void *)light); - } else { - log_v("No color dimmable light endpoint found"); - } + if (zdo_status == ESP_ZB_ZDP_STATUS_SUCCESS) { + log_d("Found light endpoint"); + esp_zb_zdo_bind_req_param_t bind_req; + zb_device_params_t *light = (zb_device_params_t *)malloc(sizeof(zb_device_params_t)); + light->endpoint = endpoint; + light->short_addr = addr; + esp_zb_ieee_address_by_short(light->short_addr, light->ieee_addr); + esp_zb_get_long_address(bind_req.src_address); + bind_req.src_endp = _endpoint; + bind_req.cluster_id = ESP_ZB_ZCL_CLUSTER_ID_ON_OFF; + bind_req.dst_addr_mode = ESP_ZB_ZDO_BIND_DST_ADDR_MODE_64_BIT_EXTENDED; + memcpy(bind_req.dst_address_u.addr_long, light->ieee_addr, sizeof(esp_zb_ieee_addr_t)); + bind_req.dst_endp = endpoint; + bind_req.req_dst_addr = esp_zb_get_short_address(); + log_v("Try to bind on/off control of dimmable light"); + esp_zb_zdo_device_bind_req(&bind_req, bindCb, NULL); + bind_req.cluster_id = ESP_ZB_ZCL_CLUSTER_ID_LEVEL_CONTROL; + log_v("Try to bind level control of dimmable light"); + esp_zb_zdo_device_bind_req(&bind_req, bindCb, NULL); + bind_req.cluster_id = ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL; + log_v("Try to bind color control of dimmable light"); + esp_zb_zdo_device_bind_req(&bind_req, bindCb, (void *)light); + } else { + log_v("No color dimmable light endpoint found"); + } } // find on_off light endpoint void ZigbeeColorDimmerSwitch::findEndpoint(esp_zb_zdo_match_desc_req_param_t *cmd_req) { - uint16_t cluster_list[] = {ESP_ZB_ZCL_CLUSTER_ID_ON_OFF, ESP_ZB_ZCL_CLUSTER_ID_LEVEL_CONTROL, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, - ESP_ZB_ZCL_CLUSTER_ID_ON_OFF, ESP_ZB_ZCL_CLUSTER_ID_LEVEL_CONTROL, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL}; - esp_zb_zdo_match_desc_req_param_t color_dimmable_light_req = { - .dst_nwk_addr = cmd_req->dst_nwk_addr, - .addr_of_interest = cmd_req->addr_of_interest, - .profile_id = ESP_ZB_AF_HA_PROFILE_ID, - .num_in_clusters = 3, - .num_out_clusters = 3, - .cluster_list = cluster_list, - }; - esp_zb_zdo_match_cluster(&color_dimmable_light_req, findCb, NULL); + uint16_t cluster_list[] = {ESP_ZB_ZCL_CLUSTER_ID_ON_OFF, ESP_ZB_ZCL_CLUSTER_ID_LEVEL_CONTROL, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, + ESP_ZB_ZCL_CLUSTER_ID_ON_OFF, ESP_ZB_ZCL_CLUSTER_ID_LEVEL_CONTROL, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL}; + esp_zb_zdo_match_desc_req_param_t color_dimmable_light_req = { + .dst_nwk_addr = cmd_req->dst_nwk_addr, + .addr_of_interest = cmd_req->addr_of_interest, + .profile_id = ESP_ZB_AF_HA_PROFILE_ID, + .num_in_clusters = 3, + .num_out_clusters = 3, + .cluster_list = cluster_list, + }; + esp_zb_zdo_match_cluster(&color_dimmable_light_req, findCb, NULL); } // Methods to control the light void ZigbeeColorDimmerSwitch::lightToggle() { - if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req; - cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; - cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; - cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_TOGGLE_ID; - log_i("Sending 'light toggle' command"); - //esp_zb_lock_acquire(portMAX_DELAY); - esp_zb_zcl_on_off_cmd_req(&cmd_req); - //esp_zb_lock_release(); - } else { - log_e("Light not bound"); - } + if (_is_bound) { + esp_zb_zcl_on_off_cmd_t cmd_req; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; + cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_TOGGLE_ID; + log_i("Sending 'light toggle' command"); + //esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_on_off_cmd_req(&cmd_req); + //esp_zb_lock_release(); + } else { + log_e("Light not bound"); + } } void ZigbeeColorDimmerSwitch::lightToggle(uint16_t group_addr) { - if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req; - cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; - cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr; - cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT; - cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_TOGGLE_ID; - log_i("Sending 'light toggle' command to group address 0x%x", group_addr); - esp_zb_lock_acquire(portMAX_DELAY); - esp_zb_zcl_on_off_cmd_req(&cmd_req); - esp_zb_lock_release(); - } else { - log_e("Light not bound"); - } + if (_is_bound) { + esp_zb_zcl_on_off_cmd_t cmd_req; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr; + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT; + cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_TOGGLE_ID; + log_i("Sending 'light toggle' command to group address 0x%x", group_addr); + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_on_off_cmd_req(&cmd_req); + esp_zb_lock_release(); + } else { + log_e("Light not bound"); + } } void ZigbeeColorDimmerSwitch::lightToggle(uint8_t endpoint, uint16_t short_addr) { - if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req; - cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; - cmd_req.zcl_basic_cmd.dst_endpoint = endpoint; - cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr; - cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT; - cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_TOGGLE_ID; - log_i("Sending 'light toggle' command to endpoint %d, address 0x%x", endpoint, short_addr); - esp_zb_lock_acquire(portMAX_DELAY); - esp_zb_zcl_on_off_cmd_req(&cmd_req); - esp_zb_lock_release(); - } else { - log_e("Light not bound"); - } + if (_is_bound) { + esp_zb_zcl_on_off_cmd_t cmd_req; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.zcl_basic_cmd.dst_endpoint = endpoint; + cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr; + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT; + cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_TOGGLE_ID; + log_i("Sending 'light toggle' command to endpoint %d, address 0x%x", endpoint, short_addr); + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_on_off_cmd_req(&cmd_req); + esp_zb_lock_release(); + } else { + log_e("Light not bound"); + } } void ZigbeeColorDimmerSwitch::lightOn() { - if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req; - cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; - cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; - cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_ON_ID; - log_i("Sending 'light on' command"); - esp_zb_lock_acquire(portMAX_DELAY); - esp_zb_zcl_on_off_cmd_req(&cmd_req); - esp_zb_lock_release(); - } else { - log_e("Light not bound"); - } + if (_is_bound) { + esp_zb_zcl_on_off_cmd_t cmd_req; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; + cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_ON_ID; + log_i("Sending 'light on' command"); + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_on_off_cmd_req(&cmd_req); + esp_zb_lock_release(); + } else { + log_e("Light not bound"); + } } void ZigbeeColorDimmerSwitch::lightOn(uint16_t group_addr) { - if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req; - cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; - cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr; - cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT; - cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_ON_ID; - log_i("Sending 'light on' command to group address 0x%x", group_addr); - esp_zb_lock_acquire(portMAX_DELAY); - esp_zb_zcl_on_off_cmd_req(&cmd_req); - esp_zb_lock_release(); - } else { - log_e("Light not bound"); - } + if (_is_bound) { + esp_zb_zcl_on_off_cmd_t cmd_req; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr; + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT; + cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_ON_ID; + log_i("Sending 'light on' command to group address 0x%x", group_addr); + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_on_off_cmd_req(&cmd_req); + esp_zb_lock_release(); + } else { + log_e("Light not bound"); + } } void ZigbeeColorDimmerSwitch::lightOn(uint8_t endpoint, uint16_t short_addr) { - if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req; - cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; - cmd_req.zcl_basic_cmd.dst_endpoint = endpoint; - cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr; - cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT; - cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_ON_ID; - log_i("Sending 'light on' command to endpoint %d, address 0x%x", endpoint, short_addr); - esp_zb_lock_acquire(portMAX_DELAY); - esp_zb_zcl_on_off_cmd_req(&cmd_req); - esp_zb_lock_release(); - } else { - log_e("Light not bound"); - } + if (_is_bound) { + esp_zb_zcl_on_off_cmd_t cmd_req; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.zcl_basic_cmd.dst_endpoint = endpoint; + cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr; + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT; + cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_ON_ID; + log_i("Sending 'light on' command to endpoint %d, address 0x%x", endpoint, short_addr); + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_on_off_cmd_req(&cmd_req); + esp_zb_lock_release(); + } else { + log_e("Light not bound"); + } } void ZigbeeColorDimmerSwitch::lightOff() { - if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req; - cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; - cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; - cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_OFF_ID; - log_i("Sending 'light off' command"); - esp_zb_lock_acquire(portMAX_DELAY); - esp_zb_zcl_on_off_cmd_req(&cmd_req); - esp_zb_lock_release(); - } else { - log_e("Light not bound"); - } + if (_is_bound) { + esp_zb_zcl_on_off_cmd_t cmd_req; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; + cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_OFF_ID; + log_i("Sending 'light off' command"); + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_on_off_cmd_req(&cmd_req); + esp_zb_lock_release(); + } else { + log_e("Light not bound"); + } } void ZigbeeColorDimmerSwitch::lightOff(uint16_t group_addr) { - if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req; - cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; - cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr; - cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT; - cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_OFF_ID; - log_i("Sending 'light off' command to group address 0x%x", group_addr); - esp_zb_lock_acquire(portMAX_DELAY); - esp_zb_zcl_on_off_cmd_req(&cmd_req); - esp_zb_lock_release(); - } else { - log_e("Light not bound"); - } + if (_is_bound) { + esp_zb_zcl_on_off_cmd_t cmd_req; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr; + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT; + cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_OFF_ID; + log_i("Sending 'light off' command to group address 0x%x", group_addr); + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_on_off_cmd_req(&cmd_req); + esp_zb_lock_release(); + } else { + log_e("Light not bound"); + } } void ZigbeeColorDimmerSwitch::lightOff(uint8_t endpoint, uint16_t short_addr) { - if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req; - cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; - cmd_req.zcl_basic_cmd.dst_endpoint = endpoint; - cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr; - cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT; - cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_OFF_ID; - log_i("Sending 'light off' command to endpoint %d, address 0x%x", endpoint, short_addr); - esp_zb_lock_acquire(portMAX_DELAY); - esp_zb_zcl_on_off_cmd_req(&cmd_req); - esp_zb_lock_release(); - } else { - log_e("Light not bound"); - } + if (_is_bound) { + esp_zb_zcl_on_off_cmd_t cmd_req; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.zcl_basic_cmd.dst_endpoint = endpoint; + cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr; + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT; + cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_OFF_ID; + log_i("Sending 'light off' command to endpoint %d, address 0x%x", endpoint, short_addr); + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_on_off_cmd_req(&cmd_req); + esp_zb_lock_release(); + } else { + log_e("Light not bound"); + } } void ZigbeeColorDimmerSwitch::lightOffWithEffect(uint8_t effect_id, uint8_t effect_variant) { - if (_is_bound) { - esp_zb_zcl_on_off_off_with_effect_cmd_t cmd_req; - cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; - cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; - cmd_req.effect_id = effect_id; - cmd_req.effect_variant = effect_variant; - log_i("Sending 'light off with effect' command"); - esp_zb_lock_acquire(portMAX_DELAY); - esp_zb_zcl_on_off_off_with_effect_cmd_req(&cmd_req); - esp_zb_lock_release(); - } else { - log_e("Light not bound"); - } + if (_is_bound) { + esp_zb_zcl_on_off_off_with_effect_cmd_t cmd_req; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; + cmd_req.effect_id = effect_id; + cmd_req.effect_variant = effect_variant; + log_i("Sending 'light off with effect' command"); + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_on_off_off_with_effect_cmd_req(&cmd_req); + esp_zb_lock_release(); + } else { + log_e("Light not bound"); + } } void ZigbeeColorDimmerSwitch::lightOnWithSceneRecall() { - if (_is_bound) { - esp_zb_zcl_on_off_on_with_recall_global_scene_cmd_t cmd_req; - cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; - cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; - log_i("Sending 'light on with scene recall' command"); - esp_zb_lock_acquire(portMAX_DELAY); - esp_zb_zcl_on_off_on_with_recall_global_scene_cmd_req(&cmd_req); - esp_zb_lock_release(); - } else { - log_e("Light not bound"); - } + if (_is_bound) { + esp_zb_zcl_on_off_on_with_recall_global_scene_cmd_t cmd_req; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; + log_i("Sending 'light on with scene recall' command"); + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_on_off_on_with_recall_global_scene_cmd_req(&cmd_req); + esp_zb_lock_release(); + } else { + log_e("Light not bound"); + } } void ZigbeeColorDimmerSwitch::lightOnWithTimedOff(uint8_t on_off_control, uint16_t time_on, uint16_t time_off) { - if (_is_bound) { - esp_zb_zcl_on_off_on_with_timed_off_cmd_t cmd_req; - cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; - cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; - cmd_req.on_off_control = on_off_control; //TODO: Test how it works, then maybe change API - cmd_req.on_time = time_on; - cmd_req.off_wait_time = time_off; - log_i("Sending 'light on with time off' command"); - esp_zb_lock_acquire(portMAX_DELAY); - esp_zb_zcl_on_off_on_with_timed_off_cmd_req(&cmd_req); - esp_zb_lock_release(); - } else { - log_e("Light not bound"); - } + if (_is_bound) { + esp_zb_zcl_on_off_on_with_timed_off_cmd_t cmd_req; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; + cmd_req.on_off_control = on_off_control; //TODO: Test how it works, then maybe change API + cmd_req.on_time = time_on; + cmd_req.off_wait_time = time_off; + log_i("Sending 'light on with time off' command"); + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_on_off_on_with_timed_off_cmd_req(&cmd_req); + esp_zb_lock_release(); + } else { + log_e("Light not bound"); + } } void ZigbeeColorDimmerSwitch::setLightLevel(uint8_t level) { - if (_is_bound) { - esp_zb_zcl_move_to_level_cmd_t cmd_req; - cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; - cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; - cmd_req.level = level; - cmd_req.transition_time = 0xffff; - log_i("Sending 'set light level' command"); - esp_zb_lock_acquire(portMAX_DELAY); - esp_zb_zcl_level_move_to_level_cmd_req(&cmd_req); - esp_zb_lock_release(); - } else { - log_e("Light not bound"); - } + if (_is_bound) { + esp_zb_zcl_move_to_level_cmd_t cmd_req; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; + cmd_req.level = level; + cmd_req.transition_time = 0xffff; + log_i("Sending 'set light level' command"); + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_level_move_to_level_cmd_req(&cmd_req); + esp_zb_lock_release(); + } else { + log_e("Light not bound"); + } } void ZigbeeColorDimmerSwitch::setLightLevel(uint8_t level, uint16_t group_addr) { - if (_is_bound) { - esp_zb_zcl_move_to_level_cmd_t cmd_req; - cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; - cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr; - cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT; - cmd_req.level = level; - cmd_req.transition_time = 0xffff; - log_i("Sending 'set light level' command to group address 0x%x", group_addr); - esp_zb_lock_acquire(portMAX_DELAY); - esp_zb_zcl_level_move_to_level_cmd_req(&cmd_req); - esp_zb_lock_release(); - } else { - log_e("Light not bound"); - } + if (_is_bound) { + esp_zb_zcl_move_to_level_cmd_t cmd_req; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr; + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT; + cmd_req.level = level; + cmd_req.transition_time = 0xffff; + log_i("Sending 'set light level' command to group address 0x%x", group_addr); + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_level_move_to_level_cmd_req(&cmd_req); + esp_zb_lock_release(); + } else { + log_e("Light not bound"); + } } void ZigbeeColorDimmerSwitch::setLightLevel(uint8_t level, uint8_t endpoint, uint16_t short_addr) { - if (_is_bound) { - esp_zb_zcl_move_to_level_cmd_t cmd_req; - cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; - cmd_req.zcl_basic_cmd.dst_endpoint = endpoint; - cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr; - cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT; - cmd_req.level = level; - cmd_req.transition_time = 0xffff; - log_i("Sending 'set light level' command to endpoint %d, address 0x%x", endpoint, short_addr); - esp_zb_lock_acquire(portMAX_DELAY); - esp_zb_zcl_level_move_to_level_cmd_req(&cmd_req); - esp_zb_lock_release(); - } else { - log_e("Light not bound"); - } + if (_is_bound) { + esp_zb_zcl_move_to_level_cmd_t cmd_req; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.zcl_basic_cmd.dst_endpoint = endpoint; + cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr; + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT; + cmd_req.level = level; + cmd_req.transition_time = 0xffff; + log_i("Sending 'set light level' command to endpoint %d, address 0x%x", endpoint, short_addr); + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_level_move_to_level_cmd_req(&cmd_req); + esp_zb_lock_release(); + } else { + log_e("Light not bound"); + } } void ZigbeeColorDimmerSwitch::setLightColor(uint8_t red, uint8_t green, uint8_t blue) { - if (_is_bound) { - //Convert RGB to XY - uint16_t color_x, color_y; - calculateXY(red, green, blue, color_x, color_y); - - esp_zb_zcl_color_move_to_color_cmd_t cmd_req; - cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; - cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; - cmd_req.color_x = color_x; - cmd_req.color_y = color_y; - cmd_req.transition_time = 0; - log_i("Sending 'set light color' command"); - esp_zb_lock_acquire(portMAX_DELAY); - esp_zb_zcl_color_move_to_color_cmd_req(&cmd_req); - esp_zb_lock_release(); - } else { - log_e("Light not bound"); - } + if (_is_bound) { + //Convert RGB to XY + uint16_t color_x, color_y; + calculateXY(red, green, blue, color_x, color_y); + + esp_zb_zcl_color_move_to_color_cmd_t cmd_req; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; + cmd_req.color_x = color_x; + cmd_req.color_y = color_y; + cmd_req.transition_time = 0; + log_i("Sending 'set light color' command"); + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_color_move_to_color_cmd_req(&cmd_req); + esp_zb_lock_release(); + } else { + log_e("Light not bound"); + } } void ZigbeeColorDimmerSwitch::setLightColor(uint8_t red, uint8_t green, uint8_t blue, uint16_t group_addr) { - if (_is_bound) { - //Convert RGB to XY - uint16_t color_x, color_y; - calculateXY(red, green, blue, color_x, color_y); - - esp_zb_zcl_color_move_to_color_cmd_t cmd_req; - cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; - cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr; - cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT; - cmd_req.color_x = color_x; - cmd_req.color_y = color_y; - cmd_req.transition_time = 0; - log_i("Sending 'set light color' command to group address 0x%x", group_addr); - esp_zb_lock_acquire(portMAX_DELAY); - esp_zb_zcl_color_move_to_color_cmd_req(&cmd_req); - esp_zb_lock_release(); - } else { - log_e("Light not bound"); - } + if (_is_bound) { + //Convert RGB to XY + uint16_t color_x, color_y; + calculateXY(red, green, blue, color_x, color_y); + + esp_zb_zcl_color_move_to_color_cmd_t cmd_req; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr; + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT; + cmd_req.color_x = color_x; + cmd_req.color_y = color_y; + cmd_req.transition_time = 0; + log_i("Sending 'set light color' command to group address 0x%x", group_addr); + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_color_move_to_color_cmd_req(&cmd_req); + esp_zb_lock_release(); + } else { + log_e("Light not bound"); + } } void ZigbeeColorDimmerSwitch::setLightColor(uint8_t red, uint8_t green, uint8_t blue, uint8_t endpoint, uint16_t short_addr) { - if (_is_bound) { - //Convert RGB to XY - uint16_t color_x, color_y; - calculateXY(red, green, blue, color_x, color_y); - - esp_zb_zcl_color_move_to_color_cmd_t cmd_req; - cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; - cmd_req.zcl_basic_cmd.dst_endpoint = endpoint; - cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr; - cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT; - cmd_req.color_x = color_x; - cmd_req.color_y = color_y; - cmd_req.transition_time = 0; - log_i("Sending 'set light color' command to endpoint %d, address 0x%x", endpoint, short_addr); - esp_zb_lock_acquire(portMAX_DELAY); - esp_zb_zcl_color_move_to_color_cmd_req(&cmd_req); - esp_zb_lock_release(); - } else { - log_e("Light not bound"); - } + if (_is_bound) { + //Convert RGB to XY + uint16_t color_x, color_y; + calculateXY(red, green, blue, color_x, color_y); + + esp_zb_zcl_color_move_to_color_cmd_t cmd_req; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.zcl_basic_cmd.dst_endpoint = endpoint; + cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr; + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT; + cmd_req.color_x = color_x; + cmd_req.color_y = color_y; + cmd_req.transition_time = 0; + log_i("Sending 'set light color' command to endpoint %d, address 0x%x", endpoint, short_addr); + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_color_move_to_color_cmd_req(&cmd_req); + esp_zb_lock_release(); + } else { + log_e("Light not bound"); + } } -#endif //SOC_IEEE802154_SUPPORTED +#endif //SOC_IEEE802154_SUPPORTED diff --git a/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.h b/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.h index fb75e2125c8..2263f3235ca 100644 --- a/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.h +++ b/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.h @@ -9,52 +9,52 @@ #include "ha/esp_zigbee_ha_standard.h" class ZigbeeColorDimmerSwitch : public ZigbeeEP { - public: - ZigbeeColorDimmerSwitch(uint8_t endpoint); - ~ZigbeeColorDimmerSwitch(); +public: + ZigbeeColorDimmerSwitch(uint8_t endpoint); + ~ZigbeeColorDimmerSwitch(); - // methods to control the color dimmable light - void lightToggle(); - void lightToggle(uint16_t group_addr); - void lightToggle(uint8_t endpoint, uint16_t short_addr); + // methods to control the color dimmable light + void lightToggle(); + void lightToggle(uint16_t group_addr); + void lightToggle(uint8_t endpoint, uint16_t short_addr); - void lightOn(); - void lightOn(uint16_t group_addr); - void lightOn(uint8_t endpoint, uint16_t short_addr); + void lightOn(); + void lightOn(uint16_t group_addr); + void lightOn(uint8_t endpoint, uint16_t short_addr); - void lightOff(); - void lightOff(uint16_t group_addr); - void lightOff(uint8_t endpoint, uint16_t short_addr); + void lightOff(); + void lightOff(uint16_t group_addr); + void lightOff(uint8_t endpoint, uint16_t short_addr); - void lightOffWithEffect(uint8_t effect_id, uint8_t effect_variant); - void lightOnWithTimedOff(uint8_t on_off_control, uint16_t time_on, uint16_t time_off); - void lightOnWithSceneRecall(); + void lightOffWithEffect(uint8_t effect_id, uint8_t effect_variant); + void lightOnWithTimedOff(uint8_t on_off_control, uint16_t time_on, uint16_t time_off); + void lightOnWithSceneRecall(); - void setLightLevel(uint8_t level); - void setLightLevel(uint8_t level, uint16_t group_addr); - void setLightLevel(uint8_t level, uint8_t endpoint, uint16_t short_addr); + void setLightLevel(uint8_t level); + void setLightLevel(uint8_t level, uint16_t group_addr); + void setLightLevel(uint8_t level, uint8_t endpoint, uint16_t short_addr); - void setLightColor(uint8_t red, uint8_t green, uint8_t blue); - void setLightColor(uint8_t red, uint8_t green, uint8_t blue, uint16_t group_addr); - void setLightColor(uint8_t red, uint8_t green, uint8_t blue, uint8_t endpoint, uint16_t short_addr); + void setLightColor(uint8_t red, uint8_t green, uint8_t blue); + void setLightColor(uint8_t red, uint8_t green, uint8_t blue, uint16_t group_addr); + void setLightColor(uint8_t red, uint8_t green, uint8_t blue, uint8_t endpoint, uint16_t short_addr); - void setLightColorSaturation(uint8_t value); - void setLightColorSaturation(uint8_t value, uint16_t group_addr); - void setLightColorSaturation(uint8_t value, uint8_t endpoint, uint16_t short_addr); + void setLightColorSaturation(uint8_t value); + void setLightColorSaturation(uint8_t value, uint16_t group_addr); + void setLightColorSaturation(uint8_t value, uint8_t endpoint, uint16_t short_addr); - void setLightColorHue(uint8_t value); - void setLightColorHue(uint8_t value, uint16_t group_addr); - void setLightColorHue(uint8_t value, uint8_t endpoint, uint16_t short_addr); + void setLightColorHue(uint8_t value); + void setLightColorHue(uint8_t value, uint16_t group_addr); + void setLightColorHue(uint8_t value, uint8_t endpoint, uint16_t short_addr); - private: - // save instance of the class in order to use it in static functions - static ZigbeeColorDimmerSwitch* _instance; +private: + // save instance of the class in order to use it in static functions + static ZigbeeColorDimmerSwitch *_instance; - void findEndpoint(esp_zb_zdo_match_desc_req_param_t *cmd_req); - static void bindCb(esp_zb_zdp_status_t zdo_status, void *user_ctx); - static void findCb(esp_zb_zdp_status_t zdo_status, uint16_t addr, uint8_t endpoint, void *user_ctx); + void findEndpoint(esp_zb_zdo_match_desc_req_param_t *cmd_req); + static void bindCb(esp_zb_zdp_status_t zdo_status, void *user_ctx); + static void findCb(esp_zb_zdp_status_t zdo_status, uint16_t addr, uint8_t endpoint, void *user_ctx); - void calculateXY(uint8_t red, uint8_t green, uint8_t blue, uint16_t &x, uint16_t &y); + void calculateXY(uint8_t red, uint8_t green, uint8_t blue, uint16_t &x, uint16_t &y); }; -#endif //SOC_IEEE802154_SUPPORTED +#endif //SOC_IEEE802154_SUPPORTED diff --git a/libraries/Zigbee/src/ep/ZigbeeLight.cpp b/libraries/Zigbee/src/ep/ZigbeeLight.cpp index 75e72bbac35..108faee5dc3 100644 --- a/libraries/Zigbee/src/ep/ZigbeeLight.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeLight.cpp @@ -2,41 +2,34 @@ #if SOC_IEEE802154_SUPPORTED ZigbeeLight::ZigbeeLight(uint8_t endpoint) : ZigbeeEP(endpoint) { - _device_id = ESP_ZB_HA_ON_OFF_LIGHT_DEVICE_ID; + _device_id = ESP_ZB_HA_ON_OFF_LIGHT_DEVICE_ID; - esp_zb_on_off_light_cfg_t light_cfg = ESP_ZB_DEFAULT_ON_OFF_LIGHT_CONFIG(); - _cluster_list = esp_zb_on_off_light_clusters_create(&light_cfg); // use esp_zb_zcl_cluster_list_create() instead of esp_zb_on_off_light_clusters_create() - _ep_config = { - .endpoint = _endpoint, - .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, - .app_device_id = ESP_ZB_HA_ON_OFF_LIGHT_DEVICE_ID, - .app_device_version = 0 - }; + esp_zb_on_off_light_cfg_t light_cfg = ESP_ZB_DEFAULT_ON_OFF_LIGHT_CONFIG(); + _cluster_list = esp_zb_on_off_light_clusters_create(&light_cfg); // use esp_zb_zcl_cluster_list_create() instead of esp_zb_on_off_light_clusters_create() + _ep_config = {.endpoint = _endpoint, .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, .app_device_id = ESP_ZB_HA_ON_OFF_LIGHT_DEVICE_ID, .app_device_version = 0}; } //set attribude method -> methon overriden in child class void ZigbeeLight::zbAttributeSet(const esp_zb_zcl_set_attr_value_message_t *message) { - //check the data and call right method - if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_ON_OFF) { - if (message->attribute.id == ESP_ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID && message->attribute.data.type == ESP_ZB_ZCL_ATTR_TYPE_BOOL) { - _current_state = *(bool *)message->attribute.data.value; - lightChanged(); - } - else { - log_w("Recieved message ignored. Attribute ID: %d not supported for On/Off Light", message->attribute.id); - } - } - else { - log_w("Recieved message ignored. Cluster ID: %d not supported for On/Off Light", message->info.cluster); + //check the data and call right method + if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_ON_OFF) { + if (message->attribute.id == ESP_ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID && message->attribute.data.type == ESP_ZB_ZCL_ATTR_TYPE_BOOL) { + _current_state = *(bool *)message->attribute.data.value; + lightChanged(); + } else { + log_w("Recieved message ignored. Attribute ID: %d not supported for On/Off Light", message->attribute.id); } + } else { + log_w("Recieved message ignored. Cluster ID: %d not supported for On/Off Light", message->info.cluster); + } } void ZigbeeLight::lightChanged() { - if(_on_light_change) { - _on_light_change(_current_state); - } else { - log_w("No callback function set for light change"); - } + if (_on_light_change) { + _on_light_change(_current_state); + } else { + log_w("No callback function set for light change"); + } } -#endif //SOC_IEEE802154_SUPPORTED +#endif //SOC_IEEE802154_SUPPORTED diff --git a/libraries/Zigbee/src/ep/ZigbeeLight.h b/libraries/Zigbee/src/ep/ZigbeeLight.h index 20b1e71ea9b..32e4e8c9bdc 100644 --- a/libraries/Zigbee/src/ep/ZigbeeLight.h +++ b/libraries/Zigbee/src/ep/ZigbeeLight.h @@ -9,21 +9,25 @@ #include "ha/esp_zigbee_ha_standard.h" class ZigbeeLight : public ZigbeeEP { - public: - ZigbeeLight(uint8_t endpoint); - ~ZigbeeLight(); - - // Use tp set a cb function to be called on light change - void onLightChange(void (*callback)(bool)) { _on_light_change = callback; } - void restoreLight() { lightChanged(); } - - private: - void zbAttributeSet(const esp_zb_zcl_set_attr_value_message_t *message) override; - //callback function to be called on light change - void (*_on_light_change)(bool); - void lightChanged(); - - bool _current_state; +public: + ZigbeeLight(uint8_t endpoint); + ~ZigbeeLight(); + + // Use tp set a cb function to be called on light change + void onLightChange(void (*callback)(bool)) { + _on_light_change = callback; + } + void restoreLight() { + lightChanged(); + } + +private: + void zbAttributeSet(const esp_zb_zcl_set_attr_value_message_t *message) override; + //callback function to be called on light change + void (*_on_light_change)(bool); + void lightChanged(); + + bool _current_state; }; -#endif //SOC_IEEE802154_SUPPORTED +#endif //SOC_IEEE802154_SUPPORTED diff --git a/libraries/Zigbee/src/ep/ZigbeeSwitch.cpp b/libraries/Zigbee/src/ep/ZigbeeSwitch.cpp index 15b1ce89de0..9152732e376 100644 --- a/libraries/Zigbee/src/ep/ZigbeeSwitch.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeSwitch.cpp @@ -2,237 +2,232 @@ #if SOC_IEEE802154_SUPPORTED // Initialize the static instance pointer -ZigbeeSwitch* ZigbeeSwitch::_instance = nullptr; +ZigbeeSwitch *ZigbeeSwitch::_instance = nullptr; ZigbeeSwitch::ZigbeeSwitch(uint8_t endpoint) : ZigbeeEP(endpoint) { - _device_id = ESP_ZB_HA_ON_OFF_SWITCH_DEVICE_ID; - _instance = this; // Set the static pointer to this instance + _device_id = ESP_ZB_HA_ON_OFF_SWITCH_DEVICE_ID; + _instance = this; // Set the static pointer to this instance - esp_zb_on_off_switch_cfg_t switch_cfg = ESP_ZB_DEFAULT_ON_OFF_SWITCH_CONFIG(); - _cluster_list = esp_zb_on_off_switch_clusters_create(&switch_cfg); + esp_zb_on_off_switch_cfg_t switch_cfg = ESP_ZB_DEFAULT_ON_OFF_SWITCH_CONFIG(); + _cluster_list = esp_zb_on_off_switch_clusters_create(&switch_cfg); - _ep_config = { - .endpoint = _endpoint, - .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, - .app_device_id = ESP_ZB_HA_ON_OFF_SWITCH_DEVICE_ID, - .app_device_version = 0 - }; + _ep_config = {.endpoint = _endpoint, .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, .app_device_id = ESP_ZB_HA_ON_OFF_SWITCH_DEVICE_ID, .app_device_version = 0}; } void ZigbeeSwitch::bindCb(esp_zb_zdp_status_t zdo_status, void *user_ctx) { - if (zdo_status == ESP_ZB_ZDP_STATUS_SUCCESS) { - log_i("Bound successfully!"); - if (user_ctx) { - zb_device_params_t *light = (zb_device_params_t *)user_ctx; - log_i("The light originating from address(0x%x) on endpoint(%d)", light->short_addr, light->endpoint); - _instance->_bound_devices.push_back(light); - } - _is_bound = true; + if (zdo_status == ESP_ZB_ZDP_STATUS_SUCCESS) { + log_i("Bound successfully!"); + if (user_ctx) { + zb_device_params_t *light = (zb_device_params_t *)user_ctx; + log_i("The light originating from address(0x%x) on endpoint(%d)", light->short_addr, light->endpoint); + _instance->_bound_devices.push_back(light); } + _is_bound = true; + } } void ZigbeeSwitch::findCb(esp_zb_zdp_status_t zdo_status, uint16_t addr, uint8_t endpoint, void *user_ctx) { - if (zdo_status == ESP_ZB_ZDP_STATUS_SUCCESS) { - log_d("Found light endpoint"); - esp_zb_zdo_bind_req_param_t bind_req; - zb_device_params_t *light = (zb_device_params_t *)malloc(sizeof(zb_device_params_t)); - light->endpoint = endpoint; - light->short_addr = addr; - esp_zb_ieee_address_by_short(light->short_addr, light->ieee_addr); - esp_zb_get_long_address(bind_req.src_address); - bind_req.src_endp = _endpoint; //_dev_endpoint; - bind_req.cluster_id = ESP_ZB_ZCL_CLUSTER_ID_ON_OFF; - bind_req.dst_addr_mode = ESP_ZB_ZDO_BIND_DST_ADDR_MODE_64_BIT_EXTENDED; - memcpy(bind_req.dst_address_u.addr_long, light->ieee_addr, sizeof(esp_zb_ieee_addr_t)); - bind_req.dst_endp = endpoint; - bind_req.req_dst_addr = esp_zb_get_short_address(); - log_i("Try to bind On/Off"); - esp_zb_zdo_device_bind_req(&bind_req, bindCb, (void *)light); - } else { - log_d("No light endpoint found"); - } + if (zdo_status == ESP_ZB_ZDP_STATUS_SUCCESS) { + log_d("Found light endpoint"); + esp_zb_zdo_bind_req_param_t bind_req; + zb_device_params_t *light = (zb_device_params_t *)malloc(sizeof(zb_device_params_t)); + light->endpoint = endpoint; + light->short_addr = addr; + esp_zb_ieee_address_by_short(light->short_addr, light->ieee_addr); + esp_zb_get_long_address(bind_req.src_address); + bind_req.src_endp = _endpoint; //_dev_endpoint; + bind_req.cluster_id = ESP_ZB_ZCL_CLUSTER_ID_ON_OFF; + bind_req.dst_addr_mode = ESP_ZB_ZDO_BIND_DST_ADDR_MODE_64_BIT_EXTENDED; + memcpy(bind_req.dst_address_u.addr_long, light->ieee_addr, sizeof(esp_zb_ieee_addr_t)); + bind_req.dst_endp = endpoint; + bind_req.req_dst_addr = esp_zb_get_short_address(); + log_i("Try to bind On/Off"); + esp_zb_zdo_device_bind_req(&bind_req, bindCb, (void *)light); + } else { + log_d("No light endpoint found"); + } } // find on_off light endpoint void ZigbeeSwitch::findEndpoint(esp_zb_zdo_match_desc_req_param_t *cmd_req) { - uint16_t cluster_list[] = {ESP_ZB_ZCL_CLUSTER_ID_ON_OFF, ESP_ZB_ZCL_CLUSTER_ID_ON_OFF}; - esp_zb_zdo_match_desc_req_param_t on_off_req = { - .dst_nwk_addr = cmd_req->dst_nwk_addr, - .addr_of_interest = cmd_req->addr_of_interest, - .profile_id = ESP_ZB_AF_HA_PROFILE_ID, - .num_in_clusters = 1, - .num_out_clusters = 1, - .cluster_list = cluster_list, - }; + uint16_t cluster_list[] = {ESP_ZB_ZCL_CLUSTER_ID_ON_OFF, ESP_ZB_ZCL_CLUSTER_ID_ON_OFF}; + esp_zb_zdo_match_desc_req_param_t on_off_req = { + .dst_nwk_addr = cmd_req->dst_nwk_addr, + .addr_of_interest = cmd_req->addr_of_interest, + .profile_id = ESP_ZB_AF_HA_PROFILE_ID, + .num_in_clusters = 1, + .num_out_clusters = 1, + .cluster_list = cluster_list, + }; - esp_zb_zdo_match_cluster(&on_off_req, findCb, NULL); + esp_zb_zdo_match_cluster(&on_off_req, findCb, NULL); } // Methods to control the light void ZigbeeSwitch::lightToggle() { - if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req; - cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; - cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; - cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_TOGGLE_ID; - log_i("Sending 'light toggle' command"); - esp_zb_zcl_on_off_cmd_req(&cmd_req); - } else { - log_e("Light not bound"); - } + if (_is_bound) { + esp_zb_zcl_on_off_cmd_t cmd_req; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; + cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_TOGGLE_ID; + log_i("Sending 'light toggle' command"); + esp_zb_zcl_on_off_cmd_req(&cmd_req); + } else { + log_e("Light not bound"); + } } void ZigbeeSwitch::lightToggle(uint16_t group_addr) { - if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req; - cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; - cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr; - cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT; - cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_TOGGLE_ID; - log_i("Sending 'light toggle' command to group address 0x%x", group_addr); - esp_zb_zcl_on_off_cmd_req(&cmd_req); - } else { - log_e("Light not bound"); - } + if (_is_bound) { + esp_zb_zcl_on_off_cmd_t cmd_req; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr; + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT; + cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_TOGGLE_ID; + log_i("Sending 'light toggle' command to group address 0x%x", group_addr); + esp_zb_zcl_on_off_cmd_req(&cmd_req); + } else { + log_e("Light not bound"); + } } void ZigbeeSwitch::lightToggle(uint8_t endpoint, uint16_t short_addr) { - if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req; - cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; - cmd_req.zcl_basic_cmd.dst_endpoint = endpoint; - cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr; - cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT; - cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_TOGGLE_ID; - log_i("Sending 'light toggle' command to endpoint %d, address 0x%x", endpoint, short_addr); - esp_zb_zcl_on_off_cmd_req(&cmd_req); - } else { - log_e("Light not bound"); - } + if (_is_bound) { + esp_zb_zcl_on_off_cmd_t cmd_req; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.zcl_basic_cmd.dst_endpoint = endpoint; + cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr; + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT; + cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_TOGGLE_ID; + log_i("Sending 'light toggle' command to endpoint %d, address 0x%x", endpoint, short_addr); + esp_zb_zcl_on_off_cmd_req(&cmd_req); + } else { + log_e("Light not bound"); + } } void ZigbeeSwitch::lightOn() { - if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req; - cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; - cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; - cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_ON_ID; - log_i("Sending 'light on' command"); - esp_zb_zcl_on_off_cmd_req(&cmd_req); - } else { - log_e("Light not bound"); - } + if (_is_bound) { + esp_zb_zcl_on_off_cmd_t cmd_req; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; + cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_ON_ID; + log_i("Sending 'light on' command"); + esp_zb_zcl_on_off_cmd_req(&cmd_req); + } else { + log_e("Light not bound"); + } } void ZigbeeSwitch::lightOn(uint16_t group_addr) { - if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req; - cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; - cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr; - cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT; - cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_ON_ID; - log_i("Sending 'light on' command to group address 0x%x", group_addr); - esp_zb_zcl_on_off_cmd_req(&cmd_req); - } else { - log_e("Light not bound"); - } + if (_is_bound) { + esp_zb_zcl_on_off_cmd_t cmd_req; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr; + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT; + cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_ON_ID; + log_i("Sending 'light on' command to group address 0x%x", group_addr); + esp_zb_zcl_on_off_cmd_req(&cmd_req); + } else { + log_e("Light not bound"); + } } void ZigbeeSwitch::lightOn(uint8_t endpoint, uint16_t short_addr) { - if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req; - cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; - cmd_req.zcl_basic_cmd.dst_endpoint = endpoint; - cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr; - cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT; - cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_ON_ID; - log_i("Sending 'light on' command to endpoint %d, address 0x%x", endpoint, short_addr); - esp_zb_zcl_on_off_cmd_req(&cmd_req); - } else { - log_e("Light not bound"); - } + if (_is_bound) { + esp_zb_zcl_on_off_cmd_t cmd_req; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.zcl_basic_cmd.dst_endpoint = endpoint; + cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr; + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT; + cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_ON_ID; + log_i("Sending 'light on' command to endpoint %d, address 0x%x", endpoint, short_addr); + esp_zb_zcl_on_off_cmd_req(&cmd_req); + } else { + log_e("Light not bound"); + } } void ZigbeeSwitch::lightOff() { - if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req; - cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; - cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; - cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_OFF_ID; - log_i("Sending 'light off' command"); - esp_zb_zcl_on_off_cmd_req(&cmd_req); - } else { - log_e("Light not bound"); - } + if (_is_bound) { + esp_zb_zcl_on_off_cmd_t cmd_req; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; + cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_OFF_ID; + log_i("Sending 'light off' command"); + esp_zb_zcl_on_off_cmd_req(&cmd_req); + } else { + log_e("Light not bound"); + } } void ZigbeeSwitch::lightOff(uint16_t group_addr) { - if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req; - cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; - cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr; - cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT; - cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_OFF_ID; - log_i("Sending 'light off' command to group address 0x%x", group_addr); - esp_zb_zcl_on_off_cmd_req(&cmd_req); - } else { - log_e("Light not bound"); - } + if (_is_bound) { + esp_zb_zcl_on_off_cmd_t cmd_req; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr; + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT; + cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_OFF_ID; + log_i("Sending 'light off' command to group address 0x%x", group_addr); + esp_zb_zcl_on_off_cmd_req(&cmd_req); + } else { + log_e("Light not bound"); + } } void ZigbeeSwitch::lightOff(uint8_t endpoint, uint16_t short_addr) { - if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req; - cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; - cmd_req.zcl_basic_cmd.dst_endpoint = endpoint; - cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr; - cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT; - cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_OFF_ID; - log_i("Sending 'light off' command to endpoint %d, address 0x%x", endpoint, short_addr); - esp_zb_zcl_on_off_cmd_req(&cmd_req); - } else { - log_e("Light not bound"); - } + if (_is_bound) { + esp_zb_zcl_on_off_cmd_t cmd_req; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.zcl_basic_cmd.dst_endpoint = endpoint; + cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr; + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT; + cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_OFF_ID; + log_i("Sending 'light off' command to endpoint %d, address 0x%x", endpoint, short_addr); + esp_zb_zcl_on_off_cmd_req(&cmd_req); + } else { + log_e("Light not bound"); + } } void ZigbeeSwitch::lightOffWithEffect(uint8_t effect_id, uint8_t effect_variant) { - if (_is_bound) { - esp_zb_zcl_on_off_off_with_effect_cmd_t cmd_req; - cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; - cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; - cmd_req.effect_id = effect_id; - cmd_req.effect_variant = effect_variant; - log_i("Sending 'light off with effect' command"); - esp_zb_zcl_on_off_off_with_effect_cmd_req(&cmd_req); - } else { - log_e("Light not bound"); - } + if (_is_bound) { + esp_zb_zcl_on_off_off_with_effect_cmd_t cmd_req; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; + cmd_req.effect_id = effect_id; + cmd_req.effect_variant = effect_variant; + log_i("Sending 'light off with effect' command"); + esp_zb_zcl_on_off_off_with_effect_cmd_req(&cmd_req); + } else { + log_e("Light not bound"); + } } void ZigbeeSwitch::lightOnWithSceneRecall() { - if (_is_bound) { - esp_zb_zcl_on_off_on_with_recall_global_scene_cmd_t cmd_req; - cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; - cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; - log_i("Sending 'light on with scene recall' command"); - esp_zb_zcl_on_off_on_with_recall_global_scene_cmd_req(&cmd_req); - } else { - log_e("Light not bound"); - } + if (_is_bound) { + esp_zb_zcl_on_off_on_with_recall_global_scene_cmd_t cmd_req; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; + log_i("Sending 'light on with scene recall' command"); + esp_zb_zcl_on_off_on_with_recall_global_scene_cmd_req(&cmd_req); + } else { + log_e("Light not bound"); + } } void ZigbeeSwitch::lightOnWithTimedOff(uint8_t on_off_control, uint16_t time_on, uint16_t time_off) { - if (_is_bound) { - esp_zb_zcl_on_off_on_with_timed_off_cmd_t cmd_req; - cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; - cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; - cmd_req.on_off_control = on_off_control; //TODO: Test how it works, then maybe change API - cmd_req.on_time = time_on; - cmd_req.off_wait_time = time_off; - log_i("Sending 'light on with time off' command"); - esp_zb_zcl_on_off_on_with_timed_off_cmd_req(&cmd_req); - } else { - log_e("Light not bound"); - } -} - -#endif //SOC_IEEE802154_SUPPORTED + if (_is_bound) { + esp_zb_zcl_on_off_on_with_timed_off_cmd_t cmd_req; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; + cmd_req.on_off_control = on_off_control; //TODO: Test how it works, then maybe change API + cmd_req.on_time = time_on; + cmd_req.off_wait_time = time_off; + log_i("Sending 'light on with time off' command"); + esp_zb_zcl_on_off_on_with_timed_off_cmd_req(&cmd_req); + } else { + log_e("Light not bound"); + } +} + +#endif //SOC_IEEE802154_SUPPORTED diff --git a/libraries/Zigbee/src/ep/ZigbeeSwitch.h b/libraries/Zigbee/src/ep/ZigbeeSwitch.h index 322c7b7443b..bbc6c0a91dc 100644 --- a/libraries/Zigbee/src/ep/ZigbeeSwitch.h +++ b/libraries/Zigbee/src/ep/ZigbeeSwitch.h @@ -9,35 +9,34 @@ #include "ha/esp_zigbee_ha_standard.h" class ZigbeeSwitch : public ZigbeeEP { - public: - ZigbeeSwitch(uint8_t endpoint); - ~ZigbeeSwitch(); - - // methods to control the on/off light - void lightToggle(); - void lightToggle(uint16_t group_addr); - void lightToggle(uint8_t endpoint, uint16_t short_addr); - - void lightOn(); - void lightOn(uint16_t group_addr); - void lightOn(uint8_t endpoint, uint16_t short_addr); - - void lightOff(); - void lightOff(uint16_t group_addr); - void lightOff(uint8_t endpoint, uint16_t short_addr); - - void lightOffWithEffect(uint8_t effect_id, uint8_t effect_variant); - void lightOnWithTimedOff(uint8_t on_off_control, uint16_t time_on, uint16_t time_off); - void lightOnWithSceneRecall(); - - private: - // save instance of the class in order to use it in static functions - static ZigbeeSwitch* _instance; - - void findEndpoint(esp_zb_zdo_match_desc_req_param_t *cmd_req); - static void bindCb(esp_zb_zdp_status_t zdo_status, void *user_ctx); - static void findCb(esp_zb_zdp_status_t zdo_status, uint16_t addr, uint8_t endpoint, void *user_ctx); - +public: + ZigbeeSwitch(uint8_t endpoint); + ~ZigbeeSwitch(); + + // methods to control the on/off light + void lightToggle(); + void lightToggle(uint16_t group_addr); + void lightToggle(uint8_t endpoint, uint16_t short_addr); + + void lightOn(); + void lightOn(uint16_t group_addr); + void lightOn(uint8_t endpoint, uint16_t short_addr); + + void lightOff(); + void lightOff(uint16_t group_addr); + void lightOff(uint8_t endpoint, uint16_t short_addr); + + void lightOffWithEffect(uint8_t effect_id, uint8_t effect_variant); + void lightOnWithTimedOff(uint8_t on_off_control, uint16_t time_on, uint16_t time_off); + void lightOnWithSceneRecall(); + +private: + // save instance of the class in order to use it in static functions + static ZigbeeSwitch *_instance; + + void findEndpoint(esp_zb_zdo_match_desc_req_param_t *cmd_req); + static void bindCb(esp_zb_zdp_status_t zdo_status, void *user_ctx); + static void findCb(esp_zb_zdp_status_t zdo_status, uint16_t addr, uint8_t endpoint, void *user_ctx); }; -#endif //SOC_IEEE802154_SUPPORTED +#endif //SOC_IEEE802154_SUPPORTED diff --git a/libraries/Zigbee/src/ep/ZigbeeTempSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeTempSensor.cpp index e4bba80246d..e0dba03da5c 100644 --- a/libraries/Zigbee/src/ep/ZigbeeTempSensor.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeTempSensor.cpp @@ -2,17 +2,14 @@ #if SOC_IEEE802154_SUPPORTED ZigbeeTempSensor::ZigbeeTempSensor(uint8_t endpoint) : ZigbeeEP(endpoint) { - _device_id = ESP_ZB_HA_TEMPERATURE_SENSOR_DEVICE_ID; + _device_id = ESP_ZB_HA_TEMPERATURE_SENSOR_DEVICE_ID; - esp_zb_temperature_sensor_cfg_t temp_sensor_cfg = ESP_ZB_DEFAULT_TEMPERATURE_SENSOR_CONFIG(); - _cluster_list = esp_zb_temperature_sensor_clusters_create(&temp_sensor_cfg); - - _ep_config = { - .endpoint = _endpoint, - .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, - .app_device_id = ESP_ZB_HA_TEMPERATURE_SENSOR_DEVICE_ID, - .app_device_version = 0 - }; + esp_zb_temperature_sensor_cfg_t temp_sensor_cfg = ESP_ZB_DEFAULT_TEMPERATURE_SENSOR_CONFIG(); + _cluster_list = esp_zb_temperature_sensor_clusters_create(&temp_sensor_cfg); + + _ep_config = { + .endpoint = _endpoint, .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, .app_device_id = ESP_ZB_HA_TEMPERATURE_SENSOR_DEVICE_ID, .app_device_version = 0 + }; } static int16_t zb_temperature_to_s16(float temp) { @@ -20,73 +17,77 @@ static int16_t zb_temperature_to_s16(float temp) { } void ZigbeeTempSensor::setMinMaxValue(float min, float max) { - int16_t zb_min = zb_temperature_to_s16(min); - int16_t zb_max = zb_temperature_to_s16(max); - esp_zb_attribute_list_t *temp_measure_cluster = esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); - esp_zb_cluster_update_attr(temp_measure_cluster, ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_MIN_VALUE_ID, (void *)&zb_min); - esp_zb_cluster_update_attr(temp_measure_cluster, ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_MAX_VALUE_ID, (void *)&zb_max); + int16_t zb_min = zb_temperature_to_s16(min); + int16_t zb_max = zb_temperature_to_s16(max); + esp_zb_attribute_list_t *temp_measure_cluster = + esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_zb_cluster_update_attr(temp_measure_cluster, ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_MIN_VALUE_ID, (void *)&zb_min); + esp_zb_cluster_update_attr(temp_measure_cluster, ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_MAX_VALUE_ID, (void *)&zb_max); } void ZigbeeTempSensor::setTolerance(float tolerance) { - // Convert tolerance to ZCL uint16_t - uint16_t zb_tolerance = (uint16_t)(tolerance * 100); - esp_zb_attribute_list_t *temp_measure_cluster = esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); - esp_zb_temperature_meas_cluster_add_attr(temp_measure_cluster, ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_TOLERANCE_ID, (void *)&zb_tolerance); + // Convert tolerance to ZCL uint16_t + uint16_t zb_tolerance = (uint16_t)(tolerance * 100); + esp_zb_attribute_list_t *temp_measure_cluster = + esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_zb_temperature_meas_cluster_add_attr(temp_measure_cluster, ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_TOLERANCE_ID, (void *)&zb_tolerance); } void ZigbeeTempSensor::setReporting(uint16_t min_interval, uint16_t max_interval, float delta) { - esp_zb_zcl_reporting_info_t reporting_info = { - .direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_SRV, - .ep = _endpoint, - .cluster_id = ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT, - .cluster_role = ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, - .attr_id = ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID, - .u = - { - .send_info = - { - .min_interval = min_interval, - .max_interval = max_interval, - .delta = - { - .u16 = (uint16_t)(delta * 100), // Convert delta to ZCL uint16_t - }, - .def_min_interval = min_interval, - .def_max_interval = max_interval, - }, - }, - .dst = - { - .profile_id = ESP_ZB_AF_HA_PROFILE_ID, - }, - .manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC, - }; + esp_zb_zcl_reporting_info_t reporting_info = { + .direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_SRV, + .ep = _endpoint, + .cluster_id = ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT, + .cluster_role = ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, + .attr_id = ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID, + .u = + { + .send_info = + { + .min_interval = min_interval, + .max_interval = max_interval, + .delta = + { + .u16 = (uint16_t)(delta * 100), // Convert delta to ZCL uint16_t + }, + .def_min_interval = min_interval, + .def_max_interval = max_interval, + }, + }, + .dst = + { + .profile_id = ESP_ZB_AF_HA_PROFILE_ID, + }, + .manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC, + }; esp_zb_zcl_update_reporting_info(&reporting_info); } void ZigbeeTempSensor::setTemperature(float temperature) { - int16_t zb_temperature = zb_temperature_to_s16(temperature); - log_v("Updating temperature sensor value..."); - /* Update temperature sensor measured value */ - log_d("Setting temperature to %d", zb_temperature); - esp_zb_lock_acquire(portMAX_DELAY); - esp_zb_zcl_set_attribute_val(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID, &zb_temperature, false); - esp_zb_lock_release(); + int16_t zb_temperature = zb_temperature_to_s16(temperature); + log_v("Updating temperature sensor value..."); + /* Update temperature sensor measured value */ + log_d("Setting temperature to %d", zb_temperature); + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_set_attribute_val( + _endpoint, ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID, &zb_temperature, false + ); + esp_zb_lock_release(); } void ZigbeeTempSensor::reportTemperature() { - /* Send report attributes command */ - esp_zb_zcl_report_attr_cmd_t report_attr_cmd; - report_attr_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; - report_attr_cmd.attributeID = ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID; - report_attr_cmd.cluster_role = ESP_ZB_ZCL_CLUSTER_SERVER_ROLE; - report_attr_cmd.clusterID = ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT; - report_attr_cmd.zcl_basic_cmd.src_endpoint = _endpoint; + /* Send report attributes command */ + esp_zb_zcl_report_attr_cmd_t report_attr_cmd; + report_attr_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; + report_attr_cmd.attributeID = ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID; + report_attr_cmd.cluster_role = ESP_ZB_ZCL_CLUSTER_SERVER_ROLE; + report_attr_cmd.clusterID = ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT; + report_attr_cmd.zcl_basic_cmd.src_endpoint = _endpoint; - esp_zb_lock_acquire(portMAX_DELAY); - esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd); - esp_zb_lock_release(); - log_v("Temperature report sent"); + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd); + esp_zb_lock_release(); + log_v("Temperature report sent"); } -#endif //SOC_IEEE802154_SUPPORTED +#endif //SOC_IEEE802154_SUPPORTED diff --git a/libraries/Zigbee/src/ep/ZigbeeTempSensor.h b/libraries/Zigbee/src/ep/ZigbeeTempSensor.h index 2f15e6029f6..22317721fc4 100644 --- a/libraries/Zigbee/src/ep/ZigbeeTempSensor.h +++ b/libraries/Zigbee/src/ep/ZigbeeTempSensor.h @@ -9,22 +9,22 @@ #include "ha/esp_zigbee_ha_standard.h" class ZigbeeTempSensor : public ZigbeeEP { - public: - ZigbeeTempSensor(uint8_t endpoint); - ~ZigbeeTempSensor(); +public: + ZigbeeTempSensor(uint8_t endpoint); + ~ZigbeeTempSensor(); - // Set the temperature value in 0,01°C - void setTemperature(float value); + // Set the temperature value in 0,01°C + void setTemperature(float value); - // Set the min and max value for the temperature sensor in 0,01°C - void setMinMaxValue(float min, float max); + // Set the min and max value for the temperature sensor in 0,01°C + void setMinMaxValue(float min, float max); - // Set the tolerance value for the temperature sensor in 0,01°C - void setTolerance(float tolerance); + // Set the tolerance value for the temperature sensor in 0,01°C + void setTolerance(float tolerance); - // Set the reporting interval for temperature measurement in seconds and delta (temp change in 0,01 °C) - void setReporting(uint16_t min_interval, uint16_t max_interval, float delta); - void reportTemperature(); + // Set the reporting interval for temperature measurement in seconds and delta (temp change in 0,01 °C) + void setReporting(uint16_t min_interval, uint16_t max_interval, float delta); + void reportTemperature(); }; -#endif //SOC_IEEE802154_SUPPORTED +#endif //SOC_IEEE802154_SUPPORTED diff --git a/libraries/Zigbee/src/ep/ZigbeeThermostat.cpp b/libraries/Zigbee/src/ep/ZigbeeThermostat.cpp index 86c1a8fc18c..28ed2a70cd2 100644 --- a/libraries/Zigbee/src/ep/ZigbeeThermostat.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeThermostat.cpp @@ -6,46 +6,40 @@ static float zb_s16_to_temperature(int16_t value) { } // Initialize the static instance of the class -ZigbeeThermostat* ZigbeeThermostat::_instance = nullptr; +ZigbeeThermostat *ZigbeeThermostat::_instance = nullptr; ZigbeeThermostat::ZigbeeThermostat(uint8_t endpoint) : ZigbeeEP(endpoint) { - _device_id = ESP_ZB_HA_THERMOSTAT_DEVICE_ID; - _instance = this; // Set the static pointer to this instance - - //use custom config to avoid narrowing error -> must be fixed in zigbee-sdk - esp_zb_thermostat_cfg_t thermostat_cfg = ZB_DEFAULT_THERMOSTAT_CONFIG(); - - //use custom cluster creating to accept reportings from temperature sensor - _cluster_list = esp_zb_zcl_cluster_list_create(); - esp_zb_attribute_list_t *basic_cluster = esp_zb_basic_cluster_create(&(thermostat_cfg.basic_cfg)); - esp_zb_cluster_list_add_basic_cluster(_cluster_list, basic_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); - esp_zb_cluster_list_add_identify_cluster(_cluster_list, esp_zb_identify_cluster_create(&(thermostat_cfg.identify_cfg)), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); - esp_zb_cluster_list_add_identify_cluster(_cluster_list, esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_IDENTIFY), ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE); - esp_zb_cluster_list_add_thermostat_cluster(_cluster_list, esp_zb_thermostat_cluster_create(&(thermostat_cfg.thermostat_cfg)), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); - /* Add temperature measurement cluster for attribute reporting */ - esp_zb_cluster_list_add_temperature_meas_cluster(_cluster_list, esp_zb_temperature_meas_cluster_create(NULL), ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE); - - _ep_config = { - .endpoint = _endpoint, - .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, - .app_device_id = ESP_ZB_HA_THERMOSTAT_DEVICE_ID, - .app_device_version = 0 - }; + _device_id = ESP_ZB_HA_THERMOSTAT_DEVICE_ID; + _instance = this; // Set the static pointer to this instance + + //use custom config to avoid narrowing error -> must be fixed in zigbee-sdk + esp_zb_thermostat_cfg_t thermostat_cfg = ZB_DEFAULT_THERMOSTAT_CONFIG(); + + //use custom cluster creating to accept reportings from temperature sensor + _cluster_list = esp_zb_zcl_cluster_list_create(); + esp_zb_attribute_list_t *basic_cluster = esp_zb_basic_cluster_create(&(thermostat_cfg.basic_cfg)); + esp_zb_cluster_list_add_basic_cluster(_cluster_list, basic_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_zb_cluster_list_add_identify_cluster(_cluster_list, esp_zb_identify_cluster_create(&(thermostat_cfg.identify_cfg)), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_zb_cluster_list_add_identify_cluster(_cluster_list, esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_IDENTIFY), ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE); + esp_zb_cluster_list_add_thermostat_cluster(_cluster_list, esp_zb_thermostat_cluster_create(&(thermostat_cfg.thermostat_cfg)), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + /* Add temperature measurement cluster for attribute reporting */ + esp_zb_cluster_list_add_temperature_meas_cluster(_cluster_list, esp_zb_temperature_meas_cluster_create(NULL), ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE); + + _ep_config = {.endpoint = _endpoint, .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, .app_device_id = ESP_ZB_HA_THERMOSTAT_DEVICE_ID, .app_device_version = 0}; } void ZigbeeThermostat::bindCb(esp_zb_zdp_status_t zdo_status, void *user_ctx) { if (zdo_status == ESP_ZB_ZDP_STATUS_SUCCESS) { - if (user_ctx) { - zb_device_params_t *sensor = (zb_device_params_t *)user_ctx; - log_i("The temperature sensor originating from address(0x%x) on endpoint(%d)", sensor->short_addr, sensor->endpoint); - _instance->_bound_devices.push_back(sensor); - } - else { - log_v("Local binding success"); - } - _is_bound = true; + if (user_ctx) { + zb_device_params_t *sensor = (zb_device_params_t *)user_ctx; + log_i("The temperature sensor originating from address(0x%x) on endpoint(%d)", sensor->short_addr, sensor->endpoint); + _instance->_bound_devices.push_back(sensor); + } else { + log_v("Local binding success"); + } + _is_bound = true; } else { - log_e("Binding failed!"); + log_e("Binding failed!"); } } @@ -97,20 +91,20 @@ void ZigbeeThermostat::findCb(esp_zb_zdp_status_t zdo_status, uint16_t addr, uin } void ZigbeeThermostat::findEndpoint(esp_zb_zdo_match_desc_req_param_t *param) { - uint16_t cluster_list[] = {ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT}; - param->profile_id = ESP_ZB_AF_HA_PROFILE_ID; - param->num_in_clusters = 1; - param->num_out_clusters = 0; - param->cluster_list = cluster_list; - esp_zb_zdo_match_cluster(param, findCb, NULL); + uint16_t cluster_list[] = {ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT}; + param->profile_id = ESP_ZB_AF_HA_PROFILE_ID; + param->num_in_clusters = 1; + param->num_out_clusters = 0; + param->cluster_list = cluster_list; + esp_zb_zdo_match_cluster(param, findCb, NULL); } void ZigbeeThermostat::zbAttributeRead(uint16_t cluster_id, const esp_zb_zcl_attribute_t *attribute) { - static uint8_t read_config = 0; - if (cluster_id == ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT) { + static uint8_t read_config = 0; + if (cluster_id == ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT) { if (attribute->id == ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID && attribute->data.type == ESP_ZB_ZCL_ATTR_TYPE_S16) { int16_t value = attribute->data.value ? *(int16_t *)attribute->data.value : 0; - if(_on_temp_recieve){ + if (_on_temp_recieve) { _on_temp_recieve(zb_s16_to_temperature(value)); } } @@ -129,88 +123,83 @@ void ZigbeeThermostat::zbAttributeRead(uint16_t cluster_id, const esp_zb_zcl_att _tolerance = 1.0 * tolerance / 100; read_config++; } - if(read_config == 3){ + if (read_config == 3) { read_config = 0; xSemaphoreGive(lock); } } } -void ZigbeeThermostat::getTemperature(){ - /* Send "read attributes" command to the bound sensor */ - esp_zb_zcl_read_attr_cmd_t read_req; - read_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; - read_req.zcl_basic_cmd.src_endpoint = _endpoint; - read_req.clusterID = ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT; - - uint16_t attributes[] = { - ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID - }; - read_req.attr_number = ZB_ARRAY_LENTH(attributes); - read_req.attr_field = attributes; - - log_i("Sending 'read temperature' command"); - esp_zb_lock_acquire(portMAX_DELAY); - esp_zb_zcl_read_attr_cmd_req(&read_req); - esp_zb_lock_release(); +void ZigbeeThermostat::getTemperature() { + /* Send "read attributes" command to the bound sensor */ + esp_zb_zcl_read_attr_cmd_t read_req; + read_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; + read_req.zcl_basic_cmd.src_endpoint = _endpoint; + read_req.clusterID = ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT; + + uint16_t attributes[] = {ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID}; + read_req.attr_number = ZB_ARRAY_LENTH(attributes); + read_req.attr_field = attributes; + + log_i("Sending 'read temperature' command"); + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_read_attr_cmd_req(&read_req); + esp_zb_lock_release(); } -void ZigbeeThermostat::getSensorSettings(){ - /* Send "read attributes" command to the bound sensor */ - esp_zb_zcl_read_attr_cmd_t read_req; - read_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; - read_req.zcl_basic_cmd.src_endpoint = _endpoint; - read_req.clusterID = ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT; - - uint16_t attributes[] = { - ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_MIN_VALUE_ID, - ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_MAX_VALUE_ID, - ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_TOLERANCE_ID - }; - read_req.attr_number = ZB_ARRAY_LENTH(attributes); - read_req.attr_field = attributes; - - log_i("Sending 'read temperature' command"); - esp_zb_lock_acquire(portMAX_DELAY); - esp_zb_zcl_read_attr_cmd_req(&read_req); - esp_zb_lock_release(); - - //Take semaphore to wait for response of all attributes - if(xSemaphoreTake(lock, portMAX_DELAY) != pdTRUE){ - log_e("Error while reading attributes"); - return; - } - else{ - //Call the callback function when all attributes are read - _on_config_recieve(_min_temp, _max_temp, _tolerance); - } +void ZigbeeThermostat::getSensorSettings() { + /* Send "read attributes" command to the bound sensor */ + esp_zb_zcl_read_attr_cmd_t read_req; + read_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; + read_req.zcl_basic_cmd.src_endpoint = _endpoint; + read_req.clusterID = ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT; + + uint16_t attributes[] = { + ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_MIN_VALUE_ID, ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_MAX_VALUE_ID, ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_TOLERANCE_ID + }; + read_req.attr_number = ZB_ARRAY_LENTH(attributes); + read_req.attr_field = attributes; + + log_i("Sending 'read temperature' command"); + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_read_attr_cmd_req(&read_req); + esp_zb_lock_release(); + + //Take semaphore to wait for response of all attributes + if (xSemaphoreTake(lock, portMAX_DELAY) != pdTRUE) { + log_e("Error while reading attributes"); + return; + } else { + //Call the callback function when all attributes are read + _on_config_recieve(_min_temp, _max_temp, _tolerance); + } } -void ZigbeeThermostat::setTemperatureReporting(uint16_t min_interval, uint16_t max_interval, float delta){ +void ZigbeeThermostat::setTemperatureReporting(uint16_t min_interval, uint16_t max_interval, float delta) { /* Send "configure report attribute" command to the bound sensor */ - esp_zb_zcl_config_report_cmd_t report_cmd; - report_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; - report_cmd.zcl_basic_cmd.src_endpoint = _endpoint; - report_cmd.clusterID = ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT; - - int16_t report_change = (int16_t)delta * 100; - esp_zb_zcl_config_report_record_t records[] = { - { - .direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_SRV, - .attributeID = ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID, - .attrType = ESP_ZB_ZCL_ATTR_TYPE_S16, - .min_interval = min_interval, - .max_interval = max_interval, - .reportable_change = &report_change, - }, - }; - report_cmd.record_number = ZB_ARRAY_LENTH(records); - report_cmd.record_field = records; - - log_i("Sending 'configure reporting' command"); - esp_zb_lock_acquire(portMAX_DELAY); - esp_zb_zcl_config_report_cmd_req(&report_cmd); - esp_zb_lock_release(); + esp_zb_zcl_config_report_cmd_t report_cmd; + report_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; + report_cmd.zcl_basic_cmd.src_endpoint = _endpoint; + report_cmd.clusterID = ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT; + + int16_t report_change = (int16_t)delta * 100; + esp_zb_zcl_config_report_record_t records[] = { + { + .direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_SRV, + .attributeID = ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID, + .attrType = ESP_ZB_ZCL_ATTR_TYPE_S16, + .min_interval = min_interval, + .max_interval = max_interval, + .reportable_change = &report_change, + }, + }; + report_cmd.record_number = ZB_ARRAY_LENTH(records); + report_cmd.record_field = records; + + log_i("Sending 'configure reporting' command"); + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_config_report_cmd_req(&report_cmd); + esp_zb_lock_release(); } -#endif //SOC_IEEE802154_SUPPORTED +#endif //SOC_IEEE802154_SUPPORTED diff --git a/libraries/Zigbee/src/ep/ZigbeeThermostat.h b/libraries/Zigbee/src/ep/ZigbeeThermostat.h index f0c1b5588e1..7d63cd9f726 100644 --- a/libraries/Zigbee/src/ep/ZigbeeThermostat.h +++ b/libraries/Zigbee/src/ep/ZigbeeThermostat.h @@ -9,53 +9,56 @@ #include "ha/esp_zigbee_ha_standard.h" //define the thermostat configuration to avoid narrowing conversion issue in zigbee-sdk -#define ZB_DEFAULT_THERMOSTAT_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, \ - }, \ - .thermostat_cfg = \ - { \ - .local_temperature = (int16_t)ESP_ZB_ZCL_THERMOSTAT_LOCAL_TEMPERATURE_DEFAULT_VALUE, \ - .occupied_cooling_setpoint = ESP_ZB_ZCL_THERMOSTAT_OCCUPIED_COOLING_SETPOINT_DEFAULT_VALUE, \ - .occupied_heating_setpoint = ESP_ZB_ZCL_THERMOSTAT_OCCUPIED_HEATING_SETPOINT_DEFAULT_VALUE, \ - .control_sequence_of_operation = ESP_ZB_ZCL_THERMOSTAT_CONTROL_SEQ_OF_OPERATION_DEFAULT_VALUE, \ - .system_mode = ESP_ZB_ZCL_THERMOSTAT_CONTROL_SYSTEM_MODE_DEFAULT_VALUE, \ - }, \ - } +#define ZB_DEFAULT_THERMOSTAT_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, \ + }, \ + .thermostat_cfg = { \ + .local_temperature = (int16_t)ESP_ZB_ZCL_THERMOSTAT_LOCAL_TEMPERATURE_DEFAULT_VALUE, \ + .occupied_cooling_setpoint = ESP_ZB_ZCL_THERMOSTAT_OCCUPIED_COOLING_SETPOINT_DEFAULT_VALUE, \ + .occupied_heating_setpoint = ESP_ZB_ZCL_THERMOSTAT_OCCUPIED_HEATING_SETPOINT_DEFAULT_VALUE, \ + .control_sequence_of_operation = ESP_ZB_ZCL_THERMOSTAT_CONTROL_SEQ_OF_OPERATION_DEFAULT_VALUE, \ + .system_mode = ESP_ZB_ZCL_THERMOSTAT_CONTROL_SYSTEM_MODE_DEFAULT_VALUE, \ + }, \ + } class ZigbeeThermostat : public ZigbeeEP { - public: - ZigbeeThermostat(uint8_t endpoint); - ~ZigbeeThermostat(); +public: + ZigbeeThermostat(uint8_t endpoint); + ~ZigbeeThermostat(); - void onTempRecieve(void (*callback)(float)) { _on_temp_recieve = callback; } - void onConfigRecieve(void (*callback)(float, float, float)) { _on_config_recieve = callback; } + void onTempRecieve(void (*callback)(float)) { + _on_temp_recieve = callback; + } + void onConfigRecieve(void (*callback)(float, float, float)) { + _on_config_recieve = callback; + } - void getTemperature(); - void getSensorSettings(); - void setTemperatureReporting(uint16_t min_interval, uint16_t max_interval, float delta); + void getTemperature(); + void getSensorSettings(); + void setTemperatureReporting(uint16_t min_interval, uint16_t max_interval, float delta); - private: - // save instance of the class in order to use it in static functions - static ZigbeeThermostat* _instance; +private: + // save instance of the class in order to use it in static functions + static ZigbeeThermostat *_instance; - void (*_on_temp_recieve)(float); - void (*_on_config_recieve)(float, float, float); - float _min_temp; - float _max_temp; - float _tolerance; + void (*_on_temp_recieve)(float); + void (*_on_config_recieve)(float, float, float); + float _min_temp; + float _max_temp; + float _tolerance; - void findEndpoint(esp_zb_zdo_match_desc_req_param_t *cmd_req); - static void bindCb(esp_zb_zdp_status_t zdo_status, void *user_ctx); - static void findCb(esp_zb_zdp_status_t zdo_status, uint16_t addr, uint8_t endpoint, void *user_ctx); + void findEndpoint(esp_zb_zdo_match_desc_req_param_t *cmd_req); + static void bindCb(esp_zb_zdp_status_t zdo_status, void *user_ctx); + static void findCb(esp_zb_zdp_status_t zdo_status, uint16_t addr, uint8_t endpoint, void *user_ctx); - void zbAttributeRead(uint16_t cluster_id, const esp_zb_zcl_attribute_t *attribute) override; + void zbAttributeRead(uint16_t cluster_id, const esp_zb_zcl_attribute_t *attribute) override; }; -#endif //SOC_IEEE802154_SUPPORTED +#endif //SOC_IEEE802154_SUPPORTED