Variable in a variable

Hi, I’m new to templates and have reached a wall.
What I’m doing is that I want to abstract a procedure that I’ll use a lot in my automations. All my scenes follow a very specific naming scheme so I can template these names together. I will check whether a copy of a scene has been created and if it hasn’t, I’ll create one and activate it in both cases (might sound weird but trust me, the context makes sense :smiley:). However, I’m not sure how to do that exactly. (or maybe I just lack the correct wording in my googling efforts)
For a test. I want to check whether or not a copy of a scene has been created yet. This is what I have done so far in the template tryout:

{%set area = "couch"%}
{%set occupancy = "occupied"%}
{{states.scene.<area>_<occupancy>_<states.input_select.mode.state>_copy.state is defined }}

as you can see, I want to input the values of ‘area’ and ‘occupancy’ variables into this entity ID, and then also use the currently selected value of ‘mode’, and input selector. Is this possible and how would I do it? (I know that the <> don’t work, it’s just to show my intentions here). let’s say the entity ID I actually want to test here is scene.couch_occupied_movie_copy.

Use states() so you just build the string:

{{states('scene.'~area~'_'~occupancy~'_'~states('input_select.mode')~'_copy') is defined}}

If you need to use the state object you can do the same string concatenation but use bracket notation:

{{states['scene.'~area~'_'~occupancy~'_'~states('input_select.mode')~'_copy'].last_changed }}
1 Like

Thanks @Didgeridrew ! I have actually just found out the first suggestion myself by searching for “variable in a variable” :slight_smile: Bracket notation is a great tip which I’ll try out!
But now I’m stuck on the next thing that I guess is related? Trying to create a scene copy of the non-’_copy’-scene in a script. I’m calling the scene.turn_on service and want to catch the same entities as are included in the template scene. Now the issue is, I can’t save the script when writing the following code, so I believe something is wrong there:

service: scene.create
data:
  scene_id: scene.{{ room }}_{{ area }}_{{ occupancy }}_{{ states.input_select.mode.state }}_copy
  snapshot_entities: {{ state_attr('scene.'~room~'_'~area~'_'~occupancy~'_'~states.input_select.mode.state , 'entity_id') }}

Now I thought maybe it needs to be the same format as when you manually write it, so I attempted this wizardry, but to no avail either. When I manage to save after changing something else in the script and then reopen it, it’s just substituted with ‘null’.

service: scene.create
data:
  scene_id: scene.{{ room }}_{{ area }}_{{ occupancy }}_{{ states.input_select.mode.state }}_copy
  snapshot_entities: 
{% for entity_ids in state_attr('scene.'~area~'_'~occupancy~'_'~states.input_select.mode.state , 'entity_id') -%}
{{'    - ' ~ entity_ids ~ '\n'}} 
{%- endfor %}

Any ideas why this won’t work? The scene_id seems to work as the editor gets a blue ribbon when I have just that…

  1. The scene_id is just the object id… it shouldn’t include scene.

  2. snapshot_entities needs to be a real list not a list-shaped string. In this case, you can just use the entity_id attribute. Other cases might require the use of namepace() to return an actual list from the loop.

  3. snapshot_entities indents are off and the | multiline quote indicator is missing.

service: scene.create
data:
  scene_id: "{{ room }}_{{ area }}_{{ occupancy }}_{{ states.input_select.mode.state }}_copy"
  snapshot_entities: |
    {{ state_attr('scene.'~area~'_'~occupancy~'_'~states.input_select.mode.state , 'entity_id') -}}
1 Like

Thanks a ton, this worked!
Also thanks for #1, wasn’t sure :slight_smile:

Hey, actually one more question I ran into :smiley: Now I’m using the state/attribute changes of any light entity in the room as an automation trigger. I tried using that multiline quote indicator but it doesn’t work for some reason. Not sure what’s wrong here and not sure why you put the “-” at the end inside the template, what does it do? Do I need to use that namespace() stuff you mentioned? This is my code atm:

platform: state
entity_id:| 
  {{ expand(area_entities('Living Room') | select('match', 'light')) | map(attribute='entity_id') | list -}}

State triggers do not accept templates for any value except in the duration/for field.

There really isn’t a great way to have dynamic grouping for a trigger like that… you’re best bet is to manually add the entity IDs.

Oh, that’s very sad as it kind of destroys my plans :smiley:
Is there really no way at all, or is there some hacky way? (that listens to all attribute changes, not just on/off)
And do you know whether this is some technical limitation or would a feature request make sense?

This is untested, but you could try creating a template sensor whose state is the most recent last_updated of your grouping…

template:
  - sensor:
      - name: Most recent LR light updated
        state: |
          {{ expand(area_entities('Living Room') 
          | select('match', 'light')) 
          | sort(attribute='last_updated', reverse=true)
          | map(attribute='last_updated')| first -}}

Then you would set your State trigger to listen to that sensor.

I really don’t know, but I think it might be related to the order in which certain processes and resources have to come online during startup. There have been a few feature requests around this issue, but I don’t know if any decisions have been made to change the current functionality.

FR to add ability to expand groups in State triggers
FR to allow Wildcards in entity_id in State triggers
FR to change Template triggers from true/false

Thanks!
State will always have the ‘|’ in the front for some reason. After I put everything in a single line, it now shows only the latest time though. Not sure, why that is? Haven’t really understood the whole point of the | yet I guess :smiley:
Besides that, I had to change it so it’s sort(attribute='last_updated', reverse=true). After that, it works perfectly and I had a little “f*** yeah!” moment thanks to you! :slight_smile:

The | or > are block scalar/multi-line quote indicators, they should only be used when your template is written across multiple lines… and the template must start on the line below where the indicators is and indented 2 spaces. Similarly, a single line template needs to be surrounded by either single or double quotation marks.

1 Like