Cada nodo de un servidor OPC UA tiene un NodeId: un índice de espacio de nombres y un identificador, escrito como ns=2;s=LineA.Temperature. El identificador es de uno de cuatro tipos: numérico (i=), cadena (s=), GUID (g=) o bytes opacos (b=). Un cliente, como un sistema SCADA o un Gateway, se conecta a un endpoint del servidor y usa los NodeId para leer, escribir o suscribirse.
Una integración OPC UA que hoy lee el valor correcto puede leer otro tras actualizar el servidor si guardó un identificador que no permanece estable. Un servidor OPC UA contiene un espacio de direcciones: nodos que describen los equipos, sus valores y sus relaciones. Una integración fiable identifica cada valor por su NodeId y su espacio de nombres, y conserva junto a él su estado y sus marcas temporales. Esta guía explica esas identidades y cómo validar un punto antes de añadir cien.
Esta guía forma parte de la serie sobre OPC UA y MQTT. Trata el intercambio habitual entre cliente y servidor basado en sesiones, no OPC UA PubSub.
Cliente frente a servidor OPC UA
La descripción general de OPC Foundation (parte 1) distingue dos funciones. El servidor posee el espacio de direcciones y ofrece servicios sobre él. El cliente se conecta y utiliza esos servicios. Una aplicación puede desempeñar ambas funciones: un Gateway puede leer como cliente el servidor de un PLC y ofrecer su propio servidor a un sistema SCADA. Son dos interfaces, cada una con sus propias especificaciones y pruebas. Otro caso habitual es un adaptador que presenta un servidor UA delante de un servidor OPC DA anterior; la guía de migración de OPC DA lo explica.
Compruebe por separado cada servicio que necesite el proyecto: Browse, Read, Write, suscripciones (elementos monitorizados), llamadas a métodos y acceso al historial. Una lectura correcta de un valor escalar solo demuestra que esa lectura funciona para ese nodo y ese usuario.
URL de endpoint y seguridad
Una URL de endpoint como opc.tcp://plc-line-a.example:4840/UA/Process identifica una conexión, no un valor. opc.tcp es el protocolo binario sobre TCP. El puerto 4840 es el que IANA registra para OPC UA sobre TCP, pero muchos servidores escuchan en otro, así que copie la URL que indique el servidor. Cada endpoint anuncia en su EndpointDescription:
- una política de seguridad, es decir, el conjunto de algoritmos;
- un modo de seguridad de mensajes: None, Sign o SignAndEncrypt;
- los tipos de credenciales de usuario que admite: acceso anónimo, nombre de usuario y contraseña, o certificado.
De ello se derivan dos decisiones de confianza distintas. El cliente y el servidor deben confiar en los certificados de aplicación del otro. Después, el servidor debe autorizar al usuario. Confiar en un certificado no autoriza al usuario, y que se abra una conexión TCP no demuestra ninguna de las dos cosas. Registre el endpoint, la política y el modo de seguridad, la identidad del usuario y dónde se confía en cada certificado.
NodeIds y espacios de nombres
Un NodeId identifica un nodo. La parte 3 de la especificación (OPC 10000-3, 8.2) le da tres partes: un índice de espacio de nombres (un UInt16), un tipo de identificador y el identificador. La parte 6 (OPC 10000-6, 5.1.12) define la forma de texto ns=<índice>;<tipo>=<identificador>. Hay cuatro tipos de identificador:
| Tipo de identificador | Prefijo | Ejemplo | Reglas |
|---|---|---|---|
| Numérico | i= | ns=3;i=1001 | Un entero sin signo. Los nodos que define OPC Foundation son numéricos: i=2258 es la hora actual del servidor |
| Cadena | s= | ns=2;s=LineA.Temperature | Hasta 4.096 caracteres, sin caracteres de control |
| GUID | g= | ns=4;g=09087e75-8e5e-499b-954f-f2a9603db28a | 32 dígitos hexadecimales en la forma 8-4-4-4-12 |
| Opaco | b= | ns=5;b=M/RbKBsRVkePCePcx24oRA== | Bytes escritos en Base64, hasta 4.096 bytes, en un formato que define el servidor |
El espacio de nombres 0 es el de OPC UA, http://opcfoundation.org/UA/, y sus NodeId se escriben sin ns=, como i=2258. El índice 1 está reservado para el espacio de nombres local del propio servidor (OPC 10000-5, 6.3.1). Los espacios de nombres del modelo de información de un dispositivo o de las etiquetas de un PLC empiezan en el índice 2 o superior. La parte 6 también permite escribir la URI en lugar del índice, como en nsu=urn:example:process-model;s=LineA.Temperature, pero los clientes y herramientas más antiguos no aceptan esa forma.
El índice es una posición en el NamespaceArray del servidor; cada posición contiene una URI de espacio de nombres. La URI es el nombre estable. El índice puede cambiar al modificar la configuración o el firmware del servidor. La parte 5 prohíbe que un servidor modifique o elimine entradas mientras un cliente tenga una sesión abierta y recomienda que solo añada entradas nuevas, pero admite que un cambio puede ser inevitable, así que un cliente debe comprobar los índices al iniciar una sesión:
Registre la URI de espacio de nombres con cada NodeId de la lista de puntos. Tras cualquier cambio del servidor, compruebe el NamespaceArray antes de confiar en los índices anteriores.
Un nombre para mostrar y una ruta de navegación tampoco son NodeIds. Úselos para encontrar el nodo y después registre su NodeId.
El valor, su estado y sus marcas temporales
Una lectura devuelve un DataValue, definido en la parte 4. Conserve toda su información:
| Campo | Qué indica |
|---|---|
| Value | El valor, según el tipo de datos del nodo: escalar, matriz o estructura |
| StatusCode | Good, Uncertain o Bad, con un motivo |
| SourceTimestamp | Cuándo se midió o cambió el valor en su origen, si el servidor lo sabe |
| ServerTimestamp | Cuándo supo el servidor por última vez que el valor seguía vigente |
Reglas para utilizarlos:
- Compruebe primero el estado. Un valor Bad no es una medición. Acuerde una regla para Uncertain.
- Mantenga separadas las dos marcas temporales. Un valor constante puede conservar una marca de origen antigua mientras el servidor lo confirma repetidamente. «Sin cambios durante una hora» no significa «sin comunicación durante una hora».
- Compruebe el tipo de datos. Registre el tipo declarado y si es una matriz. Un contador UInt64 es válido en OPC UA, pero puede perder precisión en un programa que guarda números como coma flotante de 64 bits.
- Sepa qué marca temporal conserva el recopilador. Algunos guardan la marca del servidor o la de origen; otros, su propia hora de lectura. La guía sobre marcas temporales explica la diferencia.
Valide un punto antes de ampliar
Para el primer punto, anote el endpoint, la configuración de seguridad, el usuario, la URI de espacio de nombres, el NodeId, el tipo de datos, la unidad, cualquier escala y el intervalo de lectura. Después:
- Compare el valor con una referencia independiente mientras cambia.
- Registre el código de estado y las marcas temporales en el servidor, el recopilador y el destino final.
- Detenga la fuente o la conexión con autorización. Los datos deben mostrar un hueco o un estado Bad o Uncertain, no un valor anterior con una marca temporal nueva.
- Reinicie el recopilador y compruebe que vuelve a leer el mismo nodo.
- Intente leer un nodo inexistente y otro para el que el usuario no tenga permisos. Ambos deben fallar claramente y no devolver el valor de otro nodo.
Pruebe las escrituras por separado, con la autorización del responsable del equipo y una comprobación independiente del resultado físico.
OPC UA con Edge
Edge en el Gateway ZGW-20 actúa como cliente OPC UA. Se conecta a un endpoint con la política y el modo de seguridad que ofrezca el servidor (None, Sign o SignAndEncrypt), como usuario anónimo, con nombre de usuario o con certificado. Lee cada nodo de variable de forma programada, desde una vez por segundo hasta una vez al día, y aplica los multiplicadores y desplazamientos configurados. Edge identifica cada nodo por su cadena NodeId completa, de hasta 512 caracteres, incluido el índice de espacio de nombres. Copie el NodeId del espacio de direcciones del servidor, porque un nombre de exploración por sí solo no es una dirección, y compruebe el índice después de cualquier cambio del servidor. Edge asigna una marca temporal a cada valor cuando lo lee.
Preguntas frecuentes
¿Qué es un NodeId en OPC UA?
Es el identificador de un nodo en el espacio de direcciones de un servidor. Consta de un índice de espacio de nombres y un identificador, que puede ser un número, una cadena, un GUID o bytes. Por ejemplo, ns=2;s=LineA.Temperature identifica la cadena LineA.Temperature en el espacio de nombres 2.
¿Qué es un espacio de nombres OPC UA?
Es un grupo de identificadores de nodos nombrado mediante una URI. El servidor enumera sus espacios de nombres en NamespaceArray y un NodeId hace referencia a uno por su posición en esa matriz. La URI es estable; la posición, o índice, puede cambiar si cambia la configuración del servidor.
¿Qué diferencia hay entre un cliente y un servidor OPC UA?
El servidor posee el espacio de direcciones y ofrece servicios sobre él. El cliente se conecta y usa esos servicios para navegar, leer, escribir o suscribirse. Una aplicación puede desempeñar ambas funciones: por ejemplo, un Gateway que lee como cliente el servidor de un PLC y ofrece su propio servidor a SCADA.
¿Qué significa un código de estado OPC UA?
Cada valor devuelto por un servidor lleva un código de estado: Good, Uncertain o Bad, con un motivo. Un valor Bad no debe utilizarse como medición. Para los valores Uncertain se necesita una regla acordada para el proyecto.
¿Qué significa ns=2;s= en un NodeId OPC UA?
ns=2 es el índice del espacio de nombres, la posición 2 del NamespaceArray del servidor. s= indica que el identificador que sigue es una cadena. Los demás tipos de identificador son i= para un número, g= para un GUID y b= para bytes opacos en Base64. Un NodeId del espacio de nombres 0, como i=2258, se escribe sin ns=.
¿Puede cambiar el índice de espacio de nombres de un NodeId?
Sí. OPC 10000-5 prohíbe que un servidor modifique o elimine entradas de la tabla de espacios de nombres mientras un cliente tenga una sesión abierta, y recomienda que los servidores solo añadan entradas nuevas. También admite que un cambio puede ser inevitable, así que un cliente debe comprobar los índices al iniciar una sesión. La URI del espacio de nombres no cambia.