Hello,
There is an option to run a service (or script) in loop ?
Means, can the service repeat 10 times (without a delay) ?
The following is my automation that play a shot sound, and I wants to repeat this sound for 10 times.
- alias: 'The house was flooded with water notification'
trigger:
platform: state
entity_id:
- binary_sensor.storage_water_sensor
from: 'off'
to: 'on'
action:
- service: media_player.play_media
data:
entity_id: media_player.alex_s_echo_dot
media_content_type: sound
media_content_id: amzn_sfx_church_bell_1x_02
No, there’s no posibility to do a loop. Couldn’t you just create a single media file that loops the sound 10 times and then just play the media file?
To answer your question about a service in a loop:
You’ll have to do 2 scripts sadly. A script cannot run multiple times, so it can’t call itself recursively.
Also, I add wait_templates to be sure the recursive scripts are actually done before continuing.
# Scripts
notify_loop:
sequence:
# Wait for the loop script to be completely done, then call it again.
- wait_template: "{{ is_state('script.notify', 'off' }}"
- service: script.notify
notify:
sequence:
- service: #thing_I_want_to_loop
- delay: "00:00:10"
# Wait until the notify_loop script is completely done. Can't call it
# again if it's still running. It should be done by now, but that
# depends on how long your delay is...
- wait_template: "{{ is_state('script.notify_loop', 'off') }}"
- service: script.notify_loop
To solve it the correct way, simply create an automation that does nothing but repeat every X seconds/minutes/hours. Then turn this automation on/off.
- alias: Looping alarm
trigger:
platform: time_pattern
# With the / in front, will play when the minutes are evenly divisible by this number.
# So, every 1 minute in this case.
minutes: "/1"
action:
- service: media_player.play_media
data:
entity_id: media_player.alex_s_echo_dot
media_content_type: sound
media_content_id: amzn_sfx_church_bell_1x_02
- alias: 'The house was flooded with water notification'
trigger:
platform: state
entity_id:
- binary_sensor.storage_water_sensor
from: 'off'
to: 'on'
action:
# Turn on the automation that just loops every X minutes.
- service: homeassistant.turn_on
entity_id: automation.looping_alarm
Then turn that looping automation off by whatever method you choose.
action:
- service_template >
{% for i in range(0, 9) %}
media_player.play_media
data:
entity_id: media_player.alex_s_echo_dot
media_content_type: sound
media_content_id: amzn_sfx_church_bell_1x_02
{% endfor %}
And technically it will loop, but without a wait template in there to prevent the service being called while still playing the previous iteration it wont work. And there is no way to shoehorn in a wait template.
service_data = {'entity_id':'media_player.alex_s_echo_dot', 'media_content_type':'sound', 'media_content_id':'amzn_sfx_church_bell_1x_02'}
for i in range(10):
hass.services.call('media_player', 'play_media', service_data, False)
time.sleep(2)
Adjust sleep(2) to the number of seconds needed to allow for the playing of the media content.
Automation simply becomes this:
- alias: 'The house was flooded with water notification'
trigger:
platform: state
entity_id:
- binary_sensor.storage_water_sensor
from: 'off'
to: 'on'
action:
service: python_script.church_bells
If there is a way to do that, I don’t know how. The python_script integration supports python code and wait_template is something specific to Jinja2 templating in Home Assistant.
Here’s my concept of creating loops.
I replaced your binary_sensor.storage_water_sensor with an input_boolean as it’s easier to test and also used persistent_notification.create service to get a feedback.
The number of loops (10) is hardcoded but it’s easy to change the code so it would take it from say, input_number and that way you’ll have a configurable loop
There is an option to turn off the python_script in a middle (let’s say that the for loop is already running),
From the automation that called to this python_script ?