Using Repeat in a Script

Trying to use repeat in a script to replace a very long script that slowly dims lights (since light doesn’t support transitions) based on https://www.home-assistant.io/docs/scripts/#while-loop

If I update the script to:

slow_dim_familyroom_fourty:
  alias: FamRoom Fade to 40% Down
  # mode: single
  repeat:
    while:
      - condition: template
        value_template: "{{ states.light.familyroom_overhead.attributes.brightness | int >= 110 }}"
    sequence:
      - service: light.turn_on
        data_template:
          entity_id: light.familyroom_overhead
          brightness: >
            {% set n = states.light.familyroom_overhead.attributes.brightness %}
            {{ n - 10 }}
      - delay: 00:00:01

and run the Configuration validation tool it says: “Invalid config for [script]: [repeat] is an invalid option for [script]. Check: script->script->slow_dim_familyroom_fourty->repeat”

I am running Home Assistant 0.113.0

The working, but insanely long (and continues to run after its done) script I am trying to replace is:



slow_dim_familyroom_fourty:
  alias: FamRoom Fade to 40% Down
  sequence:
    - service: light.turn_on
      data_template:
        entity_id: light.familyroom_overhead
        brightness: >
          {% set n = states.light.familyroom_overhead.attributes.brightness %}
          {% if n > 110 %}
            {{ n - 10 }}
          {% else %}
            {{ n }}
          {% endif %}
    - delay: 00:00:01
    - service: light.turn_on
      data_template:
        entity_id: light.familyroom_overhead
        brightness: >
          {% set n = states.light.familyroom_overhead.attributes.brightness %}
          {% if n > 110 %}
            {{ n - 10 }}
          {% else %}
            {{ n }}
          {% endif %}
    - delay: 00:00:03
    - service: light.turn_on
      data_template:
        entity_id: light.familyroom_overhead
        brightness: >
          {% set n = states.light.familyroom_overhead.attributes.brightness %}
          {% if n > 110 %}
            {{ n - 10 }}
          {% else %}
            {{ n }}
          {% endif %}
    - delay: 00:00:03
    - service: light.turn_on
      data_template:
        entity_id: light.familyroom_overhead
        brightness: >
          {% set n = states.light.familyroom_overhead.attributes.brightness %}
          {% if n > 110 %}
            {{ n - 10 }}
          {% else %}
            {{ n }}
          {% endif %}
    - delay: 00:00:03
    - service: light.turn_on
      data_template:
        entity_id: light.familyroom_overhead
        brightness: >
          {% set n = states.light.familyroom_overhead.attributes.brightness %}
          {% if n > 110 %}
            {{ n - 10 }}
          {% else %}
            {{ n }}
          {% endif %}
    - delay: 00:00:03
    - service: light.turn_on
      data_template:
        entity_id: light.familyroom_overhead
        brightness: >
          {% set n = states.light.familyroom_overhead.attributes.brightness %}
          {% if n > 110 %}
            {{ n - 10 }}
          {% else %}
            {{ n }}
          {% endif %}
    - delay: 00:00:03
    - service: light.turn_on
      data_template:
        entity_id: light.familyroom_overhead
        brightness: >
          {% set n = states.light.familyroom_overhead.attributes.brightness %}
          {% if n > 110 %}
            {{ n - 10 }}
          {% else %}
            {{ n }}
          {% endif %}
    - delay: 00:00:03
    - service: light.turn_on
      data_template:
        entity_id: light.familyroom_overhead
        brightness: >
          {% set n = states.light.familyroom_overhead.attributes.brightness %}
          {% if n > 110 %}
            {{ n - 10 }}
          {% else %}
            {{ n }}
          {% endif %}
    - delay: 00:00:03
    - service: light.turn_on
      data_template:
        entity_id: light.familyroom_overhead
        brightness: >
          {% set n = states.light.familyroom_overhead.attributes.brightness %}
          {% if n > 110 %}
            {{ n - 10 }}
          {% else %}
            {{ n }}
          {% endif %}
    - delay: 00:00:03
    - service: light.turn_on
      data_template:
        entity_id: light.familyroom_overhead
        brightness: >
          {% set n = states.light.familyroom_overhead.attributes.brightness %}
          {% if n > 110 %}
            {{ n - 10 }}
          {% else %}
            {{ n }}
          {% endif %}
    - delay: 00:00:03
    - service: light.turn_on
      data_template:
        entity_id: light.familyroom_overhead
        brightness: >
          {% set n = states.light.familyroom_overhead.attributes.brightness %}
          {% if n > 110 %}
            {{ n - 10 }}
          {% else %}
            {{ n }}
          {% endif %}
    - delay: 00:00:03
    - service: light.turn_on
      data_template:
        entity_id: light.familyroom_overhead
        brightness: >
          {% set n = states.light.familyroom_overhead.attributes.brightness %}
          {% if n > 110 %}
            {{ n - 10 }}
          {% else %}
            {{ n }}
          {% endif %}
    - delay: 00:00:03
    - service: light.turn_on
      data_template:
        entity_id: light.familyroom_overhead
        brightness: >
          {% set n = states.light.familyroom_overhead.attributes.brightness %}
          {% if n > 110 %}
            {{ n - 10 }}
          {% else %}
            {{ n }}
          {% endif %}
    - delay: 00:00:03
    - service: light.turn_on
      data_template:
        entity_id: light.familyroom_overhead
        brightness: >
          {% set n = states.light.familyroom_overhead.attributes.brightness %}
          {% if n > 110 %}
            {{ n - 10 }}
          {% else %}
            {{ n }}
          {% endif %}


