An Architecture for Unified Access to the Internet of Things

Jack Jansen, Steven Pemberton, CWI Amsterdam

1957: The first municipal computer (Norwich, UK)

The First Computer in Norwich

Just one of 21 cabinets making up the computer.

2015: The Raspberry Pi Zero

Raspberry Pi in Norwich

The first computer so cheap that they gave it away on the cover of a magazine

Which is faster?

Want to guess which of the two computers is the faster, and by how much?

Which is faster?

The Raspberry Pi is about one million times faster...

If they had run the Elliot 24 hours a day for 10 years, it would have done the amount of computing you can do on a Raspberry Pi Zero in about 5 minutes!

Compare

Elliott 405 Raspberry Pi Zero Factor
Year 1957 2015 58
Price £85K (1957)
(£2M-7M in 2015 money)
£4 ½M-2M
CPU cycle time 10.71-0.918 ms (93-1089 Hz) 1 ns (1 GHz clock) 1M
Main memory 1280 bytes 512 MB ½M
Secondary memory 16 kB drum store 8 GB (typical SD card - not included) ½M
Tertiary memory 1.2MB (300 kword mag film) 1TB (Typical - not included) 1M
Output bandwidth 25 cps 373 MB/s (HDMI) 60MB/s (USB) 2M-10M
Weight 3-6 tons 9 g ½M
Size 21 cabinets x 2m x .77m x .77m 65 x 30 x 5.4mm 2.3M
Median UK wage ~ £250 (men), £125 (women) ~ £30000 (men), £25000 (women) 120-200

(Updated version of this original)

Compare

So the Raspberry Pi is:

A factor of a million million (billion for Europeans, trillion for Anglo-Saxons).

A terabyte is a million million bytes: nowadays we talk in terms of very large numbers.

Want to guess how long a million million seconds is?

A million million seconds

Is 30,000 years...

In other words, a really big number...

Moore's Law

In fact a million million times improvement is about what you would expect from Moore's Law over 58 years.

Except: the Raspberry Pi is a million times smaller as well, so it is much better than even that.

Abstract

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.

Internet of Things

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.

Not new, just Ubiquitous

Twenty years ago a typical petrol station would have had embedded devices in the pumps, the storage tanks, the tills, the vending machines, and these would all have been centrally accessible and controllable.

What is new is the ubiquity, and the diversity.

The P in "IoT" stands for Privacy

And the S stands for security...

IoT is introducing lots of social problems:

Ownership: Who owns the data?

Privacy: Who can see the data?

Control: Who is allowed to do anything with the data?

What we are doing

Creating a system that allows us to

Uses a REST-style declarative interface to access and control the devices with no worry about the variety of device-interfaces and formats.

The Architecture

Architectural elements: repository

XML repository: elements for data, attributes for (system) metadata.

Repository is kept up-to-date with the devices bi-directionally: if the device changes, the repository is updated to match, and if the data in the repository is changed, the device is updated.

For instance: change the data value for the lights from 0 to 1, and the lights go on.

Architectural elements: communication

Thin functional layer around the repository communicates with the devices.

Plug-ins for devices and formats are responsible for knowing how to access the data from the devices:

One or more instances of the database can intercommunicate.

Architectural elements: events

Events can be listened for and reacted to within the repository.

The fundamental event is value changed, which allows event listeners to react.

Other events include timer events, and events signalling changes in the structure of a sub-tree, such as insertions and deletions.

Events bubble, which allows listening at a collection level rather than an individual value level.

Architectural elements: relationships

Constraints and relationships specify how values relate to each other.

Ensures that values that depend on each other are automatically updated (in the process possibly changing the state of the related devices).

REST

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.

System is entirely operated using REST.

(Necessarily simple) Examples

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 ;-) )

Lights!

There are two ways to influence a value in the repository. One is equality "=", which ensures that the equality is always true:

lights = jack-home

However this means 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.

Lights!

The other method is "←". This changes the value only when the value of the expression changes.

lights ← jack-home

This ensures 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:

lights ← switch

Note how switches are no longer hard-wired to their function.

XPath

For the purpose of this talk, we treat jack-home as if it were a single standalone value.

In reality it is part of a structured value, such as

home/people/person[name="Jack"]/present

Dark

You don't want the lights to come on when it is already light, but you can have a sensor that detects whether it is dark or not, with an affiliated bit in the store:

lights ← jack-home & dark

This

Modularity

Note that you could combine the statements into a single one using equality:

lights = (jack-home & dark) or switch

However, the separate statements allow a certain degree of modularity, since, for instance, if you decide to reassign the switch to another purpose, the other statements continue to work.

How do we know if Jack is home?

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

Living together

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.

Lock

One of the devices we have built is a door lock that is openable with any RFID device (a phone, a bank card, a dongle, etc) that has been registered with the lock.

Opening the lock is easy. If you swipe the RFID by the reader, the identification gets stored in the repository at lock/request, so the lock may be opened if that identification is in the list of allowed values:

lock/unlocked ← lock/request in lock/allowed

Relock

There are two options for relocking.

If the lock is intended to be opened, and left open until it is locked again, then you swipe a second time to lock it, and replace the previous statement with:

lock/unlocked ← lock/unlocked xor
        (lock/request in lock/allowed)

Then a swipe just toggles the locked/unlocked state.

The other option is if the lock is opened with a swipe and then locks itself shortly after.

Timed Relock

For timed relocking we use timer events:

lock/unlocked ← lock/request in lock/allowed

changed(lock/unlock):
    dispatch(init, lock, 2sec)

init(lock):
    lock/request ← ""
    lock/unlock ← 0

Here we see a listener for the value-changed event on the lock. This dispatches an init event to the lock after 2 seconds. The listener for the init event relocks the lock.

(We may change how we do timers in the future)

Distributed

There is nothing you can do if there is a powercut and no backup power supply, but you don't want to depend on the wifi to be running, or the domain name server to be up, in order to be able to get in to your house.

Therefore individual devices must have as few dependencies on the general infrastructure as possible.

So our system runs on the local devices as well: several copies of the system distributed, and communicating with each other.

No requirement that a central version of the system is up and running.

Privacy

None of the data is visible outside the system, unless explicitly revealed to someone.

Jack can expose that he is home to someone, without revealing details such as his phone identity.

This means the janitor can't also determine if Jack is at the bar down the road.

Advantages of State

Since the architecture is primarily state-based, with events a side-effect, in effect it is the reverse of IFTTT-style systems that are quite common nowadays for IoT solutions.

Fine-grained access control in an event-based system like IFTTT would be more difficult, because there would basically have to be access rules for every event/trigger.

State-based:

With this system it can be done on the basis of subtrees.

Privacy mechanism

Data is stored in XML elements and attributes are used for system meta-data, part of which is information about access.

Exact mechanism is still being investigated.

Current preference is for Capabilities [CAP], where to access a part of the structure you have to be in possession of a token.

UI

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).

Conclusion

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.

Runs on Raspberry Pi.

It gives us a very simple yet powerful mechanism for reading and controlling devices.

We currently have a system running 24/7 at two locations.

You are welcome to play: https://github.com/cwi-dis/igor