Repeating a service (or script)?

There’s no way the if statement is getting missed. The only possibility is that the state machine isn’t updating.

In my case, the state machine is the for loop ?
And what can I do to refresh/update it ?

The state machine that @petro is talking about, and I don’t know if I would use that term for it, is the hass.states object that you can query for the state of entities. I had previously been under the impression that those calls would do live queries to home assistant, and give you an up-to-date version of the state, but it appears that it might be handing the python script a static dictionary of entities that contain the states they were at the time of calling the script.

Now, I haven’t dug into this, and I don’t know for sure what’s happening here one way or the other, but it appears that the state of your input_boolean is continuing to come back as ‘on’, so the script is continuing to run.

Yeah. I would like to reproduce the wait_template functionallity in a python_script. Is that possible? Thanks!!

I checked that… the input_boolean is changed to ‘off’.

I’m writing a test script now to investigate this.

edit: This script worked exactly as expected. I watched my home assistant logs, saw the python script logging and when I turned off light.office_fluoro, the script immediately stopped logging.

My world view remains intact :slight_smile:



for j in range(4):
   stateObject = hass.states.get('light.office_fluoro')
   logger.warning("(" + str(j) + ", " + str(0) + "): " + "state = " + stateObject.state);

   if stateObject.state != 'on':
      break

   time.sleep(1)

   for i in range(5):
      stateObject = hass.states.get('light.office_fluoro')
      logger.warning("(" + str(j) + ", " + str(i) + "): " + "state = " + stateObject.state);

      if stateObject.state != 'on':
         break
    
      time.sleep(1)

Edit 2: here’s the logging output of the script. You can see it exits the inner loop, and then exits the outer loop immediately after the light is turned on.

2020-04-17 14:04:52 WARNING (SyncWorker_7) [homeassistant.components.python_script.test.py] (0, -): state = on
2020-04-17 14:04:53 WARNING (SyncWorker_7) [homeassistant.components.python_script.test.py] (0, 0): state = on
2020-04-17 14:04:54 WARNING (SyncWorker_7) [homeassistant.components.python_script.test.py] (0, 1): state = on
2020-04-17 14:04:55 WARNING (SyncWorker_7) [homeassistant.components.python_script.test.py] (0, 2): state = on
2020-04-17 14:04:56 WARNING (SyncWorker_7) [homeassistant.components.python_script.test.py] (0, 3): state = on
2020-04-17 14:04:57 WARNING (SyncWorker_7) [homeassistant.components.python_script.test.py] (0, 4): state = on
2020-04-17 14:04:58 WARNING (SyncWorker_7) [homeassistant.components.python_script.test.py] (1, -): state = on
2020-04-17 14:04:59 WARNING (SyncWorker_7) [homeassistant.components.python_script.test.py] (1, 0): state = on
2020-04-17 14:05:00 WARNING (SyncWorker_7) [homeassistant.components.python_script.test.py] (1, 1): state = on
2020-04-17 14:05:01 WARNING (SyncWorker_7) [homeassistant.components.python_script.test.py] (1, 2): state = on
2020-04-17 14:05:02 WARNING (SyncWorker_7) [homeassistant.components.python_script.test.py] (1, 3): state = off
2020-04-17 14:05:02 WARNING (SyncWorker_7) [homeassistant.components.python_script.test.py] (2, -): state = off
1 Like

:confetti_ball: :partying_face:

@SteveDinn

Thanks for the investigation… I try the same, and it’s looks like that in my case - when Alexa tts is involved, there is a different behavior.
means that before the first tts message fired, the whole loop finished.

2020-04-17 20:26:46 WARNING (SyncWorker_18) [homeassistant.components.python_script.water_sensor_sirens.py] (0, 0): state = on
2020-04-17 20:26:47 WARNING (SyncWorker_18) [homeassistant.components.python_script.water_sensor_sirens.py] (0, 0): state = on
2020-04-17 20:26:48 WARNING (SyncWorker_18) [homeassistant.components.python_script.water_sensor_sirens.py] (0, 1): state = on
2020-04-17 20:26:49 WARNING (SyncWorker_18) [homeassistant.components.python_script.water_sensor_sirens.py] (0, 2): state = on
2020-04-17 20:26:50 WARNING (SyncWorker_18) [homeassistant.components.python_script.water_sensor_sirens.py] (0, 3): state = on
2020-04-17 20:26:51 WARNING (SyncWorker_18) [homeassistant.components.python_script.water_sensor_sirens.py] (0, 4): state = on
2020-04-17 20:26:52 WARNING (SyncWorker_18) [homeassistant.components.python_script.water_sensor_sirens.py] (1, 0): state = on
2020-04-17 20:26:53 WARNING (SyncWorker_18) [homeassistant.components.python_script.water_sensor_sirens.py] (1, 0): state = on
2020-04-17 20:26:54 WARNING (SyncWorker_18) [homeassistant.components.python_script.water_sensor_sirens.py] (1, 1): state = on
2020-04-17 20:26:55 WARNING (SyncWorker_18) [homeassistant.components.python_script.water_sensor_sirens.py] (1, 2): state = on
2020-04-17 20:26:56 WARNING (SyncWorker_18) [homeassistant.components.python_script.water_sensor_sirens.py] (1, 3): state = on
2020-04-17 20:26:57 WARNING (SyncWorker_18) [homeassistant.components.python_script.water_sensor_sirens.py] (1, 4): state = on
2020-04-17 20:26:58 WARNING (SyncWorker_18) [homeassistant.components.python_script.water_sensor_sirens.py] (2, 0): state = on
2020-04-17 20:26:59 WARNING (SyncWorker_18) [homeassistant.components.python_script.water_sensor_sirens.py] (2, 0): state = on
2020-04-17 20:27:00 WARNING (SyncWorker_18) [homeassistant.components.python_script.water_sensor_sirens.py] (2, 1): state = on
2020-04-17 20:27:01 WARNING (SyncWorker_18) [homeassistant.components.python_script.water_sensor_sirens.py] (2, 2): state = on
2020-04-17 20:27:02 WARNING (SyncWorker_18) [homeassistant.components.python_script.water_sensor_sirens.py] (2, 3): state = on
2020-04-17 20:27:03 WARNING (SyncWorker_18) [homeassistant.components.python_script.water_sensor_sirens.py] (2, 4): state = on
2020-04-17 20:27:04 WARNING (SyncWorker_18) [homeassistant.components.python_script.water_sensor_sirens.py] (3, 0): state = on
2020-04-17 20:27:05 WARNING (SyncWorker_18) [homeassistant.components.python_script.water_sensor_sirens.py] (3, 0): state = on
2020-04-17 20:27:06 WARNING (SyncWorker_18) [homeassistant.components.python_script.water_sensor_sirens.py] (3, 1): state = on
2020-04-17 20:27:07 WARNING (SyncWorker_18) [homeassistant.components.python_script.water_sensor_sirens.py] (3, 2): state = on
2020-04-17 20:27:08 WARNING (SyncWorker_18) [homeassistant.components.python_script.water_sensor_sirens.py] (3, 3): state = on
2020-04-17 20:27:09 WARNING (SyncWorker_18) [homeassistant.components.python_script.water_sensor_sirens.py] (3, 4): state = on