Can anyone help with my syntax or answer why repeat is not available to this script?

repeat is not a script option, it’s a script action. It belongs under sequence. I don’t understand why everyone is making this mistake…

slow_dim_familyroom_fourty:
  alias: FamRoom Fade to 40% Down
  # mode: single
  sequence:
    - repeat:
        while:
          - condition: template
            value_template: "{{ states.light.familyroom_overhead.attributes.brightness | int >= 110 }}"
        sequence:
          - service: light.turn_on
            data_template:
              entity_id: light.familyroom_overhead
              brightness: >
                {% set n = states.light.familyroom_overhead.attributes.brightness %}
                {{ n - 10 }}
          - delay: 1

FWIW, the release notes have been updated to attempt to make this more clear, and I just submitted a change to the main docs to also try to make it more clear.

The confusion likely comes from the docs https://www.home-assistant.io/docs/scripts/#while-loop so thank you for submitting a change! The Configuration validation tool liked your changes, I give the actual script a run when I can.

Thank you very much for your help!!

See, I don’t understand that. That entire page is loaded with examples (and always has been) that are single actions, not complete scripts. I don’t understand why all of a sudden everyone sees these new examples as complete scripts. :man_shrugging:

Yea, I dont really know. That is just the way I read it from the while loop doc. I guess if others are making they same mistake they are also reading it that way. I think I/they just copy the example code and modify from there.

1 Like

I finally read the script docs linked to above and I can definitely see why there is so much confusion.

The docs seem to be mixing script syntax with automation syntax. And because it adds the “alias” which is usually the first line of a script or automation with everything else starting below there it also looks like the “repeat” replaces “sequence” in the script syntax. I believe adding “- alias:” to the beginning is the biggest reason for the confusion. If you changed that to “sequence:” I think it would help a lot.

Hopefully the new docs clear it up. It would be best to make sure the docs use full examples instead of just snippets.

3 Likes

Unfortunately, I do… :wink: :slight_smile: The problem is in the inconsistent way, different pages in the documentation handle these. Some pages are like the ones you noted, some are complete scripts… Maybe some guidelines would help keeping things in place and understandable throughout the entire documentation. :slight_smile:

Every action in a script (or at least most) can have an alias. Sorry if people don’t know that.

The example starts with a “-”, but somehow everyone just overlooks that. When they say “I just copy the example”, that’s not true. They obviously delete that dash character or just don’t copy it.

I also re-read the entire doc page and except for the very top, where it gives a complete example before it describes the various types of actions (and the event action which is an outlier) every other example is just an action, not a complete script or automation. It’s very consistent.

