node-opcua icon indicating copy to clipboard operation
node-opcua copied to clipboard

Publish on opcua server

Open FabioAlmeida25 opened this issue 3 years ago • 13 comments

Hello guys! I am using node opc ua, and I know how to do a subscription on opcua server, but I don't know how to do a publish on my opcua server. Anyone can help me please, or send me a example??

Thank You.

FabioAlmeida25 avatar Oct 04 '21 19:10 FabioAlmeida25

https://reference.opcfoundation.org/v104/Core/docs/Part4/5.13.1/

a datachange notification is triggered if the vlaue changes or the statuscode!

AndreasHeine avatar Oct 04 '21 20:10 AndreasHeine

Thanks for your response. For example, imagine I want to send number of button clicks to opcua server, how I do that?

io.on('connection', function(client) {  
            //when the server receives clicked message, do this
            client.on('clicked', function(data) {
                  clickCount++;
                  //send a message to ALL connected clients
                  io.emit('buttonUpdate', clickCount);
            });
        });

FabioAlmeida25 avatar Oct 05 '21 09:10 FabioAlmeida25

Websocketclient (sends msg) -> [ Websocketserver (onmessage updates Variable1) -> OPC UA Server (UAVariable: getter returns Variable1 value) ] -> OPC UA Client

AndreasHeine avatar Oct 06 '21 09:10 AndreasHeine

I try, but dont do nothing. My code in index.html: image My code in app.js: image And in inside on this function I want to update the state of variable on opcua server.

FabioAlmeida25 avatar Oct 08 '21 12:10 FabioAlmeida25

you could look into a example etienne made years ago https://github.com/node-opcua/node-opcua-htmlpanel but you need to swap the client with a server ^^

AndreasHeine avatar Oct 08 '21 12:10 AndreasHeine

Its the link on example what I use as a base for my application. What do you say it was i need to create a server to send data to opc ua server ??

FabioAlmeida25 avatar Oct 08 '21 15:10 FabioAlmeida25

But I continue to don´t understand how is the process to send data to opcua server.

FabioAlmeida25 avatar Oct 08 '21 15:10 FabioAlmeida25

If you need my code to understand more what I am doing?? I send to your email, if you don´t mind.

FabioAlmeida25 avatar Oct 08 '21 15:10 FabioAlmeida25

Browser -> node.js application (websocketserver + opc ua server) Browser emits value -> websocketserver stores the value in a variable -> opc ua server's uavariable has a getter to the variable which holds the value from browser -> if some one accesses the uavariable lets say a opc ua client it will return the value of the variable written from the websocket

AndreasHeine avatar Oct 08 '21 17:10 AndreasHeine

Ok, first thing, I can now write on especific node id. using this code:

//##########################################################################################
let val = await session.read({nodeId: "ns=4;i=83"})
        console.log("Antes de escrever: ", val.value.value)

        dataToWrite = {
            //dataType: "Int32",
            //value: 25
            dataType: "Boolean",
            value: true
        }
        let risultato = await session.writeSingleNode("ns=4;i=83", dataToWrite)
        console.log("Depois de escrever: ", risultato)
        val = await session.read({nodeId: "ns=4;i=83"})
        console.log("Ler valor do node id :", val.value.value)`
//##########################################################################################

But what I want is, when I press this button, I want to send the value true no node id: image

I used the code bellow, but dont work, I but the code inside an async function, because, if I dont use inside gime me an error, but anyway, it doesn´t work this way:

io.on('connection', function(client) {  
            client.on('B_Stop_OP_BSF_Pressionado', function() {
                console.log("BOTÃO PRESSIONADO -> App");
                writevariable;
            });
        });      
        async function writevariable() {
            let val = await session.read({nodeId: "ns=4;i=83"})
            console.log("Antes de escrever: ", val.value.value)
            dataToWrite = {
                dataType: "Boolean",
                value: true
            }
            let risultato = await session.writeSingleNode("ns=4;i=83", dataToWrite)
            console.log("Depois de escrever: ", risultato)
            val = await session.read({nodeId: "ns=4;i=83"})
            console.log("Ler valor do node id :", val.value.value)
            console.log("Done");
        }

Conclusion: I can write, but what I want is for me to click the button, and then call me the writevariable function.

FabioAlmeida25 avatar Oct 09 '21 11:10 FabioAlmeida25

is your http backend opc ua server? or client? i assume your events get lost because of open ends... its kind of hard to understand your code!

AndreasHeine avatar Oct 09 '21 11:10 AndreasHeine

I am learning from scratch, and it's the first time working with node opcua and socket.io. I am using for my master's thesis. Sorry if it's hard for you to understand, in mid time I finally made it works.

html code: image

app.js: image

FabioAlmeida25 avatar Oct 09 '21 11:10 FabioAlmeida25

grafik

Webserver + OPC UA Server:

// Webserver Part

const express = require('express');
const app = express();

const http = require('http');
const server = http.createServer(app);

const { Server } = require("socket.io");
const io = new Server(server);

app.get('/', (req, res) => {  res.sendFile(__dirname + '/index.html');});

let variable1 = 0;

io.on('connection', (socket) => {  
    socket.emit("hello")
    console.log('a user connected');
    socket.on('buttonClick', (data) => {
        variable1 = variable1 + 1  
        console.log("buttonClick", variable1) 
    })
});

server.listen(3000, () => {  
    console.log('listening on *:3000');
});

// OPC UA Part -> Server

const { OPCUAServer, Variant, DataType, StatusCodes } = require("node-opcua");

(async () => {
    const server = new OPCUAServer({
        port: 4840,
        resourcePath: "/UA",
    });
    await server.initialize();
    console.log("initialized");
    const addressSpace = server.engine.addressSpace;
    const namespace = addressSpace.getOwnNamespace();
    
    namespace.addVariable({

        organizedBy: addressSpace.rootFolder.objects,

        nodeId: "s=clickcount", // a string nodeID
        browseName: "clickcount",
        dataType: "Int32",
        value: {
            get: () => new Variant({ dataType: DataType.Int32, value: variable1})
        }
    });

    server.start(function() {
        console.log("Server is now listening ... ( press CTRL+C to stop)");
        console.log("port ", server.endpoints[0].port);
        const endpointUrl = server.endpoints[0].endpointDescriptions()[0].endpointUrl;
        console.log(" the primary server endpoint url is ", endpointUrl);
    });
})();

index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button id="button1">Click Me!</button>

    <script src="/socket.io/socket.io.js"></script>
    <script>
        const socket = io("http://127.0.0.1:3000/");
        socket.on("connect", () => {
            console.log("connected")
            
            socket.on("hello", () => {
                console.log("hello from backend")
            })

            const button1 = document.getElementById('button1');
            button1.addEventListener('click', function(e) {    
                e.preventDefault(); 
                console.log("clicked")      
                socket.emit('buttonClick');      
            });
        })

    </script>
</body>
</html>

AndreasHeine avatar Oct 09 '21 12:10 AndreasHeine

@FabioAlmeida25 finally got it working; Closing

erossignon avatar May 07 '23 17:05 erossignon