Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 97643ec

Browse filesBrowse files
committed
feat(zigbee): Recall bound devices after reboot
1 parent 9f5f95e commit 97643ec
Copy full SHA for 97643ec

10 files changed

+312
-89
lines changed

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

Copy file name to clipboardExpand all lines: libraries/Zigbee/examples/Zigbee_On_Off_Switch/Zigbee_On_Off_Switch.ino
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,8 @@ void setup() {
147147
"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],
148148
device->ieee_addr[4], device->ieee_addr[5], device->ieee_addr[6], device->ieee_addr[7]
149149
);
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));
150+
Serial.printf("Light manufacturer: %s", zbSwitch.readManufacturer(device->endpoint, device->short_addr, device->ieee_addr));
151+
Serial.printf("Light model: %s", zbSwitch.readModel(device->endpoint, device->short_addr, device->ieee_addr));
152152
}
153153

154154
Serial.println();

‎libraries/Zigbee/src/ZigbeeCore.cpp

Copy file name to clipboardExpand all lines: libraries/Zigbee/src/ZigbeeCore.cpp
+68-2Lines changed: 68 additions & 2 deletions
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,8 +310,7 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct) {
309310
Bit 6 – Security capability
310311
Bit 7 – Reserved
311312
*/
312-
313-
// for each endpoint in the list call the findEndpoint function if not bounded or allowed to bind multiple devices
313+
// 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()) {
316316
(*it)->findEndpoint(&cmd_req);
@@ -391,6 +391,72 @@ void ZigbeeCore::scanDelete() {
391391
_scan_status = ZB_SCAN_FAILED;
392392
}
393393

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

‎libraries/Zigbee/src/ZigbeeCore.h

Copy file name to clipboardExpand all lines: libraries/Zigbee/src/ZigbeeCore.h
+2Lines 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

Copy file name to clipboardExpand all lines: libraries/Zigbee/src/ZigbeeEP.cpp
+20-6Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,13 +112,20 @@ void ZigbeeEP::reportBatteryPercentage() {
112112
log_v("Battery percentage reported");
113113
}
114114

115-
char *ZigbeeEP::readManufacturer(uint8_t endpoint, uint16_t short_addr) {
115+
char *ZigbeeEP::readManufacturer(uint8_t endpoint, uint16_t short_addr, esp_zb_ieee_addr_t ieee_addr) {
116116
/* Read peer Manufacture Name & Model Identifier */
117117
esp_zb_zcl_read_attr_cmd_t read_req;
118-
read_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
118+
119+
if(short_addr != 0){
120+
read_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
121+
read_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr;
122+
} else {
123+
read_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT;
124+
memcpy(read_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t));
125+
}
126+
119127
read_req.zcl_basic_cmd.src_endpoint = _endpoint;
120128
read_req.zcl_basic_cmd.dst_endpoint = endpoint;
121-
read_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr;
122129
read_req.clusterID = ESP_ZB_ZCL_CLUSTER_ID_BASIC;
123130

124131
uint16_t attributes[] = {
@@ -139,13 +146,20 @@ char *ZigbeeEP::readManufacturer(uint8_t endpoint, uint16_t short_addr) {
139146
return _read_manufacturer;
140147
}
141148

142-
char *ZigbeeEP::readModel(uint8_t endpoint, uint16_t short_addr) {
149+
char *ZigbeeEP::readModel(uint8_t endpoint, uint16_t short_addr, esp_zb_ieee_addr_t ieee_addr) {
143150
/* Read peer Manufacture Name & Model Identifier */
144151
esp_zb_zcl_read_attr_cmd_t read_req;
145-
read_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
152+
153+
if(short_addr != 0){
154+
read_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
155+
read_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr;
156+
} else {
157+
read_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT;
158+
memcpy(read_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t));
159+
}
160+
146161
read_req.zcl_basic_cmd.src_endpoint = _endpoint;
147162
read_req.zcl_basic_cmd.dst_endpoint = endpoint;
148-
read_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr;
149163
read_req.clusterID = ESP_ZB_ZCL_CLUSTER_ID_BASIC;
150164

151165
uint16_t attributes[] = {

‎libraries/Zigbee/src/ZigbeeEP.h

Copy file name to clipboardExpand all lines: libraries/Zigbee/src/ZigbeeEP.h
+9-3Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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,7 @@ class ZigbeeEP {
108108
}
109109

110110
private:
111-
static bool _allow_multiple_binding;
111+
112112
char *_read_manufacturer;
113113
char *_read_model;
114114
void (*_on_identify)(uint16_t time);
@@ -119,10 +119,16 @@ class ZigbeeEP {
119119
esp_zb_endpoint_config_t _ep_config;
120120
esp_zb_cluster_list_t *_cluster_list;
121121
static bool _is_bound;
122+
static bool _allow_multiple_binding;
122123
std::list<zb_device_params_t *> _bound_devices;
123124
SemaphoreHandle_t lock;
124125
zb_power_source_t _power_source;
125126

127+
void addBoundDevice(zb_device_params_t *device) {
128+
_bound_devices.push_back(device);
129+
_is_bound = true;
130+
}
131+
126132
friend class ZigbeeCore;
127133
};
128134

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.