unable to join zigbee network with ESP32-H2
Posted: Tue Nov 19, 2024 1:20 pm
Hi,
I have programmed an ESP32-H2 to join a zigbee network.
Here is the log of the esp:
I (23) boot: ESP-IDF v5.2.2-dirty 2nd stage bootloader
I (24) boot: compile time Nov 15 2024 18:52:35
I (25) boot: chip revision: v0.1
I (27) boot.esp32h2: SPI Speed : 64MHz
I (32) boot.esp32h2: SPI Mode : DIO
I (37) boot.esp32h2: SPI Flash Size : 2MB
I (41) boot: Enabling RNG early entropy source...
I (47) boot: Partition Table:
I (50) boot: ## Label Usage Type ST Offset Length
I (58) boot: 0 nvs WiFi data 01 02 00009000 00006000
I (65) boot: 1 phy_init RF data 01 01 0000f000 00001000
I (72) boot: 2 factory factory app 00 00 00010000 000e1000
I (80) boot: 3 zb_storage Unknown data 01 81 000f1000 00004000
I (87) boot: 4 zb_fct Unknown data 01 81 000f5000 00000400
I (95) boot: End of partition table
I (99) esp_image: segment 0: paddr=00010020 vaddr=42078020 size=11988h ( 72072) map
I (130) esp_image: segment 1: paddr=000219b0 vaddr=40800000 size=06668h ( 26216) load
I (140) esp_image: segment 2: paddr=00028020 vaddr=42000020 size=769fch (485884) map
I (289) esp_image: segment 3: paddr=0009ea24 vaddr=40806668 size=059d0h ( 22992) load
I (298) esp_image: segment 4: paddr=000a43fc vaddr=4080c040 size=01c1ch ( 7196) load
I (301) esp_image: segment 5: paddr=000a6020 vaddr=50000000 size=00004h ( 4) load
I (307) boot: Loaded app from partition at offset 0x10000
I (309) boot: Disabling RNG early entropy source...
I (326) cpu_start: Unicore app
W (335) clk: esp_perip_clk_init() has not been implemented yet
I (342) cpu_start: Pro cpu start user code
I (342) cpu_start: cpu freq: 96000000 Hz
I (343) heap_init: Initializing. RAM available for dynamic allocation:
I (347) heap_init: At 40813160 len 0003A220 (232 KiB): RAM
I (353) heap_init: At 4084D380 len 00002B60 (10 KiB): RAM
I (361) spi_flash: detected chip: generic
I (364) spi_flash: flash io: dio
W (368) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (382) sleep: Configure to isolate all GPIO pins in sleep state
I (388) sleep: Enable automatic switching of GPIO sleep configuration
I (396) main_task: Started on CPU0
I (396) main_task: Calling app_main()
I (406) MAIN: Zigbee is starting ...
I (416) phy: phy_version: 230,2, 9aae6ea, Jan 15 2024, 11:17:12
I (416) phy: libbtbb version: 944f18e, Jan 15 2024, 11:17:25
I (426) ZIGBEE: ESP32 is in Router mode.
I (446) gpio: GPIO[4]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0
I (446) gpio: GPIO[5]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0
I (456) ZIGBEE_SIGNAL: Received signal: ZDO Config Ready (0x17), status: ESP_FAIL
W (456) SIGNAL: ZDO signal: ZDO Config Ready (0x17), status: ESP_FAIL
I (466) IEEE: Starting ieee address detection
E (466) IEEE: We didn't find any remote devices. ZDO status = 85
I (476) ZIGBEE_SIGNAL: Received signal: ZDO Device Unavailable (0x3c), status: ESP_OK
W (486) SIGNAL: ZDO signal: ZDO Device Unavailable (0x3c), status: ESP_OK
I (496) gpio: GPIO[1]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
I (716) sen5x: Serial number: 25�38b80�7EU7DdB5�97�78�
I (716) sen5x: Product name: SE�N5U0
I (716) sen5x: Firmware version: 02 00
I (816) sgp30: Serial Number: 00 00 81
I (816) sgp30: Feature set version: 00 22 65
SGP30 still needs 15 seconds to calibrate.
SGP30 still needs 14 seconds to calibrate.
I (2896) ZIGBEE_SIGNAL: Received signal: BDB Device Start (0x5), status: ESP_FAIL
I (2896) SIGNAL: First start : ZDO signal BDB Device Start (Ox5), status: ESP_FAIL
Starting the BDB in network steering mode
SGP30 still needs 13 seconds to calibrate.
SGP30 still needs 12 seconds to calibrate.
I (5306) ZIGBEE_SIGNAL: Received signal: BDB Steering (0xa), status: ESP_FAIL
W (5306) SIGNAL: Network steering is going on but failing : ESP_FAIL status, steering
SGP30 still needs 11 seconds to calibrate.
I (6316) ZIGBEE: Starting Zigbee commissioning...
I (6316) ZIGBEE: Zigbee commissioning started successfully.
SGP30 still needs 10 seconds to calibrate.
SGP30 still needs 9 seconds to calibrate.
I (8716) ZIGBEE_SIGNAL: Received signal: BDB Steering (0xa), status: ESP_FAIL
W (8716) SIGNAL: Network steering is going on but failing : ESP_FAIL status, steering
SGP30 still needs 8 seconds to calibrate.
I (9726) ZIGBEE: Starting Zigbee commissioning...
I (9726) ZIGBEE: Zigbee commissioning started successfully.
SGP30 still needs 7 seconds to calibrate.
SGP30 still needs 6 seconds to calibrate.
SGP30 still needs 5 seconds to calibrate.
I (12126) ZIGBEE_SIGNAL: Received signal: BDB Steering (0xa), status: ESP_FAIL
W (12126) SIGNAL: Network steering is going on but failing : ESP_FAIL status, steering
SGP30 still needs 4 seconds to calibrate.
I (13136) ZIGBEE: Starting Zigbee commissioning...
I (13136) ZIGBEE: Zigbee commissioning started successfully.
SGP30 still needs 3 seconds to calibrate.
SGP30 still needs 2 seconds to calibrate.
I (15536) ZIGBEE_SIGNAL: Received signal: BDB Steering (0xa), status: ESP_FAIL
W (15536) SIGNAL: Network steering is going on but failing : ESP_FAIL status, steering
SGP30 still needs 1 seconds to calibrate.
I (16506) Values:
Temperature : -1.0 °C Humidity : -1 % VOC : -1 ppb
CO2 : -1 ppm Volume : -1 dB PM1.0 : -1.0 µg/m³
PM2.5 : -1.0 µg/m³ PM4.0 : -1.0 µg/m³ PM10.0 : -1.0 µg/m³
PM0.5 : 0.0 part/cm³ PM1.0 : 0.0 part/cm³ PM2.5 : 0.0 part/cm³
PM4.0 : 0.0 part/cm³ PM10. : 0.0 part/cm³ Typ. size : 0.00 µm
I (16526) ZIGBEE_SIGNAL: Received signal: ZDO Device Unavailable (0x3c), status: ESP_OK
W (16536) SIGNAL: ZDO signal: ZDO Device Unavailable (0x3c), status: ESP_OK
I (16536) main_task: Returned from app_main()
I (16546) ZIGBEE: Starting Zigbee commissioning...
I (16546) ZIGBEE: Zigbee commissioning started successfully.
SGP30 still needs 0 seconds to calibrate.
I (17526) Values:
Temperature : 24.4 °C Humidity : 45 % VOC : 6 ppb
CO2 : 400 ppm Volume : -1 dB PM1.0 : 3.7 µg/m³
PM2.5 : 6.2 µg/m³ PM4.0 : 8.2 µg/m³ PM10.0 : 9.1 µg/m³
PM0.5 : 20.2 part/cm³ PM1.0 : 26.8 part/cm³ PM2.5 : 29.0 part/cm³
PM4.0 : 29.4 part/cm³ PM10. : 29.5 part/cm³ Typ. size : 8.67 µm
I (17546) ZIGBEE_SIGNAL: Received signal: ZDO Device Unavailable (0x3c), status: ESP_OK
W (17556) SIGNAL: ZDO signal: ZDO Device Unavailable (0x3c), status: ESP_OK
I see errors ZDO Device Unavailable and Network steering is going on but failing : ESP_FAIL
What can cause these errors?
Here is the zigbee part of the code:
/**
* @brief This is used to store device informations
*/
typedef struct device_params_s {
esp_zb_ieee_addr_t ieee_addr; /* This is the ieee addresse of the remote device*/
uint16_t short_addr; /* This is the short addresse of the remote device adresse unique courte de l'esp qui a rejoint le réseau*/
int16_t lost; /* This is used to determined wether the coordo is lost or not*/
} device_params_t;
/* remote device struct for recording and managing node info */
device_params_t remote_zb_device = {
.lost = -1,
};
/**
* @brief This is used to start the Base Device Behavior commissioning
*
* @param mode_mask Used to determine wich mode the bdb must be in when starting
*/
static void bdb_start_top_level_commissioning_cb(uint8_t mode_mask) //ORE: fonction ok
{
//changement par ORE:
//ESP_RETURN_ON_FALSE(esp_zb_bdb_start_top_level_commissioning(mode_mask) == ESP_OK, , "BDB", "Failed to start BDB commission");
ESP_LOGI("ZIGBEE", "Starting Zigbee commissioning...");
esp_err_t ret = esp_zb_bdb_start_top_level_commissioning(ESP_ZB_BDB_MODE_NETWORK_STEERING);
if (ret != ESP_OK) {
ESP_LOGE("ZIGBEE", "Failed to start BDB commissioning: %s", esp_err_to_name(ret));
vTaskDelete(NULL); // Supprime la tâche en cas d'échec
return;
}
ESP_LOGI("ZIGBEE", "Zigbee commissioning started successfully.");
}
/**
* @brief Used to determine if the coordinator is still on or not and to reconnect to the network if it has been lost and found back
*
* @param zdo_status The zdo status defines what event just happened and is used to determine what to do
* @param ieee_addr It's the address of the newly found remote device
* @param user_ctx A pointer that contains the user defines additional information
*/
static void check_coordo_alive_cb(esp_zb_zdp_status_t zdo_status, esp_zb_ieee_addr_t ieee_addr, void *user_ctx)
{
if (zdo_status != ESP_ZB_ZDP_STATUS_SUCCESS) {
if (remote_zb_device.lost == -1) {
} else if (remote_zb_device.lost == 0) {
remote_zb_device.lost = 1;
ESP_LOGE("COORDO", "We've lost the coordo.");
} else if (remote_zb_device.lost < 5) {
remote_zb_device.lost += 1;
} else if (remote_zb_device.lost >= 5) {
ESP_LOGE("COORDO", "Restart"); // Redémarrage si le coordonnateur est perdu
esp_restart();
}
} else {
remote_zb_device.lost = 0; // Réinitialisation parce que le coordonnateur est trouvé
}
}
/**
* @brief This is used to get ieee addresse from remote device
*
* @param zdo_status The zdo status defines what event just happened and is used to determine what to do
* @param ieee_addr It's the address of the newly found remote device
* @param user_ctx A pointer that contains the user defines additional information
*/
static void ieee_cb(esp_zb_zdp_status_t zdo_status, esp_zb_ieee_addr_t ieee_addr, void *user_ctx) // ORE: warning sur le deuxieme argument
{
ESP_LOGI("IEEE", "Starting ieee address detection");
if (zdo_status == ESP_ZB_ZDP_STATUS_SUCCESS) {
//ajout ORE:
ESP_LOGI("ZIGBEE", "Zigbee IEEE Address: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
ieee_addr[7], ieee_addr[6], ieee_addr[5], ieee_addr[4],
ieee_addr[3], ieee_addr[2], ieee_addr[1], ieee_addr[0]);
//fin ajout ORE
remote_zb_device.lost = 0;
memcpy(&(remote_zb_device.ieee_addr), ieee_addr, sizeof(esp_zb_ieee_addr_t));
ESP_LOGI("IEEE", "IEEE address of the device: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
ieee_addr[7], ieee_addr[6], ieee_addr[5], ieee_addr[4],
ieee_addr[3], ieee_addr[2], ieee_addr[1], ieee_addr[0]);
}
else {
ESP_LOGE("IEEE", "We didn't find any remote devices. ZDO status = %x", zdo_status);
}
}
/**
* @brief This is used to get the simple descriptor of an endpoint
*
* @param zdo_status The zdo status defines what event just happened and is used to determine what to do
* @param simple_desc A simple descriptor of found endpoint
* @param user_ctx A pointer that contains the user defines additional information
*/
static void simple_desc_cb(esp_zb_zdp_status_t zdo_status, esp_zb_af_simple_desc_1_1_t *simple_desc, void *user_ctx)
{
ESP_LOGI("CLUSTERs", "Starting cluster detection");
if (zdo_status == ESP_ZB_ZDP_STATUS_SUCCESS) {
ESP_LOGI("CLUSTERs", "Simple description response: status(%d), device_id(%d), app_version(%d), profile_id(0x%x), endpoint_ID(%d)", zdo_status,
simple_desc->app_device_id, simple_desc->app_device_version, simple_desc->app_profile_id, simple_desc->endpoint);
ESP_LOGI("CLUSTERs", "Listing all the cluster in this endpoint : ");
for (int i = 0; i < (simple_desc->app_input_cluster_count + simple_desc->app_output_cluster_count); i++) {
ESP_LOGI("CLUSTERs", "Cluster ID list: 0x%x", *(simple_desc->app_cluster_list + i));
}
}
else{
ESP_LOGE("CLUSTERs", "We didn't find any endpoints. ZDO status = %d", zdo_status);
}
}
/**
* @brief This is used when detecting endpoints
*
* @param zdo_status The zdo status defines what event just happened and is used to determine what to do
* @param ep_count Number of endpoints found on the network
* @param ed_id_list The list of endpoints' IDs
* @param user_ctx A pointer that contains the user defines additional information
*/
static void ep_cb(esp_zb_zdp_status_t zdo_status, uint8_t ep_count, uint8_t *ep_id_list, void *user_ctx)
{
ESP_LOGI("EPs", "Starting endpoints detection");
if (zdo_status == ESP_ZB_ZDP_STATUS_SUCCESS) {
ESP_LOGI("EPs", "Active endpoint response: status(%d) and endpoint count(%d)", zdo_status, ep_count);
for (int i = 0; i < ep_count; i++) {
ESP_LOGI("EPs", "Endpoint ID List: %d", ep_id_list);
/* get the node simple descriptor */
esp_zb_zdo_simple_desc_req_param_t simple_desc_req;
simple_desc_req.addr_of_interest = remote_zb_device.short_addr;
simple_desc_req.endpoint = ep_id_list;
esp_zb_zdo_simple_desc_req(&simple_desc_req, simple_desc_cb, NULL);
}
}
else {
ESP_LOGE("EPs", "We didn't find any endpoints. ZDO status = %d", zdo_status);
}
}
/**
* @brief Callback for a device joining or rejoining the network
*
* @param dev_annce_params Pointer to params given by the app signal handler
*/
void simple_gw_dev_annce_cb(esp_zb_zdo_signal_device_annce_params_t *dev_annce_params)
{
ESP_LOGI("DEVICE ANNOUNCED CB", "New device joined the network : Short address = %d, IEEE address = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, Capability = %d", dev_annce_params->device_short_addr, dev_annce_params->ieee_addr[7], dev_annce_params->ieee_addr[6], dev_annce_params->ieee_addr[5], dev_annce_params->ieee_addr[4], dev_annce_params->ieee_addr[3], dev_annce_params->ieee_addr[2], dev_annce_params->ieee_addr[1], dev_annce_params->ieee_addr[0], dev_annce_params->capability);
}
/**
* @brief This is used to descrbe remote zb user
*
* @param zdo_status The zdo status defines what event just happened and is used to determine what to do
* @param addr Address of the newly found user
* @param node_desc The description of
*
*/
static void user_find_cb(esp_zb_zdp_status_t zdo_status, uint16_t addr, esp_zb_af_node_desc_t *node_desc, void *user_ctx) {
if (zdo_status == ESP_ZB_ZDP_STATUS_SUCCESS) {
/* save into remote device record structure for future use */
remote_zb_device.short_addr = addr;
//ajout de ORE:
ESP_LOGI("USER", "Device found with short address: 0x%04x. Connection to the network is active.", addr);
/* find the active endpoint */
esp_zb_zdo_active_ep_req_param_t active_ep_req;
active_ep_req.addr_of_interest = remote_zb_device.short_addr;
esp_zb_zdo_active_ep_req(&active_ep_req, ep_cb, NULL);
/* get the device ieee address */
esp_zb_zdo_ieee_addr_req_param_t ieee_req;
ieee_req.addr_of_interest = remote_zb_device.short_addr;
ieee_req.dst_nwk_addr = remote_zb_device.short_addr;
ieee_req.request_type = 0;
ieee_req.start_index = 0;
esp_zb_zdo_ieee_addr_req(&ieee_req, ieee_cb, NULL); //ORE: warning
vTaskDelay(1000 / portTICK_PERIOD_MS);
} else {
ESP_LOGE("USER", "We didn't found any device. ZDO status = %d", zdo_status);
}
}
/**
* @brief This is the function that handle the application, it uses the state signal of the app to do different actions
*
* @param signal_struct The app signal tranmitted to the handler to decide wich action needs to be executed
*/
void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct)
{
uint32_t *p_sg_p = signal_struct->p_app_signal;
esp_err_t err_status = signal_struct->esp_err_status;
esp_zb_app_signal_type_t sig_type = *p_sg_p;
esp_zb_zdo_signal_leave_params_t *leave_params = NULL;
//ajout de trace par ORE:
ESP_LOGI("ZIGBEE_SIGNAL", "Received signal: %s (0x%x), status: %s", esp_zb_zdo_signal_to_string(sig_type), sig_type, esp_err_to_name(err_status)); //ORE: erreur
//fin ajout ORE
switch (sig_type) {
case ESP_ZB_BDB_SIGNAL_DEVICE_FIRST_START:
ESP_LOGI("SIGNAL", "First start : ZDO signal %s (Ox%x), status: %s\nStarting the BDB in network steering mode", esp_zb_zdo_signal_to_string(sig_type), sig_type, esp_err_to_name(err_status));
esp_zb_bdb_start_top_level_commissioning(ESP_ZB_BDB_MODE_NETWORK_STEERING);
break;
case ESP_ZB_BDB_SIGNAL_DEVICE_REBOOT:
ESP_LOGI("SIGNAL", "Device rebooted : ZDO signal %s (Ox%x), status: %s\nStarting the BDB in network steering mode", esp_zb_zdo_signal_to_string(sig_type), sig_type, esp_err_to_name(err_status));
esp_zb_bdb_start_top_level_commissioning(ESP_ZB_BDB_MODE_NETWORK_STEERING);
vTaskDelay(1000 / portTICK_PERIOD_MS);
break;
case ESP_ZB_BDB_SIGNAL_STEERING:
if (err_status != ESP_OK) {
ESP_LOGW("SIGNAL", "Network steering is going on but failing : %s status, steering", esp_err_to_name(err_status)); //ORE: erreur ici
esp_zb_scheduler_alarm((esp_zb_callback_t)bdb_start_top_level_commissioning_cb, ESP_ZB_BDB_MODE_NETWORK_STEERING, 5000); //ORE: 5000 au lieu de 1000
} else {
/* device auto start successfully and on a formed network */
esp_zb_ieee_addr_t extended_pan_id;
esp_zb_get_extended_pan_id(extended_pan_id);
ESP_LOGI("SIGNAL", "We've successfully join the network. (Extended PAN ID: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, PAN ID: 0x%04hx, Channel:%d, Short Address: 0x%04hx)",
extended_pan_id[7], extended_pan_id[6], extended_pan_id[5], extended_pan_id[4],
extended_pan_id[3], extended_pan_id[2], extended_pan_id[1], extended_pan_id[0],
esp_zb_get_pan_id(), esp_zb_get_current_channel(), esp_zb_get_short_address());
esp_zb_zdo_node_desc_req_param_t cmd_req;
cmd_req.dst_nwk_addr = 0x0000;
esp_zb_zdo_node_desc_req(&cmd_req, user_find_cb, NULL);
}
break;
case ESP_ZB_ZDO_SIGNAL_LEAVE:
leave_params = (esp_zb_zdo_signal_leave_params_t *)esp_zb_app_signal_get_params(p_sg_p);
if (leave_params->leave_type == ESP_ZB_NWK_LEAVE_TYPE_RESET) {
ESP_LOGI("SIGNAL", "You should reset the device");
}
break;
case ESP_ZB_NLME_STATUS_INDICATION:
break;
case ESP_ZB_ZDO_DEVICE_UNAVAILABLE: //ajout de Guillaume
ESP_LOGW("COUCOU", "COUCOU: %s (0x%x), status: %s", esp_zb_zdo_signal_to_string(sig_type), sig_type, esp_err_to_name(err_status));
break;
default:
ESP_LOGW("SIGNAL", "ZDO signal: %s (0x%x), status: %s", esp_zb_zdo_signal_to_string(sig_type), sig_type, esp_err_to_name(err_status));
break;
}
}
/**
* @brief This handles the attribut report message
*
* @param message The attribut message report
*
* @return ESP_OK Success - ESP_ERR_INVALID_ARG Received an incorrect message - ESP_FAIL Empty message
*/
static esp_err_t zb_attribute_reporting_handler(const esp_zb_zcl_report_attr_message_t *message)
{
ESP_RETURN_ON_FALSE(message, ESP_FAIL, "ATTR REPORT", "Empty message");
ESP_RETURN_ON_FALSE(message->status == ESP_ZB_ZCL_STATUS_SUCCESS, ESP_ERR_INVALID_ARG, "ATTR REPORT", "Received message: error status(%d)",
message->status);
ESP_LOGI("ATTR REPORT", "Received report from address(0x%x) src endpoint(%d) to dst endpoint(%d) cluster(0x%x)", message->src_address.u.short_addr,
message->src_endpoint, message->dst_endpoint, message->cluster);
ESP_LOGI("ATTR REPORT", "Received report information: attribute(0x%x), type(0x%x), value(%d)\n", message->attribute.id, message->attribute.data.type,
message->attribute.data.value ? *(uint8_t *)message->attribute.data.value : 0);
return ESP_OK;
}
/**
* @brief This handles the read attribut response
*
* @param message The attribut reading response message
*
* @return ESP_OK Success - ESP_ERR_INVALID_ARG Received an incorrect message - ESP_FAIL Empty message
*/
static esp_err_t zb_read_attr_resp_handler(const esp_zb_zcl_cmd_read_attr_resp_message_t *message)
{
ESP_RETURN_ON_FALSE(message, ESP_FAIL, "READ ATTR", "Empty message");
ESP_RETURN_ON_FALSE(message->info.status == ESP_ZB_ZCL_STATUS_SUCCESS, ESP_ERR_INVALID_ARG, "READ ATTR", "Received message: error status(%d)",
message->info.status);
esp_zb_zcl_read_attr_resp_variable_t *variable = message->variables;
while (variable) {
ESP_LOGI("READ ATTR", "Read attribute response: status(%d), cluster(0x%x), attribute(0x%x), type(0x%x), value(%d)", variable->status,
message->info.cluster, variable->attribute.id, variable->attribute.data.type,
variable->attribute.data.value ? *(uint8_t *)variable->attribute.data.value : 0);
variable = variable->next;
}
return ESP_OK;
}
/**
* @brief This handles the configure report response
*
* @param message The configure report message
*
* @return ESP_OK Success - ESP_ERR_INVALID_ARG Received an incorrect message - ESP_FAIL Empty message
*/
static esp_err_t zb_configure_report_resp_handler(const esp_zb_zcl_cmd_config_report_resp_message_t *message)
{
ESP_RETURN_ON_FALSE(message, ESP_FAIL, "CONF REPORT", "Empty message");
ESP_RETURN_ON_FALSE(message->info.status == ESP_ZB_ZCL_STATUS_SUCCESS, ESP_ERR_INVALID_ARG, "CONF REPORT", "Received message: error status(%d)",
message->info.status);
esp_zb_zcl_config_report_resp_variable_t *variable = message->variables;
while (variable) {
ESP_LOGI("CONF REPORT", "Configure report response: status(%d), cluster(0x%x), attribute(0x%x)", message->info.status, message->info.cluster,
variable->attribute_id);
variable = variable->next;
}
return ESP_OK;
}
/**
* @brief This handles actions callback
*
* @param callback_id The callback id corresponding to the action asked
* @param message The message corresponding to the callback id
*
* @return ESP_OK Success - ESP_ERR_INVALID_ARG Received an incorrect message - ESP_FAIL Empty message
*/
static esp_err_t zb_action_handler(esp_zb_core_action_callback_id_t callback_id, const void *message)
{
esp_err_t ret = ESP_OK;
switch (callback_id) {
case ESP_ZB_CORE_REPORT_ATTR_CB_ID:
ret = zb_attribute_reporting_handler((esp_zb_zcl_report_attr_message_t *)message);
break;
case ESP_ZB_CORE_CMD_READ_ATTR_RESP_CB_ID:
ret = zb_read_attr_resp_handler((esp_zb_zcl_cmd_read_attr_resp_message_t *)message);
break;
case ESP_ZB_CORE_CMD_REPORT_CONFIG_RESP_CB_ID:
ret = zb_configure_report_resp_handler((esp_zb_zcl_cmd_config_report_resp_message_t *)message);
break;
default:
ESP_LOGW("ACTION", "Receive Zigbee action(0x%x) callback", callback_id);
break;
}
return ret;
}
/**
* @brief The main zigbee task. Creates device, endpoints, clusters and attributs. Starts the main zigbee loop
*
* @param pvParameters Pointer that will be used as the parameter for the task being created
*
* @return ESP_OK Success - ESP_ERR_INVALID_ARG Received an incorrect message - ESP_FAIL Empty message
*/
static void esp_zb_task(void *pvParameters)
{
/* initialize Zigbee stack */
esp_zb_cfg_t zb_nwk_cfg = ESP_ZB_ZR_CONFIG();
esp_zb_init(&zb_nwk_cfg);
//ajout de ORE:
ESP_LOGI("ZIGBEE", "Channel 11 à 26");
esp_zb_set_primary_network_channel_set(0x07FFF800); // le dongle est sur le channel 20 Valid channel mask is from 0x00000800 (only channel 11) to 0x07FFF800 (all channels from 11 to 26)
// ajout de ORE: PAN_ID
esp_zb_set_pan_id(PAN_ID);
//ajout de ORE: verification mode router
esp_zb_nwk_device_type_t device_type = esp_zb_get_network_device_role();
if (device_type == ESP_ZB_DEVICE_TYPE_ROUTER)
ESP_LOGI("ZIGBEE", "ESP32 is in Router mode.");
//ajout de ORE: demander sa propre adresse:
esp_zb_zdo_ieee_addr_req_param_t ieee_req;
ieee_req.addr_of_interest = 0xFFFF; // Adresse de diffusion pour obtenir l'adresse
esp_zb_zdo_ieee_addr_req(&ieee_req, ieee_cb, NULL); //ORE:warning
/* Creation of a zigbee analog input cluster for temperature*/
esp_zb_analog_input_cluster_cfg_t analog_input_cluster_Temp;
analog_input_cluster_Temp.out_of_service = ESP_ZB_ZCL_ANALOG_INPUT_OUT_OF_SERVICE_DEFAULT_VALUE;
analog_input_cluster_Temp.status_flags = ESP_ZB_ZCL_ANALOG_INPUT_STATUS_FLAG_OVERRIDDEN;
analog_input_cluster_Temp.present_value = measured_temperature;
/* Creation of a zigbee analog input cluster for humidity*/
esp_zb_analog_input_cluster_cfg_t analog_input_cluster_hum;
analog_input_cluster_hum.out_of_service = ESP_ZB_ZCL_ANALOG_INPUT_OUT_OF_SERVICE_DEFAULT_VALUE;
analog_input_cluster_hum.status_flags = ESP_ZB_ZCL_ANALOG_INPUT_STATUS_FLAG_OVERRIDDEN;
analog_input_cluster_hum.present_value = measured_humidity;
/* Creation of a zigbee analog input cluster for voc*/
esp_zb_analog_input_cluster_cfg_t analog_input_cluster_voc;
analog_input_cluster_voc.out_of_service = ESP_ZB_ZCL_ANALOG_INPUT_OUT_OF_SERVICE_DEFAULT_VALUE;
analog_input_cluster_voc.status_flags = ESP_ZB_ZCL_ANALOG_INPUT_STATUS_FLAG_OVERRIDDEN;
analog_input_cluster_voc.present_value = measured_voc;
/* Creation of a zigbee analog input cluster for Co2*/
esp_zb_analog_input_cluster_cfg_t analog_input_cluster_co2;
analog_input_cluster_co2.out_of_service = ESP_ZB_ZCL_ANALOG_INPUT_OUT_OF_SERVICE_DEFAULT_VALUE;
analog_input_cluster_co2.status_flags = ESP_ZB_ZCL_ANALOG_INPUT_STATUS_FLAG_OVERRIDDEN;
analog_input_cluster_co2.present_value = measured_co2;
/* Creation of a zigbee analog input cluster for volume*/
esp_zb_analog_input_cluster_cfg_t analog_input_cluster_vol;
analog_input_cluster_vol.out_of_service = ESP_ZB_ZCL_ANALOG_INPUT_OUT_OF_SERVICE_DEFAULT_VALUE;
analog_input_cluster_vol.status_flags = ESP_ZB_ZCL_ANALOG_INPUT_STATUS_FLAG_OVERRIDDEN;
analog_input_cluster_vol.present_value = measured_volume;
/* Creation of a zigbee analog input cluster for pm 1.0*/
esp_zb_analog_input_cluster_cfg_t analog_input_cluster_pm1_0;
analog_input_cluster_pm1_0.out_of_service = ESP_ZB_ZCL_ANALOG_INPUT_OUT_OF_SERVICE_DEFAULT_VALUE;
analog_input_cluster_pm1_0.status_flags = ESP_ZB_ZCL_ANALOG_INPUT_STATUS_FLAG_OVERRIDDEN;
analog_input_cluster_pm1_0.present_value = measured_pm1_0;
/* Creation of a zigbee analog input cluster for pm 2.5*/
esp_zb_analog_input_cluster_cfg_t analog_input_cluster_pm2_5;
analog_input_cluster_pm2_5.out_of_service = ESP_ZB_ZCL_ANALOG_INPUT_OUT_OF_SERVICE_DEFAULT_VALUE;
analog_input_cluster_pm2_5.status_flags = ESP_ZB_ZCL_ANALOG_INPUT_STATUS_FLAG_OVERRIDDEN;
analog_input_cluster_pm2_5.present_value = measured_pm2_5;
/* Creation of a zigbee analog input cluster for pm 4.0*/
esp_zb_analog_input_cluster_cfg_t analog_input_cluster_pm4_0;
analog_input_cluster_pm4_0.out_of_service = ESP_ZB_ZCL_ANALOG_INPUT_OUT_OF_SERVICE_DEFAULT_VALUE;
analog_input_cluster_pm4_0.status_flags = ESP_ZB_ZCL_ANALOG_INPUT_STATUS_FLAG_OVERRIDDEN;
analog_input_cluster_pm4_0.present_value = measured_pm4_0;
/* Creation of a zigbee analog input cluster for pm 10.0*/
esp_zb_analog_input_cluster_cfg_t analog_input_cluster_pm10_0;
analog_input_cluster_pm10_0.out_of_service = ESP_ZB_ZCL_ANALOG_INPUT_OUT_OF_SERVICE_DEFAULT_VALUE;
analog_input_cluster_pm10_0.status_flags = ESP_ZB_ZCL_ANALOG_INPUT_STATUS_FLAG_OVERRIDDEN;
analog_input_cluster_pm10_0.present_value = measured_pm10_0;
esp_zb_ep_list_t *esp_zb_ep_list = esp_zb_ep_list_create();
/* Creation of an endpoint that contains the temperature analog input cluster*/
esp_zb_attribute_list_t *esp_zb_analog_input_cluster_temp = esp_zb_analog_input_cluster_create(&analog_input_cluster_Temp);
esp_zb_cluster_list_t *esp_zb_cluster_list_temp = esp_zb_zcl_cluster_list_create();
esp_zb_cluster_list_add_analog_input_cluster(esp_zb_cluster_list_temp, esp_zb_analog_input_cluster_temp, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);
esp_zb_endpoint_config_t endpoint_config_temp = {
.endpoint = ANALOG_INPUT_ENDPOINT_TEMP,
.app_profile_id = ESP_ZB_AF_HA_PROFILE_ID,
.app_device_id = ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID,
.app_device_version = 0
};
esp_zb_ep_list_add_ep(esp_zb_ep_list, esp_zb_cluster_list_temp, endpoint_config_temp);
/* Creation of an endpoint that contains the humidity analog input cluster*/
esp_zb_attribute_list_t *esp_zb_analog_input_cluster_hum = esp_zb_analog_input_cluster_create(&analog_input_cluster_hum);
esp_zb_cluster_list_t *esp_zb_cluster_list_hum = esp_zb_zcl_cluster_list_create();
esp_zb_cluster_list_add_analog_input_cluster(esp_zb_cluster_list_hum, esp_zb_analog_input_cluster_hum, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);
esp_zb_endpoint_config_t endpoint_config_hum = {
.endpoint = ANALOG_INPUT_ENDPOINT_HUM,
.app_profile_id = ESP_ZB_AF_HA_PROFILE_ID,
.app_device_id = ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID,
.app_device_version = 0
};
esp_zb_ep_list_add_ep(esp_zb_ep_list, esp_zb_cluster_list_hum, endpoint_config_hum);
/* Creation of an endpoint that contains the voc analog input cluster*/
esp_zb_attribute_list_t *esp_zb_analog_input_cluster_voc = esp_zb_analog_input_cluster_create(&analog_input_cluster_voc);
esp_zb_cluster_list_t *esp_zb_cluster_list_voc = esp_zb_zcl_cluster_list_create();
esp_zb_cluster_list_add_analog_input_cluster(esp_zb_cluster_list_voc, esp_zb_analog_input_cluster_voc, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);
esp_zb_endpoint_config_t endpoint_config_voc = {
.endpoint = ANALOG_INPUT_ENDPOINT_VOC,
.app_profile_id = ESP_ZB_AF_HA_PROFILE_ID,
.app_device_id = ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID,
.app_device_version = 0
};
esp_zb_ep_list_add_ep(esp_zb_ep_list, esp_zb_cluster_list_voc, endpoint_config_voc);
/* Creation of an endpoint that contains the Co2 analog input cluster*/
esp_zb_attribute_list_t *esp_zb_analog_input_cluster_co2 = esp_zb_analog_input_cluster_create(&analog_input_cluster_co2);
esp_zb_cluster_list_t *esp_zb_cluster_list_co2 = esp_zb_zcl_cluster_list_create();
esp_zb_cluster_list_add_analog_input_cluster(esp_zb_cluster_list_co2, esp_zb_analog_input_cluster_co2, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);
esp_zb_endpoint_config_t endpoint_config_co2 = {
.endpoint = ANALOG_INPUT_ENDPOINT_CO2,
.app_profile_id = ESP_ZB_AF_HA_PROFILE_ID,
.app_device_id = ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID,
.app_device_version = 0
};
esp_zb_ep_list_add_ep(esp_zb_ep_list, esp_zb_cluster_list_co2, endpoint_config_co2);
/* Creation of an endpoint that contains the volume analog input cluster*/
esp_zb_attribute_list_t *esp_zb_analog_input_cluster_vol = esp_zb_analog_input_cluster_create(&analog_input_cluster_vol);
esp_zb_cluster_list_t *esp_zb_cluster_list_vol = esp_zb_zcl_cluster_list_create();
esp_zb_cluster_list_add_analog_input_cluster(esp_zb_cluster_list_vol, esp_zb_analog_input_cluster_vol, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);
esp_zb_endpoint_config_t endpoint_config_vol = {
.endpoint = ANALOG_INPUT_ENDPOINT_VOL,
.app_profile_id = ESP_ZB_AF_HA_PROFILE_ID,
.app_device_id = ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID,
.app_device_version = 0
};
esp_zb_ep_list_add_ep(esp_zb_ep_list, esp_zb_cluster_list_vol, endpoint_config_vol);
/* Creation of an endpoint that contains the pm 1.0 analog input cluster*/
esp_zb_attribute_list_t *esp_zb_analog_input_cluster_pm1_0 = esp_zb_analog_input_cluster_create(&analog_input_cluster_pm1_0);
esp_zb_cluster_list_t *esp_zb_cluster_list_pm1_0 = esp_zb_zcl_cluster_list_create();
esp_zb_cluster_list_add_analog_input_cluster(esp_zb_cluster_list_pm1_0, esp_zb_analog_input_cluster_pm1_0, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);
esp_zb_endpoint_config_t endpoint_config_pm1_0 = {
.endpoint = ANALOG_INPUT_ENDPOINT_PM1_0,
.app_profile_id = ESP_ZB_AF_HA_PROFILE_ID,
.app_device_id = ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID,
.app_device_version = 0
};
esp_zb_ep_list_add_ep(esp_zb_ep_list, esp_zb_cluster_list_pm1_0, endpoint_config_pm1_0);
/* Creation of an endpoint that contains the pm 2.5 analog input cluster*/
esp_zb_attribute_list_t *esp_zb_analog_input_cluster_pm2_5 = esp_zb_analog_input_cluster_create(&analog_input_cluster_pm2_5);
esp_zb_cluster_list_t *esp_zb_cluster_list_pm2_5 = esp_zb_zcl_cluster_list_create();
esp_zb_cluster_list_add_analog_input_cluster(esp_zb_cluster_list_pm2_5, esp_zb_analog_input_cluster_pm2_5, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);
esp_zb_endpoint_config_t endpoint_config_pm2_5 = {
.endpoint = ANALOG_INPUT_ENDPOINT_PM2_5,
.app_profile_id = ESP_ZB_AF_HA_PROFILE_ID,
.app_device_id = ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID,
.app_device_version = 0
};
esp_zb_ep_list_add_ep(esp_zb_ep_list, esp_zb_cluster_list_pm2_5, endpoint_config_pm2_5);
/* Creation of an endpoint that contains the pm 4.0 analog input cluster*/
esp_zb_attribute_list_t *esp_zb_analog_input_cluster_pm4_0 = esp_zb_analog_input_cluster_create(&analog_input_cluster_pm4_0);
esp_zb_cluster_list_t *esp_zb_cluster_list_pm4_0 = esp_zb_zcl_cluster_list_create();
esp_zb_cluster_list_add_analog_input_cluster(esp_zb_cluster_list_pm4_0, esp_zb_analog_input_cluster_pm4_0, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);
esp_zb_endpoint_config_t endpoint_config_pm4_0 = {
.endpoint = ANALOG_INPUT_ENDPOINT_PM4_0,
.app_profile_id = ESP_ZB_AF_HA_PROFILE_ID,
.app_device_id = ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID,
.app_device_version = 0
};
esp_zb_ep_list_add_ep(esp_zb_ep_list, esp_zb_cluster_list_pm4_0, endpoint_config_pm4_0);
/* Creation of an endpoint that contains the pm 10.0 analog input cluster*/
esp_zb_attribute_list_t *esp_zb_analog_input_cluster_pm10_0 = esp_zb_analog_input_cluster_create(&analog_input_cluster_pm10_0);
esp_zb_cluster_list_t *esp_zb_cluster_list_pm10_0 = esp_zb_zcl_cluster_list_create();
esp_zb_cluster_list_add_analog_input_cluster(esp_zb_cluster_list_pm10_0, esp_zb_analog_input_cluster_pm10_0, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);
esp_zb_endpoint_config_t endpoint_config_pm10_0 = {
.endpoint = ANALOG_INPUT_ENDPOINT_PM10_0,
.app_profile_id = ESP_ZB_AF_HA_PROFILE_ID,
.app_device_id = ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID,
.app_device_version = 0
};
esp_zb_ep_list_add_ep(esp_zb_ep_list, esp_zb_cluster_list_pm10_0, endpoint_config_pm10_0);
/* Creation of a zigbee device*/
esp_zb_device_register(esp_zb_ep_list);
esp_zb_core_action_handler_register(zb_action_handler);
esp_zb_set_primary_network_channel_set(ESP_ZB_PRIMARY_CHANNEL_MASK);
esp_zb_set_secondary_network_channel_set(ESP_ZB_SECONDARY_CHANNEL_MASK);
ESP_ERROR_CHECK(esp_zb_start(true));
esp_zb_main_loop_iteration();
}
/**
* @brief Change the value in the attribut present_value in the analog input cluster in the endpoint specified
*
* @param value The new value measured by the sensor
* @param endpoint The endpoint that contains the sensor's cluster
*/
static void esp_app_sensor_handler(float value, uint8_t endpoint)
{
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_set_attribute_val(endpoint,
ESP_ZB_ZCL_CLUSTER_ID_ANALOG_INPUT, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE,
ESP_ZB_ZCL_ATTR_ANALOG_INPUT_PRESENT_VALUE_ID, &value, false);
esp_zb_lock_release();
}
/**
* @brief Changes values of all the sensors
*/
static void esp_zb_value_task(){
esp_zb_zdo_ieee_addr_req_param_t ieee_req;
ieee_req.addr_of_interest = remote_zb_device.short_addr;
ieee_req.dst_nwk_addr = remote_zb_device.short_addr;
ieee_req.request_type = 0;
ieee_req.start_index = 0;
while(1) {
esp_app_sensor_handler(measured_temperature, ANALOG_INPUT_ENDPOINT_TEMP);
esp_app_sensor_handler(measured_humidity, ANALOG_INPUT_ENDPOINT_HUM);
esp_app_sensor_handler(measured_voc, ANALOG_INPUT_ENDPOINT_VOC);
esp_app_sensor_handler(measured_co2, ANALOG_INPUT_ENDPOINT_CO2);
esp_app_sensor_handler(measured_volume, ANALOG_INPUT_ENDPOINT_VOL);
esp_app_sensor_handler(measured_pm1_0, ANALOG_INPUT_ENDPOINT_PM1_0);
esp_app_sensor_handler(measured_pm2_5, ANALOG_INPUT_ENDPOINT_PM2_5);
esp_app_sensor_handler(measured_pm4_0, ANALOG_INPUT_ENDPOINT_PM4_0);
esp_app_sensor_handler(measured_pm10_0, ANALOG_INPUT_ENDPOINT_PM10_0);
ESP_LOGI("Values", "\
\nTemperature : %.1f °C\t\tHumidity : %.0f %%\t\t\tVOC : %.0f ppb\
\nCO2 : %.0f ppm\t\t\tVolume : %.0f dB\t\t\tPM1.0 : %.1f µg/m³\
\nPM2.5 : %.1f µg/m³\t\tPM4.0 : %.1f µg/m³\t\tPM10.0 : %.1f µg/m³\
\nPM0.5 : %.1f part/cm³\t\tPM1.0 : %.1f part/cm³\t\tPM2.5 : %.1f part/cm³\
\nPM4.0 : %.1f part/cm³\t\tPM10. : %.1f part/cm³\t\tTyp. size : %.2f µm",
measured_temperature,
measured_humidity,
measured_voc, measured_co2,
measured_volume,
measured_pm1_0,
measured_pm2_5,
measured_pm4_0,
measured_pm10_0,
sen5x_dev.pm0p5_nbr,
sen5x_dev.pm1p0_nbr,
sen5x_dev.pm2p5_nbr,
sen5x_dev.pm4p0_nbr,
sen5x_dev.pm10p0_nbr,
sen5x_dev.typical_particul_size);
esp_zb_zdo_ieee_addr_req(&ieee_req, check_coordo_alive_cb, NULL);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
/**
* @brief Main function of the application. Starts automatically when the ESP boots
*/
void app_main(void)
{
/* Configuration of zigbee*/
esp_zb_platform_config_t config = {
.radio_config = ESP_ZB_DEFAULT_RADIO_CONFIG(),
.host_config = ESP_ZB_DEFAULT_HOST_CONFIG(),
};
ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_zb_platform_config(&config));
/* Starts the main zigbee task*/
ESP_LOGI("MAIN", "Zigbee is starting ...");
xTaskCreate(esp_zb_task, "Zigbee_main", 4096, NULL, 5, NULL);
/* setup of i2c*/
i2c_master_bus_config_t bus_config = {
.i2c_port = CONFIG_I2C_MASTER_PORT_NUM,
.sda_io_num = CONFIG_I2C_MASTER_SDA,
.scl_io_num = CONFIG_I2C_MASTER_SCL,
.clk_source = I2C_CLK_SRC_DEFAULT,
.flags.enable_internal_pullup = 1,
};
ESP_ERROR_CHECK(i2c_new_master_bus(&bus_config, &bus_mst_handle));
xTaskCreate(measurement_task, "Measurement task", 4096, NULL, 5, NULL);
vTaskDelay(16000 / portTICK_PERIOD_MS);
xTaskCreate(esp_zb_value_task, "Zigbee_measurement_task", 4096, NULL, 5, NULL);
}
I have programmed an ESP32-H2 to join a zigbee network.
Here is the log of the esp:
I (23) boot: ESP-IDF v5.2.2-dirty 2nd stage bootloader
I (24) boot: compile time Nov 15 2024 18:52:35
I (25) boot: chip revision: v0.1
I (27) boot.esp32h2: SPI Speed : 64MHz
I (32) boot.esp32h2: SPI Mode : DIO
I (37) boot.esp32h2: SPI Flash Size : 2MB
I (41) boot: Enabling RNG early entropy source...
I (47) boot: Partition Table:
I (50) boot: ## Label Usage Type ST Offset Length
I (58) boot: 0 nvs WiFi data 01 02 00009000 00006000
I (65) boot: 1 phy_init RF data 01 01 0000f000 00001000
I (72) boot: 2 factory factory app 00 00 00010000 000e1000
I (80) boot: 3 zb_storage Unknown data 01 81 000f1000 00004000
I (87) boot: 4 zb_fct Unknown data 01 81 000f5000 00000400
I (95) boot: End of partition table
I (99) esp_image: segment 0: paddr=00010020 vaddr=42078020 size=11988h ( 72072) map
I (130) esp_image: segment 1: paddr=000219b0 vaddr=40800000 size=06668h ( 26216) load
I (140) esp_image: segment 2: paddr=00028020 vaddr=42000020 size=769fch (485884) map
I (289) esp_image: segment 3: paddr=0009ea24 vaddr=40806668 size=059d0h ( 22992) load
I (298) esp_image: segment 4: paddr=000a43fc vaddr=4080c040 size=01c1ch ( 7196) load
I (301) esp_image: segment 5: paddr=000a6020 vaddr=50000000 size=00004h ( 4) load
I (307) boot: Loaded app from partition at offset 0x10000
I (309) boot: Disabling RNG early entropy source...
I (326) cpu_start: Unicore app
W (335) clk: esp_perip_clk_init() has not been implemented yet
I (342) cpu_start: Pro cpu start user code
I (342) cpu_start: cpu freq: 96000000 Hz
I (343) heap_init: Initializing. RAM available for dynamic allocation:
I (347) heap_init: At 40813160 len 0003A220 (232 KiB): RAM
I (353) heap_init: At 4084D380 len 00002B60 (10 KiB): RAM
I (361) spi_flash: detected chip: generic
I (364) spi_flash: flash io: dio
W (368) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (382) sleep: Configure to isolate all GPIO pins in sleep state
I (388) sleep: Enable automatic switching of GPIO sleep configuration
I (396) main_task: Started on CPU0
I (396) main_task: Calling app_main()
I (406) MAIN: Zigbee is starting ...
I (416) phy: phy_version: 230,2, 9aae6ea, Jan 15 2024, 11:17:12
I (416) phy: libbtbb version: 944f18e, Jan 15 2024, 11:17:25
I (426) ZIGBEE: ESP32 is in Router mode.
I (446) gpio: GPIO[4]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0
I (446) gpio: GPIO[5]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0
I (456) ZIGBEE_SIGNAL: Received signal: ZDO Config Ready (0x17), status: ESP_FAIL
W (456) SIGNAL: ZDO signal: ZDO Config Ready (0x17), status: ESP_FAIL
I (466) IEEE: Starting ieee address detection
E (466) IEEE: We didn't find any remote devices. ZDO status = 85
I (476) ZIGBEE_SIGNAL: Received signal: ZDO Device Unavailable (0x3c), status: ESP_OK
W (486) SIGNAL: ZDO signal: ZDO Device Unavailable (0x3c), status: ESP_OK
I (496) gpio: GPIO[1]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
I (716) sen5x: Serial number: 25�38b80�7EU7DdB5�97�78�
I (716) sen5x: Product name: SE�N5U0
I (716) sen5x: Firmware version: 02 00
I (816) sgp30: Serial Number: 00 00 81
I (816) sgp30: Feature set version: 00 22 65
SGP30 still needs 15 seconds to calibrate.
SGP30 still needs 14 seconds to calibrate.
I (2896) ZIGBEE_SIGNAL: Received signal: BDB Device Start (0x5), status: ESP_FAIL
I (2896) SIGNAL: First start : ZDO signal BDB Device Start (Ox5), status: ESP_FAIL
Starting the BDB in network steering mode
SGP30 still needs 13 seconds to calibrate.
SGP30 still needs 12 seconds to calibrate.
I (5306) ZIGBEE_SIGNAL: Received signal: BDB Steering (0xa), status: ESP_FAIL
W (5306) SIGNAL: Network steering is going on but failing : ESP_FAIL status, steering
SGP30 still needs 11 seconds to calibrate.
I (6316) ZIGBEE: Starting Zigbee commissioning...
I (6316) ZIGBEE: Zigbee commissioning started successfully.
SGP30 still needs 10 seconds to calibrate.
SGP30 still needs 9 seconds to calibrate.
I (8716) ZIGBEE_SIGNAL: Received signal: BDB Steering (0xa), status: ESP_FAIL
W (8716) SIGNAL: Network steering is going on but failing : ESP_FAIL status, steering
SGP30 still needs 8 seconds to calibrate.
I (9726) ZIGBEE: Starting Zigbee commissioning...
I (9726) ZIGBEE: Zigbee commissioning started successfully.
SGP30 still needs 7 seconds to calibrate.
SGP30 still needs 6 seconds to calibrate.
SGP30 still needs 5 seconds to calibrate.
I (12126) ZIGBEE_SIGNAL: Received signal: BDB Steering (0xa), status: ESP_FAIL
W (12126) SIGNAL: Network steering is going on but failing : ESP_FAIL status, steering
SGP30 still needs 4 seconds to calibrate.
I (13136) ZIGBEE: Starting Zigbee commissioning...
I (13136) ZIGBEE: Zigbee commissioning started successfully.
SGP30 still needs 3 seconds to calibrate.
SGP30 still needs 2 seconds to calibrate.
I (15536) ZIGBEE_SIGNAL: Received signal: BDB Steering (0xa), status: ESP_FAIL
W (15536) SIGNAL: Network steering is going on but failing : ESP_FAIL status, steering
SGP30 still needs 1 seconds to calibrate.
I (16506) Values:
Temperature : -1.0 °C Humidity : -1 % VOC : -1 ppb
CO2 : -1 ppm Volume : -1 dB PM1.0 : -1.0 µg/m³
PM2.5 : -1.0 µg/m³ PM4.0 : -1.0 µg/m³ PM10.0 : -1.0 µg/m³
PM0.5 : 0.0 part/cm³ PM1.0 : 0.0 part/cm³ PM2.5 : 0.0 part/cm³
PM4.0 : 0.0 part/cm³ PM10. : 0.0 part/cm³ Typ. size : 0.00 µm
I (16526) ZIGBEE_SIGNAL: Received signal: ZDO Device Unavailable (0x3c), status: ESP_OK
W (16536) SIGNAL: ZDO signal: ZDO Device Unavailable (0x3c), status: ESP_OK
I (16536) main_task: Returned from app_main()
I (16546) ZIGBEE: Starting Zigbee commissioning...
I (16546) ZIGBEE: Zigbee commissioning started successfully.
SGP30 still needs 0 seconds to calibrate.
I (17526) Values:
Temperature : 24.4 °C Humidity : 45 % VOC : 6 ppb
CO2 : 400 ppm Volume : -1 dB PM1.0 : 3.7 µg/m³
PM2.5 : 6.2 µg/m³ PM4.0 : 8.2 µg/m³ PM10.0 : 9.1 µg/m³
PM0.5 : 20.2 part/cm³ PM1.0 : 26.8 part/cm³ PM2.5 : 29.0 part/cm³
PM4.0 : 29.4 part/cm³ PM10. : 29.5 part/cm³ Typ. size : 8.67 µm
I (17546) ZIGBEE_SIGNAL: Received signal: ZDO Device Unavailable (0x3c), status: ESP_OK
W (17556) SIGNAL: ZDO signal: ZDO Device Unavailable (0x3c), status: ESP_OK
I see errors ZDO Device Unavailable and Network steering is going on but failing : ESP_FAIL
What can cause these errors?
Here is the zigbee part of the code:
/**
* @brief This is used to store device informations
*/
typedef struct device_params_s {
esp_zb_ieee_addr_t ieee_addr; /* This is the ieee addresse of the remote device*/
uint16_t short_addr; /* This is the short addresse of the remote device adresse unique courte de l'esp qui a rejoint le réseau*/
int16_t lost; /* This is used to determined wether the coordo is lost or not*/
} device_params_t;
/* remote device struct for recording and managing node info */
device_params_t remote_zb_device = {
.lost = -1,
};
/**
* @brief This is used to start the Base Device Behavior commissioning
*
* @param mode_mask Used to determine wich mode the bdb must be in when starting
*/
static void bdb_start_top_level_commissioning_cb(uint8_t mode_mask) //ORE: fonction ok
{
//changement par ORE:
//ESP_RETURN_ON_FALSE(esp_zb_bdb_start_top_level_commissioning(mode_mask) == ESP_OK, , "BDB", "Failed to start BDB commission");
ESP_LOGI("ZIGBEE", "Starting Zigbee commissioning...");
esp_err_t ret = esp_zb_bdb_start_top_level_commissioning(ESP_ZB_BDB_MODE_NETWORK_STEERING);
if (ret != ESP_OK) {
ESP_LOGE("ZIGBEE", "Failed to start BDB commissioning: %s", esp_err_to_name(ret));
vTaskDelete(NULL); // Supprime la tâche en cas d'échec
return;
}
ESP_LOGI("ZIGBEE", "Zigbee commissioning started successfully.");
}
/**
* @brief Used to determine if the coordinator is still on or not and to reconnect to the network if it has been lost and found back
*
* @param zdo_status The zdo status defines what event just happened and is used to determine what to do
* @param ieee_addr It's the address of the newly found remote device
* @param user_ctx A pointer that contains the user defines additional information
*/
static void check_coordo_alive_cb(esp_zb_zdp_status_t zdo_status, esp_zb_ieee_addr_t ieee_addr, void *user_ctx)
{
if (zdo_status != ESP_ZB_ZDP_STATUS_SUCCESS) {
if (remote_zb_device.lost == -1) {
} else if (remote_zb_device.lost == 0) {
remote_zb_device.lost = 1;
ESP_LOGE("COORDO", "We've lost the coordo.");
} else if (remote_zb_device.lost < 5) {
remote_zb_device.lost += 1;
} else if (remote_zb_device.lost >= 5) {
ESP_LOGE("COORDO", "Restart"); // Redémarrage si le coordonnateur est perdu
esp_restart();
}
} else {
remote_zb_device.lost = 0; // Réinitialisation parce que le coordonnateur est trouvé
}
}
/**
* @brief This is used to get ieee addresse from remote device
*
* @param zdo_status The zdo status defines what event just happened and is used to determine what to do
* @param ieee_addr It's the address of the newly found remote device
* @param user_ctx A pointer that contains the user defines additional information
*/
static void ieee_cb(esp_zb_zdp_status_t zdo_status, esp_zb_ieee_addr_t ieee_addr, void *user_ctx) // ORE: warning sur le deuxieme argument
{
ESP_LOGI("IEEE", "Starting ieee address detection");
if (zdo_status == ESP_ZB_ZDP_STATUS_SUCCESS) {
//ajout ORE:
ESP_LOGI("ZIGBEE", "Zigbee IEEE Address: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
ieee_addr[7], ieee_addr[6], ieee_addr[5], ieee_addr[4],
ieee_addr[3], ieee_addr[2], ieee_addr[1], ieee_addr[0]);
//fin ajout ORE
remote_zb_device.lost = 0;
memcpy(&(remote_zb_device.ieee_addr), ieee_addr, sizeof(esp_zb_ieee_addr_t));
ESP_LOGI("IEEE", "IEEE address of the device: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
ieee_addr[7], ieee_addr[6], ieee_addr[5], ieee_addr[4],
ieee_addr[3], ieee_addr[2], ieee_addr[1], ieee_addr[0]);
}
else {
ESP_LOGE("IEEE", "We didn't find any remote devices. ZDO status = %x", zdo_status);
}
}
/**
* @brief This is used to get the simple descriptor of an endpoint
*
* @param zdo_status The zdo status defines what event just happened and is used to determine what to do
* @param simple_desc A simple descriptor of found endpoint
* @param user_ctx A pointer that contains the user defines additional information
*/
static void simple_desc_cb(esp_zb_zdp_status_t zdo_status, esp_zb_af_simple_desc_1_1_t *simple_desc, void *user_ctx)
{
ESP_LOGI("CLUSTERs", "Starting cluster detection");
if (zdo_status == ESP_ZB_ZDP_STATUS_SUCCESS) {
ESP_LOGI("CLUSTERs", "Simple description response: status(%d), device_id(%d), app_version(%d), profile_id(0x%x), endpoint_ID(%d)", zdo_status,
simple_desc->app_device_id, simple_desc->app_device_version, simple_desc->app_profile_id, simple_desc->endpoint);
ESP_LOGI("CLUSTERs", "Listing all the cluster in this endpoint : ");
for (int i = 0; i < (simple_desc->app_input_cluster_count + simple_desc->app_output_cluster_count); i++) {
ESP_LOGI("CLUSTERs", "Cluster ID list: 0x%x", *(simple_desc->app_cluster_list + i));
}
}
else{
ESP_LOGE("CLUSTERs", "We didn't find any endpoints. ZDO status = %d", zdo_status);
}
}
/**
* @brief This is used when detecting endpoints
*
* @param zdo_status The zdo status defines what event just happened and is used to determine what to do
* @param ep_count Number of endpoints found on the network
* @param ed_id_list The list of endpoints' IDs
* @param user_ctx A pointer that contains the user defines additional information
*/
static void ep_cb(esp_zb_zdp_status_t zdo_status, uint8_t ep_count, uint8_t *ep_id_list, void *user_ctx)
{
ESP_LOGI("EPs", "Starting endpoints detection");
if (zdo_status == ESP_ZB_ZDP_STATUS_SUCCESS) {
ESP_LOGI("EPs", "Active endpoint response: status(%d) and endpoint count(%d)", zdo_status, ep_count);
for (int i = 0; i < ep_count; i++) {
ESP_LOGI("EPs", "Endpoint ID List: %d", ep_id_list);
/* get the node simple descriptor */
esp_zb_zdo_simple_desc_req_param_t simple_desc_req;
simple_desc_req.addr_of_interest = remote_zb_device.short_addr;
simple_desc_req.endpoint = ep_id_list;
esp_zb_zdo_simple_desc_req(&simple_desc_req, simple_desc_cb, NULL);
}
}
else {
ESP_LOGE("EPs", "We didn't find any endpoints. ZDO status = %d", zdo_status);
}
}
/**
* @brief Callback for a device joining or rejoining the network
*
* @param dev_annce_params Pointer to params given by the app signal handler
*/
void simple_gw_dev_annce_cb(esp_zb_zdo_signal_device_annce_params_t *dev_annce_params)
{
ESP_LOGI("DEVICE ANNOUNCED CB", "New device joined the network : Short address = %d, IEEE address = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, Capability = %d", dev_annce_params->device_short_addr, dev_annce_params->ieee_addr[7], dev_annce_params->ieee_addr[6], dev_annce_params->ieee_addr[5], dev_annce_params->ieee_addr[4], dev_annce_params->ieee_addr[3], dev_annce_params->ieee_addr[2], dev_annce_params->ieee_addr[1], dev_annce_params->ieee_addr[0], dev_annce_params->capability);
}
/**
* @brief This is used to descrbe remote zb user
*
* @param zdo_status The zdo status defines what event just happened and is used to determine what to do
* @param addr Address of the newly found user
* @param node_desc The description of
*
*/
static void user_find_cb(esp_zb_zdp_status_t zdo_status, uint16_t addr, esp_zb_af_node_desc_t *node_desc, void *user_ctx) {
if (zdo_status == ESP_ZB_ZDP_STATUS_SUCCESS) {
/* save into remote device record structure for future use */
remote_zb_device.short_addr = addr;
//ajout de ORE:
ESP_LOGI("USER", "Device found with short address: 0x%04x. Connection to the network is active.", addr);
/* find the active endpoint */
esp_zb_zdo_active_ep_req_param_t active_ep_req;
active_ep_req.addr_of_interest = remote_zb_device.short_addr;
esp_zb_zdo_active_ep_req(&active_ep_req, ep_cb, NULL);
/* get the device ieee address */
esp_zb_zdo_ieee_addr_req_param_t ieee_req;
ieee_req.addr_of_interest = remote_zb_device.short_addr;
ieee_req.dst_nwk_addr = remote_zb_device.short_addr;
ieee_req.request_type = 0;
ieee_req.start_index = 0;
esp_zb_zdo_ieee_addr_req(&ieee_req, ieee_cb, NULL); //ORE: warning
vTaskDelay(1000 / portTICK_PERIOD_MS);
} else {
ESP_LOGE("USER", "We didn't found any device. ZDO status = %d", zdo_status);
}
}
/**
* @brief This is the function that handle the application, it uses the state signal of the app to do different actions
*
* @param signal_struct The app signal tranmitted to the handler to decide wich action needs to be executed
*/
void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct)
{
uint32_t *p_sg_p = signal_struct->p_app_signal;
esp_err_t err_status = signal_struct->esp_err_status;
esp_zb_app_signal_type_t sig_type = *p_sg_p;
esp_zb_zdo_signal_leave_params_t *leave_params = NULL;
//ajout de trace par ORE:
ESP_LOGI("ZIGBEE_SIGNAL", "Received signal: %s (0x%x), status: %s", esp_zb_zdo_signal_to_string(sig_type), sig_type, esp_err_to_name(err_status)); //ORE: erreur
//fin ajout ORE
switch (sig_type) {
case ESP_ZB_BDB_SIGNAL_DEVICE_FIRST_START:
ESP_LOGI("SIGNAL", "First start : ZDO signal %s (Ox%x), status: %s\nStarting the BDB in network steering mode", esp_zb_zdo_signal_to_string(sig_type), sig_type, esp_err_to_name(err_status));
esp_zb_bdb_start_top_level_commissioning(ESP_ZB_BDB_MODE_NETWORK_STEERING);
break;
case ESP_ZB_BDB_SIGNAL_DEVICE_REBOOT:
ESP_LOGI("SIGNAL", "Device rebooted : ZDO signal %s (Ox%x), status: %s\nStarting the BDB in network steering mode", esp_zb_zdo_signal_to_string(sig_type), sig_type, esp_err_to_name(err_status));
esp_zb_bdb_start_top_level_commissioning(ESP_ZB_BDB_MODE_NETWORK_STEERING);
vTaskDelay(1000 / portTICK_PERIOD_MS);
break;
case ESP_ZB_BDB_SIGNAL_STEERING:
if (err_status != ESP_OK) {
ESP_LOGW("SIGNAL", "Network steering is going on but failing : %s status, steering", esp_err_to_name(err_status)); //ORE: erreur ici
esp_zb_scheduler_alarm((esp_zb_callback_t)bdb_start_top_level_commissioning_cb, ESP_ZB_BDB_MODE_NETWORK_STEERING, 5000); //ORE: 5000 au lieu de 1000
} else {
/* device auto start successfully and on a formed network */
esp_zb_ieee_addr_t extended_pan_id;
esp_zb_get_extended_pan_id(extended_pan_id);
ESP_LOGI("SIGNAL", "We've successfully join the network. (Extended PAN ID: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, PAN ID: 0x%04hx, Channel:%d, Short Address: 0x%04hx)",
extended_pan_id[7], extended_pan_id[6], extended_pan_id[5], extended_pan_id[4],
extended_pan_id[3], extended_pan_id[2], extended_pan_id[1], extended_pan_id[0],
esp_zb_get_pan_id(), esp_zb_get_current_channel(), esp_zb_get_short_address());
esp_zb_zdo_node_desc_req_param_t cmd_req;
cmd_req.dst_nwk_addr = 0x0000;
esp_zb_zdo_node_desc_req(&cmd_req, user_find_cb, NULL);
}
break;
case ESP_ZB_ZDO_SIGNAL_LEAVE:
leave_params = (esp_zb_zdo_signal_leave_params_t *)esp_zb_app_signal_get_params(p_sg_p);
if (leave_params->leave_type == ESP_ZB_NWK_LEAVE_TYPE_RESET) {
ESP_LOGI("SIGNAL", "You should reset the device");
}
break;
case ESP_ZB_NLME_STATUS_INDICATION:
break;
case ESP_ZB_ZDO_DEVICE_UNAVAILABLE: //ajout de Guillaume
ESP_LOGW("COUCOU", "COUCOU: %s (0x%x), status: %s", esp_zb_zdo_signal_to_string(sig_type), sig_type, esp_err_to_name(err_status));
break;
default:
ESP_LOGW("SIGNAL", "ZDO signal: %s (0x%x), status: %s", esp_zb_zdo_signal_to_string(sig_type), sig_type, esp_err_to_name(err_status));
break;
}
}
/**
* @brief This handles the attribut report message
*
* @param message The attribut message report
*
* @return ESP_OK Success - ESP_ERR_INVALID_ARG Received an incorrect message - ESP_FAIL Empty message
*/
static esp_err_t zb_attribute_reporting_handler(const esp_zb_zcl_report_attr_message_t *message)
{
ESP_RETURN_ON_FALSE(message, ESP_FAIL, "ATTR REPORT", "Empty message");
ESP_RETURN_ON_FALSE(message->status == ESP_ZB_ZCL_STATUS_SUCCESS, ESP_ERR_INVALID_ARG, "ATTR REPORT", "Received message: error status(%d)",
message->status);
ESP_LOGI("ATTR REPORT", "Received report from address(0x%x) src endpoint(%d) to dst endpoint(%d) cluster(0x%x)", message->src_address.u.short_addr,
message->src_endpoint, message->dst_endpoint, message->cluster);
ESP_LOGI("ATTR REPORT", "Received report information: attribute(0x%x), type(0x%x), value(%d)\n", message->attribute.id, message->attribute.data.type,
message->attribute.data.value ? *(uint8_t *)message->attribute.data.value : 0);
return ESP_OK;
}
/**
* @brief This handles the read attribut response
*
* @param message The attribut reading response message
*
* @return ESP_OK Success - ESP_ERR_INVALID_ARG Received an incorrect message - ESP_FAIL Empty message
*/
static esp_err_t zb_read_attr_resp_handler(const esp_zb_zcl_cmd_read_attr_resp_message_t *message)
{
ESP_RETURN_ON_FALSE(message, ESP_FAIL, "READ ATTR", "Empty message");
ESP_RETURN_ON_FALSE(message->info.status == ESP_ZB_ZCL_STATUS_SUCCESS, ESP_ERR_INVALID_ARG, "READ ATTR", "Received message: error status(%d)",
message->info.status);
esp_zb_zcl_read_attr_resp_variable_t *variable = message->variables;
while (variable) {
ESP_LOGI("READ ATTR", "Read attribute response: status(%d), cluster(0x%x), attribute(0x%x), type(0x%x), value(%d)", variable->status,
message->info.cluster, variable->attribute.id, variable->attribute.data.type,
variable->attribute.data.value ? *(uint8_t *)variable->attribute.data.value : 0);
variable = variable->next;
}
return ESP_OK;
}
/**
* @brief This handles the configure report response
*
* @param message The configure report message
*
* @return ESP_OK Success - ESP_ERR_INVALID_ARG Received an incorrect message - ESP_FAIL Empty message
*/
static esp_err_t zb_configure_report_resp_handler(const esp_zb_zcl_cmd_config_report_resp_message_t *message)
{
ESP_RETURN_ON_FALSE(message, ESP_FAIL, "CONF REPORT", "Empty message");
ESP_RETURN_ON_FALSE(message->info.status == ESP_ZB_ZCL_STATUS_SUCCESS, ESP_ERR_INVALID_ARG, "CONF REPORT", "Received message: error status(%d)",
message->info.status);
esp_zb_zcl_config_report_resp_variable_t *variable = message->variables;
while (variable) {
ESP_LOGI("CONF REPORT", "Configure report response: status(%d), cluster(0x%x), attribute(0x%x)", message->info.status, message->info.cluster,
variable->attribute_id);
variable = variable->next;
}
return ESP_OK;
}
/**
* @brief This handles actions callback
*
* @param callback_id The callback id corresponding to the action asked
* @param message The message corresponding to the callback id
*
* @return ESP_OK Success - ESP_ERR_INVALID_ARG Received an incorrect message - ESP_FAIL Empty message
*/
static esp_err_t zb_action_handler(esp_zb_core_action_callback_id_t callback_id, const void *message)
{
esp_err_t ret = ESP_OK;
switch (callback_id) {
case ESP_ZB_CORE_REPORT_ATTR_CB_ID:
ret = zb_attribute_reporting_handler((esp_zb_zcl_report_attr_message_t *)message);
break;
case ESP_ZB_CORE_CMD_READ_ATTR_RESP_CB_ID:
ret = zb_read_attr_resp_handler((esp_zb_zcl_cmd_read_attr_resp_message_t *)message);
break;
case ESP_ZB_CORE_CMD_REPORT_CONFIG_RESP_CB_ID:
ret = zb_configure_report_resp_handler((esp_zb_zcl_cmd_config_report_resp_message_t *)message);
break;
default:
ESP_LOGW("ACTION", "Receive Zigbee action(0x%x) callback", callback_id);
break;
}
return ret;
}
/**
* @brief The main zigbee task. Creates device, endpoints, clusters and attributs. Starts the main zigbee loop
*
* @param pvParameters Pointer that will be used as the parameter for the task being created
*
* @return ESP_OK Success - ESP_ERR_INVALID_ARG Received an incorrect message - ESP_FAIL Empty message
*/
static void esp_zb_task(void *pvParameters)
{
/* initialize Zigbee stack */
esp_zb_cfg_t zb_nwk_cfg = ESP_ZB_ZR_CONFIG();
esp_zb_init(&zb_nwk_cfg);
//ajout de ORE:
ESP_LOGI("ZIGBEE", "Channel 11 à 26");
esp_zb_set_primary_network_channel_set(0x07FFF800); // le dongle est sur le channel 20 Valid channel mask is from 0x00000800 (only channel 11) to 0x07FFF800 (all channels from 11 to 26)
// ajout de ORE: PAN_ID
esp_zb_set_pan_id(PAN_ID);
//ajout de ORE: verification mode router
esp_zb_nwk_device_type_t device_type = esp_zb_get_network_device_role();
if (device_type == ESP_ZB_DEVICE_TYPE_ROUTER)
ESP_LOGI("ZIGBEE", "ESP32 is in Router mode.");
//ajout de ORE: demander sa propre adresse:
esp_zb_zdo_ieee_addr_req_param_t ieee_req;
ieee_req.addr_of_interest = 0xFFFF; // Adresse de diffusion pour obtenir l'adresse
esp_zb_zdo_ieee_addr_req(&ieee_req, ieee_cb, NULL); //ORE:warning
/* Creation of a zigbee analog input cluster for temperature*/
esp_zb_analog_input_cluster_cfg_t analog_input_cluster_Temp;
analog_input_cluster_Temp.out_of_service = ESP_ZB_ZCL_ANALOG_INPUT_OUT_OF_SERVICE_DEFAULT_VALUE;
analog_input_cluster_Temp.status_flags = ESP_ZB_ZCL_ANALOG_INPUT_STATUS_FLAG_OVERRIDDEN;
analog_input_cluster_Temp.present_value = measured_temperature;
/* Creation of a zigbee analog input cluster for humidity*/
esp_zb_analog_input_cluster_cfg_t analog_input_cluster_hum;
analog_input_cluster_hum.out_of_service = ESP_ZB_ZCL_ANALOG_INPUT_OUT_OF_SERVICE_DEFAULT_VALUE;
analog_input_cluster_hum.status_flags = ESP_ZB_ZCL_ANALOG_INPUT_STATUS_FLAG_OVERRIDDEN;
analog_input_cluster_hum.present_value = measured_humidity;
/* Creation of a zigbee analog input cluster for voc*/
esp_zb_analog_input_cluster_cfg_t analog_input_cluster_voc;
analog_input_cluster_voc.out_of_service = ESP_ZB_ZCL_ANALOG_INPUT_OUT_OF_SERVICE_DEFAULT_VALUE;
analog_input_cluster_voc.status_flags = ESP_ZB_ZCL_ANALOG_INPUT_STATUS_FLAG_OVERRIDDEN;
analog_input_cluster_voc.present_value = measured_voc;
/* Creation of a zigbee analog input cluster for Co2*/
esp_zb_analog_input_cluster_cfg_t analog_input_cluster_co2;
analog_input_cluster_co2.out_of_service = ESP_ZB_ZCL_ANALOG_INPUT_OUT_OF_SERVICE_DEFAULT_VALUE;
analog_input_cluster_co2.status_flags = ESP_ZB_ZCL_ANALOG_INPUT_STATUS_FLAG_OVERRIDDEN;
analog_input_cluster_co2.present_value = measured_co2;
/* Creation of a zigbee analog input cluster for volume*/
esp_zb_analog_input_cluster_cfg_t analog_input_cluster_vol;
analog_input_cluster_vol.out_of_service = ESP_ZB_ZCL_ANALOG_INPUT_OUT_OF_SERVICE_DEFAULT_VALUE;
analog_input_cluster_vol.status_flags = ESP_ZB_ZCL_ANALOG_INPUT_STATUS_FLAG_OVERRIDDEN;
analog_input_cluster_vol.present_value = measured_volume;
/* Creation of a zigbee analog input cluster for pm 1.0*/
esp_zb_analog_input_cluster_cfg_t analog_input_cluster_pm1_0;
analog_input_cluster_pm1_0.out_of_service = ESP_ZB_ZCL_ANALOG_INPUT_OUT_OF_SERVICE_DEFAULT_VALUE;
analog_input_cluster_pm1_0.status_flags = ESP_ZB_ZCL_ANALOG_INPUT_STATUS_FLAG_OVERRIDDEN;
analog_input_cluster_pm1_0.present_value = measured_pm1_0;
/* Creation of a zigbee analog input cluster for pm 2.5*/
esp_zb_analog_input_cluster_cfg_t analog_input_cluster_pm2_5;
analog_input_cluster_pm2_5.out_of_service = ESP_ZB_ZCL_ANALOG_INPUT_OUT_OF_SERVICE_DEFAULT_VALUE;
analog_input_cluster_pm2_5.status_flags = ESP_ZB_ZCL_ANALOG_INPUT_STATUS_FLAG_OVERRIDDEN;
analog_input_cluster_pm2_5.present_value = measured_pm2_5;
/* Creation of a zigbee analog input cluster for pm 4.0*/
esp_zb_analog_input_cluster_cfg_t analog_input_cluster_pm4_0;
analog_input_cluster_pm4_0.out_of_service = ESP_ZB_ZCL_ANALOG_INPUT_OUT_OF_SERVICE_DEFAULT_VALUE;
analog_input_cluster_pm4_0.status_flags = ESP_ZB_ZCL_ANALOG_INPUT_STATUS_FLAG_OVERRIDDEN;
analog_input_cluster_pm4_0.present_value = measured_pm4_0;
/* Creation of a zigbee analog input cluster for pm 10.0*/
esp_zb_analog_input_cluster_cfg_t analog_input_cluster_pm10_0;
analog_input_cluster_pm10_0.out_of_service = ESP_ZB_ZCL_ANALOG_INPUT_OUT_OF_SERVICE_DEFAULT_VALUE;
analog_input_cluster_pm10_0.status_flags = ESP_ZB_ZCL_ANALOG_INPUT_STATUS_FLAG_OVERRIDDEN;
analog_input_cluster_pm10_0.present_value = measured_pm10_0;
esp_zb_ep_list_t *esp_zb_ep_list = esp_zb_ep_list_create();
/* Creation of an endpoint that contains the temperature analog input cluster*/
esp_zb_attribute_list_t *esp_zb_analog_input_cluster_temp = esp_zb_analog_input_cluster_create(&analog_input_cluster_Temp);
esp_zb_cluster_list_t *esp_zb_cluster_list_temp = esp_zb_zcl_cluster_list_create();
esp_zb_cluster_list_add_analog_input_cluster(esp_zb_cluster_list_temp, esp_zb_analog_input_cluster_temp, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);
esp_zb_endpoint_config_t endpoint_config_temp = {
.endpoint = ANALOG_INPUT_ENDPOINT_TEMP,
.app_profile_id = ESP_ZB_AF_HA_PROFILE_ID,
.app_device_id = ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID,
.app_device_version = 0
};
esp_zb_ep_list_add_ep(esp_zb_ep_list, esp_zb_cluster_list_temp, endpoint_config_temp);
/* Creation of an endpoint that contains the humidity analog input cluster*/
esp_zb_attribute_list_t *esp_zb_analog_input_cluster_hum = esp_zb_analog_input_cluster_create(&analog_input_cluster_hum);
esp_zb_cluster_list_t *esp_zb_cluster_list_hum = esp_zb_zcl_cluster_list_create();
esp_zb_cluster_list_add_analog_input_cluster(esp_zb_cluster_list_hum, esp_zb_analog_input_cluster_hum, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);
esp_zb_endpoint_config_t endpoint_config_hum = {
.endpoint = ANALOG_INPUT_ENDPOINT_HUM,
.app_profile_id = ESP_ZB_AF_HA_PROFILE_ID,
.app_device_id = ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID,
.app_device_version = 0
};
esp_zb_ep_list_add_ep(esp_zb_ep_list, esp_zb_cluster_list_hum, endpoint_config_hum);
/* Creation of an endpoint that contains the voc analog input cluster*/
esp_zb_attribute_list_t *esp_zb_analog_input_cluster_voc = esp_zb_analog_input_cluster_create(&analog_input_cluster_voc);
esp_zb_cluster_list_t *esp_zb_cluster_list_voc = esp_zb_zcl_cluster_list_create();
esp_zb_cluster_list_add_analog_input_cluster(esp_zb_cluster_list_voc, esp_zb_analog_input_cluster_voc, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);
esp_zb_endpoint_config_t endpoint_config_voc = {
.endpoint = ANALOG_INPUT_ENDPOINT_VOC,
.app_profile_id = ESP_ZB_AF_HA_PROFILE_ID,
.app_device_id = ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID,
.app_device_version = 0
};
esp_zb_ep_list_add_ep(esp_zb_ep_list, esp_zb_cluster_list_voc, endpoint_config_voc);
/* Creation of an endpoint that contains the Co2 analog input cluster*/
esp_zb_attribute_list_t *esp_zb_analog_input_cluster_co2 = esp_zb_analog_input_cluster_create(&analog_input_cluster_co2);
esp_zb_cluster_list_t *esp_zb_cluster_list_co2 = esp_zb_zcl_cluster_list_create();
esp_zb_cluster_list_add_analog_input_cluster(esp_zb_cluster_list_co2, esp_zb_analog_input_cluster_co2, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);
esp_zb_endpoint_config_t endpoint_config_co2 = {
.endpoint = ANALOG_INPUT_ENDPOINT_CO2,
.app_profile_id = ESP_ZB_AF_HA_PROFILE_ID,
.app_device_id = ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID,
.app_device_version = 0
};
esp_zb_ep_list_add_ep(esp_zb_ep_list, esp_zb_cluster_list_co2, endpoint_config_co2);
/* Creation of an endpoint that contains the volume analog input cluster*/
esp_zb_attribute_list_t *esp_zb_analog_input_cluster_vol = esp_zb_analog_input_cluster_create(&analog_input_cluster_vol);
esp_zb_cluster_list_t *esp_zb_cluster_list_vol = esp_zb_zcl_cluster_list_create();
esp_zb_cluster_list_add_analog_input_cluster(esp_zb_cluster_list_vol, esp_zb_analog_input_cluster_vol, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);
esp_zb_endpoint_config_t endpoint_config_vol = {
.endpoint = ANALOG_INPUT_ENDPOINT_VOL,
.app_profile_id = ESP_ZB_AF_HA_PROFILE_ID,
.app_device_id = ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID,
.app_device_version = 0
};
esp_zb_ep_list_add_ep(esp_zb_ep_list, esp_zb_cluster_list_vol, endpoint_config_vol);
/* Creation of an endpoint that contains the pm 1.0 analog input cluster*/
esp_zb_attribute_list_t *esp_zb_analog_input_cluster_pm1_0 = esp_zb_analog_input_cluster_create(&analog_input_cluster_pm1_0);
esp_zb_cluster_list_t *esp_zb_cluster_list_pm1_0 = esp_zb_zcl_cluster_list_create();
esp_zb_cluster_list_add_analog_input_cluster(esp_zb_cluster_list_pm1_0, esp_zb_analog_input_cluster_pm1_0, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);
esp_zb_endpoint_config_t endpoint_config_pm1_0 = {
.endpoint = ANALOG_INPUT_ENDPOINT_PM1_0,
.app_profile_id = ESP_ZB_AF_HA_PROFILE_ID,
.app_device_id = ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID,
.app_device_version = 0
};
esp_zb_ep_list_add_ep(esp_zb_ep_list, esp_zb_cluster_list_pm1_0, endpoint_config_pm1_0);
/* Creation of an endpoint that contains the pm 2.5 analog input cluster*/
esp_zb_attribute_list_t *esp_zb_analog_input_cluster_pm2_5 = esp_zb_analog_input_cluster_create(&analog_input_cluster_pm2_5);
esp_zb_cluster_list_t *esp_zb_cluster_list_pm2_5 = esp_zb_zcl_cluster_list_create();
esp_zb_cluster_list_add_analog_input_cluster(esp_zb_cluster_list_pm2_5, esp_zb_analog_input_cluster_pm2_5, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);
esp_zb_endpoint_config_t endpoint_config_pm2_5 = {
.endpoint = ANALOG_INPUT_ENDPOINT_PM2_5,
.app_profile_id = ESP_ZB_AF_HA_PROFILE_ID,
.app_device_id = ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID,
.app_device_version = 0
};
esp_zb_ep_list_add_ep(esp_zb_ep_list, esp_zb_cluster_list_pm2_5, endpoint_config_pm2_5);
/* Creation of an endpoint that contains the pm 4.0 analog input cluster*/
esp_zb_attribute_list_t *esp_zb_analog_input_cluster_pm4_0 = esp_zb_analog_input_cluster_create(&analog_input_cluster_pm4_0);
esp_zb_cluster_list_t *esp_zb_cluster_list_pm4_0 = esp_zb_zcl_cluster_list_create();
esp_zb_cluster_list_add_analog_input_cluster(esp_zb_cluster_list_pm4_0, esp_zb_analog_input_cluster_pm4_0, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);
esp_zb_endpoint_config_t endpoint_config_pm4_0 = {
.endpoint = ANALOG_INPUT_ENDPOINT_PM4_0,
.app_profile_id = ESP_ZB_AF_HA_PROFILE_ID,
.app_device_id = ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID,
.app_device_version = 0
};
esp_zb_ep_list_add_ep(esp_zb_ep_list, esp_zb_cluster_list_pm4_0, endpoint_config_pm4_0);
/* Creation of an endpoint that contains the pm 10.0 analog input cluster*/
esp_zb_attribute_list_t *esp_zb_analog_input_cluster_pm10_0 = esp_zb_analog_input_cluster_create(&analog_input_cluster_pm10_0);
esp_zb_cluster_list_t *esp_zb_cluster_list_pm10_0 = esp_zb_zcl_cluster_list_create();
esp_zb_cluster_list_add_analog_input_cluster(esp_zb_cluster_list_pm10_0, esp_zb_analog_input_cluster_pm10_0, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);
esp_zb_endpoint_config_t endpoint_config_pm10_0 = {
.endpoint = ANALOG_INPUT_ENDPOINT_PM10_0,
.app_profile_id = ESP_ZB_AF_HA_PROFILE_ID,
.app_device_id = ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID,
.app_device_version = 0
};
esp_zb_ep_list_add_ep(esp_zb_ep_list, esp_zb_cluster_list_pm10_0, endpoint_config_pm10_0);
/* Creation of a zigbee device*/
esp_zb_device_register(esp_zb_ep_list);
esp_zb_core_action_handler_register(zb_action_handler);
esp_zb_set_primary_network_channel_set(ESP_ZB_PRIMARY_CHANNEL_MASK);
esp_zb_set_secondary_network_channel_set(ESP_ZB_SECONDARY_CHANNEL_MASK);
ESP_ERROR_CHECK(esp_zb_start(true));
esp_zb_main_loop_iteration();
}
/**
* @brief Change the value in the attribut present_value in the analog input cluster in the endpoint specified
*
* @param value The new value measured by the sensor
* @param endpoint The endpoint that contains the sensor's cluster
*/
static void esp_app_sensor_handler(float value, uint8_t endpoint)
{
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_set_attribute_val(endpoint,
ESP_ZB_ZCL_CLUSTER_ID_ANALOG_INPUT, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE,
ESP_ZB_ZCL_ATTR_ANALOG_INPUT_PRESENT_VALUE_ID, &value, false);
esp_zb_lock_release();
}
/**
* @brief Changes values of all the sensors
*/
static void esp_zb_value_task(){
esp_zb_zdo_ieee_addr_req_param_t ieee_req;
ieee_req.addr_of_interest = remote_zb_device.short_addr;
ieee_req.dst_nwk_addr = remote_zb_device.short_addr;
ieee_req.request_type = 0;
ieee_req.start_index = 0;
while(1) {
esp_app_sensor_handler(measured_temperature, ANALOG_INPUT_ENDPOINT_TEMP);
esp_app_sensor_handler(measured_humidity, ANALOG_INPUT_ENDPOINT_HUM);
esp_app_sensor_handler(measured_voc, ANALOG_INPUT_ENDPOINT_VOC);
esp_app_sensor_handler(measured_co2, ANALOG_INPUT_ENDPOINT_CO2);
esp_app_sensor_handler(measured_volume, ANALOG_INPUT_ENDPOINT_VOL);
esp_app_sensor_handler(measured_pm1_0, ANALOG_INPUT_ENDPOINT_PM1_0);
esp_app_sensor_handler(measured_pm2_5, ANALOG_INPUT_ENDPOINT_PM2_5);
esp_app_sensor_handler(measured_pm4_0, ANALOG_INPUT_ENDPOINT_PM4_0);
esp_app_sensor_handler(measured_pm10_0, ANALOG_INPUT_ENDPOINT_PM10_0);
ESP_LOGI("Values", "\
\nTemperature : %.1f °C\t\tHumidity : %.0f %%\t\t\tVOC : %.0f ppb\
\nCO2 : %.0f ppm\t\t\tVolume : %.0f dB\t\t\tPM1.0 : %.1f µg/m³\
\nPM2.5 : %.1f µg/m³\t\tPM4.0 : %.1f µg/m³\t\tPM10.0 : %.1f µg/m³\
\nPM0.5 : %.1f part/cm³\t\tPM1.0 : %.1f part/cm³\t\tPM2.5 : %.1f part/cm³\
\nPM4.0 : %.1f part/cm³\t\tPM10. : %.1f part/cm³\t\tTyp. size : %.2f µm",
measured_temperature,
measured_humidity,
measured_voc, measured_co2,
measured_volume,
measured_pm1_0,
measured_pm2_5,
measured_pm4_0,
measured_pm10_0,
sen5x_dev.pm0p5_nbr,
sen5x_dev.pm1p0_nbr,
sen5x_dev.pm2p5_nbr,
sen5x_dev.pm4p0_nbr,
sen5x_dev.pm10p0_nbr,
sen5x_dev.typical_particul_size);
esp_zb_zdo_ieee_addr_req(&ieee_req, check_coordo_alive_cb, NULL);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
/**
* @brief Main function of the application. Starts automatically when the ESP boots
*/
void app_main(void)
{
/* Configuration of zigbee*/
esp_zb_platform_config_t config = {
.radio_config = ESP_ZB_DEFAULT_RADIO_CONFIG(),
.host_config = ESP_ZB_DEFAULT_HOST_CONFIG(),
};
ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_zb_platform_config(&config));
/* Starts the main zigbee task*/
ESP_LOGI("MAIN", "Zigbee is starting ...");
xTaskCreate(esp_zb_task, "Zigbee_main", 4096, NULL, 5, NULL);
/* setup of i2c*/
i2c_master_bus_config_t bus_config = {
.i2c_port = CONFIG_I2C_MASTER_PORT_NUM,
.sda_io_num = CONFIG_I2C_MASTER_SDA,
.scl_io_num = CONFIG_I2C_MASTER_SCL,
.clk_source = I2C_CLK_SRC_DEFAULT,
.flags.enable_internal_pullup = 1,
};
ESP_ERROR_CHECK(i2c_new_master_bus(&bus_config, &bus_mst_handle));
xTaskCreate(measurement_task, "Measurement task", 4096, NULL, 5, NULL);
vTaskDelay(16000 / portTICK_PERIOD_MS);
xTaskCreate(esp_zb_value_task, "Zigbee_measurement_task", 4096, NULL, 5, NULL);
}