How to read cluster attribute values for on/Off cluster in Zigbee Network Coordinator

Hi 
What is the best way to read cluster attributes periodically in zigbee network coordnicator?

any sample code available for one time request or subscription for value change or periodic subscription ?

Parents
  • Hi,

    You can for instance use attribute reporting. This method allows the coordinator to receive automatic updates from devices when attribute values change, without having to constantly poll for data. Here's how you can set it up:

    1. Create a binding between the coordinator and the device for the specific cluster you want to monitor. This is done using the `zdo bind on` command [Zigbee shell](developer.nordicsemi.com/.../shell.html).

    2. Configure attribute reporting using the `zcl subscribe on` command. This sets up the reporting intervals for the attributes you're interested in [Zigbee shell](developer.nordicsemi.com/.../shell.html).

    Here's an example of how to set this up:

    1. Create a binding: zdo bind on <source_eui64> <source_ep> <dst_addr> <dst_ep> <cluster_id> <request_dst_addr>

    2. Configure attribute reporting: zcl subscribe on <addr> <ep> <cluster> <profile> <attr_id> <attr_type> [<min_interval>] [<max_interval>] 

    For example, to set up reporting for a temperature attribute every 5 to 20 seconds: zcl subscribe on 0x1234 10 0x0402 0x0104 0x0000 29 5 20

    This approach is more efficient than constantly reading attributes, as it reduces network traffic and power consumption on battery-operated devices. The coordinator will receive automatic updates when attribute values change within the specified intervals https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/applications/zigbee_weather_station/README.html#creating_bindings_for_periodic_notifications 

    If you need to manually read attributes at specific times, you can use the `zcl attr read` command https://developer.nordicsemi.com/nRF_Connect_SDK/doc/2.5.0/nrf/libraries/zigbee/shell.html, but this is not recommended for frequent, periodic readings. 

    Kind regards,
    Andreas

  • I did binding as well subscription but it never reported values


    zb_uint8_t zcl_endpoint_handler(zb_uint8_t param)
    {
        LOG_INF("Bulb state:");
        zb_zcl_parsed_hdr_t *cmd_info = ZB_BUF_GET_PARAM(param, zb_zcl_parsed_hdr_t);
    
        if (cmd_info->cmd_id == ZB_ZCL_CMD_READ_ATTRIB_RESP)
        {
            zb_zcl_read_attr_res_t *attr_resp;
            ZB_ZCL_GENERAL_GET_NEXT_READ_ATTR_RES(param, attr_resp);
            if (attr_resp->status == ZB_ZCL_STATUS_SUCCESS)
            {
                zb_uint8_t on_off_value = attr_resp->attr_value[0];
                LOG_INF("Bulb state: %s", on_off_value ? "ON" : "OFF");
            }
            else
            {
                LOG_ERR("Failed to read attribute. Status: %d", attr_resp->status);
            }
            return ZB_TRUE;
        }
        if (cmd_info->cmd_id == ZB_ZCL_CMD_REPORT_ATTRIB)
        {
            zb_zcl_report_attr_req_t *report_attr_req;
            ZB_ZCL_GENERAL_GET_NEXT_REPORT_ATTR_REQ(param, report_attr_req);
    
            if (report_attr_req->attr_id == ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID)
            {
                zb_uint8_t on_off_status = report_attr_req->attr_value[0];
                printf("Received on/off status: %d\n", on_off_status);
            }
        }
        return ZB_FALSE;
    }
    
    
    
    static zb_callback_t zb_bind_callback()
    {
        printf("Device Binding Completed:\n");
    }
    
    static void bind_req(uint16_t short_addr, zb_ieee_addr_t iee_addr, uint16_t ep)
    {
        zb_bufid_t bufid;
        zb_ieee_addr_t recv_nwk_addr;
        zb_zdo_bind_req_param_t *p_req;
    
        bufid = zb_buf_get_out();
    
        // Get the long address of the reporting device
        zb_osif_get_ieee_eui64(recv_nwk_addr);
    
        zb_uint16_t receiver_short_addr = 0x0000;
    
        p_req = ZB_BUF_GET_PARAM(bufid, zb_zdo_bind_req_param_t);
        // receiver_nwk_addr is the long address of the device that will receive the reports
        // This needs to be retrieved in some way
        ZB_MEMCPY(p_req->src_address, iee_addr, sizeof(zb_ieee_addr_t));
        p_req->src_endp = ep;
        p_req->cluster_id = ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID;
        p_req->dst_addr_mode = ZB_BIND_DST_ADDR_MODE_64_BIT_EXTENDED;
        ZB_MEMCPY(p_req->dst_address.addr_long, recv_nwk_addr, sizeof(zb_ieee_addr_t));
        p_req->dst_endp = ZIGBEE_COORDINATOR_ENDPOINT;
    
        p_req->req_dst_addr = receiver_short_addr;
    
        zb_zdo_bind_req(bufid, zb_bind_callback);
    }
    
    void print_read_attr_subscribe_resp(zb_bufid_t bufid)
    {
        zb_zcl_configure_reporting_res_t *resp;
        ZB_ZCL_GENERAL_GET_NEXT_CONFIGURE_REPORTING_RES(bufid, resp);
    
        if (resp != NULL)
        {
            printf("Configure Reporting Response:\n");
            printf("Status: 0x%02x\n", resp->status);
            printf("Direction: 0x%02x\n", resp->direction);
            printf("Attribute ID: 0x%04x\n", resp->attr_id);
    
            if (resp->status == ZB_ZCL_STATUS_SUCCESS)
            {
                printf("Configure Reporting request was successful\n");
            }
            else
            {
                printf("Configure Reporting request failed\n");
            }
        }
        else
        {
            printf("No Configure Reporting response received\n");
        }
    }
    void read_device_state(uint16_t short_addr, uint16_t ep)
    {
        zb_uint8_t *p_cmd_buf;
        zb_bufid_t bufid;
        bufid = zb_buf_get_out();
    
        ZB_ZCL_GENERAL_INIT_READ_ATTR_REQ(bufid, p_cmd_buf, ZB_ZCL_ENABLE_DEFAULT_RESPONSE);
        // printf("log3 %s\n", bufid);
        ZB_ZCL_GENERAL_ADD_ID_READ_ATTR_REQ(p_cmd_buf, ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID);
        ZB_ZCL_GENERAL_SEND_READ_ATTR_REQ(bufid, p_cmd_buf, short_addr,
                                          ZB_APS_ADDR_MODE_16_ENDP_PRESENT, ep,
                                          ZIGBEE_COORDINATOR_ENDPOINT, ZB_AF_HA_PROFILE_ID,
                                          ZB_ZCL_CLUSTER_ID_ON_OFF, print_read_attr_resp); // print_read_attr_resp);
    
        zb_bufid_t cfg_buf = zb_buf_get_out();
        ZB_ZCL_GENERAL_INIT_CONFIGURE_REPORTING_SRV_REQ(cfg_buf, p_cmd_buf, ZB_ZCL_ENABLE_DEFAULT_RESPONSE);
        ZB_ZCL_GENERAL_ADD_SEND_REPORT_CONFIGURE_REPORTING_REQ(
            p_cmd_buf,
            ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID,
            ZB_ZCL_ATTR_TYPE_BOOL,
            0x0005,
            0x0010,
            0); // reportable change for Boolean is always 0
        ZB_ZCL_GENERAL_SEND_CONFIGURE_REPORTING_REQ(
            cfg_buf,
            p_cmd_buf,
            short_addr,
            ZB_APS_ADDR_MODE_16_ENDP_PRESENT,
            ep,
            ZIGBEE_COORDINATOR_ENDPOINT,
            ZB_AF_HA_PROFILE_ID,
            ZB_ZCL_CLUSTER_ID_ON_OFF,
            print_read_attr_subscribe_resp);
    }



    Here is logs 
    [00:00:42.424,224] <inf> app: New device commissioned or rejoined (short: 0xc3cf)
    [00:00:42.448,852] <inf> app: IEEE Address: 30:88:e7:fe:ff:44:5b:38
    
    [00:00:42.489,288] <inf> app: 0
    [00:00:42.508,544] <inf> app: Joining period extended.
    Device Binding Completed:
    [00:00:42.597,106] <inf> app: Bulb state:
    [00:00:42.618,743] <inf> app: Bulb state: ON
    [00:00:42.647,247] <inf> app: read attribute called!
    
    [00:00:42.669,036] <inf> app: Bulb state:
    Configure Reporting Response:
    Status: 0x00
    Direction: 0x01
    Attribute ID: 0x0006
    Configure Reporting request was successful
    [00:00:45.282,226] <inf> zigbee_app_utils: Device authorization event received (short: 0xc3cf, long: 385b44fffee78830, authorization type: 1, authorization status: 0)
    [00:00:48.439,147] <inf> zigbee_app_utils: Unimplemented signal (signal: 54, status: 0)
    


    It works to read values but subscription didnt responded 
  • Hi,

    Could you do a Zigbee sniffer trace and see if your nodes actually does send attribute reports or not when the state changes?

    Kind regards,
    Andreas

  • Hi I dont have sniffer right now

    but I am confused as well that all standard zigbee device will have attributing supported or not

  • Here's a pointer to where to get started with this: https://www.nordicsemi.com/Products/Development-tools/nRF-Sniffer-for-802154 

    Dhaval Dalvadi said:
    but I am confused as well that all standard zigbee device will have attributing supported or not

    It should be supported. What I want you to investigate with the sniffer is to see if you're actually sending the signal so we can look closer into why it does not report anything.

    Kind regards,
    Andreas

  • Hi AHaug I have sniffer with nrf52840 dongle 
    I will try that as well if needed 

    I tried the zigbee shell example with the plug but didnt worked so I was trying it with nrf connect sdk zigbee light_bulb sample 

    here are the command which I tried 


    turn on : zcl cmd 0x8259 10 0x0006 0x01
    turn off : zcl cmd 0x8259 10 0x0006 0x00
    attribute read: zcl attr read 0x8259 10 0x0006 0x0104 0x00

    bind:  zdo bind on f4ce369c73f4aea1 10 f4ce36f9f41b69c4 1 0x0006 0x8259
    subscribe: zcl subscribe on 0x8259 10 0x0006 0x0104 0x00 16


    0x8259 device address
    f4ce36f9f41b69c4 coordniatore devEUI
    f4ce369c73f4aea1 bulb devEUI

    on off and attribute read works bund and subscribe there is no error but no response when I have executed on/off command after it

  • Hi,

    Unless you've changed the code, then the shell's endpoint is 64 and not 1. Could you try with the following instead?

    bind:  zdo bind on f4ce369c73f4aea1 10 f4ce36f9f41b69c4 64 0x0006 0x8259

    Kind regards,
    Andreas

Reply Children
Related