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

I love the feel of fraternity on this thread, all of you guys adding upgrades to the script… what if we put the script in a gist on github to trace the changes and keep it tidy to all the HA community?

Tracing a single version would be good, yes.

The best efforts would be to turn this beautiful code into a Blueprint for the community.

That means we can get away from custom entities listed in the scripts and simply present the user with a series of options to select.


I would love to start this but never got this working - perhaps someone that has can start a repo and I would be happy to start reviewing or contributing to it!

A few days ago I started writing a pkg for the management of notifications (push, telegram, alexa and google_home), what I miss is precisely to restart the music to the various google. While I can safely handle it with volume …
With alexa, on the other hand, there is no problem.
I share the part related to google if it can help.

full automation is a touch of many points and would be off topic for the post

  • parallel:

                - alias: Verifica se google abilitato e con entità inserite
    
                  if:
    
                    - alias: Verifica se gruppo google abilitato
    
                      condition: template
    
                      value_template: "{{ states('group.notify_all_google')!= 'unknown' }}"
    
                    - condition:
    
                      - '{{ trigger.event.data.google_on != "false" }}'
    
                  then:
    
                    - alias: Verifica se orario abilitato
    
                      if:
    
                          - or:
    
                            - condition:
    
                              - '{{ trigger.event.data.orario_media_player == "false" or trigger.event.data.orario_media_player is not defined}}'
    
                            - and:
    
                              - condition: time
    
                                after: *hours_start
    
                                before: *hours_end
    
                              - condition:
    
                                - '{{ trigger.event.data.orario_media_player == "true" }}'
    
                                - '{{ trigger.event.data.orario_media_player is defined }}'
    
                      then:
    
                          - alias: Setta il gruppo Google con esclusioni
    
                            service: group.set
    
                            data_template:
    
                              object_id: notify_all_google
    
                              entities: >-
    
                                {{(state_attr('group.notify_all_google','entity_id')|select('ne', trigger.event.data.escludi_1)
    
                                |select('ne',trigger.event.data.escludi_2)|select('ne',trigger.event.data.escludi_3)
    
                                |select('ne',trigger.event.data.escludi_4)|select('ne',trigger.event.data.escludi_5))|list}}
    
             
    
                          - alias: Accendi i google del gruppo
    
                            service: media_player.turn_on    
    
                            data: {}
    
                            target:
    
                              entity_id: >-
    
                                {{expand('group.notify_all_google') |map(attribute='entity_id')|list}}
    
                          - alias: Attendi accensione del gruppo
    
                            wait_template: >-
    
                              {{ expand('group.notify_all_google')| selectattr('state', 'eq', 'off')
    
                              |map(attribute='entity_id') |list|count == 0}}
    
                            continue_on_timeout: true
    
                            timeout: "5"
    
                          - alias: Crea scena del gruppo per recuperare il volume    
    
                            service: scene.create
    
                            data:
    
                              scene_id: volume_precedente_google
    
                              snapshot_entities: >-
    
                                    {{expand('group.notify_all_google') |map(attribute='entity_id')|list}}
    
                          - alias: Imposta il volume per la notifica
    
                            service: media_player.volume_set
    
                            data:
    
                              entity_id: >-
    
                                {{expand('group.notify_all_google') |map(attribute='entity_id')|list}}
    
                              volume_level: "{{ trigger.event.data.volume | default(0.5) }}"
    
                          - alias: Invia notifica
    
                            service: tts.google_translate_say
    
                            continue_on_error: true
    
                            data:
    
                              entity_id: group.notify_all_google
    
                              message: >-
    
                                {% if trigger.event.data.tts_text is defined and trigger.event.data.tts_text != 'false'%}
    
                                  "{{trigger.event.data.tts_text}}"
    
                                {% else %}
    
                                "{{ trigger.event.data.message | default('Notifica con messaggio non impostata')}}"
    
                                {% endif %}
    
                          - alias: Attendi lettura messaggio
    
                            delay:  # vedere se riesco a recupere durata messaggio da evento...
    
                              seconds: "{{(3 + (trigger.event.data.message.count(', ') + trigger.event.data.message.count('. ') +
    
                                trigger.event.data.message.count('! ') + trigger.event.data.message.count('? ') +
    
                                trigger.event.data.message.count(': ') + trigger.event.data.message.count('; ')) | float(0) * 0.35 +
    
                                (trigger.event.data.message | length) * 0.06) | round(default=0)}}"
    
                          - alias: Applica volume precedente alla notifica
    
                            service: scene.turn_on
    
                            target:
    
                              entity_id: scene.volume_precedente_google
    
           
    
                          - delay:
    
                              seconds: 2

I did found an other way and it works good.

Well create an dim automation with no trigger and no condition.
Call it after how many seconds it needs to trigger.
This depends on how long your tts message is.

