Archivo de la categoría: Node-RED Developer

Ejercicio Node-RED: Reconocimiento de Matrículas

Hacer un sistema de reconocimiento de matrículas con Node-RED usando la API de https://platerecognizer.com/ 

Mandar una foto por diversos medios y obtener la matrícula o matrículas y otros datos que ofrece la API de https://platerecognizer.com/

Es posible montar una instancia on-premise de platerecognizer.com: 

Usar el nodo: https://flows.nodered.org/node/node-red-contrib-plate-recognizer (servicio externo)

Crear un dashboard para cargar, visualizar las imágenes y las matrículas detectadas y controlar las consultas hechas a la API con la versión Free.

Carga de imágenes:

Mostrar resultados:

Resultado de la detección: https://docs.platerecognizer.com/#read-number-plates-from-an-image

  • results/dscore – Confidence level for plate detection.
  • results/score Confidence level for reading the license plate text.

Mostrar en un panel el nº de consultas de mi cuenta este mes en https://platerecognizer.com/ y las que me quedan.

Repositorio con la solución: https://github.com/aprendiendonodered/EJERCICIO32_Reconocimiento_Matriculas 

Anuncio publicitario

Ejercicio Node-RED: Uso de BBDD Locales y Cloud

En una instancia de Node-RED montada como edge que recoge datos por MQTT realizar la siguiente configuración:

  • En una BBDD SQLite guardar los datos de forma local y que se pueda hacer búsqueda de datos rápidamente y compara datos
  • Mandar los datos de series temporales de datos a una BBDD InfluxDB en cloud
  • Mandar los datos de tablas de forma periódica a una BBDD MySQL en cloud

Crear una tabla en SQLite llamada sondas donde se guardarán los datos de las sondas de temperatura. Mantener sólo los datos durante 30 días. Los campos son el nombre del dispositivo y las variables que guarde.

Crear tabla:

CREATE TABLE "sondas" ( "id" INTEGER UNIQUE, "fecha" TEXT, "dispositivo" TEXT, "CPU" REAL,"Temperatura" REAL,"Memoria" INTEGER, PRIMARY KEY("id" AUTOINCREMENT) );

Borrar datos de los últimos 30 días:

DELETE FROM sondas WHERE unixepoch(fecha) < unixepoch('now','-1 months');

Insertar datos:

INSERT INTO "sonda" ("fecha", "raspberry","CPU","Temperatura","Memoria") VALUES (CURRENT_TIMESTAMP, $raspberry, $CPU, $Temperatura, $Memoria);

SQLite date and time functions: https://www.sqlite.org/lang_datefunc.html 

Los datos también se mandarán a una BBDD InfluxDB cloud en enriquecrespo.com

Grabar puntos de la monitorización del curso.

  • Para raspberry pi usar las tags: nombre raspberry pi y nombre de la persona
  • Para los wemos usar las tags: nombre del wemos y nombre de la persona

Ejemplo de punto:

[{"CPU":0.85,"Temperatura":63.4,"Memoria":107},{"raspberry":"raspberrypitt","nombre":"enrique"}]

Repositorio con las soluciones: https://github.com/aprendiendonodered/EJERCICIO31_Uso_BBDD

Ejercicios Finales Node-RED

Ejercicio 1

Hacer un CSV con los datos de temperatura, memoria y CPU que manda vuestra Raspberry PI y guardar en un fichero llamado raspberrypi.csv. Añadir también el campo timestamp al fichero csv.

Para ello tomar los datos publicados en MQTT, ordenarlos y prepararlos para que los pase a un nodo join y los ponga en este orden: timestamp,CPU,Memory,Temperature 

Para que los ordene de forma automática el nodo join debemos hacer uso de la propiedad parts como hace el nodo split usando:

  • parts.index – para el orden de los elementos del grupo a unir
  • parts.id – para indicar que es el mismo grupo
  • parts.count – para indicar el nº de mensajes del grupo

También crear un flujo con un nodo inject que cree el fichero con la cabecera: “timestamp,CPU,Memory,Temperature” y que además al hacerlo vacíe el fichero existente.

Crear otro flujo con un nodo inject que lee con “file in” el contenido del fichero y lo mande a la pantalla de debug.

Luego con un botón del dashboard hacer la parte de inicializar el fichero (que aparezca una notificación del dashboard para confirmar que se desea inicializar) y con otro botón del dashboard un flujo que lea el fichero y lo mande al nodo chart del dashboard y hacer las gráficas.

Opcionalmente, hacer un tercer botón que mande por email el fichero csv, como fichero adjunto.

Opcionalmente, hacer un flujo que lea los datos del fichero llamado raspberrypi.csv y obtener los datos de media, máxima y mínima de la temperatura, memoria y CPU y mostrar en el dashboard en un nodo texto.

Opcionalmente, hacer un flujo que agrupe los datos en grupos de 100 y sacar los datos de media, máxima y mínima cada 100 valores y guardar en otro fichero llamado raspberrypi_agrupados.csv con los campos: timestamp,CPU_AVG,CPU_MAX,CPU_MIN,Memory_AVG,Memory_MAX,Memory_MIN,Temperature_AVG,Temperature_MAX,Temperature_MIN

Mandar datos al nodo chart: https://github.com/node-red/node-red-dashboard/blob/master/Charts.md 

Código: https://github.com/aprendiendonodered/ejercicio10

Ejercicio 2 – Seguridad

Poner un pin para encender los Reles, de forma que si no hay pin no se puede encender desde el dashboard. Simular una cerradura de forma que al poner el pin correcto se abre y luego a los 5 segundos se cierra.

Mostar en el dashboard el estado de la cerradura.

Crear un tab nuevo en el dashboard llamado pin de seguridad

Basarse en el flujo:

Hacer el flujo como un subflow.

Dashboard

Flujo

Subflow

Código:

Ejercicio 3 – Email y SMS

Hacer un formulario en el dashboard para mandar un correo electrónico y otro para mandar un SMS usando el servicio de Twilio: https://www.twilio.com/

Dashboard

Flujo

Código: https://github.com/jecrespo/Curso-Node-RED/blob/master/04-Ejercicio%20Final/Ejercicio_4/Ejercicio_4.json

Luego usar esta configuración para enviar un correo y un SMS cuando se pulse el botón de la Raspberry Pi y el relé del nodo remoto 14 esté encendido, viéndolo en un dashboard.

Ejercicio 4 – Predicción de Lluvia con datos AEMET

Hacer un panel de control que muestre la predicción de lluvia de los próximos 7 días de una ciudad usando los datos de AEMET y su API.

Solución: https://github.com/aprendiendonodered/AEMET_Prediccion_Dias

Además mostrar la predicción de temperatura de los próximos 5 días usado el nodo de open weather map https://flows.nodered.org/node/node-red-node-openweathermap 

Por último publicar todos los datos por MQTT con el topic: “educantabria/nodo00/santander/predicción/[lluvia/santander]/{dia}/{hora}”

Topics publicados:

  • casa/santander/prediccion/lluvia/{dia} – Publica la predicción de lluvia de santander obtenida de AEMET
  • casa/santander/prediccion/temperatura/{dia}/{hora} – Publica la predicción de temperatura de santander obtenida de Open Weather

Creación y Modificación Nodos en Node-RED

Es posible ampliar Node-RED creando nuevos nodos y agregar los nuevos nodos a su paleta. Los nodos se pueden publicar como módulos npm en el repositorio público de npm y agregar a la biblioteca de flujo de Node-RED para que estén disponibles para la comunidad.

Los nodos de Node-RED se empaquetan como módulos y se publican en el repositorio público de npm https://www.npmjs.com/. Una vez publicados en npm, se pueden agregar a la biblioteca de flujo mediante un formulario.

Hay algunos principios generales a seguir al crear nuevos nodos. Estos reflejan el enfoque adoptado por los nodos centrales y ayudan a proporcionar una experiencia de usuario coherente.

Consideraciones Generales

Hay algunos principios generales a seguir al crear nuevos nodos. Estos reflejan el enfoque adoptado por los nodos centrales y ayudan a proporcionar una experiencia de usuario coherente.

Los nodos deben:

  • Estar bien definidos en su propósito. Un nodo que expone todas las opciones posibles de una API es potencialmente menos útil que un grupo de nodos, cada uno de los cuales tiene un único propósito.
  • Ser fácil de usar, independientemente de la funcionalidad subyacente. Ocultar la complejidad.
  • Ser abierto con los tipos de propiedades de mensaje que acepta. Las propiedades de los mensajes pueden ser cadenas, números, valores booleanos, búferes, objetos, matrices o nulos. Un nodo debe hacer lo correcto cuando se enfrenta a cualquiera de estos, evitando ser estricto en el tipo de dato a admitir..
  • Sea consistente en lo que envían. Los nodos deben documentar las propiedades que agregan a los mensajes y deben ser consistentes y predecibles en su comportamiento.
  • Detectar errores. Si un nodo arroja un error no detectado, Node-RED detendrá todo el flujo ya que ya no se conoce el estado del sistema. Siempre que sea posible, los nodos deben detectar errores o registrar controladores de errores para cualquier llamada asincrónica que realicen.

