IOT experiment part One: Connect to cloud

Imagine you bought an Arduino Kit and successfully gotten “Hello world” projects work, what would happen next? I was on the same foot, and decided to make it more interesting by wiring it up in the connected world. However, it wasn’t not as simple as I expected.
A complete picture would be a multi-directional communication between devices, through the internet. Basically, all I want is having sensors push data to the cloud so that I can visualize my own data, and having detection that can either notify me through application or other smart devices. The architecture should look like this:

With that in mind, this article focuses on one way communication between sensors and application (web), and the next one will be about connected devices. There are a couple challenges I faced doing this, which I will go through each of them now.

I. Requirements
The first objective that came to my mind is able to have multiple sensors measure different things in my home. Even though I live in small apartment, it would be better with wireless network. Also, I want to have some local control over my devices, then later connect to the internet. Finally, I want to be able to view my data in real-time with a web interface. To simplify experiment, the objective is to display my home temperature on the web interface with Highchart.
II. Architecture
Zbee is chosen for local wireless connection as it is easy to use, and I already had a couple zbees at home. The idea is to measure temperature with Arduino, sync data to local hub (Raspi, home server), do some processing and push it to the cloud. MQTT is picked up as messaging system as it is really lightweight, and support sockets communication to used directly on the web or mobile. Because the application is really simple, I use AWS lambda to simplify deployment process. Frontend is built with React + Highchart to support real-time data visualization, and authentication is linked with Auth0.
III. Challenges
1- Zbee connection
I bought Sparkfun S1 Zbee kits which provides basic devices to connect micro-controllers to central hub. If you buy separately, you might need to consider having a Zbee, Zbee shield (with connectors), and a Zbee Explorer to connect to computer. Setting up is quite simple by following this guide, but make sure your program is compatible with Arduino Uno or Arduino Leonardo (in my case), otherwise it won’t work correctly.
Here is a little code that I get data from my temperature sensor, and send it through Zbee.
2- Getting data from Serial Port
XCTU is really handly to explore Zbee, but how can we get the data to application for furthering process? As you might already know, Zbee Explorer uses Serial Communication (so as Blutooth, ect…), so any serial libraries in any language would be sufficient to do the job. To create quick prototype, I use serialport npm package and nodejs to get the data. Zbee explorer is on /dev/ttylUSB0, as I send out data using line seperation, I have a Readline parser to correctly receive the data. Default setting with Baudrate of 9600 and 8bits. One caution, sometime you cannot receive data from Zbee even though you connected to the port. To solve this, need to send some message to establish bidirectional communication.
3- Publish and receive data from cloud
To send data to cloud in short interval, I use MQTT as message protocol, which is provided by AWS IOT by default. To start using MQTT, go to AWS console IOT and create a new thing.

Then just follow the step, we need to download certificate to authenticate our local devices.

Connect with MQTT is really simple, we can use AWS iot sdk to do the job similar to this
4- Visualizing data in real-time
MQTT also support socket connection for web application, which reduce the overhead to wiring websocket to push data on the backend. To achieve this, we need to sign MQTT connection to let client to use the protocol. To do so, I create a simple Lambda function like this:
Then the frontend can call Lambda function to get MQTT signed endpoint. When success, we can receive realtime message from the devices.
There are several libraries that facilitate visualizing the data. In this case, I use Highchart as it provide nice effect, features and easy to use. With data streaming, we only need to call update function on Highchart to show data. Performance is reasonable in my case. To use Highchart with React, create a simple wrapper like this so we can use it in different components.
5- Securing access
If you follow through the process, everyone can access my lambda gateway to get signed MQTT and read data, which is not what we want. To make it more secure, I need a way to authenticate our lambda function. Rather than using AWS Cognito, I took a similar approach using Auth0. However, I had hard time getting a temporary IAM access by exchanging auth token with AWS, so I took a simple version by creating an authentication function and put it as method request inside APIs gateway to validate user. Even though this mechanism is not efficient, it is good enough as we only need to sign MQTT channel once per authentication.
Also, I had to work around to only allow myself to access my IOT endpoint. To achieve this, I add a rule to user_metadata in Auth0 that only I had. I also need to update rule in Auth0 to get user_metadata like this (with auth0-jv v8).
IV. Drawbacks
In the experiment, I only have single micro-controller connect to the hub via Zbee, which is really simple. Imagine if we have multiple connections, how do we authenticate and authorize each devices and recognize the identity of them? Other issue is about detecting anomaly on the edge, and make sure only valid information sent to the server.
It’s also important to provide mechanism that authorizes user to publish/subscribe to their own topic. MQTT provides ways to do this by policies or role. In this case, we use policies base to grant user access to their own devices through topics. However, there is no easy way setup dynamic policies to authorize user to MQTT from external IDP.
This is really simple experiment I did in my spared time. If you have any recommendation or question, I would love to hear. Up next, how to setup Echo to notify events and be responsive!!!
