我正在尝试连接一个RFID阅读器,它根据this specification实现了一个OPC-UA服务器。
我尝试调用ScanStart方法,该方法将ScanSettings struct作为输入参数(一种AutoID数据类型),但是尽管通读了示例和文档,我还是想不出这样做的方法。
通过使用UAExpert,我可以调用该方法,并使用图形用户界面输入结构的值,这将在wireshark中生成以下转储:
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方法。我拥有的客户端代码是:
(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()
我做错了什么?我很确定这是我的承诺处理问题...
如有任何帮助,我们不胜感激!
发布于 2020-04-29 19:29:56
好了,我终于做到了。下面是使用node-opcua调用带有struct输入参数的OPC-UA方法的方法:
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);
}
});
})();https://stackoverflow.com/questions/61266294
复制相似问题