Can't get automation to include [0] in loop

I have this automation:

alias: Daily Priority 1 Chores
trigger:
  - platform: state
    entity_id:
      - input_boolean.temp_test_automations
    to: "on"
condition:
  - condition: template
    value_template: >-
      {% set Chores = state_attr('sensor.chore_list_sensor', 'Chores') %} {{
      Chores | selectattr('frequency', 'equalto', 'Daglig') |
      selectattr('prioritet', 'equalto', '1') | selectattr('status', 'equalto',
      false) | list | count > 0 }}
action:
  - variables:
      today_chores: >
        {% set Chores = state_attr('sensor.chore_list_sensor', 'Chores') %}
        {{ Chores | selectattr('frequency', 'equalto', 'Daglig') | selectattr('prioritet', 'equalto', '1') | selectattr('status', 'equalto', false) | list }}
  - repeat:
      while:
        - condition: template
          value_template: "{{ repeat.index < today_chores | length }}"
      sequence:
        - service: script.1704543720380
          data_template:
            message: >
              {% set chore = today_chores[repeat.index] %}
              {{ chore.frequency }} Oppgave: {{ chore.chore }}, verdt {{ chore.poeng }} poeng
        - service: persistent_notification.create
          data_template:
            message: "Processing chore index: {{ repeat.index }}"

sensor.chore_list_sensor state attributes looks like this:

Number of chores: 32
Pending chores: 1
Chores:
  - chore: test igjen
    frequency: Daglig
    status: false
    poeng: 5
    tildelt: No one assigned
    prioritet: "1"
  - chore: test
    frequency: Daglig
    status: false
    poeng: 5
    tildelt: No one assigned
    prioritet: "1"

and so on…

The script script.1704543720380 sends a notification.

My problem is that every time it sends me 1 less chore, than the number of chores there are in today_chores. Am I doing anything wrong?

Use the repeat until rather than the repeat while action. The condition in the until action is evaluated after the loop, but it is evaluated before the loop in the while.

https://www.home-assistant.io/docs/scripts#repeat-until

https://www.home-assistant.io/docs/scripts#while-loop

Or add one to your while template.

value_template: "{{ repeat.index < today_chores | length + 1 }}"

When changing to until, I only get 1 notification sent, instead of the expected 4. When using my original code, I get sent 3.

Adding +1 Doesn’t change anything. Neither does

value_template: "{{ repeat.index <= today_chores | length - 1 }}"

What does this return in the template editor:

{% set Chores = state_attr('sensor.chore_list_sensor', 'Chores') %}
{{ Chores | selectattr('frequency', 'equalto', 'Daglig') | selectattr('prioritet', 'equalto', '1') | selectattr('status', 'equalto', false) | list }}
[
  {
    "chore": "test igjen",
    "frequency": "Daglig",
    "status": false,
    "poeng": 5,
    "tildelt": "No one assigned",
    "prioritet": "1"
  },
  {
    "chore": "test",
    "frequency": "Daglig",
    "status": false,
    "poeng": 5,
    "tildelt": "No one assigned",
    "prioritet": "1"
  },
  {
    "chore": "Gå ut med søpla",
    "frequency": "Daglig",
    "status": false,
    "poeng": 10,
    "tildelt": "No one assigned",
    "prioritet": "1"
  },
  {
    "chore": "Tøm oppvaskmaskin og fyll på igjen",
    "frequency": "Daglig",
    "status": false,
    "poeng": 5,
    "tildelt": "No one assigned",
    "prioritet": "1"
  }
]

Ok that all looks good. I think the problem is that your loop sequence is completing too fast for the message services to complete before they have to process the next loop.

Try adding a delay at the end of your loop actions:

      sequence:
        - service: script.1704543720380
          data_template:
            message: >
              {% set chore = today_chores[repeat.index] %}
              {{ chore.frequency }} Oppgave: {{ chore.chore }}, verdt {{ chore.poeng }} poeng
        - service: persistent_notification.create
          data_template:
            message: "Processing chore index: {{ repeat.index }}"
        - delay: 2

Sorry, had to sleep.
The issue still remained. 3 sent, expecting 4. I am keeping that, though, since it doesn’t spam the phone as much. Thanks. Always the last created chore that doesn’t get sent. When using repeat until, I only get the last 3rd. I never get the first one in the list, which indicates that it doesn’t start looping at 0.

The documentation says for index: “The iteration number of the loop: 1, 2, 3,” so it seems it doesn’t count 0.
I tried adding chore_index as repeat.index - 1. This seems to align repeat.index starting from 1 with the actual list index starting from 0. That worked!

1 Like

For future reference:

action:
  - variables:
      today_chores: >
        {% set Chores = state_attr('sensor.chore_list_sensor', 'Chores') %}
        {{ Chores | selectattr('frequency', 'equalto', 'Daglig') | selectattr('prioritet', 'equalto', '1') | selectattr('status', 'equalto', false) | list }}
  - repeat:
      while:
        - condition: template
          value_template: "{{ repeat.index <= today_chores | length }}"
      sequence:
        - service: script.send_chore_notification
          data_template:
            message: >
              {% set chore_index = repeat.index - 1 %}
              {% set chore = today_chores[chore_index] %}
              {{ chore.frequency }} Oppgave: {{ chore.chore }}, verdt {{ chore.poeng }} poeng