espressif / esp-matter

Espressif's SDK for Matter
Apache License 2.0
679 stars 155 forks source link

temperature mesurement device (CON-1362) #1105

Open lboue opened 2 weeks ago

lboue commented 2 weeks ago

Describe the question/query that you have Could you add a basic example of temperature mesurement device?

This would help beginners understand how things work.

Additional context Use that example for BME280, DS18B20.

shubhamdp commented 2 weeks ago

@lboue TBH, there are more than 15 examples demonstrating how to develop a matter accessory. For starters, the basic example is light. You have API calls to create a Matter device, updating the LED driver and handling button press from the driver.

I think this example is enough for beginners to understand how things work.

There's this all_device_types_app, where you can specify the device type through console and it becomes that. In the same example's esp_matter_console_helpers.cpp, you can find the APIs which creates the data model for almost all the supported device types. So, this is like the meta-app for Matter devices.

Now, about adding one more example, temperature measurement device, is an overkill and a maintenance overhead. Plus we don't know what sort of temperature sensor one would use. You have suggested BME280, DS18B20, someone may come ask for supporting some other one.

What may be I could think of is a template example, which has all the things in place, and you would just create your data-model, handle updates to/from the driver.

lboue commented 2 weeks ago

Thanks, I will check you links. It seems more relevant to me to have an example of a temperature sensor than a refrigerator. This is just my opinion.

lboue commented 2 weeks ago

Now I have build app_main.cpp.txt. Do you have an exemple for attribute value update?

esp_err_t app_driver_attribute_update(app_driver_handle_t driver_handle, uint16_t endpoint_id, uint32_t cluster_id,
                                      uint32_t attribute_id, esp_matter_attr_val_t *val)
{
    esp_err_t err = ESP_OK;
    if (endpoint_id == temp_endpoint_id) {
        led_indicator_handle_t handle = (led_indicator_handle_t)driver_handle;
        if (cluster_id == TemperatureMeasurement::Id) {
            if (attribute_id == TemperatureMeasurement::Attributes::MeasuredValue::Id) {
                err = app_driver_temp_set_temperature(handle, val);
            }
        }
    }
    return err;
}
shubhamdp commented 1 week ago

@lboue please check the below example, code is from esp-matter/light/app_driver.cpp. It updates the state of light when we toggle the boot button on dev-kit.

https://github.com/espressif/esp-matter/blob/42b6412e011c6d0fea431123cd77a3b138e3ae4d/examples/light/main/app_driver.cpp#L91-L104

shubhamdp commented 1 week ago

It seems more relevant to me to have an example of a temperature sensor than a refrigerator

Agreed. We added the refrigerator to demonstrate the appliance class device. But, we don't have any sensor class application in the example. We'll add the temperature-measurement example soon.

luko6202 commented 1 week ago

Maybe this could help you as well. Here I've implemented a bridged temperature sensor (should be the same behaviour). The app_driver_attribute_update function you tried to use is only for incoming attribute changes use attribute::report() instead. By calling attribute::report the attribute is set locally and the update is reported to the matter controller and other matter devices.

The sample conversion of the proprietary standard. Set newTemp as 100ths:

// Offset 3-4 A 2 bytes wide unsigned integer value. Big-endian. The measurement value. Temperature: A value
// n in the range from 0 to 65535
uint16_t temp = (uint16_t)(value[3] << 8) | value[4];
int16_t newTemp = (int16_t)(temp * 5 - 27315);
SetI16AttributeValue(this->GetEndpointId(), TemperatureMeasurement::Id, TemperatureMeasurement::Attributes::MeasuredValue::Id, newTemp);

Attribute report routine (using nullable int16 as measured value)

esp_err_t SetI16AttributeValue(EndpointId endpointId, ClusterId clusterId, AttributeId attributeId, int16_t value)
{
    esp_err_t err = ESP_OK;
    esp_matter_attr_val_t val;
    val.type = ESP_MATTER_VAL_TYPE_NULLABLE_INT16; // Set the type of the attribute value
    val.val.i16 = value; // Set the new value
    err = attribute::report(endpointId, clusterId, attributeId, &val);
    if (ESP_OK == err) {
        esp_log_write(ESP_LOG_INFO, TAG,
                      "Attribute value updated successfully. Endpoint ID: %" PRIu16 ", Cluster ID: %" PRIu32
                      ", Attribute ID: %" PRIu32 ", New Value: %d\n",
                      endpointId, clusterId, attributeId, val.val.i16);
    } else {
        esp_log_write(ESP_LOG_ERROR, TAG,
                      "Failed to update attribute value. Endpoint ID: %" PRIu16 ", Cluster ID: %" PRIu32
                      ", Attribute ID: %" PRIu32 ", Value: %d\n",
                      endpointId, clusterId, attributeId, val.val.i16);
    }
    return err;
};
lboue commented 1 week ago

Maybe this could help you as well. Here I've implemented a bridged temperature sensor (should be the same behaviour). The app_driver_attribute_update function you tried to use is only for incoming attribute changes use attribute::report() instead.

That's why I was asking for help. Thanks @luko6202.

mortezaMoezzifar commented 3 days ago

https://github.com/YOGYUI?tab=repositories Hello, this includes several examples with an understandable structure about "Metter".