How continue play the previous music after a tts voice announcement?

hi @ghassan,

Looking for some help here. Any idea if this will work with YouTube Music? It’s clear the script is working (based on the state of the device), but it doesn’t resume playing music.

Here’s the state before and after the script:
Before:

After:

Hi @shanf67,

Looks like the source is restored correctly but the most basic which is the state is not.
We verify that if you manually start playing on the device and check if it plays the correct, media. Please do the test and tell me the result.

The script has been under development and is shared here in different versions.
From which post nr did you copy it?

Even if I attempt to play again manually, it doesn’t work. I’m assuming because the app changes.

I’m using the following for the script:

alias: TTSandresume
variables:
  mediaplayer_State: '{{ states(tts_entity) }}'
  mediaplayer_media_content_id: '{{ state_attr(tts_entity,''media_content_id'') }}'
  mediaplayer_Source: '{{ state_attr(tts_entity,''media_channel'') }}'
  mediaplayer_volume_level: '{{ state_attr(tts_entity,''volume_level'') }}'
sequence:
  - service: media_player.volume_set
    data:
      entity_id: '{{ tts_entity }}'
      volume_level: 0.25
  - service: tts.google_translate_say
    data:
      entity_id: '{{ tts_entity }}'
      language: en
      message: '{{ msg }}'
  - delay:
      hours: 0
      minutes: 0
      seconds: 5
      milliseconds: 0
  - service: media_player.volume_set
    data:
      entity_id: '{{ tts_entity }}'
      volume_level: '{{ mediaplayer_volume_level }}'
  - service: media_player.play_media
    data:
      entity_id: '{{ tts_entity }}'
      media_content_id: '{{ mediaplayer_media_content_id }}'
      media_content_type: music
  - delay:
      hours: 0
      minutes: 0
      seconds: 10
      milliseconds: 0
  - choose:
      - conditions:
          - condition: template
            value_template: '{{ mediaplayer_Source != None }}'
        sequence:
          - service: media_player.select_source
            data:
              entity_id: '{{ tts_entity }}'
              source: '{{ mediaplayer_Source }}'
  - choose:
      - conditions:
          - condition: template
            value_template: '{{ mediaplayer_State != ''playing'' }}'
        sequence:
          - service: media_player.media_pause
            data:
              entity_id: '{{ tts_entity }}'
mode: single

Hi @shanf67 ,

I guess you are right, this is very likely because we miss to backup and then update some important attributes.

I am not sure which of these exactly but probably the app_id / name

But don’t worry this can be done. We can backup and restore all these attributes.

To be able to do that, I have installed and use a python script, and I do it successfully in my version of the script. But i just cant remember which script it is and where to find it.

I’ll search for it and get back to you

In the meanwhile you can work identifying which attribute we still need to adjust.

You can start changing the app_Id
you can do that from the developer tool, in the state attributes window, and then hit “Set state”
Then try to start playing from the lovelace or any other place you can control the media_player and see if it works.
if not, then try another attribute and so on.

Stay tuned :slight_smile: .’

Here it is:

as you can read in the post around that

  • you have to save the script into a file example set_state.py and save that file in the python_scripts folder under the configuration directory. if you don’t have that folder already then create it.
  • and in the configuration.yaml file you have to add the line:
python_script:
  • then restart HA.

Let me know when you get that far, then we can proceed from there .

In order to resume after the TTS message, cant we use either wait_template or wait_for_trigger?

