32
32
33
33
#include " Zigbee.h"
34
34
35
+ #define USE_GLOBAL_ON_RESPONSE_CALLBACK 1 // Set to 0 to use local callback specified directly for the endpoint.
36
+
35
37
/* Zigbee temperature + humidity sensor configuration */
36
38
#define TEMP_SENSOR_ENDPOINT_NUMBER 10
37
39
38
40
#define uS_TO_S_FACTOR 1000000ULL /* Conversion factor for micro seconds to seconds */
39
41
#define TIME_TO_SLEEP 55 /* Sleep for 55s will + 5s delay for establishing connection => data reported every 1 minute */
42
+ #define REPORT_TIMEOUT 1000 /* Timeout for response from coordinator in ms */
40
43
41
44
uint8_t button = BOOT_PIN;
42
45
43
46
ZigbeeTempSensor zbTempSensor = ZigbeeTempSensor(TEMP_SENSOR_ENDPOINT_NUMBER);
44
47
48
+ uint8_t dataToSend = 2 ; // Temperature and humidity values are reported in same endpoint, so 2 values are reported
49
+ bool resend = false ;
50
+
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
+
45
76
/* *********************** Temp sensor *****************************/
46
- void meausureAndSleep () {
77
+ static void meausureAndSleep (void *arg ) {
47
78
// Measure temperature sensor value
48
79
float temperature = temperatureRead ();
49
80
@@ -55,13 +86,35 @@ void meausureAndSleep() {
55
86
zbTempSensor.setHumidity (humidity);
56
87
57
88
// Report temperature and humidity values
58
- zbTempSensor.report ();
89
+ zbTempSensor.report (); // reports temperature and humidity values (if humidity sensor is not added, only temperature is reported)
59
90
Serial.printf (" Reported temperature: %.2f°C, Humidity: %.2f%%\r\n " , temperature, humidity);
60
91
61
- // Add small delay to allow the data to be sent before going to sleep
62
- delay (100 );
92
+ unsigned long startTime = millis ();
93
+ const unsigned long timeout = REPORT_TIMEOUT;
94
+
95
+ Serial.printf (" Waiting for data report to be confirmed \r\n " );
96
+ // Wait until data was successfully sent
97
+ int tries = 0 ;
98
+ const int maxTries = 3 ;
99
+ while (dataToSend != 0 && tries < maxTries) {
100
+ if (resend) {
101
+ Serial.println (" Resending data on failure!" );
102
+ resend = false ;
103
+ dataToSend = 2 ;
104
+ zbTempSensor.report (); // report again
105
+ }
106
+ if (millis () - startTime >= timeout) {
107
+ Serial.println (" \n Report timeout! Report Again" );
108
+ dataToSend = 2 ;
109
+ zbTempSensor.report (); // report again
110
+ startTime = millis ();
111
+ tries++;
112
+ }
113
+ Serial.printf (" ." );
114
+ delay (50 ); // 50ms delay to avoid busy-waiting
115
+ }
63
116
64
- // Put device to deep sleep
117
+ // Put device to deep sleep after data was sent successfully or timeout
65
118
Serial.println (" Going to sleep now" );
66
119
esp_deep_sleep_start ();
67
120
}
@@ -92,6 +145,16 @@ void setup() {
92
145
// Add humidity cluster to the temperature sensor device with min, max and tolerance values
93
146
zbTempSensor.addHumiditySensor (0 , 100 , 1 );
94
147
148
+ // Set callback for default response to handle status of reported data, there are 2 options.
149
+
150
+ #if USE_GLOBAL_ON_RESPONSE_CALLBACK
151
+ // Global callback for all endpoints with more params to determine the endpoint and cluster in the callback function.
152
+ Zigbee.onGlobalDefaultResponse (onGlobalResponse);
153
+ #else
154
+ // Callback specified for endpoint
155
+ zbTempSensor.onDefaultResponse (onResponse);
156
+ #endif
157
+
95
158
// Add endpoint to Zigbee Core
96
159
Zigbee.addEndpoint (&zbTempSensor);
97
160
@@ -117,8 +180,8 @@ void setup() {
117
180
Serial.println ();
118
181
Serial.println (" Successfully connected to Zigbee network" );
119
182
120
- // Delay approx 1s (may be adjusted) to allow establishing proper connection with coordinator, needed for sleepy devices
121
- delay ( 1000 );
183
+ // Start Temperature sensor reading task
184
+ xTaskCreate (meausureAndSleep, " temp_sensor_update " , 2048 , NULL , 10 , NULL );
122
185
}
123
186
124
187
void loop () {
@@ -141,7 +204,5 @@ void loop() {
141
204
}
142
205
}
143
206
}
144
-
145
- // Call the function to measure temperature and put the device to sleep
146
- meausureAndSleep ();
207
+ delay (100 );
147
208
}
0 commit comments