ZB_HA_DECLARE_TEMPERATURE_SENSOR_CLUSTER_LIST not working/declared

Hi everybody,

I'm just getting into Zigbee and try to follow the example at https://docs.nordicsemi.com/bundle/ncs-2.5.1/page/nrf/protocols/zigbee/adding_clusters.html to learn how to add clusters. The ONOFF cluster works, but with the temperature cluster, I got a problem. Output is:

 *  Executing task: nRF Connect: Build: template/build (active) 

Building template
west build --build-dir /home/iteedi/ncs/v2.6.1/nrf/samples/zigbee/template/build /home/iteedi/ncs/v2.6.1/nrf/samples/zigbee/template

[1/9] Building C object CMakeFiles/app.dir/src/main.c.obj
FAILED: CMakeFiles/app.dir/src/main.c.obj 
ccache /home/iteedi/ncs/toolchains/2be090971e/opt/zephyr-sdk/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc -DCUSTOM_IEEE802154_L2=ZIGBEE_L2 -DKERNEL -DLIBZBOSS_CONFIG_FILE=\"/home/iteedi/ncs/v2.6.1/nrfxlib/zboss/production/include/osif/libzboss_config.h\" -DNRF52840_XXAA -DNRF_802154_ACK_TIMEOUT_ENABLED=1 -DNRF_802154_CARRIER_FUNCTIONS_ENABLED=0 -DNRF_802154_CCA_CORR_LIMIT_DEFAULT=2 -DNRF_802154_CCA_CORR_THRESHOLD_DEFAULT=45 -DNRF_802154_CCA_ED_THRESHOLD_DEFAULT=45 -DNRF_802154_CCA_MODE_DEFAULT=NRF_RADIO_CCA_MODE_ED -DNRF_802154_ECB_PRIORITY=-1 -DNRF_802154_ENCRYPTION_ENABLED=0 -DNRF_802154_ENERGY_DETECTED_VERSION=1 -DNRF_802154_IE_WRITER_ENABLED=0 -DNRF_802154_INTERNAL_RADIO_IRQ_HANDLING=0 -DNRF_802154_PENDING_EXTENDED_ADDRESSES=16 -DNRF_802154_PENDING_SHORT_ADDRESSES=16 -DNRF_802154_PLATFORM_ASSERT_INCLUDE=\"nrf_802154_assert_zephyr.h\" -DNRF_802154_RX_BUFFERS=16 -DNRF_802154_SECURITY_KEY_STORAGE_SIZE=3 -DNRF_802154_SECURITY_WRITER_ENABLED=0 -DNRF_802154_SERIALIZATION_HOST=0 -DNRF_802154_SWI_PRIORITY=1 -DNRF_802154_TX_STARTED_NOTIFY_ENABLED=1 -DNRF_802154_USE_RAW_API=1 -DUSE_PARTITION_MANAGER=1 -DZIGBEE_L2=ZIGBEE -D__PROGRAM_START -D__ZEPHYR__=1 -I/home/iteedi/ncs/v2.6.1/nrf/samples/zigbee/template/include -I/home/iteedi/ncs/v2.6.1/nrf/drivers/mpsl/clock_control -I/home/iteedi/ncs/v2.6.1/zephyr/include -I/home/iteedi/ncs/v2.6.1/nrf/samples/zigbee/template/build/zephyr/include/generated -I/home/iteedi/ncs/v2.6.1/zephyr/soc/arm/nordic_nrf/nrf52 -I/home/iteedi/ncs/v2.6.1/zephyr/soc/common/nordic_nrf/. -I/home/iteedi/ncs/v2.6.1/zephyr/soc/arm/nordic_nrf/common/. -I/home/iteedi/ncs/v2.6.1/nrf/include -I/home/iteedi/ncs/v2.6.1/nrf/lib/multithreading_lock/. -I/home/iteedi/ncs/v2.6.1/zephyr/drivers/flash -I/home/iteedi/ncs/v2.6.1/nrf/tests/include -I/home/iteedi/ncs/v2.6.1/modules/hal/cmsis/CMSIS/Core/Include -I/home/iteedi/ncs/v2.6.1/zephyr/modules/cmsis/. -I/home/iteedi/ncs/v2.6.1/modules/hal/nordic/nrfx -I/home/iteedi/ncs/v2.6.1/modules/hal/nordic/nrfx/drivers/include -I/home/iteedi/ncs/v2.6.1/modules/hal/nordic/nrfx/mdk -I/home/iteedi/ncs/v2.6.1/zephyr/modules/hal_nordic/nrfx/. -I/home/iteedi/ncs/v2.6.1/modules/debug/segger/SEGGER -I/home/iteedi/ncs/v2.6.1/modules/debug/segger/Config -I/home/iteedi/ncs/v2.6.1/nrfxlib/mpsl/fem/common/include -I/home/iteedi/ncs/v2.6.1/nrfxlib/mpsl/fem/nrf21540_gpio/include -I/home/iteedi/ncs/v2.6.1/nrfxlib/mpsl/fem/nrf21540_gpio_spi/include -I/home/iteedi/ncs/v2.6.1/nrfxlib/mpsl/fem/simple_gpio/include -I/home/iteedi/ncs/v2.6.1/nrfxlib/mpsl/fem/include -I/home/iteedi/ncs/v2.6.1/nrfxlib/mpsl/fem/include/protocol -I/home/iteedi/ncs/v2.6.1/nrfxlib/mpsl/include -I/home/iteedi/ncs/v2.6.1/nrfxlib/mpsl/include/protocol -I/home/iteedi/ncs/v2.6.1/nrfxlib/nrf_802154/driver/include -I/home/iteedi/ncs/v2.6.1/nrfxlib/nrf_802154/sl/include -I/home/iteedi/ncs/v2.6.1/nrfxlib/nrf_802154/common/include -I/home/iteedi/ncs/v2.6.1/zephyr/modules/hal_nordic/nrf_802154/include -I/home/iteedi/ncs/v2.6.1/nrf/subsys/zigbee/osif -I/home/iteedi/ncs/v2.6.1/nrfxlib/zboss/production/src/zb_error -I/home/iteedi/ncs/v2.6.1/nrfxlib/zboss/production/include/addons -I/home/iteedi/ncs/v2.6.1/nrfxlib/zboss/production/include -I/home/iteedi/ncs/v2.6.1/nrfxlib/zboss/production/include/zcl -I/home/iteedi/ncs/v2.6.1/nrfxlib/zboss/production/include/ha -I/home/iteedi/ncs/v2.6.1/nrfxlib/zboss/production/include/se -I/home/iteedi/ncs/v2.6.1/nrfxlib/zboss/production/include/osif -isystem /home/iteedi/ncs/v2.6.1/zephyr/lib/libc/minimal/include -isystem /home/iteedi/ncs/v2.6.1/zephyr/lib/libc/common/include -isystem /home/iteedi/ncs/toolchains/2be090971e/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/include -isystem /home/iteedi/ncs/toolchains/2be090971e/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/include-fixed -isystem /home/iteedi/ncs/v2.6.1/nrfxlib/crypto/nrf_cc310_platform/include -fno-strict-aliasing -Os -imacros /home/iteedi/ncs/v2.6.1/nrf/samples/zigbee/template/build/zephyr/include/generated/autoconf.h -ffreestanding -fno-common -g -gdwarf-4 -fdiagnostics-color=always -mcpu=cortex-m4 -mthumb -mabi=aapcs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mfp16-format=ieee --sysroot=/home/iteedi/ncs/toolchains/2be090971e/opt/zephyr-sdk/arm-zephyr-eabi/arm-zephyr-eabi -imacros /home/iteedi/ncs/v2.6.1/zephyr/include/zephyr/toolchain/zephyr_stdint.h -Wall -Wformat -Wformat-security -Wno-format-zero-length -Wno-pointer-sign -Wpointer-arith -Wexpansion-to-defined -Wno-unused-but-set-variable -Werror=implicit-int -fno-pic -fno-pie -fno-asynchronous-unwind-tables -fno-reorder-functions --param=min-pagesize=0 -fno-defer-pop -fmacro-prefix-map=/home/iteedi/ncs/v2.6.1/nrf/samples/zigbee/template=CMAKE_SOURCE_DIR -fmacro-prefix-map=/home/iteedi/ncs/v2.6.1/zephyr=ZEPHYR_BASE -fmacro-prefix-map=/home/iteedi/ncs/v2.6.1=WEST_TOPDIR -ffunction-sections -fdata-sections -std=c99 -nostdinc -Wno-packed-bitfield-compat -MD -MT CMakeFiles/app.dir/src/main.c.obj -MF CMakeFiles/app.dir/src/main.c.obj.d -o CMakeFiles/app.dir/src/main.c.obj -c /home/iteedi/ncs/v2.6.1/nrf/samples/zigbee/template/src/main.c
/home/iteedi/ncs/v2.6.1/nrf/samples/zigbee/template/src/main.c:103:1: warning: data definition has no type or storage class
  103 | ZB_HA_DECLARE_TEMPERATURE_SENSOR_CLUSTER_LIST(temperature_sensor_clusters, basic_attr_list, identify_attr_list, temp_measurement_attr_list);
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/iteedi/ncs/v2.6.1/nrf/samples/zigbee/template/src/main.c:103:1: error: type defaults to 'int' in declaration of 'ZB_HA_DECLARE_TEMPERATURE_SENSOR_CLUSTER_LIST' [-Werror=implicit-int]
/home/iteedi/ncs/v2.6.1/nrf/samples/zigbee/template/src/main.c:103:1: warning: parameter names (without types) in function declaration
/home/iteedi/ncs/v2.6.1/nrf/samples/zigbee/template/src/main.c:105:59: error: expected ')' before numeric constant
  105 | ZB_HA_DECLARE_TEMPERATURE_SENSOR_EP(temperature_sensor_ep, TEMPERATURE_SENSOR_ENDPOINT, temperature_sensor_clusters);
      |                                                           ^
      |                                                           )
