Ir al contenido

Servidor OPC UA en un Raspberry PLC con Node-RED: flujos de ejemplo

Crea el espacio de direcciones, escribe una entrada del PLC, léela con un cliente y protege el servidor
16 de enero de 2024 por
Servidor OPC UA en un Raspberry PLC con Node-RED: flujos de ejemplo
Boot & Work Corp. S.L, DAVID CORONADO TRAVASET

Para ejecutar un servidor OPC UA en un Raspberry PLC, instala Node-RED con los nodos node-red-contrib-iiot-opcua, construye el espacio de direcciones (carpetas y variables) con nodos Server-ASO y arranca un nodo OPCUA-IIoT-Server en un puerto TCP. Después, cualquier cliente OPC UA, como UaExpert o un SCADA, navega y lee las variables en opc.tcp://<IP del PLC>:<puerto>/.

Este ejemplo usa el puerto 55488 (el puerto registrado por defecto para OPC UA es el 4840), escribe cada segundo la entrada analógica I0.10 del PLC en la variable ns=1;s=Variable1 y la vuelve a leer con un cliente de node-red-contrib-opcua. Los tres flujos están más abajo, listos para importar.

¿Qué es OPC UA?

OPC UA (OPC Unified Architecture) es el estándar independiente de plataforma de la OPC Foundation para el intercambio de datos industriales, publicado como IEC 62541. Sustituye a OPC Classic (DA, HDA, A&E), que dependía de COM/DCOM de Windows, y añade un modelo de información, seguridad integrada y transportes que funcionan en cualquier sistema operativo, desde un PLC hasta la nube.

  • Independiente de la plataforma: funciona en Linux, Windows y sistemas embebidos, así que un Raspberry PLC puede ser servidor.
  • Modelo de información: los datos se organizan como nodos (objetos, variables, métodos) con tipos, unidades y calidad, no como registros planos.
  • Seguridad: los certificados de aplicación, la autenticación de usuarios, la firma y el cifrado forman parte del estándar.
  • Cliente y servidor, y PubSub: los clientes navegan, leen, escriben y se suscriben a un servidor; PubSub añade publicación y suscripción sobre UDP o MQTT.

Para compararlo con Modbus en un enlace con el SCADA, mira Modbus RTU frente a Modbus TCP frente a OPC UA.

Formas de ejecutar un servidor OPC UA en un Raspberry PLC

OpciónLenguajeNotas
node-red-contrib-iiot-opcuaNode-REDSe usa en este ejemplo para el servidor. Versión 4.1.2, probada por sus autores con Node.js 16 y Node-RED 3.0; no se actualiza desde hace unos cuatro años, así que pruébala en tu versión de Node-RED.
node-red-contrib-opcuaNode-REDSe usa en este ejemplo para el cliente. Se mantiene activamente y se basa en node-opcua; también tiene un nodo OpcUa-Server con usuarios, políticas de seguridad y comandos como addFolder y addVariable.
asyncuaPythonLibrería de código abierto de cliente y servidor; buena opción cuando el resto del programa del PLC está en Python.
open62541CPila OPC UA de código abierto para servidores embebidos y de alto rendimiento.
CODESYSIEC 61131-3El runtime de CODESYS incluye un servidor OPC UA; las variables se eligen en la Symbol Configuration. Mira CODESYS en un Raspberry PLC.

Qué necesitas

  • Un Raspberry PLC con su sistema operativo y las librerías de Industrial Shields instaladas. Empieza con los primeros pasos con el Raspberry PLC.
  • Node-RED en el PLC, con tres paquetes del gestor de paleta: node-red-contrib-iiot-opcua (servidor), node-red-contrib-opcua (cliente) y los nodos del Raspberry PLC de Industrial Shields, @industrial-shields/node-red-librpiplc, que aportan los nodos rpiplc-config y rpiplc-analog-read del flujo 2 y necesitan la librería C librpiplc.
  • node-red-dashboard si quieres ver los indicadores de los flujos 2 y 3.
  • Un cliente OPC UA en tu PC para comprobar el servidor, por ejemplo UaExpert de Unified Automation (descarga gratuita con registro).

