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

Zigbee attribute reporting only on value change

Hello,

I am using the Zigbee CLI Agent as coordinator, and when a router device or end device joins the network I want to configure attribute reporting.

I am able to configure attribute reporting, and the CLI log (zigbee.report module) prints the reports. But, I don't understand how to configure reporting only on value change. I tried to call the CLI command: subscribe on (after binding the cluster to the coordinator) with max_interval=0 and min_interval=0 but nothing changes.
I want the device to report only on value changes. How can I configure this with the CLI?

Best regards,
Damien

Parents
  • Hello,

    To set change based attribute reporting, you should set the maximum reporting interval field to 0x0000, and the minimum reporting interval field != 0xffff, so if you set both to 0x0000, it should be set to change based reporting. This is from the Zigbee cluster library specification Revision 7.

    However, you need to set this in the application of your router device as well (I think). Do you have access to the source code for the sensor device, or is it a 3rd party device?

  • Is it possible to configure the 3rd party device as such using the Zigbee CLI?
    What's strange is that, using the Elko dimmer (same brand as the thermostat), I am able to get reports only on changes... when I turn on/off and when I change the brightness. And this is what I want to do because otherwise, if it is reporting periodically it will pollute my application.

  • DaKa said:
    And this is what I want to do because otherwise, if it is reporting periodically it will pollute my application.

     What do you mean by that? Can you not just ignore the reports if they are the same as the previous report?

    It may of course be that the thermostat is not following the latest specification, but a previous version. Is it possible to capture a sniffer trace from the network, that captures when you write the cli commands to set the change based reports, and that it still reports periodically?

  • What do you mean by that? Can you not just ignore the reports if they are the same as the previous report?

    What I mean is that, first, I am logging everything happening between my application and the CLI, and use the log for debugging and tracking the network behavior. So, it is a bit annoying to have redundant information.
    Secondly, the communication with the module is quite slow already (uart without flow control) and for me it is useless traffic between the host processor and the SoC. I could ignore the reports but it will still use bandwidth...

    Also, the report frames contain sometimes more than one attribute report and the CLI is not able to separate them... (line 3 "2420230" should be "2300" because it is "occupied_heating_setpoint" attribute)
    Here is my log that is flooded with these reports:

    DEBUG 2020-09-09 09:33:40 pyzigbee.cli.communicator | RX: {'level': 'info', 'module': 'zigbee.report', 'string': 'Received value updates from the remote node 0x679A'}
    DEBUG 2020-09-09 09:33:40 pyzigbee.cli.communicator | RX: {'level': 'info', 'module': 'zigbee.report', 'string': '    Profile: 0x0104 Cluster: 0x0201 Attribute: 0x0000 Type: 41 Value: 2420'}
    DEBUG 2020-09-09 09:33:40 pyzigbee.cli.communicator | RX: {'level': 'info', 'module': 'zigbee.report', 'string': '    Profile: 0x0104 Cluster: 0x0201 Attribute: 0x0012 Type: 41 Value: 2420230'}
    DEBUG 2020-09-09 09:33:41 pyzigbee.cli.communicator | RX: {'level': 'info', 'module': 'zigbee.report', 'string': 'Received value updates from the remote node 0x679A'}
    DEBUG 2020-09-09 09:33:41 pyzigbee.cli.communicator | RX: {'level': 'info', 'module': 'zigbee.report', 'string': '    Profile: 0x0104 Cluster: 0x0201 Attribute: 0x0000 Type: 41 Value: 2420'}
    DEBUG 2020-09-09 09:33:41 pyzigbee.cli.communicator | RX: {'level': 'info', 'module': 'zigbee.report', 'string': '    Profile: 0x0104 Cluster: 0x0201 Attribute: 0x0012 Type: 41 Value: 24202300'}
    DEBUG 2020-09-09 09:33:42 pyzigbee.cli.communicator | RX: {'level': 'info', 'module': 'zigbee.report', 'string': 'Received value updates from the remote node 0x679A'}
    DEBUG 2020-09-09 09:33:42 pyzigbee.cli.communicator | RX: {'level': 'info', 'module': 'zigbee.report', 'string': '    Profile: 0x0104 Cluster: 0x0201 Attribute: 0x0000 Type: 41 Value: 2420'}
    DEBUG 2020-09-09 09:33:42 pyzigbee.cli.communicator | RX: {'level': 'info', 'module': 'zigbee.report', 'string': '    Profile: 0x0104 Cluster: 0x0201 Attribute: 0x0012 Type: 41 Value: 24202300'}
    DEBUG 2020-09-09 09:33:43 pyzigbee.cli.communicator | RX: {'level': 'info', 'module': 'zigbee.report', 'string': 'Received value updates from the remote node 0x679A'}
    DEBUG 2020-09-09 09:33:43 pyzigbee.cli.communicator | RX: {'level': 'info', 'module': 'zigbee.report', 'string': '    Profile: 0x0104 Cluster: 0x0201 Attribute: 0x0000 Type: 41 Value: 2420'}
    DEBUG 2020-09-09 09:33:43 pyzigbee.cli.communicator | RX: {'level': 'info', 'module': 'zigbee.report', 'string': '    Profile: 0x0104 Cluster: 0x0201 Attribute: 0x0012 Type: 41 Value: 24202300'}
    DEBUG 2020-09-09 09:33:44 pyzigbee.cli.communicator | RX: {'level': 'info', 'module': 'zigbee.report', 'string': 'Received value updates from the remote node 0x679A'}
    DEBUG 2020-09-09 09:33:44 pyzigbee.cli.communicator | RX: {'level': 'info', 'module': 'zigbee.report', 'string': '    Profile: 0x0104 Cluster: 0x0201 Attribute: 0x0000 Type: 41 Value: 2420'}
    DEBUG 2020-09-09 09:33:44 pyzigbee.cli.communicator | RX: {'level': 'info', 'module': 'zigbee.report', 'string': '    Profile: 0x0104 Cluster: 0x0201 Attribute: 0x0012 Type: 41 Value: 24202300'}
    DEBUG 2020-09-09 09:33:45 pyzigbee.cli.communicator | RX: {'level': 'info', 'module': 'zigbee.report', 'string': 'Received value updates from the remote node 0x679A'}
    DEBUG 2020-09-09 09:33:45 pyzigbee.cli.communicator | RX: {'level': 'info', 'module': 'zigbee.report', 'string': '    Profile: 0x0104 Cluster: 0x0201 Attribute: 0x0000 Type: 41 Value: 2420'}
    DEBUG 2020-09-09 09:33:45 pyzigbee.cli.communicator | RX: {'level': 'info', 'module': 'zigbee.report', 'string': '    Profile: 0x0104 Cluster: 0x0201 Attribute: 0x0012 Type: 41 Value: 24202300'}


    Attached is a sniffer capture.

    zigbee_sniff_reporting.pcapng

  • looking at the sniffer trace, I see that packet no. 181 looks like the packet where you enable subscription from the CLI device. It looks like you enable subscription for the LocalTemperature (attr id 0x0000).Then later, in packet 223, you enable subscription on OccupiedHeatingSetpoint (attr id 0x0012). 

    In both the response packets (ZCL: Configure Reporting Response), packets 188 and 229, it responds that everything is OK. 

    Let me run the trace by the Zigbee team. Perhaps they see something that I don't.

    I will also mention for them the bug that prints both values in the last cluster. Can you try to change one part in the print_attr_update() in zigbee_cli_cmd_attr_report.c file for me, and see if this solves it:

    Change:

        /* Get the contents of Read Attribute Response frame */
        ZB_ZCL_GENERAL_GET_NEXT_REPORT_ATTR_REQ(bufid, p_attr_resp);
        bytes_written = 0;
        while (p_attr_resp != NULL)
        {
            bytes_written = zcl_attr_to_str(&print_buf[bytes_written],
                                            sizeof(print_buf) - bytes_written,
                                            p_attr_resp->attr_type,
                                            p_attr_resp->attr_value);
    
            if (bytes_written < 0)
            {
                NRF_LOG_ERROR("    Unable to print updated attribute value");
            }
            else
            {
                NRF_LOG_INST_INFO(m_log.p_log, "    Profile: 0x%04x Cluster: 0x%04x Attribute: 0x%04x Type: %hu Value: %s",
                    p_zcl_hdr->profile_id, p_zcl_hdr->cluster_id, p_attr_resp->attr_id,
                    p_attr_resp->attr_type, nrf_log_push(print_buf));
            }
    
            ZB_ZCL_GENERAL_GET_NEXT_REPORT_ATTR_REQ(bufid, p_attr_resp);
        }
    }

    To:

        /* Get the contents of Read Attribute Response frame */
        ZB_ZCL_GENERAL_GET_NEXT_REPORT_ATTR_REQ(bufid, p_attr_resp);
        //bytes_written = 0;
        while (p_attr_resp != NULL)
        {
            bytes_written = 0;
            bytes_written = zcl_attr_to_str(&print_buf[bytes_written],
                                            sizeof(print_buf) - bytes_written,
                                            p_attr_resp->attr_type,
                                            p_attr_resp->attr_value);
    
            if (bytes_written < 0)
            {
                NRF_LOG_ERROR("    Unable to print updated attribute value");
            }
            else
            {
                NRF_LOG_INST_INFO(m_log.p_log, "    Profile: 0x%04x Cluster: 0x%04x Attribute: 0x%04x Type: %hu Value: %s",
                    p_zcl_hdr->profile_id, p_zcl_hdr->cluster_id, p_attr_resp->attr_id,
                    p_attr_resp->attr_type, nrf_log_push(print_buf));
            }
    
            ZB_ZCL_GENERAL_GET_NEXT_REPORT_ATTR_REQ(bufid, p_attr_resp);
        }
    }

    Does that solve that part?

    I will keep you updated. 

    Best regards,

    Edvin

  • Hello,

    A reply from our Zigbee team:

    The fact that this is a third-party device may be the reason, because we can't guarantee for the behavior of this device. But there is one thing you can try:

    Every attribute reporting configuration record contains the following fields:

    -Direction
    -Attribute identifier
    -Attribute data type
    -Minimum reporting interval
    -Maximum reporting interval
    -Reportable change
    -Timeout period.

    The CLI command does not allow you to set the "Reportable change" field, as it always uses the ZIGBEE_CLI_CONFIGURE_REPORT_DEFAULT_VALUE_CHANGE. Try to set this to 1/true. Does it still report periodically?

