Desarrolla tu aplicación SCADA basada en Node-RED

                                 

Curso de 8 Capítulos de Contenido General [IS.AC002.GC]

#0 Cómo instalar Node-RED 

Node-RED es una herramienta de programación de código abierto, basado en NodeJS, para desarrollar aplicaciones con el fin de interactuar con diferentes hardware. Además Node-RED proporciona un editor de navegador que facilita la programación y configuración de tus aplicaciones.

Ve más información de Node-RED en la web oficial:

 Sobre Node-RED

El primer paso de este curso será cómo instalar la aplicación Node-RED en tu ordenador. Antes de instalar Node-RED, debemos instalar NodeJS.  

Cómo instalar NodeJS

Solo ve a la web oficial de NodeJS y instala el código fuente de NodeJS o un instalador previo a la compilación para tu sistema operativo:  Download NodeJS  

Si quieres instalarlo desde la línea de comando Linux:   

Añade el depósito:  
sudo apt install curl  

  • Para la última versión, escribe:  

            curl -sL https://deb.nodesource.com/setup_10.x | sudo bash - 

  • Para la versión LTS, escribe:

            curl -sL https://deb.nodesource.com/setup_8.x | sudo bash - 

 Finalmente, para instalar NodeJS escribe: 

  sudo apt install nodejs  

Cómo instalar Node-RED

Después de instalar el NodeJS, nuestro equipo está listo para instalar Node-RED.  La mejor manera de instalar Node-RED es utilizar el gestor de paquetes de Node, npm, que ya viene con Node.js.

  • WINDOWS OS

Escribe el comando prompt:

  npm install -g --unsafe-perm node-red

  • Post de MQTT

Escribe la línea de comando:

sudo npm install -g --unsafe perm node-red

Echa un vistazo a la guía oficial de instalación para saber más detalles:

Instala Node-RED

Una vez tengas instalado Node-RED, podrás continuar con el siguiente capítulo del curso.

Odoo image and text block

Do you want to continue the course?...for free!!!

If you are interested in receive the next chapters for free just fill the form.

You will receive a weekly chapter to develop a NodeRed's Scada Application.

Industrial Applications can run under Open Source Platforms

Send

Cliente MQTT para PLC basado en Arduino como módulo de E/S

En el capítulo #1 se explica cómo configurar tu PLC industrial basado en Arduino como un módulo de E/S MQTT.

Antes de empezar este capítulo sería interesante echar un vistazo a cómo funciona el protocolo MQTT, qué es un JSON y sus aplicaciones. MQ TT protocol works, what is a JSON and their applications. 

Después, echa un vistazo rápido a las siguientes bibliotecas:


La arquitectura del código está hecha para un M-Duino21+, pero está diseñada para ser extendida para otros M-Duinos. Hay cuatro matrices diferentes que incluyen todas las E/S disponibles en M-Duino 21+.an M-Duino 21+ but is designed to be extended for other M-Duino's. There are four different arrays that include all available I/Os in M-Duino 21+. 

Estas matrices son: digitalOutputs , analogOutputs, digitalInputs, analogInputs

Así, cada matriz se estructurará de la siguiente manera:

