Sonos Modul

Vielen Dank, 1007, das werde ich am WE gleich mal versuchen… VG!

Hallo 1007,

Deine Einschätzung war genau richtig - ich habe die beiden neuen Play1 ebefalls bei IPS eingerichtet, nun sind die Meldungen glücklicherweise verschwunden.

Danke noch einmal, schönes WE und viele Grüße!

Hat jemand eine Idee was die Funktion macht? Bin Neugierig.
Ist wohl in 1.5.3 reingekommen

Die Funktion gibt einen Array als Antwort mit allen aktuellen Werten der Sonos Instanz zurück. Diese kann z.B. von einem Custom Skill aufgerufen werden bzw. wird auch von IPSI genutzt werden um mit Alexa sich Sachen von Sonos ansagen zu lassen. Wie Beispielsweise laufender Titel mit Interpret und so weiter.

Siehe auch

Patami Framework
bzw. Beispiel Sonos
Sonos über Alexa abrufen und steuern.

In dem Fall wird die Funktion genutzt um an die Track Info für Alexa zu kommen.

Hallo,

ich bin gerade dabei mein Netzt umzubauen. Danach würden die IoT Komponenten und die Sonos Komponenten in verschiedenen VLANs und Subnetzen stehen.

Um aber trotzdem von IPS auf SONOS mit diesem Modul zugreifen zu können muss ich eine Firewall-Regel erstellen.
Jetzt sind das ja alles Soap-Calls. Die finden auf Port 1400 statt.
Reicht es also dafür eine Firewallregel zu machen, oder was wäre noch notwendig?
Ich habe alle Komponenten von Ubiquiti (Unifi), falls das wichtig ist.

Hat damit jemand Erfahrung gesammelt?

Gruß
Christian

Mal so nen leicht anderes Thema so nebenbei:

Weiß jemand etwas vom Thorsten ? Er war schon lange nicht mehr Online lt. Profil und meldet sich hier auch nicht mehr zu Wort. Mache mir da ein wenig Sorgen, er war ja doch immer recht aktiv hier.

Hallo,

das ist aber nett :wink:

Ja, das stimmt. Hab gerade recht viel um die Ohren.
Heute habe ich mich zufällig das erste mal seit Ewigkeiten wieder auf den Aktuellen Stand gebracht.

Ja, grob richtig.
Ich habe Deinen Vorschlag mal für alle eingebaut. Danke.
-> Version 1.5.4

Ne, würde ich auch so sehen.
Immer wenn mit Sonos kommuniziert wird, geht es auf Port 1400.
Allerdings musst Du es für alle Geräte zulassen (oder hat das komplette Subnetz).

Hatte nur kurz geschaut, evtl. finde ich ja demnächst mal wieder Zeit…
Aber grundsätzlich sollte das passen.

grundsätzlich ja.
Es gibt die Soap Funktion „BecomeGroupCoordinator“. Damit sollte es funktionieren.
Allerdings müsste man dann auch die im IPS die ganzen Zuordnungnen anpassen :eek:
Den Aufwand hatte ich bislang immer gescheut.
Ich schreibe es aber mal auf die Liste…

Gruß,
Thorsten

Danke für deine Rückmeldung. „BecomeGroupCoordinator“ nutze ich, aber dann verschluckt es sich tatsächlich in IPS. Ich nutze es, um Musik zwischen Abspielgeräten zu verschieben. Würde mich freuen, wenn es sich im Modul wiederfindet !

Hallo Torsten,

vielen Dank für das super Modul.
Hab gerade meine Klingel damit realisiert.
Funktioniert einfach klasse :slight_smile:

Viele Grüße
Dieter

Hallo,

gibt es eigentlich einen Befehl, mit dem ich jeweils auf den nächsten oder den vorangehenden Radiosender einer Liste mit Radiostationen (z.B. der tuneIn-Liste) gehen kann?

Mit SNS_SetRadio kann ich ja nur auf einen konkreten Sender gehen…

