This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to configure attribute changes notifications on binding, Zigbee?

There are several topics already exist on this forum concerning the attribute reporting, namely:

https://devzone.nordicsemi.com/f/nordic-q-a/42171/zigbee-attribute-request-and-response

https://devzone.nordicsemi.com/f/nordic-q-a/42327/trying-to-send-from-a-switch-to-a-coordinator/165168#165168

and the multi sensor example is described at infocenter: https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.thread_zigbee.v3.0.0%2Fzigbee_multi_sensor_example.html

However, the question is still open, how to configure the attribute changes notification from router to coordinator just on successful Bind Request from the coordinator, so without followed explicit configuring the Attribute Reporting.

The commercial devices we are dealing with do not require the attribute reporting configuring, so they send notifications to the Coordinator once some attribute was changed just after Binding, without additional actions. And these notifications are sent only on changes, but not on the periodic basis.

Is it possible to figure out this issue somehow with the current Zigbee stack version?

  • Hi.

    However, the question is still open, how to configure the attribute changes notification from router to coordinator just on successful Bind Request from the coordinator, so without followed explicit configuring the Attribute Reporting.

    You are correct, there should be a default configuration for each attribute, this will be fixed in the next release which is coming soon. However, it will not be value change.

    In the currect SDK, can you try this:

    Use the CLI router as coordinator, and use the light bulb example and the light switch.

    1. Configure the coordinator by running these four commands:    

    log enable info zigbee.report
    bdb channel 16
    bdb role zc
    bdb start

    2. Open the light bulb example, copy this function into main.c:

    void configure_reporting_locally(void)
    {
      zb_zcl_reporting_info_t rep_info;
      memset(&rep_info, 0, sizeof(rep_info));
    
      rep_info.direction      = ZB_ZCL_CONFIGURE_REPORTING_SEND_REPORT;
      rep_info.ep             = HA_DIMMABLE_LIGHT_ENDPOINT;
      rep_info.cluster_id     = ZB_ZCL_CLUSTER_ID_LEVEL_CONTROL;
      rep_info.cluster_role   = ZB_ZCL_CLUSTER_SERVER_ROLE;
      rep_info.attr_id        = ZB_ZCL_ATTR_LEVEL_CONTROL_CURRENT_LEVEL_ID;
      rep_info.dst.profile_id = ZB_AF_HA_PROFILE_ID;
    
      rep_info.u.send_info.min_interval = 1;
      rep_info.u.send_info.max_interval = 0;
      rep_info.u.send_info.delta.u8     = 1;
    
      zb_zcl_put_default_reporting_info(&rep_info);
    } 

    Go to the main(void) function and call this function before you start the zboss stack:

    int main(void)
    {
        zb_ret_t       zb_err_code;
        zb_ieee_addr_t ieee_addr;
    
        /* Initialize timer, logging system and GPIOs. */
        timer_init();
        log_init();
        leds_buttons_init();
    
    #if (APP_BULB_USE_WS2812_LED_CHAIN)
        ret_code_t ret_code;
        ret_code = drv_ws2812_init(LED_CHAIN_DOUT_PIN);
        APP_ERROR_CHECK(ret_code);
    #endif
    
        /* Set ZigBee stack logging level and traffic dump subsystem. */
        ZB_SET_TRACE_LEVEL(ZIGBEE_TRACE_LEVEL);
        ZB_SET_TRACE_MASK(ZIGBEE_TRACE_MASK);
        ZB_SET_TRAF_DUMP_OFF();
    
        /* Initialize ZigBee stack. */
        ZB_INIT("led_bulb");
    
        /* Set device address to the value read from FICR registers. */
        zb_osif_get_ieee_eui64(ieee_addr);
        zb_set_long_address(ieee_addr);
    
        /* Set static long IEEE address. */
        zb_set_network_router_role(IEEE_CHANNEL_MASK);
        zb_set_max_children(MAX_CHILDREN);
        zigbee_erase_persistent_storage(ERASE_PERSISTENT_CONFIG);
        zb_set_keepalive_timeout(ZB_MILLISECONDS_TO_BEACON_INTERVAL(3000));
    
        /* Initialize application context structure. */
        UNUSED_RETURN_VALUE(ZB_MEMSET(&m_dev_ctx, 0, sizeof(m_dev_ctx)));
    
        /* Register callback for handling ZCL commands. */
        ZB_ZCL_REGISTER_DEVICE_CB(zcl_device_cb);
    
        /* Register dimmer switch device context (endpoints). */
        ZB_AF_REGISTER_DEVICE_CTX(&dimmable_light_ctx);
    
        bulb_clusters_attr_init();
        level_control_set_value(m_dev_ctx.level_control_attr.current_level);
    
    #if (APP_BULB_USE_WS2812_LED_CHAIN)
        /* Let's have a timer triggering refresh of led state */
        ret_code = app_timer_create(&m_ws2812_refresh_timer, APP_TIMER_MODE_REPEATED,
                ws2812_refresh_timer_timeout_handler);
        APP_ERROR_CHECK(ret_code);
        ret_code = app_timer_start(m_ws2812_refresh_timer, APP_TIMER_TICKS(5000U), NULL);
        APP_ERROR_CHECK(ret_code);
    #endif
    
        /** Start Zigbee Stack. */
        configure_reporting_locally();  //ADDED BY ME
        
        zb_err_code = zboss_start();
        ZB_ERROR_CHECK(zb_err_code);
    
        while(1)
        {
            zboss_main_loop_iteration();
            UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
    
    #if (APP_BULB_USE_WS2812_LED_CHAIN)
            if (m_ws2812_refresh_request)
            {
                if (drv_ws2812_display() == NRF_SUCCESS)
                {
                    m_ws2812_refresh_request = false;
                }
            }
    #endif
        }
    }

    Compile and flash it to a DK. Flash the light switch to another DK, make sure that both join the network by running bdb start again.

    3. Find the light bulb's endpoint, short and long addresses:

        zdo match_desc 0xFFFD 0xFFFD 0x0104 1 0x0006 0
        zdo ieee_addr <returned_short_address>

    4. Create binding FROM the light bulb TO the CLI ON the light bulb:

        zcl bind <bulb_long_addr> <bulb_ep_from_match_desc> <CLI_long_addr> <CLI_endpoint, defaults to 64> 0x0008 <bulb_short_addr>

    You should be able to see the report by clicking on the light switch:

    Wireshark log: Wireshark log.zip

    Hope this helps you.

    Best regards,

    Andreas

  • Hi Andreas.

    Thank you very much for your explanation that is excellent, as usual.

    I have been able to adapt my project for attribute reporting on bind.

    But in my case, when I called the configure_reporting_locally function before I start the zboss stack, the reporting starts on binding, and all is fine until I power off the device and power on it again. Then the device becomes unpaired, however, it didn’t leave the network before powering off. If I removing the function call, the device remains paired after power off/on, as it should.

    I checked with the example, but if I power off/on the devkit with Bulb (without coordinator restart), it remains paired, so this problem is not reproduced with the example.

    Finally, I tried to call configure_reporting_locally after the zboss stack start, and it works (reporting on bind without device unpairing after power off/on cycle).

    Maybe, you have some idea about this behavior? Could you please comment, why did you advised putting the function call before the stack start, do some unobvious and non-desirable cases possible if using the call after the stack start?

    Sincerely,

    Anna

  • Hi Anna.

    I had a quick look at the stack and based on that I said you should do the function call before you started the zboss stack. I have now taken a more thorough look at the stack and found out that it should be fine doing the call after you started the stack. So if it works best for you after the stack is started just do that :-)

    Best regards,

    Andreas

Related