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

HA profiles for Humidity, Pressure and CO2 (Carbon Dioxide) (TZ-750) #313

Closed
jorisvervuurt opened this issue Apr 9, 2024 · 10 comments
Closed

Comments

@jorisvervuurt
Copy link

jorisvervuurt commented Apr 9, 2024

Is your feature request related to a problem?

There currently only is an implementation for a temperature sensor ( see also #8 ). I am working on a Temperature, Humidity, Pressure and Carbon Dioxide (CO2) solution and I want to send it's data via Zigbee.

There is no esp_zb_humidity_sensor_ep_create, esp_zb_pressure_sensor_ep_create or esp_zb_carbon_dioxide_sensor_ep_create. I did notice some references to humidity, pressure and carbon dioxide in the esp_zigbee_type.h file, but the rest isn't there.

As for the default configs, there is ESP_ZB_DEFAULT_TEMPERATURE_SENSOR_CONFIG, but again there are no configs available for humidity, pressure and carbon dioxide.

When will these be added? Or are there instructions somewhere on how to create something custom? Thanks!

Describe the solution you'd like.

No response

Describe alternatives you've considered.

No response

Additional context.

No response

@github-actions github-actions bot changed the title HA profiles for Humidity, Pressure and CO2 (Carbon Dioxide) HA profiles for Humidity, Pressure and CO2 (Carbon Dioxide) (TZ-750) Apr 9, 2024
@acha666
Copy link

acha666 commented Apr 10, 2024

You don't need to create multiple endpoint for each sensors, just use the existing endpoint, and add extra clusters based on your need.

For more info about clusters and their different functions, take a look at ZCL Spec

You need to initalize these Clusters:

  • Temperature Measurement 0x0402
  • Relative Humidity Measurement 0x0405
  • Pressure Measurement 0x0403
  • Carbon Dioxide Measurement 0x040d

Using these APIs:

  • esp_zb_temperature_meas_cluster_create()
  • esp_zb_humidity_meas_cluster_create()
  • esp_zb_pressure_meas_cluster_create()
  • esp_zb_carbon_dioxide_measurement_cluster_create()

Here is my initialization code of temp, humi and pressure clusters:

    // ------------------------------ Cluster Temperature ------------------------------
    esp_zb_temperature_meas_cluster_cfg_t temperature_meas_cfg = {
        .measured_value = 0x8000,
        .min_value = -50,
        .max_value = 150,
    };
    uint16_t temperature_tolerance = CONFIG_PRJ_TEMP_SENSOR_TEMPERATURE_ABSOLUTE_PRECISION;
    esp_zb_attribute_list_t *esp_zb_temperature_meas_cluster = esp_zb_temperature_meas_cluster_create(&temperature_meas_cfg);
    ESP_ERROR_CHECK(esp_zb_temperature_meas_cluster_add_attr(esp_zb_temperature_meas_cluster, ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_TOLERANCE_ID, &temperature_tolerance));

    // ------------------------------ Cluster Humidity ------------------------------
    esp_zb_humidity_meas_cluster_cfg_t humidity_meas_cfg = {
        .measured_value = 0xFFFF,
        .min_value = 0,
        .max_value = 10000,
    };
    uint16_t humidity_tolerance = CONFIG_PRJ_TEMP_SENSOR_HUMIDITY_ABSOLUTE_PRECISION;
    esp_zb_attribute_list_t *esp_zb_humidity_meas_cluster = esp_zb_humidity_meas_cluster_create(&humidity_meas_cfg);
    ESP_ERROR_CHECK(esp_zb_humidity_meas_cluster_add_attr(esp_zb_humidity_meas_cluster, ESP_ZB_ZCL_ATTR_REL_HUMIDITY_TOLERANCE_ID, &humidity_tolerance));

    // ------------------------------ Cluster Pressure ------------------------------
    esp_zb_pressure_meas_cluster_cfg_t pressure_meas_cfg = {
        .measured_value = 0x8000,
        .min_value = 200,
        .max_value = 1300,
    };
    // uint16_t pressure_tolerance = (CONFIG_PRJ_PRESSURE_SENSOR_ABSOLUTE_PRECISION / 100.0 + 0.5);
    int16_t pressure_scaled_value = 0x8000; // unit: 0.1hPa, scale=1
    int16_t pressure_min_scaled_value = 2000;
    int16_t pressure_max_scaled_value = 13000;
    uint16_t pressure_scaled_tolerance = (CONFIG_PRJ_PRESSURE_SENSOR_ABSOLUTE_PRECISION / 10.0 + 0.5);
    uint8_t pressure_scale = 1;
    esp_zb_attribute_list_t *esp_zb_pressure_meas_cluster = esp_zb_pressure_meas_cluster_create(&pressure_meas_cfg);
    // ESP_ERROR_CHECK(esp_zb_pressure_meas_cluster_add_attr(esp_zb_pressure_meas_cluster, ESP_ZB_ZCL_ATTR_PRESSURE_MEASUREMENT_TOLERANCE_ID, &pressure_tolerance));  // not supported
    ESP_ERROR_CHECK(esp_zb_pressure_meas_cluster_add_attr(esp_zb_pressure_meas_cluster, ESP_ZB_ZCL_ATTR_PRESSURE_MEASUREMENT_SCALED_VALUE_ID, &pressure_scaled_value));
    ESP_ERROR_CHECK(esp_zb_pressure_meas_cluster_add_attr(esp_zb_pressure_meas_cluster, ESP_ZB_ZCL_ATTR_PRESSURE_MEASUREMENT_MIN_SCALED_VALUE_ID, &pressure_min_scaled_value));
    ESP_ERROR_CHECK(esp_zb_pressure_meas_cluster_add_attr(esp_zb_pressure_meas_cluster, ESP_ZB_ZCL_ATTR_PRESSURE_MEASUREMENT_MAX_SACLED_VALUE_ID, &pressure_max_scaled_value));
    ESP_ERROR_CHECK(esp_zb_pressure_meas_cluster_add_attr(esp_zb_pressure_meas_cluster, ESP_ZB_ZCL_ATTR_PRESSURE_MEASUREMENT_SCALED_TOLERANCE_ID, &pressure_scaled_tolerance));
    ESP_ERROR_CHECK(esp_zb_pressure_meas_cluster_add_attr(esp_zb_pressure_meas_cluster, ESP_ZB_ZCL_ATTR_PRESSURE_MEASUREMENT_SCALE_ID, &pressure_scale));

Please note that I used some extended attributes of pressure measurement cluster for higher reporting accuracy, it is not mandatory for all applications.

The ZCL Spec contains more detailed definition of different clusters and attributes

Also, I think using the IntelliSense may help you find APIs more quickly :D

@jorisvervuurt
Copy link
Author

Thank you! Will check later today. :)

