Skip to content

Commit 8ce22e1

Browse files
committed
Dev update: roles, cb removal, handlers
Fixed ep_thermostat to compile successfully Removed cb from all EP, as it have been removed, virtual methods will be used instead. Moved zigbee handlers out of Zigbee_core to Zigbee_handlers for better readability. Fixed zigbeeInit to be bool and return status of initialization for begin function. Updated examples with edited roles and custom method for on_off light
1 parent 7776aa5 commit 8ce22e1

17 files changed

+367
-121
lines changed

libraries/Zigbee/examples/Zigbee_Light_Bulb/Zigbee_Light_Bulb.ino

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,22 +39,19 @@
3939
#define LED_PIN RGB_BUILTIN
4040
#define ZIGBEE_LIGHT_ENDPOINT 10 /* esp light bulb device endpoint, used to process light controlling commands */
4141

42-
/* Handle the light attribute */
43-
// User callback for Zigbee actions to handle turning on/off the light called by Zigbee stack in zb_attribute_handler()
42+
class MyZigbeeLight : public ZigbeeLight {
43+
public:
44+
// Constructor that passes parameters to the base class constructor
45+
MyZigbeeLight(uint8_t endpoint) : ZigbeeLight(endpoint) {}
4446

45-
static void light_cb(const esp_zb_zcl_set_attr_value_message_t *message) {
46-
bool light_state = 0;
47-
if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_ON_OFF) {
48-
if (message->attribute.id == ESP_ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID && message->attribute.data.type == ESP_ZB_ZCL_ATTR_TYPE_BOOL) {
49-
light_state = message->attribute.data.value ? *(bool *)message->attribute.data.value : light_state;
50-
log_i("Light sets to %s", light_state ? "On" : "Off");
51-
neopixelWrite(LED_PIN, 255 * light_state, 255 * light_state, 255 * light_state); // Toggle light
47+
// Override the set_on_off function
48+
void set_on_off(bool value) override {
49+
log_v("Overwritten method, set on/off: %d", value);
50+
neopixelWrite(LED_PIN, 255 * value, 255 * value, 255 * value); // Toggle light
5251
}
53-
}
54-
return;
55-
}
52+
};
5653

57-
ZigbeeLight zbLight = ZigbeeLight(ZIGBEE_LIGHT_ENDPOINT, light_cb);
54+
MyZigbeeLight zbLight = MyZigbeeLight(ZIGBEE_LIGHT_ENDPOINT);
5855

5956
/********************* Arduino functions **************************/
6057
void setup() {
@@ -65,7 +62,7 @@ void setup() {
6562
log_d("Adding ZigbeeLight endpoint to Zigbee Core");
6663
Zigbee.addEndpoint(&zbLight);
6764

68-
// When all EPs are registered, start Zigbee. By default acts as Zigbee_End_Device
65+
// When all EPs are registered, start Zigbee. By default acts as ZIGBEE_END_DEVICE
6966
log_d("Calling Zigbee.begin()");
7067
Zigbee.begin();
7168
}

libraries/Zigbee/examples/Zigbee_Light_Switch/Zigbee_Light_Switch.ino

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ static void switch_gpios_intr_enabled(bool enabled) {
9898
}
9999
}
100100

101-
ZigbeeSwitch zbSwitch = ZigbeeSwitch(SWITCH_ENDPOINT_NUMBER,NULL);
101+
ZigbeeSwitch zbSwitch = ZigbeeSwitch(SWITCH_ENDPOINT_NUMBER);
102102

