Working with Mozilla's Project Things

IMPORTANT: Web Thing API support in the Moddable SDK is deprecated as of August 28, 2019.

One of the issues that plagues IoT is the lack of standards for interoperability. There are too many IoT products that connect to only one cloud service or interoperate only with other products from the same company.

At Moddable we believe IoT products should be open and customizable by the end user. And we are not the only ones who feel this way—there is a Web of Things community that is working to find solutions to this problem based on existing and well-known web standards. One of the groups involved is Mozilla, which is known for its commitment to the open web. L..ast year, the Mozilla IoT team launched a Web of Things initiative with the goal of moving "towards a more decentralized Internet of Things that is safe, open and interoperable."

At the forefront of Mozilla's Web of Things initiative is Project Things, an experimental framework of software and services that aims to "bridge the communication gap between connected devices." For the past few months, we have been experimenting with two features of Project Things: the Web Thing API and the Things Gateway. This post describes these features in more detail and shares some of the example applications we have built by combining Project Things with the Moddable SDK.

Web Thing API

The Web Thing API is a draft of a potential specification for a common data model and API for the IoT products that are part of the Internet of Things. Mozilla refers to these devices as Web Things. The goal of this API is to standardize the way devices communicate with each other; the details of the underlying hardware are irrelevant.

The basic idea is as follows:

  • Give each device a web URL.
  • Use a standard data model to describe devices, their properties, and their functions. This specification uses JSON objects.
  • Use a standard API to monitor and control them. This specification allows you to do this using HTTP or WebSockets.
  • Other devices that know the web URL of the device can determine its properties and functions by asking for its description, and then use the API to monitor and control it.

Why is this important?

Today there is no standard way to interact with IoT devices. The cloud services and mobile apps that work with a device are generally provided by the manufacturer with no alternatives. Some are compatible with hubs or apps like IFTTT, but communicating directly with many devices is often impossible.

Standardizing the ways to communicate with devices has many obvious benefits. It makes it possible for users to control their devices using custom web apps, mobile apps, or other devices. Manufacturers can still provide default cloud services and apps, but an IoT product will not become a brick if those services and apps become unavailable. It also makes it possible for different companies to make products that interoperate with each other.

The Things Gateway

The Things Gateway provides a web interface to monitor and control Web Things. There are instructions to set up your own using a Raspberry Pi on the Gateway page of the Mozilla IoT website. This section walks through how to use the Things Gateway while introducing the capabilities of the Moddable SDK Web Things module that enable these features on the device side.

Features

This post only includes information about three of the main features of the Things Gateway: discovery, the Things tab, and the Rules engine. If you are interested in learning about the other features of the gateway, see the following posts from the Mozilla blog:

Discovery

Before you can monitor and control a device from the gateway, you have to add it to your collection of Web Things. To add new devices, go to the Things tab of the gateway and click on the in the bottom right corner.

The Things Gateway searches for devices on the local network using mDNS. Note that the Web Thing API does not specify that Web Things must announce themselves as discoverable resources via mDNS, but doing so makes it easier to discover them in the gateway. There is currently no official documentation on how devices announce themselves, but this thread on GitHub explains how to do it. The Web Things module in the Moddable SDK takes care of this step for you automatically.

If a device does not automatically appear, you can manually search for it by clicking Add by URL... and entering the URL used to retrieve the description of it.

Things tab

To monitor and control devices, go to the Things tab. Each connected device has its own icon.

Image from https://iot.mozilla.org/gateway/

The description of a device optionally includes @type and @context parameters to provide more information about the device's properties and capabilities. You can read about these parameters in the Web Thing Description section of the Web Thing API. The Things Gateway checks for these parameters when it adds the device to your collection of Web Things and uses them to determine which icon to use in the Things tab and the style of other property controllers on the device's page.

For example, the OnOffLight class in the onOffLight example uses two of Mozilla's schemas—Light and OnOffSwitch—to describe itself:

class OnOffLight extends WebThing {
...
    static get description() {
        return {
            "@context": "https://iot.mozilla.org/schemas",
            "@type": ["Light", "OnOffSwitch"],
...
}

The Things Gateway recognizes Mozilla's schemas and gives devices that use them a custom icon in the Things tab.

If you remove the @type and @context parameters from the OnOffLight description, it simply shows the default icon and you have to tap the above its name to go to the device's page. This page has a controller for the on property.

You can also customize the icon manually if your device does not fit one of the Mozilla schemas.

If a device has more than one controllable property, the controllers are always on the device's page that you access by tapping the .

The Things Gateway sends HTTP requests to the device to monitor and control it. You may note that commands sent from the gateway to devices are acted upon very quickly, but it sometimes takes a few seconds for the gateway's UI to update with the state change. This is because the device does not send an HTTP request to the gateway every time its state changes; the gateway polls to monitor the state of the device by sending an HTTP request every 5 seconds asking for its status.

Rules engine

One of the most compelling features of the Things Gateway is a drag and drop interface to create "Rules" that trigger a change to properties of a device on a fixed schedule or based on the property change of another device. For example, you can create a Rule that ties the state of your light to the state of your switch so that when your switch turns on, your light turns on and when your switch turns off, your light turns off.

This example may seem trivial, but this feature is a great example of how Mozilla's initiative is working towards openness and interoperability of devices. As long as two IoT products are compatible with the Gateway, they can be used with each other. And they can be used to add functionality to devices without any changes to the application code on the device.

Examples with Moddable Zero

This video shows the examples in the Web Things folder of our open source repository. All of these examples follow the specification of the Web Thing API and are compatible with the Things Gateway.

Creating a Web Thing is a straightforward process. Start by editing the Web Things manifest.json so it includes your network credentials. This manifest is used by all of the examples to add the required network files and the Web Things module.

The Web Things module defines WebThing and WebThings classes that implement features that are common to all Web Things. For example, they set up the HTTP server and handle incoming requests.

The properties and functionalities of specific devices are defined in separate classes that extend the WebThing class. These are found in the main.js module of each example application.

Per the Web Thing API, every Web Thing must have a description property. The description is a JSON object that describes the device and its properties. Here's an example from the Web Thing API of a description for a basic on/off switch:

The switch in the onOffSwitch example has a similar description.

class OnOffSwitch extends WebThing {
    ...
    static get description() { 
        return {
            "@context": "https://iot.mozilla.org/schemas",
            "@type": ["OnOffSwitch"],
            name: "switch",
            type: "onOffSwitch",
            description: "On/off switch",
            properties: {
                on: {
                    type: "boolean",
                    description: "switch state",
                }
            }
        }
    }
}

The main differences are that our example includes the optional @context and @type parameters, and the properties.onobject does not have an href parameter, which specifies the url to monitor/control a property. This is excluded because the Web Things module automatically adds an href parameter for each property.

Each property from the properties object in the description has its own getter and setter. The Web Things module calls these automatically when a request comes in to the device to read or write the property.

In this example, the getter simply returns the value of the property and the setter updates the value and distributes the onSwitchUpdate event to the application. The on-screen switch button updates accordingly when this event is triggered.

class OnOffSwitch extends WebThing {
    ...
    get on() {
        return this.state;
    }
    set on(state) {
        if (this.state == state) return;
        this.state = state;
        application.distribute("onSwitchUpdate", state);
    }
   ...
}

Other examples might use the setter to trigger other events, like turning a physical LED on rather updating graphics on the screen. If the property is read-only, the setter does nothing.

What's Next?

The Things Gateway is one example of how the Web Thing API can be used to make communication between many devices easier. Project Things is still in an experimental phase and is not ready to be used in production, but it is exciting to see companies like Mozilla working to solve one of the biggest challenges in IoT. We look forward to working with Project Things as it continues to develop.

Stay tuned for a future post on our experiments with direct device-to-device communication using the Web Thing API and lessons we learned from using the Things Gateway.