Skip to content

Commit 1ecb566

Browse files
committed
feat(zigbee): OTA inhibit sleep
1 parent d136bce commit 1ecb566

File tree

4 files changed

+61
-2
lines changed

4 files changed

+61
-2
lines changed

libraries/Zigbee/examples/Zigbee_Temp_Hum_Sensor_Sleepy/Zigbee_Temp_Hum_Sensor_Sleepy.ino

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@
3232

3333
#include "Zigbee.h"
3434

35+
/* Zigbee OTA configuration */
36+
37+
#define OTA_UPGRADE_RUNNING_FILE_VERSION 0x01010100 // Increment this value when the running image is updated
38+
#define OTA_UPGRADE_DOWNLOADED_FILE_VERSION 0x01010101 // Increment this value when the downloaded image is updated
39+
#define OTA_UPGRADE_HW_VERSION 0x0101 // The hardware version, this can be used to differentiate between different hardware versions
40+
3541
#define USE_GLOBAL_ON_RESPONSE_CALLBACK 1 // Set to 0 to use local callback specified directly for the endpoint.
3642

3743
/* Zigbee temperature + humidity sensor configuration */
@@ -45,6 +51,7 @@ uint8_t button = BOOT_PIN;
4551

4652
ZigbeeTempSensor zbTempSensor = ZigbeeTempSensor(TEMP_SENSOR_ENDPOINT_NUMBER);
4753

54+
volatile bool otaInhibitSleep = false;
4855
uint8_t dataToSend = 2; // Temperature and humidity values are reported in same endpoint, so 2 values are reported
4956
bool resend = false;
5057

@@ -73,6 +80,15 @@ void onResponse(zb_cmd_type_t command, esp_zb_zcl_status_t status) {
7380
}
7481
#endif
7582

83+
void otaSleepInhibitCallback(bool otaActive) {
84+
otaInhibitSleep = otaActive;
85+
if (otaActive) {
86+
Serial.println("OTA started: inhibiting sleep");
87+
} else {
88+
Serial.println("OTA finished: sleep allowed");
89+
}
90+
}
91+
7692
/************************ Temp sensor *****************************/
7793
static void meausureAndSleep(void *arg) {
7894
// Measure temperature sensor value
@@ -115,8 +131,10 @@ static void meausureAndSleep(void *arg) {
115131
}
116132

117133
// Put device to deep sleep after data was sent successfully or timeout
118-
Serial.println("Going to sleep now");
119-
esp_deep_sleep_start();
134+
if (!otaInhibitSleep) {
135+
Serial.println("Going to sleep now");
136+
esp_deep_sleep_start();
137+
}
120138
}
121139

