Sei sulla pagina 1di 5

Gestione Progetto robertomana.

it
A nodejs OPCUA SERVER Interface

A nodejs OPCUA SERVER Interface


Rev Digitale 1.1 del 01/09/2019

Il codice che segue è stato scritto da Etienne Erossignon sed è disponibile su github all’indirizzo
https://github.com/node-opcua/node-opcua
http://documentation.unified-automation.com/uasdkdotnet/2.4.2/html/group__NetUaClientSdk.html

Richiede le seguenti dipendenze:


express
node-opcua
async
http
socket.io

Scrittura di un client node.js

Il client, avviata l’applicazione, mediante il metodo async.series([tasks], callback) esegue in


sequenza i seguenti 5 task:

1) Connessione al server
var client = new opcua.OPCUAClient();
client.connect(endpointUrl,function (err) { });

2) Crezione di una sessione di lavoro. Una connessione può gestire più sessioni di lavoro
var the_session = client.createSession( function(err) { });

3) Eventuale Visualizzazione dei nodi esistenti


the_session.browse("RootFolder", function(err){
Viusalizza sul Log i nodi di primo livello appesi a RootFolder :
Objects, Types, News
}

4) Creazione di una Subscription. Una sessione di lavoro può gestire più Subscription.
Per la lettura continua delle variabili, OPC UA utilizza una funzionalità molto più efficace rispetto al vecchio
polling, la cosiddetta Subscription. Un client OPC UA può definire un insieme di variabili e chiedere al
server di essere lui a monitorare queste variabili. In caso di variazione del valore di queste variabili, sarà il
server a notificare al client questa variazione tramite apposito messaggio. In questo modo si ottiene una
fortissima riduzione nello scambio dei messaggi a vantaggio di una maggiore velocità.
Una Subscription deve contenere almeno una variabile detta Monitored Item, ma può raggruppare anche più
variabili anche di tipo differente, creando una porzione di informazione detta Notification. Una Notification
quindi può contenere più Monitored Items che verranno inviati al client tutti insieme in un unico messaggio.

Quando il client imposta una Subscription deve impostare alcuni parametri:

pag 1
Gestione Progetto robertomana.it
A nodejs OPCUA SERVER Interface

 Il samplingInterval definisce, individualmente per ogni singolo Monitored Item, il tempo di


campionamento utilizzato dal server per valutare eventuali variazioni sulla variabile
 Il publishingInterval definisce invece l’intervallo di tempo (regolare) entro cui il server, in caso di
variazioni, invia al client la Notification completa. In pratica si può chiedere al server di eseguire sulla
variabile un campionamento abbastanza rapido. Se in corrispondenza del campionamento il server
intercetta una variazione, memorizza il nuovo valore all’interno di una coda. Allo scadere del
publishingInterval invia al client l’intera coda relativa anche a variabili multiple (sempre che la coda non
sia vuota). In questo modo il client può intercettare (e, ad esempio, memorizzare in un database) anche
variazioni molto rapide che diversamente andrebbero perse. Il valore di default è 1000 msec.
 queueSize definisce, individualmente per ogni singolo Monitored Item, la dimensione della coda sul
server entro la quale memorizzare le variazioni intermedie della variabile stessa. Maggiore è la differenza
fra il samplingInterval ed il publishingInterval, maggiore dovrà essere la dimensione della
queueSize. Quando i dati vengono inviati al client (publish) la coda viene svuotata. Se la dimensione
della queue size non è sufficiente, in corrispondenza di un nuovo valore il valore più vecchio viene
rimosso (discardOldest: true).
 keepAliveCount Se allo scadere del publishingInterval la coda è vuota, il server non invia
nulla. Il keepAliveCount indica quanti invii possono essere tralasciati, prima che una “empty
notification” venga inviata comunque. Questa “empty notification” server per avvisare il client che il
server è sempre attivo anche se non ha dati da segnalare
 lifetimeCount Anche il server ha bisogno di sapere se il client è ancora attivo. lifetimeCount
indica il numero di publishingInterval con cui il client invia al server una publishRequest per
segnalare al server che è ancora attivo. Se il server non riceve questo messaggio rimuove la Subscription e
cessa di inviare Notifiche al client. Si consiglia per questo parametro di impostare un valore grande
almeno 3 volte il keep alive count.

 publishingEnabled Flag che indica se la pubblicazione è abilitata o meno. Il client può decidere in
certe fasi di disabilitare temporaneamente la pubblicazione del server.
 priority Quando più Subscriptions necessitano di inviare contemporaneamente una notifica al client,
