WoT Week 2024

We attended the WoT Week 2024 and we showcased how wot-rust interoperates with dart_wot.

WoT Week and PlugFest

For a while now, the W3C is active in the Internet of Things (IoT) domain and has published Recommendations that deal with improving the interoperability of IoT devices and ecosystems – the Web of Things (WoT) family of standards. To test the interoperability of implementations and try out new features that could be incorporated into the specifications, the WoT Working Group hosts regular "PlugFests". After a long hiatus of five years where only online events were possible, members of the Working Group as well as implementors with various backgrounds finally came together in person again for a WoT Week. The event took place in the Siemens facilities in Garching, Germany, and was accompanied by the WoT conference, where results from the PlugFest were showcased.

In this blogpost, we are going to describe our contributions to the plugfest based on implementations written in Rust and Dart, and the insights we had during our interoperability tests.

As all the code used for the examples is open-source, you can also use it as a basis for your own WoT applications.

Demos

One of the long term plans for wot-rust is to make so you can write your logic once and run it on widely different targets, e.g. a normal linux target and bare metal.

On the other hand dart_wot aims at making very straightforward write consumers that can run on a desktop as well as on mobile platforms with little to no adaptation, as it can be integrated into cross-platform apps using the Flutter framework.

Flutter Client (dart_wot)

For the demo, we further developed a Flutter app that was originally created for the Eclipse Foundation's Open Community Experience (OCX) to showcase the capabilities of dart_wot together with other Eclipse Thingweb components. Similar to its reference implementation node-wot, dart_wot is based on the WoT Scripting API and offers an abstration layer to discover and interact with Things using different underlying protocols (currently HTTP, CoAP, and MQTT). To support the event mechanism offered by our Things, we added support for server-sent events (SSE) to the HTTP binding during the plugfest, which was a feature that was still missing at that point.

For the demo, we mainly relied on the HTTP binding implementation to discover Things from a (also standardized) Thing Description Directory (TDD) and perform the actual interactions with the Things, i.e. reading/writing properties, subscribing to events, and invoking actions, although the UI for providing values that should be written to the devices still has room for improvement. Besides discovery from a TDD and direct retrieval of TDs, the client also supports DNS-based service discovery via mDNS, although during the plugfest we weren't able to utilize yet (see below).

To implement the app, we relied on the riverpod package for state management which turned out to be really well-usable with dart_wot and eases a lot of pain points you might encounter when building a Flutter app in the "traditional" way (i.e., relying on the setState() method to alter a UI widget's state and trigger a re-render). With riverpod, you rely on so-called providers instead that can trigger a partial re-render of UI components when a state change occurs, in our case the value of a property, for example.

ESP32c3 Servients (wot-rust)

The demos target the ESP32c3 rust-board since it provides enough sensors and buttons out of box and is easy to source.

For this demo we used the latest version of the following crates and while at it contributed a bit to them.

esp-hal

It is the bare-metal HAL for any ESP32 cpu. It provides additional niceties such as a println implementation, a simple allocator and wifi support and within it a network stack.

wot-td

Our crate to build Thing Descriptions, now working also in no_std+alloc environments.

picoserve

It is the HTTP server we use, it is even no_alloc, but for now we didn't port wot-td to heapless yet.

edge-mdns

Sadly it didn't make the demo day since it was blocked on a embassy-net update blocked on a smoltcp update. The last day of WoT Week most of it got unblocked so now there is a branch sporting it waiting for the edge-net release that uses embassy-net 0.5.

The Things

With the above ingredients we managed to bake the following 3 demos.

thermometer

This is a sensor that updates its two states temperature and humidity with a defined cadence.

The information is exposed as a 2 properties that can be polled and events that can be subscribed.

The information is presented as a simple floating point value with an @type that could hint the consumer on how to present the information.

button

This is another kind of sensor that updates as a physical button is pressed, in this case the update is driven by an interrupt we control directly instead of relying on the shtcx abstraction.

We expose its internal boolean state through a property and an event.

light

It models an RGB light source, its internal state tracks the color and the brightness level.

In this case the properties can also be written and not just read and we expose the information using a much richer DataSchema:

    .object()
    .property("r", true, |b: DataSchemaBuilder<Nil, Nil, , …>| {
        b.finish_extend()
            .integer()
            .title("Red")
            .minimum(0)
            .maximum(255)
    })
    .property("g", true, |b: DataSchemaBuilder<Nil, Nil, , …>| {
        b.finish_extend()
            .integer()
            .title("Green")
            .minimum(0)
            .maximum(255)
    })
    .property("b", true, |b: DataSchemaBuilder<Nil, Nil, , …>| {
        b.finish_extend()
            .integer()
            .title("Blue")
            .minimum(0)
            .maximum(255)
    })

Interactions/Interoperability Tests

Since edge-net was not yet available we couldn't discover our Things via mDNS and had to rely on direct retrieval of the TDs instead. Still, the two flavours of WoT implementations worked well together after ironing out a couple of bugs and quirks that we noticed in the setup process. In the end, we were able to read and partially also write properties (i.e., the color and brightness of the LED as well as the sensor values), trigger the action that toggles the LED, and subscribe to events via SSE to be informed about temperature changes. Some of these interactions are not translated ideally into the UI yet (also due to a lack of semantic annotations, see below), but the app will further evolve in the future to better serve more interaction patterns.

Wishes for the future

During our tests, we notices a couple of aspects that will hopefully be improved in the ongoing WoT standarization process.

Better ontologies

Something we would really had enjoyed, but sadly we couldn't test nor implement is leveraging more the @type metadata since we couldn't find an ontology widespread and standard enough to make mapping our rgb object to a colorpicker in a completely automated way.

This part of WoT is out of the scope of W3C so far, so worst case we'll support what feels the most used one in the opensource communities.

TD 2.0

Our examples implement a draft of WoT Profiles 1.0 SSE and we saw how coupling the property with the event affordances makes adding observe operations potentially redundant.

One of the proposals for TD 2.0 is to describe even more relationships across affordances, not only which events to subscribe to in order to be notified as a property updates, but also have information on how an ongoing action may change exposed properties (e.g. the light demo will have a fade action that impacts the brightness property).

Another is to move the SSE support as a protocol binding and have Profiles 2.0 to signal which capabilities the Clients need in order to fully consume a conforming Thing.

Hopefully next year we'll meet again and prepare more demos showcasing what you can do with WoT.