Internet of Things devices are valuable because they bring together physical objects, apps, and the cloud. That’s also why they’re extremely difficult to build successfully. All the different pieces of an IoT system have to work seamlessly together, and they have to provide a smooth, successful user experience.
So how do you build each piece so they fit and function smoothly together? You could find several firms that are experts in different areas and give each of them one part of the software ecosystem, then bring those pieces together. But in our experience, that will result in a patched-together system with a lot of gaps and technical debt.
To delivery a successful IoT product (on time, well-functioning, user-friendly, etc.), you need to take a holistic approach to developing the entire system.
The Basic Components of an IoT System
In just about every IoT system, there are three primary components:
- The Device: The physical thing you are selling that your users will connect to the internet and use to collect data or control outputs.
- The User Interface: The mobile app (or other type of application) that will give your users access to the device or the data it produces.
- The Backend Web Service: The link that ties the other two pieces together. It stores account information and is often used as a communication bridge between devices and the user interface.
These components have very different roles and responsibilities in the overall system, but they have one thing in common: They all utilize software.
IoT Is All About Moving Data
When you hear the term IoT, what products come to mind–thermostats, lightbulbs, maybe a controller for your sprinkler system? Many IoT devices aren’t really doing anything all that exciting or new. What makes them desirable is that they provide a remote connection to something that would otherwise be isolated or off-the-grid.
So where is the complexity involved in building these systems? It’s all about fluidly moving data from one place to another.
Let’s consider for a moment the idea of an IoT coffee maker. As I am leaving work one day, I open an app on my phone and press the “Start Brew” button. That action gets translated into a Start-Brew message which gets encrypted (we don’t want anyone else knowing how much coffee we’re drinking) and sent to a web service. The web service decrypts the message, looks up my account information, finds my preferred number of cups, and then sends a message to my coffee pot telling it to start brewing six cups.
However, because I was in a rush this morning, I forgot to add water to the coffee maker. As a result, the coffee maker sends a reply back to the web service containing the Error-No-Water status code. The web service records that this error occurred and then sends a notification to my phone containing the error status and some information about the error. Finally, the app on my phone displays a friendly error message and the address of the nearest Starbucks!
As you can see, one simple instruction, “Start Brew,” resulted in several different messages with different data payloads being packed and unpacked by all three components of the IoT system. As is very often the case, the data itself is not very complex; it’s the process of moving the data fluidly and reliably between the three components of the system that is challenging.
Cohesive IoT Systems Are Holistic
A great deal of coordination is required between all three pieces of this system in order for the “Start Brew” command to to be sent from the user to the device. The steps that I described just begin to scratch the surface of the complexity inherent in a real system of this kind.
That’s why it’s best not to think of the development of each piece as an independent project, but as three parts of one system. The requirements of the system as a whole should be defined to fulfill the external demands of the project (business and end user’s needs), but the implementation of the individual components are dictated by their specific role in that system and by the other components with which they interact.
A useful analogy here is a jigsaw puzzle. Each of the pieces join together to make up a larger picture, but the profile of a single piece directly impacts the profile of the other piece (or pieces) with which it interacts.
The same is true for the different components of an IoT system. If you attempt to develop one piece in isolation from the rest (or with a compromised feedback loop), you end up with gaps that must be filled in. This often manifests as technical debt in the codebase.
Holistic Development with Colocated Teams
IoT projects are all about moving data around, and about having that data be correctly interpreted and handled by each piece of the system. They also involve several different code bases that are constantly changing and interacting with each other in new ways throughout the development process.
Under those circumstances, creating one unified, cohesive product takes a great deal of communication. Each component should be built with a deep understanding of all the others. The whole team should be focused on the high-level requirements of the system, not just one component. And when those requirements change (any they will), each part of the system must be reevaluated and adjusted, so they all continue to work smoothly and efficiently together.
So how do you accomplish this practically? How do you build a complicated IoT system the runs smoothly despite it complexity? With a poly-skilled, co-located team—one team of makers, sitting in the same room and working together to complete all aspects of the project: design, system architecture, embedded development, web and mobile development, server setup and management, etc.
You may have noticed that I haven’t mentioned the custom hardware development or industrial design that is typically involved with building a custom IoT product. That is because the skill-sets that are needed to do those things are very different from the software craft. A good software development firm will be well equipped to work directly with a hardware development firm to handle things like communicating requirements, troubleshooting hardware issues, support for testing, etc.
A Non-Holistic Approach
Some project directors choose to divide the software development across multiple firms. For example, I’ve heard it said that embedded software should be the responsibility of the firm that develops the hardware. The argument is that since the embedded software interacts directly with the hardware, the two are tightly coupled, and thus the development of the two should not be separated across firms. I believe this is a fallacy for two reasons:
- The timelines of the hardware and software projects are very different. Generally, the hardware decisions that directly impact the embedded software are made very early in the process; often in the first rev of the board. Conversely, the mobile and web development projects usually take much longer to complete, and the constraints that they impose on the functionality of the firmware can (and should be able to) change at any point throughout that process.
- As I described above, the embedded software is a crucial component of the larger system, and separating it from the development of the rest of the system precludes the holistic strategy and the benefits that come along with it.
The beauty of the holistic approach is that it allows the implementation of the system to be continuously driven by the high-level requirements of the system. As those requirements begin to be fulfilled or changed, any of the internal pieces can be enhanced so that the end result is as clean and efficient as possible at every level.