ESP-ZIGBEE-SDK: MultiState Input Cluster (Basic): Failed to update reporting info

exkoria
Posts: 2
Joined: Sun Jul 14, 2024 6:40 pm

ESP-ZIGBEE-SDK: MultiState Input Cluster (Basic): Failed to update reporting info

Postby exkoria » Mon Jul 29, 2024 7:47 am

I'm trying to modify the existing example "HA_temperature_sensor" in the ESP-ZIGBEE-SDK but cannot get the reporting info to work. I want to set it up as a MultiState Input Cluster instead. The change seems straight forward but I cannot get it to work. The call that fails is this:

Code: Select all

	// Attempt to update the reporting info
    esp_err_t err = esp_zb_zcl_update_reporting_info(&reporting_info);
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "Failed to update reporting info: %s", esp_err_to_name(err));
        // Handle error appropriately
    } else {
        ESP_LOGI(TAG, "Successfully updated reporting info");
    }
It gives me a 'ESP_ERR_NO_MEM' error.

Below is the modified code. It's very close to the temperature sensor example:

Code: Select all

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;
    switch (sig_type)
    {
    case ESP_ZB_ZDO_SIGNAL_SKIP_STARTUP:
        ESP_LOGI(TAG, "Initialize Zigbee stack");
        esp_zb_bdb_start_top_level_commissioning(ESP_ZB_BDB_MODE_INITIALIZATION);
        break;
    case ESP_ZB_BDB_SIGNAL_DEVICE_FIRST_START:
    case ESP_ZB_BDB_SIGNAL_DEVICE_REBOOT:
        if (err_status == ESP_OK)
        {
            // ESP_LOGI(TAG, "Deferred driver initialization %s", deferred_driver_init() ? "failed" : "successful");
            ESP_LOGI(TAG, "Device started up in %s factory-reset mode", esp_zb_bdb_is_factory_new() ? "" : "non");
            if (esp_zb_bdb_is_factory_new())
            {
                ESP_LOGI(TAG, "Start network steering");
                esp_zb_bdb_start_top_level_commissioning(ESP_ZB_BDB_MODE_NETWORK_STEERING);
            }
            else
            {
                ESP_LOGI(TAG, "Device rebooted");
            }
        }
        else
        {
            /* commissioning failed */
            ESP_LOGW(TAG, "Failed to initialize Zigbee stack (status: %s)", esp_err_to_name(err_status));
        }
        break;
    case ESP_ZB_BDB_SIGNAL_STEERING:
        if (err_status == ESP_OK)
        {
            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());
        }
        else
        {
            ESP_LOGI(TAG, "Network steering was not successful (status: %s)", 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);
        }
        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;
    }
}

// Function to add the Multistate Input Cluster to the cluster list
static esp_zb_cluster_list_t *custom_rain_sensor_clusters_create(esp_zb_rain_sensor_cfg_t *sensor_cfg)
{

    esp_zb_cluster_list_t *cluster_list = esp_zb_zcl_cluster_list_create();

    esp_zb_attribute_list_t *basic_cluster = esp_zb_basic_cluster_create(&(sensor_cfg->basic_cfg));

    ESP_ERROR_CHECK(esp_zb_cluster_list_add_basic_cluster(cluster_list, basic_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE));

    ESP_ERROR_CHECK(esp_zb_cluster_list_add_identify_cluster(cluster_list, esp_zb_identify_cluster_create(&(sensor_cfg->identify_cfg)), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE));
    ESP_ERROR_CHECK(esp_zb_cluster_list_add_identify_cluster(cluster_list, esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_IDENTIFY), ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE));

    // Add the Multistate Input Cluster to the cluster list
    esp_zb_attribute_list_t *attr_list = esp_zb_multistate_value_cluster_create(&(sensor_cfg->rain_sensor_cfg));

    // log_attribute_ids(attr_list);

    esp_err_t err = esp_zb_cluster_list_add_multistate_value_cluster(cluster_list, attr_list, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
        if (err != ESP_OK) {
        ESP_LOGE(TAG, "Failed to add cluster: %s", esp_err_to_name(err));
        // Handle error appropriately
    } else {
        ESP_LOGI(TAG, "Successfully added cluster");
    }

    log_cluster_list_info(cluster_list);

    return cluster_list;
}

