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

Problem with Reporting Multistate Value (TZ-1330) #491

Open
mahdi1-kh opened this issue Nov 25, 2024 · 10 comments
Open

Problem with Reporting Multistate Value (TZ-1330) #491

mahdi1-kh opened this issue Nov 25, 2024 · 10 comments
Labels

Comments

@mahdi1-kh
Copy link

mahdi1-kh commented Nov 25, 2024

Question

Description: I am attempting to create a Zigbee to UART dongle similar to the one described here.
Based on my research and observing the PTVO firmware clusters on Z2M, I concluded that I should use the MultistateValue cluster. I have read the ZCL documentation and this GitHub issue.

I have also tried making code changes based on this example.

However, after connecting the device to my Z2M network and pressing the key, no report is sent to Z2M.

I experimented with different modes of using esp_zb_zcl_report_attr_cmd_req and esp_zb_zcl_set_attribute_val. I tried these together and separately, but no report was sent.

Could you help identify the issue in my code or provide an example of using a multistate value?

Here is the code I tested:

Additional context.

 * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
 *
 * SPDX-License-Identifier: CC0-1.0
 *
 * Zigbee customized client Example
 *
 * This example code is in the Public Domain (or CC0 licensed, at your option.)
 *
 * Unless required by applicable law or agreed to in writing, this
 * software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
 * CONDITIONS OF ANY KIND, either express or implied.
 */
#include "esp_HA_customized_switch.h"
#include "esp_check.h"
#include "esp_err.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "string.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "zcl/esp_zigbee_zcl_common.h"

#if !defined ZB_ED_ROLE
#error Define ZB_ED_ROLE in idf.py menuconfig to compile light switch (End Device) source code.
#endif

static const char *TAG = "ESP_HA_ON_OFF_SWITCH";

static switch_func_pair_t button_func_pair[] = {
    {GPIO_INPUT_IO_TOGGLE_SWITCH, SWITCH_ONOFF_TOGGLE_CONTROL}
};




static void zb_buttons_handler(switch_func_pair_t *button_func_pair)
{
    uint16_t event_value = 121;

    switch (button_func_pair->func) {
    case SWITCH_ONOFF_TOGGLE_CONTROL: {
        
        esp_zb_lock_acquire(portMAX_DELAY);
        esp_zb_zcl_set_attribute_val(HA_ONOFF_SWITCH_ENDPOINT,
                                 ESP_ZB_ZCL_CLUSTER_ID_MULTI_VALUE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE,
                                 ESP_ZB_ZCL_ATTR_MULTI_VALUE_PRESENT_VALUE_ID, &event_value, false);
        esp_zb_lock_release();
        ESP_LOGI(TAG, "Set attribute");


        esp_zb_zcl_report_attr_cmd_t report_attr_cmd = {0};
        report_attr_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
        report_attr_cmd.attributeID = ESP_ZB_ZCL_ATTR_MULTI_VALUE_PRESENT_VALUE_ID;
        report_attr_cmd.direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_CLI;
        report_attr_cmd.clusterID = ESP_ZB_ZCL_CLUSTER_ID_MULTI_VALUE;
        report_attr_cmd.zcl_basic_cmd.src_endpoint = HA_ONOFF_SWITCH_ENDPOINT;



        esp_zb_lock_acquire(portMAX_DELAY);
        esp_err_t err = esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd);
        esp_zb_lock_release();

        if (err == ESP_OK)
            ESP_LOGI(TAG, "Reported button click");
        else
            ESP_LOGW(TAG, "Reporting button click failed");

    } break;
    default:
        break;
    }
}

static esp_err_t deferred_driver_init(void)
{
    ESP_RETURN_ON_FALSE(switch_driver_init(button_func_pair, PAIR_SIZE(button_func_pair), zb_buttons_handler), ESP_FAIL, TAG,
                        "Failed to initialize switch driver");
    return ESP_OK;
}

static void bdb_start_top_level_commissioning_cb(uint8_t mode_mask)
{
    ESP_RETURN_ON_FALSE(esp_zb_bdb_start_top_level_commissioning(mode_mask) == ESP_OK, , TAG, "Failed to start Zigbee bdb commissioning");
}


