Volver al inicio

OPC UA en MFC: integración de open62541

El artículo describe la implementación técnica de un cliente OPC UA en una aplicación MFC en C++ usando open62541. Se cubren la conexión a controladores Siemens S7, configuración de suscripciones, seguridad, trabajo con SQL Server y características de integración en GUI de Windows.

OPC UA en MFC: guía técnica para desarrolladores
Advertisement 728x90

OPC UA en aplicaciones MFC: Integración de open62541 para SCADA industrial en Windows

Los sistemas de automatización industrial se están alejando cada vez más de las soluciones monolíticas y propietarias de SCADA, en favor de plataformas flexibles, seguras y multiplataforma basadas en OPC UA. En este contexto, desarrollar un sistema SCADA ligero basado en Microsoft Foundation Classes (MFC) con integración de open62541 se convierte en una opción técnicamente sólida para las empresas medianas—especialmente cuando se requiere compatibilidad con infraestructuras heredadas de Windows y estrictos requisitos de latencia para la comunicación con controladores Siemens S7-1200/S7-1500.

Cambio arquitectónico: de SCADA propietario a integración impulsada por OPC UA

Las plataformas tradicionales de SCADA (WinCC, InTouch, EcoStruxure) se construyen en torno a protocolos cerrados y dependencia del proveedor. Su despliegue requiere licencias, configuraciones extensas y, a menudo, resulta en instalaciones de software abultadas—los paquetes de instalación pueden alcanzar los 20 GB, aunque solo se utilice entre el 15% y el 20% de la funcionalidad. Para las pequeñas y medianas empresas, esto no es económicamente justificable.

OPC UA aborda tres desafíos sistémicos:

Google AdInline article slot
  • Interoperabilidad: Un espacio de direcciones unificado (NodeId), variables tipadas y un mecanismo de suscripción único permiten la agregación de datos de equipos de diferentes fabricantes sin necesidad de pasarelas intermedias.
  • Seguridad lista para usar: Soporte para certificados X.509, políticas de seguridad (None, Basic128Rsa15, Basic256Sha256) y cifrado y autenticación a nivel de protocolo.
  • Flexibilidad de despliegue: Los clientes pueden ser aplicaciones nativas de Windows (MFC/Win32), servicios web o microservicios ejecutándose en Linux—sin modificar la lógica del lado del servidor.

En la práctica industrial, esto significa reemplazar sistemas SCADA costosos por soluciones personalizadas que se conectan directamente a los controladores mediante OPC UA, se integran con SQL Server para almacenar recetas y datos históricos, y permiten la monitorización remota a través de gráficos y pantallas de estado de los equipos.

Integración de open62541 en MFC: características técnicas y limitaciones

open62541 es una biblioteca de código abierto compatible con C99 y sin dependencias, diseñada para sistemas embebidos y de escritorio. Utilizarla en un proyecto MFC requiere cumplir varias condiciones:

  • El proyecto debe compilarse en modo /MD (enlace dinámico a CRT), ya que open62541 depende de la biblioteca estándar de C.
  • Es necesario inicializar explícitamente la pila TLS/SSL al utilizar políticas de seguridad—in Windows, esto implica Wincrypt.h y CryptInitialize().
  • Todos los objetos como UA_Client, UA_CreateSubscriptionRequest y UA_MonitoredItemCreateRequest deben gestionarse manualmente: asignación de memoria, llamada a UA_Client_disconnect() y liberación con UA_Client_delete().

Una limitación crítica es la ausencia de un pool de hilos incorporado. En una aplicación MFC con un hilo de GUI, todas las llamadas a UA_Client_* deben ejecutarse en un hilo de trabajo separado (AfxBeginThread) o mediante PostMessage/WM_USER para evitar bloquear la interfaz. Llamar directamente a UA_Client_connect() en CMainFrame::OnInitialUpdate() provocará que la ventana se congele.

Google AdInline article slot

Implementación de la conexión y la suscripción en C++/MFC

La función CMainFrame::ConnectCPUOnline() muestra un escenario mínimamente viable para conectar con un servidor OPC UA. Inicializa el cliente, configura los parámetros y establece la conexión. Entre los puntos clave se encuentran:

  • Usar UA_String_fromChars() para convertir cadenas CT2A en UA_String—un requisito obligatorio de la API de open62541.
  • Configurar cc->securityMode = UA_MESSAGESECURITYMODE_NONE solo es aceptable en redes aisladas; en proyectos reales, hay que elegir UA_MESSAGESECURITYMODE_SIGNANDENCRYPT y cargar certificados mediante UA_ClientConfig_setDefaultEncryption().
  • Registrar en el nivel UA_LOGLEVEL_ERROR ofrece el equilibrio óptimo entre diagnóstico y rendimiento en producción.

