PHP Sonos (Klasse zum Ansteuern einzelner Player)

Hmmm… hat das schon mal jemand probiert!? Würde es ja gerne mal testen, leider liegt mein Sonosplayer sauber verpackt im Lager!! :mad:

Denke aber nicht das das Funzt…sonst hätte Paresy das doch schon längst gemacht!!! :wink:

Hallo,

ich integriere gerade Michaels/ von Andre erweitere Klasse bei mir und habe dabei natürlich in diesem Thread und bei Schablones Code gewildert.
Ich versuche den Code möglichst allgemeingültig zu machen.
Vielen Dank an BBernhard für den Hinweis zu seiner Chromoflex Setup-Routine. :smiley:

Die weiteren Ideen zum Sonos-Handling hier im Thread versuche ich dann auch noch allgemeingültig einzubauen und bei zuviel Zeit eine Anleitung zu bauen. :wink:

Vielleicht hilft Euch mein Teil zum Anlegen der Variablen schon mal, so dass Ihr diese nicht manuell anlegen müsst
(nicht gefunde Funktionen stammen aus
BBernhards Chromoflex Setup
oder meinen br_ips_libs):

 <?
/* Customized for br_ips  on 19.01.2011
Original Header (released to pd via ip-symcon forum */

require ("functions.inc.php");

/*=============================================
skrSonos_Wohnen - Martin Heinzel - 16.11.2010
Version: 1.0

Beschreibung:
Dieses Script liest den Status des Sonos-Players im Wohnzimmer

Änderungen
----------
tt.mm.yyyy von Version x.x -> x.x

Berschreibung:

================================================*/

// ============================ Setup ==============================
$ParentID=(int)br_objParent ($IPS_SELF);
if (br_objGetVarID( $ParentID ,"Repeat")!=true){

	$position=5;

	echo ("====== Setup for Sonos " . $ParentID . " is ongoing ...");
	# Variablenprofile anlegen

	if (IPS_VariableProfileExists("Media_Transport")==False) {
	IPS_CreateVariableProfile('Media_Transport',1);
	IPS_SetVariableProfileAssociation("Media_Transport", 0, "|<","");
   IPS_SetVariableProfileAssociation("Media_Transport", 1, "Play","");
   IPS_SetVariableProfileAssociation("Media_Transport", 2, "Pause","");
   IPS_SetVariableProfileAssociation("Media_Transport", 3, "Stop","");
	IPS_SetVariableProfileAssociation("Media_Transport", 4, "|>","");

	}




	// Hide this Script
	IPS_SetHidden($IPS_SELF,true);
	# Scripte definieren
	$id_sonos_wf = @IPS_GetScriptIDByName("br_sonos_wf.php", $ParentID);
	IPS_SetHidden($id_sonos_wf,true);

	

	# DummyInstanzen anlegen
	/*
	$id_RGB = getId($name_RGB);
	IPS_SetPosition($id_RGB, 5);
	$id_T_B = getId($name_T_B);
	IPS_SetPosition($id_T_B, 10);
	*/

	#Variablen anlegen
	// Look at br_obj.handling.inc.php for CreateVariableByName and VAR_TYPE defs
	$id = CreateVariableByName($ParentID, "SONOS_IP",  VAR_TYPE_STRING);
	IPS_SetVariableCustomProfile($id, "~String");
	IPS_SetPosition($id, ++$positon);
   IPS_SetHidden($id,true);
   
   SetValueString($id, "192.168.0.115"); // DEBUG set my devel device as default

	$id = CreateVariableByName($ParentID, "Info",  VAR_TYPE_STRING);
	IPS_SetVariableCustomProfile($id, "~HTMLBox");
	IPS_SetPosition($id, ++$position);

	$id = CreateVariableByName($ParentID, "Control",  VAR_TYPE_INTEGER);
	IPS_SetVariableCustomProfile($id, "Media_Transport");
	IPS_SetPosition($id, ++$position);
		IPS_SetVariableCustomAction($id, $id_sonos_wf); // Set Sonos wf skript
   IPS_SetHidden($id,false);

	$id = CreateVariableByName($ParentID, "CoverURI",  VAR_TYPE_STRING);
	IPS_SetVariableCustomProfile($id, "~String");
	IPS_SetPosition($id, ++$position);
   IPS_SetHidden($id,true);

	$id = CreateVariableByName($ParentID, "Artist", VAR_TYPE_STRING);
	IPS_SetVariableCustomProfile($id, "~String");
	IPS_SetPosition($id, ++$position);
  IPS_SetHidden($id,true);

	$id = CreateVariableByName($ParentID, "Title",  VAR_TYPE_STRING);
	IPS_SetVariableCustomProfile($id, "~String");
	IPS_SetPosition($id, ++$position);
  IPS_SetHidden($id,true);

	$id = CreateVariableByName($ParentID, "Album",  VAR_TYPE_STRING);
	IPS_SetVariableCustomProfile($id, "~String");
	IPS_SetPosition($id, ++$position);
  IPS_SetHidden($id,true);


	$id = CreateVariableByName($ParentID, "AlbumArtist",  VAR_TYPE_STRING);
	IPS_SetVariableCustomProfile($id, "~String");
	IPS_SetPosition($id, ++$position);
  IPS_SetHidden($id,true);

	$id = CreateVariableByName($ParentID, "AlbumTrackNum",  VAR_TYPE_INTEGER);
//	IPS_SetVariableCustomProfile($id, "Integer");
	IPS_SetPosition($id, $position=$position+5);
  IPS_SetHidden($id,true);


   
   $id = CreateVariableByName($ParentID, "Position", VAR_TYPE_STRING);
	IPS_SetVariableCustomProfile($id, "~String");
	IPS_SetPosition($id, ++$position);
   IPS_SetHidden($id,true);

	$id = CreateVariableByName($ParentID, "Duration", VAR_TYPE_STRING);
	IPS_SetVariableCustomProfile($id, "~String");
	IPS_SetPosition($id, ++$position);
	IPS_SetHidden($id,true);
   
	$id = CreateVariableByName($ParentID, "Volume", VAR_TYPE_INTEGER);
	IPS_SetVariableCustomProfile($id, "~Intensity.100");
	IPS_SetPosition($id, ++$position);
	IPS_SetVariableCustomAction($id, $id_sonos_wf); // Set Sonos wf skript

	$id = CreateVariableByName($ParentID, "Mute", VAR_TYPE_BOOLEAN);
	IPS_SetVariableCustomProfile($id, "~Switch");
		IPS_SetPosition($id, ++$position);
	IPS_SetVariableCustomAction($id, $id_sonos_wf); // Set Sonos wf skript

	$id = CreateVariableByName($ParentID, "Shuffle", VAR_TYPE_BOOLEAN);
	IPS_SetVariableCustomProfile($id, "~Switch");
	IPS_SetPosition($id, ++$position);
	IPS_SetVariableCustomAction($id, $id_sonos_wf); // Set Sonos wf skript

	$id = CreateVariableByName($ParentID, "Repeat", VAR_TYPE_BOOLEAN);
	IPS_SetVariableCustomProfile($id, "~Switch");
	IPS_SetPosition($id, ++$position);
	IPS_SetVariableCustomAction($id, $id_sonos_wf); // Set Sonos wf skript

	$id = CreateVariableByName($ParentID, "Status", VAR_TYPE_INTEGER);
//	IPS_SetVariableCustomProfile($id, "SONOS.Status");
	IPS_SetPosition($id, ++$position);
   IPS_SetHidden($id,true);




	echo "===== Finished! ";
}




