Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
#include "Zigbee.h"

/* Zigbee contact sensor configuration */
#define CONTACT_SWITCH_ENDPOINT_NUMBER 10
#define CONTACT_SWITCH_ENDPOINT_NUMBER 1
uint8_t button = BOOT_PIN;
uint8_t sensor_pin = 4;

Expand Down Expand Up @@ -67,6 +67,21 @@ void setup() {
delay(100);
}
Serial.println();

// Request IAS Zone enroll
if (!zbContactSwitch.requestIASZoneEnroll()) {
Serial.println("Failed to request IAS Zone enroll!");
Serial.println("Rebooting...");
ESP.restart();
} else {
Serial.println("IAS Zone enroll requested successfully!");
}
while (!zbContactSwitch.enrolled()) {
Serial.print(".");
delay(100);
}
Serial.println();
Serial.println("Zigbee enrolled successfully!");
}

void loop() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
#include "Zigbee.h"

/* Zigbee vibration sensor configuration */
#define VIBRATION_SENSOR_ENDPOINT_NUMBER 10
#define VIBRATION_SENSOR_ENDPOINT_NUMBER 1
uint8_t button = BOOT_PIN;
uint8_t sensor_pin = 4;

Expand Down Expand Up @@ -67,6 +67,20 @@ void setup() {
delay(100);
}
Serial.println();
// Request IAS Zone enroll
if (!zbVibrationSensor.requestIASZoneEnroll()) {
Serial.println("Failed to request IAS Zone enroll!");
Serial.println("Rebooting...");
ESP.restart();
} else {
Serial.println("IAS Zone enroll requested successfully!");
}
while (!zbVibrationSensor.enrolled()) {
Serial.print(".");
delay(100);
}
Serial.println();
Serial.println("Zigbee enrolled successfully!");
}

void loop() {
Expand Down
39 changes: 26 additions & 13 deletions libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ ZigbeeContactSwitch::ZigbeeContactSwitch(uint8_t endpoint) : ZigbeeEP(endpoint)
_zone_status = 0;
_zone_id = 0xff;
_ias_cie_endpoint = 1;
_enrolled = false;

//Create custom contact switch configuration
zigbee_contact_switch_cfg_t contact_switch_cfg = ZIGBEE_DEFAULT_CONTACT_SWITCH_CONFIG();
Expand All @@ -44,31 +45,33 @@ void ZigbeeContactSwitch::setIASClientEndpoint(uint8_t ep_number) {
}

bool ZigbeeContactSwitch::setClosed() {
esp_zb_zcl_status_t ret = ESP_ZB_ZCL_STATUS_SUCCESS;
log_v("Setting Contact switch to closed");
uint8_t closed = 0; // ALARM1 = 0, ALARM2 = 0
esp_zb_lock_acquire(portMAX_DELAY);
esp_err_t ret = esp_zb_zcl_set_attribute_val(
ret = esp_zb_zcl_set_attribute_val(
_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONESTATUS_ID, &closed, false
);
esp_zb_lock_release();
if (ret != ESP_OK) {
log_e("Failed to set contact switch to closed: 0x%x: %s", ret, esp_err_to_name(ret));
if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
log_e("Failed to set contact switch to closed: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
return false;
}
_zone_status = closed;
return report();
}

bool ZigbeeContactSwitch::setOpen() {
esp_zb_zcl_status_t ret = ESP_ZB_ZCL_STATUS_SUCCESS;
log_v("Setting Contact switch to open");
uint8_t open = ESP_ZB_ZCL_IAS_ZONE_ZONE_STATUS_ALARM1 | ESP_ZB_ZCL_IAS_ZONE_ZONE_STATUS_ALARM2; // ALARM1 = 1, ALARM2 = 1
esp_zb_lock_acquire(portMAX_DELAY);
esp_err_t ret = esp_zb_zcl_set_attribute_val(
ret = esp_zb_zcl_set_attribute_val(
_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONESTATUS_ID, &open, false
);
esp_zb_lock_release();
if (ret != ESP_OK) {
log_e("Failed to set contact switch to open: 0x%x: %s", ret, esp_err_to_name(ret));
if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
log_e("Failed to set contact switch to open: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
return false;
}
_zone_status = open;
Expand All @@ -90,13 +93,9 @@ bool ZigbeeContactSwitch::report() {
status_change_notif_cmd.delay = 0;

esp_zb_lock_acquire(portMAX_DELAY);
esp_err_t ret = esp_zb_zcl_ias_zone_status_change_notif_cmd_req(&status_change_notif_cmd);
uint8_t tsn = esp_zb_zcl_ias_zone_status_change_notif_cmd_req(&status_change_notif_cmd);
esp_zb_lock_release();
if (ret != ESP_OK) {
log_e("Failed to send IAS Zone status changed notification: 0x%x: %s", ret, esp_err_to_name(ret));
return false;
}
log_v("IAS Zone status changed notification sent");
log_v("IAS Zone status changed notification sent with transaction sequence number: %u", tsn);
return true;
}

Expand All @@ -115,11 +114,25 @@ void ZigbeeContactSwitch::zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enro
);
esp_zb_lock_release();
_zone_id = message->zone_id;
_enrolled = true;
}

} else {
log_w("Received message ignored. Cluster ID: %d not supported for On/Off Light", message->info.cluster);
}
}

bool ZigbeeContactSwitch::requestIASZoneEnroll() {
esp_zb_zcl_ias_zone_enroll_request_cmd_t enroll_request;
enroll_request.zcl_basic_cmd.src_endpoint = _endpoint;
enroll_request.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
enroll_request.zone_type = ESP_ZB_ZCL_IAS_ZONE_ZONETYPE_CONTACT_SWITCH;
enroll_request.manuf_code = 0;

esp_zb_lock_acquire(portMAX_DELAY);
uint8_t tsn = esp_zb_zcl_ias_zone_enroll_cmd_req(&enroll_request);
esp_zb_lock_release();
log_v("IAS Zone enroll request send with transaction sequence number: %u", tsn);
return true;
}

#endif // CONFIG_ZB_ENABLED
7 changes: 7 additions & 0 deletions libraries/Zigbee/src/ep/ZigbeeContactSwitch.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,19 @@ class ZigbeeContactSwitch : public ZigbeeEP {
// Report the contact switch value, done automatically after setting the position
bool report();

// Request a new IAS zone enroll, needed to be called after rebooting already configured device
bool requestIASZoneEnroll();

// Check if the device is enrolled in the IAS Zone
bool enrolled() { return _enrolled; }

private:
void zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) override;
uint8_t _zone_status;
uint8_t _zone_id;
esp_zb_ieee_addr_t _ias_cie_addr;
uint8_t _ias_cie_endpoint;
bool _enrolled;
};

#endif // CONFIG_ZB_ENABLED
22 changes: 18 additions & 4 deletions libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ ZigbeeDoorWindowHandle::ZigbeeDoorWindowHandle(uint8_t endpoint) : ZigbeeEP(endp
_zone_status = 0;
_zone_id = 0xff;
_ias_cie_endpoint = 1;
_enrolled = false;

//Create custom door window handle configuration
zigbee_door_window_handle_cfg_t door_window_handle_cfg = ZIGBEE_DEFAULT_DOOR_WINDOW_HANDLE_CONFIG();
Expand Down Expand Up @@ -108,11 +109,10 @@ bool ZigbeeDoorWindowHandle::report() {
status_change_notif_cmd.zone_id = _zone_id;
status_change_notif_cmd.delay = 0;

//NOTE: Check result of esp_zb_zcl_ias_zone_status_change_notif_cmd_req() and return true if success, false if failure
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_ias_zone_status_change_notif_cmd_req(&status_change_notif_cmd);
uint8_t tsn = esp_zb_zcl_ias_zone_status_change_notif_cmd_req(&status_change_notif_cmd);
esp_zb_lock_release();
log_v("IAS Zone status changed notification sent");
log_v("IAS Zone status changed notification sent with transaction sequence number: %u", tsn);
return true;
}

Expand All @@ -131,11 +131,25 @@ void ZigbeeDoorWindowHandle::zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_e
);
esp_zb_lock_release();
_zone_id = message->zone_id;
_enrolled = true;
}

} else {
log_w("Received message ignored. Cluster ID: %d not supported for On/Off Light", message->info.cluster);
}
}

bool ZigbeeDoorWindowHandle::requestIASZoneEnroll() {
esp_zb_zcl_ias_zone_enroll_request_cmd_t enroll_request;
enroll_request.zcl_basic_cmd.src_endpoint = _endpoint;
enroll_request.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
enroll_request.zone_type = ESP_ZB_ZCL_IAS_ZONE_ZONETYPE_DOOR_WINDOW_HANDLE;
enroll_request.manuf_code = 0;

esp_zb_lock_acquire(portMAX_DELAY);
uint8_t tsn = esp_zb_zcl_ias_zone_enroll_cmd_req(&enroll_request);
esp_zb_lock_release();
log_v("IAS Zone enroll request send with transaction sequence number: %u", tsn);
return true;
}

