Programación visual con Node-RED: cableado del Internet de las cosas con facilidad

Publicado: 2022-03-11

A través de la programación, hacemos que las máquinas imiten comportamientos complejos siguiendo secuencias de instrucciones simples. El uso de lenguajes de programación textual como Assembly, C, Python y JavaScript es una de las principales formas de hacerlo. Los diseñadores de estos lenguajes de programación han pasado innumerables horas tratando de hacer que la experiencia de escribir programas sea lo más fácil posible a través de una sintaxis expresiva, construcciones de programación sólidas y cadenas de herramientas poderosas. Sin embargo, todos estos lenguajes de programación comparten un rasgo común: el código fuente textual.

Escribir programas en texto funciona, y en la mayoría de los casos funciona bien. Sin embargo, la capacidad de expresar programas visualmente suele ser deseable. Ser capaz de diseñar el flujo de información a través de varios componentes de un sistema más grande suele ser todo lo que se necesita. Las herramientas de programación visual también son indulgentes con cualquiera que sea nuevo en la programación y tenga dificultades para manejar varios conceptos como variables, punteros, señales, ámbitos, etc.

Conecte dispositivos de hardware con API usando Node-RED

Node-RED es una herramienta para programar visualmente. Muestra relaciones y funciones visualmente, y permite al usuario programar sin tener que escribir un idioma. Node-RED es un editor de flujo basado en navegador donde puede agregar o eliminar nodos y conectarlos para que se comuniquen entre sí.

En Node-RED, cada nodo es uno de los siguientes dos tipos: un nodo de inyección o un nodo de función . Los nodos de inyección producen un mensaje sin requerir ninguna entrada y envían el mensaje al siguiente nodo conectado a él. Los nodos de función, por otro lado, toman una entrada y realizan algún trabajo en ella. Con una gran cantidad de estos nodos para elegir, Node-RED hace que conectar dispositivos de hardware, API y servicios en línea sea más fácil que nunca.

Primeros pasos con Node-RED

Node-RED se basa en Node.js. Para instalar Node-RED, deberá tener instalados Node.js y NPM. Con NPM, es muy fácil instalar Node-RED:

 npm install -g node-red

El editor de flujo de Node-RED es una aplicación basada en navegador web. Para poder usarlo, ejecute Node-RED:

 node-red

&hellip y vaya a http://localhost:1880.

¡Hola Mundo!

¿Qué tutorial de programación para principiantes está completo sin aprender a decir "Hola, mundo"? Comencemos probando exactamente eso:

  1. Arrastre y suelte un nodo de inyección en el editor de flujo. Luego haga doble clic y configure la carga útil como una cadena y escriba "Hola mundo".
  2. Arrastre y suelte un nodo de depuración , de la misma manera que lo hizo con el de inyección.
  3. Cablearlos juntos.
  4. Haga clic en el botón "Implementar" en la esquina derecha.
  5. Haga clic en el botón azul justo a la izquierda del nodo de inyección .

Intentalo. Verás algo como esto:

solo JavaScript

Con Node-RED, no está limitado a solo nodos y funcionalidades simples. Como Node-RED se basa en Node.js, todo funciona con JavaScript. Los nodos son, de hecho, módulos de Node.js. Se pueden encontrar en http://flows.nodered.org/, por lo que para agregarlos a su panel izquierdo simplemente puede "instalarlos npm". De hecho, puede desarrollar su propio flujo y cargarlo en el repositorio de flujos. Las aplicaciones pueden ser tan complejas como desee, ya que puede escribir JavaScript en los nodos de función dentro del editor de código que proporciona Node-RED.

Dado que la plataforma se basa en Node.js, aprovecha el mismo modelo sin bloqueo basado en eventos. Por lo tanto, una aplicación creada en Node-RED se puede ejecutar en hardware de bajo costo como Raspberry Pi, así como en la nube.