El espacio de direcciones del ejemplo

El flujo 1 crea una carpeta y dos variables bajo la carpeta estándar Objects (ns=0;i=85). Los flujos 2 y 3 usan el mismo NodeId para escribir y leer.

NodeIdNombre de navegaciónTipoContenido
ns=1;s=TestVariablesVariablesFolderTypeCarpeta que organiza las variables
ns=1;s=TestDateTimeTestDateTimeBaseDataVariableType, DateTimeFecha y hora inyectadas al arrancar
ns=1;s=Variable1Variable1BaseDataVariableType, Int16Valor de la entrada analógica I0.10, escrito cada segundo por el flujo 2

Paso 1: crea el servidor OPC UA y su espacio de direcciones

Estos nodos crean el servidor, su carpeta y sus variables, y les dan un valor inicial. Después de Deploy, el servidor tarda unos segundos en arrancar: los nodos inject de las variables esperan 15 segundos para que la carpeta exista antes.

Flujo 1: nodos de Node-RED que crean el servidor OPC UA
Flujo 1: nodos inject, Server-ASO y Server que construyen el servidor OPC UA.
  • OPCUA-IIoT-Inject envía un mensaje una vez al arrancar, con el tipo inject.
Inject configuration
Configuración de OPCUA-IIoT-Inject.
  • OPCUA-IIoT-Server-ASO añade un nodo al espacio de direcciones: su NodeId, nombre de navegación, nodo padre y tipo. La carpeta usa FolderType, y las variables usan BaseDataVariableType con un tipo de dato.
Tag configuration
Configuración de OPCUA-IIoT-Server-ASO para la carpeta.
  • OPCUA-IIoT-Server arranca el servidor en el puerto que indiques, aquí 55488, así que el endpoint es opc.tcp://<IP del PLC>:55488/. También fija límites, descubrimiento y seguridad. El ejemplo permite acceso anónimo sin seguridad, lo que solo vale para un banco de pruebas.
Server configuration
Configuración de OPCUA-IIoT-Server: puerto 55488.
JSON del flujo 1: servidor OPC UA (importar en Node-RED)
[
  {
    "id": "526638e31bd911fe",
    "type": "tab",
    "label": "Flow 1",
    "disabled": false,
    "info": "",
    "env": []
  },
  {
    "id": "75df2f23680c144e",
    "type": "OPCUA-IIoT-Server",
    "z": "526638e31bd911fe",
    "port": "55488",
    "endpoint": "",
    "acceptExternalCommands": true,
    "maxAllowedSessionNumber": "",
    "maxConnectionsPerEndpoint": "",
    "maxAllowedSubscriptionNumber": "",
    "alternateHostname": "",
    "name": "",
    "showStatusActivities": false,
    "showErrors": false,
    "asoDemo": false,
    "allowAnonymous": true,
    "individualCerts": false,
    "isAuditing": false,
    "serverDiscovery": true,
    "users": [],
    "xmlsets": [],
    "publicCertificateFile": "",
    "privateCertificateFile": "",
    "registerServerMethod": "1",
    "discoveryServerEndpointUrl": "",
    "capabilitiesForMDNS": "",
    "maxNodesPerRead": "",
    "maxNodesPerBrowse": "",
    "delayToClose": "",
    "x": 1034.3000183105469,
    "y": 389.9999694824219,
    "wires": [
      [
        "1b7404249f5bac6e"
      ]
    ]
  },
  {
    "id": "1b7404249f5bac6e",
    "type": "debug",
    "z": "526638e31bd911fe",
    "name": "",
    "active": true,
    "tosidebar": true,
    "console": false,
    "tostatus": false,
    "complete": "true",
    "targetType": "full",
    "statusVal": "",
    "statusType": "auto",
    "x": 1214.3000183105469,
    "y": 389.9999694824219,
    "wires": []
  },
  {
    "id": "a94182acacad6858",
    "type": "OPCUA-IIoT-Server-ASO",
    "z": "526638e31bd911fe",
    "nodeId": "ns=1;s=TestVariables",
    "browsename": "Variables",
    "displayname": "Variables",
    "objecttype": "FolderType",
    "datatype": "",
    "value": "",
    "referenceNodeId": "ns=0;i=85",
    "referencetype": "Organizes",
    "name": "Folder TestVariables",
    "x": 540,
    "y": 340,
    "wires": [
      [
        "2c72a02e95e2e53a"
      ]
    ]
  },
  {
    "id": "57a7deb0b12064d7",
    "type": "OPCUA-IIoT-Inject",
    "z": "526638e31bd911fe",
    "injectType": "inject",
    "payload": "",
    "payloadType": "date",
    "topic": "",
    "repeat": "",
    "crontab": "",
    "once": true,
    "startDelay": "",
    "name": "",
    "addressSpaceItems": [],
    "x": 250,
    "y": 340,
    "wires": [
      [
        "a94182acacad6858"
      ]
    ]
  },
  {
    "id": "09ed80c457c3501a",
    "type": "OPCUA-IIoT-Server-ASO",
    "z": "526638e31bd911fe",
    "nodeId": "ns=1;s=TestDateTime",
    "browsename": "TestDateTime",
    "displayname": "Test DateTime",
    "objecttype": "BaseDataVariableType",
    "datatype": "DateTime",
    "value": "",
    "referenceNodeId": "ns=1;s=TestVariables",
    "referencetype": "Organizes",
    "name": "DateTime",
    "x": 580,
    "y": 380,
    "wires": [
      [
        "2c72a02e95e2e53a"
      ]
    ]
  },
  {
    "id": "f824a67fc665769f",
    "type": "OPCUA-IIoT-Inject",
    "z": "526638e31bd911fe",
    "injectType": "inject",
    "payload": "",
    "payloadType": "date",
    "topic": "",
    "repeat": "",
    "crontab": "",
    "once": true,
    "startDelay": "15",
    "name": "",
    "addressSpaceItems": [],
    "x": 250,
    "y": 380,
    "wires": [
      [
        "09ed80c457c3501a"
      ]
    ]
  },
  {
    "id": "2c72a02e95e2e53a",
    "type": "function",
    "z": "526638e31bd911fe",
    "name": "thru",
    "func": "\nreturn msg;",
    "outputs": 1,
    "timeout": "",
    "noerr": 0,
    "initialize": "",
    "finalize": "",
    "libs": [],
    "x": 854.3000183105469,
    "y": 389.9999694824219,
    "wires": [
      [
        "75df2f23680c144e"
      ]
    ]
  },
  {
    "id": "9b7c6cf023d4b643",
    "type": "OPCUA-IIoT-Server-ASO",
    "z": "526638e31bd911fe",
    "nodeId": "ns=1;s=Variable1",
    "browsename": "Variable1",
    "displayname": "Variable1",
    "objecttype": "BaseDataVariableType",
    "datatype": "Int16",
    "value": "",
    "referenceNodeId": "ns=1;s=TestVariables",
    "referencetype": "Organizes",
    "name": "Variable1Int16",
    "x": 560,
    "y": 420,
    "wires": [
      [
        "2c72a02e95e2e53a"
      ]
    ]
  },
  {
    "id": "9f0e92a8743be1eb",
    "type": "OPCUA-IIoT-Inject",
    "z": "526638e31bd911fe",
    "injectType": "inject",
    "payload": "125",
    "payloadType": "num",
    "topic": "",
    "repeat": "",
    "crontab": "",
    "once": true,
    "startDelay": "15",
    "name": "",
    "addressSpaceItems": [],
    "x": 270,
    "y": 420,
    "wires": [
      [
        "9b7c6cf023d4b643"
      ]
    ]
  }
]

Paso 2: escribe una entrada del PLC en el servidor OPC UA

Cada segundo, este flujo lee la entrada analógica I0.10 del Raspberry PLC, la muestra en el dashboard y la escribe en la variable ns=1;s=Variable1. El nodo rpiplc-config selecciona el modelo de PLC, aquí RPIPLC_21. Después de importar el flujo, abre rpiplc-config y selecciona la versión y el modelo de tu PLC.

Flujo 2: nodos de Node-RED que escriben una entrada del PLC en el servidor OPC UA
Flujo 2: lee I0.10 y lo escribe en la variable OPC UA.
  • OPCUA-IIoT-Node de tipo write fija el NodeId de destino y el tipo de dato, Int16.
Node configuration
Configuración de OPCUA-IIoT-Node: NodeId y tipo de dato.
  • OPCUA-IIoT-Write envía el valor al servidor a través de un conector.
Write node configuration
Configuración de OPCUA-IIoT-Write.

El conector guarda el endpoint. Como el servidor se ejecuta en el mismo PLC, apunta a opc.tcp://localhost:55488/.

Connector node configuration
Configuración de OPCUA-IIoT-Connector: endpoint opc.tcp://localhost:55488/.

El valor es una cuenta bruta del ADC, no voltios. El nodo rpiplc-analog-read devuelve un entero: hasta 12 bits (0 a 4095) en las versiones 3 a 6 del Raspberry PLC. Escálalo antes de publicarlo en unidades de ingeniería. En el flujo de abajo el indicador llega a 4095 y se llama Raw.

JSON del flujo 2: escribir I0.10 en el servidor (importar en Node-RED)
[
  {
    "id": "63f010ebc6ec597c",
    "type": "tab",
    "label": "Flow 2",
    "disabled": false,
    "info": "",
    "env": []
  },
  {
    "id": "272bd91f019aaa4a",
    "type": "rpiplc-analog-read",
    "z": "63f010ebc6ec597c",
    "rpiplc": "9440adac8659dc1d",
    "pin": "I0.10",
    "name": "",
    "x": 540,
    "y": 340,
    "wires": [
      [
        "72bb01129893f1ae",
        "27654d48016fa1bf"
      ]
    ]
  },
  {
    "id": "4591787bbefbd0b3",
    "type": "OPCUA-IIoT-Write",
    "z": "63f010ebc6ec597c",
    "connector": "875fa40fca5ccc47",
    "name": "",
    "justValue": true,
    "showStatusActivities": false,
    "showErrors": false,
    "x": 850,
    "y": 340,
    "wires": [
      [
        "e4d285975b908c13"
      ]
    ]
  },
  {
    "id": "e4d285975b908c13",
    "type": "debug",
    "z": "63f010ebc6ec597c",
    "name": "debug-set",
    "active": false,
    "tosidebar": true,
    "console": false,
    "tostatus": false,
    "complete": "payload",
    "targetType": "msg",
    "statusVal": "",
    "statusType": "auto",
    "x": 1040,
    "y": 340,
    "wires": []
  },
  {
    "id": "62aeb4828a504caa",
    "type": "inject",
    "z": "63f010ebc6ec597c",
    "name": "",
    "props": [
      {
        "p": "payload"
      },
      {
        "p": "topic",
        "vt": "str"
      }
    ],
    "repeat": "1",
    "crontab": "",
    "once": false,
    "onceDelay": 0.1,
    "topic": "",
    "payload": "",
    "payloadType": "date",
    "x": 370,
    "y": 340,
    "wires": [
      [
        "272bd91f019aaa4a"
      ]
    ]
  },
  {
    "id": "72bb01129893f1ae",
    "type": "OPCUA-IIoT-Node",
    "z": "63f010ebc6ec597c",
    "injectType": "write",
    "nodeId": "ns=1;s=Variable1",
    "datatype": "Int16",
    "value": "",
    "name": "",
    "topic": "",
    "showErrors": false,
    "x": 690,
    "y": 340,
    "wires": [
      [
        "4591787bbefbd0b3"
      ]
    ]
  },
  {
    "id": "27654d48016fa1bf",
    "type": "ui_gauge",
    "z": "63f010ebc6ec597c",
    "name": "",
    "group": "0cfb93c85cf539c8",
    "order": 0,
    "width": 0,
    "height": 0,
    "gtype": "gage",
    "title": "I0.10",
    "label": "Raw",
    "format": "{{value}}",
    "min": 0,
    "max": "4095",
    "colors": [
      "#00b500",
      "#e6e600",
      "#ca3838"
    ],
    "seg1": "",
    "seg2": "",
    "diff": false,
    "className": "",
    "x": 690,
    "y": 280,
    "wires": []
  },
  {
    "id": "9440adac8659dc1d",
    "type": "rpiplc-config",
    "model": "RPIPLC_21",
    "name": ""
  },
  {
    "id": "875fa40fca5ccc47",
    "type": "OPCUA-IIoT-Connector",
    "discoveryUrl": "",
    "endpoint": "opc.tcp://localhost:55488/",
    "endpointMustExist": false,
    "keepSessionAlive": true,
    "loginEnabled": false,
    "name": "LOCAL SERVER",
    "showErrors": false,
    "securityPolicy": "None",
    "securityMode": "None",
    "individualCerts": false,
    "publicCertificateFile": "",
    "privateKeyFile": "",
    "defaultSecureTokenLifetime": "",
    "autoSelectRightEndpoint": false,
    "strategyMaxRetry": "",
    "strategyInitialDelay": "",
    "strategyMaxDelay": "",
    "strategyRandomisationFactor": "",
    "requestedSessionTimeout": "",
    "connectionStartDelay": "",
    "reconnectDelay": "",
    "maxBadSessionRequests": "10"
  },
  {
    "id": "0cfb93c85cf539c8",
    "type": "ui_group",
    "name": "Default",
    "tab": "39450c9e599a8dde",
    "order": 1,
    "disp": true,
    "width": "6",
    "collapse": false,
    "className": ""
  },
  {
    "id": "39450c9e599a8dde",
    "type": "ui_tab",
    "name": "Home",
    "icon": "dashboard",
    "disabled": false,
    "hidden": false
  }
]

