Retour à l'accueil

OPC UA dans MFC : intégration de open62541

L'article décrit la mise en œuvre technique d'un client OPC UA dans une application MFC en C++ utilisant open62541. Sont couverts : la connexion aux contrôleurs Siemens S7, la configuration des abonnements, la sécurité, le travail avec SQL Server et les particularités de l'intégration dans l'interface graphique Windows.

OPC UA dans MFC : guide technique pour les développeurs
Advertisement 728x90

Intégration d’OPC UA dans les applications MFC : Utilisation d’open62541 pour un SCADA industriel sous Windows

Les systèmes d’automatisation industrielle s’éloignent de plus en plus des solutions monolithiques et propriétaires de SCADA au profit de plateformes flexibles, sécurisées et multiplateformes basées sur OPC UA. Dans ce contexte, développer un système SCADA léger reposant sur Microsoft Foundation Classes (MFC) avec intégration d’open62541 constitue un choix techniquement solide pour les entreprises de taille moyenne — notamment lorsque la compatibilité avec les infrastructures Windows héritées et des exigences strictes en matière de latence pour la communication avec les contrôleurs Siemens S7-1200/S7-1500 sont requises.

Changement architectural : du SCADA propriétaire à l’intégration pilotée par OPC UA

Les plateformes SCADA traditionnelles (WinCC, InTouch, EcoStruxure) sont construites autour de protocoles fermés et d’un verrouillage fournisseur. Leur déploiement nécessite des licences, une configuration approfondie et entraîne souvent des installations logicielles gonflées — les packages d’installation peuvent atteindre 20 Go, alors que seulement 15 à 20 % des fonctionnalités sont réellement utilisées. Pour les petites et moyennes entreprises, cela n’est pas économiquement justifié.

OPC UA répond à trois défis systémiques :

Google AdInline article slot
  • Interopérabilité : un espace d’adressage unifié (NodeId), des variables typées et un mécanisme de subscription unique permettent de collecter les données provenant d’équipements de différents fabricants sans passer par des passerelles intermédiaires.
  • Sécurité prête à l’emploi : prise en charge des certificats X.509, des politiques de sécurité (None, Basic128Rsa15, Basic256Sha256) ainsi que du chiffrement et de l’authentification au niveau du protocole.
  • Flexibilité de déploiement : les clients peuvent être des applications natives Windows (MFC/Win32), des services web ou des microservices exécutés sous Linux — sans modifier la logique côté serveur.

Dans la pratique industrielle, cela signifie remplacer les coûteux systèmes SCADA par des solutions sur mesure qui se connectent directement aux contrôleurs via OPC UA, s’intègrent à SQL Server pour stocker les recettes et les données historiques, et permettent la surveillance à distance grâce à des graphiques et des affichages de l’état des équipements.

Intégration d’open62541 dans MFC : caractéristiques techniques et limites

open62541 est une bibliothèque open source conforme à C99 et sans dépendance externe, conçue pour les systèmes embarqués et de bureau. Son utilisation dans un projet MFC impose de respecter plusieurs conditions :

  • Le projet doit être compilé en mode /MD (liaison dynamique à la CRT), car open62541 repose sur la bibliothèque standard C.
  • Une initialisation explicite de la pile TLS/SSL est nécessaire lorsqu’on utilise des politiques de sécurité ; sous Windows, cela implique Wincrypt.h et CryptInitialize().
  • Tous les objets tels que UA_Client, UA_CreateSubscriptionRequest et UA_MonitoredItemCreateRequest doivent être gérés manuellement : allocation de mémoire, appel à UA_Client_disconnect() et libération avec UA_Client_delete().

Une limitation critique est l’absence d’un pool de threads intégré. Dans une application MFC avec un thread GUI, tous les appels à UA_Client_* doivent être exécutés dans un thread de travail séparé (AfxBeginThread) ou via PostMessage/WM_USER afin d’éviter de bloquer l’interface. Appeler directement UA_Client_connect() dans CMainFrame::OnInitialUpdate() provoquera le blocage de la fenêtre.

Google AdInline article slot