// ID's
//---------

$id_Volume = br_objGetVarID( $ParentID ,"Volume");
$id_Mute = br_objGetVarID( $ParentID ,"Mute");
$id_Shuffle = br_objGetVarID( $ParentID ,"Shuffle");
$id_Repeat = br_objGetVarID( $ParentID ,"Repeat");
$id_Status = br_objGetVarID( $ParentID ,"Status");
$id_Position = br_objGetVarID( $ParentID ,"Position");
$id_Duration = br_objGetVarID( $ParentID ,"Duration");
$id_Artist = br_objGetVarID( $ParentID ,"Artist");
$id_Title = br_objGetVarID( $ParentID ,"Title");
$id_Album = br_objGetVarID( $ParentID ,"Album");
$id_AlbumArtist = br_objGetVarID( $ParentID ,"AlbumArtist");
$id_AlbumTrackNum = br_objGetVarID( $ParentID ,"AlbumTrackNum");
$id_CoverURI = br_objGetVarID( $ParentID ,"CoverURI");
$id_Info = br_objGetVarID($ParentID ,"Info");

//-------------------------------------------------------------

//--------------------------- Main ----------------------------

// BRIPS editted to find current SONOS
$sonos = new PHPSonos(br_objGetVar($ParentID,"SONOS_IP")); //Sonos ZP IPAdresse

$volume = $sonos->GetVolume();                             // gibt die Lautstärke als Integer zurück
$mute = $sonos->GetMute();                                 // gibt ein bool zurück: TRUE -> MUTE an, FALSE -> MUTE aus
$shuffleRepeat = $sonos->GetTransportSettings();     // gibt ein Array zurück mit den keys "shuffle" und "repeat", welche jewils bool-Werte enthalten
$status = $sonos->GetTransportInfo();                     // gibt den aktuellen Status des Sonos-Players als Integer zurück, 1: PLAYING, 2: PAUSED, 3: STOPPED
$posInfo = $sonos->GetPositionInfo();                     // gibt ein Array mit den Informationen zum aktuellen Titel zurück (Keys: position, duration, artist, title, album, albumArtist, albumTrackNumber)
$MediaInfo = $sonos->GetMediaInfo();               // gibt den Namen der Radiostation zurück. Der key ist "titel"

// ablegen der Stati
SetValueInteger($id_Volume, $volume);
SetValueBoolean($id_Mute, $mute);
SetValueBoolean($id_Shuffle, $shuffleRepeat["shuffle"]);
SetValueBoolean($id_Repeat, $shuffleRepeat["repeat"]);
SetValueInteger($id_Status, $status);
SetValueString($id_Position, $posInfo["position"]);
SetValueString($id_Duration, $posInfo["duration"]);

// Wenn es keine "duration" gibt läuft ein Radiosender
// in diesem Fall ist der Interpret die Radiostation
if ($posInfo["duration"] != "")
{
    SetValueString($id_Artist, $posInfo["artist"]);
}
else
{
    SetValueString($id_Artist, $MediaInfo["title"]);
}

