Node-red-contrib-sonos-plus - controlling group volume

@hklages

I am getting stuck with controlling group volumes from node-red. I was sure I had it working, but when I went to implement it and do some final tests, one part doesn't work.

In the flow below the "coordinator" = "loft av" details exactly in the config and when setup a group I add the loft bed to the loft av always, as I assume this is how the coordinator is defined i.e. the first device in the group.

In terms of changing the volume of each device or of the group of devices everything works from both within node-red and from the Sonos app, except for when I change the volume of the group (coordinator) from within node-red.

The volume jumps up for both the loft av and loft bed way higher than it should.

Can you please tell me what I have done wrong here?

[{"id":"7563affc.00631","type":"sonos-universal","z":"bbe5ab3b.d5c698","confignode":"193128a0.2db8a7","compatibilityMode":false,"command":"player.set.volume","state":"","stateType":"str","name":"","x":2630,"y":2640,"wires":[[]]},{"id":"480783a.980ae7c","type":"ui_slider","z":"bbe5ab3b.d5c698","name":"","label":"Loft.AV","tooltip":"","group":"9e7ae248.62254","order":16,"width":8,"height":2,"passthru":false,"outs":"end","topic":"","min":0,"max":"70","step":1,"x":2160,"y":2640,"wires":[["7563affc.00631"]]},{"id":"6db6eb01.3ef5c4","type":"sonos-universal","z":"bbe5ab3b.d5c698","confignode":"193128a0.2db8a7","compatibilityMode":false,"command":"player.get.volume","state":"","stateType":"str","name":"","x":1550,"y":2640,"wires":[["9d383a63.515938"]]},{"id":"262dbf4a.b4e4","type":"link in","z":"bbe5ab3b.d5c698","name":"","links":["32392cc8.e09924"],"x":1355,"y":2640,"wires":[["6db6eb01.3ef5c4"]]},{"id":"5e15f08f.ca4c6","type":"sonos-universal","z":"bbe5ab3b.d5c698","confignode":"4dcfd112.23351","compatibilityMode":false,"command":"group.adjust.volume","state":"","stateType":"str","name":"coordinator (group:adjust volume)","x":2680,"y":2380,"wires":[[]]},{"id":"53cf3cf5.1244c4","type":"link in","z":"bbe5ab3b.d5c698","name":"","links":["32392cc8.e09924"],"x":1355,"y":2380,"wires":[["175241c1.92370e"]]},{"id":"175241c1.92370e","type":"sonos-universal","z":"bbe5ab3b.d5c698","confignode":"4dcfd112.23351","compatibilityMode":false,"command":"group.get.volume","state":"","stateType":"str","name":"coordinator (group:get volume)","x":1590,"y":2380,"wires":[["838ed139.77746","aca0da93.fab938"]]},{"id":"ace56aad.2584a8","type":"sonos-universal","z":"bbe5ab3b.d5c698","confignode":"7b036aa9.1e0684","compatibilityMode":false,"command":"player.set.volume","state":"","stateType":"str","name":"","x":2630,"y":2800,"wires":[[]]},{"id":"6eac9ce6.ea8314","type":"ui_slider","z":"bbe5ab3b.d5c698","name":"","label":"Loft.Bd","tooltip":"","group":"9e7ae248.62254","order":20,"width":8,"height":2,"passthru":false,"outs":"end","topic":"","min":0,"max":"70","step":1,"x":2160,"y":2800,"wires":[["ace56aad.2584a8"]]},{"id":"606dfb44.e86a64","type":"sonos-universal","z":"bbe5ab3b.d5c698","confignode":"7b036aa9.1e0684","compatibilityMode":false,"command":"player.get.volume","state":"","stateType":"str","name":"","x":1550,"y":2800,"wires":[["6eb974cd.d2407c"]]},{"id":"747e92f6.0b65bc","type":"link in","z":"bbe5ab3b.d5c698","name":"","links":["32392cc8.e09924"],"x":1355,"y":2800,"wires":[["606dfb44.e86a64"]]},{"id":"c62e4ff4.e7d66","type":"ui_text","z":"bbe5ab3b.d5c698","group":"9e7ae248.62254","order":12,"width":4,"height":2,"name":"","label":"Cd Vol","format":"{{msg.payload}}","layout":"row-spread","x":2150,"y":2440,"wires":[]},{"id":"7da9d156.1d0e6","type":"ui_text","z":"bbe5ab3b.d5c698","group":"9e7ae248.62254","order":24,"width":25,"height":1,"name":"","label":"","format":"{{msg.payload}}","layout":"row-spread","x":2150,"y":2500,"wires":[]},{"id":"3cfaa4c2.088efc","type":"ui_text","z":"bbe5ab3b.d5c698","group":"9e7ae248.62254","order":21,"width":4,"height":2,"name":"","label":"LB Vol","format":"{{msg.payload}}","layout":"row-spread","x":2150,"y":2860,"wires":[]},{"id":"3ac07dc0.781652","type":"ui_text","z":"bbe5ab3b.d5c698","group":"9e7ae248.62254","order":17,"width":4,"height":2,"name":"","label":"AV Vol","format":"{{msg.payload}}","layout":"row-spread","x":2150,"y":2700,"wires":[]},{"id":"4c37e5ad.48bdfc","type":"ui_slider","z":"bbe5ab3b.d5c698","name":"","label":"Group.","tooltip":"","group":"9e7ae248.62254","order":11,"width":8,"height":2,"passthru":false,"outs":"end","topic":"","min":"-1","max":"70","step":1,"x":2150,"y":2380,"wires":[["60a458c3.902dd8"]]},{"id":"60a458c3.902dd8","type":"function","z":"bbe5ab3b.d5c698","name":"","func":"var prev_vol = flow.get(\"FP_coord_vol\",msg.payload);\n\nmsg.payload = msg.payload - prev_vol;\nnode.warn(msg.payload);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":2380,"y":2380,"wires":[["5e15f08f.ca4c6"]]},{"id":"9d383a63.515938","type":"function","z":"bbe5ab3b.d5c698","name":"volume","func":"var vol = flow.get(\"FP_loft_av_vol\");\n\nif (msg.payload == vol) \n    {return}\nelse {\n    flow.set(\"FP_loft_av_vol\",msg.payload);\n    return msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1880,"y":2640,"wires":[["480783a.980ae7c","3ac07dc0.781652"]]},{"id":"838ed139.77746","type":"function","z":"bbe5ab3b.d5c698","name":"volume","func":"var vol = flow.get(\"FP_coord_vol\");\n\nif (msg.payload == vol) \n    {return}\nelse {\n    flow.set(\"FP_coord_vol\",msg.payload);\n    return msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1880,"y":2380,"wires":[["4c37e5ad.48bdfc","c62e4ff4.e7d66"]]},{"id":"aca0da93.fab938","type":"debug","z":"bbe5ab3b.d5c698","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1870,"y":2440,"wires":[]},{"id":"6eb974cd.d2407c","type":"function","z":"bbe5ab3b.d5c698","name":"volume","func":"var vol = flow.get(\"FP_loft_bed_vol\");\n\nif (msg.payload == vol) \n    {return}\nelse {\n    flow.set(\"FP_loft_bed_vol\",msg.payload);\n    return msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1880,"y":2800,"wires":[["6eac9ce6.ea8314","3cfaa4c2.088efc"]]},{"id":"193128a0.2db8a7","type":"sonos-config","z":"","name":"Office AV","serialnum":"00-0E-58-71-3B-8E:B","ipaddress":"192.168.1.80"},{"id":"9e7ae248.62254","type":"ui_group","z":"","name":"","tab":"9b5f3ade.980978","order":6,"disp":false,"width":"26","collapse":false},{"id":"4dcfd112.23351","type":"sonos-config","z":"","name":"coordinator","serialnum":"00-0E-58-71-3B-8E:B","ipaddress":"192.168.1.80"},{"id":"7b036aa9.1e0684","type":"sonos-config","z":"","name":"Loft Bed","serialnum":"B8-E9-37-DF-FD-EC:2","ipaddress":"192.168.1.83"},{"id":"9b5f3ade.980978","type":"ui_tab","z":"","name":"SONOS PANEL","icon":"dashboard","order":4,"disabled":false,"hidden":false}]

EDIT: It seems to jump around. When I increase the group volume (from within node-red) by a little either the loft AV or the loft bed jumps way to much, so that it's over the group volume.
I can't figure out what I'm doing to make it swap over. And then sometimes it looks like they both jump a lot.

The group always looks like this in Sonos:
image

EDIT2: ok, it's working again. For the nth time, I removed the loft bed from the group and then added it again and it's now just working as you would expect.
It looks to me like a group joining issue.

Could it have something to do with how I am joining the loft bed to the loft av?

[{"id":"915965d.3766498","type":"sonos-universal","z":"bbe5ab3b.d5c698","confignode":"4dcfd112.23351","compatibilityMode":false,"command":"player.leave.group","state":"Loft Bed","stateType":"str","name":"","x":2370,"y":2100,"wires":[["d73a9d29.f9c97"]]},{"id":"f38d8582.133018","type":"sonos-universal","z":"bbe5ab3b.d5c698","confignode":"4dcfd112.23351","compatibilityMode":false,"command":"player.join.group","state":"Loft Bed","stateType":"str","name":"","x":2360,"y":2040,"wires":[["d73a9d29.f9c97"]]},{"id":"c8110206.208bd","type":"ui_button","z":"bbe5ab3b.d5c698","name":"","group":"9e7ae248.62254","order":38,"width":4,"height":1,"passthru":false,"label":"Loft Bed JOIN Loft AV","tooltip":"","color":"","bgcolor":"","icon":"","payload":"","payloadType":"str","topic":"","x":2100,"y":2040,"wires":[["f38d8582.133018"]]},{"id":"42789162.13229","type":"ui_button","z":"bbe5ab3b.d5c698","name":"","group":"9e7ae248.62254","order":39,"width":4,"height":1,"passthru":false,"label":"Loft Bed LEAVE Loft AV","tooltip":"","color":"","bgcolor":"","icon":"","payload":"","payloadType":"str","topic":"","x":2110,"y":2100,"wires":[["915965d.3766498"]]},{"id":"f74bce26.4567f","type":"sonos-universal","z":"bbe5ab3b.d5c698","confignode":"7b036aa9.1e0684","compatibilityMode":false,"command":"player.get.role","state":"","stateType":"str","name":"","x":2760,"y":2040,"wires":[["72125569.f85cdc"]]},{"id":"72125569.f85cdc","type":"ui_text","z":"bbe5ab3b.d5c698","group":"9e7ae248.62254","order":40,"width":6,"height":1,"name":"","label":"Group Status","format":"{{msg.payload}}","layout":"row-spread","x":2970,"y":2040,"wires":[]},{"id":"d73a9d29.f9c97","type":"function","z":"bbe5ab3b.d5c698","name":"","func":"\nsetTimeout(function() {\n    node.send(msg);\n},1000)\nreturn","outputs":1,"noerr":0,"initialize":"","finalize":"","x":2580,"y":2040,"wires":[["f74bce26.4567f"]]},{"id":"4dcfd112.23351","type":"sonos-config","z":"","name":"coordinator","serialnum":"00-0E-58-71-3B-8E:B","ipaddress":"192.168.1.80"},{"id":"9e7ae248.62254","type":"ui_group","z":"","name":"","tab":"9b5f3ade.980978","order":6,"disp":false,"width":"26","collapse":false},{"id":"7b036aa9.1e0684","type":"sonos-config","z":"","name":"Loft Bed","serialnum":"B8-E9-37-DF-FD-EC:2","ipaddress":"192.168.1.83"},{"id":"9b5f3ade.980978","type":"ui_tab","z":"","name":"SONOS PANEL","icon":"dashboard","order":4,"disabled":false,"hidden":false}]

I will have a look on Saturday after returning from vacation.

Group volume is an adjustment that means plus or minus based on the current group volume.
Player volume is absolute volume.

Please send the current group configuration.

Thank you for clarifying, but I get that. You can see in my flow that I have taken that into account.
The issue is to do with the volume jumping up too high in what appears to be a random fashion and to a value that does not correspond with the incremental value being sent... it's jumping up by A LOT more.

I'm not sure what you mean, why would you want to see my device ip address and mac address.

the coordinator is setup with exactly the same ip and mac address as the loft(office) av
the loft bed has it's own ip address and mac address.

Happy holidays!!! Talk later.

Hi.

I am not that good with sonos stuff, but I have Tasmota stuff and have also been in a similar situation.

(Not wanting to compete with @hklages here's my thoughts:)

There is a thing called GROUP in Tasmota and it is a neat trick you can use.
You assign all the devices to a group and rather than control a device, or send a message to a device, you send it to the group.

You also have to edit some stuff about how the devices handle group messages. Something about turning off their re-transmission of the message - I think.

So, basically you copy/clone the control parts of the flow for a device and then rather than send it to that device, you send it to the group.

I have bulbs, and it works.

I know volume is a different thing, but at the level we are doing things: it is the same.

Again: I know you are Sonoff, and not Tasmota.

But this link may help.
How to make groups in Tasmota

Thanks for the input.

If you look at my flows I have already done something similar to what you have said.

I have setup a separate flow for the coordinator of the group and am using the group commands for this flow, rather than the individual player commands

I think it's up to the master code who wrote the node to correct a mistake I have made, or much less likely, I have found a bug.

Hi Alex.

In your flow Loft Bed joins group Loft Bed - so there is no "grouping".
You can check your house wide group structure with the household.get.groups command in node Universal

Please do the following:
In your flow, Universals node, command player.join.group: use "Loft AV" as state!
In player.leave.group the state is ignored. Loft Bed will leave any group it has joined before.

Hope that helps.

@Trying_to_learn: This topic is about the SONOS music player not about SONOFF
Sonoff and Tasmota might be similiar but SONOS and Tasmota are really different :slight_smile:

@hklages

I was changing so many things trying to get it to work that the flow I pasted at the bottom of my OP was incorrect, as you have detected. Loft bed will not join Loft AV with the flow I pasted, however that was no the issue at hand.

The issue was to do with the volume going "wild", jumping up way too high and nearly deafening me in the process.

I am going to look at this again tomorrow (or sometime soon, depending on the time I have) and paste in the correct code this time, unless I managed to fix it of course, in which case I'll post back what I did differently.

So, I still can't get the coordinator to control group volumes properly. The volumes jump around all over the place.

My coordinator has the same IP address as the first Sonos player in the group (Office AV) and I have a 2nd Sonos device connect to the group (Loft AV)

I have a function before my slide to stop unwanted traffic where if the volume has not changed from the last time Sonos was polled no msg is sent to the slider and if it does change I write the new volume to a flow variable.

After the Group slider (which is the coordinator) I am retrieving the flow variable from the last volume change so I can sent only the change in volume to the group of Sonos players.

Is this how it should be setup?

[{"id":"7563affc.00631","type":"sonos-universal","z":"bbe5ab3b.d5c698","confignode":"193128a0.2db8a7","compatibilityMode":false,"command":"player.set.volume","state":"","stateType":"str","name":"","x":2630,"y":2640,"wires":[[]]},{"id":"480783a.980ae7c","type":"ui_slider","z":"bbe5ab3b.d5c698","name":"","label":"Loft.AV","tooltip":"","group":"9e7ae248.62254","order":16,"width":8,"height":2,"passthru":false,"outs":"end","topic":"","min":0,"max":"100","step":1,"x":2160,"y":2640,"wires":[["7563affc.00631"]]},{"id":"6db6eb01.3ef5c4","type":"sonos-universal","z":"bbe5ab3b.d5c698","confignode":"193128a0.2db8a7","compatibilityMode":false,"command":"player.get.volume","state":"","stateType":"str","name":"","x":1550,"y":2640,"wires":[["9d383a63.515938"]]},{"id":"262dbf4a.b4e4","type":"link in","z":"bbe5ab3b.d5c698","name":"","links":["32392cc8.e09924"],"x":1355,"y":2640,"wires":[["6db6eb01.3ef5c4"]]},{"id":"5e15f08f.ca4c6","type":"sonos-universal","z":"bbe5ab3b.d5c698","confignode":"4dcfd112.23351","compatibilityMode":false,"command":"group.adjust.volume","state":"","stateType":"str","name":"coordinator (group:adjust volume)","x":2680,"y":2380,"wires":[[]]},{"id":"53cf3cf5.1244c4","type":"link in","z":"bbe5ab3b.d5c698","name":"","links":["32392cc8.e09924"],"x":1355,"y":2380,"wires":[["175241c1.92370e"]]},{"id":"175241c1.92370e","type":"sonos-universal","z":"bbe5ab3b.d5c698","confignode":"4dcfd112.23351","compatibilityMode":false,"command":"group.get.volume","state":"","stateType":"str","name":"coordinator (group:get volume)","x":1590,"y":2380,"wires":[["838ed139.77746","aca0da93.fab938"]]},{"id":"ace56aad.2584a8","type":"sonos-universal","z":"bbe5ab3b.d5c698","confignode":"7b036aa9.1e0684","compatibilityMode":false,"command":"player.set.volume","state":"","stateType":"str","name":"","x":2630,"y":2800,"wires":[[]]},{"id":"6eac9ce6.ea8314","type":"ui_slider","z":"bbe5ab3b.d5c698","name":"","label":"Loft.Bd","tooltip":"","group":"9e7ae248.62254","order":20,"width":8,"height":2,"passthru":false,"outs":"end","topic":"","min":0,"max":"100","step":1,"x":2160,"y":2800,"wires":[["ace56aad.2584a8"]]},{"id":"606dfb44.e86a64","type":"sonos-universal","z":"bbe5ab3b.d5c698","confignode":"7b036aa9.1e0684","compatibilityMode":false,"command":"player.get.volume","state":"","stateType":"str","name":"","x":1550,"y":2800,"wires":[["6eb974cd.d2407c"]]},{"id":"747e92f6.0b65bc","type":"link in","z":"bbe5ab3b.d5c698","name":"","links":["32392cc8.e09924"],"x":1355,"y":2800,"wires":[["606dfb44.e86a64"]]},{"id":"c62e4ff4.e7d66","type":"ui_text","z":"bbe5ab3b.d5c698","group":"9e7ae248.62254","order":12,"width":4,"height":2,"name":"","label":"Cd Vol","format":"{{msg.payload}}","layout":"row-spread","x":2150,"y":2440,"wires":[]},{"id":"86865bd9.8b5948","type":"ui_text","z":"bbe5ab3b.d5c698","group":"9e7ae248.62254","order":13,"width":13,"height":6,"name":"","label":"","format":"{{msg.payload}}","layout":"row-spread","x":2150,"y":2300,"wires":[]},{"id":"7da9d156.1d0e6","type":"ui_text","z":"bbe5ab3b.d5c698","group":"9e7ae248.62254","order":24,"width":25,"height":1,"name":"","label":"","format":"{{msg.payload}}","layout":"row-spread","x":2150,"y":2500,"wires":[]},{"id":"3cfaa4c2.088efc","type":"ui_text","z":"bbe5ab3b.d5c698","group":"9e7ae248.62254","order":21,"width":4,"height":2,"name":"","label":"LB Vol","format":"{{msg.payload}}","layout":"row-spread","x":2150,"y":2860,"wires":[]},{"id":"3ac07dc0.781652","type":"ui_text","z":"bbe5ab3b.d5c698","group":"9e7ae248.62254","order":17,"width":4,"height":2,"name":"","label":"AV Vol","format":"{{msg.payload}}","layout":"row-spread","x":2150,"y":2700,"wires":[]},{"id":"4c37e5ad.48bdfc","type":"ui_slider","z":"bbe5ab3b.d5c698","name":"","label":"Group.","tooltip":"","group":"9e7ae248.62254","order":11,"width":8,"height":2,"passthru":false,"outs":"end","topic":"","min":"0","max":"100","step":1,"x":2150,"y":2380,"wires":[["60a458c3.902dd8"]]},{"id":"60a458c3.902dd8","type":"function","z":"bbe5ab3b.d5c698","name":"","func":"var prev_vol = flow.get(\"FP_coord_vol\",msg.payload);\n\nmsg.payload = msg.payload - prev_vol;\nnode.warn(msg.payload);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":2380,"y":2380,"wires":[["5e15f08f.ca4c6"]]},{"id":"9d383a63.515938","type":"function","z":"bbe5ab3b.d5c698","name":"volume","func":"var vol = flow.get(\"FP_loft_av_vol\");\n\nif (msg.payload == vol) \n    {return}\nelse {\n    flow.set(\"FP_loft_av_vol\",msg.payload);\n    return msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1880,"y":2640,"wires":[["480783a.980ae7c","3ac07dc0.781652"]]},{"id":"838ed139.77746","type":"function","z":"bbe5ab3b.d5c698","name":"volume","func":"var vol = flow.get(\"FP_coord_vol\");\n\nif (msg.payload == vol) \n    {return}\nelse {\n    flow.set(\"FP_coord_vol\",msg.payload);\n    return msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1880,"y":2380,"wires":[["4c37e5ad.48bdfc","c62e4ff4.e7d66"]]},{"id":"aca0da93.fab938","type":"debug","z":"bbe5ab3b.d5c698","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1870,"y":2440,"wires":[]},{"id":"6eb974cd.d2407c","type":"function","z":"bbe5ab3b.d5c698","name":"volume","func":"var vol = flow.get(\"FP_loft_bed_vol\");\n\nif (msg.payload == vol) \n    {return}\nelse {\n    flow.set(\"FP_loft_bed_vol\",msg.payload);\n    return msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1880,"y":2800,"wires":[["6eac9ce6.ea8314","3cfaa4c2.088efc"]]},{"id":"193128a0.2db8a7","type":"sonos-config","z":"","name":"Office AV","serialnum":"00-0E-58-71-3B-8E:B","ipaddress":"192.168.1.80"},{"id":"9e7ae248.62254","type":"ui_group","z":"","name":"","tab":"9b5f3ade.980978","order":6,"disp":false,"width":"26","collapse":false},{"id":"4dcfd112.23351","type":"sonos-config","z":"","name":"coordinator","serialnum":"00-0E-58-71-3B-8E:B","ipaddress":"192.168.1.80"},{"id":"7b036aa9.1e0684","type":"sonos-config","z":"","name":"Loft Bed","serialnum":"B8-E9-37-DF-FD-EC:2","ipaddress":"192.168.1.83"},{"id":"9b5f3ade.980978","type":"ui_tab","z":"","name":"SONOS PANEL","icon":"dashboard","order":6,"disabled":false,"hidden":false}]

In this example you can see the Office AV and Loft AV are in a Sonos group:
image

All the volumes are roughly the same in my flow:
image

And in the Sonos player:
image

However, when I drag the slider to 23 for the group, this is what happens:
image

Which is reflected in the player:
image

But if I try the same test from the Sonos player, both volumes go up together as expected.

Is anyone else using this functionality where it works?

Hi Alex.

Group volume is the average of all speaker volumes:
case 1: (14+15)/2 = 14.5 roughly 14
case 2: (9+38)/2 = 23.5 roughly 23
But it does not keep the ratio between the speakers 14/15 versus 9/38 - that's strange. It should.

What happens when you further increase the group volume - does it keep the ration 9/38?
(assuming you don't change the music stream as that may impact the ration)

In the next couple of day I will check how to "set/modify" that ratio. There is Sonos function "snapshot". Maybe that helps.

On my SONOS the ratio is 1/1 so increasing group volume by 2 works as expected.

BTW: You don't need to have separate config file for configurator. For 2 speakers you need maximum 2 config files.

Please have look at issue96.
Try the new release 4.1.4 and let me know whether its solved.
group.create.volumesnap may solve your problem.
I added also group.set.volume - may simplefy your flow.