Reply
  • Hello,

    A reply from our Zigbee team:

    The fact that this is a third-party device may be the reason, because we can't guarantee for the behavior of this device. But there is one thing you can try:

    Every attribute reporting configuration record contains the following fields:

    -Direction
    -Attribute identifier
    -Attribute data type
    -Minimum reporting interval
    -Maximum reporting interval
    -Reportable change
    -Timeout period.

    The CLI command does not allow you to set the "Reportable change" field, as it always uses the ZIGBEE_CLI_CONFIGURE_REPORT_DEFAULT_VALUE_CHANGE. Try to set this to 1/true. Does it still report periodically?

Children
  • Hi,

    Thanks for the reply.
    I tried to set the ZIGBEE_CLI_CONFIGURE_REPORT_DEFAULT_VALUE_CHANGE to 1 and flash the application but it didn't work. Even if the device replies successfully to the report configure request (checked with sniffer), the device do not send any report (only once when it is configured).
    I am using a custom hardware so far, which is running the CLI agent example and I can't flash anything on it. I tried with the dongle though. But I purchased a nRF52840 DK that should be delivered soon. I will try again maybe later when most important things are working correctly.

    BR,
    Damien

  • Just to clarify, I tested this against the multi_sensor example, and these are the changes I did to the CLI example:

    The only changes are in zigbee_cli_cmd_attr_report.c. Right below the line:

    #define ZIGBEE_CLI_CONFIGURE_REPORT_DEFAULT_VALUE_CHANGE NULL

    I add:

    zb_uint8_t minimum_report_change_value = 1;

    Then, inside cmd_zb_subscribe(), I change:

        ZB_ZCL_GENERAL_ADD_SEND_REPORT_CONFIGURE_REPORTING_REQ(p_cmd_ptr,
            req.attr_id, req.attr_type, req.interval_min, req.interval_max,
            ZIGBEE_CLI_CONFIGURE_REPORT_DEFAULT_VALUE_CHANGE);

    to

        ZB_ZCL_GENERAL_ADD_SEND_REPORT_CONFIGURE_REPORTING_REQ(p_cmd_ptr,
            req.attr_id, req.attr_type, req.interval_min, req.interval_max,
            &minimum_report_change_value);

    Those were the only changes I did to the CLI example. I tested this using the multi sensor example, running on another DK. I used the unmodified example, and changed a few things:

    Inside zb_app_timer_handler(), I removed the part that updated the new_temp_value and new_pres_value. I just set them to the same value on every timeout callback:

    static void zb_app_timer_handler(void * context)
    {
        zb_zcl_status_t zcl_status;
        static zb_int16_t new_temp_value = 1200;
        static zb_int16_t new_pres_value = 745;
    
        zcl_status = zb_zcl_set_attr_val(MULTI_SENSOR_ENDPOINT, 
                                         ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT, 
                                         ZB_ZCL_CLUSTER_SERVER_ROLE, 
                                         ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID, 
                                         (zb_uint8_t *)&new_temp_value2, 
                                         ZB_FALSE);
        if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
        {
            NRF_LOG_INFO("Set temperature value fail. zcl_status: %d", zcl_status);
        }
    
        zcl_status = zb_zcl_set_attr_val(MULTI_SENSOR_ENDPOINT,
                                         ZB_ZCL_CLUSTER_ID_PRESSURE_MEASUREMENT, 
                                         ZB_ZCL_CLUSTER_SERVER_ROLE, 
                                         ZB_ZCL_ATTR_PRES_MEASUREMENT_VALUE_ID, 
                                         (zb_uint8_t *)&new_pres_value2, 
                                         ZB_FALSE);
        if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
        {
            NRF_LOG_INFO("Set pressure value fail. zcl_status: %d", zcl_status);
        }
    }

    Then I added a button handler by modifying the leds_init() function:

    error_code = bsp_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS, my_button_event_handler);

    And finally adding the my_button_event_handler callback:

    void my_button_event_handler(bsp_event_t bsp_evt)
    {
        zb_zcl_status_t zcl_status;
        uint8_t button_pressed = bsp_evt - BSP_EVENT_KEY_0;
        NRF_LOG_INFO("button %d pressed", button_pressed);
        
        static zb_int16_t new_temp_value = 1300;
        static zb_int16_t new_pres_value = 800;
        
        if (button_pressed == 0)
        {
            new_temp_value = 1200;
            new_pres_value = 745;
        }
        else if (button_pressed == 1)
        {
            new_temp_value = 1205;
            new_pres_value = 750;
        }
        else if (button_pressed == 2)
        {
            new_temp_value = 1210;
            new_pres_value = 755;
        }
        else if (button_pressed == 3)
        {
            new_temp_value = 1250;
            new_pres_value = 745;
        }
        
        zcl_status = zb_zcl_set_attr_val(MULTI_SENSOR_ENDPOINT,
                                         ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT, 
                                         ZB_ZCL_CLUSTER_SERVER_ROLE, 
                                         ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID, 
                                         (zb_uint8_t *)&new_temp_value, 
                                         ZB_FALSE);
        if (zcl_status != ZB_ZCL_STATUS_SUCCESS)
        {
            NRF_LOG_INFO("Set temperature value fail. zcl_status: %d", zcl_status);
        }
        
        zcl_status = zb_zcl_set_attr_val(MULTI_SENSOR_ENDPOINT,
                                         ZB_ZCL_CLUSTER_ID_PRESSURE_MEASUREMENT, 
                                         ZB_ZCL_CLUSTER_SERVER_ROLE, 
                                         ZB_ZCL_ATTR_PRES_MEASUREMENT_VALUE_ID, 
                                         (zb_uint8_t *)&new_pres_value, 
                                         ZB_FALSE);
        if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
        {
            NRF_LOG_INFO("Set pressure value fail. zcl_status: %d", zcl_status);
        }
    }
    

    Then, I used the normal CLI commands to see the reports:

    bdb role zc
    bdb channel <channel that I use on the multi_sensor example>
    bdb start
    
    zdo match_desc 0xffff 0xffff 0x0104 2 0x0402 0x0403 0
    <returns addr:1234, ep:10>
    zdo ieee_addr 0x1234
    <returns "multi_sensor_long_addr">
    zdo eui64
    <returns "cli_long_addr">
    
    zdo bind on <multi_sensor_long_addr> 10 <cli_long_addr> 64 0x0402 0x1234
    zdo bind on <multi_sensor_long_addr> 10 <cli_long_addr> 64 0x0403 0x1234
    
    zcl subscribe on <multi_sensor_long_addr> 10 0x0402 0x0104 0 41 0 0
    zcl subscribe on <multi_sensor_long_addr> 10 0x0403 0x0104 0 41 0 0
    
    log enable info zigbee_report

    I don't see any reports but when I press the buttons on the multi sensor DK, it reports the changes corresponding to the button presses.

    Can you test this, to see that you modified the CLI example correctly, and then try on the device that doesn't work with change based reports?

    If that still doesn't work, I am afraid there is not much I can do. Then you need to modify your CLI device that outputs the logs. You need to store the last received values on each attribute, and only print if the values are changed since the last time.

    Best regards,

    Edvin

Related