WoT @ SXSW 2010


Hi, we're Vlad & Dom. Thanks for coming to our workshop so early on a sunday morning, that's cool! You did well as we'll present an in-depth overview of our work on the Web of Things we do/did for SAP and our research lab at ETH Zurich.

This is the menu of the day:

Disclaimer: This file (and all the content herein) are mainly offered to you for illustration purposes and most of the work presented here is academic research that works in the lab, and has not been tested (although designed) for many concurrent users. Many of the links will likely be dead when you'll try them (mainly because we want to preserve the servers from crashing during our demos). We'll open the most of the links after our presentation, and hopefully things won't crash when you'll try them... else just be patient as most of what you see here will sooner or later be released as open source projects. Our goal is to share with you our passion and exploration of the Web of Things, and hopefully inspire you to use the patterns and ideas to make the Web of Things a reality! This work is licensed under a Creative Commons Attribution-Share Alike 2.5 Switzerland License.

Oh and please join our community!

So let's start right away (use the keyboard arrows, space to display all pages at once, like for printing)!

Web of Things Intro

Microprocessors are invading us. More and more powerful devices and silently pervading our lives. They have all kinds of sensor and actuators, and are increasingly connectable to the internet. This is an infinite playground for hackers and tinkerers. Problem is there are many (really!) procotols out there to interact with devices which are often ugly and/or proprietary (e.g., ZigBee, Z-Wave, Bluetooth, etc..). Plus devices have very different functions, capabilities, features. So existing applications are expensive and difficult to prototype and customize.

So how do I build applications on top of such a heterogeneous set of networked devices? How would my toaster talk to my fridge and understand each other? What would they say to each other anyway? We need a universal application protocol that is lightweight enough to run on embedded devices, easy to use, flexible, scalable, and well... widely adopted.

We propose to reuse as much as possible of what’s already out there: use the Web as the application protocol. Indeed, the Web is widely used and scalable (>1.5 bilion users) and we can take it for granted as TCP/IP and WiFi routers are ubiquitous. It is quick and cheap to develop simple Web applications (at least in comparison to develop custom application for devices using lower-level technologies & protocols). The Web is also loosely-coupled and evolvable so resources evolve independently.

We'll present here how to adapt standard Web technologies for connecting physical objects. We envision the future Web as a dynamic collection of devices that can be recombined at runtime to build applications. Users can develop easily hybrid mashups that integrate real-time data from devices in any application using any language that has a HTTP library (sounds like a pleonasm no?). Using a high-level approach to rewire and combine data and enabling devices to be dynamically explored with a Web browser makes so much simpler to build applications.

You can find more information about WoT (and much more in this document):

RESTification of Devices

We started by figuring out what it means to have a Web-enabled devices. Playing around with SOAP based Web services we discovered REST, which is very much the core architecture of the WWW. Devices and their properties such as sensors, software/hardware parameters, functionalities are turned into Web resources. That means all these resources are available on the Web directly as they all have a unique URI and can be manipulated using HTTP.

Then we went on and RESTified the Sun SPOTs. SunSpots are cool, they are little computers with a bunch of sensors and actuators and has a low-power radion interface. You can see them in action on the SunSpot gateway running in our lab in Zurich or the local one we brought with us here. Try it, it's cool, you basically browse the sensors of the devices and you can directly interact with devices through their RESTful interface. You can even subscribe to the ATOM feed of a devices.

The truth is, we cheat a little bit here. The Spots we show you do not actually "run" a full-fledged HTTP server on board. We can do it (and actually did it), using smews, contiki, or nanohttpd with sunspots, but it's not necessary, and it's of course less efficient.

Now let's see how one can interact with a SunSPOT, we can do this with our RESTful explorer (which is an extended version of Ben Alman's simple http proxy). The explorer allows you to browse and interact RESTfully with sunspots from a javascript (through a php proxy, the point is just to illustrate this quickly). We'll demo it to show browsability, content negociation, and the uniform interface constraints among others.

The second demo illustrates the uniform interface for devices and how you can read/write data from/to sunspots by changing the colors of the LEDs. The second demo uses Erik Arvidsson's javascript sliders to input the color value to send to the SunSpot LEDs.

 

Gateways

The problem is that not all embedded devices can/need/should run HTTP directly on board (either because they aren't programmable, or because they use weird APIs or interfaces). In this case, we Web-enable them through a proxy or gateway. A gateway is simply a Web server that bridges the Web with whatever particular protocol you devices uses, which means it allows you to send RESTful HTTP requests to embedded devices. It is fully Web compliant (HTTP, URI, JSON, RSS...) and connects to all kinds of embedded devices using all kinds of communication protocols (Zigbee, bluetooth, etc). It knows all about the devices connected to it and proxies the device's functions (that are meant to be publicly accessible), so that interaction with devices is transparent (you only need to know HTTP, not the actual communication with the devices, which is fully encapsulated and hidden).

The coolest thing about the gateways is that they aren't compulsory, especially when devices are directly available on the Web. However, gateways allow you to leverage a lot of Web features that are not necessary available or feasible on individual RESTful devices (caching, high-level composition such as the average reading of all temperature sensors in the room, etc). Gateways are made to run on any embedded computer that runs java (linux/mac/windows). Early gateways were fully done in java, but the new gateway has been ported on OSGi. You can find a whole bunch of info about the old one here and here, and it is very likely that we'll also publish the source code soon, so stay tuned. We'll talk enough about the gateways later because they are an important building block of the Web of things.

To illustrate the idea of gateways, we present the Plogg, which is a simple bluetooth-enabled smart meter. We RESTified ploggs using Mongoose (an embedded Web server done in C) running on an computer with a bluetooth dongle (the gateway). You could then access the energy data of all ploggs near the gateway with a simple HTTP request, as follows:

GET http://PLOGG_GATEWAY_IP:8080/energymonitor/ploggs/*

You'll get all the data of all the ploggs connected to the ploggs gateway.

[{
"deviceName": "ComputerAndScreen",
"currentWatts": 50.52,
"KWh": 5.835,
"maxWattage": 100.56
},
"deviceName": "Fridge",
"currentWatts": 86.28.,
"KWh": 4.421,
"maxWattage": 288.92
}, {...}]

On top of the RESTful ploggs we built the Energie Visible project (which won the Jade 2008 award). It is a cute user interface that nicely displays the energy consumption of devices attached to all the ploggs discovered over bluetooth built with Google Web Toolkit, and looks like this (we'll demo it).

Then you can turn off the plogg (the device attached to it actually, like a lamp) with the following HTTP request:

PUT http://PLOGG_GATEWAY_IP:8082/EnergieVisible/ploggs/008098e7cb71/status.html
Payload: status=off

Devices gone Web

When devices connect to the Web and become RESTians, then they can theoretically do everything we humans do. Including connecting to twitter and facebook. Also, we can use the social structure of these sites for controlling access to devices. We did this using SAC (Social Access Controller) & FAT (Friends and Things). You can see FAT here, and you can see the API of SAC. Read more about FAT/SAC here.

You can use FAT to share devices with your friends on various social networks. As shown in the screenshot, you can chose a gateway, then select the resource you want to share and with whom, and also which operations (HTTP verbs) you want to allow your contact to perform on the shared device.

Once resources have been shared with you, you can then simply send them commands or register the ATOM feed of data generated by the device (in case of a sensor for example).

Examples (working iif somebody is logged in the system): the gateways are at http://vswot.inf.ethz.ch:8091/gateways, the users logged in at http://vswot.inf.ethz.ch:8091/users/loggedIn, and the shares of a user at http://vswot.inf.ethz.ch:8091/users/131072/shares

Mashups

The coolest part of using the Web on devices, is to extend the notion of mashups to the real world. This means you're not only limited to text data, but Web services become physical. The real world becomes programmable. We have built clickscript, which is a javascript-based mashup editor. It exists both as a firefox/chrome plugin and as a Web application, we'll demo the former. Try it too or see the whole screenshot. Here's what the mashup looks like:

We will also show how one can build a module for clickscript, fully in Javascript. This is component for interacting with the SunSPOT temperature sensor. See the source code (init.js).

	csComponentContainer.push({
name : "cs.web.things.temperature",
description : "Get the temperature from a WoT Sun Spot.",
inputs :
[
{
name: "IP",
type: "cs.type.String"
},
{
name: "Name",
type: "cs.type.String"
}
],
outputs:
[
{
name: "Temperature",
type: "cs.type.Number"
}
],
image: "web/things/temp.png",
exec : function(state){
this.setAsync();
var ip = state.inputs.item(0).getValue();
var name = state.inputs.item(1).getValue();
var aurl = "http://"+ip+"/sunspots/"+name+"/sensors/temperature";
var component = this;
$.ajax({
beforeSend: function(xhrObj){
xhrObj.setRequestHeader("Accept","application/json");
},
url: aurl,
type: "GET",
dataType: "json",
success: function(result){
var temp = result.resource.getters[0].value
/* write this to ouput socket, expecting a number */
state.outputs.item(0).setValue(temp)
component.finishAsync();
},
error: function(msg){
alert("Error on: "+aurl);
}
});
}
});

Eventing

Okay, all these request/response interactions with devicesare nice, but seems like something is missing, no? Applications for embedded devices usually need eventing and streaming. For example, many applications do environmental monitoring, that is gather data from various sensors (Water pH, air pollution, seismic, etc) to a central server to process and store the data. This would require devices to stream their readings over the Web (or periodic polling). A second scenario, would require eventing, that is devices must send timely notifications when something occurs in the real-world ("send me an SMS when someone enters this room").

ATOM is nice but poll-based, so not terrific for timely notifications. We explore the recent boom in the real-time Web. With HTTP push solutions such as comet, web hooks, reversehttp, websockets, etc, we can do finally much more interactive push-based solutions. Besides, we still need a push-based publish subscribe, and pubsubhubbub is yet the coolest thing out there.

curl -X POST --data "rms-publisher-name=curl&rms-publisher-uuid-type=aparat&rms-publisher-uuid-value=curl&temperature=23" 
		http://localhost:8080/aparat/rms/channels/simulation

For the demo, you need a rabbithub server running into which you get data from devices. We have one running (connect to our local WLAN to use it ssid:webofthings.com). There, we have a gateway running on 192.168.1.32 with a the rabbitmq & rabbithub interface on it. The sunspot driver is running on http://192.168.1.32:8081 (the rabbithub interface is on port 8085, but it's too ugly to be worth looking at it). We might not have the time to show this demo.

To play with this demo, first install erlang (yeah, sorry about that, but it's worth it). Then download this archive, which is an reversehttp implementation written in erlang. This is cool, because running it on your machine will enable to register to a rabbithub server and get messages from devices streamed to you via the rabbithub server. You could then directly reuse and display using javascript on your machine.

Unzip, then go to the 'reversehttp' folder and do a 'make clean' and a 'make'. Start reversehttp by executing the 'start.sh' script, then navigate to http://localhost:8000.

Data Stream Creation

Use this to create new data streams. The names of the available devices and data types are given on the right side of the page. Enter the desired devices and data types separated by comma (no spaces after comma). Furthermore enter

  1. a frequency: This will create a data stream that gives you the data in that frequency (in Hz)
  2. a frequency and a filter criteria: This will create a data stream that gives you the data in the frequency you specified. But you'll only get a message if in an interval period at least one message matched your criteria
  3. only a filter: Gives you a data stream that sends you a message as soon as a message matches your filter Filter criteria can be specified over all data fields in the data stream.

Example:

  - temperature > 10
  - (temperature > 10 && light <= 17) || !(accelerationX > 0.5)

Technically we use jquery to do a post on the messaging connector bundle. The message bundle verifies the request and creates the appropriate data stream. The stream is exposed using rabbithub. So the client gets back a URL to a rabbithub queue. The client can then use this URL to register to the hub and receive messages from the data stream. For that the client sends a HTTP POST subscription request and indicates a callback URL where the rabbithub server shall send the messages. We then use reversehttp to have a Javascript-programmable http server which can get requests to a URL. The server then gets the messages from rabbithub and we can use them directly in Javascript.

List Messages

Can be used to list messages as they arrive. Cool in conjunction with a filtering data stream. For example:

  - device: some devices
  - data: accelerationX, accelerationY
  - filter: accelerationX > 0.5 || accelerationY > 0.5

As soon as a person moves the sunspot in either x or y direction a message is submitted and will be displayed in the list. For this to work optimally set the interval with which the sunspots measure the data to a small value.

Graphical acceleration display

This demo allows to visualize acceleration data in real time. Specify a data stream with the following properties:

  - device: some devices
  - data: accelerationX, accelerationY, accelerationZ
  - frequency: 3  

Discovery

All that sounds great. But now, how can we search and discover real-world devices? The devices serve common microformats to describe devices and their properties, which makes them computer-parseable. We don't want to override network-level discovery, plus microfromats are expressive enough and quite standard. All resources are semantically annotated using microformats. For example, devices have their current location using the geo micrformat, a review using hReview, and their operations using hRests. What looks like this:

Geo

Latitude: 47.3764167
Longitude: 8.5481028
Altitude: 408

on the device driver page; is in fact this in the source code:

<h2 class = "mftitle stress">Geo</h2><span class="geo">
<span class="mftitle">Latitude: </span><span class="latitude">47.3764167</span><br/>
<span class="mftitle">Longitude: </span><span class="longitude">8.5481028</span><br/>
<span class="mftitle">Altitude: </span><span class="altitude">408</span>

In the same way, we describe pretty much everything you might want to know about devices. For example this is list of Sub Resources of the sunspot sensors:

When it comes to interacting with resources (eg, light and so), we use hRESTS to describe the individual thingies. For example this is the description of the Y-axis accelerometer. You can pretty much automatically understand how to use it (there is no input because you can't change the state, so look at the leds source code, to see the mf in action...).

I'll demo the discovery of a device and talk a little about the microformats. http://vswot.inf.ethz.ch:9090/

<span class="service">
<span class="mftitle">Label: </span><span class="label">Acceleration Y axis</span><br/>
<span class="mftitle">Data Format: </span><span class="data-format">String</span><br/>
<span class="mftitle">Operation: </span><span class="operation"><br/> <span class="mftitle">Method: </span><span class="method">GET</span><br/>
<span class="mftitle">Address: </span> <span class="address">http://vswot.inf.ethz.ch:8081/sunspots/Core2TestSpot/sensors/acceleration</span><br/>
<span class="mftitle">Input: </span><span class="input"></span><br/>
<span class="mftitle">Output: </span><span class="output">Acceleration Y-axis</span><br/>
</span>

You can access the gateway here. You register the sunspots manager simply by inputing it's base url in the register field, hit the button, wait, wait more (yeah, it takes a while as this virtually crawls all the resources and subresources on the gateway and parsing all the microformats to "understand" what is what), then sunspots and all their resources appear. Then you can simply search all of that.

Enterprise applications

The goal of EPCIS is to enable disparate applications to leverage Electronic Product Code (EPC) data via EPC-related data sharing, both within and across enterprises. In non-business jargon, it is a standard to manage and track RFID-equipped things. Fosstrack is an open source implementation of the EPCIS standard, on top of which we have build a RESTful interface (RESTful EPCIS).

You can see the RESTful epcis here. The EPC dashboard is available here.


We will demo both. Then we illustrate how to build a Twitter Widget for the dashboard (source code for your viewing). The widget is based on the twitter search goodie.

Voila, we're done

Thanks to have followed through, we hope you enjoyed the ride! Thanks a lot to you all for coming this day.

Thanks a lot to Mitchell Amihod for the invitation and to the other panelists for the workhsop & fun discussions (Dan & Kyle).

Thanks to our sponsors (ETH Zurich, SENSEI & Socrades EU Projects, SAP Research), and especially our supervisor Prof. Friedemann Mattern for his support.

A special thanks goes to our students and colleagues for all the hard work and help (Vlatko Davidovski, Ivan Delchev, Bettina Dober, S. Hong, Mathias Fischer, Michael Haenni, Andreas Kamilaris, Simon Mayer, Mathias Muller, Lukas Naef, Thomas Pham, Oliver Senn, Azu Guillen Aguilar, Samuel Wieland)!