ForEach If with value template cannot get the loop variable repeat to work

I’ve read through this
https://community.home-assistant.io/t/automation-with-for-each-and-if/422732

and specifically the response which says to use

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

and I still cannot get this to work
What I’m trying to do is to count the number of switches which are in the state matching a variable , I twant to use for each/if but I gave up and manual duplicaed the code block 9 times - - I change “switch.orchard2_on_board_d2” in each duplicated block This is the repeated code block

if:
  - condition: state
    entity_id: switch.orchard2_on_board_d2
    state:
      - "on"
then:
  - if:
      - condition: numeric_state
        entity_id: counter.d2_expectedstate
        above: 0
    then:
      - action: counter.increment
        target:
          entity_id: counter.switch_counter
else:
  - if:
      - condition: numeric_state
        entity_id: counter.d2_expectedstate
        below: 1
    then:
      - action: counter.increment
        target:
          entity_id: counter.switch_counter

This is the foreach attempt

repeat:
  for_each:
    - switch.orchard2_on_board_d2
    - switch.orchard3_on_board_d2
    - switch.orchard4_on_board_d2
    - switch.orchard5_on_board_d2
    - switch.orchard6_on_board_d2
    - switch.temp_2e8994_on_board_d2
    - switch.temp_60cd54_on_board_d2
    - switch.meterbox_on_board_d2
    - switch.pumpshedpump_on_board_d2
  sequence:
    - if:
        - condition: template
          value_template: >-
            {{ states.repeat.state ==
            states.input_text.d2_expectedstatestr.state }}
      then:
        - action: counter.increment
          metadata: {}
          target:
            entity_id: counter.switch_counter
          data: {}
    - action: notify.mobile_app_pixel_7a
      metadata: {}
      data:
        title: |-
          {{ states.repeat.state }}
          {{ states.switch.orchard2_on_board_d2.state }}
          {{ states.input_text.d2_expectedstatestr.state }}
        message: "Hello this is the state "

What I see in the messages to the mobile app is

"None on on "Hello this is the state "

so its just “repeat” is not correct - but I dont know what I’m meant to be doing

Explanation of how to get the `repeat` variable to work

Use the states() function not the state object method… the following warning has been in the docs for 5+ years:

HA Doc - Building Templates - States


Instead of …

condition: template
value_template: >-
  {{ states.repeat.state ==
  states.input_text.d2_expectedstatestr.state }}

#and

{{ states.repeat.state }}

Use:

condition: template
value_template: >-
  {{ is_state(repeat.item, states('input_text.d2_expectedstatestr')) }}

#and

{{ states(repeat.item) }}

FWIW, if for some reason you needed to use the state object method, you can do so by using bracket notation as follows:

{{ states[repeat.item].state }}

But this is unnecessary and not recommended for your use case.


There is no reason to do any of that if your goal is …

That can be done with a single template. Just list your entities, select the ones that have a matching state, and count them:

{{ ["switch.orchard2_on_board_d2","switch.orchard3_on_board_d2",
"switch.orchard4_on_board_d2","switch.orchard5_on_board_d2",
"switch.orchard6_on_board_d2","switch.temp_2e8994_on_board_d2",
"switch.temp_60cd54_on_board_d2","switch.meterbox_on_board_d2",
"switch.pumpshedpump_on_board_d2"] 
| select('is_state',  states('input_text.d2_expectedstatestr')) 
| list | count }}

Thanks
yes I read the warning and before what I had posted I tried using

{{ states(switch.orchard2_on_board_d2) }}

in the developer template this gives undefined switch

where as {{ states.switch.orchard2_on_board_d2.state }} works in the developer template and since its just a warning… I continued on

so before I started trying to get the list to work - I tried the for_each code you suggested
I deleted the notifications to pixel and put in your suggested change - Which I think is

condition: template
value_template: >-
  {{ is_state(repeat, states('input_text.d2_expectedstatestr')) }}

except without the quotes I get the message

Message malformed: template value should be a string for dictionary value @ data[‘actions’][1][‘repeat’][‘sequence’][0][‘if’][0][‘value_template’]

so with quotes I got this code - now its long and just doesn’t work I have got the same messages in the developer interface I think from when it returns an entire structured object rather than a single sting? As its a dict and cant be hashed

alias: D2 Count For Each
description: ""
triggers:
  - trigger: time_pattern
    seconds: /5
    minutes: "*"
    hours: "*"
