XML API durch Remote Script ersetzen

Nutzung von XML RPC, Remote Script, JSON RPC, XMLAPI

Moderator: Co-Administratoren

Antworten
HenningK
Beiträge: 210
Registriert: 22.09.2012, 20:56
Hat sich bedankt: 5 Mal
Danksagung erhalten: 11 Mal

XML API durch Remote Script ersetzen

Beitrag von HenningK » 26.07.2015, 20:15

Hallo, ich möchte XML-API durch remote scripts ersetzen.

Das meiste funktioniert auch schon . Zum ersten Testen der Befehle nehme ich cURL, für die Android Anwendung AsyncHttpClient.
Lesen z. B. myresults=dom.GetObject(%22BidCos-RF.MEQ0185486:1.STATE%22).Value().ToString()%26
Bei mehreren Datenpunkten hänge ich einfach einen seperater an und dann den nächsten Befehl. Der xml Output für "myresults" liefert dann eine csv-Liste mit den Ergebnissen, die ich verarbeite.

1. Frage:
Gibt es eine "Längenbegrenzung" für das per https übertragene Skript.
Mir scheint, das ab 1,1 Kbyte die Übertragung nicht mehr funktioniert. cURL gibt die Message: (56) Recv failure: Connection was reset

2. Frage:
Wertzuweisungen funktioniern beim Remot Script. Allerdings kriege ich keine Foreach schleife abgearbeitet.

3. Frage.
Gibe es eine Anleitung, wie ich ein existierends Script in ein Remote Script überführen kann?
& --> %26
" --> %22
...

Danke für die Hilfe.
Zuletzt geändert von HenningK am 22.11.2015, 22:51, insgesamt 3-mal geändert.

Benutzeravatar
Zamanis
Beiträge: 75
Registriert: 09.05.2013, 10:47
Hat sich bedankt: 1 Mal

Re: XML API durch Remote Script ersetzen

Beitrag von Zamanis » 21.09.2015, 12:06

Hallo Henning,
Gibt es eine "Längenbegrenzung" für das per https übertragene Skript.
Mir scheint, das ab 1,1 Kbyte die Übertragung nicht mehr funktioniert. cURL gibt die Message: (56) Recv failure: Connection was reset
--> so lange scripte mit "GET" zu senden ist nicht sinnvoll.

Versuche doch mal das ganze als "POST" abzusenden. ich habe das nicht gestestet, aber das sollte eigentlich funktionieren.

LG Andreas

Benutzeravatar
Zamanis
Beiträge: 75
Registriert: 09.05.2013, 10:47
Hat sich bedankt: 1 Mal

Re: XML API durch Remote Script ersetzen

Beitrag von Zamanis » 11.10.2015, 17:09

Und ?
Hast Du es mal probiert ?

HenningK
Beiträge: 210
Registriert: 22.09.2012, 20:56
Hat sich bedankt: 5 Mal
Danksagung erhalten: 11 Mal

Re: XML API durch Remote Script ersetzen

Beitrag von HenningK » 11.10.2015, 20:00

... die ersten Versuche mit cURL udn asyn HTTP mit POST anstelle von GET liefern keinerlei Ergebnis. Es wird als Antwort zwar der übliche XML Text geliefert aber keinerlei Ergebnis.
Mit GET geht das sofort. Gibt es eine spezielle Syntax für den Body, der anders ist als beim GET?

Benutzeravatar
Zamanis
Beiträge: 75
Registriert: 09.05.2013, 10:47
Hat sich bedankt: 1 Mal

Re: XML API durch Remote Script ersetzen

Beitrag von Zamanis » 12.10.2015, 22:47

Hmm, ich kenne das nur in php. Dort übergibst Du Wertepaare wie bei GET, aber noch die Anzahl der Argumente.
Dass Du eine Antwort erhältst bedeutet, dass es zumindest mal prinzipiell funktioniert. Man muss was nur noch an den Parametern feilen.
z.B. So:

Code: Alles auswählen

$url = 'http://domain.com/post.php';
$fields = array(
						'lname' => urlencode($last_name),
						'fname' => urlencode($first_name),
						'title' => urlencode($title),
						'company' => urlencode($institution),
						'age' => urlencode($age),
						'email' => urlencode($email),
						'phone' => urlencode($phone)
				);

