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

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

Open
pavel808 opened this issue Aug 7, 2024 · 19 comments

Comments

@pavel808
Copy link

pavel808 commented Aug 7, 2024

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
@github-actions github-actions bot changed the title Using a suitable cluster and attribute for the battery voltage help Using a suitable cluster and attribute for the battery voltage help (CON-1295) Aug 7, 2024
@jadhavrohit924
Copy link
Contributor

@pavel808 two things,

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

@pavel808
Copy link
Author

pavel808 commented Aug 8, 2024

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

@jadhavrohit924
Copy link
Contributor

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

@pavel808
Copy link
Author

pavel808 commented Aug 8, 2024

@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

@jadhavrohit924
Copy link
Contributor

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.

@pavel808
Copy link
Author

pavel808 commented Aug 9, 2024

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

@jadhavrohit924
Copy link
Contributor

@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.

@pavel808
Copy link
Author

@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

@jadhavrohit924
Copy link
Contributor

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.

@JoseAntonioMG
Copy link

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
Copy link

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

@jadhavrohit924
Copy link
Contributor

@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.

@pavel808
Copy link
Author

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.

@pavel808
Copy link
Author

@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

@jadhavrohit924
Copy link
Contributor

@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.

@pavel808
Copy link
Author

@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

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

@jadhavrohit924
Copy link
Contributor

@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.

@pavel808
Copy link
Author

@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.

@JoseAntonioMG
Copy link

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

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

No branches or pull requests

3 participants