Más información: https://nodered.org/docs/creating-nodes/ 

Crear Primer Nodo

Los nodos se crean cuando se implementa un flujo, pueden enviar y recibir algunos mensajes mientras el flujo se está ejecutando y se eliminan cuando se implementa el siguiente flujo.

Consisten en un par de archivos:

  • un archivo JavaScript que define lo que hace el nodo,
  • un archivo html que define las propiedades del nodo, el diálogo de edición y el texto de ayuda.

Se usa un archivo package.json para empaquetarlo todo junto como un módulo npm.

Este ejemplo mostrará cómo crear un nodo que convierta las cargas útiles de los mensajes a todos los caracteres en minúsculas. Asegúrese de tener la versión LTS actual de Node.js instalada en su sistema.

Crea un directorio donde desarrollarás tu código. Dentro de ese directorio, cree los siguientes archivos:

  • package.json – Un archivo json que npm lo usa para empaquetar. Este es el archivo estándar que utilizan los módulos de node.js para describir el contenido

Este es un archivo estándar utilizado por los módulos de Node.js para describir su contenido. Para generar un archivo package.json estándar, puede usar el comando npm init. Esto hará una serie de preguntas para ayudar a crear el contenido inicial del archivo, utilizando valores predeterminados sensibles cuando sea posible. Cuando se le solicite, asígnele el nombre node-red-contrib-example-lower-case.

Una vez generada, debe agregar una sección de Node-RED. Esto le dice al runtime qué archivos de nodo contiene el módulo:

{
  "name": "red-contrib-example-lower-case",
  "version": "1.0.0",
  "description": "first node example",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "node-red"
  ],
  "author": "jecrespo",
  "license": "ISC",
"node-red" : {
        "nodes": {
            "lower-case": "lower-case.js"
        }
    }
}

Para obtener más información sobre cómo empaquetar su nodo, incluidos los requisitos de nomenclatura y otras propiedades que deben establecerse antes de publicar su nodo, consulte la guía de empaquetado: https://nodered.org/docs/creating-nodes/packaging 

Nota: ¡No publicar este nodo de ejemplo en npm!

  • lower-case.js – Este archivo normalmente contiene una función javascript que tiene la funcionalidad del módulo de nodo. Esto se llama cuando el tiempo de ejecución carga el nodo al iniciarse.

El nodo está empaquetado como un módulo Node.js. El módulo exporta una función que se llama cuando el tiempo de ejecución carga el nodo en el inicio. La función se llama con un solo argumento, RED, que proporciona al módulo acceso a la API de tiempo de ejecución de Node-RED.

El nodo en sí está definido por una función, LowerCaseNode, que se llama cada vez que se crea una nueva instancia del nodo. Se le pasa un objeto config que contiene las propiedades específicas del nodo establecidas en el editor de flujo. La función llama a la función RED.nodes.createNode para inicializar las características compartidas por todos los nodos.

En este caso, el nodo registra un listener en el evento de entrada que se llama cada vez que llega un mensaje al nodo. Dentro de este listener, cambia la carga útil a minúsculas y luego llama a la función de envío para pasar el mensaje en el flujo.

Finalmente, la función LowerCaseNode se registra con el tiempo de ejecución usando el nombre del nodo “lower-case”.

Si el nodo tiene dependencias de módulos externos, deben incluirse en la sección de dependencias de su archivo package.json.

Para obtener más información sobre la parte de tiempo de ejecución del nodo: https://nodered.org/docs/creating-nodes/node-js 

module.exports = function(RED) {
    function LowerCaseNode(config) {
        RED.nodes.createNode(this,config);
        var node = this;
        node.on('input', function(msg) {
            msg.payload = msg.payload.toLowerCase();
            node.send(msg);
        });
    }
    RED.nodes.registerType("lower-case",LowerCaseNode);
}
  • lower-case.html – Este archivo html contiene la definición de nodo principal que está registrada con el editor. También incluye la plantilla que se muestra cuando se configura el nodo. El contenido de la ayuda y las instrucciones sobre las configuraciones necesarias para el nodo también van aquí.