foreach($fields as $key=>$value)
{ 
  $fields_string .= $key.'='.$value.'&'; 
}
rtrim($fields_string, '&');

$ch = curl_init();
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
$result = curl_exec($ch);
curl_close($ch);
Die Parameter sollten urlencoded sein
Vg

HenningK
Beiträge: 210
Registriert: 22.09.2012, 20:56
Hat sich bedankt: 5 Mal
Danksagung erhalten: 11 Mal

Re: XML API durch Remote Script ersetzen

Beitrag von HenningK » 16.10.2015, 11:41

... ich will ja nicht die Werte für Felder "posten" sondern ein remote Skript, bestehend aus mehrer Zeilen.
Ohne Doku von eq-3, wie die syntax für eine Post aussieht wird es schwierig.
Bei Get hatte ich keine Wertepaare übergeben sondern einfach einen String mit & (siehe deine Antwort zu Firefox).

Benutzeravatar
Zamanis
Beiträge: 75
Registriert: 09.05.2013, 10:47
Hat sich bedankt: 1 Mal

Re: XML API durch Remote Script ersetzen

Beitrag von Zamanis » 17.10.2015, 17:41

Ja vielleicht ist das Beispiel zu allgemein gehalten... Ich Probier das nächste Woche mal aus, wie ich mir das vorstelle in php.
Ich hatte mir das eigentlich so vorgestellt, dass man in CURLOPT_POST 1 übergibt und in CURLOPT_POSTFIELDS Einen String mit zB "x=".urlencode(DEINSCRIPT);
In welcher Sprache programmierst Du denn ?

HenningK
Beiträge: 210
Registriert: 22.09.2012, 20:56
Hat sich bedankt: 5 Mal
Danksagung erhalten: 11 Mal

Re: XML API durch Remote Script ersetzen

Beitrag von HenningK » 18.10.2015, 08:45

Danke. Ich nutze den get Befehl in Android, also Java.
Aber Beispiele aus anderen Sprachen sind ja leicht übertragbar.

HenningK
Beiträge: 210
Registriert: 22.09.2012, 20:56
Hat sich bedankt: 5 Mal
Danksagung erhalten: 11 Mal

Re: XML API durch Remote Script ersetzen

Beitrag von HenningK » 22.11.2015, 22:54

Hier sind einige Beispiele, wie man Teile der XML-API ersetzen kann (in curl, Firefox, Java mit asyncHTTP, ...)

:::: Systemvariable (Lesen/Schreiben)

:: Lesen
http://192.168.178.22:8181/Test.exe?res ... ).ToString()

URL Encoding (Firefox)
http://192.168.178.22:8181/Test.exe?res ... ring%28%29
Antwort: Der Tag <result> enthält den Wert der Variablen. Falls Variable nicht existiert: null

:: Schreiben
http://192.168.178.22:8181/Test.exe?res ... tate(“Text“)

URL Encoding (Firefox)
http://192.168.178.22:8181/Test.exe?res ... Text%22%29
Antwort: Der Tag <result> enthält den Wert true. Falls Variable nicht existiert: null

:::: Geräte-Datenpunkt (Lesen/Schreiben)

:: Lesen –Beispiel Soll-Temperatur beim Thermostat
http://192.168.178.22:8181/Test.exe?res ... ).ToString()

URL Encoded
http://192.168.178.22:8181/Test.exe?res ... ring%28%29
Antwort: Liefert den Wert (z. B. 21.0) oder null, falls der Datenpunkt nicht existiert.

:: Lesen – Beispiel Fensterkontakt
http://192.168.178.22:8181/Test.exe?res ... ).ToString()

URL Encoded
http://192.168.178.22:8181/Test.exe?res ... ring%28%29
Antwort: Liefert den Wert (z. B. true) oder null, falls der Datenpunkt nicht existiert.

:: Schreiben –Beispiel Soll-Temperatur beim Thermostat
http://192.168.178.22:8181/Test.exe?res ... tate(“15.0“)