void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct)
{
    uint32_t *p_sg_p       = signal_struct->p_app_signal;
    esp_err_t err_status = signal_struct->esp_err_status;
    esp_zb_app_signal_type_t sig_type = *p_sg_p;
    esp_zb_zdo_signal_leave_params_t *leave_params = NULL;
    switch (sig_type) {
    case ESP_ZB_BDB_SIGNAL_DEVICE_FIRST_START:
    case ESP_ZB_BDB_SIGNAL_DEVICE_REBOOT:
    case ESP_ZB_BDB_SIGNAL_STEERING:
        if (err_status != ESP_OK) {
            ESP_LOGW(TAG, "Stack %s failure with %s status, steering",esp_zb_zdo_signal_to_string(sig_type), esp_err_to_name(err_status));
            esp_zb_scheduler_alarm((esp_zb_callback_t)bdb_start_top_level_commissioning_cb, ESP_ZB_BDB_MODE_NETWORK_STEERING, 1000);
        } else {
            /* device auto start successfully and on a formed network */
            ESP_LOGI(TAG, "Deferred driver initialization %s", deferred_driver_init() ? "failed" : "successful");
            esp_zb_ieee_addr_t extended_pan_id;
            esp_zb_get_extended_pan_id(extended_pan_id);
            ESP_LOGI(TAG, "Joined network successfully (Extended PAN ID: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, PAN ID: 0x%04hx, Channel:%d, Short Address: 0x%04hx)",
                     extended_pan_id[7], extended_pan_id[6], extended_pan_id[5], extended_pan_id[4],
                     extended_pan_id[3], extended_pan_id[2], extended_pan_id[1], extended_pan_id[0],
                     esp_zb_get_pan_id(), esp_zb_get_current_channel(), esp_zb_get_short_address());
        
        }
        break;
    case ESP_ZB_ZDO_SIGNAL_LEAVE:
        leave_params = (esp_zb_zdo_signal_leave_params_t *)esp_zb_app_signal_get_params(p_sg_p);
        if (leave_params->leave_type == ESP_ZB_NWK_LEAVE_TYPE_RESET) {
            ESP_LOGI(TAG, "Reset device");
        }
        break;
    default:
        ESP_LOGI(TAG, "ZDO signal: %s (0x%x), status: %s", esp_zb_zdo_signal_to_string(sig_type), sig_type,
                 esp_err_to_name(err_status));
        break;
    }
}

static esp_err_t zb_action_handler(esp_zb_core_action_callback_id_t callback_id, const void *message)
{
    esp_err_t ret = ESP_OK;
    ESP_LOGW(TAG, "Receive Zigbee action(0x%x) callback", callback_id);
    return ret;
}

