mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Zigbee: Update Zigbee examples for the latest library
* support new API function * support esp-zboss-lib>=0.1.2, support esp-zigbee-lib>=0.2.0
This commit is contained in:
parent
e0580d2669
commit
717a3acdb6
@ -3,8 +3,6 @@
|
||||
|
||||
# Gateway Example
|
||||
|
||||
(See the `README.md` file in the upper level 'examples' directory for more information about examples.)
|
||||
|
||||
This example demonstrates how to build a Zigbee Gateway device. It runs on a Wi-Fi SoC such as ESP32, ESP32-C3 and ESP32-S3, with an 802.15.4 SoC like ESP32-H2 running [esp_zigbee_rcp](../esp_zigbee_rcp) to provide 802.15.4 radio.
|
||||
|
||||
## Hardware Required
|
||||
@ -29,6 +27,10 @@ ESP32 pin | ESP32-H2 pin
|
||||
|
||||
Before project configuration and build, make sure to set the correct chip target using `idf.py set-target esp32` or `idf.py set-target esp32s3`
|
||||
|
||||
## Erase the NVRAM
|
||||
|
||||
Before flash it to the board, it is recommended to erase NVRAM if user doesn't want to keep the previous examples or other projects stored info using `idf.py -p PORT erase-flash`
|
||||
|
||||
## Build and Flash
|
||||
|
||||
Build the project, flash it to the board, and start the monitor tool to view the serial output by running `idf.py -p PORT flash monitor`
|
||||
@ -40,13 +42,13 @@ Build the project, flash it to the board, and start the monitor tool to view the
|
||||
As you run the example, you will see the following log:
|
||||
|
||||
esp_zigbee_gateway:
|
||||
I (660) ESP_ZB_GATEWAY: status: -1
|
||||
I (670) ESP_ZB_GATEWAY: Zigbee stack initialized
|
||||
I (680) ESP_ZB_GATEWAY: Zigbee rcp device booted
|
||||
I (1280) ESP_ZB_GATEWAY: Start network formation
|
||||
I (3060) ESP_ZB_GATEWAY: Formed network successfully (ieee extended address: f9:54:2d:01:a0:03:f7:84, PAN ID: 0x8651)
|
||||
I (4060) ESP_ZB_GATEWAY: status: 0
|
||||
I (4400) ESP_ZB_GATEWAY: Network steering started
|
||||
I (660) ESP_ZB_GATEWAY: status: -1
|
||||
I (670) ESP_ZB_GATEWAY: Zigbee stack initialized
|
||||
I (680) ESP_ZB_GATEWAY: Zigbee rcp device booted
|
||||
I (1280) ESP_ZB_GATEWAY: Start network formation
|
||||
I (3060) ESP_ZB_GATEWAY: Formed network successfully (ieee extended address: f9:54:2d:01:a0:03:f7:84, PAN ID: 0x8651)
|
||||
I (4060) ESP_ZB_GATEWAY: status: 0
|
||||
I (4400) ESP_ZB_GATEWAY: Network steering started
|
||||
|
||||
## Gateway Functions
|
||||
|
||||
|
@ -41,80 +41,67 @@
|
||||
#include "esp_zigbee_gateway.h"
|
||||
|
||||
#if (!defined ZB_MACSPLIT_HOST && defined ZB_MACSPLIT_DEVICE)
|
||||
#error Only Zigbee gateway hostdevice should be defined
|
||||
#error Only Zigbee gateway host device should be defined
|
||||
#endif
|
||||
|
||||
static const char *TAG = "ESP_ZB_GATEWAY";
|
||||
|
||||
/********************* Define functions **************************/
|
||||
static void bdb_start_top_level_commissioning_cb(zb_uint8_t mode_mask)
|
||||
static void bdb_start_top_level_commissioning_cb(uint8_t mode_mask)
|
||||
{
|
||||
if (!bdb_start_top_level_commissioning(mode_mask)) {
|
||||
ESP_LOGE(TAG, "In BDB commissioning, an error occurred (for example: the device has already been running)");
|
||||
}
|
||||
ESP_ERROR_CHECK(esp_zb_bdb_start_top_level_commissioning(mode_mask));
|
||||
}
|
||||
|
||||
void zboss_signal_handler(zb_bufid_t bufid)
|
||||
void zboss_signal_handler(uint8_t bufid)
|
||||
{
|
||||
zb_zdo_app_signal_hdr_t *p_sg_p = NULL;
|
||||
zb_zdo_app_signal_type_t sig = zb_get_app_signal(bufid, &p_sg_p);
|
||||
zb_ret_t status = ZB_GET_APP_SIGNAL_STATUS(bufid);
|
||||
zb_zdo_signal_device_annce_params_t *dev_annce_params = NULL;
|
||||
zb_zdo_signal_macsplit_dev_boot_params_t *rcp_version = NULL;
|
||||
zb_uint32_t gateway_version;
|
||||
|
||||
switch (sig) {
|
||||
case ZB_ZDO_SIGNAL_SKIP_STARTUP:
|
||||
ESP_LOGI(TAG, "Zigbee stack initialized");
|
||||
bdb_start_top_level_commissioning(ZB_BDB_INITIALIZATION);
|
||||
esp_zb_bdb_start_top_level_commissioning(ZB_BDB_INITIALIZATION);
|
||||
break;
|
||||
|
||||
case ZB_MACSPLIT_DEVICE_BOOT:
|
||||
ESP_LOGI(TAG, "Zigbee rcp device booted");
|
||||
gateway_version = zb_esp_macsplit_get_version();
|
||||
rcp_version = ZB_ZDO_SIGNAL_GET_PARAMS(p_sg_p, zb_zdo_signal_macsplit_dev_boot_params_t);
|
||||
ESP_LOGI(TAG, "Zigbee rcp device version: %d.%d.%d", (rcp_version->dev_version >> 24 & 0x000000FF), (rcp_version->dev_version >> 16 & 0x000000FF), (rcp_version->dev_version & 0x000000FF));
|
||||
ESP_LOGI(TAG, "Zigbee gateway version: %d.%d.%d", (gateway_version >> 24 & 0x000000FF), (gateway_version >> 16 & 0x000000FF), (gateway_version & 0x000000FF));
|
||||
if (gateway_version != rcp_version->dev_version) {
|
||||
ESP_LOGE(TAG, "rcp has different Zigbee stack version with Zigbee gateway! Please check the rcp software or other issues");
|
||||
}
|
||||
ESP_LOGI(TAG, "Running RCP Version:%s", rcp_version->version_str);
|
||||
break;
|
||||
|
||||
case ZB_BDB_SIGNAL_DEVICE_FIRST_START:
|
||||
case ZB_BDB_SIGNAL_DEVICE_REBOOT:
|
||||
if (status == RET_OK) {
|
||||
ESP_LOGI(TAG, "Start network formation");
|
||||
bdb_start_top_level_commissioning(ZB_BDB_NETWORK_FORMATION);
|
||||
esp_zb_bdb_start_top_level_commissioning(ZB_BDB_NETWORK_FORMATION);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to initialize Zigbee stack (status: %d)", status);
|
||||
}
|
||||
break;
|
||||
|
||||
case ZB_BDB_SIGNAL_FORMATION:
|
||||
if (status == RET_OK) {
|
||||
zb_ieee_addr_t ieee_address;
|
||||
zb_get_long_address(ieee_address);
|
||||
esp_zb_get_long_address(ieee_address);
|
||||
ESP_LOGI(TAG, "Formed network successfully (ieee extended address: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, PAN ID: 0x%04hx)",
|
||||
ieee_address[7], ieee_address[6], ieee_address[5], ieee_address[4],
|
||||
ieee_address[3], ieee_address[2], ieee_address[1], ieee_address[0],
|
||||
ZB_PIBCACHE_PAN_ID());
|
||||
bdb_start_top_level_commissioning(ZB_BDB_NETWORK_STEERING);
|
||||
esp_zb_bdb_start_top_level_commissioning(ZB_BDB_NETWORK_STEERING);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Restart network formation (status: %d)", status);
|
||||
ZB_SCHEDULE_APP_ALARM((zb_callback_t)bdb_start_top_level_commissioning_cb, ZB_BDB_NETWORK_FORMATION, ZB_TIME_ONE_SECOND);
|
||||
}
|
||||
break;
|
||||
|
||||
case ZB_BDB_SIGNAL_STEERING:
|
||||
if (status == RET_OK) {
|
||||
ESP_LOGI(TAG, "Network steering started");
|
||||
}
|
||||
break;
|
||||
|
||||
case ZB_ZDO_SIGNAL_DEVICE_ANNCE:
|
||||
dev_annce_params = ZB_ZDO_SIGNAL_GET_PARAMS(p_sg_p, zb_zdo_signal_device_annce_params_t);
|
||||
ESP_LOGI(TAG, "New device commissioned or rejoined (short: 0x%04hx)", dev_annce_params->device_short_addr);
|
||||
break;
|
||||
|
||||
default:
|
||||
ESP_LOGI(TAG, "status: %d", status);
|
||||
break;
|
||||
@ -125,26 +112,23 @@ void zboss_signal_handler(zb_bufid_t bufid)
|
||||
}
|
||||
}
|
||||
|
||||
static void zboss_task(void *pvParameters)
|
||||
static void esp_zb_task(void *pvParameters)
|
||||
{
|
||||
ZB_INIT("zigbee gateway");
|
||||
zb_set_network_coordinator_role(IEEE_CHANNEL_MASK);
|
||||
zb_set_nvram_erase_at_start(ERASE_PERSISTENT_CONFIG);
|
||||
zb_set_max_children(MAX_CHILDREN);
|
||||
/* initialize Zigbee stack with Zigbee coordinator config */
|
||||
esp_zb_cfg_t zb_nwk_cfg = ESP_ZB_ZC_CONFIG();
|
||||
esp_zb_init(&zb_nwk_cfg);
|
||||
/* initiate Zigbee Stack start without zb_send_no_autostart_signal auto-start */
|
||||
ESP_ERROR_CHECK(zboss_start_no_autostart());
|
||||
while (1) {
|
||||
zboss_main_loop_iteration();
|
||||
}
|
||||
ESP_ERROR_CHECK(esp_zb_start(false));
|
||||
esp_zb_main_loop_iteration();
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
zb_esp_platform_config_t config = {
|
||||
.radio_config = ZB_ESP_DEFAULT_RADIO_CONFIG(),
|
||||
.host_config = ZB_ESP_DEFAULT_HOST_CONFIG(),
|
||||
esp_zb_platform_config_t config = {
|
||||
.radio_config = ESP_ZB_DEFAULT_RADIO_CONFIG(),
|
||||
.host_config = ESP_ZB_DEFAULT_HOST_CONFIG(),
|
||||
};
|
||||
/* load Zigbee gateway platform config to initialization */
|
||||
ESP_ERROR_CHECK(zb_esp_platform_config(&config));
|
||||
xTaskCreate(zboss_task, "zboss_main", 4096, NULL, 5, NULL);
|
||||
ESP_ERROR_CHECK(esp_zb_platform_config(&config));
|
||||
xTaskCreate(esp_zb_task, "Zigbee_main", 4096, NULL, 5, NULL);
|
||||
}
|
||||
|
@ -36,14 +36,21 @@
|
||||
*/
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "zboss_api.h"
|
||||
#include "esp_zigbee_core.h"
|
||||
|
||||
/* Zigbee Configuration */
|
||||
#define IEEE_CHANNEL_MASK (1l << 13) /* ZigBee default setting is channel 13 for light example usage */
|
||||
#define ERASE_PERSISTENT_CONFIG ZB_TRUE /* erase network devices before running example */
|
||||
#define MAX_CHILDREN 10 /* the max amount of connected devices */
|
||||
#define INSTALLCODE_POLICY_ENABLE false /* enable the install code policy for security */
|
||||
|
||||
#define ZB_ESP_DEFAULT_RADIO_CONFIG() \
|
||||
#define ESP_ZB_ZC_CONFIG() \
|
||||
{ \
|
||||
.esp_zb_role = ESP_ZB_DEVICE_TYPE_COORDINATOR, \
|
||||
.install_code_policy = INSTALLCODE_POLICY_ENABLE, \
|
||||
.nwk_cfg.zczr_cfg = { \
|
||||
.max_children = MAX_CHILDREN, \
|
||||
}, \
|
||||
}
|
||||
#define ESP_ZB_DEFAULT_RADIO_CONFIG() \
|
||||
{ \
|
||||
.radio_mode = RADIO_MODE_UART_RCP, \
|
||||
.radio_uart_config = { \
|
||||
@ -63,7 +70,7 @@
|
||||
}, \
|
||||
}
|
||||
|
||||
#define ZB_ESP_DEFAULT_HOST_CONFIG() \
|
||||
#define ESP_ZB_DEFAULT_HOST_CONFIG() \
|
||||
{ \
|
||||
.host_connection_mode = HOST_CONNECTION_MODE_NONE, \
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
## IDF Component Manager Manifest File
|
||||
dependencies:
|
||||
espressif/esp-zboss-lib: "~0.0.4"
|
||||
espressif/esp-zboss-lib: "~0.1.0"
|
||||
espressif/esp-zigbee-lib: "~0.2.0"
|
||||
## Required IDF version
|
||||
idf:
|
||||
version: ">=5.0.0"
|
||||
|
@ -3,4 +3,5 @@
|
||||
nvs, data, nvs, 0x9000, 0x6000,
|
||||
phy_init, data, phy, 0xf000, 0x1000,
|
||||
factory, app, factory, 0x10000, 1M,
|
||||
zb_storage, data, fat, , 128K,
|
||||
zb_storage, data, fat, 0x110000, 128K,
|
||||
zb_fct, data, fat, 0x130000, 1K,
|
||||
|
|
@ -3,8 +3,6 @@
|
||||
|
||||
# Rcp Example
|
||||
|
||||
(See the `README.md` file in the upper level 'examples' directory for more information about examples.)
|
||||
|
||||
This test code shows how to configure Zigbee rcp (radio co-processor) device. Rcp doesn't function alone, it needs to work together with Zigbee gateway (see [esp_zigbee_gateway example](../esp_zigbee_gateway))
|
||||
|
||||
## Hardware Required
|
||||
@ -18,6 +16,10 @@ This test code shows how to configure Zigbee rcp (radio co-processor) device. Rc
|
||||
|
||||
Before project configuration and build, make sure to set the correct chip target using `idf.py --preview set-target esp32h2`
|
||||
|
||||
## Erase the NVRAM
|
||||
|
||||
Before flash it to the board, it is recommended to erase NVRAM if user doesn't want to keep the previous examples or other projects stored info using `idf.py -p PORT erase-flash`
|
||||
|
||||
## Build and Flash
|
||||
|
||||
Build the project, flash it to the board by running `idf.py -p <PORT> build flash`
|
||||
|
@ -46,7 +46,7 @@
|
||||
#endif
|
||||
static const char *TAG = "ESP_ZB_RCP";
|
||||
|
||||
void zboss_signal_handler(zb_bufid_t bufid)
|
||||
void zboss_signal_handler(uint8_t bufid)
|
||||
{
|
||||
zb_zdo_app_signal_hdr_t *sg_p = NULL;
|
||||
/* get application signal from the buffer */
|
||||
@ -72,7 +72,7 @@ void zboss_signal_handler(zb_bufid_t bufid)
|
||||
}
|
||||
}
|
||||
|
||||
static void zboss_task(void * pvParameters)
|
||||
static void esp_zb_task(void * pvParameters)
|
||||
{
|
||||
ZB_INIT("esp_zigbee_rcp");
|
||||
while (1) {
|
||||
@ -82,11 +82,12 @@ static void zboss_task(void * pvParameters)
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
zb_esp_platform_config_t config = {
|
||||
.radio_config = ZB_ESP_DEFAULT_RADIO_CONFIG(),
|
||||
.host_config = ZB_ESP_DEFAULT_HOST_CONFIG(),
|
||||
esp_zb_platform_config_t config = {
|
||||
.radio_config = ESP_ZB_DEFAULT_RADIO_CONFIG(),
|
||||
.host_config = ESP_ZB_DEFAULT_HOST_CONFIG(),
|
||||
};
|
||||
/* load Zigbee rcp platform config to initialization */
|
||||
ESP_ERROR_CHECK(zb_esp_platform_config(&config));
|
||||
xTaskCreate(zboss_task, "zboss_main", 4096, NULL, 5, NULL);
|
||||
esp_zb_macsplit_set_version(RCP_COMPILE_DEFINE);
|
||||
ESP_ERROR_CHECK(esp_zb_platform_config(&config));
|
||||
xTaskCreate(esp_zb_task, "Zigbee_main", 4096, NULL, 5, NULL);
|
||||
}
|
||||
|
@ -34,15 +34,14 @@
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "zboss_api.h"
|
||||
|
||||
#define ZB_ESP_DEFAULT_RADIO_CONFIG() \
|
||||
#define ESP_ZB_DEFAULT_RADIO_CONFIG() \
|
||||
{ \
|
||||
.radio_mode = RADIO_MODE_NATIVE, \
|
||||
}
|
||||
|
||||
#define ZB_ESP_DEFAULT_HOST_CONFIG() \
|
||||
#define ESP_ZB_DEFAULT_HOST_CONFIG() \
|
||||
{ \
|
||||
.host_connection_mode = HOST_CONNECTION_MODE_RCP_UART, \
|
||||
.host_uart_config = { \
|
||||
|
@ -1,6 +1,6 @@
|
||||
## IDF Component Manager Manifest File
|
||||
dependencies:
|
||||
espressif/esp-zboss-lib: "~0.0.4"
|
||||
espressif/esp-zboss-lib: "~0.1.0"
|
||||
## Required IDF version
|
||||
idf:
|
||||
version: ">=5.0.0"
|
||||
|
@ -15,6 +15,5 @@ CONFIG_PARTITION_TABLE_MD5=y
|
||||
#
|
||||
CONFIG_ZB_ENABLED=y
|
||||
CONFIG_ZB_RCP=y
|
||||
CONFIG_ZB_CONSOLE_UART_BAUDRATE=115200
|
||||
# end of ZBOSS Source
|
||||
# end of Component config
|
||||
|
@ -3,20 +3,22 @@
|
||||
|
||||
# Light Bulb Example
|
||||
|
||||
(See the `README.md` file in the upper level 'examples' directory for more information about examples.)
|
||||
|
||||
This test code shows how to configure Zigbee end device and use it as a light bulb
|
||||
This test code shows how to configure Zigbee end device and use it as HA on/off light bulb
|
||||
|
||||
## Hardware Required
|
||||
|
||||
* One development board with ESP32-H2 SoC acting as Zigbee end device (loaded with light bulb example)
|
||||
* One development board with ESP32-H2 SoC acting as Zigbee end device (loaded with HA_on_off_light example)
|
||||
* A USB cable for power supply and programming
|
||||
* Choose another ESP32-H2 as Zigbee coordinator (see [light switch example](../light_switch))
|
||||
* Choose another ESP32-H2 as Zigbee coordinator (see [HA_on_off_switch example](../HA_on_off_switch))
|
||||
|
||||
## Configure the project
|
||||
|
||||
Before project configuration and build, make sure to set the correct chip target using `idf.py set-target esp32h2`.
|
||||
|
||||
## Erase the NVRAM
|
||||
|
||||
Before flash it to the board, it is recommended to erase NVRAM if user doesn't want to keep the previous examples or other projects stored info using `idf.py -p PORT erase-flash`
|
||||
|
||||
## Build and Flash
|
||||
|
||||
Build the project, flash it to the board, and start the monitor tool to view the serial output by running `idf.py -p PORT flash monitor`.
|
||||
@ -28,20 +30,20 @@ Build the project, flash it to the board, and start the monitor tool to view the
|
||||
As you run the example, you will see the following log:
|
||||
|
||||
light bulb:
|
||||
I (918) ESP_ZB_LIGHT: status: 255
|
||||
I (901) ESP_ZB_LIGHT: Zigbee stack initialized
|
||||
I (901) ESP_ZB_LIGHT: Start network steering
|
||||
I (2611) ESP_ZB_LIGHT: Joined network successfully (Extended PAN ID: aa:98:48:01:a0:03:f7:84, PAN ID: 0x0e8b)
|
||||
I (5651) ESP_ZB_LIGHT: on/off attribute setting to 1
|
||||
I (6631) ESP_ZB_LIGHT: on/off attribute setting to 0
|
||||
I (7331) ESP_ZB_LIGHT: on/off attribute setting to 1
|
||||
I (8251) ESP_ZB_LIGHT: on/off attribute setting to 0
|
||||
I (9111) ESP_ZB_LIGHT: on/off attribute setting to 1
|
||||
I (9671) ESP_ZB_LIGHT: on/off attribute setting to 0
|
||||
I (918) ESP_ZB_LIGHT: status: 255
|
||||
I (901) ESP_ZB_LIGHT: Zigbee stack initialized
|
||||
I (901) ESP_ZB_LIGHT: Start network steering
|
||||
I (2611) ESP_ZB_LIGHT: Joined network successfully (Extended PAN ID: aa:98:48:01:a0:03:f7:84, PAN ID: 0x0e8b)
|
||||
I (5651) ESP_ZB_LIGHT: on/off light set to 1
|
||||
I (6631) ESP_ZB_LIGHT: on/off light set to 0
|
||||
I (7331) ESP_ZB_LIGHT: on/off light set to 1
|
||||
I (8251) ESP_ZB_LIGHT: on/off light set to 0
|
||||
I (9111) ESP_ZB_LIGHT: on/off light set to 1
|
||||
I (9671) ESP_ZB_LIGHT: on/off light set to 0
|
||||
|
||||
## Light Control Functions
|
||||
|
||||
* By toggling the switch button (BOOT) on the ESP32-H2 board loaded with the `light switch` example, the LED on this board loaded with `light bulb` example will be on and off.
|
||||
* By toggling the switch button (BOOT) on the ESP32-H2 board loaded with the `HA_on_off_switch` example, the LED on this board loaded with `HA_on_off_light` example will be on and off.
|
||||
|
||||
## Troubleshooting
|
||||
|
144
examples/zigbee/light_sample/HA_on_off_light/main/esp_zb_light.c
Normal file
144
examples/zigbee/light_sample/HA_on_off_light/main/esp_zb_light.c
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Espressif Systems (Shanghai) CO LTD
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Espressif Systems
|
||||
* integrated circuit in a product or a software update for such product,
|
||||
* must reproduce the above copyright notice, this list of conditions and
|
||||
* the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* 4. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_zigbee_ha_standard.h"
|
||||
#include "esp_zb_light.h"
|
||||
|
||||
/**
|
||||
* @note Make sure set idf.py menuconfig in zigbee component as zigbee end device!
|
||||
*/
|
||||
#if !defined ZB_ED_ROLE
|
||||
#error Define ZB_ED_ROLE in idf.py menuconfig to compile light (End Device) source code.
|
||||
#endif
|
||||
|
||||
static const char *TAG = "ESP_ZB_ON_OFF_LIGHT";
|
||||
/********************* Define functions **************************/
|
||||
static void bdb_start_top_level_commissioning_cb(uint8_t mode_mask)
|
||||
{
|
||||
ESP_ERROR_CHECK(esp_zb_bdb_start_top_level_commissioning(mode_mask));
|
||||
}
|
||||
|
||||
void attr_cb(uint8_t status, uint8_t endpoint, uint16_t cluster_id, uint16_t attr_id, void *new_value)
|
||||
{
|
||||
if (cluster_id == ZB_ZCL_CLUSTER_ID_ON_OFF) {
|
||||
uint8_t value = *(uint8_t*)new_value;
|
||||
if (attr_id == ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID) {
|
||||
/* implemented light on/off control */
|
||||
ESP_LOGI(TAG, "on/off light set to %hd", value);
|
||||
light_driver_set_power((bool)value);
|
||||
}
|
||||
} else {
|
||||
/* Implement some actions if needed when other cluster changed */
|
||||
ESP_LOGI(TAG, "cluster:0x%x, attribute:0x%x changed ", cluster_id, attr_id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Zigbee stack event signal handler.
|
||||
*
|
||||
* @param bufid Zigbee stack buffer id used to pass signal.
|
||||
*/
|
||||
void zboss_signal_handler(uint8_t bufid)
|
||||
{
|
||||
zb_uint8_t status = ZB_GET_APP_SIGNAL_STATUS(bufid);
|
||||
zb_zdo_app_signal_type_t sig = zb_get_app_signal(bufid, NULL);
|
||||
|
||||
switch (sig) {
|
||||
case ZB_ZDO_SIGNAL_SKIP_STARTUP:
|
||||
ESP_LOGI(TAG, "Zigbee stack initialized");
|
||||
esp_zb_bdb_start_top_level_commissioning(ZB_BDB_INITIALIZATION);
|
||||
break;
|
||||
case ZB_BDB_SIGNAL_DEVICE_FIRST_START:
|
||||
case ZB_BDB_SIGNAL_DEVICE_REBOOT:
|
||||
if (status == RET_OK) {
|
||||
ESP_LOGI(TAG, "Start network steering");
|
||||
esp_zb_bdb_start_top_level_commissioning(ZB_BDB_NETWORK_STEERING);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to initialize Zigbee stack (status: %d)", status);
|
||||
}
|
||||
break;
|
||||
case ZB_BDB_SIGNAL_STEERING:
|
||||
if (status == RET_OK) {
|
||||
zb_ext_pan_id_t extended_pan_id;
|
||||
esp_zb_get_extended_pan_id(extended_pan_id);
|
||||
ESP_LOGI(TAG, "Joined network successfully (Extended PAN ID: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, PAN ID: 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());
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Network steering was not successful (status: %d)", status);
|
||||
ZB_SCHEDULE_APP_ALARM((zb_callback_t)bdb_start_top_level_commissioning_cb, ZB_BDB_NETWORK_STEERING, ZB_TIME_ONE_SECOND);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ESP_LOGI(TAG, "status: %d", status);
|
||||
break;
|
||||
}
|
||||
if (bufid) {
|
||||
zb_buf_free(bufid);
|
||||
}
|
||||
}
|
||||
|
||||
static void esp_zb_task(void *pvParameters)
|
||||
{
|
||||
/* initialize Zigbee stack with Zigbee end-device config */
|
||||
esp_zb_cfg_t zb_nwk_cfg = ESP_ZB_ZED_CONFIG();
|
||||
esp_zb_init(&zb_nwk_cfg);
|
||||
/* set the on-off light device config */
|
||||
esp_zb_on_off_light_cfg_t light_cfg = ESP_ZB_DEFAULT_ON_OFF_LIGHT_CONFIG();
|
||||
esp_zb_ep_list_t *esp_zb_on_off_light_ep = esp_zb_on_off_light_ep_create(HA_ESP_LIGHT_ENDPOINT, &light_cfg);
|
||||
esp_zb_device_register(esp_zb_on_off_light_ep);
|
||||
esp_zb_device_add_set_attr_value_cb(attr_cb);
|
||||
ESP_ERROR_CHECK(esp_zb_start(false));
|
||||
esp_zb_main_loop_iteration();
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
esp_zb_platform_config_t config = {
|
||||
.radio_config = ESP_ZB_DEFAULT_RADIO_CONFIG(),
|
||||
.host_config = ESP_ZB_DEFAULT_HOST_CONFIG(),
|
||||
};
|
||||
/* load Zigbee light_bulb platform config to initialization */
|
||||
ESP_ERROR_CHECK(esp_zb_platform_config(&config));
|
||||
/* hardware related and device init */
|
||||
light_driver_init(LIGHT_DEFAULT_OFF);
|
||||
xTaskCreate(esp_zb_task, "Zigbee_main", 4096, NULL, 5, NULL);
|
||||
}
|
@ -35,43 +35,31 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "zboss_api.h"
|
||||
#include "esp_zigbee_core.h"
|
||||
#include "light_driver.h"
|
||||
|
||||
/* Zigbee configuration */
|
||||
#define IEEE_CHANNEL_MASK (1l << 13) /* Zigbee default setting is channel 13 for light example usage */
|
||||
#define ERASE_PERSISTENT_CONFIG ZB_TRUE /* erase network devices before running example */
|
||||
#define INSTALLCODE_POLICY_ENABLE false /* enable the install code policy for security */
|
||||
#define ED_AGING_TIMEOUT ED_AGING_TIMEOUT_64MIN
|
||||
#define ED_KEEP_ALIVE ZB_MILLISECONDS_TO_BEACON_INTERVAL(3000)
|
||||
#define HA_ESP_LIGHT_ENDPOINT 10 /* esp light bulb device endpoint, used to process light controlling commands */
|
||||
|
||||
/* groups cluster attributes */
|
||||
typedef struct {
|
||||
zb_uint8_t name_support;
|
||||
} zb_zcl_groups_attrs_t;
|
||||
#define ESP_ZB_ZED_CONFIG() \
|
||||
{ \
|
||||
.esp_zb_role = ESP_ZB_DEVICE_TYPE_ED, \
|
||||
.install_code_policy = INSTALLCODE_POLICY_ENABLE, \
|
||||
.nwk_cfg.zed_cfg = { \
|
||||
.ed_timeout = ED_AGING_TIMEOUT, \
|
||||
.keep_alive = ED_KEEP_ALIVE, \
|
||||
}, \
|
||||
}
|
||||
|
||||
/* scene cluster attributes */
|
||||
typedef struct {
|
||||
zb_uint8_t scene_count;
|
||||
zb_uint8_t current_scene;
|
||||
zb_uint8_t scene_valid;
|
||||
zb_uint8_t name_support;
|
||||
zb_uint16_t current_group;
|
||||
} zb_zcl_scenes_attrs_t;
|
||||
|
||||
/* light bulb device cluster attributes */
|
||||
typedef struct {
|
||||
zb_zcl_basic_attrs_t basic_attr;
|
||||
zb_zcl_identify_attrs_t identify_attr;
|
||||
zb_zcl_groups_attrs_t groups_attr;
|
||||
zb_zcl_scenes_attrs_t scenes_attr;
|
||||
zb_zcl_on_off_attrs_t on_off_attr;
|
||||
} bulb_device_ctx_t;
|
||||
|
||||
#define HA_ESP_LIGHT_ENDPOINT 10 /* esp light bulb device endpoint, used to process light controlling commands */
|
||||
#define ZB_ESP_DEFAULT_RADIO_CONFIG() \
|
||||
#define ESP_ZB_DEFAULT_RADIO_CONFIG() \
|
||||
{ \
|
||||
.radio_mode = RADIO_MODE_NATIVE, \
|
||||
}
|
||||
|
||||
#define ZB_ESP_DEFAULT_HOST_CONFIG() \
|
||||
#define ESP_ZB_DEFAULT_HOST_CONFIG() \
|
||||
{ \
|
||||
.host_connection_mode = HOST_CONNECTION_MODE_NONE, \
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
## IDF Component Manager Manifest File
|
||||
dependencies:
|
||||
espressif/esp-zboss-lib: "~0.0.4"
|
||||
espressif/esp-zigbee-lib: "~0.2.0"
|
||||
espressif/esp-zboss-lib: "~0.1.0"
|
||||
espressif/led_strip: "~2.0.0"
|
||||
## Required IDF version
|
||||
idf:
|
@ -40,10 +40,11 @@
|
||||
#include "light_driver.h"
|
||||
|
||||
static led_strip_handle_t s_led_strip;
|
||||
static uint8_t s_red = 255, s_green = 255, s_blue = 255;
|
||||
|
||||
void light_driver_set_power(bool power)
|
||||
{
|
||||
ESP_ERROR_CHECK(led_strip_set_pixel(s_led_strip, 0, 255 * power, 255 * power, 255 * power));
|
||||
ESP_ERROR_CHECK(led_strip_set_pixel(s_led_strip, 0, s_red * power, s_green * power, s_blue * power));
|
||||
ESP_ERROR_CHECK(led_strip_refresh(s_led_strip));
|
||||
}
|
||||
|
@ -52,16 +52,16 @@ extern "C" {
|
||||
#define CONFIG_EXAMPLE_STRIP_LED_NUMBER 1
|
||||
|
||||
/**
|
||||
* @brief Set light power (on/off).
|
||||
*
|
||||
* @param power The light power to be set
|
||||
* @brief Set light power (on/off).
|
||||
*
|
||||
* @param power The light power to be set
|
||||
*/
|
||||
void light_driver_set_power(bool power);
|
||||
|
||||
/**
|
||||
* @brief color light driver init, be invoked where you want to use color light
|
||||
*
|
||||
* @param power power on/off
|
||||
* @brief color light driver init, be invoked where you want to use color light
|
||||
*
|
||||
* @param power power on/off
|
||||
*/
|
||||
void light_driver_init(bool power);
|
||||
|
@ -3,4 +3,5 @@
|
||||
nvs, data, nvs, 0x9000, 0x6000,
|
||||
phy_init, data, phy, 0xf000, 0x1000,
|
||||
factory, app, factory, 0x10000, 1M,
|
||||
zb_storage, data, fat, , 128K,
|
||||
zb_storage, data, fat, 0x110000, 128K,
|
||||
zb_fct, data, fat, 0x130000, 1K,
|
|
64
examples/zigbee/light_sample/HA_on_off_switch/README.md
Normal file
64
examples/zigbee/light_sample/HA_on_off_switch/README.md
Normal file
@ -0,0 +1,64 @@
|
||||
| Supported Targets | ESP32-H2 |
|
||||
| ----------------- | -------- |
|
||||
|
||||
# Light Switch Example
|
||||
|
||||
This test code shows how to configure Zigbee Coordinator and use it as an HA on/off_switch
|
||||
|
||||
## Hardware Required
|
||||
|
||||
* One development board with ESP32-H2 SoC acting as Zigbee Coordinator (loaded with HA_on_off_switch)
|
||||
* A USB cable for power supply and programming
|
||||
* Choose another ESP32-H2 as Zigbee end-device (see [HA_on_off_light](../HA_on_off_light/))
|
||||
|
||||
## Configure the project
|
||||
|
||||
Before project configuration and build, make sure to set the correct chip target using `idf.py set-target esp32h2`.
|
||||
|
||||
## Erase the NVRAM
|
||||
|
||||
Before flash it to the board, it is recommended to erase NVRAM if user doesn't want to keep the previous examples or other projects stored info using `idf.py -p PORT erase-flash`
|
||||
|
||||
## Build and Flash
|
||||
|
||||
Build the project, flash it to the board, and start the monitor tool to view the serial output by running `idf.py -p PORT flash monitor`.
|
||||
|
||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||
|
||||
## Example Output
|
||||
|
||||
As you run the example, you will see the following log:
|
||||
|
||||
light switch:
|
||||
I (318) gpio: GPIO[9]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:2
|
||||
I (328) system_api: Base MAC address is not set
|
||||
I (328) system_api: read default base MAC address from EFUSE
|
||||
I (408) phy: libbtbb version: 6c47ec3, Mar 16 2022, 18:54:24
|
||||
I (408) phy: phy_version: 101, bb2a234, Mar 16 2022, 18:54:11
|
||||
I (818) ESP_ZB_ON_OFF_SWITCH: status: 255
|
||||
I (818) ESP_ZB_ON_OFF_SWITCH: Zigbee stack initialized
|
||||
I (818) ESP_ZB_ON_OFF_SWITCH: Start network formation
|
||||
I (1318) ESP_ZB_ON_OFF_SWITCH: Formed network successfully (Extended PAN ID: ff:fc:7c:c0:f0:bd:97:10, PAN ID: 0x88e7)
|
||||
I (1778) ESP_ZB_ON_OFF_SWITCH: status: 0
|
||||
I (5528) ESP_ZB_ON_OFF_SWITCH: status: 0
|
||||
I (6038) ESP_ZB_ON_OFF_SWITCH: status: 0
|
||||
I (6068) ESP_ZB_ON_OFF_SWITCH: New device commissioned or rejoined (short: 0x2878)
|
||||
I (6098) ESP_ZB_ON_OFF_SWITCH: User find cb: address:0x2878, endpoint:10
|
||||
I (6638) ESP_ZB_ON_OFF_SWITCH: status: 0
|
||||
I (6678) ESP_ZB_ON_OFF_SWITCH: status: 0
|
||||
I (8168) ESP_ZB_ON_OFF_SWITCH: send move to on_off toggle command
|
||||
I (8898) ESP_ZB_ON_OFF_SWITCH: send move to on_off toggle command
|
||||
I (9458) ESP_ZB_ON_OFF_SWITCH: send move to on_off toggle command
|
||||
I (10088) ESP_ZB_ON_OFF_SWITCH: send move to on_off toggle command
|
||||
I (10588) ESP_ZB_ON_OFF_SWITCH: send move to on_off toggle command
|
||||
I (11098) ESP_ZB_ON_OFF_SWITCH: send move to on_off toggle command
|
||||
|
||||
|
||||
## Light Control Functions
|
||||
|
||||
* By toggling the switch button (BOOT) on this board, the LED on the board loaded with the `HA_on_off_light` example will turn on and off.
|
||||
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon.
|
@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Espressif Systems (Shanghai) CO LTD
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Espressif Systems
|
||||
* integrated circuit in a product or a software update for such product,
|
||||
* must reproduce the above copyright notice, this list of conditions and
|
||||
* the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* 4. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_zigbee_ha_standard.h"
|
||||
#include "esp_zb_switch.h"
|
||||
|
||||
/**
|
||||
* @note Make sure set idf.py menuconfig in zigbee component as zigbee coordinator device!
|
||||
*/
|
||||
#if defined ZB_ED_ROLE
|
||||
#error Define ZB_COORDINATOR_ROLE in idf.py menuconfig to compile light switch source code.
|
||||
#endif
|
||||
|
||||
/* define a single remote device struct for managing */
|
||||
typedef struct light_bulb_device_params_s {
|
||||
esp_zb_ieee_addr_t ieee_addr;
|
||||
uint8_t endpoint;
|
||||
uint16_t short_addr;
|
||||
} light_bulb_device_params_t;
|
||||
|
||||
/* define Button function currently only 1 switch define */
|
||||
static switch_func_pair_t button_func_pair[] = {
|
||||
{GPIO_INPUT_IO_TOGGLE_SWITCH, SWITCH_ONOFF_TOGGLE_CONTROL}
|
||||
};
|
||||
|
||||
static const char *TAG = "ESP_ZB_ON_OFF_SWITCH";
|
||||
/* remote device struct for recording and managing node info */
|
||||
light_bulb_device_params_t on_off_light;
|
||||
/********************* Define functions **************************/
|
||||
|
||||
/**
|
||||
* @brief Callback for button events, currently only toggle event available
|
||||
*
|
||||
* @param button_func_pair Incoming event from the button_pair.
|
||||
*/
|
||||
static void esp_zb_buttons_handler(switch_func_pair_t *button_func_pair)
|
||||
{
|
||||
if (button_func_pair->func == SWITCH_ONOFF_TOGGLE_CONTROL) {
|
||||
/* implemented light switch toggle functionality */
|
||||
esp_zb_zcl_on_off_cmd_t cmd_req;
|
||||
cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = on_off_light.short_addr;
|
||||
cmd_req.zcl_basic_cmd.dst_endpoint = on_off_light.endpoint;
|
||||
cmd_req.zcl_basic_cmd.src_endpoint = HA_ONOFF_SWITCH_ENDPOINT;
|
||||
cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
|
||||
cmd_req.on_off_cmd_id = ZB_ZCL_CMD_ON_OFF_TOGGLE_ID;
|
||||
ESP_EARLY_LOGI(TAG, "send 'on_off toggle' command");
|
||||
esp_zb_zcl_on_off_cmd_req(&cmd_req);
|
||||
}
|
||||
}
|
||||
|
||||
static void bdb_start_top_level_commissioning_cb(uint8_t mode_mask)
|
||||
{
|
||||
ESP_ERROR_CHECK(esp_zb_bdb_start_top_level_commissioning(mode_mask));
|
||||
}
|
||||
|
||||
void user_find_cb(uint8_t zdo_status, uint16_t addr, uint8_t endpoint)
|
||||
{
|
||||
ESP_LOGI(TAG, "User find cb: address:0x%x, endpoint:%d, response_status:%d", addr, endpoint, zdo_status);
|
||||
if (zdo_status == ZB_ZDP_STATUS_SUCCESS) {
|
||||
on_off_light.endpoint = endpoint;
|
||||
on_off_light.short_addr = addr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Zigbee stack event signal handler.
|
||||
*
|
||||
* @param bufid Zigbee stack buffer id used to pass signal.
|
||||
*/
|
||||
void zboss_signal_handler(uint8_t bufid)
|
||||
{
|
||||
zb_zdo_app_signal_hdr_t *p_sg_p = NULL;
|
||||
zb_uint8_t status = ZB_GET_APP_SIGNAL_STATUS(bufid);
|
||||
zb_zdo_app_signal_type_t sig = zb_get_app_signal(bufid, &p_sg_p);
|
||||
zb_zdo_signal_device_annce_params_t *dev_annce_params = NULL;
|
||||
switch (sig) {
|
||||
case ZB_ZDO_SIGNAL_SKIP_STARTUP:
|
||||
ESP_LOGI(TAG, "Zigbee stack initialized");
|
||||
esp_zb_bdb_start_top_level_commissioning(ZB_BDB_INITIALIZATION);
|
||||
break;
|
||||
case ZB_BDB_SIGNAL_DEVICE_FIRST_START:
|
||||
case ZB_BDB_SIGNAL_DEVICE_REBOOT:
|
||||
if (status == RET_OK) {
|
||||
ESP_LOGI(TAG, "Start network formation");
|
||||
esp_zb_bdb_start_top_level_commissioning(ZB_BDB_NETWORK_FORMATION);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to initialize Zigbee stack (status: %d)", status);
|
||||
}
|
||||
break;
|
||||
case ZB_BDB_SIGNAL_FORMATION:
|
||||
if (status == RET_OK) {
|
||||
zb_ext_pan_id_t extended_pan_id;
|
||||
esp_zb_get_extended_pan_id(extended_pan_id);
|
||||
ESP_LOGI(TAG, "Formed network successfully (Extended PAN ID: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, PAN ID: 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_bdb_start_top_level_commissioning(ZB_BDB_NETWORK_STEERING);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Restart network formation (status: %d)", status);
|
||||
ZB_SCHEDULE_APP_ALARM((zb_callback_t)bdb_start_top_level_commissioning_cb, ZB_BDB_NETWORK_FORMATION, ZB_TIME_ONE_SECOND);
|
||||
}
|
||||
break;
|
||||
case ZB_BDB_SIGNAL_STEERING:
|
||||
if (status == RET_OK) {
|
||||
ESP_LOGI(TAG, "Network steering started");
|
||||
}
|
||||
break;
|
||||
case ZB_ZDO_SIGNAL_DEVICE_ANNCE:
|
||||
dev_annce_params = ZB_ZDO_SIGNAL_GET_PARAMS(p_sg_p, zb_zdo_signal_device_annce_params_t);
|
||||
ESP_LOGI(TAG, "New device commissioned or rejoined (short: 0x%04hx)", dev_annce_params->device_short_addr);
|
||||
esp_zb_zdo_match_desc_req_param_t cmd_req;
|
||||
cmd_req.dst_nwk_addr = dev_annce_params->device_short_addr;
|
||||
cmd_req.addr_of_interest = dev_annce_params->device_short_addr;
|
||||
esp_zb_zdo_find_on_off_light(&cmd_req, user_find_cb);
|
||||
break;
|
||||
default:
|
||||
ESP_LOGI(TAG, "status: %d", status);
|
||||
break;
|
||||
}
|
||||
if (bufid) {
|
||||
zb_buf_free(bufid);
|
||||
}
|
||||
}
|
||||
|
||||
static void esp_zb_task(void *pvParameters)
|
||||
{
|
||||
/* initialize Zigbee stack with Zigbee coordinator config */
|
||||
esp_zb_cfg_t zb_nwk_cfg = ESP_ZB_ZC_CONFIG();
|
||||
esp_zb_init(&zb_nwk_cfg);
|
||||
/* set the on-off switch device config */
|
||||
esp_zb_on_off_switch_cfg_t switch_cfg = ESP_ZB_DEFAULT_ON_OFF_SWITCH_CONFIG();
|
||||
esp_zb_ep_list_t *esp_zb_on_off_switch_ep = esp_zb_on_off_switch_ep_create(HA_ONOFF_SWITCH_ENDPOINT, &switch_cfg);
|
||||
esp_zb_device_register(esp_zb_on_off_switch_ep);
|
||||
ESP_ERROR_CHECK(esp_zb_start(false));
|
||||
esp_zb_main_loop_iteration();
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
esp_zb_platform_config_t config = {
|
||||
.radio_config = ESP_ZB_DEFAULT_RADIO_CONFIG(),
|
||||
.host_config = ESP_ZB_DEFAULT_HOST_CONFIG(),
|
||||
};
|
||||
/* load Zigbee switch platform config to initialization */
|
||||
ESP_ERROR_CHECK(esp_zb_platform_config(&config));
|
||||
/* hardware related and device init */
|
||||
switch_driver_init(button_func_pair, PAIR_SIZE(button_func_pair), esp_zb_buttons_handler);
|
||||
xTaskCreate(esp_zb_task, "Zigbee_main", 4096, NULL, 5, NULL);
|
||||
}
|
@ -34,39 +34,29 @@
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "zboss_api.h"
|
||||
#include "zboss_api_zcl.h"
|
||||
#include "zb_ha.h"
|
||||
#include "esp_zigbee_core.h"
|
||||
#include "switch_driver.h"
|
||||
|
||||
/* Zigbee configuration */
|
||||
#define IEEE_CHANNEL_MASK (1l << 13) /* ZigBee default setting is channel 13 for light example usage */
|
||||
#define ERASE_PERSISTENT_CONFIG ZB_TRUE /* erase network devices before running example */
|
||||
#define MAX_CHILDREN 10 /* the max number of connected devices */
|
||||
#define MAX_CHILDREN 10 /* the max amount of connected devices */
|
||||
#define INSTALLCODE_POLICY_ENABLE false /* enable the install code policy for security */
|
||||
#define HA_ONOFF_SWITCH_ENDPOINT 1 /* esp light switch device endpoint */
|
||||
|
||||
/* ZCL configuration */
|
||||
#define HA_ONOFF_SWITCH_ENDPOINT 1
|
||||
#define MATCH_DESC_REQ_START_DELAY (2 * ZB_TIME_ONE_SECOND) /* time delay between the light switch startup and light finding procedure */
|
||||
#define MATCH_DESC_REQ_TIMEOUT (5 * ZB_TIME_ONE_SECOND) /* timeout for finding bulb */
|
||||
#define MATCH_DESC_REQ_ROLE ZB_NWK_BROADCAST_RX_ON_WHEN_IDLE /* find non-sleep Zigbee device */
|
||||
#define ESP_ZB_ZC_CONFIG() \
|
||||
{ \
|
||||
.esp_zb_role = ESP_ZB_DEVICE_TYPE_COORDINATOR, \
|
||||
.install_code_policy = INSTALLCODE_POLICY_ENABLE, \
|
||||
.nwk_cfg.zczr_cfg = { \
|
||||
.max_children = MAX_CHILDREN, \
|
||||
}, \
|
||||
}
|
||||
|
||||
typedef struct light_switch_bulb_params_s {
|
||||
zb_uint8_t endpoint;
|
||||
zb_uint16_t short_addr;
|
||||
} light_switch_bulb_params_t;
|
||||
|
||||
/* light switch device cluster attributes */
|
||||
typedef struct {
|
||||
zb_zcl_basic_attrs_t basic_attr;
|
||||
zb_zcl_identify_attrs_t identify_attr;
|
||||
light_switch_bulb_params_t bulb_params;
|
||||
} switch_device_ctx_t;
|
||||
#define ZB_ESP_DEFAULT_RADIO_CONFIG() \
|
||||
#define ESP_ZB_DEFAULT_RADIO_CONFIG() \
|
||||
{ \
|
||||
.radio_mode = RADIO_MODE_NATIVE, \
|
||||
}
|
||||
|
||||
#define ZB_ESP_DEFAULT_HOST_CONFIG() \
|
||||
#define ESP_ZB_DEFAULT_HOST_CONFIG() \
|
||||
{ \
|
||||
.host_connection_mode = HOST_CONNECTION_MODE_NONE, \
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
## IDF Component Manager Manifest File
|
||||
dependencies:
|
||||
espressif/esp-zboss-lib: "~0.0.4"
|
||||
espressif/esp-zigbee-lib: "~0.2.0"
|
||||
espressif/esp-zboss-lib: "~0.1.0"
|
||||
## Required IDF version
|
||||
idf:
|
||||
version: ">=5.0.0"
|
@ -113,7 +113,7 @@ static void switch_driver_button_detected(void *arg)
|
||||
case SWITCH_RELEASE_DETECTED:
|
||||
switch_state = SWITCH_IDLE;
|
||||
/* callback to button_handler */
|
||||
(*func_ptr)(button_func_pair);
|
||||
(*func_ptr)(&button_func_pair);
|
||||
break;
|
||||
default:
|
||||
break;
|
@ -78,7 +78,7 @@ typedef struct {
|
||||
switch_func_t func;
|
||||
} switch_func_pair_t;
|
||||
|
||||
typedef void (*esp_switch_callback_t)(switch_func_pair_t param);
|
||||
typedef void (*esp_switch_callback_t)(switch_func_pair_t *param);
|
||||
|
||||
/**
|
||||
* @brief init function for switch and callback setup
|
@ -3,4 +3,5 @@
|
||||
nvs, data, nvs, 0x9000, 0x6000,
|
||||
phy_init, data, phy, 0xf000, 0x1000,
|
||||
factory, app, factory, 0x10000, 1M,
|
||||
zb_storage, data, fat, , 128K,
|
||||
zb_storage, data, fat,0x110000, 128K,
|
||||
zb_fct,data,fat,0x130000,1K
|
|
@ -6,7 +6,7 @@
|
||||
|
||||
The folder contains examples demonstrating Zigbee Coordinator and End-Device roles
|
||||
|
||||
* [light_bulb](light_bulb) is a light bulb example demonstrating Zigbee End-Device role. It provides a simple on/off condition for a Zigbee light. It runs on an 802.15.4 SoC like ESP32-H2. For more details see the example readme file.
|
||||
* [HA_on_off_light](HA_on_off_light) is a standard HA on-off light bulb example demonstrating Zigbee End-device. It provides a simple on/off condition for a Zigbee light. It runs on an 802.15.4 SoC like ESP32-H2. For more details see the example readme file.
|
||||
|
||||
* [light_switch](light_switch) is a light switch example demonstrating Zigbee Coordinator role. It provides an on/off toggle to control light. It runs on an 802.15.4 SoC like ESP32-H2. For more details to see the example readme file.
|
||||
* [HA_on_off_switch](HA_on_off_switch) is a standard HA on-off switch example demonstrating Zigbee Coordinator role. It provides an on/off toggle to control a Zigbee HA on off light. It runs on an 802.15.4 SoC like ESP32-H2. For more details to see the example readme file.
|
||||
|
||||
|
@ -1,254 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Espressif Systems (Shanghai) CO LTD
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Espressif Systems
|
||||
* integrated circuit in a product or a software update for such product,
|
||||
* must reproduce the above copyright notice, this list of conditions and
|
||||
* the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* 4. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_zb_light.h"
|
||||
|
||||
/**
|
||||
* @note Make sure set idf.py menuconfig in zigbee component as zigbee end-device device!
|
||||
*/
|
||||
#if !defined ZB_ED_ROLE
|
||||
#error Define ZB_ED_ROLE in idf.py menuconfig to compile light bulb source code.
|
||||
#endif
|
||||
|
||||
static bulb_device_ctx_t esp_light_ctx = {
|
||||
/* basic cluster attributes data */
|
||||
.basic_attr.zcl_version = ZB_ZCL_VERSION,
|
||||
.basic_attr.power_source = ZB_ZCL_BASIC_POWER_SOURCE_UNKNOWN,
|
||||
/* identify cluster attributes data */
|
||||
.identify_attr.identify_time = 0,
|
||||
/* groups cluster attributes data */
|
||||
.groups_attr.name_support = 0,
|
||||
/* on/off cluster attributes data */
|
||||
.on_off_attr.on_off = ZB_ZCL_ON_OFF_IS_OFF,
|
||||
};
|
||||
|
||||
static const char *TAG = "ESP_ZB_LIGHT";
|
||||
/******************* Declare attributes ************************/
|
||||
|
||||
/* basic cluster attributes data */
|
||||
ZB_ZCL_DECLARE_BASIC_ATTRIB_LIST(basic_attr_list,
|
||||
&esp_light_ctx.basic_attr.zcl_version,
|
||||
&esp_light_ctx.basic_attr.power_source);
|
||||
|
||||
/* identify cluster attributes data */
|
||||
ZB_ZCL_DECLARE_IDENTIFY_ATTRIB_LIST(identify_attr_list,
|
||||
&esp_light_ctx.identify_attr.identify_time);
|
||||
|
||||
/* groups cluster attributes data */
|
||||
ZB_ZCL_DECLARE_GROUPS_ATTRIB_LIST(groups_attr_list,
|
||||
&esp_light_ctx.groups_attr.name_support);
|
||||
|
||||
/* scenes cluster attribute data */
|
||||
ZB_ZCL_DECLARE_SCENES_ATTRIB_LIST(scenes_attr_list,
|
||||
&esp_light_ctx.scenes_attr.scene_count,
|
||||
&esp_light_ctx.scenes_attr.current_scene,
|
||||
&esp_light_ctx.scenes_attr.current_group,
|
||||
&esp_light_ctx.scenes_attr.scene_valid,
|
||||
&esp_light_ctx.scenes_attr.name_support);
|
||||
|
||||
/* on/off cluster attributes data */
|
||||
ZB_ZCL_DECLARE_ON_OFF_ATTRIB_LIST(on_off_attr_list,
|
||||
&esp_light_ctx.on_off_attr.on_off);
|
||||
|
||||
/********************* Declare device **************************/
|
||||
ZB_HA_DECLARE_ON_OFF_OUTPUT_CLUSTER_LIST(custom_light_clusters,
|
||||
on_off_attr_list,
|
||||
basic_attr_list,
|
||||
identify_attr_list,
|
||||
groups_attr_list,
|
||||
scenes_attr_list);
|
||||
|
||||
ZB_HA_DECLARE_ON_OFF_OUTPUT_EP(custom_esp_light_ep,
|
||||
HA_ESP_LIGHT_ENDPOINT,
|
||||
custom_light_clusters);
|
||||
|
||||
ZB_HA_DECLARE_ON_OFF_OUTPUT_CTX(esp_zb_light_ctx,
|
||||
custom_esp_light_ep);
|
||||
|
||||
/********************* Define functions **************************/
|
||||
static void bdb_start_top_level_commissioning_cb(zb_uint8_t mode_mask)
|
||||
{
|
||||
if (!bdb_start_top_level_commissioning(mode_mask)) {
|
||||
ESP_LOGE(TAG, "In BDB commissioning, an error occurred (for example: the device has already been running)");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Zigbee zboss stack event signal handler.
|
||||
*
|
||||
* @param bufid Zigbee zboss stack buffer id used to pass signal.
|
||||
*/
|
||||
void zboss_signal_handler(zb_bufid_t bufid)
|
||||
{
|
||||
zb_zdo_app_signal_hdr_t *p_sg_p = NULL;
|
||||
zb_zdo_app_signal_type_t sig = zb_get_app_signal(bufid, &p_sg_p);
|
||||
zb_ret_t status = ZB_GET_APP_SIGNAL_STATUS(bufid);
|
||||
|
||||
switch (sig) {
|
||||
case ZB_ZDO_SIGNAL_SKIP_STARTUP:
|
||||
ESP_LOGI(TAG, "Zigbee stack initialized");
|
||||
bdb_start_top_level_commissioning(ZB_BDB_INITIALIZATION);
|
||||
break;
|
||||
case ZB_BDB_SIGNAL_DEVICE_FIRST_START:
|
||||
if (status == RET_OK) {
|
||||
ESP_LOGI(TAG, "Start network steering");
|
||||
bdb_start_top_level_commissioning(ZB_BDB_NETWORK_STEERING);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to initialize Zigbee stack (status: %d)", status);
|
||||
}
|
||||
break;
|
||||
case ZB_BDB_SIGNAL_STEERING:
|
||||
if (status == RET_OK) {
|
||||
zb_ext_pan_id_t extended_pan_id;
|
||||
zb_get_extended_pan_id(extended_pan_id);
|
||||
ESP_LOGI(TAG, "Joined network successfully (Extended PAN ID: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, PAN ID: 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],
|
||||
ZB_PIBCACHE_PAN_ID());
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Network steering was not successful (status: %d)", status);
|
||||
ZB_SCHEDULE_APP_ALARM((zb_callback_t)bdb_start_top_level_commissioning_cb, ZB_BDB_NETWORK_STEERING, ZB_TIME_ONE_SECOND);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ESP_LOGI(TAG, "status: %d", status);
|
||||
break;
|
||||
}
|
||||
if (bufid) {
|
||||
zb_buf_free(bufid);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function for turning on/off the light bulb.
|
||||
*
|
||||
* @param power Boolean light bulb state power on/off.
|
||||
*/
|
||||
static void esp_zb_light_set_value(zb_bool_t power)
|
||||
{
|
||||
ZB_ZCL_SET_ATTRIBUTE(HA_ESP_LIGHT_ENDPOINT,
|
||||
ZB_ZCL_CLUSTER_ID_ON_OFF,
|
||||
ZB_ZCL_CLUSTER_SERVER_ROLE,
|
||||
ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID,
|
||||
(zb_uint8_t *)&power,
|
||||
ZB_FALSE);
|
||||
|
||||
light_driver_set_power(power);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Callback function for handling attribute value from ZCL.
|
||||
*
|
||||
* @param bufid Zigbee zboss stack buffer id used to pass received data.
|
||||
*/
|
||||
static void esp_zb_light_cb(zb_bufid_t bufid)
|
||||
{
|
||||
zb_zcl_device_callback_param_t *p_device_cb_param = ZB_BUF_GET_PARAM(bufid, zb_zcl_device_callback_param_t);
|
||||
zb_zcl_device_callback_id_t device_cb_id = p_device_cb_param->device_cb_id;
|
||||
zb_uint16_t cluster_id = p_device_cb_param->cb_param.set_attr_value_param.cluster_id;
|
||||
zb_uint16_t attr_id = p_device_cb_param->cb_param.set_attr_value_param.attr_id;
|
||||
p_device_cb_param->status = RET_OK;
|
||||
|
||||
switch (device_cb_id) {
|
||||
/* ZCL set attribute value */
|
||||
case ZB_ZCL_SET_ATTR_VALUE_CB_ID:
|
||||
if (cluster_id == ZB_ZCL_CLUSTER_ID_ON_OFF) {
|
||||
uint8_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data8;
|
||||
ESP_LOGI(TAG, "on/off attribute setting to %hd", value);
|
||||
|
||||
if (attr_id == ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID) {
|
||||
/* implemented light on/off control */
|
||||
esp_zb_light_set_value((zb_bool_t) value);
|
||||
}
|
||||
} else if (cluster_id == ZB_ZCL_CLUSTER_ID_LEVEL_CONTROL) {
|
||||
uint16_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data16;
|
||||
ESP_LOGI(TAG, "level control attribute setting to %hd", value);
|
||||
|
||||
if (attr_id == ZB_ZCL_ATTR_LEVEL_CONTROL_CURRENT_LEVEL_ID) {
|
||||
/* implement light level control if needed */
|
||||
}
|
||||
} else if (cluster_id == ZB_ZCL_CLUSTER_ID_COLOR_CONTROL) {
|
||||
uint16_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data8;
|
||||
ESP_LOGI(TAG, "attribute 0x%x setting to %d", attr_id, value);
|
||||
|
||||
if (attr_id == ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_HUE_ID) {
|
||||
/* implement light color change if needed */
|
||||
}
|
||||
} else {
|
||||
/* other clusters attribute handled here */
|
||||
ESP_LOGI(TAG, "Unhandled cluster attribute id: %d", cluster_id);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
p_device_cb_param->status = RET_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void zboss_task(void *pvParameters)
|
||||
{
|
||||
/* initialize Zigbee stack */
|
||||
ZB_INIT("light_bulb");
|
||||
zb_set_network_ed_role(IEEE_CHANNEL_MASK);
|
||||
zb_set_nvram_erase_at_start(ERASE_PERSISTENT_CONFIG);
|
||||
zb_set_ed_timeout(ED_AGING_TIMEOUT_64MIN);
|
||||
zb_set_keepalive_timeout(ZB_MILLISECONDS_TO_BEACON_INTERVAL(3000));
|
||||
/* hardware related and device init */
|
||||
light_driver_init(LIGHT_DEFAULT_OFF);
|
||||
/* register callback for handling ZCL commands */
|
||||
ZB_ZCL_REGISTER_DEVICE_CB(esp_zb_light_cb);
|
||||
/* register light device context (endpoints) */
|
||||
ZB_AF_REGISTER_DEVICE_CTX(&esp_zb_light_ctx);
|
||||
ESP_ERROR_CHECK(zboss_start_no_autostart());
|
||||
while (1) {
|
||||
zboss_main_loop_iteration();
|
||||
}
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
zb_esp_platform_config_t config = {
|
||||
.radio_config = ZB_ESP_DEFAULT_RADIO_CONFIG(),
|
||||
.host_config = ZB_ESP_DEFAULT_HOST_CONFIG(),
|
||||
};
|
||||
/* load Zigbee light_bulb platform config to initialization */
|
||||
ESP_ERROR_CHECK(zb_esp_platform_config(&config));
|
||||
xTaskCreate(zboss_task, "zboss_main", 4096, NULL, 5, NULL);
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
| Supported Targets | ESP32-H2 |
|
||||
| ----------------- | -------- |
|
||||
|
||||
# Light Switch Example
|
||||
|
||||
(See the `README.md` file in the upper level 'examples' directory for more information about examples.)
|
||||
|
||||
This test code shows how to configure Zigbee end device and use it as a light switch
|
||||
|
||||
## Hardware Required
|
||||
|
||||
* One development board with ESP32-H2 SoC acting as Zigbee coordinator (loaded with light switch example)
|
||||
* A USB cable for power supply and programming
|
||||
* Choose another ESP32-H2 as Zigbee end-device (see [light bulb example](../light_bulb))
|
||||
|
||||
## Configure the project
|
||||
|
||||
Before project configuration and build, make sure to set the correct chip target using `idf.py set-target esp32h2`.
|
||||
|
||||
## Build and Flash
|
||||
|
||||
Build the project, flash it to the board, and start the monitor tool to view the serial output by running `idf.py -p PORT flash monitor`.
|
||||
|
||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||
|
||||
## Example Output
|
||||
|
||||
As you run the example, you will see the following log:
|
||||
|
||||
light switch:
|
||||
I (767) gpio: GPIO[9]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:2
|
||||
I (857) ESP_ZB_SWITCH: status: 255
|
||||
I (857) ESP_ZB_SWITCH: Zigbee stack initialized
|
||||
I (857) ESP_ZB_SWITCH: Start network formation
|
||||
I (1377) ESP_ZB_SWITCH: Joined network successfully (Extended PAN ID: aa:98:48:01:a0:03:f7:84, PAN ID: 0xb8db)
|
||||
I (1837) ESP_ZB_SWITCH: status: 0
|
||||
I (1837) ESP_ZB_SWITCH: Network steering started
|
||||
I (6587) ESP_ZB_SWITCH: status: 0
|
||||
I (7097) ESP_ZB_SWITCH: status: 0
|
||||
I (7147) ESP_ZB_SWITCH: New device commissioned or rejoined (short: 0xd200)
|
||||
I (7717) ESP_ZB_SWITCH: status: 0
|
||||
I (7757) ESP_ZB_SWITCH: status: 0
|
||||
I (9217) ESP_ZB_SWITCH: Found bulb addr: 0x77ea ep: 10
|
||||
I (11657) ESP_ZB_SWITCH: Send ON/OFF toggle command
|
||||
I (12197) ESP_ZB_SWITCH: Send ON/OFF toggle command
|
||||
I (12547) ESP_ZB_SWITCH: Send ON/OFF toggle command
|
||||
I (12857) ESP_ZB_SWITCH: Send ON/OFF toggle command
|
||||
I (17327) ESP_ZB_SWITCH: Send ON/OFF toggle command
|
||||
|
||||
## Light Control Functions
|
||||
|
||||
* By toggling the switch button (BOOT) on this board, the LED on the board loaded with the `light bulb` example will be on and off.
|
||||
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon.
|
@ -1,323 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Espressif Systems (Shanghai) CO LTD
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Espressif Systems
|
||||
* integrated circuit in a product or a software update for such product,
|
||||
* must reproduce the above copyright notice, this list of conditions and
|
||||
* the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* 4. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_zb_switch.h"
|
||||
|
||||
/**
|
||||
* @note Make sure set idf.py menuconfig in zigbee component as zigbee coordinator device!
|
||||
*/
|
||||
#if defined ZB_ED_ROLE
|
||||
#error Define ZB_COORDINATOR_ROLE in idf.py menuconfig to compile light switch source code.
|
||||
#endif
|
||||
|
||||
/* define Button function currently only 1 switch define */
|
||||
static switch_func_pair_t button_func_pair[] = {
|
||||
{GPIO_INPUT_IO_TOGGLE_SWITCH, SWITCH_ONOFF_TOGGLE_CONTROL}
|
||||
};
|
||||
|
||||
static switch_device_ctx_t esp_switch_ctx = {
|
||||
/* basic cluster attributes data */
|
||||
.basic_attr.zcl_version = ZB_ZCL_VERSION,
|
||||
.basic_attr.power_source = ZB_ZCL_BASIC_POWER_SOURCE_UNKNOWN,
|
||||
/* identify cluster attributes data */
|
||||
.identify_attr.identify_time = 0,
|
||||
/* bulb parameters */
|
||||
.bulb_params.short_addr = 0xffff,
|
||||
};
|
||||
|
||||
static const char *TAG = "ESP_ZB_SWITCH";
|
||||
/******************* Declare attributes ************************/
|
||||
|
||||
/* basic cluster attributes data */
|
||||
ZB_ZCL_DECLARE_BASIC_ATTRIB_LIST(basic_attr_list,
|
||||
&esp_switch_ctx.basic_attr.zcl_version,
|
||||
&esp_switch_ctx.basic_attr.power_source);
|
||||
|
||||
/* identify cluster attributes data */
|
||||
ZB_ZCL_DECLARE_IDENTIFY_ATTRIB_LIST(identify_attr_list,
|
||||
&esp_switch_ctx.identify_attr.identify_time);
|
||||
|
||||
/* switch config cluster attributes data */
|
||||
zb_uint8_t attr_switch_type =
|
||||
ZB_ZCL_ON_OFF_SWITCH_CONFIGURATION_SWITCH_TYPE_TOGGLE;
|
||||
zb_uint8_t attr_switch_actions =
|
||||
ZB_ZCL_ON_OFF_SWITCH_CONFIGURATION_SWITCH_ACTIONS_DEFAULT_VALUE;
|
||||
|
||||
ZB_ZCL_DECLARE_ON_OFF_SWITCH_CONFIGURATION_ATTRIB_LIST(switch_cfg_attr_list, &attr_switch_type, &attr_switch_actions);
|
||||
|
||||
/********************* Declare device **************************/
|
||||
|
||||
ZB_HA_DECLARE_ON_OFF_SWITCH_CLUSTER_LIST(on_off_switch_clusters, switch_cfg_attr_list, basic_attr_list, identify_attr_list);
|
||||
|
||||
ZB_HA_DECLARE_ON_OFF_SWITCH_EP(on_off_switch_ep, HA_ONOFF_SWITCH_ENDPOINT, on_off_switch_clusters);
|
||||
|
||||
ZB_HA_DECLARE_ON_OFF_SWITCH_CTX(on_off_switch_ctx, on_off_switch_ep);
|
||||
|
||||
static void esp_zb_find_light_bulb_cb(zb_bufid_t bufid);
|
||||
|
||||
/********************* Define functions **************************/
|
||||
/**
|
||||
* @brief return true is switch find bulb
|
||||
*/
|
||||
static bool esp_zb_already_find_light_bulb(void)
|
||||
{
|
||||
return !(esp_switch_ctx.bulb_params.short_addr == 0xffff);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function for sending on/off and Level Control find request.
|
||||
*
|
||||
* @param bufid Zigbee zboss stack buffer id will be used to construct find request.
|
||||
*/
|
||||
static void esp_zb_find_light_bulb(zb_bufid_t bufid)
|
||||
{
|
||||
zb_zdo_match_desc_param_t *p_req;
|
||||
|
||||
/* initialize pointers inside buffer and reserve space for zb_zdo_match_desc_param_t request */
|
||||
p_req = zb_buf_initial_alloc(bufid, sizeof(zb_zdo_match_desc_param_t) + (1) * sizeof(zb_uint16_t));
|
||||
p_req->nwk_addr = MATCH_DESC_REQ_ROLE; /* send to devices specified by MATCH_DESC_REQ_ROLE */
|
||||
p_req->addr_of_interest = MATCH_DESC_REQ_ROLE; /* get responses from devices specified by MATCH_DESC_REQ_ROLE */
|
||||
p_req->profile_id = ZB_AF_HA_PROFILE_ID; /* look for Home Automation profile clusters */
|
||||
|
||||
/* we are searching for 1 cluster:
|
||||
on/off
|
||||
*/
|
||||
p_req->num_in_clusters = 1;
|
||||
p_req->num_out_clusters = 0;
|
||||
p_req->cluster_list[0] = ZB_ZCL_CLUSTER_ID_ON_OFF;
|
||||
/* set 0xFFFF to reset short address in order to parse only one response. */
|
||||
esp_switch_ctx.bulb_params.short_addr = 0xFFFF;
|
||||
zb_zdo_match_desc_req(bufid, esp_zb_find_light_bulb_cb);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Finding procedure timeout handler.
|
||||
*
|
||||
* @param bufid Zigbee zboss stack buffer id will be used to construct find request.
|
||||
*/
|
||||
static void esp_zb_find_light_bulb_timeout(zb_bufid_t bufid)
|
||||
{
|
||||
zb_ret_t zb_err_code;
|
||||
|
||||
if (bufid) {
|
||||
ESP_LOGW(TAG, "Bulb not found, try again");
|
||||
zb_err_code = ZB_SCHEDULE_APP_ALARM(esp_zb_find_light_bulb, bufid, MATCH_DESC_REQ_START_DELAY);
|
||||
ESP_ERROR_CHECK(zb_err_code);
|
||||
zb_err_code = ZB_SCHEDULE_APP_ALARM(esp_zb_find_light_bulb_timeout, 0, MATCH_DESC_REQ_TIMEOUT);
|
||||
ESP_ERROR_CHECK(zb_err_code);
|
||||
} else {
|
||||
zb_err_code = zb_buf_get_out_delayed(esp_zb_find_light_bulb_timeout);
|
||||
ESP_ERROR_CHECK(zb_err_code);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Callback function receiving finding procedure results.
|
||||
*
|
||||
* @param bufid Zigbee zboss stack buffer id is used to pass received data.
|
||||
*/
|
||||
static void esp_zb_find_light_bulb_cb(zb_bufid_t bufid)
|
||||
{
|
||||
zb_zdo_match_desc_resp_t *p_resp = (zb_zdo_match_desc_resp_t *) zb_buf_begin(bufid); /* get the beginning of the response */
|
||||
zb_apsde_data_indication_t *p_ind = ZB_BUF_GET_PARAM(bufid, zb_apsde_data_indication_t); /* get the pointer to the parameters buffer, which stores APS layer response */
|
||||
zb_uint8_t *p_match_ep;
|
||||
zb_ret_t zb_err_code;
|
||||
|
||||
if ((p_resp->status == ZB_ZDP_STATUS_SUCCESS) && (p_resp->match_len > 0) && (esp_switch_ctx.bulb_params.short_addr == 0xFFFF)) {
|
||||
/* match EP list follows right after response header */
|
||||
p_match_ep = (zb_uint8_t *)(p_resp + 1);
|
||||
|
||||
/* We are searching for exact cluster, so only 1 EP may be found */
|
||||
esp_switch_ctx.bulb_params.endpoint = *p_match_ep;
|
||||
esp_switch_ctx.bulb_params.short_addr = p_ind->src_addr;
|
||||
|
||||
ESP_LOGI(TAG, "Found bulb addr: 0x%x ep: %d", esp_switch_ctx.bulb_params.short_addr, esp_switch_ctx.bulb_params.endpoint);
|
||||
zb_err_code = ZB_SCHEDULE_APP_ALARM_CANCEL(esp_zb_find_light_bulb_timeout, ZB_ALARM_ANY_PARAM);
|
||||
ESP_ERROR_CHECK(zb_err_code);
|
||||
}
|
||||
if (bufid) {
|
||||
zb_buf_free(bufid);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function for sending on/off Toggle requests to the light bulb.
|
||||
*
|
||||
* @param bufid Zigbee zboss stack buffer id will be used to construct on/off request.
|
||||
* @param on_off_toggle unused value.
|
||||
*/
|
||||
static void esp_zb_light_switch_send_on_off_toggle(zb_bufid_t bufid, zb_uint16_t on_off_toggle)
|
||||
{
|
||||
static zb_uint8_t cmd_id = ZB_ZCL_CMD_ON_OFF_TOGGLE_ID;
|
||||
|
||||
ESP_LOGI(TAG, "Send ON/OFF toggle command");
|
||||
ZB_ZCL_ON_OFF_SEND_REQ(bufid,
|
||||
esp_switch_ctx.bulb_params.short_addr,
|
||||
ZB_APS_ADDR_MODE_16_ENDP_PRESENT,
|
||||
esp_switch_ctx.bulb_params.endpoint,
|
||||
HA_ONOFF_SWITCH_ENDPOINT,
|
||||
ZB_AF_HA_PROFILE_ID,
|
||||
ZB_ZCL_DISABLE_DEFAULT_RESPONSE,
|
||||
cmd_id,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Callback for button events, currently only toggle event available
|
||||
*
|
||||
* @param button_func_pair Incoming event from the button_pair.
|
||||
*/
|
||||
static void esp_zb_buttons_handler(switch_func_pair_t button_func_pair)
|
||||
{
|
||||
zb_ret_t zb_err_code = ESP_OK;
|
||||
|
||||
if (!esp_zb_already_find_light_bulb()) {
|
||||
/* no bulb found yet */
|
||||
return;
|
||||
}
|
||||
if (button_func_pair.func == SWITCH_ONOFF_TOGGLE_CONTROL) {
|
||||
/* implemented light switch toggle functionality */
|
||||
zb_err_code = zb_buf_get_out_delayed_ext(esp_zb_light_switch_send_on_off_toggle, 0, 0);
|
||||
}
|
||||
ESP_ERROR_CHECK(zb_err_code);
|
||||
}
|
||||
|
||||
static void bdb_start_top_level_commissioning_cb(zb_uint8_t mode_mask)
|
||||
{
|
||||
if (!bdb_start_top_level_commissioning(mode_mask)) {
|
||||
ESP_LOGE(TAG, "In BDB commissioning, an error occurred (for example: the device has already been running)");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Zigbee zboss stack event signal handler.
|
||||
*
|
||||
* @param bufid Zigbee zboss stack buffer id used to pass signal.
|
||||
*/
|
||||
void zboss_signal_handler(zb_bufid_t bufid)
|
||||
{
|
||||
zb_zdo_app_signal_hdr_t *p_sg_p = NULL;
|
||||
zb_uint8_t status = ZB_GET_APP_SIGNAL_STATUS(bufid);
|
||||
zb_zdo_app_signal_type_t sig = zb_get_app_signal(bufid, &p_sg_p);
|
||||
zb_zdo_signal_device_annce_params_t *dev_annce_params = NULL;
|
||||
zb_ret_t zb_err_code;
|
||||
zb_nlme_permit_joining_request_t *request = NULL;
|
||||
switch (sig) {
|
||||
case ZB_ZDO_SIGNAL_SKIP_STARTUP:
|
||||
ESP_LOGI(TAG, "Zigbee stack initialized");
|
||||
bdb_start_top_level_commissioning(ZB_BDB_INITIALIZATION);
|
||||
break;
|
||||
case ZB_BDB_SIGNAL_DEVICE_FIRST_START:
|
||||
if (status == RET_OK) {
|
||||
ESP_LOGI(TAG, "Start network formation");
|
||||
bdb_start_top_level_commissioning(ZB_BDB_NETWORK_FORMATION);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to initialize Zigbee stack (status: %d)", status);
|
||||
}
|
||||
break;
|
||||
case ZB_BDB_SIGNAL_FORMATION:
|
||||
if (status == RET_OK) {
|
||||
zb_ext_pan_id_t extended_pan_id;
|
||||
zb_get_extended_pan_id(extended_pan_id);
|
||||
ESP_LOGI(TAG, "Joined network successfully (Extended PAN ID: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, PAN ID: 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],
|
||||
ZB_PIBCACHE_PAN_ID());
|
||||
bdb_start_top_level_commissioning(ZB_BDB_NETWORK_STEERING);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Restart network formation (status: %d)", status);
|
||||
ZB_SCHEDULE_APP_ALARM((zb_callback_t)bdb_start_top_level_commissioning_cb, ZB_BDB_NETWORK_FORMATION, ZB_TIME_ONE_SECOND);
|
||||
}
|
||||
break;
|
||||
case ZB_BDB_SIGNAL_STEERING:
|
||||
if (status == RET_OK) {
|
||||
request = ZB_BUF_GET_PARAM(bufid, zb_nlme_permit_joining_request_t);
|
||||
ESP_LOGI(TAG, "Network steering started/refreshed");
|
||||
ZB_SCHEDULE_APP_ALARM((zb_callback_t)bdb_start_top_level_commissioning_cb, ZB_BDB_NETWORK_STEERING, (request->permit_duration)*ZB_TIME_ONE_SECOND);
|
||||
}
|
||||
break;
|
||||
case ZB_ZDO_SIGNAL_DEVICE_ANNCE:
|
||||
dev_annce_params = ZB_ZDO_SIGNAL_GET_PARAMS(p_sg_p, zb_zdo_signal_device_annce_params_t);
|
||||
ESP_LOGI(TAG, "New device commissioned or rejoined (short: 0x%04hx)", dev_annce_params->device_short_addr);
|
||||
/* check the light device address */
|
||||
if (!esp_zb_already_find_light_bulb()) {
|
||||
zb_err_code = ZB_SCHEDULE_APP_ALARM(esp_zb_find_light_bulb, bufid, MATCH_DESC_REQ_START_DELAY);
|
||||
ESP_ERROR_CHECK(zb_err_code);
|
||||
zb_err_code = ZB_SCHEDULE_APP_ALARM(esp_zb_find_light_bulb_timeout, 0, MATCH_DESC_REQ_TIMEOUT);
|
||||
ESP_ERROR_CHECK(zb_err_code);
|
||||
bufid = 0; /* Do not free buffer - it will be reused by find_light_bulb callback */
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ESP_LOGI(TAG, "status: %d", status);
|
||||
break;
|
||||
}
|
||||
if (bufid) {
|
||||
zb_buf_free(bufid);
|
||||
}
|
||||
}
|
||||
|
||||
static void zboss_task(void *pvParameters)
|
||||
{
|
||||
/* initialize Zigbee stack. */
|
||||
ZB_INIT("light_switch");
|
||||
zb_set_network_coordinator_role(IEEE_CHANNEL_MASK);
|
||||
zb_set_max_children(MAX_CHILDREN);
|
||||
zb_set_nvram_erase_at_start(ERASE_PERSISTENT_CONFIG);
|
||||
/* hardware related and device init */
|
||||
switch_driver_init(button_func_pair, PAIR_SIZE(button_func_pair), esp_zb_buttons_handler);
|
||||
/* register on_off switch device context (endpoints) */
|
||||
ZB_AF_REGISTER_DEVICE_CTX(&on_off_switch_ctx);
|
||||
ESP_ERROR_CHECK(zboss_start_no_autostart());
|
||||
|
||||
while (1) {
|
||||
zboss_main_loop_iteration();
|
||||
}
|
||||
}
|
||||
void app_main(void)
|
||||
{
|
||||
zb_esp_platform_config_t config = {
|
||||
.radio_config = ZB_ESP_DEFAULT_RADIO_CONFIG(),
|
||||
.host_config = ZB_ESP_DEFAULT_HOST_CONFIG(),
|
||||
};
|
||||
/* load Zigbee switch platform config to initialization */
|
||||
ESP_ERROR_CHECK(zb_esp_platform_config(&config));
|
||||
xTaskCreate(zboss_task, "zboss_main", 4096, NULL, 5, NULL);
|
||||
}
|
Loading…
Reference in New Issue
Block a user