conditions: []
actions:
  - action: counter.reset
    metadata: {}
    target:
      entity_id: counter.switch_counter
    data: {}
  - repeat:
      for_each:
        - switch.orchard2_on_board_d2
        - switch.orchard3_on_board_d2
        - switch.orchard4_on_board_d2
        - switch.orchard5_on_board_d2
        - switch.orchard6_on_board_d2
        - switch.temp_2e8994_on_board_d2
        - switch.temp_60cd54_on_board_d2
        - switch.meterbox_on_board_d2
        - switch.pumpshedpump_on_board_d2
      sequence:
        - if:
            - condition: template
              value_template: "{{ is_state(repeat, states('input_text.d2_expectedstatestr')) }}"
          then:
            - action: counter.increment
              metadata: {}
              target:
                entity_id: counter.switch_counter
              data: {}
mode: single

but Everything evaluates as false and the trace is

Conditionally execute an action

Iteration 1

Executed: February 7, 2026 at 2:14:15 PM

Conditionally execute an action

Iteration 2

Executed: February 7, 2026 at 2:14:16 PM

Conditionally execute an action

Iteration 3

Executed: February 7, 2026 at 2:14:16 PM

Conditionally execute an action

Iteration 4

Executed: February 7, 2026 at 2:14:17 PM

Conditionally execute an action

Iteration 5

Executed: February 7, 2026 at 2:14:17 PM

Conditionally execute an action

Iteration 6

Executed: February 7, 2026 at 2:14:17 PM

if

Iteration 1

Executed: February 7, 2026 at 2:14:15 PM
Result:

result: null

if

Iteration 2

Executed: February 7, 2026 at 2:14:16 PM
Result:

result: null

if

Iteration 3

Executed: February 7, 2026 at 2:14:16 PM
Result:

result: null

if

Iteration 4

Executed: February 7, 2026 at 2:14:17 PM
Result:

result: null

if

Iteration 5

Executed: February 7, 2026 at 2:14:17 PM
Result:

result: null

if

Iteration 6

Executed: February 7, 2026 at 2:14:17 PM
Result:

result: null

if/condition/0

Iteration 1

[If template renders a value equal to true]
Executed: February 7, 2026 at 2:14:15 PM

Error: In ‘template’ condition: TypeError: unhashable type: ‘dict’

if/condition/0

Iteration 2

[If template renders a value equal to true]
Executed: February 7, 2026 at 2:14:16 PM

Error: In ‘template’ condition: TypeError: unhashable type: ‘dict’

if/condition/0

Iteration 3

[If template renders a value equal to true]
Executed: February 7, 2026 at 2:14:16 PM

Error: In ‘template’ condition: TypeError: unhashable type: ‘dict’

if/condition/0

Iteration 4

[If template renders a value equal to true]
Executed: February 7, 2026 at 2:14:17 PM

Error: In ‘template’ condition: TypeError: unhashable type: ‘dict’

if/condition/0

Iteration 5

[If template renders a value equal to true]
Executed: February 7, 2026 at 2:14:17 PM

Error: In ‘template’ condition: TypeError: unhashable type: ‘dict’

if/condition/0

Iteration 6

[If template renders a value equal to true]
Executed: February 7, 2026 at 2:14:17 PM

Blockquote

Error: In ‘template’ condition: TypeError: unhashable type: ‘dict’

For the list template - thanks - once I worked out all the background - it worked great - and much easier to understand than the YAML stuff

Just for completeness the complete automation is

alias: Count by list
description: ""
triggers:
  - trigger: time_pattern
    seconds: /5
    minutes: "*"
    hours: "*"
conditions: []
actions:
  - target:
      entity_id: input_number.d2_countinstate
    data:
      value: >-
        {{ ["switch.orchard2_on_board_d2","switch.orchard3_on_board_d2",
        "switch.orchard4_on_board_d2","switch.orchard5_on_board_d2",
        "switch.orchard6_on_board_d2","switch.temp_2e8994_on_board_d2",
        "switch.temp_60cd54_on_board_d2","switch.meterbox_on_board_d2",
        "switch.pumpshedpump_on_board_d2"]  | select('is_state', states("input_text.d2_expectedstatestr")) | list
         count }}
    action: input_number.set_value
mode: single

I know you’ve found a better solution than using a for_each repeat sequence, but for the record:

I suspect the reason your code (and even Didgeridrew’s suggested solution with repeat) wasn’t working was because you tried to work on repeat as a variable for each switch in the loop, rather than repeat.item, as indeed your initial quote from the documentation showed you.

Thanks , maybe when I need for_each I’ll try it