@jorisvervuurt
Copy link
Author

jorisvervuurt commented Apr 10, 2024

@acha666 coming from Arduino, ESP-IDF proves to be a learning curve. Is there any chance you could provide a basic example for Zigbee temperature, humidity, pressure and CO2 (just static values in code). The documentation is not very clear... thanks!

@acha666
Copy link

acha666 commented Apr 11, 2024

@jorisvervuurt

codes you need to modify:

  1. create attribute list for clusters you need, e.g.
// ------------------------------ Cluster Humidity ------------------------------
esp_zb_humidity_meas_cluster_cfg_t humidity_meas_cfg = {
    .measured_value = 0xFFFF,
    .min_value = 0,
    .max_value = 10000,
};
uint16_t humidity_tolerance = CONFIG_PRJ_TEMP_SENSOR_HUMIDITY_ABSOLUTE_PRECISION;
esp_zb_attribute_list_t *esp_zb_humidity_meas_cluster = esp_zb_humidity_meas_cluster_create(&humidity_meas_cfg);
ESP_ERROR_CHECK(esp_zb_humidity_meas_cluster_add_attr(esp_zb_humidity_meas_cluster, ESP_ZB_ZCL_ATTR_REL_HUMIDITY_TOLERANCE_ID, &humidity_tolerance));
  1. add cluster to cluster list, e.g.
