esp-matter icon indicating copy to clipboard operation
esp-matter copied to clipboard

Using a suitable cluster and attribute for the battery voltage help (CON-1295)

Open paul-252 opened this issue 1 year ago • 19 comments

I am creating an application for the ESP32-C6. One of the functions is to monitor the connected battery voltage through a GPIO pin and ADC, and update a matter attribute which can be read from a client such as chip-tool.

I am trying to use the electrical_power_measurement cluster and its voltage attribute for this as follows :

// During initializiation

electrical_power_measurement::config power_meas_config;

esp_matter::cluster_t *power_meas_cluster = electrical_power_measurement::create(endpoint, &power_meas_config, CLUSTER_FLAG_SERVER,  electrical_power_measurement::feature::direct_current::get_id()
            | electrical_power_measurement::feature::alternating_current::get_id());

// Then called periodically from a separate thread 

void read_bat_voltage()
{
	ESP_LOGI(TAG, "Reading voltage");

	ESP_ERROR_CHECK(adc_oneshot_read(adc1_handle, EXAMPLE_ADC1_CHAN0, &adc_raw[0][0]));
	ESP_LOGI(TAG, "ADC%d Channel[%d] Raw Data: %d", ADC_UNIT_1 + 1, EXAMPLE_ADC1_CHAN0, adc_raw[0][0]);

	if (do_calibration1_chan0)
	{
		ESP_ERROR_CHECK(adc_cali_raw_to_voltage(adc1_cali_chan0_handle, adc_raw[0][0], &voltage[0][0]));
		ESP_LOGI(TAG, "ADC%d Channel[%d] Calibrated Voltage: %d mV", ADC_UNIT_1 + 1, EXAMPLE_ADC1_CHAN0, voltage[0][0]);
	}

	esp_matter_attr_val_t voltageVal;

	voltageVal.type = ESP_MATTER_VAL_TYPE_INT64;

	// Dummy value to test at first
	voltageVal.val.i64 = 33;

	//voltageVal.val.i32 = voltage[0][0];

       // This fails!!
	attribute::update(light_endpoint_id,
			       chip::app::Clusters::ElectricalPowerMeasurement::Id,
			       chip::app::Clusters::ElectricalPowerMeasurement::Attributes::Voltage::Id, &voltageVal);
}

On trying to update he attribute as above, I get the following runtime error and crash. Any idea what is wrong here? Thanks in advance.

