IPS Nachrichten über Sonos abspielen

Hallo,

ich möchte hier mein kleines Sonosscript vorstellen.
Ist noch nicht ganz fertig und nur wenig getestet. Aber ich poste es schonmal. So kann der eine oder andere die Sache schonmal antesten.
Voraussetzung für das Script ist die von mir angepasste Sonos-Klasse aus diesem Thread.

Kopiert den Code in irgendein Script. Editiert am Anfang die richtige IP und MAC Adresse eures Sonos-ZP. Dann das Script einmal ausführen.
Es wird dann ein Dummy „Sonos“ und alle Hilfsvariablen erstellt.
Anschließend könnt ihr in die Variable „Message“ einen über das Netzwerk erreichbaren link zu der IPS-Nachricht eintragen.
Z.B.: „//server/Nachrichten/Achtung.mp3“ (Man beachte „/“ nicht „“)
Das laufende Programm am Sonos wird unterbrochen und die Nachricht abgespielt. Danach sollte das alte „Programm“ wieder anlaufen.
Im Moment kann nur eine Nachricht abgespielt werden. D.h. solange „playing“ „true“ ist, darf keine weitere Nachricht in „Message“ geschrieben werden.
Vielleicht mach ich auch mal ne Warteschlange.

Bekannte Probleme:

  • braucht etwas viele Variablen

Hier nun das Script:

<?
include ("PHPSonos.inc.php");

$sonos_ip = "192.168.1.1";  // IP Adresse des Sonosspielers
$sonos_mac = "000XXXXXXXXX";  // MAC Adresse des Sonospielers
$sonos_vol = 25;              // Lautstärke in der die Nachricht wiedergegeben werden soll


//Ab hier nichts mehr ändern
$object = IPS_GetObject($IPS_SELF);
$parentID = $object['ParentID'];

//Installer
if ($IPS_SENDER == "Execute")
{
  IPS_SetHidden($IPS_SELF, true);
  IPS_SetName($IPS_SELF, "Play-Message");
  $parentObject = IPS_GetObject($parentID);
  if ($parentObject['ObjectType'] !== 1)
  {
      $instanceID = IPS_CreateInstance("{485D0419-BE97-4548-AA9C-C083EB82E61E}");
      IPS_SetParent($instanceID, $parentID);
      $parentID = $instanceID;
      IPS_SetParent($IPS_SELF, $parentID);
      IPS_SetName($instanceID, "Sonos");
  }

}

// Benötigte Variablen anlegen, bzw id besorgen.
$PositionInfo_Var = CreateVariableByName($parentID, "PositionInfo", 3);
$MediaInfo_Var = CreateVariableByName($parentID, "MediaInfo", 3);
$OldStatus_Var = CreateVariableByName($parentID, "OldStatus", 1);
$Messages_Var = CreateVariableByName($parentID, "Message", 3);
$Playing_Var = CreateVariableByName($parentID, "playing", 0);
$OldVol_Var = CreateVariableByName($parentID, "OldVol", 1);
$Mute_Var = CreateVariableByName($parentID, "Mute", 0);


// Setzen einer Events von Message auf dieses Script
$eventlist = IPS_GetEventList();
$isset = false;
foreach($eventlist as $event_id)
{
	$event = IPS_GetEvent($event_id);
	// Merken, wenn unsere Message Variable bereist für ein Ereignis benutzt wurde
	if ($event["TriggerVariableID"] === $Messages_Var)
	{
	   $isset = true;
	}
}
if ($isset == false)
{  // Es wurde noch kein Ereigniss gefunden. Also eins neu anlegen
	$event = IPS_CreateEvent(0);
	IPS_SetEventTrigger($event, 0, $Messages_Var);
	IPS_SetParent($event, $IPS_SELF);
	IPS_SetEventActive($event, true);
}
// Setzen des Events ENDE

$Message = GetValueString($Messages_Var); // Datei muss das Format "//server/Dir/Name.mp3" haben.


