Abstract

This document proposes the basis of a common model to describe the virtual counterpart of physical objects in the Web of Things. It defines a model and Web API for Things to be followed by anyone wanting to create a product, device, service, or application for the Web of Things. This document considers the definition of the Web of Things (WoT) proposed in [WoTPaper] and [WoTBook], i.e., the Application layer of the Internet of Things. The model and protocols proposed here aim at making the interaction between Things in the Internet of Things accessible through Web standards to facilitate the implementation of Web applications making use or retrieving data from real-world objects.

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 can be found in the W3C technical reports index at http://www.w3.org/TR/.

This document is based on work undertaken within the COMPOSE European project and submitted to W3C as a possible starting point for a future Working Group chartered to work on the Web of Things.

By publishing this document, W3C acknowledges that the Submitting Members have made a formal Submission request to W3C for discussion. Publication of this document by W3C indicates no endorsement of its content by W3C, nor that W3C has, is, or will be allocating any resources to the issues addressed by it. This document is not the product of a chartered W3C group, but is published as potential input to the W3C Process. A W3C Team Comment has been published in conjunction with this Member Submission. Publication of acknowledged Member Submissions at the W3C site is one of the benefits of W3C Membership. Please consult the requirements associated with Member Submissions of section 3.3 of the W3C Patent Policy. Please consult the complete list of acknowledged W3C Member Submissions.

Table of Contents

1. Introduction

This section is non-normative.

The following guidelines and recommendations aim at ensuring interoperability across all entities on the Web of Things. Unlike custom (non-Web) protocols used for machine-to-machine communications that create a “parallel universe” to the existing Web; the Web of Things is designed to be seamlessly integrated to the existing Web so it can fully leverage its infrastructure and standards to minimize integrations across applications and systems.

The proposal is composed of three sub-parts:

Note

While the Web Things Requirements are described with the HTTP and WebSockets protocols using JSON because they are well supported on the Web of browsers, the Web Thing Model can also be applied to describe the models and interactions of Things supported via other RESTful protocols such as CoAP [RFC7252] or even pub/sub protocols such as [MQTT].

Web Thing Model levels build on top of each other, from a Web Thing that implement the requirements to the Extended Web Thing and Semantic Web Thing
Fig. 1 Web Thing Model levels (source: [WoTBook])

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

This specification has two classes of products:

Web Thing
A Web Thing (or simply Thing) is a digital representation of a physical object accessible via a RESTful Web API. Examples of Web Things are: an Arduino board, a garage door, a bottle of soda, a building, a TV, etc. The API of the Web Thing can be hosted on the Thing itself or on an intermediate host in the network such as a Gateway or a Cloud service (for Things that aren't accessible through the Internet).

A Web Thing conforms to this specification if it follows the statements defined in 5. Web Things requirements.

Extended Web Thing
An Extended Web Thing is a Web Thing that additionally supports the REST API and data model defined in this specification, thus enabling its automatic inclusion in more complex systems.

An Extended Web Thing conforms to this specification if it follows the statements defined in 5. Web Things requirements and 6. Web Things model.

3. Terminology

The following terms are considered in this proposal:

Client
A Client refers to any physical or digital entity that can interact with a Web Thing. This can be a mobile application, a Web browser, a proxy, a desktop application, but also another Web Things (e.g., in the case of Machine to Machine communication).
Property
A Property is a variable of a Web Thing. Properties represent the internal state of a Web Thing. Clients can subscribe to properties to receive a notification message when specific conditions are met (e.g. value of one or more properties changed).
Action
An Action is a function offered by a Web Thing. A Client invokes a function on a Web Thing which initiates a state transition by sending it an Action. Examples of Actions are “open” or “close” for a garage door; “enable” or “disable” for a smoke alarm; “check-in” or “scan” for a bottle of soda or a place. The direction of an Action is from the Client to the Web Thing.

4. Web Things integration patterns

This part looks into the different ways of integrating physical objects to the Web to make them Web Things. Once a pattern has been choosen, the server of a Web Thing should follow the Web Things Requirements and the resources and payloads it uses should follow the Web Things Model .

Some physical entities might not expose a Web API themselves for various reasons (e.g., a ZigBee sensor node, or a heart rate monitor accessible over Bluetooth only), in which case they are not Web Things as such, but they can use another Web Thing as a proxy or gateway to provide a Web API for them, therefore turning them into Web Things.

While the three integration patterns described below need to be taken into account, it is worth noting that the requirements and model apply regardless of the integration pattern of choice.

4.1 Direct Connectivity

In the most straightforward case, a Web Thing is simply a Web API that Clients send requests to. In some cases, the Client and the Web Thing can be on the same network or on different networks. In both cases, you are sending the same request to a Web Thing. The only difference is the URL to which you are sending the request (and obviously how the Web Thing gets the message).

When a Web Thing exposes a Web API, Clients can directly connect to it, potential through a local address if they are both on the same network
Fig. 2 Direct connectivity between a Client and a Web Thing (source: [WoTBook])

4.2 Gateway-Based Connectivity

Gateway-based connectivity is used when a Thing cannot offer a Web API directly. In this case an intermediate Web Thing - the gateway - exposes a Web API on the Thing's behalf. The Web Thing therefore acts as a proxy for the Thing (or gateway depending on the complexity/layer of the translation).

When a Web Thing cannot expose a Web API directly, Clients connect to it through a Gateway that exposes the Web API on their behalf
Fig. 3 Gateway-based connectivity between a Client and a Web Thing (source: [WoTBook])

4.3 Cloud-Based Connectivity

This third case is similar to 4.2 Gateway-Based Connectivity. However, in this case the gateway is a cloud service and not another device in situ.

A cloud service may expose the Web API of a Web Thing for Clients to connect to it
Fig. 4 Cloud-based connectivity between a Client and a Web Thing (source: [WoTBook])

5. Web Things requirements

This part defines a set of rules for implementing Web Things. It assumes that an Integration Pattern was chosen.

5.1 Level 0 – MUST

This section defines the Level 0 requirements – all of which MUST be in place in any Web Thing implementation, as all Clients will expect these constraints.

5.1.1 R0.1 – A Web Thing MUST at least be an HTTP/1.1 server

All Web Things MUST support communication over HTTP/1.1 [RFC2616]. When possible, Web Things SHOULD also support HTTP/2 [RFC7540].

Note

HTTP/1.1 is the most widely spread protocol over the Web and virtually any HTTP client or server implementation supports it, therefore it is likely that the majority of clients might not support HTTP/2 as of yet. This can be implemented directly on the Web Thing or can be provided via a proxy (see Integration Patterns).

Note

As a consequence, while Clients should not expect support for HTTP/2, communication with a Web Thing using HTTP/1.1 is always possible.

5.1.2 R0.2 – A Web Thing MUST have a root resource accessible via an HTTP URL

A Web Thing MUST have a so-called “root resource” identified by a HTTP URL (uses the HTTP protocol, therefore starts with http:// or https://) that acts as the entry point for the Web Thing and enables the interaction with it. This root resource makes the Web Thing both uniquely identifiable and addressable over a network so that Clients can interact with it.

If the Web Thing is a device connected on a LAN (e.g. a printer, a lamp, etc.), the root URL of a Web Thing SHOULD be its IP address and standard HTTP port, so that, knowing only the IP address of a networked device that is a Web Thing, a Client can send an HTTP GET request on that IP address over the default port (80 for HTTP, 443 for HTTPS) to retrieve a representation of the Web Thing. This feature is envisioned to facilitate discovery of devices at the network level, without requiring an additional protocol.

Note

A Web Thing does not need to be publicly accessible over the Internet, as some Web of Things scenarios might only work within a local area network (LAN) as defined above. This means a root URL does not need to be public and can be simply the local IP address of a device. The Root URL of a Web Thing is referred to as {wt} throughout this document.

Example 1: Valid root URLs
http://gateway.api.com/devices/TV
http://kitchen-raspberry.device-lab.co.uk
https://192.168.10.10:9002
https://kitchen:3000/fridge/root

5.1.3 R0.3 – A Web Thing MUST support GET, POST, PUT and DELETE HTTP verbs

The Web of Things aims to maximise interoperability by exposing the services of Things using REST [REST]. For this idea to come to reality, supporting certain HTTP verbs of the specification is required. Considering that the REST paradigm is based on resources and CRUD operations on them, a Web Thing MUST support GET for reading operations, POST for creation, PUT for updates and state changes, and DELETE for removal.

5.1.4 R0.4 – A Web Thing MUST implement HTTP status codes 200, 400, 500

Proper usage of HTTP/1.1 error codes is advisable. However, considering that some devices are restricted, only the following subset is mandatory:

  • 2XX Success. Returned for any successful action. The Web Thing MUST at least support the 200 OK response.
  • 4XX Client Error. This should be returned for any error due to the client that sent the request (from a wrong URL, to invalid authentication, or incorrect parameter). The Web Thing MUST at least support the 400 Bad Request error code.
  • 5XX Server Error. This should be used for any error on the Web Thing side when a request was valid but cannot be processed at this time for any reason, e.g. the Web Thing has a server error, etc. The Web Thing MUST at least support the 500 Internal Server Error error code.

5.1.5 R0.5 – A Web Thing MUST support JSON as default representation

A Web Thing MUST always accept a valid JSON document [RFC7159] as input payload for requests and always return a JSON representation when requested. If no Accept: HTTP header is specified in the request (or if the format is unknown or not supported), the Web Thing SHOULD return an appropriate error code, but it also MAY return JSON as default. Fields in JSON objects should follow the camelCase convention starting with a lowerCase letter (e.g., backColor) or a special character (e.g., _customRelation).

A Web Thing MAY support additional formats.

Note

A consequence of supporting JSON is that UTF-8 is the default encoding for payloads (see Character Encoding in the JSON specification [RFC7159])

5.1.6 R0.6 – A Web Thing MUST support GET on its root URL

Because they all have a unique root URL and sometimes it is all we know about them, Web Things MUST respond to HTTP GET requests on their root URL with their basic representation, so that Clients can use and understand it.

Note

The basic representation returned by an Extended Web Thing is defined in 6. Web Things model

5.2 Level 1 – SHOULD

Unless there are technical or practical limitations for not adhering to Level 1 constraints, Web Things SHOULD support the following constraints.

5.2.1 R1.1 – A Web Thing SHOULD use secure HTTP connections (HTTPS)

Ideally, Web Thing SHOULD support secure connections with HTTP over TLS [RFC5246]. The ideal case for security is to support only HTTP over TLS. Web Thing that are exposed on the Internet MUST always implement HTTP over TLS.

Web Things MAY use other security mechanisms if they want to (in addition or in place of HTTPS). In some cases, it might be impossible or impractical to implement HTTPS over TLS (for example in pure intranet scenario), in which case using another security mechanism is still highly recommended.

5.2.2 R1.2 – A Web Thing SHOULD implement the WebSocket Protocol

Clients SHOULD be able to subscribe to notifications from Web Thing using a Publish/Subscribe (Pub/Sub) pattern implemented using the WebSocket protocol [RFC6455].

5.2.3 R1.3 – A Web Thing SHOULD support the Web Things model

If possible, every Web Thing SHOULD implement the Web Things Model. It is not essential to use it for a device to be part of the Web of Things, but implementing it will lead to a higher degree of interoperability.

Note

An Extended Web Thing fulfills this requirement by definition. In other words, while this specification acknowledges the usefulness of the Web Thing level to accommodate legacy devices and very restricted scenarios, implementers are encouraged to implement Extended Web Things.

5.2.4 R1.4 – A Web Thing SHOULD return a 204 for all write operations

By default, all PUT, POST, and DELETE requests to a Web Thing should not return the payload of the object that was created/modified, therefore should return a 204 NO CONTENT response and no response body.

5.2.5 R1.5 – A Web Thing SHOULD provide a default human-readable documentation

To interact with a Web Thing, a Client needs to know how to use a Web Thing. The format of the API documentation is left to implementers, but should describe the resources offered, the verbs they support, the payloads accepted and returned, and possible status codes that can be returned and when.

5.3 Level 2 – MAY

A Web Thing MAY support these rules, but is not expected to. It depends on the device capabilities and other implementation aspects.

5.3.1 R2.1 – A Web Thing MAY support the HTTP OPTIONS verb for each of its resources

Any resource of a Web Thing should implement the OPTIONS verb to describe what verbs are supported by each resource.

5.3.2 R2.2 – A Web Thing MAY provide additional representation mechanisms (RDF, XML, JSON-LD)

A Web Thing MAY provide additional representations of its data and descriptions. JSON is the only mandatory representation. Additional formats are up to the implementers if needed for additional purposes. The discovery of additional representation SHOULD be supported via HTTP content-negotiation [content-negotiation].

5.3.3 R2.3 – A Web Thing MAY offer a HTML-based user interface

A Web Thing MAY expose a UI in HTML, CSS and JavaScript. For example, the UI may be a HTML widget to integrate the Web Thing in dashboard environments.

5.3.4 R2.4 – A Web Thing MAY provide precise information about the intended meaning of individual parts of the model

A Web Thing MAY provide additional meta data to precisely describe the meaning of individual building blocks of a model in a machine-understandable way.

6. Web Things model

This part defines the model, JSON payloads and REST API that an Extended Web Thing MUST implement to allow Clients to automatically discover and use its properties. It assumes an Integration Pattern and that the Web Thing follows the Web Things Requirements. As such, the Web Things model is a contract between clients and Things in the IoT.

Note

An Extended Web Thing has a root resource accessible via an HTTP URL and supports HTTP GET requests on that URL (see 5.1.2 R0.2 – A Web Thing MUST have a root resource accessible via an HTTP URL and 5.1.6 R0.6 – A Web Thing MUST support GET on its root URL).

An Extended Web Thing MUST create a URL endpoint for all the resources that it exposes, including itself. Relative URLs are to be resolved against the URL of the resource that includes them. Implementers are encouraged to create a logical tree structure for resources and to use relative URLs to keep JSON payloads short, for instance:

URL Description
{wt} The root resource URL
{wt}/model/ The model of a Web Thing
{wt}/properties/ The list of properties
{wt}/properties/{id} A specific property
{wt}/actions/ The list of actions
{wt}/actions/{id} A specific action
{wt}/actions/{id}/{actionId} A specific execution of an action
{wt}/.../ ...

6.1 Common Constructs

In response to an HTTP GET request on one of its resources (including the root resource), an Extended Web Thing MUST return a JSON representation of that resource that follows the JSON schema defined in the table below:

Field name Type Description
id String The URL of this resource following the URI format [RFC3986]. Relative URLs are resolved against the URL of the enclosing resource.
This field is required.
createdAt String Timestamp when this resource was created, following the ISO8601 notation [ISO8601].
updatedAt String Timestamp when this resource was last updated, following the ISO8601 notation [ISO8601].
name String A short human-readable name for the resource.
description String A human-readable description of the resource.
tags [String] An array of tags.
customFields Object A JSON object with key-value pairs to store custom information about this resource (e.g. {"key":"value",...}).
links Object A JSON object that lists the sub-resources that this resource links to. See 6.2 Links for details.
Example 2: Basic JSON payload
{
  "id": "myCar",
  "name": "My great car",
  "description": "This is such a great car.",
  "createdAt": "2012-08-24T17:29:11.683Z",
  "updatedAt": "2012-08-24T17:29:11.683Z",
  "tags": [
    "cart",
    "device",
    "test"
  ],
  "customFields": {
    "size": "20",
    "color": "blue"
  },
  "links": {
    "model": {
      "link": "model/",
      "title": "Model this Web Thing."
    },
    "properties": {
      "link": "properties/",
      "title": "Properties of this Web Thing."
    },
    "actions": {
      "link": "actions/",
      "title": "Actions of this Web Thing."
    },
    ...
  }
}

The JSON response MAY contain additional fields, depending on the type of resource being considered, check the 6.4 Resources for details.

Pagination

Requests on things of a gateway, on properties that store the history of value changes or on executed actions return many items will be paginated to 30 items by default. You can specify any further page to be returned using the ?page parameter. For example, set a custom page size up to 100 with the ?perPage parameter with: GET {wt}/properties/acceleration?page=3&perPage=100 Extra pagination data is sent in response headers.
Example 3: Extra pagination data is sent in response headers
Result-Count: 562
Link: <http://webofthings.io/properties/acceleration?page=3&perPage=100<; rel="next",
<http://webofthings.io/properties/acceleration?page=56&perPage=100<; rel="last"
The Result-Count header contains the total number of results. The pagination info is included in the Link header.
rel value Description
next The URL of the last page of results.
first The URL of the first page of results.
prev The URL of the immediate previous page of results.

6.3 Values

Several resources support values (particularly Actions and Properties). A values object contains the description of a set of values identified by their name. The description includes the value type, unit, and possible concrete values that the value can take. A values object is typically used to define the parameters a Client can use when it issues an Action or accesses the channels of a Property.

The following fields MAY be used to describe a values object:

Field name Type Description
<valueName> String The identifier of this value
This field is required.
name String A human-readable caption for this value.
description String A human-readable description of this value.
type String The type of this value. The supported types are integer, float, boolean, string.
unit String The unit of this value using one the (case-insensitive) full names defined in the International System of Units [SI].
Example: "meter per second squared"
required Boolean Specifies whether this value is required or optional. If omitted, the default is true.
minValue Number The minimal concrete value that this value can take.
maxValue Number The maximal concrete value of this value
enum Object Specifies a set of concrete values that this value can take, e.g.
{"LOCK":"Locks the door.", "UNLOCK":"unlocks the door."}
Example 7: Values object model
{
  ...
  "values": {
    "<valueName>":{
      "name":"<String>",
      "description":"<String>",
      "type":"<String>",
      "unit":"<String>",
      "required":"<Boolean>",
      "minValue":"<Numeric>",
      "maxValue":"<Numeric>"
    },
    ...
  }
  ...
}

The value name timestamp is reserved. An Extended Web Thing MUST append a timestamp, set to the current date and time, whenever it creates a value unless that timestamp is already provided. The timestamp field follows the ISO8601 notation [ISO8601]. The createdAt is different from timestamp because it used to refer when a resource has been created (server side information only), whereas the timestamp indicates when a value (property) has been measured (by the client or the Web Thing).

6.4 Resources

6.4.1 HTTP verbs support

Ideally, an Extended Web Thing SHOULD support all end-points. The letters D,G,C refer to 4. Web Things integration patterns and is here as an indication of which type of integration would typically implement these resources. A D means that the resource should be implemented on Web Things using the the Direct integration pattern, a G means the resource should be implemented when using the Gateway integration pattern, a C means the resource should be implemented when using the Cloud integration pattern.

Note

The URLs used in this table are indicative as an Extended Web Thing may choose to use other URLs for them. The actual URLs are to be reported in the representation of the in Link HTTP Headers and in the JSON links field as described in 6.2 Links of the Model resource.

REST URL POST GET PUT DELETE OPTIONS Details
{wt} G,C D,G,C D,G,C G,C D,G,C Thing Resource
{wt}/model - D,G,C G,C - D,G,C Model Resource
{wt}/properties G,C D,G,C - - D,G,C Properties Resource
{wt}/properties/{id} - D,G,C G,C - D,G,C Properties Resource
{wt}/actions G,C D,G,C - - D,G,C Actions Resource
{wt}/actions/{id} D,G,C D,G,C - - D,G,C Actions Resource
{wt}/actions/{id}/{actionId} - D,G,C - D,G,C D,G,C Actions Resource
{wt}/things G,C G,C - - G,C Things Resource
{wt}/things/{id} - G,C G,C G,C G,C Things Resource
{wt}/subscriptions - D,G,C - D,G,C D,G,C Subscriptions Resource

6.4.2 Web Thing Resource

A Web Thing is the virtual representation of a physical object. It is the root resource of the Web Things model.

The Web Thing URL is either the root URL of the API or, in the case of a proxy for other Web Things, the result of resolving the id returned in the representation of the Web Things resource.

6.4.2.1 Retrieve a Web Thing

In response to an HTTP GET request on the root URL of a Thing, an Extended Web Thing MUST return an object that its representation.

Example 8: Get the Root Resource of a Web Thing
--> REQUEST
GET {wt}
 
<-- RESPONSE
200 OK
Link: <model/>; rel="model"
Link: <properties/>; rel="properties"
Link: <actions/>; rel="actions"
Link: <product/>; rel="product"
Link: <type/>; rel="type"
Link: <help/>; rel="help"
Link: <ui/>; rel="ui"
Link: <_myCustomLinkRelType/>; rel="_myCustomLinkRelType"

{
  "id": "myCar",
  "name": "My super great car",
  "description": "This is such a great car.",
  "createdAd": "2012-08-24T17:29:11.683Z",
  "updatedAd": "2012-08-24T17:29:11.683Z",
  "tags":["cart", "device", "test"],
  "customFields":{
      "size": "20",
      "color":"blue"
  }
}
6.4.2.2 Update a Web Thing

In response to an HTTP PUT request on a Web Thing URL with a Web Thing object as request body, an Extended Web Thing MUST either reject the request with the appropriate status code (e.g. because the Client is unauthenticated or because the Thing is read-only) or store the provided value(s) by updating the Web Thing. Partial updates are authorized and result in updating the fields that were provided in the request body.

Example 9: Update my super great car
--> REQUEST
PUT {wt}
    
{
  "name":"My really super great car"
}

<-- RESPONSE
204 NO CONTENT

6.4.3 Model Resource

A Model describes the values of properties and actions that can be performed on Things.

The Model URL is the result of resolving the id returned in the representation of a Property against the destination URL of the properties link that gave birth to it.

6.4.3.1 Retrieve the model of a Thing

In response to an HTTP GET request on the destination URL of a model link, an Extended Web Thing MUST return an object containing the model of the Thing.

Example 10: Model of a Web Thing
--> REQUEST
GET {wt}/model

<-- RESPONSE
200 OK

{
  "id": "pi",
  "name": "My WoT Raspberry PI",
  "description": "A simple WoT-connected Raspberry PI for the WoT Label.",
  "tags": [
    "raspberry",
    "pi",
    "WoT"
  ],
  "customFields" : {
    "port" : 8484
  },
  "links": {
    "product": {
      "link": "https://www.raspberrypi.org/products/raspberry-pi-2-model-b/",
      "title": "Product this Web Thing is based on"
    },
    "properties": {
      "link": "/properties",
      "title": "List of Properties",
      "resources": {
        "temperature": {
          "name": "Temperature Sensor",
          "description": "An ambient temperature sensor.",
          "values": {
            "temp": {
              "name": "Temperature sensor",
              "description": "The temperature in celsius",
              "unit": "celsius",
              "customFields": {
"gpio": 21
              }
            }
          },
          "tags": [
            "sensor",
            "public",
            "indoors"
          ]
        },
        "humidity": {
          "name": "Humidity Sensor",
          "description": "An ambient humidity sensor.",
          "values": {
            "h": {
              "name": "Humidity",
              "description": "Percentage of Humidity",
              "unit": "percent",
              "customFields": {
"gpio": 21
              }
            }
          },
          "tags": [
            "sensor",
            "public"
          ]
        },
        "pir": {
          "name": "Passive Infrared",
          "description": "A passive infrared sensor.",
          "values": {
            "p": {
              "name": "Presence",
              "description": "Current sensor value (true=motion detected)",
              "type": "boolean",
              "customFields": {
"gpio": 20
              }
            }
          },
          "tags": [
            "sensor",
            "public"
          ]
        },
        "leds": {
          "name": "LEDs",
          "description": "The LEDs of this device.",
          "values": {
            "1": {
              "name": "LED 1",
              "customFields": {
"gpio": 17
              }
            },
            "2": {
              "name": "LED 2",
              "customFields": {
"gpio": 19
              }
            }
          },
          "tags": [
            "sensor",
            "public"
          ]
        }
      }
    },
    "actions": {
      "link": "/actions",
      "title": "Actions of this Web Thing",
      "resources": {
        "ledState": {
          "values": {
            "ledId": {
              "type": "string",
              "required": true
            },
            "state": {
              "type": "boolean",
              "required" : true
            }
          }
        }
      }
    },
    "type": {
      "link": "http://w3c.org/schemas/webthing/",
      "title": "Instance type of the Pi"
    },
    "help": {
      "link": "http://webofthings.org/docs/pi/",
      "title": "Documentation"
    },
    "ui": {
      "link": "/ui",
      "title": "User Interface"
    }
  }
}
6.4.3.2 Update the model of a Thing

In response to an HTTP PUT request on a Model URL with a Model object as request body, an Extended Web Thing MUST either reject the request with the appropriate status code (e.g. because the Client is unauthenticated or because the Model is read-only) or store the provided value(s) by updating the Model. Partial updates are authorized and result in updating the fields that were provided in the request body.

Note

Usually, the model will be hardcoded in the device and generally cannot be altered by clients. If the Web Thing is hosted on a cloud service, the model can be updated by sending an HTTP PUT request to the same URL, with the new model document in the request body.

6.4.4 Properties Resource

A Property keeps track of a set of variables about a device (its location, the temperature sensor reading, etc.).

The Property URL is the result of resolving the id returned in the representation of a Property against the destination URL of the properties link that gave birth to it.

6.4.4.1 Retrieve a list of properties

In response to an HTTP GET request on the destination URL of a properties link, an Extended Web Thing MUST return an array of Property that the initial resource contains.

Example 11: List of properties
--> REQUEST
GET {wt}/properties


<-- RESPONSE
200 OK
Link: <http://webofthings.io/properties>; rel="type"

[
  {
    "id":"temperature",
    "name":"Kitchen Temperature Sensor",
    "values":{
      "temp":22,
      "timestamp":"2015-06-14T14:30:00.000Z"
    }
  },
  {
    "id":"status",
    "name":"Device Status",
    "values":{
      "status":"OK",
      "timestamp":"2015-06-14T14:30:00.000Z"
    }
  },
  {
    "id":"acceleration",
    "name":"Acceleration",
    "values":{
      "x":22,
      "y":22.56,
      "z":1.4,
      "timestamp":"2015-06-14T14:30:00.000Z"
    }
  },
  {
    "id":"engineAngle",
    "name":"Engine Angle",
    "values":{
      "theta":2,
      "rho":-0.1,
      "timestamp":"2015-06-14T14:30:00.000Z"
    }
  }
]
6.4.4.2 Retrieve the value of a property

In response to an HTTP GET request on a Property URL, an Extended Web Thing MUST return an array that lists recent values of that Property.

Note

Some Web Things might not store the history of sensor readings but only the most recent value of a given property, in which case the array will always contain one object. However, Web Things on clouds and gateway are likely to store many past values of the property, in which case they can be retrieved using pagination.

Example 12: Retrieve the last measures of an accelerometer property
--> REQUEST
GET {wt}/properties/acceleration

<-- RESPONSE
200 OK
Link <model/>; rel="model"

[
  {
    "x":11,
    "y":1,
    "z":-4.4,
    "timestamp":"2015-06-14T14:30:00.000Z"
  },
  {
    "x":3.4,
    "y":-1,
    "z":-4.6,
    "timestamp":"2015-06-14T14:00:00.000Z"
  }
]
6.4.4.3 Update a specific property

In response to an HTTP PUT request on a Property URL with an array of values as request body, an Extended Web Thing MUST either reject the request with the appropriate status code (e.g. because the Client is unauthenticated or because the Property is read-only) or store the provided value(s) as new values for the Property. The body of the request SHOULD always be an array of values (at least one), which allows to send several property value updates within a single request.

Example 13: Update the Values of the Temperature Property
--> REQUEST
PUT {wt}/properties/temperature/

[
  {
    "temp":24
  }
]


<-- RESPONSE
204 NO CONTENT
Location: {wt}/properties/temperature/
Note

A Property URL is always a collection of resources, therefore its representation is an array of individual values with different timestamps. The individual values are not adressable individually, therefore the Location: header in response to a successful property update request SHOULD always be the Property URL itself.

6.4.4.4 Update multiple properties at once

In response to an HTTP POST request on the destination URL of a properties link, an Extended Web Thing MUST either reject the request with the appropriate status code or store the provided values as new values for each of the provided Properties.

Example 14: Update multiple properties at once
--> REQUEST
PUT {wt}/properties/

[
  {
    "id":"temperature",
    "value":{
      "temp":24,
      "timestamp":"2015-06-14T14:30:00.000Z"
    }
  },
  {
    "id":"acceleration",
    "value":{
      "x":-22,
      "y":2.1,
      "z":3,
    }
  }
]

<-- RESPONSE
204 NO CONTENT
Location: {wt}/properties/

6.4.5 Actions Resource

On top of 6.1 Common Constructs, the JSON representation used to describe an Action includes the following fields:

Field name Type Description
values Object A description of the parameters that his action accepts.
See 6.3 Values.
This field is required.

The Action URL is the result of resolving the id returned in an Action description against the destination URL of the actions link that gave birth to it.

6.4.5.1 Retrieve a list of actions

In response to an HTTP GET request on the destination URL of an actions link exposed by a resource, an Extended Web Thing MUST return an array of Action descriptions that the initial resource may perform.

Example 15: List of actions
--> REQUEST
GET {wt}/actions


<-- RESPONSE
200 OK
Link: <http://webofthings.org/actions/upgradefirmware>; rel="type"

[
  {
    "id":"upgradeFirmware",
    "name":"Upgrade Device Firmware"  
  },
  {
    "id":"reboot",
    "name":"Reboot"  
  }
]
6.4.5.2 Retrieve recent executions of a specific action

In response to an HTTP GET request on an Action URL, an Extended Web Thing MUST return an array that lists the recent executions of a specific Action.

On top of 6.1 Common Constructs, the JSON representation used to describe the execution of an Action includes the following fields:

Field name Type Description
status String The execution status. One of pending, executing, completed or failed
Example 16: Retrieve the recent executions of a specific action
--> REQUEST
GET {wt}/actions/upgradefirmware

<-- RESPONSE
200 OK
Link: <http://webofthings.org/actions/upgradefirmware>; rel="type"
Link: <model/>; rel="model"

[
  {
    "id":"223",
    "value":{
      "delay":30,
      "mode":"SOFT"
    },
    "status":"executing"
    "timestamp":"2015-06-14T18:33:25.938Z"
  },
  {
    "id":"222",
    "value":{
      "delay":60,
      "mode":"FORCE"
    },
    "status":"completed"
    "timestamp":"2015-06-14T14:22:23.233Z"
  }
]
6.4.5.3 Execute an action

In response to an HTTP POST request on an Action URL with valid parameters as request body, an Extended Web Thing MUST either reject the request with the appropriate status code or queue a task to run the action and return the status of that action in a 201 Created response. The action may not run immediately. The Location HTTP header identifies the URL to use to retrieve the most recent update on the action's status.

Note

This is how a Client sends a command to a device.

Example 17: Schedule a reboot
--> REQUEST
POST {wt}/actions/reboot

{
  "delay":50,
  "mode":"debug"
}

<-- RESPONSE
204 NO RESPONSE
Location: {wt}/actions/reboot/233
6.4.5.4 Retrieve the status of an action

In response to an HTTP GET request on the URL targeted by the Location HTTP header returned in response to the request to execute an action, an Extended Web Thing MUST return the status of this action or a 404 Not Found status code if the action's status is no longer available.

Example 18: See a Reboot Action
--> REQUEST
GET {wt}/actions/reboot/233

<-- RESPONSE
200 OK

{
  "id":"233",
  "value":{
    "delay":50,
    "mode":"debug"
  },
  "status":"executing",
  "timestamp":"2015-06-14T14:30:00.000Z"
}

6.4.6 Things Resource

A Web Thing may proxy other Web Things via the Things resource. For instance, it is expected that gateways and cloud services will proxy a number of third party devices. On top of 6.1 Common Constructs, the JSON representation used to describe a link to another thing includes the following fields:

Field name Type Description
rootUrl String The URL of the root resource of the Web Thing if it is different from {wt}/thing/{id}
6.4.6.1 Retrieve a list of Web Things

In response to an HTTP GET request on the destination URL of a things link, an Extended Web Thing MUST return an array of things descriptions.

Example 19: List of things proxied by a device
--> REQUEST
GET {wt}/things
            
<-- RESPONSE
200 OK

[
  {
    "id":"982tjqogeih",
    "name":"Shopping Cart"
  },  
  {
    "id":"2398h87wt489foz",
    "name":"Shopping Cart",
    "rootUrl":"/pi",
    "description":"Shopping Cart that updates its location as it moves"
  },  
  {
    "id":"p9qrnc89w48oh",
    "name":"Shopping Cart",
    "rootUrl":"https://192.168.0.6/",
    "description":"LAN-connected gateway to Lamp #4."
  }
]
Note

The id can be interpreted as a URL, but if a Web Thing can be directly accessed without the proxy, the rootUrl can be used to provide a different Root URL.

6.4.6.2 Add a Web Thing to a gateway

Clients can add new Things to be proxied by a Web Thing (especially for gateways/cloud) using an HTTP POST request on the Thing URL of a Web Thing and by sending in the request body the root resource representation of the Thing to be proxied.

Example 20: List of things proxied by a device
--> REQUEST
POST {wt}/things

{
  "id":"p9qrnc89w48oh",
  "name":"Shopping Cart",
  "rootUrl":"https://192.168.0.6/",
  "description":"LAN-connected gateway to Lamp #4."
}
            
<-- RESPONSE
204 NO CONTENT
Location: {wt}/things/p9qrnc89w48oh

6.4.7 Subscriptions Resource

All resources can be subscribed to but in particular, an Extended Web Thing SHOULD enable subscriptions to Actions and Properties. Subscriptions allows for a Client to be notified via a push event whenever the state of an observed resource changes.

The Subscription resource allows to list current subscriptions to resources as well as cancelling a subscription. Such a resource is accessible via the root URL of the Extended Web Thing.

On top of 6.1 Common Constructs, the JSON representation used to describe a subscription includes the following fields:

Field name Type Description
subscriberId String A unique identifier for the subscriber
This field is required.
type String The type of connection used to exchange updates with the subscriber. One of httpCallback or websockets
resource String The URL of the resource whose changes the subscriber is subscribed to.
6.4.7.1 Create a subscription

An Extended Web Thing SHOULD support subscriptions via the WebSocket [RFC6455] protocol and MAY support subscriptions via WebHooks (HTTP callbacks). Subscriptions are enabled via the HTTP protocol upgrade mechanism [RFC2616] as shown below.

Clients can subscribe to resources via a protocol upgrade.
Fig. 5 Client subscription to a resource via a protocol upgrade, first via Websocket, second via a Webhook (HTTP callback).

To subscribe to a resource the following HTTP headers should be provided via a GET request (e.g., on /properties/temp).

Header name Description
Upgrade The protocol that should be used for the subscription, one of webhook or websocket
This header is required.
Callback The callback URL to which updates should be pushed. webhook or websocket
This header is required in the case of a webhook subscription.

In response to a HTTP GET request on the destination URL of a resource, an Extended Web Thing MUST either reject the request with an appropriate status code or MUST return a 101 Switching Protocol response for a subscription via Websocket or a 200 OK for a subscription via Webhook. It SHOULD then create a record for the subscription that can be retrieved via the /subscriptions URL. For both Websockets and Webhooks subscriptions the following headers must be returned (on top of the protocol specific headers):

Header name Description
Subscription-ID The identifier of the subscription
This header is required.
6.4.7.2 Retrieve a list of subscriptions

In response to an HTTP GET request on the destination URL of a subscriptions link, an Extended Web Thing MUST return the array of subscriptions to the underlying resource.

Example 21: List of subscriptions
[
  {
    "id":"2349",
    "type":"webhook",
    "resource":"/properties/temperature",
    "callbackUrl":"http://www.compose-project.eu/so/ServiceObject-123213213/callback"
  },
  {
    "id":"2350",
    "subscriberId":"ServiceObject-123213213",
    "type":"websocket",
    "resource":"/properties/location"
  }
]

The Subscription URL is the result of resolving the id returned in a Subscription resource description against the destination URL of the subscriptions link that gave birth to it.

6.4.7.3 Retrieve information about a specific subscription

In response to an HTTP GET request on a Subscription URL, an Extended Web Thing MUST return a JSON representation of the subscription. The JSON representation should be the same as the one returned for that subscription in 6.4.7.2 Retrieve a list of subscriptions.

Example 22: Retrieve information about a specific subscription
{
  "id":"2349",
  "type":"webhook",
  "resource":"/properties/temperature",
  "callbackUrl":"http://www.compose-project.eu/so/ServiceObject-123213213/callback"
}
6.4.7.4 Delete a subscription

In response to an HTTP DELETE request on the destination URL of a subscriptions an Extended Web Thing MUST either reject the request with an appropriate status code or remove (unsubscribe) the subscription and return a 200 OK status code.

6.5 Semantic Extensions

While it defines a basic semantic for Things in the IoT, the data model defined in this specification benefits from alignment with more detailed vocabularies such as those used in schema.org. The support for semantic extensions SHOULD be implemented using JSON-LD by referencing a JSON-LD context via an HTTP Link Header using the using the http://www.w3.org/ns/json-ld#context link relation as defined in [JSONLD].
Example 23
GET /model HTTP/1.1
Host: mydevice.webofthings.org
Accept: application/json,application/ld+json,*/*;q=0.1

====================================

HTTP/1.1 200 OK
...
Content-Type: application/json
Link: <https://schema.org/Product>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"

{
    "name": "Beaglebone Black",
    "description": "A Beaglebone Black embedded device",
    "productID" : "asin:B00CO3MZCW",
    "manufacturer" : "Beagleboard", ...
}

7. Acknowledgments

This work is supported by the European Union's 7th Research Framework Programme (FP7/2013-2015) under grant agreement nº317862 – COMPOSE).

The authors would like to thank the participants of the W3C Web of Things Interest Group, the Web of Things online community and in particular Joel Vogt and Iker Larizgoitia Abad, Francois Daoust, Johannes Hund and Joerg Heuer who have provided very valuable feedback on the drafts of this submission.

Note

Further tools and examples to work with this specification are available on Web of Things online community Website.

 

A. References

A.1 Normative references

[ISO8601]
Representation of dates and times. International Organization for Standardization. 2004. ISO 8601:2004. URL: http://www.iso.org/iso/catalogue_detail?csnumber=40874
[JSON-LD]
Manu Sporny; Gregg Kellogg; Markus Lanthaler. JSON-LD 1.0. 16 January 2014. W3C Recommendation. URL: http://www.w3.org/TR/json-ld/
[JSONLD]
JSON-LD - Interpreting JSON as JSON-LD. URL: http://www.w3.org/TR/json-ld/#interpreting-json-as-json-ld
[MQTT]
MQTT Version 3.1.1. URL: http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/mqtt-v3.1.1.html
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
[RFC2616]
R. Fielding; J. Gettys; J. Mogul; H. Frystyk; L. Masinter; P. Leach; T. Berners-Lee. Hypertext Transfer Protocol -- HTTP/1.1. June 1999. Draft Standard. URL: https://tools.ietf.org/html/rfc2616
[RFC3986]
T. Berners-Lee; R. Fielding; L. Masinter. Uniform Resource Identifier (URI): Generic Syntax. January 2005. Internet Standard. URL: https://tools.ietf.org/html/rfc3986
[RFC5246]
T. Dierks; E. Rescorla. The Transport Layer Security (TLS) Protocol Version 1.2. August 2008. Proposed Standard. URL: https://tools.ietf.org/html/rfc5246
[RFC5988]
M. Nottingham. Web Linking. October 2010. Proposed Standard. URL: https://tools.ietf.org/html/rfc5988
[RFC6455]
I. Fette; A. Melnikov. The WebSocket Protocol. December 2011. Proposed Standard. URL: https://tools.ietf.org/html/rfc6455
[RFC7159]
T. Bray, Ed.. The JavaScript Object Notation (JSON) Data Interchange Format. March 2014. Proposed Standard. URL: https://tools.ietf.org/html/rfc7159
[RFC7252]
Z. Shelby; K. Hartke; C. Bormann. The Constrained Application Protocol (CoAP). June 2014. Proposed Standard. URL: https://tools.ietf.org/html/rfc7252
[RFC7540]
M. Belshe; R. Peon; M. Thomson, Ed.. Hypertext Transfer Protocol Version 2 (HTTP/2). May 2015. Proposed Standard. URL: https://tools.ietf.org/html/rfc7540
[SI]
International System of Units (SI). URL: http://physics.nist.gov/cuu/Units/units.html
[content-negotiation]
HTTP 1.1. Content Negotiation. URL: http://www.w3.org/Protocols/rfc2616/rfc2616-sec12.html

A.2 Informative references

[REST]
Roy Thomas Fielding. Architectural Styles and the Design of Network-based Software Architectures. September 2000. Doctoral Dissertation. URL: http://roy.gbiv.com/pubs/dissertation/top.htm
[WoTBook]
Dominique Guinard; Vlad Trifa. Building the Web of Things. May 2015. URL: http://book.webofthings.io
[WoTPaper]
Dominique Guinard; Vlad Trifa. Towards the Web of Things: Web Mashups for Embedded Devices. April 20, 2009. WWW 2009 Conference Paper. URL: http://www.vs.inf.ethz.ch/publ/bibtex.html?file=papers/dguinard_09_WOTMashups