Sonos announcement issue: not playing on all group members & restore not restoring prior groups (if any)

Well, aside a few seconds extra delay (not added in by my delays) to get the TTS announcement and then to resume the audio, the only issue I have is that sonos.restore function starts with the next song in the queue and not where we stopped.

- id: da21735e-351c-11ee-be56-0242ac120002
  alias: Sonos Doorbell Announcement
  trigger:
    - platform: state
      entity_id: binary_sensor.doorbell_button_pressed
      to: 'on'
  action:
  - delay: '00:00:01'
  - service: sonos.snapshot
    data: 
      with_group: true
      entity_id: all
#        - media_player.family_room
#        - media_player.tv_room
#        - media_player.kitchen
#        - media_player.dining_room
#        - media_player.move_2
#        - media_player.sonos_roam
  - delay: '00:00:01'  # Ensures face recognition has time to process
#  - service: media_player.join
#    data:
#      group_members:
#        - media_player.tv_room
#        - media_player.family_room
#        - media_player.dining_room
#        - media_player.move_2
#        - media_player.sonos_roam
#    target:
#      entity_id: media_player.kitchen
#  - delay: '00:00:01'  # Brief delay to ensure the group is formed
  - choose:
      - conditions:
          - condition: template
            value_template: >  # Check for face recognition matches
              {{ state_attr('sensor.double_take_doorbell', 'matches') | length > 0 }}
        sequence:
          - service: chime_tts.say
            data_template:
              entity_id: 
                - media_player.kitchen
                - media_player.dining_room
                - media_player.tv_room
#                - media_player.family_room
#                - media_player.sonos_roam
#                - media_player.move_2
              message: >
                {% set matches = state_attr('sensor.double_take_doorbell', 'matches') %}
                {% set faces = matches | map(attribute='name') | list %}
                {% set corrected_faces = faces | map('trim') | list %}
                {% if 'viviana' in corrected_faces %}
                  {% set corrected_faces = corrected_faces | map('capitalize') | list %}
                  {% set corrected_faces = corrected_faces | map('replace', 'viviana', 'Viv-ee-ah-nah') | list %}
                {% endif %}
                {% if corrected_faces | length == 1 %}
                  {{ corrected_faces[0] }} is at the front door.
                {% else %}
                  {{ corrected_faces | join(', ') }} are at the front door.
                {% endif %}
              tts_service: tts.cloud_say  # Use Nabu Casa TTS service
              join_players: true
              unjoin_players: true
#              announce: true
    default:
      - service: chime_tts.say
        data:
          entity_id: group.sonos_speakers
            - media_player.kitchen
            - media_player.dining_room
            - media_player.tv_room
#            - media_player.family_room
#            - media_player.sonos_roam
#            - media_player.move_2
          message: Someone is at the front door.
          tts_service: tts.cloud_say
          join_players: true
          unjoin_players: true
#          announce: true
  - wait_template: "{{ not is_state('media_player.kitchen', 'playing') }}"
    timeout: '00:00:03'  # Timeout to avoid indefinite waiting
    continue_on_timeout: true
#  - delay: '00:00:02'  # Brief delay to prevent timeout from Sonos API
  - service: sonos.restore
    data: 
      with_group: true
      entity_id: all
#        - media_player.family_room
#        - media_player.tv_room
#        - media_player.kitchen
#        - media_player.dining_room
#        - media_player.move_2
#        - media_player.sonos_roam
  mode: single

Have you tried removing the snapshot/restore service calls and uncommenting announce: true ?

Wouldn’t removing Sonos parameters cause groups to be lost after the announcement? Or does your join/unjoin not affect the actual groups somehow?

Chime TTS offer the same join/unjoin services as the standard Home Assistant media_player entity. I don’t own any Sonos speakers, but I know from Chime TTS users who do, that the join/unjoin is problematic and they recommended not to use it.

Have you tried removing the snapshot/restore service calls and uncommenting announce: true ?

Did you try?

So, I did six tests:

Removing the sonos.snapshot and sonos.restore; adding announce; and keeping join/unjoin with no music playing on devices results in an announcement.

With the Sonos speakers that grouped playing music at TTS event, the ones that receive the TTS input do not rejoin the group after playing music.

