Lambda for loop id(variable).state


I have got myself into a problem trying to use a for loop and a variable(i) in an id(text_variable).state

Just want to add a variable on the end eg:
// uint16_t cell_voltage_test = id(cell_voltage_i).state * 1000; // Want something like this note i variable

Have tried using a string but it doesn’t compile.
Error: Lambda contains reference to entity-id-style ID ‘cv.c_str’. The id() wrapper only works for ESPHome-internal types. For importing states from Home Assistant use the ‘homeassistant’ sensor platforms.

Anyone got any ideas how to solve?

for (int i = 16; i > 0; i--) {
  std::string cv = "cell_voltage_" + std::to_string(i);
  // uint16_t cell_voltage_test = id(cell_voltage_i).state * 1000; // Want something like this note i
  uint16_t cell_voltage_test = id(cv.cstr()).state * 1000;
  ESP_LOGI("main", "cell voltage_%i: %X", i, cell_voltage_test); 

So what I think you are trying to do is loop through a bunch of sensors named “cell_voltage_1” through 16?

Your problem will be that ESPHome converts the id references to internal pointers at compile time - I don’t believe it does it at run-time like your code assumes. Thus it can’t find a matching id to convert when it compiles the code.

Yep, that’s the problem, any idea how to workaround?

I have manually generated the code for 16 different sensors, but if there is pragmatically only 15 then there are issues.

Not really. Depends what you are trying to achieve… Can you perform the actions you require using sensor filters? There’s a bunch of different things you can do there.

I’m deep in mid Lambda(300 lines in), after this the uint16_t cell_voltage_test is inserted it into a vector and then whole vector is transmitted via uart.

You’ll anyway have to expose a fixed list of available sensors in your code.

To dynamically access one of the sensors based on an ID of your choice, can have a look at this solution (the lambda part). In this example it’s using a numeric number as key and a LightState pointer as value.

In your case I have no idea what class this “cell_voltage_1” component is. You’ll need to post some more yaml for that.

I don’t think that helps as I don’t know how many available sensors(cell_voltage_1 to 24) until run time.
It is defined by what is connected via serial data.

Thinking I may have to do it the hard way, load all 24 into the vector with duplicated code for each one, and then remove the not required ones from the vector.

Not really optimal, but seems it’s the only way?