Is it possible to shorten this code?

Use_case: I don’t want to send a command when it is not necessary.
So when the cover is already open, then do nothing.

    - choose:
        - conditions:
            - condition: template
              value_template: "{{ state_attr('cover.rollo_sz_fenster_klein','current_position') | int(default=0) < 100 }}"
          sequence:
            - service: cover.open_cover
              entity_id: cover.rollo_sz_fenster_klein
    - delay: "00:02:00"
    - choose:
        - conditions:
            - condition: template
              value_template: "{{ state_attr('cover.rollo_fitnessraum','current_position') | int(default=0) < 100 }}"
          sequence:
            - service: cover.open_cover
              entity_id: cover.rollo_fitnessraum
    - delay: "00:02:00"
    - choose:
        - conditions:
            - condition: template
              value_template: "{{ state_attr('cover.rollo_gastezimmer','current_position') | int(default=0) < 100 }}"
          sequence:
            - service: cover.open_cover
              entity_id: cover.rollo_gastezimmer

I don’t think you can use a for() loop in an automation

{% for i in range(1, 3) %}
   [..]
{% endfor %}

…so perhaps make a script and call it 3 times?

Is the delay necessary for the covers to open?

Otherwise, you could create a covers group from your covers, then use the expand function to select only the relevant covers (i.e. those whose current_position attribute is <100) under a single service call - HA allows you to supply a list for the entity_id key.

I can give you an example if you’re interested.

The delay is in order to avoid overutilizing the duty cycle. Otherwise it would have been simpler with group indeed

You’re right. A loop but as well as scripts doesn’t make things better.
It seams, that there is no other way to shorten this.

You should be able to use the Repeat For Each action…

action:
  - repeat:
      for_each:
        - "rollo_gastezimmer"
        - "rollo_fitnessraum"
        - "rollo_sz_fenster_klein"
      sequence:
        - condition: numeric_state
          entity_id: 'cover.{{ repeat.item }}'
          attribute: current_position
          below: 100
        - service: cover.open_cover
          entity_id: 'cover.{{ repeat.item }}'
  - delay: '00:02:00'
4 Likes

Hey, that’s it! Thank you. That looks much smarter.

PS:
That did not work.
This part is not allowed:

- condition: numeric_state
  entity_id: 'cover.{{ repeat.item }}'
  attribute: current_position
  below: 100
2022-08-06 09:03:58 ERROR (MainThread) [homeassistant.config] Invalid config for [automation]: Entity cover.{{ repeat.item }} is neither a valid entity ID nor a valid UUID for dictionary value @ data['action'][0]['repeat']['sequence'][0]['entity_id']. Got None. (See /config/configuration.yaml, line 28).

weird. I use something similar very successful:

- service: media_player.volume_set
      data:
        entity_id: "media_player.{{ state_attr('variable.active_alarm_target','alias') }}"
        volume_level: 0.1

All parts of the Service action are templatable, but that’s not true about every part of automations and script. Sometimes it’s hard to remember exactly which fields of which functions will or won’t accept templates.

Try it as a template condition instead…

action:
  - repeat:
      for_each:
        - "rollo_gastezimmer"
        - "rollo_fitnessraum"
        - "rollo_sz_fenster_klein"
      sequence:
        - condition: template
          value_template: >
             {% set entity = 'cover.'~ repeat.item %}
             {{ state_attr(entity, 'current_position') < 100}}
        - service: cover.open_cover
          entity_id: 'cover.{{ repeat.item }}'
  - delay: '00:02:00'