El archivo HTML de un nodo proporciona lo siguiente:

  • la definición de nodo principal que está registrada con el editor
  • la plantilla de edición
  • el texto de ayuda

En este ejemplo, el nodo tiene una única propiedad editable, name. Si bien no es obligatorio, existe una convención ampliamente utilizada para esta propiedad para ayudar a distinguir entre múltiples instancias de un nodo en un solo flujo.

Para obtener más información sobre la parte del editor del nodo, ver https://nodered.org/docs/creating-nodes/node-html

<script type="text/javascript">
    RED.nodes.registerType('lower-case',{
        category: 'function',
        color: '#a6bbcf',
        defaults: {
            name: {value:""}
        },
        inputs:1,
        outputs:1,
        icon: "file.png",
        label: function() {
            return this.name||"lower-case";
        }
    });
</script>

<script type="text/html" data-template-name="lower-case">
    <div class="form-row">
        <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
        <input type="text" id="node-input-name" placeholder="Name">
    </div>
</script>

<script type="text/html" data-help-name="lower-case">
    <p>A simple node that converts the message payloads into all lower-case characters</p>
</script>

Una vez creado, vamos a instalarlo. Una vez que haya creado un módulo de nodo básico, puede instalarlo en su runtime de Node-RED. Para probar un módulo de nodo localmente, se puede usar el comando npm install <carpeta>. Esto le permite desarrollar el nodo en un directorio local y vincularlo a una instalación local de node-red durante el desarrollo.

En su directorio de usuario de node-red, normalmente ~/node-red, ejecutar: npm install ../nr_node_development/node-red-contrib-example-lower-case/

Devuelve:

+ red-contrib-example-lower-case@1.0.0
added 1 package from 1 contributor and audited 675 packages in 7.513s

Esto crea un enlace simbólico al directorio del proyecto del módulo de nodo en ~/.node-red/node_modules para que Node-RED detecte el nodo cuando se inicie. Cualquier cambio en el archivo del nodo se puede recoger simplemente reiniciando Node-RED. 

Reiniciar Node-RED y comprobar que aparece el nuevo nodo: 

Más información: https://nodered.org/docs/creating-nodes/ 

Ejemplo. Basado en el nodo lower-case crear un nodo que cuentes los caracteres de un string llamado “char-count”

Pasos:

  • mkdir node-red-contrib-example-charcount
  • crear package.json – npm init
  • Añadir en package.json:
"node-red" : {
        "nodes": {
            "charcount": "charcount.js"
        }
    }
  • crear el fichero charcount.js
module.exports = function(RED) {
    function CharCountNode(config) {
        RED.nodes.createNode(this,config);
        var node = this;
        node.on('input', function(msg) {
            msg.payload = Number(msg.payload.length);
            node.send(msg);
        });
    }
    RED.nodes.registerType("charcount",CharCountNode);
}
  • Crear el fichero charcount.html
<script type="text/javascript">
    RED.nodes.registerType('charcount',{
        category: 'function',
        color: '#a6bbcf',
        defaults: {
            name: {value:""}
        },
        inputs:1,
        outputs:1,
        icon: "file.png",
        label: function() {
            return this.name||"charcount";
        }
    });
</script>
<script type="text/html" data-template-name="charcount">
    <div class="form-row">
        <label for="node-input-name"><i class="fa fa-tag"></i>Name</label>
        <input type="text" id="node-input-name" placeholder="Name">
    </div>
</script>
<type="text/html" data-help-name="charcount">
    <p>Node to find the number of characters in payload</p>
</script>
  • Ir al directorio de la instancia de Node-RED e instalar con:  npm install ../nr_node_development/node-red-contrib-example-charcount/
  • Reiniciar Node-RED y comprobar que funciona.

Más información:

Crear Nodos a Partir de Subflows

Ahora es posible empaquetar un subflujo como un módulo y publicarlo en npm para que se instale en la paleta como cualquier otro nodo

Los subflujos se pueden empaquetar como módulos npm y distribuirse como cualquier otro nodo. Cuando estén instalados, aparecerán en la paleta como nodos regulares. Los usuarios no pueden ver ni modificar el flujo dentro del subflujo.

En esta etapa, la creación del módulo de subflujo es un proceso manual que requiere la edición manual del subflujo JSON. Se proporcionarán herramientas en el futuro para ayudar a automatizar esto.

Cualquier subflujo se puede empaquetar como un módulo. Antes de hacerlo, debe pensar en cómo se utilizará. La siguiente lista de verificación es un recordatorio útil de las cosas a considerar:

  • Configuración: qué deberá configurar el usuario en el subflujo. Puede definir propiedades de subflujo y qué interfaz de usuario se proporciona para establecer esas propiedades a través del cuadro de diálogo de edición propiedades de subflujo.
  • Manejo de errores: ¿El subflujo maneja los errores correctamente? Algunos errores pueden tener sentido de manejar dentro del subflujo, algunos pueden necesitar ser pasados fuera del subflujo para permitir que el usuario final los maneje.
  • Estado: agregar una salida de estado personalizada a su subflujo que puede manejar el nodo «Estado».
  • Apariencia: dar al subflujo un ícono, color y categoría que tenga sentido para la función que proporciona.

Añadir metadatos al subflujo. El subflujo puede contener metadatos adicionales que se pueden usar para definir el módulo en el que se empaquetará. En el cuadro de diálogo de edición Propiedades del módulo de subflujo, puede establecer las siguientes propiedades:

  • Módulo: el nombre del paquete npm
  • Tipo de nodo: se establecerá de forma predeterminada en la propiedad id del subflujo. Es útil proporcionar un mejor valor de tipo. Como ocurre con los tipos de nodos normales, debe ser único para evitar conflictos con otros nodos.
  • Versión
  • Descripción
  • Licencia
  • Autor
  • Palabras clave

Como ejemplo vamos a crear un nodo basándose en un subflow llamado charcount2 que tiene una entrada y una salida y una función que cuenta caracteres del mensaje entrante:

var newMsg = { "payload": Number(msg.payload.length)};
return newMsg;

Crear el módulo. Este trabajo es manual fuera de Node-RED.

  • crear un directorio con el nombre que quieras darle al módulo. Para este ejemplo, usaremos node-red-example-charcount2.: mkdir node-red-example-charcount2
  • User npm init para crear un archivo package.json. Hará una serie de preguntas coincidentes a los valores agregados a los metadatos del subflujo.
  • Agregar un archivo README.md, ya que todos los módulos buenos deben tener un archivo README.
  • Crear un contenedor de JavaScript para el módulo. Para este ejemplo, usaremos example.js. Esto lee el contenido de un archivo llamado subflow.json, que crearemos luego, lo analiza y luego lo pasa a la función RED.nodes.registerSubflow.
const fs = require("fs");
 const path = require("path");

 module.exports = function(RED) {
     const subflowFile = path.join(__dirname,"subflow.json");
     const subflowContents = fs.readFileSync(subflowFile);
     const subflowJSON = JSON.parse(subflowContents);
     RED.nodes.registerSubflow(subflowJSON);
 }

Añadir el json del subflow. Ahora agregar el subflujo al módulo. Esto requiere una edición cuidadosa del subflujo json. 

  • En el editor Node-RED, agregue una nueva instancia de su subflujo al espacio de trabajo.
  • Con la instancia seleccionada, exporte el nodo (Ctrl-E o Menú-> Exportar) y pegue el JSON en un editor de texto. Los siguientes pasos serán más fáciles si selecciona la opción «formateado» en la pestaña JSON del cuadro de diálogo Exportar.