if ($Message !== "")
{
	$sonos = new PHPSonos($sonos_ip);   // ZP in Küche

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

	//print_r ($PositionInfo);
	//print_r ($MediaInfo);

	if($IPS_SENDER == "TimerEvent")
	{  //Script hat sich selber aufgerufen. Warten auf das Ende der Nachricht
		//print "Transport: ".$sonos->GetTransportInfo()."
";
		if((intval($sonos->GetTransportinfo()) !== 1) || intval($PositionInfo["track"]) !== intval($MediaInfo["tracks"]))
		{  // Wiedergabe ist gestoppt, Oder es wird nicht mehr der letzte Titel gespielt
			// Letzen Titel löschen
		   $sonos->RemoveFromQueue(intval($MediaInfo["tracks"]));
		   // Event löschen
		   IPS_DeleteEvent($IPS_EVENT);

		   // Die alten Einstellungen wiederherstellen
		   // Zurücklesen des gespeicherten Arrays
		   $string = GetValueString($PositionInfo_Var);
			$lines = explode("
", $string);
		   foreach($lines as $line)
		   {
		      list($key, $val) = explode('=', $line);
		      $PositionInfo[trim($key)] = trim($val);
		   }
		   $string = GetValueString($MediaInfo_Var);
			$lines = explode("
", $string);
		   foreach($lines as $line)
		   {
		      list($key, $val) = explode('=', $line);
		      $MediaInfo[trim($key)] = trim($val);
		   }

		   // wurde zuletzt Radio gespielt?
		   if (stripos($PositionInfo["URI"], "mp3radio") > 0)
		   {  // Es wurde eine Radiostation gehört
		      $sonos->SetRadio($PositionInfo["URI"], $MediaInfo["title"]);
		      $sonos->SetVolume(GetValueInteger($OldVol_Var));
		      $sonos->SetMute(GetValueBoolean($Mute_Var));
		      if (GetValueInteger($OldStatus_Var) === 1)
		      	$sonos->Play();
		   }
		   else
		   {  // Vorher lief eine Musikliste
		      $sonos->SetTrack(intval($PositionInfo["track"]));
		      $sonos->SetVolume(GetValueInteger($OldVol_Var));
		      $sonos->SetMute(GetValueBoolean($Mute_Var));
		      // An die alte Stelle springen
 		      $sonos->Seek(trim($PositionInfo["position"]));
		      if (GetValueInteger($OldStatus_Var) === 1)
			      $sonos->Play();

		   }
		   // Merken, dass eine nachricht abgespielt wurde
			SetValueBoolean($Playing_Var, false);
			// löschen der Verknüpfuing zur Nachrichtendatei
			SetValueString($Messages_Var, "");
		}
	}
	else
	{
	   //Sichern der alten Einstellungen
	   $string = "";
	   foreach($PositionInfo as $key => $val)
	   {
	      $string .= "$key = $val
";
	   }
	   SetValueString($PositionInfo_Var, $string);

	   $string = "";
	   foreach($MediaInfo as $key => $val)
	   {
	      $string .= "$key = $val
";
	   }
	   SetValueString($MediaInfo_Var, $string);
	   SetValueBoolean($Mute_Var, $sonos->GetMute());
	   SetValueInteger($OldVol_Var, $sonos->GetVolume());
	   SetValueInteger($OldStatus_Var, $sonos->GetTransportInfo());

		if ($MediaInfo["title"] !== "")
		{  // Es läuft eine Radiostation
	  	   //Wenn Radio läuft, muss zuerst die Liste wieder aktiviert werden
			$sonos->SetQueue("x-rincon-queue:RINCON_".$sonos_mac."01400#0"); //Playliste aktivieren
	   }
		else // Es läuft eine Musikliste
		{
			// Nichts besonderes zu tun
		}
		   // Merken, dass eine nachricht abgespielt wird
			SetValueBoolean($Playing_Var, true);
		   $sonos->AddToQueue("x-file-cifs:".$Message);
		   //Nochmal Infos einholen
		   $PositionInfo = $sonos->GetPositionInfo();
		   $MediaInfo = $sonos->GetMediaInfo();
		   //Auf den neuen Track zeigen
			$sonos->SetTrack($MediaInfo["tracks"]);
			$sonos->SetMute(false);
			$sonos->SetVolume($sonos_vol);
			$sonos->Play();   // Abspielen
			// Selber aufrufen, um das Ende der Nachricht abzuwarten
			IPS_SetScriptTimer($IPS_SELF, 1);
	}
}

function CreateVariableByName($id, $name, $type)
{
  global $IPS_SELF;
  $vid = @IPS_GetVariableIDByName($name, $id);
  if($vid === false)
  {
      $vid = IPS_CreateVariable($type);
      IPS_SetParent($vid, $id);
      IPS_SetName($vid, $name);
      IPS_SetInfo($vid, "this variable was created by script #$IPS_SELF");
  }
  return $vid;
}

?>

Edit: V2 Die alte TransportInfo wird nun auch gespeichert.

Viel Spass beim Testen.
Ich geh erstmal schlafen. :wink:

cu…

Neue Version angefügt.

Btw. Wie kann ich eigentlich den Titel ändern? Hat sich ein kleiner Verschreiber eingeschlichen.

cu…

Editiere mal deinen ersten Beitrag, müsste eigentlich gehen

Hab ich schon gemacht. Hier im Thread ist es ja richtig.
Aber in der Threadliste ist es noch falsch.

cu…

hab es mal angepasst.

Hallo, habe das Script mal ausprobiert. Wenn ich am Sonos ne Playliste laufen hab unterbricht er diese und macht auch an der Stelle wo er pausiert hat weiter. Aber ein Meldung bekomme ich nicht.
Höre ich einen Radiosender unterbricht er gar nicht. In beiden fällen habe ich am Ende des MP3 Files, zumindest glaube ich das es das Ende ist da ich ja nichs höre, ein kurz blinkendes rotes Ausrufezeichen vor dem Script…

Woran kann das liegen…?

Ach ja. Wie kann ich denn WAV Dateien abspielen die ich mit Text to Speach über IPS erzeuge…? Geht das überhaupt?

//Server/Dir/Datei.mp3

Wo darf die Datei denn liegen? Wie gebe ich z.B. den korekten Pfad für das IPS Verzeichnis Sounds an…?
//IP-Symcon/Sounds/test.mp3

Ist ja schon ein bißchen her.
Zum einen musst Du die alten Systemvariablen anpassen ($IPS_SELF -> $_IPS[‚SELF‘]).
Zum anderen muss die erzeugte mp3 Datei in einer Freigabe landen, die Sonos auch findet und abspielen kann.
Teste das am besten mal von Hand.
Deine erzeugte mp3 muss in der Bibliothek von Sonos auftauchen und abspielbar sein.

cu…

Also das mit der Freigabe hab ich nun hinbekommen.

Allerdings funktioniert es weiterhin nur wenn ich eine Playliste läuft. Bei einzelnen Liedern und Radiosendern bekomme ich weiterhin eine Fehlermeldung.

Hatte jetzt alle $IPS geändert… dann ging aber gar nix mehr…

Muss ich das auch in der „PHPSonos.inc.php“ ändern?

Beachte die Migrationsanleitung.
Aus dem:

IPS_SetInfo($vid, "this variable was created by script #$IPS_SELF");

sollte man z.b.:

IPS_SetInfo($vid, "this variable was created by script #" . $_IPS['SELF']);

machen.

cu…

Hallo zusammen,
ich wollte mal Fragen, ob noch jemand dieses Script verwendet? Aktuell kämpfe ich mit ein paar Fehlermeldungen.
Ich habe die Variablen wie beschrieben angepasst.
Der Sonos Player lädt auch die Playliste und das File ist an einem Ort, welcher in der Bibliothek des Sonos Players verfügbar ist.

Allerdings erhalte ich einen Error:

Fatal error: Uncaught exception ‚Exception‘ with message 'Error sending command: HTTP/1.1 500 Internal Server Error
CONTENT-LENGTH: 347
CONTENT-TYPE: text/xml; charset=„utf-8“
EXT:
Server: Linux UPnP/1.0 Sonos/22.0-65180b (ZPS3)
Connection: close

s:ClientUPnPError’ in C:\IP-Symcon\scripts\PHPSonos.inc.php:1183

Bei all den PHPSonos.inc.php Versionen die es da draussen gibt, weis ich gar nicht ob ich die richtige verwende. Habe versucht die „neuste“ zu bekommen und auch 2-3 ausprobiert.

Die MP3 kommt in die Playliste, die aktuelle Liste wird auch ausgelsen, aber wenn’s dann Play machen sollte bricht das Script ab.

Das selbe Phänomen habe auch bei einem viel einfacherem Script:
$sonos->ClearQueue(); //Playlist löschen
$sonos->AddToQueue(„x-file-cifs://ipsserver/Public/test.mp3“); //Datei hinzufügen
$sonos->SetQueue(„x-rincon-queue:RINCON_“.„HIER DIE MAC DES PLAYERS ZB: FFEEDDCCBBAA“.„01400#0“); //Playlist auswählen (Nötig, wenn Radio vorher ausgewählt war)
$sonos->Play();

Internetradio geht aber… Hat jemand ein Tipp?

Gruss & Danke

Kleines Update:
Folge Zeile scheint das Problem zu sein:
$sonos->SetQueue(„x-rincon-queue:RINCON_“.„HIER DIE MAC DES PLAYERS ZB: FFEEDDCCBBAA“.„01400#0“); //Playlist auswählen (Nötig, wen

Sieht bei mir so aus: $sonos->SetQueue(„x-rincon-queue:RINCON_“.„000e58778a4c“.„01400#0“);

Wenn ich die auskommentiere spielt er, aber eben, Radio Stream Problem…

Mit ein bisschen rumprobieren hats dann mit dem funktioniert:

http://www.ip-symcon.de/forum/threads/7676-PHP-Sonos-(Klasse-zum-Ansteuern-einzelner-Player)?p=116280#post116280

Steht auch so im Wiki, aber das andere Interface / Ablaufe wäre auch cool!