UNPKG

node-red-contrib-iiot-opcua

Version:

An Industrial IoT OPC UA toolbox contribution package for Node-RED based on node-opcua.

156 lines (148 loc) 9.89 kB
<!-- The BSD 3-Clause License Copyright 2022 - DATATRONiQ GmbH (https://datatroniq.com) Copyright (c) 2018-2022 Klaus Landsdorf (http://node-red.plus/) Copyright 2015,2016 - Mika Karaila, Valmet Automation Inc. (node-red-contrib-opcua) All rights reserved. node-red-contrib-iiot-opcua --> <script type='text/javascript'> RED.nodes.registerType('OPCUA-IIoT-Browser', { category: 'IIoT', color: '#ABCDEF', defaults: { nodeId: {value: ""}, name: {value: ""}, justValue: {value: true}, sendNodesToRead: {value: false}, sendNodesToBrowser: {value: false}, sendNodesToListener: {value: false}, multipleOutputs: {value: false}, showStatusActivities: {value: false}, showErrors: {value: false}, recursiveBrowse: {value: false}, recursiveDepth: {value: 1}, delayPerMessage: {value: 0.2}, connector: {type: "OPCUA-IIoT-Connector", required: true} }, inputs: 1, outputs: 1, align: "left", icon: "icon.png", label: function () { return this.name || "Browser"; }, labelStyle: function () { return this.item ? "node_label_italic" : ""; }, oneditprepare: function () { let node = this node.lookupItems = [] let nodeIdLookupButton = $("#node-lookup-nodeId") let nodeIdField = $("#node-input-nodeId") nodeIdLookupButton.on("click", function () { nodeIdLookupButton.addClass('disabled') let rootid = nodeIdField.val() || 'ns=0;i=84' // root $.getJSON('/opcuaIIoT/browse/'+ node.id + '/' + encodeURIComponent(rootid), function (data) { nodeIdLookupButton.removeClass('disabled') node.lookupItems = [] $.each(data, function (i, entry) { node.lookupItems.push({value: entry.nodeId, label: entry.displayName.text}) }) nodeIdField.autocomplete({ source: node.lookupItems, minLength: 0, focus: function (event, ui) { nodeIdField.val(ui.item.label); return false; }, select: function (event, ui) { nodeIdField.val(ui.item.value) return false; }, close: function (event, ui) { nodeIdField.autocomplete("destroy") } }).autocomplete("search", "") }) }) let tabs = RED.tabs.create({ id: "node-input-browser-tabs", onchange: function (tab) { $("#node-input-browser-tabs-content").children().hide() $("#" + tab.id).show() } }) tabs.addTab({ id: "opcuaiiot-browser-tab-settings", label: this._("opcua-iiot-contrib.tabs-label.settings") }) tabs.addTab({ id: "opcuaiiot-browser-tab-browse", label: this._("opcua-iiot-contrib.tabs-label.browser") }) } }); </script> <script type='text/x-red' data-template-name='OPCUA-IIoT-Browser'> <div class='form-row'> <ul style='background:#fff;min-width:600px;margin-bottom:20px' id='node-input-browser-tabs'> </ul> </div> <div id='node-input-browser-tabs-content' style='min-height:170px'> <div id='opcuaiiot-browser-tab-settings' style='display:none'> <div class='form-row' style='min-width:640px'> <label for='node-input-connector'><i class='icon-globe'></i> <span data-i18n='opcua-iiot-contrib.label.connector'></span> </label> <input type='text' id='node-input-connector'> </div> <div class='form-row'> <label for='node-input-name'><i class='fa fa-tag'></i> <span data-i18n='node-red:common.label.name'></span></label> <input type='text' id='node-input-name' placeholder='Name'> </div> <hr> <div class='form-row'> <label style='min-width:160px' for='node-input-justValue'><i class='fa fa-simplybuilt'></i> <span data-i18n='opcua-iiot-contrib.label.justValue'> </span></label> <input type='checkbox' id='node-input-justValue' style='max-width:30px'> </div> <div class='form-row'> <label style='min-width:160px' for='node-input-sendNodesToRead'><i class='fa fa-th'></i> <span data-i18n='opcua-iiot-contrib.label.sendNodesToRead'></span></label> <input type='checkbox' id='node-input-sendNodesToRead' style='max-width:30px'> </div> <div class='form-row'> <label style='min-width:160px' for='node-input-sendNodesToListener'><i class='fa fa-th'></i> <span data-i18n='opcua-iiot-contrib.label.sendNodesToListener'></span></label> <input type='checkbox' id='node-input-sendNodesToListener' style='max-width:30px'> </div> <div class='form-row'> <label style='min-width:160px' for='node-input-sendNodesToBrowser'><i class='fa fa-th'></i> <span data-i18n='opcua-iiot-contrib.label.sendNodesToBrowser'></span></label> <input type='checkbox' id='node-input-sendNodesToBrowser' style='max-width:30px'> </div> <div class='form-row'> <label style='min-width:160px' for='node-input-multipleOutputs'><i class='fa fa-object-group'></i> <span data-i18n='opcua-iiot-contrib.label.multipleOutputs'></span></label> <input type='checkbox' id='node-input-multipleOutputs' style='max-width:30px'> </div> <hr> <div class='form-row'> <label style='min-width:160px' for='node-input-showStatusActivities'><i class='fa fa-bolt'></i> <span data-i18n='opcua-iiot-contrib.label.showActivities'></span></label> <input type='checkbox' id='node-input-showStatusActivities' style='max-width:30px'> </div> <div class='form-row'> <label style='min-width:160px' for='node-input-showErrors'><i class='fa fa-exclamation-circle'></i> <span data-i18n='opcua-iiot-contrib.label.showErrors'></span></label> <input type='checkbox' id='node-input-showErrors' style='max-width:30px'> </div> </div> <div id='opcuaiiot-browser-tab-browse' style='display:none'> <div class='form-row'> <div style='margin:15px'> <span data-i18n='opcua-iiot-contrib.label.lookupUseHint'></span> </div> </div> <div class='form-row'> <label for='node-input-nodeId'><i class='icon-search'></i> <span data-i18n='opcua-iiot-contrib.label.nodeId'></span></label> <input type='text' id='node-input-nodeId' style='width:40%' placeholder='ns=0;i=84'> <a id='node-lookup-nodeId' class='btn'><i id='node-lookup-topic-icon' class='fa fa-search'></i> </a> </div> <div class='form-row'> <label for='node-input-recursiveBrowse'><i class='icon-repeat'></i> <span data-i18n='opcua-iiot-contrib.label.recursiveBrowse'></span></label> <input type='checkbox' id='node-input-recursiveBrowse' style='max-width:30px'> </div> <div class='form-row'> <label for='node-input-recursiveDepth'><i class='icon-tag'></i> <span data-i18n='opcua-iiot-contrib.label.recursiveDepth'> </span></label> <input type='text' id='node-input-recursiveDepth' placeholder='1' style='max-width:80px'> </div> <div class='form-row'> <label for='node-input-delayPerMessage'><i class='icon-time'></i> <span data-i18n='opcua-iiot-contrib.label.delayPerMessage'></span></label> <input type='text' id='node-input-delayPerMessage' placeholder='0.2' style='max-width:80px'> sec. </div> </div> </div> <!-- TODO: ReferenceTypeIds List to add or remove reference types to browse for --> </script> <script type='text/x-red' data-help-name='OPCUA-IIoT-Browser'> @browser-data-help <h2>OPC UA IIoT Browser</h2> <p> Use the Browser to browse OPC UA address spaces. It normally starts with the root folder or object by using an OPC UA Node-Id like ns=0;i=85 (root->Objects). It also can get a state to start at any desired Node-Id as a root within the address space. </p> <h3>Configuration</h3> <p> The browser tab inside the configuration section is used to set a default starting OPC UA Node-Id.</p><p> </p><p> Use the lookup button to browse for Node-Id's. (needs a deploy first) Empty the input text box to start from root again. </p> <h3>Examples</h3> <a href='https://github.com/biancode/node-red-contrib-iiot-opcua/blob/master/examples/' target='_blank'>GitHub Browser example flow</a> <p> You'll find the examples under Node-RED menu > Import > Examples > iiot opcua</p> <h3>Input</h3> <p> The input could be empty or should hold addressSpaceItems (Array of objects) to browse for. A datatype is not required here - it just requires the nodeId in the addressSpaceItems objects here. </p> <p> With the multiple outputs option, the output gets spilt into one message per addressSpaceItem sent from the previous node and an extra message if a Node-Id is configured in the Browser tab. The delay per msg option helps to get some time between every msg outputs. </p> <h3>Recursive Browse</h3> <p> Sometime you need to browse into structure and the crawler gets too much data. In that case you could try to work with the recursive browse if the server allows that operation. It does not work in any case, but it helps to build some better results for you. </p> <h3>Output</h3> <p> The output returns either a structured JSON object with the requested data or the error messages from node-opcua.</p> <div> <strong>Content of a browse result:</strong> <ul> <li>payload (value) <ul> <li>rootNodeId </li><li> browserResults (Array of Objects) </li><li>browserResultsCount </li><li>recursiveBrowse </li><li>recursiveDepth </li> <li>recursiveDepthMax </li><li>listenerParameters </li><li>browseTopic (node browse root) </li><li> addressSpaceItems (input) </li></ul> </li><li>justValue </li><li>topic </li><li>nodetype (browse) </li><li> injectType (inject) </li><li>addressSpaceItems (Array of Objects to browse) </li><li>optional <ul> <li> nodesToRead (Array of String resluts to read) </li><li>nodesToReadCount </li><li> addressItemsToRead (Array of Object results to listen) </li><li>addressItemsToReadCount </li><li> addressItemsToBrowse (Array of Object results to browse) </li><li>addressItemsToBrowseCount </li></ul> </li></ul> </div> <h3> Defaults </h3> <p> </p> <strong>Name</strong> <p>Name in the flow of Node-RED.</p> <p> Set showErrors to get errors from node-opcua on browse.</p> </script>