Вот пример в TypeScript с использованием предоставленной node-opcua, которая может быть хорошей отправной точкой:
import { OPCUAClient, ClientSession, NodeCrawler, CacheNode, UserData, BrowseDirection, NodeClass, CacheNodeVariable, DataType } from "node-opcua";
const endpointUrl = "opc.tcp://opcuademo.sterfive.com:26543";
const js2xml = require("js2xmlparser");
const nodeId = "ns=1;i=1000"; // MyDevices
(async () => {
try {
function onBrowse(crawler: NodeCrawler, cacheNode: CacheNode, userData: UserData) {
if (cacheNode.nodeClass === NodeClass.ReferenceType) {
return;
}
const node: any = { "@": {} };
node["@"].nodeClass = NodeClass[cacheNode.nodeClass];
if (cacheNode.nodeClass === NodeClass.Variable) {
const cacheNodeVariable = (cacheNode as CacheNodeVariable);
node["@"].dataType = DataType[cacheNodeVariable.dataValue.value.dataType];
if (typeof cacheNodeVariable.dataValue.value.value !== "object") {
node["#"] = cacheNodeVariable.dataValue.value.value;
} else {
node.value = cacheNodeVariable.dataValue.value.value;
}
}
const myUserData = {
onBrowse,
root: node,
};
(userData as any).root[cacheNode.browseName.name.toString()] = node;
if (cacheNode.nodeClass === NodeClass.Variable) {
return;
}
NodeCrawler.follow(crawler, cacheNode, myUserData, "Organizes", BrowseDirection.Forward);
NodeCrawler.follow(crawler, cacheNode, myUserData, "HasComponent", BrowseDirection.Forward);
NodeCrawler.follow(crawler, cacheNode, myUserData, "HasProperty", BrowseDirection.Forward);
}
const client = OPCUAClient.create({ endpoint_must_exist: false });
client.on("backoff", () => { console.log("keep trying to connect"); });
const pojo = await client.withSessionAsync(endpointUrl, async (session: ClientSession) => {
const crawler = new NodeCrawler(session);
const userData = { onBrowse, root: {} };
await crawler.crawl(nodeId, userData);
return userData.root;
});
console.log(js2xml.parse("data", pojo));
} catch (err) {
console.log(err);
process.exit(1);
}
})();
В этом примере будет получен вывод, подобный этому
<?xml version='1.0'?>
<data>
<MyDevices nodeClass='Object'>
<FanSpeed nodeClass='Variable' dataType='Double'>1009.7567008059738</FanSpeed>
<PumpSpeed nodeClass='Variable' dataType='Double'>288.4219646868176</PumpSpeed>
<SomeDate nodeClass='Variable' dataType='DateTime'>
<value>Thu Oct 13 2016 10:40:00 GMT+0200 (GMT+02:00)</value>
</SomeDate>
<Pressure nodeClass='Variable' dataType='Double'>0.3612702142780426</Pressure>
<Temperature nodeClass='Variable' dataType='Double'>28.789330946565517</Temperature>
<TemperatureAnalogItem nodeClass='Variable' dataType='Double'>19.418976965847598</TemperatureAnalogItem>
</MyDevices>
</data>