digitalOutputs[NUM_ZONES][NUM_DIGITAL_OUTPUTS_PER_ZONE] = {{Q0_0, Q0_1... }, {Q1_0, Q1_1...}, {Q2_0, Q2_1...} 

Este último ejemplo será para un M-Duino 58+, cada zona está subdividida con su nomenclatura de pines relacionados.

Después de haber explicado cómo acceder al mapeo de entradas estamos listos para explicar el resto del código.

En la función  setup()  sólo estamos haciendo la inicialización de la Ethernet y del cliente MQTT llamado MQTT, relacionando la función callback cuando recibimos un mensaje a través de MQTT y todos los valores de entrada reales. Después de eso, sólo tenemos tres funciones principales en la función loop(). Estamos llamando a la función reconnect() si no hay conexión con el servidor, si hay una conexión sólo estamos usando la función mqtt.loop() que mantendrá la conectividad con nuestro servidor. Además de estas dos funciones, tenemos la función updateInputs() que actualizará el valor real de las entradas.


Profundicemos en las funciones para tener una mejor comprensión de lo que hacen:

  • GESTIÓN DE SALIDAS:

En primer lugar, tenemos la función reconnect() que se suscribirá a los temas "Q" y "A". Un tema está dedicado a las salidas analógicas y el otro está dedicado a las salidas digitales. Si no se conecta al servidor, entonces se detendrá la conexión del cliente para no causar ningún problema con los puertos del servidor.

Second, to understand how the outputs control works we need to look into the callback function. In this program the callback function is receiveMqttMessage() . The receiveMqttMessage() function will run every time that we receive a message. So, when we receive a message the callback function will decide if the topic is for analog or digital pins and then will call the right function for it, setDigitalOutput() function or setAnalgoOutput() function.

setDigitalOutput ()  extrae y analiza el archivo JSON, confirma que la zona y el pin existen y luego ejecuta la función digitalWrite() para actualizar la salida deseada.

The setAnalogOutput() function work exactly the in the same way that setDigitalOutput()

ANALOG_OUTPUTS_OFFSET es usado para compensar el valor de los pines analógicos. Los pines analógicos se colocan e n  las posiciones 5, 6 ,7. Por eso el ANALOG_OUTPUTS_OFFSET es 5.

  • GESTIÓN DE ENTRADAS:

In the main loop, we have the function updateInputs()that will update all the values of the inputs. This function will be comparing all the previous values to the current ones and if the new value has changed, then the program will publish the new value through MQTT. The digital values will be compering if there is a 0 or a 1, the function that makes this work is updateDigitalInput().

En el sitio analógico el programa comparará si el valor analógico ha cambiado más de 5 puntos si el valor actual es mayor o menor que el anterior, entonces publicará el nuevo valor. La función que hace este trabajo es updateAnalogInput().


/*
   Copyright (c) 2019 Boot&Work Corp., S.L. All rights reserved
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Lesser General Public License for more details.
   You should have received a copy of the GNU Lesser General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

// included library depending of M-Duino version 
#ifdef MDUINO_PLUS
#include <Ethernet2.h>
#else
#include <Ethernet.h>
#endif

// libraries needed for MQTT communication
#include <ArduinoJson.h>
#include <PubSubClient.h>
#define MQTT_ID "demo"
#define NUM_ZONES 1
#define NUM_DIGITAL_OUTPUTS_PER_ZONE 5
#define DIGITAL_OUTPUTS_OFFSET 0

const int digitalOutputs[NUM_ZONES][NUM_DIGITAL_OUTPUTS_PER_ZONE] = {
  {Q0_0, Q0_1, Q0_2, Q0_3, Q0_4},
};
#define NUM_ANALOG_OUTPUTS_PER_ZONE 3
#define ANALOG_OUTPUTS_OFFSET 5

const int analogOutputs[NUM_ZONES][NUM_DIGITAL_OUTPUTS_PER_ZONE] = {
  {A0_5, A0_6, A0_7},
};
#define NUM_DIGITAL_INPUTS_PER_ZONE 7
#define DIGITAL_INPUTS_OFFSET 0

const int digitalInputs[NUM_ZONES][NUM_DIGITAL_INPUTS_PER_ZONE] = {
  {I0_0, I0_1, I0_2, I0_3, I0_4, I0_5, I0_6},
};
#define NUM_ANALOG_INPUTS_PER_ZONE 6
#define ANALOG_INPUTS_OFFSET 7
#define ANALOG_INPUTS_THRESHOLD 5 // Filtering threshold

const int analogInputs[NUM_ZONES][NUM_ANALOG_INPUTS_PER_ZONE] = {
  {I0_7, I0_8, I0_9, I0_10, I0_11, I0_12},
};
byte mac[] = { 0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xAE };
IPAddress broker(10, 0, 3, 21);
unsigned port = 1883;
// Initialize client
EthernetClient client;
PubSubClient mqtt(client);
int digitalInputsValues[NUM_ZONES][NUM_DIGITAL_INPUTS_PER_ZONE];
int analogInputsValues[NUM_ZONES][NUM_ANALOG_INPUTS_PER_ZONE];

////////////////////////////////////////////////////////////////////////////////////////////////////
void setup(){ 
  Ethernet.begin(mac);
  mqtt.setServer(broker, port);
  mqtt.setCallback(receiveMqttMessage);
  // Init variables
  for (int i = 0; i < NUM_ZONES; ++i) {
    for (int j = 0; j < NUM_DIGITAL_INPUTS_PER_ZONE; ++j) {
      digitalInputsValues[i][j] = digitalRead(digitalInputs[i][j]);
    }
    for (int j = 0; j < NUM_ANALOG_INPUTS_PER_ZONE; ++j) {
      analogInputsValues[i][j] = analogRead(analogInputs[i][j]);
    }
  }
}

////////////////////////////////////////////////////////////////////////////////////////////////////
void loop() {
  if (!mqtt.connected()) {
    reconnect();
  } else {
    mqtt.loop();
  }
  updateInputs();
}

////////////////////////////////////////////////////////////////////////////////////////////////////
void updateInputs() {
  for (int i = 0; i < NUM_ZONES; ++i) {
    for (int j = 0; j < NUM_DIGITAL_INPUTS_PER_ZONE; ++j) {
      updateDigitalInput(i, j);
    }
    for (int j = 0; j < NUM_ANALOG_INPUTS_PER_ZONE; ++j) {
      updateAnalogInput(i, j);
    }
  }
}

////////////////////////////////////////////////////////////////////////////////////////////////////
void updateDigitalInput(int zone, int index) {
  int value = digitalRead(digitalInputs[zone][index]);
  if (value != digitalInputsValues[zone][index]) {
    digitalInputsValues[zone][index] = value;
    publishInput(zone, index + DIGITAL_INPUTS_OFFSET, value);
  }
}

////////////////////////////////////////////////////////////////////////////////////////////////////
void updateAnalogInput(int zone, int index) {
  int value = analogRead(analogInputs[zone][index]);
  int minValue = value > ANALOG_INPUTS_THRESHOLD ? value - ANALOG_INPUTS_THRESHOLD : 0;
  int maxValue = value < 1023 - ANALOG_INPUTS_THRESHOLD ? value + ANALOG_INPUTS_THRESHOLD : 1023;
  if ((analogInputsValues[zone][index] < minValue) || (analogInputsValues[zone][index] > maxValue)) {
    analogInputsValues[zone][index] = value;
    publishInput(zone, index + ANALOG_INPUTS_OFFSET, value);
  }
}

////////////////////////////////////////////////////////////////////////////////////////////////////
void setDigitalOutput(char *payload, unsigned int len) {
  DynamicJsonBuffer json(JSON_OBJECT_SIZE(3));
  JsonObject &root = json.parseObject(payload, len);
  if (root.success()) {
    int zone = root["zone"];
    if (zone >= NUM_ZONES) {
      // Invalid zone
      return;
    }
    int index = root["index"];
    index -= DIGITAL_OUTPUTS_OFFSET;
    if (index >= NUM_DIGITAL_OUTPUTS_PER_ZONE) {
      // Invalid digital output
      return;
    }
    int value = root["value"];
    digitalWrite(digitalOutputs[zone][index], value);
  }
}

////////////////////////////////////////////////////////////////////////////////////////////////////
void setAnalogOutput(char *payload, unsigned int len) {
  DynamicJsonBuffer json(JSON_OBJECT_SIZE(3));
  JsonObject &root = json.parseObject(payload, len);
  if (root.success()) {
    int zone = root["zone"];
    if (zone >= NUM_ZONES) {
      // Invalid zone
      return;
    }
    int index = root["index"];
    index -= ANALOG_OUTPUTS_OFFSET; 
    if (index >= NUM_ANALOG_OUTPUTS_PER_ZONE) {
      // Invalid analog output
      return;
    }
    int value = root["value"];
    analogWrite(analogOutputs[zone][index], value);
  }
}

////////////////////////////////////////////////////////////////////////////////////////////////////
void reconnect() {
  if (mqtt.connect(MQTT_ID)) {
    mqtt.subscribe("Q");
    mqtt.subscribe("A");
  } else {
    // MQTT connect fail
    client.stop();
  }
}

////////////////////////////////////////////////////////////////////////////////////////////////////
void receiveMqttMessage(char* topic, byte* payload, unsigned int len) {
  if (strcmp(topic, "Q") == 0) {
    // Set digital output
    setDigitalOutput((char*) payload, len);
  } else if (strcmp(topic, "A") == 0) {
    // Set analog output
    setAnalogOutput((char*) payload, len);
  }
}

////////////////////////////////////////////////////////////////////////////////////////////////////
void publishInput(int zone, int index, int value) {
  DynamicJsonBuffer json(JSON_OBJECT_SIZE(3));
  JsonObject &root = json.createObject();
  if (root.success()) {
    root["zone"] = zone;
    root["index"] = index;
    root["value"] = value;
    publish("I", root);
  }
}

////////////////////////////////////////////////////////////////////////////////////////////////////
void publish(const char *topic, JsonObject &root) {
  unsigned len = root.measureLength();
  if (len > 0) {
    char *payload = new char[len + 1];
    if (payload) {
      root.printTo(payload, len + 1);
      publish(topic, payload);
      delete[] payload;
    }
  }
}

////////////////////////////////////////////////////////////////////////////////////////////////////
void publish(const char *topic, const char *payload) {
  if (mqtt.connected()) {
    mqtt.publish(topic, payload);
  }
}

Cómo visualizar las entradas

En los capítulos anteriores, hemos visto cómo instalar Node-RED en nuestro ordenador y un código útil de Arduino utilizando unidades Industrial Shields. Este código estará relacionado durante todo el curso e iremos interactuando con él para depurar nuestros propios programas.

Así, en el capítulo #2 daremos un paso adelante y veremos cómo visualizar los valores de entrada de nuestro M-Duino en un Dashboard.

El primer paso es instalar la versión estable de Node-RED-Dashboards API. Recuerda que Node-RED-Dashboard requiere que Node-RED esté instalado. Escribiendo en el terminal iremos a nuestro directorio ~/.node-red using:

                            cd .node-red/
                          

Luego teclearemos el comando para instalar Node-RED-Dashboard:

                            npm install node-red-dashboard
                          

Si quieres más información sobre Node-RED-Dashboard echa un vistazo al siguiente enlace:Node-RED-Dashboard

Ejecutando NodeRED

Una vez instalado Node-RED-Dashboard podemos proceder a poner en marcha el primer programa.

First of all, we will learn how to execute the Node-RED and how to change our programs. If you have installed Node-RED you can use the node-red command:

                            node-red
                          
Running Node-RED - Chapter 2 - Develop you SCADA Application based on Node-RED

Después de ejecutar el comando node-red, podemos ir al the localhost:1880/

Escribe localhost:1880/ en tu navegador. Verás la interfaz de usuario de Node-RED donde podremos desarrollar, depurar y modificar nuestros programas.

Node-RED user interface - Chapter 2 - Develop you SCADA Application based on Node-RED

Ahora podemos ver los diferentes bloques de Node-RED en el sitio correcto. Si haces clic en un módulo verás que en la parte izquierda se muestra una documentación de ayuda que te será muy útil para entender el bloque.

Creating our first program

Finally, our first step creating our program:

Elige un blog de entrada MQTT.

Este módulo será nuestro mensaje de entrada MQTT desde el broker MQTT. Haz un doble click y cambia el topic por "I". Este cambio relacionará el blog de entrada con todos los mensajes que recibamos a través del tema "I". En realidad, el bloque se ha suscrito a "I".

Además, debemos cambiar el servidor. Verás que no tienes ningún servidor creado. Cree un nuevo servidor, nómbralo y configúralo de la siguiente manera. Estos serán la dirección IP y el puerto donde se encuentra el broker MQTT. Fíjate en la siguiente imagen. Hemos llamado al servidor "Localhost broker".

Connection - Chapter 2 - Develop you SCADA Application based on Node-RED

Nuestra suscripción MQTT está configurada correctamente.

De este bloque recibiremos una cadena JSON con la siguiente estructura:

                                    "{"zone" = 0, "index" = 0 , "value" = 0 }"
                                  

Trabajar con la cadena no es práctico. Por esta razón, tenemos que convertir esta cadena en un objeto JavaScript. Node-RED tiene un bloque dedicado a hacer este trabajo. Este bloque se llama Json y lo podemos encontrar en los bloques de funciones. Haz doble clic en este bloque. Cambia la acción a "Convertir siempre a objeto JavaScript". Ahora a la salida de este mensaje tendremos el objeto JavaScript y será muy fácil organizar nuestro programa.

Always convert to JavaScript Object - Chapter 2 - Develop your SCADA application based on Node-RED

Después de convertir el mensaje del tema MQTT "I" a JavaScript estamos listos para analizar el objeto y dividirlo en diferentes zonas e índices. En este curso, sólo veremos un ejemplo de M-Duino 21+. Así que tendremos la siguiente estructura de entrada.

ZONE 0

  • INDEX 0 = I0_0

  • INDEX 1 = I0_1

  • INDEX 2 = I0_2

  • INDEX 3 = I0_3

  • INDEX 4 = I0_4

  • INDEX 5 = I0_5

  • INDEX 6 = I0_6

  • INDEX 7 = I0_7

  • INDEX 8 = I0_8

  • INDEX 9 = I0_9

  • INDEX 10 = I0_10

  • INDEX 11 = I0_11

  • INDEX 12 = I0_12

ZONE 1

ZONA 1 (M-Duino 42+, M-Duino 38R, M-Duino 38AR+...):

ZONE 2

ZONA 2 (M-Duino 57R+, M-Duino 58+...)

Echa un vistazo a las entradas del M-Duino 21+, y verás que de I0_7 a I0_12 son entradas analógicas . De hecho, los valores se representarán de forma diferente porque uno es digital y el otro será Analógico (de 0 a 1024). Pero lo veremos más adelante.

M-Duino 21+ Inputs - Chapter 2 - Develop you SCADA Application based on Node-RED

La primera división al objeto será la zona.

Node-RED tiene un bloque llamado switch que nos será muy útil para dividir la información y dirigirla hacia donde queramos. Así, para filtrar la zona añadiremos el switch y con un doble clic cambiaremos la configuración. Añadiremos dos nuevas condiciones y las configuraremos en la siguiente imagen. Añadiendo payload.zone indicaremos con parte del objeto que el switch deberá mirar para clasificar el mensaje.

Zone switch - Edit switch node - Chapter 2 - Develop you SCADA Application based on Node-RED

Tras el primer cambio de zona, procederemos a hacer lo mismo con el índice.

Index switch - Edit switch node - Chapter 2 - Develop you SCADA Application based on Node-RED

Antes de colocar los bloques finales para mostrar los valores en el tablero, necesitamos crear algunos grupos.

En el lado derecho, tenemos tres pestañas diferentes. Uno para ver los mensajes de depuración, otro para información y otro para la distribución de nuestro tablero.

En el lado Layout, hemos distribuido el espacio en tres grupos, entradas digitales y dos para entradas analógicas. Cuando creamos los bloques de tablero adecuados, decidiremos dónde colocar estos bloques en nuestro tablero. Aparte de eso, hay otras configuraciones dentro y pestañas de temas que le darán un aspecto personalizado a nuestro tablero.

Entonces, luego de haber analizado y dividido el mensaje completo, ahora solo nos falta mostrar en nuestro tablero el valor real y actualizado. De hecho, solo necesitamos conectar el bloque de interruptores para entradas digitales y el bloque de indicadores para las entradas analógicas, puedes encontrar estos bloques en el grupo del tablero en el lado izquierdo.

Node-RED también tiene opciones como un gráfico para señales analógicas.

Echa un vistazo a las siguientes imágenes para tener una mejor comprensión.

Inputs Dashboard - Chapter 2 - Develop your SCADA application based on Node-RED

Digital Inputs - Edit switch node - Chapter 2 - Develop your SCADA application based on Node-RED







Analog inputs - Edit gauge node - Chapter 2 - Develop your SCADA application based on Node-RED






Te habrás dado cuenta de que en la última imagen del bloque hemos colocado el bloque msg. Este blog es el bloque de depuración. El bloque de depuración es muy útil para depurar nuestro programa y hacer un seguimiento de cada función para ver cómo fluye el mensaje en nuestro flujo de trabajo.

Finalmente, tenemos nuestra lógica programada y solo necesitamos personalizar nuestro tablero. Configura el diseño, el sitio y el tema para darle el aspecto que quieras a tu tablero. Como ejemplo, mira las siguientes imágenes.

Dashboard Layout - Chapter 2 - Develop your SCADA application based on Node-RED


Dashboard Site - Chapter 2 - Develop your SCADA application based on Node-RED


Dashboard Theme - Chapter 2 - Develop your SCADA application based on Node-RED

Finalmente, el trabajo está hecho. Con el fin de probar nuestro nuevo programa, tendremos al broker mosquito MQTT en nuestro ordenador y conectaremos el M-Duino a la misma red. A continuación, se muestra una imagen de cómo se mostrará el tablero.

Node-RED Dasboard - Chapter 2 - Develop your SCADA application based on Node-RED

Además, tienes un ejemplo de video de cómo verás el tablero en tiempo real mientras cambian los valores de entrada.


 
 

Cómo interactuar con las salidas

En el capítulo #3 se muestra cómo interactuar con nuestras salidas de un PLC Industrial Shields. Antes de comenzar, este capítulo asegura que has logrado los pasos de los capítulos anteriores. Durante el curso iremos aumentando la aplicación Node-RED, por lo que en este ya tenemos las entradas en el dashboard.

Requirements

  • Node-RED y NodeJS instalados y en ejecución

  • Node-RED-Dashboard instalado

  • Broker Mosquitto MQTT instalado y en ejecución

  • PLC con el código del capítulo#1 ejecutándose

Una vez cumplidos los requisitos, comenzaremos a explicar cómo funcionará la arquitectura de la salida.

Outputs Architecture

Como se ha mencionado anteriormente, este curso está diseñado para ser utilizado con una familia de PLC M-Duino. Como ejemplo, usamos un M-Duino 21+.

En nuestro M-Duino 21+ tenemos 8 salidas digitales (de Q0_0 a Q0_7), aparte de eso sabemos que tres de estas salidas digitales pueden funcionar como salidas analógicas. Entonces, en nuestro ejemplo, tendrá 5 salidas digitales (de Q0_0 a Q0_4) y 3 salidas analógicas (de A0_5 a A0_7). Para extender la aplicación Node-RED a más salidas, el procedimiento es exactamente el mismo.

Adding a new tab

Para tener una mejor organización de nuestro dashboard será colocar correctamente una nueva pestaña donde podamos controlar nuestras salidas y no mezclarlas con nuestras entradas. Obviamente este es un ejemplo, en tu aplicación puedes colocar los diferentes componentes en función de tus necesidades.

Entonces, en la primera parte de este capítulo, veremos cómo agregar una nueva pestaña.

Ves a la interfaz de usuario de Node-RED a través de tu navegador. En la parte superior derecha, selecciona el menú y haz clic en flow -> Add a new flow. Luego ves a renombrar un Outputs flow.

Edit flow 4 - Chapter 3 - Develop your SCADA application based on Node-RED

Después de eso, se creará una pestaña automática. En nuestro Diseño, podremos nombrar y agregar los nuevos grupos. Nombra tu nueva pestaña Outputs y agrega dos nuevos grupos, uno llamado Salidas Analógicas y el otro llamado Salidas Digitales.

Dashboard Layout- Chapter 3 - Develop your SCADA application based on Node-RED

 

Ahora estamos listos para agregar los elementos del tablero. Agrega un interruptor y un control deslizante. Haz clic en ellos y nómbralos. Selecciona también el grupo que se colocará, selecciona Salidas Analógicas para el control deslizante y Salidas digitales para el interruptor.

* No olvides agregar el tema en la parte inferior del nodo Editar interruptor. 'A' para Salidas Analógicas y 'Q' para Salidas Digitales.

Topics of Edit Switch - Chapter 3 - Develop your SCADA application based on Node-RED
Digital Inputs - Edit Switch node - Chapter 3 - Develop your SCADA application based on Node-RED
Analog Inputs - Edit Slider node - Chapter 3 - Develop your SCADA application based on Node-RED

Sending the MQTT Message

Desde aquí hemos colocado los elementos en nuestro tablero. Entonces, ahora es el momento de proceder a conectar estos elementos al bróker MQTT, es decir, enviar un mensaje con el tema A y Q.

Primero, es necesario relacionar el interruptor y el control deslizante con el objeto JS correcto. Selecciona la función Change y configúrala de la siguiente manera:

Edit Change node 1 - Chapter 3 - Develop your SCADA application based on Node-RED

* Para cada entrada diferente, debemos establecer el valor del índice. En este caso, es un "0" porque estamos configurando el Q0_0.

La función Change agregará contenido nuevo, ahora tenemos un índice aparte de la carga útil donde tenemos el valor del interruptor o el control deslizante analógico. Además del índice, necesitamos agregar la zona. Entonces, agrega otra función de cambio y agrega el parámetro de zona. Echa un vistazo a la siguiente imagen:

Edit Change node 2 - Chapter 3 - Develop your SCADA application based on Node-RED

* Para cada zona diferente, debemos establecer el valor adecuado de la zona. En este caso, es un "0" porque estamos configurando la zona 0 (entre Q0_0 y A0_7).

Ahora tenemos el objeto JS configurado correctamente. Ahora solo debemos crear el JSON y enviarlo al bróker MQTT. Toma la función json y edítala como "Convertir siempre a cadena JSON". Luego agrega la función de salida MQTT y selecciona el corredor. En nuestro caso, nuestro broker se está ejecutando en nuestro ordenador, por lo que seleccionamos "Broker de localhost".

* Recuerda que hemos agregado el tema a la función de cambio. También podemos definir la función de salida MQTT, pero luego tendremos que crear dos bloques diferentes.

Echa un vistazo al ejemplo de cómo configurar la función json y la función de salida MQTT.

Edit json node - Chapter 3 - Develop your SCADA application based on Node-RED
Edit mqtt out node - Chapter 3 - Develop your SCADA application based on Node-RED

Finalmente, agrega todas las E / S que quieres usar y coloca el interruptor y los controles deslizantes donde quieras.

Nuestro programa Node-RED debería verse como

Node-RED program - Chapter 3 - Develop your SCADA application based on Node-RED
Outputs - Node-RED program - Chapter 3 - Develop your SCADA application based on Node-RED

Cómo configurar tu PLC Industrial Shields a través de MQTT

En el capítulo #4 se explica cómo configurar nuestro PLC. Los PLC de Industrial Shields tienen una EEPROM donde puedes establecer y guardar algunos valores importantes que son muy relevantes para tu aplicación.

En este capítulo, seguiremos una aplicación imaginaria. Imagina un; HVAC (Calefacción, Ventilación y Aire Acondicionado) una aplicación donde tienes un valor de humedad y temperatura que son tu punto de referencia para el sistema. Estos valores deberán estar en tu EEPROM para no perderla durante un corte de energía y cuando el PLC reinicie nuevamente solo tome el último valor de la EEPROM para continuar con su funcionalidad.

Entonces, en el post, aprenderemos cómo usar nuestra EEPROM, cómo enviar desde el Node-RED valores bien interpretados por el PLC y cómo obtener valores correctamente interpretados desde el PLC a la aplicación Node-RED.

Requirements

Los requisitos para este capítulo son:

  • Mosquitto u otro corredor de MQTT en ejecución

  • Node-RED instalado y en ejecución

  • PLC de la familia M-Duino

  • Red Ethernet

  • Arduino IDE instalado con la Librería MQTT adecuada

*Sigue los capítulos anteriores para ver estos pasos.

Empecemos por la parte práctica. Al principio, comenzaremos con la aplicación Node-RED. Nuestra aplicación Node-RED consistirá en un Editar Nodo Numérico donde el usuario podrá introducir el valor deseado de nuestro sistema. Por lo tanto, agrega dos Editar nodo numérico desde las funciones del tablero.

Nuestro rango de temperatura estará entre 15-35ºC (paso 0.1) y nuestra humedad estará entre 0-100% (paso 1).

Edit numeric node 1 - Chapter 4 - Develop your SCADA Application based on Node-RED


Una vez colocados los dos Nodos de edición numéricos, configúralos para que se muestren en la tercera pestaña de nuestro panel de control como una pestaña de configuración.


Configuration Tab - Chapter 4 - Develop your SCADA Application based on Node-RED

Ahora nuestro dashboard se ve bien. Solo atendamos a la lógica de la aplicación. Queremos enviar este valor directamente a nuestro corredor MQTT. Antes de hacer eso tendremos que realizar algunos cambios en esta variable para que sea más fácil entender los datos en nuestro controlador. Todas las variables de Java Scrips son de 64 bits, esto es un problema para nosotros porque Arduino Mega o Leonardo usado en Industrial Shields PLC solo usan como máximo aceptado de 32 bits.

Para cambiar este valor, tendremos que crear una nueva función en nuestro flujo de trabajo Node-RED.

Agrega una función vacía y configurada de la siguiente manera:

Edit function node 1 - Chapter 4 - Develop your SCADA Application on Node-RED

La función Buffer.allocUnsafe () devuelve un nuevo buffer no inicializado del tamaño especificado. En nuestro caso queremos un buffer de 4 bytes, echa un vistazo a este enlace para saber más sobre las Librerías NodeJS.  NodeJS buffer information

Una vez que se inicializa el buffer podemos proceder a transformar nuestro valor en un int32_t little endian ya que nuestro controlador puede leer con cualquier problema. Para hacer eso, estamos usando la función writeInt32LE (valor, compensación). Lee más sobre esto en: Buffer WriteInt32 function

Para darle más resolución a nuestro sistema hemos decidido multiplicar el valor de temperatura por 10 con el fin de tratar con números centenarios en nuestro PLC o controlador. Así que agrega una función corta como esa:

Edit function node 2 - Chapter 4 - Develop your SCADA Application on Node-RED

Después de eso, nuestro valor está listo para ser enviado. Agrega la función de envío MQTT con el tema deseado. Por el momento, nuestro flujo de trabajo se verá así:

Workflow shall 1 - Chapter 4 - Develop your SCADA Application on Node-RED

Edit mqtt out node - Chapter 4 - Develop your SCADA Application on Node-RED

La mitad del Node-Red está lista. Como ya sabes, los nodos Node-RED se activan cuando el nodo sufre un cambio, entonces imagina que por alguna razón tienes un corte de energía en tu sistema, el PLC estará funcionando como se esperaba porque tiene el valor configurado en su EEPROM, pero el sistema lo hará. No sé en qué valor está funcionando el PLC. Para solucionar este problema enviaremos a través del mismo tema el valor configurado guardado en la EEPROM del PLC cuando el PLC reinicie su funcionalidad.

Cómo relacionamos esto con nuestra edición de nodo numérico. Es igual que antes pero al revés.

Agrega una función de recepción MQTT, suscríbete al mismo tema y luego agrega una función editable adicional. Configura la función de la siguiente manera:

Edit function node 3 - Chapter 4 - Develop your SCADA Application on Node-RED

Como puedes ver, solo usamos una función aquí. Echa un vistazo a los enlaces anteriores de NodeJS para ver cómo funciona esta función. Básicamente, la función leerá un valor de 32 bits en little endian y lo cambiará por un valor de Java Script. El valor se trata adecuadamente para nuestra aplicación Node-RED. Simplemente agrega una nueva función para dividir el valor de temperatura entre 10.

Nuestro workflow se verá así:

Edit function node 4 - Chapter 4 - Develop your SCADA Application on Node-RED
Workflow shall 2 - How to configure your Industrial Shields PLC through MQTT

Software de PLC

Siguiendo la aplicación Node-RED, necesitaremos un controlador que pueda interactuar con él. En esta segunda parte del capítulo, se muestra un código de ejemplo. El código es un ejemplo simple de cómo usar nuestra EEPROM, estructuras y protocolo de comunicación MQTT.

En nuestro PLC basado en Arduino, tendremos una estructura compuesta por dos int32_t, uno para temperatura y otro para humedad. Estos valores serán valores del sistema para establecer el comportamiento del sistema.

//Configuration structure
typedef struct {
  int32_t temperature;
  int32_t humidity; 
} actualConfig_t; 

actualConfig_t actualConfig;

Para obtener y poner valores en la EEPROM, usaremos la biblioteca EEPROM.h. El código usa dos funciones principales de esta biblioteca, una es EEPROM.get (eaddress, variable); para obtener valores y EEPROM.put (dirección, variable; a valores seguros.


La otra parte del código, que es muy importante, es cómo leer los valores del MQTT. Para hacer eso usamos la función setCallBack.

mqtt.setCallback(receiveMqttMsg);
TEsta función será llamada cada vez que recibamos un mensaje MQTT.
 
void receiveMqttMsg(char* topic, uint8_t* payload, unsigned int len){
    if (strcmp(topic, "configTemp") == 0){
        //Set config to variable 
        memcpy(&actualConfig.temperature, payload, len);
        //Print to debug
        Serial.print("Temperature set to: ");
        Serial.println(actualConfig.temperature);
        //Set config to EEPROM
        EEPROM.put(eeAdressTEMP, actualConfig.temperature);
    }
    if (strcmp(topic, "configHum") == 0){
        //Set config to EEPROM
        memcpy(&actualConfig.humidity, payload, len);
        //Print to debug
        Serial.print("Humidity set to: ");
        Serial.println(actualConfig.humidity);
        //Set config to EPROM
        EEPROM.put(eeAdressHUM, actualConfig.humidity);
    }
}

Esta función comparará el tema para saber si el valor está usando temperatura o humedad:  strcmp(topic, "configTemp") == 0
Luego usará memcpy (&address, data, datalen) para almacenar los datos de la función callBack de MQTT en nuestra variable de trabajo. Si en la aplicación NodeRED no modificamos los datos, este proceso será mucho más complicado. Ahora tenemos un dato little endian int32_t, que son muy fáciles de tratar.

Una vez que los datos están en nuestra RAM es muy fácil almacenar información en la EEPROM simplemente usando la función EEPROM.put().

Aparte del código se crea una función de depuración que puedes utilizar para conocer el estado de las variables durante el flujo de trabajo. 

A continuación se muestra el código completo:

////////////////////////////////////////////////////////////////////////////////////////////////////
//Configuration structure
typedef struct {
  int32_t temperature;
  int32_t humidity; 
} actualConfig_t; 

#define MQTT_ID "demo"

//including library for MQTT
#include <PubSubClient.h>

//including EEPROM library
#include <EEPROM.h>
//including Ethernet library depending of M-Duino version 
#ifdef MDUINO_PLUS
#include <Ethernet2.h>
#else
#include <Ethernet.h>
#endif

actualConfig_t actualConfig;
const byte eeAdressTEMP = 0;
const byte eeAdressHUM = 4;
byte mac[] = { 0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xAE };
IPAddress ip(10, 10, 11, 2);
IPAddress broker(10, 10, 11, 1);
unsigned port = 1883;
EthernetClient ethClient;
PubSubClient mqtt(ethClient);

void setup(){
    Serial.begin(9600); 
    //Set up Ethernet
    Ethernet.begin(mac, ip);
    Serial.print("Local IP: ");
    Serial.println(Ethernet.localIP());
    //Set up MQTT 
    mqtt.setServer(broker, port);
    mqtt.setCallback(receiveMqttMsg);
    updateFromEEPROM();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void loop(){
    if (!mqtt.connected()){
        reconnect();
        if (mqtt.connected()){
            mqtt.publish("actualConfigTemp", (uint8_t*) &actualConfig.temperature);
            mqtt.publish("actualConfigHum", (uint8_t*) &actualConfig.humidity);
        }
    }else{
        mqtt.loop();
    }
//Rest of the logic
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void reconnect(){
    if (mqtt.connect(MQTT_ID)){
        mqtt.subscribe("configTemp");
        mqtt.subscribe("configHum");
    }else{
        //connection fail
        ethClient.stop();
    }
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void receiveMqttMsg(char* topic, uint8_t* payload, unsigned int len){
    if (strcmp(topic, "configTemp") == 0){
        //Set config to variable 
        memcpy(&actualConfig.temperature, payload, len);
        //Print to debug
        Serial.print("Temperature set to: ");
        Serial.println(actualConfig.temperature);
        //Set config to EEPROM
        EEPROM.put(eeAdressTEMP, actualConfig.temperature);
    }
    if (strcmp(topic, "configHum") == 0){
        //Set config to EEPROM
        memcpy(&actualConfig.humidity, payload, len);
        //Print to debug
        Serial.print("Humidity set to: ");
        Serial.println(actualConfig.humidity);
        //Set config to EPROM
        EEPROM.put(eeAdressHUM, actualConfig.humidity);
    }
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void updateFromEEPROM(){
    EEPROM.get(eeAdressTEMP, actualConfig.temperature);
    EEPROM.get(eeAdressHUM, actualConfig.humidity);
}
void debug(){
    Serial.println("------------------Debug:-------------------");
    Serial.print("Temp Value:");
    Serial.println(actualConfig.temperature);
    Serial.print("Hum Value:");
    Serial.println(actualConfig.humidity);
}


A continuación se adjunta un video donde se muestra la funcionalidad del sistema. Por un lado tenemos el tablero de NodeRED y por el otro lado, tenemos el monitor serial de Arduino IDE para ver cómo recibimos los datos. Recuerda que NodeRED y Mosquitto se están ejecutando y M-Duino PLC está conectado a la misma red del broker MQTT y el servicio NodeRED:

 
 

#5 Communications: How to read variables from a Slave device      through Modbus TCP/I

Introducción

El contenido del capítulo 5 se centra en controlar un dispositivo esclavo a través de Modbus TCP / IP. Este dispositivo está conectado a la misma red a través de Ethernet. En este caso, el dispositivo es un M-Duino 21+ que usa el código esclavo que se publica en our blog.

Este es el primer requisito para completar y probar la nueva lección, además de tener instalado NodeRED.

Modbus es un estándar muy útil que nos permite comunicar varios dispositivos de diferentes fabricantes en una misma red. Además, Modbus TCP / IP se transfiere a través de Ethernet, que es uno de los protocolos más fiables del mercado.

En este caso, mostraremos cómo configurar NodeRED para controlar uno de los esclavos de nuestro sistema.

Los maestros Modbus normalmente tienen 8 funciones principales:

readCoils();
readDiscreteInputs();
readHoldingRegisters();
readInputRegisters();
writeSingleCoil();
writeSingleRegister();
writeMultipleCoils();
writeMultipleRegisters();


Instalación y Actualización

Entonces, en primer lugar, necesitaremos instalar la biblioteca adecuada para tener estas funciones disponibles en nuestra aplicación NodeRED.

Escribe tu terminal o símbolo del sistema después de colocar tu terminal en el directorio raíz de tu NodeRED, normalmente usa el .node-red /:

 cd .node-red/npm install node-red-contrib-modbustcp

Ahora verás que en tu aplicación NodeRED hay dos nuevas funciones Modbus disponibles.

Developing the Application

A menudo, en nuestras instalaciones, tenemos las mismas dos funcionalidades principales que controlar. Entradas y salidas. Como hemos hecho en los capítulos anteriores, hemos dividido el contenido.

Inputs

/////////////////Developing////

Outputs

Nodo cliente Modbus TCP. Se conecta a un servidor Modbus TCP para escribir msg.payload en una bobina o registro.

Los códigos de función admitidos actualmente incluyen:

  • FC 5: Escribe una única Bobina

  • FC 6: Escribe un único registro de retención

  • FC 15: Escribe múltiples Bobinas

  • FC 16: Escribe múltiples registros de retención

Al elegir el dataType y la Address podremos acceder a nuestras salidas esclavas y controlarlas.

Después de instalar la biblioteca NodeRED para usar el protocolo de comunicación Modbus TCP / IP, podemos usar sus nodos. Pero antes de utilizar el bloque principal que organizará la comunicación tendremos que configurar algunos parámetros. Tendremos que especificar el Type (tipo) y la Address (dirección). El Type será la función Modbus y la Address será la posición de la matriz Node-RED donde se colocan nuestras E/S deseadas.

Selecciona un interruptor y el nombre que quieras. No hay configuración adicional para este nodo.

Luego selecciona el bloque de cambio colocado en los bloques de funciones. Escribe la dirección en la función para dar una dirección al objeto Java Script.

Java Script Object - Edit change node - Chapter 5 - Develop your SCADA Application on Node-RED

Después de eso, nuestro interruptor enviará un mensaje (1/0) y, además, tendrá una dirección que apunta a la salida correcta.

Haz lo mismo para el dataType, agrega una función de cambio, escribe dataType y haz lo mismo para todos los interruptores, FC5.

Switches - Edit change node - Chapter 5 - Develop your SCADA Application on Node-RED

Finally, select the modbustcp block into the outputs nodes. Give a name to the block. Into the configurations, Type and Address are toked for the node if you are not defined before for other nodes. In our case, we will define before having just one connection opened with our PLC. 

Por lo tanto, selecciona cualquier tipo y dirección. Luego configura tu Modbus IP Server para el nodo, en nuestro ejemplo, hemos usado 10.10.10.4 IP.

Modbus IP Server to node - Edit change node - Chapter 5 - Develop your SCADA Application on Node-RED

If we do the same process for Analog outputs, adding sliders instead of switches, we got the entire control of the outputs. For the second change node, we must select dataType as FC6. 

A continuación se muestra el flujo de salida completo y la interfaz de usuario.

Output flow and user interface - Chapter 5 - Develop your SCADA Application on Node-RED
Node-RED Dashboard - Chapter 5 - Develop your SCADA Application on Node-RED

#6 Install NodeRed on Raspberry Pi or Industrial Panel PC based   on Linux

Introduction

El contenido del capítulo # 6 es cómo instalar nuestra aplicación NodeRED en una de nuestras Touchberry Pi u otra PC Panels basada en Linux. Este tipo de aplicaciones son muy utilizadas por nuestros clientes porque es una forma fácil y robusta de tener un panel táctil SCADA al lado de la instalación. Otro punto en el que nos centraremos durante el capítulo es cómo agregar la capacidad de inicio automático, por lo que una vez que nos encontramos en el panel el sistema nos mostrará directamente la aplicación NodeRED.

Installation and Upgrade

Dependiendo de la versión de Panel PC tendremos instaladas distintas versiones de Debian o Ubuntu. Actualiza o instala la última versión de NodeRED en tu sistema escribiendo en la terminal:

                            b
                            
                              ash <(curl -sL https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/update-nodejs-and-nodered)       
                            
                          

Actualiza npm antes de instalar cualquier paquete usando los siguientes comandos:

                             
                            
                              cd ~/.node-red npm outdated npm update
                            
                             
                          

Ejecutando NodeRED

Para iniciar NodeRED, abre una nueva ventana de terminal y escribe:

                        node-red-start
                      

* Cerrar la terminal o ctrl-c no detiene la ejecución de NodeRED. Seguirá ejecutándose en segundo plano.

Para detener la ejecución, escribe:

                        node-red-stop
                      


Inicio automático al arrancar

Probablemente en tu aplicación querrás que el NodeRED se inicie cuando enciendas tu Touchberry Pi. Para ello volveremos a abrir la terminal y teclearemos:

                        sudo systemctl enable nodered.service
                      

y para deshabilitar el tipo:

                        sudo systemctl disable nodered.service
                      


Estos son los conceptos básicos para instalar NodeRED en nuestra Touchberry Pi u otr Panel PC Industrial Shields basada en Linux.

Si necesitas información adicional al respecto, sigue el siguiente  link.

Administrador de alarmas por correo electrónico

El contenido del capítulo # 7 está enfocado en generar alarmas con NodeRED. Básicamente, veremos cómo crear un módulo para enviara un correo electrónico si algún parámetro supera el valor deseado.

El requisito previo de este capítulo es tener un servidor de correo electrónico con credenciales válidas.

Instalación y Actualización

Ejecuta el siguiente comando en tu directorio de usuario de NodeRED, normalmente como ya sabemos ~ / .node-red:

                            cd .node-red
sudo npm i node-red-node-email                    
                          
Command NodeRED user directory - Alarms Manager by Email

Una vez que el blog esté instalado, echa un vistazo a los bloques sociales en la aplicación NodeRED. Verás un bloque de salida llamado correo electrónico. Llévalo a tu flujo, también agrega un bloque de inyección.

En nuestro bloque de inyección lo configuraremos con un tema y una carga útil. El tema será nuestro asunto de correo electrónico y la carga útil será el contenido de nuestro correo electrónico. A continuación se muestra un ejemplo:

Node properties - Chapter 7 - Develop your SCADA Application based on NodeRED

Después de eso, solo tenemos que conectarlo a nuestro bloque de salida de correo electrónico y configurarlo. Debes tener un correo electrónico válido y la seguridad bien configurada. Configura tu bloqueo de la siguiente manera, recuerda que To (Para) es el ID de correo electrónico al que deseas enviar el correo electrónico y el UserID (Identificación) de usuario y la Password (Contraseña) son para el correo electrónico desde donde deseas enviar el correo electrónico:

Automatic Email inject node 2 - Alarms Manager by Email

Cuando hagas clic en el blog, el correo electrónico debe enviarse al destino. Si deseas automatizar eso, solo necesitas crear una función que controle el vaciado de los datos del correo electrónico.

Si ves el siguiente error:

Error Invalid Login - Alarms Manager by Email

Configure your email to accept  Control access to less secure apps  these must unblock Node-RED to use your email. In this example, we have used Gmail. To change these parameters, you just need to go to your secure configuration on your Gmail account. With other email service providers, contact their technical team to know how to unblock the control access.


Usando SQLite DataBase con NodeRED

Introducción

SQLite es una biblioteca de lenguaje basada en C que implementa el motor de base de datos SQL. Es pequeño, rápido, autónomo, de alta confiabilidad y con todas las funciones. Aparte de eso, se basa en código abierto y es la base de datos más utilizada del mundo.

En este capítulo, centraremos nuestros esfuerzos en explicar cómo implementar una base de datos usando SQLite con NodeRED.

SQLite - Chapter 8 - Develop your SCADA Application based on Node-RED

Instalación

Escribe tu terminal:

                        
sudo npm install -g [email protected]
hash -r
cd ~/.node-red
npm install node-red-node-sqlite

Una vez que tenemos la biblioteca instalada en nuestro NodeRED, podemos usar sus bloques en ella. Otra herramienta útil que recomendamos es DB Browser para SQLite. Existen distribuciones para los sistemas operativos más populares.


Ejemplo

Antes de comenzar con el ejemplo, es importante comprobar cómo funciona SQLite. Si es la primera vez que usas SQLite, echa un vistazo a
their website
Antes de introducir datos en la base de datos debemos crearlos. Para crear una base de datos solo tenemos que ejecutar este código:

                          
CREATE TABLE IF NOT EXISTS log(  time INT PRIMARY KEY, value INT) 
Para ejecutar este código, debemos agregar el bloque principal de SQLite a nuestro flujo de trabajo. Tendremos que editar el bloque y crear la base de datos. Al hacer clic, dentro del bloque, en el botón editar junto al nombre de la base de datos, crearemos un nuevo archivo donde se colocará nuestra base de datos. En nuestro caso, hemos creado el archivo Chapter8_SQLite.db.
Además, al agregar una marca de tiempo y editar el tema con el código anterior, crearemos una base de datos dentro del archivo.
Echa un vistazo a las siguientes imágenes para comprender mejor este procedimiento:

Chapter8_SQLite.db file - Chapter 8 - Develop your SCADA Application based on Node-RED
Edit SQLite node - Chapter8_SQLite.db file - Chapter 8 - Develop your SCADA Application based on Node-RED
Edit inject node - Chapter8_SQLite.db file - Chapter 8 - Develop your SCADA Application based on Node-RED

Ahora podemos hacer clic en implementar y luego hacer clic en Create DB Table (Crear tabla de base de datos), ejecutaremos el código SQLite a través del bloque y nuestra base de datos se creará correctamente.

Una vez que hemos creado la base de datos es el momento de introducir nuestros primeros caracteres y leerlos. Imagina que tenemos un PLC datalogger que está enviando a nuestra aplicación NodeRED el valor analógico de algún sensor, y nuestro proyecto es conocer sus valores a lo largo del tiempo. Luego tenemos que crear una base de datos donde la hora y los valores deben estar en la misma fila de nuestra base de datos.

Para ello, hemos creado una interfaz de usuario como ejemplo con un control deslizante, un botón y un texto. El control deslizante será para simular el valor analógico externo, el texto se utilizará para mostrar el último valor en nuestra base de datos y el botón será para actualizar el último valor que se mostrará en el texto.

¿Como hacer eso? Es muy sencillo.

En primer lugar, introduce el control deslizante y configúralos como quieras. Es importante verificar la salida del caso "solo en el lanzamiento", si no en cada cambio, guardaremos un valor en nuestra base de datos. Después de configurar nuestro control deslizante debemos introducir una función entre el control deslizante y el bloque SQLite.

Sobre esta función colocaremos el siguiente código siguiendo las bases SQLite:

                            
return {
"topic": "INSERT INTO log (time, value) VALUES ( " + Date.now() +", "+ msg.payload +")"

Este fragmento de código se lanzará cada vez que cambiemos el valor en el control deslizante al bloque SQLite. Con esto, insertaremos un valor y una marca de tiempo en nuestra tabla.

A continuación se muestran algunas imágenes de este proceso:

SQLite bases - Chapter 8 - Develop your SCADA Application based on Node-RED
 
Edit slider node - SQLite bases - Using SQLite DataBase with NodeRED
 
Edit function node - SQLite bases - Chapter 8 - Develop your SCADA Application based on Node-RED

El último paso será mostrar el último valor de nuestra base de datos. Usamos el mismo método, simplemente agregando un código diferente en nuestro bloque de funciones:

var time = msg.payload
var newMsg = {
"topic": "SELECT * FROM log ORDER BY time DESC LIMIT 1"

return newMsg;

A continuación se muestra la configuración de cada bloque en caso de que exista alguna duda:

Configuration of every block - Using SQLite DataBase with NodeRED
 
Edit function node - Configuration of every block - Chapter 8 - Develop your SCADA Application based on Node-RED
 
Edit text node - Chapter 8 - Develop your SCADA Application based on Node-RED

Finalmente, agrega tus parámetros personalizados al diseño.

Espero que este capítulo te haya ayudado a tener una nueva característica de NodeRED y que ahora puedas implementar bases de datos en tu proyecto.

A continuación se muestra nuestro diseño de ejemplo:

Example layout - Chapter 8 - Develop your SCADA Application based on Node-RED