How to use a template sensors states as input list for entity_id in an action?

Hi all, I’m new to HomeAssistant and struggle with the following issue:

I have a sensor template defined like this:

{{states.cover
| selectattr('entity_id', 'in', area_entities('buro'))
| selectattr('attributes.device_class', 'eq', 'window')
| map(attribute='entity_id')
| list
| join(', ') }}

Developer tools “template” resolves this
{{ states('sensor.alle_fenster_buro') }}

to this
cover.buro_fenster_2, cover.buro_fenster_1
Result type: string

Now I’d like to use this as an input for entity_id in an action:

  - type: custom:bubble-card
    card_type: separator
    name: Fenster
    icon: mdi:window-closed
    sub_button:
      - icon: mdi:arrow-up-bold-circle-outline
        tap_action:
          action: perform-action
          perform_action: cover.open_cover
          target:
            entity_id: [{{ states('sensor.alle_fenster_buro') }}]

→ it gives me the following error: “Failed to perform the action cover/open_cover”. unhashable type: ‘dict’

If I use the entity_ids directly instead of states it works flawlessly:

  - type: custom:bubble-card
    card_type: separator
    name: Fenster
    icon: mdi:window-closed
    sub_button:
      - icon: mdi:arrow-up-bold-circle-outline
        tap_action:
          action: perform-action
          perform_action: cover.open_cover
          target:
            entity_id: cover.buro_fenster_2, cover.buro_fenster_1

Any ideas?

I think you’re missing quotation marks (one-liners need them):

I’m not sure about the square brackets, but they seem redundant for a string (if you want a list, don’t call join in your template sensor).

1 Like

I think that’s it it’s not reading it as a list because of the join etc. Quotes yes brackets no and remove the join. Then I BELIEVE it will see the data passed in as a LIST not a dict.

Card actions almost never support templating. You need to place your templated action in a script, then call that script from the card action.

Other issues:

All templates must be surrounded by quotes or be preceded by a multi-line quote indicator.

It’s not likely to be a big problem in this case where you are listing covers in a single room, but it is best practice to use a attribute to store a list. States are strings with a 255 character limit, so a long list of entity IDs may get truncated and break your action.

1 Like

Dangit @Didgeridrew I completely missed the card action… Nice catch.

Many thanks, this works.

How would I dynamically store all cover entities in an attribute instead of in a state?

Attributes are currently only configurable via YAML.

This is how I would typically set it up, so the state returns a count of open windows and the attribute entity_id returns the entity ids (like it does for group helpers).

template:
  - sensor:
      - name: Buro Covers
        unique_id: buro_covers_0001
        state: |
          {{ area_entities('buro') | select('match', 'cover')
          | select('is_state_attr','device_class', 'window')
          | select('is_state', 'on') | list | count }}
        attributes:
          entity_id:  |
            {{ area_entities('buro') | select('match', 'cover')
            | select('is_state_attr','device_class', 'window') | list }}
2 Likes

Awesome, it works like a charm now. Many thanks!

So what I currently have is two scripts for one room - one for open and one for close. What I’m trying to do is to be more dynamic. Is it possible to have one script and call it using parameters for the open/close operation and for the area? If so, how would the script look like and how would the call look like? I was searching for that but came accross different approaches and none of them worked for me. Also the sensor: Would it be possible to dynamically generate attributes for each area in one sensor and then fill those with the names of the window entities?

Here’s my current open script for the area buro:

sequence:
  - action: cover.open_cover
    target:
      entity_id: "{{ state_attr('sensor.fenster_buro', 'entity_id') }}"
    data: {}
alias: fenster-buro-open
description: ""

Here’s the sensor:

template:
  - sensor:
      - name: Fenster Büro
        unique_id: fenster_buro_0001
        state: |
          {{ area_entities('buro') | select('match', 'cover')
          | select('is_state_attr','device_class', 'window')
          | select('is_state', 'open') | list | count }}
        attributes:
          entity_id:  |
            {{ area_entities('buro') | select('match', 'cover')
            | select('is_state_attr','device_class', 'window') | list }}

And here’s the card part:

- type: custom:bubble-card
    card_type: separator
    name: Fenster
    icon: mdi:window-closed
    sub_button:
      - icon: mdi:arrow-up-bold-circle-outline
        tap_action:
          action: toggle
        entity: script.fenster_buro_open
      - icon: mdi:arrow-down-bold-circle-outline
        tap_action:
          action: toggle
        entity: script.fenster_buro_close

Yes, but you will have to tell us how you plan on handling the Area part. Will the sensors follow a specific ID convention that contains the Area? Will you assign the sensor to the Area or give them a label? Basically, we need to know how the sensor will be linked to the area so we can construct a template that leverages that link to get the sensor’s entity ID.

First set up a script to receive data from variables:

alias: fenster-control
description: ""
fields:
  target_area:
    name: Area
    description: The Area with the windows you want to control
    example: Buro
    selector:
      area:
        multiple: false
        entity:
          domain: cover
  action:
    name: Cover Action
    description: The window cover action you want to perform
    example: open
    selector:
      select:
        options:
          - open
          - close
sequence:
  - action: cover.{{action}}_cover
    target:
      entity_id: |
        {# For this example I'm assuming you are using a strict ID convention for your sensors #}
        {% set entity = 'sensor.fenster_' ~ target_area|slugify %}
        {{ state_attr(entity, 'entity_id') }}
    data: {}

Then, instead of calling a toggle action in your card, call the script directly as a service with the appropriate service data.

  - type: custom:bubble-card
    card_type: separator
    name: Fenster
    icon: mdi:window-closed
    sub_button:
      - icon: mdi:arrow-up-bold-circle-outline
        tap_action:
          action: call-service
          service: script.fenster_control
          data:
            action: open
            target_area: Buro
      - icon: mdi:arrow-down-bold-circle-outline
        tap_action:
          action: call-service
          service: script.fenster_control
          data:
            action: close
            target_area: Buro
1 Like

Awesome! Thank you very much! You got me on the right track. I customized it a bit more to my needs and now it works perfect.