El JSON está estructurado como un array de objetos de nodo. La última entrada menos una es la definición de subflujo y la última entrada es la instancia de subflujo que agregó al espacio de trabajo.

  • Elimine el nodo de instancia de subflujo, la última entrada en la matriz.
  • Mueva el nodo de definición de subflujo a la parte superior del archivo, encima de la apertura  [ de la matriz
  • Mueva la matriz restante de nodos dentro del nodo de definición de subflujo como una nueva propiedad llamada «flujo».
  • Asegúrese de ordenar las comas finales entre las entradas movidas.
  • Guarde este archivo como subflow.json
{
    "id": "8c0f41ecebfd3445",
    "type": "subflow",
    "name": "charcount2",
    "info": "",
    "category": "",
    "in": [
        {
            "x": 80,
            "y": 40,
            "wires": [
                {
                    "id": "59bf81d1faddd2e9"
                }
            ]
        }
    ],
    "out": [
        {
            "x": 320,
            "y": 40,
            "wires": [
                {
                    "id": "59bf81d1faddd2e9",
                    "port": 0
                }
            ]
        }
    ],
    "env": [],
    "meta": {
        "module": "charcount2",
        "version": "1.0.0",
        "author": "jecrespo",
        "desc": "count char in payload",
        "keywords": "node-red"
    },
    "color": "#DDAA99",
    "flow": [
        {
            "id": "59bf81d1faddd2e9",
            "type": "function",
            "z": "8c0f41ecebfd3445",
            "name": "",
            "func": "var newMsg = { \"payload\": Number(msg.payload.length)};\nreturn newMsg;",
            "outputs": 1,
            "noerr": 0,
            "initialize": "",
            "finalize": "",
            "libs": [],
            "x": 200,
            "y": 40,
            "wires": [
                []
            ]
        }
    ]
}  

Actualizar package.json: La tarea final es actualizar el package.json para que Node-RED sepa qué contiene su módulo. Agrega una sección «node-red», con una sección de «nodes» que contiene una entrada para tu archivo .js:

{
    "name": "node-red-example-subflow",
    ...
    "node-red": {
        "nodes": {
            "charcount2": "example.js"
        }
    }
}

Añadir dependencias: Si el subflujo utiliza nodos no predeterminados, debe asegurarse de que el archivo package.json los enumera como dependencias. Esto asegurará que se instalen junto con su módulo.

Los módulos se enumeran en la sección «dependencies» de nivel superior estándar y una sección «dependencies» en la sección «node-red».

{
    "name": "node-red-example-subflow",
    ...
    "node-red": {
        "nodes": {
            "example-node": "example.js"
        },
        "dependencies": [
            "node-red-node-random"
        ]
    },
    "dependencies": {
        "node-red-node-random": "1.2.3"
    }
}

Una vez que haya creado un módulo de nodo básico, puede instalarlo en su runtime de Node-RED. Para probar un módulo de nodo localmente, se puede usar el comando npm install <carpeta>. Esto le permite desarrollar el nodo en un directorio local y vincularlo a una instalación local de node-red durante el desarrollo.

En su directorio de usuario de node-red, normalmente ~/node-red, ejecutar: npm install ../nr_node_development/node-red-example-charcount2/

Esto crea un enlace simbólico al directorio del proyecto del módulo de nodo en ~/.node-red/node_modules para que Node-RED detecte el nodo cuando se inicie. Cualquier cambio en el archivo del nodo se puede recoger simplemente reiniciando Node-RED. 

Reiniciar Node-RED y comprobar que aparece el nuevo nodo (subflow y nodo): 

Más información: https://nodered.org/docs/creating-nodes/subflow-modules 

Empaquetado de los Módulos

Los nodos se pueden empaquetar como módulos y publicar en el repositorio npm. Esto lo hace fácil de instalar junto con las dependencias que puedan tener.

Si desea usar node-red en el nombre del nodo, use node-red-contrib- como prefijo al nombre para dejar en claro que no son mantenidos por el proyecto Node-RED. Alternativamente, se puede usar cualquier nombre que no use node-red como prefijo.

Esta es la típica estructura de directorios. No hay requisitos estrictos sobre la estructura de directorios utilizada dentro del paquete. Si un paquete contiene varios nodos, todos podrían existir en el mismo directorio o cada uno podría colocarse en su propio subdirectorio.

├── LICENSE
├── README.md
├── package.json
└── sample
    ├── examples
    │   ├── example-1.json
    │   └── example-2.json
    ├── icons
    │   └── my-icon.svg
    ├── sample.html
    └── sample.js

Junto con las entradas habituales, el archivo package.json debe contener una entrada “node-red” que enumere los archivos .js que contienen nodos para que se cargue el tiempo de ejecución. Si tiene varios nodos en un solo archivo, solo tiene que listar el archivo una vez. Si alguno de los nodos tiene dependencias de otros módulos npm, debe incluirse en la propiedad de dependencias.

Para ayudar a que los nodos sean detectables dentro del repositorio npm, el archivo debe incluir node-red en su propiedad de palabras clave. Esto asegurará que el paquete aparezca al buscar por palabra clave.

El archivo README.md debe describir las capacidades del nodo y enumerar los requisitos previos necesarios para que funcione. También puede ser útil incluir cualquier instrucción adicional que no esté incluida en la parte de la pestaña de información del archivo html del nodo, y tal vez incluso un pequeño flujo de ejemplo que demuestre su uso.

Una vez hecho, publicar en npm. Una guía para ello es: https://docs.npmjs.com/cli/v8/using-npm/developers 

Añadir a flows.nodered.org

A partir de abril de 2020, la biblioteca de flujo Node-RED ya no puede indexar y actualizar automáticamente los nodos publicados en npm con la palabra clave node-red. En cambio, una solicitud de envío debe realizarse manualmente.

Para hacerlo, asegúrese de que se cumplan todas os requisitos de packaging. Para agregar un nuevo nodo a la biblioteca, haga clic en el botón + en la parte superior de la página de la biblioteca https://flows.nodered.org/ y seleccione la opción «nodo». Este botón lo lleva a la página Agregar un nodo. Aquí, la lista de requisitos se repite y describe los pasos para agregarla a la biblioteca.

Para actualizar un nodo existente, puede volver a enviarlo de la misma manera que lo haría para un nuevo nodo o solicitar una actualización desde la página del nodo en la biblioteca de flujo a través del enlace «solicitar actualización». Esto solo es visible para los usuarios registrados.
Más información: https://nodered.org/docs/creating-nodes/packaging

Ejercicios Subflows y Funciones Node-RED

Ejercicio 01

Hacer un dashboard para controlar los wemos D1 Mini con el firmware instalado en el curso: https://aprendiendoarduino.wordpress.com/2021/02/20/mqtt-y-esp8266/

El Dashboard tendrá:

  • Un gauge y una gráfica indicando la temperatura de la sonda DS18B20
  • Un pulsador para encender y apagar el led del Wemos D1 Mini
  • Un pulsador para encender y apagar el relé
  • Un Input text o un formulario para mandar mensajes a la pantalla oled
  • Un slider para encender los 8 niveles de la matriz led.

Código: https://github.com/aprendiendonodered/ejercicio11 

Flujo:

Dashboard:

Ejercicio 2

Configura Node-RED para que se vea un dashboard “Home” con tres grupos:

  • Suscripciones: las 3 suscripciones y botón que resete los valores
  • Pulsadores: dos botones para encender led y relé de nodo remoto
  • RPi: un pulsador que maneje el LED de la RPi y un gauge con el estado del pulsador.

Además al pulsar el pulsador encender el led detectando flaco, una pulsación enciende y otra pulsación apaga.

La configuración en Node-RED es:

https://github.com/jecrespo/Curso-Node-RED/blob/master/04-Ejercicio%20Final/Ejercicio_1/Dashboard_1.png?raw=true

Código: https://github.com/jecrespo/Curso-Node-RED/blob/master/04-Ejercicio%20Final/Ejercicio_1/Ejercicio_1-1.json

Código: https://github.com/jecrespo/Curso-Node-RED/blob/master/04-Ejercicio%20Final/Ejercicio_1/Ejercicio_1-2.json

Ejercicio 03

Hacer un subflujo con 5 salidas, que pasándole una variable de entorno con el número de datos a analizar, devuelva la media, máxima y mínima de esos datos por cada salida, una vez retenidos y analizados. En la cuarta salida me devuelva un array de los datos analizados y en la quinta el contador interno.

Personalizar el flujo, añadiendo documentación de lo que hace el subflow y lo que devuelve cada salida.

Código: https://github.com/aprendiendonodered/ejercicio07 

Ejercicio 04

Hacer una función que guarde los últimos 20 valores en una variable de contexto y una vez tenga los 20, mande la media, máximo y mínimo por tres salidas y en una cuarta mande los 20 mensajes que ha retenido de forma consecutiva. En la quinta salida mandar el dato del contador interno.

Una vez hecho, añadir una funcionalidad para que si recibe un mensaje en la propiedad msg.acumulado, tome ese dato como el número de datos a acumular para hacer el cálculo. Una vez llegue este dato, actualiza el acumulado del contador y en función de lo que lleve acumulado, espera hasta llegar al nuevo dato o si lo ha superado, manda lo que ya tiene.

Por último, encapsular esta función en un subflow para poder reutilizarlo.

Añadir dato a un array: https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Array/push 

Función reduce: https://www.w3schools.com/jsref/jsref_reduce.asp 

Función Max: https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Math/max 

Código: https://github.com/aprendiendonodered/ejercicio09