this is an example of the automation, with only 1 radio station for now called 108 jamz


choose:
  - conditions: []
    sequence:
      - if: []
        then:
          - delay:
              hours: 0
              minutes: 0
              seconds: 10
              milliseconds: 0
          - service: media_player.play_media
            data:
              enqueue: replace
              media_content_id: >-
                media-source://radio_browser/c550de06-48be-11e8-b1b0-52543be04c81
              media_content_type: music
            target:
              entity_id: media_player.living_room

what you need to do now is add this action in all the actions you want.
Remember, this only triggers if the radio station 108 jamz is playing.

The template checks the content id and see if it contains a part of my radio station name (HOT).
I think using a | between words, can check for more stations in one go, if you use an ip instead of part of a name, it triggers only when TTS was triggered by cloud or local

This automation will check if that station is playing and play the TTS message when someone is at my door, and after it will resume the radio station (after 10 seconds)
If else it directly TTS my message without resuming.

value_template: “{{ ‘hot’ in state_attr(“media_player.living_room”, “media_content_id”) }}”

  • hot = the name to trigger u can use also: hot | 108 | jamz | to trigger more words in one go
  • media_player.living_room = my media entity
  • media_content_id = the attribute

if:
  - condition: template
    value_template: "{{ 'hot' in state_attr(\"media_player.living_room\", \"media_content_id\") }}"
then:
  - service: tts.cloud_say
    data:
      entity_id: media_player.living_room
      message: Front door just opened
  - service: automation.trigger
    data: {}
    target:
      entity_id: automation.delay_timer_test_music
else:
  - service: tts.cloud_say
    data:
      entity_id: media_player.living_room
      message: Front door just opened

hope this helps a bit.
This is just a bit of a work around, but mainly for special TTS broadcasts on my google devices i use ASSISTANT RELAY add-on.

//UPDATE: use this regex to trigger on multiple words:

{{ state_attr('media_player.living_room', 'media_content_id') | regex_search('hot|spotify') }}

Hi dear,
could you tell me how I could get this run with Alexa?
In the end I just want after a tts notification with “ Sends a notification message using the alexa_media_sascha_s_sonos_beam integration” that the loudness goes back to the previous state.
My Sonos Beam is connected with the TV and I can’t get it run with “scene.create” only if my TV is off it works.
I have really no idea how I could get this run.
Thanks a lot

Loving the thread - thank you all for contributing! I’ve just created my first script based on the various code snippets here to announce a door opening via TTS, and then resuming the music. Got it all working, resuming the media stream on the Sonos. was feeling very happy with myself before I realised that it was now ONLY running the TTS and Resume IF there was media playing. If the sonos was idle, then it would not run. Hoping I can spend some time this weekend creating some Conditions to either call a straight TTS action if Sonos is idle OR call the TTS & Resume script if media is playing! thanks again.

Hi, I know this is an old thread, but Google sent me here… :slightly_smiling_face: Just wanted to say this was exactly what I was looking for - works great, both on Google- and Sonos speakers. :+1: Thanks a lot!

1 Like

FYI, since Home Assistant 2023.1 it’s possible to use the Google Assistant SDK to broadcast text to speech message to your Google devices and continue playback, see Google Assistant SDK - Home Assistant

You can use the service notify.google_assistant_sdk to broadcast messages to Google Assistant speakers and displays without interrupting music/video playback.

Hello @myT
I try and work fine but… I can’t eliminate the initial Google mesaje “you have a new anoucement” and the Target option not work fine , the message is broadcasted by all my speakers .
you have this problems? how you solucionated ?

You can’t prevent that, it’s a Google thing.

Hi! I was looking for this solution and happy when I found it, but I think I do something wrong, but don’t know what I do wrong…
In automation.yaml I have this code, is that all I have to do?

# melding doorgeven en verder gaan met muziek        
- alias: TTS and resume
  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.75
  - service: tts.google_translate_say
    data:
      entity_id: '{{ tts_entity }}'
      language: nl
      message: '{{ msg }}'
  - delay:
      hours: 0
      minutes: 0
      seconds: 15
      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

# omroepen was is klaar

- alias: Send alert when washing machine is clean
  trigger:
    - platform: state
      entity_id: input_select.washing_machine_status
      to: Klaar!
  condition:
    condition: and
    conditions:
      - condition: state
        entity_id: input_select.washing_machine_status
        state: Klaar!
  action:
    - service: script.turn_on
      target:
        entity_id: script.tts_and_continue
      data:
        variables:
        msg: De was is klaar!
        tts_entity: media_player.huiskamer

Or am I missing a step somewhere?

The initial message can’t be removed I’d expect.
If no target is set, it will broadcast to all google devices
If you provide a target, it should only be casted onto that target device.
The target needs to use the name of the room as defined within Google Home app!

