We’re researching programming stacks as we develop tools and applications for a smart kitchen
The advent of Bluetooth Low Energy (BLE) devices has allowed for the addition of wireless capability to low-powered devices, and expanding the possibilities for the Internet of Things. Because BLE was part of an update to the Bluetooth Standard in 2011, new code had to be written to support devices that utilized the technology. The Generic Attribute Profile (GATT) specification allows for a standardized method of accessing data from BLE devices, and libraries have been written to support this data collection in various languages. By using this technology, we explored the possibility of creating a “smart” kitchen, such that we could wirelessly receive temperature readings from a variety of Bluetooth thermometers.
What We Did
This project aimed to create a server capable of communicating with BLE devices and running on a Raspberry Pi, by utilizing the GATT interface. Before a fully functional server could be created, however, we had to find a library capable of interfacing with our Bluetooth thermometers. As we discovered, the Bluetooth firmware on the Raspberry Pi was accessible through the D-Bus interface, and so one option was to write our server by accessing the interface directly, using any language of our choosing. Due to the complexities of the raw interface, however, we instead sought a wrapper library to simplify accessing D-Bus.
Our first attempt was with Py-GATT, a Python library specifically designed for accessing BLE devices with GATT. While this library did allow us to connect to the thermometers and obtain temperature readings, it carried the limitation of not allowing both an active connection to the device for temperature readings and also a way to get RSSI values. Although RSSI is not needed for the server to work, it does provide an additional source of information when debugging, and so it was therefore an important feature. As a result of this shortcoming, we moved away from using Py-GATT and searched for an alternative.
The replacement library we found was Noble, a BLE library written for the NodeJS platform. Although it was a challenge keeping track of all of the needed callback functions due to how the library is designed, it did give us the needed ability to get RSSI readings from active BLE connections. This meant that we could proceed with creating the server, and so the next step was writing interfaces for the different thermometers that we had. Because we had different thermometers from different companies, the GATT characteristics for accessing the temperatures were different. As a result, it was important that the interfaces for each of these devices provided identical functionality, even if the underlying designs were different due to the device-specific constraints. Having these identical interfaces allows us to connect and disconnect the thermometers from the server at will, and also extend the server to support other thermometers in the future.
The last piece to the BLE server puzzle was adding MQTT support so that we could send the readings back to a central server for further processing. MQTT is a lightweight messaging protocol, and its design makes it a good choice for IoT device communication. The NodeJS package “mqtt” added the needed protocol support, and it was then just a matter of creating JSON output with the temperature readings and RSSI values we were obtaining.
One challenge with adding multiple-device support was finding a way to get data in the same manner, even if the “trigger” for reading temperature values for each device was different. For example, we have two devices from different manufacturers — the first device has a button that will trigger a temperature reading, while the second device just sends data once per second. The interfaces had to be written in such a way that the trigger mechanisms were preserved, but also so that the server could call the same functions on each device, regardless of how the trigger functioned.
A second challenge was dealing with limited GATT characteristics. While one of our devices had an extensive API that allowed for obtaining almost all possible data about the device, the other thermometer we had did not provide as much information. This made creating a standardized JSON output difficult, because each device had different amounts of information available.
The server currently has support for two different thermometers, and can send data over the MQTT protocol. However, further expansion is possible, by adding support for additional thermometers. Furthermore, because Noble is a generic BLE library, we could also add support for other sensors, and further expand upon the idea of having a “smart” kitchen.