Smart routing of sonos_say script

I had a yaml automation that would announce via sonos_say when my Ring doorbell was rung, with the condition that it would only announce if the Pool Sonos was playing (indicating I might be in the backyard). I want to have a more sophisticated version of that using Node-red. I made a basic flow triggered by the ring’s binary sensor, which then fans out to condition state nodes for each media player (halt if paused). It then calls the sonos_say service for each media player with the following example json:
{ "sonos_entity": "media_player.pool", "volume": 0.7, "message": "Someone's at the door", "delay": "00:00:02" }
And looks like this:
image
Oddly, when I run this, only one Sonos will make the announcement if more than one is playing (which, as far as I can tell, is based on the order I added the condition nodes).
Can anyone show me a more elegant execution of this? I’m thinking it’d do something to create a sonos snapshot, temporarily join all playing sonos and play the announcement, then restore the snapshot.

Did you ever figure this out? I can’t even figure out how to use TTS with my Sonos via Node-red.

Me neither, however I found this: https://www.home-assistant.io/cookbook/sonos_say/

I’m using a Node-Red node for Sonos which works really well. I use it for all kind of announcements.

I use node-red all the time and downloaded the Sonos nodes, but can’t get those to work either. I wonder what I’m doing wrong??

yes, It was a bit tricky to setup … I will share my flow later

That would be great! Thanks

All my Sonos messages are done with the Polly-TTS Node

I have configured 3 global variables which either get set by HA or from within Node-Red flows (see Inject node in this sample)

  • global.sonos_message = containing the message string
  • global.Sonos_msg_volume = the volume of the message
  • global.Sonos_msg_room = Room-Name of the Sonos device to say-out the message

In this sample I have i have 4 events

  • General Message , (controlled via the Global Variable)
  • Doorbell , which is called from the motionsensor at front-door
  • Abbey_is_outside, which is called when the backdoor is closed and the motion sensor in front of the backdoor is triggered
  • Abbey_wants_out, which is called when the backdoor is closed and the motion sensor inside the backdoor is triggered

The good thing is that Polly-TTS is doing a local cache, so the last 3 events are triggered and said-out-load, when there is no internet connection

[{"id":"9cd719e1.24c3b8","type":"inject","z":"ced8e004.0bd76","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":145,"y":350,"wires":[["44f6cbc7.2fefd4"]]},{"id":"44f6cbc7.2fefd4","type":"change","z":"ced8e004.0bd76","name":"Sonos MSG","rules":[{"t":"delete","p":"payload","pt":"msg"},{"t":"set","p":"sonos_message","pt":"global","to":"This is a Test","tot":"str"},{"t":"set","p":"Sonos_msg_volume","pt":"msg","to":"0.5","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":205,"y":100,"wires":[["96f5450a.8e2308"]]},{"id":"96f5450a.8e2308","type":"change","z":"ced8e004.0bd76","name":"Sonos MSG","rules":[{"t":"delete","p":"payload","pt":"msg"},{"t":"set","p":"payload","pt":"msg","to":"sonos_message","tot":"global"},{"t":"set","p":"volume","pt":"msg","to":"Sonos_msg_volume","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":370,"y":70,"wires":[["cf50cc2d.0b55"]]},{"id":"cf50cc2d.0b55","type":"switch","z":"ced8e004.0bd76","name":"Sonos?","property":"Sonos_msg_room","propertyType":"global","rules":[{"t":"eq","v":"Bedroom","vt":"str"},{"t":"eq","v":"Kitchen","vt":"str"},{"t":"eq","v":"Living","vt":"str"}],"checkall":"true","repair":false,"outputs":3,"x":540,"y":70,"wires":[["f888efa1.91e9b","dc5d67b9.51e428"],["b4f46022.ec31f","74083f65.078de"],[]]},{"id":"722e0882.1a3968","type":"link in","z":"ced8e004.0bd76","name":">> TTS Polly","links":["3401c13.2f8b93e"],"x":200,"y":70,"wires":[["96f5450a.8e2308"]]},{"id":"f888efa1.91e9b","type":"sonospollytts","z":"ced8e004.0bd76","name":"","voice":"0","ssml":false,"dir":"/tmp","sonosipaddress":"192.168.1.223","sonosvolume":"5","sonoshailing":"0","noderedipaddress":"192.168.1.200","noderedport":"1880","config":"e1b5b40b.260d88","x":760,"y":60,"wires":[]},{"id":"dc5d67b9.51e428","type":"debug","z":"ced8e004.0bd76","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":775,"y":170,"wires":[]},{"id":"b4f46022.ec31f","type":"sonospollytts","z":"ced8e004.0bd76","name":"","voice":"0","ssml":false,"dir":"/tmp","sonosipaddress":"192.168.1.220","sonosvolume":"5","sonoshailing":"0","noderedipaddress":"192.168.1.200","noderedport":"1880","config":"e1b5b40b.260d88","x":760,"y":110,"wires":[]},{"id":"74083f65.078de","type":"debug","z":"ced8e004.0bd76","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":795,"y":200,"wires":[]},{"id":"192584f0.f53b3b","type":"change","z":"ced8e004.0bd76","name":"Doorbell","rules":[{"t":"delete","p":"payload","pt":"msg"},{"t":"set","p":"payload","pt":"msg","to":"http://192.168.1.199:8123/local/doorbell.mp3","tot":"str"},{"t":"set","p":"volume","pt":"msg","to":"50","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":360,"y":140,"wires":[["cf50cc2d.0b55"]]},{"id":"73c7c571.34aa1c","type":"change","z":"ced8e004.0bd76","name":"Abbey_is_outside","rules":[{"t":"delete","p":"payload","pt":"msg"},{"t":"set","p":"payload","pt":"msg","to":"http://192.168.1.199:8123/local/Abbey_is_outside.mp3","tot":"str"},{"t":"set","p":"volume","pt":"msg","to":"Sonos_msg_volume","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":390,"y":180,"wires":[["cf50cc2d.0b55"]]},{"id":"caab3279.d8b6d","type":"change","z":"ced8e004.0bd76","name":"Abbey_wants_out","rules":[{"t":"delete","p":"payload","pt":"msg"},{"t":"set","p":"payload","pt":"msg","to":"http://192.168.1.199:8123/local/Abbey_wants_out.mp3","tot":"str"},{"t":"set","p":"volume","pt":"msg","to":"Sonos_msg_volume","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":390,"y":220,"wires":[["cf50cc2d.0b55"]]},{"id":"3bc2de2e.d4b2d2","type":"link in","z":"ced8e004.0bd76","name":">> Doorbell","links":["c2223c20.eab57"],"x":200,"y":140,"wires":[["192584f0.f53b3b"]]},{"id":"7ef49e1c.013a9","type":"link in","z":"ced8e004.0bd76","name":">> Abbey_is_outside","links":["6c8c1414.55b71c"],"x":200,"y":180,"wires":[["73c7c571.34aa1c"]]},{"id":"1e700ea2.832a71","type":"link in","z":"ced8e004.0bd76","name":">> Abbey_wants_out","links":["3b7b7b96.58e6c4"],"x":200,"y":220,"wires":[["caab3279.d8b6d"]]},{"id":"e1b5b40b.260d88","type":"sonospollytts-config","z":0,"name":"AWS"}]

I hope it helps

Having a bit of trouble getting my head around it, since it uses locally stored mp3 files. Also, I get “pausing error” on my sonospollytts node whenever I try to do anything with it. Any idea what might be causing that?

Yes, the MP3 files are stored locally but this is the same approach with most TTS systems as the announcment can be very lonng. The good thing is that repeated announcements will be played from cache and do not need internet connect.

I do not have a pausing error with my system. Is the pausing for a new announcement or for cached files?

  1. Delay with cached files - do you have audio compression on your sonos? … I had to disable mine due to delays and pause with other features
  2. Delay with new announcements - can be the network or internet connect

Hello
if you have problem with Sonospollytts, please submit an issue on github.
I’ll be glad to help you.
Thanks.

1 Like

I am having issues with the third part device (Sonos) accessing Node-red according to the developer. I’m not clear how that can be as I have other Sonos nodes working, which I assume operate in the same manner, and I can also get Polly to function in a separate node, but it is much more complex to then get to Sonos.

I essentially get an error in the Sonos app when trying to play the mp3 saying it can’t access 192.168.x.xxx:1880 (node red)

I use the Google TTS component with lots of success. It gives you a service call you can use in Node-Red. I have that use for announcements on my Sonos devices and Echos. Works like a champ and if you use the Sonos component you can get pretty sophisticated in grouping your Sonos devices so that the announcement is in sync across your devices.

Yes, finding the right location for the mp3 file was a challenge for me too. This is not an issue with the node but with the node-red and raspberry setup. I have stored my mp3 in a location accessible from any device.
There is a setting in node-red for these kind of files to be stored and used locally (would be my preferred way). Maybe @Supergiovane can help in his post!?

Hello @El_Duderino
Sonospollytts works in that manner:
The node retrieves the audio text from Polly service and stores the related mp3 in the default temp folder. <<— Are you able to tell me, where hassio stores the temp folder?
The node, then, tells Sonos device to play this mp3 by passing the entire path (http: //yournoderedip:port/tempfolder/yourtext.mp3)
At this point, the Sonos device act as a stream player by contacting this URL and by playing the mp3. This is where the problem occurs. Sonos device cannot reach nodered behind hass.io.
I’ve had no problem at all with nodered installed directly, but i know that, when nodered rund behind something like hassio or other apps, it’s a bit tricky to access it.
I’ll guide you to some steps to find out a solution. I’ve never used hassio, but i’ll try to figure out, what the problem is.
What is the url address you type in the browser, to access nodered?

https://192.168.x.xxx:1880/ I also have a duckdns address that might help mitigate that, but I obviously don’t want to share that here.

As for the temp folder, I’m not sure but there is a “tts” folder in the Hassio configuration directory that other nodes seem to leverage.

The above example posted by @xx_Nexus_xx uses the following location: http://192.168.1.199:8123/local/Abbey_is_outside.mp3. Not sure if that helps.

@strangedesign13, would it be possible to share one of your flows using this logic? I like the idea of Polly because it sounds much more natural than most of the other TTS I’ve heard, but happy to look at other options.

Hello
i’ll put an option to manually select the temp folder, so you can use “/local” as done by xx_nexus_xx.
Next release of sonospollytts will be out shortly.

1 Like

The new version 1.0.15 is out. Try to put /local in the Temp Folder option

1 Like

Sure. Here is part of the flow I use. I will say upfront I am no Node-Red expert so I am sure this flow could be improved upon (it bothers me to have the so many delay nodes for instance) but it works for me.

Note: This assumes you have already have set up the Google TTS component in HA or Hass.IO. Side note if you use Hass.io you will need to restart the Node-Red add-on AFTER you get Google TTS working.

Flow Overview:
This flow is triggered for any house announcement I want to make. So the trigger can be anything you want and you can get fancier with the flow trigger piece (for instance I have a trigger that figures out when my daughter leaves or enters a zone and then sets the Text to the specifics "left school, arrived home, etc.) Then it checks the three Sonos speakers I use for announcements, see’s if they are playing something, pauses them if they are and then snapshots them, groups them, announces, ungroups them, restores them and then unpauses them. I have found that I need the pause/unpause piece as for some reason not all snapshots restore to the state, like internet radio stations, they restore to the queue but don’t’ restore playing.

Flow Visual:

Flow Code:
https://pastebin.com/rbP1ypkM

4 Likes