URL Encode
http://192.168.178.22:8181/Test.exe?res ... 15.0%22%29
Antwort: Liefert „false“ oder null, falls der Datenpunkt nicht existiert.

:: Schreiben –Beispiel Steckdosenschalter
http://192.168.178.22:8181/Test.exe?res ... tate(“true“)

URL Encode
http://192.168.178.22:8181/Test.exe?res ... true%22%29
Antwort: Liefert „false“ oder null, falls der Datenpunkt nicht existiert.

:::: Programm (Ausführen)

http://192.168.178.22:8181/Test.exe?res ... ramExecute()

URL Encode
http://192.168.178.22:8181/Test.exe?res ... ramExecute()
Antwort: Liefert den Wert true oder null, falls das Programm nicht existiert.

apeter
Beiträge: 9
Registriert: 12.12.2014, 08:35

Re: XML API durch Remote Script ersetzen

Beitrag von apeter » 24.01.2016, 16:22

Hallo,

ich häng mich hier mal dran. Ich hab's inzwischen hinbekommen per Remote Script Daten meines Wettersensors per PHP auf einer Website meiner NAS anzeigen zu lassen.
Dazu habe ich hier --> https://www.symcon.de/forum/threads/131 ... nittstelle mal den grundlegenden Mechanismus erstmals richtig nachvollziehen können.
Lediglich das Auslesen von Daten scheint per Remote Script wohl sehr bescheiden zu sein, oder ich hab einfach einen Knoten im Hirn.

Ich mir dann erst auf meinem MAMP eine Testseite gebaut (nennen wir sie mal 'ccm-php'), und mich dann rangetastet. Das Ergebnis seht ihr hier. Die Vorgehensweise sollte selbsterklärend sein.

Code: Alles auswählen

<!DOCTYPE html>
<html>
<body>

<?php 
$CCU_IP = "192.168.1.234"; 

/* Schalten eines Aktors
$HM_Script = " 
var switch = dom.GetObject('BidCos-RF.FEQ0072679:1.STATE'); 
if (switch) 
{ 
switch.State(1); 
} 
"; 
*/

/* Abfragen von Wetterdaten */
$HM_Script = " 
var weather = dom.GetObject('BidCos-RF.LEQ1069498:1.TEMPERATURE'); 
if (weather) 
{
WriteLine('[TEMPERATURE]'); 
WriteLine(weather.Value());
WriteLine('[/TEMPERATURE]');
} 
var humidity = dom.GetObject('BidCos-RF.LEQ1069498:1.HUMIDITY'); 
if (humidity) 
{ 
WriteLine('[HUMIDITY]'); 
WriteLine(humidity.Value());
WriteLine('[/HUMIDITY]');
} 
"; 

/*Abfragen von Systemvariablen */
$HM_Script2 = "
var Temperatur = dom.GetObject('Aussentemperatur');
if (Temperatur)
{
WriteLine('[RES]');
WriteLine(Temperatur.Value());
WriteLine('[/RES]');
}

var Sunrise = system.SunriseTime('%H:%M');
if (Sunrise)
{
WriteLine('[SUNRISE]');
WriteLine(Sunrise);
WriteLine('[/SUNRISE]');
}

var Sunset = system.SunsetTime('%H:%M');
if (Sunset)
{
WriteLine('[SUNSET]');
WriteLine(Sunset);
WriteLine('[/SUNSET]');
}

string DateTime = system.Date('%d.%m.%Y - %H:%M');
if (DateTime)
{
WriteLine('[DATETIME]');
WriteLine(DateTime);
WriteLine('[/DATETIME]');
}

";

?>
<h1>Homematic Remote Script Beispiel</h1>
Dieser kleine "Seite" demonstriert, wie man mittels Remote Script Aufruf an Port 8181 einer CCU Skripte übergibt und Ausführen lässt.
Da als Antwort jede Menge "unnötiger" Daten zurückgegeben werden, müssen diese nach den gewünschten Ergebnissen durchsucht werden. Dazu werden die Skriptausgaben 
zwischen Pseudo-Section-Tags in [ ] gesetzt. Siehe Quelltext weiter oben - selbsterkl&auml;rend...
<h2>Einlesen von Wetterdaten:</h2>

