Sonos2mqtt - vielleicht hat jemand Lust mitzumachen

Begonnen von Otto123, 31 Mai 2020, 18:30:55

Vorheriges Thema - Nächstes Thema

87insane

Hey,

hatte das letzte genommen was ich gefunden hatte.. Hab auf der Grundlage weiter gemacht. Natürlich kann das rein :) - Habe ich also einen doch nicht ganz aktuellen Stand erwischt.
Würde das ganze am Ende noch ein wenig optimieren. Aber zuerst mal so weiter machen. Es wird sicher noch die eine oder andere Prüfung eingebaut werden müssen oder eine andere Weg fallen.

Habe aber noch ein paar Baustellen.

- Bisher gibt es keine sauber laufende Lösung für Gruppen (Master / Slave verhalten - TrackInfo usw).
- Ich hätte gerne in jedem Player anstelle von "joinGroup - Frei Textfeld", ein Dropdown Menu mit allen Player Namen drin (Also ein Menu aus allen existierenden Playern und angezeigt, soll der Name werden).
Wäre bei mir im Moment: Badezimmer, Wohnzimmer, Küche
- Direkte Aktualisierung vom Slave Player in FHEM Web. Das geht immer nur bei dem Player der auch Master ist, da Slave ja keine Readings mehr erhält.
Der erste und dritte Punkt könnte ggf. hier erschlagen werden: https://forum.fhem.de/index.php/topic,112737.0.html

Ach ja, ich möchte am liebsten KEINE notify/doif. Das habe ich ja schon öfter gesagt. Alles geht irgendwie immer auch ohne die kleinen Helfer. Ich habe (leider) schon öfter hier erlebt, man muss nur lang genug jammern und auf einmal geht es doch :-P

Otto123

#406
Naja die devStateIcon Entwicklung läuft quasi auseinander. Das zeigt mir ganz deutlich, dass sowas (wenn überhaupt) nur als Angebot ausgeliefert werden kann. Da wird es pro Anwender 3 Meinungen dazu geben ;)

Zur Gruppenauswahl ein Codeschnipsel (für die FHEM Kommandozeile):
{my @list = devspec2array('model=sonos2mqtt_speaker');;
my @arr = ();;
foreach (@list) { my $gn = (split(' ',ReadingsVal($_,'groupName','')))[0];;
  if (!grep(/$gn/, @arr)){push @arr,$gn}
  }
return join ',',@arr}
Muss man jetzt bloß in die setList bauen. Ich weiß, Du magst auch keine Arrays - das wird irgendwann eng :)

Als bekennender notiphobiker kannst Du doch mit dem Code aus meinen beiden notifys einfach eine Setup Routine mit Warteschleifen bauen.  ;D
Das war meine erste Variante der Entwicklung:
{my @list = devspec2array('model=sonos2mqtt_speaker');; foreach (@list) {...}}



Edit: geändert MQTT2_RINCON_.* > model=sonos2mqtt_speaker
Edit: smartmatch ersetzt

Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

Beta-User

Aua.

Könntet ihr bitte möglichst folgendes vermeiden:
- namensbezogene Auswertungen (hatten wir schon; lieber über das readingList-Attribut auswerten)
- Smartmatch (das geht nicht mit allen Perl-Versionen und ich gehe davon aus, dass es mittelfristig wieder ausgebaut wird; ein Perl-Spezialist hatte mich mal gebeten, das aus RandomTimer auszubauen...).
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

Otto123

wobei wir uns auch geeinigt hatten das MQTT2_RINCON_.* legitim wäre :) habe es geändert.
hast Du für meinen Smartmatch Test eine Alternative? Ist nämlich so schön einfach :)
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

Beta-User

Legitim zu der Zeit des Anlegens der Devices. "Irgendwann" später dann nicht mehr, und hier ging es um devStateIcon.



Das mit der Prüfung sollte mit einem grep gehen, auf die Schnelle müßte eigentlich sowas wie https://svn.fhem.de/trac/browser/trunk/fhem/FHEM/98_WeekdayTimer.pm#L1317 ein Anfang sein:
  push @newt, grep { $_ !~ m{\A$wp_name\b}xms } @t;Falls es etwas komplexer werden muss: https://svn.fhem.de/trac/browser/trunk/fhem/FHEM/00_MYSENSORS.pm#L752 ff; das sollte das Verwenden von anonymen subs erlauben...
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

Otto123