Danke und viele Grüße…

Leider ist ein weiteres Problem aufgetreten:

Ein Play1 ist verbunden und über das Webinterface des Play1 auch erreichbar über den Browser. Dennoch bekomme ich in IPS beim Einrichten die Meldung

Error: "Connection timed out after 1001 milliseconds." - Code 28

Auch das Neueinrichten funktioniert nicht, ebenso wenig, den Play1 vom Strom zu nehmen oder den Timeout z.B. auf 5000 zu stellen…

Kann jemand helfen???

Danke und viele Grüße…

Hallo zusammen,

ich versuche gerade das Sonos Modul in IPSView darzustellen. Klappt soweit auch alles, bis auf den Sleeptimer.

Jedemal wenn ich ihn hoch setze wird der Sleeptimer jedes mal wieder auf „0“ gesetzt.
Liegt das an dem _updateStatus-Skript, welches alle 5 Sekunde aktualisiert oder muss ich dabei noch etwas anderes beachten?

Beste Grüße
Kai

Einen solchen Befehl konnte ich weiter nicht finden. Ich habe daher derzeit parallel noch diese Steuerung laufen:

https://homematic-forum.de/forum/viewtopic.php?f=31&t=14198&p=111626#p111626

Dort ist folgender php-code hinterlegt, in dem Radiostationen eingegeben werden und mit „nextradio“ weitergeschaltet werden können:

<?php
#####################################################################################
#
# Version: 	0.4.0
# Datum: 	01.09.2013
# Veröffentlicht im Forum: http://homematic-forum.de
# Username: dzvo
# 
# Bekannte Probleme:
# ------------------
# 
#
# 
# Anmerkungen:
# ------------
# - Volumen kann angegeben werden muss jedoch nicht, wenn keine Angabe wird Standard Lautstärke eingestellt 
# 
# Grundlegender URL Aufbau:
# -------------------------
# sonos2.php?zonen=SONOSPLAYER&action=BEFEHL&BEFEHL=Option
# Beispiele:
# sonos2.php?zonen=buero&action=play              			 	-> Absielen Starten
# sonos2.php?zonen=buero&action=pause							-> Abspielen Pausieren
# sonos2.php?zonen=buero&action=next							-> Nächster Titel
# sonos2.php?zonen=buero&action=previous						-> Verheriger Titel
# sonos2.php?zonen=buero&action=mute&mute=false					-> Sonos Laut schalten - false
# sonos2.php?zonen=buero&action=mute&mute=true					-> Sonos Leise schalten - true
# sonos2.php?zonen=buero&message=1&volumen=20					-> Nachricht 1 anspielen mit Lautstärke 20
# sonos2.php?zonen=buero&action=titelinfo						-> einfache HTML Playlist Anzeige
# sonos2.php?zonen=buero&action=addmember&member=kueche			-> Zone Kueche zur Zone Buero hinzufügen
# sonos2.php?zonen=buero&action=removemember&member=kueche		-> Zone Kueche aus der Zone Buero entfernen
# sonos2.php?zonen=schlafzimmer&action=sonosplaylist&playlist=Einschlafmusik&volume=1
# sonos2.php?zonen=schlafzimmer&action=stop
#
#
# zonen=			(wohnzimmer,buero,bad,kueche,schlafzimmer)	-> kleinschreibung, keine Leer oder Sonderzeichen
#		
# action=							
#		play													-> Abspielen
#		pause													-> Pause
#		next													-> nachster Titel
#		previous												-> vorheriger Titel
#		rewind													-> Beginn des Titels
# 		mute				(true,false)						-> Stumm schalten
#		stop													-> Absielen beenden
#		toggle													-> Play / Pause umschalten
#		playmode			(normal,shuffle_norepeat,
#								repeat_all,shuffle)				-> Abspielmodus
#		crossfade			(0,1)								-> Titelübergang aus, aus
#		remove				(Nummer des Titels)					-> Titel aus der Playlist löschen
#		clearqueue												-> Playlist löschen
#		playqueue												-> Absielen (nach Radiohöhren) der aktuellen Playlist
#		volume				(0-100)								-> Lautstärke setzen
#		volumeup												-> Lautstärke um 3% erhöhen
#		volumedown												-> Lautstärke um 5% verringern
#		addMember			(&member=SONOSZONE)					-> weitere Zone der Vorhanden hinzufügen
#		removemember		(&member=SONOSZONE)					-> vorhandene Zone entfernen
#		nextradio												-> nächsten Radiosender aus der Liste abspielen
#		prevradio												-> verherigen Radiosender aus der Liste absielen
#		sonosplaylist		(&playlist=SONOS Playlist)			-> Abspielen einer SONOS Playlist
#		radioplaylist		(&playlist=SONOS Radio Playlist)	-> Radioliste unter "Meine Radiosender" 
#		message				(&message=ZAHL&[volume=ZAHL])		-> Abspielen von Nachrichten z.B. ... 
#																	1.mp3 - Waschmaschiene ist ferig
#																	2.mp3 - Es hat geklingelt an der Tür
#																	3.mp3 -  ...
#									
#									
#									
#									
#									
#									
######## Anzupassender Bereich #######################################################

# Hier kommem die einzelnen Sonos Player rein "name_kleingeschrieben" => "IP Adresse des Players"
$sonoszone = array(	"wohnzimmer" => "192.168.100.230",
					"buero" => "192.168.100.231",
					"bad"  => "192.168.100.232",
					"kueche"  => "192.168.100.233",
					"schlafzimmer"  => "192.168.100.234");
					
# Hier können eigene Radio Sender definiert werden, welche bei radionext oder radioprev angesteuert werden
# An der Stelle kommt nur der Stationsname rein.
$radio_name = array ( 	"NDR 1 Niedersachsen",
						"Antenne Bayern Chillout",
						"Space Music");
					  
# und hier die URL zum Stationsnamen.
$radio_adresse = array ("x-rincon-mp3radio://ndrstream.ic.llnwd.net/stream/ndrstream_ndr1niedersachsen_hi_mp3",
						"x-rincon-mp3radio://mp3channels.webradio.antenne.de/chillout",
						"x-rincon-mp3radio://pub5.di.fm:80/di_spacemusic");

# Speicherort der Nachrichten zur Durchsage
$messagespeicher = "//Storage/Multimedia/iTunes/Temp";   # Windows Backslash \\ und Slash \ in Pfadangaben durch // und / ersetzen ohne Slash am Ende

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

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

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

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

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

$debug = 0;