Now Let's Go Pro: hora de la automatización del hogar

Para demostrar cómo Node-RED encaja en el ámbito de Internet de las cosas, creemos una aplicación para cambiar el color de una bombilla inteligente. Es posible que no todos tengan el mismo sistema de iluminación inteligente a su disposición, pero no hay nada de qué preocuparse, ya que puede encontrar el módulo Node-RED adecuado en el repositorio de flujo oficial. Sin embargo, para hacer las cosas aún más fáciles, optemos por algo más inteligente.

Conoce a Netbeast. Es una plataforma de código abierto para desarrollar aplicaciones para aparatos y dispositivos de Internet de las cosas sin tener que preocuparse por detalles como los protocolos inalámbricos, la compatibilidad de marcas o tener que saber cómo manejar cada API específica que existe. ¡Nos permite utilizar dispositivos virtuales que actúan como reales! Así que aunque no tengas una bombilla inteligente, tienes una virtual disponible.

Podemos instalar el paquete Netbeast para Node-RED npm globalmente así:

 npm install -g node-red-contrib-netbeast

El nodo netbeast-red representará el Tablero de Netbeast, que traducirá sus primitivas de API a todos los dispositivos inteligentes que tenga en casa. ¡Afortunadamente, también está disponible como módulo!

Inicie Netbeast:

 npm install -g netbeast-cli netbeast start

Esto hará que el tablero esté disponible en el puerto 8000 y SSL en el 8443. A continuación, abra su navegador en http://localhost:8000 y navegue hasta Explorar. Allí podremos encontrar gran cantidad de aplicaciones y complementos. Busque las marcas de sus bombillas inteligentes (Philips Hue, LIFX, WeMo) o, si no tiene una, intente descargar el complemento de bombilla. ¡Compruebe que los complementos de su Panel de control contengan uno de estos!

La insignia amarilla indica que los complementos se están ejecutando, pero no pueden encontrar ningún dispositivo. Haga clic en el complemento de la bombilla para crear una bombilla virtual. Cualquier otro dispositivo descubierto debería aparecer en Red.

Con todo en su lugar, volvamos al trabajo. Haremos un flujo simple:

  1. Arrastre y suelte un nodo de inyección.
  2. Arrastre y suelte el nodo Netbeast.
  3. Arrastre y suelte un nodo de depuración.
  4. Conecte todo como se muestra a continuación:

Ahora enviemos una solicitud HTTP al panel. Usando la API de Netbeast, tendremos que enviar a través del nodo de inyección un JSON que contenga los valores que queremos activar en nuestra bombilla.

¡Presiona el botón para inyectar color y energía a todas tus bombillas inteligentes!

Cada tema representa un tipo diferente de dispositivo. Entonces, hay temas para luces, pero también para música, calefacción y video; así como sensores de humedad, presencia, temperatura, y la lista continúa. Puedes encontrar en su documentación una lista de temas y su estructura recomendada para ser traducidos a todo tipo de dispositivos. Este motor de IoT es inmaduro, pero poderoso. Código abierto que permite a los desarrolladores reutilizar la información para crear escenarios verdaderamente conectados, siendo así inteligentes.

Vayamos más profundo

A continuación, crearemos un segundo flujo usando otro complemento, un detector de ruido ambiental, para usarlo como disparador para cambiar el color de la bombilla como un semáforo de ruido. En este tutorial, usaremos uno virtual, por lo que no es necesario comprar hardware nuevo. Comencemos haciendo clic en el botón "más" en el editor de Node-RED.

Vaya de nuevo al Tablero http://localhost:8000/explore a la sección Explorar y busque Volume-Plugin. Es una aplicación web muy rudimentaria que aprovecha getUserMedia() dentro del navegador para capturar medios desde una aplicación HTML simple. ¡Así que probablemente solo funcionará en los navegadores modernos!

Haga clic en él para abrir, como con la bombilla virtual. Le pedirá permiso para grabar desde su micrófono. Luego enviará los mensajes al broker MQTT de Netbeast, que se compartirán en todo el Dashboard, y así podremos suscribirnos. Para hacer tal cosa, solo necesitaremos arrastrar y soltar un nodo netbeast-trigger en el editor de node-red. Luego, insertaremos una función entre el disparador y el nodo Netbeast para decidir cuándo es demasiado alto o no. Además, deberíamos usar algunos nodos de depuración para verificar si todo está bien. El esquema ahora se verá algo así:

Ahora, ingresemos algo de código en el nodo de la función tooLoud. Sí, sé que te prometí que podrías programar sin tener que codificar, ¡pero ya he demostrado que puedes! Y puede intentar combinar los diferentes elementos disponibles u otros nodos del registro para lograr lo siguiente.

 var volume = msg.payload.volume node.log(volume) if (volume < 50) { return { topic: 'lights', payload: { power: 1, color: '#00CC00'}} } else if (volume < 75) { return { topic: 'lights', payload: { power: 1, color: '#CCCC00'}} } else { return { topic: 'lights', payload: { power: 1, color: '#FF0000'}} }

Este fragmento de código bastante simple devuelve una de las tres cargas para el siguiente nodo con un código de color específico, según el nivel de volumen informado por el nodo anterior.

Ahora estamos listos para ir! Presionemos el botón Implementar de nuevo y hagamos algo de ruido. ¡Veamos cómo la bombilla cambia de un color a otro inmediatamente!

Dado que el micrófono y el navegador web que está utilizando pueden ser diferentes, siéntase libre de ajustar los valores y umbrales de la función, y también juegue con los valores de color para ver cómo cambia sus bombillas.

Crear sus propios complementos

Esta bombilla en CSS puro se inspiró en este cssdeck.

Como habrás notado, la bombilla virtual de antes es muy rudimentaria, por lo que es posible que desees modificarla. O incluso mejor, puede crear sus propios controladores inteligentes para el hogar. Así que pasaremos por el proceso de creación de un complemento virtual para Netbeast, que le permitirá crear sus propios controladores para dispositivos inteligentes.

Puede usar el paquete netbeast-cli para generar código automáticamente. Al ejecutar netbeast create myplugin --plugin , terminaríamos con un proyecto básico como el siguiente:

 myplugin ├── README.md ├── index.js ├── package.json └── test.js

La interfaz

Ahora, comencemos a imitar la bombilla con una interfaz. Los controladores de dispositivos generalmente no tendrán uno, por lo que aún no se incluye ninguna carpeta pública en el comando scaffold. Vamos a crear un directorio public dentro del proyecto y colocar allí los siguientes archivos HTML, CSS y JS.

índice.html

 <head> <title>Netbeast Bulb Plugin</title> <link rel="stylesheet" href="bulb.css" media="screen" charset="utf-8"> </head> <body> <div class="top-decoration"></div> <div> </div> <div class="bulb-container small"> <div class="bulb light"> <div> <div class="bulb top"></div> <div class="bulb middle-1"></div> <div class="bulb middle-2"></div> <div class="bulb middle-3"></div> <div class="bulb bottom"></div> </div> <div> <div class="screw-top"></div> <div class="screw a"></div> <div class="screw b"></div> <div class="screw a"></div> <div class="screw b"></div> <div class="screw a"></div> <div class="screw b"></div> <div class="screw c"></div> <div class="screw d"></div> </div> </div> </div> <div class="code-container"> <pre><i class="txt-red">beast</i>(<i class="txt-green">'lights'</i>).<i class="txt-blue">set</i>({ <i class="txt-green">color</i>: <i class="txt-green">"<input type="text" class="color" name="color" value="00fea5">"</i>, <i class="txt-green">power</i>: <i class="txt-green">"<input type="text" class="power" name="power" value="on">"</i> })</pre> <button> RUN </button> </div><!-- wrapper --> <!-- declares bulb features and methods --> <script type="text/javascript" src="bulb.js"></script> <!-- real time comms library --> <script type="text/javascript" src="socketio.js"></script> <!-- simulates hardware communication --> <script type="text/javascript" src="hw-api.js"></script> </body>

bombilla.css

 section { float: left; padding: 20px 50px 20px 50px; } .bulb-light { border: 0; background: transparent; margin: 0 auto !important; padding: 0 !important; display: block; z-index: 1; } #bulb { opacity: 1; z-index: 3; display: block;} .bulb.top { border: 0; width: 300px; height: 300px; margin: 0 auto; padding: 0; border-radius: 999px; background: #E7E7E7; } .bulb.middle-1 { margin: -75px auto 0 auto; width: 190px; border-left: 35px solid transparent; border-right: 35px solid transparent; border-top: 55px solid #E7E7E7; } .bulb.middle-2 { margin: -22px auto 0 auto; width: 178px; border-left: 19px solid transparent; border-right: 19px solid transparent; border-top: 50px solid #E7E7E7; } .bulb.middle-3 { margin: -20px auto 0 auto; width: 182px; border-left: 5px solid transparent; border-right: 5px solid transparent; border-top: 30px solid #E7E7E7; } .bulb.bottom { width: 184px; height: 65px; margin: -8px auto 0 auto; padding: 0; border-radius: 0 0 999px 999px; background: #E7E7E7; } #base { position:relative; z-index: 2; } .screw { transform: rotate(-3deg); -ms-transform: rotate(-3deg); -webkit-transform: rotate(-3deg); padding: 0; } .screw-top { margin: -18px auto -4px auto; padding: 0; width: 132px; height: 0; border-left: 15px solid transparent; border-right: 15px solid transparent; border-top: 21px solid #D3D3D3; border-radius: 999px; } .screw.a { background: #DDD; width: 150px; height: 15px; border-radius: 999px; margin: -1px auto 0px; } .screw.b { background: #D9D9D9; width: 135px; height: 15px; margin: -1px auto 0px; } .screw.c { margin: -1px auto 0px; width: 78px; height: 0; border-left: 30px solid transparent; border-right: 30px solid transparent; border-top: 20px solid #DDD; border-radius: 8px; } .screw.d { margin: 0 auto; width: 15px; height: 0; border-left: 30px solid transparent; border-right: 30px solid transparent; border-top: 15px solid #444; } .on #light { -moz-opacity: 1; -khtml-opacity: 1; opacity: 1; } .bulb.top, .bulb.bottom { transition: all 0.5s ease-in-out; } .bulb.middle-1, .bulb.middle-2, .bulb.middle-3 { transition: all 0.5s ease-in-out; }

Con estos archivos HTML y CSS, ya debería poder ver una forma de bombilla en su navegador. ¡Continúe y abra su archivo HTML para verlo en vivo! ¿Está funcionando? Genial, ahora vamos a darle algo de funcionalidad.

bombilla.js

Este archivo imitará el comportamiento de una bombilla con un simple clic para encender y apagar y configurará un par de funciones que se usarán en un momento para cambiar su color a través de Netbeast.

 var color = document.getElementById('color') var power = document.getElementById('power') var bulb = document.getElementById('bulb') var button = document.getElementById('run-btn') var light = document.getElementById('light') button.onclick = function toggleBulbState () { changeBulbParams({ color: color.value, power: power.value }) } function setBulbParams (params) { if (params.power === 'off') { params = { color: 'E7E7E7' } } console.log('set params', params) var bulb_parts = ['.bulb.middle-1', '.bulb.middle-2', '.bulb.middle-3'] document.querySelector('.bulb.top').style.boxShadow = '0px 0px 98px #' + params.color document.querySelector('.bulb.top').style.backgroundColor = params.color document.querySelector('.bulb.bottom').style.backgroundColor = params.color bulb_parts.forEach(function (className) { document.querySelector(className).style.borderTopColor = params.color }) } function changeBulbParams (params) { console.log('change params', params) /* Overwrite html fields if necessary */ color.value = params.color || color.value power.value = params.power || power.value setBulbParams({color: color.value, power: power.value}) }

