Copyright © 2017-2019 W3C® (MIT, ERCIM, Keio, Beihang). W3C liability, trademark and permissive document license rules apply.
This document describes a formal model and a common representation for a Web of Things (WoT) Thing Description. A Thing Description describes the metadata and interfaces of Things, where a Thing is an abstraction of a physical or virtual entity that provides interactions to and participates in the Web of Things. Thing Descriptions provide a set of interactions based on a small vocabulary that makes it possible both to integrate diverse devices and to allow diverse applications to interoperate. Thing Descriptions, by default, are encoded in a JSON format that also allows JSON-LD processing. The latter provides a powerful foundation to represent knowledge about Things in a machine-understandable way. A Thing Description instance can be hosted by the Thing itself or hosted externally when a Thing has resource restrictions (e.g., limited memory space) or when a Web of Things-compatible legacy device is retrofitted with a Thing Description.
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/.
The following features are considered at risk of removal due to potentially insufficient implementation experience (reports).
APIKeySecurityScheme
, §
5.3.3.7
CertSecurityScheme
, §
5.3.3.8
PSKSecurityScheme
, §
5.3.3.9
PublicSecurityScheme
, §
5.3.3.10
PoPSecurityScheme
and §
5.3.3.11
OAuth2SecurityScheme
.
proxy
in §
5.3.3.1
SecurityScheme
, qop
in
§
5.3.3.4
DigestSecurityScheme
and
scopes
term in §
5.3.4.2
Form
.
Text or table entries highlighted with a yellow background indicate an at-risk feature for which insufficient implementation experience currently exists. In each such case the annotation "This feature is at risk" is attached. When an entire section is at risk the annotation "This section is at risk" is placed at the start of the section and highlighted with a yellow background. When an entire section is at risk individual items within that section are not highlighted or annotated.
The Working Group seeks implementation feedback, having set the requirement of at least two implementations of each feature as the exit criteria for the Candidate Recommendation phase. The group aims to obtain reports from one TD producer and one TD consumer for each feature if applicable. For details, including definitions of implementation, TD producer, and TD consumer, see the draft implementation report.
This document was published by the Web of Things Working Group as a Candidate Recommendation. This document is intended to become a W3C Recommendation.
GitHub Issues are preferred for discussion of this specification. Alternatively, you can send comments to our mailing list. Please send them to public-wot-wg@w3.org (subscribe, archives).
W3C publishes a Candidate Recommendation to indicate that the document is believed to be stable and to encourage implementation by the developer community. This Candidate Recommendation is expected to advance to Proposed Recommendation no earlier than 13 June 2019.
Please see the Working Group's implementation report.
Publication as a Candidate Recommendation 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.
This section is non-normative.
The WoT Thing Description (TD) is a central building block in the W3C Web of Things (WoT) and can be considered as the entry point of a Thing (much like the index.html of a Web site). A TD instance has four main components: textual metadata about the Thing itself, a set of Interaction Affordances that indicate how the Thing can be used, schemas for the data exchanged with the Thing for machine-understandability, and, finally, Web links to express any formal or informal relation to other Things or documents on the Web.
The Interaction Model of W3C WoT defines three types
of Interaction Affordances: Properties
(PropertyAffordance
class) can be used for sensing and controlling parameters, such
as getting the current value or setting an operation state.
Actions (ActionAffordance
class)
model invocation of physical (and hence time-consuming)
processes, but can also be used to abstract RPC-like calls of
existing platforms. Events (EventAffordance
class) are
used for the push model of communication where notifications,
discrete events, or streams of values are sent asynchronously
to the receiver. See [wot-architecture]
for details.
In general, the TD provides metadata for different Protocol Bindings identified by URI schemes
[iana-uri-schemes]
(e.g., http
, coap
, etc.), content
types based on media types (e.g.,
application/json
, application/xml
,
application/cbor
, application/exi
etc.) [iana-media-types], and security
mechanisms (for authentication, authorization, confidentiality,
etc.). Serialization of TD instances is based on JSON
[rfc8259],
where JSON names refer to terms of the TD vocabulary, as
defined in this specification document. In addition the JSON
serialization of TDs follows the syntax of JSON-LD 1.1
[json-ld11] to enable extensions and
rich semantic processing.
Example 1 shows a TD instance and illustrates the Interaction Model with Properties, Actions, and Events by describing a lamp Thing with the title MyLampThing.
From this TD example, we know there exists one Property affordance with the title
status. In addition, information is provided to indicate
that this Property is accessible via (the secure form of) the
HTTP protocol with a GET method at the URI
https://mylamp.example.com/status
(announced
within the forms
structure by the
href
member), and will return a string-based
status value. The use of the GET method is not stated
explicitly, but is one of the default assumptions defined by
this document.
In a similar manner, an Action
affordance is specified to toggle the switch status using
the POST method on the
https://mylamp.example.com/toggle
resource, where
POST is again a default assumption for invoking Actions.
The Event affordance enables
a mechanism for asynchronous messages to be sent by a Thing. Here, a subscription to be notified upon a
possible overheating event of the lamp can be obtained by using
HTTP with its long polling subprotocol on
https://mylamp.example.com/oh
.
This example also specifies the basic
security
scheme, requiring a username and password for access. Note that
a security scheme is first given a name in a
securityDefinition
and then activated by
specifying that name in a security
section. In
combination with the use of the HTTP protocol this example
demonstrates the use of HTTP Basic Authentication.
Specification of at least one security scheme at the top level
is mandatory, and gives the default access requirements for
every resource. However, security schemes can also be specified
per-form, with configurations given at the form level
overriding configurations given at the Thing
level, allowing for the specification of fine-grained access
control. It is also possible to use a special
nosec
security scheme to indicate that no access
control mechanisms are used. Additional examples will be
provided later.
The Thing Description offers the possibility to add
contextual definitions in some namespace. This mechanism can be
used to integrate additional semantics to the content of the
Thing Description instance, provided that formal knowledge,
e.g. logic rules for a specific domain of application, can be
found under the given namespace. Contextual information can
also help specify some configurations and behavior of the
underlying communication protocols declared in the
forms
field. Example 2 extends
the TD sample from Example 1 by introducing a second definition
in the @context
to declare the prefix
saref
as referring to the SAREF vocabulary
namespace [smartM2M].
The SAREF vocabulary includes terms to describe lighting
devices and other home automation devices that one can embed in
a TD as semantic labels in the @type
property. In
the present example, the Thing is labelled with
saref:LightSwitch
, the form of the
status
property affordance is labelled with
saref:GetCommand
, the form of the
toggle
action affordance with
saref:ToggleCommand
and the form the
overheating
event affordance with
saref:NotifyCommand
.
The declaration mechanism inside some @context
is specified by JSON-LD. A TD instance complies to version 1.1
of this specification [json-ld11]. The
TD instance can be also processed as an RDF document (details
are given in §
D.
Transformation to RDF).
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 MAY, MUST, MUST NOT, RECOMMENDED, 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.
A Thing Description instance complies with this specification if it follows the normative statements in § 5. TD Information Model and § 6. TD Representation Format regarding Thing Description serialization.
A JSON Schema [JSON-SCHEMA-VALIDATION] to validate Thing Description instances is provided in Appendix § B. JSON Schema for TD Instance Validation.
A set of SHACL shapes [SHACL] is provided under the TD namespace IRI as an alternative to validate Thing Description instances after transformation to RDF. See Appendix § D. Transformation to RDF.
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:
Thing
class. For that purpose, a TD Processor may compute canonical forms of
Thing Descriptions in which all
possible Default Values are assigned. A
TD Processor is typically a
sub-system of a WoT Runtime.
These definitions are further developed in § 5.2 Preliminaries.
The version of the TD Information Model defined in § 5. TD Information Model of this specification is identified by the following IRI:
https://www.w3.org/2019/wot/td/v1
This IRI, which is also a URI, can be dereferenced to obtain a JSON-LD context file [json-ld11], allowing the compact strings in TD Documents to be expanded to full IRI-based Vocabulary Terms. However, this processing is only required when transforming JSON-based TD Documents to RDF, an optional feature of TD Processor implementations. See § D.1 Thing Description JSON-LD Context for more details on this aspect.
In the present specification, Vocabulary Terms are always presented in their compact form. Their expanded form can be accessed under the namespace IRI of the Vocabulary they belong to. These namespaces follow the structure of § 5.3 Class Definitions. Each Vocabulary used in the TD Information Model has its own namespace IRI, as follows:
Vocabulary | Namespace IRI |
---|---|
Core | https://www.w3.org/2019/wot/td# |
Data Schema |
https://www.w3.org/2019/wot/json-schema# |
Security |
https://www.w3.org/2019/wot/security# |
Hypermedia Controls |
https://www.w3.org/2019/wot/hypermedia# |
The Vocabularies are independent from each other. They
may be reused and extended in other W3C specifications. Every
breaking change in the design of a Vocabulary will require
the assignment of a new year-based namespace URI. Note that to
maintain the general coherence of the TD Information
Model, the associated JSON-LD context file is versioned
such that every version has its own URI (v1
,
v1.1
, v2
, ...) to also identify
non-breaking changes, in particular the addition of new
Terms.
Because a Vocabulary under some namespace IRI can only undergo non-breaking changes, its content can be safely cached or embedded in applications. One advantage of exposing relatively static content under a namespace IRI is to optimize payload sizes of messages exchanged between constrained devices. It also avoids any privacy leakage resulting from devices accessing publicly available vocabularies from private networks (see also § 9.1 Context Dereferencing Privacy Risk).
This section introduces the TD Information Model. The TD Information Model serves as the conceptual basis for the processing of Thing Descriptions and their serialization, which is described separately in § 6. TD Representation Format.
The TD Information Model is built upon the following, independent Vocabularies:
Each of these Vocabularies is essentially a set of Terms that can be used to build data structures, interpreted as objects in the traditional object-oriented sense. Objects are instances of classes and have properties. In the context of W3C WoT, they denote Things and their Interaction Affordances. A formal definition of objects is given in § 5.2 Preliminaries. The main elements of the TD Information Model are then presented in § 5.3 Class Definitions. Certain object properties may be omitted in a TD when Default Values exist. A list of defaults is given in § 5.4 Default Value Definitions.
The UML diagram shown next gives an overview of the
TD Information Model. It represents all classes as
tables and the associations that exist between classes,
starting from the class Thing
, as directed arrows. For the
sake of readability, the diagram was split in four parts, one
for each of the four base Vocabularies.
To provide a model that can be easily processes by both, simple rules on a tree-based document (i.e., raw JSON processing) and rich Semantic Web tooling (i.e., JSON-LD processing), this document defines the following formal preliminaries to construct the TD Information Model accordingly.
All definitions in this section refer to sets, which intuitively are collections of elements that can themselves be sets. All arbitrarily complex data structures can be defined in terms of sets. In particular, an Object is a data structure recursively defined as follows:
Though this definition does not prevent Objects to include multiple name-value pairs with the same name, they are generally not considered in this specification. An Object whose elements only have numbers as names is called an Array. Similarly, an Object whose elements only have Terms (that do not belong to any Vocabulary) as names is called a Map. All names appearing in some name-value pair in a Map are assumed to be unique within the scope of the Map.
Moreover, Objects can be instances of some Class. A Class, which is denoted by a Vocabulary Term, is first defined by a set of Vocabulary Terms called a Signature. A Class whose Signature is empty is called a Simple Type.
The Signature of a Class allows to
construct two functions that further define Classes: an Assignment Function and a
Type
Function. The Assignment Function of
a Class takes a Vocabulary Term of the
Class's Signature as input and
returns either true
or false
as
output. Intuitively, the Assignment
Function indicates whether an element of the Signature is mandatory or optional when
instantiating the Class. The Type Function of a Class also takes a
Vocabulary Term of the Class's Signature as input and returns another Class as output. These functions are
partial: their domain is limited to the Signature of the Class being
defined.
On the basis of these two functions, an Instance Relation can be defined for a pair composed of an Object and a Class. This relation is defined as constraints to be satisfied. That is, an Object is an instance of a Class if the two following constraints are both satisfied:
true
, the Object includes a name-value pair with the
Vocabulary Term as name.
According to the definition above, an Object would be an instance of every Simple Type, regardless of its structure. Instead,
another definition for the Instance
Relation is introduced for Simple Types: an
Object is an instance of a Simple Type if it is a Term with a
given lexical form (e.g. true
,
false
for the boolean
type,
1
, 2
, 3
, ... for the
unsignedInt
type, etc).
Moreover, additional Classes, called Parameterized Classes, can be derived from the generic Map and Array structures. An Object is a Map of some Class, that is, an instance of the Map type parameterized with some Class, if it is a Map such that the value in all the name-value pairs it contains is an instance of this Class. The same applies to Arrays.
Finally, a Class is a Subclass of some other Class if every instance of the former is also an instance of the latter.
Given all definitions above, the TD Information
Model is to be understood as a set of Class definitions, which include a Class name (a Vocabulary Term), a
Signature (a set of Vocabulary
Terms), an Assignment Function,
and a Type Function. These Class definitions are provided as tables in
§
5.3
Class Definitions. For each table, the values
"mandatory" (respectively, "optional") in the assignment
column indicates that the Assignment
Function returns true
(respectively,
false
) for the corresponding Vocabulary Term.
By convention, Simple Types are
denoted by names starting with lowercase. The TD Information Model references the following
Simple Types defined in XML
Schema [xmlschema11-2-20120405]:
string
, anyURI
,
dateTime
, integer
,
unsignedInt
, double
, and
boolean
. Their definition (i.e. the
specification of their lexical form) is outside of the scope
of the TD Information Model.
In addition, the TD Information Model
defines a global function on pairs of Vocabulary Terms. The function takes a Class name and another Vocabulary Term
as input and returns an Object. If the
returned Object is different from
null
, it represents the Default
Value for some assignment on the input Vocabulary Term in an instance of the input
Class. This function allows to relax the constraint
defined above on the Assignment
Function: an Object is an instance of a Class if it includes all mandatory assignments
or if Default Value exist
for the missing assignments. All Default Values
are given in the table of §
5.4
Default Value Definitions. In each table of
§
5.3
Class Definitions, the assignment column contains
the value "with default" if a Default Value is
available for the corresponding combination of Class and Vocabulary Term in the
TD Information Model.
The formalization introduced here does not consider the possible relation between Objects as abstract data structures and physical world objects such as Things. However, care was given to the possibility of re-interpreting all Vocabulary Terms involved in the TD Information Model as RDF resources, so as to integrate them in a larger model of the physical world (an ontology). This aspect is dealt with in Appendix § D.2 Thing Description Ontology.
A TD Processor MUST be able to detect that a TD does not meet Class instantiation constraints on all Classes defined in § 5.3.1 Core Vocabulary Definitions, § 5.3.2 Data Schema Vocabulary Definitions, § 5.3.3 Security Vocabulary Definitions, and § 5.3.4 Hypermedia Controls Vocabulary Definitions.
Thing
An abstraction of a physical or a virtual entity whose metadata and interfaces are described by a WoT Thing Description, whereas a virtual entity is the composition of one or more Things.
Vocabulary term | Description | Assignment | Type |
---|---|---|---|
@context |
JSON-LD keyword to define short-hand names called terms that are used throughout a TD document. | mandatory |
anyURI or Array
|
@type |
JSON-LD keyword to label the object with semantic tags (or types). | optional |
string or Array of
string
|
id |
unique identifier of the Thing (URI, e.g. custom URN). | mandatory |
anyURI
|
title |
Provides a human-readable title (e.g., display a text for UI representation) based on a default language. | mandatory |
string
|
titles |
Provides multi-language human-readable titles (e.g., display a text for UI representation in different languages). | optional |
MultiLanguage
|
description |
Provides additional (human-readable) information based on a default language. | optional |
string
|
descriptions |
Can be used to support (human-readable) information in different languages. | optional |
MultiLanguage
|
version |
Provides version information. | optional |
VersionInfo
|
created |
Provides information when the TD instance was created. | optional |
dateTime
|
modified |
Provides information when the TD instance was last modified. | optional |
dateTime
|
support |
Provides information about the TD maintainer as URI scheme (e.g., mailto [RFC6068], tel [RFC3966], https). | optional |
anyURI
|
base |
Define the base URI that is used for all
relative URI references throughout a TD document.
In TD instances, all relative URIs are resolved
relative to the base URI using the algorithm
defined in [RFC3986].base does not affect the URIs used in
@context and the IRIs [RFC3987]
used within Linked Data [LINKED-DATA]
graphs that are relevant when semantic processing
is applied to TD instances. |
optional |
anyURI
|
properties |
All Property-based interaction affordance of the Thing. | optional |
Map of PropertyAffordance
|
actions |
All Action-based interaction affordance of the Thing. | optional |
Map of ActionAffordance
|
events |
All Event-based interaction affordance of the Thing. | optional |
Map of EventAffordance
|
links |
Provides Web links to arbitrary resources that relate to the specified Thing Description. | optional |
Array of Link
|
forms |
Set of form hypermedia controls that describe how an operation can be performed. Forms are serializations of Protocol Bindings. In this version of TD, all operations that can be described at the Thing level are concerning how to interact with the Thing's property affordances collectively at once. | optional |
Array of Form
|
security |
Set of security definition names, chosen from those defined in securityDefinitions. These must all be satisfied for access to resources. | mandatory |
string or Array of
string
|
securityDefinitions |
Set of named security configurations (definitions only). Not actually applied unless names are used in a security section. | mandatory |
Map of SecurityScheme
|
The @context
name-value pair MUST contain the anyURI
https://www.w3.org/2019/wot/td/v1
either
directly when of type anyURI
or as first
element when of type Array.
When @context
is an Array, the anyURI
https://www.w3.org/2019/wot/td/v1
MAY be followed by elements of
type anyURI
or type Map in any
order, while it is RECOMMENDED to include only one
Map with all the name-value pairs in the
@context
Array.
Maps contained in an @context
Array MAY
contain name-value pairs, where the value is a namespace
identifier of type anyURI
and the name a
Term or prefix denoting that
namespace. One Map
contained in an @context
Array SHOULD contain a name-value pair that
defines the default language for the Thing Description,
where the name is the Term
@language
and the value is a well-formed
language tag as defined by [BCP47] (e.g.,
en
, de-AT
, gsw-CH
,
zh-Hans
, zh-Hant-HK
,
sl-nedis
).
The computation of the base direction of all human-readable text strings is defined by the following set of rules:
MultiLanguage
Maps, the base
direction MAY be
inferred from the language tag of the default
language.MultiLanguage
Maps, the base
direction of each value of the name-value pairs
MAY be inferred
from the language tag given in the corresponding
name.@language
or
MultiLanguage
Maps MUST include a script
subtag, so that an appropriate base direction can be
inferred. An example is Azeri, which is written
LTR when Latin script is used (specified using
az-Latn
) and RTL when Arabic script is
used (specified using az-Arab
).TD Processors should be aware of certain special cases when processing bidirectional text. They should take care to use bidi isolation when presenting strings to users, particularly when embedding in surrounding text (e.g., for Web user interface). Mixed direction text can occur in any language, even when the language is properly identified.
TD producers should attempt to provide mixed direction strings in a way that can be displayed successfully by a naive user agent. For example, if an RTL string begins with an LTR run (such as a number or a brand or trade name in Latin script), including an RLM character at the start of the string or wrapping opposite direction runs in bidi controls can assist in proper display.
Strings on the Web: Language and Direction Metadata [string-meta] provides some guidance and illustrates a number of pitfalls when using bidirectional text.
In addition to the
explicitly provided Interaction
Affordances in the properties
,
actions
, and events
Arrays, a Thing can also
provide meta-interactions, which are indicated by
Form
instances in its optional
forms
Array.
When
the forms
Array of a
Thing instance contains Form
instances, the string values assigned to the name
op
, either directly or within an Array, MUST be one of the following operation
types: readallproperties
,
writeallproperties
,
readmultipleproperties
, or
writemultipleproperties
. (See
an example for an
usage of form
in a Thing instance.)
The data schema for each of these meta-interactions is
constructed by combining the data schemas of each
PropertyAffordance
instance in a single ObjectSchema
instance,
where the properties
Map of the
ObjectSchema
instance contains each data
schema of the PropertyAffordances
identified
by the name of the corresponding
PropertyAffordances
instance.
If not specified otherwise (e.g., through a TD Context Extension), the request data of the
readmultipleproperties
operation is an
Array that contains the intended
PropertyAffordances
instance names, which is
serialized to the content type specified by the
Form
instance.
InteractionAffordance
Metadata of a Thing that shows the possible choices to Consumers, thereby suggesting how Consumers may interact with the Thing. There are many types of potential affordances, but W3C WoT defines three types of Interaction Affordances: Properties, Actions, and Events.
Vocabulary term | Description | Assignment | Type |
---|---|---|---|
@type |
JSON-LD keyword to label the object with semantic tags (or types). | optional |
string or Array of
string
|
title |
Provides a human-readable title (e.g., display a text for UI representation) based on a default language. | optional |
string
|
titles |
Provides multi-language human-readable titles (e.g., display a text for UI representation in different languages). | optional |
MultiLanguage
|
description |
Provides additional (human-readable) information based on a default language. | optional |
string
|
descriptions |
Can be used to support (human-readable) information in different languages. | optional |
MultiLanguage
|
forms |
Set of form hypermedia controls that describe how an operation can be performed. Forms are serializations of Protocol Bindings. | mandatory |
Array of Form
|
uriVariables |
Define URI template variables as collection based on DataSchema declarations. | optional |
Map of DataSchema
|
The class InteractionAffordance
has the
following subclasses:
PropertyAffordance
An Interaction Affordance that exposes state of the Thing. This state can then be retrieved (read) and optionally updated (write). Things can also choose to make Properties observable by pushing the new state after a change.
Vocabulary term | Description | Assignment | Type |
---|---|---|---|
observable |
A hint that indicates whether Servients hosting
the Thing and Intermediaries should provide a
Protocol Binding that supports the
observeproperty operation for this
Property. |
optional |
boolean
|
Property instances are also instances of
the class DataSchema. Therefore, it can contain the
type
, unit
,
readOnly
and writeOnly
members, among others.
PropertyAffordance
is a Subclass of the
InteractionAffordance
Class and
the DataSchema
Class.
When a Form instance is within a
PropertyAffordance
Class, the
value assigned to op
MUST be one of
readproperty
, writeproperty
,
observeproperty
,
unobserveproperty
or an Array
containing a combination of these terms.
ActionAffordance
An Interaction Affordance that allows to invoke a function of the Thing, which manipulates state (e.g., toggling a lamp on or off) or triggers a process on the Thing (e.g., dimm a lamp over time).
Vocabulary term | Description | Assignment | Type |
---|---|---|---|
input |
Used to define the input data schema of the action. | optional |
DataSchema
|
output |
Used to define the output data schema of the action. | optional |
DataSchema
|
safe |
Signals if the action is safe (=true) or not. Used to signal if there is no internal state (cf. resource state) is changed when invoking an Action. In that case responses can be cached as example. | with default |
boolean
|
idempotent |
Indicates whether the action is idempotent (=true) or not. Informs whether the action can be called repeatedly with the same result, if present, based on the same input. | with default |
boolean
|
ActionAffordance
is a Subclass of the
InteractionAffordance
Class.
When a Form instance is within an
instance of the ActionAffordance
Class, the value assigned to op MUST be
invokeaction
.
EventAffordance
An Interaction Affordance that describes an event source, which asynchronously pushes event data to Consumers (e.g., overheating alerts).
Vocabulary term | Description | Assignment | Type |
---|---|---|---|
subscription |
Defines data that needs to be passed upon subscription, e.g., filters or message format for setting up Webhooks. | optional |
DataSchema
|
data |
Defines the data schema of the Event instance messages pushed by the Thing. | optional |
DataSchema
|
cancellation |
Defines any data that needs to be passed to cancel a subscription, e.g., a specific message to remove a Webhook. | optional |
DataSchema
|
EventAffordance
is a Subclass of the
InteractionAffordance
Class.
When
a Form instance is within an instance of the
EventAffordance
Class, the value
assigned to op
MUST be either subscribeevent
,
unsubscribeevent
, or both terms within an
Array.
VersionInfo
Metadata of a Thing that provides version information about the TD document. If required, additional version information such as firmware and hardware version (term definitions outside of the TD namespace) can be extended via the TD Context Extension mechanism.
Vocabulary term | Description | Assignment | Type |
---|---|---|---|
instance |
Provides a version identicator of this TD instance. | mandatory |
string
|
It is recommended that the values within instances of
the VersionInfo
Class follow the
semantic versioning pattern, where a sequence of three
numbers separated by a dot indicates the major version,
minor version, and patch version, respectively. See
[SemVer] for
details.
MultiLanguage
A Map providing a set of human-readable texts in different languages identified by language tags described in [BCP47]. See § 6.3.2 Human-Readable Metadata for example usages of this container in a Thing Description instance.
Each name of the
MultiLanguage
Map MUST be a language tag as
defined in [BCP47].
Each value of the
MultiLanguage
Map MUST be of type
string
.
The data schema definition is reflecting a very common subset of the terms defined by JSON Schema [JSON-SCHEMA-VALIDATION]. It is noted that data schema definitions within Thing Description instances are not limited to this defined subset and MAY use additional terms found in JSON Schema. In that case, it is recommended to use a TD Context Extension for the additional terms as described in § 7. TD Context Extensions, otherwise these terms are semantically ignored by TD Processors (also see § D. Transformation to RDF).
DataSchema
Metadata that describes the data format used. It can be used for validation.
Vocabulary term | Description | Assignment | Type |
---|---|---|---|
@type |
JSON-LD keyword to label the object with semantic tags (or types) | optional |
string or Array of
string
|
title |
Provides a human-readable title (e.g., display a text for UI representation) based on a default language. | optional |
string
|
titles |
Provides multi-language human-readable titles (e.g., display a text for UI representation in different languages). | optional |
MultiLanguage
|
description |
Provides additional (human-readable) information based on a default language. | optional |
string
|
descriptions |
Can be used to support (human-readable) information in different languages. | optional |
MultiLanguage
|
type |
Assignment of JSON-based data types compatible with JSON Schema (one of boolean, integer, number, string, object, array, or null). | optional |
string (one of
object , array ,
string , number ,
integer , boolean , or
null )
|
const |
Provides a constant value. | optional | any type |
unit |
Provides unit information that is used, e.g., in international science, engineering, and business. | optional |
string
|
oneOf |
Used to ensure that the data is valid against one of the specified schemas in the array. | optional |
Array of DataSchema
|
enum |
Restricted set of values provided as an array. | optional | Array of any type |
readOnly |
Boolean value that is a hint to indicate whether a property interaction / value is read only (=true) or not (=false). | with default |
boolean
|
writeOnly |
Boolean value that is a hint to indicate whether a property interaction / value is write only (=true) or not (=false). | with default |
boolean
|
format |
Allows validation based on a format pattern such as "date-time", "email", "uri", etc. (Also see below.) | optional |
string
|
The class DataSchema
has the following
subclasses:
The format
string values are known from a
fixed set of values and their corresponding format rules
defined in [JSON-SCHEMA-VALIDATION]
(Section 7.3 Defined Formats in particular). Servients MAY use the
format
value to perform additional
validation accordingly. When a value that is
not found in the known set of values is assigned to
format
, such a validation SHOULD succeed.
ArraySchema
Metadata describing data of type Array. This
Subclass is indicated by the
value array
assigned to type
in
DataSchema
instances.
Vocabulary term | Description | Assignment | Type |
---|---|---|---|
items |
Used to define the characteristics of an array. | optional |
DataSchema
or Array of DataSchema
|
minItems |
Defines the minimum number of items that have to be in the array. | optional |
unsignedInt
|
maxItems |
Defines the maximum number of items that have to be in the array. | optional |
unsignedInt
|
BooleanSchema
Metadata describing data of type boolean
.
This Subclass is indicated by the
value boolean
assigned to type
in DataSchema
instances.
NumberSchema
Metadata describing data of type number
.
This Subclass is indicated by the
value number
assigned to type
in DataSchema
instances.
Vocabulary term | Description | Assignment | Type |
---|---|---|---|
minimum |
Specifies a minimum numeric value. Only applicable for associated number or integer types. | optional |
double
|
maximum |
Specifies a maximum numeric value. Only applicable for associated number or integer types. | optional |
double
|
IntegerSchema
Metadata describing data of type integer
.
This Subclass is indicated by the
value integer
assigned to type
in DataSchema
instances.
Vocabulary term | Description | Assignment | Type |
---|---|---|---|
minimum |
Specifies a minimum numeric value. Only applicable for associated number or integer types. | optional |
integer
|
maximum |
Specifies a maximum numeric value. Only applicable for associated number or integer types. | optional |
integer
|
ObjectSchema
Metadata describing data of type object
.
This Subclass is indicated by the
value object
assigned to type
in DataSchema
instances.
Vocabulary term | Description | Assignment | Type |
---|---|---|---|
properties |
Data schema nested definitions. | optional |
Map of DataSchema
|
required |
Defines which members of the object type are mandatory. | optional |
Array of
string
|
StringSchema
Metadata describing data of type string
.
This Subclass is indicated by the
value string
assigned to type
in DataSchema
instances.
NullSchema
Metadata describing data of type null
.
This Subclass is indicated by the
value null
assigned to type
in
DataSchema
instances. This Subclass
describes only one acceptable value, namely
null
. It can be used as part of a
oneOf
declaration, where it is used to
indicate, that the data can also be
null
.
This specification provides a selection of well-established security mechanisms that are directly built into protocols eligible as Protocol Bindings for W3C WoT or are widely in use with those protocols. The current set of HTTP security schemes is partly based on OpenAPI 3.0.1 (see also [OPENAPI]). However while the HTTP security schemes, Vocabulary, and syntax given in this specification share many similarities with OpenAPI, they are not compatible.
SecurityScheme
Metadata describing the configuration of a security
mechanism. The value assigned to the name
scheme
MUST be defined within a Vocabulary
included in the Thing Description,
either in the standard Vocabulary defined
in §
5.
TD Information Model or in a TD Context Extension.
Vocabulary term | Description | Assignment | Type |
---|---|---|---|
@type |
JSON-LD keyword to label the object with semantic tags (or types). | optional |
string or Array of
string
|
scheme |
Identification of the security mechanism being configured. | mandatory |
string (e.g. nosec ,
basic , cert ,
digest , bearer ,
pop , psk ,
public , oauth2 , or
apikey )
|
description |
Provides additional (human-readable) information based on a default language. | optional |
string
|
descriptions |
Can be used to support (human-readable) information in different languages. | optional |
MultiLanguage
|
proxy |
URI of the proxy server this security
configuration provides access to. If not given, the
corresponding security configuration is for the
endpoint. This feature is at risk. |
optional |
anyURI
|
The class SecurityScheme
has the
following subclasses:
NoSecurityScheme
A security configuration corresponding to identified
by the Vocabulary Term
nosec
(i.e., "scheme":
"nosec"
), indicating there is no authentication or
other mechanism required to access the resource.
BasicSecurityScheme
Basic authentication security configuration identified
by the Vocabulary Term
basic
(i.e., "scheme":
"basic"
), using an unencrypted username and
password. This scheme should be used with some other
security mechanism providing confidentiality, for
example, TLS.
Vocabulary term | Description | Assignment | Type |
---|---|---|---|
in |
Specifies the location of security authentication information. | with default |
string (one of
header , query ,
body , or cookie )
|
name |
Name for query, header, or cookie parameters. | optional |
string
|
DigestSecurityScheme
Digest authentication security configuration
identified by the Vocabulary Term
digest
(i.e., "scheme":
"digest"
). This scheme is similar to basic
authentication but with added features to avoid
man-in-the-middle attacks.
Vocabulary term | Description | Assignment | Type |
---|---|---|---|
qop |
Quality of protection. This feature is at risk. |
with default |
string (one of
auth , or auth-int )
|
in |
Specifies the location of security authentication information. | with default |
string (one of
header , query ,
body , or cookie )
|
name |
Name for query, header, or cookie parameters. | optional |
string
|
APIKeySecurityScheme
This section is at risk.
API key authentication security configuration
identified by the Vocabulary Term
apikey
(i.e., "scheme":
"apikey"
). This is for the case where the access
token is opaque and is not using a standard token
format.
Vocabulary term | Description | Assignment | Type |
---|---|---|---|
in |
Specifies the location of security authentication information. | with default |
string (one of
header , query ,
body , or cookie )
|
name |
Name for query, header, or cookie parameters. | optional |
string
|
BearerSecurityScheme
Bearer token authentication security configuration
identified by the Vocabulary Term
bearer
(i.e., "scheme":
"bearer"
). This scheme is intended for situations
where bearer tokens are used independently of OAuth2. If
the oauth2
scheme is specified it is not
generally necessary to specify this scheme as well as it
is implied. For format
, the value
jwt
indicates conformance with
[RFC7519],
jws
indicates conformance with
[RFC7797],
cwt
indicates conformance with
[RFC8392], and
jwe
indicates conformance with
[RFC7516], with
values for alg
interpreted consistently with
those standards. Other formats and
algorithms for bearer tokens MAY be specified in vocabulary
extensions..
Vocabulary term | Description | Assignment | Type |
---|---|---|---|
authorization |
URI of the authorization server. | optional |
anyURI
|
alg |
Encoding, encryption, or digest algorithm. | with default |
string (e.g. MD5 ,
ES256 , or ES512-256 )
|
format |
Specifies format of security authentication information. | with default |
string (e.g. jwt ,
cwt , jwe , or
jws )
|
in |
Specifies the location of security authentication information. | with default |
string (one of
header , query ,
body , or cookie )
|
name |
Name for query, header, or cookie parameters. | optional |
string
|
CertSecurityScheme
This section is at risk.
Certificate-based asymmetric key security
configuration conformant with [X509V3]
identified by the Vocabulary Term
cert
(i.e., "scheme":
"cert"
).
Vocabulary term | Description | Assignment | Type |
---|---|---|---|
identity |
Identifier providing information which can be used for selection or confirmation. | optional |
string
|
PSKSecurityScheme
This section is at risk.
Pre-shared key authentication security configuration
identified by the Vocabulary Term
psk
(i.e., "scheme":
"psk"
).
Vocabulary term | Description | Assignment | Type |
---|---|---|---|
identity |
Identifier providing information which can be used for selection or confirmation. | optional |
string
|
PublicSecurityScheme
This section is at risk.
Raw public key asymmetric key security configuration
identified by the Vocabulary Term
public
(i.e., "scheme":
"public"
).
Vocabulary term | Description | Assignment | Type |
---|---|---|---|
identity |
Identifier providing information which can be used for selection or confirmation. | optional |
string
|
PoPSecurityScheme
This section is at risk.
Proof-of-possession (PoP) token authentication
security configuration identified by the Vocabulary Term pop
(i.e.,
"scheme": "pop"
). Here jwt
indicates conformance with [RFC7519],
jws
indicates conformance with
[RFC7797],
cwt
indicates conformance with
[RFC8392], and
jwe
indicates conformance with
[RFC7516], with
values for alg
interpreted consistently with
those standards. Other formats and
algorithms for PoP tokens MAY be specified in vocabulary
extensions..
Vocabulary term | Description | Assignment | Type |
---|---|---|---|
authorization |
URI of the authorization server. | optional |
anyURI
|
alg |
Encoding, encryption, or digest algorithm. | with default |
string (e.g. MD5 ,
ES256 , or ES512-256 )
|
format |
Specifies format of security authentication information. | with default |
string (e.g. jwt ,
cwt , jwe , or
jws )
|
in |
Specifies the location of security authentication information. | with default |
string (one of
header , query ,
body , or cookie )
|
name |
Name for query, header, or cookie parameters. | optional |
string
|
OAuth2SecurityScheme
This section is at risk.
OAuth2 authentication security configuration for
systems conformant with [RFC6749]
and [RFC8252],
identified by the Vocabulary Term
oauth2
(i.e., "scheme":
"oauth2"
). For the
implicit
flow authorization
MUST be
included. For the
password
and client
flows
token
MUST be included. For
the code
flow both
authorization
and token
MUST be
included. If no scopes
are defined in
the SecurityScheme
then they are considered
to be empty.
Vocabulary term | Description | Assignment | Type |
---|---|---|---|
authorization |
URI of the authorization server. | optional |
anyURI
|
token |
URI of the token server. | optional |
anyURI
|
refresh |
URI of the refresh server. | optional |
anyURI
|
scopes |
Set of authorization scope identifiers provided
as an array. These are provided in tokens returned
by an authorization server and associated with
forms in order to identify what resources a client
may access and how. The values associated with a
form should be chosen from those defined in an
OAuth2SecurityScheme active on that
form.This feature is at risk. |
optional |
string or Array of
string
|
flow |
Authorization flow. | with default |
string (one of
implicit , password ,
client , or code )
|
The present model provides a representation for (typed)
Web links and Web forms exposed by a Thing. The
Link
class definition is reflecting a very
common subset of the terms defined in Web Linking
[RFC8288]. The defined terms can be
used, e.g., to describe the relation to another Thing such as a Lamp Thing is controlled
by a Switch Thing. The Form
class
corresponds to a newly introduced form of hypermedia
control to manipulate the state of Things (and
other Web resources).
Link
A link can be viewed as a statement of the form "link context has a relation type resource at link target", where the optional target attributes may further describe the resource.
Vocabulary term | Description | Assignment | Type |
---|---|---|---|
href |
target IRI of a link or submission target of a form. | mandatory |
anyURI
|
type |
Target attribute providing a hint indicating what the media type [IANA-MEDIA-TYPES] of the result of dereferencing the link should be. | optional |
string
|
rel |
A link relation type identifies the semantics of a link. | optional |
string
|
anchor |
By default, the context, or anchor, of a link conveyed in the Link header field is the URL of the representation it is associated with, as defined in RFC7231, Section 3.1.4.1, and is serialized as a URI. | optional |
anyURI
|
Form
A form can be viewed as a statement of "To perform an operation type operation on form context, make a request method request to submission target" where the optional form fields may further describe the required request. In Thing Descriptions, the form context is the surrounding Object, such as Properties, Actions, and Events or the Thing itself for meta-interactions.
Vocabulary term | Description | Assignment | Type |
---|---|---|---|
op |
Indicates the semantic intention of performing
the operation(s) described by the form.
For example, the Property interaction allows
get and set operations. op can be assigned one or more interaction verb(s) each representing a semantic intention of an operation. |
with default |
string or Array of
string (one of
readproperty ,
writeproperty ,
observeproperty ,
unobserveproperty ,
invokeaction ,
subscribeevent ,
unsubscribeevent ,
readallproperties ,
writeallproperties ,
readmultipleproperties , or
writemultipleproperties )
|
href |
target IRI of a link or submission target of a form. | mandatory |
anyURI
|
contentType |
Assign a content type based on a media type [IANA-MEDIA-TYPES] (e.g., 'text/plain') and potential parameters (e.g., 'charset=utf-8') for the media type. | with default |
string
|
contentCoding |
Content coding values indicate an encoding transformation that has been or can be applied to a representation. Content codings are primarily used to allow a representation to be compressed or otherwise usefully transformed without losing the identity of its underlying media type and without loss of information. Examples of content coding include "gzip", "deflate", etc. . | optional |
string
|
subprotocol |
Indicates the exact mechanism by which an
interaction will be accomplished for a given
protocol when there are multiple options.
For example, for HTTP and Events, it indicates which of several available mechanisms should be used for asynchronous notifications such as long polling, websub (also see https://www.w3.org/TR/websub/), or server sent events (also see https://www.w3.org/TR/eventsource/). Please note that there is no restriction on the sub-protocol selection and other mechanisms can also be announced by this subprotocol term. |
optional |
string (e.g.
longpoll , websub , or
sse )
|
security |
Set of security definition names, chosen from those defined in securityDefinitions. These must all be satisfied for access to resources. | optional |
string or Array of
string
|
scopes |
Set of authorization scope identifiers provided
as an array. These are provided in tokens returned
by an authorization server and associated with
forms in order to identify what resources a client
may access and how. The values associated with a
form should be chosen from those defined in an
OAuth2SecurityScheme active on that
form.This feature is at risk. |
optional |
string or Array of
string
|
response |
This optional term can be used if, e.g., the output communication metadata differ from input metadata (e.g., output contentType differ from the input contentType). The response name contains metadata that is only valid for the response messages. | optional |
ExpectedResponse
|
The list of possible operation types of a form is fixed. As of this version of the specification, it only includes the well-known types necessary to implement the WoT interaction model described in [WOT-ARCHITECTURE]. Future versions of the standard may extend this list but operations types SHOULD NOT be arbitrarily set by servients .
The optional response
name-value pair can
be used to provide metadata for the expected response
message. With the core vocabulary, it only includes
content type information, but TD Context Extensions could
be applied. If no
response
name-value pair is provided, it
MUST be assumed
that the content type of the response is equal to the
content type assigned to the Form instance. Note
that contentType
within an
ExpectedResponse
Class does not
have a Default Value. For instance, if
the value of the content type of the form is
application/xml
the assumed value of the
content type of the response will be also
application/xml
.
In some use cases, input and output data might be
represented in a different form, for instance an Action
that accepts JSON, but returns an image. In such a case,
the optional response
name-value pair can
describe the content type of the expected response.
If the content type of
the expected response differs from the content type of
the form, the Form
instance MUST include a name-value
pair with the name response
. For
instance, an ActionAffordance
could only
accept application/json
for its input data,
while it will respond with an image/jpeg
content type for its output data. In that case the
content types differ and the response
name-value pair has to be used to provide response
content type (image/jpeg
) information to the
Consumer.
Possible values for the contentCoding
property can be found e.g. in the
IANA HTTP content coding registry.
ExpectedResponse
Communication metadata describing the expected response message.
Vocabulary term | Description | Assignment | Type |
---|---|---|---|
contentType |
Assign a content type based on a media type [IANA-MEDIA-TYPES] (e.g., 'text/plain') and potential parameters (e.g., 'charset=utf-8') for the media type. | mandatory |
string
|
When assignments in a TD are missing, a TD Processor MUST follow the Default Value assignments expressed in the table of § 5.4 Default Value Definitions.
The following table gives all Default Values defined in the TD Information Model.
Class | Vocabulary Term | Default Value | Comment |
---|---|---|---|
Form |
contentType |
application/json |
|
DataSchema |
readOnly |
false |
|
DataSchema |
writeOnly |
false |
|
ActionAffordance |
safe |
false |
|
ActionAffordance |
idempotent |
false |
|
Form |
op |
Array of string
with the elements readproperty and
writeproperty |
If defined within an instance of
PropertyAffordance |
Form |
op |
invokeaction |
If defined within an instance of
ActionAffordance |
Form |
op |
subscribeevent |
If defined within an instance of
EventAffordance |
BasicSecurityScheme |
in |
header |
|
DigestSecurityScheme |
in |
header |
|
BearerSecurityScheme |
in |
header |
|
PoPSecurityScheme This feature is at risk. |
in |
header |
|
APIKeySecurityScheme This feature is at risk. |
in |
query |
|
DigestSecurityScheme This feature is at risk. |
qop |
auth |
|
BearerSecurityScheme |
alg |
ES256 |
|
PoPSecurityScheme This feature is at risk. |
alg |
ES256 |
|
BearerSecurityScheme |
format |
jwt |
|
PoPSecurityScheme This feature is at risk. |
format |
jwt |
|
OAuth2SecurityScheme This feature is at risk. |
flow |
implicit |
WoT Thing Descriptions represent Things and are modeled and
structured based on §
5.
TD Information Model. This section defines a
JSON-based representation format for Things, a
serialization of instances of the Class Thing
defined by the TD Information Model.
A TD Processor MUST be able to serialize Thing Descriptions into the JSON format [RFC8259] and deserialize Thing Descriptions from that format, according to the rules noted in § 6.1 Mapping to JSON Types and § 6.3 Information Model Serialization.
The JSON serialization of the TD Information Model is aligned with the syntax of JSON-LD 1.1 [json-ld11] in order to streamline semantic evaluation. Hence, the TD representation format can be processed either as raw JSON or with a JSON-LD 1.1 processor, as further detailed in § D. Transformation to RDF.
In order to support interoperable internationalization, TDs MUST be serialized according to the requirements defined in Section 8.1 of RFC8259 [RFC8259] for open ecosystems. In summary, this requires the following:
The TD Information Model is constructed, so that there is an easy mapping between model Objects and JSON types. Every Class instances maps to a JSON object, where each name-value pair of the Class instance is a member of the JSON object.
Every Simple Type mentioned in §
5.3
Class Definitions (i.e., string
,
anyURI
, dateTime
,
integer
, unsignedInt
,
double
, and boolean
) maps to a
primitive JSON type (string, number, boolean), as per the
rules listed below. These rules apply to values in name-value
pairs:
string
or anyURI
MUST be serialized as JSON
strings.dateTime
MUST be serialized as JSON strings following
the "date-time" format specified by [RFC3339].
Examples would include 2019-05-24T13:12:45Z
and 2015-07-11T09:32:26+08:00
. Values that are of type
dateTime
SHOULD use the literal Z
representing the UTC time zone instead of an
offset.integer
or unsignedInt
MUST be serialized as JSON
numbers without a fraction or exponent part.double
MUST be serialized as JSON number.boolean
MUST be serialized as JSON boolean.Every complex type of the TD Information Model (i.e., Arrays, Maps, and Class instances) maps to a structured JSON type (array and object), as per the rules listed below:
A Thing Description serialization may omit Vocabulary Term for which Default Values are defined, as listed in the table given in § 5.4 Default Value Definitions.
The following example shows the TD instance from Example 1 with a checkbox to also include the members with Default Values (=checkbox checked). These members can be omitted (=checkbox unchecked) to simplify the TD serialization. Note that a TD Processor interprets these omitted members identically as if they were explicitly present with a given Default Value.
Please note that, depending on the Protocol Binding used, additional protocol-specific Vocabulary Terms may apply. They may also have associated Default Values, and hence can also be omitted as explained in this subsection. Further information can be found in § 8.3 Protocol Bindings.
A Thing Description is a data structure rooted at an
Object of type Thing
. In turn, a JSON
serialization of the Thing Description is a JSON object,
which is the root of a syntax tree constructed from the
TD Information Model.
The root
element of a TD Serialization MUST be a JSON object that includes a
member with the name @context
and a value of
type string or array that equals or respectively contains
https://www.w3.org/2019/wot/td/v1
.
In general, this URI is used to identify the TD
representation format version defined by this
specification. For JSON-LD processing [json-ld11], this URI specifies the
Thing Description context file. An @context
of
type array indicates TD Context
Extensions (see
for details).
{
"@context": "https://www.w3.org/2019/wot/td/v1",
...
}
All name-value pairs of an instance
of Thing
, where the name is a Vocabulary Term in the Signature of
Thing
, MUST be serialized as JSON members of the root
object.
A TD snippet for a serialized root object including all mandatory and optional members is given below:
{
"@context": "https://www.w3.org/2019/wot/td/v1",
"@type": "Thing",
"id": "urn:dev:ops:32473-Thing-1234",
"title": "MyThing",
"titles": {...},
"description": "Human readable information.",
"descriptions": {...},
"support": "mailto:support@example.com",
"version" : {...},
"created" : "2018-11-14T19:10:23.824Z",
"modified" : "2019-06-01T09:12:43.124Z",
"securityDefinitions": {...},
"security": ...,
"base": "https://servient.example.com/",
"properties": {...},
"actions": {...},
"events": {...},
"links": [...],
"forms": [...]
}
All
values assigned to version
,
securityDefinitions
, properties
,
actions
, and events
in an
instance of the Class Thing
MUST be serialized as
JSON objects.
All
values assigned to links
, and
forms
in an instance of the Class Thing
MUST be serialized as JSON arrays
containing JSON objects as defined in §
6.3.8
links
and §
6.3.9
forms
, respectively.
The value assigned to
security
in an instance of Class Thing
MUST be serialized as
JSON string or as JSON array whose elements are JSON
strings.
JSON members named title
and
description
are used within a TD document to
provide human-readable metadata. They can be used as
comments for developers inspecting a TD document or as
display texts for user interface.
As defined in §
5.3.1.1
Thing
, the base text direction used
to display human-readable metadata can either be estimated
using heuristics such as the first-strong rule or inferred
from language information. In TD documents the default
language is defined by a value assigned to
@language
in the @context
, and
this, along with a script subtag if necessary, can be used
to determine a base text direction. However,
when interpreting human-readable text, each human-readable
string value MUST be
processed independently. In other words, a TD Processor cannot carry forward changes in
direction from one string to another, or infer direction
for one string from another one elsewhere in the TD.
Strings on the Web [string-meta] suggests both strong-first and language-based inferencing as means to determine the base text direction. Given that the Thing Description format is based on JSON-LD 1.1 [json-ld11], which currently lacks explicit direction metadata, these approaches are currently considered appropriate at the time of this publication. However, if JSON-LD 1.1 adopts support for explicit base direction metadata as recommended by [string-meta], the Thing Description format should be updated to take advantage of that feature.
A TD snippet using title
and
description
is shown below. The default
language is set to en
through the definition
of the @language
member within a JSON object
in the @context
array.
{
"@context": [
"https://www.w3.org/2019/wot/td/v1",
{ "@language" : "en" }
],
"title": "MyThing",
"description": "Human readable information.",
...
"properties": {
"on": {
"title" : "On/Off",
"type": "boolean",
"forms": [...]
},
"status": {
"title" : "Status",
"type": "object",
...
"forms": [...]
}
},
...
}
The JSON members named titles
and
descriptions
are used within the TD document
to provide human-readable metadata in multiple languages
within a single TD document. All name-value
pairs of a MultiLanguage
Map MUST be serialized as
members of a JSON object, where the name is a well-formed
language tag as defined by [BCP47] and the
value is a human-readable string in the language indicated
by the tag. See §
5.3.1.7
MultiLanguage
for details.
All
MultiLanguage
object within a TD document
SHOULD contain the
same set of language members.
A TD snippet using titles
and
descriptions
at different levels is given
below:
{
"@context": "https://www.w3.org/2019/wot/td/v1",
"title": "MyThing",
"titles": {
"en":"MyThing",
"de": "MeinDing",
"ja" : "私の物",
"zh-Hans" : "我的东西",
"zh-Hant" : "我的東西"
},
"descriptions": {
"en":"Human readable information.",
"de": "Menschenlesbare Informationen.",
"ja" : "人間が読むことができる情報",
"zh-Hans" : "人们可阅读的信息",
"zh-Hant" : "人們可閱讀的資訊"
},
...
"properties": {
"on": {
"titles": {
"en": "On/Off",
"de": "An/Aus",
"ja": "オンオフ",
"zh-Hans": "开关",
"zh-Hant": "開關" },
"type": "boolean",
"forms": [...]
},
"status": {
"titles": {
"en": "Status",
"de": "Zustand",
"ja": "状態",
"zh-Hans": "状态",
"zh-Hant": "狀態" },
"type": "object",
...
"forms": [...]
}
},
...
}
TD instances may also combine the use of
title
and description
with
titles
and descriptions
.
When title
and
titles
or description
and
descriptions
are present within the same JSON
object, the values of title
and
description
MAY be seen as the default text.
When title
and
titles
or description
and
descriptions
are present in a TD document,
each title
and description
member
SHOULD have a
corresponding titles
and
descriptions
member, respectively. The
the language of the default text is indicated by the
default language, which is usually set by the creator of
the Thing Description instance.
{
"@context": [
"https://www.w3.org/2019/wot/td/v1",
{ "@language" : "de" }
],
"title": "MyThing",
"titles": {
"en":"MyThing",
"de": "MeinDing",
"ja" : "私の物",
"zh-Hans" : "我的东西",
"zh-Hant" : "我的東西"
},
"description": "Menschenlesbare Informationen.",
"descriptions": {
"en":"Human readable information.",
"de": "Menschenlesbare Informationen.",
"ja" : "人間が読むことができる情報",
"zh-Hans" : "人们可阅读的信息",
"zh-Hant" : "人們可閱讀的資訊"
},
...
"properties": {
"on": {
"title" : "An/Aus",
"titles": {
"en": "On/Off",
"de": "An/Aus",
"ja": "オンオフ",
"zh-Hans": "开关",
"zh-Hant": "開關" },
"type": "boolean",
"forms": [...]
},
"status": {
"title" : "Zustand",
"titles": {
"en": "Status",
"de": "Zustand",
"ja": "状態",
"zh-Hans": "状态",
"zh-Hant": "狀態" },
"type": "object",
...
"forms": [...]
}
},
...
}
Another possibility to set the default language is
through a language negotiation mechanism, such as the
Accept-Language
header field of HTTP.
In cases where
the default language has been negotiated, an
@language
member MUST be present to indicate the result of the
negotiation and the corresponding default language of the
returned content. When
the default language has been negotiated successfully, TD
documents SHOULD
include the appropriate matching values for the members
title
and description
in
preference to MultiLanguage
objects in
titles
and descriptions
members. Note
however that Things MAY choose to not support such
dynamically-generated TDs nor to support language
negotiation (e.g., because of resource
constraints).
version
All
name-value pairs of an instance of
VersionInfo
, where the name is a Vocabulary Term included in the Signature of VersionInfo
, MUST be serialized as JSON
members with the Vocabulary Term as
name.
A TD snippet of a version information object is given below:
{
...
"version": { "instance": "1.2.1" },
...
}
The version
member is intended as container
for additional application- and/or device-specific version
information based on TD Context
Extensions. See §
7.1
Semantic Annotations for details.
securityDefinitions
and
security
In a Thing
instance, the value assigned to
securityDefinitions
is a Map of
instances of SecurityScheme
. All name-value pairs
of a Map of SecurityScheme
instances
MUST be
serialized as members of the JSON object that results from
serializing the Map; the name of a pair MUST be serialized as a
JSON string and the value of the pair, an instance of
SecurityScheme
, MUST be serialized as a JSON object.
All name-value pairs of an instance
of one of the Subclasses of
SecurityScheme
, where the name is a Vocabulary Term included in the Signature of that Subclass or in the
Signature of
SecurityScheme
, MUST be serialized as members of the JSON
object that results from serializing the
SecurityScheme
Subclass's instance,
with the Vocabulary Term as
name.
The following TD snippet shows a simple security
configuration specifying basic username/password
authentication in the header. The value given for
in
is actually the Default Value (header
) and could be
omitted. A named security configuration must be given in
the securityDefinitions
map. That definition
must be activated by including its JSON name in the
security
member, which can be of type string
when only one definition is activated.
...
"securityDefinitions": {
"basic_sc": {
"scheme": "basic",
"in": "header"
}
},
"security": "basic_sc",
...
Here is a more complex example: a TD snippet showing
digest authentication on a proxy combined with bearer token
authentication on the Thing. In the
digest
scheme, the Default Value of in
(i.e.,
header
) is omitted, but still applies. Note
that the corresponding private security configuration such
as username/password and tokens must be configured in the
Consumer to interact successfully. When
activating multiple security definitions, the
security
member becomes an array.
...
"securityDefinitions": {
"proxy_sc": {
"scheme": "digest",
"proxy": "https://portal.example.com/"
},
"bearer_sc": {
"in":"header",
"scheme": "bearer",
"format": "jwt",
"alg": "ES256",
"authorization": "https://servient.example.com:8443/"
}
},
"security": ["proxy_sc", "bearer_sc"],
...
Security configuration in the TD is mandatory.
At least one security definition
MUST be activated
through the security
array at the Thing level
(i.e., in the TD root object). This configuration
can be seen as the default security mechanism required to
interact with the Thing. Security
definitions MAY also
be activated at the form level by including a
security
member in form objects, which
overrides (i.e., completely replace) all definitions
activated at the Thing level.
The nosec
security scheme is provided for
the case that no security is needed. The minimal security
configuration for a Thing is activation
of the nosec
security scheme at the Thing
level, as shown in the following example:
{
"@context": "https://www.w3.org/2019/wot/td/v1",
"id": "urn:dev:ops:32473-Thing-1234",
"title": "MyThing",
"description": "Human readable information.",
"support": "https://servient.example.com/contact",
"securityDefinitions": { "nosec_sc": { "scheme": "nosec" }},
"security": "nosec_sc",
"properties": {...},
"actions": {...},
"events": {...},
"links": [...]
}
To give a more complex example, suppose we have a
Thing where all Interaction Affordances require
basic authentication except for one, for which no
authentication is required. For the status
Property and the toggle
Action,
basic
authentication is required and defined
at the Thing level. For the overheating
Event,
however, no authentication is required, and hence the
security configuration is overridden at the form level.
{
...
"securityDefinitions": {
"basic_sc": {"scheme": "basic"},
"nosec_sc": {"scheme": "nosec"}
},
"security": ["basic_sc"],
...
"properties": {
"status": {
...
"forms": [{
"href": "https://mylamp.example.com/status"
}]
}
},
"actions": {
"toggle": {
...
"forms": [{
"href": "https://mylamp.example.com/toggle"
}]
}
},
"events": {
"overheating": {
...
"forms": [{
"href": "https://mylamp.example.com/oh",
"security": ["nosec_sc"]
}]
}
}
}
Security configurations can also can be specified for
different forms within the same Interaction Affordance. This may
be required for devices that support multiple protocols,
for example HTTP and CoAP [RFC7252],
which support different security mechanisms. This is also
useful when alternative authentication mechanisms are
allowed. Here is a TD snippet demonstrating three possible
ways to activate a Property affordance: via HTTPS with
basic authentication, via HTTPS via digest authentication,
or via CoAPS with a pre-shared key (PSK). In other words,
the use of different security configurations within
multiple forms provides a way to combine security
mechanisms in an "OR" fashion. In contrast, putting
multiple security configurations in the same
security
member combines them in an "AND"
fashion, since in that case they would all need to be
satisfied to allow activation of the Interaction Affordance. Note that
activating one (default) configuration at the Thing level
is still mandatory.
{
...
"securityDefinitions": {
"basic_sc": { "scheme": "basic" },
"digest_sc": { "scheme": "digest", "qop": "auth", "in": "header" },
"psk_sc": { "scheme": "psk" }
},
"security": ["basic_sc"],
...
"properties": {
"status": {
...
"forms": [{
"href": "https://mylamp.example.com/status"
}, {
"href": "https://mylamp.example.com/status",
"security": ["digest_sc"]
}, {
"href": "coaps://mylamp.example.com:5684/status",
"security": ["psk_sc"]
}]
}
},
...
}
As another more complex example, OAuth2 makes use of
scopes. These are identifiers that may appear in tokens and
must match with corresponding identifiers in a resource to
allow access to that resource (or Interaction Affordance in the case
of W3C WoT).
For example, in the following, the status
Property can be read by Consumers using
bearer tokens containing the scope limited
,
but the configure
Action can only be invoked
with a token containing the special
scope.
Scopes are not identical to roles, but are often associated
with them; for example, perhaps only those in an
administrative role are authorized to perform "special"
interactions. Tokens can have more than one scope. In this
example, an administrator would probably be issued tokens
with both the limited
and special
scopes, while ordinary users would only be issued tokens
with the limited
scope.
{
...
"securityDefinitions": {
"oauth2_sc": {
"scheme": "oauth2",
...
"flow": "implicit",
"authorization": "https://example.com/authorization",
"scopes": ["limited", "special"]
}
},
"security": ["oauth2_sc"],
...
"properties": {
"status": {
...
"forms": [{
"href": "https://scopes.example.com/status",
"scopes": ["limited"]
}]
}
},
"action": {
"configure": {
...
"forms": [{
"href": "https://scopes.example.com/configure",
"scopes": ["special"]
}]
}
},
...
}
properties
The value assigned to properties
in a
Thing
instance is a Map of instances of
PropertyAffordance
. All name-value pairs
of a Map of PropertyAffordance
instances
MUST be
serialized as members of the JSON object that results from
serializing the Map; the name of a pair MUST be serialized as a
JSON string and the value of the pair, an instance of
PropertyAffordance
, MUST be serialized as a JSON object.
All name-value pairs of an instance of
PropertyAffordance
, where the name is a
Vocabulary Term included in (one
of) the Signatures of
PropertyAffordance
,
InteractionAffordance
, or
DataSchema
, MUST be serialized as members of the JSON
object that results from serializing the
PropertyAffordance
instance, with the Vocabulary Term as name. See §
6.3.10
Data Schemas for details on serializing DataSchema
instances.
The value assigned to
forms
in an instance of
PropertyAffordance
MUST be serialized as a JSON array containing
one or more JSON object serializations as defined in
§
6.3.9
forms
.
A snippet for two Property affordances is given below:
actions
In a Thing
instance, the value assigned to
actions
is a Map of instances of
ActionAffordance
. All name-value pairs of
a Map of ActionAffordance
instances
MUST be
serialized as members of the JSON object that results from
serializing the Map; the name of a pair MUST be serialized as a
JSON string and the value of the pair, an instance of
ActionAffordance
, MUST be serialized as a JSON object.
All
name-value pairs of an instance of
ActionAffordance
, where the name is a Vocabulary Term included in (one of) the Signatures of ActionAffordance
or
InteractionAffordance
, MUST be serialized as members of the JSON
object that results from serializing the
ActionAffordance
instance, with the Vocabulary Term as name.
The values assigned to
input
and output
in an instance
of ActionAffordance
MUST be serialized as JSON objects. They
rely on the the Class DataSchema
, whose serialization
is defined in §
6.3.10
Data Schemas.
The value assigned to forms
in an instance of ActionAffordance
MUST be serialized as a JSON
array containing one or more JSON object serializations as
defined in §
6.3.9
forms
.
A TD snippet of an Action affordance is given below:
events
In a Thing
instance, the value assigned to
events
is a map of instances of
EventAffordance
. All name-value pairs of
a Map of EventAffordance
instances
MUST be
serialized as members of the JSON object that results from
serializing the Map; the name of a pair MUST be serialized as a
JSON string and the value of the pair, an instance of
EventAffordance
, MUST be serialized as a JSON object.
All
name-value pairs of an instance of
EventAffordance
, where the name is a Vocabulary Term included in (one of) the Signatures of EventAffordance
or
InteractionAffordance
, MUST be serialized as members of the JSON
object that results from serializing the
EventAffordance
instance, with the Vocabulary Term as name.
The values assigned to
subscription
, data
, and
cancellation
in an instance of
EventAffordance
MUST be serialized as JSON objects. They
rely on the the Class DataSchema
, whose serialization
is defined in §
6.3.10
Data Schemas.
The
value assigned to forms
in an instance of
EventAffordance
MUST be serialized as a JSON array containing
one or more JSON object serializations as defined in
§
6.3.9
forms
.
A TD snippet of an Event object is given below:
Event affordances have been defined in a flexible
manner, in order to adopt existing (e.g., WebSub) or
customer-oriented event mechanisms (e.g., Webhooks). For
this reason, subscription
and
cancellation
can be defined according to the
desired mechanism. Please find further details in
[WoT-Binding-Templates].
Example §
A.3
Webhook Event Example illustrates how Events can
use subscription
and cancellation
to describe Webhooks.
links
All
name-value pairs of an instance of Link
, where
the name is a Vocabulary Term included in the
Signature of Link
,
MUST be serialized as
members of the JSON object that results from serializing
the Link
instance, with the Vocabulary Term as name.
A TD snippet of a link object in the links
array is given below:
forms
All
name-value pairs of an instance of Form
, where
the name is a Vocabulary Term included in the
Signature of Form
,
MUST be serialized as
members of the JSON object that results from serializing
the Form
instance, with the Vocabulary Term as name.
If required, form objects MAY be supplemented with protocol-specific Vocabulary Terms identified with a prefix. See also § 8.3 Protocol Bindings.
A TD snippet of a form object in the forms
array is given below:
href
may also carry a URI that contains
dynamic variables such as p and d in
http://192.168.1.25/left?p=2&d=1. In that case the URI
can be defined as 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 Class DataSchema
,
whose serialization is defined in §
6.3.10
Data Schemas.
A TD snippet using a URI Template and
uriVariables
is given below:
{
"@context": [
"https://www.w3.org/2019/wot/td/v1",
{ "eg": "http://www.example.org/iot" }
],
...
"actions": {
"LeftDown": {
...
"uriVariables": {
"p" : { "type": "integer", "minimum": 0, "maximum": 16, "@type": "eg:SomeKindOfAngle" },
"d" : { "type": "integer", "minimum": 0, "maximum": 1, "@type": "eg:Direction" }
},
"forms": [{
"href" : "http://192.168.1.25/left{?p,d}",
"htv:methodName": "GET"
}]
},
...
},
...
}
The contentType
member is used to assign a
media types [IANA-MEDIA-TYPES] including media
type parameters as attribute-value pairs separated by a
;
character. Example:
...
"contentType" : "text/plain; charset=utf-8",
...
In some use cases, the form metadata of the Interaction Affordance not only
describes the request, but also provides metadata for the
expected response. For instance, an Action
takePhoto
defines an input
schema
to submit parameter settings of a camera (aperture
priority, timer, etc.) using JSON for the request payload
(i.e., "contentType": "application/json"
). The
output of this action is the photo taken, which is
available in JPEG format, for example. In such cases, the
response
member is used to indicate the
representation format of the response payload (e.g.,
"contentType": "image/jpeg"
). Here no
output
schema is required, as the content type
fully specifies the representation format.
If present, the value assigned to
response
in an instance of Form
MUST be a JSON
object. If present, the response object
MUST contain a
contentType
member as defined in the Class definition of ExpectedResponse
.
A form
snippet with the
response
member is shown below based on the
takePhoto
Action described above:
{
...
"actions": {
"takePhoto": {
...
"forms": [{
"op": "invokeaction",
"href": "http://camera.example.com/api/snapshot",
"contentType": "application/json",
"response": {
"contentType": "image/jpeg"
}
}]
}
},
...
}
When forms
is present at the top level, it
can be used to describe meta interactions offered by a
Thing. For example, the operation types
"readallproperties" and "writeallproperties" are for meta
interactions with a Thing by which
Consumers can read and write all properties at
once. In the example below, a forms
member is
included in the TD root object and the Consumer can use the submission target
https://mylamp.example.com/allproperties
both
to read or write all Properties (i.e., on
,
brightness
, and timer
) of the
Thing in a single protocol transaction.
{
...
"properties": {
"on": {
"type": "boolean",
"forms": [...]
},
"brightness": {
"type": "number",
"forms": [...]
},
"timer": {
"type": "integer",
"forms": [...]
}
},
...
"forms": [{
"op": "readallproperties",
"href": "https://mylamp.example.com/allproperties",
"contentType": "application/json",
"htv:methodName": "GET"
}, {
"op": "writeallproperties",
"href": "https://mylamp.example.com/allproperties",
"contentType": "application/json",
"htv:methodName": "PUT"
}]
}
The data schemas of the WoT Thing Description defined
through the DataSchema
Class are
based on a subset of the JSON Schema terms [JSON-SCHEMA-VALIDATION].
Thus, serializations of the TD data schemas can be fed
directly into JSON Schema validator implementations to
validate the data exchanged with Things.
Data schema serialization applies to
PropertyAffordance
instances, the values
assigned to input
and output
in
ActionAffordance
instances, the values
assigned to subscription
, data
,
and cancellation
in
EventAffordance
instances, and the value
assigned to uriVariables
in instances of
Subclasses of InteractionAffordance
(when a form object
uses a URI Template).
All
name-value pairs of an instance of one of the Subclasses of DataSchema
, where the
name is a Vocabulary Term included in the
Signature of that Subclass or in the Signature of
DataSchema
, MUST be serialized as members of the JSON
object that results from serializing the
DataSchema
Subclass's instance,
with the Vocabulary Term as
name.
The value assigned to
properties
in an instance of
ObjectSchema
MUST be serialized as a JSON object.
The values assigned to
enum
, required
, and
oneOf
in an instance of
DataSchema
MUST be serialized as a JSON array.
The value assigned to
items
in an instance of
ArraySchema
MUST be serialized as a JSON object or a JSON
array containing JSON objects.
A TD snippet data schema members is given below. Note
that the surrounding object may be a data schema object
(e.g., for input
and output
) or a
Property object, which would contain additional
members.
The terms readOnly
and
writeOnly
can be used signal which data items
are exchanged in read interactions (i.e., when reading a
Property) and which in write interactions (i.e., when
writing a Property). This can be used as workaround when
Properties of an unconventional Thing exhibit
different data for reading and writing, which can be the
case when augmenting an existing device or service with a
Thing Description.
A TD snippet with the usage of readOnly
and
writeOnly
is given below:
...
"properties": {
"status": {
"description": "Read or write On/Off status.",
"type": "object",
"properties": {
"latestStatus": {
"type": "string",
"enum": ["On", "Off"],
"readOnly": true
},
"newStatusValue": {
"type": "string",
"enum": ["On", "Off"],
"writeOnly": true
}
},
forms: [...]
}
}
...
When the status
Property is read, the
status data is returned using a latestStatus
member in the payload. To update the status
Property, the new value must be provided through a
newStatusValue
member in the payload.
As an additional feature, a Thing Description instance
allows the usage of a unit
member within data
schemas. This can be used to associate a unit of measure to
a data item. Its string value can be selected freely,
however, it is recommended to select units based on
existing definitions by integrating the corresponding
namespace (e.g., from Smart Appliances REFerence (SAREF)
ontology or Ontology of units of Measure (OM)). See
§
7.
TD Context Extensions for details.
The JSON-based serialization of Thing Descriptions is
identified by the media type application/td+json
or the CoAP Content-Format ID T.B.D.
(see
§
10.
IANA Considerations).
CoAP-based WoT implementations can use the
experimental Content-Format 65100
until the
final Content-Format ID has been assigned.
This section is non-normative.
In addition to the standard Vocabulary definitions in § 5. TD Information Model, the WoT Thing Description offers the possibility to add context knowledge from additional namespaces. This mechanism can be used to enrich the Thing Description instances with additional (e.g., domain-specific) semantics. It can also be used to import additional Protocol Bindings or new security schemes in the future.
For such TD Context Extensions, the Thing
Descriptions use the @context
mechanism known from
JSON-LD [json-ld11]. When using TD
Context Extensions, the value of @context
of
the Class Thing
is an Array with additional
elements of type anyURI
identifying JSON-LD
context files or Map containing namespace IRIs as
defined in §
5.3.1.1
Thing
.
The serialization rules for complex types in §
6.1
Mapping to JSON Types define the serialization of an
extended @context
name-value pair. A snippet with
TD Context Extensions is given below:
{
"@context": [
"https://www.w3.org/2019/wot/td/v1",
{
"iot": "http://example.org/iot",
"cov": "http://www.example.org/coap-binding#"
},
"https://schema.org/"
],
...
}
This section is non-normative.
TD Context Extensions allow for
additional Vocabulary Terms to a Thing
Description instance. If the included namespaces are based on
Class definitions such as those provided by the RDF
Schema or OWL, they can be used to annotate any Class instance of a Thing Description semantically
by associating the instance to a such an external Class definition. This is done by assigning a
Class name to the @type
name-value
pair or including Class name in its Array value for multiple associations/annotations.
Following the serialization rules in §
6.1
Mapping to JSON Types, @type
is either
serialized as JSON string or as JSON array.
@type
is the JSON-LD keyword [json-ld11] used to set the type of a
node.
TD Context Extensions also allow the inclusion of additional name-value pairs and well-defined values within any Class instance of a Thing Description. These pairs and values are defined through the included Vocabulary Terms and are serialized as additional members in the corresponding JSON objects or values of existing members, respectively. Examples are additional version metadata for the Thing or units of measure for data items.
As an example, the TD snippet given below extends the version information container by adding version numbers for the hardware and firmware of the Thing, semantically annotates a Property, and uses a well-defined value for the data schema unit.
{
"@context": [
"https://www.w3.org/2019/wot/td/v1",
{
"v": "http://www.example.org/versioningTerms#",
"saref": "https://w3id.org/saref#",
"om": "http://www.wurvoc.org/vocabularies/om-1.8/"
}
],
"@type": "Thing",
"version": {
"instance": "1.2.1",
"v:firmware": "0.9.1",
"v:hardware": "1.0"
},
...
"properties": {
"temperature": {
"@type": "saref:Temperature",
"description": "Temperature value of the weather station",
"type": "number",
"minimum": -32.5,
"maximum": 55.2,
"unit": "om:degree_Celsius",
"forms": [...]
},
...
},
...
}
In many cases, context extension may be used to annotate
pieces of a data schema, as in the TD snippet below. The
example references SSN/SOSA [vocab-ssn] and
OM 1.8, an ontology for units of measure [Rijgersberg-et-al-2013].
Note that object assigned to temperature
is a
data schema and not the actual temperature property of the
physical world object. More details on modeling the physical
world can be found in Appendix §
D.2
Thing Description Ontology.
{
"@context": [
"https://www.w3.org/2019/wot/td/v1",
{
"sosa": "http://www.w3.org/ns/sosa/",
"ssn": "http://www.w3.org/ns/ssn/",
"om": "http://www.wurvoc.org/vocabularies/om-1.8/"
}
],
"@type": "Thing",
"id": "urn:dev:ops:32473-WoTLamp-1234",
"sosa:observes": {
"@id": "urn:dev:ops:32473-WoTStation-1234/temperature",
"@type": "om:Temperature"
},
...
"properties": {
"temperature": {
"ssn:forProperty": "urn:dev:ops:32473-WoTStation-1234/temperature",
"description": "Temperature measurement of the weather station",
"type": "number",
"minimum": -32.5,
"maximum": 55.2,
"unit": "om:degree_Celsius",
"forms": [...]
},
...
},
...
}
This section is non-normative.
With the TD Context Extensions in a Thing
Description, the communication metadata can be supplemented
or new Protocol Bindings added through
additional Vocabulary Terms serialized into
JSON objects representing a Form
instance. (see
also §
8.3
Protocol Bindings).
The following TD example uses a fictional CoAP Protocol Binding, as no such Protocol Binding is available at the time of
writing this specification. This TD Context
Extension assumes that there is a CoAP RDF vocabulary
similar to [HTTP-in-RDF10]
that is accessible via the namespace
http://www.example.org/coap-binding#
. 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).
This section is non-normative.
Finally, new security schemes that are not included in
§
5.3.3
Security Vocabulary Definitions can be imported
using the TD Context Extension mechanism. This
example uses a fictional ACE security scheme based on
[draft-ietf-ace-oauth-authz]
that is, for this example, defined by the namespace at
http://www.example.org/ace-security#
. Note that
such additional security schemes must be Subclasses of the Class SecurityScheme
.
{
@context: [
"https://www.w3.org/2019/wot/td/v1",
{
"cov": "http://www.example.org/coap-binding#",
"ace": "http://www.example.org/ace-security#"
}
],
...
"securityDefinitions": {
"ace_sc": {
"scheme": "ace:ACESecurityScheme",
...
"ace:as": "coaps://as.example.com/token",
"ace:audience": "coaps://rs.example.com",
"ace:scopes": ["limited", "special"],
"ace:cnonce": true
}
},
"security": ["ace_sc"],
"properties": {
"status": {
...
"forms": [{
"op": "readproperty",
"href": "coaps://rs.example.com/status",
"contentType": "application/cbor",
"cov:methodName": "GET",
"ace:scopes": ["limited"]
}]
}
},
"action": {
"configure": {
...
"forms": [{
"op": "invokeaction",
"href": "coaps://rs.example.com/configure",
"contentType": "application/cbor",
"cov:methodName": "POST",
"ace:scopes": ["special"]
}]
}
},
...
}
Note that all security schemes defined in § 5.3.3 Security Vocabulary Definitions are already part of the TD context and need not to be included through a context extension.
The following assertions relate to the behavior of components of a WoT system, as opposed to the representation or information model of the TD. However, note that TDs are descriptive, and may in particular be used to describe pre-existing network interfaces. In these cases, assertions cannot be made that constrain the behavior of such pre-existing interfaces. Instead, the assertions must be interpreted as constraints on the TD to accurately represent such interfaces.
To enable secure interoperation, security configurations must accurately reflect the requirements of the Thing:
The data schemas provided in the TD should accurately represent the data payloads returned and accepted by the described Thing in the interactions specified in the TD. 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. In general, Things are described by WoT Thing Descriptions, but Consumers are constrained to follow WoT Thing Descriptions when interacting with Things.
A Protocol Binding is the mapping from
an Interaction Affordance to concrete
messages of a specific protocol such as HTTP [RFC7231],
CoAP [RFC7252],
or MQTT [MQTT]. Protocol Bindings of Interaction Affordances are
serialized as forms
as defined in §
6.3.9
forms
.
Every form in a WoT Thing Description must have a
submission target, given by the href
member. The
URI scheme of this submission target indicates what Protocol Binding the Thing implements
[WoT-Architecture].
For instance, if the target starts with http
or
https
, a Consumer can then
infer the Thing implements the HTTP Protocol Binding and it should expect HTTP-specific
terms in the form instance (see next section, §
8.3.1
HTTP Protocol Binding).
href
member.Per default the Thing Description supports the HTTP
Protocol Binding and includes the
HTTP RDF vocabulary set definitions from [HTTP-in-RDF10] and
can be directly used within TD instances by the usage of
the prefix htv
, which points to
http://www.w3.org/2011/http#
.
To interact with a Thing that
implements the HTTP Protocol Binding, a
Consumer needs to know what HTTP method to use
when submitting a form. In the general case, a Thing
Description can explicitly include a term indicating the
method, i.e., htv:methodName
. For the sake of
conciseness, the HTTP Protocol
Binding defines Default Values for
each operation type, which also aims at convergence of the
methods expected by Things (e.g., GET to
read, PUT to write). When no method is indicated in a
form representing an HTTP Protocol
Binding, a Default Value
MUST be assumed as
shown in the following table.
Vocabulary term | Default value | Context |
---|---|---|
htv:methodName |
GET |
Form with operation type
readproperty |
htv:methodName |
PUT |
Form with operation type
writeproperty |
htv:methodName |
POST |
Form with operation type
invokeaction |
For example, the following Default Values should be assumed for forms in the introductory TD example:
The number of Protocol Bindings a Thing can implement is not restricted. Other Protocol Bindings (e.g., for CoAP, MQTT, or OPC UA) are intended to be standardized in separate documents such as a protocol Vocabulary similar to HTTP Vocabulary in RDF 1.0 [HTTP-in-RDF10] or specifications including Default Value definitions. Such protocols can be simply integrated into the TD by the usage of the context extension mechanism (§ 7. TD Context Extensions).
This section is non-normative.
In general the security measures taken to protect a WoT system will depend on the threats and attackers that system may face and the value of the assets needs to protect. A detailed discussion of security and privacy considerations for the Web of Things, including a threat model that can be adapted to various circumstances, is presented in the informative document [WOT-SECURITY-CONSIDERATIONS]. This section discusses only security and privacy risks and possible mitigations directly relevant to the WoT Thing Description.
A WoT Thing Description can describe both secure and insecure network interfaces. When a Thing Description is retro-fitted to an existing network interface, no change in the security status of the network interface is to be expected.
The use of a WoT Thing Description introduces the security and privacy risks given in the following sections. After each risk, we suggest some possible mitigations.
Deferencing the vocabulary files given in the
@context
member of any JSON-LD [json-ld11] document can be a privacy
risk. In the case of the WoT, an attacker can observe the
network traffic produced by such deferences and can use the
metadata of the dereference, such as the destination IP
address, to infer information about the device especially if
domain-specific vocabularies are used. This is a risk even if
the connection is encrypted, and is related to DNS privacy
leaks.
@context
member serving only as an
identifier of the (known) vocabulary. This requires the use
of strict version control, as updates should use a new URI
to ensure that existing URIs can refer to immutable data.
Use well-known standard vocabulary files whenever possible
to improve the chances that the context file will be
available locally to systems interpreting the metadata in a
Thing Description.The fact that a Thing Description contains a unique identifier means that should it be associated with a person it can be used to track that person and therefore pose a risk to privacy.
id
of a Thing. Specifically, the id
of a
Thing should not be fixed in hardware. This
does, however, conflict with the Linked Data ideal that
identifiers are fixed URIs. In many circumstances it will
be acceptable to only allow updates to identifiers if a
Thing is reinitialized. In this case as a
software entity the old Thing ceases to
exist and a new Thing is created. This can be
sufficient to break a tracking chain when, for example, a
device is sold to a new owner. Alternatively, if more
frequent changes are desired during the operational phase
of a device, a mechanism can be put into place to notify
only authorized users of the change in identifier when a
change is made. Note however that some classes of
devices, e.g. medical devices, may require immutable IDs
by law in some jurisdictions. In this case extra
attention should be paid to secure access to files, such
as Thing Descriptions, containing such immutable
identifiers.
As noted above, the id
member in a TD can
pose a privacy risk. However, even if the id
is
updated as described to mitigate its tracking risk, it may
still be possible to associate a TD with a particular
physical device, and from there to a person, through
fingerprinting.
Intercepting and tampering with TDs can be used to launch man-in-the-middle attacks, for example by rewriting URLs in TDs to redirect accesses to a malicious intermediary that can capture or manipulate data.
Intercepting and tampering with context files can be used to facilitate attacks by modifying the interpretation of vocabulary.
In many locales, in order to protect the privacy of users, there are legal requirements for the handling of personally identifiable information, that is, information that can be associated with a particular person. Such information can of course be generated by IoT devices directly. However, the existence and metadata of IoT devices (the kind of data stored in a Thing Description) can also contain or be used to infer personally identifiable information. This information can be as simple as the fact that a certain person owns a certain type of device, which can lead to additional inferences about that person.
application/td+json
Media Type
Registration
Since WoT Thing Description is
intended to be a pure data exchange format for Thing metadata, the serialization SHOULD NOT be passed
through a code execution mechanism such as JavaScript's
eval()
function to be parsed. An
(invalid) document may contain code that, when executed,
could lead to unexpected side effects compromising the
security of a system.
WoT Thing Descriptions can be evaluated with a JSON-LD 1.1 processor, which typically follows links to remote contexts (i.e., TD context extensions, see § 7. TD Context Extensions) automatically, resulting in the transfer of files without the explicit request of the Consumer for each one. If remote contexts are served by third parties, it may allow them to gather usage patterns or similar information leading to privacy concerns. While implementations on resource-constrained devices are expected to perform raw JSON processing (as opposed to JSON-LD processing), implementations in general SHOULD statically cache vetted versions of their supported context extensions and not to follow links to remote contexts. Supported context extensions can be managed through a secure software update mechanism instead.
Context Extensions (see § 7. TD Context Extensions) that are loaded from the Web over non-secure connections, such as HTTP, run the risk of being altered by an attacker such that they may modify the TD Information Model in a way that could compromise security. For this reason, Consumer again SHOULD vet and cache remote contexts before allowing the system to use it.
Given that JSON-LD processing usually includes the substitution of long IRIs with short terms, WoT Thing Descriptions may expand considerably when processed using a JSON-LD 1.1 processor and, in the worst case, the resulting data might consume all of the recipient's resources. Consumers SHOULD treat any TD metadata with due skepticism.
Rules for processing both conforming and non-conforming content are defined in this specification.
IANA assigns compact CoAP Content-Format IDs for media types in the CoAP Content-Formats subregistry within the Constrained RESTful Environments (CoRE) Parameters registry [RFC7252]. The Content-Format ID for WoT Thing Description is (t.b.d.) in the 256-9999 range (IETF Review or IESG Approval).
This section is non-normative.
Feature list of the Thing:
{
"@context": [
"https://www.w3.org/2019/wot/td/v1",
{
"cov": "http://www.example.org/coap-binding#"
}
],
"id": "urn:dev:ops:32473-WoTLamp-1234",
"title": "MyLampThing",
"description" : "MyLampThing uses JSON serialization",
"securityDefinitions": {"psk_sc":{"scheme": "psk"}},
"security": ["psk_sc"],
"properties": {
"status": {
"description" : "Shows the current status of the lamp",
"type": "string",
"forms": [{
"href": "coaps://mylamp.example.com/status",
"cov:methodName" : "GET"
}]
}
},
"actions": {
"toggle": {
"description" : "Turn on or off the lamp",
"forms": [{
"href": "coaps://mylamp.example.com/toggle",
"cov:methodName" : "POST"
}]
}
},
"events": {
"overheating": {
"description" : "Lamp reaches a critical temperature (overheating)",
"data": {"type": "string"},
"forms": [{
"href": "coaps://mylamp.example.com/oh",
"cov:methodName" : "GET",
"subprotocol" : "cov:observe"
}]
}
}
}
Feature list of the Thing:
{
"@context": "https://www.w3.org/2019/wot/td/v1",
"title": "MyLightSensor",
"id": "urn:dev:ops:32473-WoTLightSensor-1234",
"securityDefinitions": {"nosec_sc": {"scheme": "nosec"}},
"security": ["nosec_sc"],
"events": {
"lightSensor": {
"data":{"type": "integer"},
"forms": [
{
"href": "mqtt://192.168.1.187:1883/lightSensor",
"contentType" : "text/plain"
}
]
}
}
}
Feature list of the Thing:
temperature
which periodically
pushes the latest temperature value to the Consumer using a Webhook mechanism, where the
Thing sends POST requests to a callback URI
provided by the Consumer. To describe this, the
subscription
member defines a write-only
parameter callbackURL
, which must be
submitted through the subscribeevent
form.
The read-only parameter subscriptionID
is
returned by the subscription. The WebhookThing
will then periodically POST to this callback URI with a
payload defined by data
. To unsubscribe, the
Consumer has to submit the
unsubscribeevent
form, which makes use of a
URI Template. The uriVariables
member
informs the Consumer to include the
subscriptionID
string. This can be further
automated by using a context extension to include proper
semantic annotations. Alternatively, one can imagine
unsubscribing using the cancellation
member
similarly to subscription
and combine this
with a unsubscribeevent
form that describes
a POST request with payload to unsubscribe.
{
"@context": "https://www.w3.org/2019/wot/td/v1",
"id": "urn:dev:ops:32473-Thing-1234",
"title": "WebhookThing",
"description": "Webhook-based Event with subscription and unsubscribe form.",
"securityDefinitions": {"nosec_sc": {"scheme": "nosec"}},
"security": ["nosec_sc"],
"events": {
"temperature": {
"description": "Provides periodic temperature value updates.",
"subscription": {
"type": "object",
"properties": {
"callbackURL": {
"type": "string",
"format": "uri",
"description": "Callback URL provided by subscriber for Webhook notifications.",
"writeOnly": true
},
"subscriptionID": {
"type": "string",
"description": "Unique subscription ID for cancellation provided by WebhookThing.",
"readOnly": true
}
}
},
"data": {
"type": "number",
"description": "Latest temperature value that is sent to the callback URL."
},
"cancellation": {
"type": "object",
"properties": {
"subscriptionID": {
"type": "integer",
"description": "Required subscription ID to cancel subscription.",
"writeOnly": true
}
}
},
"uriVariables": {
"subscriptionID": { "type": "string" }
},
"forms": [
{
"op": "subscribeevent",
"href": "http://192.168.0.124:8080/events/temp/subscribe",
"contentType": "application/json",
"htv:methodName": "POST"
},
{
"op": "unsubscribeevent",
"href": "http://192.168.0.124:8080/events/temp/{subscriptionID}",
"htv:methodName": "DELETE"
}
]
}
}
}
This section is non-normative.
Below is a JSON Schema [JSON-SCHEMA-VALIDATION] document for syntactically validating Thing Description instances serialized in JSON based format.
The Thing Description defined by this document
allows for adding external vocabularies by using
@context
mechanism known from JSON-LD
[json-ld11], and the terms in those
external vocabularies can be used in addition to the terms
defined in §
5.
TD Information Model. For this reason, the below
JSON schema is intentionally non-strict in that regard. You
can replace the value of additionalProperties
schema property true
with false
in
different scopes/levels in order to perform a stricter
validation in case no external vocabularies are used.
Please note that some JSON Schema validation
tools do not support the iri
string format.
The following JSON Schema for validating TD instances does not require the terms with Default Values to be present. Thus the terms with Default Values are optional. (see also § 5.4 Default Value Definitions)
{
"title": "WoT TD Schema - 08 May 2019",
"description": "JSON Schema for validating TD instances against the TD model. TD instances can be with or without terms that have default values",
"$schema ": "http://json-schema.org/draft-07/schema#",
"definitions": {
"thing-context-w3c-uri": {
"type": "string",
"enum": [
"https://www.w3.org/2019/wot/td/v1"
]
},
"thing-context": {
"oneOf": [{
"type": "array",
"items": {
"anyOf": [{
"$ref": "#/definitions/anyUri"
},
{
"type": "object"
}
]
},
"contains": {
"$ref": "#/definitions/thing-context-w3c-uri"
}
},
{
"$ref": "#/definitions/thing-context-w3c-uri"
}
]
},
"type_declaration": {
"oneOf": [{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
},
"property_element": {
"type": "object",
"properties": {
"@type": {
"$ref": "#/definitions/type_declaration"
},
"description": {
"$ref": "#/definitions/description"
},
"descriptions": {
"$ref": "#/definitions/descriptions"
},
"title": {
"$ref": "#/definitions/title"
},
"titles": {
"$ref": "#/definitions/titles"
},
"uriVariables": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/dataSchema"
}
},
"forms": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/definitions/form_element_property"
}
},
"observable": {
"type": "boolean"
},
"writeOnly": {
"type": "boolean"
},
"readOnly": {
"type": "boolean"
},
"oneOf": {
"type": "array",
"items": {
"$ref": "#/definitions/dataSchema"
}
},
"unit": {
"type": "string"
},
"enum": {
"type": "array",
"minItems": 1,
"uniqueItems": true
},
"format": {
"type": "string"
},
"const": {},
"type": {
"type": "string",
"enum": [
"boolean",
"integer",
"number",
"string",
"object",
"array",
"null"
]
},
"items": {
"oneOf": [{
"$ref": "#/definitions/dataSchema"
},
{
"type": "array",
"items": {
"$ref": "#/definitions/dataSchema"
}
}
]
},
"maxItems": {
"type": "integer",
"minimum": 0
},
"minItems": {
"type": "integer",
"minimum": 0
},
"minimum": {
"type": "number"
},
"maximum": {
"type": "number"
},
"properties": {
"additionalProperties": {
"$ref": "#/definitions/dataSchema"
}
},
"required": {
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"forms"
],
"additionalProperties": true
},
"action_element": {
"type": "object",
"properties": {
"description": {
"type": "string"
},
"descriptions": {
"$ref": "#/definitions/descriptions"
},
"title": {
"$ref": "#/definitions/title"
},
"titles": {
"$ref": "#/definitions/titles"
},
"uriVariables": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/dataSchema"
}
},
"@type": {
"$ref": "#/definitions/type_declaration"
},
"forms": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/definitions/form_element_action"
}
},
"input": {
"$ref": "#/definitions/dataSchema"
},
"output": {
"$ref": "#/definitions/dataSchema"
},
"safe": {
"type": "boolean"
},
"idempotent": {
"type": "boolean"
}
},
"required": [
"forms"
],
"additionalProperties": true
},
"event_element": {
"type": "object",
"properties": {
"description": {
"type": "string"
},
"descriptions": {
"$ref": "#/definitions/descriptions"
},
"title": {
"$ref": "#/definitions/title"
},
"titles": {
"$ref": "#/definitions/titles"
},
"uriVariables": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/dataSchema"
}
},
"@type": {
"$ref": "#/definitions/type_declaration"
},
"forms": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/definitions/form_element_event"
}
},
"subscription": {
"$ref": "#/definitions/dataSchema"
},
"data": {
"$ref": "#/definitions/dataSchema"
},
"cancellation": {
"$ref": "#/definitions/dataSchema"
},
"type": {
"not": {}
},
"enum": {
"not": {}
},
"const": {
"not": {}
}
},
"required": [
"forms"
],
"additionalProperties": true
},
"form_element_property": {
"type": "object",
"properties": {
"href": {
"$ref": "#/definitions/anyUri"
},
"op": {
"oneOf": [{
"type": "string",
"enum": [
"readproperty",
"writeproperty",
"observeproperty",
"unobserveproperty"
]
},
{
"type": "array",
"items": {
"type": "string",
"enum": [
"readproperty",
"writeproperty",
"observeproperty",
"unobserveproperty"
]
}
}
]
},
"contentType": {
"type": "string"
},
"security": {
"type": "array",
"items": {
"type": "string"
}
},
"scopes": {
"type": "array",
"items": {
"type": "string"
}
},
"subProtocol": {
"type": "string",
"enum": [
"longpoll",
"websub",
"sse"
]
},
"response": {
"type": "object",
"properties": {
"contentType": {
"type": "string"
}
}
}
},
"required": [
"href"
],
"additionalProperties": true
},
"form_element_action": {
"type": "object",
"properties": {
"href": {
"$ref": "#/definitions/anyUri"
},
"op": {
"oneOf": [{
"type": "string",
"enum": [
"invokeaction"
]
},
{
"type": "array",
"items": {
"type": "string",
"enum": [
"invokeaction"
]
}
}
]
},
"contentType": {
"type": "string"
},
"security": {
"type": "array",
"items": {
"type": "string"
}
},
"scopes": {
"type": "array",
"items": {
"type": "string"
}
},
"subProtocol": {
"type": "string",
"enum": [
"longpoll",
"websub",
"sse"
]
},
"response": {
"type": "object",
"properties": {
"contentType": {
"type": "string"
}
}
}
},
"required": [
"href"
],
"additionalProperties": true
},
"form_element_event": {
"type": "object",
"properties": {
"href": {
"$ref": "#/definitions/anyUri"
},
"op": {
"oneOf": [{
"type": "string",
"enum": [
"subscribeevent",
"unsubscribeevent"
]
},
{
"type": "array",
"items": {
"type": "string",
"enum": [
"subscribeevent",
"unsubscribeevent"
]
}
}
]
},
"contentType": {
"type": "string"
},
"security": {
"type": "array",
"items": {
"type": "string"
}
},
"scopes": {
"type": "array",
"items": {
"type": "string"
}
},
"subProtocol": {
"type": "string",
"enum": [
"longpoll",
"websub",
"sse"
]
},
"response": {
"type": "object",
"properties": {
"contentType": {
"type": "string"
}
}
}
},
"required": [
"href"
],
"additionalProperties": true
},
"form_element_root": {
"type": "object",
"properties": {
"href": {
"$ref": "#/definitions/anyUri"
},
"op": {
"oneOf": [{
"type": "string",
"enum": [
"readallproperties",
"writeallproperties",
"readmultipleproperties",
"writemultipleproperties"
]
},
{
"type": "array",
"items": {
"type": "string",
"enum": [
"readallproperties",
"writeallproperties",
"readmultipleproperties",
"writemultipleproperties"
]
}
}
]
},
"contentType": {
"type": "string"
},
"security": {
"type": "array",
"items": {
"type": "string"
}
},
"scopes": {
"type": "array",
"items": {
"type": "string"
}
},
"subProtocol": {
"type": "string",
"enum": [
"longpoll",
"websub",
"sse"
]
},
"response": {
"type": "object",
"properties": {
"contentType": {
"type": "string"
}
}
}
},
"required": [
"href"
],
"additionalProperties": true
},
"description": {
"type": "string"
},
"title": {
"type": "string"
},
"descriptions": {
"type": "object"
},
"titles": {
"type": "object"
},
"dataSchema": {
"type": "object",
"properties": {
"@type": {
"$ref": "#/definitions/type_declaration"
},
"description": {
"$ref": "#/definitions/description"
},
"title": {
"$ref": "#/definitions/title"
},
"descriptions": {
"$ref": "#/definitions/descriptions"
},
"titles": {
"$ref": "#/definitions/titles"
},
"writeOnly": {
"type": "boolean"
},
"readOnly": {
"type": "boolean"
},
"oneOf": {
"type": "array",
"items": {
"$ref": "#/definitions/dataSchema"
}
},
"unit": {
"type": "string"
},
"enum": {
"type": "array",
"minItems": 1,
"uniqueItems": true
},
"format": {
"type": "string"
},
"const": {},
"type": {
"type": "string",
"enum": [
"boolean",
"integer",
"number",
"string",
"object",
"array",
"null"
]
},
"items": {
"oneOf": [{
"$ref": "#/definitions/dataSchema"
},
{
"type": "array",
"items": {
"$ref": "#/definitions/dataSchema"
}
}
]
},
"maxItems": {
"type": "integer",
"minimum": 0
},
"minItems": {
"type": "integer",
"minimum": 0
},
"minimum": {
"type": "number"
},
"maximum": {
"type": "number"
},
"properties": {
"additionalProperties": {
"$ref": "#/definitions/dataSchema"
}
},
"required": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"link_element": {
"type": "object",
"properties": {
"anchor": {
"$ref": "#/definitions/anyUri"
},
"href": {
"$ref": "#/definitions/anyUri"
},
"rel": {
"type": "string"
},
"type": {
"type": "string"
}
},
"required": [
"href"
],
"additionalProperties": true
},
"securityScheme": {
"oneOf": [{
"type": "object",
"properties": {
"@type": {
"$ref": "#/definitions/type_declaration"
},
"description": {
"$ref": "#/definitions/description"
},
"descriptions": {
"$ref": "#/definitions/descriptions"
},
"proxy": {
"$ref": "#/definitions/anyUri"
},
"scheme": {
"type": "string",
"enum": [
"nosec"
]
}
},
"required": [
"scheme"
]
},
{
"type": "object",
"properties": {
"@type": {
"$ref": "#/definitions/type_declaration"
},
"description": {
"$ref": "#/definitions/description"
},
"descriptions": {
"$ref": "#/definitions/descriptions"
},
"proxy": {
"$ref": "#/definitions/anyUri"
},
"scheme": {
"type": "string",
"enum": [
"basic"
]
},
"in": {
"type": "string",
"enum": [
"header",
"query",
"body",
"cookie"
]
},
"name": {
"type": "string"
}
},
"required": [
"scheme"
]
},
{
"type": "object",
"properties": {
"@type": {
"$ref": "#/definitions/type_declaration"
},
"description": {
"$ref": "#/definitions/description"
},
"descriptions": {
"$ref": "#/definitions/descriptions"
},
"proxy": {
"$ref": "#/definitions/anyUri"
},
"scheme": {
"type": "string",
"enum": [
"cert"
]
},
"identity": {
"type": "string"
}
},
"required": [
"scheme"
]
},
{
"type": "object",
"properties": {
"@type": {
"$ref": "#/definitions/type_declaration"
},
"description": {
"$ref": "#/definitions/description"
},
"descriptions": {
"$ref": "#/definitions/descriptions"
},
"proxy": {
"$ref": "#/definitions/anyUri"
},
"scheme": {
"type": "string",
"enum": [
"digest"
]
},
"qop": {
"type": "string",
"enum": [
"auth",
"auth-int"
]
},
"in": {
"type": "string",
"enum": [
"header",
"query",
"body",
"cookie"
]
},
"name": {
"type": "string"
}
},
"required": [
"scheme"
]
},
{
"type": "object",
"properties": {
"@type": {
"$ref": "#/definitions/type_declaration"
},
"description": {
"$ref": "#/definitions/description"
},
"descriptions": {
"$ref": "#/definitions/descriptions"
},
"proxy": {
"$ref": "#/definitions/anyUri"
},
"scheme": {
"type": "string",
"enum": [
"bearer"
]
},
"authorization": {
"$ref": "#/definitions/anyUri"
},
"alg": {
"type": "string",
"enum": [
"MD5",
"ES256",
"ES512-256"
]
},
"format": {
"type": "string",
"enum": [
"jwt",
"jwe",
"jws"
]
},
"in": {
"type": "string",
"enum": [
"header",
"query",
"body",
"cookie"
]
},
"name": {
"type": "string"
}
},
"required": [
"scheme"
]
},
{
"type": "object",
"properties": {
"@type": {
"$ref": "#/definitions/type_declaration"
},
"description": {
"$ref": "#/definitions/description"
},
"descriptions": {
"$ref": "#/definitions/descriptions"
},
"proxy": {
"$ref": "#/definitions/anyUri"
},
"scheme": {
"type": "string",
"enum": [
"psk"
]
},
"identity": {
"type": "string"
}
},
"required": [
"scheme"
]
},
{
"type": "object",
"properties": {
"@type": {
"$ref": "#/definitions/type_declaration"
},
"description": {
"$ref": "#/definitions/description"
},
"descriptions": {
"$ref": "#/definitions/descriptions"
},
"proxy": {
"$ref": "#/definitions/anyUri"
},
"scheme": {
"type": "string",
"enum": [
"public"
]
},
"identity": {
"type": "string"
}
},
"required": [
"scheme"
]
},
{
"type": "object",
"properties": {
"@type": {
"$ref": "#/definitions/type_declaration"
},
"description": {
"$ref": "#/definitions/description"
},
"descriptions": {
"$ref": "#/definitions/descriptions"
},
"proxy": {
"$ref": "#/definitions/anyUri"
},
"scheme": {
"type": "string",
"enum": [
"oauth2"
]
},
"authorization": {
"$ref": "#/definitions/anyUri"
},
"token": {
"$ref": "#/definitions/anyUri"
},
"refresh": {
"$ref": "#/definitions/anyUri"
},
"scopes": {
"type": "array",
"items": {
"type": "string"
}
},
"flow": {
"type": "string",
"enum": [
"implicit",
"password",
"client",
"code"
]
}
},
"required": [
"scheme"
]
},
{
"type": "object",
"properties": {
"@type": {
"$ref": "#/definitions/type_declaration"
},
"description": {
"$ref": "#/definitions/description"
},
"descriptions": {
"$ref": "#/definitions/descriptions"
},
"proxy": {
"$ref": "#/definitions/anyUri"
},
"scheme": {
"type": "string",
"enum": [
"apikey"
]
},
"in": {
"type": "string",
"enum": [
"header",
"query",
"body",
"cookie"
]
},
"name": {
"type": "string"
}
},
"required": [
"scheme"
]
},
{
"type": "object",
"properties": {
"@type": {
"$ref": "#/definitions/type_declaration"
},
"description": {
"$ref": "#/definitions/description"
},
"descriptions": {
"$ref": "#/definitions/descriptions"
},
"proxy": {
"$ref": "#/definitions/anyUri"
},
"scheme": {
"type": "string",
"enum": [
"pop"
]
},
"authorization": {
"$ref": "#/definitions/anyUri"
},
"format": {
"type": "string",
"enum": [
"jwt",
"jwe",
"jws"
]
},
"alg": {
"type": "string",
"enum": [
"MD5",
"ES256",
"ES512-256"
]
},
"in": {
"type": "string",
"enum": [
"header",
"query",
"body",
"cookie"
]
},
"name": {
"type": "string"
}
},
"required": [
"scheme"
]
}
]
},
"anyUri": {
"type": "string",
"format": "iri-reference"
}
},
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uri"
},
"title": {
"$ref": "#/definitions/title"
},
"titles": {
"$ref": "#/definitions/titles"
},
"properties": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/property_element"
}
},
"actions": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/action_element"
}
},
"events": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/event_element"
}
},
"description": {
"$ref": "#/definitions/description"
},
"descriptions": {
"$ref": "#/definitions/descriptions"
},
"version": {
"type": "object",
"properties": {
"instance": {
"type": "string"
}
},
"required": [
"instance"
]
},
"links": {
"type": "array",
"items": {
"$ref": "#/definitions/link_element"
}
},
"forms": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/definitions/form_element_root"
}
},
"base": {
"$ref": "#/definitions/anyUri"
},
"securityDefinitions": {
"type": "object",
"minProperties": 1,
"additionalProperties": {
"$ref": "#/definitions/securityScheme"
}
},
"support": {
"$ref": "#/definitions/anyUri"
},
"created": {
"type": "string"
},
"modified": {
"type": "string"
},
"security": {
"type": "array",
"minItems": 1,
"items": {
"type": "string"
}
},
"@type": {
"$ref": "#/definitions/type_declaration"
},
"@context": {
"$ref": "#/definitions/thing-context"
}
},
"required": [
"title",
"id",
"security",
"securityDefinitions",
"@context"
],
"additionalProperties": true
}
This section is non-normative.
A Thing Template is a description for a class of Things. It describes the properties, actions, events and common metadata that are shared for an entire group of Things, to enable the common handling of thousands of devices by a cloud server, which is not practical on a per-Thing basis. The Thing Template uses the same core vocabulary and information model from section 5.
The Thing Template enables:
The Thing Template is a logical description of the interface and possible interaction with devices (properties, actions and events), however it does not contain device-specific information, such as a serial number, GPS location, security information or concrete protocol endpoints.
Since a Thing Template does not contain a Protocol Binding to specific endpoints and does not define a specific security mechanism, the forms and securityDefinitions and security keys must not be present.
The same Thing Template can be implemented by Things from multiple vendors, a Thing can implement multiple Thing Templates, define additional metadata (vendor, location, security) and define bindings to concrete protocols. To avoid conflicts between properties, actions and events from different Thing Templates that are combined into a common Thing, all these identifiers must be unique within a Thing.
A common Thing Template for a class of devices enables writing applications across vendors and creates a more attractive market for application developers. A concrete Thing Description can implement multiple Thing Templates and thus can aggregate function blocks into a combined device.
The business models of cloud vendors are typically built on managing thousands of identical devices. All devices with the same Thing Template can be managed in the same way by cloud applications. It is easy to create multiple simulated devices, if the interface and the instance are treated separately.
Since a Thing Template is a subset of the Thing Description in which some optional and mandatory Vocabulary Terms
do not exist, however, it can be serialized in the same way and in the same formats as a Thing Description. Note that Thing Template instances cannot be validated in the same way as Thing Description instances due to some missing mandatory terms.
This section shows a Thing Template for a lamp and a Thing Template for a buzzer.
{
"@context": ["https://www.w3.org/2019/wot/td/v1"],
"@type" : "ThingTemplate",
"title": "Lamp Thing Template",
"description" : "Lamp Thing Template",
"properties": {
"status": {
"description" : "current status of the lamp (on|off)",
"type": "string",
"readOnly": true
}
},
"actions": {
"toggle": {
"description" : "Turn the lamp on or off"
}
},
"events": {
"overheating": {
"description" : "Lamp reaches a critical temperature (overheating)",
"data": {"type": "string"}
}
}
}
{
"@context": ["https://www.w3.org/2019/wot/td/v1"],
"@type" : "ThingTemplate",
"title": "Buzzer Thing Template",
"description" : "Thing template of a buzzer that makes noise for 10 seconds",
"actions": {
"buzz": {
"description" : "buzz for 10 seconds"
}
}
}
This section is non-normative.
To integrate a Thing Description instance with external knowledge and contextual information (like SAREF annotations), the use of JSON-LD 1.1 and its processing API [json-ld11-api], as well as RDF-based tools [rdf11-concepts] and libraries is highly recommended. This appendix introduces two non-normative elements of the Thing Description model based on RDF: the default JSON-LD context for TD and the TD ontology.
A TD document can be transformed into RDF by a standard
JSON-LD processor (to then be uploaded to an RDF store for
further processing). The following procedure loads the
context of the TD, given by the term @context
,
and generates RDF triples:
When applying this procedure to the introductory TD example (Example 2 ) with all Default Values, the following triples are obtained:
Most importantly, the JSON-LD context maps JSON strings to
RDF IRIs (hence, the notion of context: in two
different contexts, the same string can have different
meanings). The mapping here is rather
straightforward: every vocabulary of the TD information
model is defined its own namespace and every vocabulary term
maps to some name, appended to the corresponding namespace.
Strings that are not part of any vocabulary map to
RDF literals (strings with an optional datatype). For
instance, title
maps to
https://www.w3.org/2019/wot/td#title
and
MyLampThing
remains unchanged. Applying this
mapping is called context
expansion.
Then, after expanding JSON strings to full IRIs, all map
structures of the TD document must be turned into RDF
triples. In a simple case, a triple is produced for every
key/value pair in the map. For instance, the very first
triple of the example above was produced from
"title": "myLampThing"
.
Other cases rely on specific JSON-LD features. Most of these features were introduced in the 1.1 version of the standard and thus require an appropriate JSON-LD 1.1 implementation. They are listed below:
@
but in certain cases, it is more
convenient to define aliases for these keywords, e.g. to
more easily process JSON-LD document in a specific
programming environment. In the TD core vocabulary,
id
is an alias for @id
, which
must be an IRI used as the subject of triples when
producing RDF. For this reason, the first triples in the
example have urn:dev:ops:32473-WoTLamp-1234
as a subject instead of an arbitrary blank node.
properties
is
used both in the core vocabulary and in the data schema
vocabulary. Yet, a JSON string cannot map to two IRIs
simultaneously in the same context definition. The
mapping from properties
to
https://www.w3.org/2019/wot/json-schema#properties
must therefore be scoped to instances of
DataSchema
only.
status
, toggle
and
overheating
appear as keys in a map but they
do not produce triples in which they become predicates.
This special structure is called an index
map. Without any indication in the context, the index
key is lost when an index map is turned into RDF. To make
the transformation to RDF reversible, it is possible to
indicate that index keys should produce triples with a
given predicate. Each vocabulary can include an RDF term
for this purpose. In the core vocabulary, the property
https://www.w3.org/2019/wot/td#name
is used.
security
definitions.
JSON-LD 1.1 includes another indexing mechanism for that
purpose. In the above example,
securityDefinitions
does not produce any
triple.
The last two JSON-LD features (property-based data indexing and indexing without a predicate) are still experimental; they have not been published in any Editors' Draft yet.
As presented in the previous section, all Vocabulary Terms (including those denoting Classes) follow the RDF convention of belonging to a Vocabulary identified by a namespace IRI. As a result, the TD information model can be reformulated in the Web Ontology Language (OWL) [owl2-overview]. Class definitions become OWL axioms defined on the Vocabulary Terms of the TD model. The axioms that are particularly of interest in the present document are those of the TD ontology available under the TD namespace IRI, both as an RDF file and as a human-readable HTML documentation. Default Values cannot be directly translated to OWL, they are therefore ignored in the TD ontology.
The axioms included in the TD ontology may be used to
validate a TD but its primary purpose is to serve as an entry
point for a deeper semantic description of WoT Things that
would make clients behave in a more autonomous way, as
desired in WoT [wot-architecture].
A semantic description is nothing more than a description of
the physical world, in which WoT systems may have tangible
effects. OWL should be the preferred language for this
purpose. OWL is indeed a language to specify
ontologies, that is, conceptualizations of the
physical world. To this end, an ontology does not cover one
possible model of the physical world by constructing abstract
data structures. Instead, it provides necessary constraints
on all possible models of the world for these models to be
sound. This principle, at the basis of model theory,
is what the semantics of RDF (and OWL) is based on
[rdf11-mt]. In the following
diagram, because the only fact we know about
urn:dev:ops:32473-WoTLamp-1234
is that it is a
light switch with generic affordances, it could be any light
switch, be it mechanical, digital or even virtual.
As a consequence, the TD ontology is meant to be integrated into a larger ontology, as it would not suffice to describe physical world objects alone. An ontology is generally designed for a specific domain of application, like transportation or home automation. For the latter domain, the TD ontology can e.g. be integrated with SAREF, as illustrated in several examples in this document.
An intelligent WoT client can be assigned the task of
turning a light off in ontological terms, using SAREF. For
instance, the task could be expressed as a post-condition on
the saref:OnOffState
of some
saref:LightSwitch
. Assuming a server exposes the
TD of Example
2
, the client has two possibilities to perform this
task: it can either write the status
property as
off
or it can invoke the action
toggle
and see if the resulting
status
is indeed equal to off
.
Yet, in the TD example, the switch state is not directly
exposed. Assuming the client has no prior knowledge of the
meaning of status
, it must infer possible
operations from the semantic annotations available in the TD
and its domain-specific ontology, that includes SAREF. The
following ontological axioms can be formulated for SAREF, in
the OWL Manchester syntax [owl2-manchester-syntax]:
They respectively state that a light switch must have an
on/off state and that a toggle command must act on some
on/off state. They may seem intuitive to humans but it is
only possible for the client to know what to do from such
axioms. If we assume that a saref:GetCommand
always exposes the state of the Thing
, the
client can then automatically infer what form(s) to submit to
change the switch state: a writeproperty
on the
saref:GetCommand
or an invokeaction
on the saref:ToggleCommand
. Note that the result
of the operation cannot be known for certain, as the TD does
not expose its internal state. However, by selecting certain
models of the physical world, either by statistical means or
by further axiomatization, clients can still reach a certain
level of autonomy with an ontological approach.
descriptions
and titles
Vocabulary Terms).
@language
to declare a default
language and specified how to infer text direction in
human-readable metadata.InteractionPattern
Class to InteractionAffordance
.
@context
and optional
@type
Vocabulary Terms
to the Thing Class.
created
and
modified
Vocabulary
Terms to the Thing Class to provide information as to when the
TD instance was created or last modified, resp.
version
vocabulary term to the Thing Class to provide
version information.
readallproperties
,
writeallproperties
,
readmultipleproperties
, and
writemultipleproperties
.
@type
Vocabulary Term to the InteractionAffordance
Class to make semantic
annotations part of the Information Model.
uriVariables
Vocabulary Terms to InteractionAffordance
Class to describe URI
Template variables.
safe
and
idempotent
Vocabulary
Terms to the ActionAffordance Class to provide information about the
safeness and idempotency of the Action.
subscription
and
cancellation
Vocabulary
Terms to the EventAffordance Class to describe data that needs to be
passed upon subscription and cancellation, resp.
label
to title
in
the InteractionAffordance
Class to be consistent with
JSON Schema.
security
and
scopes
Vocabulary Terms
from the InteractionAffordance
Class to simplify mechanism.
writable
vocabulary term from the PropertyAffordance
Class and made Property affordances both readable
and writable by default; this can be overridden using
the op
vocabulary
term of the Form Class.
mediaType
to type
in the Link Class to
align with RFC 8288.
response
vocabulary term to the Form Class to
describe possible response messages.
mediaType
to
contentType
in the Form Class to reflect
that request might need to set also media type
parameters.
rel
to op
in the
Form Class to resolve
perceived conflicts with link relations.
unobserveproperty
to the
enumerated values for the op
vocabulary term.
@type
vocabulary term to the
DataSchema Class to make
semantic annotations part of the Information Model.
unit
vocabulary term to the
DataSchema Class to
provide unit metadata.
oneOf
vocabulary term to the
DataSchema Class to allow
for alternative schemas.
format
vocabulary term to the
DataSchema Class to allow
for pattern validation.
@type
vocabulary term to the SecurityScheme
Class to make semantic annotations part of the
Information Model.
securityDefinitions
vocabulary term to the Thing Class to declare
security definitions.
security
vocabulary term in the Thing and Form
Classes to be used to
activate declared security definitions.
securityDefinitions
and security
configuration is
mandatory.
Url
postfixes from
security scheme Vocabulary
Terms.
Changes from Second Public Working Draft are described in the Third Public Working Draft
The editors would like to thank Matthias Kovatsch, Michael Koster, Michael Lagally, Kazuyuki Ashimura, Ege Korkan, Daniel Peintner, Kawaguchi Toru, María Poveda, Dave Raggett, Kunihiko Toumura, Takeshi Yamada, Ben Francis, Manu Sporny, Klaus Hartke, Addison Phillips and Jose M. Cantera for providing contributions, guidance and expertise.
Also, many thanks to the W3C staff and all other active Participants of the W3C Web of Things Interest Group (WoT IG) and Working Group (WoT WG) for their support, technical input and suggestions that led to improvements to this document.