I did it. I defeated the horrible Google Home "cast-start" prompt sound!

yes, here:

So it looks like they implemented a fix in 2021.12.5 that is working but now I’m finding the state of my Plex client isn’t updating, which is very similar to this issue. Anybody seeing that problem as well?

someone succeed to remove volume up and the volume down sound ?
thanks

I finally figured out after hours what the issue is.
This will only work for a single google home it seems.
From my testing it looks like the last google home in your account that has been triggered puts all the others to sleep.
Example:
I trigger google home 1 with silent track i get the blink and I can control volume
I trigger google home 1 again before it sleeps, no blink, but can still control volume
Keep doing above, no blink, still control volume

I trigger google home 1 with a silent track, i get the blink, and have volume control
I trigger google home 2 with a silent track, i get the blink, and have volume control of #2 but no longer #1
I trigger google home 1 with a silent track, i get the blink, and have volume control of #1 but no longer #2

any idea of my issue ? :slight_smile:

Hello all!

Sorry to hijack this post, but it’s very, very relevant.

I have been working over the last few weeks to develop this script which can be called by other scripts and automations. It’s as user-friendly as the usual media player service. No need to edit the script, in fact, I encourage you not to if you’re not sure what you’re doing.

What is it?

The script will allow you to select a player, set an optional volume and link to your media player content. No need for any “silent” tracks, loops, or anything other than the script.

The script will play the media (without any casting sound), and then restore its state back to what it was before.
For example, you can use it to ring an alert, and after the alert, it will restore volume (if changed) and continue playing whatever was playing before.

Installation:
Create a new script, switch to YAML mode, and copy-paste the script below in and save it. That’s it! It’s ready to use

Issues:

Some issues is that sometimes you will hear a volume “bloop” sound at the end of the automation if you changed the volume. I’ve also had it not resume playback of media it was previously playing, but that may have been because of my Internet connection (it was a radio stream).

I may improve the script over time with some feedback. One feature that could be considered is an option to not restore the previous state, but that’s not a part of this script.

Tested on the latest Home Assistant to this date (2022.2) on my Google Home Minis.

Enjoy!

alias: Google Speaker Play
mode: parallel
icon: mdi:cast-audio
description: >-
  Plays media (on Google Speakers) at the specified volume without the extra
  bleeps and bloops. Restores the state back after it is done.
fields:
  playback_entity:
    name: Playback Entity
    description: The entity that will play the sound
    required: true
    selector:
      entity:
        domain: media_player
  playback_volume:
    name: Volume
    description: Volume to play the sound at
    required: false
    selector:
      number:
        min: 0
        max: 100
        step: 10
        unit_of_measurement: percent
        mode: slider
  media_location:
    name: Content ID
    description: The ID of the content to play. Platform dependent.
    example: media-source://media_source/local/folder_name/file.wav
    required: true
    selector:
      text: null
  media_type:
    name: Content type
    description: >-
      The type of the content to play. Like image, music, tvshow, video,
      episode, channel or playlist.
    example: media-source://media_source/local/folder_name/file.wav
    required: true
    default: music
    selector:
      text: null
sequence:
  - service: scene.create
    data:
      scene_id: before_state_{{ playback_entity|replace(".", "_") }}
      snapshot_entities: '{{ playback_entity }}'
  - service: media_player.volume_mute
    data:
      is_volume_muted: true
    target:
      entity_id: '{{ playback_entity }}'
  - service: media_player.play_media
    data:
      media_content_id: '{{ media_location }}'
      media_content_type: '{{ media_type }}'
    target:
      entity_id: '{{ playback_entity }}'
  - wait_template: '{% if states(playback_entity) == ''playing'' %}true{% endif %}'
    timeout: '00:00:02'
    continue_on_timeout: true
  - choose:
      - conditions:
          - condition: template
            value_template: '{{ playback_volume is number and playback_volume > -1 }}'
        sequence:
          - service: media_player.volume_set
            data:
              volume_level: ' {{ playback_volume / 100 }} '
            target:
              entity_id: '{{ playback_entity }}'
  - service: media_player.volume_mute
    data:
      is_volume_muted: false
    target:
      entity_id: '{{ playback_entity }}'
  - wait_template: '{% if states(playback_entity) == ''idle'' %}true{% endif %}'
    timeout: '00:05:00'
    continue_on_timeout: false
  - service: scene.turn_on
    data: {}
    target:
      entity_id: scene.before_state_{{ playback_entity|replace(".", "_") }}
2 Likes

Thanks, I’ve tried this in my HA (2022.2) and Nest Mini(s), but

  1. I still get the casting sound
  2. Although the volume level is properly restored after the script is called, it’s not resuming the playback

Am I missing something?
Thanks!

@markdavidoff I also don’t see why this would help not getting the cast sound. While testing it myself, I also still get the sound.
Resume of media also does not work by use of scenes with Google Home, becuase of that I have created a script which does work, but which is almost 1000 lines long (also because I try to incorporate all use cases, and it works differently for Spotify, TuneIn, Youtube Music.
Here is a link to my script: Script to resume Google Cast devices after they have been interrupted by any action

I think to not get the cast sound, the approach above in the first post will work best. I do see some room for improvement though, maybe I will look into it in the near future.

1 Like

This. With this: GitHub - anars/blank-audio: Set of blank MP3 audio files

Thanks for sharing this workaround!

1 Like

I’m just hoping one day there’s an out the box feature to use the Google Home “broadcast” messages so I can use HA to give text to speech alerts without interrupting what’s playing. One day…

2 Likes

There is a solution, just not quite ‘out of the box’. Assistant Relay.

True, but that project was abandoned a while ago so without security updates and patches its not for me.

I remember trying it a while back when I was using a Pi4 and it used up quite a bit of CPU too which wasn’t really worth it to keep running at all times just for the occasional message I’d like to broadcast. It would be ideal to just have it included as a native service but since it’s not been done yet I assume there’s a technical limitation with Google stopping it which is fair enough.

It uses almost zero cpu here. I’m using Uncle Bobs Assistant Webserver though.

This is how I achieve a defeated cast sound and use broadcast as a backup if a speaker is ‘busy’. When one is busy it’ll send a non-synced media play (tiny bit echoy through the house but its okay) and fallback the busy device to a assistant_relay approach. I created a script and then funnel all tts calls through it. Been working very well.

You have to create groups in HA mirroring your Google Cast groups as it will use those to broadcast when a speaker is busy.

alias: TTS No Interrupt
sequence:
  - variables:
      available: |-
        {% set entities = expand(target) %}
        {% set ready = entities 
          | rejectattr('state','in',('idle','off','unavailable','paused'))
          | selectattr("attributes.app_name", 'defined') 
          | selectattr('attributes.app_name','in',('Home Assistant Media Player','Home Assistant Lovelace Player','Default Media Receiver'))
          | map(attribute='entity_id') 
          | list %}
        {% set haready = entities  
          | selectattr('state','in',('idle','off','unavailable','paused'))
          | map(attribute='entity_id') 
          | list %}
        {% if is_state('input_boolean.company','on') %}
          {{ (haready + ready) | unique | reject('==','media_player.back_office_speaker') | list }}
        {% else %}
          {{ (haready + ready) | unique | list }}
        {% endif %}
      busy: |-
        {% set entities = expand(target) %}
        {% set busy = entities 
          | rejectattr('state','in',('idle','off','unavailable','paused'))
          | selectattr("attributes.app_name", 'defined') 
          | rejectattr('attributes.app_name','in',('Home Assistant Media Player','Home Assistant Lovelace Player','Default Media Receiver'))
          | map(attribute='entity_id') 
          | list %}
        {% if is_state('input_boolean.company','on') %}
          {{ busy | reject('==','media_player.back_office_speaker') | list }}
        {% else %}
          {{ busy }}
        {% endif %}
  - if:
      - condition: template
        value_template: '{{available|count > 0}}'
    then:
      - service: script.turn_on
        data:
          variables:
            volume_level: 0.001
            entity_id: '{{ available }}'
        target:
          entity_id: script.media_player_volume_set_helper
      - delay:
          hours: 0
          minutes: 0
          seconds: 0
          milliseconds: 300
      - choose:
          - conditions:
              - alias: All Available and no company.  Use google broadcast group
                condition: template
                value_template: '{{media_content_id | length > 0 }}'
              - condition: template
                value_template: '{{ is_state(''input_boolean.company'',''off'') }}'
              - condition: template
                value_template: '{{ busy | count == 0 }}'
            sequence:
              - service: media_player.play_media
                target:
                  entity_id: '{{target.replace(''group.'',''media_player.'')}}'
                data:
                  media_content_id: '{{ media_content_id }}'
                  media_content_type: '{{ media_content_type }}'
                metadata: {}
          - conditions:
              - alias: All Available and no company.  Use google broadcast group
                condition: template
                value_template: '{{ message | count > 0 }}'
              - condition: template
                value_template: '{{ is_state(''input_boolean.company'',''off'') }}'
              - condition: template
                value_template: '{{ busy | count == 0 }}'
            sequence:
              - service: script.turn_on
                data:
                  variables:
                    message: '{{message|default(''One Test Message One'',true) }}'
                    entity_id: '{{target.replace(''group.'',''media_player.'')}}'
                target:
                  entity_id: script.cloud_say_helper
          - conditions:
              - alias: Something busy or company.  Use slimmed HA group
                condition: template
                value_template: '{{media_content_id | length > 0 }}'
            sequence:
              - service: media_player.play_media
                target:
                  entity_id: '{{available | replace(''group.'',''media_player.'')}}'
                data:
                  media_content_id: '{{ media_content_id }}'
                  media_content_type: '{{ media_content_type }}'
                metadata: {}
          - conditions:
              - alias: Something busy or company.  Use slimmed HA group
                condition: template
                value_template: '{{ message | count > 0 }}'
            sequence:
              - service: script.turn_on
                data:
                  variables:
                    message: '{{message|default(''One Test Message One'',true) }}'
                    entity_id: '{{available | replace(''group.'',''media_player.'')}}'
                target:
                  entity_id: script.cloud_say_helper
        default: []
      - if:
          - condition: template
            value_template: '{{volume | default(0)  > 0 }}'
            alias: Custom volume requested.
        then:
          - service: script.turn_on
            data:
              variables:
                volume_level: '{{ volume | default(''0.5'') }}'
                entity_id: '{{ available}}'
            target:
              entity_id: script.media_player_volume_set_helper
          - delay: '{{ delay_to_stop | default(10) }}'
      - service: script.media_player_volume_set
        alias: Correct the volume after the custom volume delay.
        data:
          entity_id: '{{available}}'
      - repeat:
          count: '{{ busy | count }}'
          sequence:
            - variables:
                speaker: '{{ busy[repeat.index - 1] }}'
            - if:
                - condition: template
                  value_template: '{{ message | length > 0 }}'
                - condition: template
                  value_template: '{{ media_content_id | length < 1 }}'
              then:
                - service: script.turn_on
                  data:
                    variables:
                      message: >-
                        broadcast to {{ state_attr('' ~ speaker,'friendly_name')
                        }}, {{message|default('Test Message',true) }}
                  target:
                    entity_id: script.run_ga_command
      - delay:
          hours: 0
          minutes: 0
          seconds: 0
          milliseconds: 200
      - if:
          - condition: template
            value_template: |-
              {{ expand('media_player.kitchen_display')
                | rejectattr('state','in',('idle','off','unavailable','paused'))
                | selectattr('attributes.app_name', 'defined')
                | selectattr('attributes.app_name','in',('Home Assistant Media Player','Home Assistant Lovelace Player','Default Media Receiver'))
                | list | count > 0 
                and  'media_player.kitchen_display' in expand(target) | map(attribute='entity_id') | join(', ') }}
          - condition: template
            value_template: '{{ stop_display | default(true) }}'
        then:
          - wait_for_trigger:
              - platform: state
                entity_id: media_player.kitchen_display
                from: playing
                to: idle
            timeout: |-
              {% if delay_to_stop | default(0) > 0 %}
                1
              {% else %}
                {{ delay_to_stop | default(10) }}
              {% endif %}
          - service: media_player.turn_off
            target:
              entity_id: media_player.kitchen_display
            data: {}
mode: parallel
fields:
  message:
    description: Message to send
    example: This is a message
  target:
    description: The group/entity to broadcast to
    example: group.downstairs_speakers
  media_content_id:
    description: The media to send
    example: https://xxx.xxxx.xxx:xxxx/local/light-chime.wav
  media_content_type:
    description: The type of media
    example: audio/mp3
  stop_display:
    description: Stop the display at the end
    example: true
  volume:
    description: Specify target volume
    example: 0.5
  delay_to_stop:
    description: The Delay to stop the Display
    example: 15
max: 10
alias: Cloud Say helper
sequence:
  - service: tts.google_cloud_say
    data:
      message: '{{ message|default("Just a Message", true) }}'
      entity_id: '{{entity_id|default("media_player.all_speakers", true)}}'
mode: parallel
fields:
  message:
    description: Message of the android alert
    example: Default Message
  entity_id:
    description: entity_id
    example: media_player.all_speakers
max: 10
alias: Run GA Command
sequence:
  - service: notify.ga_command
    data:
      message: '{{ message }}'
mode: parallel
fields:
  message:
    description: Message to send
    example: This is a message
alias: Media Player Volume Set Helper
sequence:
  - service: media_player.volume_set
    data:
      volume_level: '{{ volume_level|default("0.5", true) | float}}'
      entity_id: '{{entity_id|default("no", true)}}'
mode: parallel
fields:
  volume_level:
    description: volume_level to set
    example: 0.5
  entity_id:
    description: entity_id
    example: media_player.all_speakers
max: 10
1 Like

Just found this. Thank you so much for posting this @calisro !!

1 Like

Has anyone noticed yet another new ‘cast sound’ for the nest displays? I just started noticing this new sound the other day.

I got a new sound a couple of months ago on my minis.
It’s more of a “positive” chime than the previous

On mine it feels like a ‘error’ chime. Please stop google. :expressionless:

I see there’s a new “announce” flag for play media . Sadly it doesn’t work on my google speakers but hopefully it does mean someone is aware of how useful it would be so fingers crossed we’ll have something native at some point.

I’m pretty sure it won’t work with google as the speakers need to actually support the announce. I’ve been using Uncle Bob’s google assistant webserver as an announce feature but that will likely break in October when the authentication method it is using goes deprecated by Google. It needs to be updated.