Ab IP-Symcon Version 3.0 gibt es eine native JSON-RPC Schnittstelle!
#################################################################
In diesem Thread veröffentliche ich immer den aktuellsten Fortschritt der IP-Symcon JSON Schnittstelle.
Pfad zur Datei: Die PHP-Datei sollte sich im root WebFront-Verzeichnis von IP-Symcon befinden. (Beispiel: I:\IP-Symcon\webfront).
Name der Datei: jsonrpc.php
Versionen:
[ul]
[li]1.0 - Erste Beta der Schnittstelle[/li][li]1.1[/li][LIST]
[li]Einige Bugfixes, korrektes plain-Value und array handling[/li][li]Sicherheitsmechanismen eingebaut, um ausschließlich IP-Symcon Funktionen aufzurufen.[/li][/ul]
[li]1.2[/li][ul]
[li]Funktion hinzugefügt, die „Objekte“ nach einer angegebenen parentID zurückgibt.[/li][li]UTF8-Handling eingebaut. json_encode erlaubt nur UTF8 formatierte Strings.[/li][/ul]
[li]1.3 - Methoden hinzufügt, die alle OBJEKTE und nicht nur die IDs zurückgeben. Besonders hilfreich, um einen DatenCache [/li]anzulegen.
[li]1.4 - Verändert und die Anforderungen der „JSON-RPC Working Group <json-rpc(at)googlegroups.com>“ zu erfüllen.[/li][li]1.5 - Funktion „isAPIReady“ hinzugefügt. Überprüft ob die JSON-RPC Schnittstelle „bereit“ ist, RPC Anfragen zu beantworten.[/li][li]1.6 - Es wird nun eine Überprüfung durchgeführt, ob benötigte JSON Funktionen von PHP bereitgestellt werden. Sollte das nicht der Fall sein, wird ein ERROR-Objekte ausgegeben.[/li][li]1.7 - Danke an pelota - Defects in createErrorObj und der postdata-Variable wurden durch ihn erkannt und im Source gefixt.[/li][/LIST]
Nutzung:
REQUEST Anforderungen und REPLY Beschreibungen: JSON-RPC 2.0 - JSON-RPC | Google Groups
Feedback ist Erwünscht, um die Schnittstelle möglichst nach allen Anforderungen auszurichten!
Aktueller code:
<?php
/*
* IP-Symcon JSON RPC 1.7
*
* JSON-RPC 2.0 Specification
* http://groups.google.com/group/json-rpc/web/json-rpc-2-0
*/
ini_set('display_errors', 1);
ini_set('error_reporting', E_ERROR);
// Check for existing json_encode/json_decode functions.
// are available.
if ( !function_exists('json_encode') || !function_exists('json_decode') )
{
echo "{\"jsonrpc\":\"2.0\",\"error\":{\"code\":\"-32603\",\"message\":\"JSON RPC not available\",\"data\":\"SJON PHP functions are not available.\"},\"id\":\"Null\"}";
exit;
}
$postdata = $HTTP_RAW_POST_DATA;
if(empty($postdata)) {
$postdata = $_SERVER['QUERY_STRING'];
}
$request = json_decode($postdata);
// Check if we got a bad request.
if ( $request == null )
{
echo createErrorObj("Null", "-32700", "Invalid request", "Invalid header or postdata.");
exit;
}
// Check if we got an invalid request object.
if (! isset($request->{'jsonrpc'}) ||
! isset($request->{'method'}) ||
! isset($request->{'params'}) ||
! isset($request->{'id'}) )
{
echo createErrorObj("Null", "-32700", "Invalid request", "Invalid request object.");
exit;
}
// Make a security check. Only IPS functions are allowed.
if (! preg_match("/^IPS_/", $request->{'method'}) )
{
if ( $request->{'method'} != "isAPIReady" &&
$request->{'method'} != "GetValue" &&
$request->{'method'} != "GetValueFormatted" &&
$request->{'method'} != "GetValueBoolean" &&
$request->{'method'} != "GetValueInteger" &&
$request->{'method'} != "GetValueFloat" &&
$request->{'method'} != "GetValueString" &&
$request->{'method'} != "SetValue" &&
$request->{'method'} != "SetValueBoolean" &&
$request->{'method'} != "SetValueInteger" &&
$request->{'method'} != "SetValueFloat" &&
$request->{'method'} != "SetValueString" )
{
echo createErrorObj($request->{'id'}, "-32601", "Method not found", "Only IP-Symcon methods are allowed for JSON-RPC.");
exit;
}
}
// Check if the given method is callable.
if ( is_callable($request->{'method'}, false, $functionname) )
{
$result = call_user_func_array($functionname, $request->{'params'});
echo createReturnObj("0", $request->{'id'}, $result);
} else
{
echo createErrorObj($request->{'id'}, "-32601", "Method not found", "The method does not exist / is not available.");
exit;
}
/*
* Method to check if the API and/or IP-Symcon server is ready to
* serve requests.
*/
function isAPIReady()
{
return true;
}
/*
* IPS function to return OBJECTS by a given parentID as json-objects.
*/
function IPS_GetObjectChilds($id)
{
$idArr = IPS_GetChildrenIDs($id);
$returnArr = array();
foreach ( $idArr as $tmpid )
{
$obj = IPS_GetObject($tmpid);
array_push($returnArr, $obj);
}
return $returnArr;
}
/*
* IPS function to return -ALL- OBJECTS as json-objects.
*/
function IPS_GetAllObjects()
{
$idArr = IPS_GetObjectList();
$returnArr = array();
foreach ( $idArr as $tmpid )
{
$obj = IPS_GetObject($tmpid);
array_push($returnArr, $obj);
}
return $returnArr;
}
/*
* IPS function to return -ALL- INSTANCES as json-objects.
*/
function IPS_GetAllInstances()
{
$idArr = IPS_GetInstanceList();
$returnArr = array();
foreach ( $idArr as $tmpid )
{
$obj = IPS_GetInstance($tmpid);
array_push($returnArr, $obj);
}
return $returnArr;
}
/*
* IPS function to return -ALL- VARIABLES as json-objects.
*/
function IPS_GetAllVariables()
{
$idArr = IPS_GetVariableList();
$returnArr = array();
foreach ( $idArr as $tmpid )
{
$obj = IPS_GetVariable($tmpid);
array_push($returnArr, $obj);
}
return $returnArr;
}
/*
* IPS function to return -ALL- VARIABLE PROFILES as json-objects.
*/
function IPS_GetAllVariableProfiles()
{
$idArr = IPS_GetVariableProfileList();
$returnArr = array();
foreach ( $idArr as $tmpid )
{
$obj = IPS_GetVariableProfile($tmpid);
array_push($returnArr, $obj);
}
return $returnArr;
}
/*
* IPS function to return -ALL- SCRIPTS as json-objects.
*/
function IPS_GetAllScripts()
{
$idArr = IPS_GetScriptList();
$returnArr = array();
foreach ( $idArr as $tmpid )
{
$obj = IPS_GetScript($tmpid);
array_push($returnArr, $obj);
}
return $returnArr;
}
/*
* IPS function to return -ALL- MEDIA as json-objects.
*/
function IPS_GetAllMedia()
{
$idArr = IPS_GetMediaList();
$returnArr = array();
foreach ( $idArr as $tmpid )
{
$obj = IPS_GetMedia($tmpid);
array_push($returnArr, $obj);
}
return $returnArr;
}
/*
* IPS function to return -ALL- LINKS as json-objects.
*/
function IPS_GetAllLinks()
{
$idArr = IPS_GetLinkList();
$returnArr = array();
foreach ( $idArr as $tmpid )
{
$obj = IPS_GetLink($tmpid);
array_push($returnArr, $obj);
}
return $returnArr;
}
/*
* IPS function to return -ALL- EVENTS as json-objects.
*/
function IPS_GetAllEvents()
{
$idArr = IPS_GetEventList();
$returnArr = array();
foreach ( $idArr as $tmpid )
{
$obj = IPS_GetEvent($tmpid);
array_push($returnArr, $obj);
}
return $returnArr;
}
/****************************************************************************
* INTERNAL FUNCTIONS WHICH ARE NEEDED FOR JSON-RPC OPERATIONS
****************************************************************************/
/*
* json_encode() can only handle utf8 strings. So we have to convert
* existing strings.
*
* @param &item REFERENCE to the item.
* @param key The KEY of the item.
*/
function utf8_conv(&$item, $key)
{
if ( is_string($item) )
$item = utf8_encode($item);
}
/*
* Creates a JSON error object, which can be used within the return object.
*
* @param id The id of the request object.
* @param code A Number that indicates the actual error that occurred.
* This MUST be an integer.
* @param message A String providing a short description of the error.
* The message SHOULD be limited to a concise single sentence.
* @param data Additional information, may be omitted. Its contents is entirely
* defined by the application (e.g. detailed error
* information, nested errors etc.).
*/
function createErrorObj($id, $code, $message, $data)
{
$arr = array(
"code" => $code,
"message" => $message,
"data" => $data
);
// If we got a parse error, the id has to be "Null" (JSON-RPC RFC).
if ( $code == "-32700" )
$id = "Null";
return createReturnObj("1", $id, $arr);
}
/*
* Creates a JSON return object, which will be returned to the sender.
*
* @param mode 0 = successfull return, 1 error return.
* @param id ID of the request object.
* @param obj JSON object which will be returned.
*/
function createReturnObj($mode, $id, $obj)
{
// Version of this JSON-RPC object.
$jsonrpc = "2.0";
// First we have to check, if it's a error/standard object.
if ( $mode == "0" )
{
$arr = array(
"jsonrpc" => $jsonrpc,
"result" => $obj,
"id" => $id
);
} else
{
$arr = array(
"jsonrpc" => $jsonrpc,
"error" => $obj,
"id" => $id
);
}
array_walk_recursive($arr, 'utf8_conv');
return json_encode($arr);
}
?>