// Wenn es keine "duration" gibt läuft ein Radiosender
// in diesem Fall kommt der Titel von dem Radiosender
if ($posInfo["duration"] != "")
{
    SetValueString($id_Title, $posInfo["title"]);
}
else
{
    SetValueString($id_Title, $posInfo["streamContent"]);
}

SetValueString($id_Album, $posInfo["album"]);
SetValueString($id_AlbumArtist, $posInfo["albumArtist"]);
SetValueInteger($id_AlbumTrackNum, intval($posInfo["albumTrackNumber"]));
SetValueString($id_CoverURI, $posInfo["albumArtURI"]);

// Calculate Percent Played Bar

$Percent_Played= (int) (time_to_sec(br_objGetVar($ParentID ,"Position")) / time_to_sec(br_objGetVar($ParentID ,"Duration")) *100);
$PercentBar= "[";
for ($i=1; $i<=(0.25*$Percent_Played-1);$i++) $PercentBar=$PercentBar. "-";
$PercentBar=$PercentBar. "|";
for ($i=(0.25*$Percent_Played-1); $i<=25;$i++) $PercentBar=$PercentBar. "-";
$PercentBar=$PercentBar. "]";
echo $PercentBar;

// Set HTMl info

$HTMLInfo = "<table border=0><tr><td colspan=\"2\">"
. "[". br_objGetVar($ParentID ,"AlbumTrackNum"). "]  <b>" . br_objGetVar($ParentID ,"Title") . "</b> "
. "</td></tr><tr><td width=\"50%\">"
. "" . br_objGetVar($ParentID ,"Artist") . " </td><td width=\"50%\"> " . br_objGetVar($ParentID ,"Album")
. "</td></tr><tr><td>"
. "(". sec_to_time(time_to_sec(br_objGetVar($ParentID ,"Position"))). "/" . sec_to_time(time_to_sec(br_objGetVar($ParentID ,"Duration"))) . ") " // Look at br_timeanddate.inc.php
. "</td> <td>"
. $PercentBar
. "</td></tr></table> <br>";


SetValueString($id_Info, $HTMLInfo);


//---------------------- Main Ende ----------------------------
/* br: http://www.ip-symcon.de/forum/f53/php-sonos-klasse-ansteuern-einzelner-player-7676/index4.html */


?>

}
// written by bbernhard
/*
VariablenTyp
 Wert
 Beschreibung

0
 legt eine Variable vom Typ Boolean an

1
 legt eine Variable vom Typ Integer an

2
 legt eine Variable vom Typ Float an

3
 legt eine Variable vom Typ String an


*/
define("VAR_TYPE_BOOLEAN", '0');
define("VAR_TYPE_INTEGER", '1');
define("VAR_TYPE_FLOAT", '2');
define("VAR_TYPE_STRING", '3');


function CreateVariableByName($id, $name, $type)
{
global $IPS_SELF;
   $vid = @IPS_GetVariableIDByName($name, $id);
   if($vid===false) {
      $vid = IPS_CreateVariable((int) $type);
        IPS_SetParent($vid, $id);
      IPS_SetName($vid, $name);
      IPS_SetInfo($vid, "This Variable was created by Script #$IPS_SELF");
    }
   return $vid;
}
// written by bbernhard
function getId($name) {
   global $IPS_SELF;
   $ParentID = IPS_GetObject($IPS_SELF);
    $ParentID = $ParentID['ParentID'];

    $ID = @IPS_GetObjectIDByName($name, $ParentID);
    if ($ID == 0) {
          $dummy=IPS_CreateInstance("{485D0419-BE97-4548-AA9C-C083EB82E61E}");  #Dummy Instance
        IPS_ApplyChanges($dummy);
        IPS_SetName($dummy,$name);
        IPS_SetParent($dummy,$ParentID);
   $ID = @IPS_GetObjectIDByName($name, $ParentID);
    }
return $ID;

function br_objParent($item)
{
    $obj = IPS_GetObject($item);
    return $obj['ParentID'];
}

// Source http://php.net/manual/en/book.datetime.php

function time_to_sec($time) {
$hours = substr($time, 0, -6);
$minutes = substr($time, -5, 2);
$seconds = substr($time, -2);

return $hours * 3600 + $minutes * 60 + $seconds;
}

function sec_to_time($seconds) {
$hours = floor($seconds / 3600);
$minutes = floor($seconds % 3600 / 60);
$seconds = $seconds % 60;

return sprintf("%02d:%02d:%02d", $hours, $minutes, $seconds);
}


Ach… :loveips:
Viele Grüße, Benjamin

Hallo,

es gibt noch ein paar nette Sonos SOAP Methoden zum Abfragen und Setzen der LED (Neue Mail Led?)

	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);
	}
	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);
	}

$sonos = new PHPSonos(br_objGetVar($ParentID,"SONOS_IP")); //Sonos ZP IPAdresse
$state =  $sonos->GetLEDState();
echo "

 LED: " . $state . "!!

";

oder um z.B. ein automatisches Anheben oder Absenken der Lautstärke auf den Zone Playern durchzuführen (Aufwachen, Absenken vor Mute und Anheben danach etc).

Des Weiteren kann man von den Geräten auch ohne Event Subscription Infos über die Gruppierung der Zonen erhalten und diese danach schalten (schon per Device Spy erfolgreich getestet).

