Skip to content

Commit 8910320

Browse files
committed
feat(zigbee): Add restoreIASZone from flash method
1 parent f5f3295 commit 8910320

File tree

7 files changed

+126
-14
lines changed

7 files changed

+126
-14
lines changed

libraries/Zigbee/examples/Zigbee_Contact_Switch/Zigbee_Contact_Switch.ino

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#endif
3232

3333
#include "Zigbee.h"
34+
#include <Preferences.h>
3435

3536
/* Zigbee contact sensor configuration */
3637
#define CONTACT_SWITCH_ENDPOINT_NUMBER 1
@@ -39,9 +40,16 @@ uint8_t sensor_pin = 4;
3940

4041
ZigbeeContactSwitch zbContactSwitch = ZigbeeContactSwitch(CONTACT_SWITCH_ENDPOINT_NUMBER);
4142

43+
/* Preferences for storing ENROLLED flag to persist across reboots */
44+
Preferences preferences;
45+
4246
void setup() {
4347
Serial.begin(115200);
4448

49+
preferences.begin("Zigbee", false); // Save ENROLLED flag in flash so it persists across reboots
50+
bool enrolled = preferences.getBool("ENROLLED"); // Get ENROLLED flag from preferences
51+
preferences.end();
52+
4553
// Init button + switch
4654
pinMode(button, INPUT_PULLUP);
4755
pinMode(sensor_pin, INPUT_PULLUP);
@@ -68,20 +76,30 @@ void setup() {
6876
}
6977
Serial.println();
7078

71-
// Request IAS Zone enroll
72-
if (!zbContactSwitch.requestIASZoneEnroll()) {
73-
Serial.println("Failed to request IAS Zone enroll!");
74-
Serial.println("Rebooting...");
75-
ESP.restart();
79+
// Check if device has been enrolled before restarting - if so, restore IAS Zone enroll, otherwise request new IAS Zone enroll
80+
if (enrolled) {
81+
Serial.println("Device has been enrolled before - restoring IAS Zone enrollment");
82+
zbContactSwitch.restoreIASZoneEnroll();
7683
} else {
77-
Serial.println("IAS Zone enroll requested successfully!");
84+
Serial.println("Device is factory new - first time joining network - requesting new IAS Zone enrollment");
85+
zbContactSwitch.requestIASZoneEnroll();
7886
}
87+
7988
while (!zbContactSwitch.enrolled()) {
8089
Serial.print(".");
8190
delay(100);
8291
}
8392
Serial.println();
8493
Serial.println("Zigbee enrolled successfully!");
94+
95+
// Store ENROLLED flag only if this was a new enrollment (previous flag was false)
96+
// Skip writing if we just restored enrollment (flag was already true)
97+
if (!enrolled) {
98+
preferences.begin("Zigbee", false);
99+
preferences.putBool("ENROLLED", true); // set ENROLLED flag to true
100+
preferences.end();
101+
Serial.println("ENROLLED flag saved to preferences");
102+
}
85103
}
86104

87105
void loop() {
@@ -106,6 +124,11 @@ void loop() {
106124
if ((millis() - startTime) > 3000) {
107125
// If key pressed for more than 3secs, factory reset Zigbee and reboot
108126
Serial.println("Resetting Zigbee to factory and rebooting in 1s.");
127+
// Clear the ENROLLED flag from preferences
128+
preferences.begin("Zigbee", false);
129+
preferences.putBool("ENROLLED", false); // set ENROLLED flag to false
130+
preferences.end();
131+
Serial.println("ENROLLED flag cleared from preferences");
109132
delay(1000);
110133
Zigbee.factoryReset();
111134
}

libraries/Zigbee/examples/Zigbee_Vibration_Sensor/Zigbee_Vibration_Sensor.ino

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#endif
3232

3333
#include "Zigbee.h"
34+
#include <Preferences.h>
3435

3536
/* Zigbee vibration sensor configuration */
3637
#define VIBRATION_SENSOR_ENDPOINT_NUMBER 1
@@ -39,9 +40,16 @@ uint8_t sensor_pin = 4;
3940

4041
ZigbeeVibrationSensor zbVibrationSensor = ZigbeeVibrationSensor(VIBRATION_SENSOR_ENDPOINT_NUMBER);
4142

43+
/* Preferences for storing ENROLLED flag to persist across reboots */
44+
Preferences preferences;
45+
4246
void setup() {
4347
Serial.begin(115200);
4448

49+
preferences.begin("Zigbee", false); // Save ENROLLED flag in flash so it persists across reboots
50+
bool enrolled = preferences.getBool("ENROLLED"); // Get ENROLLED flag from preferences
51+
preferences.end();
52+
4553
// Init button + sensor
4654
pinMode(button, INPUT_PULLUP);
4755
pinMode(sensor_pin, INPUT);
@@ -67,20 +75,31 @@ void setup() {
6775
delay(100);
6876
}
6977
Serial.println();
70-
// Request IAS Zone enroll
71-
if (!zbVibrationSensor.requestIASZoneEnroll()) {
72-
Serial.println("Failed to request IAS Zone enroll!");
73-
Serial.println("Rebooting...");
74-
ESP.restart();
78+
79+
// Check if device has been enrolled before restarting - if so, restore IAS Zone enroll, otherwise request new IAS Zone enroll
80+
if (enrolled) {
81+
Serial.println("Device has been enrolled before - restoring IAS Zone enrollment");
82+
zbVibrationSensor.restoreIASZoneEnroll();
7583
} else {
76-
Serial.println("IAS Zone enroll requested successfully!");
84+
Serial.println("Device is factory new - first time joining network - requesting new IAS Zone enrollment");
85+
zbVibrationSensor.requestIASZoneEnroll();
7786
}
87+
7888
while (!zbVibrationSensor.enrolled()) {
7989
Serial.print(".");
8090
delay(100);
8191
}
8292
Serial.println();
8393
Serial.println("Zigbee enrolled successfully!");
94+
95+
// Store ENROLLED flag only if this was a new enrollment (previous flag was false)
96+
// Skip writing if we just restored enrollment (flag was already true)
97+
if (!enrolled) {
98+
preferences.begin("Zigbee", false);
99+
preferences.putBool("ENROLLED", true); // set ENROLLED flag to true
100+
preferences.end();
101+
Serial.println("ENROLLED flag saved to preferences");
102+
}
84103
}
85104

86105
void loop() {
@@ -109,6 +128,11 @@ void loop() {
109128
if ((millis() - startTime) > 3000) {
110129
// If key pressed for more than 3secs, factory reset Zigbee and reboot
111130
Serial.println("Resetting Zigbee to factory and rebooting in 1s.");
131+
// Clear the ENROLLED flag from preferences
132+
preferences.begin("Zigbee", false);
133+
preferences.putBool("ENROLLED", false); // set ENROLLED flag to false
134+
preferences.end();
135+
Serial.println("ENROLLED flag cleared from preferences");
112136
delay(1000);
113137
Zigbee.factoryReset();
114138
}

libraries/Zigbee/keywords.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,9 @@ setIASClientEndpoint KEYWORD2
209209
setClosed KEYWORD2
210210
setOpen KEYWORD2
211211
setTilted KEYWORD2
212+
requestIASZoneEnroll KEYWORD2
213+
restoreIASZoneEnroll KEYWORD2
214+
enrolled KEYWORD2
212215

213216
# ZigbeeVibrationSensor
214217
setVibration KEYWORD2

libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,4 +135,32 @@ bool ZigbeeContactSwitch::requestIASZoneEnroll() {
135135
return true;
136136
}
137137

138+
bool ZigbeeContactSwitch::restoreIASZoneEnroll() {
139+
esp_zb_lock_acquire(portMAX_DELAY);
140+
memcpy(
141+
_ias_cie_addr,
142+
(*(esp_zb_ieee_addr_t *)
143+
esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_IAS_CIE_ADDRESS_ID)
144+
->data_p),
145+
sizeof(esp_zb_ieee_addr_t)
146+
);
147+
_zone_id = (*(uint8_t *)
148+
esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONEID_ID)
149+
->data_p);
150+
esp_zb_lock_release();
151+
152+
log_d("Restored IAS Zone enroll: zone id(%d), ias cie address(%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X)", _zone_id, _ias_cie_addr[0], _ias_cie_addr[1], _ias_cie_addr[2], _ias_cie_addr[3], _ias_cie_addr[4], _ias_cie_addr[5], _ias_cie_addr[6], _ias_cie_addr[7]);
153+
154+
if (_zone_id == 0xFF) {
155+
log_e("Failed to restore IAS Zone enroll: zone id not found");
156+
return false;
157+
}
158+
if (_ias_cie_addr == NULL) {
159+
log_e("Failed to restore IAS Zone enroll: ias cie address not found");
160+
return false;
161+
}
162+
_enrolled = true;
163+
return true;
164+
}
165+
138166
#endif // CONFIG_ZB_ENABLED

libraries/Zigbee/src/ep/ZigbeeContactSwitch.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,12 @@ class ZigbeeContactSwitch : public ZigbeeEP {
7070
// Report the contact switch value, done automatically after setting the position
7171
bool report();
7272

73-
// Request a new IAS zone enroll, needed to be called after rebooting already configured device
73+
// Request a new IAS zone enroll, can be called to enroll a new device or to re-enroll an already enrolled device
7474
bool requestIASZoneEnroll();
7575

76+
// Restore IAS Zone enroll, needed to be called after rebooting already enrolled device - restored from flash memory (faster for sleepy devices)
77+
bool restoreIASZoneEnroll();
78+
7679
// Check if the device is enrolled in the IAS Zone
7780
bool enrolled() { return _enrolled; }
7881

libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,4 +117,32 @@ bool ZigbeeVibrationSensor::requestIASZoneEnroll() {
117117
return true;
118118
}
119119

120+
bool ZigbeeVibrationSensor::restoreIASZoneEnroll() {
121+
esp_zb_lock_acquire(portMAX_DELAY);
122+
memcpy(
123+
_ias_cie_addr,
124+
(*(esp_zb_ieee_addr_t *)
125+
esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_IAS_CIE_ADDRESS_ID)
126+
->data_p),
127+
sizeof(esp_zb_ieee_addr_t)
128+
);
129+
_zone_id = (*(uint8_t *)
130+
esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONEID_ID)
131+
->data_p);
132+
esp_zb_lock_release();
133+
134+
log_d("Restored IAS Zone enroll: zone id(%d), ias cie address(%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X)", _zone_id, _ias_cie_addr[0], _ias_cie_addr[1], _ias_cie_addr[2], _ias_cie_addr[3], _ias_cie_addr[4], _ias_cie_addr[5], _ias_cie_addr[6], _ias_cie_addr[7]);
135+
136+
if (_zone_id == 0xFF) {
137+
log_e("Failed to restore IAS Zone enroll: zone id not found");
138+
return false;
139+
}
140+
if (_ias_cie_addr == NULL) {
141+
log_e("Failed to restore IAS Zone enroll: ias cie address not found");
142+
return false;
143+
}
144+
_enrolled = true;
145+
return true;
146+
}
147+
120148
#endif // CONFIG_ZB_ENABLED

libraries/Zigbee/src/ep/ZigbeeVibrationSensor.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,12 @@ class ZigbeeVibrationSensor : public ZigbeeEP {
6767
// Report the vibration sensor value, done automatically after setting the sensed value
6868
bool report();
6969

70-
// Request a new IAS zone enroll, needed to be called after rebooting already configured device
70+
// Request a new IAS zone enroll, can be called to enroll a new device or to re-enroll an already enrolled device
7171
bool requestIASZoneEnroll();
7272

73+
// Restore IAS Zone enroll, needed to be called after rebooting already enrolled device - restored from flash memory (faster for sleepy devices)
74+
bool restoreIASZoneEnroll();
75+
7376
// Check if the device is enrolled in the IAS Zone
7477
bool enrolled() { return _enrolled; }
7578

0 commit comments

Comments
 (0)