Bluetooth Smart or Bluetooth low energy (BLE) is a welcome addition to the Internet of Things (IoT) world. Devices using this wireless technology only require little power consumption. This means low cost for IoT system operation. In this article, we share our experience in developing IoT applications utilising Bluetooth Smart devices (BLE nodes).
A Bluetooth Smart device like this one, have integrated sensors and actuators, e.g., temperature sensor, LEDs, buttons. Typically, those devices communicate with each other and the Internet via a router or gateway (e.g., a Raspberry Pi). In our example, we use two BLE nodes and a Raspberry Pi as depicted in the following figure.
There are two applications: one runs on BLE nodes and the other is executed on the Raspberry Pi. The code on BLE nodes is generic. That is, the same code is used for all BLE nodes, for any system we want to make. The application that we focus on in this blog post is the one on the Pi. As will be shown later, it contains reusable blocks that correspond to the generic code on BLE nodes and application specific logic.
Since BLE nodes have limited memory and storage, the Constraint Application Protocol (CoAP) is a logical choice. The protocol provides a request/response interaction like HTTP, but simpler and with very low overhead. Sensors and actuators on BLE nodes are simply CoAP resources. The application that runs on the Raspberry Pi obtains current temperature by sending GET requests. To turn on/off or toggle LEDs we use PUT requests. What should we use for buttons? An option is to poll buttons’ state periodically. But, we may miss some button events. We decided to use another approach in which button events are sent as CoAP requests to the application running on the Pi.
The BLE Node Block
In Reactive Blocks, a block representing a BLE node looks like the figure below.
Block CoAP Resource Discovery taken from our CoAP library is used to find out what resources are available in a BLE node. Then, for each resource, an instance block is created depending on the resource type. For example, block Led is instantiated for a LED resource on the BLE. Note the shadow around block Led and the multiplicity [0..*] next to the block title. This is the multi-session feature of Reactive Blocks. Find out more about sessions here.
You might be wondering what is inside the Led block. It encapsulates blocks and code to send PUT requests to turn on/off or toggle a LED on a BLE node. Similarly, block Temperature reports the result of sending GET requests to a BLE node. Block Button sets the address where button events should be sent to by a BLE node. As you can see in the block BLE Node, events are generated for each resource creation and temperature reading. Moreover, the block can also receive events, i.e., commands to manipulate LEDs.
For two BLE nodes, we need two instances of block BLE Node. Yes, you are right. The BLE Node block is also a multi-session block.
The Fire Alarm Example
As an example, we develop a fire alarm application. Imagine that two BLE nodes are installed in two different rooms in a house. When the temperature is too high, the application turns on the fire alarm and switch on LEDs, but only on the corresponding BLE node. A button on the same BLE node is used to reset the alarm. The fire alarm application block is shown in the following figure.
Block BLE Nodes on the bottom-left encapsulates the BLE Node block described in the previous section and a block that receives button events. The rest describes application specific behavior that is based-on events. Actions are taken based on events received from BLE nodes and commands are encapsulated also as events.
The fire alarm example also sends temperature data on one of the BLE nodes via MQTT to AirVantage, a cloud service provider from Sierra Wireless. This was done by simply adding related blocks from our library. Checkout this article. The application can also receive a command to start a fire drill from the cloud. In this case, any button on any BLE node can be used to stop the warning.