Sonos Steuerung

Problemlösungen und Hinweise von allgemeinem Interesse zur Haussteuerung mit HomeMatic

Moderator: Co-Administratoren

TonyDom
Beiträge: 31
Registriert: 01.12.2016, 22:57
Danksagung erhalten: 1 Mal

Re: Sonos Steuerung

Beitrag von TonyDom » 14.12.2016, 09:45

Hallo Koppenho,

ich habe den Thread 10 mal durchgelesen und durchsucht, ob nicht jemand seine Sonos auch mit Toslink am TV nutzt und evtl. die gleichen Probleme hat.

Ich habe sämtliche Downloads hier probiert und ganz bestimmt auch was du im Vorpost empfohlen hast. (So wild ist das nicht, das bisschen Kopieren und Anpassen vom Script)

Es funktioniert alles wie es soll, mit Ausnahme wenn der TV an ist, der bei mir immer über die Sonos via Toslink läuft.

Im Prinzip bin ich ja happy, weil es mit dem anderen Script geht!

Ich nutze das Addon wie folgt: Ich habe für das Bad eine Art Timer eingerichtet. Das Heizventil wird zuerst geboostet und dann aufgeheizt. Nach einer Stunde schaltet die Heizung vom Bad wieder ab. Und das Abschalten der Heizung kann man jetzt in der Sonos hören. GENIAL ... sagt sogar meine Frau .... und das will was heißen :)

Viele Grüße

shen
Ehrenmitglied
Beiträge: 753
Registriert: 14.07.2006, 19:24
Wohnort: Wegberg
Kontaktdaten:

Re: Sonos Steuerung

Beitrag von shen » 19.12.2016, 13:22

Hallo zusammen,

Aufgrund der aktuellen Rabatte habe ich mir auch einige Play:1 angeschafft :-)
Insbesondere wenn ich im Werkkeller Musik höre entgeht mir die Haustürklingel - da liegt es ja nahe, das akustisch über SONOS zu signalisieren. Der Klingelsignalsensor ist auch schon fertig gelötet und betriebsbereit - was mir fehlt, ist SONOS-Ansteuerung, die ich gerne über die hier vorgestellten Skripte auf einem meiner lokalen Webserver realisieren möchte, das scheint wohl aktuell die gängigste und zukunftssicherste Methode zu sein.

Was mir hier aber fehlt ist ein deutlicher Hinweis auf die jeweils aktuellsten Skripte - wir können wir das besser lösen? Es wäre schön, wenn die jeweils aktuellste Version im Ausgangsposting zu finden wäre - wer würde sich denn darum kümmern wollen?
Gruß
Stefan Hendricks (ehemaliger HomeMatic-Forum Betreiber)

virgin
Beiträge: 636
Registriert: 09.01.2013, 18:36
Wohnort: Leichlingen
Hat sich bedankt: 124 Mal
Danksagung erhalten: 5 Mal
Kontaktdaten:

Re: Sonos Steuerung

Beitrag von virgin » 19.12.2016, 14:06

Gute Idee! Du? :D

Ich glaube aber, das kann immer nur der , der den Fred erstellt hat.
Bernd

Benutzeravatar
Homoran
Beiträge: 8613
Registriert: 02.07.2013, 15:29
Wohnort: Köln
Danksagung erhalten: 4 Mal

Re: Sonos Steuerung

Beitrag von Homoran » 19.12.2016, 15:06

virgin hat geschrieben:Gute Idee! Du? :D
Ich glaube aber, das kann immer nur der , der den Fred erstellt hat.
Naja, Stefan kann schon einiges - muss er aber nicht!
shen hat geschrieben:Es wäre schön, wenn die jeweils aktuellste Version im Ausgangsposting zu finden wäre
dazu noch ein Hinweis:
auch der Ursprungscode sollte noch im Startposting enthalten sein, damit die anschließende Diskussion nicht den Sinn verliert.
zusätzlich dann der jeweils aktuelle code, deutlich als solcher markiert wäre optimal!

Gruß
Rainer
Alle meine Hinweise sind auf eigene Gefahr umzusetzen. Immer einen Fachmann zu Rate ziehen!

TonyDom
Beiträge: 31
Registriert: 01.12.2016, 22:57
Danksagung erhalten: 1 Mal

Re: Sonos Steuerung

Beitrag von TonyDom » 19.12.2016, 15:37

shen hat geschrieben:Was mir hier aber fehlt ist ein deutlicher Hinweis auf die jeweils aktuellsten Skripte - wir können wir das besser lösen? Es wäre schön, wenn die jeweils aktuellste Version im Ausgangsposting zu finden wäre - wer würde sich denn darum kümmern wollen?
Das wird nur der Ersteller von diesem Thread können, aber falls du wissen willst, was funktioniert .... bei mir funktioniert das .. http://trautner.net/547-sonos-mit-gira- ... ue-version

shen
Ehrenmitglied
Beiträge: 753
Registriert: 14.07.2006, 19:24
Wohnort: Wegberg
Kontaktdaten:

Re: Sonos Steuerung

Beitrag von shen » 19.12.2016, 17:55

Wir haben ja einige Moderatoren, die das auch könnten - vllt. ist ja einer von diesen selbst mit SONOS aktiv :)

Eine andere Möglichkeit wäre, dass derjenige, der sich darum kümmern würde, einfach ein neues Thema aufmacht mit einem neuen Startposting welches kurz und knackig die wesentlichen Infos und Skripte beinhaltet. Im Anschluss könnte die Moderation (oder ich) dann die beiden Themen zusammenführen, sprich dieses Thema in dem wir gerade sind dem neuen Thema hinten anhängen.
Gruß
Stefan Hendricks (ehemaliger HomeMatic-Forum Betreiber)

wuscheltuschel
Beiträge: 668
Registriert: 03.12.2012, 19:51
Hat sich bedankt: 7 Mal
Danksagung erhalten: 3 Mal

Re: Sonos Steuerung

Beitrag von wuscheltuschel » 26.12.2016, 02:56

bei mir funktioniert das .. http://trautner.net/547-sonos-mit-gira- ... ue-version
verstehe ich nicht, das ist doch für GIRA?

wäre wirklich schön wenn jemand das aktuelle Script verlinken könnte.

falls es überhaupt eines gibt welches aktuell funktioniert?

virgin
Beiträge: 636
Registriert: 09.01.2013, 18:36
Wohnort: Leichlingen
Hat sich bedankt: 124 Mal
Danksagung erhalten: 5 Mal
Kontaktdaten:

Re: Sonos Steuerung

Beitrag von virgin » 26.12.2016, 09:31

Hier noch einmal meine Sonos Skripte, die bei mir perfekt funktionieren. Vielleicht kann sie jemand an den Anfang des Freds setzen. Sie müssen natürlich individuell angepasst werden.

Frohe Weihnachten

PHPSonos.inc.php

Code: Alles auswählen

<?php
// URL to gen documentation on my (br) system http://192.168.0.5:82/user/PhpDocumentor/

/**
 * PHPSonos.inc.php
 *
 * PHPSonos class originally released as: Sonos PHP Script - Copyright: Michael Maroszek - Version: 1.0, 09.07.2009
 *
 * Wiki: {@link http://www.ip-symcon.de/wiki/PHPSonos PHPSonos IPS-WIKI }
 *
 * @author Michael Maroszek <office@ip-symcon.de> and many others
 * @version see date of edit
 * @package PHPSonos.inc.php
 * @copyright original 1.0 version Michael Maroszek; later additions if not otherwise stated are released to public domain
 */

/**
 * PHPSonos Class
 *
 * PHPSonos Class originally released as: Sonos PHP Script - Copyright: Michael Maroszek - Version: 1.0, 09.07.2009
 *
 * Wiki: {@link http://www.ip-symcon.de/wiki/PHPSonos PHPSonos IPS-WIKI }
 *
 * Die PHPSonos Klasse wurde von Paresy zuerst im Thread Einzelne Sonos Player ansteuern ver?ffentlicht und sp?ter in einer aktualisierten Fassung im Thread PHP Sonos (Klasse zum Ansteuern einzelner Player) als Klasse zur Verf?gung gestellt.
 *
 * Verschiedene IPS Benutzer haben die Klasse inzwischen erweitert oder im zuletzt genannten Thread Hinweise zum Handling ausgetauscht.
 *
 * Paresy released his first version of PHPsonos in this forum thread Einzelne Sonos Player ansteuern. He later build a class and rereleased his routines in this thread: PHP Sonos (Klasse zum Ansteuern einzelner Player).
 *
 * There is a growing community of sonos enthusiasts supporting and developing PHPSONOS - we share knowledge and developements in this thread PHP Sonos (Klasse zum Ansteuern einzelner Player)
 *
 *
 *
 * <br>
 * <b>Changelog:</b><br>
 * <pre>
 *
 * - andre added setter functions
 * - 110108  - br added comments based on UPNP information from devicespy;
 *  also added the function XMLsendPacket to get non filtered answers
 * - 110120 - br added Set and GetLEDState
 * - 110202 - br added GetZoneAttributes
 * - 110202 - br added GetZoneInfo
 * - 110203 - br added gestposinfo TrackURI (contains x-rincon of the zone master if we are slave)
 * - 110206 - br added AddMember(Rincon...) and RemoveMember(Rincon...)
 * - 110207 - br added RamptoVolume
 * - 110208 - br added calculation of Content-Length to some functions
 * - 110318 - br fiddled with Playmode (maybe fixed a bug)
 * - 110318 - br added Get and Set CrossfadeMode
 * - 110318 - br added SaveQueue
 * - 110328 - ta lun added GetPlaylist($value)
 * - 110328 - ta lun added GetImportedPlaylists()
 * - 110328 - ta lun added GetSonosPlaylists()
 * - 110328 - ta lun added GetCurrentPlaylist()
 * - 110328 - br corrected titel to title and other things...
 * - 110328 - br added optional parameter id to SaveQueue
 * - 110406 - br edited Seek to accept UPNP Unit parameter as option (sec. arg is Target then)
 * - 110406 - br edited GetPositionInfo to also reflect UPNP return value names
 * - 110406 - br fixed non valid soap request in seek()
 * - 110406 - br added return of CurrentURI and CurrentUriMetaData to Get (Current File or QUEUE)
            This info is needed to restart a queue, pl or radiostation
 * - 110407 - br consolidated SetRadio, SetQueue and SetAVTransportURI
            the two last now also support MetaData as optional, 2nd parameter; SetRadio supports the name of a radiostation as an optional second parameter
 * - 110529 - br GetMediaInfo now returns Radio station in the array, key is title
 * - 110529 - ta lun added browse functions
 * - 110529 - iamking added GetAlarmTime()
 * - 110529 - ta lun fixed misc bugs and GetAlarmTime() now returns an array
 * - 110530 - br edited Browse() to reflect upnp possibilities
 * - 110601 - br renamed GetAlarmtime to ListAlarms to reflect upnp Names
 * - 110601 - iamking improved ListAlarms - added ProgramURI, ProgramMetaData, PlayMode, Volume, IncludeLinkedZones
 * - 110614 - br added parameters to Browse / http://www.ip-symcon.de/forum/f53/php-sonos-klasse-ansteuern-einzelner-player-7676/index10.html#post120977
 * - 110627 - talun edited GetSonosPlaylists: urlencode file
 * - 110711 - br fixed Problems in SetAVTransportUri
 * - 110821 - br/talun edited Browse to return duration
 * - 110821 - br added GetAudioInputAttributes
 * - 110828 - br added Radiotime Radio Cover for GetPositionInfo (patching?in Raditiome Cover URI)
 * - 110901 - br shifted Radiotime Functions from getpositioninfo to new Function RadiotimeGetNowPlaying (returns array)
 * - 110905 - br fixed Bug in getpositioninfo for getting the actual Track in a playlist (quickfix)
 * - 110907 - br deleted, added and edited comment lines
 * - 110908 - br added phpdoc tags for documentation
 * - 110909 - br found sendpacket commented out in RemoveMember and reenabled the sending now (TEST?!)
 * - 110911 - br added phpdoc tags for documentation
 * - 110915 - br added PhpSonos API key/ partnerid for Intune (usable for ANYONE who uses the PHPSonos class noncommercial or commercial) - thanks to Ben@tunein for advocation and great support!
 *             Drop me a note if you are a PHPSonos developer and need access to documentation of tunein APIs.
 * - 110916 - br added GetCurrentTransportActions() which returns the currently valid actions (nearly always returns all actions "Play, Stop, Pause, Seek, Next, Previous" for me)...
 * - 110916 - br added Get and SetInvisible to make it possible to change visibilty for party mode or other things (kids should not see their player in the night *g)
 * - 110916 - br improved phpdoc tags
 * - 111021 - br added soap parameters to ramptovolume (function did not work anymore without)
 * - 111028 - br added parameters id and parentid to setradio (only very rare use for this)
 * - 111130 - br minor improvements: phpdoc tags
 * - 120205 - PeterChrisben/br improved phpdoc for setplaymode and gettransportsettings
 * </pre>
 *
 * <b>Links:</b><br>
 * {@link http://travelmarx.blogspot.com/2010/06/exploring-sonos-via-upnp.html }<br>
 * {@link http://travelmarx.blogspot.com/2011/01/extracting-sonos-playlist-simple-sonos.html }<br>
 * {@link http://opentools.homeip.net/dev-tools-for-upnp }<br>
 * {@link http://www.ip-symcon.de/forum/f53/php-sonos-klasse-ansteuern-einzelner-player-7676/ }<br>
 * {@link http://your.sonos.i.p:1400/status }<br>
 * {@link http://your.sonos.i.p1400/support/review }<br>
 * {@link http://play.er.i.p:1400/xml/zone_player.xml }<br>
 *
 * @author Michael Maroszek <office@ip-symcon.de> and many others
 * @version see date of edit
 * @package PHPSonos
 * @copyright original 1.0 version Michael Maroszek; later additions if not otherwise stated are released to public domain
 **/