But when I turn off the input_boolean before the first tts message, I managed to stop even before the second round.

2020-04-17 20:34:52 WARNING (SyncWorker_3) [homeassistant.components.python_script.water_sensor_sirens.py] (0, 0): state = on
2020-04-17 20:34:53 WARNING (SyncWorker_3) [homeassistant.components.python_script.water_sensor_sirens.py] (0, 0): state = off
2020-04-17 20:34:53 WARNING (SyncWorker_3) [homeassistant.components.python_script.water_sensor_sirens.py] (1, 0): state = off
2020-04-17 20:34:53 WARNING (SyncWorker_3) [homeassistant.components.python_script.water_sensor_sirens.py] The endstate = off

Therefore, I think in this case that the compiler filling some fifo or working in pipeline, so there is no way to stop it from outside immediately.

You have a roughly 21 seconds to hit the off to stop it for the 4th iteration. do you have your sleeps set for the duration of the announcements? If your alarm is a 3 second alarm, you could be stopping it after the loop finished but alexa is still catching up to all the spooled sound bytes.

A solution could also be to simply sleep for the same duration as the media that is playing due to the notification.

Another potential solution: Does the notify service call cause a ‘media_player’ entity to change state? You could do another wait_template style loop to check the state of the echo dot media_player entity.

I don’t understand why are you using a nested loop.

Is not this code valid?

for j in range(20):
   stateObject = hass.states.get('light.office_fluoro')
   logger.warning("({}): state = {}".format(j, stateObject.state));

   if stateObject.state != 'on':
      break

   time.sleep(1)

That code is perfectly valid. My script was that way in order to reproduce an issue that @alexmo was seeing, so I made minimal changes to his original script.

Hi guys,

I’m trying to do something similar to do repeat on mediaplayer.
I’ve decided to use plex playlist because the default media player via DLNA doesn’t have the ability to play all songs within a folder. (please let me know if this is possible as I’ve tried it and failed)

so here is the script that I have

alias: playmedia
sequence:
  - service: media_player.play_media
    target:
      entity_id: media_player.sunny
    data:
      media_content_id: plex://71978
      media_content_type: playlist
    metadata:
      title: 'test '
      thumbnail: /api/plex_image_proxy/39d9b5a614ae8d5fd29fe2e448bc7dcb0ef464cf/71978
      media_class: playlist
      children_media_class: track
      navigateIds:
        - {}
        - media_content_type: plex
          media_content_id: ''
        - media_content_type: playlists
          media_content_id: plex://all
        - media_content_type: playlist
          media_content_id: plex://71978
  - delay:
      hours: 0
      minutes: 0
      seconds: 0
      milliseconds: 0
mode: restart

then the automation

alias: Play Sleeping Song (Duplicate)
description: ''
trigger: []
condition: []
action:
  - repeat:
      count: 3
      sequence:
        - service: script.m
          data: {}
        - delay:
            seconds: 1
mode: restart

I also tried putting everything in automation

alias: Play Sleeping Song
description: ''
trigger: []
condition: []
action:
  - repeat:
      while:
        - condition: template
          value_template: '{{ repeat.index <= 50}}'
      sequence:
        - service: media_player.play_media
          target:
            entity_id: media_player.sunny
          data:
            media_content_id: plex://71978
            media_content_type: playlist
          metadata:
            title: 'test '
            thumbnail: >-
              /api/plex_image_proxy/39d9b5a614ae8d5fd29fe2e448bc7dcb0ef464cf/71978
            media_class: playlist
            children_media_class: track
            navigateIds:
              - {}
              - media_content_type: plex
                media_content_id: ''
              - media_content_type: playlists
                media_content_id: plex://all
              - media_content_type: playlist
                media_content_id: plex://71978
initial_state: false
mode: parallel
max: 10

I also tried a different combination of using repeat count in the automation. Also tried putting repeat count in script, and used the condition template for repeat in script and none of these worked.

I am still learning and hope anyone can show me perhaps if there’s a better way to do this?
I saw some examples of using phython, but it’s rather over my head as I’m not sure where to put the phython file and how to call them.

my end goal ideally is to play the playlist which will play a whole bunch of songs and repeat them endlessly until I stop them. OR even better to play until certain time or until a particular sensor state is off.

Cheers guys