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 an Editor's Draft.
Comments regarding this document are welcome. Please send them to public-wot-wg@w3.org ( archives ).
Publication as an Editor's Draft 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 . W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of 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 [ RFC8428 ] might use the following construct:
Example
3
:
SenML
Example
|
Example
4
:
DataSchema
for
SenML
Payload
|
A Batch Collection according to OCF[ 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 [ 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-
)
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>
<brightness>
<integer>200</integer>
</brightness>
<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
[
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 summarizes the vocabulary used for Binding Templates. The vocabulary is defined in other documents, in particular the WoT Thing Description [ WOT-THING-DESCRIPTION ]
DataSchema
Vocabulary
DataSchema
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.
The
protocol
vocabularies
for
each
protocol
are
presented
as
two
tables
per
protocol.
The
first
table
details
the
vocabulary
terms,
whereas
the
second
one
lists
a
default
mapping
of
the
op
for
the
given
protocol,
if
that
op
value
is
defined
for
the
given
protocol.
Other
protocols
can
be
easily
integrated
into
a
Thing
Description.
To
do
so,
the
vocabulary
of
the
protocol
should
be
linked
via
@context
context
extension,
in
which
the
different
vocabulary
terms
used
for
the
protocol
should
be
described.
A
URI
Scheme
of
the
protocol
is
also
necessary
to
identify
it
in
the
href
value.
A
Consumer
should
be
able
to
construct
the
appropriate
requests
based
vocabulary
terms
defined
in
the
Thing
Description
and
should
not
rely
on
out-of-band
information.
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
Vocabulary
The
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.