[0;32mI (2294) app_main: Reading voltage[0m
[0;32mI (2294) app_main: ADC1 Channel[2] Raw Data: 593[0m
[0;32mI (2304) app_main: ADC1 Channel[2] Calibrated Voltage: 582 mV[0m
[0;32mI (2314) chip[ZCL]: 0x421475e8 ep 1 clus 0x0000_0090 attr 0x0000_0004 not supported[0m
[0;31mE (2314) esp_matter_attribute: Error updating Endpoint 0x0001's Cluster 0x00000090's Attribute 0x00000004 to matter: 0x86[0m
[5n[6n 
abort() was called at PC 0x420add5f on core 0
Core  0 register dump:
MEPC    : 0x408004b4  RA      : 0x4080d1ea  SP      : 0x4082fb70  GP      : 0x408152f0  
TP      : 0x407ef1c8  T0      : 0x37363534  T1      : 0x7271706f  T2      : 0x33323130  
S0/FP   : 0x4082fbac  S1      : 0x4082fbac  A0      : 0x4082fbac  A1      : 0x4082fb8e  
A2      : 0x00000000  A3      : 0x4082fbd9  A4      : 0x00000001  A5      : 0x4082b000  
A6      : 0x00000000  A7      : 0x76757473  S2      : 0x4082fb90  S3      : 0x00000001  
S4      : 0x4082b000  S5      : 0x00000000  S6      : 0x00000000  S7      : 0x00000000  
S8      : 0x00000000  S9      : 0x00000000  S10     : 0x00000000  S11     : 0x00000000  
T3      : 0x6e6d6c6b  T4      : 0x6a696867  T5      : 0x66656463  T6      : 0x62613938  
MSTATUS : 0x00001881  MTVEC   : 0x40800001  MCAUSE  : 0x00000007  MTVAL   : 0x00000000  
MHARTID : 0x00000000  

Stack memory:
4082fb70: 0x40847ac8 0x408472c4 0x4082fbac 0x408139d0 0x4082b000 0x4082b000 0x00000000 0x20000030
4082fb90: 0x61303234 0x66356464 0x00000800 0x4081672c 0x4082fb90 0x40816748 0x4082fb8c 0x726f6261
4082fbb0: 0x20292874 0x20736177 0x6c6c6163 0x61206465 0x43502074 0x34783020 0x64613032 0x20663564
4082fbd0: 0x63206e6f 0x2065726f 0x00000030 0x00000000 0x40836054 0x4083555c 0x42143000 0x420add62
4082fbf0: 0x40836054 0x4083555c 0x4082b000 0x420add8c 0x40836054 0x4083555c 0x42143000 0x4200850a
4082fc10: 0xa5a5a5a5 0xa5a5a5a5 0x408322b0 0x408321b0 0x0000008e 0x00000000 0x00000000 0x00000000
4082fc30: 0x00000000 0x00000000 0xa5a5a5a5 0xa5a5a5a5 0x000003ce 0xa5a5a5a5 0x40845b64 0x00000000
4082fc50: 0x00190004 0x80008000 0x00000001 0x00000000 0x0000000a 0x00000032 0x00000009 0x00000c00
4082fc70: 0x0

paul-252 avatar Aug 07 '24 17:08 paul-252

@pavel808 two things,

  1. Use chip lock when you try to update the attribute.
  2. You cannot update the attribute before the matter starts.

jadhavrohit924 avatar Aug 08 '24 07:08 jadhavrohit924

@pavel808 two things,

  1. Use chip lock when you try to update the attribute.
  2. You cannot update the attribute before the matter starts.

@jadhavrohit924 Thanks for your reply.

I am updating the attribute after the Matter starts. Just before I attempt to update that Voltage attribute, I update a Temperature attribute as below and it works fine.

float tsens_value;
ESP_ERROR_CHECK(temperature_sensor_get_celsius(temp_sensor, &tsens_value));
ESP_LOGI(TAG, "Temperature value %.02f ℃", tsens_value);

esp_matter_attr_val_t valtemp;

valtemp.type = ESP_MATTER_VAL_TYPE_FLOAT;
valtemp.val.f = tsens_value;

attribute::update(light_endpoint_id,
			chip::app::Clusters::TemperatureMeasurement::Id,
			chip::app::Clusters::TemperatureMeasurement::Attributes::MeasuredValue::Id, &valtemp);

How to use chip lock exactly?

I have a suspicion that the power_meas_config here is not correct in my case to pass to the function to create the electrical_power_measurement cluster ?

electrical_power_measurement::config power_meas_config;

esp_matter::cluster_t *power_meas_cluster = electrical_power_measurement::create(endpoint, &power_meas_config, CLUSTER_FLAG_SERVER,  electrical_power_measurement::feature::direct_current::get_id()
            | electrical_power_measurement::feature::alternating_current::get_id());

paul-252 avatar Aug 08 '24 10:08 paul-252

@pavel808 Please provide me the backtrace of the crash in the file.

jadhavrohit924 avatar Aug 08 '24 14:08 jadhavrohit924

@pavel808 Please provide me the backtrace of the crash in the file.

Hi @jadhavrohit924 . Attached are my logs from the application, with multiple crashes. Thanks.

putty.log

paul-252 avatar Aug 08 '24 16:08 paul-252

There is no backtrace in the logs!!! Please redirect the crash to either uart or partition and generate the backtrace using https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-guides/core_dump.html.

jadhavrohit924 avatar Aug 09 '24 06:08 jadhavrohit924

There is no backtrace in the logs!!! Please redirect the crash to either uart or partition and generate the backtrace using https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-guides/core_dump.html.

@jadhavrohit924 Ah yes. Attached is my core dump file. The crash was re-directed over UART. Thanks.
core-dump.log

paul-252 avatar Aug 09 '24 20:08 paul-252

@pavel808 The core dump you shared is encrypted. The one having ELF can only decrypt it. You can use the command idf.py coredump-info to decrypt, please take the help of the above docs.

Did you make any changes on top of any standard esp-matter example app? If you do, can you please share it with me to debug.

jadhavrohit924 avatar Aug 14 '24 12:08 jadhavrohit924

@pavel808 The core dump you shared is encrypted. The one having ELF can only decrypt it. You can use the command idf.py coredump-info to decrypt, please take the help of the above docs.

Did you make any changes on top of any standard esp-matter example app? If you do, can you please share it with me to debug.

@jadhavrohit924 Apologies. Here is the decoded core dump file attached. I have made changes to an esp-matter example app. I took the light example more or less and customized it. Everything is working fine up to the point where I try to update that Voltage attribute.

I have attached my app_main.cpp file also (I had to change the extension type here as cpp files are not permitted). Thank you.

core-dump.txt app_main_cpp.txt

paul-252 avatar Aug 14 '24 19:08 paul-252

Hi @pavel808, the crash is caused by using a different thread to update the attribute. If you join the thread you can avoid the crash.

jadhavrohit924 avatar Aug 21 '24 11:08 jadhavrohit924

I think the problem is that you are updating the cluster attribute 0x90 (electricalpowermeasurement) with endpoint 1 (which corresponds to light). You have to use the electrical_power_measurement endpoint (I think it's 2)

JoseAntonioMG avatar Aug 23 '24 21:08 JoseAntonioMG

It is an error when copying the example code from light, in the line:

attribute::update(light_endpoint_id,
chip::app::Clusters::ElectricalPowerMeasurement::Id,
chip::app::Clusters::ElectricalPowerMeasurement::Attributes::Voltage::Id, &voltageVal);

light_endpoint_id change to electrical_power_measurenment_endpoint_id

where electrical_power_measurenment_endpoint_id is the variable that saves the end point of the created cluster

JoseAntonioMG avatar Aug 23 '24 22:08 JoseAntonioMG

@JoseAntonioMG If you check the app_main attached above, @pavel808 has created only one endpoint and added the ElectricalPowerMeasurement cluster on endpoint 1 only. Please correct me if I'm wrong.

jadhavrohit924 avatar Aug 26 '24 05:08 jadhavrohit924

Hi @pavel808, the crash is caused by using a different thread to update the attribute. If you join the thread you can avoid the crash.

Indeed you are right. The main thread wasn't waiting for the other thread :-/. The crash is no longer there. Thanks.

paul-252 avatar Aug 26 '24 19:08 paul-252

@JoseAntonioMG If you check the app_main attached above, @pavel808 has created only one endpoint and added the ElectricalPowerMeasurement cluster on endpoint 1 only. Please correct me if I'm wrong.

@jadhavrohit924 @JoseAntonioMG

Exactly. I am only using one endpoint here and don't want to use more.

Some code is emitted here , but basically, what i'm trying to do :

endpoint_t *endpoint = extended_color_light::create(node, &light_config, ENDPOINT_FLAG_NONE, light_handle);

uint16_t light_endpoint_id;

light_endpoint_id = endpoint::get_id(endpoint);

 esp_matter::cluster_t *power_meas_cluster = electrical_power_measurement::create(endpoint, &power_meas_config, CLUSTER_FLAG_SERVER,  electrical_power_measurement::feature::direct_current::get_id()
            | electrical_power_measurement::feature::alternating_current::get_id());

Then from another separate thread later after things are set up :

esp_matter_attr_val_t voltageVal;

voltageVal.type = ESP_MATTER_VAL_TYPE_INT64;

// Dummy value to test
voltageVal.val.i64 = 33;

attribute::update(light_endpoint_id,
	                    chip::app::Clusters::ElectricalPowerMeasurement::Id,
	                    chip::app::Clusters::ElectricalPowerMeasurement::Attributes::Voltage::Id, &voltageVal);

Now I get that the attribute is not supported : ?

[0;32mI (1416922) chip[ZCL]: 0x421477fc ep 1 clus 0x0000_0090 attr 0x0000_0004 not supported[0m
[0;31mE (1416932) esp_matter_attribute: Error updating Endpoint 0x0001's Cluster 0x00000090's Attribute 0x00000004 to matter: 0x86[0m

paul-252 avatar Aug 26 '24 19:08 paul-252

@pavel808 Looks like you have not created a Voltage attribute. It is optional in Matter Spec so you have to create it in your application. Also, you have used the wrong attribute_type here, the correct attribute type of Voltage is ESP_MATTER_VAL_TYPE_NULLABLE_INT64.

jadhavrohit924 avatar Aug 28 '24 07:08 jadhavrohit924

@pavel808 Looks like you have not created a Voltage attribute. It is optional in Matter Spec so you have to create it in your application. Also, you have used the wrong attribute_type here, the correct attribute type of Voltage is ESP_MATTER_VAL_TYPE_NULLABLE_INT64.

Hi @jadhavrohit924 I'm not sure if I understand fully. The Voltage attribute is there in Attributes.h :

namespace ElectricalPowerMeasurement { 
namespace Attributes {
//.....................................................................................
namespace Voltage {
static constexpr AttributeId Id = 0x00000004;
} // namespace Voltage

//--------------------------------------
}
}

paul-252 avatar Aug 28 '24 12:08 paul-252

@pavel808 The above code is from connectedhomeip, right? If you are using ESP-Matter SDK, you have to create attributes/commands/events that are optional in Matter Specification that you need in your application. ESP-Matter only creates mandatory things by default. Please take a look at esp-matter-componets for better understanding.

jadhavrohit924 avatar Aug 28 '24 14:08 jadhavrohit924

@pavel808 The above code is from connectedhomeip, right? If you are using ESP-Matter SDK, you have to create attributes/commands/events that are optional in Matter Specification that you need in your application. ESP-Matter only creates mandatory things by default. Please take a look at esp-matter-componets for better understanding.

@jadhavrohit924 Yes, that code was from connectedhomeip. Ah ok I understand now.

I have successfully managed to create a new attribute for the electricalpowermeasurement cluster. What i'm doing is as follows :

// On initialization
attribute_t *voltage_attribute;
static const uint32_t voltage_attribute_id = 0x50;

esp_matter::cluster_t *power_meas_cluster = electrical_power_measurement::create(endpoint, &power_meas_config, CLUSTER_FLAG_SERVER, electrical_power_measurement::feature::direct_current::get_id()
            | electrical_power_measurement::feature::alternating_current::get_id());

voltage_attribute = attribute::create(power_meas_cluster, voltage_attribute_id, ATTRIBUTE_FLAG_NULLABLE | ATTRIBUTE_FLAG_WRITABLE, esp_matter_nullable_int32(0));

// Then later when data is getting updated

esp_matter_attr_val_t voltageVal;
voltageVal.type = ESP_MATTER_VAL_TYPE_NULLABLE_INT32;
voltageVal.val.i32 = 99; // Just a dummy value to test

attribute::update(light_endpoint_id,
					  chip::app::Clusters::ElectricalPowerMeasurement::Id,
					  voltage_attribute_id, &voltageVal);

I try to read the attribute using chip-tool as follows :

chip-tool electricalpowermeasurement read-by-id 0x50 0x7000 0x1

However, I get the following error in the response that it doesn't know how to log the attribute.

 Endpoint: 1 Cluster: 0x0000_0090 Attribute 0x0000_0050 DataVersion: 1128848908
[1724957685.730063][74763:74765] CHIP:TOO:   Don't know how to log atribute value
[1724957685.730148][74763:74765] CHIP:EM: <<< [E:42615i S:481 M:135825630 (Ack:86179102)] (S) Msg TX to 1:0000000000007000 [1650] [UDP:[fd09:26b8:c42f:1:e1cf:ce38:a687:97e8]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck)

I believe that I am still missing something, not sure what, but almost there. Many thanks for your help.

paul-252 avatar Aug 29 '24 18:08 paul-252

To create a new voltage attribute, you have to do it like this:

int64_t Voltage = 0; electrical_power_measurement::attribute::create_voltage(power_meas_cluster, Voltage);

JoseAntonioMG avatar Aug 29 '24 21:08 JoseAntonioMG

@pavel808 Can you close this if the issue is resolved?

dhrishi avatar Sep 26 '24 06:09 dhrishi