JSON-RPC API

The server is still in ALPHA development status. This means that there is too much that still can change hence meaning we will start writing the API down when the server reaches BETA status

This page currently only explains the base specifications that are followed.

JSON-RPC is the interface for communicating with the PiDome server and is used on the http and raw socket interfaces. It is based on the JSON-RPC 2.0 Specification. The RPC mehtods are developed from the ground up and is designed in such a way that it will be apply-able through different transportation methods.

The current implementation status is as close as currently possible to the specifications. Current specification support for now is:

  1. Client -> Server
    1. Method calls,
    2. Parameters by name,
    3. Parameters by position.
    4. Status and error responses.

There is no introspect method available yet. But as soon it is available it will be posted on this page.

Entry endpoints

There are currently three entry points available to communicate with JSON-RPC. These are via http and https, websockets and TCP over SSL and non SSL.

http

The http endpoint is only available when the web interface is enabled on the server. The methods supported are GET and POST. If you need to send data which can cause confusion when encoding use the POST method.

The entry point for GET is:

http://<server-ip>:<server-port>/jsonrpc.json?rpc={JSON-STRING}

You must send the rpc string url encoded.

For POST method use the same entry point but then as:

http://<server-ip>:<server-port>/jsonrpc.json

And use “rpc” as the post parameter containing the json string. This method does not require encoding.

Websocket and TCP sockets

The JSON-RPC specification is also used on the websockets and tcp sockets (both ssl and non ssl). There are no special requirements needed to pass on data to these sockets but only it is conform the JSON-RPC specifications

Implementation specification

As said the implementation will be following the JSON-RPC 2.0 format. This means that all the messages must include as the specification tells. The following implementation rules apply to the server:

Requests

Requests send to the server must include (as specified) the rpc version number, an id, a method to be executed, and parameters if needed for that method. The server will always respond with the mentioned id send to the server (unless there is a serious server error and the id can not be resolved or the error is raised by a low level system component). The id can be a Number or a String.

Where the server differs from the specification is that the specification allows the id to be a NULL. The server does not allow a NULL for the id. The reason for this is a NULL is used for server errors or for responses which have a unknown id. Also fractional Numbers are not allowed to be used. So if the id is NULL or a fractional number the server will respond with a parse error.

Methods

The methods used by the server are prefixed (extension) methods. A method to be executed is prefixed with the internal (extension) handler. For devices this is the DeviceService, for macro’s the MacroService, for Media this is the MediaService etc. So to execute a method for sending a command to a device this thus would be “DeviceService.sendDevice”.

Responses

Server responses are accordingly to the specification. It will always contain the jsonrpc version number (“2.0”), the send id (unless see above) and the result or error object.

Result object

The result object from a response will always contain the parameter success telling if a method has been executed with success. This parameter is a Boolean containing true or false. Next to this parameter there will be a message parameter. When the success parameter is false, the message parameter will contain a String why a method could not be executed (Unless the error is a server error).

Error object

When there is a server error,parse error, method not found error, an invalid parameters error, etc., the server will respond with the error codes and corresponding message as the specification requires (See the above link). The data parameter in this message is an object containing extra parameters which explains the server error occurred. This can be helpful in solving problems which could exist in the server. When the server is set in debug mode there will be an extra parameter called trace which gives a stack trace of the error.

Batching

Method batching is currently not supported

Documentation

The documentation will be straight forward. Because of the use of named and unnamed parameters the parameters if needed will be explained in order of the unnamed method. So if an specific object is expected at position 3, then at position 3 in the list the explanation will be shown with the named parameter. In the example below this is shown in more detail.

A request example with documentation

Here is an example of a request send to the server to handle a command to be executed by a device:

Documentation:
DeviceService.sendDevice: Send a device action request.

Method: “DeviceService.sendDevice”
Parameters:

  1. id: int – The id of the device
  2. group: String – The device command group
  3. set: String – The device command set
  4. command: String = The command the device should handle

So the above method explanation tells that, if unnamed parameters used, at position one the device id is expected and at position 4 the command string. If you would use named parameters there is no position restriction.

The above documentation would result in the next JSON-RPC calls:

Named parameters (Not position restricted)

{"jsonrpc": "2.0", "method": "DeviceService.sendDevice", "params": {"id": 1, "command":"turn-on", "group": "groupName", "set":"setName"}, "id": "sendadevicecommand"}

Unnamed parameters (Position restricted)

{"jsonrpc": "2.0", "method": "DeviceService.sendDevice", "params": [1, "groupName", "setName", "turn-on"], "id": "sendadevicecommand"}

Possible responses

If the above command is used, and the command executes with success, the response would be:

{"jsonrpc":"2.0", "id": "sendadevicecomand","result":{"message":"","success":true}}

When a command should return a result, because a listing or object is requested, the result looks like:

{"jsonrpc":"2.0", "id": "sendadevicecomand","result":{"message":"","success":true, "data": Object-or-Array}}

If the command fails the response looks like:

{"jsonrpc":"2.0", "id": "sendadevicecomand","result":{"message":"Reason why not executed","success":false}}

Server/parse/method/parameters error responses (part of specification)

When there is one of the above mentioned errors the server response object will be according the specifications. However, where the default error messaging is possible not really constructive, we have extended the error message with a data parameter which, when possible, tells more about the error. The example below shows how this error is constructed:

{
    "jsonrpc": "2.0",
    "error": {
        "code": -32601,
        "message": "Method not found",
        "data": {
            "message": "Method not found in DeviceService",
            "trace": "org.pidome.server.system.rpc.PidomeJSONRPCException\n    at org.pidome.server.system.rpc.PidomeJSONRPC.handleDeviceRequest(PidomeJSONRPC.java:140)\n    at org.pidome.server.system.rpc.PidomeJSONRPC.handle(PidomeJSONRPC.java:96)\n    at org.pidome.server.system.webservice.webclient.Webclient_jsonrpc.collect(Webclient_jsonrpc.java:44)\n    at org.pidome.server.system.webservice.HTTPClientHandler.run(HTTPClientHandler.java:106)\n    at java.lang.Thread.run(Thread.java:724)\n"
        }
    },
    "id": "invalidmethod"
}

As you can see The above message is a message constructed with an extra message with more detail and includes the stack trace. The trace is only when the server is in debug mode otherwise the trace is omitted so this is a parameter you can not rely on and only use while developing. To comply to the specification the trace replaces the tabs in the traces with spaces to keep indentation and replaces the newlines with the actual newline character.

Broadcasts

Broadcasts are real time happenings in the server and are initiated by the server. Therefore broadcasts will NOT contain an id, and even not a null id. It is completely omitted. If an id is present, then always, and really always it is a response to the client.

The specification of a response is exactly like methods specification, but without an id.

Availability

Currently the server is in ALPHA state. We will start with publishing the API when the server is beta meaning all API functionalities have been function frozen and will not change