feat(Zigbee): Recall bounded devices after reboot + IEEE address option for commands (#10676)

* feat(zigbee): Recall bound devices after reboot

* fix(zigbee): Add missing locks + allow printBoundDevices to Serial

* fix(Zigbee): Add locks to temp sensor setReporting

* fix(Zigbee): remove unnecessary space in formatting

* fix(Zigbee): proper parameter in printBoundDevices

* feat(Zigbee): factory reset when removed from network

* fix(zigbee): Update comment

* fix(zigbee): fix serial and add missing factoryReset to example

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
This commit is contained in:
Jan Procházka 2024-12-09 13:30:15 +01:00 committed by GitHub
parent e159bf6e46
commit 92dd841ffc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 376 additions and 59 deletions

View file

@ -145,6 +145,6 @@ void loop() {
static uint32_t last_print = 0;
if (millis() - last_print > 30000) {
last_print = millis();
zbSwitch.printBoundDevices();
zbSwitch.printBoundDevices(Serial);
}
}

View file

@ -138,17 +138,16 @@ void setup() {
delay(500);
}
// Optional: read manufacturer and model name from the bound light
// Optional: List all bound devices and read manufacturer and model name
std::list<zb_device_params_t *> boundLights = zbSwitch.getBoundDevices();
//List all bound lights
for (const auto &device : boundLights) {
Serial.printf("Device on endpoint %d, short address: 0x%x\n", device->endpoint, device->short_addr);
Serial.printf("Device on endpoint %d, short address: 0x%x\r\n", device->endpoint, device->short_addr);
Serial.printf(
"IEEE Address: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n", device->ieee_addr[0], device->ieee_addr[1], device->ieee_addr[2], device->ieee_addr[3],
device->ieee_addr[4], device->ieee_addr[5], device->ieee_addr[6], device->ieee_addr[7]
"IEEE Address: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\r\n", device->ieee_addr[7], device->ieee_addr[6], device->ieee_addr[5], device->ieee_addr[4],
device->ieee_addr[3], device->ieee_addr[2], device->ieee_addr[1], device->ieee_addr[0]
);
Serial.printf("Light manufacturer: %s", zbSwitch.readManufacturer(device->endpoint, device->short_addr));
Serial.printf("Light model: %s", zbSwitch.readModel(device->endpoint, device->short_addr));
Serial.printf("Light manufacturer: %s\r\n", zbSwitch.readManufacturer(device->endpoint, device->short_addr, device->ieee_addr));
Serial.printf("Light model: %s\r\n", zbSwitch.readModel(device->endpoint, device->short_addr, device->ieee_addr));
}
Serial.println();
@ -191,6 +190,6 @@ void loop() {
static uint32_t lastPrint = 0;
if (millis() - lastPrint > 10000) {
lastPrint = millis();
zbSwitch.printBoundDevices();
zbSwitch.printBoundDevices(Serial);
}
}

View file

@ -128,6 +128,7 @@ void loop() {
// If key pressed for more than 3secs, factory reset Zigbee and reboot
Serial.println("Resetting Zigbee to factory and rebooting in 1s.");
delay(1000);
Zigbee.factoryReset();
}
}
}

View file

