This document describes a common data model and API for the Web of Things. The Web Thing Description provides a vocabulary for describing physical devices connected to the World Wide Web in a machine readable format with a default JSON encoding. The Web Thing REST API and Web Thing WebSocket API allow a web client to access the properties of devices, request the execution of actions and subscribe to events representing a change in state. Some basic Web Thing Types are provided and additional types can be defined using semantic extensions with JSON-LD.

In addition to this specification there is a note on Web Thing API Protocol Bindings which proposes non-normative bindings of the Web Thing API to various existing IoT protocols. There is also a document describing Web of Things Integration Patterns which provides advice on different design patterns for integrating connected devices with the Web of Things, and where each pattern is most appropriate.

This document is a draft being prepared for submission; it has not yet been submitted to W3C.

Introduction

The goal of the Web of Things is to extend the web of pages into a web of things by giving connected devices URLs on the World Wide Web. This will allow the web to be used as a unifying application layer for a decentralized Internet of Things.

Whilst web technologies are already in widespread use on the Internet of Things, this is currently done with mostly proprietary data formats and APIs which require per-vendor integrations to make devices interoperable. In order to promote ad-hoc interoperability on the Internet of Things a shared vocabulary and common API is needed.

In this document we propose a common data model and API for the Web of Things.

Web Thing Description

The Thing Description provides a vocabulary for describing physical devices connected to the World Wide Web in a machine readable format with a default JSON encoding.

Example

{
  "name":"WoT Pi",
  "type": "thing",
  "description": "A WoT-connected Raspberry Pi",
  "properties": {
    "temperature": {
      "type": "number",
      "unit": "celsius",
      "description": "An ambient temperature sensor",
      "href": "/things/pi/properties/temperature"
    },
    "humidity": {
      "type": "number",
      "unit": "percent",
      "href": "/things/pi/properties/humidity"
    },
    "led": {
      "type": "boolean",
      "description": "A red LED",
      "href": "/things/pi/properties/led"
    }
  },
  "actions": {
    "reboot": {
      "description": "Reboot the device"
    }
  },
  "events": {
    "reboot": {
      "description": "Going down for reboot"
    }
  },
  "links": {
    "properties": "/thing/pi/properties",
    "actions": "/things/pi/actions",
    "events": "/things/pi/events",
    "websocket": "wss://mywebthingserver.com/things/pi"
  }
}
        

name member

The name member is a user friendly string which describes the device. This can be set to any value by the device creator and may include a brand name or model number.

type member

The type member defines the type of device described by the Thing Description. See "Device Types" for possible values.

description member

The description member is a user friendly string which describes the device and its functions. This can be set to any value by the device creator.

properties member

The properties member is a map of property objects which describe the attributes of the device.

actions member

The actions member is a map of action objects which describe functions that can be carried out on a device. Actions are used when the setting of properties is not sufficient to affect a required change in state. This may be used to describe a function which manipulates multiple properties or accepts arguments and has a different effect depending on which arguments are provided. An example might include a "reboot" action which power cycles a device.

events member

The events member is a map of event objects which define the types of events which may be emitted by a device. Events can be used where subscribing to a change in property state is not sufficient. This may be used to monitor changes in multiple properties or events which describe something other than a property change. An example might be an event which is emitted when a device is about to reboot.

links member

The links member provides a map of URLs for Properties, Actions and Events resources. It can also contain a WebSocket URL to be used for the Thing's WebSocket API. Entries in this map have a key which can be one of "properties", "actions", "events" or "websocket" and a string value representing a URL.

Property object

A property object describes an attribute of a Thing and is indexed by a property name. A property description may include its type, unit, description and URL.

Action object

An action object describes a function which can be carried out on a device. An action description may include action parameters and a human friendly description which describes what the action does.

Event object

An event object describes a type of event which may be emitted by a device. This may include the type of values which may be included in the event and a human friendly description which describes what the event means.

Alternative Encodings

