Web of Things (WoT) Protocol Binding Templates

W3C Working Group Note

This version:
https://www.w3.org/TR/2018/NOTE-wot-binding-templates-20180405/
Latest published version:
https://www.w3.org/TR/wot-binding-templates/
Latest editor's draft:
https://w3c.github.io/wot-binding-templates/
Editor:
Michael Koster (Invited Expert)
Contributors:
In the GitHub repository
Repository:
We are on GitHub
File a bug

Abstract

W3C Web of Things enables applications to interact with and orchestrate connected Things at Web scale. The standardized abstract interaction model exposed by the WoT Thing Description enables applications to scale and evolve independently of the individual Things.

Many network-level protocols and standards for connected Things have already been developed, and have millions of devices deployed in the field today. These standards are converging on a common set of transport protocols and transfer layers, but each has peculiar content formats, payload schemas, and data types.

Despite using unique formats and data models, the high-level interactions exposed by most connected things can be modeled using the Property, Action, and Event interaction patterns of the WoT Thing Description.

Protocol Binding Templates enable a Thing Description to be adapted to the specific protocol usage across the different standards. This is done through additional descriptive vocabulary that is used in the Thing Description.

This document describes the initial set of design pattern and vocabulary extensions to the WoT Thing Description that make up the Protocol Binding Templates. It is expected over time that additional protocols will be accommodated by further extending the Binding Templates, adding new vocabulary and new design patterns.

Status of This Document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at https://www.w3.org/TR/.

Editor's note: The W3C WoT WG is asking for feedback

Please contribute to this draft using the GitHub Issue feature of the WoT Protocol Binding Templates repository. For feedback on security and privacy considerations, please use the WoT Security and Privacy Issues, as they are cross-cutting over all our documents.

This document was published by the Web of Things Working Group as an Editor's Draft. Comments regarding this document are welcome. Please send them to public-wot-wg@w3.org (subscribe, archives).

Publication as a Working Group Note does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

This document was produced by a group operating under the W3C Patent Policy.

This document is governed by the 1 February 2018 W3C Process Document.

1. Introduction

Protocol Binding Templates consist of reusable vocabulary and design pattern extensions to the WoT Thing Description format that enable an application client to interact, using a consistent interaction model, with Things that expose diverse protocols and protocol usage.

1.1 Protocol Adaptation

Protocol Binding Templates enable clients to adapt to the underlying protocol and network-facing API constructions. Once the base protocol (e.g., HTTP, CoAP, MQTT, etc.) is identified, the following adaptions specifiy the particular use within the given Platform.

Editor's note: Additional Protocol Bindings

This document contains examples of Protocol Bindings for HTTP, CoAP, and MQTT. Other prococols may be added, following the same design style, and using payload mappings that can be expressed as JSON compatible entities. Future extensions to other payload definition formats are also contemplated.

1.1.1 Protocol Methods and Options

Most protocols have a relatively small set of methods that define the message type, the semantic intention of the message. As a starting point, a superset of REST and PubSub can cover most standard communication patterns. Common methods are GET, PUT, POST, DELETE, PUBLISH, and SUBSCRIBE.

The protocol methods are mapped to the abstract WoT Interaction verbs readProperty, writeProperty, observeProperty, invokeAction, subscribeEvent, unsubscribeEvent.

Possible protocol options are also specified in the Protocol Binding. They are used to select transfer modes, to request notifications from observable resources, or otherwise extend the semantics of the protocol methods.

1.1.2 Media Types

Maximum use should be made of IANA-registered Media Types (e.g., application/json) in order to decouple applications from connected Things. Standard bridges and translations from proprietary formats to Web-friendly languages such as JSON and XML are part of the adaptation needed.

WoT Protocol Bindings depend on consistent use of Media Types for customization of the upper layers.

1.1.3 Payload Structure

Data serialized to a standard Media Type still remains in a structure specific to the Platform data model and needs to be understood by clients (cf. various types of JSON documents).

The data definition language of DataSchema elements, described in [TD], allows for describing arbitrary structures by nesting of arrays and objects. Constants and variable specifications may be intermixed.

1.1.4 Data Types and Value Constraints

Simple data types and value constraints are currently used in a layered and descriptive way in WoT Thing Description. Additional forms of constraints are available to help adapt to the underlying data types. A Platform-specific 8-bit unsigned integer, for instance, can be defined as Integer with a minimum of 0 and maximum of 255; the system-specific representation (e.g., exact number of bits) on server and client is not relevant for interoperability.

2. Protocol Binding Templates Overview

This section is non-normative.

This section describes the mechanisms of protocol binding templates with examples.

2.1 Data Schema

The DataSchema elements describe the payload structure and data items that are passed between client and server during interactions.

2.1.1 Payload Structure

Payload Structure is determined by the DataSchema elements. [TD] describes the use of the DataSchema keywords "schema", "inputSchema", and outputSchema in the examples contained in this document.

In addition to the example pattern in [TD] of an object with name/value constructs or simple arrays, Protocol Bindings for existing standards may require nested arrays and objects, and some constant values to be specified.

For example, a simple payload structure may use a map:

Example 1: Simple Payload Structure
{
  "level": 50,
  "time": 10
}

SenML might use the following construct:

Example 2: SenML Example
[
  {
    "bn": "/example/light/"
  },
  {
    "n": "level",
    "v": 50
  },
  {
    "n": "time",
    "v": 10
  }
]

A Batch Collection according to OCF may be structured like this:

Example 3: OCF Batch Example
[
  {
    "href": "/example/light/level",
    "rep": {
      "dimming": 50
    }
  },
  {
    "href": "/example/light/time",
    "rep": {
      "ramptime": 10
    }
  }
]

And an IPSO Smart Object on LWM2M might look like the following:

Example 4: IPSO/LWM2M Example
{
  "bn": "/3001/0/",
  "e": [
    {
      "n": "5044",
      "v": 0.5
    },
    {
      "n": "5002",
      "v": 10.0
    }
  ]
}

The Protocol Binding template for each of these payloads will be structured according to the desired payload structure.

For the Simple Payload in Example 1 above, the data schema element would be structured as follows:

Example 5: data Schema for Simple JSON Object Payload
{
  "schema": {
    "type": "object",
    "field": [
      {
        "name": "level",
        "@type": ["iot:LevelData],
        "schema": {
          "type": "integer",
          "minimum": 0,
          "maximum": 255
        }
      },
      {
        "name": "time",
        "@type": ["iot:TransitionTimeData"],
        "schema": {
          "type": "integer",
          "minimum": 0,
          "maximum": 65535
        }
      }
    ]
  }
}

For the SenML Payload in Example 2 above, the DataSchema element would be structured as follows:

Example 6: DataSchema for SenML Payload
{
  "schema": {
    "type": "array",
    "items": [
      {
        "type": "object",
        "field": [
          {
            "name": "bn",
            "schema": {
              "type": "string",
              "const": "example/light"
            }
          }
        ]
      },
      {
        "type": "object",
        "field": [
          {
            "name": "n",
            "schema": {
              "type": "string",
              "const": "level"
            }
          },
          {
            "name": "v",
            "@type": ["iot:LevelData"],
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 255
            }
          }
        ]
      },
      {
        "type": "object",
        "field": [
          {
            "name": "n",
            "schema": {
              "type": "string",
              "const": "time"
            }
          },
          {
            "name": "v",
            "@type": ["iot:TransitionTimeData"],
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 65535
            }
          }
        ]
      ]
    }
  }
}

For the OCF Batch Payload in Example 3 above, the DataSchema element would be structured as follows:

Example 7: DataSchema for OCF Batch Payload
{
  "schema": {
    "type": "array",
    "items": [
      {
        "type": "object",
        "field": [
          {
            "name": "href",
            "schema": {
              "type": "string",
              "const": "/light/level"
            }
          },
          {
            "name": "rep",
            "type": "object",
            "field": [
              {
                "name": "dimming",
                "@type": ["iot:LevelData"],
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 255
                }
              }
            ]
          }
        ]
      },
      {
        "type": "object",
        "field": [
          {
            "name": "href",
            "schema": {
              "type": "string",
              "const": "/light/time"
            }
          },
          {
            "name": "rep",
            "schema": {
              "type": "object",
              "field": [
                {
                  "name": "ramptime",
                  "@type": ["iot:TransitionTimeData"],
                  "schema": {
                    "type":"integer",
                    "minimum": 0,
                    "maximum": 65535
                  }
                }
              ]
            }
          }
        ]
      ]
    }
  }
}

For the IPSO/LWM2M Payload in Example 4 above, the DataSchema element would be structured as follows:

Example 8: DataSchema for IPSO/LWM2M Payload
{
  "schema": {
    "type": "object",
    "field": [
      {
        "name": "bn",
        "schema": {
          "type": "string",
          "const": "/3001/0/"
        }
      },
      {
        "name": "e",
        "type": "array",
        "items": [
          {
            "type": "object",
            "field": [
              {
                "name": "n",
                "schema": {
                  "type": "string",
                  "const": "5044"
                }
              },
              {
                "name": "v",
                "@type": ["iot:LevelData"],
                "schema": {
                  "type": "number",
                  "minimum": 0.0,
                  "maximum": 1.0
                }
              }
            ]
          },
          {
            "type": "object",
            "field": [
              {
                "name": "n",
                "schema": {
                  "type": "string",
                  "const": "5002"
                }
              },
              {
                "name": "v",
                "@type": ["iot:TransitionTimeData"],
                "schema": {
                  "type": "number",
                  "minimum": 0.0,
                  "maximum": 6553.5
                }
              }
            ]
          ]
        }
      }
    ]
  }
}

2.1.2 Data Types and value constraints

Note that in Example 5 above, the values are floating point while the other examples have integer values. It is up to the client to adapt to the range and type as well as the engineering units provided.

2.2 Form Element

The "form" element contains the URI pointing to an instance of the interaction and descriptions of the protocol settings and options expected to be used when between the client and server for the interaction.

2.2.1 Relation Types

Form Relation Types describe the expected result of performing the operation described by the form.

For example, the Property interaction allows read and write operations. The protocol binding may contain a form for the read operation and a different form for the write operation. The value of the "rel" attribute of the form indicates which form is which and allows the client to select the correct form for the operation required.

Example 9: Form Relation Types
"rel": "readProperty"
"rel": "writeProperty"

The vocabulary in section 5 lists the recommended set of form relations, and the full TD examples in section 6 contain example uses of form relation types.

2.2.2 Media Types

Media Types define the serialization details and other rules for processing the payloads. The media type is used to select a serializer/deserializer and to select an additional set of rules and constraints for the protocol driver.

For example, the mediaType "application/ocf+cbor" indicates that CBOR serialization is used, but also that OCF rules and namespaces apply to the processing of the representations.

Additionally, there may be a profile which points to a URI for further description, for example a form with profile=http://iotschema.org/protocols/ipso.jsonld indicates that the target representation follows a set of additional encoding rules and constraints which are further defined at the URI by the profile attribute's value.

Some special protocol drivers may be invoked by using a non-registered media type e.g. x-<echonet> along with a custom URI scheme and its own set of protocol methods and options defined for that URI scheme.

2.2.3 Protocol Methods and Options

Each target protocol may specify different method names for similar methods, and there may be semantic differences between similar methods of different protocols. Additionally, will use different methods for mapping to a particular WoT Interaction type. For example, POST may be used for setting a property value in one protocol, while PUT may be used in another. For these reasons, we require the ability to specify which method to use for a particular interaction. We also will provide vocabulary to differentiate between methods of different protocols.

The W3C RDF vocabulary for HTTP [ref] is used to identify the methods and options specified in the HTTP protocol bindings.

For the sake of consistency, we will use the same ontology design pattern to derive a vocabulary for each target protocol, e.g. CoAP, MQTT.

The example below shows some method definitions for various protocols.

Example 10: Vocabulary Example for Methods
"http:methodName": "GET"

"mqtt:commandCode": 8

"coap:methodCode": 1

Header options in HTTP, CoAP, MQTT sometimes must be included in a protocol binding in order to successfully interact with the underlying protocol. The example below shows the structure of the definition for http header options, according to the W3C HTTP Vocabulary in RDF.

Example 11: HTTP Vocabulary Example for Header Options
"http:headers":
  [
    {
      "http:fieldName": "Accept",
      "http:fieldValue": "application/json"
    },
    {
      "http:fieldName": "Transfer-Encoding",
      "http:fieldValue": "chunked"
    }
  ]

Note: different forms in a binding may need different header constructions, therefore the headers construct is an extension of the TD "form" element.

Protocols may have defined sub-protocols that can be used for some interaction types. For example, to recieve asynchronous notifications using http, some servers may support long polling, EventSource, or a simple non-multiplexed websocket protocol. The "subProtocol" item may be defined in a form instance to indicate the use of one of these protocols, for example:

Example 12: subProtocol
{
"subProtocol": "LongPoll"
}

2.3 Interaction Types

This section is non-normative.

This section describes unique aspects of protocol bindings for the three WoT interaction types.

2.3.1 Bindings for Properties

This section describes unique aspects of protocol bindings for WoT Property type interactions.

The abstract methods exposed for the Property Interaction are readProperty, writeProperty, and observeProperty. These are mapped by using form relations that describe the abstract method, resulting in a semantic interpretation similar to HTML form submission.

Example 13: Example use of form relation for Property
  For example a form having href=/example/level, rel=writeProperty, and
  http:methodName=POST conveys the statement:


  To do a writeProperty of the subject Property (context of the form),
  perform a POST on the resource at the target URI /example/level.

Properties may be observable, defined by the TD keyword "observable". If there is an observe form and a retrieve form, the observe form may be indicated by including rel=observeProperty in the form. The observe form may also specify header options to use, for example CoAP observe option=0 in the header to start observation.

2.3.2 Bindings for Actions

This section is non-normative.

This section describes unique aspects of protocol bindings for WoT Action type interactions.

The abstract method on Actions is invokeAction. In the same way that the abstract methods on properties are mapped using form relations, the abstract methods of actions are also mapped.

Example 14: Example use of form relation for Action
  For example a form with href=/example/levelaction, rel=invokeAction,
  and http:methodName=POST conveys the statement:


  To do an invokeAction of the subject Action (context of the form),
  perform a POST on the resource at /example/levelaction.

2.3.3 Bindings for Events

This section is non-normative.

This section describes unique aspects of protocol bindings for WoT Event type interactions.

The abstract methods on Events are subscribeEvent and unsubscribeEvent. The subscribeEvent operation returns a location or resource URI from which events may be obtained, either by observation or some other method, depending on the transfer protocol.

The binding for Events allows pre-defined URIs to observable resources, or pubsub topica encoded in URI.

If the binding offers a subscription, there will be a form with rel=subscribeEvent

If the binding offers an observable Event resource from which events are obtained, there will be a form which describes the required transfer layer operation, for example CoAP Observe or HTTP Long Polling.

Example 15: Example use of form relation for Events
  For example, a form having href=mqtt://0m2m.net/example/levelevent,
  rel=subscribeEvent,
  and mqtt:methodCode=8 conveys the statement:


  To do a subscribeEvent of the subject Event (context of the form),
  perform an MQTT SUBSCRIBE (code 8) on the topic /example/levelevent
  on the broker at mqtt://0m2m.net using the default MQTT port.

2.4 Processing Model and Runtime

This section is non-normative.

This section describes the processing model for Protocol Bindings with respect to the abstract WoT Interactions provided by the Scripting API.

DataSchema elements (see Section 2.1) are processed, and value scaling is performed, in the application library or adaptation layer.

Form elements that specify href, method, options, and mediaType are processed in a driver context which is isolated from the application.

The application, or a protocol adaptation layer, constructs an instance of the appropriate DataSchema element and sends it along with the selected form contents to the protocol driver or, in the case of get, receives a payload form the protocol driver and uses the appropriate DataSchema element to extract the field values of interest.

The separation of execution context between the application and the protocol driver enables isolation of fault domains and isolation of security domains.

Editor's note: Multiple Security Bindings

Additional information in the Thing Description may be considered part of the Protocol Binding, relating to security protocols. There is currently a single declaration of security bindings for each TD instance, with no defined way to indicate a different security protocol for each form element, which may specify a different transfer protocol.

Protocol Bindings may be used by proxies, where a Consumed Thing has its Protocol Binding, and the corresponding Exposed Thing may have a different Protocol Binding.

3. Vocabulary

This section is non-normative.

This section specifies the vocabulary for protocol binding templates

3.1 DataSchema Vocabulary

DataSchema elements describe the structure of the payload. The DataSchema vocabulary is described in [TD]. Properties and Events define a "schema" for data transfer in either direction. Actions may define "inputSchema" for actuation data being sent to the resource using, for example, POST or PUT, and "outputSchema" for result or status data being returned from the Action resource.

3.2 Interaction Verbs

Interactions have one or more defined interaction verbs for each interaction pattern. Form Relations allow an interaction to have separate protocol mechanisms to support different interaction verbs.

3.2.1 Property Interactions

Properties provide '"read" and, optionally, "write" operations, which map to GET and PUT/POST of a REST API. Properties may also by observed, though some properties may not be observable.

readProperty

writeProperty

observeProperty

3.2.2 Action Interactions

Actions provide '"invoke" operations, which can map to PUT, POST, or PUBLISH operations.

invokeAction

3.2.3 Event Interactions

Events may directly expose observable resources from which to obtain event instances.

subscribeEvent

unsubscribeEvent

3.3 Form Vocabulary

Extensions to the form vocabulary provide a way to inform the client about protocol methods, options, and status codes.

3.3.1 HTTP form vocabulary

http:methodName [ "GET", "PUT", "POST", "DELETE"]

http:headers example: [ {"http:fieldName": "accept", "http:fieldValue": "text/plain"} ]

http:fieldName [ accept, content-type, transfer-encoding ]

http:fieldValue

3.3.2 CoAP form vocabulary

coap:methodCode [ 1, 2, 3, 4 ]

coap:options example: [ { "coap:optionCode": 6, "coap:optionValue": 49 } ]

coap:optionCode [ 0..65535 ]

coap:optionValue [ any type ]

3.3.3 MQTT form vocabulary

mqtt:commandCode [ 3, 8, 10 ]

mqtt:options example: [ { "mqtt:optionName": "qos", "mqtt:optionValue": 1 }]

mqtt:optionName [ qos, retain ]

mqtt:optionValue (qos) [ 0, 1, 2, 3 ] mqtt:optionValue (retain) [ 0, 1 ]

3.3.4 subProtocol form vocabulary

subProtocol [ "LongPoll", "EventSource" ]

subProtocol values for websockets are registered by IANA: Websocket Subprotocols

4. Examples of Thing Descriptions including protocol bindings

This section is non-normative.

TD with simple payload format

Example 16: TD with a simple Payload
{
  "@context": [
    "https://w3c.github.io/wot/w3c-wot-td-context.jsonld",
    "https://w3c.github.io/wot/w3c-wot-common-context.jsonld",
	  {
      "iot": "http://iotschema.org/",
      "http": "http://iotschema.org/protocol/http",
      "coap": "http://iotschema.org/protocol/coap",
      "mqtt": "http://iotschema.org/protocol/mqtt"
    }
  ],
  "@type": [ "Thing", "iot:Light", "iot:LevelCapability", "iot:BinarySwitch" ],
  "base": "http://example.com",
  "name": "Lamp",
  "interaction": [
    {
      "name": "Switch State",
      "@type": ["Property", "iot:SwitchStatus"],
      "schema":  {
        "@type": ["iot:SwitchData"],
        "type": "boolean"
      },
      "writable": false,
      "observable": false,
      "form": [
        {
          "href": "/example/light/currentswitch",
          "rel": ["readProperty", "writeProperty"],
          "mediaType": "application/json"
        }
      ]
    },
    {
      "name": "Current brightness",
      "@type": ["Property", "iot:CurrentLevel"],
      "schema":  {
        "@type": ["iot:LevelData"],
        "type": "number"
      },
      "writable": false,
      "observable": false,
      "form": [
        {
          "href": "/example/light/currentdimmer",
          "rel": ["readProperty", "writeProperty"],
          "mediaType": "application/json"
        }
      ]
    },
    {
      "name": "Switch On",
      "@type": ["Action", "iot:SwitchOn"],
      "inputSchema":  {
        "type": "boolean",
        "const": true
      },
      "form": [
        {
          "href": "/example/light/currentswitch",
          "rel": ["invokeAction"],
          "mediaType": "application/json"
        }
      ]
    },
    {
      "name": "Switch Off",
      "@type": ["Action", "iot:SwitchOff"],
      "inputSchema":  {
        "type": "boolean",
        "const": false
      },
      "form": [
        {
          "href": "/example/light/currentswitch",
          "rel": ["invokeAction"],
          "mediaType": "application/json"
        }
      ]
    },
    {
      "name": "Set brightness level",
      "@type": ["Action", "iot:SetLevel"],
      "inputSchema":  {
        "@type": ["iot:LevelData"],
        "type": "number"
      },
      "form": [
        {
          "href": "/example/light/currentdimmer",
          "rel": ["invokeAction"],
          "mediaType": "application/json"
        }
      ]
    }
  ]
}

TD with complex payload and multiple protocol options

Example 17: TD with protocol options and complex payload
{
  "@context": [
    "https://w3c.github.io/wot/w3c-wot-td-context.jsonld",
    "https://w3c.github.io/wot/w3c-wot-common-context.jsonld",
    {
      "iot": "http://iotschema.org/",
      "http": "http://iotschema.org/protocol/http",
      "coap": "http://iotschema.org/protocol/coap",
      "mqtt": "http://iotschema.org/protocol/mqtt"
    }
  ],
  "base": "http://example.com/",
  "@type": [ "Thing", "iot:Light", "iot:LevelCapability", "iot:BinarySwitch" ],
  "name": "Lamp",
  "interaction": [
    {
      "name": "Switch State",
      "@type": ["Property", "iot:SwitchStatus"],
      "schema":  {
        "type": "object",
        "field": [
          {
            "name": "switch",
            "@type": ["iot:SwitchData"],
            "schema": {
              "type": "boolean"
            }
          }
        ]
      },
      "writable": true,
      "observable": true,
      "form": [
        {
          "href": "/example/light/currentswitch",
          "mediaType": "application/json",
          "rel": ["readProperty"],
          "http:methodName": "GET"
        },
        {
          "href": "/example/light/currentswitch",
          "mediaType": "application/json",
          "rel": ["writeProperty"],
          "http:methodName": "POST"
        },
        {
          "href": "mqtt://example.com/example/light/currentswitch",
          "rel": ["observeProperty"],
          "mqtt:commandCode": 8
        }
      ]
    },
    {
      "name": "Current brightness",
      "@type": ["Property", "iot:CurrentLevel"],
      "schema": {
        "type": "object",
        "field": [
          {
            "name": "brightness",
            "@type": ["iot:LevelData" ],
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 255
            }
          }
        ]
      },
      "writable": true,
      "observable": true,
      "form": [
        {
          "href": "/example/light/currentdimmer",
          "mediaType": "application/json",
          "rel": ["readProperty"],
          "http:methodName": "GET"
        },
        {
          "href": "/example/light/currentdimmer",
          "mediaType": "application/json",
          "rel": ["writeProperty"],
          "http:methodName": "POST"
        },
        {
          "href": "mqtt://example.com/example/light/currentdimmer",
          "rel": ["observeProperty"],
          "mqtt:commandCode": 8
        }
      ]
    },
    {
      "name": "Transition Time",
      "@type": ["Property", "iot:TransitionTime"],
      "schema": {
        "type": "object",
        "field": [
          {
            "name": "transitiontime",
            "@type": ["iot:TransitionTimeData" ],
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 255
            }
          }
        ]
      },
      "writable": true,
      "observable": false,
      "form": [
        {
          "href": "/example/light/transitiontime",
          "mediaType": "application/json",
          "rel": ["readProperty"],
          "http:methodName": "GET"
        },
        {
          "href": "/example/light/transitiontime",
          "mediaType": "application/json",
          "rel": ["writeProperty"],
          "http:methodName": "POST"
        }
      ]
    },
    {
      "name": "Switch On",
      "@type": ["Action", "iot:SwitchOn"],
      "inputSchema":  {
        "type": "object",
        "field": [
          {
            "name": "switch",
            "schema":{
              "type": "boolean",
              "const": true
            }
          }
        ]
      },
      "form": [
        {
          "href": "/example/light/currentswitch",
          "mediaType": "application/json",
          "rel": ["invokeAction"],
          "http:methodName": "POST"
        }
      ]
    },
    {
      "name": "Switch Off",
      "@type": ["Action", "iot:SwitchOff"],
      "inputSchema":  {
        "type": "object",
        "field": [
          {
            "name": "switch",
            "schema": {
              "type": "boolean",
              "const": false
            }
          }
        ]
      },
      "form": [
        {
          "href": "/example/light/currentswitch",
          "mediaType": "application/json",
          "rel": ["invokeAction"],
          "http:methodName": "POST"
        }
      ]
    },
    {
      "name": "Set brightness level",
      "@type": ["Action", "iot:SetLevel"],
      "inputSchema": {
        "type": "object",
        "field": [
          {
            "name": "brightness",
            "@type": ["iot:LevelData"],
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 255
            }
          },
          {
            "name": "transitiontime",
            "@type": ["iot:TransitionTimeData"],
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 65535
            }
          }
        ]
      },
      "form": [
        {
          "href": "/example/light/",
          "mediaType": "application/json",
          "rel": ["invokeAction"],
          "http:methodName": "POST"
        }
      ]
    }
  ]
}

5. References

This section is non-normative.

IANA link relations

"profile" relation

A media type defines both the semantics and the serialization of a specific type of content. In many cases, media types have some built-in extensibility or openness, so that specific instances of the media type can layer additional semantics on top of the media type's foundation. In this case, a profile is the appropriate mechanism to signal that the original semantics and processing model of the media type still apply, but that an additional processing model can be used to extract additional semantics.

HTTP vocabulary

IANA Registry for Websocket Subprotocols

6. Security and Privacy Considerations

Editor's note

Security and privacy considerations are still under discussion and development; the content below should be considered preliminary. Due to the complexity of the subject we are considering producing a separate document containing a detailed security and privacy considerations discussion including a risk analysis, threat model, recommended mitigations, and appropriate references to best practices. A summary will be included here. Work in progress is located in the WoT Security and Privacy repository. Please file any security or privacy considerations and/or concerns using the GitHub Issue feature.

Security is a cross-cutting issue that needs to be taken into account in all WoT building blocks. The W3C WoT does not define any new security mechanisms, but provides guidelines to apply the best practices from Web security, IoT security, and information security for general software and hardware considerations.

The WoT Thing Description must be used together with integrity protection mechanisms and access control policies. Users must ensure that no sensitive information is included in the TDs themselves.

The WoT Binding Templates must correctly cover the security mechanisms employed by the underlying IoT Platform. Due to the automation of network interactions necessary in the IoT, operators need to ensure that Things are exposed and consumed in a way that is compliant with their security policies.

The WoT Runtime implementation for the WoT Scripting API must have mechanisms to prevent malicious access to the system and isolate scripts in multi-tenant Servients.

A. Acknowledgements

Special thanks to all active Participants of the W3C Web of Things Interest Group and Working Group for their technical input and suggestions that led to improvements to this document.