Removing join/unjoin with announce = true results in everything staying grouped in Sonos app and music playing. But, the speakers are not in sync with the TTS.

Removing join/unjoin/announce results in the TTS being synced across devices, the Sonos group remains intact after TTS, but the Sonos queue and music is cleared.

Removing join/unjoin with fade_audio = true results in the TTS being synced across devices, the Sonos group remains intact after TTS, but the Sonos queue and music is cleared.

Removing join/unjoin with announce = true results && setting 0ms for the integration’s fade transition in everything staying grouped in Sonos app and music playing. And, the speakers ARE in sync with the TTS.

Sweet.

EDIT Apologies, I meant to reply to derekcentrico.

I’m intrigued by the ability to have the announcement played in sync because my understanding is the announce option is incapable of doing this on unjoined speakers.

In your tests, you say you removed “join/unjoin” but does that mean you did not use an explicit media_player.join service call and used the integration’s own ability to do it?

Or are you saying you used no form of joining whatsoever and played the announcement, in sync, on multiple unjoined speakers?


I wasn’t able to find a “fade transition” option in the integration’s documentation. Are you referring to delay or something else?

image

Apologies, I replied to Nimrod_Dolev but meant to reply to you.

Man, I was torn about pasting my changes per each test and flooding the place with useless text. Should’ve done it to help you visualize.

I removed the join/unjoin and used the announce variable. Whether it works as designed or is an anomaly I don’t know. However, 2 ARCs, 1 One SL, 1 Move2, 1 Roam, and 1 Era 100 are all playing the announcement at the same time -and- I am not losing playing music and not losing Sonos app groups.

The only caveat is that I’m a bit deaf in my left ear (thanks to a lovely IED explosion). But, my right ear is good and the echo I heard across speakers is not occurring at the moment.

Here’s my current code (cleaned up and less Sonos devices being used but still working as described):

- id: da21735e-351c-11ee-be56-0242ac120002
  alias: Sonos Doorbell Announcement
  trigger:
    - platform: state
      entity_id: binary_sensor.doorbell_button_pressed
      to: 'on'
  action:
  - delay: '00:00:03'  # compreface can be sluggish right now for some reason
  - choose:
      - conditions:
          - condition: template
            value_template: >  # Check for face recognition matches
              {{ state_attr('sensor.double_take_doorbell', 'matches') | length > 0 }}
        sequence:
          - service: chime_tts.say
            data_template:
              entity_id: 
                - media_player.kitchen
                - media_player.dining_room
                - media_player.tv_room
#                - media_player.family_room
                - media_player.sonos_roam
                - media_player.move_2
              message: >
                {% set matches = state_attr('sensor.double_take_doorbell', 'matches') %}
                {% set faces = matches | map(attribute='name') | list %}
                {% set corrected_faces = faces | map('trim') | list %}
                {% if 'viviana' in corrected_faces %}
                  {% set corrected_faces = corrected_faces | map('capitalize') | list %}
                  {% set corrected_faces = corrected_faces | map('replace', 'viviana', 'Viv-ee-ah-nah') | list %}
                {% endif %}
                {% if corrected_faces | length == 1 %}
                  {{ corrected_faces[0] }} is at the front door.
                {% else %}
                  {{ corrected_faces | join(', ') }} are at the front door.
                {% endif %}
              tts_service: tts.cloud_say  # Use Nabu Casa TTS service
              announce: true
    default:
      - service: chime_tts.say
        data:
          entity_id: 
            - media_player.kitchen
            - media_player.dining_room
            - media_player.tv_room
#            - media_player.family_room
            - media_player.sonos_roam
            - media_player.move_2
          message: Someone is at the front door.
          tts_service: tts.cloud_say
          announce: true
  - wait_template: "{{ not is_state('media_player.kitchen', 'playing') }}"
    timeout: '00:00:04'  # Timeout to avoid indefinite waiting
    continue_on_timeout: true
  mode: single

You haven’t configured chime_tts.say to use join_players: true so the list of speakers are not joined yet they play the announcement in sync. You have inspired me to test it on my system.

Exactly. Eliminating that allows Sonos groups to survive if not using the sonos.snapshot and restore function.