Wenn in den nächsten Tagen mal Zeit ist, werd ich die Klasse wohl mal ein wenig erweitern… - stay tuned! :smiley:

Grüße, Benjamin

Genau das brauche ich noch. Bin gespannt.

Du kannst aus den Scripten ruhig das „Martin Heinzel…“ raus nehmen. Ich habe da keine Rechte dran, oder so was. Hab’s halt gerne sauber Dokumentiert. :slight_smile:

Hallo Martin,

ich entferne aus meinen Quellen ggf. mal Deinen Namen - muss da eh die Kommentare aufräumen. Ich füge dann aber gerne Links auf Threads oder Web-Quellen ein, dann kann ich meine Quelle schnell wiederfinden.

Die erweiterten Abfragen der Infos folgen übrigens diesem Muster (falls Du selbst ein wenig probieren willst):


	
public function GetZoneAttributes() // added br
	{

$content='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
Content-Length: 295

<?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>'
;

$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
 	}

Die Rückgabe von GetPositionInfo „TrackURI“ enthält „x-rincon“ (bzw. die ID des Masters)) und TrackMetaData ist (String) „NOT_IMPLEMENTED“ (wie viele andere Antwortwerte), wenn der abgefragte ZP nicht der Zone Master ist.

Bis Alles fertig und zusammengebaut ist, dauert es sicher noch ein wenig.

Viele Grüße, Benjamin

Hallo,
ich habe die Klasse (Datei angehängt) jetzt um folgende Funktionen erweitert:

  • XMLsendPacket (XML Antworten erhalten)
  • SetLEDSate und GetLEDState (weiße LED am Gerät abfragen/ setzen)
  • GetZoneAttributes
  • GetZoneInfo
  • in gestposinfo TrackURI hinzugefügt
  • AddMember und RemoveMember (Zone Group Management)
  • RamptoVolume (mit verschiedenen Sonos internen Methoden Lautstärke faden)

Beispiele:

<?

// br_ips: br_sonos_test
// Test / Example script for PHPSonos

// Include br_ips Libs - PHPSonos still works without this lib!
require ("functions.inc.php");
// Get Script Parent
$ParentID=(int)br_objParent ($IPS_SELF);
// Talk to Coord
$sonos = new PHPSonos(br_objGetVar($ParentID,"SONOS_IP")); //Sonos ZP IPAdresse


/******************************* LEDSTATE EXAMPLE *******************************************
echo "
 LED: " . $sonos->GetLEDState() . "
";
$sonos->SetLEDState(true);
 echo "
 LED: " . $sonos->GetLEDState() . "
";
IPS_Sleep(600);
$sonos->SetLEDState(false);
echo "
 LED: " . $sonos->GetLEDState() . "
";
IPS_Sleep(600);
$sonos->SetLEDState("On");
echo "
 LED: " . $sonos->GetLEDState() . "
";
// ******************************* /LEDSTATE EXAMPLE *********************************************/


/* ****************************** ZONEATTR AND INFO EXAMPLE ***********************************
$ZoneAttributes = $sonos->GetZoneAttributes();
print_r( $ZoneAttributes);
$ZoneInfo = $sonos->GetZoneInfo();
print_r( $ZoneInfo);
// ******************************* /ZONEATTR AND INFO EXAMPLE ************************************/


/* ****************************** AddMember and RemoveMember EXAMPLE****************************

$AddMember = $sonos->AddMember("RINCON_000E5825xxx201400");
echo "
DEBUG AddMember:
";
print_r( $AddMember);

// Talk to slave
$sonos = new PHPSonos("192.168.0.111"); //Slave Sonos ZP IPAddress
echo "
";
$ret = $sonos->SetAVTransportURI("x-rincon:" . "RINCON_000E5832xxxC01400");
echo "
DEBUG SetAVTransportURI to "."x-rincon:" . "RINCON_000E5832xxxC01400" ."
";
// Playing starts

IPS_Sleep(1000);

// Talk to Coord
$sonos = new PHPSonos(br_objGetVar($ParentID,"SONOS_IP")); //Sonos ZP IPAdresse
$RemoveMember = $sonos->RemoveMember("RINCON_000E5825xxx201400");
echo "
DEBUG RemoveMember:
";
print_r( $RemoveMember);

// Talk to slave
$sonos = new PHPSonos("192.168.0.xx1"); //Slave Sonos ZP IPAddress
// needed for stop of playback on Slave
$sonos->SetAVTransportURI("");
echo "
DEBUG SetAVTransportURI to NONE 
";
//Playing stops
// ****************************** /AddMember and RemoveMember EXAMPLE****************************/


$sonos = new PHPSonos(br_objGetVar($ParentID,"SONOS_IP")); //Sonos ZP IPAdresse

// ****************************** Volume Ramp EXAMPLE****************************/

echo "RampTime: ". $sonos->RampToVolume("SLEEP_TIMER_RAMP_TYPE",40) . "
";

// ****************************** /Volume Ramp EXAMPLE****************************/


?>

Falls Ihr einen Bug entdeckt, meldet Euch gerne bei mir.

Grüße, Benjamin

PHPSonos.inc.zip (6.38 KB)

Hallo Benjamin,