‘wait_template: {{ is_state(tts_entity,  ‘’paused'’) }}’

or

wait_for_trigger
  - platform: state
      entity_id: {{ tts_entity }}
      to: 'paused'

Hi @Tankdoz,

Sounds like a good idea, it assures waiting the proper amount of time.But I haven’t tried that,

You could probably give it a try, and let me know if you face challenges, then I will try to assist resolving these.

Looking forward to hear the result.

Kind regards,
Ghassan

Hi @ghassan,

Eventually I got the script to work, however I changed it quite a lot. As I am using Sonos for my TTS, fortunately there is an option to snapshot most settings in one go and restore the settings after the TTS message. By using sonos.snapshot it remembers also how far along in a song you were and at resume does not start the song from the beginning. I got the wait_template working, although I still use a small delay before the resume.

alias: TTS and Resume (sonos)
sequence:
  - service: sonos.snapshot
    data:
      entity_id: '{{ tts_entity }}'
      with_group: true
  - service: media_player.volume_set
    data:
      entity_id: '{{ tts_entity }}'
      volume_level: 0.35
  - service: tts.google_translate_say
    data:
      entity_id: '{{ tts_entity }}'
      language: '{{ language }}'
      message: '{{ message }}'
  - delay: 1
  - alias: Wait until media player is paused
    wait_template: '{{ is_state(tts_entity, ''paused'') }}'
  - service: media_player.volume_set
    data:
      entity_id: '{{ tts_entity }}'
      volume_level: '{{ mediaplayer_volume_level }}'
  - service: sonos.restore
    data:
      entity_id: '{{ tts_entity }}'
      with_group: true
icon: mdi:text-to-speech
variables:
  mediaplayer_volume_level: '{{ state_attr(tts_entity,''volume_level'') }}'
mode: single
6 Likes

Looks good,
I have Sonos as well as other devices and wanted a generic solution,
That’s why i didn’t use the snapshot/restore approach.

This is much more simple.

Well done :slight_smile:

@ghassan ,
My main challenge was that I could not get the original script to remember how far along in a song the player was. After the TTS it would start the right track, but it would start from the beginning. The snapshot solution makes the script very compact, but it also makes it sonos specific and not well suited for a generic solution.Come to think of it, I didn’t test yet if volume settings are also ‘snapshotted’. In that case you could even reduce it further. KR, Tankdoz

Hi @Tankdoz ,

A reasonable approach I think.
From the documentation it sounds like the volume is not restored by but give it a try.

Kind regards,
Ghassan

Hello everyone!

I’m looking for long time for an option to use TTS with my HomePod Mini. As HomePod Mini is now available as an Mediaplayer i can use TTS. I tried to use the provided Script-Code:

alias: TTS and resume
variables:
  media_content_type_HPMini: '{{ state_attr(''media_player.homepod_mini_esszimmer'',''media_content_type'') }}'
  media_position_HPMini: '{{ state_attr(''media_player.homepod_mini_esszimmer'',''media_position'') }}'
  media_title_HPMini: '{{ state_attr(''media_player.homepod_mini_esszimmer'',''media_title'') }}'
  mediaplayer_volume_level_HPMini: '{{ state_attr(''media_player.homepod_mini_esszimmer'',''volume_level'') }}'
  mediaplayer_State_HPMini: '{{ states(''media_player.homepod_mini_esszimmer'') }}'
  volumen_output: '{{ volumen }}'
sequence:
  - service: media_player.media_pause
    data:
      entity_id: '{{ ''media_player.homepod_mini_esszimmer'' }}'
  - delay: 1
  - service: media_player.volume_set
    data:
      entity_id: '{{ ''media_player.homepod_mini_esszimmer'' }}'
      volume_level: '{{ volumen_output }}'
  - delay: 1
  - service: tts.google_translate_say
    entity_id: media_player.homepod_mini_esszimmer
    data:
      message: '{{ message }}'
      language: "de"      
  - delay: '{{ espera }}'
  - choose:
      - conditions:
          - condition: template
            value_template: '{{ mediaplayer_State_HPMini == ''playing'' }}'
        sequence:
          - service: media_player.volume_set
            data:
              entity_id: '{{ ''media_player.homepod_mini_esszimmer'' }}'
              volume_level: '{{ mediaplayer_volume_level_HPMini }}'
          - delay: 2
          - service: media_player.play_media
            data:
              entity_id: '{{ ''media_player.homepod_mini_esszimmer'' }}'
              media_content_type: '{{ media_content_type_HPMini }}'
              media_position: '{{ media_position_HPMini }}'
              media_title: '{{ media_title_HPMini }}'
    default:
      - service: media_player.turn_off
        data:
          entity_id: '{{ ''media_player.homepod_mini_esszimmer'' }}'
mode: single

Unfortunately neither the former volume-level is restored nor the music continues to play. Does anyone set up this script with an HomePod Mini?

Thanks!

Hi,

i have a code that works for me with a HomePod Mini. I tested it when a radio-channel is played.

alias: TTS and resume 2
variables:
  volume_before: '{{ state_attr("media_player.homepod_mini_esszimmer","volume_level")}}'
fields:
  volume_tts:
    name: Lautstärke für TTS
    example: '0.7'
  delay:
    name: Verzögerung
    example: '3'
  message:
    name: Nachricht
sequence:
  - choose:
      - conditions:
          - condition: device
            device_id: xyz
            domain: media_player
            entity_id: media_player.homepod_mini_esszimmer
            type: is_playing
        sequence:
          - service: media_player.media_pause
            data: {}
            target:
              entity_id: media_player.homepod_mini_esszimmer
          - delay:
              hours: 0
              minutes: 0
              seconds: 0
              milliseconds: 500
          - service: media_player.volume_set
            data:
              volume_level: '{{ volume_tts }}'
            target:
              entity_id: media_player.homepod_mini_esszimmer
          - delay:
              hours: 0
              minutes: 0
              seconds: 0
              milliseconds: 500
          - service: tts.google_translate_say
            data:
              entity_id: media_player.homepod_mini_esszimmer
              language: de
              message: '{{ message }}'
          - delay:
              hours: 0
              minutes: 0
              seconds: '{{ delay }}'
              milliseconds: 0
          - service: media_player.volume_set
            data:
              volume_level: '{{ volume_before }}'
            target:
              entity_id: media_player.homepod_mini_esszimmer
          - delay:
              hours: 0
              minutes: 0
              seconds: 0
              milliseconds: 500
          - service: media_player.media_play
            data: {}
            target:
              entity_id: media_player.homepod_mini_esszimmer
      - conditions:
          - condition: device
            device_id: xyz
            domain: media_player
            entity_id: media_player.homepod_mini_esszimmer
            type: is_paused
        sequence:
          - service: media_player.volume_set
            data:
              volume_level: '{{ volume_tts }}'
            target:
              entity_id: media_player.homepod_mini_esszimmer
          - delay:
              hours: 0
              minutes: 0
              seconds: 0
              milliseconds: 500
          - service: tts.google_translate_say
            data:
              entity_id: media_player.homepod_mini_esszimmer
              language: de
              message: '{{ message }}'
          - delay:
              hours: 0
              minutes: 0
              seconds: '{{ delay }}'
              milliseconds: 0
          - service: media_player.volume_set
            data:
              volume_level: '{{ volume_before }}'
            target:
              entity_id: media_player.homepod_mini_esszimmer
    default: []
mode: single

If anyone has some tipps for enhancements, please let me know.

3 Likes

Sorry I’m chiming in late on this thread but I just tried to set this up with the Sonos Ones running Alexa. The announcement works fine but nothing resumes playing after the announcement. Any insight?

Were you able to get this script to work for youtube music. If so can i see your final script. Side not @ghassan does this script support resuming music on previously playing speakers or just resuming music on the speakers used for tts. For example if im listening to music on media_player.xyz, media_player.abc, media_player.lol, and media_player.trx and i get and anoucement on xyz & and abc will all players resume music afterwards?

my code work now in the 2022.9
resume playing in my 3 media player , each one the independent player previous to the tts.
in my case , the tts is play y all the media players. you can add a variable indicate the media player you want to use to the tts, or create a script to each media player.
my code include a day/night time select ,. to change the volume off TTS accord to the hour.
regards.

alias: TTS and resume todos
variables:
  level_night: "{{ states('input_number.volumen_avisos_noche') }}"
  level_day: "{{ states('input_number.volumen_avisos_dia') }}"
  reduce_night: 0.4
  message: "{% if message is undefined %} prueba {% else %} message {% endif %}"
  espera: "{{ ( ( message | length ) / 10 + 4  ) | int }}"
  media_content_id_home_mini: "{{ state_attr('media_player.home_mini','media_content_id') }}"
  mediaplayer_volume_level_home_mini: "{{ state_attr('media_player.home_mini','volume_level') }}"
  mediaplayer_State_home_mini: "{{ states('media_player.home_mini') }}"
  media_content_id_radio_lenovo: "{{ state_attr('media_player.radio_lenovo','media_content_id') }}"
  mediaplayer_volume_level_radio_lenovo: "{{ state_attr('media_player.radio_lenovo','volume_level') }}"
  mediaplayer_State_radio_lenovo: "{{ states('media_player.radio_lenovo') }}"
  media_content_id_smartclock: "{{ state_attr('media_player.smartclock','media_content_id') }}"
  mediaplayer_volume_level_smartclock: "{{ state_attr('media_player.smartclock','volume_level') }}"
  mediaplayer_State_smartclock: "{{ states('media_player.smartclock') }}"
  volumen_output: |
    {% if volumen_level is undefined %}
      {% if ( now() > today_at(states('input_datetime.silencio_fin')) ) and ( now() < today_at(states('input_datetime.silencio_ini')) ) %}
        {{level_day }}
      {% else %}
        {{level_night }}
      {% endif %}
    {% else %}
       {% if ( now() > today_at(states('input_datetime.silencio_fin')) ) and ( now() < today_at(states('input_datetime.silencio_ini')) ) %}
        {{ volumen_level }}
       {% else %}
        {{  (volumen_level * reduce_night  )  }}
      {% endif %}
    {% endif %}
sequence:
  - service: media_player.volume_set
    data:
      entity_id: "{{ 'media_player.home_mini' }}"
      volume_level: "{{ volumen_output  }}"
  - service: media_player.volume_set
    data:
      entity_id: "{{ 'media_player.radio_lenovo' }}"
      volume_level: "{{ volumen_output  }}"
  - service: media_player.volume_set
    data:
      entity_id: "{{ 'media_player.smartclock' }}"
      volume_level: "{{ volumen_output  }}"
  - service: tts.google_say
    entity_id: media_player.altavoces
    data:
      message: "{{ message }}"
  - delay: "{{ espera }}"
  - choose:
      - conditions:
          - condition: template
            value_template: "{{ mediaplayer_State_home_mini == 'playing' }}"
        sequence:
          - service: media_player.volume_set
            data:
              entity_id: "{{ 'media_player.home_mini' }}"
              volume_level: "{{ mediaplayer_volume_level_home_mini }}"
          - delay: 1
          - service: media_player.play_media
            data:
              entity_id: "{{ 'media_player.home_mini' }}"
              media_content_id: "{{ media_content_id_home_mini }}"
              media_content_type: music
  - choose:
      - conditions:
          - condition: template
            value_template: "{{ mediaplayer_State_radio_lenovo == 'playing' }}"
        sequence:
          - service: media_player.volume_set
            data:
              entity_id: "{{ 'media_player.radio_lenovo' }}"
              volume_level: "{{ mediaplayer_volume_level_radio_lenovo }}"
          - delay: 1
          - service: media_player.play_media
            data:
              entity_id: "{{ 'media_player.radio_lenovo' }}"
              media_content_id: "{{ media_content_id_radio_lenovo }}"
              media_content_type: music
  - choose:
      - conditions:
          - condition: template
            value_template: "{{ mediaplayer_State_smartclock == 'playing' }}"
        sequence:
          - service: media_player.volume_set
            data:
              entity_id: "{{ 'media_player.smartclock' }}"
              volume_level: "{{ mediaplayer_volume_level_smartclock }}"
          - delay: 1
          - service: media_player.play_media
            data:
              entity_id: "{{ 'media_player.smartclock' }}"
              media_content_id: "{{ media_content_id_smartclock }}"
              media_content_type: music
  - delay:
      hours: 0
      minutes: 0
      seconds: 5
      milliseconds: 0
mode: queued
max: 2
icon: mdi:text-to-speech

1 Like

@ghassan Thank you a lot for this work. Works very well for me and solved an issue!
I have one question:
I’m using the script to control a google nest hub with a display and I’m using 2 modified versions of your script to 1) resume after tts announcement and 2) resume after streaming videos from IP cameras (e.g. when someone rings the doorbell it streams the campera for 30 seconds and than resumes). This works fine in case one is playing music etc. However, it doesn’t stop the media_player (state: off) when it was off prior to the tts announcement or stream. Since I’m using the hub with display it needs to stop media_player at the end if it was stopped/off prior because otherwise it will not return to the photo frame mode of the nest hub.

I tried to solve this by modifying the end of the script but this does not work:

stream_and_resume_test:
  alias: Stream and resume test-version
  variables:
    mediaplayer_State: '{{ states(tts_entity) }}'
    mediaplayer_volume_level: '{{ state_attr(tts_entity,''volume_level'') }}'
    mediaplayer_media_content_id: '{{ state_attr(tts_entity,''media_content_id'') }}'
    mediaplayer_app_name: '{{ state_attr(tts_entity,''app_name'') }}'
    mediaplayer_Source: '{{ state_attr(tts_entity,''media_channel'') }}'
    volume_output: |
      {% if volume_level is undefined %}
         0.7
      {% elif now().hour > 7 and now().hour < 22 %}
        {{ volume_level }}
      {% else %}
        {{  (volume_level * 0.6 ) | round(1) }}
      {% endif %}
  sequence:
    - service: media_player.volume_set
      data:
        entity_id: '{{ tts_entity }}'
        volume_level: '{{ volume_output }}'
    - service: media_player.play_media
      data_template:
        entity_id: '{{ tts_entity }}'
        media_content_id: '{{ stream_source }}'
        media_content_type: image/jpg
    - delay: '{{ stream_duration }}'
    - service: media_player.volume_set
      data:
        entity_id: '{{ tts_entity }}'
        volume_level: '{{ mediaplayer_volume_level }}'
    - choose:
        - conditions:
            - condition: template
              value_template: '{{ mediaplayer_app_name == ''Spotify'' }}'
          sequence:
            - service: spotcast.start
              data:
                entity_id: '{{ tts_entity }}'
      default:
        - service: media_player.play_media
          data:
            entity_id: '{{ tts_entity }}'
            media_content_id: '{{ mediaplayer_media_content_id }}'
            media_content_type: music
    - delay: 4
    - choose:
        - conditions:
            - condition: template
              value_template: '{{ mediaplayer_Source != None }}'
          sequence:
            - service: media_player.select_source
              data:
                entity_id: '{{ tts_entity }}'
                source: '{{ mediaplayer_Source }}'
            - delay: 4
    - service: media_player.media_pause
      data:
        entity_id: '{{ tts_entity }}'
    - choose:
        - conditions:
            - condition: template
              value_template: '{{ mediaplayer_State == ''playing'' }}'
          sequence:
            - delay: 4
            - service: media_player.media_play
              data:
                entity_id: '{{ tts_entity }}'
        - conditions:
            - condition: template
              value_template: '{{ mediaplayer_State == ''off'' }}'
          sequence:
            - service: media_player.turn_off
              data:
                entity_id: '{{ tts_entity }}'
  mode: single

In case of an tts announcement it ends with the media_player state “idle” and in case of the stream (code shown above) it keeps showing the stream without stopping it (even if the same script returns to the playing source succesfully if it was playing something before).

Any suggestion how to turn off the media player in the end in case it was turned off before starting the script?

Thank you a lot and kind regards
Benedikt

try to add a delay in the execution , the google media players are slow to power up and down.

@ArielBaravalle
Thank you for helping!
Tried this but it regrettably didn’t change the outcome: Stream keeps streaming and after TTS status is “idle” instead “off”…