Let me know how it goes for you. Seems to still be functional after a HA Green reboot.

Don’t want to mark it as solved in case you have a different experience or see something more logical when toying.

I carried out a simple test and received unexpected results.

I used media_player.play_media directly, like this:

service: media_player.play_media
data:
  media_content_type: music
  media_content_id: http://io/TTS/tts_2.wav
  announce: true
target:
  entity_id:
    - media_player.bedroom
    - media_player.move
    - media_player.living_room

Test Results

  • The WAV file played in sync but only on two of the three speakers. The third was silent.

  • I tried it again and the file played, in sync, on only two of the three speakers but not the same two as in the first trial.

  • A third trial produced the same results as the second one.

  • I added a fourth speaker and the results were the same as in the second trial (only two out four played the file).

  • I added a fifth speaker and, once again, only two speakers played the file in sync and all others were silent. For this trial, the two that played were different from previous trials.

  • I joined all five speakers first then played the file (to all five). Only two speakers played the file and it was not in sync. For this trial, the two that played were the same as in the fifth trial.


Based on these results, I can’t use the service call’s announce feature to reliably play on more than two speakers. Why it behaves this way is unclear to me because the speakers work properly when used to play any file without announce (i.e. using Home Assistant or the Sonos app).

FWIW, I have been using a script of my own invention to play announcements. It creates a snapshot, pauses the desired speakers (if playing), unjoins them from any existing group(s), joins them into a new group, sets their volume, plays an optional preamble (i.e. prerecorded sound effect), plays the supplied file, then restores the snapshot. The script has been used at least once a day for over two years with reliable performance.

I experimented with announce when it was first introduced and it played out of sync but, I now realize, I had always tested it with joined speakers. Anyways, my latest test results, with unjoined speakers, aren’t ideal (at least not for me). Perhaps the next step is to test Nimrod_Dolev’s Chime integration with my speakers.

Interesting. I tried similarly at first, albeit with a sonos group created via groups.yaml. This was all out of sync and messed up everything.

I wonder if playing TTS vs. the recorded file would be any different for you. Probably not.

I’ve been having the same issues, but I want to throw this out there cause I didn’t see it mentioned. I know the announce feature is only supported by S2/Gen 2 Sonos HW. You may need to upgrade to resolve some of the out-of-sync issues with announce. I however am still running into issues as I have created a group for all my speakers and get the announcement played via media_player.play_media but the music if playing does not return after the announcement.

I’ve been following this thread with some interest, as I’m also in a similar boat. I have six Sonos speakers scattered around the house, and they pretty much only get used for various announcements (front door motion, somebody arriving home, etc.) All the speakers are in a helper ‘Media Group’, so are referenced as a single entity.

Originally, I was using the media_player.play_media call (first taking a Sonos snapshot of one speaker), playing a local mp3 file that had a combined chime and text, then restoring the snapshot. This worked well for about a year, but occasionally one (or more) of the speakers would refuse to play the announcement, but those speakers that did play were in sync.

To get around the issues, I tried using Dov’s TTS_Chime integration. I couldn’t get it to play a custom chime, but using his default chimes and a message (using Google Translate as the TTS platform), it seems to work…but the speakers are, for the most part, slightly out of sync. I don’t use the join/unjoin, as the speakers are a single ‘entity’. I can live with a little out-of-sync, as the speakers are in different rooms. (One nice feature of Dov’s integration is the ability to higher the volume for announcements, then it automatically resets to its original level afterwards.)

