Copyright © 2017-2020 W3C® (MIT, ERCIM, Keio, Beihang). W3C liability, trademark and permissive document license rules apply.
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 affordances of the WoT Thing Description.
Binding Templates enable a Thing Description to be adapted to the specific protocol or data payload 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 vocabulary extensions to the WoT Thing Description that make up the Binding Templates. It is expected over time that additional protocols and payload structures will be accommodated by further extending the Binding Templates.
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/.
Please contribute to this draft using the GitHub Issue feature of the WoT 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 a Working Group Note.
Comments regarding this document are welcome. Please send them to public-wot-wg@w3.org (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 March 2019 W3C Process Document.
Binding Templates consist of reusable vocabulary and extensions to the WoT Thing Description[WOT-THING-DESCRIPTION] format that enable an application client (a Consumer) to interact, using a consistent interaction model, with Things that expose diverse protocols and protocol usage.
Binding Templates enable Consumers to adapt to the underlying protocol and network-facing API constructions. Once the base protocol (e.g., HTTP[RFC7231], CoAP[RFC7252], MQTT[MQTT], etc.) is identified, the following adaptions specify the particular use within the given platform.
This document contains examples of Protocol Bindings for HTTP, CoAP, and MQTT. Other protocols 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.
Most protocols have a relatively small set of methods that define the message type, the semantic intention of the message. REST and PubSub architecture patterns result in different protocols with different methods. Common methods found in these protocols are GET, PUT, POST, DELETE, PUBLISH, and SUBSCRIBE. Binding Templates describe how these existing methods and vocabularies can be described in a Thing Description.
This is done by mapping the protocol methods to the
abstract WoT Interaction Affordance terms
readproperty
, writeproperty
,
observeproperty
, unobserveproperty
,
invokeaction
, subscribeevent
,
unsubscribeevent
,
readallproperties
,
writeallproperties
,
readmultipleproperties
,
writemultipleproperties
.
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.
Maximum use should be made of IANA-registered Media Types
[IANA-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.
Correct indication of Media Types enables proper processing of the serialized documents. This way, the documents can be exchanged in any format and allow the upper layers of an application to adapt to different formats.
Data serialized to a standard Media Type still remains in a structure specific to the platform data model and needs to be understood by Consumers (cf. various types of JSON documents).
The data definition language of DataSchema
elements, described in [WOT-THING-DESCRIPTION],
allows for describing arbitrary structures by nesting of
arrays and objects. Constants and variable specifications may
be intermixed.
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 the Thing and the Consumer is not relevant for interoperability.
As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
The key words MUST, MUST NOT, SHOULD, and SHOULD NOT in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.
This section is non-normative.
The fundamental WoT terminology such as Thing, Consumer, Thing Description (TD), Interaction Model, Interaction Affordance, Property, Action, Event, Protocol Binding, Servient, WoT Interface, WoT Runtime, etc. is defined in Section 3 of the WoT Architecture specification [WOT-ARCHITECTURE].
In addition, this specification introduces the following definitions:
@context
as specified in
JSON-LD[json-ld11]. It is the basis for
semantic annotations and extensions to core mechanisms such
as Protocol Bindings, Security Schemes, and Data Schemas.
This section is non-normative.
This section describes the mechanisms of binding templates with examples.
A data schema describes the payload structure and included data items that are passed between the Consumer and the Thing during interactions.
Payload Structure is determined by
DataSchema
elements of a Thing Description.
DataSchema elements should be used by an instance of a
PropertyAffordance
,
input
/output
of
ActionAffordance
,
data
/subscription
/cancellation
of an EventAffordance
or by a
uriVariable
of the
InteractionAffordance
. As indicated in the
[WOT-THING-DESCRIPTION],
DataSchema
Vocabulary is a subset of JSON
Schema [json-schema]
In the case of Action Affordances, the additional
keywords input
and output
are
used to provide two different schemas when data might be
exchanged in both directions, such as in the case of
invoking an Action Affordance with input parameters and
receiving status information.
In the case of Event Affordances, the additional
keywords data
, subscription
and
cancellation
are used to describe the payload
when the event data is delivered by the Exposed Thing, the
payload needed to subscribe to the event and the payload
needed to cancel receiving event data from the Exposed
Thing, respectively.
In addition to the example pattern in [WOT-THING-DESCRIPTION] 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.
Below are examples of different payloads and their
corresponding DataSchema
.
For example, a simple payload structure may use a map:
Example
1:
Simple JSON Object Payload
|
Example 2: DataSchema for Simple JSON
Object Payload
|
SenML might use the following construct:
Example
3:
SenML Example
|
Example
4:
DataSchema for SenML Payload
|
A Batch Collection according to OCF may be structured like this:
Example
5:
OCF Batch Example
|
Example
6:
DataSchema for OCF Batch Payload
|
And an IPSO Smart Object on LWM2M might look like the following:
Example
7:
IPSO/LWM2M Example
|
Example
8:
DataSchema for IPSO/LWM2M Payload
|
Note that in Example 7 above, the values are floating
point (double
) while the other examples have
integer values. In general, Consumers should follow the
data schemas strictly, not generating anything not given in
the WoT Thing Description, but should accept additional
data from the Thing not given explicitly in the WoT Thing
Description. This means that a Consumer sending the payload
of the Example 7 should use floating points in the
payload.
id
(of type
integer
) and name
(of type
string
) where id
is required to
be present.
{
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
},
"required": [
"id"
]
}
object
is anonymous (i.e. it
is the root, or participates in an array
definition), the above object
definition
transforms to the following XML Schema element
definition.
<xs:element name="object" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType>
<xs:all>
<xs:element name="id">
<xs:complexType>
<xs:sequence>
<xs:element name="integer" type="xs:integer" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="name" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="string" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
object
is a member
of another object
definition, thus has a
name), the object definition transforms to the following
XML schema element definition. Note $name
represents the name of the object
, and needs
to be replaced by the actual name of the
object
.
<xs:element name="$name" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType>
<xs:sequence>
<!--Until the next comment, it is a copy of the previous example-->
<xs:element name="object">
<xs:complexType>
<xs:all>
<xs:element name="id">
<xs:complexType>
<xs:sequence>
<xs:element name="integer" type="xs:integer" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="name" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="string" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
<!--Until here-->
</xs:sequence>
</xs:complexType>
</xs:element>
array
consists of exactly three number
literals with each value within the value range of [ 0
... 2047 ].
{
"type": "array",
"items": {
"type": "number",
"minimum": 0,
"maximum": 2047
},
"minItems": 3,
"maxItems": 3
}
array
is anonymous (i.e. it
is the root, or participates in another
array
definition), the above
array
definition transforms to the following
XML Schema element definition.
<xs:element name="array" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType>
<xs:sequence>
<xs:element name="double" minOccurs="3" maxOccurs="3">
<xs:simpleType name="minInclusive">
<xs:restriction base="xs:double">
<xs:minInclusive value="0"/>
<xs:maxInclusive value="2047"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
array
is a member
of an object
definition, thus has a name),
the array
definition transforms to the
following XML schema element definition. Note
$name
represents the name of the
array
, and needs to be replaced by the
actual name of the array
.
<xs:element name="$name" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType>
<xs:sequence>
<!--Until the next comment, it is a copy of the previous example-->
<xs:element name="array">
<xs:complexType>
<xs:sequence>
<xs:element name="double" minOccurs="3" maxOccurs="3" >
<xs:simpleType name="minInclusive">
<xs:restriction base="xs:double">
<xs:minInclusive value="0"/>
<xs:maxInclusive value="2047"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<!--Until here-->
</xs:sequence>
</xs:complexType>
</xs:element>
The form elements contain the URI [RFC3986] pointing to an instance of the interaction and descriptions of the protocol settings and options expected to be used when between the Consumer and the Thing for the interaction.
Form Operation Types describe the intended semantics 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 op
attribute of
the form indicates which form is which and allows the
Consumer to select the correct form for the operation
required.
"op": "readproperty"
"op": "writeproperty"
The vocabulary in section 4 lists the recommended set of form operations, and the full TD examples in section 5 contain example uses of form operations types.
Content Types define the serialization details and other rules for processing the payloads. The content type is used to select a serializer/deserializer and to select an additional set of rules and constraints for the protocol driver. Content type includes the media type and potential parameters for the media type.
For example, the media type
application/ocf+cbor
indicates that CBOR
serialization is used, but also that OCF rules and
namespaces apply to the processing of the
representations.
Some special protocol drivers may be invoked by using a
non-registered media type (e.g.,
x-<echonet>
) along with a custom URI
Scheme [RFC3986]
and its own set of protocol methods and options defined for
that URI Scheme.
When the media type is application/xml
(or
its binary representation application/exi
) and
there is a Data Schema provided for the payload, the
payloads are constrained by a XML Schema derived from the
Data Schema. See § 3.1.3 XML Schema
Binding Schema Binding for how to derive a XML Schema
from a Data Schema definition.
Below are some examples of payloads in JSON and their corresponding equivalent payloads in XML.
{
"brightness": 200,
"frequency": "fast"
}
<object>
<id>
<integer>200</integer>
</id>
<frequency>
<string>fast</string>
</frequency>
</object>
[
520,
184,
1314
]
<array>
<number>520</number>
<number>184</number>
<number>1314</number>
</array>
Each target protocol may specify different method names for similar operations, and there may be semantic differences between similar method names of different protocols. Additionally, platforms may use different methods for realizing a particular WoT Interaction Affordance. For example, POST may be used for writing a Property value in one platform, 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 [HTTP-in-RDF10] 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.
"htv:methodName": "GET"
"mqv:controlPacketValue": "SUBSCRIBE"
"cov:methodName": "GET"
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.
"htv:headers":
[
{
"htv:fieldName": "Accept",
"htv:fieldValue": "application/json"
},
{
"htv:fieldName": "Transfer-Encoding",
"htv:fieldValue": "chunked"
}
]
Note: different forms in a binding may need different
header constructions, therefore the
htv: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 receive
asynchronous notifications using HTTP, some servers may
support long polling (longpoll
), WebSub
[WebSub]
(websub
) and Server-Sent Events
[html] (also know as EventSource;
sse
). The subprotocol
item may
be defined in a form instance to indicate the use of one of
these protocols, for example long polling with its special
use of HTTP:
{
"op": "subscribeevent",
"href": "https://mylamp.example.com/overheating",
"subprotocol": "longpoll"
}
When Interaction Affordances require dynamic variables
in the href
, they can be described using
uriVariables
in the Data Schema of the
interaction. For example, p
and d
in http://192.168.1.25/left?p=2&d=1
can be
described with a template as defined in [RFC6570] ]:
http://192.168.1.25/left{?p,d}
.
In such a case, the URI Template variables MUST be collected in the
JSON-object based uriVariables
member with the
associated (unique) variable names as JSON names.
The serialization of each value in the map assigned to
uriVariables
in an instance of
Form
MUST rely on the DataSchema as explained in
§
3.1 Data Schema.
An action affordance snippet using a URI Template and
uriVariables
is given below:
...
"actions": {
"LeftDown": {
...
"uriVariables": {
"p" : { "type": "integer", "minimum": 0, "maximum": 16 },
"d" : { "type": "integer", "minimum": 0, "maximum": 1 }
},
"forms": [{
"href" : "http://192.168.1.25/left{?p,d}",
"htv:methodName": "GET"
}]
},
...
},
...
This section is non-normative.
This section describes unique aspects of protocol bindings for the three WoT Interaction Affordances.
This section describes unique aspects of protocol bindings for WoT Property interactions.
The abstract operations exposed for the Property
Interaction are readproperty
,
writeproperty
, observeproperty
and unobserveproperty
. These are mapped by
using form operations that describe how the abstract
operation is performed, resulting in a semantic
interpretation similar to HTML form submission.
Additionally, the abstract operations exposed for
multiple Property Interactions are
readallproperties
,
writeallproperties
,
readmultipleproperties
and
writemultipleproperties
.
{
"op": "writeproperty",
"href": "/example/level",
"htv:methodName": "POST"
}
The form element in the example above conveys the
statement: "To do a writeproperty
of the
subject Property (context of the form), perform an
HTTP 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
op=observeproperty
in the form. The observe
form may also specify header options to use, as specified
in Observing in CoAP[RFC7641]for
example setting the CoAP Observe option to 0
in the header, starts observation.
This section is non-normative.
This section describes unique aspects of protocol bindings for Actions.
The abstract operation on Actions is
invokeaction
. In the same way that the
abstract operations on Properties are mapped using form
operation types, the abstract operation of Actions is also
mapped.
{
"op": "invokeaction",
"href": "/example/levelaction",
"http:methodName": "POST"
}
The form element in the example above conveys the
statement: "To do an invokeaction
of the
subject Action (context of the form), perform a
POST
on the resource at the target URI
/example/levelaction
."
This section is non-normative.
This section describes unique aspects of protocol bindings for WoT Event Interaction Affordances.
The abstract operations on Events are
subscribeevent
and
unsubscribeevent
. The
subscribeevent
operation may directly enable
event instance delivery from the pre-defined URI to
observable resources or pubsub topics encoded in URIs.
Alternatively, it may return a location or resource URI
from which event instance may be obtained, either by
observation or some other mechanism, depending on the
transfer protocol.
Usually, the unsubscribeevent
only occurs
when the transfer protocol has no implicit unsubscribe
operation such as closing the connection. Examples are
Webhooks that require particular unsubscribe requests.
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.
{
"op": "subscribeevent",
"href": "mqtt://wot.example.com/levelevent",
"mqv:controlPacketValue": "SUBSCRIBE"
}
The form element in the example above conveys the
statement: "To do an subscribeevent
of the
subject Event (context of the form), perform an MQTT
SUBSCRIBE
on the topic /levelevent
on
the broker at wot.example.com
using the
default MQTT port."
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 § 3.1 Data Schema ) are processed, and value
scaling is performed, in the application library or
adaptation layer.
Form elements that specify href, method, options, and contentType 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.
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.
This section summarizes the vocabulary used for Binding Templates. The vocabulary is defined in other documents, in particular the WoT Thing Description [WOT-THING-DESCRIPTION]
DataSchema
VocabularyDataSchema
elements describe the structure of
the payload. The DataSchema
class and vocabulary
is defined in [WOT-THING-DESCRIPTION].
Properties and Events directly implement the
DataSchema
class (i.e., they contain the
corresponding fields such as type
), which
describes the data transfer in either direction. Actions may
define an input
data schema for actuation data
being sent to the Action and/or an output
data
schema for result or status data being returned from the
Action.
Each interaction affordance has associated form operation
types (i.e. op
) that are used to select the form
element corresponding to the intended interaction from the
Array of forms. For example, for one interaction, a Consumer
can choose the form element corresponding to reading a
Property, observing a Property or writing to Property by
using the form operation type.
Properties can provide readproperty
and
writeproperty
operations, which map to GET and
PUT/POST of a REST API, respectively. Properties may also
by observed if they provide an observeproperty
operation and the observation can be stopped if the
property provides an unobserveproperty
operation.
op Term |
Description |
---|---|
readproperty |
Read a Property. Requires writeOnly
to be set to false . |
writeproperty |
Write a Property. Requires readOnly
to be set to false . |
observeproperty |
Observe a Property. Requires
observable to be set to
true . |
unobserveproperty |
Unobserve a Property. Requires
observable to be set to
true . |
Actions only provide invokeaction
operations. For completeness, there is also a form
operation type defined.
op Term |
Description |
---|---|
invokeaction |
Invoke an Action. |
Events describe subscription endpoints from which to event instances can be received and unsubscription endpoints to stop receiving event instances.
op Term |
Description |
---|---|
subscribeevent |
Subscribe to an Event. |
unsubscribeevent |
Unsubscribe from an Event. |
Extensions to the Thing Description core vocabulary can inform the Consumer about protocol-specific message configurations such as methods, options, and status codes. By using such information, the Consumer can build the protocol specific request that allows interaction with the Exposed Thing. Per default the Thing Description includes HTTP Vocabulary by including the HTTP RDF vocabulary definitions from HTTP Vocabulary in RDF 1.0 [HTTP-in-RDF10].
The WoT Working Group is investigating good ways to also provide COAP and MQTT Vocabulary in RDF. Whether the WG will publish corresponding WG Notes is still subject to discussion.
op
for the given protocol, if
that op
value is defined for the given protocol.
Vocabulary term | Description | Assignment | Type |
---|---|---|---|
htv:methodName |
HTTP method name (Literal). | optional |
string
(one of |
htv:headers |
HTTP headers sent with the message. | optional |
array of
htv:MessageHeader
|
htv:fieldName |
Header name (Literal), e.g.,
"Accept" ,
"Transfer-Encoding" . |
mandatory within
htv:MessageHeader |
string
|
htv:fieldValue |
Header value (Literal). | mandatory within
htv:MessageHeader |
string
|
op value |
Default Binding |
---|---|
readproperty |
"htv:methodName": "GET" |
writeproperty |
"htv:methodName": "PUT" |
invokeaction |
"htv:methodName": "POST" |
readallproperties |
"htv:methodName": "GET" |
writeallproperties |
"htv:methodName": "PUT" |
readmultipleproperties |
"htv:methodName": "GET" |
writemultipleproperties |
"htv:methodName": "PUT" |
Vocabulary term | Description | Assignment | Type |
---|---|---|---|
cov:methodName |
CoAP method name (Literal). | optional |
string
(one of |
cov:options |
CoAP options sent with the message, e.g.,
[ { "cov:optionName": "Accept",
"cov:optionValue": 110 }] to observe. |
optional | array of cov:MessageOption |
cov:optionName |
Option name (Literal), see CoRE Parameters. | mandatory within
cov:MessageOption |
string
|
cov:optionValue |
Header value (Literal). | mandatory within
cov:MessageOption |
anyType
|
op value |
Default Binding |
---|---|
readproperty |
"cov:methodName": "GET" |
writeproperty |
"cov:methodName": "PUT" |
observeproperty |
"cov:methodName":
"GET" ,"subprotocol":"cov:observe" |
unobserveproperty |
"cov:methodName":
"GET" ,"subprotocol":"cov:observe" |
invokeaction |
"cov:methodName": "POST" |
subscribeevent |
"cov:methodName":
"GET" ,"subprotocol":"cov:observe" |
unsubscribeevent |
"cov:methodName":
"GET" ,"subprotocol":"cov:observe" |
readallproperties |
"cov:methodName": "GET" |
writeallproperties |
"cov:methodName": "PUT" |
readmultipleproperties |
"cov:methodName": "GET" |
writemultipleproperties |
"cov:methodName": "PUT" |
cov:options
with the value
[ { "cov:optionName": "Observe", "cov:optionValue": 0
}]
. However, this is not enough to describe the
mechanism of getting asynchronous updates from the observed
resource. Thus, "subprotocol":"cov:observe"
is
used to indicate the observation mechanism.
As indicated by the CoAP
Default Vocabulary Terms, it is recommended to use
the subprotocol
to describe the observation.
Thus, cov:options
with the value [ {
"cov:optionName": "Observe", "cov:optionValue": 0
}]
MUST
NOT be used together with
"subprotocol":"cov:observe"
, since it can
lead to confusion.
Vocabulary term | Description | Assignment | Type |
---|---|---|---|
mqv:controlPacketValue |
MQTT Control Packet type (Literal). | optional |
string
(one of |
mqv:options |
MQTT options sent with the message, e.g.,
[ { "mqv:optionName": "qos",
"mqv:optionValue": 1 }] . |
optional | array of mqv:MessageOption |
mqv:optionName |
Option name (Literal). | mandatory within
mqv:MessageOption ) |
string
(one of |
mqv:optionValue |
Header value (Literal). | mandatory within
mqv:MessageOption ) |
One of 0 , 1 or
2 (only for qos ) |
op value |
Default Binding |
---|---|
readproperty |
"mqv:controlPacketValue":
"SUBSCRIBE", |
writeproperty |
"mqv:controlPacketValue":
"PUBLISH" |
observeproperty |
"mqv:controlPacketValue":
"SUBSCRIBE" |
unobserveproperty |
"mqv:controlPacketValue":
"UNSUBSCRIBE" |
invokeaction |
"mqv:controlPacketValue":
"PUBLISH" |
subscribeevent |
"mqv:controlPacketValue":
"SUBSCRIBE" |
unsubscribeevent |
"mqv:controlPacketValue":
"UNSUBSCRIBE" |
readallproperties |
"mqv:controlPacketValue":
"SUBSCRIBE" |
writeallproperties |
"mqv:controlPacketValue":
"PUBLISH" |
readmultipleproperties |
"mqv:controlPacketValue":
"SUBSCRIBE" |
writemultipleproperties |
"mqv:controlPacketValue":
"PUBLISH" |
op
contains readproperty
(meaning that retain flag is set to true), it SHOULD also contain
observeproperty
. On the other hand, if the
MQTT publisher does not set the retain flag to true, the
property will be only observable. In this case, the
property in the exposed Thing Description SHOULD NOT have Form
elements with MQTT protocol containing
readproperty
operation.
subprotocol
VocabularyThe subprotocol
field is defined in
[WOT-THING-DESCRIPTION].
Currently, the supported values are
longpoll
, websub
and
sse
defined for HTTP. Subprotocols can be used
for asynchronous event delivery or observing
Properties.
For WebSockets, the IANA-registered Websocket Subprotocols [iana-web-socket-registry] may be used.
For CoAP, "subprotocol":"cov:observe"
can
be used to describe asynchronous observation operations as
defined by [RFC6741]
This section is non-normative.
The following TD examples uses a fictional CoAP and MQTT
Protocol Bindings, as no such Protocol Binding is available at
the time of writing this specification. These TD
Context Extensions assume that there is a CoAP and MQTT in
RDF vocabulary similar to [HTTP-in-RDF10] that is
accessible via the namespace
http://www.example.org/coap-binding#
and
http://www.example.org/mqtt-binding#
,
respectively. The supplemented cov:methodName
member instructs the Consumer which CoAP method has to be
applied (e.g., GET
for the CoAP Method Code 0.01,
POST
for the CoAP Method Code 0.02, or
iPATCH
for CoAP Method Code 0.07). The
supplemented "mqv:controlPacketValue"
member
instructs the Consumer which MQTT command has to be applied
(e.g., 8
for the subscribing and 10
for unsubscribing).
A TD with simple payload format and protocols can be seen below. Here each interaction affordance has one form with one protocol.
{
"@context": [
"https://www.w3.org/2019/wot/td/v1",
{
"iot": "http://iotschema.org/",
"cov": "http://www.example.org/coap-binding#"
"mqv": "http://www.example.org/mqtt-binding#"
}
],
"@type": [ "Thing", "iot:Light", "iot:LevelCapability", "iot:BinarySwitchCapability" ],
"base": "http://example.com",
"title": "Lamp",
"id": "urn:dev:ops:32473-WoTLamp-1234",
"securityDefinitions": {"basic_sc": {
"scheme": "basic",
"in": "header"
}},
"security": ["basic_sc"],
"properties": {
"switchState": {
"@type": ["iot:SwitchStatus", "iot:SwitchData"],
"type": "boolean",
"writeOnly": false,
"readOnly": false,
"observable": false,
"forms": [
{
"href": "/example/light/currentswitch",
"op": ["readproperty", "writeproperty"],
"contentType": "application/json"
}
]
},
"brightness": {
"@type": ["iot:CurrentLevel", "iot:LevelData"],
"type": "number",
"writeOnly": false,
"readOnly": false,
"observable": false,
"forms": [
{
"href": "coap://example.com/example/light/currentdimmer",
"op": ["readproperty", "writeproperty"],
"contentType": "application/json"
}
]
}
},
"actions": {
"switchOn": {
"@type": ["iot:SwitchOnAction"],
"input": {
"type": "boolean",
"const": true
},
"forms": [
{
"href": "/example/light/currentswitch",
"op": ["invokeaction"],
"contentType": "application/json"
}
]
},
"switchOff": {
"@type": ["iot:SwitchOff"],
"input": {
"type": "boolean",
"const": false
},
"forms": [
{
"href": "/example/light/currentswitch",
"op": ["invokeaction"],
"contentType": "application/json"
}
]
},
"setBrightness": {
"@type": ["iot:SetLevelAction"],
"input": {
"@type": ["iot:LevelData"],
"type": "number"
},
"forms": [
{
"href": "/example/light/currentdimmer",
"op": ["invokeaction"],
"contentType": "application/json"
}
]
}
}
}
Another version of the previous TD with complex payload and
multiple protocol options is shown below. Notably, the
brightness
property can be read via HTTP, written
to via CoAP and observed via MQTT.
{
"@context": [
"https://www.w3.org/2019/wot/td/v1",
{
"iot": "http://iotschema.org/",
"cov": "http://www.example.org/coap-binding#"
"mqv": "http://www.example.org/mqtt-binding#"
}
],
"base": "http://example.com/",
"@type": [ "Thing", "iot:Light", "iot:LevelCapability", "iot:BinarySwitch" ],
"title": "Lamp",
"id": "urn:dev:ops:32473-WoTLamp-1234",
"securityDefinitions": {"basic_sc": {
"scheme": "basic",
"in": "header"
}},
"security": ["basic_sc"],
"properties": {
"switchState": {
"@type": ["iot:SwitchStatus"],
"type": "object",
"properties": {
"switch": {
"@type": ["iot:SwitchData"],
"type": "boolean"
}
},
"writeOnly": false,
"readOnly": false,
"observable": true,
"forms": [
{
"href": "/example/light/currentswitch",
"contentType": "application/json",
"op": ["readproperty"],
"htv:methodName": "GET"
},
{
"href": "/example/light/currentswitch",
"contentType": "application/json",
"op": ["writeproperty"],
"htv:methodName": "POST"
},
{
"href": "mqtt://example.com/example/light/currentswitch",
"op": ["observeproperty"],
"mqv:controlPacketValue": "SUBSCRIBE"
}
]
},
"brightness": {
"@type": ["iot:CurrentLevel"],
"type": "object",
"properties": {
"brightness": {
"@type": ["iot:LevelData" ],
"type": "integer",
"minimum": 0,
"maximum": 255
}
},
"writeOnly": false,
"readOnly": false,
"observable": true,
"forms": [
{
"href": "coap://example.com/example/light/currentdimmer",
"contentType": "application/json",
"op": ["readproperty"],
"cov:methodName": "GET"
},
{
"href": "/example/light/currentdimmer",
"contentType": "application/json",
"op": ["writeproperty"],
"htv:methodName": "POST"
},
{
"href": "mqtt://example.com/example/light/currentdimmer",
"op": ["observeproperty"],
"mqv:controlPacketValue": "SUBSCRIBE"
}
]
},
"transitionTime": {
"@type": ["iot:TransitionTime"],
"type": "object",
"properties": {
"transitionTime": {
"@type": ["iot:TransitionTimeData" ],
"type": "integer",
"minimum": 0,
"maximum": 255
}
},
"writeOnly": false,
"readOnly": false,
"observable": false,
"forms": [
{
"href": "/example/light/transitiontime",
"contentType": "application/json",
"op": ["readproperty"],
"htv:methodName": "GET"
},
{
"href": "/example/light/transitiontime",
"contentType": "application/json",
"op": ["writeproperty"],
"htv:methodName": "POST"
}
]
}
},
"actions": {
"switchOn": {
"@type": ["iot:SwitchOnAction"],
"input": {
"type": "object",
"properties": {
"type": "boolean",
"const": true
}
},
"forms": [
{
"href": "/example/light/currentswitch",
"contentType": "application/json",
"op": ["invokeaction"],
"htv:methodName": "POST"
}
]
},
"switchOff": {
"@type": ["iot:SwitchOffAction"],
"input": {
"type": "boolean",
"const": false
}
},
"forms": [
{
"href": "/example/light/currentswitch",
"contentType": "application/json",
"op": ["invokeaction"],
"htv:methodName": "POST"
}
]
},
"setBrightness": {
"title": "Set Brightness Level",
"@type": ["iot:SetLevelAction"],
"input": {
"type": "object",
"properties": {
"brightness": {
"@type": ["iot:LevelData"],
"type": "integer",
"minimum": 0,
"maximum": 255
}
},
"transitionTime": {
"@type": ["iot:TransitionTimeData"],
"type": "integer",
"minimum": 0,
"maximum": 65535
}
},
"forms": [
{
"href": "/example/light/",
"contentType": "application/json",
"op": ["invokeaction"],
"htv:methodName": "POST"
}
]
}
}
}
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.
This section is non-normative.
This section illustrates example sequences of application and protocol transactions that correspond to operations (defined in the Thing Description Specification) implementing various interactions among WoT Consumer and WoT Things. The illustrations show both the concrete protocol transactions and the interactions between the applications running inside the WoT Consumer and WoT Thing and the Consumed Thing and Exposed Thing abstractions.
For the sake of simplicity, remote and local proxies between the Consumer and the Thing are omitted from the following sequences. We also assume HTTP as the concrete protocol and omit any additional transactions for implementing security, such as those that would be used for authentication or to set up a secure connection for HTTPS. Other concrete protocols and the addition of security transactions however would only affect the concrete protocol transactions, not the application-level interactions with the Consumed Thing and Exposed Thing abstractions.
The following sequence illustrates application and
network transactions to implement the
readproperty
operation with an HTTP protocol
binding.
The following sequence illustrates application and
network transactions to implement the
writeproperty
operation with an HTTP protocol
binding.
The following sequence illustrates application and
network transactions to implement the
observeproperty
operation with an HTTP
protocol binding using the "longpolling" (Long Polling)
subprotocol.
The following sequence illustrates application and
network transactions to implement the
observeproperty
operation with an HTTP
protocol binding using the "sse" (Server Sent Event)
subprotocol.
The following sequence illustrates application and
network transactions to implement the
observeproperty
operation with an HTTP
protocol binding using a WebSocket-based subprotocol.
The following sequence illustrates application and
network transactions to implement the
invokeaction
operation with an HTTP protocol
binding, where the operation is synchronous and the
response from the server is delayed until after the action
completes.
In the following, note that there is no explicit operation
defined for event notification itself. The subprotocol used
for notification is associated with the
subscribeevent
operation, and any necessary
concrete protocol transactions are managed by the Protocol
Binding subsystem.
There are also several subprotocols possible for event notification using WebSockets. The interaction diagrams show only one of several possible implementations.
The following sequence illustrates application and
network transactions to implement the
subscribeevent
and
unsubscribeevent
operations with an HTTP
protocol binding using the Long Polling subprotocol.
The following sequence illustrates application and
network transactions to implement the
subscribeevent
and
unsubscribeevent
operations with an HTTP
protocol binding using the Server Sent Event
subprotocol.
The following sequence illustrates application and
network transactions to implement the
subscribeevent
and
unsubscribeevent
operations with an HTTP
protocol binding using a WebSocket subprotocol.
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.