When I remodeled my home office, I moved the servers into a closet to get them out of the way. That closet can get quite warm, particularly in the summer. To get the heat out and the servers running, I cut a hole into the ceiling of the closet, and added bathroom ceiling fan and exhaust pipe to the outside.
Of course, I don’t want to run that fan all the time; only when it’s needed. So I put it on a relay, driven by another Raspberry Pi, stuck a few 1-wire thermometers through the ceiling, and hooked them up to some extremely trivial code that switches the fan on and off based on simple temperature thresholds. Actually it’s only the thermometer in the closet whose temperature drives the fan; the other thermometers are in adjacent spaces (the office, the hallway) and not really used for anything right now except for fun. It took only a few more minutes to add them, and they are cheap, so I did.
As I’m investigating what Mozilla is up to in their Web-of-Things project, I have been looking for some real-world examples to throw at the architecture, to understand how it applies in the real world. Nothing like the real world to evaluate architectures (mine or other people’s) that look pretty on paper! Well, my attic fan is indeed in the real world, it works and it is mission-critical (well, at least in the summer). Unlike for most other projects I could think of, I have complete control over all the parts (hardware, software, sensors, actuators, networking…) and I don’t need to implement any workarounds like proxying commercial IoT devices so they speak the “proper” protocol. So let’s see where this almost complete greenfield application of the Web-of-Things architecture leads us.
I’m blogging this as I think my way through this. This means I will change my mind every now and then and perhaps rewrite what I wrote earlier. Just to warn you … also, feedback is very much appreciated!
URLs for the thermometers and the fan
The first step, of course, would be to give each of the sensors and actuators — the thermometers and the switch for the fan — a unique URL each. That’s the whole central point of the Web-of-Things architecture! So that’s where we start.
I run my own DNS server on my network, so adding suitable hostnames to the local domain will be easy. My router is a PC with dual Ethernet cards, running UBOS of course, and UBOS network configuration “gateway” sets up a local DNS server automatically, together with firewall, a DHCP server etc. So setting this up was not even complicated. If I have the MAC address of the corresponding network interface, I can even get a consistent IP address for my device(s) simply by editing a file on that router, and restarting dnsmasq.
What URLs should I give those sensors and actuators? Well, they are all wired to the same Raspberry Pi, so I could simply use the hostname of that Pi (it’s already on the network with name attic.aviatis.com — the domain aviatis.com is the domain on my home network). That leads to URLs like the following:
But on second thought, I don’t like this structure. It encodes an implementation detail (that the sensors are connected to the same device in the attic) in their public interface, and that’s just as bad practice in picking URLs as it is in object-oriented (or indeed any kind of) programming. If I were to attach one of the sensors to a different device in the future, or replace it with one that has its own network interface and doesn’t need the Raspberry Pi, the URL would have to change. But then everything that is connected to such a URL would have to be modified to access a different URL. That’s clearly highly undesirable. I shouldn’t have to visit a different URL to search the web just because Google replaced one computer with another. The same idea applies here.
So it appears it makes more sense to assign separate hostnames for each of them, even if those hostnames all resolve to the same Raspberry Pi for the foreseeable future. Which leads to:
This is better. But perhaps still not right: if the number of sensors and actuators in my house keeps growing as all the world’s IoT promoters claim they will, it would probably help to further organize the name space reflecting the structure of the house. That would also help me be certain which sensor or actuator is which, so I don’t accidentially drive the closet fan from a thermometer in a different room. So let’s do this:
Namespace design is work! I feel exhausted already and I haven’t really “done” anything yet. But if experience is any guide in this, this kind of planning activity is really important up-front so I don’t encode wrong assumptions into things (like code) that would be much more expensive to fix later.
What if I didn’t run my own DNS?
But what if I weren’t a geek, and I just want to buy some (so far hypothetical, the tech is too young) Web-of-Things-enabled thermometers at the Home Depot that are supposed to work out of the box with minimal provisioning?
Well, in general it appears that there are two deployment models for this kind of system:
- The gateway-centric model. In this model, the IoT system is managed by a (typically all-seeing, all-knowing) gateway.
- The gateway-free model. In this model, the IoT system has no help from a gateway, and all the devices need to connect to each other peer-to-peer.
In the gateway-centric model, the new thermometer always registers with the gateway (either automatically or manually), and gateway products (like Mozilla’s, or OpenHAB) usually offer the user the ability to name the device, so they can remember which thermometer is which, for example. It would be straighforward for such a gateway to also act as a DNS server that resolves the assigned hostnames according to the names given to the devices by the user. Well, it would be straightforward as long as the IoT gateway is also the network DNS server. Certainly, in my case, the IoT gateway software (should I choose to run some) would run on the UBOS box that acts as my router, so that would be easy. Not so easy if it is a different box.
In the gateway-free model, all we can do is mDNS: devices connecting to the network pick names on their own, while attempting to avoid collisions with other names picked by other devices. (This is why my Apple TV so often comes up as “Apple TV (99)”. No, I don’t own 99 Apple TVs, just one. The oddities of mDNS in practice …) So we might end up with URLs such:
That’s clearly not so great because we don’t know now which thermometer is which. Worse, if some of those temporarily disappear from the network (e.g. because of a tripped circuit breaker) and come back up in a different sequence, they might actually change hostnames from one day to the next! If some of those sensors automatically drive some action, that’d be a fun house to live in :-(
Alternatively we could postulate that the user needs to connect to each device individually, with something like a mobile app, and give it a unique name that the device then needs to use for mDNS. Unfortunately, you can’t implement error checking that way — unless you introduce a central coordinator, but we said we didn’t want a central coordinator like a gateway in this model — and so some hostnames may still conflict and thus “randomly” change when devices follow the mDNS rules to avoid conflicts.
This discussion so far assumes that the devices would all be on the network independently of each other. If the commercial product was like my Raspberry Pi, on the other hand, chances are that it would just advertise the RPi as a whole, such as:
and the URLs for the sensors and actuators would be below that hostname, as in my first version of the URL namespace above. As we have seen there, this is clearly sub-optimal.
Taken all of this together, it appears that we should strongly prefer a gateway-centric model of deployment over a gateway-free one, just based on URL namespace considerations alone.
To be continued …
Now I know the URLs of my sensors and actuator. Next we will ponder what we might want to do with them, and how! To be continued …