// Create the Endpoint Function
static esp_zb_ep_list_t *esp_zb_rain_sensor_ep_create(uint8_t endpoint_id, esp_zb_rain_sensor_cfg_t *sensor_cfg)
{

    esp_zb_ep_list_t *ep_list = esp_zb_ep_list_create();
    esp_zb_endpoint_config_t endpoint_config = {
        .endpoint = endpoint_id,
        .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID,
        .app_device_id = ESP_ZB_HA_RAIN_SENSOR_DEVICE_ID,
        .app_device_version = 0};

    esp_zb_ep_list_add_ep(ep_list, custom_rain_sensor_clusters_create(sensor_cfg), endpoint_config);

    zcl_basic_manufacturer_info_t info = {
        .manufacturer_name = MANUFACTURER_NAME,
        .model_identifier = MODEL_IDENTIFIER,
    };

    esp_zcl_utility_add_ep_basic_manufacturer_info(ep_list, endpoint_id, &info);

    return ep_list;
}

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

    esp_zb_rain_sensor_cfg_t rain_sensor_cfg = {
        .basic_cfg = {
            .zcl_version = ESP_ZB_ZCL_BASIC_ZCL_VERSION_DEFAULT_VALUE,
            .power_source = ESP_ZB_ZCL_BASIC_POWER_SOURCE_DEFAULT_VALUE},
        .identify_cfg = {.identify_time = ESP_ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE},
        .rain_sensor_cfg = {.number_of_states = (uint16_t)256, .out_of_service = false, .present_value = (uint16_t)1, .status_flags = STATUS_NORMAL_OPERATION}};

    esp_zb_ep_list_t *esp_zb_sensor_ep = esp_zb_rain_sensor_ep_create(HA_ESP_SENSOR_ENDPOINT, &rain_sensor_cfg);

    // /* Register the device */
    esp_zb_device_register(esp_zb_sensor_ep);

    // /* Config the reporting info  */
    esp_zb_zcl_reporting_info_t reporting_info = {
        .direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_SRV,
        .ep = HA_ESP_SENSOR_ENDPOINT, 
        .cluster_id = 0x0014, //0x0014, /*!< Multistate Input cluster ID */
        .cluster_role = ESP_ZB_ZCL_CLUSTER_SERVER_ROLE,
        .dst.profile_id = ESP_ZB_AF_HA_PROFILE_ID,
        .u.send_info.min_interval = 30, // Minimum interval of 30 seconds
        .u.send_info.max_interval = 600, // Maximum interval of 10 minutes
        .u.send_info.def_min_interval = 30, // Default minimum interval of 30 seconds
        .u.send_info.def_max_interval = 600, // Default maximum interval of 10 minutes
        .u.send_info.delta.u16 = 1, // Report on every state change
        .attr_id = 0x0055, //0x0055, /*!< PresentValue attribute */
        .manuf_code = 0xFFFF,
    };

    // Attempt to update the reporting info
    esp_err_t err = esp_zb_zcl_update_reporting_info(&reporting_info);
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "Failed to update reporting info: %s", esp_err_to_name(err));
        // Handle error appropriately
    } else {
        ESP_LOGI(TAG, "Successfully updated reporting info");
    }

    esp_zb_set_primary_network_channel_set(ESP_ZB_PRIMARY_CHANNEL_MASK);
    ESP_ERROR_CHECK(esp_zb_start(false));

    esp_zb_main_loop_iteration();
}
I can see that the cluster is successfully added and I can read the attribute present_value from the coordinator but I the esp_zb_zcl_update_reporting_info(&reporting_info) fails. Does anyone have a clue why that might be?

aliarifat794
Posts: 200
Joined: Sun Jun 23, 2024 6:18 pm

Re: ESP-ZIGBEE-SDK: MultiState Input Cluster (Basic): Failed to update reporting info

Postby aliarifat794 » Mon Jul 29, 2024 3:01 pm

The ESP_ERR_NO_MEM error indicates that there is insufficient memory available for the requested operation. Check the available heap memory before and after calling esp_zb_zcl_update_reporting_info(). This will help identify if memory is getting consumed somewhere unexpectedly.

theorlangur
Posts: 2
Joined: Wed Oct 02, 2024 6:19 pm

Re: ESP-ZIGBEE-SDK: MultiState Input Cluster (Basic): Failed to update reporting info

Postby theorlangur » Wed Oct 02, 2024 6:21 pm

@exkoria, were you able to figure out the reason?
I'm having similar troubles. I was able to configure reporting for one attribute but as soon as I'm trying to configure reporting for another one I get ESP_ERR_NO_MEM. I check the heap usage and I had plenty of memory available. This must be some very specific kind of memory.

theorlangur
Posts: 2
Joined: Wed Oct 02, 2024 6:19 pm

Re: ESP-ZIGBEE-SDK: MultiState Input Cluster (Basic): Failed to update reporting info

Postby theorlangur » Sun Oct 06, 2024 7:03 pm

theorlangur wrote:
Wed Oct 02, 2024 6:21 pm
@exkoria, were you able to figure out the reason?
I'm having similar troubles. I was able to configure reporting for one attribute but as soon as I'm trying to configure reporting for another one I get ESP_ERR_NO_MEM. I check the heap usage and I had plenty of memory available. This must be some very specific kind of memory.
I think I've figured it out. Maybe it'll help somebody else with similar issues. It seems that this

Code: Select all

ESP_ERR_NO_MEM
has nothing to do with memory. If you enable zigbee debug then you'll see an error message saying that there are no free reporting slots. In the structure

Code: Select all

esp_zb_endpoint_t
one can find a field

Code: Select all

rep_info_count
which I guess reflects exactly this aspect. However it seems to be initialized sometime later in the depths of the zigbee library. The conclusion that I've reached was: the system reserves exactly the number of reporting slots as the amount of attributes that require reporting your device has. In my case it was 1 and I tried to conigure reporting for one of the standard attributes from Zcl that were not marked with 'P' for reporting. So I got an error. Later when I was configuring a custom zigbee cluster and adding custom attributes, I marked 1 of those attributes with

Code: Select all

ESP_ZB_ZCL_ATTR_ACCESS_REPORTING
and after that I could configure also the reporting for it.

Who is online

Users browsing this forum: No registered users and 75 guests