@ghassan , can you help me further?

Hi @Bas81, I’ll try to look into it tomorrow.
I’ll get back to you :blush:

1 Like

Hi,

I am also using Sonos and I created @Tankdoz’s script but I can’t get it to work…
I get an error: Can’t call script: UndefinedError: ‘media_player’ is undefined

alias: TTS and Resume (sonos)
sequence:
  - service: sonos.snapshot
    data:
      entity_id: media_player.living
      with_group: true
  - service: media_player.volume_set
    data:
      entity_id: media_player.living
      volume_level: 0.15
  - service: tts.cloud_say
    data:
      cache: false
      entity_id: media_player.living
      message: Test!
  - delay: 1
  - alias: Wait until media player is paused
    wait_template: "{{ is_state(media_player.living, 'paused') }}"
  - service: media_player.volume_set
    data:
      entity_id: media_player.living
      volume_level: "{{ mediaplayer_volume_level }}"
  - service: sonos.restore
    data:
      entity_id: media_player.living
      with_group: true
icon: mdi:text-to-speech
variables:
  mediaplayer_volume_level: "{{ state_attr(media_player.living, 'volume_level') }}"
mode: single

Wrap media_player.living in quotes. That makes it a string. Without the quotes, it’s interpreted as the name of a (non-existent) variable.

  - alias: Wait until media player is paused
    wait_template: "{{ is_state('media_player.living', 'paused') }}"

@123, thanks, it’s working now!

Hi @Bas81,
two things:
1- The first part is a script and not an automation. you have to save it in scripts.yaml
2- when calling the scrip from the second part, your automation, you have to call it by the name (Alias) you gave it. otherwise you’ll get an error saying the script is not found.

so if you keep

- alias: TTS and resume

in the first part, then in the second part (the automation)

 entity_id: script.tts_and_continue

must be modified to:

 entity_id: script.tts_and_resume

Hope this makes sense, otherwise let me know and we try again taking it step by step.

1 Like

Hi @ghassan ,

sorry for my late answer, was pretty busy last days.
Thank you for your kind response, but unfortunately it still doens’t work. I think made a mistake somewhere.

After rebooting, I have this error in my log:

Source: components/script/config.py:212
Integration: Script (documentation, issues)
First occurred: 19:58:40 (4 occurrences)
Last logged: 19:58:40
Script with object id 'alias' could not be validated and has been disabled: expected a dictionary. Got 'TTS and resume'
Script with object id 'variables' could not be validated and has been disabled: extra keys not allowed @ data['mediaplayer_Source']. Got "{{ state_attr(tts_entity,'media_channel') }}" extra keys not allowed @ data['mediaplayer_State']. Got '{{ states(tts_entity) }}' extra keys not allowed @ data['mediaplayer_media_content_id']. Got "{{ state_attr(tts_entity,'media_content_id') }}" extra keys not allowed @ data['mediaplayer_volume_level']. Got "{{ state_attr(tts_entity,'volume_level') }}" required key not provided @ data['sequence']. Got None
Script with object id 'sequence' could not be validated and has been disabled: expected a dictionary. Got [OrderedDict([('service', 'media_player.volume_set'), ('data', OrderedDict([('entity_id', '{{ tts_entity }}'), ('volume_level', 0.75)]))]), OrderedDict([('service', 'tts.google_translate_say'), ('data', OrderedDict([('entity_id', '{{ tts_entity }}'), ('language', 'en'), ('message', '{{ msg }}')]))]), OrderedDict([('delay', OrderedDict([('hours', 0), ('minutes', 0), ('seconds', 5), ('milliseconds', 0)]))]), OrderedDict([('service', 'media_player.volume_set'), ('data', OrderedDict([('entity_id'...
Script with object id 'mode' could not be validated and has been disabled: expected a dictionary. Got 'single'

Automation.yaml

# omroepen was is klaar

- alias: Send alert when washing machine is clean
  trigger:
    - platform: state
      entity_id: input_select.washing_machine_status
      to: Klaar!
  condition:
    condition: and
    conditions:
      - condition: state
        entity_id: input_select.washing_machine_status
        state: Klaar!
  action:
    - service: script.turn_on
      target:
        entity_id: script.tts_and_resume
      data:
        variables:
          msg: De was is klaar!
          tts_entity: media_player.huiskamer

scripts.yaml

# melding doorgeven en verder gaan met muziek        
alias: TTS and resume
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.75
  - 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

Can you find the error?

Hi,
I tried both script versions, the one created by @ghasssan and the one created by @Tankdo and with both, if I play a Spotify playlist from Sonos, after the TTS script intervenes, what was playing before the interruption does not come back. If I play the music from the Sonos playlist or YouTube Music playlist, everything comes back the same after the intervention of the script with TTS.
Is there any fix for this?