class PHPSonos {
   private $address = "";
   public function __construct( $address ) {
      $this->address = $address;
// Maybe we could integrate/provide some more info here (ZoneAttr / Zoneinfo etc.) ?

   }


/*
 * urn:schemas-upnp-org:device:ZonePlayer:1 
 * http://play.er.i.p:1400/xml/zone_player.xml
 */

/*
 * urn:upnp-org:serviceId:AlarmClock
 *   Not fully implemented
 */
 
/**
 * Returns a list of alarms from sonos device
 *
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:ZonePlayer:1
 * - <b>WSDL:</b> http://play.er.i.p:1400/xml/zone_player.xml
 * - <b>Service:</b> urn:upnp-org:serviceId:AlarmClock
 *
 * @return Array
 *
 * @link http://www.ip-symcon.de/forum/f53/php-sonos-klasse-ansteuern-einzelner-player-7676/index9.html#post120731 Forum-Post
 */
 public function ListAlarms()
    {

$header='POST /AlarmClock/Control HTTP/1.1
SOAPACTION: "urn:schemas-upnp-org:service:AlarmClock:1#ListAlarms"
CONTENT-TYPE: text/xml; charset="utf-8"
HOST: '.$this->address.':1400';
$xml='<?xml version="1.0" encoding="utf-8"?> <s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<u:AlarmClock xmlns:u="urn:schemas-upnp-org:service:AlarmClock:1"/>
</s:Body>
</s:Envelope>';
$content=$header . '
Content-Length: '. strlen($xml) .'

'. $xml;

                $returnContent = $this->XMLsendPacket($content);
                $returnContent = substr($returnContent, stripos($returnContent, '<'));
        $returnContent = substr($returnContent, 0, strrpos($returnContent, '>') + 4);
        $returnContent = str_replace(array("<", ">", """, "&", "%3a", "%2f", "%25"), array("<", ">", "\"", "&", ":", "/", "%"), $returnContent);
        $xmlr = new SimpleXMLElement($returnContent);
        $liste = array();
        for($i=0,$size=count($xmlr);$i<$size;$i++)
        {
        $attr = $xmlr->Alarm[$i]->attributes();
            $liste[$i]['ID'] = (string)$attr['ID'];
            $liste[$i]['StartTime'] = (string)$attr['StartTime'];
            $liste[$i]['Duration'] = (string)$attr['Duration'];
            $liste[$i]['Recurrence'] = (string)$attr['Recurrence'];
            $liste[$i]['Enabled'] = (string)$attr['Enabled'];
            $liste[$i]['RoomUUID'] = (string)$attr['RoomUUID'];
            $liste[$i]['ProgramURI'] = (string)$attr['ProgramURI'];
            $liste[$i]['ProgramMetaData'] = (string)$attr['ProgramMetaData'];
            $liste[$i]['PlayMode'] = (string)$attr['PlayMode'];
            $liste[$i]['Volume'] = (string)$attr['Volume'];
            $liste[$i]['IncludeLinkedZones'] = (string)$attr['IncludeLinkedZones'];

        }
        return $liste;
     }
     
 /**
 * Updates an existing alarm
 *
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:ZonePlayer:1
 * - <b>WSDL:</b> http://play.er.i.p:1400/xml/zone_player.xml
 * - <b>Service:</b> urn:upnp-org:serviceId:AlarmClock
 * - <b>Returns:</b> None
 * - <b>NOTE:</b> fill in
 *
 * @param string $id             Id of the Alarm
 * @param string $startzeit       StartLocalTime
 * @param string $duration       Duration
 * @param string $welchetage       Recurrence 
 * @param string $an             Enabled? (true/false)
 * @param string $roomid         Room UUID
 * @param string $programm       ProgramUri
 * @param string $programmmeta   ProgramMetadata
 * @param string $playmode       PlayMode
 * @param string $volume          Volume
 * @param string $linkedzone       IncludeLinkedZones
 *
 * @return Void
 *
 * @link http://www.ip-symcon.de/forum/f53/php-sonos-klasse-ansteuern-einzelner-player-7676/index9.html#post120710 Forum-post
 */
public function UpdateAlarm($id, $startzeit, $duration, $welchetage, $an, $roomid, $programm, $programmeta, $playmode, $volume, $linkedzone)
{
    $payload = '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body><u:UpdateAlarm xmlns:u="urn:schemas-upnp-org:service:AlarmClock:1">
<ID>'.$id.'</ID>
<StartLocalTime>'.$startzeit.'</StartLocalTime>
<Duration>'.$duration.'</Duration>
<Recurrence>'.$welchetage.'</Recurrence>
<Enabled>'.$an.'</Enabled>
<RoomUUID>'.$roomid.'</RoomUUID>
<ProgramURI>'.htmlspecialchars($programm).'</ProgramURI>
<ProgramMetaData>'.htmlspecialchars($programmeta).'</ProgramMetaData>
<PlayMode>'.$playmode.'</PlayMode>
<Volume>'.$volume.'</Volume>
<IncludeLinkedZones>'.$linkedzone.'</IncludeLinkedZones>
</u:updateAlarm></s:Body></s:Envelope>';


$content='POST /AlarmClock/Control HTTP/1.1
CONNECTION: close
HOST: '.$this->address.':1400
CONTENT-LENGTH: '.strlen($payload).'
CONTENT-TYPE: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:AlarmClock:1#UpdateAlarm"

'.$payload;

        $this->sendPacket($content);
    }

   
/* urn:upnp-org:serviceId:AudioIn */
   // Not fully implemented
   
 /**
 * Get information of devices inputs
 *
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:ZonePlayer:1
 * - <b>WSDL:</b> http://play.er.i.p:1400/xml/zone_player.xml
 * - <b>Service:</b> urn:upnp-org:serviceId:AudioIn
 * - <b>Returns:</b> Array
 * - <b>NOTE:</b> fill in
 *
 * @return Array
 *
 * @link http://www.ip-symcon.de/forum/f53/php-sonos-klasse-ansteuern-einzelner-player-7676/index15.html#post131481 Forum-Post
 */
   public function GetAudioInputAttributes() // added br
   {

$header='POST /AudioIn/Control HTTP/1.1
SOAPACTION: "urn:schemas-upnp-org:service:AudioIn:1#GetAudioInputAttributes"
CONTENT-TYPE: text/xml; charset="utf-8"
HOST: '.$this->address.':1400';
$xml='<?xml version="1.0" encoding="utf-8"?>
<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<u:GetAudioInputAttributes xmlns:u="urn:schemas-upnp-org:service:AudioIn:1"/>
</s:Body>
</s:Envelope>';
$content=$header . '
Content-Length: '. strlen($xml) .'

'. $xml;

$returnContent = $this->XMLsendPacket($content);


      $xmlParser = xml_parser_create("UTF-8");
      xml_parser_set_option($xmlParser, XML_OPTION_TARGET_ENCODING, "ISO-8859-1");
      xml_parse_into_struct($xmlParser, $returnContent, $vals, $index);
      xml_parser_free($xmlParser);



      $AudioInReturn = Array();

      $key="CurrentName"; // Lookfor
      if ( isset($index[strtoupper($key)][0]) and isset($vals[ $index[strtoupper($key)][0] ]['value'])) {$AudioInReturn[$key] = $vals[ $index[strtoupper($key)][0] ]['value'];
      } else { $AudioInReturn[$key] = ""; }

      $key="CurrentIcon"; // Lookfor
      if ( isset($index[strtoupper($key)][0]) and isset($vals[ $index[strtoupper($key)][0] ]['value'])) {$AudioInReturn[$key] = $vals[ $index[strtoupper($key)][0] ]['value'];
      } else { $AudioInReturn[$key] = ""; }


      return $AudioInReturn; //Assoziatives Array
    }
 
   
/* urn:upnp-org:serviceId:DeviceProperties */


 /**
 * Reads Zone Attributes
 *
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:ZonePlayer:1
 * - <b>WSDL:</b> http://play.er.i.p:1400/xml/zone_player.xml
 * - <b>Service:</b> urn:upnp-org:serviceId:DeviceProperties
 * - <b>Returns:</b> Example:
 * <code> Array
 * (
 *  [CurrentZoneName] => Kxz Boxyz
 *  [CurrentIcon] => x-rincon-roomicon:office
 * )
 * </code>
 * @return Array
 *
 * @link http://www.ip-symcon.de/wiki/PHPSonos Wiki
 *
 **/

   public function GetZoneAttributes() // added br
   {
$header='POST /DeviceProperties/Control HTTP/1.1
SOAPACTION: "urn:schemas-upnp-org:service:DeviceProperties:1#GetZoneAttributes"
CONTENT-TYPE: text/xml; charset="utf-8"
HOST: '.$this->address.':1400';
$xml='<?xml version="1.0" encoding="utf-8"?>
<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<u:GetZoneAttributes xmlns:u="urn:schemas-upnp-org:service:DeviceProperties:1"/>
</s:Body>
</s:Envelope>';
$content=$header . '
Content-Length: '. strlen($xml) .'

'. $xml;

$returnContent = $this->XMLsendPacket($content);


      $xmlParser = xml_parser_create("UTF-8");
      xml_parser_set_option($xmlParser, XML_OPTION_TARGET_ENCODING, "ISO-8859-1");
      xml_parse_into_struct($xmlParser, $returnContent, $vals, $index);
      xml_parser_free($xmlParser);


      $ZoneAttributes = Array();

      $key="CurrentZoneName"; // Lookfor
      if ( isset($index[strtoupper($key)][0]) and isset($vals[ $index[strtoupper($key)][0] ]['value'])) {$ZoneAttributes[$key] = $vals[ $index[strtoupper($key)][0] ]['value'];
      } else { $ZoneAttributes[$key] = ""; }

      $key="CurrentIcon"; // Lookfor
      if ( isset($index[strtoupper($key)][0]) and isset($vals[ $index[strtoupper($key)][0] ]['value'])) {$ZoneAttributes[$key] = $vals[ $index[strtoupper($key)][0] ]['value'];
      } else { $ZoneAttributes[$key] = ""; }


      return $ZoneAttributes; //Assoziatives Array
    }

 /**
 * Reads Zone Information
 *
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:ZonePlayer:1
 * - <b>WSDL:</b> http://play.er.i.p:1400/xml/zone_player.xml
 * - <b>Service:</b> urn:upnp-org:serviceId:DeviceProperties
 * - <b>Returns:</b> Example:
 * <code> Array
 * (
 *   [SerialNumber] => 00-zz-58-32-yy-xx:5
 *    [SoftwareVersion] => 15.4-442xx
 *    [DisplaySoftwareVersion] => 3.5.x
 *    [HardwareVersion] => 1.16.3.z-y
 *    [IPAddress] => yyy.168.z.xxx
 *    [MACAddress] => 00:zz:58:32:yy:xx
 *    [CopyrightInfo] => ? 2004-2007 Sonos, Inc. All Rights Reserved.
 *    [ExtraInfo] => OTP: 1.1.x(1-yy-3-0.x)
 *)
 * </code>
 *
 * @return Array
 *
 * @link http://www.ip-symcon.de/wiki/PHPSonos Wiki
 */
   public function GetZoneInfo() // added br
   {
$header='POST /DeviceProperties/Control HTTP/1.1
SOAPACTION: "urn:schemas-upnp-org:service:DeviceProperties:1#GetZoneInfo"
CONTENT-TYPE: text/xml; charset="utf-8"
HOST: '.$this->address.':1400';
$xml='<?xml version="1.0" encoding="utf-8"?>
<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<u:GetZoneInfo xmlns:u="urn:schemas-upnp-org:service:DeviceProperties:1"/>
</s:Body>
</s:Envelope>';
$content=$header . '
Content-Length: '. strlen($xml) .'

'. $xml;

$returnContent = $this->XMLsendPacket($content);


      $xmlParser = xml_parser_create("UTF-8");
      xml_parser_set_option($xmlParser, XML_OPTION_TARGET_ENCODING, "ISO-8859-1"); 
      xml_parse_into_struct($xmlParser, $returnContent, $vals, $index);
      xml_parser_free($xmlParser);


      $ZoneInfo = Array();

      $key="SerialNumber"; // Lookfor
      if ( isset($index[strtoupper($key)][0]) and isset($vals[ $index[strtoupper($key)][0] ]['value'])) {$ZoneInfo[$key] = $vals[ $index[strtoupper($key)][0] ]['value'];
      } else { $ZoneInfo[$key] = ""; }

      $key="SoftwareVersion"; // Lookfor
      if ( isset($index[strtoupper($key)][0]) and isset($vals[ $index[strtoupper($key)][0] ]['value'])) {$ZoneInfo[$key] = $vals[ $index[strtoupper($key)][0] ]['value'];
      } else { $ZoneInfo[$key] = ""; }

      $key="SoftwareVersion"; // Lookfor
      if ( isset($index[strtoupper($key)][0]) and isset($vals[ $index[strtoupper($key)][0] ]['value'])) {$ZoneInfo[$key] = $vals[ $index[strtoupper($key)][0] ]['value'];
      } else { $ZoneInfo[$key] = ""; }

      $key="DisplaySoftwareVersion"; // Lookfor
      if ( isset($index[strtoupper($key)][0]) and isset($vals[ $index[strtoupper($key)][0] ]['value'])) {$ZoneInfo[$key] = $vals[ $index[strtoupper($key)][0] ]['value'];
      } else { $ZoneInfo[$key] = ""; }

      $key="HardwareVersion"; // Lookfor
      if ( isset($index[strtoupper($key)][0]) and isset($vals[ $index[strtoupper($key)][0] ]['value'])) {$ZoneInfo[$key] = $vals[ $index[strtoupper($key)][0] ]['value'];
      } else { $ZoneInfo[$key] = ""; }

      $key="IPAddress"; // Lookfor
      if ( isset($index[strtoupper($key)][0]) and isset($vals[ $index[strtoupper($key)][0] ]['value'])) {$ZoneInfo[$key] = $vals[ $index[strtoupper($key)][0] ]['value'];
      } else { $ZoneInfo[$key] = ""; }


      $key="MACAddress"; // Lookfor
      if ( isset($index[strtoupper($key)][0]) and isset($vals[ $index[strtoupper($key)][0] ]['value'])) {$ZoneInfo[$key] = $vals[ $index[strtoupper($key)][0] ]['value'];
      } else { $ZoneInfo[$key] = ""; }


      $key="CopyrightInfo"; // Lookfor
      if ( isset($index[strtoupper($key)][0]) and isset($vals[ $index[strtoupper($key)][0] ]['value'])) {$ZoneInfo[$key] = $vals[ $index[strtoupper($key)][0] ]['value'];
      } else { $ZoneInfo[$key] = ""; }


      $key="ExtraInfo"; // Lookfor
      if ( isset($index[strtoupper($key)][0]) and isset($vals[ $index[strtoupper($key)][0] ]['value'])) {$ZoneInfo[$key] = $vals[ $index[strtoupper($key)][0] ]['value'];
      } else { $ZoneInfo[$key] = ""; }


      return $ZoneInfo; //Assoziatives Array
    }

 /**
 * Sets the state of the white LED
 *
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:ZonePlayer:1
 * - <b>WSDL:</b> http://play.er.i.p:1400/xml/zone_player.xml
 * - <b>Service:</b> urn:upnp-org:serviceId:DeviceProperties
 *
 * @param string $state             true||false value or On / Off
 *
 * @return Boolean
 *
 * @link http://www.ip-symcon.de/wiki/PHPSonos Wiki
 */
   public function SetLEDState($state) // added br
   {
   if($state=="On") { $state = "On"; } else
      {   if($state=="Off") { $state = "Off"; } else {
            if($state) { $state = "On"; } else { $state = "Off"; }
         }
      }
      
$content='POST /DeviceProperties/Control HTTP/1.1
CONNECTION: close
HOST: '.$this->address.':1400
CONTENT-LENGTH: 250
CONTENT-TYPE: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:DeviceProperties:1#SetLEDState"

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:SetLEDState xmlns:u="urn:schemas-upnp-org:service:DeviceProperties:1"><DesiredLEDState>' .$state. '</DesiredLEDState><u:SetLEDState></s:Body></s:Envelope>';

      return (bool)$this->sendPacket($content);
   }

 /**
 * Gets the state of the white LED
 *
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:ZonePlayer:1
 * - <b>WSDL:</b> http://play.er.i.p:1400/xml/zone_player.xml
 * - <b>Service:</b> urn:upnp-org:serviceId:DeviceProperties
 *
 *
 * @return Boolean
 *
 * @link http://www.ip-symcon.de/wiki/PHPSonos Wiki
 */
   public function GetLEDState() // added br
   {

$content='POST /DeviceProperties/Control HTTP/1.1
CONNECTION: close
HOST: '.$this->address.':1400
CONTENT-LENGTH: 250
CONTENT-TYPE: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:DeviceProperties:1#GetLEDState"

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

      if ($this->sendPacket($content)=="On") { return(true); }else return(false);
   }


 /**
 * Sets ZP to visible or unvisable
 *
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:ZonePlayer:1
 * - <b>WSDL:</b> http://play.er.i.p:1400/xml/zone_player.xml
 * - <b>Service:</b> urn:upnp-org:serviceId:DeviceProperties
 * - <b>Returns:</b> True or False for invisble status
 * - <b>NOTE:</b> It is highly *NOT* recommended to try this function if you don?t know what it will do. Don?t cry if you miss a Zoneplayer!!
 *
 * @param string $state             integer true||false value or string True/ False
 *
 * @return Boolean
 *
 * @link http://www.ip-symcon.de/wiki/PHPSonos Wiki
 */
   public function SetInvisible($state) // added br 110916
   {
   if($state=="True") { $state = "True"; } else
      {   if($state=="False") { $state = "False"; } else {
            if($state) { $state = "True"; } else { $state = "False"; }
         }
  }

$content='POST /DeviceProperties/Control HTTP/1.1
CONNECTION: close
HOST: '.$this->address.':1400
CONTENT-LENGTH: 250
CONTENT-TYPE: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:DeviceProperties:1#SetInvisible"

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:SetInvisible xmlns:u="urn:schemas-upnp-org:service:DeviceProperties:1"><DesiredInvisible>' .$state. '</DesiredInvisible><u:SetInvisible></s:Body></s:Envelope>';

      return (bool)$this->sendPacket($content);
   }

 /**
 * Gets ZP invisible information
 *
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:ZonePlayer:1
 * - <b>WSDL:</b> http://play.er.i.p:1400/xml/zone_player.xml
 * - <b>Service:</b> urn:upnp-org:serviceId:DeviceProperties
 * - <b>Returns:</b> True or False for invisble status
 * - <b>NOTE:</b> If you miss a Zoneplayer try this!!
 *
 * @return Boolean
 *
 * @link http://www.ip-symcon.de/wiki/PHPSonos Wiki
 */
   public function GetInvisible() // added br 110916
   {

$content='POST /DeviceProperties/Control HTTP/1.1
CONNECTION: close
HOST: '.$this->address.':1400
CONTENT-LENGTH: 250
CONTENT-TYPE: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:DeviceProperties:1#GetInvisible"

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

      if ($this->sendPacket($content)=="1") { return(true); }else return(false);
   }



/* urn:upnp-org:serviceId:GroupManagement */


   function SubscribeZPGroupManagement($callback){ // added br
$content='SUBSCRIBE /GroupManagement/Event HTTP/1.1
HOST: '.$this->address.':1400
CALLBACK: <'.$callback.'>
NT: upnp:event
TIMEOUT: Second-300
Content-Length: 0

';
$this->sendPacket($content);
}

 /**
 * Adds a Member to a existing ZoneGroup
 * (a single player is also considered a existing group)
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:ZonePlayer:1
 * - <b>WSDL:</b> http://play.er.i.p:1400/xml/zone_player.xml
 * - <b>Service:</b>  urn:upnp-org:serviceId:GroupManagement
 * - <b>Returns:</b> array with CurrentTransportsettings and GroupUUIDJoined as keys
 *
 *
 * @param string $MemberID             LocalUUID/ Rincon of Player to add
 *
 * @return Array
 *
 * @link http://www.ip-symcon.de/wiki/PHPSonos Wiki
 */

   public function AddMember($MemberID) // added br
      {

$header='POST /GroupManagement/Control HTTP/1.1
SOAPACTION: "urn:schemas-upnp-org:service:GroupManagement:1#AddMember"
CONTENT-TYPE: text/xml; charset="utf-8"
HOST: '.$this->address.':1400';
$xml='<?xml version="1.0" encoding="utf-8"?><s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body><u:AddMember xmlns:u="urn:schemas-upnp-org:service:GroupManagement:1"><MemberID>' . $MemberID . '</MemberID>
</u:AddMember></s:Body></s:Envelope>';
$content=$header . '
Content-Length: '. strlen($xml) .'

'. $xml;


$returnContent = $this->XMLsendPacket($content);

      $xmlParser = xml_parser_create("UTF-8");
      xml_parser_set_option($xmlParser, XML_OPTION_TARGET_ENCODING, "ISO-8859-1");
      xml_parse_into_struct($xmlParser, $returnContent, $vals, $index);
      xml_parser_free($xmlParser);


      $ZoneAttributes = Array();

      $key="CurrentTransportSettings"; // Lookfor
      if ( isset($index[strtoupper($key)][0]) and isset($vals[ $index[strtoupper($key)][0] ]['value'])) {$ZoneAttributes[$key] = $vals[ $index[strtoupper($key)][0] ]['value'];
      } else { $ZoneAttributes[$key] = ""; }

      $key="GroupUUIDJoined"; // Lookfor
      if ( isset($index[strtoupper($key)][0]) and isset($vals[ $index[strtoupper($key)][0] ]['value'])) {$ZoneAttributes[$key] = $vals[ $index[strtoupper($key)][0] ]['value'];
      } else { $ZoneAttributes[$key] = ""; }


      return $ZoneAttributes; //Assoziatives Array
      // set AVtransporturi ist notwendig
    }


 /**
 * Removes a Member from an existing ZoneGroup
 * (a single player is also considered an existing group and the action will result in muting the player)
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:ZonePlayer:1
 * - <b>WSDL:</b> http://play.er.i.p:1400/xml/zone_player.xml
 * - <b>Service:</b>  urn:upnp-org:serviceId:GroupManagement
 * - <b>Returns:</b>  for now the sendPacketAnswer
 *
 * @param string $MemberID             LocalUUID/ Rincon of Player to remove
 *
 * @return Sring
 *
 * @todo br 20110909   return $this->sendPacket($content);  this Line was commented out; i dont understand why... changed this
 *
 * @link http://www.ip-symcon.de/wiki/PHPSonos Wiki
 */
      public function RemoveMember($MemberID) // added br

      {

$header='POST /GroupManagement/Control HTTP/1.1
SOAPACTION: "urn:schemas-upnp-org:service:GroupManagement:1#RemoveMember"
CONTENT-TYPE: text/xml; charset="utf-8"
HOST: '.$this->address.':1400';
$xml='<?xml version="1.0" encoding="utf-8"?><s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body><u:RemoveMember xmlns:u="urn:schemas-upnp-org:service:GroupManagement:1"><MemberID>' . $MemberID . '</MemberID>
</u:RemoveMember></s:Body></s:Envelope>';
$content=$header . '
Content-Length: '. strlen($xml) .'

'. $xml;
  return $this->sendPacket($content); 

    }





/* urn:upnp-org:serviceId:MusicServices */
   // Not implemented
/* urn:upnp-org:serviceId:SystemProperties */
   // Not implemented
/* urn:upnp-org:serviceId:ZoneGroupTopology */
   // Not implemented


/******************* urn:schemas-upnp-org:device:MediaRenderer:1 ***********

***************************************************************************/

/* urn:upnp-org:serviceId:RenderingControl */

 /**
 * Ramps Volume to $volume using $ramp_type ; different algorithms are possible
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaRenderer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b>  urn:upnp-org:serviceId:RenderingControl
 * - <b>Returns:</b> Function Should return Rampseconds but this is NOT implemented!
 * @todo Function Should return Rampseconds but this is NOT implemented!
 * @param string $ramp_type            Ramp_type<br>
 *   Ramps Volume to $volume using the Method mentioned in $ramp_type as string:<br>
 *   "SLEEP_TIMER_RAMP_TYPE" - mutes and ups Volume per default within 17 seconds to desiredVolume<br>
 *   "ALARM_RAMP_TYPE" -Switches audio off and slowly goes to volume<br>
 *   "AUTOPLAY_RAMP_TYPE" - very fast and smooth; Implemented from Sonos for the autoplay feature.<br>
 *
 * @param string $volume               DesiredVolume
 *
 * @return Void
 *
 *
 * @link http://www.ip-symcon.de/wiki/PHPSonos Wiki
 */
   public function RampToVolume($ramp_type, $volume) //added br // added soap parameters 20111021
   {


$header='POST /MediaRenderer/RenderingControl/Control HTTP/1.1
HOST: '.$this->address.':1400
CONTENT-TYPE: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:RenderingControl:1#RampToVolume"
';
$xml='<?xml version="1.0" encoding="utf-8"?><s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body><u:RampToVolume xmlns:u="urn:schemas-upnp-org:service:RenderingControl:1"><InstanceID>0</InstanceID><Channel>Master</Channel><RampType>'.$ramp_type.'</RampType><DesiredVolume>'.$volume.'</DesiredVolume>
<ResetVolumeAfter>false</ResetVolumeAfter><ProgramURI></ProgramURI>
</u:RampToVolume></s:Body></s:Envelope>';
$content=$header . 'Content-Length: '. strlen($xml) .'

'. $xml;


      return (int) $this->sendPacket($content);

   }
/* urn:upnp-org:serviceId:AVTransport */

 /**
 * TEST Function for MediaRenderAVT Callback and IPS Register Vars
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaRenderer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:schemas-upnp-org:service:AVTransport:1 none
 * - <b>Returns:</b> Sendpacket contents
 *
 * @param string $callback             CallbackURL Well gat a HTTP Callback at this URl (SOAP)
 * @return Void
 */

   function SubscribeMRAVTransport($callback){ // added br
$content='SUBSCRIBE /MediaRenderer/AVTransport/Event HTTP/1.1
HOST: '.$this->address.':1400
CALLBACK: <'.$callback.'>
NT: upnp:event
TIMEOUT: Second-300
Content-Length: 0

';
$this->sendPacket($content);
}

 /**
 * Save current queue off to sonos
 *
 * - <b>NOTE:</b> If you don?t set the id to the playlist?s id you want to edit, you?ll get duplicate playlists with the same name $title!!
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaRenderer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:schemas-upnp-org:service:AVTransport:1
 * - <b>Returns:</b> Sendpacket contents
 *
 *
 * @param string $title          Title of Playlist
 * @param string $id             Playlists ID (optional)
 *
 * @return string
 *
 * @link http://www.ip-symcon.de/wiki/PHPSonos Wiki
 */
    public function SaveQueue($title,$id="") // added br
    {

        $header='POST /MediaRenderer/AVTransport/Control HTTP/1.1
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#SaveQueue"
CONTENT-TYPE: text/xml; charset="utf-8"
HOST: '.$this->address.':1400';
$xml='<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body>
<u:SaveQueue xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><InstanceID>0</InstanceID><Title>'.$title.'</Title><ObjectID>'.$id.'</ObjectID></u:SaveQueue>
</s:Body>
</s:Envelope>';
$content=$header . '
Content-Length: '. strlen($xml) .'

'. $xml;

    $returnContent = $this->sendPacket($content);
   }

 /**
 * Get info on actual crossfademode
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaRenderer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:schemas-upnp-org:service:AVTransport:1
 * - <b>Returns:</b> Boolean
 *
 *
 * @return Boolean
 */
   public function GetCrossfadeMode() // added br
   {

$header='POST /MediaRenderer/AVTransport/Control HTTP/1.1
HOST: '.$this->address.':1400
CONTENT-TYPE: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#GetCrossfadeMode"
';
$xml='<?xml version="1.0" encoding="utf-8"?><s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body><u:GetCrossfadeMode xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><InstanceID>0</InstanceID>
</u:GetCrossfadeMode></s:Body></s:Envelope>';
$content=$header . 'Content-Length: '. strlen($xml) .'

'. $xml;

      return (bool)$this->sendPacket($content);
   }

 /**
 * Set crossfade to true or false
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaRenderer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:schemas-upnp-org:service:AVTransport:1
 * - <b>Returns:</b> Void; shoud return sendpacket return
 *
 * @param string $mode          Enable/ Disable = 1/0 (string) = true /false (boolean)
 *
 * @return Void
 *
 * @link http://www.ip-symcon.de/wiki/PHPSonos Wiki
 */
   public function SetCrossfadeMode($mode) // added br
   {


      if($mode) { $mode = "1"; } else { $mode = "0"; }
$header='POST /MediaRenderer/AVTransport/Control HTTP/1.1
HOST: '.$this->address.':1400
CONTENT-TYPE: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#SetCrossfadeMode"
';
$xml='<?xml version="1.0" encoding="utf-8"?><s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body><u:SetCrossfadeMode xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><InstanceID>0</InstanceID><CrossfadeMode>'.$mode.'</CrossfadeMode></u:SetCrossfadeMode></u:SetCrossfadeMode></s:Body></s:Envelope>';
$content=$header . 'Content-Length: '. strlen($xml) .'

'. $xml;

   $this->sendPacket($content);
      

   }
 /**
 * STOP Stops playback
 *
 * - <b>NOTE:</b> It is sometimes necessary to send a stop after removing a zone from a group
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaRenderer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:schemas-upnp-org:service:AVTransport:1
 * - <b>Returns:</b> Void
 * @todo return should be sendpacket contents
 *
 * @return Void
 */
   public function Stop()
   {
$content='POST /MediaRenderer/AVTransport/Control HTTP/1.1
CONNECTION: close
HOST: '.$this->address.':1400
CONTENT-LENGTH: 250
CONTENT-TYPE: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#Stop"

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

      $this->sendPacket($content);
   }


/**
 * PAUSE pauses playback
 *
 * - <b>NOTE:</b> It is NOT always possible to send a PAUSE command (so you may get an error)!!
 * Please look at the Soap Method GetCurrentTransportActions (which returns valid actions)
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaRenderer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:schemas-upnp-org:service:AVTransport:1
 * - <b>Returns:</b> Void
 * @todo return should be sendpacket contents
 *
 * @return Void
 */
   public function Pause()
   {
$content='POST /MediaRenderer/AVTransport/Control HTTP/1.1
CONNECTION: close
HOST: '.$this->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>';

      $this->sendPacket($content);
   }

/**
 * PLAY plays or continues playback
 *
 * - <b>NOTE:</b> It is sometimes necessary to send a play after messing with zonegroups and/or starting a new play on a new uri
 * Please look at the Soap Method GetCurrentTransportActions (which returns valid actions)
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaRenderer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:schemas-upnp-org:service:AVTransport:1
 * - <b>Returns:</b> Void; shoud be sendpacket contents
 *
 * @return Void
 */
   public function Play()
   {

$content='POST /MediaRenderer/AVTransport/Control HTTP/1.1
CONNECTION: close
HOST: '.$this->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>';

      $this->sendPacket($content);
   }
   
/**
 * NEXT
 *
 * - <b>NOTE:</b>  Please look at the Soap Method GetCurrentTransportActions (which returns valid actions)
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaRenderer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:schemas-upnp-org:service:AVTransport:1
 * - <b>Returns:</b> Void; shoud be sendpacket contents
 *
 * @return Void
 */
   public function Next()
   {
   
$content='POST /MediaRenderer/AVTransport/Control HTTP/1.1
CONNECTION: close
HOST: '.$this->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>';

      $this->sendPacket($content);
   }
   
/**
 * PREVIOUS
 *
 * - <b>NOTE:</b>  Please look at the Soap Method GetCurrentTransportActions (which returns valid actions)
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaRenderer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:schemas-upnp-org:service:AVTransport:1
 * - <b>Returns:</b> Void; shoud be sendpacket contents
 *
 * @return Void
 */
   public function Previous()
   {
   
$content='POST /MediaRenderer/AVTransport/Control HTTP/1.1
CONNECTION: close
HOST: '.$this->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>';

      $this->sendPacket($content);
   }
   
/**
 * SEEK
 *
 * - <b>NOTE:</b>  Please look at the Soap Method GetCurrentTransportActions (which returns valid actions)
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaRenderer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:schemas-upnp-org:service:AVTransport:1
 * - <b>Returns:</b> String; shoud be sendpacket contents as array
 *
 * @param string $arg1           Unit ("TRACK_NR" || "REL_TIME" || "SECTION")
 * @param string $arg2             Target (if this Arg is not set Arg1 is considered to be "REL_TIME and the real arg1 value is set as arg2 value)
 *
 * @return String
 */
   public function Seek($arg1,$arg2="NONE")
   {
// Abw?rtskompatibel zu Paresys Original sein // edited by br
   if ($arg2=="NONE"){
      $Unit="REL_TIME"; $position=$arg1;
   } else {$Unit=$arg1; $position=$arg2;}

 $header='POST /MediaRenderer/AVTransport/Control HTTP/1.1
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#Seek"
CONTENT-TYPE: text/xml; charset="utf-8"
CONNECTION: close
HOST: '.$this->address.':1400';
$xml='<?xml version="1.0" encoding="utf-8"?>
<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>'. $Unit .'</Unit><Target>'.$position.'</Target></u:Seek></s:Envelope></s:Body></s:Envelope>';
$content=$header . '
Content-Length: '. strlen($xml) .'

'. $xml;

    $returnContent = $this->sendPacket($content);



   }
   
/**
 * REWIND
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaRenderer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:schemas-upnp-org:service:AVTransport:1
 * - <b>Returns:</b> String
 * @todo should be sendpacket Return
 *
 * - <b>SOAP</b> this Functions calls seek REL_TIME with target set to 00:00:00
 * There is a also a function called previous.
 *
 * @return String
 */
   public function Rewind()
   {
   
$content='POST /MediaRenderer/AVTransport/Control HTTP/1.1
CONNECTION: close
HOST: '.$this->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>';

      $this->sendPacket($content);
   }
   
/**
 * Sets volume for a player
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaRenderer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:schemas-upnp-org:service:AVTransport:1
 * - <b>Returns:</b> String; sendpacket Return
 *
 *
 * @param string $volume          Volume in percent
 *
 * @return String
 */
   public function SetVolume($volume)
   {

$content='POST /MediaRenderer/RenderingControl/Control HTTP/1.1
CONNECTION: close
HOST: '.$this->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>';

      $this->sendPacket($content);
   }
   
/**
 * Gets current volume information from player
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaRenderer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:schemas-upnp-org:service:AVTransport:1
 * - <b>Returns:</b> String; sendpacket Return
 *
 * @return String
 */
   public function GetVolume()
   {

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

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

      return (int)$this->sendPacket($content);
   }
   
/**
 * Sets mute/ unmute for a player
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaRenderer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:schemas-upnp-org:service:AVTransport:1
 * - <b>Returns:</b> String; sendpacket Return
 *
 * @param string $mute           Mute unmute as (boolean)true/false or (string)1/0
 *
 * @return String
 */
   public function SetMute($mute)
   {

      if($mute) { $mute = "1"; } else { $mute = "0"; }

$content='POST /MediaRenderer/RenderingControl/Control HTTP/1.1
CONNECTION: close
HOST: '.$this->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>';

      $this->sendPacket($content);
   }
   
/**
 * Gets mute/ unmute status for a player
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaRenderer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:schemas-upnp-org:service:AVTransport:1
 * - <b>Returns:</b> String; sendpacket Return
 *
 * @return string
 */

   public function GetMute()
   {

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

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

      return (bool)$this->sendPacket($content);
   }
   

/**
 * Sets Playmode for a renderer (could affect more than one zone!)
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaRenderer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:schemas-upnp-org:service:AVTransport:1
 * - <b>Returns:</b> String; sendpacket Return
 * - <b>NOTE:</b>
 * <PRE>
 * NORMAL = SHUFFLE and REPEAT -->FALSE
 * REPEAT_ALL = REPEAT --> TRUE, Shuffle --> FALSE
 * SHUFFLE_NOREPEAT = SHUFFLE -->TRUE / REPEAT = FALSE
 * SHUFFLE = SHUFFLE and REPEAT -->TRUE </PRE>
 *
 * @param string $mode "NORMAL" || "REPEAT_ALL" || "SHUFFLE_NOREPEAT" || "SHUFFLE"
 *
 * @return String
 */
   public function SetPlayMode($mode)
   {

$content='POST /MediaRenderer/AVTransport/Control HTTP/1.1
CONNECTION: close
HOST: '.$this->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>';

      $this->sendPacket($content);
   }
   
/**
 * Gets transport settings for a renderer
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaRenderer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:schemas-upnp-org:service:AVTransport:1
 * - <b>Returns:</b> Array with "repeat" and "shuffle" as keys and true/false as value
 * - <b>NOTE:</b>
 * <PRE>
 * SOAP return sometimes is PLAYING; I don?t know what this means, maybe only Radio (see the code below).
 *
 * NORMAL = SHUFFLE and REPEAT -->FALSE
 * REPEAT_ALL = REPEAT --> TRUE, Shuffle --> FALSE
 * SHUFFLE_NOREPEAT = SHUFFLE -->TRUE / REPEAT = FALSE
 * SHUFFLE = SHUFFLE and REPEAT -->TRUE </PRE>
 *
 * @todo: what is PLAYING??? TAG_NOTE_BR
 *
 * @return Array
 */
   public function GetTransportSettings()
   {

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

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

      $returnContent = $this->sendPacket($content);

//   echo "\n===" . $this->address. "====\n" . $returnContent . "\n===\n";

      if (strstr($returnContent, "NORMAL") !== false) {
         return Array (
            "repeat" => false,
            "shuffle" => false
         );
      } elseif (strstr($returnContent, "REPEAT_ALL") !== false) {
         return Array (
            "repeat" => true,
            "shuffle" => false
         );   
      
      } elseif (strstr($returnContent, "SHUFFLE_NOREPEAT") !== false) {
         return Array (
            "repeat" => false,
            "shuffle" => true
         );

      } elseif (strstr($returnContent, "SHUFFLE") !== false) {
         return Array (
            "repeat" => true,
            "shuffle" => true
         );
      }



   /*   } elseif (strstr($returnContent, "PLAYING") !== false) {
         return Array (
            "repeat" => false,
            "shuffle" => true
         );
      } */

   }

/**
 * Gets transport settings for a renderer
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaRenderer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:schemas-upnp-org:service:AVTransport:1
 * - <b>Returns:</b> String (comma sep.) with available actions
 * - <b>NOTE:</b>
 *
 * @return String
 */
   public function GetCurrentTransportActions()
   {

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

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

      $returnContent = $this->sendPacket($content);

//   echo "\n===" . $this->address. "====\n" . $returnContent . "\n===\n";

      $ret=preg_replace("#(.*)<Actions>(.*?)\</Actions>(.*)#is",'$2',$returnContent);
      return $ret;

   }


/**
 * Gets transport settings for a renderer
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaRenderer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:schemas-upnp-org:service:AVTransport:1
 * - <b>Returns:</b> Array with "repeat" and "shuffle" as keys and true/false as value
 * - <b>NOTE:</b> SOAP return sometimes is PLAYING; I don?t know what this means, maybe only Radio (see the code below).
 *
 * @return Array
 */
   public function GetTransportInfo()
   {

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

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

      $returnContent = $this->sendPacket($content);
      
      if (strstr($returnContent, "PLAYING") !== false) {
         return 1;
      } elseif (strstr($returnContent, "PAUSED_PLAYBACK") !== false) {
         return 2;
      } elseif (strstr($returnContent, "STOPPED") !== false) {
         return 3;
      }
      
   }

/**
 * Gets Media Info
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaRenderer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:schemas-upnp-org:service:AVTransport:1
 * - <b>Returns:</b> 
 * <code>
 * Array    (
 * [CurrentURI] => http://192.168.0.2:10243/WMPNSSv4/1458092455/0_ezg1ODYxQzMwLTEyNzgtNDc0Ri05MkQ0LTQxNzE1MDQ0MjMyMX0uMC40.mp3
 * [CurrentURIMetaData] => <DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/">    <item id="{85861C30-1278-474F-92D4-417150442321}.0.4" restricted="0" parentID="4">        <dc:title>Car Crazy Cutie</dc:title>        <dc:creator>Beach Boys</dc:creator>        <res size="2753092" duration="0:02:50.000" bitrate="16000" protocolInfo="http-get:*:audio/mpeg:DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000" sampleFrequency="44100" bitsPerSample="16" nrAudioChannels="2" microsoft:codec="{00000055-0000-0010-8000-00AA00389B71}" xmlns:microsoft="urn:schemas-microsoft-com:WMPNSS-1-0/">http://192.168.0.2:10243/WMPNSSv4/1458092455/0_ezg1ODYxQzMwLTEyNzgtNDc0Ri05MkQ0LTQxNzE1MDQ0MjMyMX0uMC40.mp3</res>        <res duration="0:02:50.000" bitrate="16000" protocolInfo="http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=10;DLNA.ORG_CI=1;DLNA.ORG_FLAGS=01500000000000000000000000000000" sampleFrequency="44100" nrAudioChannels="1" microso
 * [title] => Car Crazy Cutie                         )
 *  </code>
 *
 * - <b>NOTE:</b> SOAP returns CurrentURIMetaData this has to be parsed 
 *
 * @return Array
 */

      public function GetMediaInfo()
   {

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

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

      $returnContent = $this->XMLsendPacket($content);

      $xmlParser = xml_parser_create("UTF-8");
      xml_parser_set_option($xmlParser, XML_OPTION_TARGET_ENCODING, "ISO-8859-1");
      xml_parse_into_struct($xmlParser, $returnContent, $vals, $index);
      xml_parser_free($xmlParser);

      $mediaInfo = Array();
   


      if (isset($vals[$index["CURRENTURI"][0]]["value"])) {
         $mediaInfo["CurrentURI"] = $vals[$index["CURRENTURI"][0]]["value"];
      } else {
         $mediaInfo["CurrentURI"] = "";
      }

      if (isset($vals[$index["CURRENTURIMETADATA"][0]]["value"])) {
         $mediaInfo["CurrentURIMetaData"] = $vals[$index["CURRENTURIMETADATA"][0]]["value"];
         
      // print_r($index);
      // print_r($vals);


                  $xmlParser = xml_parser_create("UTF-8");
                  xml_parser_set_option($xmlParser, XML_OPTION_TARGET_ENCODING, "ISO-8859-1");
                  xml_parse_into_struct($xmlParser, $mediaInfo["CurrentURIMetaData"], $vals, $index);
                  xml_parser_free($xmlParser);

    //print_r($index);
    //print_r($vals);

                  if (isset($index["DC:TITLE"]) and isset($vals[$index["DC:TITLE"][0]]["value"])) {
                     $mediaInfo["title"] = $vals[$index["DC:TITLE"][0]]["value"];
                  } else {
                     $mediaInfo["title"] = "";
                  }

      } else {
         $mediaInfo["CurrentURIMetaData"] = "";
      }
      return $mediaInfo;
   }

/**
 * Gets position info
 *
 * - <b>NOTE:</b> this is one of the most interesting and complex functions with most interesting informations! You may get radio and zonegroup info out of parsing this information!
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaRenderer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:schemas-upnp-org:service:AVTransport:1
 * - <b>Returns:</b> Example: 
 * <code> Array
 *  (
 *    [position] => 0:00:59
 *    [RelTime] => 0:00:59
 *    [duration] => 0:01:51
 *    [TrackDuration] => 0:01:51
 *    [URI] => http://zzz.yyy.0.x:10243/WMPNSSv4/1458092455/0_ezRENTU5NjFDLUE3MDctNDIwRC04NTc4LUFDODgxQTVFMzMxQX0uMC40.mp3
 *    [TrackURI] => http://192.168.0.x:10243/WMPNSSv4/1458092455/0_ezRENTU5NjFDLUE3MDctNDIwRC04NTc4LUFDODgxQTVFMzMxQX0uMC40.mp3
 *    [artist] => Beach Bxxx....
 *    [title] => Cher... What?
 *    [album] => Little Deuce...
 *    [albumArtURI] => http://zzz.168.y.xxx:1400/getaa?u=http://zzz.168.y.xxx:10243/WMPNSSv4/1458092455/0_ezRENTU5NjFDLUE3MDctNDIwRC04NTc4LUFDODgxQTVFMzMxQX0uMC40.mp3&v=279
 *    [albumArtist] => Beach xxx....
 *    [albumTrackNumber] => 5
 *    [streamContent] =>
 *    [trackURI] =>
 *    [Track] => 1
 *  ) </code>
 * 
 * @return Array
 */
   public function GetPositionInfo()
   {
$content='POST /MediaRenderer/AVTransport/Control HTTP/1.1
CONNECTION: close
HOST: '.$this->address.':1400
CONTENT-LENGTH: 272
CONTENT-TYPE: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#GetPositionInfo"

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

      $returnContent = $this->sendPacket($content);
   
      $position = substr($returnContent, stripos($returnContent, "NOT_IMPLEMENTED") - 7, 7);

      $returnContent = substr($returnContent, stripos($returnContent, '<'));
      $returnContent = substr($returnContent, 0, strrpos($returnContent, '>') + 4);
      $returnContent = str_replace(array("<", ">", """, "&", "%3a", "%2f", "%25"), array("<", ">", "\"", "&", ":", "/", "%"), $returnContent);
      
      
      $xmlParser = xml_parser_create("UTF-8");
      xml_parser_set_option($xmlParser, XML_OPTION_TARGET_ENCODING, "UTF-8");
      xml_parse_into_struct($xmlParser, $returnContent, $vals, $index);
      xml_parser_free($xmlParser);
   
      $positionInfo = Array ();
      
      $positionInfo["position"] = $position;
      $positionInfo["RelTime"] = $position;
      

      if (isset($index["RES"]) and isset($vals[$index["RES"][0]]["attributes"]["DURATION"])) {
         $positionInfo["duration"] = $vals[$index["RES"][0]]["attributes"]["DURATION"];
            $positionInfo["TrackDuration"] = $vals[$index["RES"][0]]["attributes"]["DURATION"];
      } else {
         $positionInfo["duration"] = "";
            $positionInfo["TrackDuration"] = "";
      }

      if (isset($index["RES"]) and isset($vals[$index["RES"][0]]["value"])) {
         $positionInfo["URI"] = $vals[$index["RES"][0]]["value"];
         $positionInfo["TrackURI"] = $vals[$index["RES"][0]]["value"];
      } else {
         $positionInfo["URI"] = "";
         $positionInfo["TrackURI"] = "";
      }
      
      if (isset($index["DC:CREATOR"]) and isset($vals[$index["DC:CREATOR"][0]]["value"])) {
         $positionInfo["artist"] = $vals[$index["DC:CREATOR"][0]]["value"];
      } else {
         $positionInfo["artist"] = "";
      }
      
      if (isset($index["DC:TITLE"]) and isset($vals[$index["DC:TITLE"][0]]["value"])) {
         $positionInfo["title"] = $vals[$index["DC:TITLE"][0]]["value"];
      } else {
         $positionInfo["title"] = "";
      }
      
      if (isset($index["UPNP:ALBUM"]) and isset($vals[$index["UPNP:ALBUM"][0]]["value"])) {
         $positionInfo["album"] = $vals[$index["UPNP:ALBUM"][0]]["value"];
      } else {
         $positionInfo["album"] = "";
      }
      
      if (isset($index["UPNP:ALBUMARTURI"]) and isset($vals[$index["UPNP:ALBUMARTURI"][0]]["value"])) {
         $positionInfo["albumArtURI"] = "http://" . $this->address . ":1400" . $vals[$index["UPNP:ALBUMARTURI"][0]]["value"];
      } else {
      
/*
               // Ask Radiotime (added br as a test)
               $mi=$this->GetMediaInfo();
            
               $station=preg_replace("#(.*)x-sonosapi-stream:(.*?)\?sid(.*)#is",'$2',$mi['CurrentURI']);
            //   echo "\n!!!!!!!!!!!!!!!!!!!!!!!!!!".$station."########\n";
               if (($station!="")and $station[0]=="s"){
                  $content = @file_get_contents("http://opml.radiotime.com/Describe.ashx?c=nowplaying&id=".$station."&partnerId=Sonos&serial=00-0E-58-25-41-12:4");
               //   echo "----". $content;
                  $albumArtURI=preg_replace("#(.*)<LOGO>(.*?)\</LOGO>(.*)#is",'$2',$content);
               //   echo $albumArtURI;
                  $positionInfo["albumArtURI"] = $albumArtURI;
               } else{
               
*/
                     $positionInfo["albumArtURI"] = "";
/*               }
*/
      }

      if (isset($index["R:ALBUMARTIST"]) and isset($vals[$index["R:ALBUMARTIST"][0]]["value"])) {
         $positionInfo["albumArtist"] = $vals[$index["R:ALBUMARTIST"][0]]["value"];
      } else {
         $positionInfo["albumArtist"] = "";
      }
      
      if (isset($index["UPNP:ORIGINALTRACKNUMBER"]) and isset($vals[$index["UPNP:ORIGINALTRACKNUMBER"][0]]["value"])) {
         $positionInfo["albumTrackNumber"] = $vals[$index["UPNP:ORIGINALTRACKNUMBER"][0]]["value"];
      } else {
         $positionInfo["albumTrackNumber"] = "";
      }
      
      if (isset($index["R:STREAMCONTENT"]) and isset($vals[$index["R:STREAMCONTENT"][0]]["value"])) {
         $positionInfo["streamContent"] = $vals[$index["R:STREAMCONTENT"][0]]["value"];
         
         
      } else {
         $positionInfo["streamContent"] = "";
      }
      // added br if this contains "rincon" we are slave to a coordinator mentioned in this field (otherwise path to the file is provided)!
      // implemented via second XMLsendpacket to not break michaels current code

   if (isset($index["RES"][0]) and isset($vals[($index["RES"][0])]["value"])) {
         $positionInfo["trackURI"] = $vals[($index["RES"][0])]["value"];

      } else {
         $returnContent = $this->XMLsendPacket($content);

         $xmlParser = xml_parser_create("UTF-8");
         xml_parser_set_option($xmlParser, XML_OPTION_TARGET_ENCODING, "ISO-8859-1");
         xml_parse_into_struct($xmlParser, $returnContent, $vals, $index);
         xml_parser_free($xmlParser);
     }
    
         if (isset($index["TRACKURI"][0]) and isset($vals[($index["TRACKURI"][0])]["value"])) {
         $positionInfo["trackURI"] = $vals[($index["TRACKURI"][0])]["value"];
         $positionInfo["TrackURI"] = $vals[($index["TRACKURI"][0])]["value"];
         } else {
            $positionInfo["trackURI"] = "";
         }
      
         // Track Number in Playlist
         $returnContent = $this->XMLsendPacket($content);

         $xmlParser = xml_parser_create("UTF-8");
         xml_parser_set_option($xmlParser, XML_OPTION_TARGET_ENCODING, "ISO-8859-1");
         xml_parse_into_struct($xmlParser, $returnContent, $vals, $index);
         xml_parser_free($xmlParser);

         if (isset($index["TRACK"][0]) and isset($vals[($index["TRACK"][0])]["value"])) {
         $positionInfo["Track"] = $vals[($index["TRACK"][0])]["value"];

         } else {
            $positionInfo["Track"] = "";
         }
   
      return $positionInfo;
   }


/**
 * Play Radio station
 *
 * - <b>NOTE:</b> This is only a SetAVTransportURI Wrapper to switch to a radio station
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaRenderer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:schemas-upnp-org:service:AVTransport:1
 * - <b>Returns:</b> Array with $radio and $ MetaData as key
 *
 * @param string $radio            radio url
 * @param string $Name            Name of station (optional, default IP-Symcon Radio)
 * @param string $id             ID of Station (optional, default R:0/0/0)
 * @param string $parentID           parentID (optional, default R:0/0)
 * @return array
 */
   public function SetRadio($radio,$Name="IP-Symcon Radio",$id="R:0/0/0",$parentID="R:0/0")
   { 
   $MetaData="<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="".$id."" parentID="".$parentID."" restricted="true"><dc:title>".$Name."</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>";

    $this->SetAVTransportURI($radio,$MetaData);

   }

/**
 * Sets Av Transport URI
 *
 * - <b>NOTE:</b> Main SOAP method to set play URI - this is the plain SetAVTransportURI
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaRenderer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:schemas-upnp-org:service:AVTransport:1
 * - <b>Returns:</b> sendpacket return
 *
 * @param string $tspuri      Transport URI
 * @param string $MetaData    (optional for MetaData)
 *
 * @return String
 */
   public function SetAVTransportURI($tspuri,$MetaData="")
   {

$content='POST /MediaRenderer/AVTransport/Control HTTP/1.1
CONNECTION: close
HOST: '.$this->address.':1400
CONTENT-LENGTH: '.(342+strlen(htmlspecialchars($tspuri))+strlen($MetaData)).'
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($tspuri).'</CurrentURI><CurrentURIMetaData>'.$MetaData.'.</CurrentURIMetaData></u:SetAVTransportURI></s:Body></s:Envelope>';

      $this->sendPacket($content);
   }


/**
 * Sets Queue
 *
 * - <b>NOTE:</b> This is only a Wrapper for setting a queue via SetAVTransportURI
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaRenderer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:schemas-upnp-org:service:AVTransport:1
 * - <b>Returns:</b> Void
 * @todo SHOULD return something else
 *
 * @param string $queue      transport URI or Queue
 * @param string $MetaData    (optional for MetaData)
 *
 * @return Void
 */
   public function SetQueue($queue,$MetaData="")
   {
    $this->SetAVTransportURI($queue,$MetaData);

   }

/**
 * Clears devices Queue
 *
 * - <b>NOTE:</b> This function clears the actual playing queue but not the actually selected playlist
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaRenderer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:schemas-upnp-org:service:AVTransport:1
 * - <b>Returns:</b> Sendpacket returns
 *
 * @return String
 */
   public function ClearQueue()
   {

$content='POST /MediaRenderer/AVTransport/Control HTTP/1.1
CONNECTION: close
HOST: '.$this->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>';

      $this->sendPacket($content);
   }

/**
 * Adds URI to Queue (not the Playlist!!)
 *
 * - <b>NOTE:</b> Works on queue
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaRenderer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:schemas-upnp-org:service:AVTransport:1
 * - <b>Returns:</b> Sendpacket returns
 *
 * @param string $file     Uri or Filename
 *
 * @return String
 */
   public function AddToQueue($file)
   {
   
$content='POST /MediaRenderer/AVTransport/Control HTTP/1.1
CONNECTION: close
HOST: '.$this->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>'.htmlspecialchars($file).'</EnqueuedURI><EnqueuedURIMetaData></EnqueuedURIMetaData><DesiredFirstTrackNumberEnqueued>0</DesiredFirstTrackNumberEnqueued><EnqueueAsNext>1</EnqueueAsNext></u:AddURIToQueue></s:Body></s:Envelope>';

      $this->sendPacket($content);
   }
   
/**
 * Removes track from queue (not the Playlist!!)
 *
 * - <b>NOTE:</b> Works on queue
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaRenderer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:schemas-upnp-org:service:AVTransport:1
 * - <b>Returns:</b> Sendpacket returns
 *
 * @param string $track  Tracknumber/id to remove from current sonos queue (!)
 *
 * @return string
 */
   public function RemoveFromQueue($track)
   {

$content='POST /MediaRenderer/AVTransport/Control HTTP/1.1
CONNECTION: close
HOST: '.$this->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>';

      $this->sendPacket($content);
   }
   
/**
 * Jumps directly to the track
 *
 * - <b>NOTE:</b> I think I never used this method (br) ... ever used direkt seek call. So note this is only a wrapper!
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaRenderer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:schemas-upnp-org:service:AVTransport:1
 * - <b>Returns:</b> Sendpacket returns
 *
 * @param string $track    Number/ID of the track to play in queue
 *
 * @return string
 */
   public function SetTrack($track)
   {
   
$content='POST /MediaRenderer/AVTransport/Control HTTP/1.1
CONNECTION: close
HOST: '.$this->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>';

      $this->sendPacket($content);
   }
   

/******************* // urn:schemas-upnp-org:device:MediaServer:1 ***********

***************************************************************************/

/* urn:upnp-org:serviceId:ContentDirectory */

/**
 * Returns an array with the songs of the actual sonos queue
 *
 * - <b>NOTE:</b> Wrapper for Browse
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaServer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:upnp-org:serviceId:ContentDirectory
 * - <b>Returns:</b> (String) Playlist ID
 *
 * @return String
 */
     public function GetCurrentPlaylist()
    {
        $header='POST /MediaServer/ContentDirectory/Control HTTP/1.1
SOAPACTION: "urn:schemas-upnp-org:service:ContentDirectory:1#Browse"
CONTENT-TYPE: text/xml; charset="utf-8"
HOST: '.$this->address.':1400';
$xml='<?xml version="1.0" encoding="utf-8"?>
<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<u:Browse xmlns:u="urn:schemas-upnp-org:service:ContentDirectory:1"><ObjectID>Q:0</ObjectID><BrowseFlag>BrowseDirectChildren</BrowseFlag><Filter></Filter><StartingIndex>0</StartingIndex><RequestedCount>1000</RequestedCount><SortCriteria></SortCriteria></u:Browse>
</s:Body>
</s:Envelope>';
$content=$header . '
Content-Length: '. strlen($xml) .'

'. $xml;

    $returnContent = $this->sendPacket($content);

        $returnContent = substr($returnContent, stripos($returnContent, '<'));
        $returnContent = substr($returnContent, 0, strrpos($returnContent, '>') + 4);
        $returnContent = str_replace(array("<", ">", """, "&", "%3a", "%2f", "%25"), array("<", ">", "\"", "&", ":", "/", "%"), $returnContent);

        $xml = new SimpleXMLElement($returnContent);
        $liste = array();
        for($i=0,$size=count($xml);$i<$size;$i++)
        {
            $aktrow = $xml->item[$i];
            $albumart = $aktrow->xpath("upnp:albumArtURI");
            $title = $aktrow->xpath("dc:title");
            $artist = $aktrow->xpath("dc:creator");
            $album = $aktrow->xpath("upnp:album");
            $liste[$i]['listid']=$i+1;
            if(isset($albumart[0])){
                $liste[$i]['albumArtURI']="http://" . $this->address . ":1400".(string)$albumart[0];
            }else{
                $liste[$i]['albumArtURI'] ="";
            }
            $liste[$i]['title']=(string)$title[0];
            if(isset($artist[0])){
                $liste[$i]['artist']=(string)$artist[0];
            }else{
                $liste[$i]['artist']="";
            }
            if(isset($album[0])){
                $liste[$i]['album']=(string)$album[0];
            }else{
                $liste[$i]['album']="";
            }
        }
return $liste;
}

/**
 * Returns an array with all sonos playlists
 *
 * - <b>NOTE:</b> Wrapper for Browse
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaServer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:upnp-org:serviceId:ContentDirectory
 * - <b>Returns:</b> Array with all Sonos Pl
 *
 * @return Array
 */
    public function GetSonosPlaylists()
    {
        $header='POST /MediaServer/ContentDirectory/Control HTTP/1.1
SOAPACTION: "urn:schemas-upnp-org:service:ContentDirectory:1#Browse"
CONTENT-TYPE: text/xml; charset="utf-8"
HOST: '.$this->address.':1400';
$xml='<?xml version="1.0" encoding="utf-8"?>
<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<u:Browse xmlns:u="urn:schemas-upnp-org:service:ContentDirectory:1"><ObjectID>SQ:</ObjectID><BrowseFlag>BrowseDirectChildren</BrowseFlag><Filter></Filter><StartingIndex>0</StartingIndex><RequestedCount>100</RequestedCount><SortCriteria></SortCriteria></u:Browse>
</s:Body>
</s:Envelope>';
$content=$header . '
Content-Length: '. strlen($xml) .'

'. $xml;

    $returnContent = $this->sendPacket($content);
    $returnContent = substr($returnContent, stripos($returnContent, '<'));
        $returnContent = substr($returnContent, 0, strrpos($returnContent, '>') + 4);
        $returnContent = str_replace(array("<", ">", """, "&", "%3a", "%2f", "%25"), array("<", ">", "\"", "&", ":", "/", "%"), $returnContent);

        $xml = new SimpleXMLElement($returnContent);
        $liste = array();
        for($i=0,$size=count($xml);$i<$size;$i++)
        {
            $attr = $xml->container[$i]->attributes();
            $liste[$i]['id'] = (string)$attr['id'];
            $title = $xml->container[$i];
            $title = $title->xpath('dc:title');
            $liste[$i]['title'] = (string)$title[0];
            $liste[$i]['typ'] = "Sonos";
           $liste[$i]['file'] = urlencode((string)$xml->container[$i]->res);

        }


return $liste;
    }

/**
 * Returns an array with all imported PL
 *
 * - <b>NOTE:</b> Wrapper for Browse
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaServer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:upnp-org:serviceId:ContentDirectory
 * - <b>Returns:</b> Array with all imported PL (Share, Mediaplayer, itunes....)
 *
 * @return Array
 */
    public function GetImportedPlaylists()
    {
        $header='POST /MediaServer/ContentDirectory/Control HTTP/1.1
SOAPACTION: "urn:schemas-upnp-org:service:ContentDirectory:1#Browse"
CONTENT-TYPE: text/xml; charset="utf-8"
HOST: '.$this->address.':1400';
$xml='<?xml version="1.0" encoding="utf-8"?>
<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<u:Browse xmlns:u="urn:schemas-upnp-org:service:ContentDirectory:1"><ObjectID>A:PLAYLISTS</ObjectID><BrowseFlag>BrowseDirectChildren</BrowseFlag><Filter></Filter><StartingIndex>0</StartingIndex><RequestedCount>100</RequestedCount><SortCriteria></SortCriteria></u:Browse>
</s:Body>
</s:Envelope>';
$content=$header . '
Content-Length: '. strlen($xml) .'

'. $xml;

    $returnContent = $this->sendPacket($content);
    $returnContent = substr($returnContent, stripos($returnContent, '<'));
        $returnContent = substr($returnContent, 0, strrpos($returnContent, '>') + 4);
       $returnContent = str_replace(array("<", ">", """, "&", "%3a", "%2f", "%25"), array("<", ">", "\"", "&", ":", "/", "%"), $returnContent);

        $xml = new SimpleXMLElement($returnContent);
        $liste = array();
        for($i=0,$size=count($xml);$i<$size;$i++)
        {
            $attr = $xml->container[$i]->attributes();
            $liste[$i]['id'] = (string)$attr['id'];
            $title = $xml->container[$i];
            $title = $title->xpath('dc:title');
            // br substring use cuts my playlist names at the 4th char
         
            $liste[$i]['title'] = (string)$title[0];
               $liste[$i]['title']=preg_replace("/^(.+)\.m3u$/i","\\1",$liste[$i]['title']);
            $liste[$i]['typ'] = "Import";
            $liste[$i]['file'] = (string)$xml->container[$i]->res;
        }


return $liste;
    }

/**
 * Returns an array with all songs of a specific Playlist
 *
 * - <b>NOTE:</b> Wrapper for Browse
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaServer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:upnp-org:serviceId:ContentDirectory
 * - <b>Returns:</b> Array with MetaData on the songs
 *
 * @param string $value Id of the playlist
 *
 * @return Array
 */
    public function GetPlaylist($value)
    {
        $header='POST /MediaServer/ContentDirectory/Control HTTP/1.1
SOAPACTION: "urn:schemas-upnp-org:service:ContentDirectory:1#Browse"
CONTENT-TYPE: text/xml; charset="utf-8"
HOST: '.$this->address.':1400';
$xml='<?xml version="1.0" encoding="utf-8"?>
<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<u:Browse xmlns:u="urn:schemas-upnp-org:service:ContentDirectory:1"><ObjectID>'.$value.'</ObjectID><BrowseFlag>BrowseDirectChildren</BrowseFlag><Filter></Filter><StartingIndex>0</StartingIndex><RequestedCount>1000</RequestedCount><SortCriteria></SortCriteria></u:Browse>
</s:Body>
</s:Envelope>';
$content=$header . '
Content-Length: '. strlen($xml) .'

'. $xml;

    $returnContent = $this->sendPacket($content);
    $xmlParser = xml_parser_create();
        $returnContent = substr($returnContent, stripos($returnContent, '<'));
        $returnContent = substr($returnContent, 0, strrpos($returnContent, '>') + 4);
        $returnContent = str_replace(array("<", ">", """, "&", "%3a", "%2f", "%25"), array("<", ">", "\"", "&", ":", "/", "%"), $returnContent);

        $xml = new SimpleXMLElement($returnContent);
        $liste = array();
        for($i=0,$size=count($xml);$i<$size;$i++)
        {
            $aktrow = $xml->item[$i];
            $albumart = $aktrow->xpath("upnp:albumArtURI");
            $title = $aktrow->xpath("dc:title");
            $artist = $aktrow->xpath("dc:creator");
            $album = $aktrow->xpath("upnp:album");
            $liste[$i]['listid']=$i+1;
            if(isset($albumart[0])){
                $liste[$i]['albumArtURI']="http://" . $this->address . ":1400".(string)$albumart[0];
            }else{
                $liste[$i]['albumArtURI'] ="";
            }
            $liste[$i]['title']=(string)$title[0];
            if(isset($interpret[0])){
                $liste[$i]['artist']=(string)$artist[0];
            }else{
                $liste[$i]['artist']="";
            }
            if(isset($album[0])){
                $liste[$i]['album']=(string)$album[0];
            }else{
                $liste[$i]['album']="";
            }
        }
return $liste;
    }

/**
 * Universal function to browse ContentDirectory
 *
 * - <b>NOTE:</b> please use upnp and sonos documentation to get an idea of the return
 *
 * - <b>Device:</b> urn:schemas-upnp-org:device:MediaServer:1
 * - <b>WSDL:</b> fill in
 * - <b>Service:</b> urn:upnp-org:serviceId:ContentDirectory
 * - <b>Returns:</b> Array with metadata; please use upnp and sonos documentation to get an idea of the return
 *
 * @param string $value    ObjectID 
 * @param string $meta     BrowseFlag
 * @param string $filter   Filter
 * @param string $sindex   SearchIndex
 * @param string $rcount   ResultCount
 * @param string $sc       SortCriteria
 *
 * @return Array
 */
     public function Browse($value,$meta="BrowseDirectChildren",$filter="",$sindex="0",$rcount="1000",$sc="")
    {

       switch($meta){
       case 'BrowseDirectChildren':
       case 'c':
       case 'child':
         $meta="BrowseDirectChildren";
       break;
       case 'BrowseMetadata':
       case 'm':
       case 'meta':
             $meta = "BrowseMetadata";
       break;
       default:
       return false;
      }
        $header='POST /MediaServer/ContentDirectory/Control HTTP/1.1
SOAPACTION: "urn:schemas-upnp-org:service:ContentDirectory:1#Browse"
CONTENT-TYPE: text/xml; charset="utf-8"
HOST: '.$this->address.':1400';
$xml='<?xml version="1.0" encoding="utf-8"?>
<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<u:Browse xmlns:u="urn:schemas-upnp-org:service:ContentDirectory:1"><ObjectID>'.htmlspecialchars($value).'</ObjectID><BrowseFlag>'.$meta.'</BrowseFlag><Filter>'.$filter.'</Filter><StartingIndex>'.$sindex.'</StartingIndex><RequestedCount>'.$rcount.'</RequestedCount><SortCriteria>'.$sc.'</SortCriteria></u:Browse>
</s:Body>
</s:Envelope>';
$content=$header . '
Content-Length: '. strlen($xml) .'

'. $xml;

    $returnContent = $this->sendPacket($content);
    $xmlParser = xml_parser_create();
        $returnContent = substr($returnContent, stripos($returnContent, '<'));
        $returnContent = substr($returnContent, 0, strrpos($returnContent, '>') + 4);
        $returnContent = str_replace(array("<", ">", """, "&", "%3a", "%2f", "%25"), array("<", ">", "\"", "&", ":", "/", "%"), $returnContent);

        $xml = new SimpleXMLElement($returnContent);
        $liste = array();
        for($i=0,$size=count($xml);$i<$size;$i++)
        {
            //Wenn Container vorhanden, dann ist es ein Browse Element
            //Wenn Item vorhanden, dann ist es ein Song.
            if(isset($xml->container[$i])){
                  $aktrow = $xml->container[$i];
                  $attr = $xml->container[$i]->attributes();
                  $liste[$i]['typ'] = "container";
             }else if(isset($xml->item[$i])){
               //Item vorhanden also nur noch Musik
                  $aktrow = $xml->item[$i];
                  $attr = $xml->item[$i]->attributes();
                  $liste[$i]['typ'] = "item";
            }else{
               //Fehler aufgetreten
               return;
            }
                  $id = $attr['id'];
                  $parentid = $attr['parentID'];
                  $albumart = $aktrow->xpath("upnp:albumArtURI");
                  $titel = $aktrow->xpath("dc:title");
                  $interpret = $aktrow->xpath("dc:creator");
                  $album = $aktrow->xpath("upnp:album");
                  if(isset($aktrow->res)){
                     $res = (string)$aktrow->res;
                     $liste[$i]['res'] = urlencode($res);

                   }else{
                      $liste[$i]['res'] = "leer";
                   }
                      $resattr = $aktrow->res->attributes();
                           if(isset($resattr['duration'])){
                         $liste[$i]['duration']=(string)$resattr['duration'];
                      }else{
                         $liste[$i]['duration']="leer";
                      }
                  if(isset($albumart[0])){
                   $liste[$i]['albumArtURI']="http://" . $this->address . ":1400".(string)$albumart[0];
                  }else{
                   $liste[$i]['albumArtURI'] ="leer";
                  }
                  $liste[$i]['title']=(string)$titel[0];
                  if(isset($interpret[0])){
                      $liste[$i]['artist']=(string)$interpret[0];
                  }else{
                     $liste[$i]['artist']="leer";
                  }
                  if(isset($id) && !empty($id)){
                      $liste[$i]['id']=urlencode((string)$id);
                  }else{
                      $liste[$i]['id']="leer";
                  }
                  if(isset($parentid) && !empty($parentid)){
                      $liste[$i]['parentid']=urlencode((string)$parentid);
                  }else{
                      $liste[$i]['parentid']="leer";
                  }
                    if(isset($album[0])){
                   $liste[$i]['album']=(string)$album[0];
                  }else{
                   $liste[$i]['album']="leer";
                  }

        }
return $liste;
    }

/***************************************************************************
            Radiotime / Tunein
***************************************************************************/

/**
 * 
 Get Now Playing information from Radiotime via opml
 *
 * - <b>NOTE:</b> it?s maybe better to use SOAP to get this information
 *
 * - <b>Device:</b>       -
 * - <b>WSDL:</b>       -
 * - <b>Service:</b>    -
 * - <b>Returns:</b> Array with Status, Version info and Logos
 *
 * @return Array
 */
 
// Note: Our partnerId is in here
public function RadiotimeGetNowPlaying() // added br
    {
    $list["version"] = "";
    $list["status"] = "";
    $list["logo"] = "";
    
    // Serial for Tunein is our MAC - prevents block / throttling (maybe we should shift this off)
    $zoneinfo=$this->GetZoneInfo($this->address);
    $serial=$zoneinfo['MACAddress'];

    
               // Get mi
               $mi=$this->GetMediaInfo();
               // Filter out station id
               $station=preg_replace("#(.*)x-sonosapi-stream:(.*?)\?sid(.*)#is",'$2',$mi['CurrentURI']);
         
            
               // Only Ask Radiotime / Tunein for valid stationids (!!)
               if (($station!="")and $station[0]=="s"){
                  // Ask with PHPSonos PartnerID and serial (mac)
                  $content = @file_get_contents("http://opml.radiotime.com/Describe.ashx?c=nowplaying&id=".$station."&partnerId=IAeIhU42&serial=".$serial);
                  // DEBUG DEEP ONLY
                  // echo "----". $content;
                  $list["version"]=preg_replace('#(.*)version="(.*?)\">(.*)#is','$2',$content);
                  $list["status"]=preg_replace('#(.*)<status>(.*?)\</status>(.*)#is','$2',$content);
               
                  
                  $list["outline"]=preg_replace('#(.*)<body>(.*)<outline type="text" text="(.*?)\" guide_id="(.*)\" key#is','$2',$content);
                  
               
                  $list["logo"]=preg_replace('#(.*)<LOGO>(.*?)\</LOGO>(.*)#is','$2',$content);
                  // TAG_DEBUG_DEEP for Intune-Throttling (or blocking!)
                  // echo "\n!!!!!!!!!!!!!!!!!INTUNE REQUEST EXECUTED!!!!!!!!!!!!!!\n";

               }
return $list;
      }


/***************************************************************************
            Helper / sendPacket
***************************************************************************/

/**
 * XMLsendPacket
 *
 * - <b>NOTE:</b> This function does send of a soap query and DOES NOT filter a xml answer
 * - <b>Returns:</b> Answer as XML
 *
 * @return Array
 */
   private function XMLsendPacket( $content )
   {
      $fp = fsockopen($this->address, 1400 /* Port */, $errno, $errstr, 10);
      if (!$fp)
          throw new Exception("Error opening socket: ".$errstr." (".$errno.")");
          
      fputs ($fp, $content);
      $ret = "";
      $buffer = "";
      while (!feof($fp)) {
         $buffer = fgets($fp,128);
      //   echo "\n;" . $buffer . ";\n"; //DEBUG
         $ret.= $buffer;
      }

      // echo "\n\nReturn:" . $ret . "!!\n";
      fclose($fp);

      if(strpos($ret, "200 OK") === false)
         throw new Exception("Error sending command: ".$ret);
      $array = preg_split("/\n/", $ret);
      
      return $array[count($array) - 1];
   }

/**
 * sendPacket - communicate with the device
 *
 * - <b>NOTE:</b> This function does send of a soap query and may filter xml answers
 * - <b>Returns:</b> Answer
 *
 * @return Array
 */
   function getHeaderData($header) { 
        $headerParts = preg_split("/\n/", $header); 
         
        $headerData = array(); 
         
        foreach($headerParts as $headerPart) { 
            $key_value = explode(':',$headerPart); 
            $headerData[trim($key_value[0])] = (isset($key_value[1]) ? trim($key_value[1]): ""); 
        } 
         
        return $headerData; 
    }  
   
   private function sendPacket( $content ) 
    { 
        $fp = fsockopen($this->address, 1400 /* Port */, $errno, $errstr, 10); 
        if (!$fp) 
            throw new Exception("Error opening socket: ".$errstr." (".$errno.")"); 

        fputs ($fp, $content); 

        $ret = ""; 
        while (!feof($fp)) { 
            $ret.= fgetss($fp,128); // filters xml answer 
        } 
        fclose($fp); 
         
        if(strpos($ret, "200 OK") === false) { 
             IPS_LogMessage ( "sendPacket", $ret); 
            throw new Exception("Error sending command: ".$ret); 
        } 
         
        // TAG_DEBUG_DEEP sendpacketdebug 
        //echo "sendPacketDebug: "; //DEBUG 
        //IPS_LogMessage("WHOLE",$ret); 
         
        $parts = preg_split("/\r\n\r\n/", $ret); // split to header und body 
        $header = $parts[0]; 
         
        $headerData = $this->getHeaderData($header); 
         
        if (isset($headerData["TRANSFER-ENCODING"]) && $headerData["TRANSFER-ENCODING"] === "chunked") { 
            $chunked = true;     
        } 
        else { 
            $chunked = false;  
        } 
         
        $body     = $parts[1]; 
         
        $array = preg_split("/\r\n/", $body); // split to header und body 

        if (count($array) > 0) { 
            $index = count($array) - 1; 
        } 
        else { 
            $index = null; 
        } 
         
        for ($i=0; $i < count($array); $i++) { 
            if (strpos($array[$i], '<DIDL') !== false) { 
                $index = $i; 
            } 
            else { 
                if (!ctype_xdigit(trim($array[$i]))) { // is not hex 
                    $array[$index] .= $array[$i]; 
                } 
            } 
        } 
        
        if ($index !== null) { 
                $returnContent = $array[$index]; 
        } 
        else { 
                $returnContent = $body; 
        } 
        return $returnContent; 
    }  

}

?>
und die sonos2.php

Code: Alles auswählen

<?php

#####################################################################################
#
# Version: 	0.4.7
# Datum: 	28.04.2014
# Veröffentlicht im Forum: http://homematic-forum.de
# Username: dzvo
# 
# Historie:
# ---------
# 0.4.6		Änderung an der Telefon Funktion. Die aktuelle Lautstärke wird gespeichert und nach beenden des Telefonates wider langsam angefahren
# 0.4.7		Änderung an der Telefon Funktion. Unterscheidung bei Radio wird nur Stumm geschaltet (damit der Stream nicht neu geladen wird und Werbung eingeblendet, bei MP3 auf Pause
#			beide Streamarten werden nun langsam eingeblendet auf vorheriger Lautstärke.
#
#
# AUFRUF (Beispiel)
# -----------------			
#
# http://XXX.XXX.XXX.XXX/sonos2.php?zonen=schlafzimmer&action=message&message=1&volume=50
#
#
#
# Bekannte Probleme:
# ------------------
# 
# 
# 
# Anmerkungen:
# ------------
# - Volumen kann angegeben werden muss jedoch nicht, wenn keine Angabe wird Standard Lautstärke (messagevolume) eingestellt
 
# 
# Grundlegender URL Aufbau:
# -------------------------
# sonos2.php?zonen=SONOSPLAYER&action=BEFEHL&BEFEHL=Option
# Beispiele:
# sonos2.php?zonen=buero&action=play              			 			-> Absielen Starten
# sonos2.php?zonen=buero&action=pause								-> Abspielen Pausieren
# sonos2.php?zonen=buero&action=next								-> Nächster Titel
# sonos2.php?zonen=buero&action=previous								-> Verheriger Titel
# sonos2.php?zonen=buero&action=mute&mute=false							-> Sonos Laut schalten - false
# sonos2.php?zonen=buero&action=mute&mute=true							-> Sonos Leise schalten - true
# sonos2.php?zonen=schlafzimmer&action=message&message=1&volume=75			-> Nachricht 1 anspielen mit Lautstärke 75
# sonos2.php?zonen=buero&action=titelinfo								-> einfache HTML Playlist Anzeige
# sonos2.php?zonen=buero&action=addmember&member=kueche						-> Zone Kueche zur Zone Buero hinzufügen
# sonos2.php?zonen=buero&action=removemember&member=kueche					-> Zone Kueche aus der Zone Buero entfernen
# sonos2.php?zonen=schlafzimmer&action=sonosplaylist&playlist=Einschlafmusik&volume=1
# sonos2.php?zonen=schlafzimmer&action=stop
#
#
# zonen=	(wohnzimmer,buero,bad,kueche,schlafzimmer)					-> kleinschreibung, keine Leer oder Sonderzeichen
#		
# action=							
#		play											-> Abspielen
#		pause											-> Pause
#		next											-> nachster Titel
#		previous										-> vorheriger Titel
# 		mute			(true,false)							-> Stumm schalten
#		rewind											-> Beginn des Titels
#		stop											-> Absielen beenden
#		toggle											-> Play / Pause umschalten
#		playmode		(normal,shuffle_norepeat,
#					repeat_all,shuffle)						-> Abspielmodus
#		crossfade		(0,1)								-> Titelübergang aus, aus
#		remove			(Nummer des Titels)						-> Titel aus der Playlist löschen
#		clearqueue										-> Playlist löschen
#		playqueue										-> Absielen (nach Radiohöhren) der aktuellen Playlist
#		volume			(0-100)							-> Lautstärke setzen
#		volumeup										-> Lautstärke um 3% erhöhen
#		volumedown										-> Lautstärke um 5% verringern
#		addMember		(&member=SONOSZONE)						-> weitere Zone der Vorhanden hinzufügen
#		removemember		(&member=SONOSZONE)						-> vorhandene Zone entfernen
#		nextradio										-> nächsten Radiosender aus der UNTEN stehenden Liste abspielen. Hat nichts mit der SONOS Radioplaylist zu tun
#		prevradio										-> verherigen Radiosender aus der UNTEN stehenden Liste absielen. Hat nichts mit der SONOS Radioplaylist zu tun
#		sonosplaylist		(&playlist=SONOS Playlist)					-> Abspielen einer SONOS Playlist
#		radioplaylist		(&playlist=SONOS Radio Playlist)				-> Radioliste unter "Meine Radiosender" im SONOS Gerät, hat nicht mit nextradio, prevradio zu tun
#					(&ambiente=an)						-> Zusätzliche Option, die verhindert das eine vorhandene Playlist durch einen Radiosender überschriben wird
#													   Einsetzbar z.B. wenn im Bad automatisch nach X Sec ein Radiosender angehen soll, jedoch mann vorher eine 
#													   eigene Playlist fürs Baden zusammen gestellt hat.
#		message		(&message=ZAHL&[volume=ZAHL])				-> Abspielen von Nachrichten z.B. ... 
#													   1.mp3 - Waschmaschiene ist ferig
#													   2.mp3 - Es hat geklingelt an der Tür
#													   3.mp3 -  ...
#		stopall										-> alle Zonen Musik beenden (Abwesenheit)							
#		telefon										-> Player wird angehalten und wieder abgespielt
#													   im Gegensatz zu toggle wird die Wiedergabe nicht automatisch
#													   gestartet, sondern nur wenn vorher im Abspielmodus war.
#		group											-> alle Zonen mit einander Verbinden, die angegebene Zone ist der Master
#		ungroup										-> Alle Zonen auftrennen, Playlist löschen, Lautstärke Standard, Zeiger auf Playlist
#		radiourl										-> Gibt die Radio Stram URL aus.
#
#		titelinfo
#		
#
#
#									
######## Anzupassender Bereich #######################################################

# Hier kommem die einzelnen Sonos Player rein "name_kleingeschrieben" => "IP Adresse des Players"
$sonoszone = array(	"name_kleingeschrieben" => "XXX.XXX.XXX.XXX",
					"name_kleingeschrieben" => "XXX.XXX.XXX.XXX",
					"name_kleingeschrieben"  => "XXX.XXX.XXX.XXX",
					"name_kleingeschrieben"  => "XXX.XXX.XXX.XXX",
					"name_kleingeschrieben" => "XXX.XXX.XXX.XXX");
					
# Hier können eigene Radio Sender definiert werden, welche bei nextradio oder prevradio angesteuert werden
# 
# An der Stelle kommt nur der Stationsname rein.
$radio_name = array ( 	"NDR 1 Niedersachsen",
							"ANTENNE BAYERN Chillout",
							"RTL Oldie");
					  
# und hier die URL zum Stationsnamen.
$radio_adresse = array ("x-rincon-mp3radio://ndr-ndr1-han-mp3.akacast.akamaistream.net/7/807/273766/v1/gnl.akacast.akamaistream.net/ndr_ndr1_han_mp3",
						"x-rincon-mp3radio://mp3channels.webradio.antenne.de/chillout",
						"x-rincon-mp3radio://81.92.237.118:8080/listen.pls");

# Speicherort der Nachrichten zur Durchsage
$messagespeicher = "//XXX.XXX.XXX.XXX/verzeichnis";   # Windows Backslash \\ und Slash \ in Pfadangaben durch // und / ersetzen ohne Slash am Ende

# Standardlautstärke wenn nichts anderes mit angegeben wurde
$stdvolume = 20;

# Standardwert für Lautstärkeeinstellen über "Volumeup" & "Volumedown"
$volumeup = 3; # Lautstärke um 3 % lauter
$volumedown = 5; # Lautstärke um 5% leiser

# Standardlautstärke wenn nichts anderes angegeben wurde für message durchsagen
$messagevolume = 40;

# Einstellungen zu Lautstärke
# Hier ist es möglich unterschiedliche Arten des Ansteigen der Lautstärke zu definieren
# z.B. sleep - für den Wecker / Musik morgens, damit dieser langsamm lauter wird
#
# 	"sleep" 	- von aktueller Lautstärke auf die Ziel Lautstärke ändernd, fest eingestellt in 17 Sekunden.
#	"alarm" 	- von 0 auf die Ziel Lautstärke ansteigend.
#	"auto" 		- von 0 auf die Ziel Lautstärke ansteigend, sehr schnell und gleichmäßig.
#
$rampto = "alarm";

######## Script Code #######################################################

$debug = 0;
 if($debug == 1) { echo "<pre><br>"; }

include("PHPSonos.inc.php");

if($debug == 1) { 
	include ("mp3info.php"); 
	}




if(is_numeric($_GET['volume']) && $_GET['volume'] >= 0 && $_GET['volume'] <= 100) {
echo $volume;
	$volume = $_GET['volume'];
	}
	else {
	$volume = $stdvolume;
	}

if(isset($_GET['rampto'])) {
		switch($_GET['rampto'])
		{
			case 'sleep';
				$rampto = "SLEEP_TIMER_RAMP_TYPE";
				break;

			case 'alarm';
				$rampto = "ALARM_RAMP_TYPE";
				break;

			case 'auto';
				$rampto = "AUTOPLAY_RAMP_TYPE";
				break;
		}
	}
	else {
		switch($rampto)
		{
			case 'sleep';
				$rampto = "SLEEP_TIMER_RAMP_TYPE";
				break;

			case 'alarm';
				$rampto = "ALARM_RAMP_TYPE";
				break;

			case 'auto';
				$rampto = "AUTOPLAY_RAMP_TYPE";
				break;
		}

	}

if(array_key_exists($_GET['zonen'], $sonoszone))
{ 
	$zonen = $_GET['zonen'];
	$sonos = new PHPSonos($sonoszone[$zonen]); //Sonos IPAdresse

	switch($_GET['action'])
	{
		  
		case 'play';
			if(count($sonos->GetCurrentPlaylist()) > 0) { ;
				$sonos->RampToVolume($rampto, $volume);
				$sonos->Play();
			}
			else
			{
				die("Keine Titel in der Playlist zum abspielen.");
			}
			break;
		
		case 'pause';
				$sonos->Pause();
			break;
		
		case 'next';
			$titelgesammt = $sonos->GetPositionInfo();
			$titelaktuel = $titelgesammt["Track"];
			$playlistgesammt = count($sonos->GetCurrentPlaylist());
						
			if ($titelaktuel < $playlistgesammt) {
			$sonos->Next();
			}
			else
			{
				die("Kein wieter Titel in der Playlist");
			}
			break;

		case 'previous';
				$sonos->Previous();
			break;  

		case 'rewind':
				$sonos->Rewind();
			break; 

		case 'mute';
			if($_GET['mute'] == 'false') {
				$sonos->SetMute(false);
			}
			else if($_GET['mute'] == 'true') {
				$sonos->SetMute(true);
			}
			else {
				die('Falscher Mute Parameter');
			}       
			break;
			
		case 'stop';
				$sonos->Stop();
			break;      
		  
		case 'toggle':
			if($sonos->GetTransportInfo() == 1)  {
				$sonos->Pause();
			}
			else  {
				$sonos->Play();
			}
			break;  

		case 'telefon':

			function read($raum) {
			
			if( !@$datei = fopen($raum .".txt","r+") ) { 
				# Fehlerbehandlung erstellen der Datei
					$dateineu = fopen($raum .".txt","w+");
					rewind($dateineu);
					fwrite($dateineu, "");
					fclose($dateineu);
				}
				# Datei existiert
				$datei = fopen($raum .".txt","r+");
				$zustand = fgets($datei, 10);
			return $zustand;
			}
			
			function write($raum, $zustandneu) {
				$dateischreiben = fopen("" . $raum .".txt","w+");
				rewind($dateischreiben);
				fwrite($dateischreiben, $zustandneu);
				fclose($dateischreiben);
			}
		

				
				if($debug==1) {
					echo "<br>Lautstärke: " . read($zonen . "-LS")."<br>";
					echo "Read: ".read($zonen)."<br>";
					echo "Transtort: " . $sonos->GetTransportInfo() . "<br>";
					echo "mute: " . $sonos->GetMute() . "<br>";
					echo "Quelle: ";
					$quelle = $sonos->GetMediaInfo();
					if ($quelle["CurrentURIMetaData"] != "" ) { echo "Radio<br>"; }
					if ($quelle["CurrentURIMetaData"] == "" ) { echo "MP3<br>"; }
					
					
				}

			# 1 = PLAYING
			# 2 = PAUSED_PLAYBACK
			# 3 = STOPPED
			
			if ($quelle["CurrentURIMetaData"] == "" && $sonos->GetTransportInfo() < 3 ) {
			# für MP3
			
				if(read($zonen) == 1 )  {
						# gemerkte Lautstärke einstellen
						$sonos->RampToVolume("ALARM_RAMP_TYPE", read($zonen . "-LS"));
						$sonos->Play();	
					write($zonen, 0);						
					}	
				
				if($sonos->GetTransportInfo() == 1 && read($zonen) == 0 )  {
						# Lautstärke merken
						write($zonen . "-LS", $sonos->GetVolume());
							$sonos->Pause();
					write($zonen, 1);
				}
			} # für MP3
			
			if ($quelle["CurrentURIMetaData"] != "" && $sonos->GetTransportInfo() == 1 ) {
			# für Radio
			
				if($sonos->GetMute() == 1 )  {
					$sonos->SetMute(false);
					# gemerkte lautstärke einstellen
					$sonos->RampToVolume("AUTOPLAY_RAMP_TYPE", read($zonen . "-LS"));
				write($zonen, 0);
				} else {
						
					if($sonos->GetMute == 0 )  {
						#Radio
						# Lautstärke merken
							write($zonen . "-LS", $sonos->GetVolume());
							$sonos->SetMute(true);
					write($zonen, 1);
					}	
				}			

				
				

			} # für Radio


		break;  

			
		case 'playmode';
		
			if( ($_GET['playmode'] == "normal") || ($_GET['playmode'] == "repeat_all") || ($_GET['playmode'] == "shuffle_norepeat") || ($_GET['playmode'] == "shuffle")  ) {
				$sonos->SetPlayMode(strtoupper($_GET['playmode']));
			}
			else {
				die('falscher PlayMode');
			}    
			break;           
	  
		case 'crossfade':
			if((is_numeric($_GET['crossfade'])) && ($_GET['crossfade'] == 0) || ($_GET['crossfade'] == 1)) { 
				$crossfade = $_GET['crossfade'];
			}
			else {
				die ("Falscher Playmode -> 0 = aus / 1 = an");
			}
				$sonos->SetCrossfadeMode($crossfade);
			break; 
		  
		case 'remove':
			if(is_numeric($_GET['remove'])) {
				$sonos->RemoveFromQueue($_GET['remove']);
			} 
			break;   
		
		case 'playqueue':
		
			$titelgesammt = $sonos->GetPositionInfo();
			$titelaktuel = $titelgesammt["Track"];
			$playlistgesammt = count($sonos->GetCurrentPlaylist());
						
			if ($titelaktuel < $playlistgesammt) {
			$sonos->SetQueue("x-rincon-queue:" . getRINCON($sonoszone[$zonen]) . "#0");
			$sonos->RampToVolume($rampto, $volume);
			$sonos->Play();
			}
			else {
				die("Keine Titel in der Playlist zum Abspielen.");
			}


			break;
		
		case 'clearqueue':
				$sonos->SetQueue("x-rincon-queue:" . getRINCON($sonoszone[$zonen]) . "#0");
				$sonos->ClearQueue();
			break;  
		  
		case 'volume':
			if(isset($volume)) {
				$sonos->SetVolume($volume);
			}
			else {
				die('falscher Wertebereich für das Volume');
			}
			break;  
		  
		case 'volumeup': 
			$volume = $sonos->GetVolume();
			if($volume < 100) {
				$volume = $volume + $volumeup;
				$sonos->SetVolume($volume);
			}      
			break;
			  
		case 'volumedown':
			$volume = $sonos->GetVolume();
			if($volume > 0) {
				$volume = $volume - $volumedown;
			$sonos->SetVolume($volume);
			}
			break;      

		case 'addmember':
			if ($debug == 1) {
				echo debug();
			}
			
			if($debug == 1) {
				echo "<pre>";
				echo "Member IP: " . $sonoszone[$_GET['member']] . "<br>";
				echo "Member RINCON: " . getRINCON($sonoszone[$_GET['member']]). "<br>";
				echo "</pre>";
			}
			
			if(isset($_GET['member'])) {
				$AddMember = $sonos->AddMember(getRINCON($sonoszone[$_GET['member']])); # Member Rincon
				$sonos = new PHPSonos($sonoszone[$_GET['member']]); //Slave Sonos ZP IPAddress
				$ret = $sonos->SetAVTransportURI("x-rincon:" . getRINCON($sonoszone[$zonen])); // Master Sonos ZP IPAddress
			  } 
			else {
				die('Die Zone konnte nicht gefunden werden.');
			  }
			
			if($debug==1) {			
			  echo zonenmaster($_GET['member']);
			}
			
		  break;

		case 'removemember':

			if(isset($_GET['member'])) {
			
				if($debug ==1) {
				echo "zonen: " . $zonen . "<br>";
				echo "member: " . $_GET['member'] . "<br>";
				}
				
				# wenn Member gleich Zone ist 

				
				if ($zonen == $_GET['member']) {
				die("Der Master kann sich selber nicht entfernen.");
				}
				
				
				# nachschauen ob die Zone überhaupt verbunden ist
				$master = zonenmaster($_GET['member']);
				
				if (isset($master)) {
				#	$RemoveMember = $sonos->RemoveMember(getRINCON($sonoszone[$_GET['member']])); # Member Rincon
					$sonos = new PHPSonos($sonoszone[$_GET['member']]); //Slave Sonos ZP IPAddress
					$sonos->SetAVTransportURI("");
				}
				else {
					die("Der Player ist nicht mir dem Master verbunden.");
				}

		  }
		   else  {
			die('Die Zone konnte nicht gefunden werden.');
		  }
		  break;
		  
		case 'nextradio':
		
			$radiosender = $sonos->GetPositionInfo();
			$senderuri = $radiosender["URI"];
			$radioanzahl = $result = count($radio_name);
			
			$senderaktuell = array_search($senderuri,  $radio_adresse);
			
			# Wenn nextradio aufgerufen wird ohne eine vorherigen Radiosender
			if( $senderaktuell == "" && $senderuri == "" || substr($senderuri,0,12) == "x-file-cifs:" ) {
				$senderaktuell = -1;
				}
			
				if ($senderaktuell < ($radioanzahl) ) {
					$sonos->SetRadio($radio_adresse[$senderaktuell + 1], $radio_name[$senderaktuell + 1]);
				}
				
				if ($senderaktuell == $radioanzahl - 1) {
					$sonos->SetRadio($radio_adresse[0], $radio_name[0]);
				}
				
			if( $debug == 1) {
					echo "Senderuri vorher: " . $senderuri . "<br>";
					echo "Sender aktuell: " . $senderaktuell . "<br>";
					echo "Radioanzahl: " .$radioanzahl . "<br>";
				}
			
			$sonos->RampToVolume($rampto, $volume);
			$sonos->Play();
		
		  break;

		case 'prevradio':
		
			$radiosender = $sonos->GetPositionInfo();
			$senderuri = $radiosender["URI"];
			$radioanzahl = $result = count($radio_name);
			$senderaktuell = array_search($senderuri, $radio_adresse);
			
			# Wenn prevradio aufgerufen wird ohne eine vorherigen Radiosender
			if( $senderaktuell == "" && $senderuri == "" || substr($senderuri,0,12) == "x-file-cifs:") {
					$sonos->SetRadio($radio_adresse[$radioanzahl], $radio_name[$radioanzahl]);
				}
			
				if ($senderaktuell <= ($radioanzahl - 1) ) {
					$sonos->SetRadio($radio_adresse[$senderaktuell - 1], $radio_name[$senderaktuell - 1]);
				}
				if ($senderaktuell == 0) {
					$sonos->SetRadio($radio_adresse[$radioanzahl - 1], $radio_name[$radioanzahl - 1]);
				}
				
				if( $debug == 1) {
					echo "Senderuri vorher: " . $senderuri . "<br>";
					echo "Sender aktuell: " . $senderaktuell . "<br>";
					echo "Radioanzahl: " .$radioanzahl . "<br>";
				}
			$sonos->RampToVolume($rampto, $volume);	
			$sonos->Play();
		
		  break;
		  
		case 'sonosplaylist':
			if($debug == 1) {
				echo $sonoszone[$zonen] . "<br>";
				echo getRINCON($sonoszone[$zonen]) . "<br>";	
			}
		
			
			if(isset($_GET['playlist'])) {
				$sonos->SetQueue("x-rincon-queue:" . getRINCON($sonoszone[$zonen]) . "#0"); 
				$playlist = $_GET['playlist'];
			}
			else {
			  die ("Keine Liste mit dem Namen gefunden.");
			}
		
		# Sonos Playlist ermitteln und mit übergebene vergleichen	
		$sonoslists=$sonos->GetSONOSPlaylists();

			$pleinzeln = 0;
			while ( $pleinzeln < count($sonoslists) ) {
				if (debug == 1) {
					echo "Playlist " . $pleinzeln . "<br>\n\n";
					echo "ID: " . $sonoslists[$pleinzeln]["id"] . "<br>\n";
					echo "Titel: " . $sonoslists[$pleinzeln]["title"] . "<br>\n";
					echo "Typ: " . $sonoslists[$pleinzeln]["typ"] . "<br>\n";
					echo "File: " . $sonoslists[$pleinzeln]["file"] . "<br>\n";
					echo urldecode($sonoslists[$pleinzeln]["file"]) . "<br>\n";
					echo "ausgewählte Liste: " . $liste . "<br>\n";
					echo "<br>\n";
				}
				
				if($playlist == $sonoslists[$pleinzeln]["title"]) {
					$plfile = urldecode($sonoslists[$pleinzeln]["file"]);

					$sonos->ClearQueue();
					$sonos->AddToQueue($plfile); //Datei hinzufügen
					$sonos->SetQueue("x-rincon-queue:". getRINCON($sonoszone[$zonen]) ."#0"); 
					$sonos->RampToVolume($rampto, $volume);
					$sonos->Play();
					$gefunden = 1;
						
				}
				$pleinzeln++;
				if (($pleinzeln == count($sonoslists) ) && ($gefunden != 1)) {
					die("Keine Liste mit dem Namen gefunden.");
				}
			}			
		  
		  break;

		case 'radioplaylist':
			
			if(isset($_GET['playlist'])) {
				$playlist = $_GET['playlist'];
			}
			else {
			  die ("Playlist (Radioname) vergessen mit anzugeben.");
			}
			
			$GetCurrentPlaylist = $sonos->GetCurrentPlaylist();
			if ($debug == 1) {
			echo "Anzahl:  " . count($GetCurrentPlaylist) . "<br>";
			echo "Transtort: " . $sonos->GetTransportInfo() . "<br>";
			}
			
			# Ist Abmiente gesetzt wird die vorhandene Playlist abgespielt und nicht durch das angegebene Radio überspielt.
			if(isset($_GET['ambiente']) && (count($GetCurrentPlaylist) > 0 )) {
			
				if($sonos->GetTransportInfo() == 1) {
					$sonos->Pause();
					}
					elseif ($sonos->GetTransportInfo() == 1) {
					$sonos->Stop();
					}
									
				$sonos->RampToVolume($rampto, $volume);	
				$sonos->Play();
			
			} 
			else {
			
			
				# Sonos Radio Playlist ermitteln und mit übergebene vergleichen	
				$radiolists = $sonos->Browse("R:0/0","c");
					if ($debug == 1) {
						echo "Playlist: >" . $playlist . "<<br>\n";
					}
					
				$rleinzeln = 0;
				while ( $rleinzeln < count($radiolists) ) {
					if ($debug == 1) {
					
						echo "Radioliste " . $rleinzeln . "<br>\n\n";
						echo "ID: " . $radiolists[$rleinzeln]["id"] . "<br>\n";
						echo "Titel: " . $radiolists[$rleinzeln]["title"] . "<br>\n";
						echo "Typ: " . $radiolists[$rleinzeln]["typ"] . "<br>\n";
						echo "File: " . $radiolists[$rleinzeln]["res"] . "<br>\n";
						echo urldecode($radiolists[$rleinzeln]["res"]) . "<br>\n";
				
						echo "ausgewählter Radiosender: >" .  urldecode($playlist) . "<<br>\n";
						echo "<br>\n";
					}
					$gefunden = false;
					
						$radio = urldecode($playlist);
						$sender = $radiolists[$rleinzeln]["title"];
					
							if ($radio == $sender) {
																
								$sonos->SetRadio(urldecode($radiolists[$rleinzeln]["res"]));
								$sonos->RampToVolume($rampto, $volume);
								$sonos->play();
								$gefunden = true;
							}
				$rleinzeln++;
				}
				if($gefunden == false) {
					die("Sender nicht in Sonos-Favoriten gefunden.");
				}
			
			} #ambiente
			
		break;
		
		case 'titelinfo':
		
			if($debug == 1) {
				echo debug();
			}

			$PositionInfo = $sonos->GetPositionInfo();
			$GetMediaInfo = $sonos->GetMediaInfo();

			$title = $PositionInfo["title"];
			$album = $PositionInfo["album"];
			$artist = $PositionInfo["artist"];
			$albumartist = $PositionInfo["albumArtist"];
			$reltime = $PositionInfo["RelTime"];
			$bild = $PositionInfo["albumArtURI"];
		
		
				echo'
					<table>
						<tr>
							<td><img src="' . $bild . '" width="200" height="200" border="0"></td>
							<td>
							Titel: ' . $title . '<br><br>
							Album: ' . $album . '<br><br>
							Artist: ' . $artist . '</td>
						</tr>
						<tr>
						<td>
						<a href="'.$_SERVER['SCRIPT_NAME'].'?zonen='.$zonen.'&action=previous" target="_blank">Zurück</a>
						<a href="'.$_SERVER['SCRIPT_NAME'].'?zonen='.$zonen.'&action=play" target="_blank">Abspielen</a>
						<a href="'.$_SERVER['SCRIPT_NAME'].'?zonen='.$zonen.'&action=pause" target="_blank">Pause</a>
						<a href="'.$_SERVER['SCRIPT_NAME'].'?zonen='.$zonen.'&action=stop" target="_blank">Stop</a>
						<a href="'.$_SERVER['SCRIPT_NAME'].'?zonen='.$zonen.'&action=next" target="_blank">Nächster</a>
						
					</table>
				';
					
			break;
		  
		case 'message':
			if(isset($_GET['message']) )
			{
				$message = $_GET['message'];
				
				if(isset($_GET['volume']) && is_numeric($_GET['volume']) && $_GET['volume'] >= 0 && $_GET['volume'] <= 100) {
					$volume = $_GET['volume'];
				}
				else
				{
					$volume = $messagevolume;
				}
			
				 # Einstellungen speichern
					$save_MediaInfo = $sonos->GetMediaInfo();
					$save_PositionInfo = $sonos->GetPositionInfo();
					$save_Mute =$sonos->GetMute();
					$save_Vol = $sonos->GetVolume();
					$save_Status = $sonos->GetTransportInfo();
					$save_TransportSettings = $sonos->GetTransportSettings();
					$save_GetCurrentPlaylist = $sonos->GetCurrentPlaylist();

					
					if ($debug == 1) {
						echo '<PRE>';
						echo '<br />GetPositionInfo:';
						print_r($save_PositionInfo);
						echo '<br />GetCurrentPlaylist:';
						#print_r ($save_GetCurrentPlaylist);
						echo "<br />Anzahl Playlist Lieder: " . count($save_GetCurrentPlaylist) . "<br />";
						echo '<br />GetMediaInfo:';
						print_r ($save_MediaInfo); // Radio
						echo '<br />GetMute:';
						print_r ($save_Mute);
						echo '<br />GetVolume:';
						print_r ($save_Vol);
						echo '<br />GetTransportInfo:';
						print_r ($save_Status);
						echo '<br />GetTransportSettings:';
						print_r ($save_TransportSettings);    
						echo '</PRE>';
					}

					# Es läuft eine Radiostation
					# Wenn Radio läuft, muss zuerst die Liste wieder aktiviert werden
					if (substr($save_PositionInfo["TrackURI"], 0, 17) == "x-rincon-mp3radio")
					{  
						# zum Wiederherstellen es lief ein Radio Sender
						$wiederherstellen = "Radio";
						$message_pos = count($save_GetCurrentPlaylist) + 1;
						$sonos->SetQueue("x-rincon-queue:" . getRINCON($sonoszone[$zonen]) . "#0"); //Playliste aktivieren
					}
					elseif (substr($save_PositionInfo["TrackURI"], 0, 11) == "x-file-cifs") // Es läuft eine Musikliste 
					{
						$wiederherstellen = "Playlist";
						$message_pos = count($save_GetCurrentPlaylist) + 1;
					}
					elseif ($save_PositionInfo["TrackURI"] == "" ) {
						
						# es wird keine Musik abgespielt, also einfach nur nachricht abspielen
						$message_pos = count($save_GetCurrentPlaylist) + 1;
					}
					
					$sonos->AddToQueue("x-file-cifs:" . $messagespeicher . "/" . $message . ".mp3");

					//Auf den neuen Track zeigen
					$sonos->SetTrack($message_pos);
					$sonos->SetMute(false);
					$sonos->SetVolume($volume);
					$sonos->Play();   // Abspielen

					$abort = false;

					# Prüfen ob Meldung zu ende gespielt ist
					do {
						# Infos zur Message einlesen
						$message_PositionInfo = $sonos->GetPositionInfo();
			
							if ($message_PositionInfo["RelTime"] == $message_PositionInfo["TrackDuration"] ) {
								if($debug == 1) {
								#	echo "message Laufzeit aktuell: " . $message_PositionInfo["RelTime"] . "<br>";
								#	echo "message Laufzeit gesammt: " . $message_PositionInfo["TrackDuration"] . "<br>";
								}
								sleep(7);
								$abort = true; // Message fertig
							}
					} # do
					
					while($abort == false);
					
							#Message wieder aus Queue entfernen
							$sonos->RemoveFromQueue($message_pos);
						
						# Wieder alten Zustand herstellen
						if ($wiederherstellen == "Playlist" ){
							
							// alte Playlist weiterspielen
							$sonos->SetTrack($save_PositionInfo["Track"]);
							$sonos->Seek($save_PositionInfo["RelTime"],"NONE");
							$sonos->SetVolume($save_Vol);
							$sonos->SetMute($save_Mute);
							
							# Wenn alte Playlist in Pause war dann Pause setzen an sonsten Play
							# save_Status //1 = PLAYING //2 = PAUSED_PLAYBACK //3 = STOPPED
							# $save_TransportSettings  repeat shuffle ...	
							
							# wenn Repeat oder Shuffle aktiviert ist und die Musik nicht läuft, 
							# muss die Pause gesetzt werden, da sonst die Musik anläuft
							if($save_Status != 1 && ($save_TransportSettings['shuffle'] == 1 || $save_TransportSettings['repeat'] == 1)) {
								$sonos->Pause();
								}  

							if ($save_Status == 1) {            
								  $sonos->Play();
								}
							if ($save_Status == 3 ) {
								$sonos->Stop();
								}
							
						}elseif ($wiederherstellen == "Radio" ){
							
							# je nach dem ob Radio vorhier Lief oder nicht Zustand wieder herstellen.
							# save_Status //1 = PLAYING //2 = PAUSED_PLAYBACK //3 = STOPPED
							# $save_TransportSettings  repeat shuffle ...	
							
							# alten Radiosender weiterspielen
							
								$sonos->SetRadio($save_PositionInfo["URI"], $save_MediaInfo["title"]);
								$sonos->SetVolume($save_Vol);
								$sonos->SetMute($save_Mute);
								
								if($save_Status == 1) {
									$sonos->Play();
							}
						}
				} 
			else
			{
				die ("Keine Nachricht, keine Lautstärke angegeben oder falsche Werte angegeben.");
			}
	
    break;
	
	case 'group':
		
		# Zonen zusamenfügen
			$masterrincon = getRINCON($sonoszone[$zonen]);
			$sonos->SetVolume($volume);
					
			foreach ($sonoszone as $zone => $ip) {
				
					if($zone != $_GET['zonen']) {
						$sonos = new PHPSonos($ip); 
						$sonos->SetVolume($volume);
						$sonos->SetAVTransportURI("x-rincon:" . $masterrincon); 
					}	
			}
		
	break;
		
	case 'ungroup':
		
			
		
		foreach($sonoszone as $zonen => $ip)
		{
			$sonos = new PHPSonos($sonoszone[$zonen]); //Sonos IPAdresse
			$sonos->SetQueue("x-rincon-queue:" . getRINCON($sonoszone[$zonen]) . "#0");
			$sonos->SetVolume($volume);
			$sonos->ClearQueue();
			$sonos->Stop();
		}
	
	
	break;
	
		case 'mp3':
		
			$mp3 = mp3info("mp3/whale.mp3");
			
			print_r($mp3);

			
			
	
	break;			
					
	
	# Debug Bereich ------------------------------------------------------
		case 'getmedianfo':
				echo '<PRE>';
				print_r($sonos->GetMediaInfo());
				echo '</PRE>';
			break;

		case 'getpositioninfo':
				echo '<PRE>';
				print_r($sonos->GetPositionInfo());
				echo '</PRE>';
			break;      

		case 'gettransportsettings':
				echo '<PRE>';
				print_r($sonos->GetTransportSettings());
				echo '</PRE>';
			break;   
		  
		case 'gettransportinfo':
			# 1 = PLAYING
			# 2 = PAUSED_PLAYBACK
			# 3 = STOPPED

				echo '<PRE>';
					print_r($sonos->GetTransportInfo());
				echo '</PRE>';
			break;        
		
		case 'getradiotimegetnowplaying':
				$radio = $sonos->RadiotimeGetNowPlaying();
				print_r($radio);
			break;
		  
		case 'getvolume':
				echo '<PRE>';
					print_r($sonos->GetVolume());
				echo '</PRE>';
			break;
		  
	
		case 'masterplayer':
		
			foreach ($sonoszone as $player => $ip) {

				$sonos = new PHPSonos($ip); //Slave Sonos ZP IPAddress
				$temp = $sonos->GetPositionInfo();

				if (substr($temp["TrackURI"], 0, 9) == "x-rincon:" ) {
					$masterrincon = substr($temp["TrackURI"], 9 ,24);
					}
				
				foreach ($sonoszone as $masterplayer => $ip) {
					if(getRINCON($ip) == $masterrincon) {
						echo "<br>" . $player . " -> ";
						echo "Master des Players: " . $masterplayer;
					}
				}
				$masterrincon = "";
			}
			break;
		
		case 'radiourl':
		
			$GetPositionInfo = $sonos->GetPositionInfo();
			echo "Die Radio URL lautet: " . $GetPositionInfo["URI"];
		
		break;



		  
	default:
       die("Dieser Befehl ist nicht bekannt. <br>sonos2.php?zonen=SONOSPLAYER&action=BEFEHL&BEFEHL=Option");


	} # switch
	
	
}
else {
	echo "Der Zonen ist nicht im anzupassen Bereich vorhanden.";
	}



 # Funktionen
 
 function getRINCON($zoneplayerIp) {
  $url = "http://" . $zoneplayerIp . ":1400/status/zp";
  $xml = simpleXML_load_file($url);  
  $uid = $xml->ZPInfo->LocalUID;
  return $uid;  
}


 function zonenmaster($member) {
		global $sonos, $sonoszone;
			
		foreach ($sonoszone as $player => $ip) {
			#echo "<br>" . $player;
			$sonos = new PHPSonos($ip); //Slave Sonos ZP IPAddress
			$temp = $sonos->GetPositionInfo();

			if (substr($temp["TrackURI"], 0, 9) == "x-rincon:" ) {
				$masterrincon = substr($temp["TrackURI"], 9 ,24);
				}
			
			foreach ($sonoszone as $masterplayer => $ip) {
				if(getRINCON($ip) == $masterrincon) {
					if ($member == $player) {
				#	echo "<br>" . $player . " -> ";
				#	echo "Master des Players: " . $masterplayer;
					return  $masterplayer;				
					}
				}
			}
			unset($masterrincon);
			unset($sonos);
		}
	
 }


 function debug() {
 
	global $sonos, $sonoszone;
 
	$GetPositionInfo = $sonos->GetPositionInfo();
	$GetMediaInfo = $sonos->GetMediaInfo();
	$GetTransportInfo = $sonos->GetTransportInfo();
	$GetTransportSettings = $sonos->GetTransportSettings();
	$GetCurrentPlaylist = $sonos->GetCurrentPlaylist();
	
	echo '<PRE>';
	echo '<br />GetPositionInfo:';
	print_r($GetPositionInfo);

	echo '<br />GetMediaInfo:';
	print_r ($GetMediaInfo); // Radio

	echo '<br />GetTransportInfo:';
	print_r ($GetTransportInfo);
	
	echo '<br />GetTransportSettings:';
	print_r ($GetTransportSettings);  
	
	echo '<br />GetCurrentPlaylist:';
	print_r ($GetCurrentPlaylist);
	echo '</PRE>';
}

 if($debug == 1) { echo "</pre>"; }




?>
Bernd

TonyDom
Beiträge: 31
Registriert: 01.12.2016, 22:57
Danksagung erhalten: 1 Mal

Re: Sonos Steuerung

Beitrag von TonyDom » 26.12.2016, 10:05

virgin hat geschrieben:Hier noch einmal meine Sonos Skripte, die bei mir perfekt funktionieren.
Hallo Virgin,

was genau funktioniert bei dir alles? Hast du auch eine Bar und steuerst die mit dem Fernseher über Toslink an?

Genau da habe ich nämlich Probleme. Bei TV hauts öfter nicht hin. Die Message kommt zwar wie gewünscht, die Sonos geht jedoch nicht immer wieder zurück und spielt TV.

Mal gehts, mal gehts nicht. Ich versuche jetzt nochmal das obige Script.

virgin
Beiträge: 636
Registriert: 09.01.2013, 18:36
Wohnort: Leichlingen
Hat sich bedankt: 124 Mal
Danksagung erhalten: 5 Mal
Kontaktdaten:

Re: Sonos Steuerung

Beitrag von virgin » 26.12.2016, 10:38

was genau funktioniert bei dir alles? Hast du auch eine Bar und steuerst die mit dem Fernseher über Toslink an?
Nein, habe ich nicht und kann daher auch nichts dazu sagen
Bernd

Antworten

Zurück zu „HomeMatic Tipps & Tricks - keine Fragen!“