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

Zigbee attribute read request

Hello, I' trying to use the macro here below, but there are no sample in SDK.
Have you any example for using it?
Many thanks

Abele

Parents
  • Hi,

    Take a look at the source code of the Zigbee CLI example and see inside zigbee_cli_cmd_attr.c function readattr_send().

    I can also share with you a code snippet from an on-going tutorial project I am working on where I want to read the on/off state from the on/off cluster from a device with index idx from a list of devices stored in a custom light switch entry structure:

    /*Read device On/Off state from the On/Off cluster. */
    static void read_device_state(zb_uint8_t param, zb_uint16_t idx)
    {
        zb_uint8_t           * p_cmd_buf;
        zb_buf_t             * p_buf   = ZB_BUF_FROM_REF(param);
        light_switch_entry_t * p_entry = get_by_idx(idx);
    
        if (p_entry == NULL)
        {
            NRF_LOG_WARNING("Unable to read device state. Device with idx: %d not found.", idx);
            ZB_FREE_BUF_BY_REF(param);
    
            return;
        }
    
        NRF_LOG_INFO("Resolve device state for device with idx: %d", idx);
        ZB_ZCL_GENERAL_INIT_READ_ATTR_REQ(p_buf, p_cmd_buf, ZB_ZCL_ENABLE_DEFAULT_RESPONSE);
        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(p_buf, 
            p_cmd_buf,
            p_entry->short_address,
            ZB_APS_ADDR_MODE_16_ENDP_PRESENT, 
            p_entry->endpoint,
            LIGHT_COORDINATOR_EP, //Sending endpoint 
            ZB_AF_HA_PROFILE_ID,
            ZB_ZCL_CLUSTER_ID_ON_OFF, 
            read_device_state_cb); // For this type of requests the response will not arrive inside the callback. Please take a look at the endpoint handler. You can use the callback for further configuration (call another function) but if not you can just use it to free the buffer, see frame_acked_cb in CLI example.   
    }

    I hope this was of help, let me know if you had more questions.

    Best regards,

    Marjeris

  • Hi Marjeris,

    many thanks for your answer.
    Waiting for, I'm also seen CLI example. then I added this code to my application (function name is different but the code is like).
    Using PC10059 dongle and Wireshark as Zigbee communication sniffer, I see the EndNode answer that contains expected data, but I'm not be able to get the received data to store it in my custom database. (the callback as commented on your code is not the right way)
    Have you any suggest or any example how to get the received data??

    /**@brief Actually construct the Read Attribute frame and send it.
     *
     * @param param ZBOSS buffer to fill.
     * @param cb_param Row of the read attribute table to refer to.
     */
    static zb_void_t readattr_send(zb_uint8_t param, zb_uint16_t cb_param)
    {
        zb_ret_t zb_err_code;
        zb_buf_t * p_buf = ZB_BUF_FROM_REF(param);
        zb_uint8_t row = cb_param;
        zb_uint8_t * p_cmd_buf;
        attr_query_t * p_row = &(m_attr_table[row]);
    
        p_row->seq_num = ZCL_CTX().seq_number;
        ZB_ZCL_GENERAL_INIT_READ_ATTR_REQ_A(p_buf, p_cmd_buf, p_row->direction, ZB_ZCL_ENABLE_DEFAULT_RESPONSE);
        ZB_ZCL_GENERAL_ADD_ID_READ_ATTR_REQ(p_cmd_buf, p_row->attr_id);
        ZB_ZCL_GENERAL_SEND_READ_ATTR_REQ(p_buf, p_cmd_buf, 
                                          p_row->remote_node,
                                          p_row->remote_addr_mode, 
                                          p_row->remote_ep,
                                          LIGHT_SWITCH_ENDPOINT, 
                                          p_row->profile_id,
                                          p_row->cluster_id, 
                                          frame_acked_cb);
    
        zb_err_code = ZB_SCHEDULE_ALARM(invalidate_row_cb, row,
                                        ATTRIBUTE_ROW_TIMEOUT_S * ZB_TIME_ONE_SECOND);
        ZB_ERROR_CHECK(zb_err_code);
    }

  • Hi Marjeris
    I have seen the code you suggest; I think that it is intended for End-Node devices.
    I'm developing a Zigbee Coordinator + BLE and I need populate the GATT database with info fro all device commissioned and connected to network
    I use the readattr_send function I got from CLI example, that I have adapted to insert on my code and with radio sniffer I see the request from Coordinator to Endnode, the answer from Endnode to Coordinator and all related ACK. My purpose is to get data received from endnode.
    How can I reach my goal? How can I get the read_attr data on Coordinator side?

  • Hi Abele,

    The code is from a coordinator node. I have a table with entries for each light switch connected to the coordinator and I update this table with the current on/off state of the switch/lightbulb by reading their on/off state attribute. Have you tried to implement an endpoint handler to intercept the answer from the endnode to the coordinator?

  • Hi Marjeris,
    I apologize for the delay, but I was busy with other works. Now I'm on this project, and I tried to add the functions you suggest, but I have some errors and I'm not be able to find the right definitions, for example, for the light_switch_entry_t typedef and LIGHT_COORDINATOR_EP macro.
    Where I can find these? What the sample code you refer to?
    Many thanks for your help!
    Abele

  • Hi Abele,

    The code snippet I shared was just so you could see an example on how the ZB_ZCL_GENERAL_SEND_READ_ATTR_REQ macro is implemented and how to implement an endpoint handler to intercept the response, I don't recommend copying it directly, as some functions and structs in that snippet are defined by myself, sorry for the confusion about that. For example light_switch_entry_t is just a selfmade structure I defined to help me store the on/off state of the devices in the network.

    And for example should change the "LIGHT_COORDINATOR_EP" for the name you have defined for your sending endpoint (from which endpoint are you sending the send read attribute request?).

    I think it would be easier for me to help you if you could share your code (main.c) here.

    BR,

    Marjeris

  • Hi Marjeris,

    many thanks for your help, now I'm be able to intercept the ZCL attr request response.
    In my code I forgot the ZB_AF_REGISTER_DEVICE_CTX() initialization, then my macro call ZB_AF_SET_ENDPOINT_HANDLER(ZIGBEE_ZC_MAIN_ENDPOINT, callback_ep_handler) had no effects.
    Now, when i send a read_attr request, the callback_ep_handler() function is invoked.
    Two further questions:
    - the callback_ep_handler() return the "zb_uint8_t param" value set to 0x04, it's right? What's the meaning of this parameter?
    - I need using Groupcast command: for example, I have set cluster 4 inside two light bulb with the command "add group" (both with same group code, of course). How can I send the "groupcast" on/off command? There is an example how to make this?
    Kind regards

    Abele

