Aller au contenu

Module opcua

Le module opcua permet de communiquer avec des serveurs OPC UA (Unified Architecture) pour lire et écrire des données industrielles.

Import

Pour importer le module en Lua :

local opcua = require("opcua1")

Configuration YAML

Le module opcua nécessite une configuration dans le fichier YAML de l'agent :

iot:
  modules:
    opcua:
      - name: opcua1                                # nom unique de l'instance
        endpoint: "opc.tcp://localhost:4840"        # URL du serveur OPC UA
        cert_file: "/etc/alemca/opcua/client.pem"   # certificat client (optionnel)
        key_file: "/etc/alemca/opcua/client.key"    # clé privée RSA (optionnel)
        trusted_dir: "/etc/alemca/opcua/trusted"    # dossier certs serveur fiables (optionnel)
        username: ""                                # nom d'utilisateur (optionnel)
        password: ""                                # mot de passe (optionnel)
        timeout: 30                                 # timeout en secondes (optionnel, défaut: 30)

Détails de la configuration

  • name : Nom unique de l'instance du module. Utilisé pour l'import en Lua.
  • endpoint : URL complète du serveur OPC UA (format opc.tcp://host:port). L'agent utilise toujours cette URL comme cible de connexion, même si le serveur annonce une URL différente pendant la découverte — utile derrière un NAT ou dans des déploiements conteneurisés.
  • cert_file : Chemin vers le certificat client au format PEM. Quand fourni (avec key_file), active le SecureChannel chiffré et signé. La policy et le mode sont auto-négociés avec le serveur (typiquement Basic256Sha256 + SignAndEncrypt). Le certificat doit contenir un ApplicationURI dans les Subject Alternative Names (exigence OPC UA).
  • key_file : Chemin vers la clé privée RSA au format PEM (PKCS#1 ou PKCS#8). Doit correspondre à cert_file. Permissions recommandées : 0600 (un warning est loggé sinon).
  • trusted_dir : Dossier optionnel contenant les certificats serveur de confiance (*.pem, *.crt). Si renseigné, seuls les serveurs dont le certificat vérifie contre ce pool sont acceptés ; sinon, tout certificat serveur est accepté.
  • username / password : Authentification utilisateur optionnelle.
  • timeout : Délai d'attente pour les opérations, en secondes (défaut: 30).

Génération d'un certificat client

Le serveur OPC UA exige qu'un ApplicationURI soit présent dans le SAN du certificat client. Exemple avec OpenSSL :

openssl req -x509 -newkey rsa:2048 \
  -keyout client.key -out client.pem \
  -days 3650 -nodes \
  -subj "/CN=alemca-agent" \
  -addext "subjectAltName=URI:urn:alemca:agent"
chmod 600 client.key

Déposez ensuite client.pem dans la trust list du serveur OPC UA (la procédure dépend du serveur : souvent un dossier pki/trusted/ avec redémarrage du service).

Migration depuis les anciennes versions

Les champs security_policy et security_mode ne sont plus reconnus. Ils sont silencieusement ignorés dans les anciennes configurations. Pour activer la sécurité, fournissez désormais cert_file et key_file : la policy et le mode sont auto-négociés à partir des endpoints que le serveur annonce.

API Lua

Liste des fonctions

Fonction Signature Lua Rôle Retour (succès) Retour (échec)
connect bool, err = opcua.connect() Connecte au serveur OPC UA. true, nil nil, "msg"
disconnect bool, err = opcua.disconnect() Ferme la connexion. true, nil nil, "msg"
read value, err = opcua.read(nodeId) Lit la valeur d'un noeud. string, nil nil, "msg"
write bool, err = opcua.write(nodeId, value) Écrit une valeur dans un noeud. true, nil nil, "msg"
Champs opcua.name, opcua.type Métadonnées du module.

opcua.connect()

Établit une connexion avec le serveur OPC UA.

  • Paramètres : Aucun
  • Retour :
  • true si la connexion est réussie.
  • nil et un message d'erreur en cas d'échec.
local opcua = require("opcua1")

local ok, err = opcua.connect()
if not ok then
    print("Erreur de connexion : " .. err)
    return
end

print("Connecté au serveur OPC UA")

opcua.disconnect()

Ferme la connexion avec le serveur OPC UA.

  • Paramètres : Aucun
  • Retour :
  • true si la déconnexion est réussie.
  • nil et un message d'erreur en cas d'échec.
local opcua = require("opcua1")

local ok, err = opcua.disconnect()
if not ok then
    print("Erreur de déconnexion : " .. err)
end

opcua.read(nodeId)

Lit la valeur d'un noeud OPC UA.

  • Paramètres :
  • nodeId (string) : Identifiant du noeud à lire (ex. ns=2;s=Temperature).

  • Retour :

  • La valeur du noeud (convertie en string).
  • nil et un message d'erreur en cas d'échec.
local opcua = require("opcua1")

opcua.connect()

-- Lecture d'un noeud par son NodeId
local value, err = opcua.read("ns=2;s=Temperature")
if not value then
    print("Erreur de lecture : " .. err)
else
    print("Température : " .. value)
end

opcua.disconnect()

opcua.write(nodeId, value)

Écrit une valeur dans un noeud OPC UA.

  • Paramètres :
  • nodeId (string) : Identifiant du noeud à écrire.
  • value (string) : Valeur à écrire.

  • Retour :

  • true si l'écriture est réussie.
  • nil et un message d'erreur en cas d'échec.
local opcua = require("opcua1")

opcua.connect()

-- Écriture d'une valeur
local ok, err = opcua.write("ns=2;s=Setpoint", "25.5")
if not ok then
    print("Erreur d'écriture : " .. err)
else
    print("Valeur écrite avec succès")
end

opcua.disconnect()

Exemple complet

local opcua = require("opcua1")
local json = require("json")
local alemca = require("alemca")

-- Connexion au serveur
local ok, err = opcua.connect()
if not ok then
    printError("Connexion OPC UA échouée : " .. err)
    return
end

-- Lecture de plusieurs noeuds
local nodes = {
    "ns=2;s=Temperature",
    "ns=2;s=Humidity",
    "ns=2;s=Pressure"
}

local data = {}
for _, nodeId in ipairs(nodes) do
    local value, err = opcua.read(nodeId)
    if value then
        data[nodeId] = tonumber(value) or value
    else
        printError("Erreur lecture " .. nodeId .. " : " .. err)
    end
end

-- Publication des données
alemca.publish(json.encode(data), "opcua_data")

-- Déconnexion
opcua.disconnect()

Formats de NodeId

Les NodeId OPC UA peuvent être spécifiés dans plusieurs formats :

Format Exemple Description
Numérique ns=0;i=2258 Identifiant numérique
String ns=2;s=Temperature Identifiant texte
GUID ns=1;g=09087e75-8e5e-499b-954f-f2a9603db28a Identifiant GUID
Opaque ns=1;b=M/RbKBsRVkePCePcx24oRA== Identifiant opaque (base64)

Champs Lua associés

  • opcua.name : Retourne le nom de l'instance du module.
  • opcua.type : Retourne le type du module ("opcua").