besten Dank soweit. Habs gerade heruntergeladen und werde es bei Gelegenheit ausprobieren. Ich muss mich aber erst mal etwas damit beschäftigen. Hab dein Script auf die schnelle nicht verstanden. Mir ist noch nicht ganz klar was das für eine „functions.inc.php“ ist. Ich denke das da die Funktion „br_objGetVar“ drin ist.

Stecken die neuen Funktionen in der Sonos-Klasse oder in der functions.inc.php?

Ach vergiss et. Bin nur zu faul selber zu schaun.:wink:

Wenn ich Fragen habe melde ich mich.

Du bis ne Bütz!!! Besten Dank.

Hallo Schablone,
kein Problem, vielleicht haben sich diese Fragen ja noch einige Andere gestellt.

Die functions.inc.php sorgt bei mir für das Einbinden meiner Hilfsfunktionen br_ips (siehe http://www.ip-symcon.de/forum/f53/br_ips-php-libraries-ip-symcon-10467/#post86488), welche auch die br_objGetVar enthält.

Stecken die neuen Funktionen in der Sonos-Klasse oder in der functions.inc.php?

Die neuen Funktionen stecken in der phpsonos.inc.php. Die br_ Funktionen werden nur in der br_sonos_test.php (dem Beispielcode zur Benutzung) genutzt. Du kannst die Funktionen durch normale IPS Funktionen bzw. direkt durch IDs ersetzen oder Dir die entsprechenden Lib unter dem o.g. Link laden

DIe PHPSonos Klasse ist - wie gesagt - unabhängig von diesen Funktionen.
Grüße, Benjamin

Moin,
ich hab die Klasse nochmal ein wenig erweitert.


Sonos PHP Script
Copyright: Michael Maroszek
Version: 1.0, 09.07.2009
Comment:

- 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
[b]- 180311 - br fiddled with Playmode (maybe fixed a bug)
- 180311 - br added Get and Set CrossfadeMode
- 180311 - br added SaveQueue[/b]

Beispiel:



<?

// br_ips: br_sonos_test
// Test / Example script for PHPSonos

// Include br_ips Libs - PHPSonos still works without this lib!
require ("functions.inc.php"); // use PHPSonos.inc.php here
// Get Script Parent
$ParentID=(int)br_objParent ($IPS_SELF);
// Talk to Coord
$sonos = new PHPSonos("192.168.0.115"); //Sonos ZP IPAdresse


/******************************* LEDSTATE EXAMPLE *******************************************
echo "
 LED: " . $sonos->GetLEDState() . "
";
$sonos->SetLEDState(true);
 echo "
 LED: " . $sonos->GetLEDState() . "
";
IPS_Sleep(600);
$sonos->SetLEDState(false);
echo "
 LED: " . $sonos->GetLEDState() . "
";
IPS_Sleep(600);
$sonos->SetLEDState("On");
echo "
 LED: " . $sonos->GetLEDState() . "
";
// ******************************* /LEDSTATE EXAMPLE *********************************************/


/* ****************************** ZONEATTR AND INFO EXAMPLE ***********************************
$ZoneAttributes = $sonos->GetZoneAttributes();
print_r( $ZoneAttributes);
$ZoneInfo = $sonos->GetZoneInfo();
print_r( $ZoneInfo);
// ******************************* /ZONEATTR AND INFO EXAMPLE ************************************/


/* ****************************** AddMember and RemoveMember EXAMPLE****************************

$AddMember = $sonos->AddMember("RINCON_000E5825411201400");
echo "
DEBUG AddMember:
";
print_r( $AddMember);

// Talk to slave
$sonos = new PHPSonos("192.168.0.111"); //Slave Sonos ZP IPAddress
echo "
";
$ret = $sonos->SetAVTransportURI("x-rincon:" . "RINCON_000E5832FB5C01400");
echo "
DEBUG SetAVTransportURI to "."x-rincon:" . "RINCON_000E5832FB5C01400" ."
";
// Playing starts

IPS_Sleep(1000);

// Talk to Coord
$sonos = new PHPSonos("192.168.0.115"); //Sonos ZP IPAdresse
$RemoveMember = $sonos->RemoveMember("RINCON_000E5825411201400");
echo "
DEBUG RemoveMember:
";
print_r( $RemoveMember);

// Talk to slave
$sonos = new PHPSonos("192.168.0.111"); //Slave Sonos ZP IPAddress
// needed for stop of playback on Slave
$sonos->SetAVTransportURI("");
echo "
DEBUG SetAVTransportURI to NONE 
";
//Playing stops
// ****************************** /AddMember and RemoveMember EXAMPLE****************************/


$sonos = new PHPSonos("192.168.0.115"); //Sonos ZP IPAdresse

// ****************************** Volume Ramp EXAMPLE****************************/

// echo "RampTime: ". $sonos->RampToVolume("SLEEP_TIMER_RAMP_TYPE",40) . "
";

// ****************************** /Volume Ramp EXAMPLE****************************/

// ****************************** Crossfade EXAMPLE****************************/

 echo "GetCrossfadeMode: ". $sonos->GetCrossfadeMode() . "
";
IPS_Sleep(1000);
echo "SetCrossfadeMode true: ". $sonos->SetCrossfadeMode(true) . "
";
echo "GetCrossfadeMode: ". $sonos->GetCrossfadeMode() . "
";
IPS_Sleep(1000);
echo "SetCrossfadeMode false: ". $sonos->SetCrossfadeMode(false) . "
";
echo "GetCrossfadeMode: ". $sonos->GetCrossfadeMode() . "
";
// ****************************** /Crossfade EXAMPLE****************************/

// ****************************** SaveQueue EXAMPLE****************************/

 echo "SaveQueue as TEST (SONOS Playlist): ". $sonos->SaveQueue("Test") . "
";

// ****************************** /SaveQueue EXAMPLE****************************/


?>

Grüße, Benjamin

PHPSonos.inc.zip (6.64 KB)

Hallo Benjamin,

das ist ja mittlerweile eine umfangreiche Classe geworden. :slight_smile:
Besten Dank dafür.

Ich bin jetzt doch mal angefangen die neuen Funktionen zu probieren.

Ich habe noch eine Frage zu „AddMember and RemoveMember“.

Woher weis ich wie der/die Name/n meines/r Player/s ist?
„… AddMember(„RINCON_000E5825xxx201400“)“ das habe ich bei dir gesehen.
Woher hast Du das?

Besten Dank für deine Hilfe.

Hallo Martin,
ich habe mir Funktionen geschrieben, welche die Hierarchie der Gruppen auslesen (auch die Rincon) und in ein Array schreiben - die sind aber noch nicht ganz fertig. Dazu gibt es schon ein allgemeines Setup und ein Zonensetup Skript, welche die ganzen Variablen anlegen.

Die Gruppen Infos siehst Du z.B. im angehängten Bild unter dem Fortschrittsbalken als „Boden Wohnzimmer“. Ich hab mir allerdings noch nicht genau überlegt wie ich das Remove und Add von/ zu den Gruppen im Webfront umsetzen kann… Ich wollte nicht noch mehr An/ Aus Schalter einbauen.

Du kannst die Rincon_* z.B. über

http://ip-des-players:1400/xml/zone_player.xml

rausfinden, wenn Du die IP kennst.

Einfacher geht´s auch unter Windows in der Netzwerkumgebung: Rechtsklick auf den Player -> Eigenschaften.

Viele Grüße, Benjamin

Hab ich gefunden. Besten Dank!!

Moin Moin,
die Steuerung des Sonos System finde ich echt klasse und da hier ja noch weiter Entwicklung statt findet habe ich folgende Fragen.

1.)
Ich habe die Klasse ein wenig erweitert um eigene Funktionen wie z.B. GetPlaylists (alle Wiedergabelisten) GetPlaylist (eine bestimmte liefern)
Auch das Speichern unter neuen sowie vorhandene Überschreiben.
Habt ihr an sowas interesse?

2.)
Ich större mich ein wenig an der Antwortzeit der PHP Klasse und weiß aber nicht warum dies so lange dauert.
Beispiel ich sende den Befehl für Play ab und der ZP fängt an zu dudeln. Toll.
Nur braucht die Klasse, bis die Antwort generiert wurde, weil die Antowrt vom Sonos zu lange braucht. (Sprich Code 200 Seite OK)
Gibts da eine Möglichkeit dies zu ändern?

3.) Wenn Ihr meine Änderungen nicht komplett integrieren wollt, ist das völlig ok wäre es denn möglich die private Variablen und funktionen auf Protected zu setzen? Dann kann ich mir eine Ableitung davon basteln.

Wenn interesse besteht werde ich heute Abend das mal einstellen.

So anbei mein Code mit Erklärung:
Erweiterung der Klasse:

//Speichern der Qurrent Playlist unter einem Namen
	public function SaveAsCurrentQueue($name)
	{
		$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>'.$name.'</Title><ObjectID></ObjectID></u:SaveQueue>
</s:Body>
</s:Envelope>';
$content=$header . '
Content-Length: '. strlen($xml) .'

'. $xml;		

	$returnContent = $this->sendPacket($content);
	}
	//Speichern Current Playlist unter einer vorhandenen Playlist. 
	//Parameter $name= Vorhandener Name einer Playlist $id= ID der Playlist Abhängig vom Namen
	public function SaveCurrentQueue($name,$id)
	{
		$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>'.$name.'</Title><ObjectID>'.$id.'</ObjectID></u:SaveQueue>
</s:Body>
</s:Envelope>';
$content=$header . '
Content-Length: '. strlen($xml) .'

'. $xml;		

	$returnContent = $this->sendPacket($content);
	}
	//Liefert ein Array mit allen Sonos Wiedergabelisten und deren Aufrufinformationen
	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'];
			$titel = $xml->container[$i];
			$titel = $titel->xpath('dc:title');
			$liste[$i]['titel'] = (string)$titel[0];
			$liste[$i]['typ'] = "Sonos";
			$liste[$i]['file'] = (string)$xml->container[$i]->res;
		}
		
		
return $liste;
	}
	//Liefert ein Array mit allen "Importierte Playlisten" Wiedergabelisten und deren Aufrufinformationen
	public function GetImportetPlaylists()
	{
		$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'];
			$titel = $xml->container[$i];
			$titel = $titel->xpath('dc:title');
			$liste[$i]['titel'] = substr((string)$titel[0],0,-4);
			$liste[$i]['typ'] = "Import";
			$liste[$i]['file'] = (string)$xml->container[$i]->res;
		}
		
		