Reply
  • Hi Marjeris,

    many thanks for your help, now I'm be able to intercept the ZCL attr request response.
    In my code I forgot the ZB_AF_REGISTER_DEVICE_CTX() initialization, then my macro call ZB_AF_SET_ENDPOINT_HANDLER(ZIGBEE_ZC_MAIN_ENDPOINT, callback_ep_handler) had no effects.
    Now, when i send a read_attr request, the callback_ep_handler() function is invoked.
    Two further questions:
    - the callback_ep_handler() return the "zb_uint8_t param" value set to 0x04, it's right? What's the meaning of this parameter?
    - I need using Groupcast command: for example, I have set cluster 4 inside two light bulb with the command "add group" (both with same group code, of course). How can I send the "groupcast" on/off command? There is an example how to make this?
    Kind regards

    Abele

Children
  •  Hi Abele,

    Sorry for the late reply. Can you share the code of callback_ep_handler()? The packet ZCL packet handler (in this case callback_ep_handler()) should either return ZB_FALSE, if the packet is not processed by the application and the default ZCL handling is applied, or ZB_TRUE if the aplication does handle the packet and no default processing is needed. See "Implementing algorithm for overriding the handling of ZCL commands".

    For sending and a group command you need to use the group ID as the destination address. Take a look at the light_switch_groups examples under example/zigbee/experimental

    static zb_void_t light_switch_send_on_off(zb_uint8_t param, zb_uint16_t on_off)
    {
        zb_uint8_t           cmd_id;
        zb_uint16_t          group_id = DEFAULT_GROUP_ID;
        zb_buf_t           * p_buf = ZB_BUF_FROM_REF(param);
    
        if (on_off)
        {
            cmd_id = ZB_ZCL_CMD_ON_OFF_ON_ID;
        }
        else
        {
            cmd_id = ZB_ZCL_CMD_ON_OFF_OFF_ID;
        }
    
        NRF_LOG_INFO("Send ON/OFF command: %d", on_off);
    
        ZB_ZCL_ON_OFF_SEND_REQ(p_buf,
                               group_id,
                               ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT,
                               0,
                               LIGHT_SWITCH_ENDPOINT,
                               ZB_AF_HA_PROFILE_ID,
                               ZB_ZCL_DISABLE_DEFAULT_RESPONSE,
                               cmd_id,
                               NULL);
    }

    Best regards,

    Marjeris

Related