Sonos im Tablet UI - Beispielkonfiguration

Begonnen von Sturi2011, 12 Dezember 2016, 23:23:19

Vorheriges Thema - Nächstes Thema

l2r

schaut euch mal den WIKI-Eintrag zu Sonos an. Da wurde eine Beispiel-Config ergänzt.

Gruß Michael
Wissen ist Macht.
Ich weiß nix.
Macht nix.

eddtima

Hey Sturi2011,

super gemacht ich kann ja kaum verstehen, warum der Thread so wenig Beachtung findet. Ich finde, Du hast das super gelöst und endlich sieht die Sonos mal gelungen in der Tablet UI aus. Nicht zu gross, damit man einige Sonos-Zonen auf eine Seite bekommt und zudem ist auch noch das Problem mit dem Gruppieren gelöst - Chapeau - wirklich gelungen!

An alle, die noch mit den Ausrichtungsproblemen von Version 2.6 kämpfen: Lediglich die class="cell" am Ende der Buttons muss gegen class="inline" ausgetauscht werden. Das sieht das auch unter Tablet UI 2.6 wieder alles gut aus.

Noch eine Frage an Sturi2011: Hast Du irgendwo den Code für die "Group/Ungroup-Buttons" gepostet? Oder habe ich das einfach nur übersehen?

Vielen Dank für Deine Konfiguration!
FHEM auf Odroid N2, FTUI, etwa 110 Homematic Devices verschiedenster Coleur, BMWi3, Gardena, Hue, Sonos, Alexa, Harmony Hub, Samsung TV

Masterfunk

Zitat von: Sturi2011 am 30 Januar 2017, 17:33:01
Hi,

ich habe das Ganze mal auf möglichst wenige Readings am Dummy umgebaut.
Die Version enthält natürlich meinen Sonderwunsch mit der Current Playlist.
Das habe ich aber selbst in das Sonos Mudul eingepatcht.
Du musst das DIV mit dem FA-List Icon entfernen....oer per PN die gepatchte Version bekommen ;)

Gruß Andreas

Was hast Du den gemacht, um die CurrentPlayList zu erzeugen?

Gruß Detlef

Masterfunk

Habe das ganze nochmal überarbeitet (Basierend auf Reinerleins's Config).

Rechts oben wird beim Player noch folgendes angezeigt:
1. Status des Players
2. Status Power-Switch für Player
3. Aktueller "TrackProvider" mit entsprechenden Icons

Hier die Config Dateien:

template_music_sonos.html
<div class="top-space container cell row">
<div Class="col-3-4">

<div data-type="popup" data-width="45%" data-height="80%" class="inline">
<div data-type="image"
data-device="Device"
data-get="currentAlbumArtURL"
data-width="210px"
data-height="210px"
class="nocache">
</div>

<div class="dialog">
<header>Cover für Name</header>

<div data-type="switch"
data-device="Device"
data-get="transportState"
data-states='["PLAYING","PAUSED_PLAYBACK","STOPPED"]'
data-set-states='["Pause","Play","Play"]'
data-background-icon="-"
data-background-colors='["orange","white","white"]'
data-colors='["orange","white","white"]'
data-icons='["fa-play","fa-pause","fa-pause"]'
class="inline"
style="position: absolute; top: 25px; left: 5px;"
onclick="$('.dialog-close').trigger('click');">
</div>

<div data-type="image"
data-device="Device"
data-get="currentAlbumArtURL"
data-width="750px"
data-height="750px"
class="nocache"
onclick="$('.dialog-close').trigger('click');">
</div>

<div data-type="classchanger" data-device="Device" data-get="currentNormalAudio" data-get-on="1" data-get-off="0" data-off-class="hide">
<div data-type="slider"
data-device="Device"
data-get="currentTrackPositionSec"
data-max="currentTrackDurationSec" data-min="0"
data-step="1"
data-handle-diameter="5"
data-width="750px"
class="horizontal top-narrow readonly centered"></div>
</div>

<div data-type="classchanger" data-device="Device" data-get="currentNormalAudio" data-get-on="1" data-get-off="0" data-off-class="hide">
<div data-type="joinedlabel" data-device="Device" data-mask="[$1][ ~ $2][ ~ $3]" data-get='["currentTitle","currentArtist","currentAlbum"]' class="truncate top-space"></div>
</div>
<div data-type="classchanger" data-device="Device" data-get="currentStreamAudio" data-get-on="1" data-get-off="0" data-off-class="hide">
<div data-type="joinedlabel" data-device="Device" data-mask="[$1 ~ ][$2][: $3]" data-get='["currentSenderInfo","currentSender","currentSenderCurrent"]' class="truncate top-space"></div>
</div>
</div>
</div>
</div>

<div Class="col-1-4 top-align">
    <div class="sheet">
        <div class="row">

<div data-type="switch" data-device="Device"
     data-states='["appeared","initialized","disappeared"]'
data-icons='["fa-thumbs-o-up","fa-thumbs-o-down fa-blink","fa-thumbs-o-down"]'
data-background-icons='["-","-","-"]'
     data-colors='["#aa6900","#505050","#505050"]'
     class="readonly inline small top-align left-narrow">
</div>
<div data-type="switch" data-device="Switch"
     data-states='["on","off","set_on"]'
     data-set-states='["off","on","on"]'
data-icons='["fa-power-off","fa-power-off","fa-power-off fa-blink"]'
data-background-icons='["-","-","-"]'
     data-colors='["#aa6900","#505050","#aa6900"]'
     class="inline small top-align left-narrow">
</div>
<div data-type="symbol" data-device="Device" data-get="currentTrackProvider"
     data-states='["Spotify","Bibliothek","Radio","Gruppenwiedergabe:.*",""]'
     data-icons='["fa-spotify","oa-it_nas","oa-it_radio","fa-object-group","fa-question"]'
     data-colors='["green","orange","orange","orange","red"]'
class="inline small top-align left-narrow" ></div>
</div>
</div>



<br>
   <div data-type="label" class="inline" >Titel</div>
<div data-type="label" class="inline" data-device="Device" data-get="currentTrack"></div>
<div data-type="label" class="inline" >von</div>
   <div data-type="label" class="inline" data-device="Device" data-get="numberOfTracks"></div>
<br>
<br>
<div data-type="classchanger" data-device="Device" data-get="nextAlbumArtURL" data-get-on="/fhem/sonos/cover/empty.jpg" data-get-off="!on" data-on-class="hide">
<div data-type="image"
data-device="Device"
data-get="nextAlbumArtURL"
data-width="80px"
data-height="80px"
class="inline nocache">
</div>
<br>
   <div data-type="label" class="inline" >Next</div>
</div>
</div>
<br>
<br>
<div data-type="classchanger" data-device="Device" data-get="currentNormalAudio" data-get-on="1" data-get-off="0" data-off-class="hide">
<div data-type="label" data-device="Device" data-get="currentTrackPosition" class="inline"></div>
<div data-type="slider"
data-device="Device"
data-set="CurrentTrackPosition"
data-get="currentTrackPositionSec"
data-max="currentTrackDurationSec" data-min="0"
data-step="1"
data-handle-diameter="5"
data-width="350"
class="horizontal tap inline">
</div>
<div data-type="label" data-device="Device" data-get="currentTrackDuration" class="inline"></div>


</div>

<div data-type="classchanger" data-device="Device" data-get="currentStreamAudio" data-get-on="1" data-get-off="0" data-off-class="hide">
<div style="height: 36px;"> </div> <!-- Leerer Ersatz für die bei Streams fehlende Positionsanzeige -->
</div>

<div class="large top-space">
<div data-type="classchanger" data-device="Device" data-get="currentNormalAudio" data-get-on="1" data-get-off="0" data-off-class="hide">
<div data-type="label" data-device="Device" data-get="currentTitle" class="bold truncate" style="height: 21px;"></div>
<div data-type="joinedlabel" data-device="Device" data-mask="[$1][ ~ $2]" data-get='["currentArtist","currentAlbum"]' class="truncate" style="height: 21px;"></div>
</div>
<div data-type="classchanger" data-device="Device" data-get="currentStreamAudio" data-get-on="1" data-get-off="0" data-off-class="hide">
<div data-type="label" data-device="Device" data-get="currentSenderInfo" class="bold truncate" style="height: 21px;"></div>
<div data-type="joinedlabel" data-device="Device" data-mask="[$1][: $2]" data-get='["currentSender","currentSenderCurrent"]' class="truncate" style="height: 21px;"></div>
</div>
</div>

<div class="top-space">

<div data-type="classchanger" data-device="Device" data-get="currentNormalAudio" data-get-on="1" data-get-off="0" data-off-class="hide" class="inline top-space">
<div data-type="switch" data-device="Device" data-get="Repeat" data-set="Repeat"
data-icon="fa-repeat" data-background-icon="-"
data-on-color="#aa6900" data-off-color="gray"
data-get-on="1" data-get-off="0"
data-set-on="1" data-set-off="0" class="inline ">
</div>

<div data-type="push" data-device="Device"
data-icon="fa-step-backward" data-background-icon="-"
data-off-color="#fff" data-on-color="#aa6900"
data-set-on="Previous" class="inline ">
</div>

<div data-type="push" data-device="Device"
data-set="CurrentTrackPosition"
data-icon="fa-backward" data-background-icon="-"
data-off-color="#fff" data-on-color="#aa6900"
data-set-on="-15" class="inline ">
</div>
</div>

<div data-type="switch"
data-device="Device"
data-get="transportState"
data-states='["PLAYING","PAUSED_PLAYBACK","STOPPED"]'
data-set-states='["Pause","Play","Play"]'
data-background-icon="fa-circle-thin"
data-background-colors='["orange","white","white"]'
data-colors='["white","white","white"]'
data-icons='["fa-pause","fa-play","fa-play"]'
class="inline ">
</div>

<div data-type="classchanger" data-device="Device" data-get="currentNormalAudio" data-get-on="1" data-get-off="0" data-off-class="hide" class="inline">
<div data-type="push" data-device="Device"
data-set="CurrentTrackPosition"
data-icon="fa-forward" data-background-icon="-"
data-off-color="#fff" data-on-color="#aa6900"
data-set-on="+15" class="inline ">
</div>

<div data-type="push" data-device="Device"
data-icon="fa-step-forward" data-background-icon="-"
data-off-color="#fff" data-on-color="#aa6900"
data-set-on="Next" class="inline ">
</div>

<div data-type="switch" data-device="Device" data-get="Shuffle" data-set="Shuffle"
data-icon="fa-random" data-background-icon="-"
data-on-color="#aa6900" data-off-color="gray"
data-get-on="1" data-get-off="0"
data-set-on="1" data-set-off="0" class="inline ">
</div>
</div>

<div data-type="popup" class="inline" data-width="470px" data-height="250px">
<div data-type="push"
data-icon="fa-list-ul" data-background-icon="-"
data-off-color="#fff" data-on-color="#aa6900"
class="">
</div>

<div class="dialog">
<header>Musikauswahl für Name</header>

<div class="top-space-10 left-align left-space">
<br>
<div>
<div class="large middle inline">Favoriten: </div>
<div data-type="select"
data-device="Device"
data-list="FavouritesList"
data-alias="FavouritesListAlias"
data-delimiter="|"
data-quote="/"
data-get="currentFavouriteNameMasked"
data-set="StartFavourite"
class="inline w3x"
onchange="$('.dialog-close').trigger('click');"></div>
</div>
<br>
<div>
<div class="large middle inline">Playlists: </div>
<div data-type="select"
data-device="Device"
data-list="PlaylistsList"
data-alias="PlaylistsListAlias"
data-delimiter="|"
data-quote="/"
data-get="currentPlaylistNameMasked"
data-set="StartPlaylist"
class="inline w3x"
onchange="$('.dialog-close').trigger('click');"></div>
</div>
<br>
<div>
<div class="large middle inline">Radiosta.: </div>
<div data-type="select"
data-device="Device"
data-list="RadiosList"
data-alias="RadiosListAlias"
data-delimiter="|"
data-quote="/"
data-get="currentRadioNameMasked"
data-set="StartRadio"
class="inline w3x"
onchange="$('.dialog-close').trigger('click');"></div>
</div>
</div>
</div>
</div>
</div>

<div data-type="slider" class="inline horizontal value tap" data-device="Device"
data-get="Volume" data-set="Volume" data-min="0" data-max="100" data-width="400px"></div>

<div data-type="switch" data-device="Device" data-get="Mute" data-set="Mute"
data-icon="oa-audio_volume_mute" data-background-icon="-"
data-on-color="#aa6900" data-off-color="gray"
data-get-on="1" data-get-off="0"
data-set-on="1" data-set-off="0" class="inline ">
</div>
</div>


Und die Einbindung auf meiner Media-Seite:
<!-- ========= Sonos Kueche =============== -->
<!-- ====================================== -->
<li class="transparent50" data-row="2" data-col="1" data-sizex="4" data-sizey="4">

<header>SONOS Küche</header>
<div data-template="template_musik_sonos.html" data-parameter='{"Name":"Kueche","Device":"Sonos_Kueche","Switch":"KU_Sonos_SW_Sw"}'></div>

</li>
<!-- ========= Sonos Schlafzimmer============ -->
<!-- ====================================== -->
<li class="transparent50" data-row="6" data-col="1" data-sizex="4" data-sizey="4">

<header>SONOS Schlafzimmer</header>
<div data-template="template_musik_sonos.html" data-parameter='{"Name":"Schlafzimmer","Device":"Sonos_Schlafzimmer","Switch":"SZ_Sonos_SW_Sw"}'></div>

</li>
<!-- ========= Sonos Wohnzimmer =============== -->
<!-- ====================================== -->
<li class="transparent50" data-row="2" data-col="5" data-sizex="4" data-sizey="4">

<header>SONOS Wohnzimmer</header>
<div data-template="template_musik_sonos.html" data-parameter='{"Name":"Wohnzimmer","Device":"Sonos_Wohnzimmer","Switch":"WZ_Sonos_SW"}'></div>

</li>
<!-- ========= Sonos Bad ================== -->
<!-- ====================================== -->
<li class="transparent50" data-row="6" data-col="5" data-sizex="4" data-sizey="4">

<header>SONOS Bad</header>
<div data-template="template_musik_sonos.html" data-parameter='{"Name":"Bad","Device":"Sonos_Bad","Switch":"BZ_Sonos_SW"}'></div>

</li>


Gruß Detlef

ToM_ToM

Hey,

sagt mal wo bekommt ihr denn die Readings RadioList und RadioListAlias her?
Ich habe nur das Reading Radios.

VG, Thomas
Hardware: BananaPi, Busmaster CUL, SanDisk 16GB Ultra SD, 16 GB USB-Stick | Software: Armbian, FHEM 5.8

Masterfunk

Zitat von: ToM_ToM am 27 März 2017, 20:12:47
Hey,

sagt mal wo bekommt ihr denn die Readings RadioList und RadioListAlias her?
Ich habe nur das Reading Radios.

VG, Thomas

Guckst Du:

https://forum.fhem.de/index.php/topic,69290.0.html

Gruß Detlef

TottiToad

Zitat von: Masterfunk am 19 März 2017, 13:12:23
Habe das ganze nochmal überarbeitet (Basierend auf Reinerleins's Config).

Rechts oben wird beim Player noch folgendes angezeigt:
1. Status des Players
2. Status Power-Switch für Player
3. Aktueller "TrackProvider" mit entsprechenden Icons
...

Hi,

habe gerade mal deine "Überarbeitung" genutzt.

Vorab, Genial !

Es mussten zwar bei mir ein paar Änderung bzgl. currentTrackPositionSimulatedSec umgestellt werden, doch jetzt läuft !


Hab da jedoch noch ne Frage zu den Symbolen rechts oben

- Bei werden zum einen 4 Symbole anzeigt, nicht 3
- 1 Symbol zeigt aktuellen Track Provider mit Symbol
- 2 Symbol schaltet einfach nur Switch on und off (Was hast Du damit geschaltet ?)
- 3 Symbol ist ohne Funktion
- 4 Symbol ist zum Player zu bzw. wegschabten


Grüße & Danke
Totti

Masterfunk

Zitat von: TottiToad am 26 Oktober 2017, 17:07:06
Hab da jedoch noch ne Frage zu den Symbolen rechts oben

- Bei werden zum einen 4 Symbole anzeigt, nicht 3
- 1 Symbol zeigt aktuellen Track Provider mit Symbol
- 2 Symbol schaltet einfach nur Switch on und off (Was hast Du damit geschaltet ?)
- 3 Symbol ist ohne Funktion
- 4 Symbol ist zum Player zu bzw. wegschabten

1. ja
2. Damit schalte ich die Steckdosen vor den Playern
3. Zeigt a ob der Player "reachable" ist
4. Zum Gruppieren

Gruß Detlef

Tobias

@ masterfunk, sieht ja super aus wie sich mein sonos template weiterentwickelt hat

Gesendet von meinem Leap mit Tapatalk

Maintainer: Text2Speech, TrashCal, MediaList

Meine Projekte: https://github.com/tobiasfaust
* PumpControl v2: allround Bewässerungssteuerung mit ESP und FHEM
* Ein Modbus RS485 zu MQTT Gateway für SolarWechselrichter

Mumpitz

Mir gefällt deine Integration Wahnsinnig gut. Leider ist sie jedoch für mein Lenovo Tab viel zu gross. Sobald ich anfange die Schriften zu verkleinern zerreisst es das ganze Layout. Kann man die Seite irgendwie einfach verkleinern oder hat jemand einen Tipp an welchen Stellen ich am schräubchen drehen muss?

mameier1234

Bei mir hatte ! alles funktioniert...

Nun kommen aber die Player Steuerungen Stop, Play , Pause usw gar nicht mehr.. werden nicht mehr angezeigt ...

Any Idea ?

chrisko

Also... irgendetwas reffe ich noch nicht.
Ich bekomme es einfach nicht hin, dass mit die Listen (Also Favoritten, Radios, usw.) angezeigt werden.
Weiß jemand Rat, as ich falsch mache, bzw. wwas genau ich beachten muss?
<div>
                  <div data-type="label" class="" >Favoriten:</div>
                  <div class="large middle "></div>
                  <div data-type="select"
                     data-device="Device"
                     data-list="FavouritesList"
                     data-alias="FavouritesListAlias"
                     data-delimiter="|"
                     data-quote="/"
                     data-get="currentFavouriteNameMasked"
                     data-set="StartFavourite"
                     class="large w3x"
                     onchange="$('.dialog-close').trigger('click');"></div>
</div>


Mir ist es nicht klar, wie ich an FavouritesList komme.
In FHEM sieht es so aus:

define Sonos_Kueche SONOSPLAYER RINCON_xxxxxxxxxxxxxxxx_MR
attr Sonos_Kueche alias Küche
attr Sonos_Kueche generateInfoSummarize1 <NormalAudio><Artist prefix="(" suffix=")"/><Title prefix=" '" suffix="'" ifempty="[Keine Musikdatei]"/><Album prefix=" vom Album '" suffix="'"/></NormalAudio> <StreamAudio><Sender suffix=":"/><SenderCurrent prefix=" '" suffix="' -"/><SenderInfo prefix=" "/></StreamAudio>
attr Sonos_Kueche generateInfoSummarize2 <TransportState/><InfoSummarize1 prefix=" => "/>
attr Sonos_Kueche generateInfoSummarize3 <Volume prefix="Lautstärke: "/><Mute instead=" ~ Kein Ton" ifempty=" ~ Ton An" emptyval="0"/> ~ Balance: <Balance ifempty="Mitte" emptyval="0"/><HeadphoneConnected instead=" ~ Kopfhörer aktiv" ifempty=" ~ Kein Kopfhörer" emptyval="0"/>
attr Sonos_Kueche generateVolumeSlider 1
attr Sonos_Kueche getAlarms 1
attr Sonos_Kueche getTitleInfoFromMaster 1
attr Sonos_Kueche group Küche
attr Sonos_Kueche icon icoSONOSPLAYER_icon-S3.png
attr Sonos_Kueche minVolume 0
attr Sonos_Kueche model Sonos_S3
attr Sonos_Kueche room Küche,Sonos
attr Sonos_Kueche simulateCurrentTrackPosition 1
attr Sonos_Kueche sortby 1
attr Sonos_Kueche stateFormat presence ~ currentTrackPositionSimulatedPercent% (currentTrackPositionSimulated / currentTrackDuration)
attr Sonos_Kueche userReadings Favourites:LastActionResult.*?GetFavouritesWithCovers.* { if (ReadingsVal($name, "LastActionResult", "") =~ m/.*?: (.*)/) { return $1;; } }, Radios:LastActionResult.*?GetRadiosWithCovers.* { if (ReadingsVal($name, "LastActionResult", "") =~ m/.*?: (.*)/) { return $1;; } }, Playlists:LastActionResult.*?GetPlaylistsWithCovers.* { if (ReadingsVal($name, "LastActionResult", "") =~ m/.*?: (.*)/) { return $1;; } }, Queue:LastActionResult.*?GetQueueWithCovers.* { if (ReadingsVal($name, "LastActionResult", "") =~ m/.*?: (.*)/) { return $1;; } }, currentTrackPosition:LastActionResult.*?GetCurrentTrackPosition.* { if (ReadingsVal($name, "LastActionResult", "") =~ m/.*?: (.*)/) { return $1;; } }
attr Sonos_Kueche webCmd Volume
define Sonos_KuecheRG_Favourites readingsGroup Sonos_Kueche:<{SONOS_getListRG($DEVICE,"Favourites",1)}@FavouritesList>
define Sonos_KuecheRG_Radios readingsGroup Sonos_Kueche:<{SONOS_getListRG($DEVICE,"Radios",1)}@RadiosList>
define Sonos_KuecheRG_Playlists readingsGroup Sonos_Kueche:<{SONOS_getListRG($DEVICE,"Playlists")}@PlaylistsList>
define Sonos_KuecheRG_Queue readingsGroup Sonos_Kueche:<{SONOS_getListRG($DEVICE,"Queue")}@QueueList>



Was läuft verkehrt? Was übersehe ich hier?

Euch schonmal vielen Dank für Eure Hilfe!

Viele Grüße,
Chris

mameier1234

Hallo Chris,

ich habe da auch ziemlich lange gekämpft...

Die Beispiele im Wiki   https://wiki.fhem.de/wiki/SONOS  ganz unten machen es dann aber am Schluss doch einfach.. Man muss sich einfach mal richtig durchkämpfen..

Da wird dann auch klar, dass es ohne die Subs in myutils nicht geht.... (deine 4 letzen Zeilen.....getListRG....)

Ist aber tatsächlich alles! im Wiki

trinitywhm

Zitat von: mameier1234 am 25 November 2017, 13:17:48
Bei mir hatte ! alles funktioniert...

Nun kommen aber die Player Steuerungen Stop, Play , Pause usw gar nicht mehr.. werden nicht mehr angezeigt ...

Any Idea ?

Bei mir sah es auch zunächst aus das die Playersteuerung nicht angezeigt wird. Aber dann habe ich rausgefunden dass es mit vier Kacheln so ist das die zweite Zeile die obere Zeile überdeckt. Bei mir ist es zumindest so. Wenn ich nur zwei Kacheln anzeige, dann laufen die Player-Steuerungen auch aus dem div raus. Ich habe es leider noch nicht hinbekommen dass es so toll aussieht wie in dem Anhang von Beitrag #33. Hat noch irgendjemand eine Idee an was das liegen könnte oder was ich ändern muss?

Ich habe die template_sonos_musik.html aus #33 übernommen und die Einbindung soweit angepasst das ich eben nur zwei statt vier Kacheln habe. Wenn der Code hierfür noch interessant sein sollte, zur Problemlösung poste ich den gerne auch noch.

Fixel2012

Hallo zusammen,

ich habe mich ran gemacht und versucht Sonos im FTUI zu konfigurieren. Habe alle maßnahmen laut Wiki getroffen, aber leider wird mir alles nur verzogen angezeigt.

Ich habe keine Ahnung an was es liegen könnte.

Hier meine DEF in FTUI:


<ul>
<!-- ========= Sonos Schlafzimmer============ -->
<!-- ====================================== -->
<li data-row="1" data-col="1" data-sizex="3" data-sizey="5" class="border-down-gray lesstransparent">
<div data-template="template_musik_sonos.html" data-parameter='{"Device":"Sonos_Schlafzimmer"}'></div>
</li>

</ul>


An der Definition sollte doch alles richtig sein?!

Mit den data-size Werten habe ich bereits wild rum gespielt, da ändert sich aber leider nicht viel am Verhalten.

Im Anhang noch ein Bild.

Würde mich freuen, wenn da jemand einen Tipp hätte.

Gruß,

Fixel
Fhem 5.8 auf Raspi 3, HMLAN und 868MHz CUL mit einigen Komponenten, Z-Wave Rollladenaktoren, Tablet UI, 433 MHz CUL mit Baumarktsteckdosen und Temp Sensoren, Amazon Echo, Echo Dot, 2x SONOS  play1, 1x SONOS Connect AMP,  presence, HUE, Lightify