Sonos Modul

Tipp: Bei so etwas, eigenes Repository anlegen, Fork vom Modul erzeugen und regelmäßig das eigene Repository mit den Änderungen mergen. Sonst läufst du immer wieder in das Problem rein.

Danke für den Tipp! Da ich noch nie was mit git gemacht habe wirkt das auf den ersten Blick einschüchternd, aber ich versuche mich mal einzulesen!

Hi Thosten,

ich hätte für das Modul eine Integration für Spotify Playlisten fertig.
Interesse ?

Müsstest gar nicht viel ändern.

Grüße
Daniel

Hi Daniel,
wäre sehr interessiert an dem Spotify Modul.

Grüße,
Jürgen

Genauer gesagt ist es eine möglichkeit Spotify Playlisten als Sonos Favoriten zu speichern und zu nutzen.
Hat den Vorteil, dass alle Streamingdienste funktionieren würden und sich die Playlisten auch automatisch syncen.

Lass mal Details sehen.
Hier oder als PM.

Gruß,
Thorsten

Gehr klar, ich poste dir nur die Methoden die Änderungen haben:

form.json:


{ "name": "PlaylistImport",            "type": "Select",            "caption": "Import Playlists",
                    "options": [ 
                                 { "label": "none",             "value": 0 },
                                 { "label": "saved",            "value": 1 },
                                 { "label": "imported",         "value": 2 },
                                 { "label": "saved & imported", "value": 3 },
                                 { "label": "favorites",        "value": 99 }
                               ] },

sonosAccess.php:


public function AddToQueue($file, $meta='')
  {
    $this->processSoapCall("/MediaRenderer/AVTransport/Control",
                           "urn:schemas-upnp-org:service:AVTransport:1",
                           "AddURIToQueue",
                           array( 
                                  new SoapParam("0"                     ,"InstanceID"                     ),
                                  new SoapParam(htmlspecialchars($file) ,"EnqueuedURI"                    ),
                                  new SoapParam($meta                   ,"EnqueuedURIMetaData"            ),
                                  new SoapParam("0"                     ,"DesiredFirstTrackNumberEnqueued"),
                                  new SoapParam("1"                     ,"EnqueueAsNext"                  )
                                ));
  }

module.php:


public function SetPlaylist(string $name)
    {
        $ip = $this->getIP();

        if(@GetValue($this->GetIDForIdent("MemberOfGroup")))
          $this->SetGroup(0);

        include_once(__DIR__ . "/sonosAccess.php");
        $sonos = new SonosAccess($ip);

        $uri = '';
        $meta = '';

        foreach ((new SimpleXMLElement($sonos->BrowseContentDirectory('SQ:','BrowseDirectChildren',999)['Result']))->container as $container) {
            if ($container->xpath('dc:title')[0] == $name){
              $uri = (string)$container->res;
              break;
            }
        }

        if($uri === '')
        {
            foreach ((new SimpleXMLElement($sonos->BrowseContentDirectory('FV:2','BrowseDirectChildren',999)['Result']))->item as $item) {
                if (preg_replace($this->getPlaylistReplacementFrom(), $this->getPlaylistReplacementTo(), $item->xpath('dc:title')[0]) == $name){
                    $uri = (string)$item->res;
                    $meta = (string)$item->xpath('r:resMD')[0];
                    break;
                }
            }
        }  

        if($uri === ''){
            foreach ((new SimpleXMLElement($sonos->BrowseContentDirectory('A:PLAYLISTS','BrowseDirectChildren',999)['Result']))->container as $container) {
                if (preg_replace($this->getPlaylistReplacementFrom(), $this->getPlaylistReplacementTo(), $container->xpath('dc:title')[0]) == $name){
                  $uri = (string)$container->res;
                  break;
                }
            }
        }

        if($uri === '')
            throw new Exception('Playlist \''.$name.'\' not found');

        $sonos->ClearQueue();
        $sonos->AddToQueue($uri, $meta);
        $sonos->SetAVTransportURI('x-rincon-queue:'.$this->ReadPropertyString("RINCON").'#0');

    }

public function UpdatePlaylists()
    {
        $ip = $this->getIP();

        if(IPS_VariableProfileExists("Playlist.SONOS"))
            IPS_DeleteVariableProfile("Playlist.SONOS");

        include_once(__DIR__ . "/sonosAccess.php");
        $sonos = new SonosAccess($ip);

        $Associations          = Array();
        $Value                 = 1;
        $PlaylistImport        = $this->ReadPropertyInteger("PlaylistImport");

        if( $PlaylistImport === 1 || $PlaylistImport === 3  ){
            foreach ((new SimpleXMLElement($sonos->BrowseContentDirectory('SQ:')['Result']))->container as $container) {
                $Associations[] = Array($Value++, (string)$container->xpath('dc:title')[0], "", -1);
                // associations only support up to 32 variables
                if( $Value === 33 ) break;
            }
        }

        if(($PlaylistImport === 2 || $PlaylistImport === 3) && $Value < 33){
            foreach ((new SimpleXMLElement($sonos->BrowseContentDirectory('A:PLAYLISTS')['Result']))->container as $container) {
                $Associations[] = Array($Value++, (string)preg_replace($this->getPlaylistReplacementFrom(), $this->getPlaylistReplacementTo(), $container->xpath('dc:title')[0]), "", -1);
                // associations only support up to 32 variables
                if( $Value === 33 ) break;
            }
        }

        if(($PlaylistImport === 99) && $Value < 33) // Spotify Playlist saved as Sonos Favorite
        {
            foreach ((new SimpleXMLElement($sonos->BrowseContentDirectory('FV:2')['Result']))->item as $item) {
                $Associations[] = Array($Value++, (string)preg_replace($this->getPlaylistReplacementFrom(), $this->getPlaylistReplacementTo(), $item->xpath('dc:title')[0]), "", -1);
                // associations only support up to 32 variables
                if( $Value === 33 ) break;
            }
        }

        $this->RegisterProfileIntegerEx("Playlist.SONOS", "Database", "", "", $Associations);
    }

Verfeinern nach deinem Gusto kannst du es ja dann noch selbst.

Hallo,

seit dem Update auf 4.2 funktioniert die Sonos Komponente nicht mehr?! Ich habe die Komponente schon mal entfernt - nochmal neu herunter geladen etc. aber nichts geht?!?

Hat jemand eine Idee wo ich suchen könnte? Bisher tat sie mit den diversen Playern ohne Probleme?!?

Danke

OK Fehler gefunden … ich hatte lange nicht mehr das Modul upgedatet und jetzt muss noch ein SNS_Play gesetzt werden um die Radiowiedergabe zu starten.

<?

$radio = „HR3“;
$InstanceID= 13542 /[3 Logik\Sonos\Sonos - WiGa]/;

SNS_SetDefaultVolume($InstanceID);
SNS_SetRadio($InstanceID,$radio);
SNS_Play($InstanceID)

?>

Und, kannst du mit dem Code etwas anfangen, Thorsten ?

Moin,

ich probiere gerade, mit SetGroup Gruppen zu setzen und zu löschen. Gibt es auch eine Möglichkeit, bei aktivierter Gruppe den Coordinator zu verschieben ?

derzeit habe ich das Problem, dass ich - wenn ich Sonos2 zu Sonos1 geaddet habe - nur die Sonos2 wieder aus dem Verbund nehmen kann. Ich würde aber gerne statt dessen auch mal Sonos1 aus dem Verbunde nehmen, dazu müsste aber Sonos2 erst zum Coordinator werden.

Grüße,
Tom

Hallo,

ich habe ein Problem. mit dem Sonos Modul, oder viel mehr mit meinen Sonos Komponenten. Ich bekomme sehr häufig Fehler im Log.
Diese beziehen sich immer auf mein Sonos im Wohnzimmer. Es handelt sich dabei um eine Gruppe aus PlayBar, Sub und zwei Play1, also das Sonos Surround System.


01.06.17 08:05:58*| PHP*| Error: Error: Maximum execution time of 30 seconds exceeded
   Error in Script C:\IPSymcon\modules\SymconSonos\Sonos\sonosAccess.php on Line 550
  134 in scripts\IPSLibrary\app\core\IPSLogger\IPSLogger.inc.php (call IPSLogger_Out)
   33 in scripts\IPSLibrary\app\core\IPSLogger\IPSLogger_PhpErrorHandler.inc.php (call IPSLogger_Err)
  121 in scripts\IPSLibrary\app\core\IPSLogger\IPSLogger_PhpErrorHandler.inc.php (call IPSLogger_PhpErrorHandler)
      in IPSLogger_PhpFatalErrorHandler


01.06.17 08:05:58*| ScriptEngine*| Ergebnis für Ereignis 12364
<br />
<b>Fatal error</b>:  Maximum execution time of 30 seconds exceeded in <b>C:\IPSymcon\modules\SymconSonos\Sonos\sonosAccess.php</b> on line <b>550</b><br />
Abort Processing during Fatal-Error: Maximum execution time of 30 seconds exceeded
   Error in Script C:\IPSymcon\modules\SymconSonos\Sonos\sonosAccess.php on Line 550

Ich weiss auch ehrlich gesagt nicht so richtig, wonach ich suchen soll.
Die Playbar ist auch noch das System welches alle anderen Sonos mit dem LAN verbindet, es ist direkt über einen Switch mit dem Router per LAN verbunden. Alle anderen Systeme nutzen das interne Sonos WLAN.

Ich kann auch leider nicht anders verkabeln, da an den anderen Stellen keine LAN Anschlüsse vorhanden sind.
Die Fehlermeldungen kommen auch, wenn gerade keine Wiedergabe stattfindet.

Hat jemand eine Idee, wonach ich suchen kann?

Gruß
Christian

Ich antworte mir mal selbst.

Ich habe noch als letzten Test mal alle Sonos Geräte vom Strom getrennt, und mit dem Master beginnende wieder eingeschaltet.

Jetzt scheinen die Fehler weg zu sein. Da hätte ich auch mal früher drauf kommen können.

Gruß
Christian

Ich bekomm das mit dem Dateipfad nicht zusammen.
Hab die Files auf meinen Raspberry liegen. Der Ordner lautet /home/pi/pi-share/xxx.mp3
Wie muss jetzt der genaue Pfad lauten, um Zugriff zu bekommen?
Hab jetzt alle möglichen Varianten durchprobiert, jedoch erhalte ich immer Fehlermeldungen.

Zum Beispiel:


SNS_PlayFiles(27852 /*[Audio\Sonos Wohnzimmer]*/, Array ("//home/pi/pi-share/Achtung_fehlender_Temperaturwert_vom_Bad.mp3"), 0);

ergibt:


Fatal error:  Uncaught exception 'Exception' with message 'Error during Soap Call: UPnPError s:Client 701 (ERROR_AV_UPNP_AVT_INVALID_TRANSITION)' in /var/lib/symcon/modules/SymconSonos/Sonos/sonosAccess.php:556
Stack trace:
#0 /var/lib/symcon/modules/SymconSonos/Sonos/sonosAccess.php(297): SonosAccess->processSoapCall('/MediaRenderer/...', 'urn:schemas-upn...', 'Play', Array)
#1 /var/lib/symcon/modules/SymconSonos/Sonos/module.php(478): SonosAccess->Play()
#2 /var/lib/symcon/scripts/__generated.inc.php(877): Sonos->PlayFiles(Array, 0)
#3 /var/lib/symcon/scripts/17524.ips.php(3): SNS_PlayFiles(27852, Array, 0)
#4 {main}
  thrown in /var/lib/symcon/modules/SymconSonos/Sonos/sonosAccess.php on line 556

Ich hab es auch schon mit der IP-Adresse vor dem eigentlichen Pfad probiert - funktioniert auch nicht.

Moin,
mach mal eine Netzwerkfreigabe auf dem Pi, und lege dort die mp3 ab.
Bei mir liegen mp3’s auf der Fritzboxfreigabe (USB-Speicher) und damit geht es :

"//192.168.1.1/fritz-box-7490/Musik/alarm-sirene.mp3"

Funktioniert auch nicht. Hab jetzt nochmals die Freigabe auf dem Samba-Laufwerk überprüft bzw. geändert. Über den Windows-Rechner kann ich auf die Ordnerstruktur zugreifen und auch die Files abspielen, über Sonos gehts nicht.

Hallo
Ich persoenlich benutze keine Freigaben sondern den Webserver von IPSymcon.
Ansagen gehen nach „…/webfront/user/SAPI/“ Ordner und Ausgabe dann mit

SNS_PlayFiles(xxxx, Array ("http://xxx.xxx.xxx.xxx:xx/user/SAPI/xxxx.mp3"), 0);  

Perfekt, das funktioniert jetzt - danke!!

Hallo,

ich habe vor kurzem 2 weitere Play1 zu meinem Sonos-System hinzugefügt, diese sind aber (noch) nicht in IPS integriert. Die anderen 6 Play1 aber schon. Ich bekomme alle paar Sekunden (!) folgende Meldungen (Ich meine, seit die anderen beiden zum System hinzugekommen sind):

22.06.2017 21:48:46*| PHP*| Error: Notice: Undefined variable: coordinatorInSonos
   Error in Script /var/lib/symcon/scripts/39359.ips.php on Line 41
  134 in IPSLibrary/app/core/IPSLogger/IPSLogger.inc.php (call IPSLogger_Out)
   44 in IPSLibrary/app/core/IPSLogger/IPSLogger_PhpErrorHandler.inc.php (call IPSLogger_Err)
   41 in 39359.ips.php (call IPSLogger_PhpErrorHandler)
22.06.2017 21:48:46*| VariableManager*| [Program\IPSLibrary\data\core\IPSLogger\IPSLogger\SingleOut_Msg] = <div style="color:#000000;background:#FF0000;">Error: Notice: Undefined variable: group
   Error in Script /var/lib/symcon/scripts/39359.ips.php on Line 42</div>

Das System wurde nach einem Update bereits neu gestartet, und auch alle mal gruppiert und die Gruppe wirder aufgelöst, aber die Meldungen blieben…?!?

Wie bekomme ich das gefixt?

Danke und vG…

Hallo
So auf die Schnelle wuerde ich sagen, das das SONOS-System die Speaker kennt und an IPSymcon
schickt die dann dort nicht gefunden werden und deshalb die Variable nicht erstellt wird.
Probier mal folgende Zeile in allen Scripten „_updateGrouping“ hinzufuegen an Zeile 27

$coordinatorInSonos = false;

Vermutlich wird dann das gleiche mit der Variablen $group passieren. Entsprechend dann hinzufuegen.