Skip to content

Commit f10ca9f

Browse files
committed
feat(zigbee): Add global default response cb option
1 parent 4cbdb44 commit f10ca9f

File tree

8 files changed

+101
-39
lines changed

8 files changed

+101
-39
lines changed

libraries/Zigbee/examples/Zigbee_Temp_Hum_Sensor_Sleepy/Zigbee_Temp_Hum_Sensor_Sleepy.ino

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232

3333
#include "Zigbee.h"
3434

35+
#define USE_GLOBAL_ON_RESPONSE_CALLBACK 1 // Set to 0 to use local callback specified directly for the endpoint.
36+
3537
/* Zigbee temperature + humidity sensor configuration */
3638
#define TEMP_SENSOR_ENDPOINT_NUMBER 10
3739

@@ -46,6 +48,31 @@ ZigbeeTempSensor zbTempSensor = ZigbeeTempSensor(TEMP_SENSOR_ENDPOINT_NUMBER);
4648
uint8_t dataToSend = 2; // Temperature and humidity values are reported in same endpoint, so 2 values are reported
4749
bool resend = false;
4850

51+
/************************ Callbacks *****************************/
52+
#if USE_GLOBAL_ON_RESPONSE_CALLBACK
53+
void onGlobalResponse(zb_cmd_type_t command, esp_zb_zcl_status_t status, uint8_t endpoint, uint16_t cluster){
54+
Serial.printf("Global response command: %d, status: %s, endpoint: %d, cluster: 0x%04x\r\n", command, esp_zb_zcl_status_to_name(status), endpoint, cluster);
55+
if((command == ZB_CMD_REPORT_ATTRIBUTE) && (endpoint == TEMP_SENSOR_ENDPOINT_NUMBER)){
56+
switch (status){
57+
case ESP_ZB_ZCL_STATUS_SUCCESS: dataToSend--; break;
58+
case ESP_ZB_ZCL_STATUS_FAIL: resend = true; break;
59+
default: break;// add more statuses like ESP_ZB_ZCL_STATUS_INVALID_VALUE, ESP_ZB_ZCL_STATUS_TIMEOUT etc.
60+
}
61+
}
62+
}
63+
#else
64+
void onResponse(zb_cmd_type_t command, esp_zb_zcl_status_t status){
65+
Serial.printf("Response command: %d, status: %s\r\n", command, esp_zb_zcl_status_to_name(status));
66+
if(command == ZB_CMD_REPORT_ATTRIBUTE){
67+
switch (status){
68+
case ESP_ZB_ZCL_STATUS_SUCCESS: dataToSend--; break;
69+
case ESP_ZB_ZCL_STATUS_FAIL: resend = true; break;
70+
default: break;// add more statuses like ESP_ZB_ZCL_STATUS_INVALID_VALUE, ESP_ZB_ZCL_STATUS_TIMEOUT etc.
71+
}
72+
}
73+
}
74+
#endif
75+
4976
/************************ Temp sensor *****************************/
5077
void meausureAndSleep() {
5178
// Measure temperature sensor value
@@ -85,16 +112,6 @@ void meausureAndSleep() {
85112
esp_deep_sleep_start();
86113
}
87114

88-
void onResponse(zb_cmd_type_t command, esp_zb_zcl_status_t status){
89-
Serial.printf("Response status received %s\r\n", zbTempSensor.esp_zb_zcl_status_to_name(status));
90-
if(command == ZB_CMD_REPORT_ATTRIBUTE){
91-
switch (status){
92-
case ESP_ZB_ZCL_STATUS_SUCCESS: dataToSend--; break;
93-
case ESP_ZB_ZCL_STATUS_FAIL: resend = true; break;
94-
default: break;// add more statuses like ESP_ZB_ZCL_STATUS_INVALID_VALUE, ESP_ZB_ZCL_STATUS_TIMEOUT etc.
95-
}
96-
}
97-
}
98115
/********************* Arduino functions **************************/
99116
void setup() {
100117
Serial.begin(115200);
@@ -121,8 +138,15 @@ void setup() {
121138
// Add humidity cluster to the temperature sensor device with min, max and tolerance values
122139
zbTempSensor.addHumiditySensor(0, 100, 1);
123140

124-
// Set callback for default response to handle status of reported data
141+
// Set callback for default response to handle status of reported data, there are 2 options.
142+
143+
#if USE_GLOBAL_ON_RESPONSE_CALLBACK
144+
// Global callback for all endpoints with more params to determine the endpoint and cluster in the callback function.
145+
Zigbee.onGlobalDefaultResponse(onGlobalResponse);
146+
#else
147+
// Callback specified for endpoint
125148
zbTempSensor.onDefaultResponse(onResponse);
149+
#endif
126150

127151
// Add endpoint to Zigbee Core
128152
Zigbee.addEndpoint(&zbTempSensor);

libraries/Zigbee/src/Zigbee.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
#pragma once
44

5+
// Common types and functions
6+
#include "ZigbeeTypes.h"
7+
58
// Core
69
#include "ZigbeeCore.h"
710
#include "ZigbeeEP.h"

libraries/Zigbee/src/ZigbeeCore.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ ZigbeeCore::ZigbeeCore() {
3232
_scan_duration = 3; // default scan duration
3333
_rx_on_when_idle = true;
3434
_debug = false;
35+
_global_default_response_cb = nullptr; // Initialize global callback to nullptr
3536
if (!lock) {
3637
lock = xSemaphoreCreateBinary();
3738
if (lock == NULL) {
@@ -792,6 +793,17 @@ const char *ZigbeeCore::getDeviceTypeString(esp_zb_ha_standard_devices_t deviceI
792793
}
793794
}
794795

796+
void ZigbeeCore::callDefaultResponseCallback(zb_cmd_type_t resp_to_cmd, esp_zb_zcl_status_t status, uint8_t endpoint, uint16_t cluster) {
797+
log_v("Global callback called: cmd=%d, status=%s, ep=%d, cluster=0x%04x", resp_to_cmd, esp_zb_zcl_status_to_name(status), endpoint, cluster);
798+
if (_global_default_response_cb) {
799+
log_v("Global callback is set, calling it");
800+
_global_default_response_cb(resp_to_cmd, status, endpoint, cluster);
801+
log_v("Global callback completed");
802+
} else {
803+
log_v("Global callback is NOT set");
804+
}
805+
}
806+
795807
ZigbeeCore Zigbee = ZigbeeCore();
796808

797809
#endif // CONFIG_ZB_ENABLED

libraries/Zigbee/src/ZigbeeCore.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "aps/esp_zigbee_aps.h"
1212
#include <esp32-hal-log.h>
1313
#include <list>
14+
#include "ZigbeeTypes.h"
1415
#include "ZigbeeEP.h"
1516
class ZigbeeEP;
1617

@@ -103,6 +104,9 @@ class ZigbeeCore {
103104
SemaphoreHandle_t lock;
104105
bool _debug;
105106

107+
// Global default response callback
108+
void (*_global_default_response_cb)(zb_cmd_type_t resp_to_cmd, esp_zb_zcl_status_t status, uint8_t endpoint, uint16_t cluster);
109+
106110
bool zigbeeInit(esp_zb_cfg_t *zb_cfg, bool erase_nvs);
107111
static void scanCompleteCallback(esp_zb_zdp_status_t zdo_status, uint8_t count, esp_zb_network_descriptor_t *nwk_descriptor);
108112
const char *getDeviceTypeString(esp_zb_ha_standard_devices_t deviceId);
@@ -176,6 +180,14 @@ class ZigbeeCore {
176180
return _debug;
177181
}
178182

183+
// Set global default response callback
184+
void onGlobalDefaultResponse(void (*callback)(zb_cmd_type_t resp_to_cmd, esp_zb_zcl_status_t status, uint8_t endpoint, uint16_t cluster)) {
185+
_global_default_response_cb = callback;
186+
}
187+
188+
// Call global default response callback (for internal use)
189+
void callDefaultResponseCallback(zb_cmd_type_t resp_to_cmd, esp_zb_zcl_status_t status, uint8_t endpoint, uint16_t cluster);
190+
179191
// Friend function declaration to allow access to private members
180192
friend void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct);
181193
friend bool zb_apsde_data_indication_handler(esp_zb_apsde_data_ind_t ind);

libraries/Zigbee/src/ZigbeeEP.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -617,7 +617,8 @@ void ZigbeeEP::zbDefaultResponse(const esp_zb_zcl_cmd_default_resp_message_t *me
617617
}
618618
}
619619

620-
const char *ZigbeeEP::esp_zb_zcl_status_to_name(esp_zb_zcl_status_t status) {
620+
// Global function implementation
621+
const char *esp_zb_zcl_status_to_name(esp_zb_zcl_status_t status) {
621622
switch (status) {
622623
case ESP_ZB_ZCL_STATUS_SUCCESS: return "Success";
623624
case ESP_ZB_ZCL_STATUS_FAIL: return "Fail";

libraries/Zigbee/src/ZigbeeEP.h

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,32 +12,6 @@
1212
#define ZB_CMD_TIMEOUT 10000 // 10 seconds
1313
#define OTA_UPGRADE_QUERY_INTERVAL (1 * 60) // 1 hour = 60 minutes
1414

15-
typedef enum {
16-
ZB_CMD_READ_ATTRIBUTE = 0x00U, /*!< Read attributes command */
17-
ZB_CMD_READ_ATTRIBUTE_RESPONSE = 0x01U, /*!< Read attributes response command */
18-
ZB_CMD_WRITE_ATTRIBUTE = 0x02U, /*!< Write attributes foundation command */
19-
ZB_CMD_WRITE_ATTRIBUTE_UNDIVIDED = 0x03U, /*!< Write attributes undivided command */
20-
ZB_CMD_WRITE_ATTRIBUTE_RESPONSE = 0x04U, /*!< Write attributes response command */
21-
ZB_CMD_WRITE_ATTRIBUTE_NO_RESPONSE = 0x05U, /*!< Write attributes no response command */
22-
ZB_CMD_CONFIGURE_REPORTING = 0x06U, /*!< Configure reporting command */
23-
ZB_CMD_CONFIGURE_REPORTING_RESPONSE = 0x07U, /*!< Configure reporting response command */
24-
ZB_CMD_READ_REPORTING_CONFIG = 0x08U, /*!< Read reporting config command */
25-
ZB_CMD_READ_REPORTING_CONFIG_RESPONSE= 0x09U, /*!< Read reporting config response command */
26-
ZB_CMD_REPORT_ATTRIBUTE = 0x0aU, /*!< Report attribute command */
27-
ZB_CMD_DEFAULT_RESPONSE = 0x0bU, /*!< Default response command */
28-
ZB_CMD_DISCOVER_ATTRIBUTES = 0x0cU, /*!< Discover attributes command */
29-
ZB_CMD_DISCOVER_ATTRIBUTES_RESPONSE = 0x0dU, /*!< Discover attributes response command */
30-
ZB_CMD_READ_ATTRIBUTE_STRUCTURED = 0x0eU, /*!< Read attributes structured */
31-
ZB_CMD_WRITE_ATTRIBUTE_STRUCTURED = 0x0fU, /*!< Write attributes structured */
32-
ZB_CMD_WRITE_ATTRIBUTE_STRUCTURED_RESPONSE = 0x10U, /*!< Write attributes structured response */
33-
ZB_CMD_DISCOVER_COMMANDS_RECEIVED = 0x11U, /*!< Discover Commands Received command */
34-
ZB_CMD_DISCOVER_COMMANDS_RECEIVED_RESPONSE = 0x12U, /*!< Discover Commands Received response command */
35-
ZB_CMD_DISCOVER_COMMANDS_GENERATED = 0x13U, /*!< Discover Commands Generated command */
36-
ZB_CMD_DISCOVER_COMMANDS_GENERATED_RESPONSE = 0x14U, /*!< Discover Commands Generated response command */
37-
ZB_CMD_DISCOVER_ATTRIBUTES_EXTENDED = 0x15U, /*!< Discover attributes extended command */
38-
ZB_CMD_DISCOVER_ATTRIBUTES_EXTENDED_RESPONSE = 0x16U, /*!< Discover attributes extended response command */
39-
} zb_cmd_type_t;
40-
4115
#define ZB_ARRAY_LENGHT(arr) (sizeof(arr) / sizeof(arr[0]))
4216

4317
#define RGB_TO_XYZ(r, g, b, X, Y, Z) \
@@ -64,6 +38,9 @@ typedef enum {
6438
ZB_POWER_SOURCE_BATTERY = 0x03,
6539
} zb_power_source_t;
6640

41+
// Global function for converting ZCL status to name
42+
const char *esp_zb_zcl_status_to_name(esp_zb_zcl_status_t status);
43+
6744
/* Zigbee End Device Class */
6845
class ZigbeeEP {
6946
public:
@@ -188,7 +165,6 @@ class ZigbeeEP {
188165
}
189166

190167
// Convert ZCL status to name
191-
const char *esp_zb_zcl_status_to_name(esp_zb_zcl_status_t status);
192168

193169
private:
194170
char *_read_manufacturer;
@@ -212,6 +188,7 @@ class ZigbeeEP {
212188
zb_power_source_t _power_source;
213189
uint8_t _time_status;
214190

191+
// Friend class declaration to allow access to protected members
215192
friend class ZigbeeCore;
216193
};
217194

libraries/Zigbee/src/ZigbeeHandlers.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,9 @@ static esp_err_t zb_cmd_default_resp_handler(const esp_zb_zcl_cmd_default_resp_m
399399
message->info.src_address.u.short_addr, message->info.src_endpoint, message->info.dst_endpoint, message->info.cluster, message->status_code
400400
);
401401

402+
// Call global callback if set
403+
Zigbee.callDefaultResponseCallback((zb_cmd_type_t)message->resp_to_cmd, message->status_code, message->info.dst_endpoint, message->info.cluster);
404+
402405
// List through all Zigbee EPs and call the callback function, with the message
403406
for (std::list<ZigbeeEP *>::iterator it = Zigbee.ep_objects.begin(); it != Zigbee.ep_objects.end(); ++it) {
404407
if (message->info.dst_endpoint == (*it)->getEndpoint()) {

libraries/Zigbee/src/ZigbeeTypes.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#pragma once
2+
3+
#include "esp_zigbee_core.h"
4+
5+
// Foundation Command Types
6+
typedef enum {
7+
ZB_CMD_READ_ATTRIBUTE = 0x00U, /*!< Read attributes command */
8+
ZB_CMD_READ_ATTRIBUTE_RESPONSE = 0x01U, /*!< Read attributes response command */
9+
ZB_CMD_WRITE_ATTRIBUTE = 0x02U, /*!< Write attributes foundation command */
10+
ZB_CMD_WRITE_ATTRIBUTE_UNDIVIDED = 0x03U, /*!< Write attributes undivided command */
11+
ZB_CMD_WRITE_ATTRIBUTE_RESPONSE = 0x04U, /*!< Write attributes response command */
12+
ZB_CMD_WRITE_ATTRIBUTE_NO_RESPONSE = 0x05U, /*!< Write attributes no response command */
13+
ZB_CMD_CONFIGURE_REPORTING = 0x06U, /*!< Configure reporting command */
14+
ZB_CMD_CONFIGURE_REPORTING_RESPONSE = 0x07U, /*!< Configure reporting response command */
15+
ZB_CMD_READ_REPORTING_CONFIG = 0x08U, /*!< Read reporting config command */
16+
ZB_CMD_READ_REPORTING_CONFIG_RESPONSE= 0x09U, /*!< Read reporting config response command */
17+
ZB_CMD_REPORT_ATTRIBUTE = 0x0aU, /*!< Report attribute command */
18+
ZB_CMD_DEFAULT_RESPONSE = 0x0bU, /*!< Default response command */
19+
ZB_CMD_DISCOVER_ATTRIBUTES = 0x0cU, /*!< Discover attributes command */
20+
ZB_CMD_DISCOVER_ATTRIBUTES_RESPONSE = 0x0dU, /*!< Discover attributes response command */
21+
ZB_CMD_READ_ATTRIBUTE_STRUCTURED = 0x0eU, /*!< Read attributes structured */
22+
ZB_CMD_WRITE_ATTRIBUTE_STRUCTURED = 0x0fU, /*!< Write attributes structured */
23+
ZB_CMD_WRITE_ATTRIBUTE_STRUCTURED_RESPONSE = 0x10U, /*!< Write attributes structured response */
24+
ZB_CMD_DISCOVER_COMMANDS_RECEIVED = 0x11U, /*!< Discover Commands Received command */
25+
ZB_CMD_DISCOVER_COMMANDS_RECEIVED_RESPONSE = 0x12U, /*!< Discover Commands Received response command */
26+
ZB_CMD_DISCOVER_COMMANDS_GENERATED = 0x13U, /*!< Discover Commands Generated command */
27+
ZB_CMD_DISCOVER_COMMANDS_GENERATED_RESPONSE = 0x14U, /*!< Discover Commands Generated response command */
28+
ZB_CMD_DISCOVER_ATTRIBUTES_EXTENDED = 0x15U, /*!< Discover attributes extended command */
29+
ZB_CMD_DISCOVER_ATTRIBUTES_EXTENDED_RESPONSE = 0x16U, /*!< Discover attributes extended response command */
30+
} zb_cmd_type_t;

0 commit comments

Comments
 (0)