103103
/********************* Arduino functions **************************/
104104
void setup() {
@@ -108,6 +108,9 @@ void setup() {
108108
//Add endpoint to Zigbee Core
109109
log_d("Adding ZigbeeSwitch endpoint to Zigbee Core");
110110
Zigbee.addEndpoint(&zbSwitch);
111+
112+
//Open network for 180 seconds after boot
113+
Zigbee.setRebootOpenNetwork(180);
111114

112115
// Init button switch
113116
for (int i = 0; i < PAIR_SIZE(button_func_pair); i++) {
@@ -121,9 +124,9 @@ void setup() {
121124
attachInterruptArg(button_func_pair[i].pin, gpio_isr_handler, (void *)(button_func_pair + i), FALLING);
122125
}
123126

124-
// When all EPs are registered, start Zigbee. By default acts as Zigbee_End_Device
127+
// When all EPs are registered, start Zigbee with ZIGBEE_COORDINATOR mode
125128
log_d("Calling Zigbee.begin()");
126-
Zigbee.begin(Zigbee_Coordinator);
129+
Zigbee.begin(ZIGBEE_COORDINATOR);
127130

128131
Serial.println("Waiting for Light to bound to the switch");
129132
//Wait for switch to bound to a light:

libraries/Zigbee/src/Zigbee_core.cpp

Lines changed: 121 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/* Zigbee Common Functions */
22
#include "Zigbee_core.h"
3+
#include "Zigbee_handlers.cpp"
34
#include "Arduino.h"
45

56
Zigbee_Core::Zigbee_Core() {
@@ -11,37 +12,44 @@ Zigbee_Core::Zigbee_Core() {
1112
}
1213
Zigbee_Core::~Zigbee_Core() {}
1314

15+
//forward declaration
16+
static esp_err_t zb_action_handler(esp_zb_core_action_callback_id_t callback_id, const void *message);
17+
1418
bool Zigbee_Core::begin(esp_zb_cfg_t *role_cfg, bool erase_nvs) {
15-
zigbeeInit(role_cfg, erase_nvs);
19+
if (!zigbeeInit(role_cfg, erase_nvs)){
20+
return false;
21+
}
1622
_role = (zigbee_role_t)role_cfg->esp_zb_role;
23+
return true;
1724
}
1825

1926
bool Zigbee_Core::begin(zigbee_role_t role, bool erase_nvs) {
27+
bool status = true;
2028
switch (role)
2129
{
22-
case Zigbee_Coordinator: {
23-
_role = Zigbee_Coordinator;
30+
case ZIGBEE_COORDINATOR: {
31+
_role = ZIGBEE_COORDINATOR;
2432
esp_zb_cfg_t zb_nwk_cfg = ZIGBEE_DEFAULT_COORDINATOR_CONFIG();
25-
zigbeeInit(&zb_nwk_cfg, erase_nvs);
33+
status = zigbeeInit(&zb_nwk_cfg, erase_nvs);
2634
break;
2735
}
28-
case Zigbee_Router: {
29-
_role = Zigbee_Router;
36+
case ZIGBEE_ROUTER: {
37+
_role = ZIGBEE_ROUTER;
3038
esp_zb_cfg_t zb_nwk_cfg = ZIGBEE_DEFAULT_ROUTER_CONFIG();
31-
zigbeeInit(&zb_nwk_cfg, erase_nvs);
39+
status = zigbeeInit(&zb_nwk_cfg, erase_nvs);
3240
break;
3341
}
34-
case Zigbee_End_Device: {
35-
_role = Zigbee_End_Device;
42+
case ZIGBEE_END_DEVICE: {
43+
_role = ZIGBEE_END_DEVICE;
3644
esp_zb_cfg_t zb_nwk_cfg = ZIGBEE_DEFAULT_ED_CONFIG();
37-
zigbeeInit(&zb_nwk_cfg, erase_nvs);
45+
status = zigbeeInit(&zb_nwk_cfg, erase_nvs);
3846
break;
3947
}
4048
default:
4149
log_e("Invalid Zigbee Role");
4250
return false;
4351
}
44-
return true;
52+
return status;
4553
}
4654

4755
void Zigbee_Core::addEndpoint(Zigbee_EP *ep) {
@@ -57,74 +65,37 @@ void Zigbee_Core::addEndpoint(Zigbee_EP *ep) {
5765
esp_zb_ep_list_add_ep(_zb_ep_list, ep->_cluster_list, ep->_ep_config);
5866
}
5967

60-
static esp_err_t zb_attribute_handler(const esp_zb_zcl_set_attr_value_message_t *message) {
61-
esp_err_t ret = ESP_OK;
62-
bool light_state = 0;
63-
64-
if (!message) {
65-
log_e("Empty message");
66-
}
67-
if (message->info.status != ESP_ZB_ZCL_STATUS_SUCCESS) {
68-
log_e("Received message: error status(%d)", message->info.status);
69-
}
70-
71-
log_i(
72-
"Received message: endpoint(%d), cluster(0x%x), attribute(0x%x), data size(%d)", message->info.dst_endpoint, message->info.cluster, message->attribute.id,
73-
message->attribute.data.size
74-
);
75-
76-
// List through all Zigbee EPs and call the callback function, with the message
77-
for (std::list<Zigbee_EP*>::iterator it = Zigbee.ep_objects.begin(); it != Zigbee.ep_objects.end(); ++it) {
78-
if (message->info.dst_endpoint == (*it)->_endpoint) {
79-
//TODO: implement argument passing to the callback function
80-
//if Zigbee_EP argument is set, pass it to the callback function
81-
// if ((*it)->_arg) {
82-
// (*it)->_cb(message, (*it)->_arg);
83-
// }
84-
// else {
85-
(*it)->_cb(message);
86-
// }
87-
}
88-
}
89-
return ret;
90-
}
91-
92-
93-
static esp_err_t zb_action_handler(esp_zb_core_action_callback_id_t callback_id, const void *message) {
94-
esp_err_t ret = ESP_OK;
95-
/* TODO:
96-
Implement handlers for different Zigbee actions (callback_id's)
97-
*/
98-
switch (callback_id) {
99-
case ESP_ZB_CORE_SET_ATTR_VALUE_CB_ID: ret = zb_attribute_handler((esp_zb_zcl_set_attr_value_message_t *)message); break;
100-
case ESP_ZB_CORE_CMD_DEFAULT_RESP_CB_ID: log_i("Received default response"); break;
101-
default: log_w("Receive unhandled Zigbee action(0x%x) callback", callback_id); break;
102-
}
103-
return ret;
104-
}
105-
10668
static void esp_zb_task(void *pvParameters) {
10769
/* initialize Zigbee stack */
10870
ESP_ERROR_CHECK(esp_zb_start(false));
10971
esp_zb_main_loop_iteration();
11072
}
11173

11274
// Zigbee core init function
113-
void Zigbee_Core::zigbeeInit(esp_zb_cfg_t *zb_cfg, bool erase_nvs) {
75+
bool Zigbee_Core::zigbeeInit(esp_zb_cfg_t *zb_cfg, bool erase_nvs) {
11476
// Zigbee platform configuration
11577
esp_zb_platform_config_t platform_config = {
11678
.radio_config = _radio_config,
11779
.host_config = _host_config,
11880
};
119-
ESP_ERROR_CHECK(esp_zb_platform_config(&platform_config));
81+
82+
esp_err_t err = esp_zb_platform_config(&platform_config);
83+
if (err != ESP_OK) {
84+
log_e("Failed to configure Zigbee platform");
85+
return false;
86+
}
12087

12188
// Initialize Zigbee stack
12289
log_d("Initialize Zigbee stack");
12390
esp_zb_init(zb_cfg);
12491

12592
// Register all Zigbee EPs in list
12693
log_d("Register all Zigbee EPs in list");
127-
esp_zb_device_register(_zb_ep_list);
94+
err = esp_zb_device_register(_zb_ep_list);
95+
if (err != ESP_OK) {
96+
log_e("Failed to register Zigbee EPs");
97+
return false;
98+
}
12899

129100
//print the list of Zigbee EPs from ep_objects
130101
log_i("List of registered Zigbee EPs:");
@@ -134,7 +105,11 @@ void Zigbee_Core::zigbeeInit(esp_zb_cfg_t *zb_cfg, bool erase_nvs) {
134105

135106
// Register Zigbee action handler
136107
esp_zb_core_action_handler_register(zb_action_handler);
137-
esp_zb_set_primary_network_channel_set(_primary_channel_mask);
108+
err = esp_zb_set_primary_network_channel_set(_primary_channel_mask);
109+
if (err != ESP_OK) {
110+
log_e("Failed to set primary network channel mask");
111+
return false;
112+
}
138113

139114
//Erase NVRAM before creating connection to new Coordinator
140115
if (erase_nvs) {
@@ -143,6 +118,8 @@ void Zigbee_Core::zigbeeInit(esp_zb_cfg_t *zb_cfg, bool erase_nvs) {
143118

144119
// Create Zigbee task and start Zigbee stack
145120
xTaskCreate(esp_zb_task, "Zigbee_main", 4096, NULL, 5, NULL);
121+
122+
return true;
146123
}
147124

148125
void Zigbee_Core::setRadioConfig(esp_zb_radio_config_t config) {
@@ -300,6 +277,89 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct) {
300277
}
301278
}
302279

280+
// // Zigbee action handlers
281+
// static esp_err_t zb_action_handler(esp_zb_core_action_callback_id_t callback_id, const void *message) {
282+
// esp_err_t ret = ESP_OK;
283+
// /* TODO:
284+
// Implement handlers for different Zigbee actions (callback_id's)
285+
// */
286+
// // NOTE: Implement all Zigbee actions that can be handled by the Zigbee_Core class, or just call user defined callback function and let the user handle the action and read the message properly
287+
// // NOTE: This may me harder for users, to know what callback_id's are available and what message type is received
288+
// switch (callback_id) {
289+
// case ESP_ZB_CORE_SET_ATTR_VALUE_CB_ID: ret = zb_attribute_set_handler((esp_zb_zcl_set_attr_value_message_t *)message); break;
290+
// case ESP_ZB_CORE_REPORT_ATTR_CB_ID: ret = zb_attribute_reporting_handler((esp_zb_zcl_report_attr_message_t *)message); break;
291+
// case ESP_ZB_CORE_CMD_READ_ATTR_RESP_CB_ID: ret = zb_read_attr_resp_handler((esp_zb_zcl_cmd_read_attr_resp_message_t *)message); break;
292+
// case ESP_ZB_CORE_CMD_REPORT_CONFIG_RESP_CB_ID: ret = zb_configure_report_resp_handler((esp_zb_zcl_cmd_config_report_resp_message_t *)message); break;
293+
// case ESP_ZB_CORE_CMD_DEFAULT_RESP_CB_ID: log_i("Received default response"); break;
294+
// default: log_w("Receive unhandled Zigbee action(0x%x) callback", callback_id); break;
295+
// }
296+
297+
// //TODO: get destination endpoint from the message:
298+
// uint8_t dst_endpoint = ((esp_zb_zcl_set_attr_value_message_t *)message)->info.dst_endpoint;
299+
300+
301+
302+
// return ret;
303+
// }
304+
305+
// static esp_err_t zb_attribute_set_handler(const esp_zb_zcl_set_attr_value_message_t *message) {
306+
// if (!message) {
307+
// log_e("Empty message");
308+
// }
309+
// if (message->info.status != ESP_ZB_ZCL_STATUS_SUCCESS) {
310+
// log_e("Received message: error status(%d)", message->info.status);
311+
// }
312+
313+
// log_i(
314+
// "Received message: endpoint(%d), cluster(0x%x), attribute(0x%x), data size(%d)", message->info.dst_endpoint, message->info.cluster, message->attribute.id,
315+
// message->attribute.data.size
316+
// );
317+
318+
// // List through all Zigbee EPs and call the callback function, with the message
319+
// for (std::list<Zigbee_EP*>::iterator it = Zigbee.ep_objects.begin(); it != Zigbee.ep_objects.end(); ++it) {
320+
// if (message->info.dst_endpoint == (*it)->_endpoint) {
321+
// //TODO: implement argument passing to the callback function
322+
// //if Zigbee_EP argument is set, pass it to the callback function
323+
// // if ((*it)->_arg) {
324+
// // (*it)->_cb(message, (*it)->_arg);
325+
// // }
326+
// // else {
327+
// (*it)->_cb(message); //method zb_attribute_set_handler in the LIGHT EP
328+
// // }
329+
// }
330+
// }
331+
// return ESP_OK;
332+
// }
333+
334+
// static esp_err_t zb_attribute_reporting_handler(const esp_zb_zcl_report_attr_message_t *message) {
335+
// if (!message) {
336+
// log_e("Empty message");
337+
// }
338+
// if (message->status != ESP_ZB_ZCL_STATUS_SUCCESS) {
339+
// log_e("Received message: error status(%d)", message->status);
340+
// }
341+
// log_i(
342+
// "Received report from address(0x%x) src endpoint(%d) to dst endpoint(%d) cluster(0x%x)", message->src_address.u.short_addr, message->src_endpoint,
343+
// message->dst_endpoint, message->cluster
344+
// );
345+
// // List through all Zigbee EPs and call the callback function, with the message
346+
// for (std::list<Zigbee_EP*>::iterator it = Zigbee.ep_objects.begin(); it != Zigbee.ep_objects.end(); ++it) {
347+
// if (message->info.dst_endpoint == (*it)->_endpoint) {
348+
// //TODO: implement argument passing to the callback function
349+
// //if Zigbee_EP argument is set, pass it to the callback function
350+
// // if ((*it)->_arg) {
351+
// // (*it)->_cb(message, (*it)->_arg);
352+
// // }
353+
// // else {
354+
// (*it)->_cb(message);
355+
// // }
356+
// }
357+
// }
358+
// return ESP_OK;
359+
// }
360+
361+
362+
303363
// TODO: Implement scanning network
304364
// /**
305365
// * @brief Active scan available network.

libraries/Zigbee/src/Zigbee_core.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ typedef struct {
2020

2121
// enum of Zigbee Roles
2222
typedef enum {
23-
ZIGBEE_COORDINATOR = 0,
24-
ZIGBEE_ROUTER = 1,
23+
ZIGBEE_COORDINATOR = 0,
24+
ZIGBEE_ROUTER = 1,
2525
ZIGBEE_END_DEVICE = 2
2626
} zigbee_role_t;
2727

@@ -82,7 +82,7 @@ class Zigbee_Core {
8282
esp_zb_host_config_t _host_config;
8383
uint32_t _primary_channel_mask;
8484

85-
void zigbeeInit(esp_zb_cfg_t *zb_cfg, bool erase_nvs);
85+
bool zigbeeInit(esp_zb_cfg_t *zb_cfg, bool erase_nvs);
8686

8787
public:
8888
esp_zb_ep_list_t *_zb_ep_list;
@@ -93,7 +93,7 @@ class Zigbee_Core {
9393
Zigbee_Core();
9494
~Zigbee_Core();
9595

96-
bool begin(zigbee_role_t role = Zigbee_End_Device, bool erase_nvs = false);
96+
bool begin(zigbee_role_t role = ZIGBEE_END_DEVICE, bool erase_nvs = false);
9797
bool begin(esp_zb_cfg_t *role_cfg, bool erase_nvs = false);
9898
// bool end();
9999

libraries/Zigbee/src/Zigbee_ep.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
/* Common Class for Zigbee End Point */
22

33
#include "Zigbee_ep.h"
4-
#include "Arduino.h"
54

65
uint8_t Zigbee_EP::_endpoint = 0;
76
bool Zigbee_EP::_is_bound = false;
87

98
/* Zigbee End Device Class */
10-
Zigbee_EP::Zigbee_EP(uint8_t endpoint, void (*cb)(const esp_zb_zcl_set_attr_value_message_t *message)) {
9+
Zigbee_EP::Zigbee_EP(uint8_t endpoint) {
1110
_endpoint = endpoint;
12-
_cb = cb;
1311
_ep_config.endpoint = 0;
1412
_cluster_list = nullptr;
1513
}

0 commit comments

Comments
 (0)