@ -243,6 +243,7 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct) {
} else {
Zigbee._connected = true;
}
Zigbee.searchBindings();
}
} else {
/* commissioning failed */
@ -309,7 +310,6 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct) {
Bit 6 Security capability
Bit 7 Reserved
*/
// for each endpoint in the list call the findEndpoint function if not bounded or allowed to bind multiple devices
for (std::list<ZigbeeEP *>::iterator it = Zigbee.ep_objects.begin(); it != Zigbee.ep_objects.end(); ++it) {
if (!(*it)->bound() || (*it)->epAllowMultipleBinding()) {
@ -329,6 +329,12 @@ void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct) {
}
}
break;
case ESP_ZB_ZDO_SIGNAL_LEAVE: // End Device + Router
// Device was removed from the network, factory reset the device
if ((zigbee_role_t)Zigbee.getRole() != ZIGBEE_COORDINATOR) {
Zigbee.factoryReset();
}
break;
default: log_v("ZDO signal: %s (0x%x), status: %s", esp_zb_zdo_signal_to_string(sig_type), sig_type, esp_err_to_name(err_status)); break;
}
}
@ -391,6 +397,75 @@ void ZigbeeCore::scanDelete() {
_scan_status = ZB_SCAN_FAILED;
}
// Recall bounded devices from the binding table after reboot
void ZigbeeCore::bindingTableCb(const esp_zb_zdo_binding_table_info_t *table_info, void *user_ctx) {
bool done = true;
esp_zb_zdo_mgmt_bind_param_t *req = (esp_zb_zdo_mgmt_bind_param_t *)user_ctx;
esp_zb_zdp_status_t zdo_status = (esp_zb_zdp_status_t)table_info->status;
log_d("Binding table callback for address 0x%04x with status %d", req->dst_addr, zdo_status);
if (zdo_status == ESP_ZB_ZDP_STATUS_SUCCESS) {
// Print binding table log simple
log_d("Binding table info: total %d, index %d, count %d", table_info->total, table_info->index, table_info->count);
if (table_info->total == 0) {
log_d("No binding table entries found");
free(req);
return;
}
esp_zb_zdo_binding_table_record_t *record = table_info->record;
for (int i = 0; i < table_info->count; i++) {
log_d(
"Binding table record: src_endp %d, dst_endp %d, cluster_id 0x%04x, dst_addr_mode %d", record->src_endp, record->dst_endp, record->cluster_id,
record->dst_addr_mode
);
zb_device_params_t *device = (zb_device_params_t *)calloc(1, sizeof(zb_device_params_t));
device->endpoint = record->dst_endp;
if (record->dst_addr_mode == ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT || record->dst_addr_mode == ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT) {
device->short_addr = record->dst_address.addr_short;
} else { //ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT
memcpy(device->ieee_addr, record->dst_address.addr_long, sizeof(esp_zb_ieee_addr_t));
}
// Add to list of bound devices of proper endpoint
for (std::list<ZigbeeEP *>::iterator it = Zigbee.ep_objects.begin(); it != Zigbee.ep_objects.end(); ++it) {
if ((*it)->getEndpoint() == record->src_endp) {
(*it)->addBoundDevice(device);
log_d(
"Device bound to EP %d -> device endpoint: %d, short addr: 0x%04x, ieee addr: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", record->src_endp,
device->endpoint, device->short_addr, device->ieee_addr[7], device->ieee_addr[6], device->ieee_addr[5], device->ieee_addr[4], device->ieee_addr[3],
device->ieee_addr[2], device->ieee_addr[1], device->ieee_addr[0]
);
}
}
record = record->next;
}
// Continue reading the binding table
if (table_info->index + table_info->count < table_info->total) {
/* There are unreported binding table entries, request for them. */
req->start_index = table_info->index + table_info->count;
esp_zb_zdo_binding_table_req(req, bindingTableCb, req);
done = false;
}
}
if (done) {
// Print bound devices
log_d("Filling bounded devices finished");
free(req);
}
}
void ZigbeeCore::searchBindings() {
esp_zb_zdo_mgmt_bind_param_t *mb_req = (esp_zb_zdo_mgmt_bind_param_t *)malloc(sizeof(esp_zb_zdo_mgmt_bind_param_t));
mb_req->dst_addr = esp_zb_get_short_address();
mb_req->start_index = 0;
log_d("Requesting binding table for address 0x%04x", mb_req->dst_addr);
esp_zb_zdo_binding_table_req(mb_req, bindingTableCb, (void *)mb_req);
}
// Function to convert enum value to string
const char *ZigbeeCore::getDeviceTypeString(esp_zb_ha_standard_devices_t deviceId) {
switch (deviceId) {

View file

@ -80,6 +80,8 @@ private:
bool zigbeeInit(esp_zb_cfg_t *zb_cfg, bool erase_nvs);
static void scanCompleteCallback(esp_zb_zdp_status_t zdo_status, uint8_t count, esp_zb_network_descriptor_t *nwk_descriptor);
const char *getDeviceTypeString(esp_zb_ha_standard_devices_t deviceId);
void searchBindings();
static void bindingTableCb(const esp_zb_zdo_binding_table_info_t *table_info, void *user_ctx);
public:
ZigbeeCore();

View file

@ -7,6 +7,8 @@
#include "esp_zigbee_cluster.h"
#include "zcl/esp_zigbee_zcl_power_config.h"
#define ZB_CMD_TIMEOUT 10000 // 10 seconds
bool ZigbeeEP::_is_bound = false;
bool ZigbeeEP::_allow_multiple_binding = false;
@ -112,13 +114,20 @@ void ZigbeeEP::reportBatteryPercentage() {
log_v("Battery percentage reported");
}
char *ZigbeeEP::readManufacturer(uint8_t endpoint, uint16_t short_addr) {
char *ZigbeeEP::readManufacturer(uint8_t endpoint, uint16_t short_addr, esp_zb_ieee_addr_t ieee_addr) {
/* Read peer Manufacture Name & Model Identifier */
esp_zb_zcl_read_attr_cmd_t read_req;
read_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
if (short_addr != 0) {
read_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
read_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr;
} else {
read_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT;
memcpy(read_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t));
}
read_req.zcl_basic_cmd.src_endpoint = _endpoint;
read_req.zcl_basic_cmd.dst_endpoint = endpoint;
read_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr;
read_req.clusterID = ESP_ZB_ZCL_CLUSTER_ID_BASIC;
uint16_t attributes[] = {
@ -130,22 +139,31 @@ char *ZigbeeEP::readManufacturer(uint8_t endpoint, uint16_t short_addr) {
// clear read manufacturer
_read_manufacturer = nullptr;
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_read_attr_cmd_req(&read_req);
esp_zb_lock_release();
//Wait for response or timeout
if (xSemaphoreTake(lock, portMAX_DELAY) != pdTRUE) {
if (xSemaphoreTake(lock, ZB_CMD_TIMEOUT) != pdTRUE) {
log_e("Error while reading manufacturer");
}
return _read_manufacturer;
}
char *ZigbeeEP::readModel(uint8_t endpoint, uint16_t short_addr) {
char *ZigbeeEP::readModel(uint8_t endpoint, uint16_t short_addr, esp_zb_ieee_addr_t ieee_addr) {
/* Read peer Manufacture Name & Model Identifier */
esp_zb_zcl_read_attr_cmd_t read_req;
read_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
if (short_addr != 0) {
read_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
read_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr;
} else {
read_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT;
memcpy(read_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t));
}
read_req.zcl_basic_cmd.src_endpoint = _endpoint;
read_req.zcl_basic_cmd.dst_endpoint = endpoint;
read_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr;
read_req.clusterID = ESP_ZB_ZCL_CLUSTER_ID_BASIC;
uint16_t attributes[] = {
@ -157,11 +175,12 @@ char *ZigbeeEP::readModel(uint8_t endpoint, uint16_t short_addr) {
// clear read model
_read_model = nullptr;
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_read_attr_cmd_req(&read_req);
esp_zb_lock_release();
//Wait for response or timeout
//Semaphore take
if (xSemaphoreTake(lock, portMAX_DELAY) != pdTRUE) {
if (xSemaphoreTake(lock, ZB_CMD_TIMEOUT) != pdTRUE) {
log_e("Error while reading model");
}
return _read_model;
@ -171,8 +190,23 @@ void ZigbeeEP::printBoundDevices() {
log_i("Bound devices:");
for ([[maybe_unused]]
const auto &device : _bound_devices) {
log_i("Device on endpoint %d, short address: 0x%x", device->endpoint, device->short_addr);
print_ieee_addr(device->ieee_addr);
log_i(
"Device on endpoint %d, short address: 0x%x, ieee address: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", device->endpoint, device->short_addr,
device->ieee_addr[7], device->ieee_addr[6], device->ieee_addr[5], device->ieee_addr[4], device->ieee_addr[3], device->ieee_addr[2], device->ieee_addr[1],
device->ieee_addr[0]
);
}
}
void ZigbeeEP::printBoundDevices(Print &print) {
print.println("Bound devices:");
for ([[maybe_unused]]
const auto &device : _bound_devices) {
print.printf(
"Device on endpoint %d, short address: 0x%x, ieee address: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\r\n", device->endpoint, device->short_addr,
device->ieee_addr[7], device->ieee_addr[6], device->ieee_addr[5], device->ieee_addr[4], device->ieee_addr[3], device->ieee_addr[2], device->ieee_addr[1],
device->ieee_addr[0]
);
}
}

View file

@ -9,8 +9,6 @@
/* Useful defines */
#define ZB_ARRAY_LENTH(arr) (sizeof(arr) / sizeof(arr[0]))
#define print_ieee_addr(addr) \
log_i("IEEE Address: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7])
#define XYZ_TO_RGB(X, Y, Z, r, g, b) \
{ \
r = (float)(3.240479 * (X) - 1.537150 * (Y) - 0.498535 * (Z)); \
@ -69,6 +67,8 @@ public:
}
void printBoundDevices();
void printBoundDevices(Print &print);
std::list<zb_device_params_t *> getBoundDevices() const {
return _bound_devices;
}
@ -87,8 +87,8 @@ public:
void reportBatteryPercentage();
// Methods to read manufacturer and model name from selected endpoint and short address
char *readManufacturer(uint8_t endpoint, uint16_t short_addr);
char *readModel(uint8_t endpoint, uint16_t short_addr);
char *readManufacturer(uint8_t endpoint, uint16_t short_addr, esp_zb_ieee_addr_t ieee_addr);
char *readModel(uint8_t endpoint, uint16_t short_addr, esp_zb_ieee_addr_t ieee_addr);
bool epAllowMultipleBinding() {
return _allow_multiple_binding;
@ -108,7 +108,6 @@ public:
}
private:
static bool _allow_multiple_binding;
char *_read_manufacturer;
char *_read_model;
void (*_on_identify)(uint16_t time);
@ -119,10 +118,15 @@ protected:
esp_zb_endpoint_config_t _ep_config;
esp_zb_cluster_list_t *_cluster_list;
static bool _is_bound;
static bool _allow_multiple_binding;
std::list<zb_device_params_t *> _bound_devices;
SemaphoreHandle_t lock;
zb_power_source_t _power_source;
void addBoundDevice(zb_device_params_t *device) {
_bound_devices.push_back(device);
_is_bound = true;
}
friend class ZigbeeCore;
};

View file

@ -98,10 +98,10 @@ void ZigbeeColorDimmerSwitch::lightToggle() {
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_TOGGLE_ID;
log_i("Sending 'light toggle' command");
//esp_zb_lock_acquire(portMAX_DELAY);
log_v("Sending 'light toggle' command");
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_on_off_cmd_req(&cmd_req);
//esp_zb_lock_release();
esp_zb_lock_release();
} else {
log_e("Light not bound");
}
@ -114,7 +114,7 @@ void ZigbeeColorDimmerSwitch::lightToggle(uint16_t group_addr) {
cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr;
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT;
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_TOGGLE_ID;
log_i("Sending 'light toggle' command to group address 0x%x", group_addr);
log_v("Sending 'light toggle' command to group address 0x%x", group_addr);
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_on_off_cmd_req(&cmd_req);
esp_zb_lock_release();
@ -131,7 +131,27 @@ void ZigbeeColorDimmerSwitch::lightToggle(uint8_t endpoint, uint16_t short_addr)
cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr;
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_TOGGLE_ID;
log_i("Sending 'light toggle' command to endpoint %d, address 0x%x", endpoint, short_addr);
log_v("Sending 'light toggle' command to endpoint %d, address 0x%x", endpoint, short_addr);
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_on_off_cmd_req(&cmd_req);
esp_zb_lock_release();
} else {
log_e("Light not bound");
}
}
void ZigbeeColorDimmerSwitch::lightToggle(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) {
if (_is_bound) {
esp_zb_zcl_on_off_cmd_t cmd_req;
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
cmd_req.zcl_basic_cmd.dst_endpoint = endpoint;
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT;
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_TOGGLE_ID;
memcpy(cmd_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t));
log_v(
"Sending 'light toggle' command to endpoint %d, ieee address %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", endpoint, ieee_addr[7], ieee_addr[6], ieee_addr[5],
ieee_addr[4], ieee_addr[3], ieee_addr[2], ieee_addr[1], ieee_addr[0]
);
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_on_off_cmd_req(&cmd_req);
esp_zb_lock_release();
@ -146,7 +166,7 @@ void ZigbeeColorDimmerSwitch::lightOn() {
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_ON_ID;
log_i("Sending 'light on' command");
log_v("Sending 'light on' command");
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_on_off_cmd_req(&cmd_req);
esp_zb_lock_release();
@ -162,7 +182,7 @@ void ZigbeeColorDimmerSwitch::lightOn(uint16_t group_addr) {
cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr;
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT;
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_ON_ID;
log_i("Sending 'light on' command to group address 0x%x", group_addr);
log_v("Sending 'light on' command to group address 0x%x", group_addr);
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_on_off_cmd_req(&cmd_req);
esp_zb_lock_release();
@ -179,7 +199,27 @@ void ZigbeeColorDimmerSwitch::lightOn(uint8_t endpoint, uint16_t short_addr) {
cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr;
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_ON_ID;
log_i("Sending 'light on' command to endpoint %d, address 0x%x", endpoint, short_addr);
log_v("Sending 'light on' command to endpoint %d, address 0x%x", endpoint, short_addr);
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_on_off_cmd_req(&cmd_req);
esp_zb_lock_release();
} else {
log_e("Light not bound");
}
}
void ZigbeeColorDimmerSwitch::lightOn(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) {
if (_is_bound) {
esp_zb_zcl_on_off_cmd_t cmd_req;
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
cmd_req.zcl_basic_cmd.dst_endpoint = endpoint;
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT;
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_ON_ID;
memcpy(cmd_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t));
log_v(
"Sending 'light on' command to endpoint %d, ieee address %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", endpoint, ieee_addr[7], ieee_addr[6], ieee_addr[5],
ieee_addr[4], ieee_addr[3], ieee_addr[2], ieee_addr[1], ieee_addr[0]
);
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_on_off_cmd_req(&cmd_req);
esp_zb_lock_release();
@ -194,7 +234,7 @@ void ZigbeeColorDimmerSwitch::lightOff() {
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_OFF_ID;
log_i("Sending 'light off' command");
log_v("Sending 'light off' command");
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_on_off_cmd_req(&cmd_req);
esp_zb_lock_release();
@ -210,7 +250,7 @@ void ZigbeeColorDimmerSwitch::lightOff(uint16_t group_addr) {
cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr;
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT;
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_OFF_ID;
log_i("Sending 'light off' command to group address 0x%x", group_addr);
log_v("Sending 'light off' command to group address 0x%x", group_addr);
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_on_off_cmd_req(&cmd_req);
esp_zb_lock_release();
@ -227,7 +267,27 @@ void ZigbeeColorDimmerSwitch::lightOff(uint8_t endpoint, uint16_t short_addr) {
cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr;
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_OFF_ID;
log_i("Sending 'light off' command to endpoint %d, address 0x%x", endpoint, short_addr);
log_v("Sending 'light off' command to endpoint %d, address 0x%x", endpoint, short_addr);
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_on_off_cmd_req(&cmd_req);
esp_zb_lock_release();
} else {
log_e("Light not bound");
}
}
void ZigbeeColorDimmerSwitch::lightOff(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) {
if (_is_bound) {
esp_zb_zcl_on_off_cmd_t cmd_req;
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
cmd_req.zcl_basic_cmd.dst_endpoint = endpoint;
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT;
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_OFF_ID;
memcpy(cmd_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t));
log_v(
"Sending 'light off' command to endpoint %d, ieee address %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", endpoint, ieee_addr[7], ieee_addr[6], ieee_addr[5],
ieee_addr[4], ieee_addr[3], ieee_addr[2], ieee_addr[1], ieee_addr[0]
);
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_on_off_cmd_req(&cmd_req);
esp_zb_lock_release();
@ -243,7 +303,7 @@ void ZigbeeColorDimmerSwitch::lightOffWithEffect(uint8_t effect_id, uint8_t effe
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
cmd_req.effect_id = effect_id;
cmd_req.effect_variant = effect_variant;
log_i("Sending 'light off with effect' command");
log_v("Sending 'light off with effect' command");
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_on_off_off_with_effect_cmd_req(&cmd_req);
esp_zb_lock_release();
@ -257,7 +317,7 @@ void ZigbeeColorDimmerSwitch::lightOnWithSceneRecall() {
esp_zb_zcl_on_off_on_with_recall_global_scene_cmd_t cmd_req;
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
log_i("Sending 'light on with scene recall' command");
log_v("Sending 'light on with scene recall' command");
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_on_off_on_with_recall_global_scene_cmd_req(&cmd_req);
esp_zb_lock_release();
@ -274,7 +334,7 @@ void ZigbeeColorDimmerSwitch::lightOnWithTimedOff(uint8_t on_off_control, uint16
cmd_req.on_off_control = on_off_control; //TODO: Test how it works, then maybe change API
cmd_req.on_time = time_on;
cmd_req.off_wait_time = time_off;
log_i("Sending 'light on with time off' command");
log_v("Sending 'light on with time off' command");
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_on_off_on_with_timed_off_cmd_req(&cmd_req);
esp_zb_lock_release();
@ -290,7 +350,7 @@ void ZigbeeColorDimmerSwitch::setLightLevel(uint8_t level) {
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
cmd_req.level = level;
cmd_req.transition_time = 0xffff;
log_i("Sending 'set light level' command");
log_v("Sending 'set light level' command");
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_level_move_to_level_cmd_req(&cmd_req);
esp_zb_lock_release();
@ -307,7 +367,7 @@ void ZigbeeColorDimmerSwitch::setLightLevel(uint8_t level, uint16_t group_addr)
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT;
cmd_req.level = level;
cmd_req.transition_time = 0xffff;
log_i("Sending 'set light level' command to group address 0x%x", group_addr);
log_v("Sending 'set light level' command to group address 0x%x", group_addr);
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_level_move_to_level_cmd_req(&cmd_req);
esp_zb_lock_release();
@ -325,7 +385,28 @@ void ZigbeeColorDimmerSwitch::setLightLevel(uint8_t level, uint8_t endpoint, uin
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
cmd_req.level = level;
cmd_req.transition_time = 0xffff;
log_i("Sending 'set light level' command to endpoint %d, address 0x%x", endpoint, short_addr);
log_v("Sending 'set light level' command to endpoint %d, address 0x%x", endpoint, short_addr);
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_level_move_to_level_cmd_req(&cmd_req);
esp_zb_lock_release();
} else {
log_e("Light not bound");
}
}
void ZigbeeColorDimmerSwitch::setLightLevel(uint8_t level, uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) {
if (_is_bound) {
esp_zb_zcl_move_to_level_cmd_t cmd_req;
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
cmd_req.zcl_basic_cmd.dst_endpoint = endpoint;
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT;
memcpy(cmd_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t));
cmd_req.level = level;
cmd_req.transition_time = 0xffff;
log_v(
"Sending 'set light level' command to endpoint %d, ieee address %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", endpoint, ieee_addr[7], ieee_addr[6],
ieee_addr[5], ieee_addr[4], ieee_addr[3], ieee_addr[2], ieee_addr[1], ieee_addr[0]
);
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_level_move_to_level_cmd_req(&cmd_req);
esp_zb_lock_release();
@ -346,7 +427,7 @@ void ZigbeeColorDimmerSwitch::setLightColor(uint8_t red, uint8_t green, uint8_t
cmd_req.color_x = color_x;
cmd_req.color_y = color_y;
cmd_req.transition_time = 0;
log_i("Sending 'set light color' command");
log_v("Sending 'set light color' command");
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_color_move_to_color_cmd_req(&cmd_req);
esp_zb_lock_release();
@ -368,7 +449,7 @@ void ZigbeeColorDimmerSwitch::setLightColor(uint8_t red, uint8_t green, uint8_t
cmd_req.color_x = color_x;
cmd_req.color_y = color_y;
cmd_req.transition_time = 0;
log_i("Sending 'set light color' command to group address 0x%x", group_addr);
log_v("Sending 'set light color' command to group address 0x%x", group_addr);
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_color_move_to_color_cmd_req(&cmd_req);
esp_zb_lock_release();
@ -391,7 +472,33 @@ void ZigbeeColorDimmerSwitch::setLightColor(uint8_t red, uint8_t green, uint8_t
cmd_req.color_x = color_x;
cmd_req.color_y = color_y;
cmd_req.transition_time = 0;
log_i("Sending 'set light color' command to endpoint %d, address 0x%x", endpoint, short_addr);
log_v("Sending 'set light color' command to endpoint %d, address 0x%x", endpoint, short_addr);
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_color_move_to_color_cmd_req(&cmd_req);
esp_zb_lock_release();
} else {
log_e("Light not bound");
}
}
void ZigbeeColorDimmerSwitch::setLightColor(uint8_t red, uint8_t green, uint8_t blue, uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) {
if (_is_bound) {
//Convert RGB to XY
uint16_t color_x, color_y;
calculateXY(red, green, blue, color_x, color_y);
esp_zb_zcl_color_move_to_color_cmd_t cmd_req;
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
cmd_req.zcl_basic_cmd.dst_endpoint = endpoint;
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT;
memcpy(cmd_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t));
cmd_req.color_x = color_x;
cmd_req.color_y = color_y;
cmd_req.transition_time = 0;
log_v(
"Sending 'set light color' command to endpoint %d, ieee address %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", endpoint, ieee_addr[7], ieee_addr[6],
ieee_addr[5], ieee_addr[4], ieee_addr[3], ieee_addr[2], ieee_addr[1], ieee_addr[0]
);
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_color_move_to_color_cmd_req(&cmd_req);
esp_zb_lock_release();

View file

@ -18,14 +18,17 @@ public:
void lightToggle();
void lightToggle(uint16_t group_addr);
void lightToggle(uint8_t endpoint, uint16_t short_addr);
void lightToggle(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr);
void lightOn();
void lightOn(uint16_t group_addr);
void lightOn(uint8_t endpoint, uint16_t short_addr);
void lightOn(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr);
void lightOff();
void lightOff(uint16_t group_addr);
void lightOff(uint8_t endpoint, uint16_t short_addr);
void lightOff(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr);
void lightOffWithEffect(uint8_t effect_id, uint8_t effect_variant);
void lightOnWithTimedOff(uint8_t on_off_control, uint16_t time_on, uint16_t time_off);
@ -34,10 +37,12 @@ public:
void setLightLevel(uint8_t level);
void setLightLevel(uint8_t level, uint16_t group_addr);
void setLightLevel(uint8_t level, uint8_t endpoint, uint16_t short_addr);
void setLightLevel(uint8_t level, uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr);
void setLightColor(uint8_t red, uint8_t green, uint8_t blue);
void setLightColor(uint8_t red, uint8_t green, uint8_t blue, uint16_t group_addr);
void setLightColor(uint8_t red, uint8_t green, uint8_t blue, uint8_t endpoint, uint16_t short_addr);
void setLightColor(uint8_t red, uint8_t green, uint8_t blue, uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr);
private:
// save instance of the class in order to use it in static functions

View file

@ -59,7 +59,6 @@ void ZigbeeSwitch::findEndpoint(esp_zb_zdo_match_desc_req_param_t *cmd_req) {
.num_out_clusters = 1,
.cluster_list = cluster_list,
};
esp_zb_zdo_match_cluster(&on_off_req, findCb, &_endpoint);
}
@ -70,8 +69,10 @@ void ZigbeeSwitch::lightToggle() {
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_TOGGLE_ID;
log_i("Sending 'light toggle' command");
log_v("Sending 'light toggle' command");
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_on_off_cmd_req(&cmd_req);
esp_zb_lock_release();
} else {
log_e("Light not bound");
}
@ -84,8 +85,10 @@ void ZigbeeSwitch::lightToggle(uint16_t group_addr) {
cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr;
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT;
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_TOGGLE_ID;
log_i("Sending 'light toggle' command to group address 0x%x", group_addr);
log_v("Sending 'light toggle' command to group address 0x%x", group_addr);
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_on_off_cmd_req(&cmd_req);
esp_zb_lock_release();
} else {
log_e("Light not bound");
}
@ -99,8 +102,30 @@ void ZigbeeSwitch::lightToggle(uint8_t endpoint, uint16_t short_addr) {
cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr;
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_TOGGLE_ID;
log_i("Sending 'light toggle' command to endpoint %d, address 0x%x", endpoint, short_addr);
log_v("Sending 'light toggle' command to endpoint %d, address 0x%x", endpoint, short_addr);
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_on_off_cmd_req(&cmd_req);
esp_zb_lock_release();
} else {
log_e("Light not bound");
}
}
void ZigbeeSwitch::lightToggle(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) {
if (_is_bound) {
esp_zb_zcl_on_off_cmd_t cmd_req;
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
cmd_req.zcl_basic_cmd.dst_endpoint = endpoint;
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT;
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_TOGGLE_ID;
memcpy(cmd_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t));
log_v(
"Sending 'light toggle' command to endpoint %d, ieee address %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", endpoint, ieee_addr[7], ieee_addr[6], ieee_addr[5],
ieee_addr[4], ieee_addr[3], ieee_addr[2], ieee_addr[1], ieee_addr[0]
);
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_on_off_cmd_req(&cmd_req);
esp_zb_lock_release();
} else {
log_e("Light not bound");
}
@ -112,8 +137,10 @@ void ZigbeeSwitch::lightOn() {
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_ON_ID;
log_i("Sending 'light on' command");
log_v("Sending 'light on' command");
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_on_off_cmd_req(&cmd_req);
esp_zb_lock_release();
} else {
log_e("Light not bound");
}
@ -126,8 +153,10 @@ void ZigbeeSwitch::lightOn(uint16_t group_addr) {
cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr;
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT;
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_ON_ID;
log_i("Sending 'light on' command to group address 0x%x", group_addr);
log_v("Sending 'light on' command to group address 0x%x", group_addr);
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_on_off_cmd_req(&cmd_req);
esp_zb_lock_release();
} else {
log_e("Light not bound");
}
@ -141,8 +170,30 @@ void ZigbeeSwitch::lightOn(uint8_t endpoint, uint16_t short_addr) {
cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr;
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_ON_ID;
log_i("Sending 'light on' command to endpoint %d, address 0x%x", endpoint, short_addr);
log_v("Sending 'light on' command to endpoint %d, address 0x%x", endpoint, short_addr);
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_on_off_cmd_req(&cmd_req);
esp_zb_lock_release();
} else {
log_e("Light not bound");
}
}
void ZigbeeSwitch::lightOn(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) {
if (_is_bound) {
esp_zb_zcl_on_off_cmd_t cmd_req;
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
cmd_req.zcl_basic_cmd.dst_endpoint = endpoint;
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT;
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_ON_ID;
memcpy(cmd_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t));
log_v(
"Sending 'light on' command to endpoint %d, ieee address %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", endpoint, ieee_addr[7], ieee_addr[6], ieee_addr[5],
ieee_addr[4], ieee_addr[3], ieee_addr[2], ieee_addr[1], ieee_addr[0]
);
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_on_off_cmd_req(&cmd_req);
esp_zb_lock_release();
} else {
log_e("Light not bound");
}
@ -154,8 +205,10 @@ void ZigbeeSwitch::lightOff() {
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_OFF_ID;
log_i("Sending 'light off' command");
log_v("Sending 'light off' command");
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_on_off_cmd_req(&cmd_req);
esp_zb_lock_release();
} else {
log_e("Light not bound");
}
@ -168,8 +221,10 @@ void ZigbeeSwitch::lightOff(uint16_t group_addr) {
cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr;
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT;
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_OFF_ID;
log_i("Sending 'light off' command to group address 0x%x", group_addr);
log_v("Sending 'light off' command to group address 0x%x", group_addr);
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_on_off_cmd_req(&cmd_req);
esp_zb_lock_release();
} else {
log_e("Light not bound");
}
@ -183,8 +238,30 @@ void ZigbeeSwitch::lightOff(uint8_t endpoint, uint16_t short_addr) {
cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr;
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_OFF_ID;
log_i("Sending 'light off' command to endpoint %d, address 0x%x", endpoint, short_addr);
log_v("Sending 'light off' command to endpoint %d, address 0x%x", endpoint, short_addr);
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_on_off_cmd_req(&cmd_req);
esp_zb_lock_release();
} else {
log_e("Light not bound");
}
}
void ZigbeeSwitch::lightOff(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) {
if (_is_bound) {
esp_zb_zcl_on_off_cmd_t cmd_req;
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
cmd_req.zcl_basic_cmd.dst_endpoint = endpoint;
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT;
cmd_req.on_off_cmd_id = ESP_ZB_ZCL_CMD_ON_OFF_OFF_ID;
memcpy(cmd_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t));
log_v(
"Sending 'light off' command to endpoint %d, ieee address %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", endpoint, ieee_addr[7], ieee_addr[6], ieee_addr[5],
ieee_addr[4], ieee_addr[3], ieee_addr[2], ieee_addr[1], ieee_addr[0]
);
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_on_off_cmd_req(&cmd_req);
esp_zb_lock_release();
} else {
log_e("Light not bound");
}
@ -197,8 +274,10 @@ void ZigbeeSwitch::lightOffWithEffect(uint8_t effect_id, uint8_t effect_variant)
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
cmd_req.effect_id = effect_id;
cmd_req.effect_variant = effect_variant;
log_i("Sending 'light off with effect' command");
log_v("Sending 'light off with effect' command");
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_on_off_off_with_effect_cmd_req(&cmd_req);
esp_zb_lock_release();
} else {
log_e("Light not bound");
}
@ -209,8 +288,10 @@ void ZigbeeSwitch::lightOnWithSceneRecall() {
esp_zb_zcl_on_off_on_with_recall_global_scene_cmd_t cmd_req;
cmd_req.zcl_basic_cmd.src_endpoint = _endpoint;
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
log_i("Sending 'light on with scene recall' command");
log_v("Sending 'light on with scene recall' command");
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_on_off_on_with_recall_global_scene_cmd_req(&cmd_req);
esp_zb_lock_release();
} else {
log_e("Light not bound");
}
@ -223,8 +304,10 @@ void ZigbeeSwitch::lightOnWithTimedOff(uint8_t on_off_control, uint16_t time_on,
cmd_req.on_off_control = on_off_control; //TODO: Test how it works, then maybe change API
cmd_req.on_time = time_on;
cmd_req.off_wait_time = time_off;
log_i("Sending 'light on with time off' command");
log_v("Sending 'light on with time off' command");
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_on_off_on_with_timed_off_cmd_req(&cmd_req);
esp_zb_lock_release();
} else {
log_e("Light not bound");
}

View file

@ -18,14 +18,17 @@ public:
void lightToggle();
void lightToggle(uint16_t group_addr);
void lightToggle(uint8_t endpoint, uint16_t short_addr);
void lightToggle(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr);
void lightOn();
void lightOn(uint16_t group_addr);
void lightOn(uint8_t endpoint, uint16_t short_addr);
void lightOn(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr);
void lightOff();
void lightOff(uint16_t group_addr);
void lightOff(uint8_t endpoint, uint16_t short_addr);
void lightOff(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr);
void lightOffWithEffect(uint8_t effect_id, uint8_t effect_variant);
void lightOnWithTimedOff(uint8_t on_off_control, uint16_t time_on, uint16_t time_off);

View file

@ -60,7 +60,9 @@ void ZigbeeTempSensor::setReporting(uint16_t min_interval, uint16_t max_interval
},
.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC,
};
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_update_reporting_info(&reporting_info);
esp_zb_lock_release();
}
void ZigbeeTempSensor::setTemperature(float temperature) {
@ -158,7 +160,9 @@ void ZigbeeTempSensor::setHumidityReporting(uint16_t min_interval, uint16_t max_
},
.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC,
};
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_update_reporting_info(&reporting_info);
esp_zb_lock_release();
}
#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED