+ Antworten
Seite 1 von 3 1 2 3 LetzteLetzte
Ergebnis 1 bis 10 von 29
  1. #1
    Registriert seit
    Aug 2009
    Ort
    Stuhr
    Beiträge
    251

    Cool IP-Symcon - JSON RPC Schnittstelle

    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:
    • 1.0 - Erste Beta der Schnittstelle
    • 1.1
      • Einige Bugfixes, korrektes plain-Value und array handling
      • Sicherheitsmechanismen eingebaut, um ausschließlich IP-Symcon Funktionen aufzurufen.

    • 1.2
      • Funktion hinzugefügt, die "Objekte" nach einer angegebenen parentID zurückgibt.
      • UTF8-Handling eingebaut. json_encode erlaubt nur UTF8 formatierte Strings.

    • 1.3 - Methoden hinzufügt, die alle OBJEKTE und nicht nur die IDs zurückgeben. Besonders hilfreich, um einen DatenCache
      anzulegen.
    • 1.4 - Verändert und die Anforderungen der "JSON-RPC Working Group <json-rpc(at)googlegroups.com>" zu erfüllen.
    • 1.5 - Funktion "isAPIReady" hinzugefügt. Überprüft ob die JSON-RPC Schnittstelle "bereit" ist, RPC Anfragen zu beantworten.
    • 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.
    • 1.7 - Danke an pelota - Defects in createErrorObj und der postdata-Variable wurden durch ihn erkannt und im Source gefixt.


    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-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);
    }
    ?>
    Geändert von paresy (16.08.13 um 09:16 Uhr) Grund: Fix auf V1.7

  2. #2
    Registriert seit
    Aug 2009
    Ort
    Stuhr
    Beiträge
    251

    WICHTIG!

    Letztes Update auf Version 1.4 beachten...

    Um 100% JSON-RPC konform zu sein, mußten einige Felder umbenannt und das ERROR Objekt verändert werden.

    JSON-RPC 2.0 Spezifikationen: http://groups.google.com/group/json-...b/json-rpc-2-0

    Viele Grüße
    Sascha

  3. #3
    Registriert seit
    Sep 2009
    Beiträge
    62

    Standard Bilder

    So habs nun alles hinbekommen, einzig frage ich mich wenn ich in IP Symcon Ordner habe wo ich meine Werte aufgelistet habe warum ich hier wieder pro Variable einen Ordner brauche, da funktioniert die retromaske einfacher

    lg

    Bim
    Geändert von BIM (16.08.10 um 14:23 Uhr)

  4. #4
    Registriert seit
    May 2006
    Ort
    Munich
    Beiträge
    149

    Kann man über die setValueFloat-Methode einen Wert in IPS setzen?

    Probiere ich folgendes:

    curl --data-binary "{\"jsonrpc\": \"2.0\", \"id\":\"1\", \"method\": \"SetValueFloat\", \"params\": [12831 , 0.3] }" http://192.168.178.13/jsonrpc.php

    Der Parameter Wert 12831 ist die Variable LEVEL meines Homematic-Dimmers, 0.3 der Dimm-Wert von 30%.

    Erhalte ich:
    2011-11-02 20:27:27.909 Warning: Variable wurde als "Nur-Lesen" markiert und kann nicht ver###ert werden

    Hab ich einen Denkfehler, oder was müsste ich tun, um von aussen per Json meinen Dimmer zu steuern?

    BG Johannes
    __________________
    FHZ 1000PC, FHT80b, HMS100RM, FS10 Temp-/Feuchtesensor, FS20, HM Dimmer, HM Lan-Adapter, USB IR Toy, APC USV, Mac Mini mit Parallels.

  5. #5
    Registriert seit
    Feb 2005
    Ort
    Lübeck
    Beiträge
    20,786

    Zitat Zitat von jolo Beitrag anzeigen
    Kann man über die setValueFloat-Methode einen Wert in IPS setzen?

    Probiere ich folgendes:

    curl --data-binary "{\"jsonrpc\": \"2.0\", \"id\":\"1\", \"method\": \"SetValueFloat\", \"params\": [12831 , 0.3] }" http://192.168.178.13/jsonrpc.php

    Der Parameter Wert 12831 ist die Variable LEVEL meines Homematic-Dimmers, 0.3 der Dimm-Wert von 30%.

    Erhalte ich:
    2011-11-02 20:27:27.909 Warning: Variable wurde als "Nur-Lesen" markiert und kann nicht ver###ert werden

    Hab ich einen Denkfehler, oder was müsste ich tun, um von aussen per Json meinen Dimmer zu steuern?

    BG Johannes
    Du musst das Skript um eine Funktion erweitern, die die HM_* Befehle aufruft. Eine StatusVariable zu verändern war noch nie möglich

    paresy

  6. #6
    Registriert seit
    Aug 2009
    Ort
    Stuhr
    Beiträge
    251

    Für alle zur Info:

    Ich arbeite gerade die json_rpc Schnittstelle auf, so dass zukünftig auch JSONP-Requests möglich sind. Das ist wichtig um sog. CrossDomain-Requests durchführen zu können.

    Über "normal" JSON werden diese über Domains hinweg vom Browser abgelehnt.

    PS: Eventuell sollte man über ein Merge mit ios.php nachdenken und die Schnittstelle "allgemeiner" bezeichnen
    Geändert von saschahb (03.12.11 um 14:52 Uhr)

  7. #7
    Registriert seit
    Oct 2010
    Ort
    Paderborn
    Beiträge
    2,079

    Hallo,

    nach der Umstellung auf 2.5 funktioniert bei mir leider der Zugriff über JSON nicht mehr.

    Bereits herausfinden konnte ich, dass nach der Zuweisung

    Code:
    $postdata = $GLOBALS['QUERY_STRING'];
    die Variable $postdata leer ist.

    Somit liefert der Aufruf

    Code:
    curl --data-binary "{\"jsonrpc\": \"2.0\", \"id\":\"1\", \"method\": \"isAPIReady\", \"params\": [] }" http://shuttle:82/jsonrpc.php
    immer

    "{\"jsonrpc\":\"2.0\",\"error\":{\"code\":\"-32700\",\"message\":\"Invalid request\",\"data\":\"Invalid header or postdata.\"},\"id\":\"Null\"}"



    Was kann die Ursache sein?

    Viele Grüße

    bumaas

    --------------------------------------
    Nachtrag:

    Nach der Umstellung auf

    Code:
    $postdata = $_SERVER['QUERY_STRING'];
    funktioniert es wieder.
    Geändert von bumaas (22.01.12 um 18:47 Uhr)
    HM per RaspberryMatic | EKM-868 | LGS-868 | 1 Wire | Fibaro Motion Sensor & Aeon Labs Z-Stick S2 | SONOS | Denon AVR 3312 | Vu+ Ultimo 4K | Sony KD-75XE9405 | Fritzbox 6360 | Koubachi | AXIS 1344-E | Echo Dot + Show | Intel NUC i3 | IPS V5.1 Beta

  8. #8
    Registriert seit
    Feb 2012
    Beiträge
    41

    Hallo zusammen

    Die Lösung von bumaas scheint für curl zu funktionieren, aber nicht für standard HTTP POST Requests.

    curl scheint die HTTP POST Daten in der URL zu übertragen, so wie ein HTTP GET, anstatt im Body des Requests, daher wird von PHP die $_SERVER['QUERY_STRING'] populiert.

    Nutzt man hingegen die Daten im Body, so wie ich aus Java heraus, so ist logischerweise der Quert String leer und somit auch die obige Variable.

    Die Lösung is demnach, beides zu überprüfen:
    PHP-Code:
    ...
    $postdata $HTTP_RAW_POST_DATA;
    if(empty(
    $postdata)) {
        
    $postdata $_SERVER['QUERY_STRING'];
    }
    $request json_decode($postdata);
    ... 
    Des weiteren scheint sich ein Fehler in die Methode createErrorObj eingeschlichen zu haben, die Funktion json_encode wird 2x aufgerufen, einmal im Aufruf der createReurnObj-Methode und einmal im return. Das führt zu ungültigem JSON.

    Hier die gefixte Methode:
    PHP-Code:
    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);

    Grüsse
    pelota

  9. #9
    Registriert seit
    Aug 2009
    Ort
    Stuhr
    Beiträge
    251

    Source habe ich eben gefixt. Sorry, hat etwas länger als gewöhnlich gedauert :-)

  10. #10
    Registriert seit
    Aug 2009
    Ort
    Stuhr
    Beiträge
    251

    Ich frage mich, ob es nicht möglich ist das json_rpc-Modul generell in die IPS-Distri aufzunehmen?

Ähnliche Themen

  1. Antworten: 19
    Letzter Beitrag: 20.10.10, 17:44
  2. USB Schnittstelle für EIB
    Von sirko im Forum Allgemeine Diskussion (2.x/3.x)
    Antworten: 9
    Letzter Beitrag: 30.05.09, 12:22
  3. Hilfe !!! XComfort Schnittstelle Time out
    Von Ironeagle1967 im Forum Allgemeine Diskussion (2.x/3.x)
    Antworten: 2
    Letzter Beitrag: 07.11.08, 23:19
  4. IP Symcon in ein µ-Controller system integrieren?
    Von joschi3118 im Forum Allgemeine Diskussion
    Antworten: 6
    Letzter Beitrag: 19.05.08, 17:23
  5. Umstieg Contronics -> IP Symcon
    Von kallewirsch im Forum Allgemeine Diskussion
    Antworten: 1
    Letzter Beitrag: 18.12.05, 19:00

Stichworte