Skip to content

Commit e0d18a1

Browse files
committed
feat(zigbee): Add cb option for default response message
1 parent 6015fd7 commit e0d18a1

File tree

5 files changed

+80
-9
lines changed

5 files changed

+80
-9
lines changed

libraries/Zigbee/examples/Zigbee_Temp_Hum_Sensor_Sleepy/Zigbee_Temp_Hum_Sensor_Sleepy.ino

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ uint8_t button = BOOT_PIN;
4242

4343
ZigbeeTempSensor zbTempSensor = ZigbeeTempSensor(TEMP_SENSOR_ENDPOINT_NUMBER);
4444

45+
uint8_t dataToSend = 2; // Temperature and humidity values are reported in same endpoint, so 2 values are reported
46+
bool resend = false;
47+
4548
/************************ Temp sensor *****************************/
4649
void meausureAndSleep() {
4750
// Measure temperature sensor value
@@ -55,17 +58,34 @@ void meausureAndSleep() {
5558
zbTempSensor.setHumidity(humidity);
5659

5760
// Report temperature and humidity values
58-
zbTempSensor.report();
61+
zbTempSensor.report(); // reports temperature and humidity values (if humidity sensor is not added, only temperature is reported)
5962
Serial.printf("Reported temperature: %.2f°C, Humidity: %.2f%%\r\n", temperature, humidity);
6063

61-
// Add small delay to allow the data to be sent before going to sleep
62-
delay(100);
64+
// Wait until data was succesfully sent
65+
while(dataToSend != 0){
66+
if(resend){
67+
Serial.println("Resending data on failure!");
68+
resend = false;
69+
dataToSend = 2;
70+
zbTempSensor.report(); // report again
71+
}
72+
}
6373

64-
// Put device to deep sleep
74+
// Put device to deep sleep after data was sent successfully
6575
Serial.println("Going to sleep now");
6676
esp_deep_sleep_start();
6777
}
6878

79+
void onResponse(zb_cmd_type_t command, esp_zb_zcl_status_t status){
80+
Serial.printf("Response status recieved %s", zbTempSensor.esp_zb_zcl_status_to_name(status));
81+
if(command == ZB_CMD_REPORT_ATTRIBUTE){
82+
switch (status){
83+
case ESP_ZB_ZCL_STATUS_SUCCESS: dataToSend--; break;
84+
case ESP_ZB_ZCL_STATUS_FAIL: resend = true; break;
85+
default: break;// add more statuses like ESP_ZB_ZCL_STATUS_INVALID_VALUE, ESP_ZB_ZCL_STATUS_TIMEOUT etc.
86+
}
87+
}
88+
}
6989
/********************* Arduino functions **************************/
7090
void setup() {
7191
Serial.begin(115200);
@@ -92,6 +112,9 @@ void setup() {
92112
// Add humidity cluster to the temperature sensor device with min, max and tolerance values
93113
zbTempSensor.addHumiditySensor(0, 100, 1);
94114

115+
// Set callback for default response to handle status of reported data
116+
zbTempSensor.onDefaultResponse(onResponse);
117+
95118
// Add endpoint to Zigbee Core
96119
Zigbee.addEndpoint(&zbTempSensor);
97120

@@ -116,9 +139,6 @@ void setup() {
116139
}
117140
Serial.println();
118141
Serial.println("Successfully connected to Zigbee network");
119-
120-
// Delay approx 1s (may be adjusted) to allow establishing proper connection with coordinator, needed for sleepy devices
121-
delay(1000);
122142
}
123143

124144
void loop() {

libraries/Zigbee/keywords.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ zb_power_source_t KEYWORD1
4747
ZigbeeWindowCoveringType KEYWORD1
4848
ZigbeeFanMode KEYWORD1
4949
ZigbeeFanModeSequence KEYWORD1
50+
zb_cmd_type_t KEYWORD1
5051

5152
#######################################
5253
# Methods and Functions (KEYWORD2)
@@ -96,6 +97,7 @@ getTime KEYWORD2
9697
getTimezone KEYWORD2
9798
addOTAClient KEYWORD2
9899
clearBoundDevices KEYWORD2
100+
onDefaultResponse KEYWORD2
99101

100102
# ZigbeeLight + ZigbeeColorDimmableLight
101103
onLightChange KEYWORD2

libraries/Zigbee/src/ZigbeeEP.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,15 @@ void ZigbeeEP::removeBoundDevice(zb_device_params_t *device) {
608608
log_w("No matching device found for removal");
609609
}
610610

611+
void ZigbeeEP::zbDefaultResponse(const esp_zb_zcl_cmd_default_resp_message_t *message) {
612+
log_v("Default response received for endpoint %d", _endpoint);
613+
log_v("Status code: %s", esp_zb_zcl_status_to_name(message->status_code));
614+
log_v("Response to command: %d", message->resp_to_cmd);
615+
if (_on_default_response) {
616+
_on_default_response((zb_cmd_type_t)message->resp_to_cmd, message->status_code);
617+
}
618+
}
619+
611620
const char *ZigbeeEP::esp_zb_zcl_status_to_name(esp_zb_zcl_status_t status) {
612621
switch (status) {
613622
case ESP_ZB_ZCL_STATUS_SUCCESS: return "Success";

libraries/Zigbee/src/ZigbeeEP.h

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,32 @@
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+
1541
#define ZB_ARRAY_LENGHT(arr) (sizeof(arr) / sizeof(arr[0]))
1642

1743
#define RGB_TO_XYZ(r, g, b, X, Y, Z) \
@@ -138,6 +164,7 @@ class ZigbeeEP {
138164
virtual void zbReadTimeCluster(const esp_zb_zcl_attribute_t *attribute); //already implemented
139165
virtual void zbIASZoneStatusChangeNotification(const esp_zb_zcl_ias_zone_status_change_notification_message_t *message) {};
140166
virtual void zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) {};
167+
virtual void zbDefaultResponse(const esp_zb_zcl_cmd_default_resp_message_t *message); //already implemented
141168

142169
virtual void addBoundDevice(zb_device_params_t *device) {
143170
_bound_devices.push_back(device);
@@ -156,16 +183,22 @@ class ZigbeeEP {
156183
_on_identify = callback;
157184
}
158185

186+
void onDefaultResponse(void (*callback)(zb_cmd_type_t resp_to_cmd, esp_zb_zcl_status_t status)) {
187+
_on_default_response = callback;
188+
}
189+
190+
// Convert ZCL status to name
191+
const char *esp_zb_zcl_status_to_name(esp_zb_zcl_status_t status);
192+
159193
private:
160194
char *_read_manufacturer;
161195
char *_read_model;
162196
void (*_on_identify)(uint16_t time);
197+
void (*_on_default_response)(zb_cmd_type_t resp_to_cmd, esp_zb_zcl_status_t status);
163198
time_t _read_time;
164199
int32_t _read_timezone;
165200

166201
protected:
167-
// Convert ZCL status to name
168-
const char *esp_zb_zcl_status_to_name(esp_zb_zcl_status_t status);
169202

170203
uint8_t _endpoint;
171204
esp_zb_ha_standard_devices_t _device_id;

libraries/Zigbee/src/ZigbeeHandlers.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,13 @@ static esp_err_t zb_cmd_default_resp_handler(const esp_zb_zcl_cmd_default_resp_m
398398
"Received default response: from address(0x%x), src_endpoint(%d) to dst_endpoint(%d), cluster(0x%x) with status 0x%x",
399399
message->info.src_address.u.short_addr, message->info.src_endpoint, message->info.dst_endpoint, message->info.cluster, message->status_code
400400
);
401+
402+
// List through all Zigbee EPs and call the callback function, with the message
403+
for (std::list<ZigbeeEP *>::iterator it = Zigbee.ep_objects.begin(); it != Zigbee.ep_objects.end(); ++it) {
404+
if (message->info.dst_endpoint == (*it)->getEndpoint()) {
405+
(*it)->zbDefaultResponse(message); //method zbDefaultResponse is implemented in the common EP class
406+
}
407+
}
401408
return ESP_OK;
402409
}
403410

0 commit comments

Comments
 (0)