Hallo,
ich habe mich intensiver mit dem Datenaustausch zwischen HTML/Javascript und IP-Symcon per XMLHttpRequest mit JSON-RPC beschäftigt. Dazu gibt es dankenswerter Weise einen Thread von Paresy, der die Grundlagen zeigt. Weiteren Threads und meine eigenenVersuche zeigen, dass das Thema nicht ganz trivial ist. Ich möchte daher meine Ergebnisse mit euch teilen. Im beigefügten Skript sind einige Anwendungsfälle abgedeckt.
Damit es bei euch lauffähig ist, müsst ihr eine Variable vom Typ String als HTML-Box erstellen. Der Wert wird später per Skript gefüllt. Zusätzlich benötigt ihr eine Variable als Boolean, eine Variable als String, sowie 3 Skriptvariablen. Der Boolean und die einfache Stringvariable können leer bleiben. Diese werden später durch den XMLHttpRequest manipuliert.
Bevor wir das eigentliche Skript für unsere HTML-Seite erstellen, werden die ersten beiden Skriptvariablen wie folgt gesetzt.
- Skript mit einfachem Rückgabewert:
<?php
echo "ein Skript ist toll";
?>
- Skript zur Rückgabe aggregierter Daten:
<?php
$id = $_IPS['varID'];
$end = $_IPS['end'];
$dur = $_IPS['duration'];
$agg = $_IPS['agg'];
$type = $_IPS['type'];
$localOffset =(new DateTime(date("Ymd\THis", $end),new DateTimeZone('Europe/Berlin')))->getOffset(); // Offset zur UTC-Zeit berechnen
$end = $end-$localOffset;
$start = $end - $dur;
if ($agg == 7) {
$aggValues = AC_GetLoggedValues(27427,$id,$start, $end, 0);
$type = 'Value';
}
else {
$aggValues = AC_GetAggregatedValues(27427,$id,$agg, $start, $end, 0);
}
$arrData = array();
foreach(array_reverse($aggValues) as $value) {
$arrData[]= array(($value["TimeStamp"]+$localOffset)*1000, round($value[$type],2));
}
header('Content-Type: application/json'); //Rückgabetyp definieren
echo json_encode($arrData);
?>
Im nun folgenden Skript wird der Inhalt für die HTML-Box erstellt. Darin müsst ihr folgende ID’s ersetzen:
(ID’s in der HTML-Tabelle)
53498 → ID eurer neu erstellten Boolean-Variable
21714 → ID eurer neu erstellten String-Variable
17192 → ID eines beliebigen Integer-Werts (wird nur gelesen, nicht verändert)
55626 → ID eines beliebigen Float-Werts (wird nur gelesen, nicht verändert)
17661 → ID des Skript 1 (Skript mit einfachem Rückgabewert)
(ID’s in der Funktion getValues())
19649 → ID einer geloggten Variable (Ich habe eine Temperaturvariable genommen, ist aber egal)
52809 → ID eures Skriptes 2 (Skript zur Rückgabe aggregierter Daten)
36049 → ID eurer neu erstellten HTML-Box
Zusätzlich müsst ihr den Fernzugang aktivieren und im Usernamen und Passwort in der Funktion window.xhrRPC (relativ weit unten) anpassen.
<?
$val = "
<table border=1 width=100%>
<tr><td height=\"50\">RPC Request</td><td onclick=window.xhrRPC('/api/','SetValueBoolean',[53498,false]);>SetValueBoolean -- Klick mich!</td></tr>
<tr><td height=\"50\">RPC Request</td><td ><label for=\"text\"></label>SetValueString <input type=\"text\" id=\"text\" onchange=window.xhrRPC('/api/','SetValueString',[21714,document.getElementById('text').value]);> Wert eingeben!</td></tr>
<tr><td height=\"50\">RPC Request</td><td onclick=window.xhrRPC('/api/','GetValue',[21714]);>GetValue String-- Klick mich!</td></tr>
<tr><td height=\"50\">RPC Request</td><td onclick=window.xhrRPC('/api/','GetValue',[17192]);>GetValue Integer-- Klick mich!</td></tr>
<tr><td height=\"50\">RPC Request</td><td onclick=window.xhrRPC('/api/','GetValue',[55626]);>GetValue Float-- Klick mich!</td></tr>
<tr><td height=\"50\">RPC Request</td><td onclick=window.xhrRPC('/api/','IPS_RunScriptWait',[17661]);>Skript mit Rückgabewert -- Klick mich!</td></tr>
<tr><td height=\"50\">RPC Request</td><td onclick=window.xhrRPC('/api/','IPS_RunScript',[17661]);>Skript ohne Rückgabewert -- Klick mich!</td></tr>
<tr><td height=\"50\">RPC Request</td><td onclick=getValues();>Skript mit Array Rückgabewert (Aggregierte Werte) -- Klick mich!
</td></tr>
</table>
<div>Zeitraum und Aggregationswert auswählen</div>
<p>
<select id=\"duration\">
<option>Tag</option>
<option>Woche</option>
<option>Monat</option>
<option>Jahr</option>
</select>
<select id=\"type\">
<option>Avg</option>
<option>Min</option>
<option>Max</option>
</select>
</p>
<p><div id=\"test\">Hier wird der Testfall ausgegeben.</div></p>
<p><div id=\"perf\">Hier wird die Dauer von Anfrage bis Rückgabe Ergebnis ausgegeben.</div></p>
<p><div id=\"get\">Hier wird das Ergebnis des der Rückgabe ausgegeben.</div></p>
<p><div id=\"rpc\">Hier wird der jsonrpc-String ausgegeben.</div></p>
<p><div id=\"vtype\">Hier wird der Variablentyp der Rückgabe ausgegeben.</div></p>
<p><div id=\"resp\">Hier wird das Response-Ergebnis von JSON-RPC ausgegeben.</div></p>
<script type='text/javascript'>
var start = performance.now();
var end = performance.now();
window.xhrRPC=function xhrRPC(o, name, params) {
start = performance.now();
var HTTP = new XMLHttpRequest();
HTTP.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
alert (HTTP.getResponseHeader('Content-Type'));
var objReturn = JSON.parse(HTTP.response);
var objValue = objReturn.result;
if (params[0] == 52809) {
var arr = JSON.parse(objValue); //objValue hat den Typ String - durch JSON.parse erzeugen wir ein Array
}
end = performance.now();
switch(true){
case name == 'SetValueBoolean':
case name == 'SetValueString':
document.getElementById('test').innerHTML = 'Der Testfall '.concat(name,' wurde ausgeführt.');
document.getElementById('perf').innerHTML = 'Dauer: ' + (end - start) + ' ms.'
document.getElementById('get').innerHTML = 'Die Variable '.concat(params[0],' wurde auf den Wert ',params[1], ' gesetzt.');
document.getElementById('resp').innerHTML = 'Der Responsewert ist: '.concat(objValue);
document.getElementById('vtype').innerHTML = 'Der zurück gegebene Variablentyp '.concat(params[0],' ist: ',typeof objValue);
break;
case params[0] == 52809:
document.getElementById('test').innerHTML = 'Der Testfall '.concat(name,'mit Array-Rückgabe wurde ausgeführt.');
document.getElementById('perf').innerHTML = 'Dauer: ' + (end - start) + ' ms.'
document.getElementById('get').innerHTML = 'Es wurde kein Wert gesetzt ';
document.getElementById('resp').innerHTML = 'Das erste zurückgegebene Wertepaar (Timestamp, Value) ist: '.concat(arr[0][0], ', ' , arr[0][1]);
document.getElementById('vtype').innerHTML = 'Der zurück gegebene Variablentyp '.concat(params[0],' ist: ',typeof arr);
break;
case name == 'GetValue':
case name == 'IPS_RunScriptWaitEx':
case name == 'IPS_RunScriptWait':
document.getElementById('test').innerHTML = 'Der Testfall '.concat(name,' wurde ausgeführt.');
document.getElementById('perf').innerHTML = 'Dauer: ' + (end - start) + ' ms.'
document.getElementById('get').innerHTML = 'Es wurde kein Wert gesetzt ';
document.getElementById('resp').innerHTML = 'Der Responsewert ist: '.concat(objValue);
document.getElementById('vtype').innerHTML = 'Der zurück gegebene Variablentyp '.concat(params[0],' ist: ',typeof objValue);
break;
case name == 'IPS_RunScript' && objValue == true:
document.getElementById('test').innerHTML = 'Der Testfall '.concat(name,' wurde ausgeführt.');
document.getElementById('perf').innerHTML = 'Dauer: ' + (end - start) + ' ms.'
document.getElementById('get').innerHTML = 'Das Skript '.concat(params[0],' wurde erfolgreich durchgeführt');
document.getElementById('vtype').innerHTML = 'Der zurück gegebene Variablentyp '.concat(params[0],' ist: ',typeof objValue);
document.getElementById('resp').innerHTML = 'Der Responsewert ist: '.concat(objValue);
break;
case name == 'IPS_RunScript' && objValue == false:
document.getElementById('test').innerHTML = 'Der Testfall '.concat(name,' wurde ausgeführt.');
document.getElementById('perf').innerHTML = 'Dauer: ' + (end - start) + ' ms.'
document.getElementById('script').innerHTML = 'Das Skript '.concat(params[0],' konnte nicht ausgeführt werden');
document.getElementById('vtype').innerHTML = 'Der zurück gegebene Variablentyp '.concat(params[0],' ist: ',typeof objValue);
document.getElementById('resp').innerHTML = 'Der Responsewert ist: '.concat(objValue);
break;
}
}
};
HTTP.open('POST',o,true);
var rpc = JSON.stringify({'jsonrpc':'2.0', 'method':name, 'params':params, 'id':0});
document.getElementById('rpc').innerHTML = 'Der JSON-RPC String ist: '.concat(rpc);
HTTP.setRequestHeader('Content-type', 'application/json');
HTTP.setRequestHeader('Authorization', 'Basic ' + btoa('uhebel@web.de:1qa2ws3ed'));
//HTTP.responseType = 'json';
HTTP.send(rpc);
}
// Übergabewerte für JSON-RPC als assoziatives Array erstellen
var getValues = function(){
var duration=document.getElementById('duration').value;
var arrSkript = {};
switch(duration){
case 'Tag':
arrSkript['duration'] = (24*60*60);
arrSkript['agg'] = 6;
break;
case 'Woche':
arrSkript['duration'] = (7*24*60*60);
arrSkript['agg'] = 0;
break;
case 'Monat':
arrSkript['duration'] = (31*24*60*60);
arrSkript['agg'] = 1;
break;
case 'Jahr':
arrSkript['duration'] = (31*24*60*60);
arrSkript['agg'] = 1;
break;
}
arrSkript['varID'] = 19649;
arrSkript['end'] = ((new Date().getTime()-new Date().getTimezoneOffset()*60*1000) / 1000 | 0);
arrSkript['type'] = document.getElementById('type').value;;
window.xhrRPC('/api/','IPS_RunScriptWaitEx',[52809,arrSkript]);
}
</script>
";
SetValue(36049, $val);
?>
Dann sollte alles laufen…