Después de conectarse, se crea una suscripción y se configuran los elementos de monitoreo. A continuación, un fragmento de cómo crear una suscripción y agregar la primera etiqueta:

// Creación de una suscripción
UA_CreateSubscriptionRequest request = UA_CreateSubscriptionRequest_default();
request.requestedPublishingInterval = 500.0; // ms
request.requestedMaxKeepAliveCount = 10;
request.requestedLifetimeCount = 30;

UA_CreateSubscriptionResponse response = UA_Client_Subscriptions_create(
    StrCPUADR[iAdr].g_clientOnline, request, NULL, NULL, NULL);

if (response.responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
    return false;
}
StrCPUADR[iAdr].g_subscriptionId = response.subscriptionId;

// Configuración del monitoreo para la etiqueta
UA_MonitoredItemCreateRequest monRequest = UA_MonitoredItemCreateRequest_default();
monRequest.itemToMonitor.nodeId = UA_NODEID_NUMERIC(0, StrDBINI[i].iIDUA);
monRequest.itemToMonitor.attributeId = UA_ATTRIBUTEID_VALUE;
monRequest.monitoringMode = UA_MONITORINGMODE_REPORTING;

UA_MonitoredItemCreateResult monResponse = UA_Client_MonitoredItems_createSingle(
    StrCPUADR[iAdr].g_clientOnline,
    StrCPUADR[iAdr].g_subscriptionId,
    &monRequest);

Nótese que iIDUA es el NodeId del controlador obtenido de la base de datos (por ejemplo, ns=2;s=Channel1.Device1.Tag1). Debe coincidir exactamente con el espacio de direcciones del servidor. Errores en el NodeId resultan en UA_STATUSCODE_BADNODEIDUNKNOWN, pero no causan un fallo—verificar monResponse.statusCode es esencial.

Google AdInline article slot

Trabajar con datos: desde la lectura hasta el registro en SQL Server

El sistema utiliza tres estructuras clave para gestionar los datos:

  • StrDBCP—configuración para las conexiones a los controladores: dirección IP, estado online/offline, puntero a UA_Client*, ID de suscripción y un búfer arrayValue para recibir valores.
  • StrDBINI—metadatos de las etiquetas: iIDUA (NodeId), iTYPEID (tipo de dato: UA_TYPES_INT32, UA_TYPES_DOUBLE, UA_TYPES_BOOLEAN) y una bandera bSaveDb para el registro.
  • StrDBVAL—tabla de valores históricos con marcas temporales, CTime, iNOMEQ, iItem y iVal.

La lógica para actualizar los valores se implementa en la función de callback UA_Client_DataChangeNotification. Cuando se recibe un nuevo valor:

  • Verificar el iTYPEID y realizar un casting seguro del tipo usando UA_Variant_getScalarCopy().
  • Escribir en arrayValue[i] teniendo en cuenta sizearray.
  • Si bSaveDb == true, formar una sentencia INSERT parametrizada en SQL Server mediante CDatabase::ExecuteSQL().

Importante: todas las operaciones sobre arrayValue deben protegerse mediante una sección crítica (CCriticalSection), ya que los datos provienen de un hilo en segundo plano mientras el hilo de GUI puede solicitarlos simultáneamente para la renderización de gráficos.

Qué importa

  • OPC UA en una aplicación MFC requiere gestión manual del ciclo de vida de UA_Client: inicialización → conexión → suscripción → lectura → cancelación de la suscripción → desconexión → eliminación.
  • La seguridad no es opcional: SECURITYPOLICY_NONE solo es aceptable en entornos de prueba; en redes industriales, los certificados X.509 y SIGNANDENCRYPT son obligatorios.
  • open62541 no proporciona APIs asíncronas para la GUI de Windows—todas las operaciones de red deben realizarse en un hilo separado y luego sincronizarse mediante PostMessage.
  • Las estructuras StrDBCP, StrDBINI y StrDBVAL forman una capa de abstracción sobre OPC UA, permitiendo cambiar entre diferentes controladores sin modificar la lógica de manejo de datos.
  • Para soportar Siemens S7-1200/S7-1500, es necesario habilitar el servidor OPC UA en el firmware del controlador y configurar adecuadamente el Control de Acceso de Usuario (UAC) en TIA Portal.

— Editorial Team

Advertisement 728x90

Leer después