Cant make a piston play a specific spotify song on sonos


I have been trying to make a piston play a specific spotify song or album on my sonos, but it does not seem to work with any of the suggestions I have seen in here and elsewhere; does anybody know if something has been changed over at spotify or sonos implying that it is no longer possible?


ST changed the sonos DH about a week ago. I’m not sure if that would have removed the spotify integration, it stopped the text to speech.

Previously, only Sonos devices setup some tome ago could use the old community written DH. My newer Sonos device had to use the official DH, so could not speak like my older ones. The change made by ST, was to move all legacy Sonos devices onto the official DH.

There are other solutions available, but not as well integrated or easy to use.


The LAN Sonos Player Websocket device handler was introduced in 2019, and at the time it was announced that the old LAN Sonos Player (non-websocket version) would be deprecated and users would eventually be forced to use the new device handler. With the Sonos v2 firmware release, things are moving forward and, while I still see the old DH listed in the IDE, I haven’t tried it to see if it still works.

As for your last statement, I run jishi’s node.js server on a Raspberry Pi. It is quick and reasonably easy to set up, very easy to use, and far more powerful that webCoRE’s integration ever was. I still have TTS, can play songs and playlists, and modify groups and even move music between room and groups. It’s a small investment of time and money to take full advantage of the power of Sonos, but to each his or her own.


I use jishi app on my rasp pi, and its working well. I was just pointing out there is more involved setting it up, including the use of the PI, compared to the simple speak command in webcore.

I’m not too keen on the voices from voicerss, so may have a look at the alternatives. I also need to look at sending the same speech to two or more devices simultaneously, I’m not sure if setting up a group for this would upset any existing sonos groupings.


I use Amazon Polly for all TTS.

When you use saypreset for TTS, the original groups, settings and stations/playlists are restored when the speech is completed. I’ve seen it fail to do so occasionally, but that is usually a result of a zone issue not the node server.


Do you have an example of the JSON to send to the saypreset command?

I’d like to write a piston to add all players to a group, say the text then return everything back to how it was.

This is my current generic piston, it sends the voice to each room, but its noy syncronised.


You need to create a preset in the presets directory of the node on the RPi. For example:


“players”: [
{ “roomName”: “Sonos Family”, “volume”: 40 },
{ “roomName”: “Sonos Office”, “volume”: 40 },
{ “roomName”: “Sonos Dining”, “volume”: 40 },
{ “roomName”: “Sonos Bedroom”, “volume”: 20 },
{ “roomName”: “Sonos Bathroom”, “volume”: 20 },
{ “roomName”: “Sonos Guest Room”, “volume”: 20 }

You then invoke the preset using the URL for your node server with a simple web request (GET).

http://192.168.x.x:xxxx/saypreset/my_preset/hi there

Of course, use the proper devices names, IP and Port. You can name the preset whatever you want. It’s easiest to test the request in the browser first before typing or pasting it into webCoRE.


I made a very small piston using preset. Have only tried it with one speaker. The presetnumber can be found in the ide.


I can’t seem to get the saypreset to work. When I try it from the browser it just sits there waiting for a response from the server. I don’t see any errors .

my sample preset anounce.json is

“players”: [
“roomName”: “lounge”,
“volume”: 10


called URL

node.js log
2020-09-18T08:34:20.562Z INFO http server listening on port 5005
2020-09-18T08:35:11.807Z INFO Presets loaded: { anounce: { players: [ { roomName: ‘lounge’, volume: 10 } ] } }


. The presetnumber can be found in the ide.

You can actually get the preset numbers and descriptions by parsing the preset data from any of your Sonos Devices. (In a single home system, all devices have the same preset data). I use this for a piston that chooses a random favorite/preset. This is part of a much larger piston but here are the key lines:

Parse JSON data Sonos Family’s presets;
Set variable {randomFavNumber} = {random(count($};
Set variable {randomFavName} = {$[randomFavNumber]};
Set variable {randomFavSource} = {$json.mediaSource[randomFavNumber]};

Edit: Note that the presets @Paul1964 and I are referring to are not the same as the Station/Playlist/Favorites presets your post references. The presets we’re discussing are group and volume presets used by jishi’s node.js server for Sonos.



Just curious, did you misspell announce intentionally? As long as it is the same in both places, that’s fine. Also, I assume you are replacing localhost with the actual IP of your RPi?


Yes, just a typo, if the preset name is wrong it gives an error.
I’m testing the url on the PI, so localhost should work. It works for other commands when testing.


One other thing to check is to make sure you’re using straight quotes. I just noted that in my example above the editor replaced my straight quotes with smart quotes.


BTW, I’ve never tried using the saypreset command with only one Sonos Device in the preset group, so, while it seems unlikely, that might be an issue as well. With a single device the “say” command provides all the same functionality.


Tried adding another sonos, now I’m getting an error returned. I’m using the legacy sonos app with a bridge, not sure if that could cause any issues?


“players”: [
“roomName”: “lounge”,
“volume”: 10
“roomName”: “spare”,
“volume”: 10



returns following in browser & console

{“status”:“error”,“error”:“Got status 500 when invoking /MediaRenderer/AVTransport/Control”,“stack”:“Error: Got status 500 when invoking /MediaRenderer/AVTransport/Control\n at Object.invoke (/home/pi/sonos/node-sonos-http-api-master/node_modules/sonos-discovery/lib/helpers/soap.js:99:10)\n at Player.setAVTransport (/home/pi/sonos/node-sonos-http-api-master/node_modules/sonos-discovery/lib/models/Player.js:727:15)\n at promise.then (/home/pi/sonos/node-sonos-http-api-master/node_modules/sonos-discovery/lib/prototypes/SonosSystem/applyPreset.js:61:40)\n at process._tickDomainCallback (internal/process/next_tick.js:135:7)”}



What happens if you do individual “say” commands on each of the two rooms? Alternately, what is the status output of /roomname/status/?

I can’t speak to the impact your configuration might be having on this, although the node.js server predates both as I recall. That might be a better question to ask jishi on gitter. In fact, posting your question there might save you some time. :grin:


I think the error was caused by the “spare” room needing an update. Its now back to not responding. Both rooms work fine with individual say commands, and the output from /state on both looks ok, implies it tried to play the test message?



Yeah, I’m stumped. :unamused:


Me too!

thanks for your help, I’ll try on the gitter message board


Looking at the built in documentation of commands (http://localhost:5005/docs/#!/sonos), saypreset is not listed, but preset is. Trying preset works, however it keeps saying the message and wont stop! Stopping the node.js server doesn’t stop it, only powering off the sonos devices works.