HTTP - RPC v1.1

Address :: https://m2.exosite.com (or HTTP)

Exosite Remote Procedure Call API
Revision 1.1

Overview

Exosite’s RPC (Remote Procedure Call) API allows developers to take full advantage of the One Platform. The Remote Procedure Calls are packaged (encoded) in JSON format and can be sent via any number of transports that can deliver a payload. Examples in this document show the RPCs encoded in JSON and sent using the HTTP transport.
Clients (devices, applications) with sufficient access rights may do the following with this API:

  • Create and Update dataports, datarules, and dispatches
  • Write / Read client resource values
  • Record a log of time-stamped client resource values
  • Mapping and Un-mapping aliases to resource IDs
  • Look-up of resource IDs and Owners
  • Listing of resourceIDs by type
  • Info available for a resource
  • Flushing all data from a resource

Libraries and Examples

If writing your own implementation for our RPC API isn’t your thing, we also post wrapper libraries to our Exosite Labs Github projects..
All of the libraries posted on github have example code as part of the project.

Specifics

Requests sent from a client device use JSON encoding and send the remote procedure call (RPC) through a transport protocol (e.g. HTTP) to the Exosite One Platform.
JSON is a data exchange format that is language independent. XML would be a similar data exchange format. The basic idea behind this RPC is that a client authenticates itself, sends one or multiple request message calls and receives responses for those calls that require a response.

Transports

  • HTTP
    • Host: m2.exosite.com
    • URL: /api:v1/rpc/process
    • Content-Type: application/json; charset=utf-8

Request Message Format

Request :: object
{
  "auth":Auth
 ,"calls":Calls
}
Auth :: object
{"cik":CIK}
CIK :: string
"aaaaaaaabbbbbbbbccccccccddddddddeeeeeeee"

A One Platform Client Interface Key

Calls :: array
[CallRequest,...]
CallRequest :: object
{
  "id":CallID
 ,"procedure":Procedure
 ,"arguments":Arguments
}

OR

{
  "procedure":Procedure
 ,"arguments":Arguments
}
CallID :: number | string

A unique identifier for each CallRequest within the Request. If no CallID is provided, no CallResponse will be returned.

Procedure :: string
"create" | "drop" | "flush" | "info" | "listing"
"lookup" | "map" | "read" | "record" | "unmap"
"update" | "write"
Arguments :: array
[Argument,...]
Argument :: value

Procedure dependent. See each Procedure reference documentation.

Response Message Format

Response :: array | object
[CallResponse,...]

OR

{"error":Error}
CallResponse :: object
{
  "id":CallID
 ,"status":string
}

OR

{
  "id":CallID
 ,"status":string
 ,"result":value
}

OR

{
  "id":CallID
 ,"error":Error
}
Error :: object
{
  "code":number
 ,"message":string
 ,"context":value
}

Procedures

Create Dataport

Procedure :: “create”
Arguments :: array
["dataport",Description]
Response result :: ResourceID
Description :: object
{
  "format":"float" | "integer" | "string"
 ,"name":string = ""
 ,"preprocess":Preprocess = []
 ,"subscribe":ResourceID | null = null
 ,"visibility":"private" | "public" = "private"
 ,"retention":
 {
 "count":number | "infinity"
 ,"duration":number | "infinity"
 }
}
Preprocess :: array
[[Operation,Constant],...]
Operation :: string
"add" | "sub" | "mul" | "div" | "mod" | "gt" | "geq" | "lt" | "leq" | "eq" | "neq" | "value"
Constant :: number
ResourceID :: string

JSON Example

CallRequest:
{
  "id":1
 ,"procedure":"create"
 ,"arguments":[
    "dataport"
   ,{
      "format":"float"
     ,"name":"Temperature C"
     ,"preprocess":[["div",100]]
 ,"retention":{"duration":"infinity", "count":"infinity"}
 }
  ]
}
CallResponse:
{
  "id":1
 ,"status":"ok"
 ,"result":"f8b185e2d6fea7434663ddca0961d7167f4654f5"
}

Create Datarule

Procedure :: “create”
Arguments :: array
["datarule",Description]
Response result :: ResourceID
Description :: object
{
  "format":"integer" | "boolean"
 ,"name":string = ""
 ,"preprocess":Preprocess = []
 ,"rule":Rule
 ,"subscribe":ResourceID = ""
 ,"visibility":"private" | "public" = "private"
}
Preprocess :: array
[[Operation,Constant],...]
Operation :: string
"add" | "sub" | "mul" | "div" | "mod" | "gt" | "geq" | "lt" | "leq" | "eq" | "neq" | "value"
Constant :: number
ResourceID :: string
Rule :: object
{
  "simple":{
    "comparison":"gt" | "lt" | "eq" | "geq" | "leq" | "neq"
   ,"constant":number
   ,"repeat":boolean
  }
}

