In the second article in this series, we discussed several IoT protocols that might be a good choice to use with Activiti, and put down some questions that should be answered to guide the selection. In this post, we’ll discuss the example use case, get answers to our questions, briefly introduce the hardware (covered in depth later), discuss the protocol stack, and the interaction with our BPM engine.
The Use Case
It’s hard to have a meaningful conversation about the interplay between IoT and Activiti without a concrete example. For the purpose of this series, we’ll look at something basic: A water sensor with an audible / visible alarm, and a remote shutoff valve. The interaction between the components is fairly simple. Water where it shouldn’t be causes an alarm to sound and a message to be sent. This message triggers a remote shutoff valve to turn off, and notifies maintenance that there is a problem. When maintenance accepts the task, the alarm is silenced. Finally, when maintenance completes their task indicating that the leak is fixed, the remote shutoff valve turns the water back on. The shutoff valve also needs to send an acknowledgement that the water is turned back on to complete the process. The messages will originate from Arduino devices, automated and human tasks, and all of the activities will be coordinated by an Activiti process.
This simple example process encompasses both M2M (sensor -> shutoff valve) communication and M2P (sensor -> staff, staff -> shutoff valve) communications. It also requires interaction between the process and IoT devices at multiple levels. Our water sensor needs to be able to start a process instance. Within that instance, we have tasks that need to send messages back to the sensor (to silence its alarm) and tasks that need to send messages to the shutoff valve (to turn the water on / off). Looking back to the last post in this series, we had a few questions that can guide our early design decisions. Now that we have a use case basically defined, we can get some answers:
- Do we just need to start a process, or do we need to be able to interact with tasks as well? – Both, for this case.
- Do we need Activiti to be able to push messages back to our device? – Yes, we do.
- Is there more than one type of device that may interact with a given workflow? – Yes, both water sensors and shutoff valves.
- Is there more than one type of workflow that may be started from a given class of device? – Not at this time.
- What triggers the interaction with the process? Is it a single condition? Is it a pattern? – A single condition will trigger the process start.
- How reliable does this need to be? Is some loss or delay of messages tolerable? – We need a guaranteed message delivery.
Making Some Choices
Based on the answers to the questions above, it’s clear that we need a protocol that can guarantee message delivery and allows easy bidirectional communication between in-flight processes and devices. The hardware in question is going to be a couple Arduinos; one for the sensor/alarm, and one for the valve. The Arduino isn’t the most powerful device so something lightweight is in order. MQTT fits the bill quite nicely. It also helps that there are a few good MQTT client libraries available for the Arduino. In addition to the client, MQTT also requires a broker to manage topics, clients and message delivery. The Eclipse Mosquitto broker supports MQTT 3.1.1, is open source (keeping with the open theme of this project), and is under active development so it makes a good choice. The final piece of the puzzle is missing and needs to be built: We need a link between Activiti and MQTT.
Connecting Activiti and MQTT
There are two components missing from the picture so far. Both depend on having an MQTT client running that is connected to our broker and subscribed to the necessary topics. The first is a component that listens to MQTT for a new message that indicates a water leak. This component also needs to know how to talk to Activiti so it can start a process instance. The second piece is a component that listens for Activiti events that need to be translated into MQTT messages and publishes them to the appropriate topic. For the sake of simplicity, both of these components will be wired into Activiti as Spring beans, taking advantage of the hooks built into Activiti. A bean that uses the process engine configuration hook point will start the connection to the MQTT broker to listen for messages that should start a process or affect tasks in an existing process, and a bean using the process engine event listener hook point will listen for the right Activiti events and pass those back through to the MQTT broker.
The extension described above can be generalized a bit. XMPP and other IoT messaging protocols can be connected in much the same way. It therefore makes sense to build a framework for connecting IoT pub/sub protocols to Activiti instead of just building a single integration for a single protocol. This first example isn’t going that far, but the initial design should keep a framework in mind and once MQTT is working we’ll explore it further.
In the next article in this series we’ll (finally!) show the code, play around with a test MQTT client and see how we can actually start processes from MQTT messages.