buschif4
(Flo)
January 24, 2021, 8:11am
41
@johannesbonn There is nothing to change on the widget because we are not performing a parent loop.
I checked the snapshot version 2160 but it seams that the issue still occours if you place serval widgets on the same page.
@ysc Unfortunately your bug fix is not working When I open a page with serval widgets it always shows the result of the last oh-repeater in all 3 widgets. To be sure I forced a cache refresh but unfortunately this was not solving the issue. In the Dev messages I can see that all commands are send with the “Bathroom” flag which was set to my last widget.
buschif4
(Flo)
January 24, 2021, 8:14am
42
@opus can you share the yaml code of one widget?
By the way, are you placing serval player widgets on the same page or are you using the player widget on different pages? There is a bug if you run the player widget multiple times on the same page as described in the previous discussion. (Hopefully ysc can help t fix this.
But if you use the widget on a per room page than it is working without any issues if it is properly configured
opus
(Jürgen Baginski)
January 24, 2021, 8:21am
43
The yaml:
component: widget:widget_Sonos_Player
config:
itemTitle: PlayBuero
itemPlayer: PlayBuero_Fernbedienung
itemSonosRule: Sonos_Multiroom_Controll
itemCover: PlayBuero_Coverbild
propZoneArray: '["Wohnzimmer"; "PlayWohnzimmer_Fernbedienung";
"PlayWohnzimmer_Lautstarke"; "PlayWohnzimmer_Master"]["Buero",
"PlayBuero_Fernbedienung"; "PlayBuero_Lautstarke";
"PlayBuero_Master"]["Kueche"; "PlayKueche_Fernbedienung";
"PlayKueche_Lautstarke"; "PlayKueche_Master"]["Gaestezimmer",
"PlayGaestezimmer_Fernbedienung"; "PlayGaestezimmer_Lautstarke";
"PlayGaestezimmer_Master"]'
itemVolume: PlayBuero_Lautstarke
itemCoordinator: PlayBuero_Master
…and I use only one widget.
buschif4
(Flo)
January 24, 2021, 8:30am
44
@opus If you want to use the “grouping” feature you need to provide the ZoneName parameter as well. Thie is related to the ZoneArray parameter. So the ZoneName identifies the current controlled group.
Try this YAML code and have a look at the last line to see which value I added.
component: widget:widget_Sonos_Player
config:
itemTitle: PlayBuero
itemPlayer: PlayBuero_Fernbedienung
itemSonosRule: Sonos_Multiroom_Controll
itemCover: PlayBuero_Coverbild
propZoneArray: '["Wohnzimmer"; "PlayWohnzimmer_Fernbedienung";
"PlayWohnzimmer_Lautstarke"; "PlayWohnzimmer_Master"]["Buero",
"PlayBuero_Fernbedienung"; "PlayBuero_Lautstarke";
"PlayBuero_Master"]["Kueche"; "PlayKueche_Fernbedienung";
"PlayKueche_Lautstarke"; "PlayKueche_Master"]["Gaestezimmer",
"PlayGaestezimmer_Fernbedienung"; "PlayGaestezimmer_Lautstarke";
"PlayGaestezimmer_Master"]'
itemVolume: PlayBuero_Lautstarke
itemCoordinator: PlayBuero_Master
propZoneName: Buero
opus
(Jürgen Baginski)
January 24, 2021, 8:39am
45
Bingo, that worked.
One more question:
As I understand ATM the intended use is one widget per room(page), the grouping would be used to group several rooms. Is that correct?
buschif4
(Flo)
January 24, 2021, 8:43am
46
Yes at the moment you can only place one widget on a page because a bug in the oh-repeater. So e.g. one in a room page “living room”. The widget aways controls the living room speaker. But it can add other speakers to the same zone or add itself to another running zone.
1 Like
Thank you for your reply! Is it possible to use several labels on one page with popups of the widget for every zone?
opus
(Jürgen Baginski)
January 24, 2021, 10:41am
48
All understood now.
The last problem I had was that the rule needs to be triggered on a command (otherwise the variable command
is not defined. IMHO that isn’t stated as needed.
opus
(Jürgen Baginski)
January 26, 2021, 6:41pm
49
Does the rule work for you when using it to Add a player? I get an Error Fail to execute action: 2
.
On my system the internally used function isSpeakerActive
is the problem (more precise the itemRegistry.getItem(mySpeaker + itemPlayExtensionName).getState().toString()
is producing the error).
[Edit:]
Without the double if-clause which uses the above function, using only the addSpeaker(getSpeakerName(coordinator), getSpeakerUUID(speakerToControl));
in any case it is working if the coordinator is palying or not.
[Edit2:]
DISREGARD all the above.using Item
I observed a “curious” REST behaviour (Add not working, other Rule-parts using itemRegistry working, saving any Widgit-config not possible), did a restart of openHAB and REST is working again normal.
In other words: No problem with the rule!! Sorry for the hussle.
1 Like
opus
(Jürgen Baginski)
January 29, 2021, 1:07pm
50
I’m receiving a WARN whenever (re)loading the widget: Attempting to send a state update of an item which doesn't exist: undefined
.
I have all needed items created, looked thrpugh the complete widget yaml code, can’t find a hint what is missing.
Daniel_O
(Daniel O )
March 15, 2021, 4:16pm
51
Thank you! After some work it works flawlessly. For all other who might be struggling … check your capitalizations! In the description for the multiroom rule there are a few suffixes like _control used with a lower case first letter, but the standard values in the rules use a capital first letter (like _Control).
I still have a visual issues with the volume item though:
all individual volume controls work
the master volume control works
But:
The “red” bar that visualizes the master volume seems to be totally off. I have set the ZoneVolume in the item Selector as described in the first post.
edit: I just noticed, I created all the ZoneVolume items as “dimmers” like the original volume items. But that wasn’t really specified in the multiroom rule (there is no info about the type of the zone volume items). So I changed them all to “number”, but it has the same effect.
It seems the scale of the volume control is completely off, see how far I have to drag the slider to get 100%. If I actually set it to 20, 25 or whatever, the proper value gets set to the zones though.
Edit 4: the workaround to this is, to add the widget into a row->column block. It doesn’t work in cell or masonry
I also have one other question: i have seen some screenshots where the widget seems to be a bit broader. Yet, for me, it’s always quite narrow, no matter whether I place it in masonry or in a row. How did you do that?
edit3:
I just implemented this through a rule, I set a place holder image, whenever the cover art item changes to UNDEF. See here
And one more thing: When I change the input to “TV” sadly there doesn’t seem to a way for the sonos binding to indicate this. The album art then changes to “undef” and makes a broken image appear. It would be nice to intercept this in the widget.
d0t
(Mike)
April 10, 2021, 7:07pm
52
@buschif4 - Great work here!
While I don’t have a Sonos device, have a bunch of Amazon Echo’s; to my surprise your widget already works quite well with the Amazon Echo Binding accept of course the multi-room control stuff. In my spare time I might rework the code to support selecting the target Amazon Echo, as well as zones.
Thanks for sharing!
vally
(Stefan)
August 27, 2021, 11:09pm
54
@buschif4
Hi Flo,
i have added all the Items Groups and so on. but when i click on the Widget for “Volume” nothing appears. The same by clicking on the Multiroom rule.
I have also changed the “Endings” in the Script to German Items.
nothing appears.
The same by click on the Speaker Selection
Widget YAML:
component: widget:widget_Sonos_Player
config:
itemTitle: SonosMoveWohnzimmer_Titel
itemAlbum: SonosMoveWohnzimmer_Album
itemArtist: SonosMoveWohnzimmer_Kunstler
itemCover: SonosMoveWohnzimmer_Coverbild
itemPlayer: SonosMoveWohnzimmer_Fernbedienung
itemVolume: SonosMoveWohnzimmer_ZoneVolume
itemShuffle: SonosMoveWohnzimmer_Shuffle
itemRepeat: SonosMoveWohnzimmer_Wiederholen
itemSonosRule: Sonos_Multiroom_Controll
propZoneArray: “[“Kueche”; “SonosOneKuche_Fernbedienung”;
“SonosOneKuche_Lautstarke”; “SonosOneKuche_Master”][“Bad”;
“SonosOneBad_Fernbedienung”; “SonosOneBad_Lautstarke”;
“SonosOneBad_Master”]”
propWidgetTitle: Wohnzimmer
propZoneName: Wohnzimmer
itemCoordinator: SonosMoveWohnzimmer_Master
Rule Volume:
triggers:
id: “3”
configuration:
groupName: Group_Sonos_ZoneVolume
type: core.GroupCommandTrigger
id: “4”
configuration:
groupName: Group_Sonos_Volumes
type: core.GroupStateChangeTrigger
id: “1”
configuration:
groupName: Group_Sonos_Coordinators
type: core.GroupStateChangeTrigger
conditions: []
actions:
inputs: {}
id: “2”
configuration:
type: application/javascript
script: >-
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ User inputrequired! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
//group where all sonos items belong to (can be a nested group)
var itemGroupName = "Group_Sonos";
//Volume item extension (controls the volume of the player)
var itemVolumeExtensionName = "_Lautstarke";
//Zone volume item for the widget. Not connected to any thing item.
var itemZoneVolumeExtensionName = "_ZoneVolume";
//Coordinator item extension (displays the master of this zone)
var itemMasterExtensionName = "_Master";
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
Rule Multiroom:
triggers:
id: “1”
configuration:
itemName: Sonos_Multiroom_Controll
type: core.ItemCommandTrigger
conditions: []
actions:
inputs: {}
id: “2”
configuration:
type: application/javascript
script: "//speaker array needs to be filled for each player → “zone name”,
“device name”, “device UUID”
var sonosSpeakers = [
\ [\"Wohnzimmer\", \"SonosMoveWohnzimmer\",
\"RINCON_XXXXX1400\"],
\ [\"Kueche\", \"SonosOneKuche\",
\"RINCON_XXXX1400\"],
\ [\"Bad\", \"SonosOneBad\", \"RINCON_XXXXXX1400\"]
];
//default volume in hours
var defaultSpeakerVolume = [8, 8, 8, 8, 8, 8, 8, 10, 12, 14, 16,
18, 18, 20, 20, 20, 20, 18, 18, 16, 14, 12, 10, 8]
//default play uri can pe a uri or tunein station id depending
of the playuri item
var defaultPlayUri = \"24878\"
//group where all sonos items belong to (can be a nested group)
var itemGroupName = \"Group_Sonos\";
//Player item extension (defines the player status)
var itemPlayExtensionName = \"_Fernbedienung\";
//Volume item extension (controls the volume of the player)
var itemVolumeExtensionName = \"_Lautstarke\";
//Add-speaker item extension (adds a speaker to the zone
coordinator)
var itemAddExtensionName = \"_Hinzufugen\";
//Remove-speaker item extension (removes speaker from the zone
coordinator)
var itemRemoveExtensionName = \"_Entfernen\";
//Play-Uri item extension (needed to play a uri on a new group)
var itemPlayUriExtensionName = \"_Tuneinstationid\";
//Standalone item extension (needed to remove player if this is
the coordinator in a multiroom zone)
var itemStandaloneExtensionName = \"_StandAlone\";
//Coordinator item extension (displays the master of this zone)
var itemMasterExtensionName = \"_Master\";
I have no Idea where is the fault…
I think the Rule is not running an action…
But why? You have an Idea.
Openhab 3.2.0M1 in Docker auf Synology
Thanks
Danke
Stefan
buschif4
(Flo)
September 4, 2021, 6:04pm
55
@vally your issue is located in the propZoneArray. It is not correct formated.
The correct formating would be
propZoneArray: '[“Kueche”; “SonosOneKuche_Fernbedienung”;
“SonosOneKuche_Lautstarke”; “SonosOneKuche_Master”][“Bad”;
“SonosOneBad_Fernbedienung”; “SonosOneBad_Lautstarke”;
“SonosOneBad_Master”]'
Hello
Is it somehow possible to import the widget into the habpanel?
Or could this be adapted with little effort?
syntacrsc
(Ralph Schnarkowski)
December 8, 2021, 4:28pm
57
Hi thanks for the beautiful widget.
I allowed myself to add some additional features:
Loudness on/off
Mute on/off
base slider
treble slider
up to 4 InTunes Radion stations
up to 4 Sonos Favorites
up to 4 Sonos Playlists
Display Sonos icon in case no albumart is available (you’ll need /static/sonos_logo.jpg)
Looks like this now:
Here’s the widget code in case anyone is interested:
uid: widget_Sonos_Player
tags: []
props:
parameters:
- description: (optional) widget title
label: (optional) widget title
name: propWidgetTitle
required: false
type: TEXT
- context: item
description: item to display the title
label: item title
name: itemTitle
required: true
type: TEXT
- context: item
description: (optional) item to display the album
label: (optional) item album
name: itemAlbum
required: false
type: TEXT
- context: item
description: (optional) item to display the artist
label: (optional) item artist
name: itemArtist
required: false
type: TEXT
- context: item
description: (optional) item to display a cover image
label: (optional) item cover image
name: itemCover
required: false
type: TEXT
- context: item
description: (optional) item to control the player
label: (optional) item player
name: itemPlayer
required: false
type: TEXT
- context: item
description: (optional) item to control the volume
label: (optional) item volume
name: itemVolume
required: false
type: TEXT
- context: item
description: (optional) item to control base
label: (optional) item base
name: itemBase
required: false
type: TEXT
- context: item
description: (optional) item to control treble
label: (optional) item treble
name: itemTreble
required: false
type: TEXT
- context: item
description: (optional) item to control loundness
label: (optional) item loudness
name: itemLoudness
required: false
type: TEXT
- context: item
description: (optional) item to control mute
label: (optional) item mute
name: itemMute
required: false
type: TEXT
- context: item
description: (optional) item for shuffle option
label: (optional) item shuffle
name: itemShuffle
required: false
type: TEXT
- context: item
description: (optional) item for repeat option
label: (optional) item repeat
name: itemRepeat
required: false
type: TEXT
- description: (optional) Name of the zone player
label: (optional) Zone name
name: propZoneName
required: false
type: TEXT
advanced: true
- context: item
description: (optional) item of the zone coordinator channel
label: (optional) item coordinator
name: itemCoordinator
required: false
type: TEXT
advanced: true
- description: (optional) speaker array like this -> ["<zoneName>", "<player>", "<volume>", "<coordinator>"]["<zoneName2>", "<player2>", "<volume2>", "<coordinator2>"]
label: (optional) speaker array
name: propZoneArray
required: false
type: TEXT
advanced: true
- context: item
description: (optional) item for the sonos mulltiroom rule. e.g. Sonos_Multiroom_Control
label: (optional) item to control the multiroom control rule
name: itemSonosRule
required: false
type: TEXT
advanced: true
- context: item
description: (optional) item to control the TuneinStations
label: (optional) item TuneinStation
name: itemTuneinStation
required: false
type: TEXT
- description: (optional) name of TuneinStation 1
label: (optional) TuneinStation 1
name: propTuneinStation1
required: false
type: TEXT
- description: (optional) name of TuneinStation 2
label: (optional) TuneinStation 2
name: propTuneinStation2
required: false
type: TEXT
- description: (optional) name of TuneinStation 3
label: (optional) TuneinStation 3
name: propTuneinStation3
required: false
type: TEXT
- description: (optional) name of TuneinStation 4
label: (optional) TuneinStation 4
name: propTuneinStation4
required: false
type: TEXT
- context: item
description: (optional) item to control the Favorites
label: (optional) item Favorite
name: itemFavorite
required: false
type: TEXT
- description: (optional) name of Favorite 1
label: (optional) Favorite 1
name: propFavorite1
required: false
type: TEXT
- description: (optional) name of Favorite 1 Icon
label: (optional) Favorite 1 Icon
name: propFavorite1IconUrl
required: false
type: TEXT
- description: (optional) name of Favorite 2
label: (optional) Favorite 2
name: propFavorite2
required: false
type: TEXT
- description: (optional) name of Favorite 2 Icon
label: (optional) Favorite 2 Icon
name: propFavorite2IconUrl
required: false
type: TEXT
- description: (optional) name of Favorite 3
label: (optional) Favorite 3
name: propFavorite3
required: false
type: TEXT
- description: (optional) name of Favorite 3 Icon
label: (optional) Favorite 3 Icon
name: propFavorite3IconUrl
required: false
type: TEXT
- description: (optional) name of Favorite 4
label: (optional) Favorite 4
name: propFavorite4
required: false
type: TEXT
- description: (optional) name of Favorite 4 Icon
label: (optional) Favorite 4 Icon
name: propFavorite4IconUrl
required: false
type: TEXT
- context: item
description: (optional) item to control the playlist
label: (optional) item playlist
name: itemPlaylist
required: false
type: TEXT
- description: (optional) name of playlist 1
label: (optional) playlist 1
name: propPlaylist1
required: false
type: TEXT
- description: (optional) name of playlist 1 Icon
label: (optional) playlist 1 Icon
name: propPlaylist1IconUrl
required: false
type: TEXT
- description: (optional) name of playlist 2
label: (optional) playlist 2
name: propPlaylist2
required: false
type: TEXT
- description: (optional) name of playlist 2 Icon
label: (optional) playlist 2 Icon
name: propPlaylist2IconUrl
required: false
type: TEXT
- description: (optional) name of playlist 3
label: (optional) playlist 3
name: propPlaylist3
required: false
type: TEXT
- description: (optional) name of playlist 3 Icon
label: (optional) playlist 3 Icon
name: propPlaylist3IconUrl
required: false
type: TEXT
- description: (optional) name of playlist 4
label: (optional) playlist 4
name: propPlaylist4
required: false
type: TEXT
- description: (optional) name of playlist 4 Icon
label: (optional) playlist 4 Icon
name: propPlaylist4IconUrl
required: false
type: TEXT
parameterGroups: []
timestamp: Dec 8, 2021, 5:09:24 PM
component: f7-card
config:
title: =props.propWidgetTitle
slots:
default:
- component: f7-card-content
slots:
default:
- component: f7-row
slots:
default:
- component: Label
config:
text: "Title: "
class:
- display-flex
- component: f7-row
config:
style:
position: relative
top: -10px
height: 30px
class:
- justify-content-center
slots:
default:
- component: Label
config:
text: =items[props.itemTitle].displayState || items[props.itemTitle].state
style:
fontSize: 28px
white-space: nowrap
overflow: hidden
- component: f7-row
config:
visible: "=(props.itemAlbum) ? true : false"
slots:
default:
- component: Label
config:
text: "Album: "
class:
- display-flex
- component: f7-row
config:
visible: "=(props.itemAlbum) ? true : false"
style:
position: relative
top: -10px
height: 30px
class:
- justify-content-center
slots:
default:
- component: Label
config:
text: =items[props.itemAlbum].displayState || items[props.itemAlbum].state
style:
fontSize: 28px
white-space: nowrap
overflow: hidden
- component: f7-row
config:
visible: "=(props.itemArtist) ? true : false"
slots:
default:
- component: Label
config:
text: "Artist: "
class:
- display-flex
- component: f7-row
config:
visible: "=(props.itemArtist) ? true : false"
style:
position: relative
top: -10px
height: 30px
class:
- justify-content-center
slots:
default:
- component: Label
config:
text: =items[props.itemArtist].displayState || items[props.itemArtist].state
style:
fontSize: 28px
white-space: nowrap
overflow: hidden
- component: f7-row
config:
class:
- margin-vertical
- justify-content-center
slots:
default:
- component: oh-image
config:
visible: '=( (props.itemCover) && items[props.itemCover].state !== "UNDEF") ? true : false'
item: =props.itemCover
style:
width: 70%
- component: oh-image
config:
visible: '=(!(props.itemCover) || items[props.itemCover].state === "UNDEF") ? true : false'
url: /static/sonos_logo.jpg
style:
width: 70%
- component: f7-row
config:
visible: "=(props.itemPlayer) ? true : false"
class:
- justify-content-space-around
- display-flex
- align-items-center
- align-content-stretch
- margin-top
style:
position: relative
top: +5px
slots:
default:
- component: f7-icon
config:
f7: '=(props.itemShuffle) ? "shuffle" : ""'
size: 20
color: '=(items[props.itemShuffle].state === "ON") ? "green" : ""'
style:
position: relative
left: +7%
slots:
default:
- component: oh-button
config:
action: command
actionItem: =props.itemShuffle
actionCommand: '=(items[props.itemShuffle].state !== "ON") ? "ON" : "OFF"'
style:
position: absolute
width: 100%
height: 100%
top: 0px
- component: oh-player-item
config:
style:
width: 150px
item: =props.itemPlayer
class:
- display-flex
- margin-
- align-content-stretch
- align-items-center
- justify-content-space-around
- component: f7-icon
config:
f7: '=(props.itemRepeat) ? (items[props.itemRepeat].state === "ALL") ? "repeat" : (items[props.itemRepeat].state === "ONE") ? "repeat_1" : "repeat" : ""'
size: 20
color: '=(items[props.itemRepeat].state === "ALL") ? "green" : (items[props.itemRepeat].state === "ONE") ? "green" : ""'
style:
position: relative
left: -8%
slots:
default:
- component: oh-button
config:
action: command
actionItem: =props.itemRepeat
actionCommand: '=(items[props.itemRepeat].state === "ALL") ? "ONE" : (items[props.itemRepeat].state === "ONE") ? "OFF": "ALL"'
style:
position: absolute
width: 100%
height: 100%
top: 0px
- component: f7-row
config:
visible: "=(props.itemVolume) ? true : false"
class:
- justify-content-space-around
- display-flex
- align-items-center
- align-content-stretch
slots:
default:
- component: f7-card
config:
noShadow: true
class: margin display-flex align-items-center
style:
fontSize: 20px
min-width: calc(100% - 20px)
slots:
default:
- component: oh-slider
config:
label: true
scale: true
style:
height: +40px
width: calc(100% - 35px)
min: 0
item: =props.itemVolume
class:
- display-flex
- margin-horizontal
- align-content-stretch
- align-items-center
- justify-content-space-around
- component: f7-button
config:
class: '=(props.propZoneArray) ? "" : "display-none"'
style:
position: absolute
height: 100%
width: 100%
top: 0px
popoverOpen: .popoverVolume
slots:
default:
- component: f7-popover
config:
class: popoverVolume
style:
min-width: 350px
slots:
default:
- component: oh-repeater
config:
for: zoneVolume
in: =props.propZoneArray.split("]")
containerClasses:
- display-flex
- flex-direction-column
slots:
default:
- component: f7-card
config:
class: '=(loop.zoneVolume.split("\"")[1] && items[loop.zoneVolume.split("\"")[7]].state === items[props.itemCoordinator].state) ? "display-flex flex-direction-row justify-content-flex-start align-items-center" : "display-none"'
style:
height: 40px
slots:
default:
- component: Label
config:
style:
fontSize: 20px
class:
- margin-left
text: =(loop.zoneVolume.split("\"")[1])
- component: oh-slider
config:
label: true
style:
height: +40px
width: calc(100% - 40%)
min: 0
item: =(loop.zoneVolume.split("\"")[5])
class:
- display-flex
- margin
- align-content-stretch
- align-items-center
- component: f7-icon
config:
visible: "=(props.itemMute) ? true : false"
f7: '=(items[props.itemMute].state !== "ON") ? "speaker_3" : "speaker_slash"'
class: margin-horizontal margin
size: 30
slots:
default:
- component: oh-button
config:
action: command
actionItem: =props.itemMute
actionCommand: '=(items[props.itemMute].state !== "ON") ? "ON" : "OFF"'
style:
position: absolute
width: 100%
height: 100%
top: 0px
- component: f7-row
config:
visible: "=(props.itemBase || props.itemTreble) ? true : false"
class:
- justify-content-space-around
- display-flex
- align-items-center
- align-content-stretch
slots:
default:
- component: f7-card
config:
noShadow: true
class: margin display-flex align-items-center
style:
fontSize: 20px
min-width: calc(100% - 20px)
slots:
default:
- component: oh-slider
config:
visible: "=(props.itemTreble) ? true : false"
label: true
scale: true
min: -10
max: 10
scaleSteps: 10
scaleSubSteps: 1
style:
height: +40px
width: calc(100% - 35px)
item: =props.itemTreble
class:
- display-flex
- margin-horizontal
- align-content-stretch
- align-items-center
- justify-content-space-around
- component: oh-slider
config:
visible: "=(props.itemBase) ? true : false"
label: true
scale: true
min: -10
max: 10
scaleSteps: 10
scaleSubSteps: 1
style:
height: +40px
width: calc(100% - 35px)
item: =props.itemBase
class:
- display-flex
- margin-horizontal
- align-content-stretch
- align-items-center
- justify-content-space-around
- component: f7-icon
config:
visible: "=(props.itemLoudness) ? true : false"
f7: '=(items[props.itemLoudness].state !== "ON") ? "speaker" : "speaker_3_fill"'
class: margin-horizontal margin
size: 30
slots:
default:
- component: oh-button
config:
action: command
actionItem: =props.itemLoudness
actionCommand: '=(items[props.itemLoudness].state !== "ON") ? "ON" : "OFF"'
style:
position: absolute
width: 100%
height: 100%
top: 0px
- component: f7-row
config:
visible: "=(props.itemTuneinStation) ? true : false"
class:
- margin-vertical
- justify-content-center
slots:
default:
- component: f7-col
config:
width: auto
slots:
default:
- component: oh-image
config:
visible: '=(props.propsTuneinStation1 !== "UNDEF") ? true : false'
url: =('https://cdn-radiotime-logos.tunein.com/s' + props.propTuneinStation1 + 'q.png')
action: command
actionItem: =props.itemTuneinStation
actionCommand: =props.propTuneinStation1
style:
width: 80%
- component: f7-col
config:
width: auto
slots:
default:
- component: oh-image
config:
visible: '=(props.propsTuneinStation2 !== "UNDEF") ? true : false'
url: =('https://cdn-radiotime-logos.tunein.com/s' + props.propTuneinStation2 + 'q.png')
action: command
actionItem: =props.itemTuneinStation
actionCommand: =props.propTuneinStation2
style:
width: 80%
- component: f7-col
config:
width: auto
slots:
default:
- component: oh-image
config:
visible: '=(props.propsTuneinStation4 !== "UNDEF") ? true : false'
url: =('https://cdn-radiotime-logos.tunein.com/s' + props.propTuneinStation3 + 'q.png')
action: command
actionItem: =props.itemTuneinStation
actionCommand: =props.propTuneinStation3
style:
width: 80%
- component: f7-col
config:
width: auto
slots:
default:
- component: oh-image
config:
visible: '=(props.propsTuneinStation4 !== "UNDEF") ? true : false'
url: =('https://cdn-radiotime-logos.tunein.com/s' + props.propTuneinStation4 + 'q.png')
action: command
actionItem: =props.itemTuneinStation
actionCommand: =props.propTuneinStation4
style:
width: 80%
- component: f7-row
config:
visible: "=(props.itemFavorite) ? true : false"
class:
- margin-vertical
- justify-content-center
slots:
default:
- component: f7-col
config:
visible: '=(props.propsFavorite1Url !== "UNDEF") ? true : false'
width: auto
slots:
default:
- component: oh-image
config:
url: =props.propFavorite1IconUrl
action: command
actionItem: =props.itemFavorite
actionCommand: =props.propFavorite1
style:
width: 80%
- component: f7-col
config:
visible: '=(props.propsFavorite2Url !== "UNDEF") ? true : false'
width: auto
slots:
default:
- component: oh-image
config:
url: =props.propFavorite2IconUrl
action: command
actionItem: =props.itemFavorite
actionCommand: =props.propFavorite2
style:
width: 80%
- component: f7-col
config:
visible: '=(props.propsFavorite3Url !== "UNDEF") ? true : false'
width: auto
slots:
default:
- component: oh-image
config:
visible: '=(props.propsFavorite4Url !== "UNDEF") ? true : false'
url: =props.propFavorite3IconUrl
action: command
actionItem: =props.itemFavorite
actionCommand: =props.propFavorite3
style:
width: 80%
- component: f7-col
config:
visible: '=(props.propsFavorite4Url !== "UNDEF") ? true : false'
width: auto
slots:
default:
- component: oh-image
config:
visible: '=(props.propsFavorite4Url !== "UNDEF") ? true : false'
url: =props.propFavorite4IconUrl
action: command
actionItem: =props.itemFavorite
actionCommand: =props.propFavorite4
style:
width: 80%
- component: f7-row
config:
visible: "=(props.itemPlaylist) ? true : false"
class:
- margin-vertical
- justify-content-center
slots:
default:
- component: f7-col
config:
width: auto
slots:
default:
- component: oh-image
config:
visible: '=(props.propsPlaylist1Url !== "UNDEF") ? true : false'
url: =props.propPlaylist1IconUrl
action: command
actionItem: =props.itemPlaylist
actionCommand: =props.propPlaylist1
style:
width: 80%
- component: f7-col
config:
width: auto
slots:
default:
- component: oh-image
config:
visible: '=(props.propsPlaylist2Url !== "UNDEF") ? true : false'
url: =props.propPlaylist2IconUrl
action: command
actionItem: =props.itemPlaylist
actionCommand: =props.propPlaylist2
style:
width: 80%
- component: f7-col
config:
width: auto
slots:
default:
- component: oh-image
config:
visible: '=(props.propsPlaylist3Url !== "UNDEF") ? true : false'
url: =props.propPlaylist3IconUrl
action: command
actionItem: =props.itemPlaylist
actionCommand: =props.propPlaylist3
style:
width: 80%
- component: f7-col
config:
width: auto
slots:
default:
- component: oh-image
config:
visible: '=(props.propsPlaylist4Url !== "UNDEF") ? true : false'
url: =props.propPlaylist4IconUrl
action: command
actionItem: =props.itemPlaylist
actionCommand: =props.propPlaylist4
style:
width: 80%
- component: f7-row
config:
class: '=(props.propZoneName && props.itemPlayer) ? "justify-content-space-around align-items-center align-content-stretch" : "display-none"'
style:
position: relative
top: -26px
height: 50px
slots:
default:
- component: f7-card
config:
noShadow: true
class: display-flex align-items-center
style:
fontSize: 20px
min-width: 130px
slots:
default:
- component: f7-icon
config:
f7: hifispeaker
size: 30
class: margin
- component: Label
config:
class: margin-right
text: =props.propZoneName
style:
fontSize: 20px
- component: f7-icon
config:
f7: '=(items[props.itemPlayer].state === "PLAY") ? "chart_bar_alt_fill" : ""'
class: margin-right
size: 20
- component: f7-button
config:
class: '=(props.propZoneArray) ? "" : "display-none"'
style:
position: absolute
height: 100%
width: 100%
top: 0px
popoverOpen: .popoverPlayer
slots:
default:
- component: f7-popover
config:
class: popoverPlayer
style:
min-width: 280px
slots:
default:
- component: oh-repeater
config:
for: zoneSpeaker
in: =props.propZoneArray.split("]")
containerClasses:
- display-flex
- flex-direction-column
slots:
default:
- component: f7-card
config:
class: '=(loop.zoneSpeaker.split("\"")[1]) ? "display-flex flex-direction-row align-items-center" : "display-none"'
style:
height: 40px
slots:
default:
- component: oh-button
config:
style:
position: absolute
top: 0px
width: 100%
height: 100%
action: command
actionItem: =props.itemSonosRule
actionCommand: '=(items[loop.zoneSpeaker.split("\"")[7]].state === items[props.itemCoordinator].state) ? "Remove:" + loop.zoneSpeaker.split("\"")[1] + "" : "Add:" + loop.zoneSpeaker.split("\"")[1] + "@" + props.propZoneName'
- component: f7-col
config:
class: margin display-flex flex-direction-row align-items-center
slots:
default:
- component: f7-icon
config:
f7: '=(items[loop.zoneSpeaker.split("\"")[7]].state === items[props.itemCoordinator].state) ? "checkmark_alt_circle_fill" : "circle"'
- component: Label
config:
class: margin-left
text: =loop.zoneSpeaker.split("\"")[1]
style:
fontSize: 20px
- component: f7-col
config:
class: margin align-items-center
slots:
default:
- component: f7-icon
config:
f7: '=(items[loop.zoneSpeaker.split("\"")[3]].state === "PLAY") ? "chart_bar_alt_fill" : ""'
Here’s the Sonos Logo jpg:
P.S.: I did not test this version with the ZoneArray logic though (didn’t understand it yet )…
1 Like
syntacrsc
(Ralph Schnarkowski)
December 8, 2021, 4:32pm
58
@Carlo_Caprez :
As far as I know there’s no way of importing OH3 widgets into habpanel but if you are looking for a Sonos Control for habpanel take a look at this post (I just posted an update of the habpanel sonos controller recently):
Beeing a complete html novice I found a post in this community by Christian for a custom built SONOS
HabPanel template.
original post by Christian
The post inspired me to learn about html and improve Christian’s template, I happily share those back to you.
The template now includes the following changes/improvements:
icon size is now more responsive (scales fitting to handhelds and PC-screens)
play/pause button do toggle - so you can see whether it’s playing or not
using sonos favorites
us…
syntacrsc
(Ralph Schnarkowski)
December 9, 2021, 12:10pm
59
I took a look at the ZoneArray logic and decided it’s too complicated for the limited capabilities of my brain so I tweaked the widget code to work w/o the scripts/rules (some minor draw backs though - see below).
The grouping/ungrouping can be done by simply clicking an item in the list (not sure if that already was the case before)
Some drawback/prerequisites though:
The item for making a speaker “standalone” (Sonos “standalone” channel - to remove it from a group) needs to follow this naming convention:
Sonos_<zone_name>_Standalone
Example: for a Zone named “Buero” the standalone-item would need to be named:
Sonos_Buero_Standalone
Alternatively you can adjust the widget code (line 861) to fit your naming convention for standalone items:
No automatic ungrouping for inactive speakers in a group
No more default uri to play on all speakers of a group
here’s the updated widget code:
uid: widget_Sonos_Player
tags: []
props:
parameters:
- description: (optional) widget title
label: (optional) widget title
name: propWidgetTitle
required: false
type: TEXT
- context: item
description: item to display the title
label: item title
name: itemTitle
required: true
type: TEXT
- context: item
description: (optional) item to display the album
label: (optional) item album
name: itemAlbum
required: false
type: TEXT
- context: item
description: (optional) item to display the artist
label: (optional) item artist
name: itemArtist
required: false
type: TEXT
- context: item
description: (optional) item to display a cover image
label: (optional) item cover image
name: itemCover
required: false
type: TEXT
- context: item
description: (optional) item to control the player
label: (optional) item player
name: itemPlayer
required: false
type: TEXT
- context: item
description: (optional) item to control the volume
label: (optional) item volume
name: itemVolume
required: false
type: TEXT
- context: item
description: (optional) item to control base
label: (optional) item base
name: itemBase
required: false
type: TEXT
- context: item
description: (optional) item to control treble
label: (optional) item treble
name: itemTreble
required: false
type: TEXT
- context: item
description: (optional) item to control loundness
label: (optional) item loudness
name: itemLoudness
required: false
type: TEXT
- context: item
description: (optional) item to control mute
label: (optional) item mute
name: itemMute
required: false
type: TEXT
- context: item
description: (optional) item for shuffle option
label: (optional) item shuffle
name: itemShuffle
required: false
type: TEXT
- context: item
description: (optional) item for repeat option
label: (optional) item repeat
name: itemRepeat
required: false
type: TEXT
- description: (optional) Name of the zone player
label: (optional) Zone name
name: propZoneName
required: false
type: TEXT
advanced: true
- context: item
description: (optional) item of the zone coordinator channel
label: (optional) item coordinator
name: itemCoordinator
required: false
type: TEXT
advanced: true
- description: (optional) speaker array like this -> ["<zoneName>", "<player>", "<volume>", "<coordinator>"]["<zoneName2>", "<player2>", "<volume2>", "<coordinator2>"]
label: (optional) speaker array
name: propZoneArray
required: false
type: TEXT
advanced: true
- context: item
description: (optional) item for the sonos mulltiroom rule. e.g. Sonos_Multiroom_Control
label: (optional) item to control the multiroom control rule
name: itemSonosRule
required: false
type: TEXT
advanced: true
- context: item
description: (optional) item for the adding another zone
label: (optional) item to add another zone
name: itemAdd
required: false
type: TEXT
advanced: true
- context: item
description: (optional) item to control the TuneinStations
label: (optional) item TuneinStation
name: itemTuneinStation
required: false
type: TEXT
- description: (optional) name of TuneinStation 1
label: (optional) TuneinStation 1
name: propTuneinStation1
required: false
type: TEXT
- description: (optional) name of TuneinStation 2
label: (optional) TuneinStation 2
name: propTuneinStation2
required: false
type: TEXT
- description: (optional) name of TuneinStation 3
label: (optional) TuneinStation 3
name: propTuneinStation3
required: false
type: TEXT
- description: (optional) name of TuneinStation 4
label: (optional) TuneinStation 4
name: propTuneinStation4
required: false
type: TEXT
- context: item
description: (optional) item to control the Favorites
label: (optional) item Favorite
name: itemFavorite
required: false
type: TEXT
- description: (optional) name of Favorite 1
label: (optional) Favorite 1
name: propFavorite1
required: false
type: TEXT
- description: (optional) name of Favorite 1 Icon
label: (optional) Favorite 1 Icon
name: propFavorite1IconUrl
required: false
type: TEXT
- description: (optional) name of Favorite 2
label: (optional) Favorite 2
name: propFavorite2
required: false
type: TEXT
- description: (optional) name of Favorite 2 Icon
label: (optional) Favorite 2 Icon
name: propFavorite2IconUrl
required: false
type: TEXT
- description: (optional) name of Favorite 3
label: (optional) Favorite 3
name: propFavorite3
required: false
type: TEXT
- description: (optional) name of Favorite 3 Icon
label: (optional) Favorite 3 Icon
name: propFavorite3IconUrl
required: false
type: TEXT
- description: (optional) name of Favorite 4
label: (optional) Favorite 4
name: propFavorite4
required: false
type: TEXT
- description: (optional) name of Favorite 4 Icon
label: (optional) Favorite 4 Icon
name: propFavorite4IconUrl
required: false
type: TEXT
- context: item
description: (optional) item to control the playlist
label: (optional) item playlist
name: itemPlaylist
required: false
type: TEXT
- description: (optional) name of playlist 1
label: (optional) playlist 1
name: propPlaylist1
required: false
type: TEXT
- description: (optional) name of playlist 1 Icon
label: (optional) playlist 1 Icon
name: propPlaylist1IconUrl
required: false
type: TEXT
- description: (optional) name of playlist 2
label: (optional) playlist 2
name: propPlaylist2
required: false
type: TEXT
- description: (optional) name of playlist 2 Icon
label: (optional) playlist 2 Icon
name: propPlaylist2IconUrl
required: false
type: TEXT
- description: (optional) name of playlist 3
label: (optional) playlist 3
name: propPlaylist3
required: false
type: TEXT
- description: (optional) name of playlist 3 Icon
label: (optional) playlist 3 Icon
name: propPlaylist3IconUrl
required: false
type: TEXT
- description: (optional) name of playlist 4
label: (optional) playlist 4
name: propPlaylist4
required: false
type: TEXT
- description: (optional) name of playlist 4 Icon
label: (optional) playlist 4 Icon
name: propPlaylist4IconUrl
required: false
type: TEXT
parameterGroups: []
timestamp: Dec 9, 2021, 12:44:31 PM
component: f7-card
config:
title: =props.propWidgetTitle
slots:
default:
- component: f7-card-content
slots:
default:
- component: f7-row
slots:
default:
- component: Label
config:
text: "Title: "
class:
- display-flex
- component: f7-row
config:
style:
position: relative
top: -10px
height: 30px
class:
- justify-content-center
slots:
default:
- component: Label
config:
text: =items[props.itemTitle].displayState || items[props.itemTitle].state
style:
fontSize: 28px
white-space: nowrap
overflow: hidden
- component: f7-row
config:
visible: "=(props.itemAlbum) ? true : false"
slots:
default:
- component: Label
config:
text: "Album: "
class:
- display-flex
- component: f7-row
config:
visible: "=(props.itemAlbum) ? true : false"
style:
position: relative
top: -10px
height: 30px
class:
- justify-content-center
slots:
default:
- component: Label
config:
text: =items[props.itemAlbum].displayState || items[props.itemAlbum].state
style:
fontSize: 28px
white-space: nowrap
overflow: hidden
- component: f7-row
config:
visible: "=(props.itemArtist) ? true : false"
slots:
default:
- component: Label
config:
text: "Artist: "
class:
- display-flex
- component: f7-row
config:
visible: "=(props.itemArtist) ? true : false"
style:
position: relative
top: -10px
height: 30px
class:
- justify-content-center
slots:
default:
- component: Label
config:
text: =items[props.itemArtist].displayState || items[props.itemArtist].state
style:
fontSize: 28px
white-space: nowrap
overflow: hidden
- component: f7-row
config:
class:
- margin-vertical
- justify-content-center
slots:
default:
- component: oh-image
config:
visible: '=( (props.itemCover) && items[props.itemCover].state !== "UNDEF") ? true : false'
item: =props.itemCover
style:
width: 70%
- component: oh-image
config:
visible: '=(!(props.itemCover) || items[props.itemCover].state === "UNDEF") ? true : false'
url: /static/sonos_logo.jpg
style:
width: 70%
- component: f7-row
config:
visible: "=(props.itemPlayer) ? true : false"
class:
- justify-content-space-around
- display-flex
- align-items-center
- align-content-stretch
- margin-top
style:
position: relative
top: +5px
slots:
default:
- component: f7-icon
config:
f7: '=(props.itemShuffle) ? "shuffle" : ""'
size: 20
color: '=(items[props.itemShuffle].state === "ON") ? "green" : ""'
style:
position: relative
left: +7%
slots:
default:
- component: oh-button
config:
action: command
actionItem: =props.itemShuffle
actionCommand: '=(items[props.itemShuffle].state !== "ON") ? "ON" : "OFF"'
style:
position: absolute
width: 100%
height: 100%
top: 0px
- component: oh-player-item
config:
style:
width: 150px
item: =props.itemPlayer
class:
- display-flex
- margin-
- align-content-stretch
- align-items-center
- justify-content-space-around
- component: f7-icon
config:
f7: '=(props.itemRepeat) ? (items[props.itemRepeat].state === "ALL") ? "repeat" : (items[props.itemRepeat].state === "ONE") ? "repeat_1" : "repeat" : ""'
size: 20
color: '=(items[props.itemRepeat].state === "ALL") ? "green" : (items[props.itemRepeat].state === "ONE") ? "green" : ""'
style:
position: relative
left: -8%
slots:
default:
- component: oh-button
config:
action: command
actionItem: =props.itemRepeat
actionCommand: '=(items[props.itemRepeat].state === "ALL") ? "ONE" : (items[props.itemRepeat].state === "ONE") ? "OFF": "ALL"'
style:
position: absolute
width: 100%
height: 100%
top: 0px
- component: f7-row
config:
visible: "=(props.itemVolume) ? true : false"
class:
- justify-content-space-around
- display-flex
- align-items-center
- align-content-stretch
slots:
default:
- component: f7-card
config:
noShadow: true
class: margin display-flex align-items-center
style:
fontSize: 20px
min-width: calc(100% - 20px)
slots:
default:
- component: oh-slider
config:
label: true
scale: true
style:
height: +40px
width: calc(100% - 35px)
min: 0
item: =props.itemVolume
class:
- display-flex
- margin-horizontal
- align-content-stretch
- align-items-center
- justify-content-space-around
- component: f7-button
config:
class: '=(props.propZoneArray) ? "" : "display-none"'
style:
position: absolute
height: 100%
width: 100%
top: 0px
popoverOpen: .popoverVolume
slots:
default:
- component: f7-popover
config:
class: popoverVolume
style:
min-width: 350px
slots:
default:
- component: oh-repeater
config:
for: zoneVolume
in: =props.propZoneArray.split("]")
containerClasses:
- display-flex
- flex-direction-column
slots:
default:
- component: f7-card
config:
class: '=(loop.zoneVolume.split("\"")[1] && items[loop.zoneVolume.split("\"")[7]].state === items[props.itemCoordinator].state) ? "display-flex flex-direction-row justify-content-flex-start align-items-center" : "display-none"'
style:
height: 40px
slots:
default:
- component: Label
config:
style:
fontSize: 20px
class:
- margin-left
text: =(loop.zoneVolume.split("\"")[1])
- component: oh-slider
config:
label: true
style:
height: +40px
width: calc(100% - 40%)
min: 0
item: =(loop.zoneVolume.split("\"")[5])
class:
- display-flex
- margin
- align-content-stretch
- align-items-center
- component: f7-icon
config:
visible: "=(props.itemMute) ? true : false"
f7: '=(items[props.itemMute].state !== "ON") ? "speaker_3" : "speaker_slash"'
color: '=(items[props.itemMute].state === "ON") ? "green" : ""'
class: margin-horizontal margin
size: 30
slots:
default:
- component: oh-button
config:
action: command
actionItem: =props.itemMute
actionCommand: '=(items[props.itemMute].state !== "ON") ? "ON" : "OFF"'
style:
position: absolute
width: 100%
height: 100%
top: 0px
- component: f7-row
config:
visible: "=(props.itemBase || props.itemTreble) ? true : false"
class:
- justify-content-space-around
- display-flex
- align-items-center
- align-content-stretch
slots:
default:
- component: f7-card
config:
noShadow: true
class: margin display-flex align-items-center
style:
fontSize: 20px
min-width: calc(100% - 20px)
slots:
default:
- component: oh-slider
config:
visible: "=(props.itemTreble) ? true : false"
label: true
scale: true
min: -10
max: 10
scaleSteps: 10
scaleSubSteps: 1
style:
height: +40px
width: calc(100% - 35px)
item: =props.itemTreble
class:
- display-flex
- margin-horizontal
- align-content-stretch
- align-items-center
- justify-content-space-around
- component: oh-slider
config:
visible: "=(props.itemBase) ? true : false"
label: true
scale: true
min: -10
max: 10
scaleSteps: 10
scaleSubSteps: 1
style:
height: +40px
width: calc(100% - 35px)
item: =props.itemBase
class:
- display-flex
- margin-horizontal
- align-content-stretch
- align-items-center
- justify-content-space-around
- component: f7-icon
config:
visible: "=(props.itemLoudness) ? true : false"
f7: '=(items[props.itemLoudness].state !== "ON") ? "speaker" : "speaker_3_fill"'
color: '=(items[props.itemLoudness].state === "ON") ? "green" : ""'
class: margin-horizontal margin
size: 30
slots:
default:
- component: oh-button
config:
action: command
actionItem: =props.itemLoudness
actionCommand: '=(items[props.itemLoudness].state !== "ON") ? "ON" : "OFF"'
style:
position: absolute
width: 100%
height: 100%
top: 0px
- component: f7-row
config:
visible: "=(props.itemTuneinStation) ? true : false"
class:
- margin-vertical
- justify-content-center
slots:
default:
- component: f7-col
config:
width: auto
slots:
default:
- component: oh-image
config:
visible: '=(props.propsTuneinStation1 !== "UNDEF") ? true : false'
url: =('https://cdn-radiotime-logos.tunein.com/s' + props.propTuneinStation1 + 'q.png')
action: command
actionItem: =props.itemTuneinStation
actionCommand: =props.propTuneinStation1
style:
width: 80%
- component: f7-col
config:
width: auto
slots:
default:
- component: oh-image
config:
visible: '=(props.propsTuneinStation2 !== "UNDEF") ? true : false'
url: =('https://cdn-radiotime-logos.tunein.com/s' + props.propTuneinStation2 + 'q.png')
action: command
actionItem: =props.itemTuneinStation
actionCommand: =props.propTuneinStation2
style:
width: 80%
- component: f7-col
config:
width: auto
slots:
default:
- component: oh-image
config:
visible: '=(props.propsTuneinStation4 !== "UNDEF") ? true : false'
url: =('https://cdn-radiotime-logos.tunein.com/s' + props.propTuneinStation3 + 'q.png')
action: command
actionItem: =props.itemTuneinStation
actionCommand: =props.propTuneinStation3
style:
width: 80%
- component: f7-col
config:
width: auto
slots:
default:
- component: oh-image
config:
visible: '=(props.propsTuneinStation4 !== "UNDEF") ? true : false'
url: =('https://cdn-radiotime-logos.tunein.com/s' + props.propTuneinStation4 + 'q.png')
action: command
actionItem: =props.itemTuneinStation
actionCommand: =props.propTuneinStation4
style:
width: 80%
- component: f7-row
config:
visible: "=(props.itemFavorite) ? true : false"
class:
- margin-vertical
- justify-content-center
slots:
default:
- component: f7-col
config:
visible: '=(props.propsFavorite1Url !== "UNDEF") ? true : false'
width: auto
slots:
default:
- component: oh-image
config:
url: =props.propFavorite1IconUrl
action: command
actionItem: =props.itemFavorite
actionCommand: =props.propFavorite1
style:
width: 80%
- component: f7-col
config:
visible: '=(props.propsFavorite2Url !== "UNDEF") ? true : false'
width: auto
slots:
default:
- component: oh-image
config:
url: =props.propFavorite2IconUrl
action: command
actionItem: =props.itemFavorite
actionCommand: =props.propFavorite2
style:
width: 80%
- component: f7-col
config:
visible: '=(props.propsFavorite3Url !== "UNDEF") ? true : false'
width: auto
slots:
default:
- component: oh-image
config:
visible: '=(props.propsFavorite4Url !== "UNDEF") ? true : false'
url: =props.propFavorite3IconUrl
action: command
actionItem: =props.itemFavorite
actionCommand: =props.propFavorite3
style:
width: 80%
- component: f7-col
config:
visible: '=(props.propsFavorite4Url !== "UNDEF") ? true : false'
width: auto
slots:
default:
- component: oh-image
config:
visible: '=(props.propsFavorite4Url !== "UNDEF") ? true : false'
url: =props.propFavorite4IconUrl
action: command
actionItem: =props.itemFavorite
actionCommand: =props.propFavorite4
style:
width: 80%
- component: f7-row
config:
visible: "=(props.itemPlaylist) ? true : false"
class:
- margin-vertical
- justify-content-center
slots:
default:
- component: f7-col
config:
width: auto
slots:
default:
- component: oh-image
config:
visible: '=(props.propsPlaylist1Url !== "UNDEF") ? true : false'
url: =props.propPlaylist1IconUrl
action: command
actionItem: =props.itemPlaylist
actionCommand: =props.propPlaylist1
style:
width: 80%
- component: f7-col
config:
width: auto
slots:
default:
- component: oh-image
config:
visible: '=(props.propsPlaylist2Url !== "UNDEF") ? true : false'
url: =props.propPlaylist2IconUrl
action: command
actionItem: =props.itemPlaylist
actionCommand: =props.propPlaylist2
style:
width: 80%
- component: f7-col
config:
width: auto
slots:
default:
- component: oh-image
config:
visible: '=(props.propsPlaylist3Url !== "UNDEF") ? true : false'
url: =props.propPlaylist3IconUrl
action: command
actionItem: =props.itemPlaylist
actionCommand: =props.propPlaylist3
style:
width: 80%
- component: f7-col
config:
width: auto
slots:
default:
- component: oh-image
config:
visible: '=(props.propsPlaylist4Url !== "UNDEF") ? true : false'
url: =props.propPlaylist4IconUrl
action: command
actionItem: =props.itemPlaylist
actionCommand: =props.propPlaylist4
style:
width: 80%
- component: f7-row
config:
class: '=(props.propZoneName && props.itemPlayer) ? "justify-content-space-around align-items-center align-content-stretch" : "display-none"'
style:
position: relative
top: -26px
height: 50px
slots:
default:
- component: f7-card
config:
noShadow: true
class: display-flex align-items-center
style:
fontSize: 20px
min-width: 130px
slots:
default:
- component: f7-icon
config:
f7: hifispeaker
size: 30
class: margin
- component: Label
config:
class: margin-right
text: =props.propZoneName
style:
fontSize: 20px
- component: f7-icon
config:
f7: '=(items[props.itemPlayer].state === "PLAY") ? "chart_bar_alt_fill" : ""'
class: margin-right
size: 20
- component: f7-button
config:
class: '=(props.propZoneArray) ? "" : "display-none"'
style:
position: absolute
height: 100%
width: 100%
top: 0px
popoverOpen: .popoverPlayer
slots:
default:
- component: f7-popover
config:
class: popoverPlayer
style:
min-width: 280px
slots:
default:
- component: oh-repeater
config:
for: zoneSpeaker
in: =props.propZoneArray.split("]")
containerClasses:
- display-flex
- flex-direction-column
slots:
default:
- component: f7-card
config:
class: '=(loop.zoneSpeaker.split("\"")[1]) ? "display-flex flex-direction-row align-items-center" : "display-none"'
style:
height: 40px
slots:
default:
- component: oh-button
config:
style:
position: absolute
top: 0px
width: 100%
height: 100%
action: command
actionItem: '=(items[loop.zoneSpeaker.split("\"")[7]].state === items[props.itemCoordinator].state) ? ("Sonos_" + (loop.zoneSpeaker.split("\"")[1]) + "_Standalone") : props.itemAdd'
actionCommand: '=(items[loop.zoneSpeaker.split("\"")[7]].state === items[props.itemCoordinator].state) ? "ON" : (loop.zoneSpeaker.split("\"")[1])'
- component: f7-col
config:
class: margin display-flex flex-direction-row align-items-center
slots:
default:
- component: f7-icon
config:
f7: '=(items[loop.zoneSpeaker.split("\"")[7]].state === items[props.itemCoordinator].state) ? "checkmark_alt_circle_fill" : "circle"'
- component: Label
config:
class: margin-left
text: =loop.zoneSpeaker.split("\"")[1]
style:
fontSize: 20px
- component: f7-col
config:
class: margin align-items-center
slots:
default:
- component: f7-icon
config:
f7: '=(items[loop.zoneSpeaker.split("\"")[3]].state === "PLAY") ? "chart_bar_alt_fill" : ""'
AldoHa
(Aldo)
January 15, 2023, 6:33pm
60
Hi Folks hope I can get some advise;
@buschif4
So from the example for the speaker array mine looks like this, added in the settings in the widget
[“Sonos Keuken”; “Sonos_Keuken_Player”; “Sonos_Keuken_Volume”; “Sonos_Keuken_Coordinator”][“Sonos Slaapkamer”; “Sonos_Slaapkamer_player”; “Sonos_Slaapkamer_Volume”; “Sonos_Slaapkamer_Coordinator”]
But it ends up in the YAML as like this;
propZoneArray: "[“Sonos_Keuken”; “Sonos_Keuken_Player”; “Sonos_Keuken_Volume”;
“Sonos_Keuken_Coordinator”][“Sonos_Slaapkamer”; “Sonos_Slaapkamer_player”;
“Sonos_Slaapkamer_Volume”; “Sonos_Slaapkamer_Coordinator”]"
As I am not able to get the multizone working I read it needs to be in single ’ ’
But whatever I tried, every time it is being saved it is changed to double quote.
Can this also be the WARN " Attempting to send a state update of an item which doesn't exist: undefined
."
Adding the array in the widget and saving it;
Checking the YAML it shows as following;
Modifying it to single in the YAML
Saving it and it is back with double as saving it from the GUI
And would be great if you can advise me as this is the last part from my migration from OH2 to OH3 and it drives me mad
Thanks already,
Aldo