viene servita prima la Subcription con priority maggiore. Il valore di default è 1. Sono ammessi valori tra 1
e 100.
 maxNotificationsPerPublish indica il numero massimo di notifiche (subscription) che il server
può inviare al client in corrispondenza del messaggio di publishing. È deciso dal client, ma il server può
inviarne un numero massimo minore in base al proprio limite stabilito. Se non tutte le notifiche disponibili
possono essere inviate in un unico messaggio, verranno inviati più messaggi.

All’interno della funzione 4 di creazione della Subscription vengono eseguite diverse azioni:
a. Creazione della subscription
var the_subscription=new opcua.ClientSubscription(the_session, {params})
params è un object contenente le impostazioni sopra descritte relative al client

b. Richiamo della callback in corrispondenza della terminazione


the_subscription.on("started",function(){
console.log("Subscription Started - Id=",the_subscription.subscriptionId)
});
the_subscription.on ("terminated",function(){
callback();
});

pag 2
Gestione Progetto robertomana.it
A nodejs OPCUA SERVER Interface

Come s può vedere la funzione di callback viene richiamata soltanto in corrispondenza dell’evento
“terminated” della Subscription, cioè nel momento in cui qualcuno termina esplicitamente la
Subscription. Non richiamando la funzione di callback, async.series rimane bloccata e non esegue mai la
callback finale.

c. Eventuale impostazione esplicita della termianzione


La terminazione della Subscription può essere eseguita in corrispondenza di un certo pulsante
dell’interfaccia grafica oppure dopo un certo tempo (es 60 sec).

setTimeout(function(){
the_subscription.terminate();
},60000);

d. Creazione dei monitored items

Questo è il passo centrale di tutto il codice; quello in cui, tramite il metodo monitor, viene definita la
variabile da monitorare e, al contempo, viene avviata la monitorizzazione:
var monitoredItem = the_subscription.monitor(
{
nodeId: opcua.resolveNodeId("ns=4;s=tappe"),
attributeId: opcua.AttributeIds.Value
},
{
// Server parameters
samplingInterval: 100,
queueSize: 10,
discardOldest: true
},
opcua.read_service.TimestampsToReturn.Both
);

Il metodo .monitor dell’oggetto Subscription si aspetta 3 parametri:


 Il primo parametro è un object contenente due informazioni: il nodeID del nodo da monitorare
(espresso come stringa) e che cosa si vuole monitorare di quel nodo, tipicamente il suo value
(attribute Id=13). tappe in pratica è il nome della variabile da monitorare.
 Il secondo parametro è un oggetto contenete i Server Parameters relativi a questa singola
variabile. Per ogni variabile si possono impostare i suoi Server Parameters
 Il terzo parametro opcua.read_service.TimestampsToReturn.Both fa sì che il
server ritorni anche i due TimeStamps (sourceTimeStamp e serverTimeStamp) relativi a data e ora
della lettura. Il valore di default è none, che andrebbe benissimo, per cui questa riga potrebbe
tranquillamente essere eliminata. Per maggiori dettagli si rimanda al seguente link
https://readthedocs.web.cern.ch/display/ICKB/OPC-UA+time-stamps+on+WinnCC+OA

e. Lettura dei valori


monitoredItem.on("changed",function(dataValue){
tappe = dataValue.value.value;
console.log("VALORE = ", tappe);
});
Evento richiamato in corrispondenza di ogni variazione della variabile. Il valore letto viene salvato nella
variabile globale tappe.

pag 3
Gestione Progetto robertomana.it
A nodejs OPCUA SERVER Interface

5) Chiusura della sessione di lavoro. La 5° funzione di async.series (che si avvia soltanto nel momento in cui
viene terminata la Subscription) si limita a chiudere la sessione di lavoro:
the_session.close(function(err) { });

Schermata di funzionamento :

pag 4
Gestione Progetto robertomana.it
A nodejs OPCUA SERVER Interface

Scrittura di una variabile da nodejs verso l’OPC UA SERVER

Il seguente codice è decisamente auto esplicativo:


app.get('/set', function (req, res) {
var vet = new Array(32);
for (var i=0; i<32; i++)
vet[i]=false;
vet[8]=true; // M1.0
vet[24]=true; // M3.0
var dataToWrite = {
dataType: "Boolean",
value: vet
};
the_session.writeSingleNode("ns=4;s=uscite", dataToWrite,
function(err, statusCode, diagnosticInfo) {
if (!err) {
console.log(" write ok" );
res.send('OK');
//console.log(diagnosticInfo);
//console.log(statusCode);
}
else {
console.log("Errore :" + err );
res.send('NOK');
}
});
});

pag 5

Potrebbero piacerti anche