Einzelne Sonos Player ansteuern

Eine verbesserte Version gibt es hier:
http://www.ip-symcon.de/forum/f52/php-sonos-klasse-ansteuern-einzelner-player-7676/#post63772

Da das Sonos Modul noch in der Pipeline hängt, habe ich ein kleines Script gebaut, welches die Grundfunktionen erlaubt.

Wichtig ist zu Wissen, dass das Script Fehlermeldungen wirft, wenn eine Zone verknüpft ist und nicht der Master angesteuert wird oder wenn eine unsinnige Aktion ausgeführt wird (z.B. Play, wenn keine Musik in der Playlist ist)

Die IP eures Players bekommt ihr über den Sonos Desktop Controller. Hilfe -> Über Sonos Desktop Controller


<?

//Sonos ZP IPAdresse
$address = "192.168.3.183";

if($IPS_SENDER == "Designer")
{
 $action = $IPS_COMPONENT; //IPSYMID Feld verwenden
}
else if($IPS_SENDER == "Variable")
{
 $action = $IPS_VALUE; //Per Variable getriggert
}
else //Aktion über Execute gestartet. Festgelegte Aktion starten
{
 $action = "Play"; //Pause, Play, Next, Previous, Rewind, SetVolume, SetPlayMode, SetMute, SetRadio, ClearQueue, AddToQueue, RemoveFromQueue, SetTrack
}

$volume = 25; //Nur bei SetVolume
$mute = 0; //Nur bei SetMute / 0 > Musik / 1 > kein Ton
$mode = "NORMAL"; //Nur Bei SetPlayMode / REPEAT_ALL, SHUFFLE, NORMAL
$track = 4; //Track Nummer zum ausählen/löschen

//Klassik Radio
$radio = "x-rincon-mp3radio://players.creacast.com/creacast/klassik/playlist.pls";
//NDR2
//$radio = "x-rincon-mp3radio://lsd.newmedia.tiscali-business.com/bb/redirect.lsc?content=live&media=ms&stream=ndr/live/ndr2.wma";

//Datei laden
$file = "x-file-cifs://ipsserver/Public/test.mp3";

//--- Nix verändern ab hier
$content_pause='POST /MediaRenderer/AVTransport/Control HTTP/1.1
CONNECTION: close
HOST: '.$address.':1400
CONTENT-LENGTH: 252
CONTENT-TYPE: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#Pause"

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:Pause xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><InstanceID>0</InstanceID></u:Pause></s:Body></s:Envelope>';

$content_play='POST /MediaRenderer/AVTransport/Control HTTP/1.1
CONNECTION: close
HOST: '.$address.':1400
CONTENT-LENGTH: 266
CONTENT-TYPE: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#Play"

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:Play xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><InstanceID>0</InstanceID><Speed>1</Speed></u:Play></s:Body></s:Envelope>';

$content_next='POST /MediaRenderer/AVTransport/Control HTTP/1.1
CONNECTION: close
HOST: '.$address.':1400
CONTENT-LENGTH: 250
CONTENT-TYPE: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#Next"

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:Next xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><InstanceID>0</InstanceID></u:Next></s:Body></s:Envelope>';

$content_previous='POST /MediaRenderer/AVTransport/Control HTTP/1.1
CONNECTION: close
HOST: '.$address.':1400
CONTENT-LENGTH: 258
CONTENT-TYPE: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#Previous"

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:Previous xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><InstanceID>0</InstanceID></u:Previous></s:Body></s:Envelope>';

$content_rewind='POST /MediaRenderer/AVTransport/Control HTTP/1.1
CONNECTION: close
HOST: '.$address.':1400
CONTENT-LENGTH: 296
CONTENT-TYPE: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#Seek"

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:Seek xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><InstanceID>0</InstanceID><Unit>REL_TIME</Unit><Target>00:00:00</Target></u:Seek></s:Body></s:Envelope>';

$content_setvolume='POST /MediaRenderer/RenderingControl/Control HTTP/1.1
CONNECTION: close
HOST: '.$address.':1400
CONTENT-LENGTH: 32'.strlen($volume).'
CONTENT-TYPE: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:RenderingControl:1#SetVolume"

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:SetVolume xmlns:u="urn:schemas-upnp-org:service:RenderingControl:1"><InstanceID>0</InstanceID><Channel>Master</Channel><DesiredVolume>'.$volume.'</DesiredVolume></u:SetVolume></s:Body></s:Envelope>';

