Automation with for_each and if

Hi,

I tried the new for_each and if feature in an automation but always get an error :frowning:
Can someone point me in the right direction?

Here is the automation:

- id: 'sunprotection'
  alias: Sun Protection
  description: ''
  trigger:
  - platform: state
    entity_id:
    - input_button.sunprotection
  condition: []
  action:
  - repeat:
    for_each:
      - sensor: binary_sensor.room1
        cover: cover.room1
        message: Room1
      - sensor: binary_sensor.room2
        cover: cover.room2
        message: Room2
    sequence:
      - if:
        - condition: state
          entity_id: {{ repeat.item.sensor }}
          state: 'off'
        then:
        - service: cover.close_cover
          data: {}
          target:
            entity_id: {{ repeat.item.cover }}
        else:
        - service: notify.mobile_app_xxx
          data:
            message: "Cover in {{ repeat.item.message }} cannot be closed!"

But when I do a config-check, I always get the error:

Error loading /config/configuration.yaml: invalid key: "OrderedDict([('repeat.item.sensor', None)])"
in "/config/automations.yaml", line 937, column 0

Thanks a lot in advance
Joerg

Did you figure this out @derjoerg ? I want to do something similar and having trouble finding the syntax.

Change to

  action:
  - repeat:
      for_each:
      - sensor: binary_sensor.room1
        cover: cover.room1
        message: Room1
      - sensor: binary_sensor.room2
        cover: cover.room2
        message: Room2 

See, docs, for_each is a child of repeat not a sibling.

@CentralCommand Thank you! Do you know if you can define a list in variables to use in a for_each loop?

Yes. for_each takes a template and templates can return a list. So if you have a variable with a list you just do this:

action:
- repeat:
    for_each: "{{ my_list }}"
  sequence:
    ...

Thank you @CentralCommand ! I was able to contribute a change to the shellies gen2 script thanks to your help! https://github.com/bieniu/ha-shellies-discovery-gen2

1 Like

Thanks a lot that did the trick for this. But now the next problem :pensive:

alias: Sun Protection
description: ''
mode: single
trigger:
  - platform: state
    entity_id:
      - input_button.sun_protection
condition: []
action:
  - repeat:
      for_each:
        - window: binary_sensor.room1
          cover: cover.room1
          message: Room1
          position: 0
        - window: binary_sensor.room2
          cover: cover.room2
          message: Room2
          position: 25
      sequence:
        - if:
            - condition: state
              entity_id: "{{ repeat.item.window }}"
              state: 'off'
          then:
            - service: cover.set_cover_position
              data:
                position: "{{ repeat.item.position }}"
              target:
                entity_id: "{{ repeat.item.cover }}"
          else:
            - service: notify.mobile_app_xyz
              data:
                message: "Cover in {{ repeat.item.message }} cannot be closed!"

I always get the error:

Message malformed: Entity {{ repeat.item.window }} is neither a valid entity ID nor a valid UUID for dictionary value @ data['action'][0]['repeat']['sequence'][0]['if'][0]['entity_id']

Can it be that I can’t use variables “{{ }}” within an if-condition?

You can. But not here:

Not all fields accept templates, some only allow constants. The entity_id field in conditions and triggers is one such field. Although it does accept templates in service calls (which admittedly is a little confusing).

Anyway you have to do your condition like this:

if:
  condition: template
  value_template: "{{ is_state(repeat.item.window, 'off') }}"

Or just this for the shorthand form:

if: "{{ is_state(repeat.item.window, 'off') }}"
3 Likes

I am getting the same error as above, but in an imo pretty simple setting:

- alias: 'Z-Wave Roller Shutter Fix Missing Power Update'
  id: rs_fix_power
  trigger:
    - platform: numeric_state
      entity_id: sensor.leistung_beschattung
      above: 0
      for: 00:05:00
  action:
    - repeat:
        for_each:
          - sensor.raff_arbeiten_links_electric_consumption_w
          - sensor.raff_arbeiten_rechts_electric_consumption_w
          - sensor.raff_essen_links_electric_consumption_w
          - sensor.raff_essen_mitte_links_electric_consumption_w
          - sensor.raff_essen_mitte_rechts_electric_consumption_w
          - sensor.raff_essen_rechts_electric_consumption_w
          - sensor.raff_kuche_fenster_electric_consumption_w
          - sensor.raff_kuche_tur_electric_consumption_w
          - sensor.raff_wohnzimmer_mitte_links_electric_consumption_w
          - sensor.raff_wohnzimmer_mitte_rechts_electric_consumption_w
          - sensor.raff_wohnzimmer_tur_links_electric_consumption_w
          - sensor.raff_ug_wohnen_links_electric_consumption_w
          - sensor.raff_ug_wohnen_rechts_electric_consumption_w
          - sensor.raff_ug_wohnen_tur_links_electric_consumption_w
          - sensor.raff_ug_wohnen_tur_rechts_electric_consumption_w 
          - sensor.roll_ankleide_electric_consumption_w
          - sensor.roll_bad_dach_electric_consumption_w
          - sensor.roll_bad_tur_electric_consumption_w
          - sensor.roll_eingang_fenster_electric_consumption_w
          - sensor.roll_eltern_dach_electric_consumption_w
          - sensor.roll_eltern_tur_electric_consumption_w
          - sensor.roll_gaste_wc_electric_consumption_w
          - sensor.roll_hannah_dach_electric_consumption_w
          - sensor.roll_hannah_tur_electric_consumption_w
          - sensor.roll_hwr_electric_consumption_w
          - sensor.roll_linus_dach_electric_consumption_w
          - sensor.roll_linus_tur_electric_consumption_w
          - sensor.roll_treppe_dach_electric_consumption_w
          - sensor.roll_ug_bad_electric_consumption_w
          - sensor.roll_ug_arbeiten_electric_consumption_w
          - sensor.roll_ug_schlafen_electric_consumption_w
        sequence:
          - condition: numeric_state
            entity_id: "{{ repeat.item }}"
            above: 0
          - service: zwave_js.refresh_value
            data:
              entity_id: "{{ repeat.item }}"
              refresh_all_values: false
          - delay: 00:00:02
          - service: notify.rsfix
            data:
              message: >
                {{ state_attr( repeat.item , 'friendly_name') }} wurde abgefragt, neuer Wert: {{ (states( repeat.item ) | float) | round(0) }}

Error:

2022-11-26 20:25:49.731 ERROR (MainThread) [homeassistant.config] Invalid config for [automation]: Entity {{ 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 37). 

I thought I followed the docs and the examples above to the point (just not naming the items for the loop as it’s only one entity to be iterated over). I also understood that using sequence in automations is possible now.

Probably a pretty simple mistake on my side, after checking for an hour I just can’t find it…

UPDATE: Dammit, the answer is in the post just above! :roll_eyes: It’s not possible to use a template in a condition (I thought that did not apply to a condition inside a sequence, just the condition part of the automation). If I use template: condition I do not get an error

The entity_id field of conditions does not support templates. So this

Won’t work. You have to use a template type condition instead. Or use a template to filter those entities out of the list in the for_each step before beginning the loop.

Not all fields support templates. entity_id fields in particular rarely do. The exception is in service calls but that’s not one of those.

1 Like

Thank you Mike for the quick response - I figured the same after re-reading your last response. This does not throw an error:

        sequence:
          - condition: template
            value_template: "{{ (states( repeat.item ) | float) > 0 }}"
2 Likes