Desarrollando un servidor OPC-UA con open62541

 

En los últimos años una de las principales tendencias en el sector de automatización industrial es la llegada de la llamada Industria 4.0 o cuarta revolución industrial, un nuevo paradigma dentro de la fabricación. Esta revolución implicará un cambio en los procesos de fabricación y modelos de negocio existentes en la actualidad gracias a la influencia de diversas tecnologías recientes como IoT (Internet de las Cosas), Big Data y las técnicas de análisis de datos. Una de estas tecnologías, que cuenta cada vez con una mayor repercusión, es OPC-UA [1].

OPC-UA, estandarizado bajo la norma IEC 62541, se plantea como una evolución del antiguo estándar OPC para crear una arquitectura orientada a servicios que permita aumentar la interoperabilidad de los activos desplegados en un entorno industrial, con independencia de la plataforma empleada, y conectar los sistemas de producción con los sistemas ERP, MES u otro tipo de herramienta empresarial. Ofrece además otras múltiples características como mecanismos de seguridad de autenticación y confidencialidad, descubrimiento de nodos o un modelo de información basado en objetos para el acceso simplificado a los datos. Es importante destacar que esta arquitectura no se plantea como una sustitución a las múltiples tecnologías de campo ya empleadas desde hace años para la transmisión de información en planta (Modbus, Profinet, DNP3…) sino que, en cierta medida, es un elemento paralelo que permite extender el alcance de la información de la planta de producción más allá de la misma o de las celdas de producción que existen en ella.

Son ya varios los fabricantes de productos orientados al sector industrial que incorporan en su portfolio sistemas que incorporan esta arquitectura, sobre todo a nivel europeo. Por ejemplo, Siemens ya incorpora servidores OPC-UA en sus controladores SIMATIC S7-1500 [2] o Beckhoff también permite desplegarlos dentro de su solución TwinCAT [3].

Por otro lado, existen múltiples SDK y frameworks para el desarrollo de soluciones OPC-UA, muchas de ellas de código abierto [4], y entre ellas las propias librerías desarrolladas dentro de la fundación OPC [5]. Hemos decidido escoger open62541 [6] por la elevada actividad del proyecto y la versatilidad de su licencia Mozilla v2.0. No obstante, es necesario destacar también que diversas funcionalidades como el cifrado todavía no se han implementado completamente (aunque muchas de ellas se incorporarán en la siguiente versión de la librería). En este enlace se pueden consultar las funcionalidades disponibles dentro de la rama master del proyecto así como el estado de las que están por implementar.

A lo largo de la próxima sección demostraremos las características básicas de esta librería a través de la creación de un servidor en código C que desplegado sobre una Beaglebone [7] permitirá leer el estado de un sencillo sensor de paso.

Programando el servidor OPC-UA

Obtención de la librería y compilación

En primer lugar nos aseguraremos que instalamos, si no las tenemos ya en nuestro sistema, las dependencias necesarias para compilar la librería.

 

También puede ser de utilidad que instalemos otras dependencias necesarias para otras funcionalidades:

 A continuación, clonaremos dentro de un directorio de nuestra elección la propia librería para proceder a compilarla.

Para compilar la librería seguiremos el procedimiento habitual con los proyectos en los que se emplea cmake:

Deberemos activar la opción UA_ENABLE_AMALGAMATION, que nos permite obtener toda la librería en dos únicos ficheros open62541.c y open62541.h. Para este ejemplo no será necesario, pero si así lo queremos es posible también activar o desactivar otras opciones de la librería.

 

Guardamos esta configuración y pasamos a compilar la librería:

Al cabo de un tiempo el proceso de compilación finalizará y tendremos dentro del directorio en el que nos encontramos los dos ficheros de la librería listos para emplear en nuestro proyecto.

Configuración inicial del proyecto

En primer lugar crearemos la estructura de directorios adecuada para nuestro proyecto:

Copiamos los ficheros de la librería de OPC-UA compilados previamente en el directorio para librerías que acabamos de crear en la estructura de nuestro proyecto.

Finalmente crearemos el fichero que contendrá el código de nuestro servidor OPC_UA:

Programación básica de un servidor

A continuación pasamos ya a crear el código para hacer funcionar nuestro servidor OPC-UA. En primer lugar nos situaremos en la carpeta del proyecto en la que guardamos el código fuente:

[code language=”bash” gutter=”false”]$ cd opcsensor/src/[/code]

El siguiente paso será abrir con nuestro editor favorito el fichero server.c que creamos anteriormente. Dentro del mismo introduciremos el siguiente código: accede al código aquí.

Verificamos que el servidor funciona correctamente compilándolo y ejecutándolo:

Posteriormente, añadiremos en primer lugar el código para definir nuestro modelo de datos, que en este caso será muy sencillo y se compondrá únicamente de una variable de tipo uint_32 para contar el número de veces que un objeto pasa por el sensor de paso. Actualizaremos el fichero fuente del servidor con el siguiente código, en el que se han añadido dos métodos adicionales y una variable global con las funciones explicadas en los comentarios del código: accede al código aquí.

 

Ahora lo único que nos falta por hacer es conectar el sensor físicamente a nuestra Beaglebone y crear el código para monitorizar su estado.

Conexión con el sensor de paso

Como ya se ha comentado previamente, para este pequeño tutorial vamos a emplear un sencillo sensor de paso infrarrojo como el que se puede ver en la figura para detectar el paso de objetos en su camino. Este sensor da continuamente un nivel alto hasta que un objeto bloquea el camino, en cuyo caso da un nivel bajo.

Para conectarlo a la Beaglebone emplearemos el GPIO60, para lo que conectaremos la tierra del mismo al pin 1 del P9 y la alimentación al pin 3 del P9. El cable que nos dará el valor del sensor lo conectaremos al pin 12 del P9. Las conexiones se pueden ver en el siguiente enlace o en la siguiente figura.

Una vez conectado físicamente el sensor a la Beaglebone sólo quedará actualizar el código para poder leer sus valores. Para ello emplearemos un thread paralelo al servidor principal que se encargará de muestrear la lectura del fichero del sensor y actualizar el contador correspondiente (NOTA: también podríamos usar alguna de las librerías disponibles para la Beaglebone para trabajar con interrupciones de manera más eficiente). El código actualizado es el siguiente: accede al código aquí.

Compilamos el servidor añadiendo la librería pthread y lo ejecutaremos con permisos de root para poder acceder sin problemas a los ficheros de los GPIOs (también podríamos configurar los permisos de estos ficheros para acceder a ellos desde nuestro usuario):

 

$ gcc -std=c99 -I../lib/open62541 ../lib/open62541/open62541.c server.c -o server -lpthread -lrt

$ sudo ./server

 

Para verificar que funciona correctamente podríamos programar nuestro propio cliente OPC-UA con la librería pero en este caso emplearemos el programa UaExpert (el programa es gratuito pero es necesario registrarse para descargarlo).

En primer lugar debemos añadir el servidor que queremos monitorizar. Para ello es necesario pulsar en el botón con un signo “+” en la barra de herramientas de la aplicación.

Se desplegará un cuadro y haremos doble click bajo la opción de “Custom Discovery”, lo que abrirá un nuevo cuadro en el que tendremos que introducir la IP y puerto de nuestra Beaglebone, tal y como aparece en la siguiente figura.

A continuación desplegamos el nuevo campo representando el servidor que se acaba de descubrir y lo seleccionamos, pulsando OK para finalizar y añadir el servidor a la lista.

Una vez añadido ya podremos visualizar los objetos incluidos dentro del servidor OPC-UA que hemos programado tras conectarnos al mismo (click derecho sobre el servidor->conectar). Aparecerán en la parte izquierda de la pantalla. En este caso aparece el nodo “Pieces counter” y “Server”, añadido por la propia librería open62541 y que contiene información del servidor. El valor actual del nodo se mostrará a la derecha de la pantalla, dentro del cuadro denominado “Attributes”.

Y con esto ya tenemos funcionando un servidor OPC-UA bastante simple que actualiza el valor de un nodo en función del valor dado por un sensor.

Conclusiones y avances futuros

A lo largo de este artículo hemos realizado una breve introducción a una de las tecnologías más prometedoras dentro de la Industria 4.0 a través de la creación de un simple servidor para la lectura de datos de sensores conectados a una Beaglebone.

Este servidor se puede completar en muchos sentidos para tener una aplicación más cercana a su aplicación en un entorno real. Algunos de los puntos de mejora son los siguientes:

  • Configuración de la autenticación. Con este código cualquiera podría acceder al servidor directamente conociendo su dirección IP y puerto. La librería open62541 tiene implementadas algunas de las funcionalidades de autenticación del estándar, que podríamos emplear en este servidor para proteger su acceso.
  • Cifrado en el transporte. Los datos en este momento se transmiten en claro, por lo que cualquier persona con acceso a la red por la que se transmiten podría verlos. Actualmente la librería ya dispone de algunas capacidades de cifrado incorporadas en la rama master, que se podrían configurar para la protección de la información transmitida.
  • Configuración del nodo contador para soportar suscripciones. De esta forma no sería necesario consultar su estado para obtener el valor del contador ya que el propio servidor se encargaría de enviar los datos al actualizarse.
  • Envío de la información a servidores empresariales o en la nube. Se trata de una funcionalidad no contemplada en la librería open62541 pero que permitiría hacer uso de herramientas Big Data o de análisis de datos de una manera sencilla (aunque este ejemplo concreto se ha simplificado demasiado para que el uso de estas herramientas tenga sentido).

Dentro de Gradiant trabajamos con esta tecnología y librería para mejorar la operativa de los procesos industriales. Para ello, estamos desarrollando servidores OPC-UA fácilmente desplegables y configurables, incluidos dentro de tecnologías de contenedores y con una conectividad y seguridad mejorada para la transmisión de la información de planta, u otros elementos, a un bus de datos. Este bus de datos permite aumentar la visibilidad de los procesos industriales, eliminando los tradicionales silos de información existentes en los mismos. A partir del mismo, basado en tecnologías estándar AMQP, se facilita la creación de un ecosistema para el almacenamiento, análisis y visualización de la información empleando otras tecnologías como Logstash, ElasticSearch o Kibana, posibilitando la conexión y despliegue sencillo de muchas otras según las necesidades de cada caso final.

Dentro de los objetivos futuros que tenemos en Gradiant para esta arquitectura se encuentran puntos tan diversos como la instanciación automática de nodos OPC-UA en base a la definición de modelos de datos y las necesidades de cada caso de uso, la aplicación de técnicas de aprendizaje máquina en el edge para el análisis de los procesos o la detección de intrusiones en los sistemas industriales junto a modificaciones dinámicas en la topología de la red industrial o la aplicación de blockchain y smart contracts en la arquitectura OPC-UA.

Referencias

[1] https://opcfoundation.org/about/opc-technologies/opc-ua/

[2] http://w3.siemens.com/mcms/automation-software/en/tia-portal-software/step7-tia-portal/simatic-step7-options/opc-ua-s7-1500/pages/default.aspx

[3] https://www.beckhoff.com/english.asp?twincat/twincat_opc_ua_server.htm

[4] https://github.com/open62541/open62541/wiki/List-of-Open-Source-OPC-UA-Implementations

[5] https://github.com/OPCFoundation

[6] https://open62541.org/

[7] https://beagleboard.org/black

 

 

 

 


Autor: Daniel García Coego, responsable técnico IoT y CPS en el área de Sistemas Inteligentes en Red (INetS) de Gradiant