I created a template widget for my Sonos system (2x Play:1, 1x Playbar) showing cover, track, controls, favorites and grouping possibilties. I use one template per player.
Please feel free to use it, develop further and give feedback. I’m not a HTML crack, so my code is not really streamlined or optimized
Screenshot
Template Code
<style>
.sonosbutton {width: 90%; height: 4em; border: 0; color: white; background-color: transparent;}
.sonosctrl {width: 90%; height: 3em; border: 0; color: white; background-color: transparent;}
.sonosbuttontxt_white {width: 100%;height: 4em; border: 0; color: white;font-size: 10pt; background-color: transparent;}
.sonosbuttontxt_red {width: 100%;height: 4em; border: 0; color: red;font-size: 10pt; background-color: transparent;}
.modgrid {padding-left: 2px; padding-right: 2px; padding-top: 2px; padding-bottom: 2px;}
.butticon {font-size:1em;}
</style>
<div id="sonos-control" class="table" >
<div class="row">
{{ itemValue('str_sonos_bad_zonename')}}
</div>
<div class="row" style="height:150px;" ng-if="itemValue('str_sonos_bad_currentalbumarturl') != 'UNDEF'" >
<img style="max-width: 90%; max-height: 90%;" ng-src="{{itemValue('str_sonos_bad_currentalbumarturl')}}" aria-hidden="false"/>
</div>
<div class="row" style="height:150px;" ng-if="itemValue('str_sonos_bad_currentalbumarturl') == 'UNDEF'" >
<img style="max-width: 90%; max-height: 90%;" ng-src="../static/sonos/sonos_logo.png"/>
</div>
<div class="row" style="height:40px;">
{{ itemValue('str_sonos_bad_currenttrack') | limitTo: 80 }}{{itemValue('str_sonos_bad_currenttrack').length > 80 ? '...' : ''}}
</div>
<div class="row">
<div class="col-md-3 modgrid">
<button class="sonosctrl" style="background-size: contain; background-repeat: no-repeat;background-position: center center;font-size:20px;"
ng-click="sendCmd('pl_sonos_bad_control', 'PREVIOUS')">
<i class="glyphicon glyphicon-step-backward butticon" alt="Step Backward"></i>
</button>
</div>
<div class="col-md-3 modgrid">
<button class="sonosctrl" style="background-size: contain; background-repeat: no-repeat;background-position: center center;font-size:20px;"
ng-click="sendCmd('pl_sonos_bad_control', 'PAUSE')">
<i class="glyphicon glyphicon-pause butticon" alt="PAUSE"></i>
</button>
</div>
<div class="col-xs-3 modgrid">
<button class="sonosctrl" style="background-size: contain; background-repeat: no-repeat;background-position: center center;font-size:20px;"
ng-click="sendCmd('pl_sonos_bad_control', 'PLAY')">
<i class="glyphicon glyphicon-play butticon" alt="Play"></i>
</button>
</div>
<div class="col-xs-3 modgrid">
<button class="sonosctrl" style="background-size: contain; background-repeat: no-repeat;background-position: center center;font-size:20px;"
ng-click="sendCmd('pl_sonos_bad_control', 'NEXT')">
<i class="glyphicon glyphicon-step-forward butticon" alt="Step Forward"></i>
</button>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div ng-init="slider = {
'item': 'dim_sonos_bad_volume',
'vertical': false,
'floor': 0,
'ceil': 100,
'step': 2,
'precision': 1,
'unit': '%',
'hidelabel': true,
'hidelimits': false,
'hidepointer': false,
'showticks': false,
'bigslider': false
}">
</div>
<widget-slider ng-model="slider"/>
</div>
</div>
<div class="row">
<div class="col-md-4 modgrid">
<button class="sonosbutton" style="background-image: url(/static/sonos/1.png); background-size: contain; background-repeat: no-repeat;background-position: center center"
ng-click="sendCmd('str_sonos_bad_radio', 'SRF 1 Basel')">
</button>
</div>
<div class="col-xs-4 modgrid">
<button class="sonosbutton" style="background-image: url(/static/sonos/2.png); background-size: contain; background-repeat: no-repeat;background-position: center center"
ng-click="sendCmd('str_sonos_bad_radio', 'SRF 2 Kultur')">
</button>
</div>
<div class="col-xs-4 modgrid">
<button class="sonosbutton" style="background-image: url(/static/sonos/3.png); background-size: contain; background-repeat: no-repeat;background-position: center center"
ng-click="sendCmd('str_sonos_bad_radio', 'SRF 3')">
</button>
</div>
</div>
<div class="row">
<div class="col-md-4 modgrid">
<button class="sonosbutton" style="background-image: url(/static/sonos/4.png); background-size: contain; background-repeat: no-repeat;background-position: center center"
ng-click="sendCmd('str_sonos_bad_radio', 'SRF 4 News')">
</button>
</div>
<div class="col-xs-4 modgrid">
<button class="sonosbutton" style="background-image: url(/static/sonos/5.png); background-size: contain; background-repeat: no-repeat;background-position: center center"
ng-click="sendCmd('str_sonos_bad_radio', 'Radio Basilisk')">
</button>
</div>
<div class="col-xs-4 modgrid">
<button class="sonosbutton" style="background-image: url(/static/sonos/6.png); background-size: contain; background-repeat: no-repeat;background-position: center center"
ng-click="sendCmd('str_sonos_bad_radio', 'NRJ Basel')">
</button>
</div>
</div>
<div class="row">
<div class="col-md-4 modgrid">
<button class="sonosbuttontxt_red" style="background-size: contain; background-repeat: no-repeat;background-position: center center"
ng-click="sendCmd('sw_sonos_bad_standalone', 'ON')">
<i class="glyphicon glyphicon-fullscreen" alt="Step Backward"></i><br>
<b>Ungroup</b>
</button>
</div>
<div class="col-md-4 modgrid">
<button class="sonosbuttontxt_white" style="background-size: contain; background-repeat: no-repeat;background-position: center center"
ng-click="sendCmd('sw_sonos_group_livingroom_with_bad', 'ON')">
<i class="glyphicon glyphicon-plus-sign butticon" alt="Step Backward"></i><br>
<b>Living</b>
</button>
</div>
<div class="col-xs-4 modgrid">
<button class="sonosbuttontxt_white" style="background-size: contain; background-repeat: no-repeat;background-position: center center"
ng-click="sendCmd('sw_sonos_group_kitchen_with_bad', 'ON')">
<i class="glyphicon glyphicon-plus-sign butticon" alt="Step Backward"></i><br>
<b>Kitchen</b>
</button>
</div>
</div>
</div>
Items
Group grSonos <player>
/*Player*/
Player pl_sonos_kitchen_control "Sonos Play:1 Küche Controller" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX8801400:control"}
Player pl_sonos_livingroom_control "Sonos Playbar Livingroom Controller" (grSonos) {channel="sonos:PLAYBAR:RINCON_XXXXXXXXXXX201400:control"}
Player pl_sonos_bad_control "Sonos Play:1 Bad Controller" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX401400:control"}
/*Radio String*/
String str_sonos_kitchen_radio "Sonos Play:1 Küche Radiosender [%s]" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX8801400:radio"}
String str_sonos_livingroom_radio "Sonos Playbar Livingroom Radiosender [%s]" (grSonos) {channel="sonos:PLAYBAR:RINCON_XXXXXXXXXXX201400:radio"}
String str_sonos_bad_radio "Sonos Play:1 Bad Radiosender [%s]" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX401400:radio"}
/*Current Track String*/
String str_sonos_kitchen_currenttrack "Sonos Play:1 Küche Current Track [%s]" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX8801400:currenttrack"}
String str_sonos_livingroom_currenttrack "Sonos Playbar Livingroom Current Track [%s]" (grSonos) {channel="sonos:PLAYBAR:RINCON_XXXXXXXXXXX201400:currenttrack"}
String str_sonos_bad_currenttrack "Sonos Play:1 Bad Current Track [%s]" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX401400:currenttrack"}
/*Current Artist String*/
String str_sonos_kitchen_currentartist "Sonos Play:1 Küche Current Track [%s]" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX8801400:currentartist"}
String str_sonos_livingroom_currentartist "Sonos Playbar Livingroom Current Track [%s]" (grSonos) {channel="sonos:PLAYBAR:RINCON_XXXXXXXXXXX201400:currentartist"}
String str_sonos_bad_currentartist "Sonos Play:1 Bad Current Track [%s]" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX401400:currentartist"}
/*Current Title String*/
String str_sonos_kitchen_currenttitle "Sonos Play:1 Küche Current Track [%s]" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX8801400:currenttitle"}
String str_sonos_livingroom_currenttitle "Sonos Playbar Livingroom Current Track [%s]" (grSonos) {channel="sonos:PLAYBAR:RINCON_XXXXXXXXXXX201400:currenttitle"}
String str_sonos_bad_currenttitle "Sonos Play:1 Bad Current Track [%s]" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX401400:currenttitle"}
/*Current Cover Image*/
Image img_sonos_kitchen_currentalbumart "Sonos Play:1 Küche Current Cover" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX8801400:currentalbumart"}
Image img_sonos_livingroom_currentalbumart "Sonos Playbar Livingroom Current Cover" (grSonos) {channel="sonos:PLAYBAR:RINCON_XXXXXXXXXXX201400:currentalbumart"}
Image img_sonos_bad_currentalbumart "Sonos Play:1 Bad Current Cover" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX401400:currentalbumart"}
/*Current Cover Image URL*/
String str_sonos_kitchen_currentalbumarturl "Sonos Play:1 Küche Current Cover URL" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX8801400:currentalbumarturl"}
String str_sonos_livingroom_currentalbumarturl "Sonos Playbar Livingroom Current Cover URL" (grSonos) {channel="sonos:PLAYBAR:RINCON_XXXXXXXXXXX201400:currentalbumarturl"}
String str_sonos_bad_currentalbumarturl "Sonos Play:1 Bad Current Cover URL" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX401400:currentalbumarturl"}
/*Current Album*/
String str_sonos_kitchen_currentalbum "Sonos Play:1 Küche Current Track [%s]" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX8801400:currentalbum"}
String str_sonos_livingroom_currentalbum "Sonos Playbar Livingroom Current Track [%s]" (grSonos) {channel="sonos:PLAYBAR:RINCON_XXXXXXXXXXX201400:currentalbum"}
String str_sonos_bad_currentalbum "Sonos Play:1 Bad Current Track [%s]" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX401400:currentalbum"}
/*Current State String*/
String str_sonos_kitchen_state "Sonos Play:1 Küche Current Track [%s]" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX8801400:state"}
String str_sonos_livingroom_state "Sonos Playbar Livingroom Current Track [%s]" (grSonos) {channel="sonos:PLAYBAR:RINCON_XXXXXXXXXXX201400:state"}
String str_sonos_bad_state "Sonos Play:1 Bad Current Track [%s]" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX401400:state"}
/*Standalone Switch*/
Switch sw_sonos_kitchen_standalone "Sonos Play:1 Küche Standalone Schalter" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX8801400:standalone"}
Switch sw_sonos_livingroom_standalone "Sonos Playbar Livingroom Standalone Schalter" (grSonos) {channel="sonos:PLAYBAR:RINCON_XXXXXXXXXXX201400:standalone"}
Switch sw_sonos_bad_standalone "Sonos Play:1 Bad Standalone Schalter" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX401400:standalone"}
/*Save Switch*/
Switch sw_sonos_kitchen_save "Sonos Play:1 Küche Save Schalter" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX8801400:save"}
Switch sw_sonos_livingroom_save "Sonos Playbar Livingroom Save Schalter" (grSonos) {channel="sonos:PLAYBAR:RINCON_XXXXXXXXXXX201400:save"}
Switch sw_sonos_bad_save "Sonos Play:1 Bad Save Schalter" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX401400:save"}
/*Restore Switch*/
Switch sw_sonos_kitchen_restore "Sonos Play:1 Küche restore Schalter" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX8801400:restore"}
Switch sw_sonos_livingroom_restore "Sonos Playbar Livingroom restore Schalter" (grSonos) {channel="sonos:PLAYBAR:RINCON_XXXXXXXXXXX201400:restore"}
Switch sw_sonos_bad_restore "Sonos Play:1 Bad restore Schalter" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX401400:restore"}
/*Current Zone Name String*/
String str_sonos_kitchen_zonename "Sonos Play:1 Küche Zone Name [%s]" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX8801400:zonename"}
String str_sonos_livingroom_zonename "Sonos Playbar Livingroom Zone Name [%s]" (grSonos) {channel="sonos:PLAYBAR:RINCON_XXXXXXXXXXX201400:zonename"}
String str_sonos_bad_zonename "Sonos Play:1 Bad Zone Name [%s]" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX401400:zonename"}
/*Volume Dimmer*/
Dimmer dim_sonos_kitchen_volume "Sonos Play:1 Küche Volume [%.1f %%]" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX8801400:volume"}
Dimmer dim_sonos_livingroom_volume "Sonos Playbar Livingroom Volume [%.1f %%]" (grSonos) {channel="sonos:PLAYBAR:RINCON_XXXXXXXXXXX201400:volume"}
Dimmer dim_sonos_bad_volume "Sonos Play:1 Bad Volume [%.1f %%]" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX401400:volume"}
/*Notification Sound*/
String str_sonos_kitchen_notification "Sonos Play:1 Notification" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX8801400:notificationsound"}
String str_sonos_livingroom_notification "Sonos Playbar Notification" (grSonos) {channel="sonos:PLAYBAR:RINCON_XXXXXXXXXXX201400:notificationsound"}
String str_sonos_bad_notification "Sonos Play:1 Notification" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX401400:notificationsound"}
/*Notification Volume*/
Dimmer dim_sonos_kitchen_notification_volume "Sonos Play:1 Küche Volume Not [%.1f %%]" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX8801400:notificationvolume"}
Dimmer dim_sonos_livingroom_notification_volume "Sonos Playbar Livingroom Volume Not[%.1f %%]" (grSonos) {channel="sonos:PLAYBAR:RINCON_XXXXXXXXXXX201400:notificationvolume"}
Dimmer dim_sonos_bad_notification_volume "Sonos Play:1 Bad Volume Not [%.1f %%]" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX401400:notificationvolume"}
/*ADD*/
String str_sonos_kitchen_add "Sonos Play:1 Küche Add" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX8801400:add"}
String str_sonos_livingroom_add "Sonos Playbar Livingroom Add" (grSonos) {channel="sonos:PLAYBAR:RINCON_XXXXXXXXXXX201400:add"}
String str_sonos_bad_add "Sonos Play:1 Bad Add" (grSonos) {channel="sonos:PLAY1:RINCON_XXXXXXXXXXX401400:add"}
/*Virtual Switches for Grouping*/
Switch sw_sonos_group_livingroom_with_bad "Rule Trigger group_livingroom_with_bad"
Switch sw_sonos_group_livingroom_with_kitchen "Rule Trigger group_livingroom_with_kitchen"
Switch sw_sonos_group_kitchen_with_bad "Rule Trigger group_kitchen_with_bad"
Switch sw_sonos_group_kitchen_with_livingroom "Rule Trigger group_kitchen_with_livingroom"
Switch sw_sonos_group_bad_with_kitchen "Rule Trigger group_bad_with_kitchen"
Switch sw_sonos_group_bad_with_livingroom "Rule Trigger group_bad_with_livingroom"
Switch sw_sonos_kitchen_doorbell "Rule Trigger Kitchen Doorbell" (grSonos)
Switch sw_sonos_livingroom_doorbell "Rule Trigger Livingroom Doorbell" (grSonos)
Switch sw_sonos_bad_doorbell "Rule Trigger Bad Doorbell" (grSonos)
Rules
rule "Group Livingroom with Bad"
when
Item sw_sonos_group_livingroom_with_bad changed to ON
then
var Number v_volume = dim_sonos_bad_volume.state as DecimalType
sendCommand(dim_sonos_livingroom_volume, v_volume)
sendCommand(str_sonos_bad_add, "RINCON_XXXXXXXXXXX201400")
sendCommand(sw_sonos_group_livingroom_with_bad, "OFF")
end
rule "Group Livingroom with Küche"
when
Item sw_sonos_group_livingroom_with_kitchen changed to ON
then
var Number v_volume = dim_sonos_kitchen_volume.state as DecimalType
sendCommand(dim_sonos_livingroom_volume, v_volume)
sendCommand(str_sonos_kitchen_add, "RINCON_XXXXXXXXXXX201400")
sendCommand(sw_sonos_group_livingroom_with_kitchen, "OFF")
end
rule "Group Küche with Bad"
when
Item sw_sonos_group_kitchen_with_bad changed to ON
then
var Number v_volume = dim_sonos_bad_volume.state as DecimalType
sendCommand(dim_sonos_kitchen_volume, v_volume)
sendCommand(str_sonos_bad_add, "RINCON_XXXXXXXXXXX8801400")
sendCommand(sw_sonos_group_kitchen_with_bad, "OFF")
end
rule "Group Küche with Livingroom"
when
Item sw_sonos_group_kitchen_with_livingroom changed to ON
then
var Number v_volume = dim_sonos_livingroom_volume.state as DecimalType
sendCommand(dim_sonos_kitchen_volume, v_volume)
sendCommand(str_sonos_livingroom_add, "RINCON_XXXXXXXXXXX8801400")
sendCommand(sw_sonos_group_kitchen_with_livingroom, "OFF")
end
rule "Group Bad with Küche"
when
Item sw_sonos_group_bad_with_kitchen changed to ON
then
var Number v_volume = dim_sonos_kitchen_volume.state as DecimalType
sendCommand(dim_sonos_bad_volume, v_volume)
sendCommand(str_sonos_kitchen_add, "RINCON_XXXXXXXXXXX401400")
sendCommand(sw_sonos_group_bad_with_kitchen, "OFF")
end
rule "Group Bad with Livingroom"
when
Item sw_sonos_group_bad_with_livingroom changed to ON
then
var Number v_volume = dim_sonos_livingroom_volume.state as DecimalType
sendCommand(dim_sonos_bad_volume, v_volume)
sendCommand(str_sonos_livingroom_add, "RINCON_XXXXXXXXXXX401400")
sendCommand(sw_sonos_group_bad_with_livingroom, "OFF")
end