$content_setmute='POST /MediaRenderer/RenderingControl/Control HTTP/1.1
CONNECTION: close
HOST: '.$address.':1400
CONTENT-LENGTH: 314
CONTENT-TYPE: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:RenderingControl:1#SetMute"

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:SetMute xmlns:u="urn:schemas-upnp-org:service:RenderingControl:1"><InstanceID>0</InstanceID><Channel>Master</Channel><DesiredMute>'.$mute.'</DesiredMute></u:SetMute></s:Body></s:Envelope>';

$content_setplaymode='POST /MediaRenderer/AVTransport/Control HTTP/1.1
CONNECTION: close
HOST: '.$address.':1400
CONTENT-LENGTH: '.(291+strlen($mode)).'
CONTENT-TYPE: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#SetPlayMode"

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:SetPlayMode xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><InstanceID>0</InstanceID><NewPlayMode>'.$mode.'</NewPlayMode></u:SetPlayMode></s:Body></s:Envelope>';

$content_setradio='POST /MediaRenderer/AVTransport/Control HTTP/1.1
CONNECTION: close
HOST: '.$address.':1400
CONTENT-LENGTH: '.(974+strlen(htmlspecialchars($radio))).'
CONTENT-TYPE: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI"

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:SetAVTransportURI xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><InstanceID>0</InstanceID><CurrentURI>'.htmlspecialchars($radio).'</CurrentURI><CurrentURIMetaData><DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:r="urn:schemas-rinconnetworks-com:metadata-1-0/" xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"><item id="R:0/0/0" parentID="R:0/0" restricted="true"><dc:title>IP-Symcon Radio</dc:title><upnp:class>object.item.audioItem.audioBroadcast</upnp:class><desc id="cdudn" nameSpace="urn:schemas-rinconnetworks-com:metadata-1-0/">SA_RINCON65031_</desc></item></DIDL-Lite></CurrentURIMetaData></u:SetAVTransportURI></s:Body></s:Envelope>';

$content_clearqueue='POST /MediaRenderer/AVTransport/Control HTTP/1.1
CONNECTION: close
HOST: '.$address.':1400
CONTENT-LENGTH: 290
CONTENT-TYPE: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#RemoveAllTracksFromQueue"

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:RemoveAllTracksFromQueue xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><InstanceID>0</InstanceID></u:RemoveAllTracksFromQueue></s:Body></s:Envelope>';

$content_addtoqueue='POST /MediaRenderer/AVTransport/Control HTTP/1.1
CONNECTION: close
HOST: '.$address.':1400
CONTENT-LENGTH: '.(438+strlen(htmlspecialchars($file))).'
CONTENT-TYPE: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#AddURIToQueue"

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:AddURIToQueue xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><InstanceID>0</InstanceID><EnqueuedURI>'.$file.'</EnqueuedURI><EnqueuedURIMetaData></EnqueuedURIMetaData><DesiredFirstTrackNumberEnqueued>0</DesiredFirstTrackNumberEnqueued><EnqueueAsNext>1</EnqueueAsNext></u:AddURIToQueue></s:Body></s:Envelope>';

$content_removefromqueue='POST /MediaRenderer/AVTransport/Control HTTP/1.1
CONNECTION: close
HOST: '.$address.':1400
CONTENT-LENGTH: '.(307+strlen($track)).'
CONTENT-TYPE: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#RemoveTrackFromQueue"

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:RemoveTrackFromQueue xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><InstanceID>0</InstanceID><ObjectID>Q:0/'.$track.'</ObjectID></u:RemoveTrackFromQueue></s:Body></s:Envelope>';

$content_settrack='POST /MediaRenderer/AVTransport/Control HTTP/1.1
CONNECTION: close
HOST: '.$address.':1400
CONTENT-LENGTH: '.(288+strlen($track)).'
CONTENT-TYPE: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#Seek"

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:Seek xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><InstanceID>0</InstanceID><Unit>TRACK_NR</Unit><Target>'.$track.'</Target></u:Seek></s:Body></s:Envelope>';

//send via socket
$port = 1400;

switch($action)
{
   case "Pause":
    $content = $content_pause;
    break;
   case "Play":
    $content = $content_play;
    break;
   case "Next":
    $content = $content_next;
    break;
   case "Previous":
    $content = $content_previous;
    break;
   case "Rewind":
    $content = $content_rewind;
    break;
   case "SetVolume":
    $content = $content_setvolume;
    break;
   case "SetMute":
    $content = $content_setmute;
    break;
   case "SetPlayMode":
    $content = $content_setplaymode;
    break;
   case "SetRadio":
    $content = $content_setradio;
    break;
   case "ClearQueue":
    $content = $content_clearqueue;
    break;
   case "AddToQueue":
    $content = $content_addtoqueue;
    break;
   case "RemoveFromQueue":
    $content = $content_removefromqueue;
    break;
   case "SetTrack":
    $content = $content_settrack;
    break;
}

$fp = fsockopen ($address, $port, $errno, $errstr, 10);
if (!$fp) {
    echo "$errstr ($errno)<br />
";
} else {
    fputs ($fp, $content);
    $ret = "";
    while (!feof($fp)) {
        $ret.= fgets($fp,128);
    }
    fclose($fp);
}

//Rückgabe
if(strpos($ret, "200 OK") === false)
{
 echo $ret;
} else {
 echo "OK";
}

?>

viel Spaß, paresy

Hallo paresy,

ich habe gerade mal dein Script für die Sonosplayer ausprobiert.
Funktioniert soweit perfekt. Aber kann man die MUTE Funktion auch noch über das Interface erreichen ? Ich weiß man kann die Lautstärke auf null stellen, dann ist aber leider die LED für MUTE nicht an. Ich benutze das als pseudo Ausschalter.

Gruß Sven

… wir haben ja am Sonntag Abend nichts anderes zu tun.
Wir schauen uns das sofort mal an …

MST

… so $action = „SetMute“ / $domute = 0; ist neu hinzugekommen.

Viel Spaß

MST

Immer wieder faszinierend:


$Differenz = $Uhrzeit_Problem_gepostet-$Uhrzeit_Problem_behoben;
echo $Differenz;

Resultat = 0:smiley:

MfG Thomas

OH man, das ging aber fix, und das am Sonntag.:smiley:

Werd es gleich mal einbauen

Danke Sven

Moin,

