Web of Things (WoT) Scripting API

W3C Working Draft 5 April

This version:
https://www.w3.org/TR/2018/WD-wot-scripting-api-20180405/ https://www.w3.org/TR/2018/WD-wot-scripting-api-20181129/
Latest published version:
https://www.w3.org/TR/wot-scripting-api/
Latest editor's draft:
https://w3c.github.io/wot-scripting-api/
Previous version:
https://www.w3.org/TR/2017/WD-wot-scripting-api-20170914/ https://www.w3.org/TR/2018/WD-wot-scripting-api-20180405/
Editors:
Zoltan Kis ( Intel )
Kazuaki Nimura ( Fujitsu Ltd. )
Daniel Peintner ( Siemens AG )
Johannes Hund (Former Editor, when at Siemens AG)
Contributors:
In the GitHub repository
Repository:
We are on GitHub
File a bug

Abstract

The overall Web of Things (WoT) provides layered interoperability between concepts are described in the WoT Architecture document. The Web of Things is made of entities ( Thing by using s) that can describe their capabilities in a machine-interpretable format, the Thing Description (TD) and expose these capabilities through the WoT Interface , that is, network interactions modeled as Properties s. for reading and writing values, Action s to execute remote procedures with or without return values and Event s for signaling notifications.

This specification describes a programming interface representing the WoT Interface that allows scripts run on a Thing to discover and consume (retrieve) other Thing Description s and to expose Things characterized by WoT Interactions , i.e. Properties , Actions and Events . specified by a script.

Scripting is an optional "convenience" building block in WoT and it is typically used in gateways that are able to run a WoT Runtime and script management , providing a convenient way to extend WoT support to new types of endpoints and implement WoT applications like Thing Directory .

Status of This Document

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

Implementers need to be aware that this specification is considered unstable. Vendors interested in implementing this specification before it eventually reaches the Candidate Recommendation phase should subscribe to the repository and take part in the discussions.

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

Please contribute to this draft using the GitHub Issue feature of the WoT Scripting API repository. For feedback on security and privacy considerations, please use the WoT Security and Privacy Issues.

This document was published by the Web of Things Working Group as a Working Draft. This document is intended to become a W3C Recommendation.

Comments regarding this document are welcome. Please send them to public-wot-wg@w3.org ( subscribe , archives ).

Changes from the previous publication can be found in Appendix A . A diff-marked version of this document is also available for comparison purposes.

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

This document was produced by a group operating under the W3C Patent Policy . W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy .

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

1. Introduction

The overall WoT concepts are described in the WoT Architecture document. The Web of Things is made of entities ( Thing s) that can describe their capabilities in a machine-interpretable format, the provides layered interoperability based on how Thing Description (TD) s are modeled: as being "consumed" and expose these capabilities through the WoT Interface . Support for scripting is optional for WoT devices. "exposed".

By consuming a TD , a client Thing creates a runtime resource model that allows accessing the Properties , Actions and Events exposed by the server Thing . exposed on a remote device.

Exposing a Thing requires defining a Thing Description (TD) and instantiating a software stack needed to serve requests for accessing the exposed Properties , Actions and Events . This specification describes how to expose and consume Thing s by a script.

Note

Typically scripts are meant to be used on devices able to provide resources (with a WoT interface Interface ) for managing (installing, updating, running) scripts, such as bridges or gateways that expose and control simpler devices as WoT Thing s.

Note

This specification does not make assumptions on how the WoT Runtime handles and runs scripts, including single or multiple tenancy, script deployment and lifecycle management. The API already supports the generic mechanisms that make it possible to implement script management, for instance by exposing a manager Thing whose Actions (action handlers) implement script lifecycle management operations.

For an introduction on how scripts could be used in Web of Things , check the Primer document. For some background on API design decisions check the Rationale document.

2. Use Cases

This section is non-normative.

The following scripting use cases are supported in this specification:

2.1 Discovery

2.2 Consuming a Thing

2.3 Exposing a Thing

3. The WoT object

The WoT object is the API entry point and it is exposed by an implementation of the WoT Runtime . The WoT object does not expose properties, only methods for discovering, consuming and exposing a Thing .

Note

Browser implementations SHOULD use a namespace object such as wot , and navigator.wot . Node.js -like runtimes MAY provide the API object through the require() or import mechanism.

