IPSSonos

Abend!

Danke fürs Einbauen :slight_smile:

Aber nur damit ich es nicht falsch verstehe…Offset ist, wie vorher für Sound, nur die Anhebung der Lautstärke um z.B. 20%, oder?! Und keine Einstellung der Lautstärke auf z.B. Lautstärke 40% bei Offset 40?!

-Chris-

yep, funktioniert analog der Sound-Ausgabe.

Hallo,

Vielen Dank für die Klasse Unterstützung rund um Sonos … eine Frage habe ich allerdings … wenn ich einen Raum von einem „anderen“ Tab wähle … zum Beispiel vom Config Tab aus … dann sehe ich eine „Verbindung / Zugriff“ auf cloudfront.net - wie kommt das denn Zustande?

Danke und Grüße,
MaLu

OK, OK, verstanden … wieso …

Hallo Joki,

Super und vielen Danke für die rasche Umsetzung!

Hallo,

ich nutze u.a. SONOS ZP90 an meiner Heimkino-Anlage. Nun habe ich es mit IPSSonos fertig gebracht, dass beim Einschalten der Zone auch die Heimkino-Anlage mit ein-/ausschaltet.

Nur muß, wenn eine Zone eingeschaltet wird, zusätzlich noch der Player auf „Play“ geschaltet werden. Also jedes Mal ein zusätzlicher Klick, der eigentlich nicht nötig wäre, weil wenn ich eine Zone ein schalte, möchte ich sie auch abbspielen.

Vielleicht könnte man mittels einer Option in der Konfig, das sofortige Abspielen nach dem Einschalten, optional aktivierbar/deaktivierbar machen.

Gruß Proxima

Hallo proxima,

das kannst du doch relativ einfach selbst mit einem Skript lösen, welches durch ein ausgelöstes Ereignis (das Anschalten der Sonos Zone oder des AV Receivers) getriggert wird.

Du musst dem Sonos dann natürlich mitgeben, was es als Default Auswahl abspielen soll. Zum Beispiel einen bestimmten Radiosender oder was auch immer…

Ich hab das bei mir andersrum gelöst, wenn ich beim Sonos im Wohnzimmer PLAY drücke (egal ob in der Handy-App oder im IPS WebFront), dann schaltet sich mein AV Receiver ein und schaltet sich dann auf den richtigen Eingang. Und wenn ich wieder STOP drücke, dann schaltet sich der AV Receiver wieder aus (wenn er davor nicht schon an war).

<?
include "DENON.Functions.ips.php";
IPSUtils_Include ('IPSSonos.inc.php', 'IPSLibrary::app::modules::IPSSonos');

$SonosWZstatus = 58331 /*[Program\IPSLibrary\data\modules\IPSSonos\Wohnzimmer\TRANSPORT]*/;
$sonos = 37451 /*[Skripte & Variablen\Szenen\Quellgerät\Sonos]*/;
$denonSocket = 31035 /*[DENON Client Socket]*/;
$denonSource = 51419 /*[DENON\Main Zone\InputSource]*/;
$denonPower = 32953 /*[DENON\Main Zone\MainZonePower]*/;
$denonWarAn = 41326 /*[Skripte & Variablen\MediaPlayer\Sonos\Wohnzimmer\Denon umschalten auf Sonos bei Play\DenonAVR war angeschaltet]*/;
$denonInputSource = 51419 /*[DENON\Main Zone\InputSource]*/;

$dreamboxWZ = 40986 /*[Skripte & Variablen\Szenen\Quellgerät\Dreambox]*/;
$playstation4 = 32420 /*[Skripte & Variablen\Szenen\Quellgerät\PlayStation 4]*/;
$miniPC = 37219 /*[Skripte & Variablen\Szenen\Quellgerät\Mini-PC]*/;
$frontHDMI = 55501 /*[Skripte & Variablen\Szenen\Quellgerät\Front-HDMI]*/;


if (GetValue($denonPower) == false) {
	IPSSonos_Stop('Wohnzimmer');
	SetValue($sonos, false);
}

if ((GetValue($SonosWZstatus) == 0) OR (GetValue($SonosWZstatus) == 1) OR (GetValue($SonosWZstatus) == 4)) {
   if (GetValue($denonPower) == true) {
		SetValue($denonWarAn, true);
	}
	if (GetValue($denonPower) == false) {
		SetValue($denonWarAn, false);
	}
	// SONOS AN >> Quelle und Denon anschalten
   SetValue($sonos, true);
	SetValue($playstation4, false);
	SetValue($dreamboxWZ, false);
	SetValue($frontHDMI, false);
	SetValue($miniPC, false);
	if (GetValue($denonPower) == false) {
	   DENON_Power($denonSocket, "ON");
		IPS_Sleep(9999);
	}
	if (GetValue($denonSource) != 1)  {
		DENON_Input($denonSocket, "CD");
   	IPS_Sleep(4000);
   	DENON_MasterVolumeFix($denonSocket, "520");  // entspricht 60
	}
}
else {
	// SONOS Pause/Stop >> Denon AUS
   SetValue($sonos, false);
	if ((GetValue($dreamboxWZ) == false) AND (GetValue($miniPC) == false) AND (GetValue($sonos) == false) AND (GetValue($playstation4) == false) AND (GetValue($frontHDMI) == false) AND (GetValue($denonWarAn) == false)) {
	   DENON_POWER($denonSocket, "STANDBY");
	   IPSSonos_Stop('Wohnzimmer');
	}
}

?>

sonosWZ.jpg

…viele Wege führen nach Rom :slight_smile: Bei dir würde es dann auch ausreichen, wenn du so etwas in der Art einbaust (getriggert durch die Variable vom Sonos, welche sich auf TRUE schaltet, wenn du es bei dir einschaltest):

$sonosZoneWohnzimmerAktiv = GetValue(12345);  // hier wird die Variable ausgelesen, welche angeschaltet wird, wenn du Sonos anschaltest

if ($sonosZoneWohnzimmerAktiv == true) {
   IPSSonos_PlayRadiostationByID('Wohnzimmer', 1);
}

…nur mal als kurzes Beispiel. Gibt wie gesagt einige Varianten :slight_smile:

Grüße,
Chris

Hallo Jörg,
kannst du bei Gelegenheit noch eine Funktion für die PlayBar hinzufügen. Ich würde gerne von Radio auf den S/PDIF zurück schalten.

Mit WireShark konnte ich folgendes mitschneiden:

Hypertext Transfer Protocol
    POST /MediaRenderer/AVTransport/Control HTTP/1.1

    CONNECTION: close

    ACCEPT-ENCODING: gzip

    HOST: 192.168.178.100:1400

    USER-AGENT: Linux UPnP/1.0 Sonos/28.1-83040 (WDCR:Microsoft Windows NT 6.2.9200.0)

    CONTENT-LENGTH: 390

    CONTENT-TYPE: text/xml; charset="utf-8"

    SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI"

    

    [Full request URI: http://192.168.178.100:1400/MediaRenderer/AVTransport/Control]
    [HTTP request 1/1]
    [Response in frame: 88]
eXtensible Markup Language
    <s:Envelope
        xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
        s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
        <s:Body>
            <u:SetAVTransportURI
                xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">
                <InstanceID>
                    0
                    </InstanceID>
                <CurrentURI>
                    x-sonos-htastream:RINCON_B8E93778BA2A01400:spdif
                    </CurrentURI>
                <CurrentURIMetaData>
                    </CurrentURIMetaData>
                </u:SetAVTransportURI>
            </s:Body>
        </s:Envelope>

Folgender Fehler ist mir aufgefallen.
Wenn man während der Wiedergabe über S/PDIF auf „Pause“ oder „Stop“ drückt wird folgendes ausgegeben.

Ansonsten hat alles super funktioniert. Vielen dank dafür!

Gruß, Raul.

Hallo joki,

das Modul wird bei mir im Webfront zur Installation gar nicht angezeigt! Woran kann das liegen?

Ist der Eintrag in der Ini KnownRepositories „Repository=https://raw.githubusercontent.com/jokide/jokideIPSLibrary/master/“ korrekt? Was mache ich falsch?

Viele Grüße und einen guten Rutsch Tommy

Hallo,

Installation der Bibliothek hat funktioniert! Warum auch immer?

Jetzt habe ich ein Problem mit der Sprachausgabe. Vielleicht weiß ja jemand Rat!

Ich höre keine Ansage obwohl die aktuelle Ausgabe unterbrochen wird und manchmal auch wieder startet! Im Sound-verzeichnis wird auch die Ansage Datei erstellt. Im Sonos Controller (Windows) erhalte ich die Meldung das der Zugriff auf die Datei verweigert wurde. Was mache ich falsch, bzw. wo muß ich noch etwas Freigeben? SMB im Sonos Controller ist erfolgt! Glaube ich zumindest, da ich das MP3 File hier direkt wiedergeben kann!

Danke und Gruß Tommy

Hallo nochmal,

habs hinbekommen! Ich habe in der Config den den SMB-Pfad so eingetragen wie er im Sonos Win-Controller steht!

function IPSSonos_GetMessageConfiguration() {
		return array(
			IPSSONOS_VAR_LPATH		=> 	'D:\\IPS-Config\\Sounds\\',				// Mandatory: Local folder to store wav and mp3 files 
			IPSSONOS_VAR_SMBPATH	=> 	'//IPS-PC/Sounds/',		// Mandatory: SMB share of the local path specified above
			IPSSONOS_VAR_TTSID		=> 	'31115',								// Optional:  ID of TTS (Text To Speech) instance
			

Über die IP geht es irgendwie nicht da hat der Player keinen Zugriff.

Danke noch mal für die tolle Arbeit!:smiley:

Gruß Tommy

Abend allerseits!

Ist es irgendwo möglich mit IPSSonos abzufragen, ob eine der Sonos Boxen gerade als Wiedergabe-Quelle „Eingang“ gewählt hat?

Es ist ja möglich abzufragen, ob gerade ein Radio-Stream abgespielt wird oder eine Datei oder sowas. Aber wenn ich in der Sonos App auf „Eingang“ gehe und dort das Audiosignal von meinem Sonos Connect Eingang abspielen lasse, dann sehe ich das in IPSSonos nicht. Ich sehe nur PLAY und sonst keine Infos, welche eine Zuordnung erlauben.
Ich kann es weder an PLAYERDETAILS, noch am TITLE oder sonstwas fest machen, dass gerade der Eingang vom Sonos Connect wiedergegeben wird…

Hat jemand eine Idee? :confused:

> Bei FHEM hat jemand wohl etwas in der Richtung gemacht, aber leider habe ich bis auf diese Sätze noch nichts an Infos finden können:
„Es gibt jetzt ein Reading ‚LineInConnected‘, welches eine ‚1‘ enthält, wenn der Line-In-Eingang angeschlossen wurde, sonst ‚0‘.“
LineInConnected: Gibt an, ob der Line-In-Eingang angeschlossen ist, oder nicht. Wird bei Änderung am Player automatisch aktualisiert, und erzeugt damit auch ein Event.
…und das wäre ja auch nicht genau das was ich möchte. Ich will ja nicht wissen, ob etwas daran angeschlossen ist, sondern ob gerade eine Sonos diesen Eingang wiedergibt…

Schön wäre es auch, wenn ich nicht nur im IPS erkennen könnte, wenn eine Sonos etwas vom „Eingang“ abspielt, sondern wenn ich auch aus IPS heraus eine Sonos Box dazu bringen könnte, den Eingang abzuspielen. Also so wie „RadioStationByID“ abspielen dann sowas in der Art wie „EingangByID“ abspielen?! Kein muss, wäre aber schön :slight_smile:

Vielen Dank im Voraus und Grüße,
Chris

Hallo,

ich musste letztens leider feststellen, dass die Funktion „IPSSonos_PlayTTSByRoomSimple“ keine Audiodatei erzeugt, wenn der Text größer 100 Zeichen ist. Diese Limitierung kommt von Google.

Es gibt aber eine „Lösung“ :smiley:

Man benötigt die PHP getid3 library.
Die library findet ihr samt Beispiel auch im Anhang.

Quelle: Text To Speech Using Google API In PHP

Hier ein Beispiel von mir für die Verwendung mit IPSSonos:


require_once('getid3/getid3.php');

define("MP3_FILENAME", "../media/Test");

$str ='Dieser Text ist länger als 100 Zeichen und wird somit nicht korrekt verarbeitet. Es wird daher keine Audiodatei erzeugt-';

converTextToMP3($str,MP3_FILENAME.".mp3");

$params =  array (
	 "Rooms"		    =>  'Esszimmer',
	 "Volume_Ramp"  =>  'fast',	
	 "Sound"         	    =>  'Test.mp3',
	 "Sound_Repeat" =>  '2',
         "Sound_Delay"   =>  '500',
	);

IPSSonos_PlayMessage($params);

/**** Don't change the code below ****/
function converTextToMP3($str,$outfile)
{
	$base_url='http://translate.google.com/translate_tts?tl=de-de&ie=UTF-8&client=&q=';
	$tts_strings = splitString($str);
	$files=array();
	foreach($tts_strings as $tts_string)
	{
		$umlaute = Array("/ä/","/ö/","/ü/","/Ä/","/Ö/","/Ü/","/ß/");
		$replace = Array("ae","oe","ue","Ae","Oe","Ue","ss");

		$tts_string = preg_replace($umlaute,$replace,$tts_string);
		$tts_string .= ".";
	
		$url= $base_url.urlencode($tts_string);

		$filename =md5($tts_string).".mp3";

		if(!downloadMP3($url,$filename))
		{
			IPSLogger_Err(LogId, "Failed to download mp3 from URL: ".$url);
			return false;
		}
		else
		{
			$files[] = $filename;
		}

	}

	if(count($files) == count($tts_strings)) //if all the strings are download
		CombineMultipleMP3sTo($outfile,$files);
	else
		echo "ERROR. Unable to convert";

	foreach($files as $file)
	{
		unlink($file);
	}
	return true;
}

function splitString($str)
{
	$ret=array();

	// Split sentences
	$arrSentences=explode(".",$str);
	// Get only the elements with content
	$arrSentences = array_filter($arrSentences);
	
	foreach($arrSentences as $sentence) {
		// Split sentence into words
		$arr=explode(" ",$sentence);
		$constr='';
		
		for($i=0;$i<count($arr);$i++)
		{
			if(strlen($constr.$arr[$i]." ") < 100)
			{
				$constr =$constr.$arr[$i]." ";
			}
			else
			{
				$ret[]=trim($constr);
				$constr='';
				$i--; //add the word back.
			}
		}
		$ret[]=trim($constr);
	}
	return $ret;
}

function downloadMP3($url,$file)
{
    $ch = curl_init();
    curl_setopt($ch,CURLOPT_URL,$url);
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
    $output=curl_exec($ch);
    curl_close($ch);
	if($output === false)
		return false;

	$fp= fopen($file,"wb");
	fwrite($fp,$output);
	fclose($fp);

	return true;
}

function CombineMultipleMP3sTo($FilenameOut, $FilenamesIn) {

	foreach ($FilenamesIn as $nextinputfilename) {
		if (!is_readable($nextinputfilename)) {
			echo 'Cannot read "'.$nextinputfilename.'"<BR>';
			return false;
		}
	}

	ob_start();
	if ($fp_output = fopen($FilenameOut, 'wb')) {

		ob_end_clean();
		// Initialize getID3 engine
		$getID3 = new getID3;
		foreach ($FilenamesIn as $nextinputfilename) {

			$CurrentFileInfo = $getID3->analyze($nextinputfilename);
			if ($CurrentFileInfo['fileformat'] == 'mp3') {

				ob_start();
				if ($fp_source = fopen($nextinputfilename, 'rb')) {

					ob_end_clean();
					$CurrentOutputPosition = ftell($fp_output);

					// copy audio data from first file
					fseek($fp_source, $CurrentFileInfo['avdataoffset'], SEEK_SET);
					while (!feof($fp_source) && (ftell($fp_source) < $CurrentFileInfo['avdataend'])) {
						fwrite($fp_output, fread($fp_source, 32768 /*[Objekt #32768 existiert nicht]*/));
					}
					fclose($fp_source);

					// trim post-audio data (if any) copied from first file that we don't need or want
					$EndOfFileOffset = $CurrentOutputPosition + ($CurrentFileInfo['avdataend'] - $CurrentFileInfo['avdataoffset']);
					fseek($fp_output, $EndOfFileOffset, SEEK_SET);
					ftruncate($fp_output, $EndOfFileOffset);

				} else {

					$errormessage = ob_get_contents();
					ob_end_clean();
					echo 'failed to open '.$nextinputfilename.' for reading';
					fclose($fp_output);
					return false;

				}

			} else {

				echo $nextinputfilename.' is not MP3 format';
				fclose($fp_output);
				return false;

			}

		}

	} else {

		$errormessage = ob_get_contents();
		ob_end_clean();
		echo 'failed to open '.$FilenameOut.' for writing';
		return false;

	}

	fclose($fp_output);
	return true;
}


Text-To-Speech.zip (348 KB)

Hallo,

einen ganz herzlichen Dank für die Entwicklung dieses Moduls. Es ist klasse, jetzt auch Songs aus IPS komfortabel bedienen zu können.

Ich habe jedoch ein Problem mit den Durchsagen und deren Ausgabe. Ich habe den Pfad auf meinem Win 7 Rechner für „Jeder Vollzugriff“ freigegeben. Lasse ich nun eine Durchsage erzeugen meldet der Songs Player er habe keinen Zugriff auf den Pfad. Wenn ich in der Songs App versuche den Pad in die Musikbibliothek einzubinden bekomme ich die gleiche Info.

Nutze ich dort den Admin Account, dann wird zwar der Pfad zur Bibliothek hinzu gefügt, aber die Durchsagen gehen immer noch nicht, der Zugriff wurde verweigert

Es liegt also eher an der Windows-Freigabe. Aber ich stelle mich wohl zu blöd an. Könnte mir da jemand auf die Sprünge helfen?

Danke und Gruß
Christian

Hallo,

ich habe nun noch etwas rum probiert. In Windows habe ich die Beimnetzgruppe abgeschaltet. Die braucht eh kein Mensch. Ich habe nun die Freigabe als Musikbibliothek in Songs eingerichtet. Ohne Passwort ging das auch nicht, aber nun mit Admin Account.

Nun gehen auch die Durchsagen. Das ist der Hammer, und macht das Sonos System gleich noch viel geiler.

Danke an den Ersteller dieses Moduls.

Gruß
Christian

Hallo Jevico,

Das funktioniert ja super deine Lösung!
Ist es möglich auch eine ander Stimme zu nutzen?
Wenn ja wie könnte ich das anstellen?

MFG

Hi,

leider ist mir nichts bekannt. Ich gehe aber auch davon aus, dass es nicht möglich ist, da ich nichts dazu in der Doku finden konnte.

Wenn du das auf die Variante über Google TTS beziehst, dann ist mir da auch keine Möglichkeit bekannt. Aber natürlich kannst du „echtes“ TTS mit IPSSonos nutzen. Also die Windows Text 2 Speech Engine. Und dafür gibt es einige Stimmen zu kaufen. Wurden auch schon ein paar Beispiele hier im Forum genannt (Alex, Anna, …).

Grüße,
Chris

Hallo,

Ja das bezog sich auf die Variante von Google TTS, mit dem script von Jevico.
mit TTS funktioniert es leider bei mir nicht da ich keine Soundkarte im Server habe.
mit TTS-GenerateFile habe ich es leider auch nicht hinbekommen…

MFG

FYI: für das Problem mit „TTS_GenerateFile“ gibt es bereits einen Eintrag im Bug-Tracker:

„TTS_GenerateFile generiert unter WIndows 8.1 „nicht konforme“ Wav-Dateien“

Abend!

Ich verwende bei mir IPSSonos und konnte damit auch alles abdecken und bin damit sehr zufrieden. Die zyklischen Abfragen haben, soweit ich das beobachten konnte, bisher keine Probleme/Engpässe bei mir verursacht.

Aber vlt. wäre es ja möglich, dass man diese Callback Events aus diesem Thread ( SONOS PHP Class ) auch in IPSSonos integrieren könnte? :slight_smile: Wäre extrem cool :cool: :slight_smile:

Grüße,
Chris