ich möchte folgenden stream ( http://www.radiobremen.de/stream/live.php?welle=bremenvier&media=ms ) über einen Taster starteten können, weil die Sonosteile anscheinende die Verbindung nicht neu aufbauen, wenn das DSL zwangsgetrennt wird. Aussdem macht der Controller in letzer Zeit öfter zicken.
Es gibt ja den Befehl StartRadio der „Welle Nord“ einschaltet. ich habe jetzt auch schon versucht an entsprechender Stelle meine Stream-Quelle einzutragen, aber es hat nicht funktioniert.

Hat jemand einen Tip für mich.

Gruß Sven

… o.g. Stream (Radio Bremen) läuft ohne Probleme und läßt sich so aus IPS starten:

//Sonos ZP IPAdresse
$address = "192.168.2.100"; // Bad  > alt 102
//$action = "Play"; //Pause, Play, SetVolume, Next, Previous, Rewind
$action = "Play";
$volume = 25; // nur bei SetVolume

//--- Nix verändern ab hier

MST

Ich komme leider erst heute dazu mich zu melden, da mein Internetprovider in den letzten Tage Probleme hatte :confused:.

Mit der Play Funktion geht es, der Stream wird neu aufgebaut. Ich hatte mich total auf die Startradio Funktion versteift. :rolleyes:
Kann man den mit der Startradio Funktion einzelne Funktion-Tasten für ein FS20-Taster erstellen ( Radiosender wechseln ) ??

Gruss Sven

… nein (zur Zeit) - Funktionen siehe:

//$action = „Play“; //Pause, Play, SetVolume, Next, Previous, Rewind

MST

Hallo,

gibt es jemand der die Sonos Geschichte im Einsatz hat ? Gibt es auch schon die Möglichkeit Sender per Taster von „außen zu wechseln?“

Gruß epogo

Ich habe die Sonos Play im Einsatz und bin sehr zufrieden. Über IP-Symcon steuer ich aber nur Pause, Play als Pseudo Ein/Aus Schalter.

Ein Umschalten auf einzelne Sender geht leider noch nicht.

Gruß Sven

Sonos scheint sich hier ja in mehrern Ecken bereits etabliert zu haben und ist - so denke ich - von den aktuellen Multiroomsystemen die weit verbreiteste, kommerzielle Variante.

Sind hier noch weitere integrative Schritte zu IPS hin geplant ? Könnte man nicht einiges vom iPhone Interface abkupfern, respektive von der PEARL Webintegration ?

Die Möglichkeit Zonen auch wieder gezielt aufzusplitten, zusammenzufügen und direkt auf die Titelsuche zugreifen zu können, oder auch gezielt Titel nur in einer Zone (egal ob vorher zusammengefügt oder nicht) abspielen zu können, wäre ein Riesen-Plus !

Dann könnte Sonos in Verbindung mit IPS auch als Medium für Informationsnachrichten dienen, wie Wetter oder Statusmeldungen.


Wenn sich hier ein findiger Entwickler mit auseinander setzen möchte, bin ich gern bereit Ihm für die Entwicklungszeit eine Sonos Komponente zur Verfügung zu stellen !

IPS Informationen, wie zum Beispiel Alarmmeldungen oder Anruferinformationen auf den Sonos wieder zugeben, das währe natürlich er hammer.

Gruß Sven

Hi,

das Script funktioniert bei meinen Sonos-Payern für Play und Pause super.

Allerdings wird bei Next und Previous die angehängte Fehlermeldung gezeigt.

Wie kann ich das Problem lösen bzw. welche Infos werden benötigt?

Gruß

Jimmy

Sonos Fehler.jpg

Liebe IP-Symcon Entwickler,

Besteht in naechster Zeit die Chance, dass noch mehr SONOS Funktionen
(z.B. Quellen Wahl / Line-In) in IP Symcon implementiert werden ?

Dies waere sehr hilfreich, da damit die Sprachausgabe verwendet werden
koennte.

Ein Vergleich der Implementierung von Play etc. mit dem Pearl Skript
sonos.pl der alle gewuenschten Funktionen unterstuetzt
Sonos Web Controller
hat mich leider nicht weitergebracht da ich mich zu wenig mit Pearl,
Upnp etc. auskenne.

Vielen Dank,

Thom/bapou

Hallo,

Empfehlung von paresy: Mit Wireshark gucken was das original App von Sonos versendet und einfach wie im vorhandenen Skript an den Controller schicken. So hat er es bei sich zu Hause auch gemacht.

Hallo Horst,

vielen Dank fuer den Tipp.
Ich habe mir Wireshark heruntergeladen und werde schauen
was ich machen kann.

Gruss
Thom

Höchst interessant ! Das hätte ich auch gern !

Interessant wäre natürlich auch die Rückmeldung bzw. auch das zu sehen was die iPhone App anzeigt (Napster, HDD, Radio) und nicht nur Kommandos senden zu können.

Hallo,

der Tip von Horst funktioniert sehr gut.

Mit Wireshark kann man den Datenverkehr gut abfangen, und aus diesem die benötigten Befehle bauen.

So habe ich es ungefähr gemacht:
Sonos Desktop Controller installieren
Wireshark installieren

-Wireshark Caption starten
-mit dem Sonos Desktop Controller die Sonos Geräte bedienen.

Nun das Ergebniss analysieren.

Im mittleren Fenster in Wireshark kann man die zweite Zeile aufklappen (Ethernet …), dann sieht man das Ziel der Packete „Destination“. Dort zeigen die entsprechenden Packete bei mir Sonos_… als Ziel.
Man kann dan nach den Sonos Befehlen Filtern, indem man in mit
der rechten Maustaste das Destination Feld als Filter kopiert („Copy as Filter“)
und dann oben in das Filter Feld einträgt.

Wenn man die gewünschten Befehle gefunden hat:

Im mittleren Fenster
rechte Maustaste
>Copy
> Bytes (printable text only)

dieses dann in den vorhandenen Skript einfügen.

Ich kann nun mit IP-Symcon auf LineIn umschalten (dort habe ich den IP-Symcon Rechner angeschlossen) und den SONOS Wecker stellen. Da sich noch installationsabhängige Parameter
(z.B. die ID des Raumes, der Name des Line-in Gerätes etc.) in den Kommandos befinden macht es wenig Sinn diese hier zu zeigen bevor ich die einzelnen Parameter verstanden habe.

Gruss

bapou/thom