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

Related