Zigbee sample works with nRF52840dk + zigbee2mqtt
This commit is contained in:
parent
af3a9add74
commit
f05d1f8e3b
5 changed files with 422 additions and 0 deletions
2
code/nrf-connect/samples/zigbee/.gitignore
vendored
Normal file
2
code/nrf-connect/samples/zigbee/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
build
|
||||||
|
build_*
|
||||||
19
code/nrf-connect/samples/zigbee/CMakeLists.txt
Normal file
19
code/nrf-connect/samples/zigbee/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2021 Nordic Semiconductor ASA
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
|
||||||
|
#
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
|
||||||
|
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||||
|
|
||||||
|
project("Zigbee application template")
|
||||||
|
|
||||||
|
# NORDIC SDK APP START
|
||||||
|
target_sources(app PRIVATE
|
||||||
|
src/main.c
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(app PRIVATE include)
|
||||||
|
# NORDIC SDK APP END
|
||||||
113
code/nrf-connect/samples/zigbee/include/zb_range_extender.h
Normal file
113
code/nrf-connect/samples/zigbee/include/zb_range_extender.h
Normal file
|
|
@ -0,0 +1,113 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 Nordic Semiconductor ASA
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ZB_RANGE_EXTENDER_H
|
||||||
|
#define ZB_RANGE_EXTENDER_H 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup ZB_DEFINE_DEVICE_RANGE_EXTENDER Range Extender
|
||||||
|
* @{
|
||||||
|
* @details
|
||||||
|
* - @ref ZB_ZCL_IDENTIFY \n
|
||||||
|
* - @ref ZB_ZCL_BASIC
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** Range Extender Device ID*/
|
||||||
|
#define ZB_RANGE_EXTENDER_DEVICE_ID 0x0008
|
||||||
|
|
||||||
|
/** Range extender device version */
|
||||||
|
#define ZB_DEVICE_VER_RANGE_EXTENDER 0
|
||||||
|
|
||||||
|
/** @cond internals_doc */
|
||||||
|
|
||||||
|
/** Range extender IN (server) clusters number */
|
||||||
|
#define ZB_RANGE_EXTENDER_IN_CLUSTER_NUM 2
|
||||||
|
|
||||||
|
/** Range extender OUT (client) clusters number */
|
||||||
|
#define ZB_RANGE_EXTENDER_OUT_CLUSTER_NUM 0
|
||||||
|
|
||||||
|
#define ZB_RANGE_EXTENDER_CLUSTER_NUM \
|
||||||
|
(ZB_RANGE_EXTENDER_IN_CLUSTER_NUM + ZB_RANGE_EXTENDER_OUT_CLUSTER_NUM)
|
||||||
|
|
||||||
|
/** Number of attribute for reporting on Range extender device */
|
||||||
|
#define ZB_RANGE_EXTENDER_REPORT_ATTR_COUNT 0
|
||||||
|
|
||||||
|
/** @endcond */ /* internals_doc */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Declare cluster list for Range extender device
|
||||||
|
* @param cluster_list_name - cluster list variable name
|
||||||
|
* @param basic_attr_list - attribute list for Basic cluster
|
||||||
|
* @param identify_attr_list - attribute list for Identify cluster
|
||||||
|
*/
|
||||||
|
#define ZB_DECLARE_RANGE_EXTENDER_CLUSTER_LIST( \
|
||||||
|
cluster_list_name, \
|
||||||
|
basic_attr_list, \
|
||||||
|
identify_attr_list) \
|
||||||
|
zb_zcl_cluster_desc_t cluster_list_name[] = \
|
||||||
|
{ \
|
||||||
|
ZB_ZCL_CLUSTER_DESC( \
|
||||||
|
ZB_ZCL_CLUSTER_ID_IDENTIFY, \
|
||||||
|
ZB_ZCL_ARRAY_SIZE(identify_attr_list, zb_zcl_attr_t), \
|
||||||
|
(identify_attr_list), \
|
||||||
|
ZB_ZCL_CLUSTER_SERVER_ROLE, \
|
||||||
|
ZB_ZCL_MANUF_CODE_INVALID \
|
||||||
|
), \
|
||||||
|
ZB_ZCL_CLUSTER_DESC( \
|
||||||
|
ZB_ZCL_CLUSTER_ID_BASIC, \
|
||||||
|
ZB_ZCL_ARRAY_SIZE(basic_attr_list, zb_zcl_attr_t), \
|
||||||
|
(basic_attr_list), \
|
||||||
|
ZB_ZCL_CLUSTER_SERVER_ROLE, \
|
||||||
|
ZB_ZCL_MANUF_CODE_INVALID \
|
||||||
|
) \
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @cond internals_doc */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Declare simple descriptor for Range extender device
|
||||||
|
* @param ep_name - endpoint variable name
|
||||||
|
* @param ep_id - endpoint ID
|
||||||
|
* @param in_clust_num - number of supported input clusters
|
||||||
|
* @param out_clust_num - number of supported output clusters
|
||||||
|
*/
|
||||||
|
#define ZB_ZCL_DECLARE_RANGE_EXTENDER_SIMPLE_DESC(ep_name, ep_id, in_clust_num, out_clust_num) \
|
||||||
|
ZB_DECLARE_SIMPLE_DESC(in_clust_num, out_clust_num); \
|
||||||
|
ZB_AF_SIMPLE_DESC_TYPE(in_clust_num, out_clust_num) simple_desc_##ep_name = \
|
||||||
|
{ \
|
||||||
|
ep_id, \
|
||||||
|
ZB_AF_HA_PROFILE_ID, \
|
||||||
|
ZB_RANGE_EXTENDER_DEVICE_ID, \
|
||||||
|
ZB_DEVICE_VER_RANGE_EXTENDER, \
|
||||||
|
0, \
|
||||||
|
in_clust_num, \
|
||||||
|
out_clust_num, \
|
||||||
|
{ \
|
||||||
|
ZB_ZCL_CLUSTER_ID_BASIC, \
|
||||||
|
ZB_ZCL_CLUSTER_ID_IDENTIFY \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @endcond */ /* internals_doc */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Declare endpoint for Range extender device
|
||||||
|
* @param ep_name - endpoint variable name
|
||||||
|
* @param ep_id - endpoint ID
|
||||||
|
* @param cluster_list - endpoint cluster list
|
||||||
|
*/
|
||||||
|
#define ZB_DECLARE_RANGE_EXTENDER_EP(ep_name, ep_id, cluster_list) \
|
||||||
|
ZB_ZCL_DECLARE_RANGE_EXTENDER_SIMPLE_DESC(ep_name, ep_id, \
|
||||||
|
ZB_RANGE_EXTENDER_IN_CLUSTER_NUM, ZB_RANGE_EXTENDER_OUT_CLUSTER_NUM); \
|
||||||
|
ZB_AF_DECLARE_ENDPOINT_DESC(ep_name, ep_id, ZB_AF_HA_PROFILE_ID, 0, NULL, \
|
||||||
|
ZB_ZCL_ARRAY_SIZE(cluster_list, zb_zcl_cluster_desc_t), cluster_list, \
|
||||||
|
(zb_af_simple_desc_1_1_t *)&simple_desc_##ep_name, \
|
||||||
|
0, NULL, /* No reporting ctx */ \
|
||||||
|
0, NULL) /* No CVC ctx */
|
||||||
|
|
||||||
|
/*! @} */
|
||||||
|
|
||||||
|
#endif /* ZB_RANGE_EXTENDER_H */
|
||||||
43
code/nrf-connect/samples/zigbee/prj.conf
Normal file
43
code/nrf-connect/samples/zigbee/prj.conf
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2021 Nordic Semiconductor ASA
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
|
||||||
|
#
|
||||||
|
|
||||||
|
CONFIG_NCS_SAMPLES_DEFAULTS=y
|
||||||
|
|
||||||
|
CONFIG_UART_INTERRUPT_DRIVEN=y
|
||||||
|
CONFIG_SERIAL=y
|
||||||
|
CONFIG_GPIO=y
|
||||||
|
|
||||||
|
# Make sure printk is not printing to the UART console
|
||||||
|
CONFIG_CONSOLE=y
|
||||||
|
CONFIG_UART_CONSOLE=y
|
||||||
|
|
||||||
|
CONFIG_HEAP_MEM_POOL_SIZE=2048
|
||||||
|
CONFIG_MAIN_THREAD_PRIORITY=7
|
||||||
|
|
||||||
|
CONFIG_ZIGBEE=y
|
||||||
|
CONFIG_ZIGBEE_APP_UTILS=y
|
||||||
|
CONFIG_ZIGBEE_ROLE_ROUTER=y
|
||||||
|
|
||||||
|
# Enable DK LED and Buttons library
|
||||||
|
CONFIG_DK_LIBRARY=y
|
||||||
|
|
||||||
|
# This example requires more workqueue stack
|
||||||
|
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
|
||||||
|
|
||||||
|
# Enable nRF ECB driver
|
||||||
|
CONFIG_CRYPTO=y
|
||||||
|
CONFIG_CRYPTO_NRF_ECB=y
|
||||||
|
CONFIG_CRYPTO_INIT_PRIORITY=80
|
||||||
|
|
||||||
|
# Networking
|
||||||
|
CONFIG_NET_IPV6_MLD=n
|
||||||
|
CONFIG_NET_IPV6_NBR_CACHE=n
|
||||||
|
CONFIG_NET_IPV6_RA_RDNSS=n
|
||||||
|
CONFIG_NET_IP_ADDR_CHECK=n
|
||||||
|
CONFIG_NET_UDP=n
|
||||||
|
|
||||||
|
# Get Zigbee to scan every channel.
|
||||||
|
CONFIG_ZIGBEE_CHANNEL_SELECTION_MODE_MULTI=y
|
||||||
245
code/nrf-connect/samples/zigbee/src/main.c
Normal file
245
code/nrf-connect/samples/zigbee/src/main.c
Normal file
|
|
@ -0,0 +1,245 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 Nordic Semiconductor ASA
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file
|
||||||
|
*
|
||||||
|
* @brief Zigbee application template.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zephyr/kernel.h>
|
||||||
|
#include <zephyr/logging/log.h>
|
||||||
|
#include <dk_buttons_and_leds.h>
|
||||||
|
|
||||||
|
#include <zboss_api.h>
|
||||||
|
#include <zigbee/zigbee_error_handler.h>
|
||||||
|
#include <zigbee/zigbee_app_utils.h>
|
||||||
|
#include <zb_nrf_platform.h>
|
||||||
|
#include "zb_range_extender.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Device endpoint, used to receive ZCL commands. */
|
||||||
|
#define APP_TEMPLATE_ENDPOINT 10
|
||||||
|
|
||||||
|
/* Type of power sources available for the device.
|
||||||
|
* For possible values see section 3.2.2.2.8 of ZCL specification.
|
||||||
|
*/
|
||||||
|
#define TEMPLATE_INIT_BASIC_POWER_SOURCE ZB_ZCL_BASIC_POWER_SOURCE_DC_SOURCE
|
||||||
|
|
||||||
|
/* LED indicating that device successfully joined Zigbee network. */
|
||||||
|
#define ZIGBEE_NETWORK_STATE_LED DK_LED3
|
||||||
|
|
||||||
|
/* LED used for device identification. */
|
||||||
|
#define IDENTIFY_LED DK_LED4
|
||||||
|
|
||||||
|
/* Button used to enter the Identify mode. */
|
||||||
|
#define IDENTIFY_MODE_BUTTON DK_BTN4_MSK
|
||||||
|
|
||||||
|
/* Button to start Factory Reset */
|
||||||
|
#define FACTORY_RESET_BUTTON IDENTIFY_MODE_BUTTON
|
||||||
|
|
||||||
|
LOG_MODULE_REGISTER(app, LOG_LEVEL_INF);
|
||||||
|
|
||||||
|
/* Main application customizable context.
|
||||||
|
* Stores all settings and static values.
|
||||||
|
*/
|
||||||
|
struct zb_device_ctx {
|
||||||
|
zb_zcl_basic_attrs_t basic_attr;
|
||||||
|
zb_zcl_identify_attrs_t identify_attr;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Zigbee device application context storage. */
|
||||||
|
static struct zb_device_ctx dev_ctx;
|
||||||
|
|
||||||
|
ZB_ZCL_DECLARE_IDENTIFY_ATTRIB_LIST(
|
||||||
|
identify_attr_list,
|
||||||
|
&dev_ctx.identify_attr.identify_time);
|
||||||
|
|
||||||
|
ZB_ZCL_DECLARE_BASIC_ATTRIB_LIST(
|
||||||
|
basic_attr_list,
|
||||||
|
&dev_ctx.basic_attr.zcl_version,
|
||||||
|
&dev_ctx.basic_attr.power_source);
|
||||||
|
|
||||||
|
ZB_DECLARE_RANGE_EXTENDER_CLUSTER_LIST(
|
||||||
|
app_template_clusters,
|
||||||
|
basic_attr_list,
|
||||||
|
identify_attr_list);
|
||||||
|
|
||||||
|
ZB_DECLARE_RANGE_EXTENDER_EP(
|
||||||
|
app_template_ep,
|
||||||
|
APP_TEMPLATE_ENDPOINT,
|
||||||
|
app_template_clusters);
|
||||||
|
|
||||||
|
ZBOSS_DECLARE_DEVICE_CTX_1_EP(
|
||||||
|
app_template_ctx,
|
||||||
|
app_template_ep);
|
||||||
|
|
||||||
|
|
||||||
|
/**@brief Function for initializing all clusters attributes. */
|
||||||
|
static void app_clusters_attr_init(void)
|
||||||
|
{
|
||||||
|
/* Basic cluster attributes data */
|
||||||
|
dev_ctx.basic_attr.zcl_version = ZB_ZCL_VERSION;
|
||||||
|
dev_ctx.basic_attr.power_source = TEMPLATE_INIT_BASIC_POWER_SOURCE;
|
||||||
|
|
||||||
|
/* Identify cluster attributes data. */
|
||||||
|
dev_ctx.identify_attr.identify_time =
|
||||||
|
ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**@brief Function to toggle the identify LED
|
||||||
|
*
|
||||||
|
* @param bufid Unused parameter, required by ZBOSS scheduler API.
|
||||||
|
*/
|
||||||
|
static void toggle_identify_led(zb_bufid_t bufid)
|
||||||
|
{
|
||||||
|
static int blink_status;
|
||||||
|
|
||||||
|
dk_set_led(IDENTIFY_LED, (++blink_status) % 2);
|
||||||
|
ZB_SCHEDULE_APP_ALARM(toggle_identify_led, bufid, ZB_MILLISECONDS_TO_BEACON_INTERVAL(100));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**@brief Function to handle identify notification events on the first endpoint.
|
||||||
|
*
|
||||||
|
* @param bufid Unused parameter, required by ZBOSS scheduler API.
|
||||||
|
*/
|
||||||
|
static void identify_cb(zb_bufid_t bufid)
|
||||||
|
{
|
||||||
|
zb_ret_t zb_err_code;
|
||||||
|
|
||||||
|
if (bufid) {
|
||||||
|
/* Schedule a self-scheduling function that will toggle the LED */
|
||||||
|
ZB_SCHEDULE_APP_CALLBACK(toggle_identify_led, bufid);
|
||||||
|
} else {
|
||||||
|
/* Cancel the toggling function alarm and turn off LED */
|
||||||
|
zb_err_code = ZB_SCHEDULE_APP_ALARM_CANCEL(toggle_identify_led, ZB_ALARM_ANY_PARAM);
|
||||||
|
ZVUNUSED(zb_err_code);
|
||||||
|
|
||||||
|
dk_set_led(IDENTIFY_LED, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**@brief Starts identifying the device.
|
||||||
|
*
|
||||||
|
* @param bufid Unused parameter, required by ZBOSS scheduler API.
|
||||||
|
*/
|
||||||
|
static void start_identifying(zb_bufid_t bufid)
|
||||||
|
{
|
||||||
|
ZVUNUSED(bufid);
|
||||||
|
|
||||||
|
if (ZB_JOINED()) {
|
||||||
|
/* Check if endpoint is in identifying mode,
|
||||||
|
* if not put desired endpoint in identifying mode.
|
||||||
|
*/
|
||||||
|
if (dev_ctx.identify_attr.identify_time ==
|
||||||
|
ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE) {
|
||||||
|
|
||||||
|
zb_ret_t zb_err_code = zb_bdb_finding_binding_target(
|
||||||
|
APP_TEMPLATE_ENDPOINT);
|
||||||
|
|
||||||
|
if (zb_err_code == RET_OK) {
|
||||||
|
LOG_INF("Enter identify mode");
|
||||||
|
} else if (zb_err_code == RET_INVALID_STATE) {
|
||||||
|
LOG_WRN("RET_INVALID_STATE - Cannot enter identify mode");
|
||||||
|
} else {
|
||||||
|
ZB_ERROR_CHECK(zb_err_code);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOG_INF("Cancel identify mode");
|
||||||
|
zb_bdb_finding_binding_target_cancel();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOG_WRN("Device not in a network - cannot enter identify mode");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**@brief Callback for button events.
|
||||||
|
*
|
||||||
|
* @param[in] button_state Bitmask containing buttons state.
|
||||||
|
* @param[in] has_changed Bitmask containing buttons
|
||||||
|
* that have changed their state.
|
||||||
|
*/
|
||||||
|
static void button_changed(uint32_t button_state, uint32_t has_changed)
|
||||||
|
{
|
||||||
|
if (IDENTIFY_MODE_BUTTON & has_changed) {
|
||||||
|
if (IDENTIFY_MODE_BUTTON & button_state) {
|
||||||
|
/* Button changed its state to pressed */
|
||||||
|
} else {
|
||||||
|
/* Button changed its state to released */
|
||||||
|
if (was_factory_reset_done()) {
|
||||||
|
/* The long press was for Factory Reset */
|
||||||
|
LOG_DBG("After Factory Reset - ignore button release");
|
||||||
|
} else {
|
||||||
|
/* Button released before Factory Reset */
|
||||||
|
|
||||||
|
/* Start identification mode */
|
||||||
|
ZB_SCHEDULE_APP_CALLBACK(start_identifying, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
check_factory_reset_button(button_state, has_changed);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**@brief Function for initializing LEDs and Buttons. */
|
||||||
|
static void configure_gpio(void)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = dk_buttons_init(button_changed);
|
||||||
|
if (err) {
|
||||||
|
LOG_ERR("Cannot init buttons (err: %d)", err);
|
||||||
|
}
|
||||||
|
|
||||||
|
err = dk_leds_init();
|
||||||
|
if (err) {
|
||||||
|
LOG_ERR("Cannot init LEDs (err: %d)", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**@brief Zigbee stack event handler.
|
||||||
|
*
|
||||||
|
* @param[in] bufid Reference to the Zigbee stack buffer
|
||||||
|
* used to pass signal.
|
||||||
|
*/
|
||||||
|
void zboss_signal_handler(zb_bufid_t bufid)
|
||||||
|
{
|
||||||
|
/* Update network status LED. */
|
||||||
|
zigbee_led_status_update(bufid, ZIGBEE_NETWORK_STATE_LED);
|
||||||
|
|
||||||
|
/* No application-specific behavior is required.
|
||||||
|
* Call default signal handler.
|
||||||
|
*/
|
||||||
|
ZB_ERROR_CHECK(zigbee_default_signal_handler(bufid));
|
||||||
|
|
||||||
|
/* All callbacks should either reuse or free passed buffers.
|
||||||
|
* If bufid == 0, the buffer is invalid (not passed).
|
||||||
|
*/
|
||||||
|
if (bufid) {
|
||||||
|
zb_buf_free(bufid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
LOG_INF("Starting Zigbee application template example");
|
||||||
|
|
||||||
|
/* Initialize */
|
||||||
|
configure_gpio();
|
||||||
|
register_factory_reset_button(FACTORY_RESET_BUTTON);
|
||||||
|
|
||||||
|
/* Register device context (endpoints). */
|
||||||
|
ZB_AF_REGISTER_DEVICE_CTX(&app_template_ctx);
|
||||||
|
|
||||||
|
app_clusters_attr_init();
|
||||||
|
|
||||||
|
/* Register handlers to identify notifications */
|
||||||
|
ZB_AF_SET_IDENTIFY_NOTIFICATION_HANDLER(APP_TEMPLATE_ENDPOINT, identify_cb);
|
||||||
|
|
||||||
|
/* Start Zigbee default thread */
|
||||||
|
zigbee_enable();
|
||||||
|
|
||||||
|
LOG_INF("Zigbee application template started");
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue