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
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
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 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
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
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