I have a script I’m using to play media through media_players, however I have a timing issue and I can’t seem to figure out how to fix it so that it works correctly.
The issue comes from setting the volume, then playing the media, waiting for the player to finish playing, then set the volume back.
It appears that when the call to play the media goes out, it’s a fire and forget type request and the state doesn’t immediately go to “playing”. To compound issues, the wait_for_trigger using the state platform doesn’t let you template the entity_id (but it doesn’t seem to work for me anyways).
What ends up happening is there’s a delay between sending the play_media command, and when the media player actually enters a ‘playing’ state. Due to that, the wait_template resolves true pretty much instantly and the volume gets reset before the media has a chance to finish playing.
What I’d like to happen is have the play_media command get sent and then wait for the player to go in to ‘playing’, then go to ‘idle’ before issuing the final reset volume command.
I have, in a few different positions within the script, with both from/to, and with just to and have had no luck. The crazy part is that even if I set it to be just waiting for a trigger to ‘idle’, even with a timeout, it still doesn’t get triggered (last action never runs).
Also, even if it did work, you can’t template the entity_id from that one which really sucks.
Just to see if it would work, and in the end, the volume doesn’t reset back to 0.5, but the trace shows that each of those waits did wait about a second or two and then passed… which means it was able to catch it going in to playing, then to idle, and then supposedly ran the volume reset action - but the entity’s volume isn’t showing the right value afterwards (I don’t see it being changed a 2nd time). Something is really strange…
Here’s the complete script, working and also includes using scenes to save/restore state (the reset of the volume explicitly is because I have a Chromecast device that doesn’t expose its volume level, so scenes don’t restore it)
alias: Play media
icon: mdi:speaker-wireless
fields:
speaker:
name: speaker
selector:
media: {}
required: true
volume:
name: volume
selector:
number:
min: 0
max: 1
step: 0.1
default: 0.5
required: false
sequence:
- alias: Generate unique ID
variables:
scene_id: "{{ slugify(this.context.id) }}"
- alias: Save media player state
service: scene.create
data:
scene_id: "{{ scene_id }}"
snapshot_entities: "{{ speaker.entity_id }}"
- alias: Set volume
service: media_player.volume_set
target:
entity_id: "{{ speaker.entity_id }}"
data:
volume_level: "{{ volume | default(0.5) }}"
- parallel:
- alias: Play media
service: media_player.play_media
target:
entity_id: "{{ speaker.entity_id }}"
data:
announce: true
media_content_id: "{{ speaker.media_content_id }}"
media_content_type: "{{ speaker.media_content_type }}"
- alias: Wait for media to start playing
wait_template: "{{ is_state(speaker.entity_id, 'playing') }}"
continue_on_timeout: true
timeout: "00:00:30"
- alias: Wait until media is finished playing
wait_template: "{{ not is_state(speaker.entity_id, 'playing') }}"
continue_on_timeout: true
timeout: "00:00:30"
- alias: Reset volume
service: media_player.volume_set
target:
entity_id: "{{ speaker.entity_id }}"
data:
volume_level: 0.5
- alias: Restore media player state
service: scene.turn_on
target:
entity_id: scene.{{ scene_id }}
- alias: Garbage collection
service: scene.delete
target:
entity_id: scene.{{ scene_id }}
mode: parallel