Mjsonrpc: Difference between revisions

From MidasWiki
Jump to navigation Jump to search
m (fixed links)
 
(18 intermediate revisions by 5 users not shown)
Line 1: Line 1:
== MIDAS JSON-RPC interface ==
{{Pagelinks}}
 
 
== Links ==
<div style="column-count:3;-moz-column-count:3;-webkit-column-count:3">
* [[Mhttpd.js|MIDAS Javascript library]]
* [[Custom Page]]
* [[Custom Page Features]]
* [[mhttpd]]
</div>
 
= MIDAS JSON-RPC interface =
This page described the MIDAS JSON-RPC interface found in the MIDAS Javascript library [[mhttpd.js]].


== JSON general information ==
== JSON general information ==
Line 22: Line 34:
MIDAS has 3 way to encode ODB data into JSON:
MIDAS has 3 way to encode ODB data into JSON:
* "save" format for saving all ODB data and metadata, ODB can be fully reloaded or restored from an ODB JSON save file. Links are preserved as links, upper and lower case in names of ODB keys is preserved.
* "save" format for saving all ODB data and metadata, ODB can be fully reloaded or restored from an ODB JSON save file. Links are preserved as links, upper and lower case in names of ODB keys is preserved.
* "db_values" format for exporting ODB data to web pages: links are followed to their final values, ODB key names are converted to lower case for use with case-sensitive languages such as Javascript.
* "db_values" format for exporting ODB data to web pages: links are followed to their final values, '''ODB key names are converted to lower case''' for use with case-sensitive languages such as Javascript.
* "list" format encodes a single ODB directory and returns the full information printed by the odbedit "ls -l" command.
* "list" format encodes a single ODB directory and returns the full information printed by the odbedit "ls -l" command.


Line 64: Line 76:
The "db_values" format is intended for easy web page development - main thing is to return easy to parse ODB values with minimal metadata (only ODB last_written is provided).
The "db_values" format is intended for easy web page development - main thing is to return easy to parse ODB values with minimal metadata (only ODB last_written is provided).


Because most programming languages and most JSON parser (including Javascript) are case sensitive, but ODB key names are not, this JSON encoding normalizes ODB key names by converting them to lower-case. (Converting spaces to underscores is also a possibility).
Because most programming languages and most JSON parser (including Javascript) are case sensitive, but ODB key names are not, this JSON encoding normalizes ODB key names by converting them to lower-case. (Converting spaces to underscores is also a possibility). Only the function "db_get_values" returns lower-case names - this remains the simplest way to have simple parsing of ODB JSON data in Javascript. "db_get_values" now returns an additional field for true names of ODB entries from before they were converted to lower case. This can be turned off with the "omit_names" RPC parameter.


This allows easy use of parsed JSON in Javascript, i.e. runinfo.state or runinfo["run number"] while avoiding case-matching getter functions (i.e. get_case_insensitive_property(runinfo, "state")).
This allows easy use of parsed JSON in Javascript, i.e. runinfo.state or runinfo["run number"] while avoiding case-matching getter functions (i.e. get_case_insensitive_property(runinfo, "state")).


Symlinks are followed to their final values and subdirectories are recursed.
Symlinks are followed to their final values and subdirectories are recursed.
An option is provided to '''transfer the minimum amount of data''' by suppressing  the 'last_written' value and the true names by setting the RPC parameters "omit_last_written" and "omit_names". See $MIDASSYS/examples/javascript1/example.html.
Also you can specify a timestamp and only data that is newer will be returned (caveats: no way to get rid of empty directories, for now, and no way to specify timestamps for individual array elements - you get the whole array or none of it).


<pre>
<pre>
Line 121: Line 138:
   ...
   ...
</pre>
</pre>
== Access to ODB arrays ==
Some (not all) JSON-RPC methods allow access to individual array elements in ODB, i.e. {{Odbpath|path=/equipment/rpcexample/settings/a[10]}}.
RPC methods that can do this are:
* db_copy
* db_get_values
* db_paste
=== Supported array index syntax ===
An array index syntax has been implemented to make it easier to write individual array elements (Table 1)
;Table 1
{| class="wikitable"
|-
! Array Syntax !! Array Elements !! Number of elements/data values
|-
| a[1] || 1 || 1
|-
| a[1,2,3] || 1,2,3 || 3
|-
| a[1-3] || 1,2,3 || 3
|-
| a[3-1] || 3,2,1 || 3
|-
| a[1,2,3-5,6] || 1,2,3,4,5,6 || 6
|-
|  a[1-3,4-6,7-9]|| 1,2,3,4,5,6,7,8,9 || 9
|-
| a[3-0,6-4,9-7] || 3,2,1,6,5,4,9,8,7 || 9 
|-
| a[4,2,5-6,8] || 4,2,5,6,8 || 5
|-
| a || 0-n || n <sup>**</sup>
|}
<sup>**</sup> <small>n=number of data values supplied - see [[#array name only]].</small>
See [[#Writing an array]] and [[#Reading an array]] for examples.


== JSON-RPC general information ==
== JSON-RPC general information ==
Line 132: Line 188:


MIDAS provides a simple client library:
MIDAS provides a simple client library:
* documentation, see the mjsonrpc functions: https://daq.triumf.ca/~daqweb/doc/midas-devel/html/mhttpd_8js.html
* documentation, see the mjsonrpc functions: https://daq.triumf.ca/~daqweb/doc/midas-develop/html/group__mjsonrpc__js.html
* source code, see the mjsonrpc functions: https://daq.triumf.ca/~daqweb/doc/midas-devel/resources/mhttpd.js
* source code, see the mjsonrpc functions: https://daq.triumf.ca/~daqweb/doc/midas-develop/resources/mhttpd.js


The MIDAS JSON RPC client library is based on the Javascript Promise pattern:
The MIDAS JSON RPC client library is based on the '''Javascript Promise''' pattern:


* http://www.html5rocks.com/en/tutorials/es6/promises/
* http://www.html5rocks.com/en/tutorials/es6/promises/
* https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise
* https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise
A simple example using the Promise API to display an ODB value on a web page:
<pre>
mjsonrpc_db_get_values(["/runinfo/run number"]).then(function(rpc) {
  document.getElementById("run_number").innerHTML = rpc.result.data[0];
}).catch(function(error) {
  mjsonrpc_error_alert(error);
});
</pre>
A partial list of available javascript functions. For the full list, and for full documentation, please go to the doxygen-generated documentation at
https://daq.triumf.ca/~daqweb/doc/midas-devel/html/mhttpd_8js.html
* function mjsonrpc_set_url (url) - set the URL of the MIDAS JSON-RPC server, if different from web page URL. Cross-site access is fully supported (see CORS).
* function mjsonrpc_call (method, params, id) - call arbitrary RPC method
* function mjsonrpc_start_program (name, id, callback, error_callback)
* function mjsonrpc_stop_program (name, unique, id, callback, error_callback)
* function mjsonrpc_db_get_values (paths, id, callback, error_callback) - read ODB values
* function mjsonrpc_db_paste (paths, values, id, callback, error_callback) - write ODB values
=== Batch Requests ===
The MIDAS mjson_rpc supports making combining together multiple different requests into the same HTTP request.  This batch mode requesting is much more efficient and should be used whenever possible.  An example of a mjson_rpc batch request for the transition status and ODB values is shown here:
<pre>
var req = new Array;
req.push(mjsonrpc_make_request("cm_transition_status"));
req.push(mjsonrpc_make_request("db_get_values", {"paths": ["/runinfo"]}));
mjsonrpc_send_request(req).then(function (rpc) {
  USER CODE HERE
}).catch(function (error) {
});
</pre>


== Examples ==
== Examples ==
Only a few examples are given below. For more examples:
* look elsewhere on this page
* look at the example experiment examples/javascript1/example.html
* look at the doxygen-generated documentation for mjsonrpc_xxx functions
* look at the implementation of the functions
* look at the implementation of mhttpd internal web pages (functions mhttpd_xxx in mhttpd.js)


<pre>
<pre>
Line 147: Line 244:
$  
$  
</pre>
</pre>
=== Read ODB data ===
The following code illustrates how to use function '''mjsonrpc_db_get_values()''' (see [https://daq.triumf.ca/~daqweb/doc/midas-devel/htm/group__mjsonrpc__js.html#ga80cf049d190f57f6a3f6004791d7f0e9| rpc get_values]) to read data from the ODB. Some of the data are displayed using InnerHTML. The data are read every 10 seconds. The time changes and a counter increments each time the data are read.
<pre>
<html>
<head>
<title>My Title</title>
<script src='mhttpd.js'>
</script>
<script>
var updatePeriod = 10000; // in msec
var updateTimerId = 0;
var counter = 0;
function update()  {
  clearTimeout(updateTimerId);
  load();
  if (updatePeriod > 0)
  updateTimerId = setTimeout('update()', updatePeriod);
}
function load()  {
    counter++;
    document.getElementById('LastUpdated').innerHTML = "Updating..." + new Date;
    document.getElementById('counter').innerHTML = 'Counter: '+ counter
    mjsonrpc_db_get_values(["/Runinfo","/Experiment/name"]).then(function(rpc) {
      var runinfo= rpc.result.data[0]
      var name =  rpc.result.data[1]
      document.getElementById("name").innerHTML ='Experiment name ='+ name
      document.getElementById("state").innerHTML ='Run State='+ runinfo.state
      document.getElementById("rn").innerHTML ='Run number='+ runinfo["run number"]
      document.getElementById("status").innerHTML = 'Status: '+ rpc.result.status
    }).catch(function(error) {
      mjsonrpc_error_alert(error);
    });
}
</script>
</head>
<body>
<h2> Javascript code example using mjson_db_get_values with Promises </h2>
<p id="LastUpdated">Last updated: never</p>
<p id="rn">Run Number : unknown</p>
<p id="state">Run State : unknown</p>
<p id="name">Experiment name : unknown</p>
<p id="status">Status : unknown</p>
<p id="counter">Counter: zero</p>
<script>
update()
</script>
</body>
</pre>
When run as a [[Custom Page]] using the web server [[mhttpd]], the above html code looks like this:
[[File: mjson_example1.jpg|center|frame|Figure 1: code to read from ODB run as a Custom Page]]
<br clear=all>  <!-- clear wraparound after image -->
The status value (rpc.result.status) is an array.
* rpc.result.status[0] is the status from reading "/Runinfo", and
* rpc.result.status[1] is the status from reading "/Experiment/name".
A value of 1 means success.
If the path does not exist, the status value will be 312, corresponding to the error DB_NO_KEY defined in midas.h.
=== Write ODB data and read it back ===
The following example illustrates how to write ODB data using the function '''mjsonrpc_db_paste()''' (see [https://daq.triumf.ca/~daqweb/doc/midas-devel/html/group__mjsonrpc__js.html#ga2a1da2269d82fbb9edf410a9241997b8| rpc db_paste]). In this example, when the "Set" button is pressed, data are written to the ODB keys {{Odbpath|path=test}}(integer), {{Odbpath|path=pi}}(float) and {{Odbpath|path=my_string}}(string), all in the ODB subdirectory {{Odbpath|path=/equipment/rpcexample/settings/}}. When the "Read" button is pressed, the three ODB keys are read and the data written to the screen (Figure 2). For convenience, in function set(), the paths of the ODB keys to be written are stored in the array "paths".  Unlike the example above, there is no automatic update.
<pre>
<html>
<head>
<title>My Custom Page Title</title>
<script src='mhttpd.js'>
</script>
<script>
var counter = 0;
function load()  {
      counter++;
      document.getElementById('LastUpdated').innerHTML = "Updating..." + new Date;
      mjsonrpc_db_get_values(["/equipment/rpcexample/settings/"]).then(function(rpc) {
        settings= rpc.result.data[0]
        document.getElementById("test").innerHTML ='Integer test ='+  settings.test
        document.getElementById("pi").innerHTML ='Float pi ='+  settings.pi
        document.getElementById("string").innerHTML ='String my_string='+ settings["my string"]
        document.getElementById("status").innerHTML = 'Read Status: '+ rpc.result.status
      }).catch(function(error) {
        mjsonrpc_error_alert(error);
      });
}
function set()  {
      var paths=["/equipment/rpcexample/settings/test","/equipment/rpcexample/settings/pi","/equipment/rpcexample/settings/my string"];
      mjsonrpc_db_paste(paths, [10,3.1416,"hallo world"]).then(function(rpc) {
result=rpc.result;      
        document.getElementById("wstatus").innerHTML = 'Write status '+rpc.result.status      
      }).catch(function(error) {
          mjsonrpc_error_alert(error);
      });
}
</script>
</head>
<body>
<h2> Example code using mjsonrpc calls to write and read </h2>
  <p id="LastUpdated">Last updated: never</p>
  <p id="test"> Test : unknown</p>
  <p id="pi">Pi : unknown</p>
  <p id="string">String : unknown</p>
  <p id="status">Read Status : unknown</p>
  <p id="wstatus">Write Status: zero</p>
  <p> <input type=button value='Set values' onClick='set();'> </input>
      <input type=button value='Read values' onClick='load();'></input> >/p>
</body>
</pre>
When run as a [[Custom Page]] using the web server [[mhttpd]], the output from the above html code is shown in Figure 2 below.
{| class="wikitable"
|-
! Figure 2a: Initial custom page !! Figure 2b: After pressing "Set" button !! Figure 2c: After pressing "Read" button
|-
|[[File: mjson_example2a.jpg|frame]] || [[File: mjson_example2b.jpg|frame ]] || [[File: mjson_example2c.jpg|frame]]
|}
<br clear=all>  <!-- clear wraparound after image -->
After the data is written (Figure 2b) the write status is shown.
The status value (rpc.result.status) is an array with each element showing the status of the three write operations to the three keys, i.e.
* rpc.result.status[0] is the status from writing "test", and
* rpc.result.status[1] is the status from writing "pi".
* rpc.result.status[2] is the status from writing "my_string"
A value of 1 means success.
After the data is read (Figure 2c), the values read and the read status is shown. In this case, the read status only has one value (1=success) because one read operation of the whole subdirectory is performed.
==== Error handling ====
If one of the paths to write does not exist, there will be an error reported in the status value. For example, if the path to write the variable "pi" does not exist, the write status will be
: Write status 1,312,1
The value 312 is that of the error DB_NO_KEY defined in midas.h.
If the number of data values supplied to the function mjsonrpc_db_paste() does not equal the number of paths (i.e. lengths of paths and data arrays are not equal) an error popup will result (Figure 3). The error message also contains the response ID - see [https://daq.triumf.ca/~daqweb/doc/midas-devel/html/group__mjsonrpc__js.html#ga2a1da2269d82fbb9edf410a9241997b8| rpc db_paste] for more information.
[[File: mjson_slerr.jpg|center|frame|Figure 3: Error popup when lengths of paths array and data array are not equal]]
<br clear=all>  <!-- clear wraparound after image -->
=== Writing an array ===
The following example shows using mjsonrpc_db_paste() to write to an array in ODB. See above for [[#supported array index syntax]].
Because each array element is accessed individually, each array element value comes with a corresponding status value of odb db_get_data_index(), encoded as an array (i.e. rpc.result.status in example below). Note that the data to be written to the array elements must be enclosed by their own square brackets [] and the number of data values must match the number of array elements listed (except when the array name is used alone -  see [[#array name only]]). Too few data values will throw an error, too many will be ignored.
If the array in the ODB is not large enough for the number of elements and data to be written, it will be expanded automatically.
==== Writing to a variable and an array ====
The following example shows using mjsonrpc_db_paste()  to
* write "9" to an integer variable called "test", and to
* write values to a number of elements of the array "array"
Both "test" and "array" are keys in the ODB subdirectory {{Odbpath|path=/equipment/rpcexample/settings/}}.
<pre>
  mjsonrpc_db_paste(["/equipment/rpcexample/settings/test","/equipment/rpcexample/settings/array[3-1,4,5,8-10]"], [9,[1,2,3,4,5,8,9,10]]).then(function(rpc) {
      document.getElementById("wstatus").innerHTML ='Set Status='+ rpc.result.status
  }).catch(function(error) {
      mjsonrpc_error_alert(error);
    });
</pre>
Assuming the array was filled with zeroes to start with, after writing to the array  and [[#reading an array|reading it back]], it would now contain the values
: Array= 0,3,2,1,4,5,0,0,8,9,10,11
: Set Status = 1,1,1,1,1,1,1,1,1  (rpc.result.status)
There are 9 elements in the rpc.result.status array, where 1=success. The first element is the status after writing "test", the next 8 the status after writing each array element.
====  Automatically expand the array ====
If the array in the ODB contains 12 elements, writing
mjsonrpc_db_paste(["/equipment/rpcexample/settings/test","/equipment/rpcexample/settings/array[3-1,4,5,8-10,14]"], [9,[1,2,3,4,5,8,9,10,14] ]).then(function(rpc) { ...
will automatically expand the array to 15 elements.
==== Too few data values ====
Supplying too few data values, e.g. writing
mjsonrpc_db_paste(["/equipment/rpcexample/settings/array[4,5,8-10]"], [ [4,5,8,9] ]).then(function(rpc) { ...
results in an error (rpc.result.status= 315) i.e. DB_TYPE_MISMATCH because there aren't enough data words supplied (4) for the number of indices (5).
<div id="array name only"></div>
==== Array name only supplied ====
If you supply just the array name, then you do not need to supply the same number of elements as the array length. For example,
mjsonrpc_db_paste(["/equipment/rpcexample/settings/array"],[ [7,6,0] ]).then(function(rpc){ ...
will write the first three elements of the array to 7,6,0. Other array elements will be untouched. In this case, there is only one status value for the whole array.
: Array= 7,6,0,1,4,5,0,0,8,9,10,11
: Set Status = 1  (rpc.result.status)
==== Set all elements to one value ====
If you want to set all 19 elements of an array to 1, you can write
<pre>
mjsonrpc_db_paste(["/equipment/rpcexample/settings/array[0-18]"], [1]).then(function(rpc) { ...
</pre>
or to set a group of indices to 999, you can write
<pre>
mjsonrpc_db_paste(["/equipment/rpcexample/settings/array[1-3,4,5,8-10]"], [999]).then(function(rpc) { ...
</pre>
Note that the single value is written as [999] rather than as an array with single value, i.e. [ [999] ].
=== Reading an array ===
In the same way, you can read all or part of an array.  See above for [[#Supported array index syntax]].
<pre>
var array = new Array();
mjsonrpc_db_get_values(["/Runinfo","/Experiment/name","/Equipment/rpcexample/Settings/array","/Equipment/rpcexample/Settings/array[3-6,11]"]).then(function(rpc) {
      document.getElementById("status").innerHTML = 'Status : '+ result.status 
      var runinfo= rpc.result.data[0]
      var name =  rpc.result.data[1]
      array = rpc.result.data[2]  // whole array
      document.getElementById("array").innerHTML ='Array='+ array
      array=rpc.result.data[3]    // array indices
      document.getElementById("array_ele").innerHTML ='Array elements='+ array
}).catch(function(error) {
  mjsonrpc_error_alert(error);
});
</pre>
This example gives
: Array=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0
: Array elements=4,5,6,7,12
: Status :  1,1,1,1,1,1,1,1  (rpc.result.status)
Note that the "Array elements" line has read the contents of indices 3-6 and 11 as requested (5 indices in total). The status array contains 8 values. The last 5 values are the status from reading the 5 array elements.


== Schema (List of all RPC methods) ==
== Schema (List of all RPC methods) ==
Line 157: Line 470:
* https://tools.ietf.org/html/draft-zyp-json-schema-04
* https://tools.ietf.org/html/draft-zyp-json-schema-04


The MIDAS JSON RPC Schema is automatically generated by mhttpd and is linked by the mhttpd "Help" page in JSON and in text format.
The MIDAS JSON RPC Schema is automatically generated by mhttpd and is <b>linked by the mhttpd "Help" page in JSON and in text format</b>.


For reference, a recent copy of the JSON RPC API Schema is pasted from the mhttpd "help" page. For final, complete and up-to-date schema, please get your own copy from the midas "help" page.
For reference, a recent copy of the JSON RPC API Schema is pasted here from the mhttpd "help" page. For final, complete and up-to-date schema, please get your own copy from the midas "help" page.


In this schema, "?" means an optional parameter, "[]" means an array parameter. (There is an artefact: all method names have question marks because they are optional as far as the schema generator is concerned).
In this schema, "?" means an optional parameter, "[]" means an array parameter. (There is an artefact: all method names have question marks because they are optional as far as the schema generator is concerned).


=== MIDAS JSON RPC API Schema ===
<pre>
<pre>
------------------------------------------------------------------------
 
-----------------------------------------------------------------------------------------------
Autogenerated schema for all MIDAS JSON-RPC methods
Autogenerated schema for all MIDAS JSON-RPC methods
------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------
cm_exist?      | calls MIDAS cm_exist() to check if given MIDAS program is running
al_reset_alarm?            | reset alarms
              | ----------------------
                            | -----------------------------------------------------------------
                            | params  | alarms[]            | array of alarm names
                            |          |                      | array of      | string   
                            | -----------------------------------------------------------------
                            | result  | status[]            | return status of al_reset_alarm() for each alarm
                            |          |                      | array of      | integer   
-----------------------------------------------------------------------------------------------
al_trigger_alarm?          | trigger an alarm
                            | -----------------------------------------------------------------
                            | params  | name                | string        | alarm name
                            |          | message              | string        | alarm message
                            |          | class                | string        | alarm class
                            |          | condition            | string        | alarm condition
                            |          | type                | integer        | alarm type (AT_xxx)
                            | -----------------------------------------------------------------
                            | result  | status              | integer        | return status of al_trigger_alarm()
------------------------
</pre>
</pre>
[[Category:Javascript library]]

Latest revision as of 01:56, 7 December 2023



Links

MIDAS JSON-RPC interface

This page described the MIDAS JSON-RPC interface found in the MIDAS Javascript library mhttpd.js.

JSON general information

JSON is a lightweight data-interchange format usually associated with Javascript and web programming. It is a popular choice as replacement for older general purpose data formats such as XML. JSON is defined by RFC-7159 (read more at http://www.json.org/). When necessary, the overhead of text encoded JSON is reduced by compressing JSON documents (using gzip), or by using binary-encoded JSON.

JSON documents look like this:

{ "Runinfo" : { "State" : 1, "Online Mode" : 1, "Run number" : 13585 } }

Note that the JSON standard is incompatible with IEEE Standard for Floating-Point Arithmetic (IEEE 754), specifically, there is no standard way to encode the special numerical values +Infinity, -Infinity and NaN ("-0.0" is ok).

In MIDAS, JSON support is provided by an ODB data encoder (in odb.c), an ODB "JSON paste" decoder (in json_paste.cxx) and a general purpose JSON encoder/decoder (mjson.h, mjson.cxx, see https://daq.triumf.ca/~daqweb/doc/midas-devel/html/mjson_8h.html and https://daq.triumf.ca/~daqweb/doc/midas-devel/html/class_m_json_node.html).

The MIDAS implementation of JSON has following variances from the JSON standard:

JSON encoding of ODB data

MIDAS has 3 way to encode ODB data into JSON:

  • "save" format for saving all ODB data and metadata, ODB can be fully reloaded or restored from an ODB JSON save file. Links are preserved as links, upper and lower case in names of ODB keys is preserved.
  • "db_values" format for exporting ODB data to web pages: links are followed to their final values, ODB key names are converted to lower case for use with case-sensitive languages such as Javascript.
  • "list" format encodes a single ODB directory and returns the full information printed by the odbedit "ls -l" command.

For example:

JSON "save" format: db_copy_json_save()

The "save" format encodes all ODB data and metadata. ODB can be fully reloaded or restored from ODB JSON save files.

$ odbedit
odbedit> cd runinfo
[local:testexpt:S]/Runinfo>json
status: 1, json: {
  "State/key" : { "type" : 7, "access_mode" : 7, "last_written" : 1438212553 },
  "State" : 1,
  "Online Mode/key" : { "type" : 7, "access_mode" : 7, "last_written" : 1436830326 },
  "Online Mode" : 1,
  "Run number/key" : { "type" : 7, "access_mode" : 7, "last_written" : 1438212481 },
  "Run number" : 13585,
  "Transition in progress/key" : { "type" : 7, "access_mode" : 7, "last_written" : 1438212553 },
  "Transition in progress" : 0,
  "Start abort/key" : { "type" : 7, "access_mode" : 7, "last_written" : 1438212552 },
  "Start abort" : 0,
  "Requested transition/key" : { "type" : 7, "access_mode" : 7, "last_written" : 1436923816 },
  "Requested transition" : 0,
  "Start time/key" : { "type" : 12, "item_size" : 32, "access_mode" : 7, "last_written" : 1438212481 },
  "Start time" : "Wed Jul 29 16:28:01 2015",
  "Start time binary/key" : { "type" : 6, "access_mode" : 7, "last_written" : 1438212481 },
  "Start time binary" : "0x55b96181",
  "Stop time/key" : { "type" : 12, "item_size" : 32, "access_mode" : 7, "last_written" : 1438212552 },
  "Stop time" : "Wed Jul 29 16:29:12 2015",
  "Stop time binary/key" : { "type" : 6, "access_mode" : 7, "last_written" : 1438212552 },
  "Stop time binary" : "0x55b961c8"
}
[local:testexpt:S]/Runinfo>

JSON "db_values" format: db_copy_json_values()

The "db_values" format is intended for easy web page development - main thing is to return easy to parse ODB values with minimal metadata (only ODB last_written is provided).

Because most programming languages and most JSON parser (including Javascript) are case sensitive, but ODB key names are not, this JSON encoding normalizes ODB key names by converting them to lower-case. (Converting spaces to underscores is also a possibility). Only the function "db_get_values" returns lower-case names - this remains the simplest way to have simple parsing of ODB JSON data in Javascript. "db_get_values" now returns an additional field for true names of ODB entries from before they were converted to lower case. This can be turned off with the "omit_names" RPC parameter.

This allows easy use of parsed JSON in Javascript, i.e. runinfo.state or runinfo["run number"] while avoiding case-matching getter functions (i.e. get_case_insensitive_property(runinfo, "state")).

Symlinks are followed to their final values and subdirectories are recursed.

An option is provided to transfer the minimum amount of data by suppressing the 'last_written' value and the true names by setting the RPC parameters "omit_last_written" and "omit_names". See $MIDASSYS/examples/javascript1/example.html.

Also you can specify a timestamp and only data that is newer will be returned (caveats: no way to get rid of empty directories, for now, and no way to specify timestamps for individual array elements - you get the whole array or none of it).


$ odbedit
odbedit> cd runinfo
[local:testexpt:S]/Runinfo>jsvalues
status: 1, json: {
  "state/last_written" : 1438212553,
  "state" : 1,
  "online mode/last_written" : 1436830326,
  "online mode" : 1,
  "run number/last_written" : 1438212481,
  "run number" : 13585,
  "transition in progress/last_written" : 1438212553,
  "transition in progress" : 0,
  "start abort/last_written" : 1438212552,
  "start abort" : 0,
  "requested transition/last_written" : 1436923816,
  "requested transition" : 0,
  "start time/last_written" : 1438212481,
  "start time" : "Wed Jul 29 16:28:01 2015",
  "start time binary/last_written" : 1438212481,
  "start time binary" : "0x55b96181",
  "stop time/last_written" : 1438212552,
  "stop time" : "Wed Jul 29 16:29:12 2015",
  "stop time binary/last_written" : 1438212552,
  "stop time binary" : "0x55b961c8"
}
[local:testexpt:S]/Runinfo>

JSON "ls" format: db_copy_json_ls()

The "ls" format returns all the data printed by odbedit command "ls -l" and shown by the mhttpd ODB editor web page. It is intended for implementing web ODB editor functions.

Note how subdirectories are encoded as empty JSON objects "{}".

$ odbedit
odbedit> cd experiment
[local:testexpt:S]/Experiment>jsls
jsls "/Experiment", status: 1, json: {
  "Name/key" : { "type" : 12, "item_size" : 32, "access_mode" : 7, "last_written" : 1448038414 },
  "Name" : "testexpt",
  "Buffer sizes" : { },
  "edit on start" : { },
  "Security" : { },
  "Transition debug flag/key" : { "type" : 7, "access_mode" : 7, "last_written" : 1436830326 },
  "Transition debug flag" : 0,
  "Transition timeout/key" : { "type" : 7, "access_mode" : 7, "last_written" : 1436830326 },
  "Transition timeout" : 30000,
  ...

Access to ODB arrays

Some (not all) JSON-RPC methods allow access to individual array elements in ODB, i.e. /equipment/rpcexample/settings/a[10].

RPC methods that can do this are:

  • db_copy
  • db_get_values
  • db_paste

Supported array index syntax

An array index syntax has been implemented to make it easier to write individual array elements (Table 1)

Table 1
Array Syntax Array Elements Number of elements/data values
a[1] 1 1
a[1,2,3] 1,2,3 3
a[1-3] 1,2,3 3
a[3-1] 3,2,1 3
a[1,2,3-5,6] 1,2,3,4,5,6 6
a[1-3,4-6,7-9] 1,2,3,4,5,6,7,8,9 9
a[3-0,6-4,9-7] 3,2,1,6,5,4,9,8,7 9
a[4,2,5-6,8] 4,2,5,6,8 5
a 0-n n **

** n=number of data values supplied - see #array name only.

See #Writing an array and #Reading an array for examples.


JSON-RPC general information

Javascript client library

MIDAS provides a simple client library:

The MIDAS JSON RPC client library is based on the Javascript Promise pattern:

A simple example using the Promise API to display an ODB value on a web page:

mjsonrpc_db_get_values(["/runinfo/run number"]).then(function(rpc) {
   document.getElementById("run_number").innerHTML = rpc.result.data[0];
}).catch(function(error) {
   mjsonrpc_error_alert(error);
});

A partial list of available javascript functions. For the full list, and for full documentation, please go to the doxygen-generated documentation at https://daq.triumf.ca/~daqweb/doc/midas-devel/html/mhttpd_8js.html

  • function mjsonrpc_set_url (url) - set the URL of the MIDAS JSON-RPC server, if different from web page URL. Cross-site access is fully supported (see CORS).
  • function mjsonrpc_call (method, params, id) - call arbitrary RPC method
  • function mjsonrpc_start_program (name, id, callback, error_callback)
  • function mjsonrpc_stop_program (name, unique, id, callback, error_callback)
  • function mjsonrpc_db_get_values (paths, id, callback, error_callback) - read ODB values
  • function mjsonrpc_db_paste (paths, values, id, callback, error_callback) - write ODB values

Batch Requests

The MIDAS mjson_rpc supports making combining together multiple different requests into the same HTTP request. This batch mode requesting is much more efficient and should be used whenever possible. An example of a mjson_rpc batch request for the transition status and ODB values is shown here:

var req = new Array;
req.push(mjsonrpc_make_request("cm_transition_status"));
req.push(mjsonrpc_make_request("db_get_values", {"paths": ["/runinfo"]}));
mjsonrpc_send_request(req).then(function (rpc) {
   USER CODE HERE
}).catch(function (error) {
});

Examples

Only a few examples are given below. For more examples:

  • look elsewhere on this page
  • look at the example experiment examples/javascript1/example.html
  • look at the doxygen-generated documentation for mjsonrpc_xxx functions
  • look at the implementation of the functions
  • look at the implementation of mhttpd internal web pages (functions mhttpd_xxx in mhttpd.js)
$ curl -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","id":null,"method":"db_get_values","params":{"paths":["/runinfo/run number"]}}' 'http://localhost:8080?mjsonrpc'
{"jsonrpc": "2.0","result":{"data":[324],"status":[1],"last_written":[1443570804]},"id":null}
$ 

Read ODB data

The following code illustrates how to use function mjsonrpc_db_get_values() (see rpc get_values) to read data from the ODB. Some of the data are displayed using InnerHTML. The data are read every 10 seconds. The time changes and a counter increments each time the data are read.

<html>
<head>
<title>My Title</title>
<script src='mhttpd.js'> 
</script>
<script>
var updatePeriod = 10000; // in msec
var updateTimerId = 0;
var counter = 0;

function update()  {
   clearTimeout(updateTimerId);
   load();
   if (updatePeriod > 0)
   updateTimerId = setTimeout('update()', updatePeriod);
}
function load()   {
    counter++;
    document.getElementById('LastUpdated').innerHTML = "Updating..." + new Date;
    document.getElementById('counter').innerHTML = 'Counter: '+ counter

    mjsonrpc_db_get_values(["/Runinfo","/Experiment/name"]).then(function(rpc) {
       var runinfo= rpc.result.data[0]
       var name =  rpc.result.data[1]
       document.getElementById("name").innerHTML ='Experiment name ='+ name
       document.getElementById("state").innerHTML ='Run State='+ runinfo.state
       document.getElementById("rn").innerHTML ='Run number='+ runinfo["run number"]
       document.getElementById("status").innerHTML = 'Status: '+ rpc.result.status
    }).catch(function(error) {
       mjsonrpc_error_alert(error);
    });
}
</script>
</head>
<body>
<h2> Javascript code example using mjson_db_get_values with Promises </h2>
<p id="LastUpdated">Last updated: never</p>
<p id="rn">Run Number : unknown</p>
<p id="state">Run State : unknown</p>
<p id="name">Experiment name : unknown</p>
<p id="status">Status : unknown</p>
<p id="counter">Counter: zero</p>
<script>
update()
</script>
</body>

When run as a Custom Page using the web server mhttpd, the above html code looks like this:

Figure 1: code to read from ODB run as a Custom Page


The status value (rpc.result.status) is an array.

  • rpc.result.status[0] is the status from reading "/Runinfo", and
  • rpc.result.status[1] is the status from reading "/Experiment/name".

A value of 1 means success. If the path does not exist, the status value will be 312, corresponding to the error DB_NO_KEY defined in midas.h.

Write ODB data and read it back

The following example illustrates how to write ODB data using the function mjsonrpc_db_paste() (see rpc db_paste). In this example, when the "Set" button is pressed, data are written to the ODB keys test(integer), pi(float) and my_string(string), all in the ODB subdirectory /equipment/rpcexample/settings/. When the "Read" button is pressed, the three ODB keys are read and the data written to the screen (Figure 2). For convenience, in function set(), the paths of the ODB keys to be written are stored in the array "paths". Unlike the example above, there is no automatic update.

<html>
<head>
<title>My Custom Page Title</title>
<script src='mhttpd.js'> 
</script>
<script>
var counter = 0;

function load()  {
      counter++;
      document.getElementById('LastUpdated').innerHTML = "Updating..." + new Date;
      mjsonrpc_db_get_values(["/equipment/rpcexample/settings/"]).then(function(rpc) {
         settings= rpc.result.data[0]
         document.getElementById("test").innerHTML ='Integer test ='+  settings.test
         document.getElementById("pi").innerHTML ='Float pi ='+  settings.pi
         document.getElementById("string").innerHTML ='String my_string='+ settings["my string"]
         document.getElementById("status").innerHTML = 'Read Status: '+ rpc.result.status
      }).catch(function(error) {
         mjsonrpc_error_alert(error);
      });
}

function set()  {
      var paths=["/equipment/rpcexample/settings/test","/equipment/rpcexample/settings/pi","/equipment/rpcexample/settings/my string"];
      mjsonrpc_db_paste(paths, [10,3.1416,"hallo world"]).then(function(rpc) {
	 result=rpc.result;	      
         document.getElementById("wstatus").innerHTML = 'Write status '+rpc.result.status	      
      }).catch(function(error) {
          mjsonrpc_error_alert(error);
      });
}
</script>
</head>
<body>
<h2> Example code using mjsonrpc calls to write and read </h2>
  <p id="LastUpdated">Last updated: never</p>
  <p id="test"> Test : unknown</p>
  <p id="pi">Pi : unknown</p>
  <p id="string">String : unknown</p>
  <p id="status">Read Status : unknown</p>
  <p id="wstatus">Write Status: zero</p>
  <p> <input type=button value='Set values' onClick='set();'> </input>
       <input type=button value='Read values' onClick='load();'></input> >/p>
</body>

When run as a Custom Page using the web server mhttpd, the output from the above html code is shown in Figure 2 below.

Figure 2a: Initial custom page Figure 2b: After pressing "Set" button Figure 2c: After pressing "Read" button
Mjson example2a.jpg
Mjson example2b.jpg
Mjson example2c.jpg


After the data is written (Figure 2b) the write status is shown. The status value (rpc.result.status) is an array with each element showing the status of the three write operations to the three keys, i.e.

  • rpc.result.status[0] is the status from writing "test", and
  • rpc.result.status[1] is the status from writing "pi".
  • rpc.result.status[2] is the status from writing "my_string"

A value of 1 means success. After the data is read (Figure 2c), the values read and the read status is shown. In this case, the read status only has one value (1=success) because one read operation of the whole subdirectory is performed.

Error handling

If one of the paths to write does not exist, there will be an error reported in the status value. For example, if the path to write the variable "pi" does not exist, the write status will be

Write status 1,312,1

The value 312 is that of the error DB_NO_KEY defined in midas.h.

If the number of data values supplied to the function mjsonrpc_db_paste() does not equal the number of paths (i.e. lengths of paths and data arrays are not equal) an error popup will result (Figure 3). The error message also contains the response ID - see rpc db_paste for more information.

Figure 3: Error popup when lengths of paths array and data array are not equal


Writing an array

The following example shows using mjsonrpc_db_paste() to write to an array in ODB. See above for #supported array index syntax. Because each array element is accessed individually, each array element value comes with a corresponding status value of odb db_get_data_index(), encoded as an array (i.e. rpc.result.status in example below). Note that the data to be written to the array elements must be enclosed by their own square brackets [] and the number of data values must match the number of array elements listed (except when the array name is used alone - see #array name only). Too few data values will throw an error, too many will be ignored. If the array in the ODB is not large enough for the number of elements and data to be written, it will be expanded automatically.

Writing to a variable and an array

The following example shows using mjsonrpc_db_paste() to

  • write "9" to an integer variable called "test", and to
  • write values to a number of elements of the array "array"

Both "test" and "array" are keys in the ODB subdirectory /equipment/rpcexample/settings/.

  mjsonrpc_db_paste(["/equipment/rpcexample/settings/test","/equipment/rpcexample/settings/array[3-1,4,5,8-10]"], [9,[1,2,3,4,5,8,9,10]]).then(function(rpc) {
       document.getElementById("wstatus").innerHTML ='Set Status='+ rpc.result.status
  }).catch(function(error) {
       mjsonrpc_error_alert(error);
    });

Assuming the array was filled with zeroes to start with, after writing to the array and reading it back, it would now contain the values

Array= 0,3,2,1,4,5,0,0,8,9,10,11
Set Status = 1,1,1,1,1,1,1,1,1 (rpc.result.status)

There are 9 elements in the rpc.result.status array, where 1=success. The first element is the status after writing "test", the next 8 the status after writing each array element.


Automatically expand the array

If the array in the ODB contains 12 elements, writing

mjsonrpc_db_paste(["/equipment/rpcexample/settings/test","/equipment/rpcexample/settings/array[3-1,4,5,8-10,14]"], [9,[1,2,3,4,5,8,9,10,14] ]).then(function(rpc) { ...

will automatically expand the array to 15 elements.


Too few data values

Supplying too few data values, e.g. writing

mjsonrpc_db_paste(["/equipment/rpcexample/settings/array[4,5,8-10]"], [ [4,5,8,9] ]).then(function(rpc) { ...

results in an error (rpc.result.status= 315) i.e. DB_TYPE_MISMATCH because there aren't enough data words supplied (4) for the number of indices (5).


Array name only supplied

If you supply just the array name, then you do not need to supply the same number of elements as the array length. For example,

mjsonrpc_db_paste(["/equipment/rpcexample/settings/array"],[ [7,6,0] ]).then(function(rpc){ ...

will write the first three elements of the array to 7,6,0. Other array elements will be untouched. In this case, there is only one status value for the whole array.

Array= 7,6,0,1,4,5,0,0,8,9,10,11
Set Status = 1 (rpc.result.status)


Set all elements to one value

If you want to set all 19 elements of an array to 1, you can write

mjsonrpc_db_paste(["/equipment/rpcexample/settings/array[0-18]"], [1]).then(function(rpc) { ...

or to set a group of indices to 999, you can write

mjsonrpc_db_paste(["/equipment/rpcexample/settings/array[1-3,4,5,8-10]"], [999]).then(function(rpc) { ...

Note that the single value is written as [999] rather than as an array with single value, i.e. [ [999] ].

Reading an array

In the same way, you can read all or part of an array. See above for #Supported array index syntax.

var array = new Array();
mjsonrpc_db_get_values(["/Runinfo","/Experiment/name","/Equipment/rpcexample/Settings/array","/Equipment/rpcexample/Settings/array[3-6,11]"]).then(function(rpc) {
      document.getElementById("status").innerHTML = 'Status : '+ result.status  
      var runinfo= rpc.result.data[0] 
      var name =  rpc.result.data[1]
      array = rpc.result.data[2]   // whole array
      document.getElementById("array").innerHTML ='Array='+ array
      array=rpc.result.data[3]    // array indices
      document.getElementById("array_ele").innerHTML ='Array elements='+ array
}).catch(function(error) {
   mjsonrpc_error_alert(error);
});

This example gives

Array=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0
Array elements=4,5,6,7,12
Status : 1,1,1,1,1,1,1,1 (rpc.result.status)

Note that the "Array elements" line has read the contents of indices 3-6 and 11 as requested (5 indices in total). The status array contains 8 values. The last 5 values are the status from reading the 5 array elements.



Schema (List of all RPC methods)

The MIDAS JSON RPC API is documented via an automatically generated JSON Schema.

The JSON Schema ("describes your JSON data format") is not a well established standard (there is no final RFC) but seems to be in common use. Multiple 3rd party tools exist to visualize, explore and interface with JSON documents described by JSON Schemas. For more general information go here:

The MIDAS JSON RPC Schema is automatically generated by mhttpd and is linked by the mhttpd "Help" page in JSON and in text format.

For reference, a recent copy of the JSON RPC API Schema is pasted here from the mhttpd "help" page. For final, complete and up-to-date schema, please get your own copy from the midas "help" page.

In this schema, "?" means an optional parameter, "[]" means an array parameter. (There is an artefact: all method names have question marks because they are optional as far as the schema generator is concerned).

MIDAS JSON RPC API Schema


-----------------------------------------------------------------------------------------------
Autogenerated schema for all MIDAS JSON-RPC methods
-----------------------------------------------------------------------------------------------
al_reset_alarm?             | reset alarms
                            | -----------------------------------------------------------------
                            | params   | alarms[]             | array of alarm names
                            |          |                      | array of       | string     
                            | -----------------------------------------------------------------
                            | result   | status[]             | return status of al_reset_alarm() for each alarm
                            |          |                      | array of       | integer    
-----------------------------------------------------------------------------------------------
al_trigger_alarm?           | trigger an alarm
                            | -----------------------------------------------------------------
                            | params   | name                 | string         | alarm name
                            |          | message              | string         | alarm message
                            |          | class                | string         | alarm class
                            |          | condition            | string         | alarm condition
                            |          | type                 | integer        | alarm type (AT_xxx)
                            | -----------------------------------------------------------------
                            | result   | status               | integer        | return status of al_trigger_alarm()
-----------------------------------------------------------------------------------------------
al_trigger_class?           | trigger an alarm
                            | -----------------------------------------------------------------
                            | params   | class                | string         | alarm class
                            |          | message              | string         | alarm message
                            |          | first?               | bool           | see al_trigger_class() in midas.c
                            | -----------------------------------------------------------------
                            | result   | status               | integer        | return status of al_trigger_class()
-----------------------------------------------------------------------------------------------
bm_receive_event?           | read event buffers
                            | -----------------------------------------------------------------
                            | params   | buffer_name          | string         | name of event buffer
                            |          | event_id?            | integer        | requested event id, -1 means any event id
                            |          | trigger_mask?        | integer        | requested trigger mask, -1 means any trigger mask
                            |          | get_recent?          | bool           | get last available event that matches this event request
                            |          | last_event_header[]? | do not resend an event we already received: event header of last received event [event_id,trigger_mask,serial_number,time_stamp]
                            |          |                      | array of       | integer    
                            |          | timeout_millisec?    | number         | how long to wait for an event
                            | -----------------------------------------------------------------
                            | result   | binary data          | arraybuffer    | binary event data
                            |          | status               | integer        | return status of bm_open_buffer(), bm_request_event(), bm_set_cache_size(), bm_receive_alloc()
-----------------------------------------------------------------------------------------------
cm_exist?                   | calls MIDAS cm_exist() to check if given MIDAS program is running
                            | -----------------------------------------------------------------
                            | params   | name                 | string         | name of the program, corresponding to ODB /Programs/name
                            |          | unique?              | bool           | bUnique argument to cm_exist()
                            | -----------------------------------------------------------------
                            | result   | status               | integer        | return status of cm_exist()
-----------------------------------------------------------------------------------------------
cm_msg1?                    | Generate a midas message using cm_msg1()
                            | -----------------------------------------------------------------
                            | params   | facility?            | string         | message facility, default is "midas"
                            |          | user?                | string         | message user, default is "javascript_commands"
                            |          | type?                | integer        | message type, MT_xxx from midas.h, default is MT_INFO
                            |          | message              | string         | message text
                            | -----------------------------------------------------------------
                            | result   | status               | integer        | return status of cm_msg1()
-----------------------------------------------------------------------------------------------
cm_msg_facilities?          | get message facilities using cm_msg_facilities()
                            | -----------------------------------------------------------------
                            | result   | status               | integer        | return status of cm_msg_facilities()
                            |          | facilities[]         | array of facility names
                            |          |                      | array of       | string     
-----------------------------------------------------------------------------------------------
cm_msg_retrieve?            | Retrieve midas messages using cm_msg_retrieve2()
                            | -----------------------------------------------------------------
                            | params   | facility?            | string         | message facility, default is "midas"
                            |          | min_messages?        | integer        | get at least this many messages, default is 1
                            |          | time?                | number         | start from given timestamp, value 0 means give me newest messages, default is 0
                            | -----------------------------------------------------------------
                            | result   | num_messages         | integer        | number of messages returned
                            |          | messages             | string         | messages separated by \n
                            |          | status               | integer        | return status of cm_msg_retrieve2()
-----------------------------------------------------------------------------------------------
cm_shutdown?                | calls MIDAS cm_shutdown() to stop given MIDAS program
                            | -----------------------------------------------------------------
                            | params   | name                 | string         | name of the program, corresponding to ODB /Programs/name
                            |          | unique?              | bool           | bUnique argument to cm_shutdown()
                            | -----------------------------------------------------------------
                            | result   | status               | integer        | return status of cm_shutdown()
-----------------------------------------------------------------------------------------------
cm_transition?              | start and stop runs
                            | -----------------------------------------------------------------
                            | params   | transition           | string         | requested transition: TR_START, TR_STOP, TR_PAUSE, TR_RESUME
                            |          | run_number?          | integer        | New run number, value 0 means /runinfo/run_number + 1, default is 0
                            |          | async_flag?          | integer        | Transition type. Default is multithreaded transition TR_MTHREAD
                            |          | debug_flag?          | integer        | See cm_transition(), value 1: trace to stdout, value 2: trace to midas.log
                            | -----------------------------------------------------------------
                            | result   | status               | integer        | return status of cm_transition()
                            |          | error_string?        | string         | return error string from cm_transition()
-----------------------------------------------------------------------------------------------
db_copy?                    | get complete ODB data in the "save" json encoding, suitable for reloading with odbedit command "load"
                            | -----------------------------------------------------------------
                            | params   | paths[]              | array of ODB subtree paths
                            |          |                      | array of       | string     
                            | -----------------------------------------------------------------
                            | result   | data[]               | keys and values of ODB data for each path
                            |          |                      | array of       | object     
                            |          | status[]             | return status of db_copy_json_save() for each path
                            |          |                      | array of       | integer    
-----------------------------------------------------------------------------------------------
db_create?                  | Create new ODB entries
                            | -----------------------------------------------------------------
                            | params[] | array of ODB paths to be created
                            |          | array of             | arguments to db_create_key() and db_set_num_values()
                            |          |                      | path           | string      | ODB path to be created
                            |          |                      | type           | integer     | MIDAS TID_xxx type
                            |          |                      | array_length?  | integer     | optional array length, default is 1
                            |          |                      | string_length? | integer     | for TID_STRING, optional string length, default is NAME_LENGTH
                            | -----------------------------------------------------------------
                            | result   | status[]             | return status of db_create_key(), db_set_num_values() and db_set_data() (for TID_STRING) for each path
                            |          |                      | array of       | integer    
-----------------------------------------------------------------------------------------------
db_delete?                  | delete ODB keys
                            | -----------------------------------------------------------------
                            | params   | paths[]              | array of ODB paths to delete
                            |          |                      | array of       | string     
                            | -----------------------------------------------------------------
                            | result   | status[]             | return status of db_delete_key() for each path
                            |          |                      | array of       | integer    
-----------------------------------------------------------------------------------------------
db_get_values?              | get values of ODB data from given subtrees
                            | -----------------------------------------------------------------
                            | params   | paths[]              | array of ODB subtree paths, see note on array indices
                            |          |                      | array of       | string     
                            |          | omit_names?          | bool           | omit the /name entries
                            |          | omit_last_written?   | bool           | omit the /last_written entries and the last_written[] result
                            |          | omit_tid?            | bool           | omit the tid[] result
                            |          | omit_old_timestamp?  | number         | omit data older than given ODB timestamp
                            |          | preserve_case?       | bool           | preserve the capitalization of ODB key names (WARNING: ODB is not case sensitive); note that this will also have side effect of setting the omit_names option
                            | -----------------------------------------------------------------
                            | result   | data[]               | values of ODB data for each path, all key names are in lower case, all symlinks are followed
                            |          |                      | array of       | any        
                            |          | status[]             | return status of db_copy_json_values() or db_copy_json_index() for each path
                            |          |                      | array of       | integer    
                            |          | tid[]?               | odb type id for each path, absent if omit_tid is true
                            |          |                      | array of       | integer    
                            |          | last_written[]?      | last_written value of the ODB subtree for each path, absent if omit_last_written is true
                            |          |                      | array of       | number     
-----------------------------------------------------------------------------------------------
db_key?                     | get ODB keys
                            | -----------------------------------------------------------------
                            | params   | paths[]              | array of ODB paths
                            |          |                      | array of       | string     
                            | -----------------------------------------------------------------
                            | result   | status[]             | return status of db_key() for each path
                            |          |                      | array of       | integer    
                            |          | keys[]               | key data for each path
                            |          |                      | array of       | object     
                            |          | keys[]               | key type TID_xxx
                            |          |                      | array of       | integer    
                            |          | keys[]               | array length, 1 for normal entries
                            |          |                      | array of       | integer    
                            |          | keys[]               | key name
                            |          |                      | array of       | string     
                            |          | keys[]               | data total size in bytes
                            |          |                      | array of       | integer    
                            |          | keys[]               | array element size, string length for TID_STRING
                            |          |                      | array of       | integer    
                            |          | keys[]               | access mode bitmap of MODE_xxx
                            |          |                      | array of       | integer    
                            |          | keys[]               | number of hotlinks attached to this key
                            |          |                      | array of       | integer    
                            |          | keys[]               | timestamp when data was last updated
                            |          |                      | array of       | integer    
-----------------------------------------------------------------------------------------------
db_link?                    | Create ODB symlinks
                            | -----------------------------------------------------------------
                            | params   | new_links[]          | array of new symlinks to be created
                            |          |                      | array of       | string     
                            |          | target_paths[]       | array of existing ODB paths for each link
                            |          |                      | array of       | string     
                            | -----------------------------------------------------------------
                            | result   | status[]             | return status of db_create_link() for each path
                            |          |                      | array of       | integer    
-----------------------------------------------------------------------------------------------
db_load?                    | Save ODB subtree to file
                            | -----------------------------------------------------------------
                            | params   | filename             | string         | Filename to read ODB contents from
                            | -----------------------------------------------------------------
                            | result   | status               | integer        | return status of db_load
-----------------------------------------------------------------------------------------------
db_ls?                      | get contents of given ODB subdirectory in the "ls" json encoding - similar to odbedit command "ls -l"
                            | -----------------------------------------------------------------
                            | params   | paths[]              | array of ODB subtree paths
                            |          |                      | array of       | string     
                            | -----------------------------------------------------------------
                            | result   | data[]               | keys and values of ODB data for each path
                            |          |                      | array of       | object     
                            |          | status[]             | return status of db_copy_json_ls() for each path
                            |          |                      | array of       | integer    
-----------------------------------------------------------------------------------------------
db_paste?                   | write data into ODB
                            | -----------------------------------------------------------------
                            | params   | paths[]              | array of ODB subtree paths, see note on array indices
                            |          |                      | array of       | string     
                            |          | values[]             | array of data values written to ODB via db_paste_json() for each path
                            |          |                      | array of       | any        
                            | -----------------------------------------------------------------
                            | result   | status[]             | array of return status of db_paste_json() for each path
                            |          |                      | array of       | integer    
-----------------------------------------------------------------------------------------------
db_rename?                  | Change size of ODB arrays
                            | -----------------------------------------------------------------
                            | params   | paths[]              | array of ODB paths to rename
                            |          |                      | array of       | string     
                            |          | new_names[]          | array of new names for each ODB path
                            |          |                      | array of       | string     
                            | -----------------------------------------------------------------
                            | result   | status[]             | return status of db_rename_key() for each path
                            |          |                      | array of       | integer    
-----------------------------------------------------------------------------------------------
db_reorder?                 | Change order of ODB keys in a subdirectory
                            | -----------------------------------------------------------------
                            | params   | paths[]              | array of new symlinks to be created
                            |          |                      | array of       | string     
                            |          | indices[]            | array of existing ODB paths for each link
                            |          |                      | array of       | integer    
                            | -----------------------------------------------------------------
                            | result   | status[]             | return status of db_reorder_key() for each path
                            |          |                      | array of       | integer    
-----------------------------------------------------------------------------------------------
db_resize?                  | Change size of ODB arrays
                            | -----------------------------------------------------------------
                            | params   | paths[]              | array of ODB paths to resize
                            |          |                      | array of       | string     
                            |          | new_lengths[]        | array of new lengths for each ODB path
                            |          |                      | array of       | integer    
                            | -----------------------------------------------------------------
                            | result   | status[]             | return status of db_set_num_values() for each path
                            |          |                      | array of       | integer    
-----------------------------------------------------------------------------------------------
db_resize_string?           | Change size of ODB string arrays
                            | -----------------------------------------------------------------
                            | params   | paths[]              | array of ODB paths to resize
                            |          |                      | array of       | string     
                            |          | new_lengths[]        | array of new lengths for each ODB path
                            |          |                      | array of       | integer    
                            |          | new_string_lengths[] | array of new string lengths for each ODB path
                            |          |                      | array of       | integer    
                            | -----------------------------------------------------------------
                            | result   | status[]             | return status of db_resize_string() for each path
                            |          |                      | array of       | integer    
-----------------------------------------------------------------------------------------------
db_save?                    | Save ODB subtree to file
                            | -----------------------------------------------------------------
                            | params   | path                 | string         | ODB path
                            |          | filename             | string         | Filename so save ODB contents to
                            | -----------------------------------------------------------------
                            | result   | status               | integer        | return status of db_save
-----------------------------------------------------------------------------------------------
db_scl?                     | Show ODB clients
                            | -----------------------------------------------------------------
                            | result   | scl                  | json           | return value of db_scl()
-----------------------------------------------------------------------------------------------
db_sor?                     | Show ODB open records starting from given ODB path
                            | -----------------------------------------------------------------
                            | params   | path?                | string         | ODB path
                            | -----------------------------------------------------------------
                            | result   | sor                  | json           | return value of db_sor()
-----------------------------------------------------------------------------------------------
el_delete?                  | Delete elog message
                            | -----------------------------------------------------------------
                            | params   | tag                  | string         | tag of message to delete
                            | -----------------------------------------------------------------
                            | result   | status               | integer        | return status of el_delete
-----------------------------------------------------------------------------------------------
el_query?                   | Query elog messages
                            | -----------------------------------------------------------------
                            | params   | last_n_hours?        | integer        | return messages from the last N hours
                            | -----------------------------------------------------------------
                            | result   | status               | integer        | return status of el_retrieve
                            |          | msg[]                | message tag
                            |          |                      | array of       | string     
-----------------------------------------------------------------------------------------------
el_retrieve?                | Get an elog message
                            | -----------------------------------------------------------------
                            | params   | tag                  | string         | elog message tag
                            | -----------------------------------------------------------------
                            | result   | status               | integer        | return status of el_retrieve
                            |          | msg.tag              | string         | message tag
-----------------------------------------------------------------------------------------------
exec_script?                | execute custom script defined in ODB /Script (scripts show in the menu) or /CustomScript (scripts from custom pages)
                            | -----------------------------------------------------------------
                            | params   | script?              | string         | Execute ODB /Script/xxx
                            |          | customscript?        | string         | Execute ODB /CustomScript/xxx
                            | -----------------------------------------------------------------
                            | result   | status               | integer        | return status of cm_exec_script()
-----------------------------------------------------------------------------------------------
ext_list_files?             | js_ext_list_files
                            | -----------------------------------------------------------------
                            | params   | subdir               | string         | List files in experiment_directory/userfiles/subdir
                            |          | fileext              | string         | Filename extension
                            | -----------------------------------------------------------------
                            | result   | status               | integer        | return status of midas library calls
                            |          | path                 | string         | Search path
                            |          | subdirs[]            | list of subdirectories
                            |          |                      | array of       | string     
                            |          | files[]              | script filename
                            |          |                      | array of       | string     
                            |          | files[]              | script description
                            |          |                      | array of       | string     
-----------------------------------------------------------------------------------------------
ext_read_file?              | js_ext_read_script
                            | -----------------------------------------------------------------
                            | params   | filename             | string         | File name, read from experiment_directory/userfiles/filename
                            | -----------------------------------------------------------------
                            | result   | content              | string         | ASCII file content
                            |          | status               | integer        | return status of midas library calls
                            |          | error                | string         | error text
-----------------------------------------------------------------------------------------------
ext_save_file?              | js_ext_save_file
                            | -----------------------------------------------------------------
                            | params   | filename             | string         | File name, save in experiment_directory/userfiles/filename
                            |          | script               | string         | ASCII content
                            | -----------------------------------------------------------------
                            | result   | status               | integer        | return status of midas library calls
                            |          | error                | string         | error text
-----------------------------------------------------------------------------------------------
get_alarms?                 | get alarm data
                            | -----------------------------------------------------------------
                            | params   | get_all?             | bool           | get all alarms, even in alarm system not active and alarms not triggered
                            | -----------------------------------------------------------------
                            | result   | status               | integer        | return status of midas library calls
                            |          | alarm_system_active  | bool           | value of ODB "/Alarms/alarm system active"
                            |          | alarms               | object         | alarm data, keyed by alarm name
                            |          | alarms[]             | alarm is triggered
                            |          |                      | array of       | bool       
                            |          | alarms[]             | alarm is enabled
                            |          |                      | array of       | bool       
                            |          | alarms[]             | alarm class
                            |          |                      | array of       | string     
                            |          | alarms[]             | alarm type AT_xxx
                            |          |                      | array of       | integer    
                            |          | alarms[]             | display background color
                            |          |                      | array of       | string     
                            |          | alarms[]             | display foreground color
                            |          |                      | array of       | string     
                            |          | alarms[]             | alarm ODB message field
                            |          |                      | array of       | string     
                            |          | alarms[]             | alarm ODB condition field
                            |          |                      | array of       | string     
                            |          | alarms[]             | evaluated alarm condition (AT_EVALUATED alarms only)
                            |          |                      | array of       | string     
                            |          | alarms[]             | next time the periodic alarm will fire (AT_PERIODIC alarms only)
                            |          |                      | array of       | string     
                            |          | alarms[]             | time when alarm was triggered
                            |          |                      | array of       | string     
                            |          | alarms[]             | final alarm text shown to user by mhttpd
                            |          |                      | array of       | string     
-----------------------------------------------------------------------------------------------
get_debug?                  | get current value of mjsonrpc_debug
                            | -----------------------------------------------------------------
                            | params   | any                  | there are no input parameters
                            | -----------------------------------------------------------------
                            | result   | integer              | current value of mjsonrpc_debug
-----------------------------------------------------------------------------------------------
get_http_trace?             | get current value of mhttpd http_trace
                            | -----------------------------------------------------------------
                            | params   | any                  | there are no input parameters
                            | -----------------------------------------------------------------
                            | result   | integer              | current value of http_trace
-----------------------------------------------------------------------------------------------
get_schema?                 | Get the MIDAS JSON-RPC schema JSON object
                            | -----------------------------------------------------------------
                            | params   | any                  | there are no input parameters
                            | -----------------------------------------------------------------
                            | result   | object               | returns the MIDAS JSON-RPC schema JSON object
-----------------------------------------------------------------------------------------------
get_sleep?                  | get current value of mjsonrpc_sleep
                            | -----------------------------------------------------------------
                            | params   | any                  | there are no input parameters
                            | -----------------------------------------------------------------
                            | result   | integer              | current value of mjsonrpc_sleep
-----------------------------------------------------------------------------------------------
get_time?                   | get current value of mjsonrpc_time
                            | -----------------------------------------------------------------
                            | params   | any                  | there are no input parameters
                            | -----------------------------------------------------------------
                            | result   | integer              | current value of mjsonrpc_time
-----------------------------------------------------------------------------------------------
get_timezone?               | get current server timezone offset in seconds
                            | -----------------------------------------------------------------
                            | params   | any                  | there are no input parameters
                            | -----------------------------------------------------------------
                            | result   | integer              | offset in seconds
-----------------------------------------------------------------------------------------------
hs_get_active_events?       | get list of active history events using hs_read_event_list()
                            | -----------------------------------------------------------------
                            | result   | status               | integer        | return status of hs_read_event_list()
                            |          | events[]             | array of history event names
                            |          |                      | array of       | string     
-----------------------------------------------------------------------------------------------
hs_get_channels?            | get list of history channels in /Logger/History
                            | -----------------------------------------------------------------
                            | result   | status               | integer        | return status of hs_get_events()
                            |          | default_channel      | string         | name of the default logger history channel in /History/LoggerHistoryChannel
                            |          | channels[]           | logger history channel names
                            |          |                      | array of       | string     
-----------------------------------------------------------------------------------------------
hs_get_events?              | get list of history events that existed at give time using hs_get_events()
                            | -----------------------------------------------------------------
                            | params   | channel?             | string         | midas history channel, default is the default reader channel
                            |          | time?                | number         | timestamp, value 0 means current time, default is 0
                            | -----------------------------------------------------------------
                            | result   | status               | integer        | return status of hs_get_events()
                            |          | channel              | string         | logger history channel name
                            |          | events[]             | array of history event names
                            |          |                      | array of       | string     
-----------------------------------------------------------------------------------------------
hs_get_last_written?        | get list of history tags for given history events that existed at give time using hs_get_last_written()
                            | -----------------------------------------------------------------
                            | params   | channel?             | string         | midas history channel, default is the default reader channel
                            |          | time?                | number         | timestamp, value 0 means current time, default is 0
                            |          | events[]             | array of history event names
                            |          |                      | array of       | string     
                            |          | tags[]               | array of history event tag names
                            |          |                      | array of       | string     
                            |          | index[]              | array of history event tag array indices
                            |          |                      | array of       | string     
                            | -----------------------------------------------------------------
                            | result   | status               | integer        | return status
                            |          | channel              | string         | logger history channel name
                            |          | last_written[]       | array of last-written times for each history event
                            |          |                      | array of       | number     
-----------------------------------------------------------------------------------------------
hs_get_tags?                | get list of history tags for given history events that existed at give time using hs_get_tags()
                            | -----------------------------------------------------------------
                            | params   | channel?             | string         | midas history channel, default is the default reader channel
                            |          | time?                | number         | timestamp, value 0 means current time, default is 0
                            |          | events[]?            | array of history event names, default is get all events using hs_get_events()
                            |          |                      | array of       | string     
                            | -----------------------------------------------------------------
                            | result   | status               | integer        | return status
                            |          | channel              | string         | logger history channel name
                            |          | events[]             | array of history event names for each history event
                            |          |                      | array of       | string     
                            |          | events[]             | array of status ohistory tags for each history event
                            |          |                      | array of       | integer    
                            |          | events[]             | array of history tags for each history event
                            |          |                      | array of       | string     
                            |          | events[]             | history tag name
                            |          |                      | array of       | string     
                            |          | events[]             | history tag midas data type
                            |          |                      | array of       | integer    
                            |          | events[]             | history tag number of array elements, omitted if 1
                            |          |                      | array of       | integer    
-----------------------------------------------------------------------------------------------
hs_image_retrieve?          | Get a list of history image files
                            | -----------------------------------------------------------------
                            | params   | image?               | string         | image name as defined under /History/Images/<image>
                            |          | start_time           | number         | start time of the data
                            |          | end_time             | number         | end time of the data
                            | -----------------------------------------------------------------
                            | result   | time[]               | array of time stamps in seconds
                            |          |                      | array of       | arraybuffer
                            |          | filename[]           | array of file names
                            |          |                      | array of       | arraybuffer
-----------------------------------------------------------------------------------------------
hs_read?                    | get history data for given history events that existed at give time using hs_read_buffer()
                            | -----------------------------------------------------------------
                            | params   | channel?             | string         | midas history channel, default is the default reader channel
                            |          | start_time           | number         | start time of the data
                            |          | end_time             | number         | end time of the data
                            |          | events[]             | array of history event names
                            |          |                      | array of       | string     
                            |          | tags[]               | array of history event tag names
                            |          |                      | array of       | string     
                            |          | index[]              | array of history event tag array indices
                            |          |                      | array of       | string     
                            | -----------------------------------------------------------------
                            | result   | status               | integer        | return status
                            |          | channel              | string         | logger history channel name
                            |          | data[]               | array of history data
                            |          |                      | array of       | array      
                            |          | data[]               | status for each event
                            |          |                      | array of       | integer    
                            |          | data[]               | number of data for each event
                            |          |                      | array of       | integer    
                            |          | data[]               | time data
                            |          |                      | array of       | number     
                            |          | data[]               | value data
                            |          |                      | array of       | number     
-----------------------------------------------------------------------------------------------
hs_read_arraybuffer?        | get history data for given history events that existed at give time using hs_read_buffer()
                            | -----------------------------------------------------------------
                            | params   | channel?             | string         | midas history channel, default is the default reader channel
                            |          | start_time           | number         | start time of the data
                            |          | end_time             | number         | end time of the data
                            |          | events[]             | array of history event names
                            |          |                      | array of       | string     
                            |          | tags[]               | array of history event tag names
                            |          |                      | array of       | string     
                            |          | index[]              | array of history event tag array indices
                            |          |                      | array of       | string     
                            | -----------------------------------------------------------------
                            | result   | binary data          | arraybuffer    | binary data, see documentation
-----------------------------------------------------------------------------------------------
hs_read_binned?             | get history data for given history events that existed at give time using hs_read_buffer()
                            | -----------------------------------------------------------------
                            | params   | channel?             | string         | midas history channel, default is the default reader channel
                            |          | start_time           | number         | start time of the data
                            |          | end_time             | number         | end time of the data
                            |          | num_bins             | integer        | number of time bins
                            |          | events[]             | array of history event names
                            |          |                      | array of       | string     
                            |          | tags[]               | array of history event tag names
                            |          |                      | array of       | string     
                            |          | index[]              | array of history event tag array indices
                            |          |                      | array of       | string     
                            | -----------------------------------------------------------------
                            | result   | status               | integer        | return status
                            |          | channel              | string         | logger history channel name
                            |          | data[]               | array of history data
                            |          |                      | array of       | array      
                            |          | data[]               | status for each event
                            |          |                      | array of       | integer    
                            |          | data[]               | number of data points for each event
                            |          |                      | array of       | integer    
                            |          | data[]               | number of data points for each bin
                            |          |                      | array of       | integer    
                            |          | data[]               | mean for each bin
                            |          |                      | array of       | number     
                            |          | data[]               | rms for each bin
                            |          |                      | array of       | number     
                            |          | data[]               | minimum value for each bin
                            |          |                      | array of       | number     
                            |          | data[]               | maximum value for each bin
                            |          |                      | array of       | number     
                            |          | data[]               | time of last data entry
                            |          |                      | array of       | number     
                            |          | data[]               | value of last data entry
                            |          |                      | array of       | number     
-----------------------------------------------------------------------------------------------
hs_read_binned_arraybuffer? | get history data for given history events that existed at give time using hs_read_buffer()
                            | -----------------------------------------------------------------
                            | params   | channel?             | string         | midas history channel, default is the default reader channel
                            |          | start_time           | number         | start time of the data
                            |          | end_time             | number         | end time of the data
                            |          | num_bins             | integer        | number of time bins
                            |          | events[]             | array of history event names
                            |          |                      | array of       | string     
                            |          | tags[]               | array of history event tag names
                            |          |                      | array of       | string     
                            |          | index[]              | array of history event tag array indices
                            |          |                      | array of       | string     
                            | -----------------------------------------------------------------
                            | result   | binary data          | arraybuffer    | binary data, see documentation
-----------------------------------------------------------------------------------------------
hs_reopen?                  | reopen the history channel to make sure we see the latest list of events using hs_clear_cache()
                            | -----------------------------------------------------------------
                            | params   | channel?             | string         | midas history channel, default is the default reader channel
                            | -----------------------------------------------------------------
                            | result   | status               | integer        | return status of hs_get_events()
                            |          | channel              | string         | logger history channel name
-----------------------------------------------------------------------------------------------
jrpc?                       | make RPC call into frontend program via RPC_JRPC
                            | -----------------------------------------------------------------
                            | params   | client_name          | string         | Connect to this MIDAS client, see cm_connect_client()
                            |          | cmd                  | string         | Command passed to client
                            |          | args                 | string         | Parameters passed to client as a string, could be JSON encoded
                            |          | max_reply_length?    | integer        | Optional maximum length of client reply. MIDAS RPC does not support returning strings of arbitrary length, maximum length has to be known ahead of time.
                            | -----------------------------------------------------------------
                            | result   | reply                | string         | Reply from client as a string, could be JSON encoded
                            |          | status               | integer        | return status of cm_connect_client() and rpc_client_call()
-----------------------------------------------------------------------------------------------
null?                       | RPC method always returns null
                            | -----------------------------------------------------------------
                            | params   | any                  | method parameters are ignored
                            | -----------------------------------------------------------------
                            | result   | null                 | always returns null
-----------------------------------------------------------------------------------------------
seq_list_files?             | js_seq_list_files
                            | -----------------------------------------------------------------
                            | params   | subdir               | string         | List files in /Seq/State/Path/subdir
                            | -----------------------------------------------------------------
                            | result   | status               | integer        | return status of midas library calls
                            |          | path                 | string         | Search path
                            |          | subdirs[]            | list of subdirectories
                            |          |                      | array of       | string     
                            |          | files[]              | script filename
                            |          |                      | array of       | string     
                            |          | files[]              | script description
                            |          |                      | array of       | string     
-----------------------------------------------------------------------------------------------
seq_save_script?            | js_seq_save_script
                            | -----------------------------------------------------------------
                            | params   | filename             | string         | Script file name
                            |          | script               | string         | Script text
                            | -----------------------------------------------------------------
                            | result   | status               | integer        | return status of midas library calls
                            |          | error                | string         | error text
-----------------------------------------------------------------------------------------------
set_debug?                  | set new value of mjsonrpc_debug
                            | -----------------------------------------------------------------
                            | params   | integer              | new value of mjsonrpc_debug
                            | -----------------------------------------------------------------
                            | result   | integer              | new value of mjsonrpc_debug
-----------------------------------------------------------------------------------------------
set_http_trace?             | set new value of mhttpd http_trace
                            | -----------------------------------------------------------------
                            | params   | integer              | new value of http_trace
                            | -----------------------------------------------------------------
                            | result   | integer              | new value of http_trace
-----------------------------------------------------------------------------------------------
set_sleep?                  | set new value of mjsonrpc_sleep
                            | -----------------------------------------------------------------
                            | params   | integer              | new value of mjsonrpc_sleep
                            | -----------------------------------------------------------------
                            | result   | integer              | new value of mjsonrpc_sleep
-----------------------------------------------------------------------------------------------
set_time?                   | set new value of mjsonrpc_time
                            | -----------------------------------------------------------------
                            | params   | integer              | new value of mjsonrpc_time
                            | -----------------------------------------------------------------
                            | result   | integer              | new value of mjsonrpc_time
-----------------------------------------------------------------------------------------------
ss_millitime?               | get current MIDAS time using ss_millitime()
                            | -----------------------------------------------------------------
                            | params   | any                  | there are no input parameters
                            | -----------------------------------------------------------------
                            | result   | integer              | current value of ss_millitime()
-----------------------------------------------------------------------------------------------
start_program?              | start MIDAS program defined in ODB /Programs/name
                            | -----------------------------------------------------------------
                            | params   | name                 | string         | name of the program, corresponding to ODB /Programs/name
                            | -----------------------------------------------------------------
                            | result   | status               | integer        | return status of ss_system()
-----------------------------------------------------------------------------------------------
user_example1?              | example of user defined RPC method that returns up to 3 results
                            | -----------------------------------------------------------------
                            | params   | arg                  | string         | example string argment
                            |          | optional_arg?        | integer        | optional example integer argument
                            | -----------------------------------------------------------------
                            | result   | string               | string         | returns the value of "arg" parameter
                            |          | integer              | integer        | returns the value of "optional_arg" parameter
-----------------------------------------------------------------------------------------------
user_example2?              | example of user defined RPC method that returns more than 3 results
                            | -----------------------------------------------------------------
                            | params   | arg                  | string         | example string argment
                            |          | optional_arg?        | integer        | optional example integer argument
                            | -----------------------------------------------------------------
                            | result   | string1              | string         | returns the value of "arg" parameter
                            |          | string2              | string         | returns "hello"
                            |          | string3              | string         | returns "world!"
                            |          | value1               | integer        | returns the value of "optional_arg" parameter
                            |          | value2               | number         | returns 3.14
-----------------------------------------------------------------------------------------------
user_example3?              | example of user defined RPC method that returns an error
                            | -----------------------------------------------------------------
                            | params   | arg                  | integer        | integer value, if zero, throws a JSON-RPC error
                            | -----------------------------------------------------------------
                            | result   | status               | integer        | returns the value of "arg" parameter