I still don’t understand why people have such problems with this one. If they wanted to know how to write a script that called a service, would they do this:

my_script:
  alias: Bedroom lights on
  service: light.turn_on
  data:
    entity_id: group.bedroom
    brightness: 100

That’s the same thing – copy the example and remove the dash. But people don’t do that. And, BTW, that example also has an alias, so that doesn’t explain it.

Oh well, I guess it is what it is. Hopefully the modifications will help.

Sorry, I’m not trying to criticize. I’m just trying to help figure out how to fix the confusion and save you from answering a thousand “why won’t this work” posts. :sweat:

I think the issue (besides the alias thing) is that it’s so new and different that people don’t get that it works just like other scripts and still requires “sequence:”

1 Like

I guess it’s a “sub sequence” maybe? I used the same term thinking that would make it easier to understand but it seems to have done just the opposite.

I think the problem is people are thinking this is another type of script as opposed to what it really is which is one type of action that can be used in a script.

1 Like

Sorry, wasn’t meant disrespectful. :slight_smile: What I meant was throughout the entire documentation (of HA). Just a feeling, but I’d say 70% of the docu (of HA) use complete examples.

I couldn’t say, I’d do something different, when I would write the documentation. But I think it is no secret, that the docu isn’t as clear as it could be. Again, not meant disrespectful, I do know, that you’d need a whole department to get a frustration free documentation, and even then…

1 Like

So here’s what I’m thinking of using for an example of the repeat action:

script:
  flash_light:
    mode: restart
    sequence:
      - service: light.turn_on
        data_template:
          entity_id: "light.{{ light }}"
      - repeat:
          count: "{{ count|int * 2 - 1 }}"
          sequence:
            - delay: 2
            - service: light.toggle
              data_template:
                entity_id: "light.{{ light }}"
  flash_hallway_light:
    sequence:
      - service: script.flash_light
        data:
          light: hallway
          count: 3

Do you think that makes it clearer and more understandable?

For me, yes. I think that if that had been the example on the docs I would have had enough information that I would not have had to post this question.

1 Like

The flash_light script accepts a variable (light). Is there a need to include the fields option, to describe the light variable, or is it completely optional?

(I haven’t written enough scripts that accept variables to know the difference. My impression is that it is completely optional; only serves to document the variable when displayed in Developer tools > Services.)

I believe those are optional. And in the interest of keeping the example as small as possible (since this page is supposed to be more of a “reference manual” than a “user’s guide” – there are other pages with more complete/extensive examples, which I also plan to update soon) I only included what I though was completely necessary.

EDIT: You can see the full set of changes starting here.

1 Like

While you would certainly know better than me, its my opinion that the code you proved for me in this thread Using Repeat in a Script is a better example of a use of a while loop for the documentation. I think the extra "light.{{ light }}" and count: "{{ count|int * 2 - 1 }}" stuff adds something new users need to try to figure out instead of just addressing the while loop that they are trying to understand at that time.

I wouldn’t necessarily say that. Clearly I assumed too much when I first wrote the examples! :wink:

Well, that particular example is not for a while loop, it’s for a counted loop. Look, there are arguments to all sides. I could easily see someone else saying (if I didn’t include stuff like that), “hey, you said the count could be specified by a template. Why didn’t you show that?!” And, if I leave it in, there are people that will just copy it (template and all, even when they really just need to specify a hard coded number) and say, “hmm, how am I supposed to define that variable???”, or “hey, this example doesn’t work!” … “Did you specify the variable when you called the script?” … “What do you mean variable?” Bottom line, examples are just examples. People need to actually think.

When I finally get around to updating the (other) examples page(s), I was thinking of the example you mention in particular. In fact, I think it could be done with a counted repeat where the brightness level for each iteration is calculated using repeat.index.

1 Like

Good job on the new documentation. I think it explains it pretty clearly now.

1 Like

I agree. It is much more clear now. Thank you.

1 Like

+1

That went out of favor a long time ago… :wink: :slight_smile: