Sonos Plus - Questions

Hey @hklages

Loving your Sonos nodes!

I have a few questions :

  1. How can I change the shuffle and repeat options for a player?

  2. When you use your nodes, do you end up querying Sonos every second for every player to get status of things like volume, mute state, playstate (playing/paused)?

  3. I am querying the Sonos controller every second for playlist information i.e. the queue. Is this what you also do.

Question 2 & 3 are about performance. I am trying to reduce the number of queries, but am stuck with the idea that I have to ping every player every second to get up to date info on them.

Hi - thanks :slight_smile:

  1. I am proud of my just finished documentation (;-): link to command - search for
    group.set.queuemode and Values (the link to headers have to be improved :frowning:

  2. Not really. I use Node-RED for automation: events such as leave/return to home, sleep, awake trigger actions. For ad hoc I use Alexa (triggering Node-RED) and for visualization my Smartwatch (it shows title, station via the Smartphone SONOS app) or Smartphone with Dashboard.

Anyway you can use this sonos notify to get a trigger when there are change.

Does it help?

1 Like

You should be proud of it.

It's epic!!!

I need to carve out some time to understand what I can do now. Wow!

@hklages
I'm trying to figure out your comment here:

" #FF0000 Important: In node-red-contrib-sonos-plus standalone player are treated as a group (with size 1)! So you should use the group commands to control standalone player!"

What is the point of the player commands then?

I wrote all my flows to distinguish between the group (controller) and individual players. I'll re-write it, just trying to understand why.

Hi Alex. You don't need to rewrite anything. Everything is done inside the nodes(internally).
I have to improve that part of the documentation.

Example: There is a "group.play" - but there is no player.play.

So to play a song on a stand alone player, just use group.play in combination with a config node pointing to that player.

(To confuse your a bit more: You can also use a config node pointing to any active player but being overuled with msg.playerName = your standalone player)

I understand the confusing part of your statement to do with overriding the player using msg.playerName, however I don't get the first part about when to use group.x vs player.x.

Unfortunately I can't tack a picture of the drop down menu in your node, but you can see from this image that there are still player.x commands:

image

When would I use the player.x commands going forward?

On another note, I am not sure if you intended the MySonos node to work this way, but I had to split my playlist messages and send them to an individual MySonos node per player....

ie passing msg.playerName does not seem to work for the MySonos node. It's no big deal, but thought I'd mentioned it, in case this wasn't how you expected it to work.

.. let's have a look at a concrete example - get queue.

Assuming play:5 (ip addresss 192.168.178.1 with name KITCHEN) and play:3 (ip address 192.168.178.2, name BATH) are grouped and the KITCHEN is the coordinator.

group.get.queue will always output the queue from KITCHEN - even if you send it to BATH. Because in this group, KITCHEN is coordinator and this queue is relevant.

player.get.queue will output the queue from BATH if you send it to BATH.

If you have stand alone player both commands will provide the same result.

Understood!

So before I was ALWAYS sending the coordinator = Kitchen (in your example above) to get the queue, now I can use any player in the group for group commands.

I just tested it for group.get.volume and it works that way you have said i.e. I sent the command to a player that was not the coordinator and yet the group volume was returned.

Thank you!

Can you please send the flow? With export. That flow looks strange. What would you like to achieve?

Of course, however I need to explain what I am doing first.

From uibuilder I am sending requests to control various players. One of those request is to change the playlist for a group.

Can you give me two mins to test your new nodes to see if the same applies to MySonos as the Universal node i.e. I'm wondering if your new version doesn't need all these nodes now.

[{"id":"2a9179ea.f2ddc6","type":"sonos-universal","z":"e28c9ca5.73e4e","confignode":"193128a0.2db8a7","compatibilityMode":false,"command":"message","state":"","stateType":"str","name":"","x":2400,"y":1600,"wires":[["3c100ca2.933b14"]]},{"id":"3c100ca2.933b14","type":"debug","z":"e28c9ca5.73e4e","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":2610,"y":1600,"wires":[]},{"id":"b9fea7cd.7e0778","type":"debug","z":"e28c9ca5.73e4e","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":2390,"y":1540,"wires":[]},{"id":"4844384a.aaea98","type":"sonos-manage-mysonos","z":"e28c9ca5.73e4e","confignode":"193128a0.2db8a7","compatibilityMode":false,"command":"mysonos.queue.item","state":"","stateType":"str","name":"","x":2920,"y":1740,"wires":[["e5d5ef5d.1b76a"]]},{"id":"5b16e9ce.5ebf38","type":"function","z":"e28c9ca5.73e4e","name":"Send Payload","func":"//\"playerName\"   : msg.playername,\n\nnode.send\n    ({\n    \"payload\"      : msg.payload,\n    })\n\n// setTimeout(function()\n//             { \n//             if (msg.type == \"playlist\") {node.warn([\"up to here now at last\", msg])\n//             return msg.payload}    \n//             }, 1500);","outputs":1,"noerr":0,"initialize":"","finalize":"","x":2680,"y":1740,"wires":[["4844384a.aaea98","65fb1e92.f2032"]]},{"id":"c8d16fd5.581c5","type":"switch","z":"e28c9ca5.73e4e","name":"PlayerName Route","property":"playerName","propertyType":"msg","rules":[{"t":"eq","v":"Office AV1","vt":"str"},{"t":"eq","v":"Office AV2","vt":"str"},{"t":"eq","v":"Kit Cabinet","vt":"str"},{"t":"eq","v":"Kit Garden","vt":"str"}],"checkall":"true","repair":false,"outputs":4,"x":2410,"y":1820,"wires":[["5b16e9ce.5ebf38"],["385128f4.39d478"],["b4f902ce.95674"],["749cf01c.71c8"]]},{"id":"a87f6ad5.b36408","type":"sonos-manage-mysonos","z":"e28c9ca5.73e4e","confignode":"ecfbb4f2.891d98","compatibilityMode":false,"command":"mysonos.queue.item","state":"","stateType":"str","name":"","x":2920,"y":1800,"wires":[["8377fac7.e7eb18"]]},{"id":"385128f4.39d478","type":"function","z":"e28c9ca5.73e4e","name":"Send Payload","func":"//\"playerName\"   : msg.playername,\n\nnode.send\n    ({\n    \"payload\"      : msg.payload,\n    })\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":2680,"y":1800,"wires":[["a87f6ad5.b36408"]]},{"id":"e5d5ef5d.1b76a","type":"debug","z":"e28c9ca5.73e4e","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":3130,"y":1740,"wires":[]},{"id":"8377fac7.e7eb18","type":"debug","z":"e28c9ca5.73e4e","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":3130,"y":1800,"wires":[]},{"id":"cb39b6f5.75bb98","type":"switch","z":"e28c9ca5.73e4e","name":"Playlist Routing","property":"type","propertyType":"msg","rules":[{"t":"neq","v":"playlist","vt":"str"},{"t":"eq","v":"playlist","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":2160,"y":1640,"wires":[["2a9179ea.f2ddc6","b9fea7cd.7e0778"],["c8d16fd5.581c5","e6411942.d18728"]]},{"id":"65fb1e92.f2032","type":"debug","z":"e28c9ca5.73e4e","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":2870,"y":1680,"wires":[]},{"id":"e6411942.d18728","type":"debug","z":"e28c9ca5.73e4e","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":2370,"y":1740,"wires":[]},{"id":"ba8d3d86.f86c1","type":"sonos-manage-mysonos","z":"e28c9ca5.73e4e","confignode":"7e7eaede.6ea5d","compatibilityMode":false,"command":"mysonos.queue.item","state":"","stateType":"str","name":"","x":2920,"y":1860,"wires":[["b0ec837d.8089c"]]},{"id":"b4f902ce.95674","type":"function","z":"e28c9ca5.73e4e","name":"Send Payload","func":"//\"playerName\"   : msg.playername,\n\nnode.send\n    ({\n    \"payload\"      : msg.payload,\n    })\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":2680,"y":1860,"wires":[["ba8d3d86.f86c1"]]},{"id":"b0ec837d.8089c","type":"debug","z":"e28c9ca5.73e4e","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":3130,"y":1860,"wires":[]},{"id":"c9837d9b.64789","type":"sonos-manage-mysonos","z":"e28c9ca5.73e4e","confignode":"175b8337.d329ad","compatibilityMode":false,"command":"mysonos.queue.item","state":"","stateType":"str","name":"","x":2920,"y":1920,"wires":[["4e6d05e7.9740dc"]]},{"id":"749cf01c.71c8","type":"function","z":"e28c9ca5.73e4e","name":"Send Payload","func":"//\"playerName\"   : msg.playername,\n\nnode.send\n    ({\n    \"payload\"      : msg.payload,\n    })\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":2680,"y":1920,"wires":[["c9837d9b.64789"]]},{"id":"4e6d05e7.9740dc","type":"debug","z":"e28c9ca5.73e4e","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":3130,"y":1920,"wires":[]},{"id":"193128a0.2db8a7","type":"sonos-config","z":"","name":"Office AV1","serialnum":"00-0E-58-71-3B-8E:B","ipaddress":"192.168.1.80"},{"id":"ecfbb4f2.891d98","type":"sonos-config","z":"","name":"Office AV2","serialnum":"00-0E-58-85-16-D8:0","ipaddress":"192.168.1.216"},{"id":"7e7eaede.6ea5d","type":"sonos-config","z":"","name":"Kit Cabinet","serialnum":"00-0E-58-57-A1-A8:B","ipaddress":"192.168.1.205"},{"id":"175b8337.d329ad","type":"sonos-config","z":"","name":"Kit Garden","serialnum":"00-0E-58-77-47-AC:8","ipaddress":"192.168.1.97"}]

EDIT: Ok, I tested it and I still get this message if I do not sent the playlist request to the coordinator of the group:

image

I'm going to load you with a few things given your responding quickly :wink:

This next one is just feedback. I get it now, but it took me some research to figure out how to send commands.

In your drop downs you show commands like this: "group: get playback state"

image

However you expect the command to be sent like this: "get.playback.state"

Now this doesn't affect me anymore, as I get it now, however I would suggest that you show the command as it's required in the drop down menu. I get that it shows the correct way on the node itself, but for the uninitiated it's not that obvious. Very minor point of feedback. Take it or leave it.

Good point. My intention was to provide a help text but it looks as if that went wrong. "group.get.playbackstate" is easier to understand.

Thats something for one of the next releases.

Are all players grouped?
yes?: You can use 1x mysonos.export.item + 1 x group.play.export

If you only want to queue without playing then group.queue.export would be good - but i have to create it. Its still missing in the current version.

Ok, let me try that combination out. Thanks!

Fyi, Not ALL my players are grouped.

EDIT: Ok, I tested your suggestion and it works!

Much simpler flow, thanks again!
image

I was very pleased with myself figuring out this flow... haha, off to the trash bin you go!

image