Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 92dd841

Browse files
P-R-O-C-H-Ypre-commit-ci-lite[bot]
andauthoredDec 9, 2024
feat(Zigbee): Recall bounded devices after reboot + IEEE address option for commands (espressif#10676)
* feat(zigbee): Recall bound devices after reboot * fix(zigbee): Add missing locks + allow printBoundDevices to Serial * fix(Zigbee): Add locks to temp sensor setReporting * fix(Zigbee): remove unnecessary space in formatting * fix(Zigbee): proper parameter in printBoundDevices * feat(Zigbee): factory reset when removed from network * fix(zigbee): Update comment * fix(zigbee): fix serial and add missing factoryReset to example * ci(pre-commit): Apply automatic fixes --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
1 parent e159bf6 commit 92dd841

File tree

12 files changed

+376
-59
lines changed

12 files changed

+376
-59
lines changed
 

‎libraries/Zigbee/examples/Zigbee_Color_Dimmer_Switch/Zigbee_Color_Dimmer_Switch.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,6 @@ void loop() {
145145
static uint32_t last_print = 0;
146146
if (millis() - last_print > 30000) {
147147
last_print = millis();
148-
zbSwitch.printBoundDevices();
148+
zbSwitch.printBoundDevices(Serial);
149149
}
150150
}

‎libraries/Zigbee/examples/Zigbee_On_Off_Switch/Zigbee_On_Off_Switch.ino

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -138,17 +138,16 @@ void setup() {
138138
delay(500);
139139
}
140140

141-
// Optional: read manufacturer and model name from the bound light
141+
// Optional: List all bound devices and read manufacturer and model name
142142
std::list<zb_device_params_t *> boundLights = zbSwitch.getBoundDevices();
143-
//List all bound lights
144143
for (const auto &device : boundLights) {
145-
Serial.printf("Device on endpoint %d, short address: 0x%x\n", device->endpoint, device->short_addr);
144+
Serial.printf("Device on endpoint %d, short address: 0x%x\r\n", device->endpoint, device->short_addr);
146145
Serial.printf(
147-
"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],
148-
device->ieee_addr[4], device->ieee_addr[5], device->ieee_addr[6], device->ieee_addr[7]
146+
"IEEE Address: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\r\n", device->ieee_addr[7], device->ieee_addr[6], device->ieee_addr[5], device->ieee_addr[4],
147+
device->ieee_addr[3], device->ieee_addr[2], device->ieee_addr[1], device->ieee_addr[0]
149148
);
150-
Serial.printf("Light manufacturer: %s", zbSwitch.readManufacturer(device->endpoint, device->short_addr));
151-
Serial.printf("Light model: %s", zbSwitch.readModel(device->endpoint, device->short_addr));
149+
Serial.printf("Light manufacturer: %s\r\n", zbSwitch.readManufacturer(device->endpoint, device->short_addr, device->ieee_addr));
150+
Serial.printf("Light model: %s\r\n", zbSwitch.readModel(device->endpoint, device->short_addr, device->ieee_addr));
152151
}
153152

154153
Serial.println();
@@ -191,6 +190,6 @@ void loop() {
191190
static uint32_t lastPrint = 0;
192191
if (millis() - lastPrint > 10000) {
193192
lastPrint = millis();
194-
zbSwitch.printBoundDevices();
193+
zbSwitch.printBoundDevices(Serial);
195194
}
196195
}

‎libraries/Zigbee/examples/Zigbee_Temp_Hum_Sensor_Sleepy/Zigbee_Temp_Hum_Sensor_Sleepy.ino

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ void loop() {
128128
// If key pressed for more than 3secs, factory reset Zigbee and reboot
129129
Serial.println("Resetting Zigbee to factory and rebooting in 1s.");
130130
delay(1000);
131+
Zigbee.factoryReset();
131132
}
132133
}
133134
}

‎libraries/Zigbee/src/ZigbeeCore.cpp

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct) {
243243
} else {
244244
Zigbee._connected = true;
245245
}
246+
Zigbee.searchBindings();
246247
}
247248
} else {
248249
/* commissioning failed */
@@ -309,7 +310,6 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct) {
309310
Bit 6 – Security capability
310311
Bit 7 – Reserved
311312
*/
312-
313313
// for each endpoint in the list call the findEndpoint function if not bounded or allowed to bind multiple devices
314314
for (std::list<ZigbeeEP *>::iterator it = Zigbee.ep_objects.begin(); it != Zigbee.ep_objects.end(); ++it) {
315315
if (!(*it)->bound() || (*it)->epAllowMultipleBinding()) {
@@ -329,6 +329,12 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct) {
329329
}
330330
}
331331
break;
332+
case ESP_ZB_ZDO_SIGNAL_LEAVE: // End Device + Router
333+
// Device was removed from the network, factory reset the device
334+
if ((zigbee_role_t)Zigbee.getRole() != ZIGBEE_COORDINATOR) {
335+
Zigbee.factoryReset();
336+
}
337+
break;
332338
default: log_v("ZDO signal: %s (0x%x), status: %s", esp_zb_zdo_signal_to_string(sig_type), sig_type, esp_err_to_name(err_status)); break;
333339
}
334340
}
@@ -391,6 +397,75 @@ void ZigbeeCore::scanDelete() {
391397
_scan_status = ZB_SCAN_FAILED;
392398
}
393399