return $liste;
	}
	//Gibt ein Array mit den einzelnen Songs der Playlist wieder
	//ObjektID aus GetSonosPlaylists() oder GetImportetPlaylists()
	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");
			$titel = $aktrow->xpath("dc:title");
			$interpret = $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'] ="images/no-cover.png";
			}
			$liste[$i]['titel']=(string)$titel[0];
			if(isset($interpret[0])){
				$liste[$i]['interpret']=(string)$interpret[0];
			}else{
				$liste[$i]['interpret']="Unbekannt";
			}
			if(isset($album[0])){
				$liste[$i]['album']=(string)$album[0];
			}else{
				$liste[$i]['album']="Unbekannt";
			}
		}
return $liste;
	}
	//Gibt ein Array mit den Songs der aktuellen Playlist
	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);
	$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");
			$titel = $aktrow->xpath("dc:title");
			$interpret = $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'] ="images/no-cover.png";
			}
			$liste[$i]['titel']=(string)$titel[0];
			if(isset($interpret[0])){
				$liste[$i]['interpret']=(string)$interpret[0];
			}else{
				$liste[$i]['interpret']="Unbekannt";
			}
			if(isset($album[0])){
				$liste[$i]['album']=(string)$album[0];
			}else{
				$liste[$i]['album']="Unbekannt";
			}
		}
return $liste;
	}

Bei Fragen kurz bescheid geben.

Hallo Ta Lun!

Jetzt hat sich mein Post mit Deinem überschnitten. :wink: Ich schaue mir das gleich mal kurz an.

Ich habe Interesse, poste einfach mal Deine Änderungen. Falls die Änderungen gegen eine ältere Version der Klasse gehen oder gegen das Original, schaue ich mal wie ich Sie in meine Arbeitsversion übernehmen kann.

2.)
Ich större mich ein wenig an der Antwortzeit der PHP Klasse und weiß aber nicht warum dies so lange dauert.
Beispiel ich sende den Befehl für Play ab und der ZP fängt an zu dudeln. Toll.
Nur braucht die Klasse, bis die Antwort generiert wurde, weil die Antowrt vom Sonos zu lange braucht. (Sprich Code 200 Seite OK)
Gibts da eine Möglichkeit dies zu ändern?

Bei mir ist die Reaktion eigentlich sofort gegeben:


	$start = microtime(true);
	$sonos->Play();
   $stop = microtime(true);

$diff= $stop - $start;

    echo "Microtime Diff: ". $diff." 
";

Ausgabe:



Microtime Diff: 0.0037369728088379 

Du kannst den o.g. Code ja mal testen. Reagiert Dein ZP mit dem Intel Device Spy Tool schneller?

3.) Wenn Ihr meine Änderungen nicht komplett integrieren wollt, ist das völlig ok wäre es denn möglich die private Variablen und funktionen auf Protected zu setzen? Dann kann ich mir eine Ableitung davon basteln.

Wenn interesse besteht werde ich heute Abend das mal einstellen.

Zur Änderung von Protected auf Private kann ich wenig sagen,
ich kenne die Auswirkungen nicht genau. Stell Deine Änderungen gerne mal ein!

Viele Grüße, Benjamin

Hi,
schön, war ich wohl einfach zu ungeduldig :wink:

Einmal kurz zur Erklärung.
Wenn eine Variable oder Funktion als private deklariert wird, dann ist diese nicht nutzbar in einer abgeleiteten Klasse. Bei Protected wäre dies gegeben.
Wenn Du natürlich meine Änderungen mit einfließen läßt, dann ist mir das natürlich auch sehr recht.

Zu den Antwortzeiten kann ich nur sagen, das die Zp´s bei mir mit dem Syp Tool schneller reagieren wobei ich glaube das dies bei mir viel mit den Ajax request zu tun hatte. Ich habe das heute nochmal ein wenig optimiert und nun rennt es doch ganz schon Also wohl Fehler bei mir.

Ich habe da noch etwas gefunden was bei mir mit Umlauten Probleme Verursacht:
Bei:
function GetPositionInfo()

$xmlParser = xml_parser_create(„UTF-8“);
xml_parser_set_option($xmlParser, XML_OPTION_TARGET_ENCODING, „ISO-8859-1“);

mußte ich das wie folgt Ändern, damit ich bei Titel/Artist etc. wo ein Umlaut war nicht null zurück bekommen habe:

	$xmlParser = xml_parser_create("UTF-8");
	xml_parser_set_option($xmlParser, XML_OPTION_TARGET_ENCODING, "UTF-8");

Sprich das Charset mußte ich auch auf UTF8 setzen.

Das Problem mit GetPostionInfo sehe ich mir später an.

  • Ich baue deine Funktionen des ContentDirectory Service gerade komplett ein, mit der Anpassung „titel“ wird wieder zu „title“. Wenn mir noch etwas auffällt, versuche ich es auch konsistent mit den bestehenden Funktionen bzw. den UPNP Namen zu machen. Vielleicht mache ich auch noch eine allgemein Browse Funktion.

  • SaveAsCurrentQueue($name) und SaveCurrentQueue($name,$id), werde ich so nicht einbauen, sondern stattdessen nah am SOAP Namen bleiben und SaveQueue um die Nutzung der ObjectID als optionalen Parameter erweitern.


- 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

Vielen Dank für die Funktionen (cool wie sich das entwickelt… :smiley: )
… sind jetzt eingebaut!

Viele Grüße, Benjamin

PHPSonos.inc.zip (7.83 KB)

