Sonos2mqtt - vielleicht hat jemand Lust mitzumachen

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

Vorheriges Thema - Nächstes Thema

Otto123

Im Übrigen macht jetzt ein next bei laufendem Radio die Weiterschaltung auf den nächsten Sender in der Liste
Die Liste wird jetzt aus den Favoriten so extrahiert, dass nur die Radios drin sind - weil nur die wirklich funktionieren.

Zumindest klappt das bei mir - vielleicht mag es jemand in seiner Umgebung probieren.

Ich habe die userReadings zum Teil in den Code der sonos2mqttUtils gelegt. Das Template sieht jetzt sehr übersichtlich aus.
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

Stefan_Hvr

Moin,

Zitat von: Otto123 am 04 März 2021, 19:50:55
Im Übrigen macht jetzt ein next bei laufendem Radio die Weiterschaltung auf den nächsten Sender in der Liste
Probier ich am WE mal aus

Zitat von: Otto123 am 04 März 2021, 19:50:55
Die Liste wird jetzt aus den Favoriten so extrahiert, dass nur die Radios drin sind - weil nur die wirklich funktionieren.
--> was heisst denn "nur"? was war denn vorher mit drin?

bei  mir stehen eh nur die Radiosender drin playFav:Bayern.3,Guldkanalen.70-tal,NDR.2.Niedersachsen,SWR3 {sonos2mqtt($NAME,$EVENT)}

Favorites {"Result":[{"AlbumArtUri":"http://cdn-radiotime-logos.tunein.com/s155675q.png","Title":"Guldkanalen 70-tal","UpnpClass":"object.itemobject.item.sonos-favorite","ItemId":"FV:2/2","ParentId":"FV:2","TrackUri":"x-sonosapi-stream:s155675?sid=254&flags=8224&sn=0","ProtocolInfo":"x-sonosapi-stream:*:*:*"},{"AlbumArtUri":"http://cdn-profiles.tunein.com/s56857/images/logoq.png?t=154228","Title":"NDR 2 Niedersachsen","UpnpClass":"object.itemobject.item.sonos-favorite","ItemId":"FV:2/0","ParentId":"FV:2","TrackUri":"x-sonosapi-stream:s56857?sid=254&flags=8224&sn=0","ProtocolInfo":"x-sonosapi-stream:*:*:*"},{"AlbumArtUri":"https://d1uner0r1fcap8.cloudfront.net/image?w=60&image=https:%2F%2Fcdn-profiles.tunein.com%2Fs24896%2Fimages%2Flogog.png%3Ft%3D1&partnerId=tunein","Title":"SWR3","UpnpClass":"object.itemobject.item.sonos-favorite","ItemId":"FV:2/8","ParentId":"FV:2","TrackUri":"x-sonosapi-stream:tunein:9479?sid=303&flags=8224&sn=3","ProtocolInfo":"x-sonosapi-stream:*:*:*"}],"NumberReturned":3,"TotalMatches":3,"UpdateID":1}
die Sonos-Playlisten wären noch toll. Die Apple-Playlisten ein Traum ;-)

Wollte am Wochenende mal prüfen ob das hier klappt
{
  "command": "adv-command",
  "input": {
    "cmd": "AVTransportService.AddURIToQueue",
    "val": {
      "InstanceID": 0,
      "DesiredFirstTrackNumberEnqueued": 0,
      "EnqueueAsNext": true,
      "EnqueuedURI":"file:///jffs/settings/savedqueues.rsq#7",
      "EnqueuedURIMetaData": {
        "UpnpClass": "object.container.playlistContainer",
        "ItemId": "SQ:7",
        "CdUdn": "RINCON_AssociatedZPUDN"
      }
    }
  }
}


von:
https://github.com/svrooij/sonos2mqtt/issues/128
Viele Grüße aus Hannover
EnOcean, Zigbee, Shelly MQTT, Homebridge, Fritzbox, Harmonyhub, Alexa, Worx MQTT, Sonos MQTT, Tahoma, Telegram, Vorwerk,IRoomba MQTT, Buderus Km200,
seit 08/2019 Hausautomation mit FHEM

Otto123

#902
Zitat--> was heisst denn "nur"? was war denn vorher mit drin?
Ich lade ja die Favoriten mit Stephans Standard Funktion, da kann alles mögliche drin sein.
Aus diesem "Json Array" habe ich bisher alle Titel in favlist extrahiert.
Jetzt wird die favlist nur aus Einträgen erzeugt die /x-sonosapi-stream/ enthalten - weil die sich einfach mit SetAVTuri starten lassen.

Die Playlisten sind irgendwelche "container" da muss man was anders machen. Wenn Du das rausfindest wäre es toll :)
So ein Eintrag sieht bsp so aus:
{"AlbumArtUri":"http://soundcloud-static.ws.sonos.com/icons/tracks_legacy.png",
"Title":"Lotta Sleeps",
"UpnpClass":"object.itemobject.item.sonos-favorite",
"ItemId":"FV:2/28",
"ParentId":"FV:2",
"TrackUri":"x-rincon-cpcontainer:0006206cuser-tracks:7212085",
"ProtocolInfo":"x-rincon-cpcontainer:*:*:*"},

Im Gegensatz zum radio, da kann man einfach die TrackUri setzen und es geht los:
{"AlbumArtUri":"http://cdn-profiles.tunein.com/s25224/images/logoq.png",
"Title":"104.6 RTL",
"UpnpClass":"object.itemobject.item.sonos-favorite",
"ItemId":"FV:2/0",
"ParentId":"FV:2",
"TrackUri":"x-sonosapi-stream:s25224?sid=254&flags=32",
"ProtocolInfo":"x-sonosapi-stream:*:*:*"},


Edit: Ich habe mal noch ne Idee für einen setter um (am Morgen) die Lautstärke sanft hochzuziehen:
Volume auf Anfangswert setzen, play starten und dann:
volSoft:noArg {for (1..10) {fhem("sleep $_;set $NAME volume {([$NAME:volume]+1)}")}}
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

binford6000

Zitat von: Otto123 am 05 März 2021, 10:07:43
Edit: Ich habe mal noch ne Idee für einen setter um (am Morgen) die Lautstärke sanft hochzuziehen:
Volume auf Anfangswert setzen, play starten und dann:
volSoft:noArg {for (1..10) {fhem("sleep $_;set $NAME volume {([$NAME:volume]+1)}")}}

Hallo Otto,
ich hab schon lange hier mitgelesen und jetzt den Umstieg von SONOS auf MQTT2 gemacht.
Was soll ich sagen - läuft mega!  :)

Was mir bis jetzt gefehlt hat war fadeIn fadeOut. Das habe ich bei mir jetzt so gelöst:
für in die setList:
fadeOut:noArg {fadeout($NAME); fhem("setreading $NAME FadeVolume [$NAME:volume]")}
fadeIn:noArg {fadein($NAME)}


Und den Code für die sonosUtils:
sub fadeout($) {
my ($dev) = @_;
my $vol = ReadingsVal($dev,"volume",10);
if ($vol > 0) {
$vol--;                               
fhem("set $dev volume $vol");             
fhem("sleep 0.8; {fadeout('$dev')}");         
}
elsif ($vol == 0) {
fhem("set $dev pause")
}
}

sub fadein($) {
my ($dev) = @_;
my $vol = ReadingsVal($dev,"volume",10);;
my $target = ReadingsVal($dev,"FadeVolume",10);
fhem("set $dev play") if (ReadingsVal($dev,'transportState','STOPPED') ne "PLAYING");
if ($vol <= $target) {
$vol++;                               
fhem("set $dev volume $vol");             
fhem("sleep 0.8; {fadein('$dev')}");         
}
}


Das geht bestimmt auch noch besser. Aber vielleicht könnte man das ja als Denkansatz verwenden.
VG Sebastian

Otto123

#904
Moin,

das hat mir gestern auch keine Ruhe gelassen. Da ist jetzt sowas bei rausgekommen. Scheint mir auch noch nicht als endgültige Fassung, aber funktioniert erstmal.
damit geht wie bisher - ohne extra setter oder Readings (erschien mir irgendwie umständlich)
set player volume 10 # regelt soft egal in welche Richtung
set player volume 20 10 # setzt auf start 10 und regelt soft auf 20 - z.B. vor einem start play
set player volume 15 15 # setzt hart auf 15
if($cmd eq 'volume') {
   my $vol = ReadingsNum($NAME,'volume',0);
   my $d = abs $arr[1] - $vol;
   my $s = $arr[1] <=> $vol;
   if ($arr[2] or ($d == 1)) {
      $payload = $arr[2] || $payload;
      if ($arr[2] and ($arr[1] != $arr[2])) {fhem("sleep 0.5;set $NAME volume $arr[1]")}
      return qq($topic { "command": "volume", "input": $payload })
   } else {
      for (1..$d) {fhem("sleep $_;set $NAME volume {([$NAME:volume]+$s)}")}}
}


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