400+
// Recall bounded devices from the binding table after reboot
401+
void ZigbeeCore::bindingTableCb(const esp_zb_zdo_binding_table_info_t *table_info, void *user_ctx) {
402+
bool done = true;
403+
esp_zb_zdo_mgmt_bind_param_t *req = (esp_zb_zdo_mgmt_bind_param_t *)user_ctx;
404+
esp_zb_zdp_status_t zdo_status = (esp_zb_zdp_status_t)table_info->status;
405+
log_d("Binding table callback for address 0x%04x with status %d", req->dst_addr, zdo_status);
406+
if (zdo_status == ESP_ZB_ZDP_STATUS_SUCCESS) {
407+
// Print binding table log simple
408+
log_d("Binding table info: total %d, index %d, count %d", table_info->total, table_info->index, table_info->count);
409+
410+
if (table_info->total == 0) {
411+
log_d("No binding table entries found");
412+
free(req);
413+
return;
414+
}
415+
416+
esp_zb_zdo_binding_table_record_t *record = table_info->record;
417+
for (int i = 0; i < table_info->count; i++) {
418+
log_d(
419+
"Binding table record: src_endp %d, dst_endp %d, cluster_id 0x%04x, dst_addr_mode %d", record->src_endp, record->dst_endp, record->cluster_id,
420+
record->dst_addr_mode
421+
);
422+
423+
zb_device_params_t *device = (zb_device_params_t *)calloc(1, sizeof(zb_device_params_t));
424+
device->endpoint = record->dst_endp;
425+
if (record->dst_addr_mode == ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT || record->dst_addr_mode == ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT) {
426+
device->short_addr = record->dst_address.addr_short;
427+
} else { //ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT
428+
memcpy(device->ieee_addr, record->dst_address.addr_long, sizeof(esp_zb_ieee_addr_t));
429+
}
430+
431+
// Add to list of bound devices of proper endpoint
432+
for (std::list<ZigbeeEP *>::iterator it = Zigbee.ep_objects.begin(); it != Zigbee.ep_objects.end(); ++it) {
433+
if ((*it)->getEndpoint() == record->src_endp) {
434+
(*it)->addBoundDevice(device);
435+
log_d(
436+
"Device bound to EP %d -> device endpoint: %d, short addr: 0x%04x, ieee addr: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", record->src_endp,
437+
device->endpoint, device->short_addr, device->ieee_addr[7], device->ieee_addr[6], device->ieee_addr[5], device->ieee_addr[4], device->ieee_addr[3],
438+
device->ieee_addr[2], device->ieee_addr[1], device->ieee_addr[0]
439+
);
440+
}
441+
}
442+
record = record->next;
443+
}
444+
445+
// Continue reading the binding table
446+
if (table_info->index + table_info->count < table_info->total) {
447+
/* There are unreported binding table entries, request for them. */
448+
req->start_index = table_info->index + table_info->count;
449+
esp_zb_zdo_binding_table_req(req, bindingTableCb, req);
450+
done = false;
451+
}
452+
}
453+
454+
if (done) {
455+
// Print bound devices
456+
log_d("Filling bounded devices finished");
457+
free(req);
458+
}
459+
}
460+
461+
void ZigbeeCore::searchBindings() {
462+
esp_zb_zdo_mgmt_bind_param_t *mb_req = (esp_zb_zdo_mgmt_bind_param_t *)malloc(sizeof(esp_zb_zdo_mgmt_bind_param_t));
463+
mb_req->dst_addr = esp_zb_get_short_address();
464+
mb_req->start_index = 0;
465+
log_d("Requesting binding table for address 0x%04x", mb_req->dst_addr);
466+
esp_zb_zdo_binding_table_req(mb_req, bindingTableCb, (void *)mb_req);
467+
}
468+
394469
// Function to convert enum value to string
395470
const char *ZigbeeCore::getDeviceTypeString(esp_zb_ha_standard_devices_t deviceId) {
396471
switch (deviceId) {

‎libraries/Zigbee/src/ZigbeeCore.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ class ZigbeeCore {
8080
bool zigbeeInit(esp_zb_cfg_t *zb_cfg, bool erase_nvs);
8181
static void scanCompleteCallback(esp_zb_zdp_status_t zdo_status, uint8_t count, esp_zb_network_descriptor_t *nwk_descriptor);
8282
const char *getDeviceTypeString(esp_zb_ha_standard_devices_t deviceId);
83+
void searchBindings();
84+
static void bindingTableCb(const esp_zb_zdo_binding_table_info_t *table_info, void *user_ctx);
8385

8486
public:
8587
ZigbeeCore();

‎libraries/Zigbee/src/ZigbeeEP.cpp

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include "esp_zigbee_cluster.h"
88
#include "zcl/esp_zigbee_zcl_power_config.h"
99

10+
#define ZB_CMD_TIMEOUT 10000 // 10 seconds
11+
1012
bool ZigbeeEP::_is_bound = false;
1113
bool ZigbeeEP::_allow_multiple_binding = false;
1214

@@ -112,13 +114,20 @@ void ZigbeeEP::reportBatteryPercentage() {
112114
log_v("Battery percentage reported");
113115
}
114116

115-
char *ZigbeeEP::readManufacturer(uint8_t endpoint, uint16_t short_addr) {
117+
char *ZigbeeEP::readManufacturer(uint8_t endpoint, uint16_t short_addr, esp_zb_ieee_addr_t ieee_addr) {
116118
/* Read peer Manufacture Name & Model Identifier */
117119
esp_zb_zcl_read_attr_cmd_t read_req;
118-
read_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
120+
121+
if (short_addr != 0) {
122+
read_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
123+
read_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr;
124+
} else {
125+
read_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT;
126+
memcpy(read_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t));
127+
}
128+
119129
read_req.zcl_basic_cmd.src_endpoint = _endpoint;
120130
read_req.zcl_basic_cmd.dst_endpoint = endpoint;
121-
read_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr;
122131
read_req.clusterID = ESP_ZB_ZCL_CLUSTER_ID_BASIC;
123132

124133
uint16_t attributes[] = {
@@ -130,22 +139,31 @@ char *ZigbeeEP::readManufacturer(uint8_t endpoint, uint16_t short_addr) {
130139
// clear read manufacturer
131140
_read_manufacturer = nullptr;
132141

142+
esp_zb_lock_acquire(portMAX_DELAY);
133143
esp_zb_zcl_read_attr_cmd_req(&read_req);
144+
esp_zb_lock_release();
134145

135146
//Wait for response or timeout
136-
if (xSemaphoreTake(lock, portMAX_DELAY) != pdTRUE) {
147+
if (xSemaphoreTake(lock, ZB_CMD_TIMEOUT) != pdTRUE) {
137148
log_e("Error while reading manufacturer");
138149
}
139150
return _read_manufacturer;
140151
}
141152

142-
char *ZigbeeEP::readModel(uint8_t endpoint, uint16_t short_addr) {
153+
char *ZigbeeEP::readModel(uint8_t endpoint, uint16_t short_addr, esp_zb_ieee_addr_t ieee_addr) {
143154
/* Read peer Manufacture Name & Model Identifier */
144155
esp_zb_zcl_read_attr_cmd_t read_req;
145-
read_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
156+
157+
if (short_addr != 0) {
158+
read_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
159+
read_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr;
160+
} else {
161+
read_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT;
162+
memcpy(read_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t));
163+
}
164+
146165
read_req.zcl_basic_cmd.src_endpoint = _endpoint;
147166
read_req.zcl_basic_cmd.dst_endpoint = endpoint;
148-
read_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr;
149167
read_req.clusterID = ESP_ZB_ZCL_CLUSTER_ID_BASIC;
150168

151169
uint16_t attributes[] = {
@@ -157,11 +175,12 @@ char *ZigbeeEP::readModel(uint8_t endpoint, uint16_t short_addr) {
157175
// clear read model
158176
_read_model = nullptr;
159177

178+
esp_zb_lock_acquire(portMAX_DELAY);
160179
esp_zb_zcl_read_attr_cmd_req(&read_req);
180+
esp_zb_lock_release();
161181

162182
//Wait for response or timeout
163-
//Semaphore take
164-
if (xSemaphoreTake(lock, portMAX_DELAY) != pdTRUE) {
183+
if (xSemaphoreTake(lock, ZB_CMD_TIMEOUT) != pdTRUE) {
165184
log_e("Error while reading model");
166185
}
167186
return _read_model;
@@ -171,8 +190,23 @@ void ZigbeeEP::printBoundDevices() {
171190
log_i("Bound devices:");
172191
for ([[maybe_unused]]
173192
const auto &device : _bound_devices) {
174-
log_i("Device on endpoint %d, short address: 0x%x", device->endpoint, device->short_addr);
175-
print_ieee_addr(device->ieee_addr);
193+
log_i(
194+
"Device on endpoint %d, short address: 0x%x, ieee address: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", device->endpoint, device->short_addr,
195+
device->ieee_addr[7], device->ieee_addr[6], device->ieee_addr[5], device->ieee_addr[4], device->ieee_addr[3], device->ieee_addr[2], device->ieee_addr[1],
196+
device->ieee_addr[0]
197+
);
198+
}
199+
}
200+
201+
void ZigbeeEP::printBoundDevices(Print &print) {
202+
print.println("Bound devices:");
203+
for ([[maybe_unused]]
204+
const auto &device : _bound_devices) {
205+
print.printf(
206+
"Device on endpoint %d, short address: 0x%x, ieee address: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\r\n", device->endpoint, device->short_addr,
207+
device->ieee_addr[7], device->ieee_addr[6], device->ieee_addr[5], device->ieee_addr[4], device->ieee_addr[3], device->ieee_addr[2], device->ieee_addr[1],
208+
device->ieee_addr[0]
209+
);
176210
}
177211
}
178212

‎libraries/Zigbee/src/ZigbeeEP.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99

1010
/* Useful defines */
1111
#define ZB_ARRAY_LENTH(arr) (sizeof(arr) / sizeof(arr[0]))
12-
#define print_ieee_addr(addr) \
13-
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])
1412
#define XYZ_TO_RGB(X, Y, Z, r, g, b) \
1513
{ \
1614
r = (float)(3.240479 * (X) - 1.537150 * (Y) - 0.498535 * (Z)); \
@@ -69,6 +67,8 @@ class ZigbeeEP {
6967
}
7068

7169
void printBoundDevices();
70+
void printBoundDevices(Print &print);
71+
7272
std::list<zb_device_params_t *> getBoundDevices() const {
7373
return _bound_devices;
7474
}
@@ -87,8 +87,8 @@ class ZigbeeEP {
8787
void reportBatteryPercentage();
8888

8989
// Methods to read manufacturer and model name from selected endpoint and short address
90-
char *readManufacturer(uint8_t endpoint, uint16_t short_addr);
91-
char *readModel(uint8_t endpoint, uint16_t short_addr);
90+
char *readManufacturer(uint8_t endpoint, uint16_t short_addr, esp_zb_ieee_addr_t ieee_addr);
91+
char *readModel(uint8_t endpoint, uint16_t short_addr, esp_zb_ieee_addr_t ieee_addr);
9292

9393
bool epAllowMultipleBinding() {
9494
return _allow_multiple_binding;
@@ -108,7 +108,6 @@ class ZigbeeEP {
108108
}
109109

110110
private:
111-
static bool _allow_multiple_binding;
112111
char *_read_manufacturer;
113112
char *_read_model;
114113
void (*_on_identify)(uint16_t time);
@@ -119,10 +118,15 @@ class ZigbeeEP {
119118
esp_zb_endpoint_config_t _ep_config;
120119
esp_zb_cluster_list_t *_cluster_list;
121120
static bool _is_bound;
121+
static bool _allow_multiple_binding;
122122
std::list<zb_device_params_t *> _bound_devices;
123123
SemaphoreHandle_t lock;
124124
zb_power_source_t _power_source;
125125

126+
void addBoundDevice(zb_device_params_t *device) {
127+
_bound_devices.push_back(device);
128+
_is_bound = true;
129+
}
126130
friend class ZigbeeCore;
127131
};
128132

‎libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.cpp

Lines changed: 127 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,10 @@ void ZigbeeColorDimmerSwitch::lightToggle() {
9898
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
9999
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
100100
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_TOGGLE_ID;
101-
log_i("Sending 'light toggle' command");
102-
//esp_zb_lock_acquire(portMAX_DELAY);
101+
log_v("Sending 'light toggle' command");
102+
esp_zb_lock_acquire(portMAX_DELAY);
103103
esp_zb_zcl_on_off_cmd_req(&cmd_req);
104-
//esp_zb_lock_release();
104+
esp_zb_lock_release();
105105
} else {
106106
log_e("Light not bound");
107107
}
@@ -114,7 +114,7 @@ void ZigbeeColorDimmerSwitch::lightToggle(uint16_t group_addr) {
114114
cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr;
115115
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT;
116116
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_TOGGLE_ID;
117-
log_i("Sending 'light toggle' command to group address 0x%x", group_addr);
117+
log_v("Sending 'light toggle' command to group address 0x%x", group_addr);
118118
esp_zb_lock_acquire(portMAX_DELAY);
119119
esp_zb_zcl_on_off_cmd_req(&cmd_req);
120120
esp_zb_lock_release();
@@ -131,7 +131,27 @@ void ZigbeeColorDimmerSwitch::lightToggle(uint8_t endpoint, uint16_t short_addr)
131131
cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr;
132132
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
133133
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_TOGGLE_ID;
134-
log_i("Sending 'light toggle' command to endpoint %d, address 0x%x", endpoint, short_addr);
134+
log_v("Sending 'light toggle' command to endpoint %d, address 0x%x", endpoint, short_addr);
135+
esp_zb_lock_acquire(portMAX_DELAY);
136+
esp_zb_zcl_on_off_cmd_req(&cmd_req);
137+
esp_zb_lock_release();
138+
} else {
139+
log_e("Light not bound");
140+
}
141+
}
142+
143+
void ZigbeeColorDimmerSwitch::lightToggle(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) {
144+
if (_is_bound) {
145+
esp_zb_zcl_on_off_cmd_t cmd_req;
146+
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
147+
cmd_req.zcl_basic_cmd.dst_endpoint = endpoint;
148+
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT;
149+
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_TOGGLE_ID;
150+
memcpy(cmd_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t));
151+
log_v(
152+
"Sending 'light toggle' command to endpoint %d, ieee address %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", endpoint, ieee_addr[7], ieee_addr[6], ieee_addr[5],
153+
ieee_addr[4], ieee_addr[3], ieee_addr[2], ieee_addr[1], ieee_addr[0]
154+
);
135155
esp_zb_lock_acquire(portMAX_DELAY);
136156
esp_zb_zcl_on_off_cmd_req(&cmd_req);
137157
esp_zb_lock_release();
@@ -146,7 +166,7 @@ void ZigbeeColorDimmerSwitch::lightOn() {
146166
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
147167
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
148168
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_ON_ID;
149-
log_i("Sending 'light on' command");
169+
log_v("Sending 'light on' command");
150170
esp_zb_lock_acquire(portMAX_DELAY);
151171
esp_zb_zcl_on_off_cmd_req(&cmd_req);
152172
esp_zb_lock_release();
@@ -162,7 +182,7 @@ void ZigbeeColorDimmerSwitch::lightOn(uint16_t group_addr) {
162182
cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr;
163183
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT;
164184
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_ON_ID;
165-
log_i("Sending 'light on' command to group address 0x%x", group_addr);
185+
log_v("Sending 'light on' command to group address 0x%x", group_addr);
166186
esp_zb_lock_acquire(portMAX_DELAY);
167187
esp_zb_zcl_on_off_cmd_req(&cmd_req);
168188
esp_zb_lock_release();
@@ -179,7 +199,27 @@ void ZigbeeColorDimmerSwitch::lightOn(uint8_t endpoint, uint16_t short_addr) {
179199
cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr;
180200
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
181201
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_ON_ID;
182-
log_i("Sending 'light on' command to endpoint %d, address 0x%x", endpoint, short_addr);
202+
log_v("Sending 'light on' command to endpoint %d, address 0x%x", endpoint, short_addr);
203+
esp_zb_lock_acquire(portMAX_DELAY);
204+
esp_zb_zcl_on_off_cmd_req(&cmd_req);
205+
esp_zb_lock_release();
206+
} else {
207+
log_e("Light not bound");
208+
}
209+
}
210+
211+
void ZigbeeColorDimmerSwitch::lightOn(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) {
212+
if (_is_bound) {
213+
esp_zb_zcl_on_off_cmd_t cmd_req;
214+
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
215+
cmd_req.zcl_basic_cmd.dst_endpoint = endpoint;
216+
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT;
217+
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_ON_ID;
218+
memcpy(cmd_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t));
219+
log_v(
220+
"Sending 'light on' command to endpoint %d, ieee address %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", endpoint, ieee_addr[7], ieee_addr[6], ieee_addr[5],
221+
ieee_addr[4], ieee_addr[3], ieee_addr[2], ieee_addr[1], ieee_addr[0]
222+
);
183223
esp_zb_lock_acquire(portMAX_DELAY);
184224
esp_zb_zcl_on_off_cmd_req(&cmd_req);
185225
esp_zb_lock_release();
@@ -194,7 +234,7 @@ void ZigbeeColorDimmerSwitch::lightOff() {
194234
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
195235
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
196236
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_OFF_ID;
197-
log_i("Sending 'light off' command");
237+
log_v("Sending 'light off' command");
198238
esp_zb_lock_acquire(portMAX_DELAY);
199239
esp_zb_zcl_on_off_cmd_req(&cmd_req);
200240
esp_zb_lock_release();
@@ -210,7 +250,7 @@ void ZigbeeColorDimmerSwitch::lightOff(uint16_t group_addr) {
210250
cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr;
211251
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT;
212252
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_OFF_ID;
213-
log_i("Sending 'light off' command to group address 0x%x", group_addr);
253+
log_v("Sending 'light off' command to group address 0x%x", group_addr);
214254
esp_zb_lock_acquire(portMAX_DELAY);
215255
esp_zb_zcl_on_off_cmd_req(&cmd_req);
216256
esp_zb_lock_release();
@@ -227,7 +267,27 @@ void ZigbeeColorDimmerSwitch::lightOff(uint8_t endpoint, uint16_t short_addr) {
227267
cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr;
228268
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
229269
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_OFF_ID;
230-
log_i("Sending 'light off' command to endpoint %d, address 0x%x", endpoint, short_addr);
270+
log_v("Sending 'light off' command to endpoint %d, address 0x%x", endpoint, short_addr);
271+
esp_zb_lock_acquire(portMAX_DELAY);
272+
esp_zb_zcl_on_off_cmd_req(&cmd_req);
273+
esp_zb_lock_release();
274+
} else {
275+
log_e("Light not bound");
276+
}
277+
}
278+
279+
void ZigbeeColorDimmerSwitch::lightOff(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) {
280+
if (_is_bound) {
281+
esp_zb_zcl_on_off_cmd_t cmd_req;
282+
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
283+
cmd_req.zcl_basic_cmd.dst_endpoint = endpoint;
284+
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT;
285+
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_OFF_ID;
286+
memcpy(cmd_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t));
287+
log_v(
288+
"Sending 'light off' command to endpoint %d, ieee address %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", endpoint, ieee_addr[7], ieee_addr[6], ieee_addr[5],
289+
ieee_addr[4], ieee_addr[3], ieee_addr[2], ieee_addr[1], ieee_addr[0]
290+
);
231291
esp_zb_lock_acquire(portMAX_DELAY);
232292
esp_zb_zcl_on_off_cmd_req(&cmd_req);
233293
esp_zb_lock_release();
@@ -243,7 +303,7 @@ void ZigbeeColorDimmerSwitch::lightOffWithEffect(uint8_t effect_id, uint8_t effe
243303
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
244304
cmd_req.effect_id = effect_id;
245305
cmd_req.effect_variant = effect_variant;
246-
log_i("Sending 'light off with effect' command");
306+
log_v("Sending 'light off with effect' command");
247307
esp_zb_lock_acquire(portMAX_DELAY);
248308
esp_zb_zcl_on_off_off_with_effect_cmd_req(&cmd_req);
249309
esp_zb_lock_release();
@@ -257,7 +317,7 @@ void ZigbeeColorDimmerSwitch::lightOnWithSceneRecall() {
257317
esp_zb_zcl_on_off_on_with_recall_global_scene_cmd_t cmd_req;
258318
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
259319
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
260-
log_i("Sending 'light on with scene recall' command");
320+
log_v("Sending 'light on with scene recall' command");
261321
esp_zb_lock_acquire(portMAX_DELAY);
262322
esp_zb_zcl_on_off_on_with_recall_global_scene_cmd_req(&cmd_req);
263323
esp_zb_lock_release();
@@ -274,7 +334,7 @@ void ZigbeeColorDimmerSwitch::lightOnWithTimedOff(uint8_t on_off_control, uint16
274334
cmd_req.on_off_control = on_off_control; //TODO: Test how it works, then maybe change API
275335
cmd_req.on_time = time_on;
276336
cmd_req.off_wait_time = time_off;
277-
log_i("Sending 'light on with time off' command");
337+
log_v("Sending 'light on with time off' command");
278338
esp_zb_lock_acquire(portMAX_DELAY);
279339
esp_zb_zcl_on_off_on_with_timed_off_cmd_req(&cmd_req);
280340
esp_zb_lock_release();
@@ -290,7 +350,7 @@ void ZigbeeColorDimmerSwitch::setLightLevel(uint8_t level) {
290350
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
291351
cmd_req.level = level;
292352
cmd_req.transition_time = 0xffff;
293-
log_i("Sending 'set light level' command");
353+
log_v("Sending 'set light level' command");
294354
esp_zb_lock_acquire(portMAX_DELAY);
295355
esp_zb_zcl_level_move_to_level_cmd_req(&cmd_req);
296356
esp_zb_lock_release();
@@ -307,7 +367,7 @@ void ZigbeeColorDimmerSwitch::setLightLevel(uint8_t level, uint16_t group_addr)
307367
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT;
308368
cmd_req.level = level;
309369
cmd_req.transition_time = 0xffff;
310-
log_i("Sending 'set light level' command to group address 0x%x", group_addr);
370+
log_v("Sending 'set light level' command to group address 0x%x", group_addr);
311371
esp_zb_lock_acquire(portMAX_DELAY);
312372
esp_zb_zcl_level_move_to_level_cmd_req(&cmd_req);
313373
esp_zb_lock_release();
@@ -325,7 +385,28 @@ void ZigbeeColorDimmerSwitch::setLightLevel(uint8_t level, uint8_t endpoint, uin
325385
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
326386
cmd_req.level = level;
327387
cmd_req.transition_time = 0xffff;
328-
log_i("Sending 'set light level' command to endpoint %d, address 0x%x", endpoint, short_addr);
388+
log_v("Sending 'set light level' command to endpoint %d, address 0x%x", endpoint, short_addr);
389+
esp_zb_lock_acquire(portMAX_DELAY);
390+
esp_zb_zcl_level_move_to_level_cmd_req(&cmd_req);
391+
esp_zb_lock_release();
392+
} else {
393+
log_e("Light not bound");
394+
}
395+
}
396+
397+
void ZigbeeColorDimmerSwitch::setLightLevel(uint8_t level, uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) {
398+
if (_is_bound) {
399+
esp_zb_zcl_move_to_level_cmd_t cmd_req;
400+
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
401+
cmd_req.zcl_basic_cmd.dst_endpoint = endpoint;
402+
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT;
403+
memcpy(cmd_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t));
404+
cmd_req.level = level;
405+
cmd_req.transition_time = 0xffff;
406+
log_v(
407+
"Sending 'set light level' command to endpoint %d, ieee address %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", endpoint, ieee_addr[7], ieee_addr[6],
408+
ieee_addr[5], ieee_addr[4], ieee_addr[3], ieee_addr[2], ieee_addr[1], ieee_addr[0]
409+
);
329410
esp_zb_lock_acquire(portMAX_DELAY);
330411
esp_zb_zcl_level_move_to_level_cmd_req(&cmd_req);
331412
esp_zb_lock_release();
@@ -346,7 +427,7 @@ void ZigbeeColorDimmerSwitch::setLightColor(uint8_t red, uint8_t green, uint8_t
346427
cmd_req.color_x = color_x;
347428
cmd_req.color_y = color_y;
348429
cmd_req.transition_time = 0;
349-
log_i("Sending 'set light color' command");
430+
log_v("Sending 'set light color' command");
350431
esp_zb_lock_acquire(portMAX_DELAY);
351432
esp_zb_zcl_color_move_to_color_cmd_req(&cmd_req);
352433
esp_zb_lock_release();
@@ -368,7 +449,7 @@ void ZigbeeColorDimmerSwitch::setLightColor(uint8_t red, uint8_t green, uint8_t
368449
cmd_req.color_x = color_x;
369450
cmd_req.color_y = color_y;
370451
cmd_req.transition_time = 0;
371-
log_i("Sending 'set light color' command to group address 0x%x", group_addr);
452+
log_v("Sending 'set light color' command to group address 0x%x", group_addr);
372453
esp_zb_lock_acquire(portMAX_DELAY);
373454
esp_zb_zcl_color_move_to_color_cmd_req(&cmd_req);
374455
esp_zb_lock_release();
@@ -391,7 +472,33 @@ void ZigbeeColorDimmerSwitch::setLightColor(uint8_t red, uint8_t green, uint8_t
391472
cmd_req.color_x = color_x;
392473
cmd_req.color_y = color_y;
393474
cmd_req.transition_time = 0;
394-
log_i("Sending 'set light color' command to endpoint %d, address 0x%x", endpoint, short_addr);
475+
log_v("Sending 'set light color' command to endpoint %d, address 0x%x", endpoint, short_addr);
476+
esp_zb_lock_acquire(portMAX_DELAY);
477+
esp_zb_zcl_color_move_to_color_cmd_req(&cmd_req);
478+
esp_zb_lock_release();
479+
} else {
480+
log_e("Light not bound");
481+
}
482+
}
483+
484+
void ZigbeeColorDimmerSwitch::setLightColor(uint8_t red, uint8_t green, uint8_t blue, uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) {
485+
if (_is_bound) {
486+
//Convert RGB to XY
487+
uint16_t color_x, color_y;
488+
calculateXY(red, green, blue, color_x, color_y);
489+
490+
esp_zb_zcl_color_move_to_color_cmd_t cmd_req;
491+
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
492+
cmd_req.zcl_basic_cmd.dst_endpoint = endpoint;
493+
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT;
494+
memcpy(cmd_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t));
495+
cmd_req.color_x = color_x;
496+
cmd_req.color_y = color_y;
497+
cmd_req.transition_time = 0;
498+
log_v(
499+
"Sending 'set light color' command to endpoint %d, ieee address %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", endpoint, ieee_addr[7], ieee_addr[6],
500+
ieee_addr[5], ieee_addr[4], ieee_addr[3], ieee_addr[2], ieee_addr[1], ieee_addr[0]
501+
);
395502
esp_zb_lock_acquire(portMAX_DELAY);
396503
esp_zb_zcl_color_move_to_color_cmd_req(&cmd_req);
397504
esp_zb_lock_release();

‎libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,17 @@ class ZigbeeColorDimmerSwitch : public ZigbeeEP {
1818
void lightToggle();
1919
void lightToggle(uint16_t group_addr);
2020
void lightToggle(uint8_t endpoint, uint16_t short_addr);
21+
void lightToggle(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr);
2122

2223
void lightOn();
2324
void lightOn(uint16_t group_addr);
2425
void lightOn(uint8_t endpoint, uint16_t short_addr);
26+
void lightOn(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr);
2527

2628
void lightOff();
2729
void lightOff(uint16_t group_addr);
2830
void lightOff(uint8_t endpoint, uint16_t short_addr);
31+
void lightOff(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr);
2932

3033
void lightOffWithEffect(uint8_t effect_id, uint8_t effect_variant);
3134
void lightOnWithTimedOff(uint8_t on_off_control, uint16_t time_on, uint16_t time_off);
@@ -34,10 +37,12 @@ class ZigbeeColorDimmerSwitch : public ZigbeeEP {
3437
void setLightLevel(uint8_t level);
3538
void setLightLevel(uint8_t level, uint16_t group_addr);
3639
void setLightLevel(uint8_t level, uint8_t endpoint, uint16_t short_addr);
40+
void setLightLevel(uint8_t level, uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr);
3741

3842
void setLightColor(uint8_t red, uint8_t green, uint8_t blue);
3943
void setLightColor(uint8_t red, uint8_t green, uint8_t blue, uint16_t group_addr);
4044
void setLightColor(uint8_t red, uint8_t green, uint8_t blue, uint8_t endpoint, uint16_t short_addr);
45+
void setLightColor(uint8_t red, uint8_t green, uint8_t blue, uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr);
4146

4247
private:
4348
// save instance of the class in order to use it in static functions

‎libraries/Zigbee/src/ep/ZigbeeSwitch.cpp

Lines changed: 96 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ void ZigbeeSwitch::findEndpoint(esp_zb_zdo_match_desc_req_param_t *cmd_req) {
5959
.num_out_clusters = 1,
6060
.cluster_list = cluster_list,
6161
};
62-
6362
esp_zb_zdo_match_cluster(&on_off_req, findCb, &_endpoint);
6463
}
6564

@@ -70,8 +69,10 @@ void ZigbeeSwitch::lightToggle() {
7069
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
7170
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
7271
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_TOGGLE_ID;
73-
log_i("Sending 'light toggle' command");
72+
log_v("Sending 'light toggle' command");
73+
esp_zb_lock_acquire(portMAX_DELAY);
7474
esp_zb_zcl_on_off_cmd_req(&cmd_req);
75+
esp_zb_lock_release();
7576
} else {
7677
log_e("Light not bound");
7778
}
@@ -84,8 +85,10 @@ void ZigbeeSwitch::lightToggle(uint16_t group_addr) {
8485
cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr;
8586
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT;
8687
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_TOGGLE_ID;
87-
log_i("Sending 'light toggle' command to group address 0x%x", group_addr);
88+
log_v("Sending 'light toggle' command to group address 0x%x", group_addr);
89+
esp_zb_lock_acquire(portMAX_DELAY);
8890
esp_zb_zcl_on_off_cmd_req(&cmd_req);
91+
esp_zb_lock_release();
8992
} else {
9093
log_e("Light not bound");
9194
}
@@ -99,8 +102,30 @@ void ZigbeeSwitch::lightToggle(uint8_t endpoint, uint16_t short_addr) {
99102
cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr;
100103
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
101104
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_TOGGLE_ID;
102-
log_i("Sending 'light toggle' command to endpoint %d, address 0x%x", endpoint, short_addr);
105+
log_v("Sending 'light toggle' command to endpoint %d, address 0x%x", endpoint, short_addr);
106+
esp_zb_lock_acquire(portMAX_DELAY);
103107
esp_zb_zcl_on_off_cmd_req(&cmd_req);
108+
esp_zb_lock_release();
109+
} else {
110+
log_e("Light not bound");
111+
}
112+
}
113+
114+
void ZigbeeSwitch::lightToggle(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) {
115+
if (_is_bound) {
116+
esp_zb_zcl_on_off_cmd_t cmd_req;
117+
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
118+
cmd_req.zcl_basic_cmd.dst_endpoint = endpoint;
119+
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT;
120+
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_TOGGLE_ID;
121+
memcpy(cmd_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t));
122+
log_v(
123+
"Sending 'light toggle' command to endpoint %d, ieee address %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", endpoint, ieee_addr[7], ieee_addr[6], ieee_addr[5],
124+
ieee_addr[4], ieee_addr[3], ieee_addr[2], ieee_addr[1], ieee_addr[0]
125+
);
126+
esp_zb_lock_acquire(portMAX_DELAY);
127+
esp_zb_zcl_on_off_cmd_req(&cmd_req);
128+
esp_zb_lock_release();
104129
} else {
105130
log_e("Light not bound");
106131
}
@@ -112,8 +137,10 @@ void ZigbeeSwitch::lightOn() {
112137
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
113138
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
114139
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_ON_ID;
115-
log_i("Sending 'light on' command");
140+
log_v("Sending 'light on' command");
141+
esp_zb_lock_acquire(portMAX_DELAY);
116142
esp_zb_zcl_on_off_cmd_req(&cmd_req);
143+
esp_zb_lock_release();
117144
} else {
118145
log_e("Light not bound");
119146
}
@@ -126,8 +153,10 @@ void ZigbeeSwitch::lightOn(uint16_t group_addr) {
126153
cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr;
127154
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT;
128155
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_ON_ID;
129-
log_i("Sending 'light on' command to group address 0x%x", group_addr);
156+
log_v("Sending 'light on' command to group address 0x%x", group_addr);
157+
esp_zb_lock_acquire(portMAX_DELAY);
130158
esp_zb_zcl_on_off_cmd_req(&cmd_req);
159+
esp_zb_lock_release();
131160
} else {
132161
log_e("Light not bound");
133162
}
@@ -141,8 +170,30 @@ void ZigbeeSwitch::lightOn(uint8_t endpoint, uint16_t short_addr) {
141170
cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr;
142171
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
143172
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_ON_ID;
144-
log_i("Sending 'light on' command to endpoint %d, address 0x%x", endpoint, short_addr);
173+
log_v("Sending 'light on' command to endpoint %d, address 0x%x", endpoint, short_addr);
174+
esp_zb_lock_acquire(portMAX_DELAY);
175+
esp_zb_zcl_on_off_cmd_req(&cmd_req);
176+
esp_zb_lock_release();
177+
} else {
178+
log_e("Light not bound");
179+
}
180+
}
181+
182+
void ZigbeeSwitch::lightOn(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) {
183+
if (_is_bound) {
184+
esp_zb_zcl_on_off_cmd_t cmd_req;
185+
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
186+
cmd_req.zcl_basic_cmd.dst_endpoint = endpoint;
187+
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT;
188+
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_ON_ID;
189+
memcpy(cmd_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t));
190+
log_v(
191+
"Sending 'light on' command to endpoint %d, ieee address %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", endpoint, ieee_addr[7], ieee_addr[6], ieee_addr[5],
192+
ieee_addr[4], ieee_addr[3], ieee_addr[2], ieee_addr[1], ieee_addr[0]
193+
);
194+
esp_zb_lock_acquire(portMAX_DELAY);
145195
esp_zb_zcl_on_off_cmd_req(&cmd_req);
196+
esp_zb_lock_release();
146197
} else {
147198
log_e("Light not bound");
148199
}
@@ -154,8 +205,10 @@ void ZigbeeSwitch::lightOff() {
154205
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
155206
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
156207
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_OFF_ID;
157-
log_i("Sending 'light off' command");
208+
log_v("Sending 'light off' command");
209+
esp_zb_lock_acquire(portMAX_DELAY);
158210
esp_zb_zcl_on_off_cmd_req(&cmd_req);
211+
esp_zb_lock_release();
159212
} else {
160213
log_e("Light not bound");
161214
}
@@ -168,8 +221,10 @@ void ZigbeeSwitch::lightOff(uint16_t group_addr) {
168221
cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr;
169222
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT;
170223
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_OFF_ID;
171-
log_i("Sending 'light off' command to group address 0x%x", group_addr);
224+
log_v("Sending 'light off' command to group address 0x%x", group_addr);
225+
esp_zb_lock_acquire(portMAX_DELAY);
172226
esp_zb_zcl_on_off_cmd_req(&cmd_req);
227+
esp_zb_lock_release();
173228
} else {
174229
log_e("Light not bound");
175230
}
@@ -183,8 +238,30 @@ void ZigbeeSwitch::lightOff(uint8_t endpoint, uint16_t short_addr) {
183238
cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr;
184239
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
185240
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_OFF_ID;
186-
log_i("Sending 'light off' command to endpoint %d, address 0x%x", endpoint, short_addr);
241+
log_v("Sending 'light off' command to endpoint %d, address 0x%x", endpoint, short_addr);
242+
esp_zb_lock_acquire(portMAX_DELAY);
243+
esp_zb_zcl_on_off_cmd_req(&cmd_req);
244+
esp_zb_lock_release();
245+
} else {
246+
log_e("Light not bound");
247+
}
248+
}
249+
250+
void ZigbeeSwitch::lightOff(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) {
251+
if (_is_bound) {
252+
esp_zb_zcl_on_off_cmd_t cmd_req;
253+
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
254+
cmd_req.zcl_basic_cmd.dst_endpoint = endpoint;
255+
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT;
256+
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_OFF_ID;
257+
memcpy(cmd_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t));
258+
log_v(
259+
"Sending 'light off' command to endpoint %d, ieee address %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", endpoint, ieee_addr[7], ieee_addr[6], ieee_addr[5],
260+
ieee_addr[4], ieee_addr[3], ieee_addr[2], ieee_addr[1], ieee_addr[0]
261+
);
262+
esp_zb_lock_acquire(portMAX_DELAY);
187263
esp_zb_zcl_on_off_cmd_req(&cmd_req);
264+
esp_zb_lock_release();
188265
} else {
189266
log_e("Light not bound");
190267
}
@@ -197,8 +274,10 @@ void ZigbeeSwitch::lightOffWithEffect(uint8_t effect_id, uint8_t effect_variant)
197274
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
198275
cmd_req.effect_id = effect_id;
199276
cmd_req.effect_variant = effect_variant;
200-
log_i("Sending 'light off with effect' command");
277+
log_v("Sending 'light off with effect' command");
278+
esp_zb_lock_acquire(portMAX_DELAY);
201279
esp_zb_zcl_on_off_off_with_effect_cmd_req(&cmd_req);
280+
esp_zb_lock_release();
202281
} else {
203282
log_e("Light not bound");
204283
}
@@ -209,8 +288,10 @@ void ZigbeeSwitch::lightOnWithSceneRecall() {
209288
esp_zb_zcl_on_off_on_with_recall_global_scene_cmd_t cmd_req;
210289
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
211290
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
212-
log_i("Sending 'light on with scene recall' command");
291+
log_v("Sending 'light on with scene recall' command");
292+
esp_zb_lock_acquire(portMAX_DELAY);
213293
esp_zb_zcl_on_off_on_with_recall_global_scene_cmd_req(&cmd_req);
294+
esp_zb_lock_release();
214295
} else {
215296
log_e("Light not bound");
216297
}
@@ -223,8 +304,10 @@ void ZigbeeSwitch::lightOnWithTimedOff(uint8_t on_off_control, uint16_t time_on,
223304
cmd_req.on_off_control = on_off_control; //TODO: Test how it works, then maybe change API
224305
cmd_req.on_time = time_on;
225306
cmd_req.off_wait_time = time_off;
226-
log_i("Sending 'light on with time off' command");
307+
log_v("Sending 'light on with time off' command");
308+
esp_zb_lock_acquire(portMAX_DELAY);
227309
esp_zb_zcl_on_off_on_with_timed_off_cmd_req(&cmd_req);
310+
esp_zb_lock_release();
228311
} else {
229312
log_e("Light not bound");
230313
}

‎libraries/Zigbee/src/ep/ZigbeeSwitch.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,17 @@ class ZigbeeSwitch : public ZigbeeEP {
1818
void lightToggle();
1919
void lightToggle(uint16_t group_addr);
2020
void lightToggle(uint8_t endpoint, uint16_t short_addr);
21+
void lightToggle(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr);
2122

2223
void lightOn();
2324
void lightOn(uint16_t group_addr);
2425
void lightOn(uint8_t endpoint, uint16_t short_addr);
26+
void lightOn(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr);
2527

2628
void lightOff();
2729
void lightOff(uint16_t group_addr);
2830
void lightOff(uint8_t endpoint, uint16_t short_addr);
31+
void lightOff(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr);
2932

3033
void lightOffWithEffect(uint8_t effect_id, uint8_t effect_variant);
3134
void lightOnWithTimedOff(uint8_t on_off_control, uint16_t time_on, uint16_t time_off);

‎libraries/Zigbee/src/ep/ZigbeeTempSensor.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@ void ZigbeeTempSensor::setReporting(uint16_t min_interval, uint16_t max_interval
6060
},
6161
.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC,
6262
};
63+
esp_zb_lock_acquire(portMAX_DELAY);
6364
esp_zb_zcl_update_reporting_info(&reporting_info);
65+
esp_zb_lock_release();
6466
}
6567

6668
void ZigbeeTempSensor::setTemperature(float temperature) {
@@ -158,7 +160,9 @@ void ZigbeeTempSensor::setHumidityReporting(uint16_t min_interval, uint16_t max_
158160
},
159161
.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC,
160162
};
163+
esp_zb_lock_acquire(portMAX_DELAY);
161164
esp_zb_zcl_update_reporting_info(&reporting_info);
165+
esp_zb_lock_release();
162166
}
163167

164168
#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED

0 commit comments

Comments
 (0)
Please sign in to comment.