首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用node-opcua调用带有struct输入参数的OPCUA方法

使用node-opcua调用带有struct输入参数的OPCUA方法
EN

Stack Overflow用户
提问于 2020-04-17 15:35:18
回答 1查看 637关注 0票数 0

我正在尝试连接一个RFID阅读器,它根据this specification实现了一个OPC-UA服务器。

我尝试调用ScanStart方法,该方法将ScanSettings struct作为输入参数(一种AutoID数据类型),但是尽管通读了示例和文档,我还是想不出这样做的方法。

通过使用UAExpert,我可以调用该方法,并使用图形用户界面输入结构的值,这将在wireshark中生成以下转储:

代码语言:javascript
复制
    ArraySize: 1
    [0]: Variant
        Variant Type: ExtensionObject (0x16)
        Value: ExtensionObject
            TypeId: ExpandedNodeId
                EncodingMask: 0x01, EncodingMask: Four byte encoded Numeric
                    .... 0001 = EncodingMask: Four byte encoded Numeric (0x1)
                    .0.. .... = has server index: False
                    0... .... = has namespace uri: False
                Namespace Index: 3
                Identifier Numeric: 5015
            EncodingMask: 0x01, has binary body
                .... ...1 = has binary body: True
                .... ..0. = has xml body: False
            ByteString: 0000000000000000000000000000000000

有没有人成功地注册了一个ExtensionObject,以便使用node-opcua传递给方法调用?在这一点上,我很高兴只发送上面的ByteString,而不需要对结构进行编码/解码,因为它总是静态的。

显然,有一种constructExtensionObject方法。我拥有的客户端代码是:

代码语言:javascript
复制
(async () => {

    const client = OPCUAClient.create({ endpoint_must_exist: false});
    client.on("backoff", () => console.log("Backoff: trying to connect to ", endpointUri));

    await client.withSessionAsync(endpointUri, async (session) => {
        let scanSettings = {
            Duration: 0,
            Cyles: 0,
            DataAvailble: false
        };
        const nodeID = new NodeId(NodeIdType.STRING, "rfr310.ScanStart.InputArguments", 4);
        const extObj = session.constructExtensionObject(nodeID, scanSettings);

        const methodsToCall = [
            {
                objectId: "ns=4;s=rfr310",
                methodId: "ns=4;s=rfr310.ScanStart",
                inputArguments: [extObj]
            }
        ];

        extObj.then(() => {
            session.call(methodsToCall,(err,results) => {
                if (err) {
                    console.log(err);
                } else {
                    console.log(results);
                }
            });
        }).catch(() => {
        })
    });
})();

生成错误"dispose when pendingTransactions is not empty",该错误由extObj.catch()

我做错了什么?我很确定这是我的承诺处理问题...

如有任何帮助,我们不胜感激!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-29 19:29:56

好了,我终于做到了。下面是使用node-opcua调用带有struct输入参数的OPC-UA方法的方法:

代码语言:javascript
复制
const { OPCUAClient, NodeId, NodeIdType, DataType} = require("node-opcua");

const endpointUri = "opc.tcp://<your-endpoint>:<your-port>";

(async () => {

    const client = OPCUAClient.create({ endpoint_must_exist: false});
    client.on("backoff", () => console.log("Backoff: trying to connect to ", endpointUri));

    await client.withSessionAsync(endpointUri, async (session) => {
        // Scan settings value input
        const scanSettingsParams = {
            duration: 0,
            cycles : 0,
            dataAvailable : false,
            locationType: 0
        };

        try {
            // NodeID for InputArguments struct type (inherits from ScanSettings)
            const nodeID = new NodeId(NodeIdType.NUMERIC, 3010, 3);
            // Create ExtensionObject for InputArguments
            const scanSettingsObj = await session.constructExtensionObject(nodeID, scanSettingsParams);

            // Populate Method call with ExtensionObject as InputArgument
            const methodToCall = {
                    objectId: "ns=4;s=rfr310",
                    methodId: "ns=4;s=rfr310.ScanStart",
                    inputArguments: [
                        {
                            dataType: DataType.ExtensionObject,
                            value: scanSettingsObj
                        }
                    ]
                };

                // Call method, passing ScanSettings as input argument
                session.call(methodToCall,(err,results) => {
                    if (err) {
                        console.log(err);
                    } else {
                        console.log(results);
                    }
                });

        } catch (err) {
            console.log(err);
        }
    });
})();
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61266294

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档