#endif // CONFIG_ZB_ENABLED
7 changes: 7 additions & 0 deletions libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,19 @@ class ZigbeeDoorWindowHandle : public ZigbeeEP {
// Report the door/window handle value, done automatically after setting the position
bool report();

// Request a new IAS zone enroll, needed to be called after rebooting already configured device
bool requestIASZoneEnroll();

// Check if the device is enrolled in the IAS Zone
bool enrolled() { return _enrolled; }

private:
void zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) override;
uint8_t _zone_status;
uint8_t _zone_id;
esp_zb_ieee_addr_t _ias_cie_addr;
uint8_t _ias_cie_endpoint;
bool _enrolled;
};

#endif // CONFIG_ZB_ENABLED
27 changes: 21 additions & 6 deletions libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ ZigbeeVibrationSensor::ZigbeeVibrationSensor(uint8_t endpoint) : ZigbeeEP(endpoi
_zone_status = 0;
_zone_id = 0xff;
_ias_cie_endpoint = 1;
_enrolled = false;

//Create custom vibration sensor configuration
zigbee_vibration_sensor_cfg_t vibration_sensor_cfg = ZIGBEE_DEFAULT_VIBRATION_SENSOR_CONFIG();
Expand All @@ -57,11 +58,10 @@ bool ZigbeeVibrationSensor::setVibration(bool sensed) {
return false;
}
_zone_status = vibration;
report();
return true;
return report();
}

void ZigbeeVibrationSensor::report() {
bool ZigbeeVibrationSensor::report() {
/* Send IAS Zone status changed notification command */

esp_zb_zcl_ias_zone_status_change_notif_cmd_t status_change_notif_cmd;
Expand All @@ -75,9 +75,10 @@ void ZigbeeVibrationSensor::report() {
status_change_notif_cmd.delay = 0;

esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_ias_zone_status_change_notif_cmd_req(&status_change_notif_cmd);
uint8_t tsn = esp_zb_zcl_ias_zone_status_change_notif_cmd_req(&status_change_notif_cmd);
esp_zb_lock_release();
log_v("IAS Zone status changed notification sent");
log_v("IAS Zone status changed notification sent with transaction sequence number: %u", tsn);
return true;
}

void ZigbeeVibrationSensor::zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) {
Expand All @@ -95,11 +96,25 @@ void ZigbeeVibrationSensor::zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_en
);
esp_zb_lock_release();
_zone_id = message->zone_id;
_enrolled = true;
}

} else {
log_w("Received message ignored. Cluster ID: %d not supported for On/Off Light", message->info.cluster);
}
}

bool ZigbeeVibrationSensor::requestIASZoneEnroll() {
esp_zb_zcl_ias_zone_enroll_request_cmd_t enroll_request;
enroll_request.zcl_basic_cmd.src_endpoint = _endpoint;
enroll_request.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
enroll_request.zone_type = ESP_ZB_ZCL_IAS_ZONE_ZONETYPE_VIBRATION_MOVEMENT;
enroll_request.manuf_code = 0;

esp_zb_lock_acquire(portMAX_DELAY);
uint8_t tsn = esp_zb_zcl_ias_zone_enroll_cmd_req(&enroll_request);
esp_zb_lock_release();
log_v("IAS Zone enroll request send with transaction sequence number: %u", tsn);
return true;
}

#endif // CONFIG_ZB_ENABLED
9 changes: 8 additions & 1 deletion libraries/Zigbee/src/ep/ZigbeeVibrationSensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,21 @@ class ZigbeeVibrationSensor : public ZigbeeEP {
bool setVibration(bool sensed);

// Report the vibration sensor value, done automatically after setting the sensed value
void report();
bool report();

// Request a new IAS zone enroll, needed to be called after rebooting already configured device
bool requestIASZoneEnroll();

// Check if the device is enrolled in the IAS Zone
bool enrolled() { return _enrolled; }

private:
void zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) override;
uint8_t _zone_status;
uint8_t _zone_id;
esp_zb_ieee_addr_t _ias_cie_addr;
uint8_t _ias_cie_endpoint;
bool _enrolled;
};

#endif // CONFIG_ZB_ENABLED
Loading