WebThingsIO / api

Web Thing API Specification
http://iot.mozilla.org/wot/
Other
164 stars 25 forks source link

Define action arguments and event payloads - closes #17 #80

Closed benfrancis closed 6 years ago

benfrancis commented 6 years ago

This pull request defines a system for providing arguments for actions and defining payload data for events. It is based on the latest experimental simplified TD proposal from Siemens and should be backwards compatible because we hadn't defined this yet.

A difference with the JSON-TD proposal is that rather than define multiple arguments for an action using a "data" object with a key-value pair for each argument, a single "input" field is provided which specifies a single value as a JSON schema. That value could be a primitive type like a "number" or "boolean", or it could be an "object" with nested "properties" in order to support multiple arguments. This approach allows re-using a lot of JSON Schema to define action argument types, aligned with a system to also define types for properties and sub-properties of Things using JSON Schema, and types for event payloads (see below). Defining an "input" field allows defining an "output" field as well in future.

"fade": {
  "description": "Fade the lamp to a given level",
  "input": {
    "type": "object",
    "properties": {
      "level": {
        "type: number",
        "minimum": 0,
        "maximum": 100
      },
      "duration": {
        "type": "number",
        "unit": "milliseconds",
      }
    }
  },
  "href": "/things/lamp/actions/fade"
}

This then maps onto an action request in the REST API by adding an "input" field to the action request.

POST https://mythingserver.com/things/lamp/actions/
Accept: application/json

{
  "fade": {
    "input": {
      "level": 50,
      "duration": 2000
    }
  }
}

Events, like properties, have a top level type which is defined by a JSON Schema (as opposed to an input and output like actions). That type can be a primitive type like a "number" or "boolean" or it can be an object, with multiple nested "properties".

Example with primitive type:

"overheated": {
  "type": "number",
  "unit": "celcius",
  "description": "The lamp has exceeded its safe operating temperature",
  "href": "/things/lamp/events/overheated"
}

Example with object:

"overheated": {
  "type": "object"
  "properties": {
    "temperature": {
      "type": "number",
      "unit": "celcius"
    } 
  }
  "description": "The lamp has exceeded its safe operating temperature",
  "href": "/things/lamp/events/overheated"
}

The events resource in the REST API includes the payload "data" for each event instance as per the type defined in the Thing Description. This part is maybe a little bit clunky because the term "data" is not defined in the Thing Description for events, whereas "input" is defined for actions. Does that matter? Should it be called "data" or something else like "detail" (often used in JavaScript events).

Example with primitive type:

[
  {
    "overheated": {
      "data": 102,
      "timestamp": "2017-01-25T15:01:35+00:00"
    }
  }
]

Example with object:

[
  {
    "overheated": {
      "data": {
        "temperature": 102
      },
      "timestamp": "2017-01-25T15:01:35+00:00"
    }
  }
]

I've also changed some of the examples to better illustrate these new features.

benfrancis commented 6 years ago

HTML view https://rawgit.com/benfrancis/wot/b5b7565ec8ca3015ade1ae1ddca2ce9006a3c34a/index.html

benfrancis commented 6 years ago

Addressed review comments.