Is it possible to get Sensor State using a dynamic Sensor Name?

I’m working on integrating api.ai into my home assistant instance and I’ve got it working based off the tutorial page.

So here’s what I am trying to do now, when I ask Google Home using api.ai that I want the temperature it will give it to me for a certain room. That can be done using the following :

speech: >
      It is {{ states('sensor.office_room_temperature') }} degrees in the {{ Room }}

but the room is hardcoded here, I want to get the room name dynamically from the api.ai request. In other cases I’ve parsed the room name like so

   data_template:
        entity_id: "light.{{ Room | replace(' ', '_') }}_light"

And this works. But I need to combine this with the first statement, Is there a way I can dynamically put the room name into the state call for temperature? Essentially I need to be able to do a nested template, I tried this but it doesn’t work

{{ states.sensor.{{ Room | replace(’ ', ‘_’) }} _temperature.state }}

I did something like this some time ago. What I ended up doing was iterating over all states and checking if the entity_id matches.

{% for s in states -%}
    {% if s.entity_id.split(".")[1] == Room | replace(' ', '_') + "_temperature" %}
      {{ s.state }}
    {% endif %}
{%- endfor %}

If you want I can elaborate on what I am doing there :slight_smile:

~Cheers

3 Likes

Thanks! This solved my issue. I changed “states” to “states.sensor” so I’m confining the for loop to just sensors, definitely a creative approach!

1 Like

Could you elaborate for some of the slower people in the room, like me? LOL I think I could learn quite a bit from that example.

Sure, I can try to help out. Let’s go line by line

{% for s in states -%}

Get all the states in home assistant and put them in a list. Now this will allow us to loop through that list, each time we go thru that loop we pick up a new state, we’ll call this s

{% if s.entity_id.split(“.”)[1] == Room | replace(’ ', ‘_’) + “_temperature” %}

Now we get the entity_id of the current object we’re on (or s in our case). And we compare it to the room name (called Room) we got from api.ai.

The Room | replace(’ ', ‘_’) is where we get the Room name and replace any spaces in it with an underscore. So “living room” becomes “living_room”.

And at the end of this line we add “_temperature” to the end of whatever room name we got.

So basically the right side of the == gives us “living_room_temperature”.

 {{ s.state }}

This says that our output will be whatever state is in our object s. Now keep in mind we only get to this line if the previous if condition was true, basically if the sensor is what we’re looking for, otherwise we keep looking thru our loop.

{% endif %}

This just ends the if statement from above

{%- endfor %}

This ends the for loop from above

3 Likes

Also an important part is this

Entity IDs are in the form of domain.entity (light.living_room) we only want to look at the entity not the domain. So we split the entity_id string by the dot and get a list with the domain on the 0 index and the entity on the 1 index. And I then access the entity directly with “[1]”.

~Cheers

2 Likes

@Alankrut and @PhyberApex -

I can’t tell you how much I appreciate that explanation. I feel like you guys should be doing tutorials because something I’ve looked at and half understood, I now “get”. Thanks for taking the time, especially @Alankrut going line by line - that really helped it make more sense to me.

Awesome! I love being in this forum!!!

4 Likes

Well I found a much simpler way…sorry for making things complicated.

{{ states("sensor." ~ (Room | replace(' ', '_')) ~ "_temperature") }}

This works because you only need the state. I needed access to attributes which can not be fetched this way.

~Cheers

5 Likes

Wow awesome, thanks!

didn’t know i can use ~ signs in the template. thanks.

1 Like