Implémentation de la connexion et de la subscription en C++/MFC

La fonction CMainFrame::ConnectCPUOnline() illustre un scénario minimalement viable pour se connecter à un serveur OPC UA. Elle initialise le client, configure les paramètres et établit la connexion. Les points clés incluent :

  • L’utilisation de UA_String_fromChars() pour convertir les chaînes CT2A en UA_String — une exigence obligatoire de l’API open62541.
  • Définir cc->securityMode = UA_MESSAGESECURITYMODE_NONE n’est acceptable qu’en réseaux isolés ; dans les projets réels, il faut choisir UA_MESSAGESECURITYMODE_SIGNANDENCRYPT et charger les certificats via UA_ClientConfig_setDefaultEncryption().
  • Une journalisation au niveau UA_LOGLEVEL_ERROR représente le meilleur compromis entre diagnostic et performance en production.

Après la connexion, une subscription est créée et les items de monitoring sont configurés. Voici un extrait de la manière de créer une subscription et d’ajouter la première tag :

// Création d’une subscription
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;

// Configuration du monitoring pour la tag
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);

Notez que iIDUA est le NodeId du contrôleur obtenu depuis la base de données (par exemple, ns=2;s=Channel1.Device1.Tag1). Il doit correspondre exactement à l’espace d’adressage du serveur. Une erreur dans le NodeId entraîne UA_STATUSCODE_BADNODEIDUNKNOWN, mais ne provoque pas de crash — il est essentiel de vérifier monResponse.statusCode.

Google AdInline article slot

Travail avec les données : de la lecture au journaling dans SQL Server

Le système utilise trois structures clés pour gérer les données :

  • StrDBCP — configuration des connexions aux contrôleurs : adresse IP, statut en ligne/offline, pointeur vers UA_Client*, ID de subscription et un buffer arrayValue pour recevoir les valeurs.
  • StrDBINI — métadonnées des tags : iIDUA (NodeId), iTYPEID (type de donnée : UA_TYPES_INT32, UA_TYPES_DOUBLE, UA_TYPES_BOOLEAN) et un drapeau bSaveDb pour le journaling.
  • StrDBVAL — table des valeurs historiques avec horodatages, CTime, iNOMEQ, iItem et iVal.

La logique de mise à jour des valeurs est implémentée dans la fonction de rappel UA_Client_DataChangeNotification. Lorsqu’une nouvelle valeur est reçue :

  • Vérifier le iTYPEID et effectuer un casting sûr du type à l’aide de UA_Variant_getScalarCopy().
  • Écrire dans arrayValue[i] en tenant compte de sizearray.
  • Si bSaveDb == true, former une instruction INSERT paramétrée dans SQL Server via CDatabase::ExecuteSQL().

Important : toutes les opérations sur arrayValue doivent être protégées par une section critique (CCriticalSection), car les données proviennent d’un thread en arrière-plan tandis que le thread GUI peut simultanément les demander pour le rendu des graphiques.

Ce qui compte

  • OPC UA dans une application MFC exige une gestion manuelle du cycle de vie de UA_Client : initialisation → connexion → subscription → lecture → désinscription → déconnexion → suppression.
  • La sécurité n’est pas optionnelle : SECURITYPOLICY_NONE n’est acceptable qu’en environnement de test ; dans les réseaux industriels, les certificats X.509 et SIGNANDENCRYPT sont obligatoires.
  • open62541 ne fournit pas d’APIs asynchrones pour l’interface Windows — toutes les opérations réseau doivent être effectuées dans un thread séparé puis synchronisées via PostMessage.
  • Les structures StrDBCP, StrDBINI et StrDBVAL forment une couche d’abstraction au-dessus d’OPC UA, permettant de basculer entre différents contrôleurs sans changer la logique de traitement des données.
  • Prendre en charge les Siemens S7-1200/S7-1500 nécessite d’activer le serveur OPC UA dans le firmware du contrôleur et de configurer correctement le Contrôle d’accès utilisateur (UAC) dans TIA Portal.

— Editorial Team

Advertisement 728x90

Lire ensuite