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 :
- 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.hetCryptInitialize(). - Tous les objets tels que
UA_Client,UA_CreateSubscriptionRequestetUA_MonitoredItemCreateRequestdoivent être gérés manuellement : allocation de mémoire, appel àUA_Client_disconnect()et libération avecUA_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.
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înesCT2AenUA_String— une exigence obligatoire de l’API open62541. - Définir
cc->securityMode = UA_MESSAGESECURITYMODE_NONEn’est acceptable qu’en réseaux isolés ; dans les projets réels, il faut choisirUA_MESSAGESECURITYMODE_SIGNANDENCRYPTet charger les certificats viaUA_ClientConfig_setDefaultEncryption(). - Une journalisation au niveau
UA_LOGLEVEL_ERRORrepré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.
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 versUA_Client*, ID de subscription et un bufferarrayValuepour 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 drapeaubSaveDbpour le journaling.StrDBVAL— table des valeurs historiques avec horodatages,CTime,iNOMEQ,iItemetiVal.
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
iTYPEIDet effectuer un casting sûr du type à l’aide deUA_Variant_getScalarCopy(). - Écrire dans
arrayValue[i]en tenant compte desizearray. - Si
bSaveDb == true, former une instruction INSERT paramétrée dans SQL Server viaCDatabase::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_NONEn’est acceptable qu’en environnement de test ; dans les réseaux industriels, les certificats X.509 etSIGNANDENCRYPTsont 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,StrDBINIetStrDBVALforment 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
Aucun commentaire pour le moment.