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 0721371ce0e..d4a71bbed89 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 @@ -66,6 +66,8 @@ static SwitchData buttonFunctionPair[] = {{GPIO_INPUT_IO_TOGGLE_SWITCH, SWITCH_O ZigbeeSwitch zbSwitch = ZigbeeSwitch(SWITCH_ENDPOINT_NUMBER); +static bool light_state = false; + /********************* Zigbee functions **************************/ static void onZbButton(SwitchData *button_func_pair) { if (button_func_pair->func == SWITCH_ONOFF_TOGGLE_CONTROL) { @@ -75,6 +77,33 @@ static void onZbButton(SwitchData *button_func_pair) { } } +static void onLightStateChange(bool state) { + if (state != light_state) { + light_state = state; + Serial.printf("Light state changed to %d\r\n", state); + } +} + +/********************* Periodic task ***************************/ +void periodicTask(void *arg) { + while (true) { + // print the bound lights every 10 seconds + static uint32_t lastPrint = 0; + if (millis() - lastPrint > 10000) { + lastPrint = millis(); + zbSwitch.printBoundDevices(Serial); + } + + // Poll light state every second + static uint32_t lastPoll = 0; + if (millis() - lastPoll > 1000) { + lastPoll = millis(); + zbSwitch.getLightState(); + } + vTaskDelay(1000 / portTICK_PERIOD_MS); + } +} + /********************* GPIO functions **************************/ static QueueHandle_t gpio_evt_queue = NULL; @@ -102,6 +131,8 @@ void setup() { //Optional to allow multiple light to bind to the switch zbSwitch.allowMultipleBinding(true); + zbSwitch.onLightStateChange(onLightStateChange); + //Add endpoint to Zigbee Core Serial.println("Adding ZigbeeSwitch endpoint to Zigbee Core"); Zigbee.addEndpoint(&zbSwitch); @@ -154,6 +185,8 @@ void setup() { } Serial.println(); + + xTaskCreate(periodicTask, "periodicTask", 1024 * 4, NULL, 10, NULL); } void loop() { @@ -188,11 +221,4 @@ void loop() { } vTaskDelay(10 / portTICK_PERIOD_MS); } - - // print the bound lights every 10 seconds - static uint32_t lastPrint = 0; - if (millis() - lastPrint > 10000) { - lastPrint = millis(); - zbSwitch.printBoundDevices(Serial); - } } diff --git a/libraries/Zigbee/keywords.txt b/libraries/Zigbee/keywords.txt index 67cb47ee319..f203de96da6 100644 --- a/libraries/Zigbee/keywords.txt +++ b/libraries/Zigbee/keywords.txt @@ -104,7 +104,6 @@ clearBoundDevices KEYWORD2 onDefaultResponse KEYWORD2 # ZigbeeLight + ZigbeeColorDimmableLight -onLightChange KEYWORD2 restoreLight KEYWORD2 setLight KEYWORD2 setLightState KEYWORD2 @@ -115,6 +114,12 @@ getLightLevel KEYWORD2 getLightRed KEYWORD2 getLightGreen KEYWORD2 getLightBlue KEYWORD2 +onLightChange KEYWORD2 +onLightColorChangeWithSource KEYWORD2 +onLightLevelChange KEYWORD2 +onLightLevelChangeWithSource KEYWORD2 +onLightStateChange KEYWORD2 +onLightStateChangeWithSource KEYWORD2 # ZigbeeSwitch + ZigbeeColorDimmerSwitch lightToggle KEYWORD2 @@ -125,6 +130,15 @@ lightOnWithTimedOff KEYWORD2 lightOnWithSceneRecall KEYWORD2 setLightLevel KEYWORD2 setLightColor KEYWORD2 +getLightState KEYWORD2 +getLightLevel KEYWORD2 +getLightColor KEYWORD2 +onLightStateChange KEYWORD2 +onLightStateChangeWithSource KEYWORD2 +onLightLevelChange KEYWORD2 +onLightLevelChangeWithSource KEYWORD2 +onLightColorChange KEYWORD2 +onLightColorChangeWithSource KEYWORD2 # ZigbeeThermostat onTempRecieve KEYWORD2 diff --git a/libraries/Zigbee/src/ZigbeeEP.cpp b/libraries/Zigbee/src/ZigbeeEP.cpp index b857eb5e7a5..48a083748f4 100644 --- a/libraries/Zigbee/src/ZigbeeEP.cpp +++ b/libraries/Zigbee/src/ZigbeeEP.cpp @@ -160,7 +160,8 @@ bool ZigbeeEP::setBatteryVoltage(uint8_t voltage) { bool ZigbeeEP::reportBatteryPercentage() { /* Send report attributes command */ - esp_zb_zcl_report_attr_cmd_t report_attr_cmd = {0}; + esp_zb_zcl_report_attr_cmd_t report_attr_cmd; + memset(&report_attr_cmd, 0, sizeof(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_POWER_CONFIG_BATTERY_PERCENTAGE_REMAINING_ID; report_attr_cmd.direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_CLI; @@ -181,7 +182,8 @@ bool ZigbeeEP::reportBatteryPercentage() { char *ZigbeeEP::readManufacturer(uint8_t endpoint, uint16_t short_addr, esp_zb_ieee_addr_t ieee_addr) { /* Read peer Manufacture Name & Model Identifier */ - esp_zb_zcl_read_attr_cmd_t read_req = {0}; + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(read_req)); if (short_addr != 0) { read_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT; @@ -219,7 +221,8 @@ char *ZigbeeEP::readManufacturer(uint8_t endpoint, uint16_t short_addr, esp_zb_i char *ZigbeeEP::readModel(uint8_t endpoint, uint16_t short_addr, esp_zb_ieee_addr_t ieee_addr) { /* Read peer Manufacture Name & Model Identifier */ - esp_zb_zcl_read_attr_cmd_t read_req = {0}; + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(read_req)); if (short_addr != 0) { read_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT; @@ -396,7 +399,8 @@ bool ZigbeeEP::setTimezone(int32_t gmt_offset) { tm ZigbeeEP::getTime(uint8_t endpoint, int32_t short_addr, esp_zb_ieee_addr_t ieee_addr) { /* Read peer time */ - esp_zb_zcl_read_attr_cmd_t read_req = {0}; + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(read_req)); if (short_addr >= 0) { read_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT; @@ -448,7 +452,8 @@ tm ZigbeeEP::getTime(uint8_t endpoint, int32_t short_addr, esp_zb_ieee_addr_t ie int32_t ZigbeeEP::getTimezone(uint8_t endpoint, int32_t short_addr, esp_zb_ieee_addr_t ieee_addr) { /* Read peer timezone */ - esp_zb_zcl_read_attr_cmd_t read_req = {0}; + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(read_req)); if (short_addr >= 0) { read_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT; @@ -564,7 +569,8 @@ static void findOTAServer(esp_zb_zdp_status_t zdo_status, uint16_t addr, uint8_t } void ZigbeeEP::requestOTAUpdate() { - esp_zb_zdo_match_desc_req_param_t req = {0}; + esp_zb_zdo_match_desc_req_param_t req; + memset(&req, 0, sizeof(req)); uint16_t cluster_list[] = {ESP_ZB_ZCL_CLUSTER_ID_OTA_UPGRADE}; /* Match the OTA server of coordinator */ diff --git a/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.cpp b/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.cpp index 1d18d3c10e8..18465104dfa 100644 --- a/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.cpp @@ -23,6 +23,16 @@ ZigbeeColorDimmerSwitch::ZigbeeColorDimmerSwitch(uint8_t endpoint) : ZigbeeEP(en _instance = this; // Set the static pointer to this instance _device = nullptr; // Initialize light pointer to null + _light_color_rgb = {0, 0, 0}; + _light_color_hsv = {0, 0, 255}; + _light_color_xy = {0, 0}; + _on_light_state_change = nullptr; + _on_light_state_change_with_source = nullptr; + _on_light_level_change = nullptr; + _on_light_level_change_with_source = nullptr; + _on_light_color_change = nullptr; + _on_light_color_change_with_source = nullptr; + 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); @@ -67,7 +77,8 @@ void ZigbeeColorDimmerSwitch::findCb(esp_zb_zdp_status_t zdo_status, uint16_t ad ZigbeeColorDimmerSwitch *instance = static_cast(user_ctx); if (zdo_status == ESP_ZB_ZDP_STATUS_SUCCESS) { log_d("Found light endpoint"); - esp_zb_zdo_bind_req_param_t bind_req = {0}; + esp_zb_zdo_bind_req_param_t bind_req; + memset(&bind_req, 0, sizeof(bind_req)); zb_device_params_t *light = (zb_device_params_t *)malloc(sizeof(zb_device_params_t)); light->endpoint = endpoint; light->short_addr = addr; @@ -111,7 +122,8 @@ void ZigbeeColorDimmerSwitch::findEndpoint(esp_zb_zdo_match_desc_req_param_t *cm // Methods to control the light void ZigbeeColorDimmerSwitch::lightToggle() { if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req = {0}; + esp_zb_zcl_on_off_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(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; @@ -126,7 +138,8 @@ void ZigbeeColorDimmerSwitch::lightToggle() { void ZigbeeColorDimmerSwitch::lightToggle(uint16_t group_addr) { if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req = {0}; + esp_zb_zcl_on_off_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(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; @@ -142,7 +155,8 @@ void ZigbeeColorDimmerSwitch::lightToggle(uint16_t group_addr) { void ZigbeeColorDimmerSwitch::lightToggle(uint8_t endpoint, uint16_t short_addr) { if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req = {0}; + esp_zb_zcl_on_off_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(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; @@ -159,7 +173,8 @@ void ZigbeeColorDimmerSwitch::lightToggle(uint8_t endpoint, uint16_t short_addr) void ZigbeeColorDimmerSwitch::lightToggle(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) { if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req = {0}; + esp_zb_zcl_on_off_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(cmd_req)); cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; cmd_req.zcl_basic_cmd.dst_endpoint = endpoint; cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT; @@ -179,7 +194,8 @@ void ZigbeeColorDimmerSwitch::lightToggle(uint8_t endpoint, esp_zb_ieee_addr_t i void ZigbeeColorDimmerSwitch::lightOn() { if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req = {0}; + esp_zb_zcl_on_off_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(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; @@ -194,7 +210,8 @@ void ZigbeeColorDimmerSwitch::lightOn() { void ZigbeeColorDimmerSwitch::lightOn(uint16_t group_addr) { if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req = {0}; + esp_zb_zcl_on_off_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(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; @@ -210,7 +227,8 @@ void ZigbeeColorDimmerSwitch::lightOn(uint16_t group_addr) { void ZigbeeColorDimmerSwitch::lightOn(uint8_t endpoint, uint16_t short_addr) { if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req = {0}; + esp_zb_zcl_on_off_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(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; @@ -227,7 +245,8 @@ void ZigbeeColorDimmerSwitch::lightOn(uint8_t endpoint, uint16_t short_addr) { void ZigbeeColorDimmerSwitch::lightOn(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) { if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req = {0}; + esp_zb_zcl_on_off_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(cmd_req)); cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; cmd_req.zcl_basic_cmd.dst_endpoint = endpoint; cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT; @@ -247,7 +266,8 @@ void ZigbeeColorDimmerSwitch::lightOn(uint8_t endpoint, esp_zb_ieee_addr_t ieee_ void ZigbeeColorDimmerSwitch::lightOff() { if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req = {0}; + esp_zb_zcl_on_off_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(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; @@ -262,7 +282,8 @@ void ZigbeeColorDimmerSwitch::lightOff() { void ZigbeeColorDimmerSwitch::lightOff(uint16_t group_addr) { if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req = {0}; + esp_zb_zcl_on_off_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(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; @@ -278,7 +299,8 @@ void ZigbeeColorDimmerSwitch::lightOff(uint16_t group_addr) { void ZigbeeColorDimmerSwitch::lightOff(uint8_t endpoint, uint16_t short_addr) { if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req = {0}; + esp_zb_zcl_on_off_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(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; @@ -295,7 +317,8 @@ void ZigbeeColorDimmerSwitch::lightOff(uint8_t endpoint, uint16_t short_addr) { void ZigbeeColorDimmerSwitch::lightOff(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) { if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req = {0}; + esp_zb_zcl_on_off_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(cmd_req)); cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; cmd_req.zcl_basic_cmd.dst_endpoint = endpoint; cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT; @@ -315,7 +338,8 @@ void ZigbeeColorDimmerSwitch::lightOff(uint8_t endpoint, esp_zb_ieee_addr_t ieee 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 = {0}; + esp_zb_zcl_on_off_off_with_effect_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(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; @@ -331,7 +355,8 @@ void ZigbeeColorDimmerSwitch::lightOffWithEffect(uint8_t effect_id, uint8_t effe void ZigbeeColorDimmerSwitch::lightOnWithSceneRecall() { if (_is_bound) { - esp_zb_zcl_on_off_on_with_recall_global_scene_cmd_t cmd_req = {0}; + esp_zb_zcl_on_off_on_with_recall_global_scene_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(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_v("Sending 'light on with scene recall' command"); @@ -345,7 +370,8 @@ void ZigbeeColorDimmerSwitch::lightOnWithSceneRecall() { 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 = {0}; + esp_zb_zcl_on_off_on_with_timed_off_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(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 @@ -362,7 +388,8 @@ void ZigbeeColorDimmerSwitch::lightOnWithTimedOff(uint8_t on_off_control, uint16 void ZigbeeColorDimmerSwitch::setLightLevel(uint8_t level) { if (_is_bound) { - esp_zb_zcl_move_to_level_cmd_t cmd_req = {0}; + esp_zb_zcl_move_to_level_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(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; @@ -378,7 +405,8 @@ void ZigbeeColorDimmerSwitch::setLightLevel(uint8_t level) { void ZigbeeColorDimmerSwitch::setLightLevel(uint8_t level, uint16_t group_addr) { if (_is_bound) { - esp_zb_zcl_move_to_level_cmd_t cmd_req = {0}; + esp_zb_zcl_move_to_level_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(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; @@ -395,7 +423,8 @@ void ZigbeeColorDimmerSwitch::setLightLevel(uint8_t level, uint16_t group_addr) 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 = {0}; + esp_zb_zcl_move_to_level_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(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; @@ -413,7 +442,8 @@ void ZigbeeColorDimmerSwitch::setLightLevel(uint8_t level, uint8_t endpoint, uin void ZigbeeColorDimmerSwitch::setLightLevel(uint8_t level, uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) { if (_is_bound) { - esp_zb_zcl_move_to_level_cmd_t cmd_req = {0}; + esp_zb_zcl_move_to_level_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(cmd_req)); cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; cmd_req.zcl_basic_cmd.dst_endpoint = endpoint; cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT; @@ -436,7 +466,8 @@ void ZigbeeColorDimmerSwitch::setLightColor(uint8_t red, uint8_t green, uint8_t if (_is_bound) { espXyColor_t xy_color = espRgbToXYColor(red, green, blue); - esp_zb_zcl_color_move_to_color_cmd_t cmd_req = {0}; + esp_zb_zcl_color_move_to_color_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(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 = xy_color.x; @@ -455,7 +486,8 @@ void ZigbeeColorDimmerSwitch::setLightColor(uint8_t red, uint8_t green, uint8_t if (_is_bound) { espXyColor_t xy_color = espRgbToXYColor(red, green, blue); - esp_zb_zcl_color_move_to_color_cmd_t cmd_req = {0}; + esp_zb_zcl_color_move_to_color_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(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; @@ -475,7 +507,8 @@ void ZigbeeColorDimmerSwitch::setLightColor(uint8_t red, uint8_t green, uint8_t if (_is_bound) { espXyColor_t xy_color = espRgbToXYColor(red, green, blue); - esp_zb_zcl_color_move_to_color_cmd_t cmd_req = {0}; + esp_zb_zcl_color_move_to_color_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(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; @@ -496,7 +529,8 @@ void ZigbeeColorDimmerSwitch::setLightColor(uint8_t red, uint8_t green, uint8_t if (_is_bound) { espXyColor_t xy_color = espRgbToXYColor(red, green, blue); - esp_zb_zcl_color_move_to_color_cmd_t cmd_req = {0}; + esp_zb_zcl_color_move_to_color_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(cmd_req)); cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; cmd_req.zcl_basic_cmd.dst_endpoint = endpoint; cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT; @@ -516,4 +550,356 @@ void ZigbeeColorDimmerSwitch::setLightColor(uint8_t red, uint8_t green, uint8_t } } +void ZigbeeColorDimmerSwitch::getLightState() { + if (_is_bound) { + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(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_ON_OFF; + read_req.attr_number = 1; + uint16_t attr_id = ESP_ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID; + read_req.attr_field = &attr_id; + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_read_attr_cmd_req(&read_req); + esp_zb_lock_release(); + } +} + +void ZigbeeColorDimmerSwitch::getLightState(uint16_t group_addr) { + if (_is_bound) { + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(read_req)); + read_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT; + read_req.zcl_basic_cmd.src_endpoint = _endpoint; + read_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr; + read_req.clusterID = ESP_ZB_ZCL_CLUSTER_ID_ON_OFF; + read_req.attr_number = 1; + uint16_t attr_id = ESP_ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID; + read_req.attr_field = &attr_id; + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_read_attr_cmd_req(&read_req); + esp_zb_lock_release(); + } +} + +void ZigbeeColorDimmerSwitch::getLightState(uint8_t endpoint, uint16_t short_addr) { + if (_is_bound) { + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(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_ON_OFF; + read_req.attr_number = 1; + uint16_t attr_id = ESP_ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID; + read_req.attr_field = &attr_id; + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_read_attr_cmd_req(&read_req); + esp_zb_lock_release(); + } +} + +void ZigbeeColorDimmerSwitch::getLightState(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) { + if (_is_bound) { + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(read_req)); + read_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT; + read_req.zcl_basic_cmd.src_endpoint = _endpoint; + read_req.zcl_basic_cmd.dst_endpoint = endpoint; + memcpy(read_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t)); + read_req.clusterID = ESP_ZB_ZCL_CLUSTER_ID_ON_OFF; + read_req.attr_number = 1; + uint16_t attr_id = ESP_ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID; + read_req.attr_field = &attr_id; + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_read_attr_cmd_req(&read_req); + esp_zb_lock_release(); + } +} + +void ZigbeeColorDimmerSwitch::getLightLevel() { + if (_is_bound) { + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(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_LEVEL_CONTROL; + read_req.attr_number = 1; + uint16_t attr_id = ESP_ZB_ZCL_ATTR_LEVEL_CONTROL_CURRENT_LEVEL_ID; + read_req.attr_field = &attr_id; + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_read_attr_cmd_req(&read_req); + esp_zb_lock_release(); + } +} + +void ZigbeeColorDimmerSwitch::getLightLevel(uint16_t group_addr) { + if (_is_bound) { + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(read_req)); + read_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT; + read_req.zcl_basic_cmd.src_endpoint = _endpoint; + read_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr; + read_req.clusterID = ESP_ZB_ZCL_CLUSTER_ID_LEVEL_CONTROL; + read_req.attr_number = 1; + uint16_t attr_id = ESP_ZB_ZCL_ATTR_LEVEL_CONTROL_CURRENT_LEVEL_ID; + read_req.attr_field = &attr_id; + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_read_attr_cmd_req(&read_req); + esp_zb_lock_release(); + } +} + +void ZigbeeColorDimmerSwitch::getLightLevel(uint8_t endpoint, uint16_t short_addr) { + if (_is_bound) { + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(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_LEVEL_CONTROL; + read_req.attr_number = 1; + uint16_t attr_id = ESP_ZB_ZCL_ATTR_LEVEL_CONTROL_CURRENT_LEVEL_ID; + read_req.attr_field = &attr_id; + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_read_attr_cmd_req(&read_req); + esp_zb_lock_release(); + } +} + +void ZigbeeColorDimmerSwitch::getLightLevel(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) { + if (_is_bound) { + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(read_req)); + read_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT; + read_req.zcl_basic_cmd.src_endpoint = _endpoint; + read_req.zcl_basic_cmd.dst_endpoint = endpoint; + memcpy(read_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t)); + read_req.clusterID = ESP_ZB_ZCL_CLUSTER_ID_LEVEL_CONTROL; + read_req.attr_number = 1; + uint16_t attr_id = ESP_ZB_ZCL_ATTR_LEVEL_CONTROL_CURRENT_LEVEL_ID; + read_req.attr_field = &attr_id; + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_read_attr_cmd_req(&read_req); + esp_zb_lock_release(); + } +} + +void ZigbeeColorDimmerSwitch::getLightColor() { + if (_is_bound) { + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(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_COLOR_CONTROL; + read_req.attr_number = 2; + uint16_t attr_id[] = {ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_X_ID, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_Y_ID}; + read_req.attr_field = attr_id; + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_read_attr_cmd_req(&read_req); + esp_zb_lock_release(); + } +} + +void ZigbeeColorDimmerSwitch::getLightColor(uint16_t group_addr) { + if (_is_bound) { + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(read_req)); + read_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT; + read_req.zcl_basic_cmd.src_endpoint = _endpoint; + read_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr; + read_req.clusterID = ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL; + read_req.attr_number = 2; + uint16_t attr_id[] = {ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_X_ID, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_Y_ID}; + read_req.attr_field = attr_id; + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_read_attr_cmd_req(&read_req); + esp_zb_lock_release(); + } +} + +void ZigbeeColorDimmerSwitch::getLightColor(uint8_t endpoint, uint16_t short_addr) { + if (_is_bound) { + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(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_COLOR_CONTROL; + read_req.attr_number = 2; + uint16_t attr_id[] = {ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_X_ID, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_Y_ID}; + read_req.attr_field = attr_id; + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_read_attr_cmd_req(&read_req); + esp_zb_lock_release(); + } +} + +void ZigbeeColorDimmerSwitch::getLightColor(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) { + if (_is_bound) { + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(read_req)); + read_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT; + read_req.zcl_basic_cmd.src_endpoint = _endpoint; + read_req.zcl_basic_cmd.dst_endpoint = endpoint; + memcpy(read_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t)); + read_req.clusterID = ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL; + read_req.attr_number = 2; + uint16_t attr_id[] = {ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_X_ID, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_Y_ID}; + read_req.attr_field = attr_id; + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_read_attr_cmd_req(&read_req); + esp_zb_lock_release(); + } +} + +void ZigbeeColorDimmerSwitch::getLightColorHS() { + if (_is_bound) { + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(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_COLOR_CONTROL; + read_req.attr_number = 2; + uint16_t attr_id[] = {ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_HUE_ID, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_SATURATION_ID}; + read_req.attr_field = attr_id; + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_read_attr_cmd_req(&read_req); + esp_zb_lock_release(); + } +} + +void ZigbeeColorDimmerSwitch::getLightColorHS(uint16_t group_addr) { + if (_is_bound) { + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(read_req)); + read_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT; + read_req.zcl_basic_cmd.src_endpoint = _endpoint; + read_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr; + read_req.clusterID = ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL; + read_req.attr_number = 2; + uint16_t attr_id[] = {ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_HUE_ID, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_SATURATION_ID}; + read_req.attr_field = attr_id; + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_read_attr_cmd_req(&read_req); + esp_zb_lock_release(); + } +} + +void ZigbeeColorDimmerSwitch::getLightColorHS(uint8_t endpoint, uint16_t short_addr) { + if (_is_bound) { + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(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_COLOR_CONTROL; + read_req.attr_number = 2; + uint16_t attr_id[] = {ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_HUE_ID, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_SATURATION_ID}; + read_req.attr_field = attr_id; + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_read_attr_cmd_req(&read_req); + esp_zb_lock_release(); + } +} + +void ZigbeeColorDimmerSwitch::getLightColorHS(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) { + if (_is_bound) { + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(read_req)); + read_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT; + read_req.zcl_basic_cmd.src_endpoint = _endpoint; + read_req.zcl_basic_cmd.dst_endpoint = endpoint; + memcpy(read_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t)); + read_req.clusterID = ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL; + read_req.attr_number = 2; + uint16_t attr_id[] = {ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_HUE_ID, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_SATURATION_ID}; + read_req.attr_field = attr_id; + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_read_attr_cmd_req(&read_req); + esp_zb_lock_release(); + } +} + +void ZigbeeColorDimmerSwitch::zbAttributeRead( + uint16_t cluster_id, const esp_zb_zcl_attribute_t *attribute, uint8_t src_endpoint, esp_zb_zcl_addr_t src_address +) { + if (cluster_id == ESP_ZB_ZCL_CLUSTER_ID_ON_OFF) { + if (attribute->id == ESP_ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID && attribute->data.type == ESP_ZB_ZCL_ATTR_TYPE_BOOL) { + bool light_state = attribute->data.value ? *(bool *)attribute->data.value : false; + if (_on_light_state_change) { + _on_light_state_change(light_state); + } + if (_on_light_state_change_with_source) { + _on_light_state_change_with_source(light_state, src_endpoint, src_address); + } + } + } + if (cluster_id == ESP_ZB_ZCL_CLUSTER_ID_LEVEL_CONTROL) { + if (attribute->id == ESP_ZB_ZCL_ATTR_LEVEL_CONTROL_CURRENT_LEVEL_ID && attribute->data.type == ESP_ZB_ZCL_ATTR_TYPE_U8) { + uint8_t light_level = attribute->data.value ? *(uint8_t *)attribute->data.value : 0; + if (_on_light_level_change) { + _on_light_level_change(light_level); + } + if (_on_light_level_change_with_source) { + _on_light_level_change_with_source(light_level, src_endpoint, src_address); + } + } + } + if (cluster_id == ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL) { + static bool x_received = false; + static bool y_received = false; + static bool h_received = false; + static bool s_received = false; + + if (attribute->id == ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_X_ID && attribute->data.type == ESP_ZB_ZCL_ATTR_TYPE_U16) { + _light_color_xy.x = attribute->data.value ? *(uint16_t *)attribute->data.value : 0; + x_received = true; + } + if (attribute->id == ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_Y_ID && attribute->data.type == ESP_ZB_ZCL_ATTR_TYPE_U16) { + _light_color_xy.y = attribute->data.value ? *(uint16_t *)attribute->data.value : 0; + y_received = true; + } + + if (attribute->id == ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_HUE_ID && attribute->data.type == ESP_ZB_ZCL_ATTR_TYPE_U8) { + _light_color_hsv.h = attribute->data.value ? *(uint8_t *)attribute->data.value : 0; + h_received = true; + } + if (attribute->id == ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_SATURATION_ID && attribute->data.type == ESP_ZB_ZCL_ATTR_TYPE_U8) { + _light_color_hsv.s = attribute->data.value ? *(uint8_t *)attribute->data.value : 0; + s_received = true; + } + + // Process XY color if both X and Y have been received + if (x_received && y_received) { + _light_color_rgb = espXYToRgbColor(255, _light_color_xy.x, _light_color_xy.y, false); + if (_on_light_color_change) { + _on_light_color_change(_light_color_rgb.r, _light_color_rgb.g, _light_color_rgb.b); + } + if (_on_light_color_change_with_source) { + _on_light_color_change_with_source(_light_color_rgb.r, _light_color_rgb.g, _light_color_rgb.b, src_endpoint, src_address); + } + x_received = false; // Reset flags after processing + y_received = false; + } + + // Process HS color if both H and S have been received + if (h_received && s_received) { + _light_color_rgb = espHsvColorToRgbColor(_light_color_hsv); + if (_on_light_color_change) { + _on_light_color_change(_light_color_rgb.r, _light_color_rgb.g, _light_color_rgb.b); + } + if (_on_light_color_change_with_source) { + _on_light_color_change_with_source(_light_color_rgb.r, _light_color_rgb.g, _light_color_rgb.b, src_endpoint, src_address); + } + h_received = false; // Reset flags after processing + s_received = false; + } + } +} #endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.h b/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.h index 9d813c47651..10484a6867f 100644 --- a/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.h +++ b/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.h @@ -58,18 +58,68 @@ class ZigbeeColorDimmerSwitch : public ZigbeeEP { 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, uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr); + void getLightState(); + void getLightState(uint16_t group_addr); + void getLightState(uint8_t endpoint, uint16_t short_addr); + void getLightState(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr); + + void getLightLevel(); + void getLightLevel(uint16_t group_addr); + void getLightLevel(uint8_t endpoint, uint16_t short_addr); + void getLightLevel(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr); + + void getLightColor(); + void getLightColor(uint16_t group_addr); + void getLightColor(uint8_t endpoint, uint16_t short_addr); + void getLightColor(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr); + + void getLightColorHS(); + void getLightColorHS(uint16_t group_addr); + void getLightColorHS(uint8_t endpoint, uint16_t short_addr); + void getLightColorHS(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr); + + void onLightStateChange(void (*callback)(bool)) { + _on_light_state_change = callback; + } + void onLightStateChangeWithSource(void (*callback)(bool, uint8_t, esp_zb_zcl_addr_t)) { + _on_light_state_change_with_source = callback; + } + void onLightLevelChange(void (*callback)(uint8_t)) { + _on_light_level_change = callback; + } + void onLightLevelChangeWithSource(void (*callback)(uint8_t, uint8_t, esp_zb_zcl_addr_t)) { + _on_light_level_change_with_source = callback; + } + void onLightColorChange(void (*callback)(uint8_t, uint8_t, uint8_t)) { + _on_light_color_change = callback; + } + void onLightColorChangeWithSource(void (*callback)(uint8_t, uint8_t, uint8_t, uint8_t, esp_zb_zcl_addr_t)) { + _on_light_color_change_with_source = callback; + } + private: // save instance of the class in order to use it in static functions static ZigbeeColorDimmerSwitch *_instance; zb_device_params_t *_device; + espHsvColor_t _light_color_hsv; + espXyColor_t _light_color_xy; + espRgbColor_t _light_color_rgb; + + void (*_on_light_state_change)(bool); + void (*_on_light_state_change_with_source)(bool, uint8_t, esp_zb_zcl_addr_t); + void (*_on_light_level_change)(uint8_t); + void (*_on_light_level_change_with_source)(uint8_t, uint8_t, esp_zb_zcl_addr_t); + void (*_on_light_color_change)(uint8_t, uint8_t, uint8_t); + void (*_on_light_color_change_with_source)(uint8_t, uint8_t, uint8_t, uint8_t, esp_zb_zcl_addr_t); + void findEndpoint(esp_zb_zdo_match_desc_req_param_t *cmd_req); void bindCb(esp_zb_zdp_status_t zdo_status, void *user_ctx); void findCb(esp_zb_zdp_status_t zdo_status, uint16_t addr, uint8_t endpoint, void *user_ctx); static void bindCbWrapper(esp_zb_zdp_status_t zdo_status, void *user_ctx); static void findCbWrapper(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 zbAttributeRead(uint16_t cluster_id, const esp_zb_zcl_attribute_t *attribute, uint8_t src_endpoint, esp_zb_zcl_addr_t src_address) override; }; #endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeSwitch.cpp b/libraries/Zigbee/src/ep/ZigbeeSwitch.cpp index d3e3aae4cf7..a81c63aed06 100644 --- a/libraries/Zigbee/src/ep/ZigbeeSwitch.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeSwitch.cpp @@ -66,7 +66,8 @@ void ZigbeeSwitch::findCb(esp_zb_zdp_status_t zdo_status, uint16_t addr, uint8_t ZigbeeSwitch *instance = static_cast(user_ctx); if (zdo_status == ESP_ZB_ZDP_STATUS_SUCCESS) { log_d("Found light endpoint"); - esp_zb_zdo_bind_req_param_t bind_req = {0}; + esp_zb_zdo_bind_req_param_t bind_req; + memset(&bind_req, 0, sizeof(bind_req)); zb_device_params_t *light = (zb_device_params_t *)malloc(sizeof(zb_device_params_t)); light->endpoint = endpoint; light->short_addr = addr; @@ -108,7 +109,8 @@ void ZigbeeSwitch::findEndpoint(esp_zb_zdo_match_desc_req_param_t *cmd_req) { // Methods to control the light void ZigbeeSwitch::lightToggle() { if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req = {0}; + esp_zb_zcl_on_off_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(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; @@ -123,7 +125,8 @@ void ZigbeeSwitch::lightToggle() { void ZigbeeSwitch::lightToggle(uint16_t group_addr) { if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req = {0}; + esp_zb_zcl_on_off_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(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; @@ -139,7 +142,8 @@ void ZigbeeSwitch::lightToggle(uint16_t group_addr) { void ZigbeeSwitch::lightToggle(uint8_t endpoint, uint16_t short_addr) { if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req = {0}; + esp_zb_zcl_on_off_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(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; @@ -156,7 +160,8 @@ void ZigbeeSwitch::lightToggle(uint8_t endpoint, uint16_t short_addr) { void ZigbeeSwitch::lightToggle(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) { if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req = {0}; + esp_zb_zcl_on_off_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(cmd_req)); cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; cmd_req.zcl_basic_cmd.dst_endpoint = endpoint; cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT; @@ -176,7 +181,8 @@ void ZigbeeSwitch::lightToggle(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) { void ZigbeeSwitch::lightOn() { if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req = {0}; + esp_zb_zcl_on_off_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(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; @@ -191,7 +197,8 @@ void ZigbeeSwitch::lightOn() { void ZigbeeSwitch::lightOn(uint16_t group_addr) { if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req = {0}; + esp_zb_zcl_on_off_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(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; @@ -207,7 +214,8 @@ void ZigbeeSwitch::lightOn(uint16_t group_addr) { void ZigbeeSwitch::lightOn(uint8_t endpoint, uint16_t short_addr) { if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req = {0}; + esp_zb_zcl_on_off_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(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; @@ -224,7 +232,8 @@ void ZigbeeSwitch::lightOn(uint8_t endpoint, uint16_t short_addr) { void ZigbeeSwitch::lightOn(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) { if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req = {0}; + esp_zb_zcl_on_off_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(cmd_req)); cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; cmd_req.zcl_basic_cmd.dst_endpoint = endpoint; cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT; @@ -244,7 +253,8 @@ void ZigbeeSwitch::lightOn(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) { void ZigbeeSwitch::lightOff() { if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req = {0}; + esp_zb_zcl_on_off_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(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; @@ -259,7 +269,8 @@ void ZigbeeSwitch::lightOff() { void ZigbeeSwitch::lightOff(uint16_t group_addr) { if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req = {0}; + esp_zb_zcl_on_off_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(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; @@ -275,7 +286,8 @@ void ZigbeeSwitch::lightOff(uint16_t group_addr) { void ZigbeeSwitch::lightOff(uint8_t endpoint, uint16_t short_addr) { if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req = {0}; + esp_zb_zcl_on_off_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(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; @@ -292,7 +304,8 @@ void ZigbeeSwitch::lightOff(uint8_t endpoint, uint16_t short_addr) { void ZigbeeSwitch::lightOff(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) { if (_is_bound) { - esp_zb_zcl_on_off_cmd_t cmd_req = {0}; + esp_zb_zcl_on_off_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(cmd_req)); cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; cmd_req.zcl_basic_cmd.dst_endpoint = endpoint; cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT; @@ -312,7 +325,8 @@ void ZigbeeSwitch::lightOff(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) { 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 = {0}; + esp_zb_zcl_on_off_off_with_effect_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(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; @@ -328,7 +342,8 @@ void ZigbeeSwitch::lightOffWithEffect(uint8_t effect_id, uint8_t effect_variant) void ZigbeeSwitch::lightOnWithSceneRecall() { if (_is_bound) { - esp_zb_zcl_on_off_on_with_recall_global_scene_cmd_t cmd_req = {0}; + esp_zb_zcl_on_off_on_with_recall_global_scene_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(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_v("Sending 'light on with scene recall' command"); @@ -339,9 +354,11 @@ void ZigbeeSwitch::lightOnWithSceneRecall() { 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 = {0}; + esp_zb_zcl_on_off_on_with_timed_off_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(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 @@ -356,4 +373,86 @@ void ZigbeeSwitch::lightOnWithTimedOff(uint8_t on_off_control, uint16_t time_on, } } +void ZigbeeSwitch::getLightState() { + if (_is_bound) { + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(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_ON_OFF; + read_req.attr_number = 1; + uint16_t attr_id = ESP_ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID; + read_req.attr_field = &attr_id; + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_read_attr_cmd_req(&read_req); + esp_zb_lock_release(); + } +} + +void ZigbeeSwitch::getLightState(uint16_t group_addr) { + if (_is_bound) { + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(read_req)); + read_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT; + read_req.zcl_basic_cmd.src_endpoint = _endpoint; + read_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr; + read_req.clusterID = ESP_ZB_ZCL_CLUSTER_ID_ON_OFF; + read_req.attr_number = 1; + uint16_t attr_id = ESP_ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID; + read_req.attr_field = &attr_id; + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_read_attr_cmd_req(&read_req); + esp_zb_lock_release(); + } +} + +void ZigbeeSwitch::getLightState(uint8_t endpoint, uint16_t short_addr) { + if (_is_bound) { + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(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_ON_OFF; + read_req.attr_number = 1; + uint16_t attr_id = ESP_ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID; + read_req.attr_field = &attr_id; + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_read_attr_cmd_req(&read_req); + esp_zb_lock_release(); + } +} + +void ZigbeeSwitch::getLightState(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) { + if (_is_bound) { + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(read_req)); + read_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT; + read_req.zcl_basic_cmd.src_endpoint = _endpoint; + read_req.zcl_basic_cmd.dst_endpoint = endpoint; + memcpy(read_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t)); + read_req.clusterID = ESP_ZB_ZCL_CLUSTER_ID_ON_OFF; + read_req.attr_number = 1; + uint16_t attr_id = ESP_ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID; + read_req.attr_field = &attr_id; + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_read_attr_cmd_req(&read_req); + esp_zb_lock_release(); + } +} + +void ZigbeeSwitch::zbAttributeRead(uint16_t cluster_id, const esp_zb_zcl_attribute_t *attribute, uint8_t src_endpoint, esp_zb_zcl_addr_t src_address) { + if (cluster_id == ESP_ZB_ZCL_CLUSTER_ID_ON_OFF) { + if (attribute->id == ESP_ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID && attribute->data.type == ESP_ZB_ZCL_ATTR_TYPE_BOOL) { + bool light_state = attribute->data.value ? *(bool *)attribute->data.value : false; + if (_on_light_state_change) { + _on_light_state_change(light_state); + } + if (_on_light_state_change_with_source) { + _on_light_state_change_with_source(light_state, src_endpoint, src_address); + } + } + } +} #endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeSwitch.h b/libraries/Zigbee/src/ep/ZigbeeSwitch.h index f449843d85c..09c17355763 100644 --- a/libraries/Zigbee/src/ep/ZigbeeSwitch.h +++ b/libraries/Zigbee/src/ep/ZigbeeSwitch.h @@ -48,15 +48,32 @@ class ZigbeeSwitch : public ZigbeeEP { void lightOnWithTimedOff(uint8_t on_off_control, uint16_t time_on, uint16_t time_off); void lightOnWithSceneRecall(); + void getLightState(); + void getLightState(uint16_t group_addr); + void getLightState(uint8_t endpoint, uint16_t short_addr); + void getLightState(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr); + + void onLightStateChange(void (*callback)(bool)) { + _on_light_state_change = callback; + } + void onLightStateChangeWithSource(void (*callback)(bool, uint8_t, esp_zb_zcl_addr_t)) { + _on_light_state_change_with_source = callback; + } + private: // save instance of the class in order to use it in static functions static ZigbeeSwitch *_instance; zb_device_params_t *_device; + + void (*_on_light_state_change)(bool); + void (*_on_light_state_change_with_source)(bool, uint8_t, esp_zb_zcl_addr_t); + void findEndpoint(esp_zb_zdo_match_desc_req_param_t *cmd_req); void bindCb(esp_zb_zdp_status_t zdo_status, void *user_ctx); void findCb(esp_zb_zdp_status_t zdo_status, uint16_t addr, uint8_t endpoint, void *user_ctx); static void findCbWrapper(esp_zb_zdp_status_t zdo_status, uint16_t addr, uint8_t endpoint, void *user_ctx); static void bindCbWrapper(esp_zb_zdp_status_t zdo_status, void *user_ctx); + void zbAttributeRead(uint16_t cluster_id, const esp_zb_zcl_attribute_t *attribute, uint8_t src_endpoint, esp_zb_zcl_addr_t src_address) override; }; #endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeThermostat.cpp b/libraries/Zigbee/src/ep/ZigbeeThermostat.cpp index b08c256ab6b..e076aff79f0 100644 --- a/libraries/Zigbee/src/ep/ZigbeeThermostat.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeThermostat.cpp @@ -79,7 +79,8 @@ void ZigbeeThermostat::findCb(esp_zb_zdp_status_t zdo_status, uint16_t addr, uin ZigbeeThermostat *instance = static_cast(user_ctx); if (zdo_status == ESP_ZB_ZDP_STATUS_SUCCESS) { log_i("Found temperature sensor"); - esp_zb_zdo_bind_req_param_t bind_req = {0}; + esp_zb_zdo_bind_req_param_t bind_req; + memset(&bind_req, 0, sizeof(bind_req)); /* Store the information of the remote device */ zb_device_params_t *sensor = (zb_device_params_t *)malloc(sizeof(zb_device_params_t)); sensor->endpoint = endpoint; @@ -169,7 +170,8 @@ void ZigbeeThermostat::zbAttributeRead(uint16_t cluster_id, const esp_zb_zcl_att void ZigbeeThermostat::getTemperature() { /* Send "read attributes" command to all bound sensors */ - esp_zb_zcl_read_attr_cmd_t read_req = {0}; + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(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; @@ -186,7 +188,8 @@ void ZigbeeThermostat::getTemperature() { void ZigbeeThermostat::getTemperature(uint16_t group_addr) { /* Send "read attributes" command to the group */ - esp_zb_zcl_read_attr_cmd_t read_req = {0}; + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(read_req)); read_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT; read_req.zcl_basic_cmd.src_endpoint = _endpoint; read_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr; @@ -204,7 +207,8 @@ void ZigbeeThermostat::getTemperature(uint16_t group_addr) { void ZigbeeThermostat::getTemperature(uint8_t endpoint, uint16_t short_addr) { /* Send "read attributes" command to specific endpoint */ - esp_zb_zcl_read_attr_cmd_t read_req = {0}; + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(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; @@ -223,7 +227,8 @@ void ZigbeeThermostat::getTemperature(uint8_t endpoint, uint16_t short_addr) { void ZigbeeThermostat::getTemperature(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) { /* Send "read attributes" command to specific endpoint */ - esp_zb_zcl_read_attr_cmd_t read_req = {0}; + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(read_req)); read_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT; read_req.zcl_basic_cmd.src_endpoint = _endpoint; read_req.zcl_basic_cmd.dst_endpoint = endpoint; @@ -245,7 +250,8 @@ void ZigbeeThermostat::getTemperature(uint8_t endpoint, esp_zb_ieee_addr_t ieee_ void ZigbeeThermostat::getSensorSettings() { /* Send "read attributes" command to all bound sensors */ - esp_zb_zcl_read_attr_cmd_t read_req = {0}; + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(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; @@ -273,7 +279,8 @@ void ZigbeeThermostat::getSensorSettings() { void ZigbeeThermostat::getSensorSettings(uint16_t group_addr) { /* Send "read attributes" command to the group */ - esp_zb_zcl_read_attr_cmd_t read_req = {0}; + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(read_req)); read_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT; read_req.zcl_basic_cmd.src_endpoint = _endpoint; read_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr; @@ -302,7 +309,8 @@ void ZigbeeThermostat::getSensorSettings(uint16_t group_addr) { void ZigbeeThermostat::getSensorSettings(uint8_t endpoint, uint16_t short_addr) { /* Send "read attributes" command to specific endpoint */ - esp_zb_zcl_read_attr_cmd_t read_req = {0}; + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(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; @@ -332,7 +340,8 @@ void ZigbeeThermostat::getSensorSettings(uint8_t endpoint, uint16_t short_addr) void ZigbeeThermostat::getSensorSettings(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) { /* Send "read attributes" command to specific endpoint */ - esp_zb_zcl_read_attr_cmd_t read_req = {0}; + esp_zb_zcl_read_attr_cmd_t read_req; + memset(&read_req, 0, sizeof(read_req)); read_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT; read_req.zcl_basic_cmd.src_endpoint = _endpoint; read_req.zcl_basic_cmd.dst_endpoint = endpoint; @@ -365,7 +374,8 @@ void ZigbeeThermostat::getSensorSettings(uint8_t endpoint, esp_zb_ieee_addr_t ie void ZigbeeThermostat::setTemperatureReporting(uint16_t min_interval, uint16_t max_interval, float delta) { /* Send "configure report attribute" command to all bound sensors */ - esp_zb_zcl_config_report_cmd_t report_cmd = {0}; + esp_zb_zcl_config_report_cmd_t report_cmd; + memset(&report_cmd, 0, sizeof(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; @@ -392,7 +402,8 @@ void ZigbeeThermostat::setTemperatureReporting(uint16_t min_interval, uint16_t m void ZigbeeThermostat::setTemperatureReporting(uint16_t group_addr, uint16_t min_interval, uint16_t max_interval, float delta) { /* Send "configure report attribute" command to the group */ - esp_zb_zcl_config_report_cmd_t report_cmd = {0}; + esp_zb_zcl_config_report_cmd_t report_cmd; + memset(&report_cmd, 0, sizeof(report_cmd)); report_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT; report_cmd.zcl_basic_cmd.src_endpoint = _endpoint; report_cmd.zcl_basic_cmd.dst_addr_u.addr_short = group_addr; @@ -420,7 +431,8 @@ void ZigbeeThermostat::setTemperatureReporting(uint16_t group_addr, uint16_t min void ZigbeeThermostat::setTemperatureReporting(uint8_t endpoint, uint16_t short_addr, uint16_t min_interval, uint16_t max_interval, float delta) { /* Send "configure report attribute" command to specific endpoint */ - esp_zb_zcl_config_report_cmd_t report_cmd = {0}; + esp_zb_zcl_config_report_cmd_t report_cmd; + memset(&report_cmd, 0, sizeof(report_cmd)); report_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT; report_cmd.zcl_basic_cmd.src_endpoint = _endpoint; report_cmd.zcl_basic_cmd.dst_endpoint = endpoint; @@ -449,7 +461,8 @@ void ZigbeeThermostat::setTemperatureReporting(uint8_t endpoint, uint16_t short_ void ZigbeeThermostat::setTemperatureReporting(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr, uint16_t min_interval, uint16_t max_interval, float delta) { /* Send "configure report attribute" command to specific endpoint */ - esp_zb_zcl_config_report_cmd_t report_cmd = {0}; + esp_zb_zcl_config_report_cmd_t report_cmd; + memset(&report_cmd, 0, sizeof(report_cmd)); report_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT; report_cmd.zcl_basic_cmd.src_endpoint = _endpoint; report_cmd.zcl_basic_cmd.dst_endpoint = endpoint;