esp_zb_cluster_list_add_humidity_meas_cluster(esp_zb_cluster_list, esp_zb_humidity_meas_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
  1. write and report the attribute(temp, humi, pressure, co2 value) when you need, e.g.
esp_err_t writeAttribute(uint8_t endpoint, uint16_t clusterID, uint16_t attributeID, void *value)
{
    esp_zb_zcl_status_t status;
    status = esp_zb_zcl_set_attribute_val(endpoint, clusterID, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, attributeID, value, false);

    if (status != ESP_ZB_ZCL_STATUS_SUCCESS)
    {
        ESP_LOGE(TAG, "Setting attribute %04x:%04x failed(0x%02x)!", clusterID, attributeID, status);
        return ESP_FAIL;
    }

    return ESP_OK;
}

esp_err_t reportAttribute(uint8_t endpoint, uint16_t clusterID, uint16_t attributeID)
{
    esp_zb_zcl_status_t status;
    esp_zb_zcl_report_attr_cmd_t cmd = {
        .zcl_basic_cmd = {
            .dst_addr_u.addr_short = 0x0000,
            .dst_endpoint = endpoint,
            .src_endpoint = endpoint,
        },
        .address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT,
        .clusterID = clusterID,
        .attributeID = attributeID,
        .cluster_role = ESP_ZB_ZCL_CLUSTER_SERVER_ROLE,
    };
    status = esp_zb_zcl_report_attr_cmd_req(&cmd);

    if (status != ESP_ZB_ZCL_STATUS_SUCCESS)
    {
        ESP_LOGE(TAG, "Updating attribute %04x:%04x failed(0x%02x)!", clusterID, attributeID, status);
        return ESP_FAIL;
    }

    return ESP_OK;
}

and use

// humidity_percent is float value of RH%
uint16_t humidity_int = humidity_percent * 100 + 0.5;
writeAttribute(HA_SENSOR_ENDPOINT, ESP_ZB_ZCL_CLUSTER_ID_REL_HUMIDITY_MEASUREMENT, ESP_ZB_ZCL_ATTR_REL_HUMIDITY_MEASUREMENT_VALUE_ID, &humidity_int);
reportAttribute(HA_SENSOR_ENDPOINT, ESP_ZB_ZCL_CLUSTER_ID_REL_HUMIDITY_MEASUREMENT, ESP_ZB_ZCL_ATTR_REL_HUMIDITY_MEASUREMENT_VALUE_ID);

to write and report the attr

@jorisvervuurt
Copy link
Author

Thanks again very much! 😄 Will try later today.

@jorisvervuurt
Copy link
Author

I've really tried my best, but unfortunately my experience with ESP-IDF hasn't been straightforward... I'm familiar with Arduino and higher level languages, but this really proves to be a big thing.

@acha666 while I've managed to get things to build, I'm missing a few steps which results in the stack failing. Is there any chance you could provide a complete .c file? It's very hard for me to know how to get things working together without a complete example. Sorry to bother you with this, but thanks again in advance. :)

@acha666
Copy link

acha666 commented Apr 14, 2024

@jorisvervuurt

This repo may help. But the project is ongoing and it contains lots of other codes like lvgl and power management.

@jorisvervuurt
Copy link
Author

Nice! I'll try to extract just the parts I need. Thanks.

@xieqinan
Copy link
Contributor

@jorisvervuurt

Do you have any other updates regarding this issue? Please feel free to discuss any problems related to the esp-zigbee-sdk. By the way, if you feel the issue has been resolved, please consider closing it.

@jorisvervuurt
Copy link
Author

Unfortunately, due to private circumstances I haven't had time to look into this. Hopefully soon; for now I will close the issue. Thanks!

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

No branches or pull requests

3 participants