The default encoding for the Thing description is JSON, but other encodings such as XML, JSON-LD or CBOR may be used. Alternative encodings are beyond the scope of this specification but may be defined separately.

References to alternative available encodings may be provided using Link HTTP response headers with the alternate link relation. A client can express a preference for an alternative encoding using HTTP content negotiation.

Web Thing REST API

The Web Thing API provides a web services based programming interface with a RESTful design for applications to access the properties of devices, request the execution of actions and access a list of events representing a change in state. A default HTTP protocol binding is defined here.

The Web Thing REST API consists of a number of different types of resources which represent different aspects of a device and can be independently referenced by a URL. The specific URLs and URL structure of resources are defined by the author of a Thing Description using a HATEOAS approach. This specification does not define a fixed URL structure.

Thing resource

A Thing Resource provides a Thing Description of a device including its name, type, description, properties, actions and events. A Thing Resource is considered the root resource of a Thing.

A Thing description is usually read only. An HTTP GET request can be used to retrieve a Thing Description for a Thing.

Example: Get a description of a Thing

Request
GET http://mythingserver.com/things/pi
Accept: application/json
Response
200 OK
{
  "name":"WoT Pi",
  "type": "thing",
  "description": "A WoT-connected Raspberry Pi",
  "properties": {
    "temperature": {
      "type": "number",
      "unit": "celsius",
      "description": "An ambient temperature sensor",
      "href": "/things/pi/properties/temperature"
    },
    "humidity": {
      "type": "number",
      "unit": "percent",
      "href": "/things/pi/properties/humidity"
    },
    "led": {
      "type": "boolean",
      "description": "A red LED",
      "href": "/things/pi/properties/led"
    }
  },
  "actions": {
    "reboot": {
      "description": "Reboot the device"
    }
  },
  "events": {
    "reboot": {
      "description": "Going down for reboot"
    }
  },
  "links": {
    "properties": "/thing/pi/properties",
    "actions": "/things/pi/actions",
    "events": "/things/pi/events",
    "websocket": "wss://mywebthingserver.com/things/pi"
  }
}

Property resource

A property resource represents a property of a device. Some property resources may be read only and some may be writable. The value of a property can be retrieved with an HTTP GET request and updated with an HTTP PUT request.

Example: Get a property

Request
GET http://mythingserver.com/things/pi/properties/temperature
Accept: application/json
Response
200 OK
{
  "temperature": 21
}

Example: Set a property

Request
PUT http://mythingserver.com/things/pi/properties/led
{
  "led": true
}
Accept: application/json
Response
200 OK

Actions resource

An actions resource represents a queue of actions to be executed on a device. A new action is created in the queue with an HTTP POST request and can be deleted from the queue with an HTTP DELETE request. The current status of an action request can be retrieved with an HTTP GET request and updated with an HTTP PUT request.

Example: Request an action

Request
POST http://mythingserver.com/things/pi/actions
{
  "name": "reboot"
}
Accept: application/json
Response
201 Created
{
  "name": "reboot"
  "href": "/things/pi/actions/123e4567-e89b-12d3-a456-426655"
}

Example: Get a list of action requests

Request
GET /things/pi/actions
Accept: application/json
Response
200 OK
[
  {
    "name": "reboot",
    "href": "/things/pi/actions/123e4567-e89b-12d3-a456-426655",
    "timeRequested": "2017-01-25T15:01:35+00:00",
    "status": "pending"
  },
  {
    "name": "reboot"
    "href": "/things/pi/actions/153e3567-e89b-12a3-a456-426351",
    "timeRequested": "2017-01-24T11:02:45+00:00",
    "timeCompleted": "2017-01-24T11:02:46+00:00",
    "status": "completed"
  }
]

Example: Get an action request

Request
GET /things/pi/actions/123e4567-e89b-12d3-a456-426655
Accept: application/json
Response
200 OK
{
  "name": "reboot"
  "href": "/things/pi/actions/123e4567-e89b-12d3-a456-426655",
  "timeRequested": "2017-01-25T15:01:35+00:00",
  "status": "pending"
}

Example: Cancel an action request

Request
DELETE /things/pi/actions/123e4567-e89b-12d3-a456-426655
Response
204 No Content

Events resource

An events resource provides a list of events emitted by a device. An events resource is usually read only.

Example: Get a list of events

Request
GET /things/pi/events
Accept: application/json
Response
200 OK
[
  {
    "name": "reboot",
    "description": "Going down for reboot",
    "time": "2017-01-25T15:01:35+00:00"
  },
  {
    "name": "reboot",
    "description": "Going down for reboot",
    "time": "2017-01-24T13:02:45+00:00"
  }
]

Things resource

A things resource represents a collection of Things exposed by a particular Web of Things server.

Example: Get a list of things

Request
GET /things
Accept: application/json
Response
200 OK
[
  {
    "name":"WoT Pi",
    "type": "thing",
    "description": "A WoT-connected Raspberry Pi",
    "properties": {
      "temperature": {
        "type": "number",
        "unit": "celsius",
        "description": "An ambient temperature sensor",
        "href": "/things/pi/properties/temperature"
      },
      "humidity": {
        "type": "number",
        "unit": "percent",
        "href": "/things/pi/properties/humidity"
      },
      "led": {
        "type": "boolean",
        "description": "A red LED",
        "href": "/things/pi/properties/led"
      }
    },
    "actions": {
      "reboot": {
        "description": "Reboot the device"
      }
    },
    "events": {
      "reboot": {
        "description": "Going down for reboot"
      }
    }
  }
]

Alternative Protocol Bindings

The default protocol binding for the Web Thing REST API is HTTP(S). Bindings to alternative application protocols (e.g. CoAP) may be used, but these bindings are beyond the scope of this specification. A Web Thing API protocol binding may also be layered on top of a non-Internet application protocol by use of a gateway.

Guidance for both types of bindings is provided in a separate note called Web Thing API Protocol Bindings.

References to available alternative protocol bindings may be provided in HTTP responses using an Alt-Svc HTTP response header.

Web Thing WebSocket API

The Web Thing WebSocket API complements the REST API to provide a realtime mechanism to make multiple requests and be notified of events as soon as they happen, by keeping a WebSocket open on the Web Thing. The "webthing" WebSocket subprotocol defined here has a simple set of message types and a JSON response format consistent with the Web Thing REST API.

Protocol Handshake

To open a WebSocket on a Thing, an HTTP GET request is upgraded to a WebSocket using a standard WebSocket protocol handshake and the "webthing" subprotocol. The WebSocket URL for a Web Thing is specified in the links member of the Web Thing Description.

Request
GET wss://mythingserver.com/things/robot
Host: mythingserver.com
Origin: https://mythingserver.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: webthing
Sec-WebSocket-Version: 13
Response
HTTP 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: webthing

A WebSocket can be opened from a web page using the JavaScript WebSocket API which will take care of the handshake detailed above and allow messages to be sent and received.

Example
const socket = new WebSocket('wss://mywebthingserver/things/robot', 'webthing');

setProperty message

The setProperty message type is sent from a web client to a Web Thing in order to set the value of one or more of its properties. This is equivalent to a PUT request on a Property resource URL using the REST API, but with the WebSocket API a property value can be changed multiple times in quick succession over an open socket and multiple properties can be set at the same time.

Example
{
  "messageType": "setProperty",
  "data": {
    "leftMotor": 100
  }
}

requestAction message

The requestAction message type is sent from a web client to a Web Thing to request an action be carried out on a Web Thing. This is equivalent to a POST request on an Actions resource URL using the REST API, but multiple actions can be requested at the same time or in quick succession over an open socket.

Example
{
  "messageType": "requestAction",
  "data": {
    "goForward": {},
  }
}

addEventSubscription message

The addEventSubscription message type is sent from a web client to a Web Thing to allow a client to subscribe to a particular event type, defined by the events member of a Web Thing description. This is similar to adding an event listener in JavaScript, but events are received as an event message over the Web Thing WebSocket API.

Example
{
  "messageType": "addEventSubscription",
  "data": {
    "motion": {}
  }
}

propertyStatus message

The propertyStatus message type is sent from a Web Thing to a web client whenever a property of a Web Thing changes. The payload data of this message is in the same format as a response to a GET request on Property resource using the REST API, but the message is pushed to the client whenever a property changes and can include multiple properties at the same time.

Example
{
  "messageType": "propertyStatus",
  "data": {
    "led": true
  }
}

actionStatus message

The actionStatus message type is sent from a Web Thing to a web client when the status of a requested action changes. The payload data is consistent with the format of an Action resource in the REST API, but messages are pushed to the client as soon as the status of an action changes.

Example
{
  "messageType": "actionStatus",
  "data": {
    "grab": {
      "href": "/actions/123e4567-e89b-12d3-a456-426655",
      "status": "completed"
    }
  }
}

event message

The event message type is sent from a Web Thing to a web client when an event occurs on the Web Thing. The payload data is consistent with the format of an Event resource in the REST API but messages are pushed to the client as soon as an event occurs.

Example
{
  "messageType": "event",
  "data": {
    "motion": {
      "timestamp": "2017-01-24T13:02:45+00:00"
    }
  }
}

Web Thing Types

This specification defines a set of common device types which can be used in a Thing Description. This list is not intended to be exhaustive, but defines a core set of built in types which can be mapped to device types in existing underlying IoT protocols, using non-normative protocol bindings.

thing type

The default device type of "thing" can be used when no more specific device type is more appropriate. The only mandatory fields for a Thing Description of this type are the "name" and “type” fields.

Fields

Field Type Values Required
name String Any Yes
type String "thing" Yes
description String Any No

onOffSwitch type

On/Off Switch is a generic device type for actuators with a boolean on/off state. This may be used for smart plugs and light switches for example.

Fields

Field Type Values Required
name String Any Yes
type String "onOffSwitch" Yes
description String Any No

Properties

Property Type Values Required
on Boolean true/false Yes

Actions

Action Arguments Description Required
toggle None Toggles boolean on/off state. No

binarySensor type

Binary Sensor is a generic device type for sensors with a boolean on/off state. This may be used for smart door, infrared movement or flood sensors for example.

Fields

Field Type Values Required
name String Any Yes
type String "binarySensor" Yes
description String Any No

Properties

Property Type Values Required
on Boolean true/false Yes

Extensibility with JSON-LD

The Web Thing Description format uses a schema based system which allows anyone to define their own Web Thing types and share them with others in order to encourage interoperability. JSON-LD notation is used to add semantic annotations to a Thing Description in order to establish a shared semantic context and define a Web Thing type.

Example
{
  "@context": "http://iot.schema.org",
  "@type": "Toaster",
  "name":"Acme Toaster",
  "description": "A web connected toaster",
  "properties": {
    "on": {
      "type": "boolean",
      "description": "Whether the toaster is currently heating bread",
      "href": "/properties/on"
    },
    "timeRemaining": {
      "type": "number",
      "unit": "seconds",
      "href": "/properties/timeRemaining"
    }
  },
  "actions": {
    "pop": {
      "description": "Pop up the toast"
    }
  },
  "events": {
    "ready": {
      "description": "Your toast is ready!"
    }
  },
  "links": {
    "properties": "/properties",
    "actions": "/actions",
    "events": "/events",
    "websocket": "wss://toaster.smith.home"
  }
}

The @context property provides an IRI which defines a globally unique "context" within which types are defined. The optional @type property specifies a Web Thing type from that context to be applied to the thing being described.

When no @context property is supplied, a default Web Thing context is assumed (to be defined) and type is equivalent to @type.

Further Information

Web Thing API Protocol Bindings
Proposed non-normative bindings of the Web Thing API to various existing IoT protocols.

Web of Things Integration Patterns
Advice on different design patterns for integrating connected devices with the Web of Things.