Skip to content

Commit 393fbe8

Browse files
committed
examples: add minimal zigbee extender device example
Signed-off-by: adamhoof <adam.hofman1@gmail.com>
1 parent 3d86dd0 commit 393fbe8

File tree

13 files changed

+244
-0
lines changed

13 files changed

+244
-0
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# The following five lines of boilerplate have to be in your project's
2+
# CMakeLists in this exact order for cmake to work correctly
3+
cmake_minimum_required(VERSION 3.16)
4+
5+
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
6+
project(ZigbeeRouter)
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
| Supported Targets | ESP32-H2 | ESP32-C6 | ESP32-C5 |
2+
| ----------------- | -------- | -------- | -------- |
3+
4+
# Range Extender Example
5+
6+
This example demonstrates how to configure a Zigbee Range Extender device without any extra functionality.
7+
8+
## Hardware Required
9+
10+
* One 802.15.4 enabled development board (e.g., ESP32-H2, ESP32-C6 or ESP32-C5).
11+
12+
## Configure the project
13+
14+
Set the correct build target `idf.py set-target TARGET` command. If ie. building for ESP32 H2, command would be idf.py set-target esp32-h2.
15+
16+
## Erase the NVRAM
17+
18+
Erase any previous configurations and partition schemes by running `idf.py -p PORT erase-flash`. If only one device is connected, -p PORT might be omitted.
19+
20+
## Build and Flash
21+
22+
Build flash and monitor to view the serial output by running `idf.py -p PORT build flash monitor`. If only one device is connected, -p PORT might be omitted.
23+
24+
(To exit the serial monitor, type ``Ctrl-]``. On a different keyboard layout, it might be ie. ``Ctrl+AltGr+G``).
25+
26+
## Application Functions
27+
28+
- When the program starts, this router device will join already existing Zigbee network (make sure Coordinator is accepting new devices to join the network in HA).
29+
![HA Zigbee device addition button image](img.png)
30+
```
31+
I (233) main_task: Calling app_main()
32+
I (255) phy: phy_version: 323,2, a8ef10c, Aug 1 2025, 17:46:10
33+
I (257) phy: libbtbb version: 4515421, Aug 1 2025, 17:46:22
34+
I (260) main_task: Returned from app_main()
35+
I (307) ESP32_RANGE_EXTENDER: ZDO signal: ZDO Config Ready (0x17), status: ESP_FAIL
36+
I (308) ESP32_RANGE_EXTENDER: Zigbee stack initialized
37+
I (312) ESP32_RANGE_EXTENDER: Device started up in factory-reset mode
38+
I (312) ESP32_RANGE_EXTENDER: Start Network Steering
39+
I (3125) ESP32_RANGE_EXTENDER: ZDO signal: NWK Permit Join (0x36), status: ESP_OK
40+
I (3301) ESP32_RANGE_EXTENDER: ZDO signal: NWK Permit Join (0x36), status: ESP_OK
41+
I (3303) ESP32_RANGE_EXTENDER: Joined network successfully
42+
```
43+
44+
- Checkout HA Zigbee network if the device is successfully recognized and should be categorized as a router.
45+
![Zigbee network image - successful Zigbee Extender addition](img_2.png)
46+
47+
- Try to connect another device that would otherwise not be able to connect to the network (ie. too far). This extender should pick it up and serve as its parent node.
48+
- NOTE: Do not be discouraged if the HA network visualisation does not show the end device being connected to anything, important are the logs on our extender device that we have received a new child node.
49+
```
50+
I (18679) ESP32_RANGE_EXTENDER: ZDO signal: ZDO Device Update (0x30), status: ESP_OK
51+
I (18695) ESP32_RANGE_EXTENDER: ZDO signal: ZDO Device Announce (0x2), status: ESP_OK
52+
I (29273) ESP32_RANGE_EXTENDER: ZDO signal: NLME Status Indication (0x32), status: ESP_OK
53+
```
54+
![img_4.png](img_4.png)
55+
56+
57+
## Troubleshooting
58+
59+
Open an [issue](https://github.com/espressif/esp-zigbee-sdk/issues) on GitHub.
14.3 KB
Loading
21.8 KB
Loading
23.1 KB
Loading
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
idf_component_register(
2+
SRC_DIRS "."
3+
INCLUDE_DIRS "."
4+
PRIV_REQUIRES nvs_flash esp_driver_uart ieee802154
5+
)
6+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
## IDF Component Manager Manifest File
2+
dependencies:
3+
## Required IDF version
4+
idf:
5+
version: '>=5.3.2'
6+
espressif/esp-zigbee-lib: ^1.6.4
7+
espressif/esp-zboss-lib: ^1.6.4
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#include "esp_check.h"
2+
#include "esp_log.h"
3+
#include "nvs_flash.h"
4+
#include "freertos/FreeRTOS.h"
5+
#include "freertos/task.h"
6+
#include "esp_zigbee_core.h"
7+
#include "zigbee_config.h"
8+
#include "zigbee_task.h"
9+
10+
#if !defined ZB_ROUTER_ROLE
11+
#error Define ZB_ED_ROLE in idf.py menuconfig to compile light (End Device) source code.
12+
#endif
13+
14+
void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct) {
15+
uint32_t *p_sg_p = signal_struct->p_app_signal;
16+
esp_err_t err_status = signal_struct->esp_err_status;
17+
esp_zb_app_signal_type_t sig_type = *p_sg_p;
18+
19+
switch (sig_type) {
20+
case ESP_ZB_ZDO_SIGNAL_SKIP_STARTUP:
21+
ESP_LOGI(TAG, "Zigbee stack initialized");
22+
esp_zb_bdb_start_top_level_commissioning(ESP_ZB_BDB_MODE_INITIALIZATION);
23+
break;
24+
25+
case ESP_ZB_BDB_SIGNAL_DEVICE_FIRST_START:
26+
case ESP_ZB_BDB_SIGNAL_DEVICE_REBOOT:
27+
if (err_status == ESP_OK) {
28+
ESP_LOGI(TAG, "Device started up in %s factory-reset mode", esp_zb_bdb_is_factory_new()? "" : "non");
29+
if (esp_zb_bdb_is_factory_new()) {
30+
ESP_LOGI(TAG, "Start Network Steering");
31+
esp_zb_bdb_start_top_level_commissioning(ESP_ZB_BDB_MODE_NETWORK_STEERING);
32+
} else {
33+
ESP_LOGI(TAG, "Device restarted");
34+
}
35+
} else {
36+
ESP_LOGW(TAG, "Failed to initialize Zigbee stack (status: %s)", esp_err_to_name(err_status));
37+
}
38+
break;
39+
40+
case ESP_ZB_BDB_SIGNAL_STEERING:
41+
if (err_status == ESP_OK) {
42+
ESP_LOGI(TAG, "Joined network successfully");
43+
} else {
44+
ESP_LOGI(TAG, "Network steering was not successful (status: %s)", esp_err_to_name(err_status));
45+
esp_zb_scheduler_alarm((esp_zb_callback_t) esp_zb_bdb_start_top_level_commissioning,
46+
ESP_ZB_BDB_MODE_NETWORK_STEERING, 1000);
47+
}
48+
break;
49+
50+
default:
51+
ESP_LOGI(TAG, "ZDO signal: %s (0x%x), status: %s", esp_zb_zdo_signal_to_string(sig_type), sig_type,
52+
esp_err_to_name(err_status));
53+
break;
54+
}
55+
}
56+
57+
void app_main(void) {
58+
esp_zb_platform_config_t config = {
59+
.radio_config = ESP_ZB_DEFAULT_RADIO_CONFIG(),
60+
.host_config = ESP_ZB_DEFAULT_HOST_CONFIG(),
61+
};
62+
ESP_ERROR_CHECK(nvs_flash_init());
63+
ESP_ERROR_CHECK(esp_zb_platform_config(&config));
64+
xTaskCreate(esp_zb_task, "Zigbee_main", 4096, NULL, 5, NULL);
65+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#pragma once
2+
3+
static const char *TAG = "ESP32_RANGE_EXTENDER";
4+
5+
#define ESP_ZB_DEFAULT_RADIO_CONFIG() \
6+
{ \
7+
.radio_mode = ZB_RADIO_MODE_NATIVE, \
8+
}
9+
#define ESP_ZB_DEFAULT_HOST_CONFIG() \
10+
{ \
11+
.host_connection_mode = ZB_HOST_CONNECTION_MODE_NONE, \
12+
}
13+
14+
#define ESP_ZB_ZR_CONFIG() \
15+
{ \
16+
.esp_zb_role = ESP_ZB_DEVICE_TYPE_ROUTER, \
17+
.install_code_policy = false, \
18+
.nwk_cfg.zczr_cfg = { \
19+
.max_children = 10, \
20+
}, \
21+
}
22+
23+
#define ESP_ZP_EP_CONFIG() \
24+
{ \
25+
.endpoint = 1, \
26+
.app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, \
27+
.app_device_id = ESP_ZB_HA_RANGE_EXTENDER_DEVICE_ID, \
28+
.app_device_version = 0 \
29+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#include "zigbee_task.h"
2+
#include "esp_zigbee_core.h"
3+
#include "zigbee_config.h"
4+
5+
void esp_zb_task(void *pvParameters) {
6+
esp_zb_cfg_t zb_nwk_cfg = ESP_ZB_ZR_CONFIG();
7+
8+
esp_zb_init(&zb_nwk_cfg);
9+
10+
esp_zb_cluster_list_t *cluster_list = esp_zb_zcl_cluster_list_create();
11+
12+
esp_zb_attribute_list_t *basic_cluster = esp_zb_basic_cluster_create(NULL);
13+
esp_zb_cluster_list_add_basic_cluster(cluster_list, basic_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
14+
15+
esp_zb_attribute_list_t *identify_cluster = esp_zb_identify_cluster_create(NULL);
16+
esp_zb_cluster_list_add_identify_cluster(cluster_list, identify_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
17+
18+
esp_zb_ep_list_t *ep_list = esp_zb_ep_list_create();
19+
20+
esp_zb_endpoint_config_t endpoint_config = ESP_ZP_EP_CONFIG();
21+
22+
esp_zb_ep_list_add_ep(ep_list, cluster_list, endpoint_config);
23+
24+
esp_zb_device_register(ep_list);
25+
26+
esp_zb_set_primary_network_channel_set(ESP_ZB_TRANSCEIVER_ALL_CHANNELS_MASK);
27+
28+
ESP_ERROR_CHECK(esp_zb_start(false));
29+
30+
esp_zb_stack_main_loop();
31+
}

0 commit comments

Comments
 (0)