Danke fürs Beispiel -hab es "unsmartmatched" ;)
Habe einem Syntax genommen den ich verstehe, mit deinem bekomme ich es nicht hin. Auf manchen Perl Syntax schau ich drauf, es gruselt mich und ich wende mich ab  :) aber jedesmal wird es besser.

Bei der Warnmeldung dachte ich mir schon man sollte nicht die Warnung abschalten (  no warnings 'experimental::smartmatch';) sondern der Code hat es seit Generationen von Perl nicht aus dem Experimentierstadium heraus geschafft - es wird seinen Grund haben.

Jetzt muss ich das zweite notify noch ändern. Ich teste das noch und geb Dir den Code fürs SVN

Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

Beta-User

Zitat von: Otto123 am 30 Juli 2020, 14:51:51
Auf manchen Perl Syntax schau ich drauf, es gruselt mich und [...]
So ähnlich geht mir das auch immer; als ich das mit smartSleep in MySensors eingebaut habe (jetzt: https://svn.fhem.de/trac/browser/trunk/fhem/FHEM/10_MYSENSORS_DEVICE.pm#L1095 ff), hatte ich auch oft das Gefühl, dass ich das nie hinbekomme, das war einfach zu abstrakt...
Na ja, es wird langsam weniger schlecht...
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

Otto123

@Beta-User Falls Du am SVN vorbeikommst :)
TV Model erweitert
smartmatch raus
Formatierung