OR

{
  "timeout":{
    "repeat":boolean
   ,"timeout":number
  }
}

OR

{
  "interval":{
    "comparison":"gt" | "lt" | "eq" | "geq" | "leq" | "neq"
   ,"constant":number
   ,"repeat":boolean
   ,"timeout":number
  }
}

OR

{
  "duration":{
    "comparison":"gt" | "lt" | "eq" | "geq" | "leq" | "neq"
   ,"constant":number
   ,"repeat":boolean
   ,"timeout":number
  }
}

OR

{
  "count":{
    "comparison":"gt" | "lt" | "eq" | "geq" | "leq" | "neq"
   ,"constant":number
   ,"count":number
   ,"repeat":boolean
   ,"timeout":number
  }
}

JSON Example

CallRequest:
{
  "id":1
 ,"procedure":"create"
 ,"arguments":[
    "datarule"
   ,{
      "format":"integer"
     ,"name":"Temperature To High"
     ,"rule":{
        "simple":{
          "comparison":"gt"
         ,"constant":90
         ,"repeat":false
        }
      }
     ,"visibility":"public"
    }
  ]
 ,"subscribe":"f8b185e2d6fea7434663ddca0961d7167f4654f5"
}
CallResponse:
{
  "id":1
 ,"status":"ok"
 ,"result":"c5dd9d32bdf00808a8e2da9f55594decdcadd87e"
}

Create Dispatch

Procedure :: “create”
Arguments :: array
["dispatch",Description]
Response result :: ResourceID
Description :: object
{
  "locked":boolean = false
 ,"message":string = ""
 ,"method":"email" | "http_get" | "http_post" | "http_put" | "sms" | "xmpp"
 ,"name":string = ""
 ,"preprocess":Preprocess = []
 ,"recipient":string
 ,"subject":string
 ,"subscribe":ResourceID | null = null
 ,"visibility":"private" | "public" = "public"
}
Preprocess :: array
[[Operation,Constant],...]
Operation :: string
"add" | "sub" | "mul" | "div" | "mod" | "gt" | "geq" | "lt" | "leq" | "eq" | "neq" | "value"
Constant :: number
ResourceID :: string

JSON Example

CallRequest:
{
  "id":1
 ,"procedure":"create"
 ,"arguments":[
    "dispatch"
   ,{
      "message":"The temperature has exceeded the 90F threshold. Please check the unit."
     ,"method":"xmpp"
     ,"preprocess":[["eq",true]]
     ,"recipient":"responsible_party@example.com"
     ,"subject":"Temp has exceeded threshold"
     ,"subscribe":"c5dd9d32bdf00808a8e2da9f55594decdcadd87e"
    }
  ]
}
CallResponse:
{
  "id":1
 ,"status":"ok"
 ,"result":"e7c5717be5e695a83179ecd7cfacf6c7e5a9e52f"
}

Update Resource

Procedure :: “update”
Arguments :: array
[ResourceID,Description]
Description :: object

See “create”.

ResourceID :: string

JSON Example

CallRequest:
{
  "id":1
 ,"procedure":"update"
 ,"arguments":[
    "c5dd9d32bdf00808a8e2da9f55594decdcadd87e"
   ,{
      "rule":{
        "simple":{
          "constant":100
        }
      }
    }
  ]
}
CallResponse:
{
  "id":1
 ,"status":"ok"
}

Drop a Resource

Procedure :: “drop”
Arguments :: array
[ResourceID]
ResourceID :: string

JSON Example

CallRequest:
{
  "id":1
 ,"procedure":"drop"
 ,"arguments":[
    "f8b185e2d6fea7434663ddca0961d7167f4654f5"
  ]
}
CallResponse:
{
  "id":1
 ,"status":"ok"
}

Flush a Resource

Procedure :: “flush”
Arguments :: array
[ResourceID]
ResourceID :: string

JSON Example

CallRequest:
{
  "id":1
 ,"procedure":"flush"
 ,"arguments":[
    "f8b185e2d6fea7434663ddca0961d7167f4654f5"
  ]
}
CallResponse:
{
  "id":1
 ,"status":"ok"
}

Alias a Resource

Procedure :: “map”
Arguments :: array
["alias",ResourceID,Alias]
ResourceID :: string
Alias :: string

JSON Example

