Sonos - Group Volume Control
This piston provides a convenient means of controlling the volume of Sonos speaker groups via your preferred voice assistant.
Changes & Features
This piston represents a major rewrite of a piston originally posted here, which has been deprecated due to recent changes to the Sonos integration with SmartThings. This piston will only work if you are using the LAN Sonos Player WebSocket device handler for all your Sonos speakers. (ST has said that all users will be moved to the new DTH after October 17, 2019)
Other than using the new WebSocket commands, the most significant change from the previous iteration of this piston is that group volume control is now provided via a simulated dimmer switch, which you must create in the IDE. I named mine “Group Volume,” which allows me to easily change the group volume by saying phrases like “Alexa, set Group Volume to 30%” or “Alexa, increase Group Volume by 10%.”
Another notable change is that this piston recognizes and can be used to control multiple groups, albeit in a rather elementary manner. By default, adjusting the level of the simulated switch will adjust the volume of the group that started playing first. If multiple groups are currently active (playing), you can toggle control to the group that started playing last by turning the simulated dimmer switch OFF. Turning it off a second time will toggle control back. (Of course, you could also pause or start play on a group to change which group the piston sees as “first” and “last.”) Speakers that are not grouped will be ignored by this piston.
There are also user-configurable limits to prevent group volume being raised to undesirable levels, specifically “Maximum Group Volume” and “Maximum Speaker Volume.” The former prevents the group volume from exceeding the specified level (in case someone misspeaks or your voice assistant misunderstands), while the latter prevents group volume increases that will result in the volume of any individual speaker in the group rising above the Maximum Speaker Volume. (For further explanation, see “About Sonos Group Volumes” below.)
Note if any changes are made to the group or any individual speaker affecting volume, playback status or group role, the piston reevaluates the speakers’ status to ensure the dimmer level reflects the actual group volume. Since such changes on a large group can result in a lot of triggers firing in succession, the piston has a built-in delay and in effect attempts to wait for the last trigger to fire before completing execution.
About Sonos Group Volumes
It may be helpful here to add a word of explanation about Group Volume: Sonos calculates “group volume” as the average of the volumes of the individual speakers (or stereo pairs) in a group. So, if you have five speakers (or speaker pairs) in your group with volume levels of 10, 17, 31, 21, 52, your “group volume” will be (10+17+31+21+52)/5 = 26. If you subsequently increase the group volume to 35, the individual volumes are adjusted on a relative basis. For example, the volume of the first speaker would change to 35/26*10 = 13 and the volumes of the individual speakers would now be 13, 23, 42, 70 and 28. Note that the first speaker increased only 3%, while the last one increased 18%. The potential for this kind of disparate impact is the reason for “Maximum Speaker Volume” limit.
Also, due to the averaging and rounding Sonos employs with in establishing volume means, it is possible that you could set the group volume to 35, and have the piston subsequently report that the actual group volume is 33. This is normal and expected, particularly if the speakers in your group have very diverse volume settings.
There are certain known limitations within webCoRE with regard to the use of device variables and device handlers that utilize custom commands. For the purposes of this piston, do not use a device variable (i.e., “allSpeakers”) to define the speakers the piston will manage. Instead, add the speakers individually where needed using webCoRE’s dropdown menus and actual physical devices.
Edit: 10/18/2019 - BugFix Line #63