include("PHPSonos.inc.php");

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

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

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

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

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

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

	}

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

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

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

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

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


			break;
		
		case 'clearqueue':
				$sonos->ClearQueue();
			break;  
		  
		case 'volume':
			if(isset($volume)) {
				$sonos->SetVolume($volume);
			}
			else {
				die('falscher Wertebereich für das Volume');
			}
			break;  
		  
		case 'volumeup': 
			$volume = $sonos->GetVolume();
			if($volume < 100) {
				$volume = $volume + $volumeup;
				$sonos->SetVolume($volume);
			}      
			break;
			  
		case 'volumedown':
			$volume = $sonos->GetVolume();
			if($volume > 0) {
				$volume = $volume - $volumedown;
			$sonos->SetVolume($volume);
			}
			break;      

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

		case 'removemember':

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

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


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

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

			$pleinzeln = 0;
			while ( $pleinzeln < count($sonoslists) ) {
				if (debug == 1) {
					echo "Playlist " . $pleinzeln . "<br>

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

					#$zustand = "NORMAL";
					#$sonos->SetPlayMode($zustand);

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

		case 'radioplaylist':
			
			if(isset($_GET['playlist'])) {
				$playlist = $_GET['playlist'];
			}
			else {
			  die ("Keine Radio Playlist gefunden.");
			}
			# Sonos Radio Playlist ermitteln und mit übergebene vergleichen	
			$radiolists = $sonos->Browse("R:0/0","c");

			$rleinzeln = 0;
			while ( $rleinzeln < count($radiolists) ) {
				if (debug == 1) {
					echo "Radioliste " . $rleinzeln . "<br>

";
					echo "ID: " . $radiolists[$rleinzeln]["id"] . "<br>
";
					echo "Titel: " . $radiolists[$rleinzeln]["title"] . "<br>
";
					echo "Typ: " . $radiolists[$rleinzeln]["typ"] . "<br>
";
					echo "File: " . $radiolists[$rleinzeln]["res"] . "<br>
";
					echo urldecode($radiolists[$rleinzeln]["res"]) . "<br>
";
					echo "ausgewählter Radiosender: " . $playlist . "<br>
";
					echo "<br>
";
				}
				
						if (urldecode($playlist) == $radiolists[$rleinzeln]["title"]) {
													
							$sonos->SetRadio(urldecode($radiolists[$rleinzeln]["res"]));
							$sonos->RampToVolume($rampto, $volume);
							$sonos->play();
						}
			$rleinzeln++;
			}	

		break;
		
		case 'titelinfo':
		
			if($debug == 1) {
				echo debug();
			}

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

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

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

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

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

			$abort = false;

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

					if ($save_Status == 1) {            
						  $sonos->Play();
						}
					if ($save_Status == 3 ) {
						$sonos->Stop();
						}
					
				}elseif ($wiederherstellen == "Radio" ){
					
					# je nach dem ob Radio vorhier Lief oder nicht Zustand wieder herstellen.
					# save_Status //1 = PLAYING //2 = PAUSED_PLAYBACK //3 = STOPPED
					# $save_TransportSettings  repeat shuffle ...	
					
					# alten Radiosender weiterspielen
					
						$sonos->SetRadio($save_PositionInfo["URI"], $save_MediaInfo["title"]);
						$sonos->SetVolume($save_Vol);
						$sonos->SetMute($save_Mute);
						
						if($save_Status == 1) {
							$sonos->Play();
					}
				}
		} 
	else
	{
		die ("Keine Nachricht, keine Lautstärke angegeben oder falsche Werte angegeben.");
	}
	
    break;
	
	# Debug Bereich ------------------------------------------------------
		case 'getmedianfo':
			echo '<PRE>';
			print_r($sonos->GetMediaInfo());
			echo '</PRE>';
		  break;

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

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

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

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

				if (substr($temp["TrackURI"], 0, 9) == "x-rincon:" ) {
					$masterrincon = substr($temp["TrackURI"], 9 ,24);
					}
				
				foreach ($sonoszone as $masterplayer => $ip) {
					if(getRINCON($ip) == $masterrincon) {
						echo "<br>" . $player . " -> ";
						echo "Master des Players: " . $masterplayer;
					}
				}
				$masterrincon = "";
			}
			break;
		
	 
		  
	default:
       die("Dieser Befehl ist nicht bekannt. <br>sonos2.php?zonen=SONOSPLAYER&action=BEFEHL&BEFEHL=Option");


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



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


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

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


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

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

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





?>

Thorsten, wäre es Dir möglich, den nextradio-Befehl updatefest zu implementieren, bspw. für die Sonos-Favoriten-Liste?

Dann könnte ich endlich eingleisig fahren…

Vielen lieben Dank und Grüße, Götz

Das ist ja eine einfache Funktion, der Array mit der Radiostationen ist ja vorhanden, es muss lediglich geschaut werden welches Radio gerade läuft und dann der nächste Key aufgerufen werden.

Ich habe das mal bei mir ergänzt, kannst Du ja mal ausprobieren, wenn es geht kann man einen Pull Request erstellen.

Hier findest Du den Fork
https://github.com/Wolbolar/SymconSonos

Die Funktionen heißen


SNS_NextRadiostation(integer $InstanceID);

und


SNS_PreviousRadioStation(integer $InstanceID);

Hallo Fonzo,

das klingt vielversprechend, vielen Dank!

Sorry für die Frage, aber ich komme nicht aus dem Bereich :confused::

Wie muss ich jetzt vorgehen, um das auszuprobieren???

Und wenn es funktioniert, was hat es mit dem Erstellen eines Pull Request (?) auf sich?

Noch mal vielen Dank für Deine Hilfe…!!!

VG, Götz

Ein Fork ist ein Zweig des Originals, Du könntest Dir z.B. auch einen Fork erstellen und dort dann Änderungen durchführen. Um das Auszuprobieren bleiben alle Sonos Instanzen bestehen, diese bleiben unverändert. Du gehst unter Kerninstanzen -> Modules und suchst dort den Eintrag vom Sonos Modul, diesen erfernst Du mit dem Minus. Damit ist zunächst mal nur das Modul entfernt die Instanzen sind aber noch existent.

Jetzts fügst Du den Fork unter Modules mit Hinzufügen dazu mit der URL


https://github.com/Wolbolar/SymconSonos

Änderungen sind hier deutsche Übersetzung, eine zusätzliche Position Variable, Deine zwei Funktionen und optional ein Media Element als Cover, die Skripte sowie die Events fallen weg, diese sind jetzt Modul intern. Wenn das hinzugefügt worden ist, solltest Du die Instanzen wie bisher nutzten können. Wenn irgendwas nicht geht machst Du den gleichen Prozess noch mal und installierst wieder das Original Repository von kugelberg.

Gesetzt den Fall es funktioniert alles wie bisher plus deine neuen Funktionen, dann kann man einen Pull Request erstellen. Dabei werden die Änderungen des Zweigs (Forks) an den kugelberg Repository übertragen. Thorsten kann dann prüfen ob er die Änderungen übernehmen will, falls ja, werden die Änderungen mit dem Original zusammengeführt (gemerged) und sind dann im Original Repository für alle verfügbar, die das Modul nutzten.

So kannst Du also jederzeit Änderungen am Modul durchführen ohne das das Thorsten immer machen muss. Erst einen Fork erstellen, die Dinge ändern die Dir fehlen und dann wieder einen Pull Request erstellen. So muss Thorsten das nicht selber machen, sondern muss nur noch prüfen ob er die Änderungen übernehmen will.

Hallo Fonzo,
was hat denn Alexa in deinem Modul zu suchen ?

Die Funktion ist bei Thorsten auch schon drinnen. Wer will kann ja Sonos über Alexa steuern, dazu ist dann halt ein Custom Skill notwendig, bzw. wen einem An / Aus und so was reicht kann man auch den SmartHomeSkill dazu nehmen. So sieht das Grob aus wenn man das selber bauen will das Skript kannst Du ja als Vorlage nutzen.
Sonos mit Custom Skill.

Sonos selber ist ja am Basteln von einem Skill für Sonos. Mal sehen was dabei raus kommt. Sollte der Funktionsumfang begrenzt sein, was ich nicht hoffe, kann man sich ja immer noch überlegen ob es sich lohnt einen Sonos Custom Skill für alle mit IPS zu veröffentlichen. So ist es zur Zeit das schnellste man richtet das selber ein.

Vielen Dank Fonzo, für Deine Geduld und die ausführliche Erörterung. Das war sehr hilfreich und damit sollte ich es dann auch schaffen. Ich gebe ein Feedback, sobald ich die Gelegeheit zum Testen hatte…

VG, Götz

Danke Fonzo,

die Daten hatte ich so noch nicht gesehen. Ich denke Sonos sollte Sonos bleiben, der Rest sollte dann in ein eigenes Modul, wie meine LCN Anbindung. Alexa hat méiner Meinung nichts in dem Sonos Modul zu suchen, wie auch andere Fremdsysteme (War mal der Wunsch hier). Muß mal überlegen, wie es weitergeht.:eek: