Script for Sonos Speakers to do Text-to-Speech and Handle Typical Oddities

Hey @goonerx1 (and congrats on your first post).

If you have a single call to the service, and don’t want to group, you can put more than one media_player in the entity_id. For example:

Does this suffice for you? Given how you worded the question, I suspect not, but figured I’d show the simple solution first.

Ya, the min_wait solves oddities … the Sonos HA integration frequently reports state changes/information incorrectly. When it seems like the script isn’t resuming it is because it is actually incorrectly using the remaining length of time of the previously playing song as the amount of time to wait before resuming (because of the HA integration state issue). Using min_wait helps address this.

I am going to look at my script to better address this so the issue will occur with less frequency (and perhaps won’t occur at all); I could argue my script is trying to be too smart and getting caught with the state change integration oddity.

Hey @billraff , been awhile!

Unfortunately, those Sonos group names aren’t available in HA … but that doesn’t mean there isn’t a potential workaround. Assuming I’m interpreting what you’re saying, I would have my automation check the receiver to see if it is set to the TV / game input and if so send the announcement to one set of speakers, and if not, send to another set of speakers.

Now unfortunately, this blueprint doesn’t allow you to group speakers automatically (like my music blueprints do), so either you could code the group and ungroup yourself, or you could comma separate the entity_id (see my comment to @goonerx1 … though the announcement playback may not be sync’ed correctly across the speakers).

If you would like I can look to add speaker grouping/ungrouping as part of this script. I’d have to test that sonos.restore will put groups back together, otherwise my script would need to (which would be a pain if multiple groups are involved).

That help?

1 Like

Glad it has been helpful!

Huh, just tested and confirmed I see the same thing … so very strange (given you can see the volume go up and back down). I’ll have to do a bit of digging.

Thanks for the information Talvish. I tested the service you referenced above and ran into the same issue where, since my Port is in a group with almost all speakers, the automation detects Sonos Port has gone from Paused to Play and so the input changes.
I was looking at what appears to be a new feature that would probably make this easier but it doesn’t appear to be fully ‘baked’ yet.

Announce = True doesn’t seem to work?

I’ll play around with my automation to see if I can ungroup/group and the ungroup/regroup the speakers.
Is there a way maybe to create an entity of the group I want to use and point the blueprint to that entity? At one point of playing around with the HASS Music Assistant I had that entity there but for some reason wasn’t able to select it.

HASS Music Assistant
First world problems :wink:
Thanks Again!

Ya, I think you could create something that holds those speaker values as state in HA … but I’m going to do some playing today and see if I can do the grouping automatically so then you would just need to figure out how to detect the source on your receiver and then make two different calls to my script. I’ll keep you posted.

I’m also going to address what @0_0 pointed out (turns out the mute button state is independent of the volume BUT I did confirm I can control that) and may change some wait handling.

1 Like

Just posted an update:

  • @0_0 , fixed your issue … turns out modifying volume doesn’t unmute speakers, so now I forcibly unmute all speakers in the group and that is done independent of speaker volume settings. Let me know if that works for you.
  • @val1, changed my wait handling so there shouldn’t be unexpected delays when resuming music. I’m also not sure if you will need the 12 second delay anymore, you can likely make it smaller, but let me know how it goes. As part of this change I have deprecated max_wait and in a future update will eliminate the max_wait entirely (didn’t now so it wouldn’t break any automations and blueprints)
  • volume, if given, is applied to all speakers in the group

@billraff , I haven’t added grouping as a parameter because it is a tad complicated to handle generically though I’m still looking at it. It needs to check all speakers provided as a parameter to see if they are in separate groups and if so do snapshots/restores for each of group.

OH, also one comment regarding not resuming when the music was started from the Spotify mobile app … this appears to be a Sonos or Sonos HA integration issue. I did some testing and digging today and added some comments to the Github issue found here.

Thnks @Talvish ,

Brilliant, works perfectly now with speakers muted. Thanks very much for the quick help.

1 Like

Didn’t realise you could do it this way, thanks for the idea @Talvish . I’ll give it a go after work :slight_smile:

@Talvish thanks!

Hey @Talvish great work on this - really love what you’ve done :slight_smile: and really takes some of the silly wrinkles out of TTS through Sonos for my automations.

I’m still fairly new to this - is there an easy way to call the script from Lovelace dynamically i.e. integrate it into a dashboard, with configurable parameters? I’ve tried the following but the script doesn’t seem to like me using Helpers as service_data. My Helper options for sonos_entity_selector are the entity_ids for each speaker e.g. media_player.sonos_move:

type: entities
title: Text to Speech
entities:
  - entity: input_text.sonos_tts_text
    type: custom:text-input-row
    name: Text
  - entity: input_select.sonos_entity_selector
    name: Select Sonos Device
  - type: call-service
    name: ' '
    icon: ' '
    action_name: Announce...
    service: script.text_to_speech_on_sonos
    service_data:
      entity_id: input_select.sonos_entity_selector
      message: input_text.sonos_tts_text
      volume_level: 0.4
show_header_toggle: true
state_color: false

Am I missing something obvious?

Thanks in advance!

Investigated a bit further and found this HACS repo, which basically enables what I’m after:

As you were :slight_smile: and thanks again for this script - it’s great.

Thanks @bungamungus … I know many (most?) people have customized their UIs, but oddly I never have. All my interactions with HA are automated (e.g. by events) or by physical hardware (e.g. Pico remotes), so I have no experience there.

Glad you found what you were looking for!

Would that be possible somehow to ungroup the speakers ( if they were left in group ) and play the announcement on a specific speaker only?

You could create a script to do a Media_player: unjoin then have the TTS script run. After the script rejoin the player to the group. It can get messy if you unjoin the master I’ve found so I don’t use that any longer. There is a Sonos: Snapshot if you need to track where all the speakers were. I haven’t found an easy way to exclude a speaker in my case.

I’m creating a calendar automation that speaks the calendar events through a sonos speaker. I would need to pass this {{ trigger.calendar_event.summary }} as message to the Text-to-Speech on Sonos script.
When trying this, the Sonos speaks the words “object object” instead of the value of the trigger.
Sorry if this was already discussed here or on the github page and I just completely missed it.

Note: When saving the automation and opening it again, I see the action is saved with this:
service: script.1676016944306
data:
entity_id: media_player.keuken
message:
"[object Object]": null
volume_level: 0.26
enabled: true

So that’s probably the reason why it says ‘object object’.
Anyone knows how to get this script say the contents of such variable?

Update. Ok, Looks like it might work like this:
message: "\"{{ trigger.calendar_event.summary }}\""

I have discovered a weird behavior when using this script with Groups integration. The issue may be related to an issue with that integration described here:

Media Player Group missing Attributes #85338

If I create a group of Sonos speakers using that integration and try an test this script in the Developer Tools it does not see the defined Group as an entity.

Using the Text-to-Speech service it does -

Here is the group defined using the integration -

Any idea on why it works with TTS but not the script?

The script’s entity_id field restricts the selection to media_players created by the Sonos integration.

You created the group of media_players, not the Sonos integration, so that’s why it’s excluded from selection.

In contrast, the TTS service call makes no restrictions other than the entity must be a media_player, so that’s why your grouped media_player is available for selection.