The Web of Things Interest Group (IG) is exploring and testdriving concepts and technologies to define WoT building blocks that appear ready for progression along the W3C Recommendation track. Furthermore, the IG is re-evaluating the current working assumptions of the Web of Things Working Group (WG) based on "running code". The central mechanism for this are the W3C WoT PlugFests, where both Member and non-member implementors of WoT building blocks come together and test their solutions as well as demo their proposals. This document defines the scope and technical basis of the PlugFests. For this, it points to the (draft) specifications that apply, documents possible deltas that need to be realized, and defines which parts are mandatory, optional, or experimental to implement for the targeted PlugFest. Each PlugFest has its own release of this document.
This document is an intermediary release of the current practices that are used at the Burlingame 2017 PlugFest of the Web of Things Interest Group.
The IG operates in parallel to the Web of Things Working Group to explore new technologies and concepts, and to validate the current working assumptions. The latter is done buy testdriving implementations of the current draft specificiations in so-called PlugFests. This document defines the scope and technical basis of the Burlingame 2017 PlugFest. It assumes that the reader is familar with the basic concepts of W3C Web of Things and aware of the Working Group documents that specify the underlying WoT building blocks. The implementation target for the PlugFest is defined by referencing the underlying Working Draft version and stating the deltas (e.g., increments or optional experimental features) that need to be applied. Furthermore, it is defined, which parts are mandatory, optional, or experimental to implement.
Note that there are different versions of the draft specifications out there:
w3.org/TR/...
to the most recent release on the w3.org Web server.
It changes whenever the group publishes a new Working Draft version.
...-20170914
.
These versions are fixed and archived on the w3.org Web server.
This document uses the following terms as defined by the WoT Architecture document. The WoT prefix is used to avoid ambiguity for terms that are defined specifically for Web of Things concepts.
Please refer to this markdown file. Once the terminology definitions are stable, they will be included here.
This section lists the different WoT building blocks that will be used in the PlugFest. For each, the PlugFest target is defined through a specified draft specification version and different deltas to be applied:
Furthermore, this document provides samples and changelogs to enable a quick start for developers already familiar with the WoT building blocks and previous PlugFests.
The basis for the Thing Description (TD) implementation is the Web of Things (WoT) Architecture W3C First Public Working Draft 14 September 2017.
The WoT Architecture is generic about the discovery mechanism, as concrete solutions have been an IG activity so far. We will continue to use the same discovery mechanisms as in previous PlugFests.
Manual discovery means that applications such as scripts for the WoT Scripting API are directly configured with the URI of the TD of the Thing to be consumed. For instance, this can be an http: URI for TD located on a Web server or a file: URI for locally stored TD (note that the WoT Runtime needs to be able to resolve file URIs).
The W3C WoT IG is providing a Thing Directory under http://plugfest.thingweb.io:8081/. Its source code is available on Github.
PlugFest participants must be able to register the TDs of their Things at the Thing Directory. This can be done by the Thing implementation itself, a commissioning tool, or manually using a Web browser extension such as Postman.
An OpenAPI (Swagger) documentation of the Thing Directory can be found here. A textual documentation is available here.
None
None
POST /td?lt=3600 HTTP/1.1 Host: plugfest.thingweb.io:8081 Content-Type: application/ld+json {TD sample t.b.d.}
None
The WoT Thing Description is the central WoT building block and must be provided if a Thing shall participate in the PlugFest. WoT Servers must provide their TD (directly or via external source such as a Web server or shared file). WoT Clients must be able to parse TDs and use the metadata correctly.
The basis for the Thing Description (TD) implementation is the Web of Things (WoT) Thing Description W3C First Public Working Draft 14 September 2017.
The Editor's Draft of the WoT Thing Description defines a new type system that will be tested at the Burlingame PlugFest.
The values of inputData
and outputData
are no longer verbatim JSON Schema, but a Linked Data version of the JSON Schema definitions. Please see Section 6.5 of the Editor's Draft for details.
Simple types do not require any changes compared to previous JSON Schema.
"outputData": { "type": "number", "minimum": 0, "maximum": 100 }
42
Complex types now have a fields
definition to avoid the naming conglict with Properties.
The field element definitions are given in an array to be JSON-LD compatible.
"outputData": { "type": "object", "fields": [ { "name": "code", "value": { "type": "integer" } }, { "name": "message", "value": { "type": "string" } } ], "required": ["code"] }
{ "code": 4711, "message": "ConsumedThing does not respond" }
The TD field security
can provide access control and security configuration metadata.
It is already defined as optional.
In Burlingame, however, PlugFest participants are encouraged to include this field and propose their solutions for their requirements (e.g., OAuth, required proxies, etc.).
Here as an example, JSON Web Token (JWT) type is assigned (cat), the corresponding hashing algorithm "HS256" (alg), and issuing authority of the security token (as).
"security": { "cat":"token:jwt", "alg":"HS256", "as":"https://authority-issuing.example.org" }
Semantic annotations are also optional by definitions. Again, Burlingame PlugFest participants are encouraged to include these annotations in their TDs.
As per Editor's Draft, Property Interactions can now have a boolean observable
flag.
When set to true, WoT Clients can subscribe for change-of-value notifications, which need to be handled by the Protocol Bindings.
A straight-forward candidate is CoAP Observe.
{ "@type": ["Property"], "name": "temperature", "outputData": { "type": "number" }, "observable": true }
Also see the related delta for the WoT Scripting API under .
The define concepts and vocabulary for the WoT Thing Descriptions. Experimental TDs may include instantiations of the WoT Binding Templates.
{ "@context": [ "http://w3c.github.io/wot/w3c-wot-td-context.jsonld", { "sensor": "http://example.org/sensors#" } ], "@type": ["Thing", "sensor:Sensor"], "name": "MyTemperatureThing", "interaction": [ { "@type": ["Property", "sensor:Temperature" ], "name": "temperature", "outputData": { "@type": "sensor:TemperatureReading", "sensor:Unit": "sensor:Celsius", "type": "number" }, "writable": false, "observable": true, "link": { "href": "https://mytemp.example.com/temp", "mediaType": "application/json", "http:methodName": "get", "observe": "http:sse" } } ] }
Note that the entry observe
is highly experimental.
inputData
and outputData
are no longer verbatim JSON Schema, but also Linked Data / JSON-LD.security
field of the TD, e.g., to describe the HTTPS authentication used, OAuth tokens, required proxies, etc.observable
flag, a boolean value. The link
field needs to provide an (experimental) way to signal how to make use of the observe feature.The WoT Binding Templates are not released as First Public Working Draft yet.
The basis for the Binding Templates implementation in TDs and Servients is the WoT Binding Templates Editor's Draft.
None
None
None
"http:methodName": "get" "http:methodName": "post" "http:methodName": "put" "http:methodName": "delete" "coap:methodName": "patch" "mqtt:methodName": "subscribe" "coap:methodName": "get" "coap:methodName": "post" "coap:methodName": "put" "coap:methodName": "delete" "coap:methodName": "fetch" "coap:methodName": "patch" "coap:methodName": "ipatch"
The WoT Scripting API is an API specification to have a uniform way to write applications for the Web of Things. It provides means for discovery, provisioning, and control of Things.
The basis for the API implementation is the WoT Scripting API First Public Working Draft from 14 September 2017.
The FPWD corrently defines the ThingPropertyInit
without a handler for Property changes. Thus, a desired new state of the Property cannot be propagated within the Thing, e.g., to adjust local hardware accordingly.
The ThingPropertyInit
interface must be implemented as:
dictionary ThingPropertyInit { DOMString name; boolean writable = true; sequencesemanticTypes; ThingDescription description; PropertyHandler onWrite; any value; };
The PropertyHandler
callback must take the old value and new value as arguments.
WoT.discover()
Method
The discovery implementation is not well documented yet.
Thus, the WoT.discover()
method may be omitted.
Burlingame PlugFest participants are encouraged, however, to implement this to gain more experience.
A possible starting point is the local
discovery, where the WoT Runtime is expected to return all Things that are local to it.
ConsumedThing.observe()
Method
The observe()
method is an alternative to the addListener()
/removeListener()
methods.
It may be omitted by PlugFest implementations.
If present, the observe()
method expects a RequestType
argument that assumes mechanisms that are not provided by Things (e.g., remote notifications when a Property is read or an Action invoked).
This argument may be ignored, so that observe()
only takes the name of the Interaction to be observed.
This can either be an Observable Property or an Event.
Section 4.9 of the FPWD defines type that are not compatible with the Thing Description model. All definitions may and are recommended to be omitted by PlugFest implementations.
RequestHandler
API
The FPWD introduced an alternative API that works more like a REST framework and exposes low-level Request
objects to the script.
All related specifications may be omitted by PlugFest implementations.
None
ThingFilter
as argument and returns an Observable.consumeDescription()
and consumeDescriptionUri()
createThing()
, createFromDescription()
, and createFromDescriptionUri
description
replaced getDescription()
ThingPropertyInit parameter
ThingActionInit
parameterThingEventInit
parameterstart()
stop()
register()
The main component so far is the TestThing. It is defined by a TD template and a script and all PlugFest implementations shall be prepared as follows.
Note: A TD template shall be a TD that does not include instance specific information such as `@id` or `href`.
WoT Clients shall be prepared to be able to consume all TDs that have one or more features included in the TestThing TD template and shall probe all the Interactions defines.
All implementations that support WoT Servers shall implement the TestThing according to its TD template. The template must be completed with instance-specific information.
All implementations that implement the WoT Scripting API, and hence support a WoT Runtime, shall be able to execute the TestThing script.
The basis for the Thing Description (TD) implementation is the WoT Thing Description First Public Working Draft from 14 September 2017.
None
None
The security mechanisms in this section describe how to to establish the authorization and the authentication of WoT interactions for the following components:
Note that adding security is regarded to be optional. Moreover, the mechanisms currently described provide basic protection of the interactions. Doing so is intentional to offer a low entry-barrier to encourage many security-enabled PlugFest implementations. For that purpose it is fully intentional to take various shortcuts. For production use additional considerations and additional security mechanisms/checks will typically be required.
The architectural security model adopted from IETF ACE define also the following components:
For a security-enabled PlugFest implementation Request Authorization and Caller Authentication is considered to be the primary goal while Message Authentication and Encryption represents a subordinate security goal for now.
We would like to point out that the technical details are the same as in previous PlugFests (see HowTo description from Nice PlugFest). That said, this is also the reason that some identifiers and names relate to Nice (e.g., NicePlugfestRS
or NicePlugfestAS
).
The goal is to authorize requests and (implicitly) authenticate callers by means of bearer security token (JWT, see [[!RFC7519]]) with minimal contents.
For the protection of high-value resources, PoP respectively HoK models may be required instead of bearer tokens.
The following security communication practices provide details for PlugFests and might be moved to a decicated section given that it does not fall anymore into the scope of this section, namely "Concepts & Building Blocks".
Resource Server (RS) Security over HTTP
NicePlugfestRS
NicePlugfestAS
{ keys: [ { kty: "RSA", e: "AQAB", use: "sig", kid: "273993369", alg: "RS256", n: "3lh9zHIe3Zi4mfYpl7AwU25dP4Axvt4WTpM2_l86YX8DBFeBzvuTE5U2yIpH_Cs9vUZnMjkwok3ez8SKzvFb6mTlPY9Lfu6Gk7_dfsolFKJoq97aNbHU_i47YOQG_Ecni4i6DhWcDKQkyA6KFAmjZZ_gxZJekisSkewuKSmDo8M" } ] }
Skipped for RSs that support RS256 for now.
Authorization
header. Respond with a 401 error if notAuthorization: Bearer
-header with non-null/empty contents. Respond with a 401 error if notAuthorization: Bearer
-header is a JWT object. Respond with a 401 error if notiss
" is NicePlugfestAS
. Respond with a 401 error if notaud
" is NicePlugfestRS
. Respond with a 401 error if notsub
" as the originator of the request and process it as usual
For more background see [[!RFC6750]] (HTTP Bearer tokens), [[!RFC7519]] (JWT), and [[!RFC7517]] (JWK).
For JWT libraries in various programming languages see http://jwt.io.
Client (C) Security over HTTP
Registration is done according [[!RFC7591]] and described in the following.
Create a HTTP request with JSON request content as in the following prototype and send it via TLS to the AM.
For the PlugFest use URL:https://plugfest.thingweb.io:8443/wos/0.1/oauth/register
.
Request
POST /wos/0.1/oauth/register HTTP/1.1
Request headers
Host: plugfest.thingweb.io
Content-Type: application/json
Accept: application/json
Request body
{
"client_name": "yourClientName",
"grant_types": ["client_credentials"]
}
Naming convention: replace all values prefixed "your" with your value i.e. use any string of your choice instead "yourClientName"
Response
Check that you get a 201 Created response and extract the value of client_id
(this value is called <c_id>
in the following) and the value of client_secret
(called <c_secret>
in the following) from the JSON response body. A response body prototype is:
{ "client_id": "889d02cf-16dd-4934-9341-a754088faxyz", "client_secret": "ahd5MU42J0hIxPXzhUhjJHt2d0Oc5M6B644CtuwUlE9zpSuF14-kXYZ" }
Store <c_id>
and <c_secret>
for use during the token acquisition.
Create a HTTP request as in the following prototype and send it via TLS to the AM.
For the PlugFest use URL:https://plugfest.thingweb.io:8443/wos/0.1/oauth/token
.
Request
POST /wos/0.1/oauth/token HTTP/1.1
Request headers
Host: plugfest.thingweb.io
Content-Type: application/x-www-form-urlencoded
Accept: application/json
Authorization: Basic Base64(<c_id>:<c_secret>)
Request body
grant_type=client_credentials
Response
Check that you get a 200 OK response and extract the value of the access_token
member from the JSON response body. A response body prototype is:
{ "access_token": "eyJraWQiOiIyNzM5OTMzNjkiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiI2MTAyYjk4NC1lNGI0LTQ5ZjctYmRiZC1hOGViMWY0ZmQxMzYiLCJzdWIiOiI2MTAyYjk4NC1lNGI0LTQ5ZjctYmRiZC1hOGViMWY0ZmQxMzYiLCJpc3MiOiJodHRwczpcL1wvcGx1Z2Zlc3QudGhpbmd3ZWIuaW86ODQ0M1wvd29zXC8wLjFcL29hdXRoXC8iLCJ0eXAiOiJvcmc6dzM6d290Omp3dDphbTphcy13cmFwOm1pbiIsImFzX3Rva2VuIjoiZXlKcmFXUWlPaUl5TnpNNU9UTXpOamtpTENKaGJHY2lPaUpTVXpJMU5pSjkuZXlKemRXSWlPaUkyTVRBeVlqazROQzFsTkdJMExUUTVaamN0WW1SaVpDMWhPR1ZpTVdZMFptUXhNellpTENKaGRXUWlPaUpPYVdObFVHeDFaMlpsYzNSU1V5SXNJbWx6Y3lJNklrNXBZMlZRYkhWblptVnpkRUZUSWl3aWRIbHdJam9pYjNKbk9uY3pPbmR2ZERwcWQzUTZZWE02YldsdUlpd2lhblJwSWpvaU5qWmxaRGs0TURJdE1XWTNZaTAwWWpGaExXRm1NVE10TlRFNE1UZGtNRGMwWVdObEluMC5ub2xsWTFfWHQ1b2llM3EtdHFzbjJZejBqNmhTUEJOQnRDMWdVQmFKRjc4VDZjLUc4UVB6MVo4aVNUdzRmV2JmRE9yNFV0cjNmTFNkbi00Q0NKb0xGbWIxQWp1eTBaNGMybmdhbTJCSVB2d0RubzZoLTRHbXFkLU01cnNQV2EteS1md3I0Yi0yVFdiY2p2Vm9xb0wyWDR1c2RMeHNLcDFza0Z6YUxCVUpmTTQiLCJqdGkiOiI0M2U4MjJlMC00N2VhLTRlOWQtYmVhYi1hNGNmZjRkOGNhZjAifQ.axhPGhk6BCP0WgzojCtwWIcpw7kmG53Gb4TiopYLMAhXPfzPmqpEZKBYWQmDeRNkFVx2xjmmw1MAam-HIfyHJbTWQAP68tKq9HIfHt6I0XraG0hvb-RP8ECEmm7pPWw1F4GntKebrjP4TawmoQpmn9MLaBuxhTpcGMo8UTkOmqA", "token_type": "bearer", "expires_in": 3600 }
Decode the value of the access_token
value. This provides a JWT structure. Optionally validate it (see above for JWT validation hints). Extract the value of the as_token
member in the JWT payload. This value is called <as_token>
in the following.
Authorization: Bearer <as_token>
header to HTTP requests to RS. Resource Server (RS) Security over CoAP
Same as for HTTP communications. See above.
Same as for HTTP communications. See above
Bearer <jwt_token>
with a non-null/empty <jwt_token>
. Respond with a 4.01 error if notiss
" is NicePlugfestAS
. Respond with a 4.01 error if notaud
" is NicePlugfestRS
. Respond with a 4.01 error if notsub
" as the originator of the request and process it as usualThe Authorization Manager (AM) and Authorization Server (AS) components also support a more advanced way of request authorization that supplies a JWT bearer security token with actual access control information in style of AIF (draft-bormann-core-ace-aif-03).
@TODO integrate advanced level of request authorization and caller authentication
Message authentication and encryption is done by means of TLS (for HTTP) and DTLS (for CoAP).
@TODO add adequate information how message authentication and encryption is to be done
Things brought to the PlugFest location can be unprotected prototypes. The PlugFest network is behind a NAT and continuous monitoring can be assumed.
Things and gateways deployed in the cloud to testdrive connectivity and synchronization of Servients should be hardened against attacks. The simplest way is to isolate them from actual infrastructure, only start them during the PlugFest hours, and monitor them during this time. When running them for a longer time (e.g., providing them already for pre-testing), the instances should be hardened through the usual Web security features such as TLS and an access control mechanism.
This section includes the goals and ideas of each WoT PlugFest in chronological order. Before reflecting the "lessons learned" of each PlugFest, which drove the development of the presented practices, the document provides a howto for participating in the PlugFests.
@TODO Add more detailed information along with pictures of each plugfest
The current status of the howto is Düsseldorf (2017-07)
This howto is kept up to date with the requirements for the latest/upcoming edition of the PlugFest. To participate in an upcoming PlugFest, prepare an implemention by deciding on the following questions. The answers to these questions will also be needed when registering for a PlugFest by filling out a table in the corresponding PlugFest page in the WoT IG Wiki. Note that there might be additional options in the future when more features are defined or more Protocol Bindings become popular in the PlugFest.
A WoT client implementation requires a TD parser and a user interface or control logic to drive the interaction with one or more other Things. Optionally, it can implement lookup support for the Repository (also see 3.2.6.2.2 Repository. An HowTo how such a lookup can be realised can be found here. For the TD parser, a JSON-LD library is recommended, but it is also possible to implement a simpler parser that exploits knowledge about which parts of the TD are actually relevant for the Thing. Simple WoT clients can have a limited notion of the semantics and only support interactions that match their own capabilities. A simple switch, for instance, does not need to understand the RGB color model. Powerful WoT clients, however, may have full RDF support and require access to Linked Data to reason about the metadata and interactions provided by the TD.
A WoT server requires resource handlers that implement Properties, Actions, or Events. The TD can vary between static or dynamically generated based on the implementd interactions. For this, a simple JSON library is enough, as the vocabulary is fully known at design time. A WoT server should also implement support for TD Repository registration. A registration HowTo can be found here.
A WoT servient is capable of thing-to-thing interaction. It needs to implement both server and client requirements. The server part is usually used to configure the Thing, so it knows which interaction to select on the other Thing(s). A powerful Thing might only need rough information such as all Things at location X and then uses semantic match between itself and the capabilities of the discovered Things. A smart switch, for instance, has the notion of being on or off, and hence binds to the firstonOffStatus
interaction it finds on discovered lamps. Resource-constrained Things usually need the exact wiring configuration by a user or comissioning tool. A smartphone app, for instance, can be used to write the TD of a specific lamp together with the@id
value of the desired interaction to the configuration Properties of a energy-harvesting switch. The client part then starts the interaction with the other Thing(s) by constructing messages based on the given TD and implemented Protocol Bindings.
The classic Web protocol is currently most common for clients (e.g., with a Web UI) and more powerful Things. There is a plethory of HTTP frameworks available for most languages and platforms.
This protocol is predominant for resource-constrained Things. Several different CoAP implementations and frameworks can be found here.
To evaluate more Protocol Bindings, implementors are welcome to bring Things with alternative protocol stacks to the PlugFests. Some protocols might require a shim layer to allow for the resource model of WoT.
The application logic is implemented directly in the firmware or a supported language of the protocol framework. This is the default for resource-constrained Things that serve a specific purpose.
Having the application logic in scripted apps means that the servient must implement a runtime environment that provides the Scripting API. Node.js may provide a good initial prototype for a WoT runtime environment on more powerful Things or cloud servients. In the embedded world, Lua is a popular scripting language that could be used for portable apps.
This first WoT PlugFest elaborated, based on a JSON-LD Thing Description, server and client role of a Thing. Protocols such as CoAP, HTTP and WebSocket were combined with JSON and EXI data formats.
More information can be found on the dedicated wiki page.
Based on the previous PlugFest in Sapporo four advances will be proposed (more information can be found on the dedicated wiki page).
Find PlugFest organization and contributor details on the dedicated WoT Montreal PlugFest wiki page.
With this PlugFest we would like to move on from testing the practices in this document to actually accomplishing real-world scenarios.
Compared to previous PlugFests we do not plan to introduce new technologies nor additional parts. Instead we focus on a broader support of the same features by different implementations.
Moreover, we especially encourage real-world scenarios in the following two areas:
Former PlugFest participants are well aware of the available actuation and sensing capabilities of Things. That said, we would like to stimulate new scenarios based on what we have seen so far (e.g., discover Properties and combine them with Actions and/or Events of other Things). Feel free to come up with rather sophisticated real-world use-cases. Please also make use of the discovery to improve PlugFest preperation and enable onsite combination of Things.
It is time to stress what we elaborated so far to actually proof it!
Find PlugFest organization and contributor details on the dedicated WoT Osaka PlugFest wiki page.
The WoT TestThing Thing Description (TD) for the PlugFest is shown below. Please note that the Link URIs are only valid for a locally running TestThing. Your TestThing implementation should provide the correct, globally reachable Links.
{ "@context": ["http://w3c.github.io/wot/w3c-wot-td-context.jsonld"], "@type": "Thing", "name": "TestThing", "interaction": [{ "@type": ["Property"], "link": [{ "href": "http://127.0.0.1:8080/TestThing/properties/bool", "mediaType": "application/json" }], "name": "bool", "outputData": { { "type": "boolean" } , "writable": true }, { "@type": ["Property"], "link": [{ "href": "http://127.0.0.1:8080/TestThing/properties/int", "mediaType": "application/json" }], "name": "int", "outputData": { "type": "integer" }, "writable": true }, { "@type": ["Property"], "link": [{ "href": "http://127.0.0.1:8080/TestThing/properties/num", "mediaType": "application/json" }], "name": "num", "outputData": { "type": "number" }, "writable": true }, { "@type": ["Property"], "link": [{ "href": "http://127.0.0.1:8080/TestThing/properties/string", "mediaType": "application/json" }], "name": "string", "outputData": { "type": "string" }, "writable": true }, { "@type": ["Property"], "link": [{ "href": "http://127.0.0.1:8080/TestThing/properties/array", "mediaType": "application/json" }], "name": "array", "outputData": { "type": "array" }, "writable": true }, { "@type": ["Property"], "link": [{ "href": "http://127.0.0.1:8080/TestThing/properties/object", "mediaType": "application/json" }], "name": "object", "outputData": { "type": "object", "properties": { "prop1": { "type": "integer" }, "prop2": { "type": "string" } }, "required": { "0": "prop1", "1": "prop2" } }, "writable": true }, { "@type": ["Action"], "link": [{ "href": "http://127.0.0.1:8080/TestThing/actions/void-void", "mediaType": "application/json" }], "name": "void-void" }, { "@type": ["Action"], "link": [{ "href": "http://127.0.0.1:8080/TestThing/actions/void-int", "mediaType": "application/json" }], "name": "void-int", "outputData": { "type": "integer" } }, { "@type": ["Action"], "inputData": { "type": "integer" }, "link": [{ "href": "http://127.0.0.1:8080/TestThing/actions/int-void", "mediaType": "application/json" }], "name": "int-void" }, { "@type": ["Action"], "inputData": { "type": "integer" }, "link": [{ "href": "http://127.0.0.1:8080/TestThing/actions/int-int", "mediaType": "application/json" }], "name": "int-int", "outputData": { "type": "integer" } }, { "@type": ["Action"], "inputData": { "type": "string" }, "link": [{ "href": "http://127.0.0.1:8080/TestThing/actions/int-string", "mediaType": "application/json" }], "name": "int-string" }, { "@type": ["Action"], "link": [{ "href": "http://127.0.0.1:8080/TestThing/actions/void-complex", "mediaType": "application/json" }], "name": "void-complex", "outputData": { "type": "object", "properties": { "prop1": { "type": "integer" }, "prop2": { "type": "string" } }, "required": { "0": "prop1", "1": "prop2" } } }, { "@type": ["Action"], "inputData": { "type": "object", "properties": { "prop1": { "type": "integer" }, "prop2": { "type": "string" } }, "required": { "0": "prop1", "1": "prop2" } }, "link": [{ "href": "http://127.0.0.1:8080/TestThing/actions/complex-void", "mediaType": "application/json" }], "name": "complex-void" }] }
Find PlugFest organization and contributor details on the dedicated WoT Düsseldorf PlugFest wiki page.
Add more information about the actual PlugFest.
What decisions came out of discussions at phone or F2F meetings. Keep arguments here why solutions were discarded or why the practice is as it is.
...
We would like to thank all PlugFest participants who helped to improve the practices given in this document.
List changes over publications and their rational...