Hi,
das ist super finde ich gut und ja Das mit dem optionalen Parameter ist besser.
Jaja manchmal sieht man den Wald vor lauter Bäumen nicht :wink:

Ich werde für mein Interface demnächst sowieso ein Browsing einbauen mit dem man dann direkt songs auswaählen kann und der Playlist zufügen.
Mal sehen wie ich das realsiere aber das wird dann wohl über das normale Browsen sein.

Das mit Titel und Title ist völlig ok und macht ja auch Sinn, das man das einheitlich macht. Auch hier wieder das Ding mit dem Baum. :smiley:

Was ich noch genial fänden würde aber noch nicht gefunden habe ist die Anzeige, was als nächstes kommt. Hast Du da eine Idee?

Was ich noch nicht verstanden habe ist das mit den Gruppen.
Ist das für Zonen-Gruppen?
Hast Du da ein Beispiel wie es funktioniert?
Ich habe rumexperimentiert aber nichts gesehen.

Gruß
Ta Lun

Hi Ta Lun!

Zonen-Gruppen

Ja, das ist für Zonen-Gruppen.

AddMember und RemoveMember fügen einer Gruppe neue Member hinzu:

/* ****************************** AddMember and RemoveMember EXAMPLE****************************/

$AddMember = $sonos->AddMember("RINCON_000E5825411201400");
echo "
DEBUG AddMember:
";
print_r( $AddMember);

// Talk to slave
$sonos = new PHPSonos("192.168.0.111"); //Slave Sonos ZP IPAddress
echo "
";
$ret = $sonos->SetAVTransportURI("x-rincon:" . "RINCON_000E5832FB5C01400");
echo "
DEBUG SetAVTransportURI to "."x-rincon:" . "RINCON_000E5832FB5C01400" ."
";
// Playing starts

IPS_Sleep(1000);

// Talk to Coord
$sonos = new PHPSonos("192.168.0.115"); //Sonos ZP IPAdresse
$RemoveMember = $sonos->RemoveMember("RINCON_000E5825411201400");
echo "
DEBUG RemoveMember:
";
print_r( $RemoveMember);

// Talk to slave
$sonos = new PHPSonos("192.168.0.111"); //Slave Sonos ZP IPAddress
// needed for stop of playback on Slave
$sonos->SetAVTransportURI("");
echo "
DEBUG SetAVTransportURI to NONE 
";
//Playing stops
// ****************************** /AddMember and RemoveMember EXAMPLE****************************/

Das Einsammeln der Infos zu bestehenden Geräten und Gruppen ist ein wenig schwieriger. Ich habe keinen Weg gefunden die Statusänderungen zu Abonomieren, deswegen pflege ich über ein Spaghetti-Code „Auslese-Skript“ diese Infos in einem Array.

Im folgenden Beitrag gibt es ein Archiv (br_ips_1.5.7PRE.zip) mit meinen aktuellen Routinen:
http://www.ip-symcon.de/forum/f53/br_ips-php-libraries-ip-symcon-10467/#post86488

1. Du musst die Dateien in den scripts Ordner kopieren
2. Dann eine Kategorie für die Includes und allgemeinen Variablen erzeugen (z.B. „SONOSLibs“). Dort erstellst Du dann ein neues Skript mit dem Inhalt von br_sonos_setup-template.php. Danach führst Du das Skript aus.
3. Nun in jedem Raum mit Sonosplayer eine Variable SONOS_IP mit der IP des Players anlegen und ein neues Skript mit dem Inhalt von br_sonos_zonesetup-template.php erzeugen und ausführen.
4. Abschließend das sonos_setup Skript aus Pkt. 2 ausführen.

Das Einlesen wird in br_sonos_inc.php und br_sonos_read.php erledigt. Die IPS Variable SONOS_GROUPS enthält die serialisierten Informationen zum Status der Gruppen.

Nächster Titel

Den nächsten Titel sollte man per SOAP über „GetMediaInfo“, als „NextURI“ und „NextURIMetaData“. Das Parsen dieser Daten ist allerdings in der PHPSONOS Klasse aktuell nicht eingebau und ich erhalte leider auch per Device Spy „NOT_IMPLEMENTED“ als Rückmeldung. Ich schaue mir das mal an.
Grüße, Benjamin

Hi,
ich teste das mal mit dem AddMember was ich das hinbekommen kann.

Ich nutze kein IPS bin halt nur wegen der Klasse hier :wink:
Daher bringt mir das leider nicht viel…

Ok wenn das in GetMediaInfo haben wir die Infos ja eigentlich schon.
Wenn Du das in der nächsten Version mit einbaust wäre das super.

Nebenbei die Geschwindigkeit, die ich bemängelt hatte war mein Entwicklerpc.
Auf meinem Server rennt das nun wie auf einem Sonos Controller :wink:

Ich baue mir mein eigenes Interface um in einem Webbrowser oder Mobilen Device (Ipad, Samsung Galaxy etc) die Sonoskomponenten zu steuern.
Ja es gibt dafür Apss aber das Sonos System supportet leider keine Lyrics oder Bewertungen. Ich hole zusätzlich zu den Infos von dem Sonossystem noch diese Infos aus meiner DB.

Wenn Interesse besteht gebe ich gerne mal nähere Infos oder Sourcen.

Gruß
Ta Lun