static void esp_zb_task(void *pvParameters)
{
    /* initialize Zigbee stack */
    esp_zb_cfg_t zb_nwk_cfg = ESP_ZB_ZED_CONFIG();
    esp_zb_init(&zb_nwk_cfg);
    uint8_t test_attr;
    test_attr = 0;
    /* basic cluster create with fully customized */
    esp_zb_attribute_list_t *esp_zb_basic_cluster = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_BASIC);
    esp_zb_basic_cluster_add_attr(esp_zb_basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MANUFACTURER_NAME_ID, ESP_MANUFACTURER_NAME);
    esp_zb_basic_cluster_add_attr(esp_zb_basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MODEL_IDENTIFIER_ID, ESP_MODEL_IDENTIFIER);

    esp_zb_basic_cluster_add_attr(esp_zb_basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_ZCL_VERSION_ID, &test_attr);
    esp_zb_basic_cluster_add_attr(esp_zb_basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_POWER_SOURCE_ID, &test_attr);
    esp_zb_cluster_update_attr(esp_zb_basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_ZCL_VERSION_ID, &test_attr);

    /* identify cluster create with fully customized */
    esp_zb_attribute_list_t *esp_zb_identify_cluster = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_IDENTIFY);
    esp_zb_identify_cluster_add_attr(esp_zb_identify_cluster, ESP_ZB_ZCL_ATTR_IDENTIFY_IDENTIFY_TIME_ID, ESP_ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE);

    /* create client role of the cluster */
    esp_zb_attribute_list_t *esp_zb_on_off_client_cluster = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_ON_OFF);
    esp_zb_attribute_list_t *esp_zb_identify_client_cluster = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_IDENTIFY);

    /* multistatevalue cluster create with fully customized */
    esp_zb_attribute_list_t *esp_zb_multistate_value_cluster = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_MULTI_VALUE);
    uint32_t application_type_value = ESP_ZB_ZCL_MV_SET_APP_TYPE_WITH_ID(0xffff,0x111);
    esp_zb_multistate_value_cluster_add_attr(esp_zb_multistate_value_cluster, 
    ESP_ZB_ZCL_ATTR_MULTI_VALUE_APPLICATION_TYPE_ID, &application_type_value);
    char desc[] = "test";
    esp_zb_multistate_value_cluster_add_attr(esp_zb_multistate_value_cluster, ESP_ZB_ZCL_ATTR_MULTI_VALUE_DESCRIPTION_ID, desc);
    uint16_t test1 = 77;
    bool test2 = true;
    esp_zb_multistate_value_cluster_add_attr(esp_zb_multistate_value_cluster, 
    ESP_ZB_ZCL_ATTR_MULTI_VALUE_OUT_OF_SERVICE_ID,  &test2);
    esp_zb_multistate_value_cluster_add_attr(esp_zb_multistate_value_cluster, 
    ESP_ZB_ZCL_ATTR_MULTI_VALUE_PRESENT_VALUE_ID,  &test1);


    /* create cluster lists for this endpoint */
    esp_zb_cluster_list_t *esp_zb_cluster_list = esp_zb_zcl_cluster_list_create();
    esp_zb_cluster_list_add_basic_cluster(esp_zb_cluster_list, esp_zb_basic_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
    esp_zb_cluster_list_add_identify_cluster(esp_zb_cluster_list, esp_zb_identify_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
    esp_zb_cluster_list_add_on_off_cluster(esp_zb_cluster_list, esp_zb_on_off_client_cluster, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);
    esp_zb_cluster_list_add_identify_cluster(esp_zb_cluster_list, esp_zb_identify_client_cluster, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);
    esp_zb_cluster_list_add_multistate_value_cluster(esp_zb_cluster_list, esp_zb_multistate_value_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);


/*--------------------------get access-------------------------*/
      esp_zb_attribute_list_t *multi_value_cluster =
        esp_zb_cluster_list_get_cluster(esp_zb_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_MULTI_VALUE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
    esp_zb_attribute_list_t *attr = multi_value_cluster;
    while (attr) {
        if (attr->attribute.id == ESP_ZB_ZCL_ATTR_MULTI_VALUE_PRESENT_VALUE_ID) {
            attr->attribute.access = multi_value_cluster->attribute.access | ESP_ZB_ZCL_ATTR_ACCESS_REPORTING;
            break;
        }
        attr = attr->next;
    }


/*--------------------------endpoint-------------------------*/

    esp_zb_ep_list_t *esp_zb_ep_list = esp_zb_ep_list_create();
    esp_zb_endpoint_config_t endpoint_config = {
        .endpoint = HA_ONOFF_SWITCH_ENDPOINT,
        .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID,
        .app_device_id = ESP_ZB_HA_ON_OFF_SWITCH_DEVICE_ID,
        .app_device_version = 0
    };
    esp_zb_ep_list_add_ep(esp_zb_ep_list, esp_zb_cluster_list, endpoint_config);

    


    esp_zb_device_register(esp_zb_ep_list);


    
    /* Config the reporting info  */
    esp_zb_zcl_reporting_info_t reporting_info = {
        .direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_SRV,
        .ep = HA_ONOFF_SWITCH_ENDPOINT,
        .cluster_id = ESP_ZB_ZCL_CLUSTER_ID_MULTI_VALUE,
        .cluster_role = ESP_ZB_ZCL_CLUSTER_SERVER_ROLE,
        .dst.profile_id = ESP_ZB_AF_HA_PROFILE_ID,
        .u.send_info.min_interval = 1,
        .u.send_info.max_interval = 0,
        .u.send_info.def_min_interval = 1,
        .u.send_info.def_max_interval = 0,
        .u.send_info.delta.u16 = 100,
        .attr_id = ESP_ZB_ZCL_ATTR_MULTI_VALUE_PRESENT_VALUE_ID,
        .manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC,
    };

    esp_zb_zcl_update_reporting_info(&reporting_info);


    esp_zb_core_action_handler_register(zb_action_handler);
    esp_zb_set_primary_network_channel_set(ESP_ZB_PRIMARY_CHANNEL_MASK);
    esp_zb_set_secondary_network_channel_set(ESP_ZB_SECONDARY_CHANNEL_MASK);

    esp_zb_ieee_addr_t my_addr = {0x32, 0x31, 0x19, 0x93, 0x21, 0xfB, 0xCD, 0xEF};
    esp_zb_set_long_address(my_addr);

    ESP_ERROR_CHECK(esp_zb_start(true));
    esp_zb_stack_main_loop();
}

void app_main(void)
{
    esp_zb_platform_config_t config = {
        .radio_config = ESP_ZB_DEFAULT_RADIO_CONFIG(),
        .host_config = ESP_ZB_DEFAULT_HOST_CONFIG(),
    };
    ESP_ERROR_CHECK(nvs_flash_init());
    ESP_ERROR_CHECK(esp_zb_platform_config(&config));
    xTaskCreate(esp_zb_task, "Zigbee_main", 4096, NULL, 5, NULL);
}
@github-actions github-actions bot changed the title Problem with Reporting Multistate Value Problem with Reporting Multistate Value (TZ-1330) Nov 25, 2024
@xieqinan
Copy link
Contributor

Hi,

I believe the issue is caused by the incorrect address mode: report_attr_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;. When using this mode, a binding relationship between the Z2M and the current device must exist in the binding table of the current device.

Could you please try using the ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT mode instead? Assign the destination endpoint to zcl_basic_cmd.dst_endpoint and the destination address to zcl_basic_cmd.dst_address. Please refer to here

@mahdi1-kh
Copy link
Author

@xieqinan
Hi

Thank you so much for your help! Your assistance resolved my issue.

I have another question regarding ESP_ZB_ZCL_ATTR_MULTI_VALUE_STATE_TEXT. Do you know when this feature will be added? If not, do you have any other suggestions that could substitute this feature? I need to solve this problem as soon as possible.

Thanks again for your help!

@xieqinan
Copy link
Contributor

@mahdi1-kh ,

The ESP_ZB_ZCL_ATTR_MULTI_VALUE_STATE_TEXT attribute is intended to describe all possible states of a multistate PresentValue. I believe this is not a necessary attribute. Could you please share how you plan to use it?

@mahdi1-kh
Copy link
Author

mahdi1-kh commented Nov 27, 2024

@xieqinan

I'm trying to build a Zigbee to UART dongle similar to the PTVO UART firmware for CC2652. My goal is to transfer an array of numbers using Zigbee. I observed the outputs of the PTVO firmware on Z2M logs, and they were as follows:

z2m: Received Zigbee message from '0x00124b002a7b4d21', type 'attributeReport', 
cluster 'genMultistateValue', data '{"stateText":{"data":[70,82,3,2,2,2,2,2,2,2,2,2,2,2,4,4,4,4,0],"type":"Buffer"}}' from endpoint 1 with groupID 0'

And that's how I know that I should use the stateTextattribute.
My goal is to replicate this with the ESP-Zigbee-SDK.

@mahdi1-kh
Copy link
Author

I was looking for a replacement and found this document. I tested the code provided
there and it worked, and I was able to get reports in Z2M, somehow solving my problem. However, when I try to change the attr_type, I can't get any reports in Z2M anymore. Here is the the changes I have made in the code:

Custom Cluster:

esp_zb_attribute_list_t *custom_cluster = esp_zb_zcl_attr_list_create(CUSTOM_CLUSTER_ID);
uint16_t custom_attr1_id = 0x01;
uint8_t custom_attr1_value[4] = {70,80,90,100};
uint16_t custom_attr2_id = 0x0000;
uint16_t custom_attr2_value = 0x1234;
esp_zb_custom_cluster_add_custom_attr(custom_cluster, custom_attr1_id, ESP_ZB_ZCL_ATTR_TYPE_ARRAY,
                                      ESP_ZB_ZCL_ATTR_ACCESS_WRITE_ONLY | ESP_ZB_ZCL_ATTR_ACCESS_REPORTING, custom_attr1_value);
esp_zb_custom_cluster_add_custom_attr(custom_cluster, custom_attr2_id, ESP_ZB_ZCL_ATTR_TYPE_U16, ESP_ZB_ZCL_ATTR_ACCESS_READ_WRITE,
                                      &custom_attr2_value);

Custom Command

 esp_zb_zcl_custom_cluster_cmd_req_t req;
        uint8_t custom_value[5] = {20,30,40,50,60};
        req.zcl_basic_cmd.dst_addr_u.addr_short = 0x000; // Set it according to the actual destination short address.
        req.zcl_basic_cmd.dst_endpoint = 1;
        req.zcl_basic_cmd.src_endpoint = 1;
        req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
        req.cluster_id = CUSTOM_CLUSTER_ID;
        req.profile_id = ESP_ZB_AF_HA_PROFILE_ID;
        req.direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_SRV;
        req.custom_cmd_id = 0x01;
        req.data.type = ESP_ZB_ZCL_ATTR_TYPE_ARRAY;
        req.data.size = (sizeof(custom_value)+2);
        req.data.value = custom_value;
        esp_zb_lock_acquire(portMAX_DELAY);
        esp_zb_zcl_custom_cluster_cmd_req(&req);
        esp_zb_lock_release();
        ESP_EARLY_LOGI(TAG, "Send %d to custom device", custom_value);

@xieqinan
Copy link
Contributor

@mahdi1-kh

And that's how I know that I should use the stateTextattribute.

The attribute will still not be supported in the upcoming release. I would like to discuss the solution you provided.

However, when I try to change the attr_type, I can't get any reports in Z2M anymore. Here is the the changes I have made in the code:

The first two bytes indicate the length of the array; refer to here.

esp_zb_attribute_list_t *custom_cluster = esp_zb_zcl_attr_list_create(CUSTOM_CLUSTER_ID);
uint16_t custom_attr1_id = 0x01;
uint8_t custom_attr1_value[6] = {0, 0, 70,80,90,100};
uint16_t custom_attr2_id = 0x0000;
uint16_t custom_attr2_value = 0x1234;

uint16_t *attr1_array_len = custom_attr1_value;
*attr1_array_len = sizeof(custom_attr1_value) - 2;

esp_zb_custom_cluster_add_custom_attr(custom_cluster, custom_attr1_id, ESP_ZB_ZCL_ATTR_TYPE_ARRAY,
                                      ESP_ZB_ZCL_ATTR_ACCESS_WRITE_ONLY | ESP_ZB_ZCL_ATTR_ACCESS_REPORTING, custom_attr1_value);
esp_zb_custom_cluster_add_custom_attr(custom_cluster, custom_attr2_id, ESP_ZB_ZCL_ATTR_TYPE_U16, ESP_ZB_ZCL_ATTR_ACCESS_READ_WRITE,
                                      &custom_attr2_value);
        esp_zb_zcl_custom_cluster_cmd_req_t req;
        uint8_t custom_value[7] = {0, 0, 20,30,40,50,60};
        
        uint16_t *value_array_len = custom_value;
        *value_array_len = sizeof(custom_value) - 2;
        
        req.zcl_basic_cmd.dst_addr_u.addr_short = 0x000; // Set it according to the actual destination short address.
        req.zcl_basic_cmd.dst_endpoint = 1;
        req.zcl_basic_cmd.src_endpoint = 1;
        req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
        req.cluster_id = CUSTOM_CLUSTER_ID;
        req.profile_id = ESP_ZB_AF_HA_PROFILE_ID;
        req.direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_SRV;
        req.custom_cmd_id = 0x01;
        req.data.type = ESP_ZB_ZCL_ATTR_TYPE_ARRAY;
        req.data.size = (sizeof(custom_value));
        req.data.value = custom_value;
        esp_zb_lock_acquire(portMAX_DELAY);
        esp_zb_zcl_custom_cluster_cmd_req(&req);
        esp_zb_lock_release();
        ESP_EARLY_LOGI(TAG, "Send %d to custom device", custom_value);

@mahdi1-kh
Copy link
Author

mahdi1-kh commented Nov 30, 2024

Thank you very much for your guidance. This code worked correctly, but I realized that the esp_zb_zcl_custom_cluster_cmd_req function causes a panic with sizes greater than 120. In my search, I encountered this guidance from you. I used the esp_zb_zcl_write_attr_cmd_req function, and it worked fine up to a data size of 154. From 155 onwards, I got no reports in Z2M. I wanted to know if this limitation is from z2m, if it's a problem with my code, or if it is a limitation of the SDK

@xieqinan
Copy link
Contributor

xieqinan commented Dec 2, 2024

Hi @mahdi1-kh ,

I used the esp_zb_zcl_write_attr_cmd_req function, and it worked fine up to a data size of 154. From 155 onwards, I got no reports in Z2M.

This issue is similar with the link, I think you can follow it and check whether your issue also can be resolved.

@mahdi1-kh
Copy link
Author

mahdi1-kh commented Dec 2, 2024

hi @xieqinan,

The way I understood the issue you mentioned that the length of the list should be stored in the first byte of the first list. I did the same thing as the code you modified here

uint16_t *attr1_array_len = custom_attr1_value;
*attr1_array_len = sizeof(custom_attr1_value) - 2;

and increased the size in the initial definition but it didn't resolve the issue and I still don't get reports in Z2M for messages with a size bigger than 154. Here's the modified code:

esp_zb_attribute_list_t *custom_cluster = esp_zb_zcl_attr_list_create(CUSTOM_CLUSTER_ID);
uint16_t custom_attr1_id = 0x01;
uint8_t custom_attr1_value[250] ;
uint16_t custom_attr2_id = 0x0000;
uint16_t custom_attr2_value = 0x1234;

for (uint16_t i = 0; i < 250; i++) { 
           custom_attr1_value[i+2] = i + 1;            
       
        }

uint16_t *attr1_array_len = custom_attr1_value;
*attr1_array_len = sizeof(custom_attr1_value) - 2;
for (size_t i = 0; i < 5; i++) { printf("custom_value[%zu] = %u\n", i, custom_attr1_value[i]); }

esp_zb_custom_cluster_add_custom_attr(custom_cluster, custom_attr1_id, ESP_ZB_ZCL_ATTR_TYPE_ARRAY,
                                     ESP_ZB_ZCL_ATTR_ACCESS_WRITE_ONLY | ESP_ZB_ZCL_ATTR_ACCESS_REPORTING, custom_attr1_value);
esp_zb_custom_cluster_add_custom_attr(custom_cluster, custom_attr2_id, ESP_ZB_ZCL_ATTR_TYPE_U16, ESP_ZB_ZCL_ATTR_ACCESS_READ_WRITE,
                                     &custom_attr2_value);
esp_zb_zcl_custom_cluster_cmd_req_t req;
        uint8_t custom_value[156] ;

        for (uint16_t i = 0; i < 154; i++) { custom_value[i+2] = i + 1;}    

        uint16_t *value_array_len = custom_value;
        *value_array_len = sizeof(custom_value) - 2;
        for (size_t i = 0; i < 5; i++) { printf("custom_value[%zu] = %u\n", i, custom_value[i]); }

esp_zb_zcl_attribute_t attr_field1[] = 
{
   {0x01, {ESP_ZB_ZCL_ATTR_TYPE_ARRAY, (sizeof(custom_value)), custom_value}}

};


esp_zb_zcl_write_attr_cmd_t test_req = {
                        .zcl_basic_cmd = {
                            .dst_addr_u.addr_short = 0x000,
                            .dst_endpoint = 1,
                            .src_endpoint = 1,
                        },
                        .address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT,
                        .clusterID = CUSTOM_CLUSTER_ID,
                        .attr_number = 1,
                        . attr_field = attr_field1,
                    };


esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_write_attr_cmd_req(&test_req);
esp_zb_lock_release();

Although 150 meets my needs, I'm just curious to understand the reason behind this issue.

@xieqinan
Copy link
Contributor

but it didn't resolve the issue and I still don't get reports in Z2M for messages with a size bigger than 154.

The maximum fragment length depends on the destination device. If the Max Incoming Transfer Size of the destination device is smaller than 154, a write attribute request exceeding this size might still be sent. Could you please verify this behavior? It would be helpful if you could share the .pcap file captured by the sniffer for further analysis.
image

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