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 of Things Gateway 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 includes a proposed plain JSON serialisation of a Thing Description and a concrete HTTP and WebSockets protocol binding for the Web of Things. This proposal is intended to complement the current W3C Web of Things Working Group's work on an abstract data model and API for the Web of Things, by defining a simple concrete serialisation and protocol binding using existing web technologies which can be used today, and don't require web clients to implement a new Scripting API, multiple non-web IoT protocols, or an RDF-based parser.

Parts of this proposal are now being incubated with other members of the W3C Web of Things Interest Group as part of an Editor's Draft. We encourage other interested parties outside of Mozilla to collaborate on that work.

While that incubation work continues, this document will continue to be maintained to reflect the current API implemented by Mozilla's own open source Web of Things implementation through Project Things. We encourage developers to continue to implement this API to build web things compatible with Mozilla's Things Gateway, and provide feedback to help us further improve the specification.

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.

{
  "name":"My Lamp",
  "type": "thing",
  "description": "A web connected lamp",
  "properties": {
    "on": {
      "type": "boolean",
      "description": "Whether the lamp is turned on",
      "href": "/things/lamp/properties/on"
    },
    "level" : {
      "type": "number",
      "description": "The level of light from 0-100",
      "minimum" : 0,
      "maximum" : 100,
      "href": "/things/lamp/properties/level"
    }
  },
  "actions": {
    "fade": {
      "description": "Fade the lamp to a given level",
      "input": {
        "type": "object",
        "properties": {
          "level": {
            "type": "number",
            "minimum": 0,
            "maximum": 100
          },
          "duration": {
            "type": "number",
            "unit": "milliseconds"
          }
        }
      },
      "href": "/things/lamp/actions/fade"
    }
  },
  "events": {
    "overheated": {
      "type": "number",
      "unit": "celsius",
      "description": "The lamp has exceeded its safe operating temperature",
      "href": "/things/lamp/events/overheated"
    }
  },
  "links": [
    {
      "rel": "properties",
      "href": "/things/lamp/properties"
    },
    {
      "rel": "actions",
      "href": "/things/lamp/actions"
    },
    {
      "rel": "events",
      "href": "/things/lamp/events"
    },
    {
      "rel": "alternate",
      "href": "wss://mywebthingserver.com/things/lamp"
    },
    {
      "rel": "alternate",
      "mediaType": "text/html",
      "href": "/things/lamp"
    }
  ]
}
        

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 a property alone is not sufficient to affect a required change in state. This may be used to describe a function which takes a period of time to complete, manipulates multiple properties, or has a different outcome based on provided arguments or current state. An example might include a "fade" action which has a specified "duration" or 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 an array of link relations (RFC 5988) to other resources of a thing. Links can include a link relation type (rel) and an optional media type (mediaType). Examples of links include URLs to get all current property values ("rel":"properties"), a queue of all thing action requests ("rel":"actions") and a list of all recent events ("rel":"events"). It can also include links to alternate representations of a thing such as a WebSocket API endpoint or an HTML user interface ("rel":"alternate").

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.

"level" : {
  "type": "number",
  "description": "The level of light from 0-100",
  "minimum" : 0,
  "maximum" : 100,
  "href": "/things/lamp/properties/level"
}
        

Action object

An action object describes a function which can be carried out on a device. An action definition may include an action input with a JSON Schema which specifies one or more parameters, a human friendly description which explains what the action does and an href which provides the URL for a corresponding Action Resource.

"fade": {
  "description": "Fade the lamp to a given level",
  "input": {
    "type": "object",
    "properties": {
      "level": {
        "type": "number",
        "minimum": 0,
        "maximum": 100
      },
      "duration": {
        "type": "number",
        "unit": "milliseconds"
      }
    }
  },
  "href": "/things/lamp/actions/fade"
}
      

Event object

An event object describes a kind of event which may be emitted by a device. This may include the type of the event payload (specified using a JSON Schema type), a human friendly description which describes what the event means and an href which provides the URL for a corresponding Event Resource.

"overheated": {
  "type": "number",
  "unit": "celsius",
  "description": "The lamp has exceeded its safe operating temperature",
  "href": "/things/lamp/events/overheated"
}
      

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": [
    {
      "rel": "properties",
      "href": "/things/pi/properties"
    },
    {
      "rel": "actions",
      "href": "/things/pi/actions"
    },
    {
      "rel": "events",
      "href": "/things/pi/events"
    },
    {
      "rel": "alternate",
      "href": "wss://mywebthingserver.com/things/pi"
    },
    {
      "rel": "alternate",
      "mediaType": "text/html",
      "href": "/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
{
  "led": true
}

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.

Action Request

POST https://mythingserver.com/things/lamp/actions/
Accept: application/json

{
  "fade": {
    "input": {
      "level": 50,
      "duration": 2000
    }
  }
}
      
201 Created

{
  "fade": {
    "input": {
      "level": 50,
      "duration": 2000
    },
    "href": "/things/lamp/actions/fade/123e4567-e89b-12d3-a456-426655"
    "status": "pending"
  }
}
      

Actions Queue

GET /things/lamp/actions
Accept: application/json
      
200 OK
[
  {
    "fade": {
      "input": {
        "level": 50,
        "duration": 2000
      },
      "href": "/things/lamp/actions/fade/123e4567-e89b-12d3-a456-426655",
      "timeRequested": "2017-01-25T15:01:35+00:00",
      "status": "pending"
    }
  },
  {
    "fade": {
      "input": {
        "level": 100,
        "duration": 2000
      },
      "href": "/things/lamp/actions/fade/123e4567-e89b-12d3-a456-426655",
      "timeRequested": "2017-01-24T11:02:45+00:00",
      "timeCompleted": "2017-01-24T11:02:46+00:00",
      "status": "completed"
    }
  }
]
      

Action Status

GET /things/lamp/actions/fade/123e4567-e89b-12d3-a456-426655
Accept: application/json
      
200 OK
{
  "fade": {
    "input": {
      "level": 50,
      "duration": 2000
    },
    "href": "/things/lamp/actions/fade/123e4567-e89b-12d3-a456-426655",
    "timeRequested": "2017-01-25T15:01:35+00:00",
    "status": "pending"
  }
}
      

Cancel an Action

DELETE /things/lamp/actions/fade/123e4567-e89b-12d3-a456-426655
      
204 No Content
      

Events resource

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

Event Log

GET /things/lamp/events
Accept: application/json
      
200 OK
[
  {
    "overheated": {
      "data": 102,
      "timestamp": "2017-01-25T15:01:35+00:00"
    }
  },
  {
    "overheated": {
      "data": 101,
      "timestamp": "2017-01-24T13:02:45+00:00"
    }
  }
]

Things resource

A things resource represents a collection of web things exposed by a particular Web of Things server. This resource is not needed for individual web things, for which the Thing Description is the entry point. It is used only by Web of Things gateways and services which expose a directory of web things.

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"
      }
    },
    "href": "/things/pi"
  }
]

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/grab/123e4567-e89b-12d3-a456-426655",
      "status": "completed",
      "timeRequested": "2017-01-24T11:02:45+00:00",
      "timeCompleted": "2017-01-24T11:02:46+00:00"
    }
  }
}

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

multilevelSwitch type

A switch with multiple levels such as a dimmer switch.

Fields

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

Properties

Property Type Unit Values Required
on Boolean n/a true/false Yes
level Number "percent" 0 to 100 Yes

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

multilevelSensor type

A generic multi level sensor with a value which can be expressed as a percentage.

Fields

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

Properties

Property Type Unit Values Required
on Boolean n/a true/false Yes
level Number "percent" 0 to 100 Yes

smartPlug type

A smart plug has a boolean on/off state and measures current power consumption. It may also have a level setting and report voltage, current and frequency.

Fields

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

Properties

Property Type Unit Required
on Boolean n/a Yes
instantaneousPower Number "watt" Yes
voltage Number "volt" No
current Number "ampere" No
frequency Number "hertz" No
level Number "percent" No

onOffLight type

A light that can be turned on and off like an LED or a bulb.

Fields

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

Properties

Property Type Unit Values Required
on Boolean n/a true/false Yes

dimmableLight type

A light that can have its brightness level set.

Fields

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

Properties

Property Type Unit Values Required
on Boolean n/a true/false Yes
level Number "percent" 0 to 100 Yes

onOffColorLight type

A colored light that can be switched on and off.

Fields

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

Properties

Property Type Unit Values Required
on Boolean n/a true/false Yes
color String n/a Hexadecimal RGB color code (e.g. #FF0000) Yes

dimmableColorLight type

A colored light that can have its brightness level set.

Fields

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

Properties

Property Type Unit Values Required
on Boolean n/a true/false Yes
level Number "percent" 0 to 100 Yes
color String n/a Hexadecimal RGB color code (e.g. #FF0000) 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": [
    {
      "rel": "properties",
      "href": "/properties"
    },
    {
      "rel": "actions",
      "href": "/actions"
    },
    {
      "rel": "events",
      "href": "/events"
    },
    {
      "rel": "alternate",
      "href": "wss://toaster.smith.home"
    },
    {
      "rel": "alternate",
      "mediaType": "text/html",
      "href": "/"
    }
  ]
}

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.