122140
/********************* Arduino functions **************************/
@@ -132,6 +150,12 @@ void setup() {
132150
// Optional: set Zigbee device name and model
133151
zbTempSensor.setManufacturerAndModel("Espressif", "SleepyZigbeeTempSensor");
134152

153+
// Optional: set ota
154+
zbTempSensor.addOTAClient(OTA_UPGRADE_RUNNING_FILE_VERSION, OTA_UPGRADE_DOWNLOADED_FILE_VERSION, OTA_UPGRADE_HW_VERSION);
155+
156+
// Optional: Register callback for OTA state change (inhibit sleep during OTA)
157+
zbTempSensor.onOTAStateChange(otaSleepInhibitCallback);
158+
135159
// Set minimum and maximum temperature measurement value (10-50°C is default range for chip temperature measurement)
136160
zbTempSensor.setMinMaxValue(10, 50);
137161

@@ -180,6 +204,9 @@ void setup() {
180204
Serial.println();
181205
Serial.println("Successfully connected to Zigbee network");
182206

207+
// Start Zigbee OTA client query, first request is within a minute and the next requests are sent every hour automatically
208+
zbLight.requestOTAUpdate();
209+
183210
// Start Temperature sensor reading task
184211
xTaskCreate(meausureAndSleep, "temp_sensor_update", 2048, NULL, 10, NULL);
185212
}
@@ -193,6 +220,10 @@ void loop() {
193220
while (digitalRead(button) == LOW) {
194221
delay(50);
195222
if ((millis() - startTime) > 10000) {
223+
if (otaInhibitSleep) {
224+
Serial.println("OTA in progress, cannot reset now");
225+
break;
226+
}
196227
// If key pressed for more than 10secs, factory reset Zigbee and reboot
197228
Serial.println("Resetting Zigbee to factory and rebooting in 1s.");
198229
delay(1000);

libraries/Zigbee/src/ZigbeeEP.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ ZigbeeEP::ZigbeeEP(uint8_t endpoint) {
2828
_ep_config.endpoint = 0;
2929
_cluster_list = nullptr;
3030
_on_identify = nullptr;
31+
_on_ota_state_change = nullptr;
3132
_read_model = NULL;
3233
_read_manufacturer = NULL;
3334
_time_status = 0;
@@ -318,6 +319,12 @@ void ZigbeeEP::zbIdentify(const esp_zb_zcl_set_attr_value_message_t *message) {
318319
}
319320
}
320321

322+
void ZigbeeEP::zbOTAState(bool otaActive) {
323+
if (_on_ota_state_change != NULL) {
324+
_on_ota_state_change(otaActive);
325+
}
326+
}
327+
321328
bool ZigbeeEP::addTimeCluster(tm time, int32_t gmt_offset) {
322329
time_t utc_time = 0;
323330
// Check if time is set

libraries/Zigbee/src/ZigbeeEP.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ class ZigbeeEP {
153153
zbWriteAttributeResponse(uint16_t cluster_id, uint16_t attribute_id, esp_zb_zcl_status_t status, uint8_t src_endpoint, esp_zb_zcl_addr_t src_address) {};
154154
virtual void zbReadBasicCluster(const esp_zb_zcl_attribute_t *attribute); //already implemented
155155
virtual void zbIdentify(const esp_zb_zcl_set_attr_value_message_t *message);
156+
virtual void zbOTAState(bool otaActive);
156157
virtual void zbWindowCoveringMovementCmd(const esp_zb_zcl_window_covering_movement_message_t *message) {};
157158
virtual void zbReadTimeCluster(const esp_zb_zcl_attribute_t *attribute); //already implemented
158159
virtual void zbIASZoneStatusChangeNotification(const esp_zb_zcl_ias_zone_status_change_notification_message_t *message) {};
@@ -176,6 +177,10 @@ class ZigbeeEP {
176177
_on_identify = callback;
177178
}
178179

180+
void onOTAStateChange(void (*callback)(bool state)) {
181+
_on_ota_state_change = callback;
182+
}
183+
179184
void onDefaultResponse(void (*callback)(zb_cmd_type_t resp_to_cmd, esp_zb_zcl_status_t status)) {
180185
_on_default_response = callback;
181186
}
@@ -186,6 +191,7 @@ class ZigbeeEP {
186191
char *_read_manufacturer;
187192
char *_read_model;
188193
void (*_on_identify)(uint16_t time);
194+
void (*_on_ota_state_change)(bool state);
189195
void (*_on_default_response)(zb_cmd_type_t resp_to_cmd, esp_zb_zcl_status_t status);
190196
time_t _read_time;
191197
int32_t _read_timezone;

libraries/Zigbee/src/ZigbeeHandlers.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,9 @@ static esp_err_t zb_ota_upgrade_status_handler(const esp_zb_zcl_ota_upgrade_valu
338338
switch (message->upgrade_status) {
339339
case ESP_ZB_ZCL_OTA_UPGRADE_STATUS_START:
340340
log_i("Zigbee - OTA upgrade start");
341+
for (std::list<ZigbeeEP *>::iterator it = Zigbee.ep_objects.begin(); it != Zigbee.ep_objects.end(); ++it) {
342+
(*it)->zbOTAState(true); // Notify that OTA is active
343+
}
341344
start_time = esp_timer_get_time();
342345
s_ota_partition = esp_ota_get_next_update_partition(NULL);
343346
assert(s_ota_partition);
@@ -348,6 +351,9 @@ static esp_err_t zb_ota_upgrade_status_handler(const esp_zb_zcl_ota_upgrade_valu
348351
#endif
349352
if (ret != ESP_OK) {
350353
log_e("Zigbee - Failed to begin OTA partition, status: %s", esp_err_to_name(ret));
354+
for (std::list<ZigbeeEP *>::iterator it = Zigbee.ep_objects.begin(); it != Zigbee.ep_objects.end(); ++it) {
355+
(*it)->zbOTAState(false); // Notify that OTA is no longer active
356+
}
351357
return ret;
352358
}
353359
break;
@@ -361,6 +367,9 @@ static esp_err_t zb_ota_upgrade_status_handler(const esp_zb_zcl_ota_upgrade_valu
361367
ret = esp_element_ota_data(total_size, message->payload, message->payload_size, &payload, &payload_size);
362368
if (ret != ESP_OK) {
363369
log_e("Zigbee - Failed to element OTA data, status: %s", esp_err_to_name(ret));
370+
for (std::list<ZigbeeEP *>::iterator it = Zigbee.ep_objects.begin(); it != Zigbee.ep_objects.end(); ++it) {
371+
(*it)->zbOTAState(false); // Notify that OTA is no longer active
372+
}
364373
return ret;
365374
}
366375
#if CONFIG_ZB_DELTA_OTA
@@ -370,6 +379,9 @@ static esp_err_t zb_ota_upgrade_status_handler(const esp_zb_zcl_ota_upgrade_valu
370379
#endif
371380
if (ret != ESP_OK) {
372381
log_e("Zigbee - Failed to write OTA data to partition, status: %s", esp_err_to_name(ret));
382+
for (std::list<ZigbeeEP *>::iterator it = Zigbee.ep_objects.begin(); it != Zigbee.ep_objects.end(); ++it) {
383+
(*it)->zbOTAState(false); // Notify that OTA is no longer active
384+
}
373385
return ret;
374386
}
375387
}
@@ -389,6 +401,9 @@ static esp_err_t zb_ota_upgrade_status_handler(const esp_zb_zcl_ota_upgrade_valu
389401
message->ota_header.file_version, message->ota_header.manufacturer_code, message->ota_header.image_type, message->ota_header.image_size,
390402
(esp_timer_get_time() - start_time) / 1000
391403
);
404+
for (std::list<ZigbeeEP *>::iterator it = Zigbee.ep_objects.begin(); it != Zigbee.ep_objects.end(); ++it) {
405+
(*it)->zbOTAState(false); // Notify that OTA is no longer active
406+
}
392407
#if CONFIG_ZB_DELTA_OTA
393408
ret = esp_delta_ota_end(s_ota_handle);
394409
#else

0 commit comments

Comments
 (0)