I also issue a very short message (using TTS-Chime, less the chime) every 12 hours, with the volume-level set to 0.2, so that it’s barely a whisper. This is to solve the issue of stale Sonos credential tokens (issue: Notifications of login attempts from Sonos · Issue #88714 · home-assistant/core · GitHub).

So, your tests results are quiet enlightening. If you see a pattern that could improve reliability (and synching), please do post.

I haven’t experimented with it any further since the last time I did (June 2024). I continue to take a snapshot and join speakers prior to playing a preamble (i.e. chime) followed by a message (then restore the snapshot). This technique ensures the selected speakers play in unison (i.e. in sync). It’s all done with a script (that I have been using long before the “announce” feature was introduced to the media_player.play_media action). The script also pauses any content that might already be playing prior to playing the preamble/message (and then restores it).

tl;dr
I don’t use the “announce” feature and continue to use old-school snapshot/join/restore.

Joining them ensures synchronization and, to my knowledge, a Media Group entity doesn’t join its members. That would explain why a Media Group’s members sound “slightly out of sync”.

Hmmm. Interesting. Maybe this is the cause of my angst.

Maybe I’ll experiment with your idea of:

  • Snapshot (although the Sonos snapshot only allows for one speaker, but there is a “with group” option)
  • Join - this would be new for me, and maybe the act of joining would force the audio to all speakers, rather than some simply not playing, and of course, synch them
  • Play (using Media_player.Play_media)
  • Un-join? Would this be appropriate? The reason that I ask is that generally, I want to treat ALL the speakers in the house as one entity - they get the same announcements and same music (when it’s being played), so there’s probably no mileage in un-joining them
  • Restore

Look forward to seeing your results! My solution with ttschime no longer synced but I haven’t had time to come back to this.

sonos.restore will reset the speakers to whatever way they were originally joined (i.e. at the moment sonos.snapshot was executed).

Perfect, thanks.
Currently, I have:

  1. Perform Action (Snap shot Kitchen Sonos)
  2. Perform Action (Join rest of Sonos speakers with Kitchen Sonos)
  3. Perform Action (Set Media Player Volume on EVERY Sonos speaker to 0.6)
  4. Perform Action (Media_Player.Play_Media the desired mp3 file)
  5. Delay 5 seconds
  6. Perform Action (restore on Kitchen Sonos)

Questions:

  1. Do I need to set volume of EVERY speaker, or as they’re now joined, or just on the master (Kitchen Sonos)?

  2. Does the restore reset the volume on all the speakers, or just the entity listed?

UPDATE: Well, that experiment was a dismal failure. The announcement only played on one speaker (the primary - Kitchen).

Bummer!

So, I tried changing the order of the Media player join/snapshot, to see if that made any difference, but alas no - it still plays only on the master (Kitchen). Below is my complete automation code for:

  1. Join all Sonos speakers to Kitchen (master)
  2. Take snapshot
  3. Increase volume of Kitchen (hopefully on all, as they should now be a group)
  4. Play audio (on Kitchen only - same rationale as above)
  5. Restore snapshot (which should reset all speakers back to their original settings)

If anyone can work out why this isn’t working as planned, I’d be very interested in hearing any suggestions.

- id: '1733089602173'
  alias: Front Door Motion New
  description: ''
  triggers:
  - trigger: state
    entity_id:
    - binary_sensor.front_door_motion_sensor_motion_sensor
    from: 'off'
    to: 'on'
  conditions:
  - condition: state
    entity_id: input_boolean.front_door_motion_detected
    state: 'off'
  - condition: state
    state: closed
    entity_id: cover.main_garage
  - condition: state
    entity_id: input_boolean.sonos_announcements
    state: 'on'
  - condition: or
    conditions:
    - condition: state
      entity_id: input_boolean.darrell_at_home
      state: 'on'
    - condition: state
      entity_id: input_boolean.barbara_at_home
      state: 'on'
  actions:
  - action: media_player.join
    data:
      group_members:
      - media_player.laundry_room_sonos
      - media_player.guest_bedroom_sonos
      - media_player.darrells_office_sonos
      - media_player.barbaras_office_sonos
      - media_player.master_bedroom_sonos
    target:
      entity_id: media_player.kitchen_sonos_1
  - action: sonos.snapshot
    data:
      with_group: true
      entity_id: media_player.kitchen_sonos_1
  - action: media_player.volume_set
    data:
      volume_level: 0.77
    target:
      entity_id: media_player.kitchen_sonos_1
  - action: media_player.play_media
    data:
      media_content_id: /local/sounds/front_door_motion.mp3
      media_content_type: music
      announce: true
    target:
      entity_id: media_player.kitchen_sonos_1
  - delay:
      hours: 0
      minutes: 0
      seconds: 5
      milliseconds: 0
  - action: sonos.restore
    data:
      with_group: true
      entity_id: media_player.kitchen_sonos_1
  mode: single