In part one of this series, we explored how the Internet of Things (IoT) and Big Data will play a major role in future app development. John Murray and I brainstormed several ideas around how sensor technologies and data collected via mobile applications can have a major effect on the enterprise automotive industry. We also explored why MQTT, the open standards based protocol from IBM, would be the ideal client for building these applications.
So our next job was to implement an MQTT client as a proof of concept for BlackBerry 10 applications. Rather than implement a standalone application, we decided a shared library that could provide an API and be used across multiple applications would be the best approach. We’ll blog about our experience in implementing the MQTT library in a later post, but for now, here’s a glimpse of what the API looks like from the library’s two key header files:
class MqttClient { private: MqttClientImpl *_mqttClientImpl; public: MqttClient(const char *hostName = "localhost", const char *portNumber = "1883"); virtual ~MqttClient(); enum QosLevel {AtMostOnce, AtLeastOnce, ExactlyOnce, Undefined}; void connect(const char *id, const char *willTopic, uint8_t willQos, uint8_t willRetain, const char *willMessage, MqttError &connectError); void connect(const uint8_t *id, ssize_t idLen, const uint8_t *willTopic, ssize_t willTopicLen, uint8_t willQos, uint8_t willRetain, const uint8_t *willMessage, ssize_t willMessageLen, MqttError &connectError); void connect(const char *id, MqttError &connectError); void connect(const uint8_t *id, ssize_t idLen, MqttError &connectError); void disconnect(MqttError &disconnectError); void publish(const char *topic, const char *payload, MqttError &publishError); void publish(const char *topic, const uint8_t *payload, ssize_t plength, MqttError &publishError); void publish(const char *topic, const uint8_t *payload, ssize_t plength, uint8_t retained, MqttError &publishError); void publish(const uint8_t *topic, ssize_t tlength, const uint8_t *payload, ssize_t plength, MqttError &publishError); void publish(const uint8_t *topic, ssize_t tlength, const uint8_t *payload, ssize_t plength, uint8_t retained, MqttError &publishError); void setCallbacks(mqttCallbacks_t callbacks); void subscribe(const char *topic, MqttError &subscribeError); void subscribe(const uint8_t *topic, ssize_t tlength, MqttError &subscribeError); void unSubscribe(const char *topic, MqttError &unSubscribeError); void unSubscribe(const uint8_t *topic, ssize_t tlength, MqttError &unSubscribeError); bool isConnected(); void setHostname(const char *hostName); void setPortNumber(const char *portNumber); void setQos(const QosLevel qos); QosLevel getQos(); void getApiVersion(char *version); }; Figure 1: the MQTT public API methods #ifndef MQTTCALLBACKS_H_ #define MQTTCALLBACKS_H_ #include <stdint.h> #include <sys/types.h> namespace mqtt_client { typedef void (*mqttSubscription_cb) (const uint8_t *topic, ssize_t tlength, const uint8_t *payload, ssize_t length); typedef void (*mqttDisconnected_cb) (); typedef void (*mqttPublish_cb) (const uint8_t *topic, ssize_t tlength, const uint8_t *payload, ssize_t plength, uint8_t retained); typedef void (*mqttPubAck_cb) (uint16_t messageId); typedef void (*mqttPubRec_cb) (uint16_t messageId); typedef void (*mqttPubComp_cb) (uint16_t messageId); typedef void (*mqttSubAck_cb) (uint16_t messageId); typedef void (*mqttUnSubAck_cb) (uint16_t messageId); typedef struct { mqttSubscription_cb subscription; mqttDisconnected_cb disconnected; mqttPublish_cb publish; mqttPubAck_cb puback; mqttPubRec_cb pubrec; mqttPubComp_cb pubcomp; mqttSubAck_cb suback; mqttUnSubAck_cb unsuback; } mqttCallbacks_t; } /* namespace mqtt_client */ #endif /* MQTTCALLBACKS_H_ */
Figure 2: the MQTT call back methods
Having created our API library, the next step was to use it in an application. Initially, we just implemented a test client that allowed us to exercise the main parts of the API. The application is called “TestMqtt,” and it’s available in GitHub. Here are a few screen shots:
Figure 3: TestMqtt on a Q10 device
Next, we looked back at our brainstorm notes with the idea that we could develop a “concept demonstration application” based on our automotive ideas. We decided a quick win would be an application that, amongst other things, processed heart rate measurement data emitted by a Bluetooth Smart heart rate monitor embedded in the driver’s seat, and transmitted it over MQTT to the cloud. If you’ve read any of our previous posts, you may know that John and I already released a Bluetooth Smart heart rate application.
Thinking beyond heart rate data, we decided our “concept demonstration application” should illustrate a variety of other ideas from our brainstorm. We also imagined the application running in an in-car mobile computing device powered by the BlackBerry 10 OS. Data collected from sensors in and around the car and driver would be transmitted over MQTT to the enterprise systems and conversely, the enterprise systems would communicate data such as:
- Geographically relevant data (such as pollen counts)
- Notifications produced through analysis of:
- The vehicle’s transmitted data alone
- Aggregation and analysis of data from all vehicles
- Information derived by augmenting vehicle and driver data with data from other systems, such as driver health records containing allergy information. We could make notifications as relevant as possible to the individual driver and the location of the vehicle.
We then realized that all these ideas would take a little more time than we had available, so we hard coded ideas for the concept application’s UI in all cases except for the heart rate measurement, which is displayed in the top left hand corner of the screen and published over MQTT to an MQTT broker.
Figure 4 shows our automotive IoT concept architecture:
Figure 4 – IoT concept architecture
Neither John nor I would claim to be the world’s greatest UI designers, and we acknowledge that an in-car console such as the one envisaged would need a really well designed UI. However, this is what we came up with and we hope that if nothing else it serves to illustrate the idea:
Figure 5 – the AutomotiveMqttConcept application UI
The UI is divided into three columns with driver information first, then information about driving and driving style, and finally, information about the vehicle including current speed and Bluetooth collected tire pressures, which we could color-code to indicate warning conditions.
If you watch our video presentation on this subject, you’ll see the heart rate data being updated live from a Bluetooth Smart heart monitor:
Integrating the concept application with our MQTT API library was really easy. Here’s the key code that achieved this:
// connect to test.mosquitto.org void HeartMonitor::monitorHeartRate() { ...... if (!_mqttClient->isConnected()) { MqttError connectError(""); _mqttClient->setHostname("test.mosquitto.org"); _mqttClient->connect(QString("MyId-").append(QString::number(qrand() % 30000)).toLatin1().data(), connectError); if (connectError.getCode() == MqttError::PASS_CODE) { qDebug() << "YYYY MQTT Connected OK"; } else { qDebug() << "YYYY MQTT Connection error: " << connectError.getDescription().data(); } } else { qDebug() << "YYYY MQTT Already Connected"; } } void HeartMonitor::logHeartRate(const QVariant &rate) { QMetaObject::invokeMethod(_root, "logHeartRate", Q_ARG(QVariant, rate)); if (_mqttClient->isConnected()) { MqttError publishError(""); _mqttClient->publish("test/hrm/rate", rate.toByteArray().data(), publishError); if (publishError.getCode() == MqttError::PASS_CODE) { qDebug() << "YYYY MQTT Published OK"; } else { qDebug() << "YYYY MQTT Publish error: " << publishError.getDescription().data(); } } }
We hope our article has provided food for thought. Phones are no longer just phones, smart or otherwise, and the era of mobile computing is upon us. Sensors are everywhere, and short-range communications technologies like Bluetooth Smart are making it easy to collect data from sensors. MQTT is well positioned to be the “protocol of choice” for the Internet of Things, and BlackBerry 10 is ready and waiting to form the heart of innovative new systems that blend the personal and mobile computing device with the enterprise, where can derive value Big Data.
Sense. Understand. Adapt
Now go and do that homework!
References
- BlackBerry 10 Bluetooth LE resource index
- BlackBerry NFC resource index
- GitHub Links:
- Wikipedia article on MQ Telemetry Transport
- Technology Review: Car Warns When Your Blood Sugar Is Low
- Mosquitto: An Open Source MQTT v3.1 Broker
- Facebook: Building Facebook Messenger
Footnotes
Martin Woolley and John Murray are members of the OASIS MQTT Technical Committee.