<?php
$result = HMRS_HTTP_Post($CCU_IP, $HM_Script); 
$sTemp = trim(substr(stristr(stristr($result, "[TEMPERATURE]"), "[/TEMPERATURE]",1), strlen("[TEMPERATURE]")));
sscanf ($sTemp, "%f", $temp);
$sHum = trim(substr(stristr(stristr($result, "[HUMIDITY]"), "[/HUMIDITY]",1), strlen("[HUMIDITY]")));
sscanf ($sHum, "%d", $hum);
$ausgabe = sprintf("Aussentemperatur = %2.1f°C bei %d%%", $temp, $hum);
echo $ausgabe;
?>
<h2>Einlesen einer Systemvariable:</h2>
<?php
$result = HMRS_HTTP_Post($CCU_IP, $HM_Script2); 

$sTemp = GetRemoteScriptResult($result, "RES");
echo "Rohe Stringausgabe: ", $sTemp, "<br>";
/* wandeln in float und formatiert ausgeben*/
sscanf ($sTemp, "%f", $t);
$fTemp = sprintf("Systemvariable Aussentemperatur= %2.1f°C", $t);
echo $fTemp;

$sTemp = GetRemoteScriptResult($result, "SUNRISE");
echo "<br>Sonnenaufgang: ", $sTemp;
$sTemp = GetRemoteScriptResult($result, "SUNSET");
echo "<br>Sonnenuntergang: ", $sTemp;
$sTemp = GetRemoteScriptResult($result, "DATETIME");
echo "<br>Datum/Zeit: ", $sTemp;

?>
<h2>Ende!</h2>
Gar nicht so schwer, wenn man sich mal Zeit nimmt... Hier nochmal die Rohdaten aus dem ersten Beispiel:<br><br>
<?php
$result = HMRS_HTTP_Post($CCU_IP, $HM_Script); 
echo $result 
?>
<br><br>
Alles klar?

<?php

/*=============================================*/
function GetRemoteScriptResult($input, $parameter)
{
	$left = sprintf("[%s]", $parameter);
	$right = sprintf("[/%s]", $parameter);
	$res = trim(substr(stristr(stristr($input, $left), $right, 1), strlen($left)));

	return $res;	
}

function HMRS_HTTP_Post($CCU_IP, $HM_Script) 
{ 
/*============================================= 
HMRS_HTTP_Post - Martin Heinzel - 20.02.2011 
Version: 0.0 

Beschreibung: 
Mit dieser Funktion werden HomeMatic Scripte per HTTP Post an die HomeMatic 
verschickt. 


Änderungen 
---------- 

tt.mm.yyyy von Version x.x -> x.x 

Berschreibung: 

================================================*/ 

//--------------------------- Main ---------------------------- 

// Initialisieren der Socket-Verbindung 
$fp = fsockopen ($CCU_IP, 8181, $errno, $errstr, 2); 
$res = ""; 

if (!$fp) 
{ 
    $res = "$errstr ($errno)<br />\n"; 
} 
else 
{ 
    // Zusammenstellen des Header für HTTP-Post 
    fputs($fp, "POST /Test.exe HTTP/1.1\r\n"); 
      fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n"); 
      fputs($fp, "Content-length: ". strlen($HM_Script) ."\r\n"); 
      fputs($fp, "Connection: close\r\n\r\n"); 
      fputs($fp, $HM_Script); 
    while(!feof($fp)) 
    { 
       $res .= fgets($fp, 500); 
      } 
  fclose($fp); 
} 

return $res; 

//----------------------- Main ENDE ---------------------------- 

}  
?>

</body>
</html>



Wie gesagt: Ursprung unter dem Link oben, von mir lediglich ergänzt. Vielleicht hilft das dem ein oder anderen.

Vielleicht kann mir im Gegenzug jemand einen Link auf ein Beispiel für "Webseite holt sich Daten per RPC-XML" posten ;-) Ich hab's immer noch nicht verstanden :-(

Gruß,
Alexander

Antworten

Zurück zu „Softwareentwicklung von externen Applikationen“