sonos2mqtt_bridge_comfort
set DEVICE attrTemplate sonos2mqtt_bridge
defmod n_configSonos1 notify global:DEFINED.MQTT2_RINCON_[A-Z0-9]+ sleep 1;;\
set $EVTPART1 attrTemplate sonos2mqtt_speaker;;\
set $EVTPART1 x_raw_payload {"command": "adv-command","input": {"cmd":"GetZoneInfo","reply":"ZoneInfo"}}
defmod n_configSonos2 notify MQTT2_RINCON_[A-Z0-9]+:IPAddress:.* {\
  my @tv = ("S14","S11","S9");;\
  my $url="http://$EVTPART1:1400";;\
  my $xmltext = GetFileFromURL("$url/xml/device_description.xml");;\
  my ($mn)=$xmltext =~ /<modelNumber>(S[0-9]+)/;;\
  my ($img)=$xmltext =~ /<url>(.*)<\/url>/;;\
  my $icon="Sonos2mqtt_icon-$mn";;\
  my $setList=AttrVal($NAME,'setList','');;\
  fhem("setreading $NAME modelNumber $mn");;\
  fhem("\"wget -qO ./www/images/default/$icon.png $url$img\"");;\
  fhem("attr $NAME icon $icon;;sleep 4 WI;;set WEB rereadicons");;\
    if (grep(/$mn/, @tv)) {$setList=~s/input:Queue \{/input:Queue,TV \{/};;\
  $setList=~s/;;/;;;;/g;;\
  fhem("attr $NAME setList $setList")\
}
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

Beta-User

...kommt bei Gelegenheit...

Sonst noch Wünsche?

[OT: falls jemand mit zigbee2mqtt hier mitliest und homeBridgeMapping für einen Taster oä. austesten mag: https://forum.fhem.de/index.php/topic,113224.0.html; vermutlich könnte man das ähnlich für Fernbedienungen usw. verwenden. Weiß nur nicht, ob das via attrTemplate überhaupt Sinn macht und wenn ja, in welcher Form bzw. ob man irgendwelche Vorbedingungen definieren sollte; Antwort ggf. bitte dort.]
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

Otto123

#414
Ich hab mal noch etwas versucht devStateIcon zu verstehen und etwas rumgebastelt:
etwas nach meinem Gusto Strukturiert...
leavegroup eingebaut
Laufschrift statt Einkürzung auf 30 Zeichen
kein currentTrack_Title wenn er nicht existiert (bei mir öfters bei Radio)

<marquee> wird als abgekündigt gehandelt - aber ich habe nichts vergleichbar einfaches gefunden. Tipps?

{
my $wpix = '250px';
my $groupname = ReadingsVal($name,'groupName','0');
my $sgroupname = (split(' ',ReadingsVal($name,'groupName','')))[0];
my $uuidtoname = (devspec2array('DEF='.ReadingsVal($name,'coordinatorUuid','0')))[0];
my $vol = ReadingsVal($name,'volume','');
my $img = ReadingsVal($name,'currentTrack_AlbumArtUri','');
my $mystate = $name eq $uuidtoname
  ? ReadingsVal($name,'state','FEHLER') : ReadingsVal($uuidtoname,'state','');
my $playpic = $mystate eq 'PLAYING'
  ? 'rc_PAUSE@red'    : $mystate eq 'PAUSED_PLAYBACK'
  ? 'rc_PLAY@green'   : $mystate eq 'STOPPED'
  ? 'rc_PLAY@green'   : $mystate eq 'TRANSITIONING'
  ? 'rc_PLAY@blue'    : $mystate eq 'set_next'
  ? 'rc_NEXT@blue'    : $mystate eq 'set_previous'
  ? 'rc_PREVIOUS@blue': $mystate eq 'set_volumeUp'
  ? 'rc_VOLUP@blue'   : $mystate eq 'set_volumeDown'
  ? 'rc_VOLDOWN@blue' : $mystate eq 'set_mute'
  ? 'rc_MUTE@blue'    : 'rc_PLAY@yellow';
my $mutecmd = ReadingsVal($name,'mute','0') eq 'false'?'on':'off';
my $mutepic = $mutecmd eq 'on'?'rc_MUTE':'rc_VOLUP';
my $show = 'FEHLER';
my $currentTrack_Artist = ReadingsVal($name,'currentTrack_Artist','FEHLER');
my $currentTrack_Title = ReadingsVal($name,'currentTrack_Title','FEHLER');
if ($currentTrack_Title =~ 'x-sonosapi-stream:'){$currentTrack_Title=''};
my $currentTrack = $mystate eq 'TRANSITIONING'
  ? 'Puffern...' : $currentTrack_Artist.' - '.$currentTrack_Title;
my $nextTrack_Artist = ReadingsVal($name,'nextTrack_Artist','FEHLER');
my $nextTrack_Title = ReadingsVal($name,'nextTrack_Title','FEHLER');
my $nextTrack = $nextTrack_Artist.' - '.$nextTrack_Title;
my $previouspic = 'rc_PREVIOUS';
my $nextpic = 'rc_NEXT';
my $voldownpic = 'rc_VOLDOWN';
my $voluppic = 'rc_VOLUP';
my $leavegrouppic = 'rc_LEFT';
my $showlg = ReadingsVal($name,"name","0") ne $groupname ? "<a href=\"/fhem?cmd.dummy=set $name leaveGroup&XHR=1\">".FW_makeImage($leavegrouppic)."</a>" : "";
if (($mystate eq 'PLAYING')
  || ($mystate eq 'TRANSITIONING' )
  || ($mystate eq 'set_next' )
  || ($mystate eq 'set_previous' )
  || ($mystate eq 'set_volumeUp' )
  || ($mystate eq 'set_volumeDown' )
  || ($mystate eq 'set_mute' )) {
    my $shownp = ReadingsVal($name,'name','') eq $sgroupname
    ? "<a href=\"/fhem?cmd.dummy=set $name previous&XHR=1\">".FW_makeImage($previouspic)."</a>
       <a href=\"/fhem?cmd.dummy=set $name next&XHR=1\">".FW_makeImage($nextpic)."</a>" : ""; 
    $show = "$showlg <a href=\"/fhem?cmd.dummy=set $name toggle&XHR=1\">".FW_makeImage($playpic)."</a>
    <a href=\"/fhem?cmd.dummy=set $name volumeDown&XHR=1\">".FW_makeImage($voldownpic)."</a>
    $shownp
    <a href=\"/fhem?cmd.dummy=set $name volumeUp&XHR=1\">".FW_makeImage($voluppic)."</a>
    &nbsp;&nbsp;&nbsp;&nbsp;
    <a href=\"/fhem?cmd.dummy=set $name mute $mutecmd&XHR=1\">".FW_makeImage($mutepic)."</a><br>";
 
    if (ReadingsVal($name,'name','') eq $sgroupname) {
      $show = ReadingsVal($name,'currentTrack_TrackUri','') =~ 'spdif'
      ? 'TV': ReadingsVal($name,'enqueuedMetadata_UpnpClass','FEHLER') ne 'object.item.audioItem.audioBroadcast'
      ? "$show<marquee style='width: $wpix'>Aktueller Track: $currentTrack<br>Nächster Track: $nextTrack</marquee>"
      : "$show<marquee style='width: $wpix'>Radio: $currentTrack</marquee>"
    }
    elsif (ReadingsVal($name,'name','') ne $groupname) {
      $show = "$show Master: $sgroupname"}
    }
    else {
      $show = $name eq $uuidtoname
      ? "$showlg <a href=\"/fhem?cmd.dummy=set $name toggle&XHR=1\">".FW_makeImage($playpic)."</a>"
      : "$showlg <a href=\"/fhem?cmd.dummy=set $name toggle&XHR=1\">".FW_makeImage($playpic)."</a><br>Master: $sgroupname"
    }
  "<div>
   <table>
     <tr>
       <td><div style='display: inline-block; margin-right: 5px; border: 1px solid lightgray;
              height: 4.00em; width: 4.00em; background-image: url($img); background-size: contain;'></div></td>
       <td>$show</td>
     </tr>
   </table>
   </div>"
}
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

87insane

Guten Morgen,

ZitatdevStateIcon Entwicklung läuft quasi auseinander
Naja ich bin aktuell nur nicht so schnell wie ihr ^^ - Bemühe mich hinterher zu kommen. Lauftext ist auf jeden Fall geiler!

Zitatkein Next Track wenn er nicht existiert
War doch bei mir auch schon drin...

Das jemand mit etwas mehr Wissen über den Quellcode schaut und diesen anpasst finde ich gut. So lerne ich auch was! Hatte die Veränderungen auch im letzten Code schon bemerkt aber die waren gut und logisch. Ich selber hätte eben erst ganz fertig gemacht und dann nochmal bereinigt. Mich kostet es vermutlich auch etwas mehr Zeit sowas zu bauen, da ich eben kein Programmierer bin und mich immer Stück für Stück weiter rein fuchsen muss.

Ja, ich mag keine Arrays. Aber ich komme nicht dran vorbei. Das ist mir klar. Aber dafür gibt es euch ja.. So lerne ich das zwangsläufig. Nur weil ich sie nicht mag, heißt es ja nicht das sie hier keinen Sinn machen.

Danke schon mal für die ganzen Ideen und Code Beispiele.

Bisher habe ich nicht weiter testen können mit rL und dem rauß filtern. Das wird ja quasi auch etwas neben diesem Thread bearbeitet.

Bevor ich aber Zeit verschwende...
- Was ist aus Sicht von Euch wirklich der beste Weg dafür?
- Was haben wir als Ziel?

Meine Ziele hatte ich oben kurz aufgeschlüsselt. Habt ihr noch weitere?

Beta-User

Zitat von: Otto123 am 30 Juli 2020, 15:46:18
@Beta-User Falls Du am SVN vorbeikommst :)
Diesen Stand habe ich jetzt mal eingecheckt.

Wie wollen wir es jetzt mit den devStateIcon halten? Separates myUtils-file mit passendem Code, das ganze ggf. in package und der einfachen Option, zwischen verschiedenen Varianten zu tauschen (über einen Parameter?)? Das würde mMn. dann Sinn machen, wenn es mehr als 2 Varianten geben soll oder man z.B. für diverse Modell-Varianten unterschiedliche Ergebnisse haben will.

Oder lieber "nur" den "erweiterten" Code direkt als 2. Variante/2. template anbieten und "gut ist"? (Ggf. mit Link auf diesen Thread oder das Wiki zum selber weiterbauen?)
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

WumpE

grüße in die runde,

ich lese auch schon eine geraume zeit mit und finde es klasse, das ihr das mit den Templates voran treibt.

kurz zu meinem setup:
ich habe s2m als DockerContainer seit ca 6 Monaten in Betrieb. Dazu EMQX als mqtt Broker in nem DockerContainer und FHEM läuft auch im Docker.

im FHEM habe ich dann ein MQTT2_CLIENT device , der die Verbindung zum Broker aufbaut.
s2m wurde dann jeder Player als MQTT2_DEVICE angelegt, welcher auch das Topic sonos/connection beherbergt.

Diese konstelation läuft seit 6 monaten fehlerfrei, ohne die lästigen verbindungsfehler mit dem nativen sonos-modul.

nun habe ich mal nen bisl mit den attrTemplates für s2m rumgespielt und möchte euch meine erkenntnisse mitteilen:

1. Ich würde den transportState nicht auf den state mappen, da der state auch kurzzeitig den Befehlsstate annimmt. brigt unschöne nebeneffekte wenn man logiken drauf laufen hat!
2. Das DevStateIcon stand "29 Juli 2020, 21:21:00" funktioniert nicht out of the box, selbst wenn man die bridge aus dem Template s2m bridge_comfort anlegt stand "27 Juli 2020". Fehler bei $bridgestate und bei split groups. auch s2m_bridge und die speaker per s2m_speaker, erzeugen dasselbe fehlerbild. (scheinbar weil die readings nicht existieren, wenn man noch keine gruppen gebildet hat, beim bridgestate konnte ich den fehler noch nicht herausfinden, da steht bei mir nen connected = 2)
3. das devstateicon würde ich nicht über das template mit ausliefern, der gedanke über ne seperate utils.pm ist glaub ausreichend. ich denke das viele  fhem nur als datensammler und logikschicht benutzen, für ne ordentliche visu, gibts andere tools.

grüße und schönes wochenende
Über Mich: Stefan, Informatiker, Systementwicklung Prozessleittechnik
Server: NUC7i5 - Debian Docker
Container: FHEM,DEBMATIC,EMQX,NODERED,SONOS2MQTT,TRAEFIK,HOMEBRIDGE,DECONZ
Aktoren/Sensoren: HM-RF, HM-IP, EnergyCam, Shelly, MiLight, Hue, SONOS, OEG KMS-D+, Echo's, Worx
Frontends: Smartvisu 2.9

87insane

Zu 1) vermutlich meinst du set_123 ... Das wären die setlist Einträge. War bisher auch gewollt. Dafür sind nur noch nicht alle Dinge angepasst.

Zu 2) bei mir ist es so, dass ich meist einmal den Dienst neu starten muss wenn sowas passiert. Generell sollte es so laufen. Da hilft aber ggf ein list des Gerätes.

Zu 3) devstateicon wird fast immer mit gegeben. Ansonsten hättest du einen nackten Player. Wer ein anderes will, kann das anpassen oder einfach löschen. An sich ist das ja nice to have. So sieht jemand der ggf nicht so tief drin steckt, wie es gehen könnte.

Danke für dein Feedback und dein Lob an die Gemeinde :)

Otto123

#419
Naja, mMn ist ein nackter Player besser als ein devStateIcon was nicht funktioniert: je komplizierter umso mehr besteht genau diese Gefahr.
Deswegen nur die simple Variante aus #390 oder so etwas in der Art ausliefern. Der Rest ... irgendwie anders später...
@WumpE
Zu 2. ist klar, hab ich ja auch schon gesagt
Zu 3. Zustimmung

@87insane
Sorry, ich meinte currentTrack_Title und nicht next_track - habe es in meinem Post korrigiert.

Ich habe heute noch ein anders Experiment angestoßen: Die Favoriten lesbar auslesen :) Das hat mir im Sonos Modul von Reiner auch irgendwie immer gefehlt oder ich habe es nicht verstanden.

Meine Codeschnipsel erzeugen ein Sammeldevice (ob das der richtige Weg ist weiß ich noch nicht genau):
Durch die Abfrage eines Players entsteht dort ein Reading mit den Favoriten. Siehe auch hier https://svrooij.io/sonos2mqtt/control/browse.html
defmod SonosControl MQTT2_DEVICE
attr SonosControl IODev mqtt2s
attr SonosControl readingList sonos/RINCON_([0-9A-Z]+)/Reply:.* Replykomplett
attr SonosControl room MQTT2_DEVICE

set alias=Büro x_raw_payload {"command": "adv-command","input": {"cmd": "GetFavorites","reply": "Reply"}}

das kann man abfragen, z.B. einen bestimmten Namen suchen (ich weiß, das ist so alles Fehleranfällig - aber ich bin erstmal froh json geparsed zu haben - Danke ):
{
use JSON;;
my $s = ReadingsVal('SonosControl','Replykomplett','');;
my $decoded = decode_json($s);;
my @arr  = @{$decoded->{'Result'}};;
foreach (@arr) {if ($_->{'Title'} =~ /Deutschlandfunk Kultur RP/){return $_->{'TrackUri'} }} ;;
}


Damit kann man dann auch einfach in der FHEM Kommandozeile mit set magic testen (beachte die zusätzlichen () die Zeilenumbrüche stören nicht) :)
set alias=Arbeitszimmer playUri {(
use JSON;;
my $s = ReadingsVal('SonosControl','Replykomplett','');;
my $decoded = decode_json($s);;
my @arr  = @{$decoded->{'Result'}};;
foreach (@arr) {if ($_->{'Title'} =~ /Deutschlandfunk Kultur RP/){return $_->{'TrackUri'} }} ;;
)}
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz