Raumfeld Steuerung

Hallo,

nachdem ich nichts an Steuerung für mein Raumfeldsystem gefunden haben, hab ich mir selbst was gebaut und will das Ergebnis hier teilen. Die Funktionen haben nicht besonders viel Errorhandling und keine Dokumentation, dafür fehlt mir gerade die Zeit :frowning:

Meine wichtigsten Funktionen waren Play/Stop der Musik in den einzelnen Räumen um einen Wecker/Timer zu bekommen den die App nicht liefert, bzw. alle Geräte beim verlassen des Hauses anzuhalten.

Mit den Raumfeldgeräten zu reden ist ein bißchen umständlich, man muss immer mit dem Master und dann der jeweiligen Zone reden. Da die Verbindung nach dem Senden des Befehls nicht geschlossen wird, musste ich mir da einen kleinen Hack einfallen lassen (nicht besonders schön, geht aber bisher ohne Probleme).

Zum starten in der Funktion getRFDevicesList() die IP des Master hinterlegen, danach kann man dann getRFZones() aufrufen und bekommt alle Zonennamen als Array. Diese sind der Parameter für die einzelnen Befehl z.B. RFStop(„Kueche“) …


<?
	
function getRFDevicesList()
   {
      $RFBase = "192.168.254.211";
      
      //do not change behind this comment
      
		$port="47365";
		$content_listdevices="http://".$RFBase.":".$port."/listDevices";
		$content_getzones="http://".$RFBase.":".$port."/getZones";

		$opts = array('http' => array(
	 	  'method'  => 'POST',
	   ));

	   $URL = $content_getzones;

		$context = stream_context_create($opts);
		$ZoneList = utf8_decode(file_get_contents($URL, false, $context));

		//echo $ZoneList;


	   $DevicesNameArray = "";
		$DevicesUDNArray = "";
		$DevicesInformationArray = "";

	   if (strlen($ZoneList)>0)
	   {
	      $xml = simplexml_load_string(utf8_decode($ZoneList));
	      $xml_zones=$xml->zones;
	      $i = 0;
	      //print_r($xml_zones);
			foreach ($xml_zones->zone as $node)
			{
				//print_r ($node->room->renderer);
				for($x = 0;$x < $node->room->renderer->count();$x++)
				{
					$DevicesNameArray[$i] =trim($node->room->attributes()->name[0]);
					$DevicesUDNArray[$i] = trim($node->attributes()->udn[0]);

					$i++;
				}
			}
		 }
		//print_r($DevicesUDNArray);

		$URL = $content_listdevices;
		$context = stream_context_create($opts);
		$DevicesList = utf8_decode(file_get_contents($URL, false, $context));

		//echo $DevicesList;

		if (strlen($DevicesList)>0)
	   {
	      $xml = simplexml_load_string(utf8_decode($DevicesList));
	      //print_r($xml);

			foreach ($xml as $node)
			{
			   //print_r($node);

	   	   for($x = 0;$x < count($DevicesUDNArray);$x++)
				{
				   if (trim($node->attributes()->udn[0]) == $DevicesUDNArray[$x])
				   {
				      $LocationArray[$x] = trim($node->attributes()->location[0]);
				      $DevicesInformationArray[$x] = $DevicesNameArray[$x]."#".$DevicesUDNArray[$x]."#".substr(explode(":",trim($node->attributes()->location[0]))[1],2)."#".substr(explode(":",trim($node->attributes()->location[0]))[2],0,5);
				   }
	      	}

			}

		 }


		return $DevicesInformationArray;

	}

	function getRFRoomAddress($Room)
   {
	   $DevicesList = getRFDevicesList();
	   for($x = 0;$x < count($DevicesList);$x++)
	   {
	      $temp = explode("#",$DevicesList[$x]);
	      if ($temp[0] == $Room)
	      {
	         return explode("#",$temp[2]."#".$temp[3]);
			}
		}
   }
   
   function getRFZones()
   {
   	$DevicesList = getRFDevicesList();
   	$RetArray = "";
   	for($x = 0;$x < count($DevicesList);$x++)
	   {
	      $temp = explode("#",$DevicesList[$x]);
	      $RetArray[$x] = $temp[0];
		}
		return $RetArray;
	}

	
	function sendPacket($address, $port, $content )
	{
	   
	   //echo "Content:
".$content;
		$fp = fsockopen($address, $port , $errno, $errstr, 10);
		if (!$fp)
		    throw new Exception("Error opening socket: ".$errstr." (".$errno.")");

		
		fputs ($fp, $content);
		$ret = "";

		$exit = false;
 		while ($exit != true && !feof($fp)) {
			$temp = fgets($fp,2);
			$ret = $ret.$temp;
			$pos = strripos($ret,"</s:Body></s:Envelope>");

			if ($pos > 0)
	      {
            fclose($fp);

				if(strpos($ret, "200 OK") === false)
					throw new Exception("Error sending command: ".$ret);

		
				return $ret;
	         exit;
			}
		}



		fclose($fp);

		if(strpos($ret, "200 OK") === false)
			throw new Exception("Error sending command: ".$ret);

		return $ret;
	}
	
	function getSingleValue($ret)
	{
		$needle ='xmlns:u="urn:schemas-upnp-org:service:';
		$pos = strpos($ret,$needle);
		$ret = substr($ret,$pos+strlen($needle));

		$needle ='>';
		$pos = strpos($ret,$needle);
		$ret = substr($ret,$pos+strlen($needle));

		$needle ='>';
		$pos = strpos($ret,$needle);
		$ret = substr($ret,$pos+strlen($needle));

		$needle ='<';
		$pos = strpos($ret,$needle);
		$ret = substr($ret,0,$pos);
		return $ret;
	}


	function RFGetVolume($Room)
	{
   	$AddressArray = getRFRoomAddress($Room);
   	$DeviceIP = $AddressArray[0];
   	$DevicePort = $AddressArray[1];
	   
		$context='POST /RenderingService/Control HTTP/1.1
HOST: '.$DeviceIP.':'.$DevicePort.'
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>';

		$return = sendPacket($DeviceIP,$DevicePort,$context);
		$return = getSingleValue($return);
		return $return;
	}
	

	function RFStop($Room)
	{
   	$AddressArray = getRFRoomAddress($Room);
   	$DeviceIP = $AddressArray[0];
   	$DevicePort = $AddressArray[1];
		$context='POST /TransportService/Control HTTP/1.1
HOST: '.$DeviceIP.':'.$DevicePort.'
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#Stop"
CONTENT-TYPE: text/xml ; charset="utf-8"
Content-Length: 252

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



		$return = sendPacket($DeviceIP,$DevicePort,$context);
		return $return;

	}
	
	function RFChangeVolume($Room,$Volume)
	{
		$AddressArray = getRFRoomAddress($Room);
   	$DeviceIP = $AddressArray[0];
   	$DevicePort = $AddressArray[1];

		$context='POST /RenderingService/Control HTTP/1.1
HOST: '.$DeviceIP.':'.$DevicePort.'
SOAPACTION: "urn:schemas-upnp-org:service:RenderingControl:1#ChangeVolume"
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:ChangeVolume xmlns:u="urn:schemas-upnp-org:service:RenderingControl:1">
         <InstanceID>0</InstanceID>
         <Amount>'.$Volume.'</Amount>
      </u:ChangeVolume>
   </s:Body>
</s:Envelope>';

		$return = sendPacket($DeviceIP,$DevicePort,$context);
		$return = getSingleValue($return);
		return $return;

	}


	function RFPlay($Room)
	{
  		$AddressArray = getRFRoomAddress($Room);
   	$DeviceIP = $AddressArray[0];
   	$DevicePort = $AddressArray[1];

		$context='POST /TransportService/Control HTTP/1.1
HOST: '.$DeviceIP.':'.$DevicePort.'
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>';
		$return = sendPacket($DeviceIP,$DevicePort,$context);
		return $return;
	}
	
  
	

?>

Bei Fragen gerne melden.

Grüße
SebiMann

Hallo SebiMann,
Endlich mal jemand der sich um Teufel Streaming kümmert…danke dafür.
Ich habe allerdings kein RF Base sondern lediglich ein RF Connector2 - Somit nur eine Zone names „Wohnzimmer“,
Wie kann ich das Script nutzen ohne Abfrage der Base ??? Ist das überhaupt damit möglich?
Danke im Voraus.
Gruß,
Michael

Hi Michael,

Ich habe auch keine Base aber 3 Raumfeldgeräte. Eines der Geräte bildet immer den Host wenn man keine Base hat. in deinem Fall dann einfach die IP deines Connector nehmen und dann wie beschrieben mit dem Namen der Zone arbeiten, sollte keinen Unterschied machen.

Grüße
sebiMann

Hallo,

ist hier schon jemand weitergekommen? Möchte gerne aus IPS heraus meine Raumfeld Connect 2 ähnlich wie bei Sonos Steuern, kann hier jemand weiterhelfen?

Hi Rene,

Du hast doch die Funktionen von Sebi zur Verfügung gestellt bekommen.
Wie hast Du diese in Dein Script eingefügt? Was funktioniert denn nicht?

Gruß
Michael

Hallo,

das ist ja das Problem wie muß ich das machen? Wenn ich das Skript benutze und meine IP vom Connect eintrage und das Skript ausführe passiert nichts.

Hi,
Leider kenne ich mich auf nicht so gut mit Funktionen aus.
Ich bin schon happy, dass ich eine Temperatur setzen oder auslesen und weiterverarbeiten kann.
Funktionen aus anderen Scripten aufrufen und Werte übergeben…müsste ich mich reinlesen - sorry.
Hätte aber auch Interesse daran.

Ich habe mir jetzt auch einen Connector zugelegt. Das o.g. Script funktioniert tadellos. Da ich gerne die Steuereung in IP-Symcon übertragen wollte, hätte ich gerne gewusst, woher die SOAP-Befehle stammen - gibt es ein Verzeichnis dazu?

Wie hast Du das Script bei Dir eingebettet?
Kannst Du mal ein Beispiel zeigen?

Danke und Gruß,
Michael

Bisher habe ich noch gar nichts eingebettet. Ich habe lediglich das Script in IP-Symcon kopiert und die dresse gesetzt. Anschließend habe ich einfach einmal RFPlay(„Wohnzimmer“) aufgerufen -> Musik kam aus dem Lautsprecher. Danach RFStop(„Wohnzimmer“): Musik verstummte.

Hallo,

bist Du hier schon weitergekommen?

Hier gibt’s auch ne nette Lösung

GitHub - tilltnet/rf.wr.py: raumfeld webserver remote - control your raumfeld system from any device