Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unbind do not stop communication (TZ-999) #383

Closed
kgkask opened this issue Jul 10, 2024 · 14 comments
Closed

Unbind do not stop communication (TZ-999) #383

kgkask opened this issue Jul 10, 2024 · 14 comments
Labels

Comments

@kgkask
Copy link

kgkask commented Jul 10, 2024

Question

How to stop communication between two devices (coordinator and end device) ?

Additional context.

I am using a modified version of this code implementation in #202, once the end device join the network it can communicate before even binding process. what I am trying to achieve is reading a certain attribute from end device if it meets the requirements it will be kept in the network, otherwise it will be unbinded.

some issue I refered to as well #318 and

to check the issue :
1- I stopped the binding -> still communicate.
2- I implement unbind after binding -> still communicate.

I want to make sure if there is an easier way to implement this, or what I am doing wrong so the communication still on gaining.

coordinator
image

end device
image

send message implementation on coordinator
'static void esp_zb_buttons_handler(switch_func_pair_t *button_func_pair) {

if (button_func_pair->func == SWITCH_ONOFF_TOGGLE_CONTROL) {

esp_zb_zcl_custom_cluster_cmd_req_t custom_req;

char *msg= "This message has a length of 230:FFGFI";
char *value;
value = (char*)malloc(sizeof(uint8_t)*(strlen(msg) +  1));
memset(value,0,sizeof(uint8_t)*(strlen(msg)+1));
ZBM_Set_Zigbee_Attr_String(value,strlen(msg),msg);

custom_req.zcl_basic_cmd.src_endpoint = HA_ONOFF_SWITCH_ENDPOINT;
custom_req.zcl_basic_cmd.dst_endpoint =  10;//0xffff; enddevice endpoint ID
custom_req.zcl_basic_cmd.dst_addr_u.addr_short = 0xffff;
custom_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
custom_req.cluster_id = CUSTOM_CLUSTER_ID;
custom_req.custom_cmd_id = 0x01;
custom_req.profile_id = ESP_ZB_AF_HA_PROFILE_ID;
custom_req.direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_SRV;// set to (-->srv) trigger the correct call back function in the ED
custom_req.data.type = ESP_ZB_ZCL_ATTR_TYPE_CHAR_STRING;
custom_req.data.value = value;

esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_custom_cluster_cmd_req(&custom_req);
esp_zb_lock_release();

log_i("Send 'specified custom number' command");

}
}'

send message implementation on end device

'// done converting to Arduino code
static void esp_zb_buttons_handler(switch_func_pair_t *button_func_pair, char *input_msg) {

if (button_func_pair->func == SWITCH_ONOFF_TOGGLE_CONTROL) {

// direct msg to coordnator
esp_zb_zcl_custom_cluster_cmd_req_t custom_req;

// Use the received input message
char *value;
value = (char*)malloc(sizeof(uint8_t)*(strlen(input_msg) +  1));
memset(value,0,sizeof(uint8_t)*(strlen(input_msg)+1));
ZBM_Set_Zigbee_Attr_String(value,strlen(input_msg),input_msg);
//                              ID  
esp_zb_zcl_attribute_t attrs = {2, {ESP_ZB_ZCL_ATTR_TYPE_CHAR_STRING, sizeof(value), value}};  

// 0xffff -> broadcast   0x0000 -> coordinator
custom_req.zcl_basic_cmd.src_endpoint = HA_ESP_LIGHT_ENDPOINT;
custom_req.zcl_basic_cmd.dst_endpoint = 1;//0xffff;// broadcast to client endpoint ID
custom_req.zcl_basic_cmd.dst_addr_u.addr_short = 0xffff; // broadcast address
custom_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
custom_req.cluster_id = CUSTOM_CLUSTER_ID;//
custom_req.custom_cmd_id = 0x02;// sent message custom cmd ID 
custom_req.profile_id = ESP_ZB_AF_HA_PROFILE_ID;
custom_req.direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_CLI;//ESP_ZB_ZCL_CMD_DIRECTION_TO_SRV;
custom_req.data.type = ESP_ZB_ZCL_ATTR_TYPE_CHAR_STRING;//ESP_ZB_ZCL_ATTR_TYPE_32BIT_ARRAY;
custom_req.data.value = value;

esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_custom_cluster_cmd_req(&custom_req);
esp_zb_lock_release();

log_i("Send 'specified custom number' command");
log_w("%02x",input_msg[0]);

}
}'

@github-actions github-actions bot changed the title Unbind do not stop communication Unbind do not stop communication (TZ-999) Jul 10, 2024
@lpy4105
Copy link
Contributor

lpy4105 commented Jul 10, 2024

You are sending commands using a network broadcast address, which is irrelevant to bindings.

Binding enables the source device to send APS data without DstAddress and DstEndpoint (i.g. ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT mode). In such mode, the DstAddress and DstEndpoint will be determined by search the binding table on the device.

@kgkask
Copy link
Author

kgkask commented Jul 10, 2024

thanks for quick reply @lpy4105 ,

I found that by printing the binding table, where all entries were removed after calling esp_zb_zdo_device_unbind_req(), however I am facing now the issue of sending the string data thro APS layer. I tried different modes and still it is not received by both coordinator and end device. I am using code in #202.

@lpy4105
Copy link
Contributor

lpy4105 commented Jul 10, 2024

however I am facing now the issue of sending the string data thro APS

I guess you want to read "long" string attribute by read attribute command. Please update to the latest SDK and have a try. We had some fixes on such issue.

@kgkask
Copy link
Author

kgkask commented Jul 10, 2024

I am using Arduino IDE not sure if the SDK got updated there. but I will check it.

one more thing I need a report command not read only. I will implement and check if it worked.

one question: does this mean custom_cmds are only used for network not application-sublayer?

@lpy4105
Copy link
Contributor

lpy4105 commented Jul 10, 2024

one more thing I need a report command not read only. I will implement and check if it worked.

Report should also work in the latest SDK.

one question: does this mean custom_cmds are only used for network not application-sublayer?

"custom_cmds" you are using is a concept in ZCL over the AF and APS layer. The command is sent via APS data service which supports 4 kind of DstAddrMode. Using the network address is just one of them.

@kgkask
Copy link
Author

kgkask commented Jul 10, 2024

@lpy4105 I tried the write command from the coordinator to end device and it works just fine, however it does not go in the other direction ( from End device to Coordinator) not sure why?!

I tried the report from the end point as well and it is not recognized be the coordinator at all not sure why?!

@lpy4105 could you please give example of how to use custom_command's as APS command so that I can stop them when end device is unbind from the coordinator.

Much thanks @lpy4105 <3

@lpy4105
Copy link
Contributor

lpy4105 commented Jul 11, 2024

I tried the write command from the coordinator to end device and it works just fine, however it does not go in the other direction ( from End device to Coordinator) not sure why?!

Conceptually, the ZCL communications are using server/client model, and don't care about the "device role" (i.e. ZC/ZR/ZED).
Back to your case, I assume you have a "custom cluster client" on the zigbee coordinator (ZC) and the same "custom cluster server" on the zigbee end device (ZED). If you want to "write attribute" to the "custom cluster client" on ZC, there must be an attribute in the "custom cluster client".

could you please give example of how to use custom_command's as APS command so that I can stop them when end device is unbind from the coordinator.

You can refer to the HA_thermostat and HA_temperature_sensor examples.

Here is the code that send command via Bindings:

/* Send "read attributes" command to the bound sensor */
esp_zb_zcl_read_attr_cmd_t read_req;
read_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
read_req.zcl_basic_cmd.src_endpoint = HA_THERMOSTAT_ENDPOINT;
read_req.clusterID = ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT;

@kgkask
Copy link
Author

kgkask commented Jul 11, 2024

So you mean I have to declare a 2 cluster in each side (client and server) so It will be as follows:
ZC ZED
Server ---------WRT-----------> client

client <-----------WRT--------- Server

Last question, the current implementation suits my application very well, So is there a way to just remove the device from the network instead of trying to replicate everything using the APS commands?

Much thanks for your responses.

@lpy4105
Copy link
Contributor

lpy4105 commented Jul 11, 2024

So you mean I have to declare a 2 cluster in each side

Generally speaking, YES.
However it really depends on how you defines your custom cluster. It is possible to have attribute on both Server and Client side with the same attribute id.

So is there a way to just remove the device from the network

I think you could try esp_zb_zdo_device_leave_req.

@kgkask
Copy link
Author

kgkask commented Jul 11, 2024

I implement it and it works however it seems that it remove the coordinator itself from the network, since when I initiated from the coordinator side while 2 end devices connected none of the devices could communicate.

anyhow I found way to implemented, however I am wondering if there is way to send backpack info with the response to any command. for example for write_cmd() the response I receive is 1082262485. which is obtained from log_e( "Received message: data (%d)", message->variables); so if there is it would be extremely helpful

image

last point, for the documentation I could not find something which is very detailed currently I am using : https://zigbeealliance.org/wp-content/uploads/2019/11/docs-05-3474-21-0csg-zigbee-specification.pdf
image

@lpy4105
Copy link
Contributor

lpy4105 commented Jul 11, 2024

write attributes command and write attributes response command are defined in the ZCL (zigbee cluster library) spec. You can also find the defination of the structures in our headers:

typedef struct esp_zb_zcl_write_attr_resp_variable_s {
esp_zb_zcl_status_t status; /*!< The field specifies the status of the write operation on this attribute */
uint16_t attribute_id; /*!< The attribute id of the write attribute response, please note that when info.status does not equal
ESP_ZB_ZCL_STATUS_SUCCESS, the attribute_id is reported; otherwise, it is an invalid value (0xFFFF) */
struct esp_zb_zcl_write_attr_resp_variable_s *next; /*!< Next variable */
} esp_zb_zcl_write_attr_resp_variable_t;
/**
* @brief The Zigbee zcl response struct for writing attribute
*
*/
typedef struct esp_zb_zcl_cmd_write_attr_resp_message_s {
esp_zb_zcl_cmd_info_t info; /*!< The basic information of the write attribute response message that refers to esp_zb_zcl_cmd_info_t */
esp_zb_zcl_write_attr_resp_variable_t *variables; /*!< The variable items, @ref esp_zb_zcl_write_attr_resp_variable_s */
} esp_zb_zcl_cmd_write_attr_resp_message_t;

Or online API reference:
https://docs.espressif.com/projects/esp-zigbee-sdk/en/latest/esp32h2/api-reference/zcl/esp_zigbee_zcl_command.html#_CPPv437esp_zb_zcl_write_attr_resp_variable_s

@kgkask
Copy link
Author

kgkask commented Jul 11, 2024

I am aware about them, but I am not sure how to initiate the response. Shall it go inside the handler for the write response?

write_attr_handler(){


esp_zb_zcl_write_attr_cmd_resp();
}

my issue I could not find the command, and will it override the automated one.

and much thanks for your patience and responses.

@lpy4105
Copy link
Contributor

lpy4105 commented Jul 11, 2024

Ahh, the SDK has done that for you, so you don't need to handle them yourself neither initiate the responses. The "write attribute command" and the response are standardized and you couldn't override them.

@kgkask
Copy link
Author

kgkask commented Jul 11, 2024

Okay,

That make sense and meet my understanding, so much thanks, and I will look for work around to implement my application.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants