Fundamentos de JavaScript, formato JSON y comunicación entre nodos
Esta presentación introduce los conceptos básicos de Node-RED, incluyendo los fundamentos de JavaScript necesarios, el formato JSON y cómo se comunican los nodos entre sí.
Node-RED es una herramienta visual e intuitiva que permite crear programas o APIs directamente desde el navegador.
Es una plataforma de programación "low-code" que facilita la conexión de dispositivos de hardware, APIs y servicios en línea.
Node-RED consiste en un motor de ejecución al que apunta un navegador web para acceder al editor de flujo.
Dentro del navegador, se crea la aplicación arrastrando los nodos de la paleta a un espacio de trabajo y conectándolos. Con un solo clic, la aplicación se implementa en el motor de ejecución donde se ejecuta.
Los flujos creados en Node-RED se almacenan utilizando JSON, lo que facilita su importación y exportación, así como el control de versiones.
JavaScript es el lenguaje de programación que impulsa Node-RED. Es esencial entender sus conceptos básicos para trabajar eficazmente con Node-RED.
String
: "Hola mundo"Number
: 42, 3.14Boolean
: true, falseObject
: {nombre: "Juan", edad: 30}Array
: [1, 2, 3, 4]null
y undefined
// Variables (pueden cambiar) let contador = 0; contador = contador + 1; // Constantes (no pueden cambiar) const PI = 3.14159;
// Declaración de función function sumar(a, b) { return a + b; } // Función flecha (ES6+) const multiplicar = (a, b) => a * b;
+
, -
, *
, /
, %
==
, ===
, !=
, !==
, <
, >
&&
(AND), ||
(OR), !
(NOT)Los literales de plantilla (template literals) son una característica de ES6 que permite crear cadenas de texto con mayor flexibilidad:
`
) en lugar de comillas${expresión}
// Concatenación tradicional let nombre = "Juan"; let edad = 30; let mensaje = "Hola, soy " + nombre + " y tengo " + edad + " años."; // Con literales de plantilla let mensajeTemplate = `Hola, soy ${nombre} y tengo ${edad} años.`;
// Strings multilínea let html = ` <div class="sensor"> <h2>Sensor de temperatura</h2> <p>Valor: ${temperatura}°C</p> </div> `; // Expresiones en interpolación let umbral = 25; let estado = `Temperatura ${temperatura > umbral ? 'alta' : 'normal'}`; // Uso con objetos let datos = { valor: temperatura, unidad: "C" }; let jsonStr = `{"temperatura": ${datos.valor}, "unidad": "${datos.unidad}"}`;
Los literales de plantilla son especialmente útiles en Node-RED para formatear mensajes, crear contenido dinámico y generar estructuras JSON de manera más legible y mantenible.
Los objetos son colecciones de pares clave-valor:
// Creación de un objeto let persona = { nombre: "María", edad: 28, profesion: "Ingeniera", saludar: function() { return "Hola, soy " + this.nombre; } }; // Acceso a propiedades console.log(persona.nombre); // "María" console.log(persona["profesion"]); // "Ingeniera" // Modificación de propiedades persona.edad = 29;
Los arrays son listas ordenadas de valores:
// Creación de un array let numeros = [1, 2, 3, 4, 5]; let mixto = [1, "dos", true, {clave: "valor"}]; // Acceso a elementos console.log(numeros[0]); // 1 // Métodos comunes de arrays numeros.push(6); // Añade al final numeros.pop(); // Elimina del final // Iteración sobre arrays numeros.forEach(function(numero) { console.log(numero * 2); });
En Node-RED, los mensajes que fluyen entre nodos son objetos JavaScript, generalmente con una propiedad payload
que contiene los datos principales.
En Node-RED, JavaScript se utiliza principalmente en los nodos de función para procesar y transformar mensajes.
// Nodo función para convertir temperatura function procesarMensaje(msg) { // Acceder a la propiedad payload del mensaje let temperatura = msg.payload; // Validar entrada if (typeof temperatura !== 'number') { node.error("El payload debe ser un número", msg); return null; // No envía ningún mensaje } // Transformar el valor (Celsius a Fahrenheit) temperatura = temperatura * 1.8 + 32; // Actualizar el payload y añadir propiedades msg.payload = temperatura; msg.unidad = "Fahrenheit"; msg.timestamp = new Date().toISOString(); // Devolver el mensaje modificado return msg; }
context.get('variable')
, flow.get('variable')
, global.get('variable')
return [msg1, msg2];
node.send(msg);
y return null;
JSON (JavaScript Object Notation) es un formato ligero de intercambio de datos, fácil de leer y escribir para humanos, y sencillo de analizar y generar para las máquinas.
{ "nombre": "Juan", "edad": 30, "activo": true, "intereses": ["programación", "IoT"], "direccion": { "calle": "Calle Principal", "numero": 123, "ciudad": "Madrid" } }
"texto"
42
, 3.14
true
, false
null
{...}
[...]
Aunque JSON está basado en la notación de objetos de JavaScript, existen diferencias importantes:
Característica | JavaScript | JSON |
---|---|---|
Nombres de propiedades | Pueden estar sin comillas | Deben estar entre comillas dobles |
Strings | Comillas simples o dobles | Solo comillas dobles |
Funciones | Permitidas | No permitidas |
Comentarios | Permitidos | No permitidos |
Comas finales | Permitidas | No permitidas |
// Objeto JavaScript a JSON (serialización) let persona = { nombre: "Ana", edad: 28 }; let personaJSON = JSON.stringify(persona); // Resultado: '{"nombre":"Ana","edad":28}' // JSON a objeto JavaScript (deserialización) let personaObjeto = JSON.parse(personaJSON);
Node-RED proporciona un nodo específico para convertir entre cadenas JSON y objetos JavaScript:
Procesamiento de datos de un sensor recibidos por MQTT:
// Datos recibidos como string JSON let mensajeJSON = `{ "dispositivo": "sensor_temp", "ubicacion": "sala", "lecturas": { "temperatura": 23.5, "humedad": 45.2 } }`; // Convertir a objeto JavaScript let datos = JSON.parse(mensajeJSON); // Acceder a propiedades anidadas let temperatura = datos.lecturas.temperatura; let humedad = datos.lecturas.humedad; // Procesar datos let tempF = temperatura * 1.8 + 32;
En Node-RED, los nodos se comunican pasando mensajes de uno a otro a través de sus conexiones.
payload
_msgid
{ "_msgid": "12345abc", "payload": 23.5, "topic": "sensor/temperatura", "timestamp": "2025-04-22T15:30:00Z", "unidad": "C" }
Los mensajes se pasan por referencia, lo que significa que si un nodo modifica una propiedad, todos los nodos posteriores verán esa modificación.
Hay varias formas de modificar mensajes:
function procesarMensaje(msg) { // Leer el payload actual let temperatura = msg.payload; // Crear un nuevo objeto msg.payload = { valor: temperatura, unidad: "C", convertido: temperatura * 1.8 + 32, timestamp: new Date().toISOString() }; return msg; }
// Flujo: [Inject] → [HTTP Request] → [JSON] → [Function] → [Dashboard] → [Debug] // Nodo Function para procesar datos del clima function procesarDatosClima(msg) { let datos = msg.payload; // Extraer solo los datos relevantes msg.payload = { temperatura: datos.main.temp, humedad: datos.main.humidity, presion: datos.main.pressure, ciudad: datos.name, timestamp: new Date().toISOString() }; return msg; }
// Flujo con múltiples caminos a partir de un mensaje // Nodo Function con múltiples salidas function procesarSensor(msg) { let temperatura = msg.payload.temperatura; let humedad = msg.payload.humedad; // Crear mensajes separados para cada valor let msgTemp = { payload: temperatura, tipo: "temperatura" }; let msgHum = { payload: humedad, tipo: "humedad" }; // Enviar a diferentes salidas return [msgTemp, msgHum]; }
let
y const
en lugar de var
¡Gracias por asistir a esta introducción a Node-RED! Recuerda que la mejor manera de aprender es practicando y experimentando con tus propios flujos.