Jack Jansen, Steven Pemberton, CWI/W3C, Amsterdam
This talk shares insights from an on-going project coordinating data from Internet of Things (IoT) devices, and using a declarative interface to that data.
REST (REpresentational State Transfer) is the architectural basis of the web. As Wikipedia points out “REST’s coordinated set of constraints, applied to the design of components in a distributed hypermedia system, can lead to a higher-performing and more maintainable software architecture.” So how can you apply the same ideas to the Internet of Things?
The Internet of Things is driven by many tiny low-powered processors that produce data in a variety of different formats, and produce the data in different ways, sometimes on demand (such as thermostats), sometimes by pushing it (such as presence detectors). Traditionally, applications have to be a mash up of accesses to devices and formats. To use the data in a cohesive application, the data has to be collected and integrated; this allows very low demands to be put on the devices themselves.
This project places a thin REST-layer around a diverse collection of Internet of Things devices, hiding the data-format and data-access differences, and updating the devices automatically as needed; this then allows a REST-style declarative interface to access and control the devices without having to worry about the variety of device-interfaces and formats.
Thousands of cheap, tiny devices, with low processing power.
Various data formats: text, xml, JSON, ...
Various access methods: on demand, push, in the cloud, ...
Turning the data into applications means programming and dealing with lots of fiddly detail.
Ownership: Who owns the data?
Privacy: Who can see the data?
Control: Who is allowed to do anything with the data?
This then allows a REST-style declarative interface to access and control the devices without having to worry about the variety of device-interfaces and formats.
We have an (XML) database, that autonomously updates itself, and autonomously keeps other devices up to date.
Changing the data in the database causes linked devices to be updated automatically.
REST (REpresentational State Transfer) is the architectural basis of the web. As Wikipedia points out:
“REST’s coordinated set of constraints, applied to the design of components in a distributed hypermedia system, can lead to a higher-performing and more maintainable software architecture.”
In other projects we actually have proof of this claim: it can save around an order of magnitude in time and costs.
So how can you apply the same ideas to the Internet of Things?
Declarative approaches describe the solution space.
Procedural approaches describe how to reach one solution.
Declarative: The square root of a number n is the number r such that r × r = n.
Procedural:
function f a: { x ← a x' ← (a + 1) ÷ 2 epsilon ← 1.19209290e-07 while abs(x − x') > epsilon × x: { x ← x' x' ← ((a ÷ x') + x') ÷ 2 } return x' }
XML Database(s)
Constraints and relationships
Events
For instance: change the data value for the lights from 0 to 1, and the lights go on.
One or more instances of the database can intercommunicate.
For instance there is a single bit: lights
.
When that bit is 1, the lights are on, and when it is 0, the lights are off.
It is a two-way relationship: to turn the lights off, you just set the bit to 0; if anything changes the value to 1 they go on again.
There is another single bit: Is jack home? (This is not two-way ;-) )
We could say
lights = jack-home
but this would mean that whenever he is home the lights are on, and whenever he isn't home, the lights are off. Upsetting if he wants to sleep.
So we use an event
value-changed(jack-home): lights ← jack-home
This would ensure the lights are on when he arrives home (they may have already been on), and ensures they are off when he leaves.
Since this only happens at events, it allows an override. For instance a switch on the wall also has a bit in the database, and this can be can be bound to the value of the lights:
value-changed(switch): lights ← switch
Note how switches are no longer hard-wired to their function any more.
How do we know if Jack is home?
Well he carries a mobile phone, that connects to the wifi, maybe a bluetooth watch that a sensor can see, and he has a laptop that also connects. These all get recorded in the database (along with other details such as IP address assigned). So we could say
jack-home = jack-phone & jack-watch & jack-laptop
However, sometimes he switches his laptop off. How about:
jack-home = jack-phone or jack-watch or jack-laptop
Well, he might accidently leave his phone at home. Then we use
jack-home = count(jack-phone, jack-watch, jack-laptop) > 1
Jack doesn't live alone though. So there is a bit that records if anyone we know is home:
someone-home = jack-home or jill-home or jim-home
We can let the central heating automatically activate depending on whether someone is home or not:
heating = someone-home
Of course, the required temperature of the heating is also a value in the database, as well as the actual temperature, so unlike the lights example, we don't need an extra override.
None of the data is visible outside the system, unless explicitely revealed to someone.
This allows Jack, should he wish, to expose that he is home, without exposing details such as his phone identity.
For instance, he can reveal to the janitor of the building whether he is home, without revealing any other details, such as his phone MAC address. This means the janitor can't also determine if Jack is at the bar down the road.
Since all actions are now controlled by changing data, all we need is a straightforward way to access and change data.
Luckily we have XForms, which has more or less the same structure as the system: a collection of (XML) data, events, and constraints.
On top of that, XForrms has a method of binding user interface controls to the data for displaying and updating the data.
See for instance the talk "XML Interfaces to the Internet of Things" (and the paper that it is based on, also available in HTML).
Early stages yet.
We have a system that insulates us from the details of the different devices, how to drive them and the format of the data.
It gives us a very simple yet powerful mechanism for reading and controlling devices.
We currently have a system running at two locations.