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

Deja una respuesta

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Salir /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Salir /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Salir /  Cambiar )

Conectando a %s

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.