Enviar mensajes device-to-cloud a Azure IoT Hub desde Raspberry usando Node.js y Docker (parte II - envío de mensajes)


Resultado de imagen para docker raspberry nodejs

Nota:

Este post es la continuación de la guía: “Enviar mensajes a Azure IoT Hub desde Raspberry usando Node.js y Docker (parte I – instalación) , favor de realizar primero los paso del post antes de seguir con esta publicación.

Azure IoT Hub nos frece mensajería confiable device-to-cloud y cloud-to-device a gran escala, lo cual nos permite medir de manera inmediata mensajes de telemetría o mensajes personalizados de cada uno de nuestros dispositivos en el mundo, seguro y con alta disponibilidad.

El objetivo de este articulo es mostrar como podemos desarrollar una aplicación de Node.js corriendo dentro de un contenedor de Docker, aislando todo el ambiente en el demonio para luego enviar mensajes a Azure IoT Hub. Esto nos permite agilizar procesos de desarrollo y despliegue a nuestros dispositivos de IoT, minimizando la curva de aprendizaje y facilitando integrar desarrollo de aplicaciones IoT en la cultura de DevOps y el desarrollo ágil.
 

Pre Requisitos

  1. Raspberry Pi2+
  2. Raspbian OS
  3. Conexión a Internet
  4. NPM
  5. Tener una suscripción de Azure

Arquitectura de envío y procesamiento de mensajes Azure IoT Hub:

Azure IoT Hub as cloud gateway in internet of things solution

Fuente: https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-what-is-iot-hub


Descargar código de GitHub:

https://github.com/Kodran/RPi-Docker-Azure-IoTHub


Crear servicio de Azure IoT Hub

Ingresamos a https://portal.azure.com y buscamos por “IoT Hub”.

Para esta demo vamos a elegir una servicio “Free” y elegimos la localización de nuestro recurso en un data center de Azure, recuerda que es recomendable elegir el data center mas cercano a nuestros dispositivos.

Una vez que llenemos toda la información, damos clic en crear y esperamos a que Azure terminé de instalar toda la infraestructura de nuestro nuevo servicio.

1

2

3

Una vez desplegado nuestro servicio de IoT Hub podremos explorar sus propiedades y llaves de conexión al servicio:

4

5

Instalar dependencias y codificar registro de dispositivo

La única manera en que un dispositivo pueda enviar mensajes Azure IoT Hub, es registrando nuestro dispositivo mediante las llaves de conexión que nos ofrece AzurePare registrar un dispositivo primero debemos de instalar la librería de IoT Hub para Node.js en la aplicación, lo cual esto permitirá crear una conexión segura a Azure para el registro y envió de mensajes device-to-cloud a IoT Hub

Instalar azure-iothub:

Devuelta en el ambiente de Raspberry, ingresamos el siguiente comando en la ruta de nuestra aplicación de Node.js:

$ cd projects/azure-iothub-demo/

$ sudo npm install azure-iothub -- save

image

image

Registrar aplicación en Azure IoT Hub:

5

Ahora lo que vamos hacer es remplazar el código que tenemos en nuestra aplicación de Node.js por el siguiente:

app.js

'use strict'; var iothub = require('azure-iothub'); var connectionString = 'your-azure-iothub-primaryKey-connectionString'; var registry = iothub.Registry.fromConnectionString(connectionString); var device = new iothub.Device(null); this.init = function(){ device.deviceId = 'dockerNodejsDevice'; registry.create(device, function(err, deviceInfo, res) { if (err) { registry.get(device.deviceId, printDeviceInfo); } if (deviceInfo) { printDeviceInfo(err, deviceInfo, res) } }); function printDeviceInfo(err, deviceInfo, res) { if (deviceInfo) { console.log('Device ID: ' + deviceInfo.deviceId); console.log('Device key: ' + deviceInfo.authentication.symmetricKey.primaryKey); } } }

this.init();

Lo que hace el código que ingresamos es registrar un dispositivo y desplegar su información en consola, si el dispositivo ya existe únicamente desplegamos su información en consola proveniente de Azure IoT Hub.


Probar registro de dispositivo

Para realizar la prueba de que nuestro dispositivo se puede registrar correctamente en Azure, vamos a correr la aplicación con el siguiente comando:

$ sudo node app.js

image

Ahora comprobamos en el portal de Azure que nuestro dispositivo realmente fue registrado:

image


Instalar dependencias y codificar envío de mensajes a Azure IoT Hub

