Get lambda id() component name from variable

Is it possible to get the component name in a lambda id() expression from a variable?

# This...
- lambda: |-
    id(sht_dewpoint).update();
# ...should become this...
- lambda: |-
    std::string comp_name = "sht_dewpoint";
    id(comp_name).update();

The motiviation for my question is to loop over multiple components. The names of the components would be provided as a list in a substitution string.

You canā€™t pass a string to id. The preprocessor uses it to convert it to C++ format sht_dewpoint->update().

Components do not have a string name representation. So, if you want to execute a function on a component based on a string name: donā€™t see a way how this can be done.

Butā€¦ components can have 1 or more sensors, each sensor has a name. If you want to execute a function on specific sensors: you can get the list of sensors through App. Below sample code to print all sensor names. You can modify it to get the sensor based on a string name.

auto sensors = App.get_sensors();
for(unsigned int i = 0; i < sensors.size(); i++) 
  ESP_LOGD("app", "Sensor: %s", sensors[i]->get_name().c_str());

Do note that there is a getter for each type of sensor. For binary sensors, need to use get_binary_sensors(). For text sensors, use get_text_sensors()

I saw a similar-ish Q on Discord recently.

There was some undocumented ways to use script parameters (which I donā€™t fully understand;).

Might be worth looking into.

Edit: Reading the OP again, I think Iā€™m off topic. Whoops. Iā€™ll leave it here anyway.

Hi Jƶrg,

I think I am in the same situation as you, need to loop over many sensors and I need to dinamically assign XX as string in ā€œid(XX)ā€.

Did you finally get it work?
Thanks!

Hi @ckxsmart,

I have followed your code and I can get the name of the sensors, but I donā€™t know how can we acces to the state of each sensor with the recovered names instead of the id() method.

Any hint?
Thanks!

Try sensors[i]->state

Thanks to all.
This works pretty well to get the name and state of a binary sensor :


            auto sensors = App.get_binary_sensors();
            for(int j=0; j < sensors.size(); j++) {   
               std::string sensor_name = sensors[j]->get_name();
               bool bin_state = sensors[j]->state; 
             }

but how can I SET the state with this approach : I want to loop through the full set of binary sensors, find the one Iā€™m looking for based on its name, and then SET its state

I tried :

             sensors[j].publish_state(1);
             sensors[j]->state(dataBool);

without any success, does not compile. Is it feasible ? how ?

1 Like

found it :

sensors[j]->publish_state(dataBool);

it can update state for binary_sensor ā€˜templateā€™, but not for binary_sensor ā€˜statusā€™

1 Like

I had a similar issue and got help on the ESPhome Discord - I figured I should share it here incase anyone else needs to do something similar as this was the closest I found.

To set a sensor in an equation:

esphome:
  name: bms-0
  on_boot:
    then:
    - lambda: |-
        std::vector<sensor::Sensor*> v = {id(cell_v_0), id(cell_v_1), id(cell_v_2), id(cell_v_3), id(cell_v_4), id(cell_v_5), id(cell_v_6)}; 
        id(cell_v_ids) = v;      

globals:
  - id: cell_v_ids
    type: 'std::vector<sensor::Sensor*>' # compiles
    restore_value: no

Then later on where you want to set one of the sensors:

id(cell_v_ids)[x]->publish_state(volts);

with x being the sensor number you want to update.

The global has to be set on_boot like that.