In file included from /home/iteedi/ncs/v2.6.1/nrfxlib/zboss/production/include/zboss_api.h:52,
                 from /home/iteedi/ncs/v2.6.1/nrf/samples/zigbee/template/src/main.c:16:
/home/iteedi/ncs/v2.6.1/nrf/samples/zigbee/template/src/main.c:107:49: error: 'temperature_sensor_ep' undeclared here (not in a function)
  107 | ZBOSS_DECLARE_DEVICE_CTX_3_EP(app_template_ctx, temperature_sensor_ep, on_off_switch_ep, app_template_ep);
      |                                                 ^~~~~~~~~~~~~~~~~~~~~
/home/iteedi/ncs/v2.6.1/nrfxlib/zboss/production/include/zboss_api_af.h:604:6: note: in definition of macro 'ZBOSS_DECLARE_DEVICE_CTX_3_EP'
  604 |     &ep1_name,                                                          \
      |      ^~~~~~~~
cc1: some warnings being treated as errors
ninja: build stopped: subcommand failed.
FATAL ERROR: command exited with status 1: /home/iteedi/ncs/toolchains/2be090971e/usr/local/bin/cmake --build /home/iteedi/ncs/v2.6.1/nrf/samples/zigbee/template/build

 *  The terminal process terminated with exit code: 1. 
 *  Terminal will be reused by tasks, press any key to close it. 

I looked for the declaration of ZB_HA_DECLARE_TEMPERATURE_SENSOR_CLUSTER_LIST, but I could not find it (but I could find the declaration of ZB_HA_DECLARE_ON_OFF_SWITCH_CLUSTER_LIST).

My code looks like this:

/*
 * 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 <zboss_api_addons.h>
#include <zigbee/zigbee_error_handler.h>
#include <zigbee/zigbee_app_utils.h>
#include <zb_nrf_platform.h>
#include <addons/zcl/zb_zcl_temp_measurement_addons.h>
#include "zb_range_extender.h"

/* Device endpoint, used to receive ZCL commands. */
#define APP_TEMPLATE_ENDPOINT 10

/* OnOff switch endpoint*/
#define ON_OFF_SWITCH_ENDPOINT 11

/* Temperature sensor endpoint*/
#define TEMPERATURE_SENSOR_ENDPOINT 12

/* Device Infos*/
#define TEMPLATE_INIT_BASIC_MANUF_NAME	  "Iten Engineering"
#define TEMPLATE_INIT_BASIC_MODEL_ID	  "Template 1.0"
#define TEMPLATE_INIT_BASIC_DATE_CODE	  "20240714"
#define TEMPLATE_INIT_BASIC_LOCATION_DESC "Somewhere"
#define TEMPLATE_INIT_BASIC_PH_ENV	  ZB_ZCL_BASIC_ENV_UNSPECIFIED

/* 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_BATTERY

/* LED indicating that device successfully joined Zigbee network. */
#define ZIGBEE_NETWORK_STATE_LED DK_LED1

