While loop doesn't work in automation

Hi everyone,

I’m trying to make an automation : when I switch an input_boolean to on, my Google Home say a message repeatitly until the input_boolean switch to off.
Here’s my conf :

- alias: "Annonce Alarme On"
  description: "Joue un message en boucle quand l'alarme est activée"
  trigger:
    - platform: state
      entity_id: input_boolean.alarm_switch
      to: 'on'
  action:
#    - repeat:
#        while:
#          - condition: state
#            entity_id: input_boolean.alarm_switch
#            state: 'on'
#        sequence:
          - service: tts.speak
            data:
              cache: true
              media_player_entity_id: media_player.musique_salon
              message: Hello
              language: fr
            target:
              entity_id: tts.google_en_com

If I don’t try to loop by commenting this part, my Google Home says Hello when I switch my input_boolean to on. But when I uncomment the loop part, it doesn’t work anymore and I can’t figured out why. Could somebody help me please

Add a delay after the TTS service call.

2 Likes

Try

action:
#    - repeat:
#        until:
#          - condition: state
#            entity_id: input_boolean.alarm_switch
#            state: 'off'

Don’t forget to add a delay at the end of your actions, as suggested.

3 Likes

Thanks ! Adding a delay worked, even if I don’t replace while by until.

Just for my personnal knowledge, how do you know I had to add a delay ?
I searched in HA Docs and can’t find something about that.

A lot of cloud services require a delay between commands due to the length of time it takes for the command to be sent and the reply received. Most cloud services will throw a HTTP 429 error (too many connections) if you call it too many times too quickly.

Since you are using the Google cloud TTS, you can generally assume that you’ll need at least a small delay between the commands. It’s just knowing the nature of cloud services versus local services.

3 Likes

Because the documentation focuses on explaining the tools, not the many things you can build with the tools.

In this case, you built something to continuously repeat a message. Whenever you “continuously repeat” anything, it will be repeated as fast as your computer can execute it.

Now you see the problem; it attempts to play the message repeatedly, as fast as it can, without waiting for the message to finish playing each time. As explained by code-in-progress, Google Cloud TTS receives a continuous stream of TTS requests from your computer (sent as fast as your computer can) and is likely to reject the flood of requests.

Adding a delay is one way to mitigate the problem. Another way is to use a wait_template that waits for the media_player’s state to no longer be playing. In other words, it waits for the media_player to finish playing the message before sending the next TTS request. This technique ensures it waits long enough regardless of the message’s length (short or long).

5 Likes

Adding just a wait_template will not change anything.
The wait_template there needs to be a small delay before the wait_template to make sure the media_players state has time to change to playing.
If it doesn’t have time to change to playing then it will be the same result as without a delay (original post)

If there’s a timing issue that obligates the addition of an initial short delay prior to the wait_template, the alternative is to use a wait_for_trigger to detect the desired state-change (employing to).

FWIW, I have used both techniques, the choice was based on the given application.