Después de esto, los campos y el botón Ejecutar deberían tener sentido. Puede comenzar a probar los diferentes colores en su nueva bombilla virtual. Sin embargo, la razón por la que vinimos hasta aquí fue para convertirlo en otro dispositivo de nuestro ecosistema de Internet de las cosas.

hw-api.js

El último de nuestro JS front-end hecho a sí mismo. Se burla de una conexión inalámbrica con el servidor, como lo haría una bombilla WiFi o Bluetooth con su control remoto, como un teléfono, servidor o concentrador. ¡Es la interfaz que usará el código del complemento real para controlarlo!

 var socket = io.connect() socket.on('connect', function () { console.log('ws:// bulb is online') }) socket.on('disconnect', function () { console.log('ws:// connection with bulb lost') }) socket.on('set', function (params) { changeBulbParams(params) // uses functions from bulb.js! }) socket.on('get', function () { const params = { power: power.value, color: color.value } socket.emit('params', params) })

Finalmente, necesitamos que la biblioteca WebSocket se incluya desde nuestro HTML, para que la interfaz esté lista. Puede copiar la fuente desde https://raw.githubusercontent.com/netbeast/bulb-plugin/master/public/socketio.js y pegarla en un archivo llamado socketio.js . Desde una terminal con curl o wget , puedes hacerlo simplemente:

 curl https://raw.githubusercontent.com/netbeast/bulb-plugin/master/public/socketio.js > public/socketio.js

Tendríamos ahora una estructura de archivos que se parece a esto:

 myplugin ├── README.md ├── index.js ├── package.json ├── public │ ├── bulb.css │ ├── bulb.js │ ├── hw-api.js │ ├── index.html │ └── socketio.js └── test.js

El backend

Ahora vamos a implementar la interfaz con el dispositivo y registrarlo en el motor de Netbeast. Escuchará los websockets para detectar que se ha instalado una bombilla en la red y luego hará un POST a la API del tablero para que los nuevos recursos estén disponibles.

Para eso, echemos un vistazo a los archivos que generamos antes:

paquete.json

Este archivo contiene todas las dependencias y la información necesaria para ejecutar su aplicación. Netbeast también usa el archivo regular package.json para recuperar información, como el nombre o el tipo. ¡Es importante especificar que este paquete es un complemento!

 { "name": "myplugin", "version": "0.0.0", "description": "Netbeast plugin for... <your description>", "main": "index.js", "netbeast": { "bootOnLoad": true, "type": "plugin" }, "dependencies": { "bluebird": "^3.3.5", "body-parser": "^1.15.0", "express": "^4.13.4", "minimist": "^1.2.0", "mocha": "^2.3.2", "morgan": "^1.6.1", "netbeast": "^1.0.6", "socket.io": "^1.4.5", "superagent": "^1.8.3" }, "devDependencies": {}, "scripts": { "test": "node test.js", "start": "node index.js" }, "repository": { "type": "git", "url": "GITHUB_REPOSITORY" }, "keywords": [ "iot", "netbeast", "plugin" ], "author": "YOUR_EMAIL", "license": "GPL 3", "bugs": { "url": "ISSUES_CHANNEL" }, "homepage": "HOMEPAGE" }

índice.js

¡Este es el código que se llama desde el panel de control de Netbeast para iniciar el complemento! Deberá aceptar el puerto mediante argumentos de línea de comando para saber dónde aceptar las solicitudes entrantes. Se iniciará como si node myplugin.js --port <a free port number> . ¡Tenga en cuenta el hashbang al principio también! #!/usr/bin/env node .

 #!/usr/bin/env node var io = require('socket.io')() var express = require('express') var bodyParser = require('body-parser') var app = express() // Netbeast apps need to accept the port to be launched by parameters var argv = require('minimist')(process.argv.slice(2)) app.use(express.static('public')) // will serve our app in an HTTP server app.use(bodyParser.json()) // will parse JSON API calls app.use('/api', require('./plugin')(io)) var server = app.listen(argv.port || 31416, function () { console.log('Bulb plugin listening at http://%s:%s', server.address().address, server.address().port) }) // we need websockets to push updates to browser view io.listen(server)

Como puede ver, nos faltaba un archivo para iniciarlo, el que realmente implementa los controladores socket.io . ¡Nada sofisticado!

plugin.js

 var express = require('express') var netbeast = require('netbeast') var router = express.Router() var bulbParams // auxiliar variable, nasty way to transmit changes, but works module.exports = function (io) { io = io // Create resource that works on lights topic and listens on /api route netbeast('lights').create({ app: 'myplugin', hook: '/api' }) io.on('connection', function () { console.log('ws:// bulb has connected to plugin') }) io.on('disconnection', function () { console.log('ws:// bulb has disconnected from plugin') }) io.on('connect_failure', function (err) { console.trace(err) }) router.post('/', function (req, res) { io.emit('set', { power: req.body.power, color: req.body.color, }) res.status(200).json(req.body) }) router.get('/', function (req, res) { io.emit('get') var timerReference = setTimeout(function () { if (bulbParams) { res.json(bulbParams) } else { res.status(200).json({ error: 'No bulb available' }) } }, 3000) }) return router }

Inicie su aplicación

Ahora es el momento de probar su aplicación. Puede hacerlo empaquetándolo en un formato tar.gz y cargándolo en su tablero en la sección de arrastrar y soltar http://localhost:8000/install.

 beast package # Compresses your app when ran in myplugin dir

¡Voila! Ahora puede ir a sus complementos y probarlo. Vaya a la sección de red (http://localhost:8000/devices) para verlo en ejecución y cambie su color desde allí.

Si algo sale mal o cree que se puede haber perdido un detalle, intente ejecutarlo localmente con node index.js , y tal vez sea más fácil de depurar que dentro del netbeast start .

Publica tu trabajo

Si desea que su aplicación se muestre en la sección Explorar del tablero de Netbeast, debe crear un repositorio en GitHub con la aplicación Netbeast o el complemento de Netbeast, ambos incluidos en la descripción y README.md .

Para encontrar las aplicaciones, utilizamos la API de búsqueda de GitHub. Vemos los mismos resultados que aparecen cuando realiza una solicitud GET a: https://api.github.com/search/repositories?q=netbeast+language:javascript

¡Sabrá que su aplicación se mostrará si aparece allí!

¿Que sigue?

Ambos proyectos son de código abierto y tienen comunidades realmente involucradas. Si desea comenzar a crear sus propios flujos o nodos para Node-RED, eche un vistazo a su documentación oficial. Siga los pasos que se describen allí y debería poder publicar su propio nodo o flujo en poco tiempo.

Por otro lado, si desea sumergirse dentro de Netbeast, también puede seguir su documentación o echar un vistazo al repositorio de Dashboard. Al usar la API de Netbeast, ya no tiene que concentrarse en dispositivos, marcas o tecnologías individuales, así que pruébelo. Puede obtener más información al respecto aquí, o unirse a su canal de Slack y hablar sobre Node-RED, IoT o Node.js.

Si desea instalar estas cosas en un Raspberry Pi, Beagle Bone o un servidor antiguo, ¡los convertiría en un Smart Hub pirateable, sin código! Hay compilaciones prefabricadas para ellos en ambos sitios.

Feliz piratería.

Relacionado: ¿Estamos creando un Internet de las cosas (IoT) inseguro?