/* 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_ext_t basic_attr;
	zb_zcl_identify_attrs_t identify_attr;
	zb_uint8_t on_off_switch_type_attr;
	zb_uint8_t on_off_switch_actions_attr;
	zb_zcl_temp_measurement_attrs_t temp_measure_attrs;
};

/* 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_EXT(basic_attr_list, &dev_ctx.basic_attr.zcl_version,
				     &dev_ctx.basic_attr.app_version,
				     &dev_ctx.basic_attr.stack_version,
				     &dev_ctx.basic_attr.hw_version, dev_ctx.basic_attr.mf_name,
				     dev_ctx.basic_attr.model_id, dev_ctx.basic_attr.date_code,
				     &dev_ctx.basic_attr.power_source,
				     dev_ctx.basic_attr.location_id, &dev_ctx.basic_attr.ph_env,
				     dev_ctx.basic_attr.sw_ver);

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);

ZB_ZCL_DECLARE_ON_OFF_SWITCH_CONFIGURATION_ATTRIB_LIST(
        on_off_switch_attr_list,
        &dev_ctx.on_off_switch_type_attr, &dev_ctx.on_off_switch_actions_attr);

ZB_HA_DECLARE_ON_OFF_SWITCH_CLUSTER_LIST(on_off_switch_clusters,
        on_off_switch_attr_list, basic_attr_list, identify_attr_list);

ZB_HA_DECLARE_ON_OFF_SWITCH_EP(on_off_switch_ep, ON_OFF_SWITCH_ENDPOINT, on_off_switch_clusters);

ZB_ZCL_DECLARE_TEMP_MEASUREMENT_ATTRIB_LIST(temp_measurement_attr_list,
                                            &dev_ctx.temp_measure_attrs.measure_value,
                                            &dev_ctx.temp_measure_attrs.min_measure_value,
                                            &dev_ctx.temp_measure_attrs.max_measure_value,
                                            &dev_ctx.temp_measure_attrs.tolerance);

ZB_HA_DECLARE_TEMPERATURE_SENSOR_CLUSTER_LIST(temperature_sensor_clusters, basic_attr_list, identify_attr_list, temp_measurement_attr_list);

ZB_HA_DECLARE_TEMPERATURE_SENSOR_EP(temperature_sensor_ep, TEMPERATURE_SENSOR_ENDPOINT, temperature_sensor_clusters);

ZBOSS_DECLARE_DEVICE_CTX_3_EP(app_template_ctx, temperature_sensor_ep, on_off_switch_ep, 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.app_version = 1;
	dev_ctx.basic_attr.stack_version = 10;
	dev_ctx.basic_attr.hw_version = 1;
	dev_ctx.basic_attr.power_source = TEMPLATE_INIT_BASIC_POWER_SOURCE;

	/* Use ZB_ZCL_SET_STRING_VAL to set strings, because the first byte
	 * should contain string length without trailing zero.
	 *
	 * For example "test" string will be encoded as:
	 *   [(0x4), 't', 'e', 's', 't']
	 */
	ZB_ZCL_SET_STRING_VAL(dev_ctx.basic_attr.mf_name, "Iten Engineering",
			      ZB_ZCL_STRING_CONST_SIZE("Iten Engineering"));

	ZB_ZCL_SET_STRING_VAL(dev_ctx.basic_attr.model_id, TEMPLATE_INIT_BASIC_MODEL_ID,
			      ZB_ZCL_STRING_CONST_SIZE(TEMPLATE_INIT_BASIC_MODEL_ID));

	ZB_ZCL_SET_STRING_VAL(dev_ctx.basic_attr.date_code, TEMPLATE_INIT_BASIC_DATE_CODE,
			      ZB_ZCL_STRING_CONST_SIZE(TEMPLATE_INIT_BASIC_DATE_CODE));

	dev_ctx.basic_attr.power_source = TEMPLATE_INIT_BASIC_POWER_SOURCE;

	ZB_ZCL_SET_STRING_VAL(dev_ctx.basic_attr.location_id, TEMPLATE_INIT_BASIC_LOCATION_DESC,
			      ZB_ZCL_STRING_CONST_SIZE(TEMPLATE_INIT_BASIC_LOCATION_DESC));

	dev_ctx.basic_attr.ph_env = TEMPLATE_INIT_BASIC_PH_ENV;

	/* 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);
	}
}

int 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");

	return 0;
}

Any ideas or hints? It seems that lot of the HA stuff is missing in the included ZBOSS:

Regards, Edi

Parents
  • Hi,

    Just to exclude one thing: I see that you're following the documentation for NCS v2.5.1 while you're working in NCS v2.6.1. Could you verify if you see the same by following the documentation matching to the version you're building for?

    Kind regards,
    Andreas

  • Hi , thanks for pointing that out. I started at docs.nordicsemi.com/.../adding_clusters.html and looked in older versions if there was a change.

    But as you mentioned it, I think there might be a bug in the documentation. On top of the page (Version 2.6.1) you can select other versions, for example 2.5.3. But then, you can't go back to 2.6.1 in this selector. Strange...

    I try to reverse-engineer the weather station example.

  • Hi, 

    Eduard Iten said:
    But as you mentioned it, I think there might be a bug in the documentation. On top of the page (Version 2.6.1) you can select other versions, for example 2.5.3. But then, you can't go back to 2.6.1 in this selector. Strange...

    Yeah, this is a known issue.. The linking on the new doc page is not 100% up and running yet. Apologies for that. A temporary workaround is to change ncs-2.5.1 to for instance ncs-2.6.1 or ncs-latest to avoid having to go back to the start page where all of the instances are availalbe from the drop down menu   

    I assume that the documentation were similar in both pages? I've unfortunately not got time go through the guide for both versions to verify, but if there are no difference the issue might require a reproduction.

    The Temperature Sensor API for HA devices can be seen here https://developer.nordicsemi.com/nRF_Connect_SDK/doc/zboss/3.11.3.0/group__ha__temperature__sensor.html, but it is as you say rather limited, unfortunately.

    Kind regards,
    Andreas

  • Hi,

    yes, the pages for 2.5.3 and 2.6.1 are identical. The defines on the link you mentioned do not exist, at least grep -r "ZB_HA_DECLARE_TEMPERATURE_SENSOR_CLUSTER_LIST" ncs/v2.6.1/ only yields results to the documentation:

    ncs/v2.6.1/nrf/doc/nrf/protocols/zigbee/adding_clusters.rst:This time, we are going to use the `ZB_HA_DECLARE_TEMPERATURE_SENSOR_CLUSTER_LIST`_ macro.
    ncs/v2.6.1/nrf/doc/nrf/protocols/zigbee/adding_clusters.rst:        ZB_HA_DECLARE_TEMPERATURE_SENSOR_CLUSTER_LIST(temperature_sensor_clusters, basic_attr_list, identify_attr_list, temp_measurement_attr_list);
    ncs/v2.6.1/nrf/doc/nrf/links.txt:.. _`ZB_HA_DECLARE_TEMPERATURE_SENSOR_CLUSTER_LIST`: https://developer.nordicsemi.com/nRF_Connect_SDK/doc/zboss/3.11.3.0/group__ha__temperature__sensor.html#ga1baeb195bbce720ee97cf9c879726cbb

    However, if someone else is looking for this, I came up with the following solution (after analyzing the Zigbee Weather Station sample for Thingy:53):

    I copied the zigbee template folder. In main.c, I have now

    /*
     * 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 <zboss_api_addons.h>
    #include <zigbee/zigbee_error_handler.h>
    #include <zigbee/zigbee_app_utils.h>
    #include <zb_nrf_platform.h>
    #include "zb_range_extender.h"
    #include "temp_sensor.h"
    
    /* Time of LED on state while blinking for identify mode */
    #define IDENTIFY_LED_BLINK_TIME_MSEC 500
    /* Weather check period */
    #define TEMP_CHECK_PERIOD_MSEC (1000 * CONFIG_TEMP_CHECK_PERIOD_SECONDS)
    
    /* Delay for first weather check */
    #define TEMP_CHECK_INITIAL_DELAY_MSEC (1000 * CONFIG_FIRST_TEMP_CHECK_DELAY_SECONDS)
    
    /* 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);
    
    /* Zigbee device application context storage. */
    static struct zb_device_ctx dev_ctx;
    
    /* Attributes setup */
    ZB_ZCL_DECLARE_BASIC_ATTRIB_LIST(
    	basic_attr_list,
    	&dev_ctx.basic_attr.zcl_version, &dev_ctx.basic_attr.power_source);
    
    /* Declare attribute list for Identify cluster (client). */
    ZB_ZCL_DECLARE_IDENTIFY_CLIENT_ATTRIB_LIST(identify_client_attr_list);
    
    /* Declare attribute list for Identify cluster (server). */
    ZB_ZCL_DECLARE_IDENTIFY_SERVER_ATTRIB_LIST(identify_server_attr_list, &dev_ctx.identify_attr.identify_time);
    
    ZB_ZCL_DECLARE_TEMP_MEASUREMENT_ATTRIB_LIST(
    	temperature_measurement_attr_list,
    	&dev_ctx.temp_attrs.measure_value,
    	&dev_ctx.temp_attrs.min_measure_value,
    	&dev_ctx.temp_attrs.max_measure_value,
    	&dev_ctx.temp_attrs.tolerance
    	);
    
    // ZB_DECLARE_RANGE_EXTENDER_CLUSTER_LIST(
    // 	app_template_clusters,
    // 	basic_attr_list,
    // 	identify_attr_list);
    
    /* Clusters setup */
    ZB_HA_DECLARE_TEMP_SENSOR_CLUSTER_LIST(
    	temp_sensor_cluster_list,
    	basic_attr_list,
    	identify_client_attr_list,
    	identify_server_attr_list,
    	temperature_measurement_attr_list
    );
    
    /* Endpoint setup (single) */
    ZB_HA_DECLARE_TEMP_SENSOR_EP(
    	temp_sensor_ep,
    	TEMP_SENSOR_ENDPOINT_NB,
    	temp_sensor_cluster_list);
    
    /* Device context */
    ZBOSS_DECLARE_DEVICE_CTX_1_EP(
    	temp_sensor_ctx,
    	temp_sensor_ep);
    
    
    /**@brief Function for initializing mandatory clusters attributes. */
    static void mandatory_clusters_attr_init(void)
    {
    	/* Basic cluster attributes */
    	dev_ctx.basic_attr.zcl_version = ZB_ZCL_VERSION;
    	dev_ctx.basic_attr.power_source = ZB_ZCL_BASIC_POWER_SOURCE_BATTERY;
    
    	/* Identify cluster attributes */
    	dev_ctx.identify_attr.identify_time = ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE;
    }
    
    static void measurements_clusters_attr_init(void)
    {
    	/* Temperature */
    	dev_ctx.temp_attrs.measure_value = ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_UNKNOWN;
    	dev_ctx.temp_attrs.min_measure_value = TEMP_SENSOR_ATTR_TEMP_MIN;
    	dev_ctx.temp_attrs.max_measure_value = TEMP_SENSOR_ATTR_TEMP_MAX;
    	dev_ctx.temp_attrs.tolerance = TEMP_SENSOR_ATTR_TEMP_TOLERANCE;
    }
    
    /**@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 bool led_on;
    
    	led_on = !led_on;
    	dk_set_led(IDENTIFY_LED, led_on);
    	zb_ret_t err = ZB_SCHEDULE_APP_ALARM(toggle_identify_led,
    					     bufid,
    					     ZB_MILLISECONDS_TO_BEACON_INTERVAL(
    						     IDENTIFY_LED_BLINK_TIME_MSEC));
    	if (err) {
    		LOG_ERR("Failed to schedule app alarm: %d", err);
    	}
    }
    
    /**@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(
    				TEMP_SENSOR_ENDPOINT_NB);
    
    			if (zb_err_code == RET_OK) {
    				LOG_INF("Manually 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("Manually cancel identify mode");
    			zb_bdb_finding_binding_target_cancel();
    		}
    	} else {
    		LOG_WRN("Device not in a network - cannot identify itself");
    	}
    }
    
    static void identify_callback(zb_bufid_t bufid)
    {
    	zb_ret_t err = RET_OK;
    
    	if (bufid) {
    		/* Schedule a self-scheduling function that will toggle the LED */
    		err = ZB_SCHEDULE_APP_CALLBACK(toggle_identify_led, bufid);
    		if (err) {
    			LOG_ERR("Failed to schedule app callback: %d", err);
    		} else {
    			LOG_INF("Enter identify mode");
    		}
    	} else {
    		/* Cancel the toggling function alarm and turn off LED */
    		err = ZB_SCHEDULE_APP_ALARM_CANCEL(toggle_identify_led,
    						   ZB_ALARM_ANY_PARAM);
    		if (err) {
    			LOG_ERR("Failed to schedule app alarm cancel: %d", err);
    		} else {
    			dk_set_led_off(IDENTIFY_LED);
    			LOG_INF("Cancel 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_INF("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);
    	}
    }
    
    int update_temperature(void)
    {
    	int err = 0;
    
    	static float measured_temperature = 0.0f;
    	int16_t temperature_attribute = 0;
    
    	measured_temperature += 1.1;
    	if (measured_temperature > 43.0) {
    		measured_temperature = -19.0;
    	}
    
    	/* Convert measured value to attribute value, as specified in ZCL */
    	temperature_attribute = (int16_t)(measured_temperature *
    					  ZCL_TEMPERATURE_MEASUREMENT_MEASURED_VALUE_MULTIPLIER);
    	LOG_INF("Attribute T:%10d", temperature_attribute);
    
    	/* Set ZCL attribute */
    	zb_zcl_status_t status = zb_zcl_set_attr_val(
    		TEMP_SENSOR_ENDPOINT_NB, ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT,
    		ZB_ZCL_CLUSTER_SERVER_ROLE, ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID,
    		(zb_uint8_t *)&temperature_attribute, ZB_FALSE);
    	if (status) {
    		LOG_ERR("Failed to set ZCL attribute: %d", status);
    		err = status;
    	}
    	return err;
    }
    
    static void check_temperature(zb_bufid_t bufid)
    {
    	ZVUNUSED(bufid);
    	int err = update_temperature();
    	if (err) {
    		LOG_ERR("Failed to update temperature: %d", err);
    	}
    	zb_ret_t zb_err = ZB_SCHEDULE_APP_ALARM(
    		check_temperature, 0, ZB_MILLISECONDS_TO_BEACON_INTERVAL(TEMP_CHECK_PERIOD_MSEC));
    	if (zb_err) {
    		LOG_ERR("Failed to schedule app alarm: %d", zb_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)
    {
    	zb_zdo_app_signal_hdr_t *signal_header = NULL;
    	zb_zdo_app_signal_type_t signal = zb_get_app_signal(bufid, &signal_header);
    	zb_ret_t err = RET_OK;
    
    	/* Update network status LED but only for debug configuration */
    	#ifdef CONFIG_LOG
    	zigbee_led_status_update(bufid, ZIGBEE_NETWORK_STATE_LED);
    	#endif /* CONFIG_LOG */
    
    	// LOG_INF("Signal received: #%u", signal);
    	
    	/* Detect ZBOSS startup */
    	switch (signal) {
    	case ZB_ZDO_SIGNAL_SKIP_STARTUP:
    		/* ZBOSS framework has started - schedule first weather check */
    		err = ZB_SCHEDULE_APP_ALARM(check_temperature,
    					    0,
    					    ZB_MILLISECONDS_TO_BEACON_INTERVAL(
    						    TEMP_CHECK_INITIAL_DELAY_MSEC));
    		if (err) {
    			LOG_ERR("Failed to schedule app alarm: %d", err);
    		}
    		break;
    	default:
    		break;
    	}
    
    	/* Let default signal handler process the signal*/
    	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);
    	}
    }
    
    static void zcl_device_cb(zb_bufid_t bufid)
    {
    	zb_uint8_t cluster_id;
    	zb_uint8_t attr_id;
    	zb_zcl_device_callback_param_t  *device_cb_param =
    		ZB_BUF_GET_PARAM(bufid, zb_zcl_device_callback_param_t);
    	LOG_INF("%s status: %hd", __func__, device_cb_param->status);
    }
    
    int main(void)
    {
    	LOG_INF("Starting Zigbee application temperature sensor");
    
    	/* Initialize */
    	configure_gpio();
    	register_factory_reset_button(FACTORY_RESET_BUTTON);
    
    	/* Register callback for handling ZCL commands. */
    	ZB_ZCL_REGISTER_DEVICE_CB(zcl_device_cb);
    
    	/* Register device context (endpoints). */
    	ZB_AF_REGISTER_DEVICE_CTX(&temp_sensor_ctx);
    
    	/* Init Basic and Identify attributes */
    	mandatory_clusters_attr_init();
    
    	/* Init measurements-related attributes */
    	measurements_clusters_attr_init();
    
    	/* Register handlers to identify notifications */
    	ZB_AF_SET_IDENTIFY_NOTIFICATION_HANDLER(TEMP_SENSOR_ENDPOINT_NB, identify_callback);
    
    	// /* Enable Sleepy End Device behavior */
    	// zb_set_rx_on_when_idle(ZB_FALSE);
    	// if (IS_ENABLED(CONFIG_RAM_POWER_DOWN_LIBRARY)) {
    	// 	power_down_unused_ram();
    	// }
    
    	/* Start Zigbee default thread */
    	zigbee_enable();
    
    	LOG_INF("Zigbee application temperature sensor started");
    
    	return 0;
    }

    temp_sensor.h looks like this:

    #ifndef TEMP_SENSOR_H
    #define TEMP_SENSOR_H
    
    #include <zcl/zb_zcl_temp_measurement_addons.h>
    
    /* Device endpoint, used to receive ZCL commands. */
    #define TEMP_SENSOR_ENDPOINT_NB	            10
    /* Temperature sensor device version */
    #define ZB_HA_DEVICE_VER_TEMPERATURE_SENSOR 0
    /* Basic, identify, temperature */
    #define ZB_HA_TEMP_SENSOR_IN_CLUSTER_NUM    3
    /* Identify */
    #define ZB_HA_TEMP_SENSOR_OUT_CLUSTER_NUM   1
    /* Temperature */
    #define ZB_HA_TEMP_SENSOR_REPORT_ATTR_COUNT 1
    
    /* Zigbee Cluster Library 4.4.2.2.1.1: MeasuredValue = 100x temperature in degrees Celsius */
    #define ZCL_TEMPERATURE_MEASUREMENT_MEASURED_VALUE_MULTIPLIER 100
    
    #define SENSOR_TEMP_CELSIUS_MIN	      (-40)
    #define SENSOR_TEMP_CELSIUS_MAX	      (85)
    #define SENSOR_TEMP_CELSIUS_TOLERANCE (1)
    
    #define TEMP_SENSOR_ATTR_TEMP_MIN                                                                  \
    	(SENSOR_TEMP_CELSIUS_MIN * ZCL_TEMPERATURE_MEASUREMENT_MEASURED_VALUE_MULTIPLIER)
    #define TEMP_SENSOR_ATTR_TEMP_MAX                                                                  \
    	(SENSOR_TEMP_CELSIUS_MAX * ZCL_TEMPERATURE_MEASUREMENT_MEASURED_VALUE_MULTIPLIER)
    #define TEMP_SENSOR_ATTR_TEMP_TOLERANCE                                                            \
    	(SENSOR_TEMP_CELSIUS_TOLERANCE * ZCL_TEMPERATURE_MEASUREMENT_MEASURED_VALUE_MULTIPLIER)
    
    #define ZB_HA_DECLARE_TEMP_SENSOR_CLUSTER_LIST(                                                    \
    	cluster_list_name, basic_attr_list, identify_client_attr_list, identify_server_attr_list,  \
    	temperature_measurement_attr_list)                                                         \
    	zb_zcl_cluster_desc_t cluster_list_name[] = {                                              \
    		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),                                    \
    		ZB_ZCL_CLUSTER_DESC(ZB_ZCL_CLUSTER_ID_IDENTIFY,                                    \
    				    ZB_ZCL_ARRAY_SIZE(identify_server_attr_list, zb_zcl_attr_t),   \
    				    (identify_server_attr_list), ZB_ZCL_CLUSTER_SERVER_ROLE,       \
    				    ZB_ZCL_MANUF_CODE_INVALID),                                    \
    		ZB_ZCL_CLUSTER_DESC(                                                               \
    			ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT,                                        \
    			ZB_ZCL_ARRAY_SIZE(temperature_measurement_attr_list, zb_zcl_attr_t),       \
    			(temperature_measurement_attr_list), ZB_ZCL_CLUSTER_SERVER_ROLE,           \
    			ZB_ZCL_MANUF_CODE_INVALID),                                                \
    		ZB_ZCL_CLUSTER_DESC(ZB_ZCL_CLUSTER_ID_IDENTIFY,                                    \
    				    ZB_ZCL_ARRAY_SIZE(identify_client_attr_list, zb_zcl_attr_t),   \
    				    (identify_client_attr_list), ZB_ZCL_CLUSTER_CLIENT_ROLE,       \
    				    ZB_ZCL_MANUF_CODE_INVALID),                                    \
    		ZB_ZCL_CLUSTER_DESC(ZB_ZCL_CLUSTER_ID_IDENTIFY,                                    \
    				    ZB_ZCL_ARRAY_SIZE(identify_client_attr_list, zb_zcl_attr_t),   \
    				    (identify_client_attr_list), ZB_ZCL_CLUSTER_CLIENT_ROLE,       \
    				    ZB_ZCL_MANUF_CODE_INVALID),                                    \
    	}
    
    #define ZB_ZCL_DECLARE_TEMP_SENSOR_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_HA_TEMPERATURE_SENSOR_DEVICE_ID,                               \
    				 ZB_HA_DEVICE_VER_TEMPERATURE_SENSOR,                              \
    				 0,                                                                \
    				 in_clust_num,                                                     \
    				 out_clust_num,                                                    \
    				 {                                                                 \
    					 ZB_ZCL_CLUSTER_ID_BASIC,                                  \
    					 ZB_ZCL_CLUSTER_ID_IDENTIFY,                               \
    					 ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT,                       \
    					 ZB_ZCL_CLUSTER_ID_IDENTIFY,                               \
    				 }                                                             \
        }
    
    #define ZB_HA_DECLARE_TEMP_SENSOR_EP(ep_name, ep_id, cluster_list)                                 \
    	ZB_ZCL_DECLARE_TEMP_SENSOR_DESC(ep_name, ep_id, ZB_HA_TEMP_SENSOR_IN_CLUSTER_NUM,          \
    					ZB_HA_TEMP_SENSOR_OUT_CLUSTER_NUM);                        \
    	ZBOSS_DEVICE_DECLARE_REPORTING_CTX(reporting_info##ep_name,                                \
    					   ZB_HA_TEMP_SENSOR_REPORT_ATTR_COUNT);                   \
    	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,                                 \
    		ZB_HA_TEMP_SENSOR_REPORT_ATTR_COUNT, reporting_info##ep_name, 0, NULL)
    
    /* 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;
    	zb_zcl_temp_measurement_attrs_t temp_attrs;
    };
    
    #endif
    

    And prj.conf:

    #
    # Copyright (c) 2021 Nordic Semiconductor ASA
    #
    # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
    #
    CONFIG_LOG=y
    CONFIG_LOG_DEFAULT_LEVEL=3
    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
    CONFIG_ZIGBEE_CHANNEL_SELECTION_MODE_MULTI=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
    
    # If you enable sleepy device, you have to disable the router role above
    # Enable API for powering down unused RAM parts
    CONFIG_RAM_POWER_DOWN_LIBRARY=y
    
    # Networking
    CONFIG_NET_IPV6=n
    CONFIG_NET_IP_ADDR_CHECK=n
    CONFIG_NET_UDP=n
    
    # Troubleshooting
    CONFIG_ZBOSS_HALT_ON_ASSERT=y
    CONFIG_RESET_ON_FATAL_ERROR=n

    But still the question remains if I forgot to install something. Unfortunately, I can't find the original ZBOSS source to verify if the macros that I am missing still exist or what they look like.

Reply
  • Hi,

    yes, the pages for 2.5.3 and 2.6.1 are identical. The defines on the link you mentioned do not exist, at least grep -r "ZB_HA_DECLARE_TEMPERATURE_SENSOR_CLUSTER_LIST" ncs/v2.6.1/ only yields results to the documentation:

    ncs/v2.6.1/nrf/doc/nrf/protocols/zigbee/adding_clusters.rst:This time, we are going to use the `ZB_HA_DECLARE_TEMPERATURE_SENSOR_CLUSTER_LIST`_ macro.
    ncs/v2.6.1/nrf/doc/nrf/protocols/zigbee/adding_clusters.rst:        ZB_HA_DECLARE_TEMPERATURE_SENSOR_CLUSTER_LIST(temperature_sensor_clusters, basic_attr_list, identify_attr_list, temp_measurement_attr_list);
    ncs/v2.6.1/nrf/doc/nrf/links.txt:.. _`ZB_HA_DECLARE_TEMPERATURE_SENSOR_CLUSTER_LIST`: https://developer.nordicsemi.com/nRF_Connect_SDK/doc/zboss/3.11.3.0/group__ha__temperature__sensor.html#ga1baeb195bbce720ee97cf9c879726cbb

    However, if someone else is looking for this, I came up with the following solution (after analyzing the Zigbee Weather Station sample for Thingy:53):

    I copied the zigbee template folder. In main.c, I have now

    /*
     * 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 <zboss_api_addons.h>
    #include <zigbee/zigbee_error_handler.h>
    #include <zigbee/zigbee_app_utils.h>
    #include <zb_nrf_platform.h>
    #include "zb_range_extender.h"
    #include "temp_sensor.h"
    
    /* Time of LED on state while blinking for identify mode */
    #define IDENTIFY_LED_BLINK_TIME_MSEC 500
    /* Weather check period */
    #define TEMP_CHECK_PERIOD_MSEC (1000 * CONFIG_TEMP_CHECK_PERIOD_SECONDS)
    
    /* Delay for first weather check */
    #define TEMP_CHECK_INITIAL_DELAY_MSEC (1000 * CONFIG_FIRST_TEMP_CHECK_DELAY_SECONDS)
    
    /* 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);
    
    /* Zigbee device application context storage. */
    static struct zb_device_ctx dev_ctx;
    
    /* Attributes setup */
    ZB_ZCL_DECLARE_BASIC_ATTRIB_LIST(
    	basic_attr_list,
    	&dev_ctx.basic_attr.zcl_version, &dev_ctx.basic_attr.power_source);
    
    /* Declare attribute list for Identify cluster (client). */
    ZB_ZCL_DECLARE_IDENTIFY_CLIENT_ATTRIB_LIST(identify_client_attr_list);
    
    /* Declare attribute list for Identify cluster (server). */
    ZB_ZCL_DECLARE_IDENTIFY_SERVER_ATTRIB_LIST(identify_server_attr_list, &dev_ctx.identify_attr.identify_time);
    
    ZB_ZCL_DECLARE_TEMP_MEASUREMENT_ATTRIB_LIST(
    	temperature_measurement_attr_list,
    	&dev_ctx.temp_attrs.measure_value,
    	&dev_ctx.temp_attrs.min_measure_value,
    	&dev_ctx.temp_attrs.max_measure_value,
    	&dev_ctx.temp_attrs.tolerance
    	);
    
    // ZB_DECLARE_RANGE_EXTENDER_CLUSTER_LIST(
    // 	app_template_clusters,
    // 	basic_attr_list,
    // 	identify_attr_list);
    
    /* Clusters setup */
    ZB_HA_DECLARE_TEMP_SENSOR_CLUSTER_LIST(
    	temp_sensor_cluster_list,
    	basic_attr_list,
    	identify_client_attr_list,
    	identify_server_attr_list,
    	temperature_measurement_attr_list
    );
    
    /* Endpoint setup (single) */
    ZB_HA_DECLARE_TEMP_SENSOR_EP(
    	temp_sensor_ep,
    	TEMP_SENSOR_ENDPOINT_NB,
    	temp_sensor_cluster_list);
    
    /* Device context */
    ZBOSS_DECLARE_DEVICE_CTX_1_EP(
    	temp_sensor_ctx,
    	temp_sensor_ep);
    
    
    /**@brief Function for initializing mandatory clusters attributes. */
    static void mandatory_clusters_attr_init(void)
    {
    	/* Basic cluster attributes */
    	dev_ctx.basic_attr.zcl_version = ZB_ZCL_VERSION;
    	dev_ctx.basic_attr.power_source = ZB_ZCL_BASIC_POWER_SOURCE_BATTERY;
    
    	/* Identify cluster attributes */
    	dev_ctx.identify_attr.identify_time = ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE;
    }
    
    static void measurements_clusters_attr_init(void)
    {
    	/* Temperature */
    	dev_ctx.temp_attrs.measure_value = ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_UNKNOWN;
    	dev_ctx.temp_attrs.min_measure_value = TEMP_SENSOR_ATTR_TEMP_MIN;
    	dev_ctx.temp_attrs.max_measure_value = TEMP_SENSOR_ATTR_TEMP_MAX;
    	dev_ctx.temp_attrs.tolerance = TEMP_SENSOR_ATTR_TEMP_TOLERANCE;
    }
    
    /**@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 bool led_on;
    
    	led_on = !led_on;
    	dk_set_led(IDENTIFY_LED, led_on);
    	zb_ret_t err = ZB_SCHEDULE_APP_ALARM(toggle_identify_led,
    					     bufid,
    					     ZB_MILLISECONDS_TO_BEACON_INTERVAL(
    						     IDENTIFY_LED_BLINK_TIME_MSEC));
    	if (err) {
    		LOG_ERR("Failed to schedule app alarm: %d", err);
    	}
    }
    
    /**@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(
    				TEMP_SENSOR_ENDPOINT_NB);
    
    			if (zb_err_code == RET_OK) {
    				LOG_INF("Manually 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("Manually cancel identify mode");
    			zb_bdb_finding_binding_target_cancel();
    		}
    	} else {
    		LOG_WRN("Device not in a network - cannot identify itself");
    	}
    }
    
    static void identify_callback(zb_bufid_t bufid)
    {
    	zb_ret_t err = RET_OK;
    
    	if (bufid) {
    		/* Schedule a self-scheduling function that will toggle the LED */
    		err = ZB_SCHEDULE_APP_CALLBACK(toggle_identify_led, bufid);
    		if (err) {
    			LOG_ERR("Failed to schedule app callback: %d", err);
    		} else {
    			LOG_INF("Enter identify mode");
    		}
    	} else {
    		/* Cancel the toggling function alarm and turn off LED */
    		err = ZB_SCHEDULE_APP_ALARM_CANCEL(toggle_identify_led,
    						   ZB_ALARM_ANY_PARAM);
    		if (err) {
    			LOG_ERR("Failed to schedule app alarm cancel: %d", err);
    		} else {
    			dk_set_led_off(IDENTIFY_LED);
    			LOG_INF("Cancel 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_INF("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);
    	}
    }
    
    int update_temperature(void)
    {
    	int err = 0;
    
    	static float measured_temperature = 0.0f;
    	int16_t temperature_attribute = 0;
    
    	measured_temperature += 1.1;
    	if (measured_temperature > 43.0) {
    		measured_temperature = -19.0;
    	}
    
    	/* Convert measured value to attribute value, as specified in ZCL */
    	temperature_attribute = (int16_t)(measured_temperature *
    					  ZCL_TEMPERATURE_MEASUREMENT_MEASURED_VALUE_MULTIPLIER);
    	LOG_INF("Attribute T:%10d", temperature_attribute);
    
    	/* Set ZCL attribute */
    	zb_zcl_status_t status = zb_zcl_set_attr_val(
    		TEMP_SENSOR_ENDPOINT_NB, ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT,
    		ZB_ZCL_CLUSTER_SERVER_ROLE, ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID,
    		(zb_uint8_t *)&temperature_attribute, ZB_FALSE);
    	if (status) {
    		LOG_ERR("Failed to set ZCL attribute: %d", status);
    		err = status;
    	}
    	return err;
    }
    
    static void check_temperature(zb_bufid_t bufid)
    {
    	ZVUNUSED(bufid);
    	int err = update_temperature();
    	if (err) {
    		LOG_ERR("Failed to update temperature: %d", err);
    	}
    	zb_ret_t zb_err = ZB_SCHEDULE_APP_ALARM(
    		check_temperature, 0, ZB_MILLISECONDS_TO_BEACON_INTERVAL(TEMP_CHECK_PERIOD_MSEC));
    	if (zb_err) {
    		LOG_ERR("Failed to schedule app alarm: %d", zb_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)
    {
    	zb_zdo_app_signal_hdr_t *signal_header = NULL;
    	zb_zdo_app_signal_type_t signal = zb_get_app_signal(bufid, &signal_header);
    	zb_ret_t err = RET_OK;
    
    	/* Update network status LED but only for debug configuration */
    	#ifdef CONFIG_LOG
    	zigbee_led_status_update(bufid, ZIGBEE_NETWORK_STATE_LED);
    	#endif /* CONFIG_LOG */
    
    	// LOG_INF("Signal received: #%u", signal);
    	
    	/* Detect ZBOSS startup */
    	switch (signal) {
    	case ZB_ZDO_SIGNAL_SKIP_STARTUP:
    		/* ZBOSS framework has started - schedule first weather check */
    		err = ZB_SCHEDULE_APP_ALARM(check_temperature,
    					    0,
    					    ZB_MILLISECONDS_TO_BEACON_INTERVAL(
    						    TEMP_CHECK_INITIAL_DELAY_MSEC));
    		if (err) {
    			LOG_ERR("Failed to schedule app alarm: %d", err);
    		}
    		break;
    	default:
    		break;
    	}
    
    	/* Let default signal handler process the signal*/
    	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);
    	}
    }
    
    static void zcl_device_cb(zb_bufid_t bufid)
    {
    	zb_uint8_t cluster_id;
    	zb_uint8_t attr_id;
    	zb_zcl_device_callback_param_t  *device_cb_param =
    		ZB_BUF_GET_PARAM(bufid, zb_zcl_device_callback_param_t);
    	LOG_INF("%s status: %hd", __func__, device_cb_param->status);
    }
    
    int main(void)
    {
    	LOG_INF("Starting Zigbee application temperature sensor");
    
    	/* Initialize */
    	configure_gpio();
    	register_factory_reset_button(FACTORY_RESET_BUTTON);
    
    	/* Register callback for handling ZCL commands. */
    	ZB_ZCL_REGISTER_DEVICE_CB(zcl_device_cb);
    
    	/* Register device context (endpoints). */
    	ZB_AF_REGISTER_DEVICE_CTX(&temp_sensor_ctx);
    
    	/* Init Basic and Identify attributes */
    	mandatory_clusters_attr_init();
    
    	/* Init measurements-related attributes */
    	measurements_clusters_attr_init();
    
    	/* Register handlers to identify notifications */
    	ZB_AF_SET_IDENTIFY_NOTIFICATION_HANDLER(TEMP_SENSOR_ENDPOINT_NB, identify_callback);
    
    	// /* Enable Sleepy End Device behavior */
    	// zb_set_rx_on_when_idle(ZB_FALSE);
    	// if (IS_ENABLED(CONFIG_RAM_POWER_DOWN_LIBRARY)) {
    	// 	power_down_unused_ram();
    	// }
    
    	/* Start Zigbee default thread */
    	zigbee_enable();
    
    	LOG_INF("Zigbee application temperature sensor started");
    
    	return 0;
    }

    temp_sensor.h looks like this:

    #ifndef TEMP_SENSOR_H
    #define TEMP_SENSOR_H
    
    #include <zcl/zb_zcl_temp_measurement_addons.h>
    
    /* Device endpoint, used to receive ZCL commands. */
    #define TEMP_SENSOR_ENDPOINT_NB	            10
    /* Temperature sensor device version */
    #define ZB_HA_DEVICE_VER_TEMPERATURE_SENSOR 0
    /* Basic, identify, temperature */
    #define ZB_HA_TEMP_SENSOR_IN_CLUSTER_NUM    3
    /* Identify */
    #define ZB_HA_TEMP_SENSOR_OUT_CLUSTER_NUM   1
    /* Temperature */
    #define ZB_HA_TEMP_SENSOR_REPORT_ATTR_COUNT 1
    
    /* Zigbee Cluster Library 4.4.2.2.1.1: MeasuredValue = 100x temperature in degrees Celsius */
    #define ZCL_TEMPERATURE_MEASUREMENT_MEASURED_VALUE_MULTIPLIER 100
    
    #define SENSOR_TEMP_CELSIUS_MIN	      (-40)
    #define SENSOR_TEMP_CELSIUS_MAX	      (85)
    #define SENSOR_TEMP_CELSIUS_TOLERANCE (1)
    
    #define TEMP_SENSOR_ATTR_TEMP_MIN                                                                  \
    	(SENSOR_TEMP_CELSIUS_MIN * ZCL_TEMPERATURE_MEASUREMENT_MEASURED_VALUE_MULTIPLIER)
    #define TEMP_SENSOR_ATTR_TEMP_MAX                                                                  \
    	(SENSOR_TEMP_CELSIUS_MAX * ZCL_TEMPERATURE_MEASUREMENT_MEASURED_VALUE_MULTIPLIER)
    #define TEMP_SENSOR_ATTR_TEMP_TOLERANCE                                                            \
    	(SENSOR_TEMP_CELSIUS_TOLERANCE * ZCL_TEMPERATURE_MEASUREMENT_MEASURED_VALUE_MULTIPLIER)
    
    #define ZB_HA_DECLARE_TEMP_SENSOR_CLUSTER_LIST(                                                    \
    	cluster_list_name, basic_attr_list, identify_client_attr_list, identify_server_attr_list,  \
    	temperature_measurement_attr_list)                                                         \
    	zb_zcl_cluster_desc_t cluster_list_name[] = {                                              \
    		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),                                    \
    		ZB_ZCL_CLUSTER_DESC(ZB_ZCL_CLUSTER_ID_IDENTIFY,                                    \
    				    ZB_ZCL_ARRAY_SIZE(identify_server_attr_list, zb_zcl_attr_t),   \
    				    (identify_server_attr_list), ZB_ZCL_CLUSTER_SERVER_ROLE,       \
    				    ZB_ZCL_MANUF_CODE_INVALID),                                    \
    		ZB_ZCL_CLUSTER_DESC(                                                               \
    			ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT,                                        \
    			ZB_ZCL_ARRAY_SIZE(temperature_measurement_attr_list, zb_zcl_attr_t),       \
    			(temperature_measurement_attr_list), ZB_ZCL_CLUSTER_SERVER_ROLE,           \
    			ZB_ZCL_MANUF_CODE_INVALID),                                                \
    		ZB_ZCL_CLUSTER_DESC(ZB_ZCL_CLUSTER_ID_IDENTIFY,                                    \
    				    ZB_ZCL_ARRAY_SIZE(identify_client_attr_list, zb_zcl_attr_t),   \
    				    (identify_client_attr_list), ZB_ZCL_CLUSTER_CLIENT_ROLE,       \
    				    ZB_ZCL_MANUF_CODE_INVALID),                                    \
    		ZB_ZCL_CLUSTER_DESC(ZB_ZCL_CLUSTER_ID_IDENTIFY,                                    \
    				    ZB_ZCL_ARRAY_SIZE(identify_client_attr_list, zb_zcl_attr_t),   \
    				    (identify_client_attr_list), ZB_ZCL_CLUSTER_CLIENT_ROLE,       \
    				    ZB_ZCL_MANUF_CODE_INVALID),                                    \
    	}
    
    #define ZB_ZCL_DECLARE_TEMP_SENSOR_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_HA_TEMPERATURE_SENSOR_DEVICE_ID,                               \
    				 ZB_HA_DEVICE_VER_TEMPERATURE_SENSOR,                              \
    				 0,                                                                \
    				 in_clust_num,                                                     \
    				 out_clust_num,                                                    \
    				 {                                                                 \
    					 ZB_ZCL_CLUSTER_ID_BASIC,                                  \
    					 ZB_ZCL_CLUSTER_ID_IDENTIFY,                               \
    					 ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT,                       \
    					 ZB_ZCL_CLUSTER_ID_IDENTIFY,                               \
    				 }                                                             \
        }
    
    #define ZB_HA_DECLARE_TEMP_SENSOR_EP(ep_name, ep_id, cluster_list)                                 \
    	ZB_ZCL_DECLARE_TEMP_SENSOR_DESC(ep_name, ep_id, ZB_HA_TEMP_SENSOR_IN_CLUSTER_NUM,          \
    					ZB_HA_TEMP_SENSOR_OUT_CLUSTER_NUM);                        \
    	ZBOSS_DEVICE_DECLARE_REPORTING_CTX(reporting_info##ep_name,                                \
    					   ZB_HA_TEMP_SENSOR_REPORT_ATTR_COUNT);                   \
    	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,                                 \
    		ZB_HA_TEMP_SENSOR_REPORT_ATTR_COUNT, reporting_info##ep_name, 0, NULL)
    
    /* 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;
    	zb_zcl_temp_measurement_attrs_t temp_attrs;
    };
    
    #endif
    

    And prj.conf:

    #
    # Copyright (c) 2021 Nordic Semiconductor ASA
    #
    # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
    #
    CONFIG_LOG=y
    CONFIG_LOG_DEFAULT_LEVEL=3
    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
    CONFIG_ZIGBEE_CHANNEL_SELECTION_MODE_MULTI=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
    
    # If you enable sleepy device, you have to disable the router role above
    # Enable API for powering down unused RAM parts
    CONFIG_RAM_POWER_DOWN_LIBRARY=y
    
    # Networking
    CONFIG_NET_IPV6=n
    CONFIG_NET_IP_ADDR_CHECK=n
    CONFIG_NET_UDP=n
    
    # Troubleshooting
    CONFIG_ZBOSS_HALT_ON_ASSERT=y
    CONFIG_RESET_ON_FATAL_ERROR=n

    But still the question remains if I forgot to install something. Unfortunately, I can't find the original ZBOSS source to verify if the macros that I am missing still exist or what they look like.

Children
No Data
Related