SonosBY (Sonos // Gruppen erstellen, Gruppen auflösen, Text to Speech, ...)

Heyho liebe IPS`ler!

Es gab nur noch eine größere Sache, welche mir zum kompletten Sonos-Glück gefehlt hat:
[b]> Sprachausgaben auf allen (oder nur bestimmten) Playern in einer Gruppe (nicht mehr jede Sonos einzeln mit „Echo-Effekt“)

Über einen Knopfdruck alle (oder bestimmte) Player in Gruppe setzen und Musik abspielen (Party-Modus)
…und vieles mehr ist mit SonosBY möglich…[/b]

Und bevor jetzt einer was sagt, ja, das könnte man sicher schöner programmieren :slight_smile: Aber so gut bin ich dann auch nicht g Es gibt zwar bereits IPSSonos, PHPSonos und brSONOS, was auch sehr gut ist und auch von mir genutzt wird, aber so habe ich die für mich optimale Funktionen-Sammlung :slight_smile:

Was ihr alles damit machen könnt und wie das jeweils funktioniert ist im Skript beschrieben.

Wenn euch irgendwas fehlt, lasst es mich wissen, VIELLEICHT baue ich es noch ein :smiley: Und da ich es auch selbst nutze, wird es auch weiter gepflegt :wink: Gerne dürft ihr aber auch selbst Erweiterungen dazu schreiben, aber bitte posted diese dann hier und behaltet die nicht für euch selbst - Danke! :slight_smile:

Außerdem wäre es sehr nett von euch, wenn ihr mal einen Kommentar hinterlassen könntet, ob alles funktioniert bei euch, ob ihr zufrieden seid, … Ich mache es euch schon immer einfach mit Copy&Paste, anstatt extra mit Download oder Verteilung per PN oder sonstwas. Aber hunderte schauen es sich an und viele davon werden es auch nutzen, aber Antworten gibt es dann so gut wie keine. Ich teile gerne alle meine Sachen mit euch, in denen teilweise richtig viel Arbeit steckt, aber eine kurze Rückmeldung wäre schon nett :cool:

Und jetzt >> Viel Spaß damit!

Dieses Skript einfach bei euch rein kopieren, umbenennen in „SonosBY.ips.php“, Konfiguration im Skript erledigen:

<?
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//   SonosBY v1.7   ///////////////////////////////////////////////////////////////////////////////////////////////////////////
//    by Bayaro     ///////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// https://www.symcon.de/forum/threads/28615-SonosBY-%28Sonos-Gruppen-erstellen-Gruppen-aufl%C3%B6sen-Text-to-Speech-%29 //////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
// Auflistungen aller aktuell verfügbaren Funktionen in diesem Skript:
//
// SonosBY_GruppeErstellen()                   << Erstellt aus allen eingetragenen Sonos Playern eine Gruppe
// SonosBY_GruppeErstellen_Auswahl($Raumliste) << Erstellt aus den aufgelisteten Räumen eine Gruppe (1. Raum = Master)   ...("Wohnzimmer,Flur,Kueche")
// SonosBY_GruppeAufloesen()              	  << Löst die (alle) Gruppe(n) auf und setzt alle Player einzeln (nur wenn nichts abgespielt wird)
// $result = SonosBY_AltenZustandLesen()  	  << Gibt den Zustand aller Player zurück (Playing/Track/TrackPosition/Volume) - wird sich nur während der Skriptlaufzeit gemerkt
// SonosBY_AltenZustandSetzen($result)    	  << Setzt den vorher gespeicherten Zustand der Player wieder (nur wenn der alte Zustand während gleicher Skriptlaufzeit gelesen wurde)
// SonosBY_SetAVTransportRincon($SonosGroupAR_NrDesPlayer, $MasterRincon, $URI)      << Setzt bei einem Player die Rincon vom Gruppen-Master, damit werden beide zu einer Gruppe und weitere Player spielen das ab, was der Gruppen-Master abspielt
// SonosBY_SetAVTransportFile($SonosGroupAR_NrDesPlayer, $Sonos_SMBPfadUndDateiname) << Spielt beim angegebenen Player eine Datei vom freigegebenen SMB-Pfad ab (z.B. "//192.168.1.50/sonos-sounds/datei.wav")
// SonosBY_SetPlaylistTrack($SonosGroupAR_NrDesPlayer, $TrackNr)         << Wählt bei einem Player eine TrackNr in der Playlist aus  ...(1, 5);   < wählt Player 1, Track 5
// SonosBY_SetTrackPosition($SonosGroupAR_NrDesPlayer, $TrackPosition)   << Setzt bei einem Player die TrackPosition  ...(2, "0:01:20");  < wählt bei bei Player 2, TrackPosition 1 Minute 20 Sekunden
// $result = SonosBY_GetTrackDurationSekunden($SonosGroupAR_NrDesPlayer) << Gibt die Dauer des aktuellen Tracks eines Players in Sekunden zurück
// $result = SonosBY_GetTransportStatus($SonosGroupAR_NrDesPlayer)       << Gibt von einem Player den Status von Transport zurück (PLAYING/STOPPED/PAUSED_PLAYBACK)
// $result = SonosBY_GetTrackPositionInfo($SonosGroupAR_NrDesPlayer)     << Gibt von einem Player ein Array mit Infos zurück (RelTime=TrackPosition, Track=TrackNr, TrackDuration=TrackLänge)
// $result = SonosBY_GetSonosInfos($SonosGroupAR_NrDesPlayer)            << Gibt Infos zum Sonos Player zurück (SoftwareVersion Build (z.B. 29.6-99010), SoftwareVersion auf Player (z.B. 6.0), HardwareVersion)
// SonosBY_StartResume_Playing($SonosGroupAR_NrDesPlayer)  << Setzt den Transport Status eines Players auf PLAY und spielt das was in seiner Queue ist ab
// SonosBY_Stop_Playing($SonosGroupAR_NrDesPlayer)  		  << Setzt den Transport Status eines Players auf STOP
// SonosBY_Pause_Playing($SonosGroupAR_NrDesPlayer)  		  << Setzt den Transport Status eines Players auf PAUSE
// $result = SonosBY_GetVolume($SonosGroupAR_NrDesPlayer)  << Liest die aktuell eingestellte Lautstärke eines Player aus
// SonosBY_SetVolume($SonosGroupAR_NrDesPlayer, $Volume)   << Setzt die Lautstärke eines Players auf einen bestimmten Wert (0-99)
// SonosBY_SetGroupVolume($Volume)                         << Ändert die Lautstärke der gruppierten Player (Relativ zur aktuellen Lautstärke der einzelnen Player)
// SonosBY_SetGroupMute(1)                                 << Setzt MUTE für die Gruppe (1 = Mute an // 0 = Mute aus)
// SonosBY_TTS($SonosGroupAR_NrDesPlayer, $TTS_Text)       << Spielt am gewählten Player einen Text als Ton ab (Instanz-ID eures "Text to Speech" angeben // oder FALSE für Google API)
// SonosBY_TTS_Alle($Text)                                 << Merkt sich den Zustand aller Player, erstellt eine Gruppe, spielt den Text ab, löst die Gruppe auf, stellt alte Zustände wieder her
// SonosBY_TTS_Auswahl($RaumlisteDerPlayer, $Text)         << Merkt sich den Zustand der gewählten Player, erstellt eine Gruppe, spielt den Text ab, löst die Gruppe auf, stellt alte Zustände wieder her
// SonosBY_DateiAbspielen_Alle($Dateiname)                 << Spielt in allen Räumen eine Datei ab (Datei muss im freigegebenen Ordner liegen)
// SonosBY_DateiAbspielen_Auswahl($Raumliste, $Dateiname)  << Spielt in bestimmten Räumen eine Datei ab (Datei muss im freigegebenen Ordner liegen)
// $result = SonosBY_GetMediaInfo($SonosGroupAR_NrDesPlayer)              << Liest aktuelle Media-Infos des Players in ein Array aus (MediaDuration, CurrentURI, CurrentURIMetaData)
// SonosBY_PlayPlaylistByName_Auswahl($Raumliste, $PlaylistName)          << Spielt in den angegebenen Räumen die angegebene Playliste ab (Name der angegebenen Playlist muss identisch dem Sonos-Playlist-Namen sein)
// SonosBY_PlayPlaylistByName_Alle($PlaylistName)          					  << Spielt in allen Räumen die angegebene Playliste ab (Name der angegebenen Playlist muss identisch dem Sonos-Playlist-Namen sein)
// SonosBY_PlayRadiostationByName_Auswahl($Raumliste, $RadiostationName)  << Spielt in den angegebenen Räumen die angegebene Radiostation ab (im Array "$SonosRadiostationenAR" definierter Name)
// SonosBY_PlayRadiostationByID_Auswahl($Raumliste, $RadiostationID)      << Spielt in den angegebenen Räumen die angegebene Radiostation ab (im Array "$SonosRadiostationenAR" definierte ID)
// SonosBY_PlayRadiostationByName_Alle($RadiostationName)     				  << Spielt in allen Räumen die angegebene Radiostation ab (im Array "$SonosRadiostationenAR" definierter Name)
// SonosBY_PlayRadiostationByID_Alle($RadiostationID)         				  << Spielt in allen Räumen die angegebene Radiostation ab (im Array "$SonosRadiostationenAR" definierte ID)
// SonosBY_SetAVTransportURI($SonosGroupAR_NrDesPlayer, $URI)             << Setzt die URI eines Players für das Abspielen eines Media-Objektes (Radiostation, File, ...)
// SonosBY_AddURItoQueue($SonosGroupAR_NrDesPlayer, $URI)                 << Fügt der aktuellen Playliste des Players eine URI (z.B. eine gespeicherte Playliste) hinzu
// SonosBY_GruppeAufloesen_Erzwingen()                                    << Löst alle Gruppen auf und setzt alle Player einzeln (egal, ob gerade etwas abgespielt wird oder nicht)
// SonosBY_VolumeLauter($Raumname, $LauterUmWert)                         << Erhöht die Lautstärke eines Player um den angegebenen Wert
// SonosBY_VolumeLeiser($Raumname, $LeiserUmWert)                         << Verringert die Lautstärke eines Player um den angegebenen Wert
// SonosBY_SetPlayMode($Raumname, $PlayMode)		                          << Ändert den PlayMode eines Players (gültige Werte sind: NORMAL, REPEAT_ALL, REPEAT_ONE, SHUFFLE_NOREPEAT, SHUFFLE, SHUFFLE_REPEAT_ONE)
// SonosBY_Stop_Playing_Alle()											    		  << Setzt den Transport Status von allen Playern auf STOP
// $result = SonosBY_BrowsePL()                                           << Liest alle Sonos-Playlisten aus und speichert die Infos in ein Array
// SonosBY_PlaylistLeeren($SonosGroupAR_NrDesPlayer)                      << Leert die Playliste vom angegebenen Player



/************************** BEISPIELE  *******************************
>> Beispiel1 (aus allen eingetragenen Playern eine Gruppe erstellen):
SonosBY_GruppeErstellen();

>> Beispiel2 (Gruppe(n) auflösen - alle Player einzeln):
SonosBY_GruppeAufloesen();

>> Beispiel3 (Alte Zustände (Playing/Track/TrackPosition/Volume) merken, Gruppe erstellen, Sprachausgabe abspielen, Gruppe auflösen, alte Zustände wiederherstellen):
$AlterZustandAR = SonosBY_AltenZustandLesen();
SonosBY_GruppeErstellen();
SonosBY_TTS(0, "Ich bin ein Test der Sprachausgabe");
SonosBY_GruppeAufloesen();
SonosBY_AltenZustandSetzen($AlterZustandAR);

>> Beispiel4 (kurze Version von Beispiel3, macht aber genau das Gleiche)
SonosBY_TTS_Alle("Ich bin ein Test");

>> Beispiel5 (Sprachausgabe auf einem Sonos Player abspielen - inkl. merken und setzen der alten Zustände):
SonosBY_TTS_Auswahl("Badezimmer","Das ist ein Test");

>> Beispiel6 (Sprachausgabe auf bestimmten Sonos Playern (in Gruppe) abspielen - inkl. merken und setzen der alten Zustände):
SonosBY_TTS_Auswahl("Badezimmer,Wohnzimmer", "Das ist ein Test);   // Spielt nur auf den Playern "Badezimmer" und "Wohnzimmer" den Text ab, aber nicht im "Flur" (ID 0) // Master ist dann der 1. genannte Raum/Player

>> Beispiel7 (Eine Datei in bestimmten Räumen abspielen - inkl. merken und setzen der alten Zustände)
SonosBY_DateiAbspielen_Alle("Waschmaschine_ist_fertig.wav");

>> Beispiel8 (Bestimmte Räume zu einer Gruppe zusammenfügen):
SonosBY_GruppeErstellen_Auswahl("Wohnzimmer,Badezimmer");  // Erstellt eine Gruppe mit beiden Räumen, Master ist Wohnzimmer

>> Beispiel9 (Spielt in bestimmten Räumen eine Radiostation ab):
SonosBY_PlayRadiostationByName_Auswahl("Wohnzimmer,Badezimmer", "FFH");

>> Beispiel10 (Spielt in bestimmten Räumen eine Sonos-Playlist ab):
SonosBY_PlayPlaylistByName_Auswahl("Wohnzimmer", "MaxMustermann");

>> Beispiel11 (Erhöht die Lautstärke um 5):
SonosBY_VolumeLauter("Wohnzimmer", 5);



// KONFIGURATION //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// */
//
// Gruppen-Master (für alle Player in einer Gruppe) als 1. bei $SonosGroupAR[0] eintragen, alle
// anderen Sonos Player danach.
//
// Wenn ihr jetzt in der Gruppe irgendwelche Musik/Radio/Sprachausgaben abspielen wollt, dann
// müsst ihr das immer nur auf dem Player machen, welchen ihr als Gruppen-Master verwendet!
// Ich habe als Master einen Player genommen, welchen ich so gut wie nie im Einsatz habe, weil
// sollte auf dem Master gerade etwas abgespielt werden, dann hört man das kurzzeitig auf der
// Lautstärke in der das TTS erfolgt und gegebenenfalls auf weiteren Playern! Klingt dann
// bei Sprachausgaben etwas "unschön". Deshalb wählt als Master am Besten einen Player, der
// so gut wie nie (oder nie) in Verwendung ist. Auch wird beim Gruppen-Master der alte Zustand
// nicht wiederhergestellt! Gilt auch für den Master, wenn ihr nur bestimmte Player zu
// einer Gruppe zusammenfasst!
//
// Das Skript prüft nicht, ob bereits Gruppen existieren und stellt diese auch nicht
// wieder her! Er nimmt sich einfach alle Player, steckt sie in eine Gruppe und beim
// Gruppe auflösen werden alle Player wieder einzeln gesetzt.
//
//
// Je nach Länge der Sprachausgaben/Musikdateien, kann es notwendig sein die max_execution_time zu erhöhen (Skript bricht dann wegen Timeout ab)
ini_set("max_execution_time", 90);
//
// Syntax: $SonosGroupAR[0] = array("Raumname","IP-Adresse","RINCON","Lautstärke des Players im Gruppenbetrieb");
// Beispiel für 3 Sonos Player // [0] = Gruppen-Master
$SonosGroupAR[0] = array("Flur","192.168.1.11","RINCON_B0000000000000000","30");
$SonosGroupAR[1] = array("Badezimmer","192.168.1.12","RINCON_B1111111111111111","35");
$SonosGroupAR[2] = array("Wohnzimmer","192.168.1.13","RINCON_B2222222222222222","30");

$Sonos_Dateiordner = "C:\\IP-Symcon\\media\\sonos-sounds\\";  // Das hier eingetragene Verzeichnis muss für Sonos freigegeben werden
$Sonos_SMBordner = "//192.168.1.50/sonos-sounds/";            // Hier den SMB-Pfad zur Netzwerkfreigabe eintragen ("//IPS-Server-IP/ORDNERNAME/")
$TTS_InstanzID = 12345 /*[Text To Speech]*/;                  // ID eurer "Text to Speech" Instanz (ID = IPS TTS, FALSE = Google TTS, TRUE = Amazon/Ivona TTS)
// Mit der Text to Speech API von Google sind max. 100 Zeichen möglich! Wer mehr Zeichen will > https://www.symcon.de/forum/threads/25562-IPSSonos?p=243647#post243647
// Mit der Amazon/Ivona API sind max. 200 Zeichen möglich und ihr müsst diese Class einbauen > https://www.symcon.de/forum/threads/29015-TTS-mit-Amazon-Ivona-statt-Google-Translate


// RADIOSENDER     (Radiosender müssen nicht im Sonos eingerichtet sein, man muss nur die Stream-URL aus dem Internet heraussuchen)
// $SonosRadiostationenAR[0] = array("NAME","URI");  // Einfach bei der Stream URL das "http" der URL durch "x-rincon-mp3radio" ersetzen
// $SonosRadiostationenAR[0] = array("FFH","x-rincon-mp3radio://streams.ffh.de/radioffh/mp3/hqlivestream.m3u");
$SonosRadiostationenAR[0] = array("FFH","x-rincon-mp3radio://streams.ffh.de/radioffh/mp3/hqlivestream.m3u");
$SonosRadiostationenAR[1] = array("hr3","x-rincon-mp3radio://metafiles.gl-systemhaus.de/hr/hr3_2.m3u");
$SonosRadiostationenAR[2] = array("planetradio","x-rincon-mp3radio://streams.planetradio.de/planetradio/mp3/hqlivestream.m3u");
$SonosRadiostationenAR[3] = array("RadioBOB","x-rincon-mp3radio://streams.radiobob.de/bob-live/mp3-192/mediaplayerbob");
$SonosRadiostationenAR[4] = array("youFM","x-rincon-mp3radio://metafiles.gl-systemhaus.de/hr/youfm_2.m3u");
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



/****** AB HIER NICHTS MEHR ÄNDERN ****************************************************************/

function SonosBY_GruppeErstellen() {
	Global $SonosGroupAR;
   $AnzahlPlayer = count($SonosGroupAR);
   
	for ($i=0; $i < $AnzahlPlayer; $i++) {
		SonosBY_SetVolume($i, (int)$SonosGroupAR[$i][3]);

	   if ($i == 0) {
			$MasterRincon = $SonosGroupAR[0][2];
		}
		else {
			SonosBY_SetAVTransportRincon($i, 0, "x-rincon:".$MasterRincon);
		}
	}
}


function SonosBY_GruppeErstellen_Auswahl($Raumliste) {
	Global $SonosGroupAR;
	if(strpos($Raumliste,",") !== false){
	   $RaumlisteAR = explode(",", $Raumliste);
	}
	else {
	   $RaumlisteAR[] = $Raumliste;
	}
	$i=0;
	foreach ($RaumlisteAR as $Raumname) {
		$ResultVal = SearchArray($Raumname, 0, $SonosGroupAR);
		$SonosGroupARx[$i] = array($SonosGroupAR[$ResultVal][0],$SonosGroupAR[$ResultVal][1],$SonosGroupAR[$ResultVal][2],$SonosGroupAR[$ResultVal][3]);
		$i++;
	}
	$SonosGroupAR = $SonosGroupARx;
   $AnzahlPlayer = count($SonosGroupAR);

	for ($i=0; $i < $AnzahlPlayer; $i++) {
		SonosBY_SetVolume($i, (int)$SonosGroupAR[$i][3]);

	   if ($i == 0) {
			$MasterRincon = $SonosGroupAR[0][2];
		}
		else {
			SonosBY_SetAVTransportRincon($i, 0, "x-rincon:".$MasterRincon);
		}
	}
}


function SonosBY_GruppeAufloesen() {
	Global $SonosGroupAR;
   $AnzahlPlayer = count($SonosGroupAR);

   IPS_Sleep(2000);
	$SonosInfos = SonosBY_GetSonosInfos(0);  // 	Bis Sonos einen Fix hat für >> Player in einer Gruppe haben IMMER den Status PLAYING
	if ($SonosInfos["DisplaySoftwareVersion"] < 5.5) {
	   $TransportStatus = SonosBY_GetTransportStatus(0);
		while ($TransportStatus == "PLAYING") {
		   $TransportStatus = SonosBY_GetTransportStatus(0);
			IPS_Sleep(100);
		}
	}
	else {
	   $AbspieldauerSekunden = SonosBY_GetTrackDurationSekunden(0);
	   $SleepWaitTime = ($AbspieldauerSekunden * 1000) + 3000;
		IPS_Sleep($SleepWaitTime);
	}

	for ($i=1; $i < $AnzahlPlayer; $i++) {
		SonosBY_SetAVTransportRincon($i, $i, "x-rincon:".$SonosGroupAR[$i][2]);
	}
}


function SonosBY_GruppeAufloesen_Erzwingen() {
	Global $SonosGroupAR;
   $AnzahlPlayer = count($SonosGroupAR);
	for ($i=1; $i < $AnzahlPlayer; $i++) {
		SonosBY_SetAVTransportRincon($i, $i, "x-rincon:".$SonosGroupAR[$i][2]);
	}
}


function SonosBY_AltenZustandLesen() {
   Global $SonosGroupAR;
   $AnzahlPlayer = count($SonosGroupAR);
	for ($i=0; $i < $AnzahlPlayer; $i++) {
		$StatuslisteAR[0][] = SonosBY_GetTransportStatus($i);
		$StatuslisteAR[1][] = SonosBY_GetVolume($i);
		$StatuslisteAR[2][] = SonosBY_GetTrackPositionInfo($i);
	}
	return $StatuslisteAR;
}


function SonosBY_AltenZustandSetzen($StatuslisteAR) {
   Global $SonosGroupAR;
   $AnzahlPlayer = count($SonosGroupAR);
	for ($i=0; $i < $AnzahlPlayer; $i++) {
		SonosBY_SetVolume($i, $StatuslisteAR[1][$i]);
		if ($StatuslisteAR[2][$i]["TrackDuration"] != "0:00:00") {
		   if ($StatuslisteAR[2][$i]["TrackNr"] != "") {
				SonosBY_SetPlaylistTrack($i, $StatuslisteAR[2][$i]["TrackNr"]);
			}
			if ($StatuslisteAR[2][$i]["RelTime"] != "") {
	      	SonosBY_SetTrackPosition($i, $StatuslisteAR[2][$i]["RelTime"]);
	      }
      }
		if ($StatuslisteAR[0][$i] == "PLAYING") {
			SonosBY_StartResume_Playing($i);
		}
	}
}


function SonosBY_SetAVTransportRincon($i, $MasterPlayerID, $AVURI) {
Global $SonosGroupAR;
$content='POST /MediaRenderer/AVTransport/Control HTTP/1.1
HOST: '.$SonosGroupAR[$i][1].':1400
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI"
CONTENT-TYPE: text/xml; charset="utf-8"
Content-Length: 477

<?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:SetAVTransportURI xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">
         <InstanceID>0</InstanceID>
         <CurrentURI>x-rincon:'.$SonosGroupAR[$MasterPlayerID][2].'</CurrentURI>
         <CurrentURIMetaData>x</CurrentURIMetaData>
      </u:SetAVTransportURI>
   </s:Body>
</s:Envelope>';
$result = SonosBY_SendSOAP($SonosGroupAR[$i][1], $content);
return $result;
}


function SonosBY_SetAVTransportFile($i, $Sonos_SMBPfadUndDateiname) {
Global $SonosGroupAR;
$SonosInfos = SonosBY_GetSonosInfos(0);
if ($SonosInfos["DisplaySoftwareVersion"] < 5.5) {
	$contentlength = 477;
}
else {
	$contentlength = 456 + strlen($Sonos_SMBPfadUndDateiname);
}
$content='POST /MediaRenderer/AVTransport/Control HTTP/1.1
HOST: '.$SonosGroupAR[$i][1].':1400
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI"
CONTENT-TYPE: text/xml; charset="utf-8"
Content-Length: '.$contentlength.'

<?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:SetAVTransportURI xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">
         <InstanceID>0</InstanceID>
         <CurrentURI>x-file-cifs:'.$Sonos_SMBPfadUndDateiname.'</CurrentURI>
         <CurrentURIMetaData>x</CurrentURIMetaData>
      </u:SetAVTransportURI>
   </s:Body>
</s:Envelope>';
$result = SonosBY_SendSOAP($SonosGroupAR[$i][1], $content);
return $result;
}


function SonosBY_SetAVTransportURI($i, $URI) {
Global $SonosGroupAR;
$SonosInfos = SonosBY_GetSonosInfos(0);
if ($SonosInfos["DisplaySoftwareVersion"] < 5.5) {
	$contentlength = 477;
}
else {
	$contentlength = 444 + strlen($URI);
}
$content='POST /MediaRenderer/AVTransport/Control HTTP/1.1
HOST: '.$SonosGroupAR[$i][1].':1400
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI"
CONTENT-TYPE: text/xml; charset="utf-8"
Content-Length: '.$contentlength.'

<?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:SetAVTransportURI xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">
         <InstanceID>0</InstanceID>
         <CurrentURI>'.$URI.'</CurrentURI>
         <CurrentURIMetaData>x</CurrentURIMetaData>
      </u:SetAVTransportURI>
   </s:Body>
</s:Envelope>';
$result = SonosBY_SendSOAP($SonosGroupAR[$i][1], $content);
return $result;
}


function SonosBY_BrowsePL() {
Global $SonosGroupAR;
$content='POST /MediaServer/ContentDirectory/Control HTTP/1.1
HOST: '.$SonosGroupAR[0][1].':1400
SOAPACTION: "urn:schemas-upnp-org:service:ContentDirectory:1#Browse"
CONTENT-TYPE: text/xml; charset="utf-8"
Content-Length: 530

<?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 />
         <StartingIndex>0</StartingIndex>
         <RequestedCount>100</RequestedCount>
         <SortCriteria />
      </u:Browse>
   </s:Body>
</s:Envelope>';
$resultBrowse = SonosBY_SendSOAP($SonosGroupAR[0][1], $content);
$resultBrowse = substr($resultBrowse, stripos($resultBrowse, '<'));
$resultBrowse = substr($resultBrowse, 0, strrpos($resultBrowse, '>') + 4);
$resultBrowse = str_replace(array("<", ">", """, "&", "%3a", "%2f", "%25"), array("<", ">", "\"", "&", ":", "/", "%"), $resultBrowse);
$xml = new SimpleXMLElement($resultBrowse);
$liste = array();
for($i=0,$size=count($xml);$i<$size;$i++) {
	$attr = $xml->container[$i]->attributes();
	$result[$i]['id'] = (string)$attr['id'];
	$title = $xml->container[$i];
	$title = $title->xpath('dc:title');
	$result[$i]['title'] = (string)$title[0];
	$result[$i]['file'] = URL_Encode((string)$xml->container[$i]->res);
}
return $result;
}


function SonosBY_PlaylistLeeren($i) {
Global $SonosGroupAR;
$content='POST /MediaRenderer/Queue/Control HTTP/1.1
HOST: '.$SonosGroupAR[$i][1].':1400
SOAPACTION: "urn:schemas-sonos-com:service:Queue:1#RemoveAllTracks"
CONTENT-TYPE: text/xml; charset="utf-8"
Content-Length: 373

<?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:RemoveAllTracks xmlns:u="urn:schemas-sonos-com:service:Queue:1">
         <QueueID>0</QueueID>
         <UpdateID>0</UpdateID>
      </u:RemoveAllTracks>
   </s:Body>
</s:Envelope>';
$result = SonosBY_SendSOAP($SonosGroupAR[$i][1], $content);
return $result;
}


function SonosBY_AddURItoQueue($i, $URI) {
Global $SonosGroupAR;
$contentlength = 541 + strlen($URI);
$content='POST /MediaRenderer/AVTransport/Control HTTP/1.1
HOST: '.$SonosGroupAR[$i][1].':1400
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#AddURIToQueue"
CONTENT-TYPE: text/xml; charset="utf-8"
Content-Length: '.$contentlength.'

<?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:AddURIToQueue xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">
         <InstanceID>0</InstanceID>
         <EnqueuedURI>'.$URI.'</EnqueuedURI>
         <EnqueuedURIMetaData />
         <DesiredFirstTrackNumberEnqueued>0</DesiredFirstTrackNumberEnqueued>
         <EnqueueAsNext>1</EnqueueAsNext>
      </u:AddURIToQueue>
   </s:Body>
</s:Envelope>';
$result = SonosBY_SendSOAP($SonosGroupAR[$i][1], $content);
return $result;
}


function SonosBY_PlayPlaylistByName_Auswahl($Raumliste, $PlaylistName) {
	Global $SonosGroupAR;
	if(strpos($Raumliste,",")!==false){
	   $RaumlisteAR = explode(",", $Raumliste);
	}
	else {
	   $RaumlisteAR[] = $Raumliste;
	}
	$i=0;
	foreach ($RaumlisteAR as $Raumname) {
		$ResultVal = SearchArray($Raumname, 0, $SonosGroupAR);
		$SonosGroupARx[$i] = array($SonosGroupAR[$ResultVal][0],$SonosGroupAR[$ResultVal][1],$SonosGroupAR[$ResultVal][2],$SonosGroupAR[$ResultVal][3]);
		$i++;
	}
	$SonosGroupAR = $SonosGroupARx;
	SonosBY_PlaylistLeeren(0);
	$SonosPlaylistenAR = SonosBY_BrowsePL();
	$ResultVal = SearchArray($PlaylistName, "title", $SonosPlaylistenAR);
	SonosBY_AddURItoQueue(0, $SonosPlaylistenAR[$ResultVal]['file']);
	SonosBY_GruppeErstellen();
	IPS_Sleep(2000);
	SonosBY_SetAVTransportURI(0, "x-rincon-queue:".$SonosGroupAR[0][2]."#0");
	SonosBY_StartResume_Playing(0);
}


function SonosBY_PlayPlaylistByName_Alle($PlaylistName) {
	Global $SonosGroupAR;
	SonosBY_PlaylistLeeren(0);
	$SonosPlaylistenAR = SonosBY_BrowsePL();
	$ResultVal = SearchArray($PlaylistName, "title", $SonosPlaylistenAR);
	SonosBY_AddURItoQueue(0, $SonosPlaylistenAR[$ResultVal]['file']);
	SonosBY_GruppeErstellen();
	IPS_Sleep(2000);
	SonosBY_SetAVTransportURI(0, "x-rincon-queue:".$SonosGroupAR[0][2]."#0");
	SonosBY_StartResume_Playing(0);
}


function SonosBY_SetPlaylistTrack($i, $TrackNr) {
Global $SonosGroupAR;
$content='POST /MediaRenderer/AVTransport/Control HTTP/1.1
HOST: '.$SonosGroupAR[$i][1].':1400
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#Seek"
CONTENT-TYPE: text/xml; charset="utf-8"
Content-Length: 390

<?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:Seek xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">
         <InstanceID>0</InstanceID>
         <Unit>TRACK_NR</Unit>
         <Target>'.$TrackNr.'</Target>
      </u:Seek>
   </s:Body>
</s:Envelope>';
$result = SonosBY_SendSOAP($SonosGroupAR[$i][1], $content);
return $result;
}


function SonosBY_SetTrackPosition($i, $TrackPosition) {
Global $SonosGroupAR;
$content='POST /MediaRenderer/AVTransport/Control HTTP/1.1
HOST: '.$SonosGroupAR[$i][1].':1400
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#Seek"
CONTENT-TYPE: text/xml; charset="utf-8"
Content-Length: 396

<?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:Seek xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">
         <InstanceID>0</InstanceID>
         <Unit>REL_TIME</Unit>
         <Target>'.$TrackPosition.'</Target>
      </u:Seek>
   </s:Body>
</s:Envelope>';
$result = SonosBY_SendSOAP($SonosGroupAR[$i][1], $content);
return $result;
}


function SonosBY_GetTransportStatus($i) {
Global $SonosGroupAR;
$content='POST /MediaRenderer/AVTransport/Control HTTP/1.1
HOST: '.$SonosGroupAR[$i][1].':1400
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#GetTransportInfo"
CONTENT-TYPE: text/xml; charset="utf-8"
Content-Length: 353

<?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:GetTransportInfo xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">
         <InstanceID>0</InstanceID>
      </u:GetTransportInfo>
   </s:Body>
</s:Envelope>';
$resultx = SonosBY_SendSOAP($SonosGroupAR[$i][1], $content);
$result = XMLFilter($resultx, "CurrentTransportState");
return $result;
}


function SonosBY_GetTrackPositionInfo($i) {
Global $SonosGroupAR;
$content='POST /MediaRenderer/AVTransport/Control HTTP/1.1
HOST: '.$SonosGroupAR[$i][1].':1400
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#GetPositionInfo"
CONTENT-TYPE: text/xml; charset="utf-8"
Content-Length: 351

<?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:GetPositionInfo xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">
         <InstanceID>0</InstanceID>
      </u:GetPositionInfo>
   </s:Body>
</s:Envelope>';
$resultTrackInfo = SonosBY_SendSOAP($SonosGroupAR[$i][1], $content);
$result["RelTime"] = XMLFilter($resultTrackInfo, "RelTime");
$result["TrackNr"] = @XMLFilter($resultTrackInfo, "Track");
$result["TrackDuration"] = XMLFilter($resultTrackInfo, "TrackDuration");
return $result;
}


function SonosBY_GetTrackDurationSekunden($i) {
	$TrackPositionInfoX = SonosBY_GetTrackPositionInfo($i);
	$DurationAR = explode(":", $TrackPositionInfoX['TrackDuration']);
	$DurationSTD = (int)$DurationAR[0];
	$DurationMIN = (int)$DurationAR[1];
	$DurationSEK = (int)$DurationAR[2];
	$DurationSekGesamt = $DurationSEK + ($DurationMIN * 60) + ($DurationSTD * 3600);
	return $DurationSekGesamt;
}


function SonosBY_GetSonosInfos($i) {
Global $SonosGroupAR;
$content='POST /DeviceProperties/Control HTTP/1.1
HOST: '.$SonosGroupAR[$i][1].':1400
SOAPACTION: "urn:schemas-upnp-org:service:DeviceProperties:1#GetZoneInfo"
CONTENT-TYPE: text/xml; charset="utf-8"
Content-Length: 289

<?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>';
$resultSonosInfos = SonosBY_SendSOAP($SonosGroupAR[$i][1], $content);
$result["SoftwareVersion"] = XMLFilter($resultSonosInfos, "SoftwareVersion");
$result["DisplaySoftwareVersion"] = @XMLFilter($resultSonosInfos, "DisplaySoftwareVersion");
$result["HardwareVersion"] = XMLFilter($resultSonosInfos, "HardwareVersion");
return $result;
}


function SonosBY_GetMediaInfo($i) {
Global $SonosGroupAR;
$content='POST /MediaRenderer/AVTransport/Control HTTP/1.1
HOST: '.$SonosGroupAR[$i][1].':1400
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#GetMediaInfo"
CONTENT-TYPE: text/xml; charset="utf-8"
Content-Length: 345

<?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:GetMediaInfo xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">
         <InstanceID>0</InstanceID>
      </u:GetMediaInfo>
   </s:Body>
</s:Envelope>';
$resultMediaInfos = SonosBY_SendSOAP($SonosGroupAR[$i][1], $content);
$result["MediaDuration"] = XMLFilter($resultMediaInfos, "MediaDuration");
$result["CurrentURI"] = @XMLFilter($resultMediaInfos, "CurrentURI");
$result["CurrentURIMetaData"] = XMLFilter($resultMediaInfos, "CurrentURIMetaData");
return $result;
}


function SonosBY_StartResume_Playing($i) {
Global $SonosGroupAR;
$content='POST /MediaRenderer/AVTransport/Control HTTP/1.1
HOST: '.$SonosGroupAR[$i][1].':1400
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#Play"
CONTENT-TYPE: text/xml; charset="utf-8"
Content-Length: 356

<?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:Play xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">
         <InstanceID>0</InstanceID>
         <Speed>1</Speed>
      </u:Play>
   </s:Body>
</s:Envelope>';
$result = SonosBY_SendSOAP($SonosGroupAR[$i][1], $content);
return $result;
}


function SonosBY_Stop_Playing($i) {
Global $SonosGroupAR;
$content='POST /MediaRenderer/AVTransport/Control HTTP/1.1
HOST: '.$SonosGroupAR[$i][1].':1400
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#Stop"
CONTENT-TYPE: text/xml; charset="utf-8"
Content-Length: 329

<?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:Stop xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">
         <InstanceID>0</InstanceID>
      </u:Stop>
   </s:Body>
</s:Envelope>';
$result = SonosBY_SendSOAP($SonosGroupAR[$i][1], $content);
return $result;
}


function SonosBY_Stop_Playing_Alle() {
	Global $SonosGroupAR;
   $AnzahlPlayer = count($SonosGroupAR);
	for ($i=0; $i < $AnzahlPlayer; $i++) {
		SonosBY_Stop_Playing($i);
	}
}


function SonosBY_Pause_Playing($i) {
Global $SonosGroupAR;
$content='POST /MediaRenderer/AVTransport/Control HTTP/1.1
HOST: '.$SonosGroupAR[$i][1].':1400
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#Pause"
CONTENT-TYPE: text/xml; charset="utf-8"
Content-Length: 331

<?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:Pause xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">
         <InstanceID>0</InstanceID>
      </u:Pause>
   </s:Body>
</s:Envelope>';
$result = SonosBY_SendSOAP($SonosGroupAR[$i][1], $content);
return $result;
}


function SonosBY_GetVolume($i) {
Global $SonosGroupAR;
$content='POST /MediaRenderer/RenderingControl/Control HTTP/1.1
HOST: '.$SonosGroupAR[$i][1].':1400
SOAPACTION: "urn:schemas-upnp-org:service:RenderingControl:1#GetVolume"
CONTENT-TYPE: text/xml; charset="utf-8"
Content-Length: 380

<?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:GetVolume xmlns:u="urn:schemas-upnp-org:service:RenderingControl:1">
         <InstanceID>0</InstanceID>
         <Channel>Master</Channel>
      </u:GetVolume>
   </s:Body>
</s:Envelope>';
$resultx = SonosBY_SendSOAP($SonosGroupAR[$i][1], $content);
$result = XMLFilter($resultx, "CurrentVolume");
return $result;
}


function SonosBY_SetVolume($i, $Volume) {
Global $SonosGroupAR;
if (strlen($Volume) > 1) {
	$contentlength = 424;
}
else {
   $contentlength = 423;
}

$content='POST /MediaRenderer/RenderingControl/Control HTTP/1.1
HOST: '.$SonosGroupAR[$i][1].':1400
SOAPACTION: "urn:schemas-upnp-org:service:RenderingControl:1#SetVolume"
CONTENT-TYPE: text/xml; charset="utf-8"
Content-Length: '.$contentlength.'

<?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: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>';
$result = SonosBY_SendSOAP($SonosGroupAR[$i][1], $content);
return $result;
}


function SonosBY_VolumeLauter($Raumname, $ErhoehungsWert) {
	Global $SonosGroupAR;
	$ResultVal = SearchArray($Raumname, 0, $SonosGroupAR);
	$SonosGroupARx[0] = array($SonosGroupAR[$ResultVal][0],$SonosGroupAR[$ResultVal][1],$SonosGroupAR[$ResultVal][2],$SonosGroupAR[$ResultVal][3]);
	$SonosGroupAR = $SonosGroupARx;
	$VolumeNeu = SonosBY_GetVolume(0) + $ErhoehungsWert;
   SonosBY_SetVolume(0, $VolumeNeu);
}


function SonosBY_VolumeLeiser($Raumname, $VerringerungsWert) {
	Global $SonosGroupAR;
	$ResultVal = SearchArray($Raumname, 0, $SonosGroupAR);
	$SonosGroupARx[0] = array($SonosGroupAR[$ResultVal][0],$SonosGroupAR[$ResultVal][1],$SonosGroupAR[$ResultVal][2],$SonosGroupAR[$ResultVal][3]);
	$SonosGroupAR = $SonosGroupARx;
	$VolumeNeu = SonosBY_GetVolume(0) - $VerringerungsWert;
   SonosBY_SetVolume(0, $VolumeNeu);
}


function SonosBY_SetGroupVolume($GroupVolume) {
Global $SonosGroupAR;
if (strlen($GroupVolume) > 1) {
	$contentlength = 403;
}
else {
   $contentlength = 402;
}

$content='POST /MediaRenderer/GroupRenderingControl/Control HTTP/1.1
HOST: '.$SonosGroupAR[0][1].':1400
SOAPACTION: "urn:schemas-upnp-org:service:GroupRenderingControl:1#SetGroupVolume"
CONTENT-TYPE: text/xml; charset="utf-8"
Content-Length: '.$contentlength.'

<?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:SetGroupVolume xmlns:u="urn:schemas-upnp-org:service:GroupRenderingControl:1">
         <InstanceID>0</InstanceID>
         <DesiredVolume>'.$GroupVolume.'</DesiredVolume>
      </u:SetGroupVolume>
   </s:Body>
</s:Envelope>';
$result = SonosBY_SendSOAP($SonosGroupAR[0][1], $content);
return $result;
}


function SonosBY_SetGroupMute($MuteEinsNull) {
Global $SonosGroupAR;
$content='POST /MediaRenderer/GroupRenderingControl/Control HTTP/1.1
HOST: '.$SonosGroupAR[0][1].':1400
SOAPACTION: "urn:schemas-upnp-org:service:GroupRenderingControl:1#SetGroupMute"
CONTENT-TYPE: text/xml; charset="utf-8"
Content-Length: 394

<?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:SetGroupMute xmlns:u="urn:schemas-upnp-org:service:GroupRenderingControl:1">
         <InstanceID>0</InstanceID>
         <DesiredMute>'.$MuteEinsNull.'</DesiredMute>
      </u:SetGroupMute>
   </s:Body>
</s:Envelope>';
$result = SonosBY_SendSOAP($SonosGroupAR[0][1], $content);
return $result;
}


function SonosBY_SetPlayMode($Raumname, $PlayMode) {
Global $SonosGroupAR;
$ResultVal = SearchArray($Raumname, 0, $SonosGroupAR);
$SonosGroupARx[0] = array($SonosGroupAR[$ResultVal][0],$SonosGroupAR[$ResultVal][1],$SonosGroupAR[$ResultVal][2],$SonosGroupAR[$ResultVal][3]);
$SonosGroupAR = $SonosGroupARx;
$contentlength = 380 + strlen($PlayMode);
$content='POST /MediaRenderer/AVTransport/Control HTTP/1.1
HOST: '.$SonosGroupAR[0][1].':1400
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#SetPlayMode"
CONTENT-TYPE: text/xml; charset="utf-8"
Content-Length: '.$contentlength.'

<?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:SetPlayMode xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">
         <InstanceID>0</InstanceID>
         <NewPlayMode>'.$PlayMode.'</NewPlayMode>
      </u:SetPlayMode>
   </s:Body>
</s:Envelope>';
$result = SonosBY_SendSOAP($SonosGroupAR[0][1], $content);
return $result;
}


function SonosBY_TTS($i, $TTS_Text) {
	Global $Sonos_Dateiordner;
	Global $Sonos_SMBordner;
	Global $TTS_InstanzID;
	if ($TTS_InstanzID === FALSE) {
	   $SonosTTS_Dateiname = "SonosBY_GoogleTTS.mp3";
		$SonosTTS_DateiPfad = $Sonos_Dateiordner.$SonosTTS_Dateiname;
		$Sonos_SMBPfadUndDateiname = $Sonos_SMBordner.$SonosTTS_Dateiname;
		$TTS_Text_UTF8 = urlencode(utf8_encode($TTS_Text));
		if (strlen($TTS_Text_UTF8) > 100) {
			IPS_LogMessage("SonosBY-TTS", "Google TTS Text darf maximal 100 Zeichen lang sein!");
			return;
		}
		$GoogleTTSmp3 = @file_get_contents('http://translate.google.de/translate_tts?tl=de&ie=UTF-8&q='.$TTS_Text_UTF8."&client=t");
		if ((strpos($http_response_header[0], "200") != false)) {
			file_put_contents($SonosTTS_DateiPfad, $GoogleTTSmp3);
		}
		IPS_Sleep(500);
		SonosBY_SetAVTransportFile($i, $Sonos_SMBPfadUndDateiname);
		SonosBY_StartResume_Playing($i);
	}
	elseif ($TTS_InstanzID === TRUE) {
	   $SonosTTS_Dateiname = "SonosBY_AmazonIvonaTTS.mp3";
		$SonosTTS_DateiPfad = $Sonos_Dateiordner.$SonosTTS_Dateiname;
		$Sonos_SMBPfadUndDateiname = $Sonos_SMBordner.$SonosTTS_Dateiname;
		$TTS_Text_UTF8 = urlencode(utf8_encode($TTS_Text));
		if (strlen($TTS_Text_UTF8) > 200) {
			IPS_LogMessage("SonosBY-TTS", "Amazon/Ivona TTS Text darf maximal 200 Zeichen lang sein!");
			return;
		}
		if (class_exists("IVONA_TTS")) {
      	$Ivona = new IVONA_TTS();
			$Ivona->save_mp3($TTS_Text_UTF8, $Sonos_SMBPfadUndDateiname);
		}
		IPS_Sleep(500);
		SonosBY_SetAVTransportFile($i, $Sonos_SMBPfadUndDateiname);
		SonosBY_StartResume_Playing($i);
	}
	else {
		$SonosTTS_Dateiname = "SonosBY_TTS.wav";
		$SonosTTS_DateiPfad = $Sonos_Dateiordner.$SonosTTS_Dateiname;
		$Sonos_SMBPfadUndDateiname = $Sonos_SMBordner.$SonosTTS_Dateiname;
		TTS_GenerateFile((int)$TTS_InstanzID, $TTS_Text, $SonosTTS_DateiPfad, 39);
		IPS_Sleep(500);
		SonosBY_SetAVTransportFile($i, $Sonos_SMBPfadUndDateiname);
		SonosBY_StartResume_Playing($i);
	}
}


function SonosBY_TTS_Alle($Text) {
	$AlterZustandAR = SonosBY_AltenZustandLesen();
	SonosBY_GruppeErstellen();
	SonosBY_TTS(0, $Text);
	SonosBY_GruppeAufloesen();
	SonosBY_AltenZustandSetzen($AlterZustandAR);
}


function SonosBY_TTS_Auswahl($Raumliste, $Text) {
	Global $SonosGroupAR;
	if(strpos($Raumliste,",")!==false){
	   $RaumlisteAR = explode(",", $Raumliste);
	}
	else {
	   $RaumlisteAR[] = $Raumliste;
	}
	$i=0;
	foreach ($RaumlisteAR as $Raumname) {
		$ResultVal = SearchArray($Raumname, 0, $SonosGroupAR);
		$SonosGroupARx[$i] = array($SonosGroupAR[$ResultVal][0],$SonosGroupAR[$ResultVal][1],$SonosGroupAR[$ResultVal][2],$SonosGroupAR[$ResultVal][3]);
		$i++;
	}
	$SonosGroupAR = $SonosGroupARx;
	$AlterZustandAR = SonosBY_AltenZustandLesen();
	SonosBY_GruppeErstellen();
	SonosBY_TTS(0, $Text);
	SonosBY_GruppeAufloesen();
	SonosBY_AltenZustandSetzen($AlterZustandAR);
}


function SonosBY_DateiAbspielen_Alle($Dateiname) {
	Global $SonosGroupAR;
	Global $Sonos_SMBordner;
	$Sonos_SMBPfadUndDateiname = $Sonos_SMBordner.$Dateiname;
	$AlterZustandAR = SonosBY_AltenZustandLesen();
	SonosBY_GruppeErstellen();
	SonosBY_SetAVTransportFile(0, $Sonos_SMBPfadUndDateiname);
	SonosBY_StartResume_Playing(0);
	SonosBY_GruppeAufloesen();
	SonosBY_AltenZustandSetzen($AlterZustandAR);
}


function SonosBY_DateiAbspielen_Auswahl($Raumliste, $Dateiname) {
	Global $SonosGroupAR;
	Global $Sonos_SMBordner;
	if(strpos($Raumliste,",")!==false){
	   $RaumlisteAR = explode(",", $Raumliste);
	}
	else {
	   $RaumlisteAR[] = $Raumliste;
	}
	$i=0;
	foreach ($RaumlisteAR as $Raumname) {
		$ResultVal = SearchArray($Raumname, 0, $SonosGroupAR);
		$SonosGroupARx[$i] = array($SonosGroupAR[$ResultVal][0],$SonosGroupAR[$ResultVal][1],$SonosGroupAR[$ResultVal][2],$SonosGroupAR[$ResultVal][3]);
		$i++;
	}
	$SonosGroupAR = $SonosGroupARx;
	$Sonos_SMBPfadUndDateiname = $Sonos_SMBordner.$Dateiname;
	$AlterZustandAR = SonosBY_AltenZustandLesen();
	SonosBY_GruppeErstellen();
	SonosBY_SetAVTransportFile(0, $Sonos_SMBPfadUndDateiname);
	SonosBY_StartResume_Playing(0);
	SonosBY_GruppeAufloesen();
	SonosBY_AltenZustandSetzen($AlterZustandAR);
}


function SonosBY_PlayRadiostationByName_Auswahl($Raumliste, $RadiostationName) {
	Global $SonosGroupAR;
	Global $SonosRadiostationenAR;
	if(strpos($Raumliste,",")!==false){
	   $RaumlisteAR = explode(",", $Raumliste);
	}
	else {
	   $RaumlisteAR[] = $Raumliste;
	}
	$i=0;
	foreach ($RaumlisteAR as $Raumname) {
		$ResultVal = SearchArray($Raumname, 0, $SonosGroupAR);
		$SonosGroupARx[$i] = array($SonosGroupAR[$ResultVal][0],$SonosGroupAR[$ResultVal][1],$SonosGroupAR[$ResultVal][2],$SonosGroupAR[$ResultVal][3]);
		$i++;
	}
	$SonosGroupAR = $SonosGroupARx;
	SonosBY_GruppeErstellen();
   $RadiostationURIid = SearchArray($RadiostationName, 0, $SonosRadiostationenAR);
	SonosBY_SetAVTransportURI(0, $SonosRadiostationenAR[$RadiostationURIid][1]);
	SonosBY_StartResume_Playing(0);
}


function SonosBY_PlayRadiostationByID_Auswahl($Raumliste, $RadiostationID) {
	Global $SonosGroupAR;
	Global $SonosRadiostationenAR;
	if(strpos($Raumliste,",")!==false){
	   $RaumlisteAR = explode(",", $Raumliste);
	}
	else {
	   $RaumlisteAR[] = $Raumliste;
	}
	$i=0;
	foreach ($RaumlisteAR as $Raumname) {
		$ResultVal = SearchArray($Raumname, 0, $SonosGroupAR);
		$SonosGroupARx[$i] = array($SonosGroupAR[$ResultVal][0],$SonosGroupAR[$ResultVal][1],$SonosGroupAR[$ResultVal][2],$SonosGroupAR[$ResultVal][3]);
		$i++;
	}
	$SonosGroupAR = $SonosGroupARx;
	SonosBY_GruppeErstellen();
	SonosBY_SetAVTransportURI(0, $SonosRadiostationenAR[$RadiostationID][1]);
	SonosBY_StartResume_Playing(0);
}


function SonosBY_PlayRadiostationByName_Alle($RadiostationName) {
	Global $SonosGroupAR;
	Global $SonosRadiostationenAR;
	SonosBY_GruppeErstellen();
   $RadiostationURIid = SearchArray($RadiostationName, 0, $SonosRadiostationenAR);
	SonosBY_SetAVTransportURI(0, $SonosRadiostationenAR[$RadiostationURIid][1]);
	SonosBY_StartResume_Playing(0);
}


function SonosBY_PlayRadiostationByID_Alle($RadiostationID) {
	Global $SonosGroupAR;
	Global $SonosRadiostationenAR;
	SonosBY_GruppeErstellen();
	SonosBY_SetAVTransportURI(0, $SonosRadiostationenAR[$RadiostationID][1]);
	SonosBY_StartResume_Playing(0);
}


function SonosBY_SendSOAP($IPaddress, $content) {
	$fp = fsockopen($IPaddress, 1400);
   fputs ($fp, $content);
   $result = stream_get_contents($fp, -1);
   fclose($fp);
   return $result;
}


function URL_Encode($string) {
	$entities = array('%21', '%2A', '%27', '%28', '%29', '%3B', '%3A', '%40', '%26', '%3D', '%2B', '%24', '%2C', '%2F', '%3F', '%25', '%23', '%5B', '%5D');
	$replacements = array('!', '*', "'", "(", ")", ";", ":", "@", "&", "=", "+", "$", ",", "/", "?", "%", "#", "[", "]");
	return str_replace($entities, $replacements, urlencode($string));
}



function XMLFilter($Var,$SuchString) {
	preg_match('/\<'.$SuchString.'\>(.+)\<\/'.$SuchString.'\>/',$Var,$result);
	return $result[1];
}


function SearchArray($value, $key, $array) {
   foreach ($array as $k => $val) {
   	if ($val[$key] == $value) {
			return $k;
		}
   }
	return NULL;
}
?>

Sonos einen Ordner freigeben vom IPS Server (für TTS):
1.) Ordner auf dem IPS-Server im Netzwerk freigeben (SMB) - Für „Jeder“
2.) Ordner in der Sonos App oder der Sonos Desktop Software einbinden in seine Bibliothek (Einstellungen > Musikbibliothek verwalten > Musikbibliothek einrichten > Pfad eingeben nach Muster „//192.168.1.10/Ordnername“)

Hier noch ein paar Beispiele, wie ihr ganz einfach aus euren Skripten die Funktionen verwenden könnt (es gibt aber noch viiiiel mehr):

<?
include 'SonosBY.ips.php';

SonosBY_TTS_Alle("Das ist ein Test");  // Spielt auf allen eingetragenen Playern (in Gruppe) den Text ab (mit Zustände merken und wiederherstellen)
?>
<?
include 'SonosBY.ips.php';

SonosBY_TTS_Auswahl("Badezimmer,Wohnzimmer","Das ist ein Test");  // Spielt nur auf genannten Playern (in Gruppe) den Text ab (mit Zustände merken und wiederherstellen)
?>
<?
include 'SonosBY.ips.php';

SonosBY_TTS_Auswahl("Badezimmer","Das ist ein Test");  // Spielt nur auf genanntem Player den Text ab (mit Zustände merken und wiederherstellen)
?>
<?
include 'SonosBY.ips.php';

SonosBY_SetVolume(2, 30);  // Setzt Player mit ID 2 in $SonosGroupAR auf Lautstärke 30
?>
<?
include 'SonosBY.ips.php';

// Spielt in allen Räumen (in Gruppe) die Datei ab (mit Zustände merken und wiederherstellen)
SonosBY_DateiAbspielen_Alle("WaeschetrocknerFertig.wav"); 

// Spielt in bestimmten Räumen (in Gruppe) oder einzelnen Räumen die Datei ab (mit Zustände merken und wiederherstellen)
SonosBY_DateiAbspielen_Auswahl("BadOben", "WaschmaschineFertig.mp3");
?>

WICHTIG >> Beim Gruppen-Master wird der alte Zustand nicht wiederhergestellt! Gilt auch für den Master, wenn ihr nur bestimmte Player zu einer Gruppe zusammenfasst, oder mit „SonosBY_***_Auswahl“ nur auf einem Raum etwas abspielen lasst!

UPDATES: (Bei einem Update müsst ihr euch nur den „Konfiguration“-Abschnitt sichern)
v1.2
>> NEU # SonosBY_SetGroupMute
>> FIX # Die Funktion „SonosBY_TTS_Alle“ hatte den falschen Namen

v1.3
>> NEU # SonosBY_GruppeErstellen_Auswahl($Raumliste)
>> NEU # SonosBY_SetGroupVolume($Volume)

v1.4
>> NEU # SonosBY_GetSonosInfos($SonosGroupAR_NrDesPlayer)
>> FIX # Ein paar Anpassungen, damit die Funktionen auch mit der Sonos Beta 6.0 funktionieren (Bei längeren Sprachausgaben (über ~10 Sek.) kann es notwendig sein einen IPS_Sleep zu ändern in der Funktion „SonosBY_GruppeAufloesen“. Ist ein workaround, bis Sonos das gefixed hat in der Beta.)

v1.5
>> NEU # Support für Sonos v5.5 und Sonos v6.0
>> NEU # SonosBY_GetTrackDurationSekunden($SonosGroupAR_NrDesPlayer)
>> NEU # SonosBY_Stop_Playing($SonosGroupAR_NrDesPlayer)
>> NEU # SonosBY_Pause_Playing($SonosGroupAR_NrDesPlayer)

v1.6
>> NEU # Support der Amazon/Ivona Class von Titus (TTS mit Amazon / Ivona statt Google Translate)
>> FIX # Optimierungen bei Auswahl mit nur einem Raum (da konnte es zu Fehlerausgaben im Log kommen)

v1.7
>> NEU # SonosBY_PlayPlaylistByName_Auswahl($Raumliste, $PlaylistName)
>> NEU # SonosBY_PlayPlaylistByName_Alle($PlaylistName)
>> NEU # SonosBY_PlayRadiostationByName_Auswahl($Raumliste, $RadiostationName)
>> NEU # SonosBY_PlayRadiostationByID_Auswahl($Raumliste, $RadiostationID)
>> NEU # SonosBY_PlayRadiostationByName_Alle($RadiostationName)
>> NEU # SonosBY_PlayRadiostationByID_Alle($RadiostationID)
>> NEU # SonosBY_SetAVTransportURI($SonosGroupAR_NrDesPlayer, $URI)
>> NEU # SonosBY_AddURItoQueue($SonosGroupAR_NrDesPlayer, $URI)
>> NEU # SonosBY_GruppeAufloesen_Erzwingen()
>> NEU # SonosBY_VolumeLauter($Raumname, $LauterUmWert)
>> NEU # SonosBY_VolumeLeiser($Raumname, $LeiserUmWert)
>> NEU # SonosBY_SetPlayMode($Raumname, $PlayMode)
>> NEU # SonosBY_Stop_Playing_Alle()
>> NEU # SonosBY_BrowsePL()
>> NEU # SonosBY_PlaylistLeeren($SonosGroupAR_NrDesPlayer)

Grüße,
Chris

Hallo Chris,

super Teil. Habe aber das Problem, (in meinem Fall 3 mal Sonos) das bei einem (Fitnessraum) er nicht wieder zurück
geht. Der bleibt dann auf zb. Testnachricht.GoogleTTS.mp3 alle anderen gehen wieder zurück.

Habe im Wohnzimmer die Soundbar, wenn ich auf TV bin geht es natürlich auch nicht mehr zurück, gibt es dafür auch eine Lösung?.

Ein Wunsch wäre noch, dass beim Aufruf „WaschmaschineFertig.waf“ oder mp3 die Datei vorher erzeugt und im Ordner abgelegt wird.

Ansonsten Top Arbeit.

Gruß Uwe

Hi!

1.) Ist dein Fitnessraum der Master? Also an Stelle 0 im Array? Weil beim Master geht er nicht wieder zurück, das will irgendwie nicht klappen g Hatte ich aber geschrieben und auch gesagt, dass man deshalb möglichst eine Sonos als Master definiert, die man selten oder nie verwendet.

2.) Gleiches Problem wie 1? Oder was meinst mit „auf TV“? Habe leider keine Soundbar und kann deshalb nicht testen.

3.) Wenn man eine der TTS-Funktionen nutzt, dann wird die Datei vorher erzeugt (im Verzeichnis auf dem IPS-Server, welcher für Sonos freigegeben und im Sonos eingebunden werden muss - wie bei IPSSonos). Ansonsten könnte er ja gar kein TTS machen. Oder was meinst du?

Grüße,
Chris

Hallo Bayaro,

vielen Dank für Deinen Beitrag.
Leider bekomme ich aber irgendwie die Freigabe für den Ordner nicht wirklich ans laufen. Die Sonosbox meldet keinen Zugriff auf die Datei zu bekommen.
Ich habe die Ordnerfreigabe aktiviert und Jeder hinzugefügt.
Hast Du einen Tip für mich?

Seinem Sonos einen Ordner freigeben vom IPS Server:

1.) Ordner auf dem IPS-Server im Netzwerk freigeben (SMB)
2.) Ordner in der Sonos App oder der Sonos Desktop Software einbinden in seine Bibliothek (Einstellungen > Musikbibliothek verwalten > Musikbibliothek einrichten > Pfad eingeben nach Muster „//192.168.1.10/Ordnername“)
3.) Fertig :slight_smile:

Grüße,
Chris

zu 1, ok habe es nicht richtig gelesen:o

zu 2, TV ist dann in diesem Fall eine ander Quelle, wenn es auf Radio oder Playlisten ist funktioniert es, nur nicht wenn es auf TV steht.

zu 3. also wenn ich zb. dein Bsp. WaescheFertig.mp3 oder wav nehme, geht es nicht. Denn diese waf oder mp3 Datei gibt es ja noch nicht.

zu 1) Ich hoffe, dass ich da noch eine Lösung finde, aber da ich genug Sonos habe und auch eine die eigentlich nur Sprachausgaben macht, ist diese mein Master und daher für mich grad nicht so dramatisch :smiley:

zu 2) Kannst du mit der Sonos App die Soundbar in eine Gruppe von anderen Räumen nehmen, wenn du auf TV bist? Oder ist die Soundbar allgemein „gesperrt“ gegen gruppieren, wenn die auf TV ist?

zu 3) Ich glaube du verstehst da was falsch :wink: Eigentlich ist das gut beschrieben :slight_smile:
Aber mal am Beispiel der Funktion „SonosBY_TTS_Alle(„Test 1 2 3“);“ - diese Funktion erstellt aus dem Text eine Sounddatei (entweder über deine Text to Speech API, wenn du die ID angibst, oder wenn man FALSE einträgt, dann über die Google TTS API). Diese Sounddatei wird dann abgespielt.
Die andere Funktion z.B. „SonosBY_DateiAbspielen_Alle“ spielt einfach nur eine Datei ab, die du vorher da abgelegt hast! Manche haben sich mal selbst was aufgenommen und dann muss das nicht jedes Mal neu generiert werden. Oder auch eine Musikdatei. Oder ein „Klingelton“, wenn es an der Haustür klingelt, …

Soweit verstanden? :slight_smile:

Grüße,
Chris

SonosBY v1.3
>> NEU # SonosBY_GruppeErstellen_Auswahl($Raumliste)
>> NEU # SonosBY_SetGroupVolume($Volume)

Perfekt. Vielen Dank. Der wichtige Hinweis war den Ordner der Bibliothek hinzuzufügen. Logisch!
DANKE

Update online

v1.4
>> NEU # SonosBY_GetSonosInfos($SonosGroupAR_NrDesPlayer)
>> FIX # Ein paar Anpassungen, damit die Funktionen auch mit der Sonos Beta 6.0 funktionieren (Bei längeren Sprachausgaben (über ~10 Sek.) kann es notwendig sein einen IPS_Sleep zu ändern in der Funktion „SonosBY_GruppeAufloesen“. Ist ein workaround, bis Sonos das gefixed hat in der Beta.)

NICHT auf Sonos Beta 6.0 updaten! Die spinnt hinten und vorne total rum! Einfach grausam!!! :mad:

Grüße,
Chris

Antwort auf diesen Beitrag:
IPSSonos - Seite 22

Wenn du in der Konfiguration „$TTS_InstanzID = false;“ eingetragen hast, dann wird die Google API verwendet um den Text in eine MP3 zu „wandeln“ und diese Datei wird dann in dem Pfad gespeichert, den du in der Konfiguration bei „$Sonos_Dateiordner“ eingetragen hast. Dieser Ordner muss freigegeben und in Sonos in der Musikverwaltung eingebunden werden.

Wird die Datei bei dir nicht erstellt, dann hast du noch irgendwo etwas falsch konfiguriert oder eine Firewall/Virenscanner blockt etwas oder irgendwas in der Richtung…

Lies dir nochmal meinen 1. Post durch in die Hinweise/Beispiele im Skript. Vielleicht fällt dir ein Fehler auf.

Grüße,
Chris

Hi Chris,

Ich denke, dass das Problem mit der MP3 neu erzeugen mit Google zusammenhängt. Wenn ich diese Stelle der „SonosBY_TTS“ Function in der „SonosBY.ips.php“ anpasse …

...
       $SonosTTS_Dateiname = "SonosBY_GoogleTTS.mp3";
        $SonosTTS_DateiPfad = $Sonos_Dateiordner.$SonosTTS_Dateiname;
        $Sonos_SMBPfadUndDateiname = $Sonos_SMBordner.$SonosTTS_Dateiname;
        $TTS_Text_UTF8 = urlencode(utf8_encode($TTS_Text));
        if (strlen($TTS_Text_UTF8) > 100) IPS_LogMessage("SonosBY", "Der TTS Text darf maximal 100 Zeichen lang sein");
        $GoogleTTSmp3 = @file_get_contents('http://translate.google.de/translate_tts?tl=de&ie=UTF-8&q='.$TTS_Text_UTF8."&client=t");		
        if ((strpos($http_response_header[0], "200") != false)) {
            file_put_contents($SonosTTS_DateiPfad, $GoogleTTSmp3);
        }
		file_put_contents($SonosTTS_DateiPfad, $GoogleTTSmp3);
        
        IPS_Sleep(500);
        SonosBY_SetAVTransportFile($i, $Sonos_SMBPfadUndDateiname);
        SonosBY_StartResume_Playing($i);
    }
...

… sodass er quasi immer einen

file_put_contents

macht und somit immer ein MP3 File erzeugt, bekomme ich die Fehlermeldung in der SonosApp, dass das MP3 File falsch codiert ist …
Habe gestern dann eine TTS Instanz angelegt und als Engine „Microsoft Hedda Desktop“ ausgewählt. Ausgang leer gelassen.
Die Wav Datei wird stehts neu angelegt - Perfekt! … ich kann mir sie auch im VLC anhören. WindowsMediaPlayer leider nicht und in der SonosApp von Windows wird sie auch nicht abgespielt. :confused:

Moin!

Ich hab leider echt keine Ahnung was da bei dir los ist. Ich hatte bei vielen Tests weder mit Google TTS noch mit Offline (Windows) TTS irgendwelche Probleme in dieser Richtung :confused: Auch IPSSonos oder sonstige Projekte mit TTS arbeiten nach der gleichen Methode, da hab ich sowas auch noch nicht gehört… Ich würde deshalb auf irgendwas lokales bei dir tippen…

Grüße,
Chris

ok … dürfte anscheinend an Windows 8.1 liegen :frowning:

https://www.symcon.de/forum/threads/26570-Problem-mit-TTS_GenerateFile?p=243455#post243455

https://www.symcon.de/forum/threads/26570-Problem-mit-TTS_GenerateFile?p=262120#post262120

Ah, ja, jetzt wo du es sagst…mit Win 8.1 war mal was :smiley: Wer nimmt auch freiwillig Win 8.x tzzzz :wink: :stuck_out_tongue:

Grüße,
Chris

Danke Dir für dieses sehr geniale Script Chris ! Hammer Arbeit ! Danke
War einfach einzurichten und funktioniert auf Anhieb ! Cool

[ul]
[li]Was nutzt ihr so wenn nicht gerade Google TTS ? Irgendwelche Online TTS to MP3 Dienste für eine erotischere oder bessere Stimme ?[/li][li]Was sind hier eure Anwendungsfälle ? Ein paar Beispiele als Anregung wären doch ganz cool. Waschmaschine fertig… Willkommen zu Hause… usw… ?![/li][/ul]

Gruß
Christian

Abend!

Danke und gerne :slight_smile:

Ich nutze die Microsoft TTS API, welche direkt in IPS als Instanz verfügbar ist. Bei uns spricht die Stimme „Alex“ von „CereProc“ (kann man auf der Webseite vom Anbieter mit eigenen Texten ausprobieren). Gibt es für kleines Geld und klingt, so finden wir, deutlich besser/menschlicher als alle bisher bekannten kostenlosen Stimmen :cool: Aber da hat wohl jeder so seine eigenen Vorlieben. Auch funktioniert die nur unter Windows.

Sprachausgaben sollte man nicht zu viele machen, sonst nervt es schnell :wink:

Ich nutze die Sprachausgabe aktuell für:
> Waschmaschine fertig
> Wäschetrockner fertig
> Tagesmeldungen mit Wetter, Mülltonnen, … (nur auf Befehl)
> Haustür ist länger als X Minuten offen
> Kühlschrank ist ausgefallen
> Alarmanlage mit jeweiligem Auslöser

Grüße,
Chris

Ich hab das Problem, dass mir zB der Transportstatus PLAYING zurückgibt für den Nicht-Gruppenmaster auch wenn die Gruppe nichts abspielt.

Beispiel:
Schlafzimmer + Küche -> Schlafzimmer ist Master

Nach Stop der Wiedergabe ist SZ auf STOPPED aber Küche weiterhin auf PLAYING

Wie kann man das Problem umgehen? Gibts da einen Ansatz dafür? Ansonsten Danke für das tolle Script! :slight_smile:

Hi!

Du hast nicht zufällig deine Sonos-Player auf 6.x aktualisiert?

Weil bei der 5.x war noch alles ok, dann hatte ich mal die Beta 6 getestet und da wurde fälschlicherweise immer Status PLAYING zurückgegeben, sobald ein Player in einer Gruppe war.

Das ist ein Fehler von Sonos (hatte denen den Bug auch schon gemeldet, hat aber keinen interessiert, Case wurde einfach geschlossen nach ein paar Tagen, obwohl der Bug noch da war) und wenn der in 6.x FINAL nicht behoben ist, dann muss ich mir da was neues einfallen lassen, damit die Gruppen sich wieder sauber auflösen.
Denn bei 5.x konnte ich so lange warten, bis PLAYING nicht mehr als Status gemeldet wurde und dann habe ich die Gruppe aufgelöst.

Grüße,
Chris

Ich hatte die 6er Beta drauf. Bin aber wegen deinem Script zurück zu 5.5 … Könnte mich schon ärgern jetzt :slight_smile: