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

Cannot set present value attribute of binary input cluster (TZ-1486) #537

Open
jonasbu01 opened this issue Jan 18, 2025 · 5 comments
Open
Labels

Comments

@jonasbu01
Copy link

Question

We are attempting to set the value of the present value attribute of the binary input cluster as follows:

    bool value = true;
    esp_zb_lock_acquire(portMAX_DELAY);
    esp_zb_zcl_status_t res = esp_zb_zcl_set_attribute_val(
        this->id,
        ESP_ZB_ZCL_CLUSTER_ID_BINARY_INPUT, 
        ESP_ZB_ZCL_CLUSTER_SERVER_ROLE,
        ESP_ZB_ZCL_ATTR_BINARY_INPUT_PRESENT_VALUE_ID, 
        &value, 
        false);
    esp_zb_lock_release();

However, esp_zb_zcl_set_attribute_val constantly returns 1 indicating an error. Even though the attribute should be writable according to the Zigbee Cluster API specification. We have also tried to make value of type uint8_t but leads to the same result. Can you give a hint how to resolve this problem?

Additional context.

We are creating the endpoint as follows:

    esp_zb_attribute_list_t *basic_cluster = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_BASIC);
    esp_zb_basic_cluster_add_attr(basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MANUFACTURER_NAME_ID, reinterpret_cast<void*>(const_cast<char*>(MANUFACTURER)));
    esp_zb_basic_cluster_add_attr(basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MODEL_IDENTIFIER_ID, reinterpret_cast<void*>(const_cast<char*>(MODEL)));

    this->config.out_of_service = false;
    this->config.status_flags = ESP_ZB_ZCL_BINARY_INPUT_STATUS_FLAG_DEFAULT_VALUE;
    esp_zb_attribute_list_t *simple_sensor_cluster = esp_zb_binary_input_cluster_create(&this->config);

    this->clusters = esp_zb_zcl_cluster_list_create();
    esp_zb_cluster_list_add_basic_cluster(this->clusters, basic_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
    esp_zb_cluster_list_update_cluster(this->clusters, esp_zb_basic_cluster_create(NULL), ESP_ZB_ZCL_CLUSTER_ID_BASIC,
                                       ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
    esp_zb_cluster_list_add_binary_input_cluster(this->clusters, simple_sensor_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);

    this->config = {
        .endpoint = endpoint_id,
        .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID,
        .app_device_id = ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID,
        .app_device_version = 0
    };

    decltype(((esp_zb_zcl_reporting_info_t*)0)->u.send_info) send_info = {
        .min_interval = 1,
        .max_interval = 1,
        .def_min_interval = 1,
        .def_max_interval = 1,
    };

    this->endpoints = esp_zb_ep_list_create();
    esp_zb_ep_list_add_ep(this->endpoints, this->clusters, this->config);

    this->reporting_info = {
        .direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_SRV,
        .ep = this->id,
        .cluster_id = ESP_ZB_ZCL_CLUSTER_ID_BINARY_INPUT,
        .cluster_role = ESP_ZB_ZCL_CLUSTER_SERVER_ROLE,
        .attr_id = ESP_ZB_ZCL_ATTR_BINARY_INPUT_PRESENT_VALUE_ID,
        .u = { .send_info = send_info },
        .dst = { .profile_id = ESP_ZB_AF_HA_PROFILE_ID },
        .manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC
    };
    esp_zb_zcl_update_reporting_info(this->reporting_info);
@github-actions github-actions bot changed the title Cannot set present value attribute of binary input cluster Cannot set present value attribute of binary input cluster (TZ-1486) Jan 18, 2025
@asward
Copy link

asward commented Jan 19, 2025

I have a similar issue. It's not clear to me that the PresentValue (0x55) attribute is added to the cluster by esp_zb_binary_input_cluster_create.

If I use esp_zb_zcl_get_attribute looking forESP_ZB_ZCL_ATTR_BINARY_INPUT_PRESENT_VALUE_ID I get:

Guru Meditation Error: Core  0 panic'ed (Load access fault). Exception was unhandled.

If I manually add the attribute as a bool type according to the spec, I can use esp_zb_zcl_get_attribute.

    esp_zb_cluster_add_attr(door_binary_input_attr_list,
            ZB_ZCL_CLUSTER_ID_BINARY_INPUT,
            ZB_ZCL_ATTR_BINARY_INPUT_PRESENT_VALUE_ID,
            ESP_ZB_ZCL_ATTR_TYPE_BOOL,
            ESP_ZB_ZCL_ATTR_ACCESS_REPORTING | ESP_ZB_ZCL_ATTR_ACCESS_READ_WRITE,
            &init_state);

However, I am unable to then set the value using esp_zb_zcl_set_attribute_val.

I have guess and checked many combinations of configuration (erase-flash between each) to no avail.

Is there a means in the API (esp or zboss) to enumerate what attributes are attached to the cluster(s) after registration?

@xieqinan
Copy link
Contributor

Hi @jonasbu01, @asward,

The esp_zb_binary_input_cluster_create() only adds the attributes ESP_ZB_ZCL_ATTR_BINARY_INPUT_OUT_OF_SERVICE_ID and ESP_ZB_ZCL_ATTR_BINARY_INPUT_STATUS_FLAG_ID to the input cluster. Therefore, the attribute ZB_ZCL_ATTR_BINARY_INPUT_PRESENT_VALUE_ID must be added by the user.

The code below provides a reference for adding this attribute:

#define HA_ESP_LIGHT_ENDPOINT 1

esp_zb_cluster_list_t *esp_zb_cluster_list = esp_zb_zcl_cluster_list_create();
    esp_zb_binary_input_cluster_cfg_t binary_input_cfg = {
        .out_of_service = false,
        .status_flags = ESP_ZB_ZCL_BINARY_INPUT_STATUS_FLAG_DEFAULT_VALUE,
    };
    esp_zb_attribute_list_t *binary_input_cluster = esp_zb_binary_input_cluster_create(&binary_input_cfg);
    bool binary_input_present_value = 0;
    esp_zb_binary_input_cluster_add_attr(binary_input_cluster, ESP_ZB_ZCL_ATTR_BINARY_INPUT_PRESENT_VALUE_ID,
                                         &binary_input_present_value);
    esp_zb_cluster_list_add_binary_input_cluster(esp_zb_cluster_list, binary_input_cluster,
                                                 ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);

    esp_zb_ep_list_t *esp_zb_ep_list = esp_zb_ep_list_create();
    /* add created endpoint (cluster_list) to endpoint list */
    esp_zb_endpoint_config_t endpoint_config = {
        .endpoint = HA_ESP_LIGHT_ENDPOINT,
        .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID,
        .app_device_id = ESP_ZB_HA_ON_OFF_LIGHT_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);

    binary_input_present_value = 1;
    esp_zb_zcl_status_t res = esp_zb_zcl_set_attribute_val(
        HA_ESP_LIGHT_ENDPOINT, ESP_ZB_ZCL_CLUSTER_ID_BINARY_INPUT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE,
        ESP_ZB_ZCL_ATTR_BINARY_INPUT_PRESENT_VALUE_ID, &binary_input_present_value, false);
    ESP_LOGW(TAG, "resp status: 0x%x", res);

    esp_zb_zcl_attr_t *attr =
        esp_zb_zcl_get_attribute(HA_ESP_LIGHT_ENDPOINT, ESP_ZB_ZCL_CLUSTER_ID_BINARY_INPUT,
                                 ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_BINARY_INPUT_PRESENT_VALUE_ID);
    ESP_LOGW(TAG, "binary input present value: 0x%x", *(uint8_t *)attr->data_p);

@asward
Copy link

asward commented Jan 22, 2025

The present value attribute is a mandatory parameter for the binary input (basic) cluster. Is there a reason to exclude it from the cluster generation initially? Further, is it possible to know what the esp zigbee api will provide as far as 'default' attributes for standard clusters? Either documentation or run-time reporting?

Without initializing the attribute (one way or another) a call to esp_zb_zcl_get_attribute yields the core panic noted above. Would it be possible to simply throw or return a error code instead? Perhaps as part of esp_zb_zcl_attr_t? Otherwise these kinds of errors are completely unsolvable without your input, or many permutations of guess and check.

I believe I had used esp_zb_binary_input_cluster_add_attr initially in my code, but favored the more generic esp_zb_cluster_add_attr because it allowed me to flag for READ/WRITE. Indeed, when I try the provided example code I get ESP_ZB_ZCL_STATUS_READ_ONLY when trying to set the attribute. Is there any other differences in the two methods other that simplicity of the binary input specific call?

@xieqinan
Copy link
Contributor

@asward

The present value attribute is a mandatory parameter for the binary input (basic) cluster. Is there a reason to exclude it from the cluster generation initially?

I believe the only reason is its omission. We will include it in the next version.

is it possible to know what the esp zigbee api will provide as far as 'default' attributes for standard clusters? Either documentation or run-time reporting?

For standard cluster creation, mandatory attributes are added by default. You can also refer to the input parameters of the creation API, such as:

esp_zb_attribute_list_t *esp_zb_binary_input_cluster_create(esp_zb_binary_input_cluster_cfg_t *binary_input_cfg)

The esp_zb_binary_input_cluster_cfg_t specifies which attributes will be added when calling esp_zb_binary_input_cluster_create().

Would it be possible to simply throw or return a error code instead? Perhaps as part of esp_zb_zcl_attr_t?

It is an optimization point, and we will consider it.

Is there any other differences in the two methods other that simplicity of the binary input specific call?

The root of the two APIs is the same: esp_zb_binary_input_cluster_add_attr() ensures that the added attribute is standard, while esp_zb_cluster_add_attr() allows the user to add custom attributes.

@asward
Copy link

asward commented Jan 22, 2025

@xieqinan I appreciate your efforts on this library! Thanks for all of those answers, it does clear things up a bit.

Hopefully @jonasbu01 was able to resolve his issues as well.

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

3 participants