Paso 3: lee la variable con un cliente OPC UA

Este flujo usa el otro paquete, node-red-contrib-opcua, como cliente. Cada segundo pide al servidor ns=1;s=Variable1 y muestra el valor en el panel de depuración y en el dashboard. Puede ejecutarse en el mismo PLC o en otro dispositivo de la red.

Flujo 3: nodos de Node-RED que leen la variable OPC UA
Flujo 3: nodos OpcUa-Item y OpcUa-Client que leen la variable.
  • OpcUa-Item fija el NodeId que se lee y su tipo de dato.
Item node configuration
Configuración de OpcUa-Item.
  • OpcUa-Client se conecta al endpoint, aquí opc.tcp://10.10.10.20:55488/ (la dirección eth0 por defecto del Raspberry PLC), con la acción read. El mismo nodo también puede escribir, suscribirse, monitorizar y navegar.
Client node configuration
Configuración de OpcUa-Client: endpoint y acción read.
JSON del flujo 3: leer la variable con un cliente (importar en Node-RED)
[
  {
    "id": "e0635bf35b9bc5c7",
    "type": "tab",
    "label": "Flow 3",
    "disabled": false,
    "info": "",
    "env": []
  },
  {
    "id": "f7aab83e0a06b0ba",
    "type": "OpcUa-Item",
    "z": "e0635bf35b9bc5c7",
    "item": "ns=1;s=Variable1",
    "datatype": "Int16",
    "value": "",
    "name": "",
    "x": 480,
    "y": 280,
    "wires": [
      [
        "c9cbb2df0b559691"
      ]
    ],
    "icon": "font-awesome/fa-tag"
  },
  {
    "id": "c9cbb2df0b559691",
    "type": "OpcUa-Client",
    "z": "e0635bf35b9bc5c7",
    "endpoint": "9911d4815d3e3bdd",
    "action": "read",
    "deadbandtype": "a",
    "deadbandvalue": 1,
    "time": 10,
    "timeUnit": "s",
    "certificate": "n",
    "localfile": "",
    "localkeyfile": "",
    "folderName4PKI": "",
    "useTransport": false,
    "maxChunkCount": "",
    "maxMessageSize": "",
    "receiveBufferSize": "",
    "sendBufferSize": "",
    "name": "",
    "x": 680,
    "y": 280,
    "wires": [
      [
        "95de452cad37e33f",
        "4faa4ea77b213280"
      ],
      []
    ],
    "icon": "font-awesome/fa-tasks"
  },
  {
    "id": "9e76fd28ede4da39",
    "type": "inject",
    "z": "e0635bf35b9bc5c7",
    "name": "",
    "props": [
      {
        "p": "payload"
      },
      {
        "p": "topic",
        "vt": "str"
      }
    ],
    "repeat": "1",
    "crontab": "",
    "once": true,
    "onceDelay": "15",
    "topic": "",
    "payload": "1",
    "payloadType": "num",
    "x": 270,
    "y": 280,
    "wires": [
      [
        "f7aab83e0a06b0ba"
      ]
    ]
  },
  {
    "id": "95de452cad37e33f",
    "type": "debug",
    "z": "e0635bf35b9bc5c7",
    "name": "debug-get",
    "active": true,
    "tosidebar": true,
    "console": false,
    "tostatus": false,
    "complete": "payload",
    "targetType": "msg",
    "statusVal": "",
    "statusType": "auto",
    "x": 900,
    "y": 300,
    "wires": []
  },
  {
    "id": "4faa4ea77b213280",
    "type": "ui_gauge",
    "z": "e0635bf35b9bc5c7",
    "name": "",
    "group": "0cfb93c85cf539c8",
    "order": 2,
    "width": 0,
    "height": 0,
    "gtype": "gage",
    "title": "Server Read",
    "label": "Raw",
    "format": "{{value}}",
    "min": 0,
    "max": "4095",
    "colors": [
      "#00b500",
      "#e6e600",
      "#ca3838"
    ],
    "seg1": "",
    "seg2": "",
    "diff": false,
    "className": "",
    "x": 910,
    "y": 260,
    "wires": []
  },
  {
    "id": "9911d4815d3e3bdd",
    "type": "OpcUa-Endpoint",
    "endpoint": "opc.tcp://10.10.10.20:55488/",
    "secpol": "None",
    "secmode": "None",
    "none": true,
    "login": false,
    "usercert": false,
    "usercertificate": "",
    "userprivatekey": ""
  },
  {
    "id": "0cfb93c85cf539c8",
    "type": "ui_group",
    "name": "Default",
    "tab": "39450c9e599a8dde",
    "order": 1,
    "disp": true,
    "width": "6",
    "collapse": false,
    "className": ""
  },
  {
    "id": "39450c9e599a8dde",
    "type": "ui_tab",
    "name": "Home",
    "icon": "dashboard",
    "disabled": false,
    "hidden": false
  }
]

Comprueba el servidor con UaExpert

  1. Conecta el PC a la misma red que el PLC y comprueba que responde al ping.
  2. En UaExpert, añade un servidor con la URL personalizada opc.tcp://<IP del PLC>:55488/ y elige el endpoint con seguridad None, como está configurado en este ejemplo.
  3. Conecta y abre Objects y después Variables en el panel del espacio de direcciones.
  4. Arrastra Variable1 a la vista de acceso a datos: el valor cambia cuando cambia la tensión en I0.10.

Antes de producción: protege el servidor

El ejemplo acepta clientes anónimos con política de seguridad None. En la red real de una planta:

  • Activa una política de seguridad como Basic256Sha256 con el modo Sign and Encrypt, y confía solo en los certificados de los clientes conocidos.
  • Desactiva el acceso anónimo y crea usuarios con contraseña.
  • Abre el puerto del servidor solo hacia la red del SCADA o del MES, con el cortafuegos del PLC o de la red.
  • Mantén actualizados Node-RED, sus paquetes y el sistema operativo, y protege el editor de Node-RED con usuario y contraseña.

Problemas habituales

SíntomaCausa probableQué hacer
El cliente no se conectaIP o puerto incorrectos, cortafuegos, o el servidor aún está arrancandoHaz ping al PLC, revisa el puerto en el nodo Server y espera unos segundos después del Deploy
BadNodeIdUnknown al escribir o leerLa variable aún no existe, o el NodeId está escrito de otra formaMantén el retardo de 15 segundos del flujo 1 y copia el NodeId exacto, con el espacio de nombres
BadTypeMismatchEl tipo de dato de la escritura no coincide con el de la variableUsa el mismo tipo (aquí Int16) en Server-ASO, OPCUA-IIoT-Node y OpcUa-Item
El valor parece incorrectoEs la cuenta bruta del ADCEscálalo a voltios o unidades de ingeniería antes de publicarlo

Llévalo a la práctica

OPC UA es una forma de pasar datos del PLC a un supervisor. Estas páginas muestran cómo un Raspberry PLC comparte sus datos de otras maneras: un gateway para un SCADA, una simulación de planta y un lector Modbus TCP.

Preguntas frecuentes sobre OPC UA en un Raspberry PLC

¿Una Raspberry Pi puede ser un servidor OPC UA?

Sí. OPC UA es independiente de la plataforma, y una Raspberry Pi o un Raspberry PLC puede ejecutar un servidor con Node-RED (node-red-contrib-iiot-opcua o node-red-contrib-opcua), Python (asyncua), C (open62541) o el servidor OPC UA del runtime de CODESYS.

¿Qué puerto usa OPC UA?

El puerto registrado por defecto para opc.tcp es el 4840, pero un servidor puede escuchar en cualquier puerto TCP libre. Este ejemplo usa el 55488, así que el endpoint es opc.tcp://<IP del PLC>:55488/.

¿Qué diferencia hay entre node-red-contrib-iiot-opcua y node-red-contrib-opcua?

Los dos llevan OPC UA a Node-RED. node-red-contrib-iiot-opcua construye aquí el servidor con nodos Server-ASO, pero no se actualiza desde hace unos cuatro años. node-red-contrib-opcua se mantiene activamente y tiene nodos de cliente y de servidor, así que es la opción más segura para proyectos nuevos.

¿Cómo pruebo un servidor OPC UA?

Conecta un cliente como UaExpert a opc.tcp://<IP del servidor>:<puerto>/, navega por la carpeta Objects y añade las variables a la vista de acceso a datos. Si los valores cambian, el servidor funciona.

¿OPC UA es mejor que Modbus TCP?

Hace más cosas: nodos con tipo y estructura, seguridad integrada y suscripciones. Modbus TCP es más ligero y más fácil de poner en marcha. Muchas plantas usan Modbus a nivel de dispositivo y OPC UA hacia el SCADA, el MES o la nube.

¿Es seguro el acceso anónimo con seguridad None?

Solo en un banco de pruebas aislado. En producción, usa una política de seguridad con Sign and Encrypt, certificados de confianza, cuentas de usuario y un cortafuegos que abra el puerto solo a la red del SCADA.

Buscar en nuestro blog

Servidor OPC UA en un Raspberry PLC con Node-RED: flujos de ejemplo
Boot & Work Corp. S.L, DAVID CORONADO TRAVASET 16 de enero de 2024
Compartir esta publicación

¿Estás buscando tu Controlador Lógico Programable ideal?

Echa un vistazo a esta comparativa de producto de varios controladores industriales basados en Arduino.

Comparamos entradas, salidas, comunicaciones y otras especificaciones con las de los equipos de otras marcas destacadas.

Comparativa de PLCs