CallRequest:
{
  "id":2
 ,"procedure":"map"
 ,"arguments":[
    "alias"
   ,"f8b185e2d6fea7434663ddca0961d7167f4654f5"
   ,"reg_1"
  ]
}
CallResponse:
{
  "id":2
 ,"status":"ok"
}

Lookup an Aliased Resource

Procedure :: “lookup”
Arguments :: array
["alias",Alias]
Response result :: ResourceID
Alias :: string

JSON Example

CallRequest:
{
  "id":3
 ,"procedure":"lookup"
 ,"arguments":[
    "alias"
   ,"reg_1"
  ]
}
CallResponse:
{
  "id":3
 ,"status":"ok"
 ,"result":"f8b185e2d6fea7434663ddca0961d7167f4654f5"
}

Write live datapoints

Procedure :: “write”
Arguments :: array
[ResourceID,Value,Options]
ResourceID :: string(40) | {“alias”:Alias}
Value :: number | string
Options :: object

Unused, set to an empty object.

JSON Example

CallRequest:
{
  "id":4
 ,"procedure":"write"
 ,"arguments":[
    "f8b185e2d6fea7434663ddca0961d7167f4654f5"
   ,6720
   ,{}
  ]
}
CallResponse:
{
  "id":4
 ,"status":"ok"
}

Record data points

Procedure :: “record”
Arguments :: array
[ResourceID,Entries,Options]
ResourceID :: string(40) | {“alias”:Alias}
Entries :: array
[[Timestamp,Value]]
Timestamp :: number

Unix seconds timestamp. If Timestamp is a negative value, it means an offset back into the past from the current time.

Value :: number | string
Options :: object

Unused, set to an empty object.

JSON Example

CallRequest:
{
  "id":4
 ,"procedure":"record"
 ,"arguments":[
    {"alias":"log"}
   ,[[1325784065, 22],[1325784084,25]]
   ,{}
  ]
}
CallResponse:
{
  "id":4
 ,"status":"ok"
}

Read datapoints

 

 

 
Procedure :: “read”
Arguments :: array
[ResourceID,Options]
ResourceID :: string(40) | {“alias”:Alias}
Options :: object
{
  "starttime":number
 ,"endtime":number
 ,"limit":number
 ,"sort":"asc" | "desc"
 ,"selection":"all" | "autowindow" | "givenwindow"
}

JSON Example

CallRequest:
{
  "id":4
 ,"procedure":"read"
 ,"arguments":[
    {"alias":"temperature"}
   ,{}
  ]
}
CallResponse:
{
  "id":4
 ,"status":"ok"
 ,"result":[[1325782540,76]]
}

Examples

Create a Dataport

Request

{
  "auth":{
    "cik":"d273a4025e702b32896aae1fdfc4ccca41841749"
  }
 ,"calls":[
    {
      "id":1
     ,"procedure":"create"
     ,"arguments":[
        "dataport"
       ,{
          "format":"float"
         ,"name":"Temperature C"
         ,"preprocess":[["div",100]]
        }
      ]
    }
   ,{
      "id":2
     ,"procedure":"create"
     ,"arguments":[
        "dataport"
       ,{
          "format":"float"
         ,"name":"Humidity"
         ,"preprocess":[["div",20]]
        }
      ]
    }
  ]
}

Response

[
  {
    "id":1
   ,"status":"ok"
   ,"result":"f8b185e2d6fea7434663ddca0961d7167f4654f5"
  }
 ,{
    "id":2
   ,"status":"ok"
   ,"result":"e7c5717be5e695a83179ecd7cfacf6c7e5a9e52f"
  }
]

Alias a Dataport

Request

{
  "auth":{
    "cik":"d273a4025e702b32896aae1fdfc4ccca41841749"
  }
 ,"calls":[
    {
      "id":1
     ,"procedure":"map"
     ,"arguments":[
        "alias"
       ,"f8b185e2d6fea7434663ddca0961d7167f4654f5"
       ,"reg_1"
      ]
    }
   ,{
      "id":2
     ,"procedure":"map"
     ,"arguments":[
        "alias"
       ,"e7c5717be5e695a83179ecd7cfacf6c7e5a9e52f"
       ,"reg_2"
      ]
    }
  ]
}

Response

[
  {
    "id":1
   ,"status":"ok"
  }
 ,{
    "id":2
   ,"status":"ok"
  }
]

Write to a Dataport

Request

{
  "auth":{
    "cik":"d273a4025e702b32896aae1fdfc4ccca41841749"
  }
 ,"calls":[
    {
      "procedure":"write"
     ,"arguments":[
        "f8b185e2d6fea7434663ddca0961d7167f4654f5"
       ,6720
       ,{}
      ]
    }
  ]
}

Response

No response, as no CallID was given in the CallRequest