Stefan_Hvr

Moin,

also zu den Playlisten: wenn ich das folgende publishe
{
  "command": "adv-command",
  "input": {
    "cmd": "GetFavorites",
    "reply": "GetFavoritesReply"
  }
}


Bekomme ich die Sender, die unter "Mein Sonos" gespeichert sind (4 Stück). Was ich absolut nicht in der Antwort sehe sind die Sonos-Playlisten.
Otto: bekommst Du die als Antwort in den GetFavoritesReply Topic?
Viele Grüße aus Hannover
EnOcean, Zigbee, Shelly MQTT, Homebridge, Fritzbox, Harmonyhub, Alexa, Worx MQTT, Sonos MQTT, Tahoma, Telegram, Vorwerk,IRoomba MQTT, Buderus Km200,
seit 08/2019 Hausautomation mit FHEM

Otto123

Richtig
GetFavorites liefert Dir das was unter Mein Sonos steht. (Das ist das was ich in der Bridge implementiert habe)
GetFavoriteRadioStations liefert Dir das was unter TuneIn / Meine Radiosender steht.

Mehr habe ich  noch nicht probiert. Ich habe aber Playlisten unter Mein Sonos, die kommen beim Ersteren mit. Es sind aber nicht die, die unter Sonos Playlisten stehen!

Mit der "Browse with own query" https://svrooij.io/sonos2mqtt/control/browse.html hatte ich bisher keinen Erfolg ...
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

Stefan_Hvr

okay Sonos Playlisten und "Mein Sonos" ist der kleine, aber feiner Unterschied.

und die kannst Du dann mit playFAV abspielen, nachdem Du sie an die Player verteilt hast??
Viele Grüße aus Hannover
EnOcean, Zigbee, Shelly MQTT, Homebridge, Fritzbox, Harmonyhub, Alexa, Worx MQTT, Sonos MQTT, Tahoma, Telegram, Vorwerk,IRoomba MQTT, Buderus Km200,
seit 08/2019 Hausautomation mit FHEM

Otto123

derzeit kann ich die Radios abspielen, die Playlisten haben ein anderes Format. Da tut er nichts ...
Siehe #902
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

Stefan_Hvr

#909
Hilft vielleicht schon mal ein wenig:

musste ich machen um das Radio auszubekommen.
{  "command": "switchtoqueue"}

Hier Liste leeren
{  "command": "adv-command",
  "input": {    "cmd": "AVTransportService.RemoveAllTracksFromQueue"  }
}


Die Ziffer 3 in EnqueuedURI und ItemId ist der Wert aus enqueuedMetadata_ItemId wenn die Liste läuft (vom Player gestartet) (also eine "Sonos-Playliste NICHT die aus "Mein Sonos")
{
  "command" : "adv-command",
  "input" : {
    "cmd" : "AVTransportService.AddURIToQueue",
    "val" : {
      "InstanceID" : 0,
      "DesiredFirstTrackNumberEnqueued" : 0,
      "EnqueueAsNext" : true,
      "EnqueuedURI" : "file:///jffs/settings/savedqueues.rsq#3",
      "EnqueuedURIMetaData" : {
        "UpnpClass" : "object.container.playlistContainer",
        "ItemId" : "SQ:3",
        "CdUdn" : "SA_RINCON2311_X_#Svc2311-0-Token"
      }
    }
  }
}


zum starten
{  "command": "play"}

und hiermit bekommt man die abgefragt :-)
{
  "command": "adv-command",
  "input": {
    "cmd": "ContentDirectoryService.BrowseParsed",
    "val": {
      "ObjectID": "SQ:",
      "BrowseFlag": "BrowseDirectChildren",
      "Filter": "*",
      "StartingIndex": 0,
      "RequestedCount": 0,
      "SortCriteria": ""
    },
    "reply": "sonosPlaylists"
  }
}


Erweitern der readingList in der Bridge, dann stehen sie schon mal da
sonos/RINCON_([0-9A-Z]+)/sonosPlaylists:.* sonosPlaylists
Viele Grüße aus Hannover
EnOcean, Zigbee, Shelly MQTT, Homebridge, Fritzbox, Harmonyhub, Alexa, Worx MQTT, Sonos MQTT, Tahoma, Telegram, Vorwerk,IRoomba MQTT, Buderus Km200,
seit 08/2019 Hausautomation mit FHEM

Otto123

Ja das müsste gehen.
Diese Routine sucht ja in dem Ergebnis nach dem Titel und liest nur die TrackUri aus. Jetzt müsste man schauen, welche variablen Teile man hier rausholen muss und in deinen Play Aufruf stecke muss .. Ist mir noch nicht ganz klar.
if($cmd eq 'playFav') {
    use JSON;use HTML::Entities;use Encode qw(encode decode);
    my $enc = 'UTF8';my $uri='';my $search=(split(' ', $EVENT,2))[1];
    $search=~s/[\/()]/./g;
    my $dev = (devspec2array('model=sonos2mqtt_bridge'))[0];
    my $decoded = decode_json(ReadingsVal($dev,'Favorites','')); # Hier kann man auch das Reading Reply einsetzen oder was anderes
    my @array=@{$decoded->{'Result'}};
    for (@array) {
      if (encode($enc, decode_entities($_->{'Title'}))=~/$search/i) # Hier Suche nach dem Titel
         {$uri = $_->{'TrackUri'} }                                 # hier die Trackuri zurück
   }
   fhem("set $NAME playUri $uri") if ($uri ne '');                # Das wird dann komplizierter...
}


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

Stefan_Hvr

#911
hier noch die Erweiterung der getList für die Bridge:
sonosPlaylists:noArg sonosPlaylists {q(sonos/).ReadingsVal((devspec2array('a:model=sonos2mqtt_speaker'))[0],'uuid','').q(/control {"command": "adv-command","input": {"cmd": "ContentDirectoryService.BrowseParsed","val": {"ObjectID": "SQ:","BrowseFlag": "BrowseDirectChildren", "Filter": "*", "StartingIndex": 0, "RequestedCount": 0, "SortCriteria": "" }, "reply":"sonosPlaylists"}})}

und die von den Favoriten kopierte und angepasste Erweiterung des userReadings der Bridge (Komma nicht vergessen ;-) )
playlist:sonosPlaylists.* {
  use JSON;use HTML::Entities;use Encode qw(encode decode);
  my $enc = 'UTF8';
  my @out;
  my $decoded = decode_json(ReadingsVal($name,'sonosPlaylists',''));
  my @arr  = @{$decoded->{'Result'}};;
  foreach (@arr) {
     my $dec = encode($enc, decode_entities($_->{'Title'}));
     $dec =~ s/\s/./g;
     push @out,$dec}
  return join ',', sort @out},
grouplist:sonosPlaylists.* {
     my @out;
     foreach (devspec2array('a:model=sonos2mqtt_speaker')) {if (ReadingsVal($_,'isMaster','')) {push @out,ReadingsVal($_,'name','')}}
  return join(',', sort @out)}
Viele Grüße aus Hannover
EnOcean, Zigbee, Shelly MQTT, Homebridge, Fritzbox, Harmonyhub, Alexa, Worx MQTT, Sonos MQTT, Tahoma, Telegram, Vorwerk,IRoomba MQTT, Buderus Km200,
seit 08/2019 Hausautomation mit FHEM

Stefan_Hvr

#912
Zitat von: Otto123 am 07 März 2021, 11:06:52
Ja das müsste gehen.
Diese Routine sucht ja in dem Ergebnis nach dem Titel und liest nur die TrackUri aus. Jetzt müsste man schauen, welche variablen Teile man hier rausholen muss und in deinen Play Aufruf stecke muss .. Ist mir noch nicht ganz klar.
if($cmd eq 'playFav') {
    use JSON;use HTML::Entities;use Encode qw(encode decode);
    my $enc = 'UTF8';my $uri='';my $search=(split(' ', $EVENT,2))[1];
    $search=~s/[\/()]/./g;
    my $dev = (devspec2array('model=sonos2mqtt_bridge'))[0];
    my $decoded = decode_json(ReadingsVal($dev,'Favorites','')); # Hier kann man auch das Reading Reply einsetzen oder was anderes
    my @array=@{$decoded->{'Result'}};
    for (@array) {
      if (encode($enc, decode_entities($_->{'Title'}))=~/$search/i) # Hier Suche nach dem Titel
         {$uri = $_->{'TrackUri'} }                                 # hier die Trackuri zurück
   }
   fhem("set $NAME playUri $uri") if ($uri ne '');                # Das wird dann komplizierter...
}


Gruß Otto

ich habe mal Eure playFav abgekupfert...das klappte irgendwie noch  nicht zuverlässig. bis ich das sleep eigefügt habe. Scheinbar braucht die Liste ne Sekunde zum laden.
Die Variabel $itemid wird falsch übernommen, krieg noch nicht raus warum :-/

ACHTUNG: ich habe nochmal an klein/großschreibung gearbeitet und würde das noch anpassen (evt. heute Abend - muss gerade mal wech.)

if($cmd eq 'playList') {
use JSON;use HTML::Entities;use Encode qw(encode decode);
my $enc = 'UTF8';my $uri='';my $itemid='';my $search=(split(' ', $EVENT,2))[1];
$search=~s/[\/()]/./g;
my $dev = (devspec2array('model=sonos2mqtt_bridge'))[0];
my $decoded = decode_json(ReadingsVal($dev,'SonosPlaylists',''));
my @array=@{$decoded->{'Result'}};
foreach (@array) {if (encode($enc, decode_entities($_->{'Title'}))=~/$search/i)
                   {$uri = $_->{'TrackUri'} }
   {$itemid = $_->{'ItemId'} }
    };
fhem("set $NAME x_raw_payload {\"command\":\"switchtoqueue\"} ; set $NAME x_raw_payload {\"command\":\"adv-command\",\"input\":{\"cmd\":\"AVTransportService.RemoveAllTracksFromQueue\"}} ; set $NAME x_raw_payload {\"command\" : \"adv-command\", \"input\" : {\"cmd\" : \"AVTransportService.AddURIToQueue\",\"val\" : {\"InstanceID\" : 0,\"DesiredFirstTrackNumberEnqueued\" : 0, \"EnqueueAsNext\" : true,\"EnqueuedURI\" : \"$uri\", \"EnqueuedURIMetaData\" : {\"ItemId\" : \"$itemid \"}}}}; sleep 1; set $NAME x_raw_payload {\"command\":\"play\"}") ;
}



geholfen hat mir:  --> http://heinz-otto.blogspot.com/2018/02/in-fhem-externe-programme-aufrufen.html  ;)
Viele Grüße aus Hannover
EnOcean, Zigbee, Shelly MQTT, Homebridge, Fritzbox, Harmonyhub, Alexa, Worx MQTT, Sonos MQTT, Tahoma, Telegram, Vorwerk,IRoomba MQTT, Buderus Km200,
seit 08/2019 Hausautomation mit FHEM

Otto123

Ich habe zum letzten Thema noch etwas rumprobiert. Mit den Sonos-Favoriten läuft es offenbar anders, da bekomme ich es nicht hin.
ich schreibe mal meine Gedanken auf:
switchtoqueue ist ja gleich input Queue  das ist implementiert - wann man das macht ist egal (vor play ;) )
das Liste Löschen könnte man als extra Kommando machen. Wenn man es nicht ausführt wird die Liste immer wieder erweitert und nicht ersetzt.
das AddURIToQueue könnte man als zusätzlichen Befehl einbauen.  Ich fürchte das ist speziell und da gibt es immer wieder andere Fälle ...
Für den Spezialfall Sonos Playlisten ist es besser den nur intern zu verwenden?

Ich würde dann drei Listen einbauen:
Radios aus Sonos-Favoriten
Radios aus TuneIn Meine Radiosender
Playlisten aus Sonos Playlisten
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

binford6000

Zitat von: Otto123 am 11 März 2021, 13:56:50
Ich würde dann drei Listen einbauen:
Radios aus Sonos-Favoriten
Radios aus TuneIn Meine Radiosender
Playlisten aus Sonos Playlisten

+1

Würde bei mir genauso passen!
VG Sebastian