Para enviar mensajes a IoT Hub se necesita las librerías “azure-iot-device y azure-iot-device-mqtt”.

Ingresamos el siguiente comando para instalar:

$ npm install azure-iot-device azure-iot-device-mqtt --save

image

Envío de mensajes:

Ahora lo que vamos hacer es agregar el siguiente código en nuestra aplicación de Node.js, agregando la llave primaria de conexión de nuestro dispositivo:

app.js

this.sendMessage = function(){ var clientFromConnectionString = require('azure-iot-device-mqtt').clientFromConnectionString; var Message = require('azure-iot-device').Message; var deviceConnectionString = 'yourDevice-primarykey-connectionString; var client = clientFromConnectionString(deviceConnectionString); function printResultFor(op) { return function printResult(err, res) { if (err) console.log(op + ' error: ' + err.toString()); if (res) console.log(op + ' status: ' + res.constructor.name); }; } var connectCallback = function (err) { if (err) { console.log('Could not connect: ' + err); } else { console.log('Client connected'); // Create a message and send it to the IoT Hub every second setInterval(function(){ var data = JSON.stringify({ deviceId: 'dockerNodejsDevice', msg: "Hello azure, i'm a dockerized nodejs app", date: new Date() }); var message = new Message(data); console.log("Sending message: " + message.getData()); client.sendEvent(message, printResultFor('send')); }, 1000); } }; client.open(connectCallback); } this.init(); this.sendMessage();

image

Al final el código de la aplicación debe quedar de la siguiente manera:

app.js

'use strict'; var iothub = require('azure-iothub'); var connectionString = 'your-iothub-primarKey-connectionString'; var registry = iothub.Registry.fromConnectionString(connectionString); var device = new iothub.Device(null); this.init = function(){ device.deviceId = 'dockerNodejsDevice'; registry.create(device, function(err, deviceInfo, res) { if (err) { registry.get(device.deviceId, printDeviceInfo); } if (deviceInfo) { printDeviceInfo(err, deviceInfo, res) } }); function printDeviceInfo(err, deviceInfo, res) { if (deviceInfo) { console.log('Device ID: ' + deviceInfo.deviceId); console.log('Device key: ' + deviceInfo.authentication.symmetricKey.primaryKey); } } } this.sendMessage = function(){ var clientFromConnectionString = require('azure-iot-device-mqtt').clientFromConnectionString; var Message = require('azure-iot-device').Message; var deviceConnectionString = 'your-device-primarKey-connectionString'; var client = clientFromConnectionString(deviceConnectionString); function printResultFor(op) { return function printResult(err, res) { if (err) console.log(op + ' error: ' + err.toString()); if (res) console.log(op + ' status: ' + res.constructor.name); }; } var connectCallback = function (err) { if (err) { console.log('Could not connect: ' + err); } else { console.log('Client connected'); // Create a message and send it to the IoT Hub every second setInterval(function(){ var data = JSON.stringify({ deviceId: 'dockerNodejsDevice', msg: "Hello azure, i'm a dockerazed nodejs app", date: new Date() }); var message = new Message(data); console.log("Sending message: " + message.getData()); client.sendEvent(message, printResultFor('send')); }, 1000); } }; client.open(connectCallback); } this.init(); this.sendMessage();


Probar envío de mensajes:

Para probar el correcto envío de mensajes a Azure IoT Hub, vamos a correr la aplicación:

$ sudo node app.js

image


Crear recibidor de mensajes de IoT Hub

Una vez que hemos logrado enviar mensajes a Azure IoT Hub, podemos crear un programa que reciba estos mensajes y de alguna manera procesarlos. En nuestro caso solo vamos a recibir mensajes  y los desplegaremos en la consola para probar el correcto funcionamiento del servicio de Azure y de nuestra aplicación.

Para dar orden a nuestro entorno, vamos a crear una carpeta llamada “reader” dentro de nuestro proyecto :

$ sudo mkdir reader

$ cd reader

$ sudo npm install azure-event-hubs --save

Ahora creamos una nueva aplicación de Node.js para leer los mensajes de IoT Hub:

package.json

{ "name": "azure-iothub-reader", "version": "1.0.0", "description": "docker nodejs azure iot hub reader", "main": "readIoTHubMessages.js", "scripts": { "start": "node readIoTHubMessages.js" }, "author": "Jorge Castro", "license": "ISC", "dependencies": { "azure-event-hubs": "0.0.8" } }

readerIoTHubMessages.js

'use strict'; var EventHubClient = require('azure-event-hubs').Client; var deviceConnectionString = 'your-iothub-primaryKey-connectionString'; this.init = function(){ var printError = function (err) { console.log(err.message); }; var printMessage = function (message) { console.log('Message received: '); console.log(JSON.stringify(message.body)); console.log(''); }; var client = EventHubClient.fromConnectionString(deviceConnectionString); client.open() .then(client.getPartitionIds.bind(client)) .then(function (partitionIds) { return partitionIds.map(function (partitionId) { return client.createReceiver('$Default', partitionId, { 'startAfterTime' : Date.now()}).then(function(receiver) { console.log('Created partition receiver: ' + partitionId) receiver.on('errorReceived', printError); receiver.on('message', printMessage); }); }); }) .catch(printError); } this.init();


Recibir mensajes de Azure IoT Hub:

Para probar que nuestros mensajes se recibieron en Azure, vamos a correr un programa para recibir estos mensajes para luego desplegarlos en consola:

Correr app.js - envío de mensajes:

$ sudo node app.js

image

Correr readerIoTHubMessages.js – recibidor de mensajes:

$ sudo node readerIoTHubMessages.js

image


Crear contenedores Docker y correr nuestras aplicaciones

Para probar que podemos enviar y recibir mensajes  desde nuestros contenedores, vamos a crear archivos Dockerfile y luego los ejecutaremos con comandos de Docker:

Crear Dockerfile de contenedor de envío de mensajes:

Crear archivo Dockerfile con los siguientes comandos:

$ cd projects/azure-iothub-demo/

Dockerfile

FROM robotany/raspberrypi-nodejs

# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# Install app dependencies
COPY package.json /usr/src/app/
RUN npm install

# Bundle app source
COPY . /usr/src/app

EXPOSE 8080
CMD [ "npm", "start" ]

Crear contenedor de envío de mensajes:

$ cd projects/azure-iothub-demo/

$ sudo docker build –t yourUser/rpi-azure-iothub-sender .

image


Crear Dockerfile de contenedor de recibidor de mensajes:

Crear archivo Dockerfile con los siguientes comandos:

$ cd projects/azure-iothub-demo/reader/

Dockerfile

FROM robotany/raspberrypi-nodejs

# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# Install app dependencies
COPY package.json /usr/src/app/
RUN npm install

# Bundle app source
COPY . /usr/src/app

Crear contenedor para recibir de mensajes:

$ cd projects/azure-iothub-demo/reader/

$ sudo docker build –t yourUser/rpi-azure-iothub-reader .

imageAhora corremos el siguiente comando para ver que nuestros contenedores fueron creados correctamente:

$ sudo docker images

image

Correr contenedor de envío de mensajes:

Para correr nuestro contenedor solo ingresamos el siguiente comando de Docker:

$ sudo docker run yourUser/rpi-azure-iothub-sender

image

Correr contenedor para recibir de mensajes:

Para correr nuestro contenedor solo ingresamos el siguiente comando de Docker:

$ sudo docker run yourUser/rpi-azure-iothub-reader

image


Genial!! hemos logrado enviar y recibir mensajes desde los contenedores de Docker en Raspberry. La conexión a Azure IoT Hub también se puede lograr con programas de .NET Core, Python o Java desde contenedores.

Ahora podemos enviar mensajes de telemetría o enviar mensajes personalizados mas adaptado a flujos de negocio a Azure IoT Hub. Las posibilidades son muchas, y gracias al poder de Azure podemos orquestar nuestros mensajes y extender la funcionalidad de IoT Hub para procesar estos mensajes para propósitos de analítica, predicción, almacenamiento, etc.

Una de las grandes ventajas de Azure IoT Hub es que podemos hacer una comunicación bidireccional entre nuestros dispositivos y la nube, en el siguiente articulo veremos como enviar mensajes desde la nube a nuestro dispositivo Raspberry.


Descargar código de GitHub:

https://github.com/Kodran/RPi-Docker-Azure-IoTHub


Siguientes pasos:

Saludos!

Comments

Popular posts from this blog

Configurar y desplegar una Web API en Azure App Service Environment

Despliegue de contenedores Docker a Azure Web Apps

Patrones de diseño para aplicaciones de alta disponibilidad en Azure - Resilient Applications (Parte I: Retry Policy)

Conectar .NET Web API con Azure API Management

Configurar trigger de Integración Continua en VSTS para ejecutar una tarea de compilación al subir cambios en Source Control