data-idl="" data-title="WoT">interface <span class=
"idlInterfaceID"><a data-no-default="" data-link-for="" data-lt=""
href="#dom-wot" class="internalDFN" data-link-type=
"dfn"> {
<span class="idlMethod" id="idl-def-wot-discover-filter" data-idl=
"" data-title="discover" data-dfn-for="wot">    <span class=
"idlMethType"><a href="#dom-observable" class="internalDFN"
data-link-type="dfn"><<a href=
"#dom-consumedthing" class="internalDFN" data-link-type=
"dfn"> <span class=
"idlMethName"><a data-no-default="" data-link-for="wot" data-lt=
"discover()|discover" href="#dom-wot-discover" class="internalDFN"
data-link-type="dfn">discover(<span class=
"idlParam">optional <a href=
"#dom-thingfilter" class="internalDFN" data-link-type=

data-idl="" data-title="WoT">// [SecureContext]
// [NamespaceObject]
interface 
data-link-for="" data-lt="" href="#dom-wot" class="internalDFN"
data-link-type="dfn">WoT {
  
data-link-type=
"dfn">Observable discover(optional 
"dfn">ThingFilter "idlParamName">filter
<span class="idlMethod" id="idl-def-wot-fetch-url" data-idl=""
data-title="fetch" data-dfn-for="wot">    <span class=
"idlMethType"><a href=
"https://heycam.github.io/webidl/#idl-promise">Promise<<a href="#dom-thingdescription"
class="internalDFN" data-link-type=

"idlParamName">filter);
  
"https://heycam.github.io/webidl/#idl-promise">Promise<
"dfn">ThingDescription> "fetch()|fetch" href="#dom-wot-fetch" class="internalDFN"
data-link-type="dfn">fetch(<span class=

"wot.fetch()|wot.fetch|fetch()|fetch" href="#dom-wot-fetch" class=
"internalDFN" data-link-type=
"dfn">fetch(
"idlParam">"https://heycam.github.io/webidl/#idl-USVString">USVString
<span class="idlMethod" id="idl-def-wot-consume-td" data-idl=""
data-title="consume" data-dfn-for="wot">    <span class=
"idlMethType"><a href="#dom-consumedthing" class="internalDFN"

"https://heycam.github.io/webidl/#idl-USVString">USVString url);
  "dfn"><a data-no-default=""
data-link-for="wot" data-lt="consume()|consume" href=

"dfn">ConsumedThing 
"#dom-wot-consume" class="internalDFN" data-link-type=
"dfn">consume<span class=
"idlParamType"><a href="#dom-thingdescription" class="internalDFN"
data-link-type=

"dfn">consume(
"dfn">ThingDescription "idlParamName">td
<span class="idlMethod" id="idl-def-wot-produce-model" data-idl=""
data-title="produce" data-dfn-for="wot">    <span class=
"idlMethType"><a href="#dom-exposedthing" class="internalDFN"

"idlParamName">td);
  "dfn"><a data-no-default=""
data-link-for="wot" data-lt="produce()|produce" href=
"#dom-wot-produce" class="internalDFN" data-link-type=
"dfn">produce<span class=
"idlParamType"><a href="#dom-thingmodel" class="internalDFN"

"dfn">ExposedThing produce(ThingModel model);
  
"https://heycam.github.io/webidl/#idl-promise">Promise<void> register(USVString directory, ExposedThing thing);
  
"https://heycam.github.io/webidl/#idl-promise">Promise<void> unregister(USVString directory, ExposedThing thing);
};
typedef object ThingFragment;
typedef object PropertyFragment;
typedef object ActionFragment;
typedef object EventFragment;
typedef object DataSchema;
typedef object SecurityScheme;
typedef object 
data-link-type=
"dfn">
};
<span class="idlTypedef" id="idl-def-thingdescription" data-idl=""
data-title="ThingDescription">typedef <span class=
"idlTypedefType"><a href=

"dfn">Link;
typedef object Form;
typedef 
"https://heycam.github.io/webidl/#idl-USVString">USVString "dfn">
<span class="idlTypedef" id="idl-def-thingmodel" data-idl=""
data-title="ThingModel">typedef <span class=
"idlTypedefType">(<a href="#dom-thingtemplate" class="internalDFN"
data-link-type="dfn"> or <a href=

"dfn">ThingDescription;
typedef (ThingFragment or 
"#dom-thingdescription" class="internalDFN" data-link-type=
"dfn">ThingDescription) 

ThingModel



;

Editor's note

The algorithms for the WoT methods will be specified later, including error handling and security considerations.

The ThingModel type represents either a ThingFragment , or a ThingDescription .

3.1 The discover() method

Starts the discovery process that will provide ConsumedThing ThingDescription objects s that match the optional argument filter of type ThingFilter . When the argument is not provided, starts the widest discovery the Thing Description and Protocol Bindings allow and support. Returns an [ Observable ](https://github.com/tc39/proposal-observable) object that can be subscribed to and unsubscribed from. The handler function provided to the Observable during subscription will receive an argument of type USVString representing a ThingDescription .

3.1.1 The DiscoveryMethod enumeration

"DiscoveryMethod">typedef <a href=

"DiscoveryMethod">typedef 
"https://heycam.github.io/webidl/#idl-DOMString">DOMString 

DiscoveryMethod



;

DiscoveryMethod represents the discovery type to be used:

3.1.2 The ThingFilter dictionary

The ThingFilter dictionary that represents the constraints for discovering Thing s as key-value pairs.

dictionary "dfn"> {
<span class="idlMember" id="idl-def-thingfilter-method" data-idl=""
data-title="method" data-dfn-for="thingfilter">    <span class=
"idlMemberType"><a href="#dom-discoverymethod" class="internalDFN"
data-link-type=
"dfn">      <span class=
"idlMemberName"><a data-no-default="" data-link-for="thingfilter"
data-lt="" href="#dom-thingfilter-method" class="internalDFN"
data-link-type="dfn"> = <span class=
"idlMemberValue">"any"
<span class="idlMember" id="idl-def-thingfilter-url" data-idl=""
data-title="url" data-dfn-for="thingfilter">    <span class=
"idlMemberType"><a href=
"https://heycam.github.io/webidl/#idl-USVString">USVString<a data-no-default=""

"dfn">ThingFilter {
  (DiscoveryMethod or DOMString) method = "any";
  
"https://heycam.github.io/webidl/#idl-USVString">USVString? 
data-link-for="thingfilter" data-lt="" href="#dom-thingfilter-url"
class="internalDFN" data-link-type=
"dfn">
<span class="idlMember" id="idl-def-thingfilter-query" data-idl=""
data-title="query" data-dfn-for="thingfilter">    <span class=
"idlMemberType"><a href=
"https://heycam.github.io/webidl/#idl-USVString">USVString<a data-no-default=""

"dfn">url;
  
"https://heycam.github.io/webidl/#idl-USVString">USVString? 
data-link-for="thingfilter" data-lt="" href=
"#dom-thingfilter-query" class="internalDFN" data-link-type=
"dfn">
<span class="idlMember" id="idl-def-thingfilter-constraints"
data-idl="" data-title="constraints" data-dfn-for=
"thingfilter">    <a href=
"https://heycam.github.io/webidl/#idl-sequence">sequence<a data-no-default=""
data-link-for="thingfilter" data-lt="" href=
"#dom-thingfilter-constraints" class="internalDFN" data-link-type=
"dfn">

"dfn">query;
  
data-link-type=
"dfn">ThingFragment? fragment;

};

The method property represents the discovery type that should be used in the discovery process. The possible values are defined by the DiscoveryMethod enumeration that can MAY be extended by string values defined by solutions (with no guarantee of interoperability).

Editor's note The DiscoveryMethod enumeration can be extended by the Thing Description with values that are not specified here. This extensibility of DiscoveryMethod by proprietary or private methods is a working assumption until consensus is formed and may be removed later.

The url property represents additional information for the discovery method, such as the URL of the target entity serving the discovery request, such as for instance a Thing Directory (if method is "directory" ) or a Thing. Thing (otherwise).

The query property represents a query string accepted by the implementation, for instance a SPARQL or JSON query. Support may be implemented locally in the WoT Runtime or remotely as a service in a Thing Directory .

The constraints fragment property represents additional information a ThingFragment dictionary used for the discovery matching property by property against discovered Thing s.

The discover(filter) method in MUST run the form of a list of sets of property-value pairs (dictionaries). The list elements (dictionaries) are in OR relationship, following steps:

  1. If invoking discover() is not allowed for the current scripting context for security reasons, throw SecurityError and within a constraint dictionary terminate these steps.
  2. Return an Observable obs and execute the key-value pairs are next steps in AND relationship. Implementations SHOULD make parallel .
  3. If obs.subscribe(handler, errorHandler, complete) is called, execute the following mapping from sub-steps:
    1. If the constraint dictionaries first argument handler is not defined or it is not a function, throw TypeError and terminate the algorithm. Otherwise configure handler to be invoked when a discovery hit happens.
    2. If the second argument errorHandler is defined, but it is not a function, throw SemanticAnnotations TypeError : for each property-value pair and terminate these steps. Otherwise if defined, save it to be invoked in error conditions.
    3. If the third argument onComplete is defined, but it is not a constraint dictionary, function, throw TypeError and terminate these steps. Otherwise if defined, save it to be invoked when the discovery process finished for other reasons than having been canceled.
    4. Each property name in If filter.query is defined, pass it as an opaque string to the constraint dictionary SHOULD underlying implementation to be matched against discovered items. The underlying implementation is responsible to parse it e.g. as a SPARQL or JSON query and match it against the either Thing Description s found during the discovery process. If queries are not supported, implementations SHOULD throw a name NotSupported property of a error and terminate these steps.
    5. If filter.fragment is defined, and if it contains other properties than the ones defined in SemanticType ThingFragment on , throw TypeError and terminate these steps. Otherwise save the target object for matching the discovered items against it.
    6. Request the underlying platform to start the discovery process, with the following parameters:
      • If filter.method is not defined or the value is "any" , use the widest discovery method supported by the underlying platform.
      • Otherwise if filter.method is "local" , use the local Thing Directory object, for discovery. Usually that defines Thing s deployed in the same device, or connected to the name of device in slave mode (e.g. sensors connected via Bluetooth or a Property on serial connection).
      • Otherwise if filter.method is "directory" , use the target remote Thing . Directory specified in filter.url .
      • When Otherwise if filter.method is "multicast" , use all the name matches, multicast discovery protocols supported by the values are compared. underlying platform.
  4. Whenever a new item td is discovered by the underlying platform, run the following sub-steps:
    1. If filter.query is defined, check if td is a match for the values match, query. The matching algorithm is encapsulated by implementations. If that returns false , discard td and continue the constraint discovery process.
    2. If filter.fragment is matched. defined, for each property defined in it, check if that property exists in td and has the same value. If this is false in any checks, discard td and continue the discovery process.
    3. Editor's note Constraints are experimental feature, implementations are
    4. Otherwise if td has not required to support them. Editor's note Semantic annotations need revisiting been discarded in order to simplify their representation. In the [ WOT-TD ] specification they represent previous steps, invoke the handler function with td as parameter.
  5. Whenever an error occurs during the discovery process, and if errorHandler is defined, invoke it with an argument of type @type Error construct. At the moment only whose @context , message property is set to @type UnknownError unless there was an error code provided by the Protocol Bindings , in which case set it to that value.
  6. When the discovery process is finished, and if onComplete is defined, invoke it run the cancel discovery steps.
  7. When the @id obs.unsubscribe() constructs are used in method is called, run the TD . following cancel discovery steps:
    1. Request the underlying platform to stop the discovery process. If this returns an error, or if it is not possible, for instance when discovery is based on open ended multicast requests, the implementation SHOULD discard subsequent discovered items.
    2. Set obs.closed to false .

3.2 The fetch() method

Accepts an url argument of type USVString that represents a URL (e.g. "file://..." or "https://..." ) and returns a Promise that resolves with a ThingDescription . (a serialized JSON-LD document of type USVString ).

3.3

The ThingDescription fetch(url) type Representation of method MUST run the Thing Description , standardized following steps:

  1. Return a Promise promise and execute the next steps in parallel .
  2. If invoking fetch() is not allowed for the Wot Things current scripting context for security reasons, reject promise with SecurityError and terminate these steps.
  3. If the argument url is not a URL, reject promise with TypeError and terminate these steps.
  4. Make a request to fetch the content of url as described by the Protocol Bindings and wait for the reply. Implementations encapsulate the fetching process and the accepted media types (such as application/td+json ), as far as a valid Thing Description specification. can be obtained as defined in [ Note WOT-TD In this version of ]. Let td be the API, Thing Description s are represented string-serialized from the returned content, as opaque strings, denoting a serialized form, for instance JSON or JSON-LD. See Issue 38 specified in the Thing Description serialization .
  5. If there was an error during the request, reject promise with an Error object error with error.message set to the error code seen by the Protocol Bindings and Issue 45 . terminate these steps.
  6. Otherwise resolve promise with td and terminate these steps.

3.4 3.3 The consume() method

Accepts an td argument of type ThingDescription and returns a ConsumedThing object instantiated based on parsing that description.

The consume(td) method must run the following steps:

  1. If the argument td is not a string, throw a TypeError and terminate these steps.
  2. Let stub be the result of running the TD parsing algorithm with td as argument. If that throws an error, re-throw the error and terminate these steps.
  3. If stub does not have an own property that is defined in ThingFragment with a default value, add that property and value to stub .
  4. Create a ConsumedThing object thing initialized from stub that implements Observable .
  5. Add the read() and write() methods to the ThingProperty elements so that they make requests to access the remote Thing s and wait for the reply, as defined by the Protocol Bindings . Also, all ThingProperty elements SHOULD implement Observable , i.e. define a subscribe() method that should make request to observe the given Properties as defined by the Protocol Bindings .
  6. Add the invoke() methods to the ThingAction elements so that they make requests to the remote Thing to invoke its actions, as defined by the Protocol Bindings .
  7. Add the subscribe() method to all ThingEvent elements so that they make requests to subscribe to the events defined by the remote Thing , as defined by the Protocol Bindings .
  8. Return thing .

3.5 3.4 The produce() method

Accepts a model argument of type ThingModel and returns an ExposedThing object, locally created based on the provided initialization parameters. An object.

The ExposedThing produce(model) can be created in method MUST run the following ways: steps:

  1. from an initial If invoking produce() is not allowed for the current scripting context for security reasons, throw SecurityError and terminate these steps.
  2. If the argument model (including is a user given name and semantic annotations ), string, then adding properties, actions, events run the TD parsing algorithm with model passed as parameter. If it throws an error, re-throw that error and request handlers; terminate this algorithm. Otherwise let model be the returned value.
  3. from a Thing Description (possibly of a If model is not an object, throw TypeError and terminate these steps.
  4. If model does not have an own property that is defined in ConsumedThing ThingFragment object), then adding request handlers. with a default value, add that property and value to model .
  5. 3.6 The
  6. Create an ThingModel ExposedThing type A Thing object thing initialized from model is used for producing a new .
  7. For each property of ExposedThing and can be either a defined in ThingTemplate ThingFragment , initialize the property based on the provided initial or a default values provided to the local WoT Runtime implementation, for instance initialize:
    1. the ThingDescription id . 3.7 The property to be the final unique identifier of the Thing ,
    2. the security object of type SemanticAnnotations SecurityScheme dictionary A dictionary that provides to represent the semantic types actual security scheme and semantic metadata. <span class="idlDictionary" id= "idl-def-semanticannotations" data-idl="" data-title= "SemanticAnnotations">dictionary <span class= "idlDictionaryID"><a data-no-default="" data-link-for="" data-lt="" href="#dom-semanticannotations" class="internalDFN" data-link-type= "dfn"> { <span class="idlMember" id= "idl-def-semanticannotations-semantictype" data-idl="" data-title= "semanticType" data-dfn-for="semanticannotations"> <span class= "idlMemberType"><a href= "https://heycam.github.io/webidl/#idl-sequence">sequence<<a href="#dom-semantictype" class="internalDFN" data-link-type= "dfn"> <span class= "idlMemberName"><a data-no-default="" data-link-for= "semanticannotations" data-lt="" href= "#dom-semanticannotations-semantictype" class="internalDFN" data-link-type="dfn"> <span class="idlMember" id="idl-def-semanticannotations-metadata" data-idl="" data-title="metadata" data-dfn-for= "semanticannotations"> <a href= "https://heycam.github.io/webidl/#idl-sequence">sequence<<a href="#dom-semanticmetadata" class="internalDFN" data-link-type= "dfn"> <span class= "idlMemberName"><a data-no-default="" data-link-for= "semanticannotations" data-lt="" href= "#dom-semanticannotations-metadata" class="internalDFN" data-link-type="dfn"> }; The its properties as set up by the implementation,
    3. the semanticType properties property denotes a list of to be an object with all properties being SemanticType ThingProperty objects that in which the read() and write() methods are provided to define local methods to get and set the Property values,
    4. the semantic types that can be used in semantic metadata type-value pairs. The metadata actions property denotes a list of to be an object with all properties being SemanticMetadata ThingAction objects (type-value pairs). 3.8 The in which the SemanticType invoke() dictionary <span class="idlDictionary" id= "idl-def-semantictype" data-idl="" data-title= "SemanticType">dictionary <span class= "idlDictionaryID"><a data-no-default="" data-link-for="" data-lt="" href="#dom-semantictype" class="internalDFN" data-link-type= "dfn"> { <span class="idlMember" id="idl-def-semantictype-name" data-idl="" data-title="name" data-dfn-for= "semantictype"> required <a href= "https://heycam.github.io/webidl/#idl-DOMString">DOMString<a data-no-default="" data-link-for="semantictype" data-lt="" href= "#dom-semantictype-name" class="internalDFN" data-link-type= "dfn"> <span class="idlMember" id="idl-def-semantictype-context" data-idl= "" data-title="context" data-dfn-for= "semantictype"> required <a href= "https://heycam.github.io/webidl/#idl-USVString">USVString<a data-no-default="" data-link-for="semantictype" data-lt="" href= "#dom-semantictype-context" class="internalDFN" data-link-type= "dfn"> <span class="idlMember" id="idl-def-semantictype-prefix" data-idl= "" data-title="prefix" data-dfn-for= "semantictype"> <a href= "https://heycam.github.io/webidl/#idl-DOMString">DOMString<a data-no-default="" data-link-for="semantictype" data-lt="" href= "#dom-semantictype-prefix" class="internalDFN" data-link-type= "dfn"> }; Represents a semantic type annotation, containing a name, a context and method is provided to define a prefix. local method to run the defined Action s,
    5. The the events property to be an object with all properties being name ExposedEvent attribute represents the name of the semantic type objects in which the given context. The context emit() attribute represents an URL link method is provided to define a local way to trigger sending notifications to all subscribed clients,
    6. and initialize the context of the semantic classification. other properties as initialized from model .
    7. Return thing .

    The prefix TD parsing algorithm attribute represents takes a short prefix associated with string td as argument and runs the following steps:

    1. Parse td according to the WoT Thing Description in order to produce a context. JSON object json . Update thing with the properties and values defined in json .
    2. Editor's note Semantic type examples to be added.
    3. If there was an error during the parsing, throw that error and terminate these steps.
    4. Otherwise return json .

3.9 3.5 The SemanticMetadata register() dictionary <span class="idlDictionary" id= "idl-def-semanticmetadata" data-idl="" data-title= "SemanticMetadata">dictionary <span class= "idlDictionaryID"><a data-no-default="" data-link-for="" data-lt="" href="#dom-semanticmetadata" class="internalDFN" data-link-type= "dfn"> { <span class="idlMember" id="idl-def-semanticmetadata-type" data-idl="" data-title="type" data-dfn-for= "semanticmetadata"> <a href= "#dom-semantictype" class="internalDFN" data-link-type= "dfn"> <span class= "idlMemberName"><a data-no-default="" data-link-for= "semanticmetadata" data-lt="" href="#dom-semanticmetadata-type" class="internalDFN" data-link-type= "dfn"> <span class="idlMember" id="idl-def-semanticmetadata-value" data-idl="" data-title="value" data-dfn-for= "semanticmetadata"> <a href= "https://heycam.github.io/webidl/#idl-any">any<a data-no-default="" data-link-for="semanticmetadata" data-lt="" href= "#dom-semanticmetadata-value" class="internalDFN" data-link-type= "dfn"> }; method

The Takes two mandatory arguments:

3.10 The ThingTemplate dictionary

A Generate the Thing Template is a dictionary that provides a user Description as td , given name, and the semantic types Properties , Action s and semantic metadata attached to the Event s defined for this ExposedThing object. Then make a request to register td to the given WoT Thing Description 's root level. Directory .

<span class="idlDictionary" id= "idl-def-thingtemplate" data-idl="" data-title= "ThingTemplate">dictionary <span class= "idlDictionaryID"><a data-no-default="" data-link-for="" data-lt="" href="#dom-thingtemplate" class="internalDFN" data-link-type= "dfn"> : <span class= "idlSuperclass"><a href="#dom-semanticannotations" class= "internalDFN" data-link-type= "dfn"> { <span class="idlMember" id="idl-def-thingtemplate-name" data-idl="" data-title="name" data-dfn-for= "thingtemplate"> required <a href= "https://heycam.github.io/webidl/#idl-DOMString">DOMString<a data-no-default="" data-link-for="thingtemplate" data-lt="" href= "#dom-thingtemplate-name" class="internalDFN" data-link-type= "dfn"> };

3.6 The ThingTemplate unregister() method dictionary extends

Takes two mandatory arguments:

Makes a request to unregister the user given name of thing from the given WoT Thing Directory . Editor's note Support for configuration and security data might be added later.

3.11 3.7 Examples

Example 1 : : Discover Things via directory
let discoveryFilter = {
  method: "directory",
  url: "http://directory.wotservice.org"
};
let subscription = wot.discover(discoveryFilter).subscribe(
  "hljs-params">thing { <span class=
"hljs-built_in">console.log(<span class=
"hljs-string">"Found Thing " + thing.name); },

"hljs-params">td => {
    console.log(
"hljs-string">"Found Thing " + td.name);
    
"hljs-comment">// fetch the TD and create a ConsumedThing
    let thing = wot.consume(td);
  },

  error => { console.log("Discovery finished because an error: " + error.message); },
  () => { console.log("Discovery finished successfully");}
);
setTimeout( () => {
    subscription.unsubscribe();
    console.log("Discovery timeout");
  },

5000

);
Note Note that canceling a discovery (through unsubscribe() ) may not be successful in all cases, for instance when discovery is based on open ended broadcast requests. However, once unsubscribe() has been called, implementations MUST suppress further event handling ( i.e. further discoveries and errors) on the Observable. Also, a discovery error may not mean the end of the discovery process. However, in order to respect Observable semantics (error always terminates processing), implementations MUST close or suppress further event handling on the Observable.
Example 2 : : Discover Things exposed by local hardware
let subscription = wot.discover({ method: "local" }).subscribe(
  "hljs-params">thing { <span class=

"hljs-params">td => { 
"hljs-built_in">console.log("hljs-string">"Found local Thing " + thing.name); },

"hljs-string">"Found local Thing " + td.name); },

  error => { console.log("Discovery error: " + error.message); },
  () => { console.log("Discovery finished successfully");}
);
Example 3 : : Same as above but with different Observable syntax
let subscription = wot.discover({ method: "local" }).subscribe({
  thing => { <span class=

  td => { 
"hljs-built_in">console.log("hljs-string">"Found local Thing " + thing.name); },

"hljs-string">"Found local Thing " + td.name); },

  error: err => { console.log("Discovery error: " + err.message); },
  complete: () => { console.log("Discovery finished successfully");}
});
Example 4 : Discover Things exposed nearby, via Bluetooth or NFC <span class= "hljs-keyword">let subscription = wot.discover({ : <span class= "hljs-string">"nearby", : [{ <span class= "hljs-attr">protocol: <span class= "hljs-string">"BLE-4.2" }, { <span class= "hljs-attr">protocol: <span class= "hljs-string">"NFC"}] }).subscribe( <span class= "hljs-params">thing { <span class= "hljs-built_in">console.log(<span class= "hljs-string">"Found nearby Thing " + thing.name); }, error => { <span class= "hljs-built_in">console.log(<span class= "hljs-string">"Discovery error: " + error.message); }, () => { <span class= "hljs-built_in">console.log(<span class= "hljs-string">"Discovery finished successfully");} ); Example 5 : Discover Things exposed in a proprietary way <span class= "hljs-keyword">let subscription = wot.discover({ : <span class= "hljs-string">"other", : [{ <span class= "hljs-attr">solution: <span class= "hljs-string">"XYZ123", <span class= "hljs-attr">key}] }).subscribe( <span class= "hljs-params">thing { <span class= "hljs-built_in">console.log(<span class= "hljs-string">"Found Thing " + thing.name); }, error => { <span class= "hljs-built_in">console.log(<span class= "hljs-string">"Discovery error: " + error.message); }, () => { <span class= "hljs-built_in">console.log(<span class= "hljs-string">"Discovery finished successfully");} );

4. The ConsumedThing interface

The Represents an object that extends a ConsumedThing ThingFragment interface is a with methods for client API interactions (send request for sending requests to servers in order to retrieve or update reading and writing Properties , ), invoke Actions , Action s, subscribe and observe Properties unsubscribe for Property changes and Events . Event s.

interface "dfn"> {
<span class="idlAttribute" id="idl-def-consumedthing-name"
data-idl="" data-title="name" data-dfn-for=
"consumedthing">    readonly attribute <span class=
"idlAttrType"><a href=
"https://heycam.github.io/webidl/#idl-DOMString">DOMString<a data-no-default=""
data-link-for="consumedthing" data-lt="" href=
"#dom-consumedthing-name" class="internalDFN" data-link-type=
"dfn">
<span class="idlMethod" id=
"idl-def-consumedthing-getthingdescription" data-idl="" data-title=
"getThingDescription" data-dfn-for="consumedthing">    <span class=
"idlMethType"><a href="#dom-thingdescription" class="internalDFN"

"dfn">ConsumedThing : 
data-link-type=
"dfn"> <span class=
"idlMethName"><a data-no-default="" data-link-for="consumedthing"
data-lt="getthingdescription()|getThingDescription" href=
"#dom-consumedthing-getthingdescription" class="internalDFN"
data-link-type="dfn">getThingDescription
<span class="idlMethod" id=
"idl-def-consumedthing-readproperty-name" data-idl="" data-title=
"readProperty" data-dfn-for="consumedthing">    <span class=
"idlMethType"><a href=
"https://heycam.github.io/webidl/#idl-promise">Promise<a data-no-default=""
data-link-for="consumedthing" data-lt="readproperty()|readProperty"
href="#dom-consumedthing-readproperty" class="internalDFN"
data-link-type="dfn">readProperty(<span class=
"idlParam"><a href=
"https://heycam.github.io/webidl/#idl-DOMString">DOMString
<span class="idlMethod" id=
"idl-def-consumedthing-writeproperty-name-value" data-idl=""
data-title="writeProperty" data-dfn-for=
"consumedthing">    <a href=
"https://heycam.github.io/webidl/#idl-promise">Promise<a data-no-default=""
data-link-for="consumedthing" data-lt=
"writeproperty()|writeProperty" href=
"#dom-consumedthing-writeproperty" class="internalDFN"
data-link-type="dfn">writeProperty(<span class=
"idlParam"><a href=
"https://heycam.github.io/webidl/#idl-DOMString">DOMString
<span class="idlMethod" id=
"idl-def-consumedthing-invokeaction-name-parameters" data-idl=""
data-title="invokeAction" data-dfn-for=
"consumedthing">    <a href=
"https://heycam.github.io/webidl/#idl-promise">Promise<a data-no-default=""
data-link-for="consumedthing" data-lt="invokeaction()|invokeAction"
href="#dom-consumedthing-invokeaction" class="internalDFN"
data-link-type="dfn">invokeAction(<span class=
"idlParam"><a href=
"https://heycam.github.io/webidl/#idl-DOMString">DOMString
<span class="idlMethod" id=
"idl-def-consumedthing-onpropertychange-name" data-idl=""
data-title="onPropertyChange" data-dfn-for=
"consumedthing">    <a href=
"#dom-observable" class="internalDFN" data-link-type=
"dfn">       <span class=
"idlMethName"><a data-no-default="" data-link-for="consumedthing"
data-lt="onpropertychange()|onPropertyChange" href=
"#dom-consumedthing-onpropertychange" class="internalDFN"
data-link-type="dfn">onPropertyChange(<span class=
"idlParam"><a href=
"https://heycam.github.io/webidl/#idl-DOMString">DOMString
<span class="idlMethod" id="idl-def-consumedthing-onevent-name"
data-idl="" data-title="onEvent" data-dfn-for=
"consumedthing">    <a href=
"#dom-observable" class="internalDFN" data-link-type=
"dfn">       <span class=
"idlMethName"><a data-no-default="" data-link-for="consumedthing"
data-lt="onevent()|onEvent" href="#dom-consumedthing-onevent"
class="internalDFN" data-link-type=
"dfn">onEvent<span class=
"idlParamType"><a href=
"https://heycam.github.io/webidl/#idl-DOMString">DOMString
<span class="idlMethod" id="idl-def-consumedthing-ontdchange"
data-idl="" data-title="onTDChange" data-dfn-for=
"consumedthing">    <a href=

"dfn">ThingFragment {
  readonly attribute DOMString id;
  readonly attribute DOMString name;
  readonly attribute DOMString? base;
  readonly attribute PropertyMap properties;
  readonly attribute ActionMap actions;
  readonly attribute EventMap events;
  // getter for ThingFragment properties
  getter 
"https://heycam.github.io/webidl/#idl-any">any (DOMString name);
};
[NoInterfaceObject]
interface PropertyMap {
  readonly maplike<DOMString, ThingProperty>;
};
[NoInterfaceObject]
interface ActionMap {
  readonly maplike<DOMString, ThingAction>;
};
[NoInterfaceObject]
interface EventMap {
  readonly maplike<DOMString, ThingEvent>;
};

"dfn">ConsumedThing includes 
"#dom-observable" class="internalDFN" data-link-type=
"dfn">       <span class=
"idlMethName"><a data-no-default="" data-link-for="consumedthing"
data-lt="ontdchange()|onTDChange" href=
"#dom-consumedthing-ontdchange" class="internalDFN" data-link-type=
"dfn">onTDChange
};

"dfn">Observable;
//
for
TD
changes


The ConsumedThing id attribute represents a local proxy object the unique identifier of the remote Thing . instance, typically a URI, IRI, or URN as USVString .

4.1

The name property The name property attribute represents the name of the Thing as specified in the TD . In this version it is read only. DOMString .

4.2

The getThingDescription() base method Returns the Thing Description of attribute represents the Thing . Editor's note In this version, introspection based on TD is out of scope. Parsing and exposing Thing Description s base URI that is discussed in Issue 38 . valid for all defined local interaction resources.

4.3

The readProperty() properties method Takes the Property name as the name argument, then requests from the underlying platform and the Protocol Bindings to retrieve the Property on the remote Thing and return the result. Returns attribute represents a dictionary of ThingProperty Promise items. The PropertyMap that resolves with the Property value or rejects with an Error . 4.4 The interface represents a maplike dictionary where all values are writeProperty() ThingProperty method Takes the Property name as the name argument and the new value as the value argument, then requests from the underlying platform objects. The read() and the Protocol Bindings write() methods make a request to update access the Property Properties on the remote Thing and return the result. Returns a represented by this ConsumedThing Promise that resolves on success or rejects with an Error . proxy object.

4.5

The invokeAction() actions method Takes the Action name from the name argument and the list of parameters, then requests from the underlying platform and the Protocol Bindings to invoke the Action on the remote Thing and return the result. Returns attribute represents a Promise dictionary of ThingAction that resolves with the return value or rejects with an Error . 4.6 items. The onPropertyChange() ActionMap method Returns an interface represents a maplike dictionary where all values are Observable ThingAction for the Property specified in the name argument, allowing subscribing to and unsubscribing from notifications. objects. The callback function passed to the subscribe() invoke() method when invoked on represents a request to invoke the returned observer will receive Action on the new property value each time it is changed. remote Thing .

4.7

The onEvent() events method Returns an attribute represents a dictionary of Observable ThingEvent for the Event specified in the name argument, allowing subscribing to and unsubscribing from notifications. The callback function passed to the subscribe() method when invoked on the returned observer will receive the event data each time the event is fired. 4.8 items. The onTDChange() EventMap method Returns an interface represents a maplike dictionary where all values are Observable ThingEvent , allowing subscribing to and unsubscribing from notifications to the Thing Description . The callback function passed objects. Subscribing to the subscribe() method when invoked events involves setting up an observation (subscription) mechanism on the returned observer will receive the new Thing Description each time it is changed. remote object.

4.9 4.1 Examples

Below a ConsumedThing interface example is given.

Example 6 4 : : Consume a Thing
try { let td = await wot.fetch("http://mmyservice.org/mySensor"); let thing = wot.consume(td); console.log("Thing " + thing.name + " has been consumed."); let subscription = thing.onPropertyChange("temperature") .subscribe(function(value) { console.log("Temperature + " has changed to " + value); }); thing.invokeAction("startMeasurement", { units: "Celsius" }) .then(() => { console.log("Temperature measurement started."); }) .catch(e => { console.log("Error starting measurement."); subscription.unsubscribe(); }) } catch(error) { console.log("Error during fetch or consume: " + error.message);
"hljs-keyword">try {
  
"hljs-keyword">let subscription = wot.discover({ method: "local" }).subscribe(
    
"hljs-params">td => {
      
"hljs-keyword">let thing = wot.consume(td);
      console.log(
"hljs-string">"Thing " + thing.name + " has been consumed.");
      
"hljs-keyword">let subscription = thing["temperature"].subscribe(function(value) {
          
"hljs-built_in">console.log("Temperature: " + value);
        });
      thing.actions["startMeasurement"].invoke({ units: "Celsius" })
        .then(() => { console.log("Temperature measurement started."); })
        .catch(e => {
           
"hljs-built_in">console.log("Error starting measurement.");
           subscription.unsubscribe();
         })
    },
    error => { console.log("Discovery error: " + error.message); },
    () => { console.log("Discovery finished successfully");}
  );
} catch(error) {
  console.log(
"hljs-string">"Error: " + error.message);

};

5. The ExposedThing interface

The ExposedThing interface is the server API that allows defining request handlers, properties, Actions , and Events to a Thing . It also implements the ConsumedThing Observable interface. An ExposedThing is created by the produce() method.

Editor's note It is under consideration to use a constructor for ExposedThing instead of a factory method.
<a href= "#dom-exposedthing" class="internalDFN" data-link-type= "dfn"> implements <a href= "#dom-consumedthing" class="internalDFN" data-link-type= "dfn"> <span class="idlInterface" id="idl-def-exposedthing" data-idl="" data-title="ExposedThing">interface <span class=
"idl-def-exposedthing" data-idl="" data-title=
"ExposedThing">interface 
"idlInterfaceID">"dfn"> {
<span class=
"idlSectionComment">    // define how to expose and run the Thing
<span class="idlMethod" id="idl-def-exposedthing-start" data-idl=""
data-title="start" data-dfn-for="exposedthing">    <span class=
"idlMethType"><a href=
"https://heycam.github.io/webidl/#idl-promise">Promise<a data-no-default=""
data-link-for="exposedthing" data-lt="start()|start" href=
"#dom-exposedthing-start" class="internalDFN" data-link-type=
"dfn">start
<span class="idlMethod" id="idl-def-exposedthing-stop" data-idl=""
data-title="stop" data-dfn-for="exposedthing">    <span class=
"idlMethType"><a href=
"https://heycam.github.io/webidl/#idl-promise">Promise<a data-no-default=""
data-link-for="exposedthing" data-lt="stop()|stop" href=
"#dom-exposedthing-stop" class="internalDFN" data-link-type=
"dfn">stop
<span class="idlMethod" id=
"idl-def-exposedthing-register-directory" data-idl="" data-title=
"register" data-dfn-for="exposedthing">    <span class=
"idlMethType"><a href=
"https://heycam.github.io/webidl/#idl-promise">Promise<a data-no-default=""
data-link-for="exposedthing" data-lt="register()|register" href=
"#dom-exposedthing-register" class="internalDFN" data-link-type=
"dfn">register(<span class=
"idlParam">optional <a href=
"https://heycam.github.io/webidl/#idl-USVString">USVString
<span class="idlMethod" id=
"idl-def-exposedthing-unregister-directory" data-idl="" data-title=
"unregister" data-dfn-for="exposedthing">    <span class=
"idlMethType"><a href=

"dfn">ExposedThing : ThingFragment {
  readonly attribute PropertyMap properties;
  readonly attribute ActionMap actions;
  readonly attribute ExposedEvents events;
  // getter for ThingFragment properties
  getter 
"https://heycam.github.io/webidl/#idl-any">any (DOMString name);
  // setter for ThingFragment properties
  setter void (
"idlParam">DOMString name, any value);
  // methods to expose and destroy the Thing
  Promise<void> data-link-for="exposedthing" data-lt="unregister()|unregister"
href="#dom-exposedthing-unregister" class="internalDFN"
data-link-type="dfn">unregister(<span class=
"idlParam">optional <a href=
"https://heycam.github.io/webidl/#idl-USVString">USVString
<span class="idlMethod" id=
"idl-def-exposedthing-emitevent-eventname-payload" data-idl=""
data-title="emitEvent" data-dfn-for="exposedthing">    <span class=
"idlMethType"><a href=

data-link-for="exposedthing" data-lt=
"exposedthing.expose()|exposedthing.expose|expose()|expose" href=
"#dom-exposedthing-expose" class="internalDFN" data-link-type=
"dfn">expose();
  Promise<void> data-link-for="exposedthing" data-lt="emitevent()|emitEvent" href=
"#dom-exposedthing-emitevent" class="internalDFN" data-link-type=
"dfn">emitEvent<span class=
"idlParamType"><a href=
"https://heycam.github.io/webidl/#idl-DOMString">DOMString
<span class=
"idlSectionComment">    // define Thing Description modifiers
<span class="idlMethod" id=
"idl-def-exposedthing-addproperty-property" data-idl="" data-title=
"addProperty" data-dfn-for="exposedthing">    <span class=
"idlMethType"><a href="#dom-exposedthing" class="internalDFN"
data-link-type=
"dfn">  <span class=

data-link-for="exposedthing" data-lt=
"exposedthing.destroy()|exposedthing.destroy|destroy()|destroy"
href="#dom-exposedthing-destroy" class="internalDFN"
data-link-type="dfn">destroy();
  // define Properties
  
"internalDFN" data-link-type=
"dfn">ExposedThing 
"idlMethName">data-lt="addproperty()|addProperty" href=
"#dom-exposedthing-addproperty" class="internalDFN" data-link-type=
"dfn">addProperty<span class=
"idlParamType"><a href="#dom-thingproperty" class="internalDFN"

data-lt=
"exposedthing.addproperty()|exposedthing.addproperty|addproperty()|addproperty"
href="#dom-exposedthing-addproperty" class="internalDFN"

data-link-type=
"dfn"> <span class=
"idlParamName">property
<span class="idlMethod" id=
"idl-def-exposedthing-removeproperty-name" data-idl="" data-title=
"removeProperty" data-dfn-for="exposedthing">    <span class=
"idlMethType"><a href="#dom-exposedthing" class="internalDFN"

"dfn">addProperty(DOMString name, PropertyFragment property, optional any initValue);
  "dfn">  <span class=

"dfn">ExposedThing 
"idlMethName">data-lt="removeproperty()|removeProperty" href=
"#dom-exposedthing-removeproperty" class="internalDFN"
data-link-type="dfn">removeProperty(<span class=

data-lt=
"exposedthing.setpropertyreadhandler()|exposedthing.setpropertyreadhandler|setpropertyreadhandler()|setpropertyreadhandler"
href="#dom-exposedthing-setpropertyreadhandler" class="internalDFN"
data-link-type=
"dfn">setPropertyReadHandler(
"idlParam">"https://heycam.github.io/webidl/#idl-DOMString">DOMString
<span class="idlMethod" id="idl-def-exposedthing-addaction-action"
data-idl="" data-title="addAction" data-dfn-for=
"exposedthing">    <a href=
"#dom-exposedthing" class="internalDFN" data-link-type=
"dfn">  <span class=
"idlMethName"><a data-no-default="" data-link-for="exposedthing"
data-lt="addaction()|addAction" href="#dom-exposedthing-addaction"
class="internalDFN" data-link-type=
"dfn">addAction<span class=
"idlParamType"><a href="#dom-thingaction" class="internalDFN"

"https://heycam.github.io/webidl/#idl-DOMString">DOMString name, PropertyReadHandler readHandler);
  "dfn"> <span class=
"idlParamName">action
<span class="idlMethod" id="idl-def-exposedthing-removeaction-name"
data-idl="" data-title="removeAction" data-dfn-for=
"exposedthing">    <a href=
"#dom-exposedthing" class="internalDFN" data-link-type=
"dfn">  <span class=

"dfn">ExposedThing 
"idlMethName">data-lt="removeaction()|removeAction" href=
"#dom-exposedthing-removeaction" class="internalDFN"
data-link-type="dfn">removeAction(<span class=

data-lt=
"exposedthing.setpropertywritehandler()|exposedthing.setpropertywritehandler|setpropertywritehandler()|setpropertywritehandler"
href="#dom-exposedthing-setpropertywritehandler" class=
"internalDFN" data-link-type=
"dfn">setPropertyWriteHandler(
"idlParam">"https://heycam.github.io/webidl/#idl-DOMString">DOMString
<span class="idlMethod" id="idl-def-exposedthing-addevent-event"
data-idl="" data-title="addEvent" data-dfn-for=
"exposedthing">    <a href=
"#dom-exposedthing" class="internalDFN" data-link-type=
"dfn">  <span class=
"idlMethName"><a data-no-default="" data-link-for="exposedthing"
data-lt="addevent()|addEvent" href="#dom-exposedthing-addevent"
class="internalDFN" data-link-type=
"dfn">addEvent<span class=
"idlParamType"><a href="#dom-thingevent" class="internalDFN"

"https://heycam.github.io/webidl/#idl-DOMString">DOMString name, PropertyWriteHandler writeHandler);
  "dfn">
<span class="idlMethod" id="idl-def-exposedthing-removeevent-name"
data-idl="" data-title="removeEvent" data-dfn-for=
"exposedthing">    <a href=
"#dom-exposedthing" class="internalDFN" data-link-type=
"dfn">  <span class=
"idlMethName"><a data-no-default="" data-link-for="exposedthing"
data-lt="removeevent()|removeEvent" href=
"#dom-exposedthing-removeevent" class="internalDFN" data-link-type=
"dfn">removeEvent<span class=
"idlParamType"><a href=
"https://heycam.github.io/webidl/#idl-DOMString">DOMString
<span class=
"idlSectionComment">    // define request handlers
<span class="idlMethod" id=
"idl-def-exposedthing-setpropertyreadhandler-name-readhandler"
data-idl="" data-title="setPropertyReadHandler" data-dfn-for=
"exposedthing">    <a href=
"#dom-exposedthing" class="internalDFN" data-link-type=
"dfn">  <span class=

"dfn">ExposedThing 
"idlMethName">data-lt="setpropertyreadhandler()|setPropertyReadHandler" href=
"#dom-exposedthing-setpropertyreadhandler" class="internalDFN"
data-link-type="dfn">setPropertyReadHandler(<span class=

data-lt=
"exposedthing.removeproperty()|exposedthing.removeproperty|removeproperty()|removeproperty"
href="#dom-exposedthing-removeproperty" class="internalDFN"
data-link-type=
"dfn">removeProperty(
"idlParam">"https://heycam.github.io/webidl/#idl-DOMString">DOMString,
                                         <span class=

"https://heycam.github.io/webidl/#idl-DOMString">DOMString name);
  // define Actions
  
"internalDFN" data-link-type=
"dfn">ExposedThing addAction(
"idlParam">"#dom-propertyreadhandler" class="internalDFN" data-link-type=
"dfn"> <span class=
"idlParamName">readHandler
<span class="idlMethod" id=
"idl-def-exposedthing-setpropertywritehandler-name-writehandler"
data-idl="" data-title="setPropertyWriteHandler" data-dfn-for=
"exposedthing">    <a href=
"#dom-exposedthing" class="internalDFN" data-link-type=
"dfn">  <span class=

"https://heycam.github.io/webidl/#idl-DOMString">DOMString name, ActionFragment init, ActionHandler action);
  
data-link-type=
"dfn">ExposedThing 
"idlMethName">data-lt="setpropertywritehandler()|setPropertyWriteHandler" href=
"#dom-exposedthing-setpropertywritehandler" class="internalDFN"

data-lt=
"exposedthing.removeaction()|exposedthing.removeaction|removeaction()|removeaction"
href="#dom-exposedthing-removeaction" class="internalDFN"

data-link-type=
"dfn">setPropertyWriteHandler,
                                          <span class=

"dfn">removeAction(
"idlParam">"#dom-propertywritehandler" class="internalDFN" data-link-type=
"dfn"> <span class=
"idlParamName">writeHandler
<span class="idlMethod" id=
"idl-def-exposedthing-setactionhandler-name-action" data-idl=""

"https://heycam.github.io/webidl/#idl-DOMString">DOMString name);
data-title="setActionHandler" data-dfn-for=
"exposedthing">    <a href=
"#dom-exposedthing" class="internalDFN" data-link-type=
"dfn">  <span class=

"exposedthing">
  
data-link-type=
"dfn">ExposedThing 
"idlMethName">data-lt="setactionhandler()|setActionHandler" href=
"#dom-exposedthing-setactionhandler" class="internalDFN"
data-link-type="dfn">setActionHandler(<span class=

data-lt=
"exposedthing.setactionhandler()|exposedthing.setactionhandler|setactionhandler()|setactionhandler"
href="#dom-exposedthing-setactionhandler" class="internalDFN"
data-link-type=
"dfn">setActionHandler(
"idlParam">"https://heycam.github.io/webidl/#idl-DOMString">DOMString<a href="#dom-actionhandler"
class="internalDFN" data-link-type=
"dfn"> <span class=
"idlParamName">action
};
<span class="idlCallback" id="idl-def-propertyreadhandler"
data-idl="" data-title="PropertyReadHandler">callback <span class=
"idlCallbackID"><a data-no-default="" data-link-for="" data-lt=""
href="#dom-propertyreadhandler" class="internalDFN" data-link-type=
"dfn"> = <span class=
"idlCallbackType"><a href=
"https://heycam.github.io/webidl/#idl-promise">Promise
<span class="idlCallback" id="idl-def-propertywritehandler"
data-idl="" data-title="PropertyWriteHandler">callback <span class=
"idlCallbackID"><a data-no-default="" data-link-for="" data-lt=""
href="#dom-propertywritehandler" class="internalDFN"
data-link-type="dfn">
<span class="idlCallback" id="idl-def-actionhandler" data-idl=""
data-title="ActionHandler">callback <span class=
"idlCallbackID"><a data-no-default="" data-link-for="" data-lt=""

"https://heycam.github.io/webidl/#idl-DOMString">DOMString name, 
href="#dom-actionhandler" class="internalDFN" data-link-type=
"dfn"> = <span class=
"idlCallbackType"><a href=

"dfn">ActionHandler action);
  // define Events
  
"internalDFN" data-link-type=
"dfn">ExposedThing addEvent(DOMString name, EventFragment event);
  
data-link-type=
"dfn">ExposedThing removeEvent(DOMString name);
};
[NoInterfaceObject]
interface ExposedEvents {
  maplike<DOMString, ExposedEvent>;
};
callback PropertyReadHandler = Promise<any> ();
callback PropertyWriteHandler = Promise<void> (any value);
callback ActionHandler = 
"https://heycam.github.io/webidl/#idl-promise">
Promise

<

any

>

(



any



parameters


);

5.1 The start() method

Start serving external requests for the Thing . 5.2 The stop() properties method Stop serving external requests for the Thing . 5.3 The attribute represents a dictionary of register() ThingProperty method Generates the Thing Description given items in which the properties, Actions read() and Event defined for this object. If a directory write() argument is given, make a request to register methods define local methods that access the Thing Description with physical representations of the given WoT repository by invoking its register Action Properties .

5.4

The unregister() actions method If attribute represents a dictionary of directory ThingAction argument is given, make a request to unregister the Thing Description with items in which the given WoT repository by invoking its unregister invoke() Action . Then, and in the case no arguments were provided method represents a local method to this function, stop the Thing and remove invoke the Thing Description Action .

5.5

The emitEvent() events method Emits an the event initialized with the event name specified by attribute represents a dictionary of ExposedEvent items that add the eventName emit() argument and data specified by method to the payload ThingEvent argument. 5.6 definition. The DataSchema ExposedEvents type <span class="idlTypedef" id= "idl-def-dataschema" data-idl="" data-title= "DataSchema">typedef <a href= "https://heycam.github.io/webidl/#idl-USVString">USVString<a data-no-default="" data-link-for="" data-lt="" href="#dom-dataschema" class= "internalDFN" data-link-type= "dfn"> interface represents a maplike dictionary where all values are DataSchema ExposedEvent objects.

5.1 ; The DataSchema expose() method type represents a data type specified in

Start serving external requests for the Thing Description , so that WoT Interactions in a serialized form. using Properties , Action s and Event s will be possible.

Editor's note

The DataSchema expose() is under development, currently it can denote any type supported by method MUST run the Thing Description following steps:

  1. Return a Promise promise and execute the WoT Runtime next steps in parallel . 5.7 The
  2. If invoking addProperty() expose() method Adds is not allowed for the current scripting context for security reasons, reject promise with SecurityError and terminate these steps.
  3. Make a Property defined by request to the argument underlying platform to attach protocol handlers and updates start serving external requests for WoT Interactions (read, write and observe Properties , invoke Action s and manage Event subscriptions), based on the Thing Description Protocol Bindings . Throws on error. Returns a reference to
  4. If there was an error during the same request, reject promise with an Error object for supporting chaining. error with error.message set to the error code seen by the Protocol Bindings and terminate these steps.
  5. Otherwise resolve promise with td and terminate these steps.

5.7.1 5.2 The ThingProperty destroy() dictionary <span class="idlDictionary" id= "idl-def-thingproperty" data-idl="" data-title= "ThingProperty">dictionary <span class= "idlDictionaryID"><a data-no-default="" data-link-for="" data-lt="" href="#dom-thingproperty" class="internalDFN" data-link-type= "dfn"> : <span class= "idlSuperclass"><a href="#dom-semanticannotations" class= "internalDFN" data-link-type= "dfn"> { <span class="idlMember" id="idl-def-thingproperty-name" data-idl="" data-title="name" data-dfn-for= "thingproperty"> required <a href= "https://heycam.github.io/webidl/#idl-DOMString">DOMString<a data-no-default="" data-link-for="thingproperty" data-lt="" href= "#dom-thingproperty-name" class="internalDFN" data-link-type= "dfn"> <span class="idlMember" id="idl-def-thingproperty-schema" data-idl= "" data-title="schema" data-dfn-for= "thingproperty"> required <a href= "#dom-dataschema" class="internalDFN" data-link-type= "dfn"> <span class= "idlMemberName"><a data-no-default="" data-link-for="thingproperty" data-lt="" href="#dom-thingproperty-schema" class="internalDFN" data-link-type="dfn"> <span class="idlMember" id="idl-def-thingproperty-value" data-idl= "" data-title="value" data-dfn-for= "thingproperty"> <a href= "https://heycam.github.io/webidl/#idl-any">any<a data-no-default="" data-link-for="thingproperty" data-lt="" href= "#dom-thingproperty-value" class="internalDFN" data-link-type= "dfn"> <span class="idlMember" id="idl-def-thingproperty-writable" data-idl="" data-title="writable" data-dfn-for= "thingproperty"> <a href= "https://heycam.github.io/webidl/#idl-boolean">boolean<a data-no-default="" data-link-for="thingproperty" data-lt="" href= "#dom-thingproperty-writable" class="internalDFN" data-link-type= "dfn"> = <span class= "idlMemberValue">false <span class="idlMember" id="idl-def-thingproperty-observable" data-idl="" data-title="observable" data-dfn-for= "thingproperty"> <a href= "https://heycam.github.io/webidl/#idl-boolean">boolean<a data-no-default="" data-link-for="thingproperty" data-lt="" href= "#dom-thingproperty-observable" class="internalDFN" data-link-type= "dfn"> = <span class= "idlMemberValue">false }; method

Represents Stop serving external requests for the Thing Property description. and destroy the object. Note that eventual unregistering should be done before invoking this method.

The name destroy() attribute represents method MUST run the name of following steps:

  1. Return a Promise promise and execute the Property next steps in parallel .
  2. The If invoking schema destroy() attribute represents the data type is not allowed for the Property described by current scripting context for security reasons, reject promise with DataSchema SecurityError . and terminate these steps.
  3. The value attribute represents Make a request to the value of underlying platform to stop serving external requests for WoT Interactions , based on the Property Protocol Bindings .
  4. The If there was an error during the request, reject promise with an writable Error attribute defines whether object error with error.message set to the Property error code seen by the Protocol Bindings can be updated. The default value is false . and terminate these steps.
  5. The Otherwise resolve promise with td and terminate these steps.

5.3 The observable addProperty() attribute defines whether the method

Adds a Property changes can be observed with name defined by the name argument, the data schema provided by the property argument of type PropertyFragment , and optionally an external client. The default initial value provided in the argument initValue whose type should match the one defined in the type property according to the value-matching algorithm . If initValue is not provided, it SHOULD be initialized as false undefined . Implementations SHOULD update the Thing Description . Throws on error. Returns a reference to the same object for supporting chaining.

5.8 5.4 The removeProperty() method

Removes the Property specified by the name argument and updates the Thing Description . Throws on error. Returns a reference to the same object for supporting chaining.

5.9 5.5 The addAction() method

Adds an Action to the actions property of a Thing object as an Action with name defined by the action name argument, defines input and output data format by the init argument of type ThingAction ActionFragment , and adds the function provided in the action argument as a handler, then updates the Thing Description . Throws on error. Returns a reference to the same object for supporting chaining.

5.9.1 The ThingAction dictionary <span class="idlDictionary" id= "idl-def-thingaction" data-idl="" data-title= "ThingAction">dictionary <span class= "idlDictionaryID"><a data-no-default="" data-link-for="" data-lt="" href="#dom-thingaction" class="internalDFN" data-link-type= "dfn"> : <span class= "idlSuperclass"><a href="#dom-semanticannotations" class= "internalDFN" data-link-type= "dfn"> { <span class="idlMember" id="idl-def-thingaction-name" data-idl="" data-title="name" data-dfn-for= "thingaction"> required <a href= "https://heycam.github.io/webidl/#idl-DOMString">DOMString<a data-no-default="" data-link-for="thingaction" data-lt="" href="#dom-thingaction-name" class="internalDFN" data-link-type= "dfn"> <span class="idlMember" id="idl-def-thingaction-inputschema" data-idl="" data-title="inputSchema" data-dfn-for= "thingaction"> <a href= "#dom-dataschema" class="internalDFN" data-link-type= "dfn"> <span class= "idlMemberName"><a data-no-default="" data-link-for="thingaction" data-lt="" href="#dom-thingaction-inputschema" class="internalDFN" data-link-type="dfn"> <span class="idlMember" id="idl-def-thingaction-outputschema" data-idl="" data-title="outputSchema" data-dfn-for= "thingaction"> <a href= "#dom-dataschema" class="internalDFN" data-link-type= "dfn"> <span class= "idlMemberName"><a data-no-default="" data-link-for="thingaction" data-lt="" href="#dom-thingaction-outputschema" class="internalDFN" data-link-type="dfn"> };

The ThingAction provided action callback function will implement invoking an Action dictionary describes the arguments and SHOULD be called by implementations when a request for invoking the return value. The name attribute provides the Action name. The inputSchema attribute provides the description of the input arguments (argument list is represented by an object). If missing, it means received from the action does not accept arguments. underlying platform. The callback will receive a outputSchema parameters attribute provides dictionary argument according to the description definition in the init.input argument and will return a value of type defined by the returned data. If missing, it means init.output argument according to the action does not return data. value-matching algorithm .

There SHOULD be exactly one handler for any given Action . If no handler is initialized for any given Action , implementations SHOULD throw a TypeError .

5.10 5.6 The removeAction() method

Removes the Action specified by the name argument and updates the Thing Description . Throws on error. Returns a reference to the same object for supporting chaining.

5.11 5.7 The addEvent() method

Adds an event to the Thing object as with name defined by the name argument and qualifiers and initialization value provided by the event argument of type ThingEvent EventFragment to the Thing object and updates the Thing Description . Throws on error. Returns a reference to the same object for supporting chaining.

5.11.1 The ThingEvent dictionary <span class="idlDictionary" id= "idl-def-thingevent" data-idl="" data-title= "ThingEvent">dictionary <span class= "idlDictionaryID"><a data-no-default="" data-link-for="" data-lt="" href="#dom-thingevent" class="internalDFN" data-link-type= "dfn"> : <span class= "idlSuperclass"><a href="#dom-semanticannotations" class= "internalDFN" data-link-type= "dfn"> { <span class="idlMember" id="idl-def-thingevent-name" data-idl="" data-title="name" data-dfn-for= "thingevent"> required <a href= "https://heycam.github.io/webidl/#idl-DOMString">DOMString<a data-no-default="" data-link-for="thingevent" data-lt="" href="#dom-thingevent-name" class="internalDFN" data-link-type= "dfn"> <span class="idlMember" id="idl-def-thingevent-schema" data-idl="" data-title="schema" data-dfn-for= "thingevent"> <a href= "#dom-dataschema" class="internalDFN" data-link-type= "dfn"> <span class= "idlMemberName"><a data-no-default="" data-link-for="thingevent" data-lt="" href="#dom-thingevent-schema" class="internalDFN" data-link-type="dfn"> }; The name attribute represents the event name. The schema attribute represents the type of the data that is attached to the event. If missing, it means the event does not carry data.

5.12 5.8 The removeEvent() method

Removes the event specified by the name argument and updates the Thing Description . Returns a reference to the same object for supporting chaining.

5.13 5.9 The PropertyReadHandler callback

A function that returns is called when an external request for reading a Property is received. It should return a Promise and resolves it with the value of the Property matching the name argument to the setPropertyReadHandler function, or rejects with an error if the property is not found or the value cannot be retrieved.

5.14 5.10 The PropertyWriteHandler callback

A function that is called with when an external request for writing a Property is received. It is given the requested new value as argument that returns and should return a Promise which is resolved when the value of the Property matching that matches the name argument to the setPropertyReadHandler function is has been updated with value , or rejects with an error if the property is not found or the value cannot be updated.

Editor's note

Note that this function is invoked by implementations before the property is updated, so the updated and it actually defines what to do when a write request is received. The code in this callback function can invoke the readProperty() read() method to find out the old value of the property, if needed. Therefore the old value is not provided to this method. function.

5.15 5.11 The ActionHandler callback

A function called with a parameters dictionary argument assembled by the WoT runtime based on the Thing Description and the external client request. It returns a Promise that rejects with an error or resolves if the action is successful or ongoing (may also resolve with a control object such as an Observable for actions that need progress notifications or that can be canceled).

5.16 5.12 The setPropertyReadHandler() method

Takes name as string argument and readHandler as argument of type PropertyReadHandler . Sets the handler function for reading the specified Property matched by name . Throws on error. Returns a reference to the same object for supporting chaining.

The readHandler callback function will implement reading a Property and SHOULD be called by implementations when a request for reading a Property is received from the underlying platform.

There SHOULD be at most one handler for any given Property and newly added handlers replace the old handlers. If no handler is initialized for any given Property , implementations SHOULD implement a default property read handler.

When an external request for reading Property propertyName is received, the runtime SHOULD execute the following steps:

  1. Return a Promise promise and execute the next steps in parallel .
  2. If a Property with propertyName does not exist, reject promise with a ReferenceError and terminate these steps.
  3. Otherwise, if no read handler has been defined for propertyName , resolve promise with the value of the Property named propertyName provided by the runtime implementation and terminate these steps.
  4. Otherwise, invoke the read handler associated with propertyName . If it rejects, then reject promise with the same error, and resolve promise with the same value.

5.17 5.13 The setPropertyWriteHandler() method

Takes name as string argument and writeHandler as argument of type PropertyWriteHandler . Sets the handler function for writing the specified Property matched by name . Throws on error. Returns a reference to the same object for supporting chaining.

There SHOULD be at most one write handler for any given Property and newly added handlers replace the old handlers. If no write handler is initialized for any given Property , implementations SHOULD implement default property update and notifying observers on change.

When an external request for writing a Property propertyName with a new value value is received, the runtime SHOULD execute the following steps:

  1. Return a Promise promise and execute the next steps in parallel .
  2. If a Property with propertyName does not exist, reject promise with a ReferenceError and terminate these steps.
  3. Otherwise, if no write handler has been defined for propertyName , the runtime implementation SHOULD update the Property value with value , resolve promise and terminate these steps.
  4. Otherwise, invoke the write handler associated with propertyName providing value as argument. If it rejects, then reject promise with the same error, and resolve promise with the same value.

5.18 5.14 The setActionHandler() method

Takes name as string argument and action as argument of type ActionHandler . Sets the handler function for the specified Action matched by name . Throws on error. Returns a reference to the same object for supporting chaining.

If provided, this The action callback function will implement invoking an Action and SHOULD be called by implementations when a request for invoking a the Action is received from the underlying platform. The callback will receive a parameters dictionary argument.

There SHOULD be exactly at most one handler for any given Action and newly added handlers replace the old handlers.

When an external request for invoking the Action identified by name is received, the runtime SHOULD execute the following steps:

  1. Return a Promise promise and execute the next steps in parallel .
  2. If an Action identified by name does not exist, reject promise with a ReferenceError and terminate these steps.
  3. Otherwise, if no action handler is initialized has been defined for any given name , reject promise with a ReferenceError and terminate these steps.
  4. Otherwise, invoke the Action , implementations SHOULD return handler associated with name . If it rejects with error , then reject promise with the same error , otherwise if it resolves with value , then resolve promise with the action is invoked by any client. same value .

5.19 5.15 Examples

Below some ExposedThing interface examples are given.

Example 7 5 : : Create a new blank exposed Thing with a simple property
        try {
  "hljs-keyword">var thing = WoT.produce({ <span class=
"hljs-attr">name: <span class=
"hljs-string">"tempSensor" });
  
  thing.addProperty({
    : <span class=
"hljs-string">"temperature",
    : <span class=
"hljs-number">0.0,
    : <span class=
"hljs-string">'{ "type": "number" }'
    <span class=
"hljs-comment">// use default values for the rest
  }).addProperty({
    : <span class=
"hljs-string">"max",
    : <span class=
"hljs-number">0.0,
    : <span class=
"hljs-string">'{ "type": "number" }'
    <span class=
"hljs-comment">// use default values for the rest
  }).addAction({
    : <span class=
"hljs-string">"reset",
    
  }).addEvent({

"hljs-keyword">var temperatureValueDefinition = {
    type: 
"hljs-string">"number",
    minimum: 
"hljs-number">-50,
    maximum: 
"hljs-number">10000
  };
  
"hljs-keyword">var temperaturePropertyDefinition = temperatureValueDefinition;
  // add the 'forms' property
  temperaturePropertyDefinition.forms = [ ... ];
  var thing = WoT.produce({
    name: "hljs-string">"onchange",
    : <span class=
"hljs-string">'{ "type": "number" }'
  });
  
  thing.setActionHandler(<span class=
"hljs-string">"reset", () => {
    .log(<span class=
"hljs-string">"Resetting maximum");
    thing.writeProperty(<span class=
"hljs-string">"max");
  });
  thing.start().then(<span class=
"hljs-params">() {
      thing.register();

"hljs-string">"tempSensor",
    properties: {      
"hljs-attr">temperature: temperaturePropertyDefinition
    },
    actions: {      reset: {        description: 
"hljs-string">"Reset the temperature sensor",
        input: {          
"hljs-attr">temperature: temperatureValueDefinition
        },
        output: 
"hljs-literal">null,
        forms: []
      },
    },
    events: {      
"hljs-attr">onchange: temperatureValueDefinition
    },
    links: []
  });
  await thing.expose();
  await wot.register("hljs-string">"https://mydirectory.org", thing);

  // define Thing business logic
  setInterval( async () => {
    let mock = Math.random()*100;
    thing.writeProperty(<span class=
"hljs-string">"temperature", mock);

    let old = "hljs-keyword">await thing.readProperty(<span class=
"hljs-string">"max");

"hljs-keyword">await thing["temperature"].read();

    if (old < mock) {
      thing.writeProperty(<span class=
"hljs-string">"max", mock);
      thing.emitEvent();

      await thing["hljs-string">"temperature"].write(mock);
      thing.emitEvent("onchange", mock);

    }
  }, 1000);
} catch (err) {
   console.log("Error creating ExposedThing: " + err);
}
Example 8 6 : Create a new exposed Thing with object property :
        try {
  var statusValueDefinition = {
    type: "hljs-string">"object",
    properties: {      brightness: {        type: 
"hljs-string">"number",
        minimum: 
"hljs-number">0.0,
        maximum: 
"hljs-number">100.0,
        required: 
"hljs-literal">true
      },
      rgb: {        type: 
"hljs-string">"array",
        "minItems": 
"hljs-number">3,
        "maxItems": 
"hljs-number">3,
        items : {            "type" : 
"hljs-string">"number",
            
"hljs-string">"minimum": 0,
            
"hljs-string">"maximum": 255
        }
      }
  };
  
"hljs-keyword">var statusPropertyDefinition = statusValueDefinition;
  // add the 'forms' property
  statusPropertyDefinition["forms"] = [];
  var thing = WoT.produce({    name: 
"hljs-string">"mySensor",
    properties: {      brightness: {        type: 
"hljs-string">"number",
        minimum: 
"hljs-number">0.0,
        maximum: 
"hljs-number">100.0,
        required: 
"hljs-literal">true,
      },
      
"hljs-attr">status: statusPropertyDefinition
    },
    actions: {      status: {        description: 
"hljs-string">"Get status object",
        input: 
"hljs-literal">null,
        output: {          
"hljs-attr">status : statusValueDefinition;
        },
        forms: []
      },
    },
    events: {      
"hljs-attr">onstatuschange: statusValueDefinition;
    },
    links: []
  });
  thing.expose().then(() => {
      thing.register();
  });
} catch (err) {
   console.log(
"hljs-string">"Error creating ExposedThing: " + err);
}
Example 7 : Create a new exposed Thing from a Thing Description
        let thingDescription = "hljs-string">'{ "@context": [ "https://w3c.github.io/wot/w3c-wot-td-context.jsonld", "https://w3c.github.io/wot/w3c-wot-common-context.jsonld" ], "@type": [ "Thing", "Sensor" ], "name": "mySensor", "geo:location": "testspace", "interaction": [ { "@type": [ "Property", "Temperature" ], "name": "prop1", "schema": { "type": "number" }, "saref:TemperatureUnit": "degree_Celsius" } ] }';

"hljs-string">'{ \
  "name": "mySensor", \
  "@context": [ "http://www.w3.org/ns/td",\
     "https://w3c.github.io/wot/w3c-wot-common-context.jsonld" ],\
  "@type": [ "Thing", "Sensor" ], \
  "geo:location": "testspace", \
  "properties": { \
    "prop1": { \
      "type": "number",\
      "@type": [ "Property", "Temperature" ], \
      "saref:TemperatureUnit": "degree_Celsius" \
  } } }';

try {
  // note that produce() fails if thingDescription contains error
  let thing = WoT.produce(thingDescription);
  // Interactions were added from TD
  // WoT adds generic handler for reading any property
  // define a specific handler for one property
  let name = "examplePropertyName";
  thing.setPropertyReadHandler(name, () => {
    console.log("Handling read request for " + name);
    return new Promise((resolve, reject) => {
        let examplePropertyValue = 5;
        resolve(examplePropertyValue);
      },
      e => {
        console.log("Error");
      });
  });
  thing.start();

  thing.expose();

} catch(err) {
   console.log("Error creating ExposedThing: " + err);
}
Example 9 8 : : Create a new exposed Thing from a TD URI
        // fetch an external TD, e.g., to set up a proxy for that Thing
WoT.fetch("http://myservice.org/mySensor/description").then(td => {
  // WoT.produce() ignores instance-specific metadata (security, form)
  let thing = WoT.produce(td);
  // Interactions were added from TD
  // add server functionality
  // ...
});

6. Experimental extensions to the ConsumedThing interface Data types and structures

The [ This section is non-normative. WOT-TD ] specification defines the WoT information model , i.e. the data types and data structures used in WoT Interactions . In this API these definitions translate to dictionary objects that are extended with methods by the interfaces defined in this specification.

In order to avoid duplication of definitions, references to these data types and structures is defined in this section, but for their full description please refer to the Thing Description specification .

6.1 The ThingDescription DataSchema dictionary and its subclasses related functionality, such as enumerating

Value types basically represent types that may be used in JSON object definitions and are used in ThingFragment to define Properties , Action s, Event s and links (introspection) Action parameters. Value types are represented as dictionary objects whose properties and possible sub-classes are defined in the DataSchema section of [ WOT-TD ].

One property of all DataSchema dictionary is an API extension that the type property whose value is out from a set of scope for enumerated strings defined in the DataSchema section of [ WOT-TD ] and is referred as DataType in this specification. However,

Based on type , the draft interfaces following sub-classes of DataSchema are defined here for informative purposes. <span class="idlInterface" id= "idl-def-consumedthing-partial-1" data-idl="" data-title= "ConsumedThing">partial interface <span class= "idlInterfaceID"><a data-no-default="" data-link-for="" data-lt="" href="#dom-consumedthing" class="internalDFN" data-link-type= "dfn"> { <span class="idlMethod" id="idl-def-consumedthing-getproperties" data-idl="" data-title="getProperties" data-dfn-for= "consumedthing"> <a href= "https://heycam.github.io/webidl/#idl-sequence">sequence<<a href="#dom-thingproperty" class="internalDFN" data-link-type= "dfn"> <span class= "idlMethName"><a data-no-default="" data-link-for="consumedthing" data-lt="getproperties()|getProperties" href= "#dom-consumedthing-getproperties" class="internalDFN" data-link-type="dfn">getProperties <span class="idlMethod" id="idl-def-consumedthing-getactions" data-idl="" data-title="getActions" data-dfn-for= "consumedthing"> <a href= "https://heycam.github.io/webidl/#idl-sequence">sequence<<a href="#dom-thingaction" class="internalDFN" data-link-type= "dfn"> <span class= "idlMethName"><a data-no-default="" data-link-for="consumedthing" data-lt="getactions()|getActions" href= "#dom-consumedthing-getactions" class="internalDFN" data-link-type= "dfn">getActions <span class="idlMethod" id="idl-def-consumedthing-getevents" data-idl="" data-title="getEvents" data-dfn-for= "consumedthing"> <a href= "https://heycam.github.io/webidl/#idl-sequence">sequence<<a href="#dom-thingevent" class="internalDFN" data-link-type= "dfn"> <span class= "idlMethName"><a data-no-default="" data-link-for="consumedthing" data-lt="getevents()|getEvents" href="#dom-consumedthing-getevents" class="internalDFN" data-link-type= "dfn">getEvents <span class="idlMethod" id="idl-def-consumedthing-getlinks" data-idl="" data-title="getLinks" data-dfn-for= "consumedthing"> <a href= "https://heycam.github.io/webidl/#idl-sequence">sequence<<a href="#dom-tdlink" class="internalDFN" data-link-type= "dfn"> <span class= "idlMethName"><a data-no-default="" data-link-for="consumedthing" data-lt="getlinks()|getLinks" href="#dom-consumedthing-getlinks" class="internalDFN" data-link-type= "dfn">getLinks }; in [ WOT-TD ]: BooleanSchema 6.1 , NumberSchema , IntegerSchema , StringSchema , ObjectSchema , ArraySchema .

6.2 The getProperties() SecurityScheme method dictionary and its subclasses

Returns the list of Properties Security metadata is represented as dictionary objects whose properties and sub-classes are defined in the Thing Description SecurityScheme section of [ WOT-TD ].

One property of the Thing SecurityScheme dictionary is the scheme property whose value is from a set of enumerated strings defined in the form SecurityScheme section of a list [ WOT-TD ]. Based on type , multiple subclasses of ThingProperty SecurityScheme objects. are defined.

6.4 The Form dictionary

Represents metadata describing service details, with properties defined in the Thing Description Form section of [ WOT-TD ].

6.5 The InteractionFragment dictionary

Represents the Thing common properties of WoT Interactions , one of Property , Action or Event , as defined in the form InteractionPattern section of [ WOT-TD ]. Its subclasses are referred as PropertyFragment , ActionFragment and EventFragment .

6.6 The PropertyFragment dictionary

Represents the Property interaction data that initializes a list ThingProperty object. Its properties are defined in the Property and InteractionPattern sections of [ WOT-TD ].

6.7 The ActionFragment dictionary

Represents the Action interaction data that initializes a ThingAction objects. object. Its properties are defined in the Action and InteractionPattern sections of [ WOT-TD ].

6.3 6.8 The getEvents() EventFragment method dictionary

Returns Represents the list of Event s interaction data that initializes a ThingEvent object. Its properties are defined in the Thing Description Event section of the [ WOT-TD ].

6.9 The ThingFragment dictionary

The ThingFragment dictionary is defined as Thing in the form of [ WOT-TD ]. It is a list dictionary that contains properties representing semantic metadata and interactions ( Properties , Action s and Event s). It is used for initializing an internal representation of a Thing Description and its properties may be used in ThingEvent ThingFilter objects. .

6.4 6.10 The getLinks() ThingDescription method type

Returns the list Serialized representation of linked resources in the Thing Description (a JSON-LD document).

Note

In this version of the API, Thing Description s are represented as an opaque USVString that can be transmitted between devices.

7. Interfaces for WoT Interactions

The data types and structures imported from [ WOT-TD ] are extended by this specification in order to provide the form of a list of interfaces for WoT Interactions .

Every Thing describes its metadata as defined in TDLink ThingFragment , and basic interactions defined as Properties , Action objects. s and Event s. The following interfaces are used for representing these interactions.

6.4.1 7.1 The TDLink Interaction dictionary interface

Contains a hyperlink reference, a relation type The Interaction interface is an abstract class to represent Thing interactions: Properties , Actions and Events .

The InteractionFragment dictionary holds the common properties of PropertyFragment , ActionFragment and EventFragment dictionaries used for initializing ThingProperty , ThingAction and ThingEvent objects in a media type. ThingFragment dictionary used for creating an ExposedThing object.

<span class="idlDictionary" id= "idl-def-tdlink" data-idl="" data-title= "TDLink">dictionary <span class= "idlDictionaryID"><a data-no-default="" data-link-for="" data-lt="" href="#dom-tdlink" class="internalDFN" data-link-type= "dfn"> { <span class="idlMember" id="idl-def-tdlink-href" data-idl="" data-title="href" data-dfn-for="tdlink"> required <span class= "idlMemberType"><a href= "https://heycam.github.io/webidl/#idl-USVString">USVString<a data-no-default="" data-link-for="tdlink" data-lt="" href="#dom-tdlink-href" class= "internalDFN" data-link-type= "dfn"> <span class="idlMember" id="idl-def-tdlink-mediatype" data-idl="" data-title="mediaType" data-dfn-for= "tdlink"> <a href= "https://heycam.github.io/webidl/#idl-USVString">USVString<a data-no-default="" data-link-for="tdlink" data-lt="" href="#dom-tdlink-mediatype"
"idl-def-interaction" data-idl="" data-title=
"Interaction">interface Interaction {
  readonly attribute (Form or FrozenArray<Form>) 
class="internalDFN" data-link-type=
"dfn">
<span class="idlMember" id="idl-def-tdlink-rel" data-idl=""
data-title="rel" data-dfn-for="tdlink">             <span class=
"idlMemberType"><a href=
"https://heycam.github.io/webidl/#idl-DOMString">DOMString<a data-no-default=""
data-link-for="tdlink" data-lt="" href="#dom-tdlink-rel" class=
"internalDFN" data-link-type=
"dfn">
};

"dfn">forms;
};

"dfn">Interaction includes 

InteractionFragment

;


The TDLink forms read-only property represents the protocol bindings initialization data and is initialized by the WoT Runtime .

7.2 The ThingProperty interface

The ThingProperty interface is used in ConsumedThing and ExposedThing objects to represent Thing Property interactions.

The PropertyFragment dictionary contains is used for initializing Property objects in a ThingFragment dictionary used for creating an ExposedThing object. It MUST implement one of the following properties: DataSchema dictionaries.

"idl-def-thingproperty" data-idl="" data-title=
"ThingProperty">interface ThingProperty : Interaction {
  // getter for PropertyFragment properties
  getter 
"https://heycam.github.io/webidl/#idl-any">any (DOMString name);
  // get and set interface for the Property
  
"https://heycam.github.io/webidl/#idl-promise">Promise<any> read();
  
"https://heycam.github.io/webidl/#idl-promise">Promise<void> write(any value);
};

"dfn">ThingProperty includes PropertyFragment;

"dfn">ThingProperty includes 

Observable

;

The href ThingProperty interface contains all the properties defined on PropertyFragment as read-only properties.

The type attribute read-only property represents the type definition for the Property as a hyperlink reference DataSchema dictionary object.

The writable read-only property tells whether the Property value can be updated. If it is false , then the set(value) method SHOULD always reject.

The observable read-only property tells whether the Property supports subscribing to value change notifications. If it is false , then the subscribe() method SHOULD always fail.

The constant read-only property - defined in DataSchema - tells whether the Property value is a constant. If true , the set() and subscribe() methods SHOULD always fail.

The required read-only property - defined in DataSchema - tells whether the Property should be always present on the ExposedThing object.

The read() method will fetch the value of the Property . Returns a Promise that resolves with the value, or rejects with an error.

The rel write() attribute represents method will attempt to set the value of the Property specified in the value argument whose type SHOULD match the one specified by the type property. Returns a relation Promise that resolves on success, or rejects on an error.

7.3 The ThingAction interface


"idl-def-thingaction" data-idl="" data-title=
"ThingAction">interface ThingAction : Interaction {
  
"https://heycam.github.io/webidl/#idl-promise">Promise<any> invoke(optional any inputValue);
};

"dfn">ThingAction includes 

ActionFragment

;

The invoke() method when invoked, starts the Action interaction with the input value provided by the inputValue argument. If inputValue is null , the action does not take any arguments and rejects if any arguments are provided. If the value is undefined , the action will ignore any arguments provided. Otherwise the type of inputValue SHOULD match the DataSchema definition in the input property. Returns a Promise that will reject with an error or will resolve with a value of type defined by the output property.

7.4 The ThingEvent interface


"idl-def-thingevent" data-idl="" data-title=
"ThingEvent">interface ThingEvent : Interaction {
};

"dfn">ThingEvent includes EventFragment;

"dfn">ThingEvent includes 

ThingProperty

;

Since ThingEvent implements Observable through the ThingProperty interface, event subscription is done by invoking the subscribe() method on the event object that returns a cancelable Subscription .

7.5 The mediaType ExposedEvent attribute represents interface


"idl-def-exposedevent" data-idl="" data-title=
"ExposedEvent">interface ExposedEvent : ThingEvent {
  void emit(any payload);
};

7.5.1 The emit() method

Emits an event that carries data specified by the payload argument.

7.6 The value-matching algorithm

The value-matching algorithm is applied to a IANA media value input in relation to a valueType property of type . For TD DataSchema , for instance the value and type properties of a PropertyFragment s there will be registered media types, so applications will be able object, or the inputValue parameter to check whether an the href invoke() link points method of a ThingAction object in relation to the same object. It executes the following steps:

  1. If valueType.type is not defined, or does not fully match a TD string enumerated in DataType , i.e. whether return false .
  2. Otherwise, if valueType.type is "null" : if value is null , return true , otherwise return false .
  3. Otherwise, if valueType.type is "boolean" : if value is either true or false , then return true , otherwise return false .
  4. Otherwise, if valueType.type is "integer" : if value is not an integer type defined by the link underlying platform (such as long or long long ), then return false , otherwise execute the following sub-steps:
    1. If valueType.minimum is fetcheable with defined and value is not greater or equal than that value, return false .
    2. If valueType.maximum is defined and value is not less or equal than that value, return false .
    3. Return true .
  5. Otherwise, if valueType.type is "number" , if value is not an integer or floating point type defined by the underlying platform (such as long or long long or double ), then return false , otherwise otherwise execute the following sub-steps:
    1. If valueType.minimum is defined and value is not greater or equal than that value, return false .
    2. If valueType.maximum is defined and value is not less or equal than that value, return false .
    3. Return true .
  6. Otherwise, if valueType.type is "string" : if value is not a string type defined by the underlying platform, then return false , otherwise return true . In this API. case the algorithm expects a third parameter valueType.enum and runs the following sub-steps:
    • If valueType.enum is an array of strings, then if value fully matches one of the strings defined in the array, return true .
    • Otherwise, return false .
  7. Otherwise, if valueType.type is "array" , execute the following sub-steps:
    1. If value is not an array, return false .
    2. If valueType.minItems is defined, and value does not contain at least valueType.minItems elements, return false .
    3. If valueType.maxItems is defined, and value contains more than valueType.maxItems elements, return false .
    4. Otherwise, if valueType.items is undefined , return false .
    5. Otherwise, if valueType.items is null , return true (i.e. any type is accepted as array element, including heterogenous arrays).
    6. Otherwise, for each element of the array value run the value-matching algorithm against the valueType.items object. If any of these runs returns false , then return false .
    7. Otherwise, return true .
  8. Otherwise, if type is "object" , execute the following sub-steps:
    1. If value is not an Object , return false .
    2. If valueType.properties is not defined, return false .
    3. If valueType.properties is null , return true (i.e. accept any object value).
    4. For each string in the valueType.required array, if it does not match a property name in the value.properties object or in the value object, then return false .
    5. For each property with name propName and value propDataSchema found in valueType.properties , run the following sub-steps:
      1. If the result of applying the value-matching algorithm on the value value[propName] and propDataSchema is false , then return false .
    6. Return true .

7. 8. Observables

This section is non-normative.

Observables are proposed to be included in ECMAScript and are used for handling pushed data associated with various possible sources, for instance events, timers, streams, etc. A minimal required implementation is described here.

Editor's note

This section is informal and contains rather laconic information for implementations on what to support for interoperability.

interface "dfn"> {
<span class="idlMethod" id=
"idl-def-observable-subscribe-next-error-complete" data-idl=""
data-title="subscribe" data-dfn-for="observable">    <span class=
"idlMethType"><a href="#dom-subscription" class="internalDFN"

"dfn">Observable {
  Subscription subscribe("idlParam">(<a href="#dom-observer"
class="internalDFN" data-link-type=
"dfn"> or <a href="#dom-onnext" class=

"idlParam">EventHandler handler,
                         optional ErrorHandler errorHandler,
                         optional 
"internalDFN" data-link-type=
"dfn"> <span class=
"idlParamName">next,
                           <span class=
"idlParam">optional <a href=
"#dom-onerror" class="internalDFN" data-link-type=
"dfn"> <span class=
"idlParamName">error,
                           <span class=
"idlParam">optional <a href=
"#dom-oncomplete" class="internalDFN" data-link-type=

"dfn">OnComplete "idlParamName">complete
};
<span class="idlInterface" id="idl-def-subscription" data-idl=""
data-title="Subscription">interface <span class=
"idlInterfaceID"><a data-no-default="" data-link-for="" data-lt=""
href="#dom-subscription" class="internalDFN" data-link-type=
"dfn"> {
<span class="idlMethod" id="idl-def-subscription-unsubscribe"
data-idl="" data-title="unsubscribe" data-dfn-for=
"subscription">    <span class=
"idlMethType">void <span class=
"idlMethName"><a data-no-default="" data-link-for="subscription"
data-lt="unsubscribe|unsubscribe()" href=
"#dom-subscription-unsubscribe" class="internalDFN" data-link-type=
"dfn">
<span class="idlAttribute" id="idl-def-subscription-closed"
data-idl="" data-title="closed" data-dfn-for=
"subscription">    readonly attribute <span class=
"idlAttrType"><a href=

"idlParamName">onComplete);
};
interface Subscription {
  void unsubscribe();
  readonly attribute 
"https://heycam.github.io/webidl/#idl-boolean">boolean data-link-for="subscription" data-lt="" href=
"#dom-subscription-closed" class="internalDFN" data-link-type=

data-link-for="subscription" data-lt="subscription.closed|closed"
href="#dom-subscription-closed" class="internalDFN" data-link-type=

"dfn">closed;
};
<span class="idlInterface" id="idl-def-observer" data-idl=""
data-title="Observer">interface <span class=
"idlInterfaceID"><a data-no-default="" data-link-for="" data-lt=""
href="#dom-observer" class="internalDFN" data-link-type=
"dfn"> {
<span class="idlMethod" id="idl-def-observer-next-value" data-idl=
"" data-title="next" data-dfn-for="observer">    <span class=
"idlMethType">void <span class=
"idlMethName"><a data-no-default="" data-link-for="observer"
data-lt="next()|next" href="#dom-observer-next" class="internalDFN"
data-link-type="dfn">next(<span class=
"idlParam"><a href=
"https://heycam.github.io/webidl/#idl-any">any
<span class="idlMethod" id="idl-def-observer-error-error" data-idl=
"" data-title="error" data-dfn-for="observer">    <span class=
"idlMethType">void <span class=
"idlMethName"><a data-no-default="" data-link-for="observer"
data-lt="error()|error" href="#dom-observer-error" class=
"internalDFN" data-link-type="dfn">error(<span class=
"idlParam"><a href=
"https://heycam.github.io/webidl/#idl-Error">Error
<span class="idlMethod" id="idl-def-observer-complete" data-idl=""
data-title="complete" data-dfn-for="observer">    <span class=
"idlMethType">void <span class=
"idlMethName"><a data-no-default="" data-link-for="observer"
data-lt="complete()|complete" href="#dom-observer-complete" class=
"internalDFN" data-link-type="dfn">complete
};
<span class="idlCallback" id="idl-def-onnext" data-idl=""
data-title="OnNext">callback <span class=
"idlCallbackID"><a data-no-default="" data-link-for="" data-lt=""
href="#dom-onnext" class="internalDFN" data-link-type=
"dfn"> = <span class=
"idlCallbackType">void<span class=

};
callback EventHandler = void (
"idlParamType">"https://heycam.github.io/webidl/#idl-any">any
<span class="idlCallback" id="idl-def-onerror" data-idl=""
data-title="OnError">callback <span class=
"idlCallbackID"><a data-no-default="" data-link-for="" data-lt=""
href="#dom-onerror" class="internalDFN" data-link-type=
"dfn"> = <span class=
"idlCallbackType">void<span class=

"https://heycam.github.io/webidl/#idl-any">any value);
callback ErrorHandler = void (
"idlParamType">"https://heycam.github.io/webidl/#idl-Error">Error
<span class="idlCallback" id="idl-def-oncomplete" data-idl=""
data-title="OnComplete">callback <span class=
"idlCallbackID"><a data-no-default="" data-link-for="" data-lt=""
href="#dom-oncomplete" class="internalDFN" data-link-type=
"dfn"> = <span class=

"https://heycam.github.io/webidl/#idl-Error">Error error);
callback OnComplete =
"idlCallbackType">
void

();

7.1 The Observer interface

The Observer interface defines the following callbacks needed can be provided when subscribing to handle an Observable :

7.2 8.1 The Subscription interface

Contains the closed property of type boolean that tells if the subscription is closed or active.

Also, contains the unsubscribe () method that cancels the subscription, i.e. makes a request to the underlying platform to stop receiving data from the source, and sets the closed property to false .

7.3 8.2 The Observable interface

The Observable interface enabled subscribing to pushed data notifications by the subscribe () method:

8. 9. Security and Privacy Editor's note Please see

In general the security measures taken to protect a WoT Security system will depend on the threats and Privacy repository attackers that system may face and the value of the assets needs to protect. A detailed discussion of security and privacy considerations for work in progress regarding the Web of Things, including a threat models, assets, risks, recommended mitigations, model that can be adapted to various circumstances, is presented in the informative document [ WOT-SECURITY-CONSIDERATIONS ]. This section includes only normative recommendations relevant to the WoT Thing Description.

When designing new devices and services for use with the WoT, we have documented a set of best practices for in [ WOT-SECURITY-BEST-PRACTICES ] that SHOULD be followed. This best-practices document may be updated as security measures evolve. Following these practices does not guarantee security, but it at least will help to avoid common known vulnerabilities and privacy for systems pitfalls.

Below are specific recommendations related to WoT runtime implementations:

Some additional specific recommendations relevant for WoT script developers:

9. 10. Terminology and conventions

The generic WoT terminology is defined in [ WOT-ARCHITECTURE ]: Thing , Thing Description (in short TD ), Web of Things (in short WoT ), WoT Interface , Protocol Bindings , WoT Runtime , Consuming a Thing Description , Thing Directory , WoT Interactions , Property , Action , Event etc.

JSON-LD is defined in [ JSON-LD ] as a JSON document that is augmented with support for Linked Data by providing a @context property with a defining URI . Data.

The terms URL and URL path are defined in [ URL ].

The following terms are defined in [ HTML52 ] and are used in the context of browser implementations: browsing context , top-level browsing context , global object , incumbent settings object , Document , document base URL , Window , WindowProxy , origin , ASCII serialized origin , executing algorithms in parallel , queue a task , task source , iframe , valid MIME type .

A browsing context refers to the environment in which Document objects are presented to the user. A given browsing context has a single WindowProxy object, but it can have many Document objects, with their associated Window objects. The script execution context associated with the browsing context identifies the entity which invokes this API, which can be a web app , a web page , or an iframe .

The term secure context is defined in [ WEBAPPSEC ].

Error , EvalError , RangeError , ReferenceError , SyntaxError , TypeError , URIError , script execution context , Promise , JSON , JSON.stringify and JSON.parse are defined in [ ECMASCRIPT ].

DOMString , USVString , ArrayBuffer , BufferSource and any are defined in [ WEBIDL ].

The algorithms utf-8 encode , and utf-8 decode are defined in [ ENCODING ].

IANA media type s (formerly known as MIME types) are defined in RFC2046 .

The terms hyperlink reference and relation type are defined in [ HTML52 ] and RFC8288 .

10. 11. Conformance

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 , SHOULD , and SHOULD NOT are to be interpreted as described in [ RFC2119 ].

This document defines conformance criteria that apply to a single product: the UA (user agent) that implements the interfaces it contains.

This specification can be used for implementing the WoT Scripting API in multiple programming languages. The interface definitions are specified in [ WEBIDL ].

The user agent (UA) may be implemented in the browser, or in a separate runtime environment, such as Node.js or small embedded runtimes.

Implementations that use ECMAScript executed in a browser to implement the APIs defined in this document MUST implement them in a manner consistent with the ECMAScript Bindings defined in the Web IDL specification [ WEBIDL ].

Implementations that use TypeScript or ECMAScript in a runtime to implement the APIs defined in this document MUST implement them in a manner consistent with the TypeScript Bindings defined in the TypeScript specification [ TYPESCRIPT ].

This document serves a general description of the WoT Scripting API. Language and runtime specific issues are discussed in separate extensions of this document.

A. Changes

The following is a list of major changes to the document. For a complete list of changes, see the github change log . You can also view the recently closed bugs issues .

B. Open issues

The following problems are being discussed and need most attention:

C. Acknowledgements Acknowledgments

Special thanks to former editor Johannes Hund (until August 2017, when at Siemens AG) for developing this specification. Also, the editors would like to thank Dave Raggett, Matthias Kovatsch, Michael Koster and Michael McCool for their comments and guidance.

D. References

D.1 Normative references

[ECMASCRIPT]
ECMAScript Language Specification . Ecma International. URL: https://tc39.github.io/ecma262/
[ENCODING]
Encoding . Anne van Kesteren; Joshua Bell; Addison Phillips. W3C. 15 December 2016. W3C Candidate Recommendation. URL: https://www.w3.org/TR/encoding/
[HTML52]
HTML 5.2 . Steve Faulkner; Arron Eicholz; Travis Leithead; Alex Danilo; Sangwhan Moon; Erika Doyle Navara; Theresa O'Connor; Robin Berjon. W3C. 14 December 2017. W3C Recommendation. URL: https://www.w3.org/TR/html52/
[JSON-LD]
JSON-LD 1.0 . Manu Sporny; Gregg Kellogg; Markus Lanthaler. W3C. 16 January 2014. W3C Recommendation. URL: https://www.w3.org/TR/json-ld/
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels . S. Bradner. IETF. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
[TYPESCRIPT]
TypeScript Language Specification . Microsoft. 1 October 2012. URL: https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md
[URL]
URL Standard . Anne van Kesteren. WHATWG. Living Standard. URL: https://url.spec.whatwg.org/
[WEBAPPSEC]
Secure Contexts . W3C. 17 July 2015. URL: https://w3c.github.io/webappsec/specs/powerfulfeatures/ https://w3c.github.io/webappsec/specs/powerfulfeatures
[WEBIDL]
Web IDL . Cameron McCormack; Boris Zbarsky; Tobie Langel. W3C. 15 December 2016. W3C Editor's Draft. URL: https://heycam.github.io/webidl/
[WOT-ARCHITECTURE]
Web of Things Architecture . W3C. 14 September 20 August 2017. URL: https://www.w3.org/TR/2017/WD-wot-architecture-20170914/ https://w3c.github.io/wot-architecture/
[WOT-SECURITY-BEST-PRACTICES]
Web of Things Security and Privacy Best Practices (WIP) . W3C. WIP. URL: https://github.com/w3c/wot-security/blob/master/wot-security-best-practices.md
[WOT-SECURITY-CONSIDERATIONS]
Web of Things Security and Privacy Considerations . W3C. 28 August 2017. URL: https://w3c.github.io/wot-security/
[WOT-SECURITY-TESTING]
Web of Things Security Testing and Validation . W3C. WIP. URL: https://github.com/w3c/wot-security/blob/master/wot-security-testing.md
[WOT-TD]
WoT Thing Description . W3C. 21 October 2018. URL: https://www.w3.org/TR/2018/WD-wot-thing-description-20181021/

D.2 Informative references

[WOT-TD]
[HTML]
WoT Thing Description HTML Standard . W3C. 20 August 2017. . Anne van Kesteren; Domenic Denicola; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. Living Standard. URL: https://www.w3.org/TR/2018/WD-wot-thing-description-20180405/ https://html.spec.whatwg.org/multipage/