UNPKG

node-red-contrib-iiot-opcua

Version:

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

350 lines 14.8 kB
[ { "id": "9e98528a1a8ac073", "type": "tab", "label": "IIoT OPC UA Flex Server", "disabled": false, "info": "" }, { "id": "9964c6a855d14944", "type": "OPCUA-IIoT-Server-Command", "z": "9e98528a1a8ac073", "commandtype": "restart", "nodeId": "", "name": "warm restart with defaults", "x": 330, "y": 140, "wires": [ [ "46ba6b0a0309a386" ] ] }, { "id": "bcc7e7a7012979b1", "type": "OPCUA-IIoT-Inject", "z": "9e98528a1a8ac073", "injectType": "inject", "payload": "", "payloadType": "date", "topic": "", "repeat": "", "crontab": "", "once": false, "startDelay": "", "name": "", "addressSpaceItems": [], "x": 140, "y": 140, "wires": [ [ "9964c6a855d14944" ] ] }, { "id": "96d5b418c0761ba8", "type": "debug", "z": "9e98528a1a8ac073", "name": "", "active": false, "console": "false", "complete": "false", "x": 690, "y": 140, "wires": [] }, { "id": "46ba6b0a0309a386", "type": "OPCUA-IIoT-Flex-Server", "z": "9e98528a1a8ac073", "port": "55380", "endpoint": "", "acceptExternalCommands": true, "maxAllowedSessionNumber": "", "maxConnectionsPerEndpoint": "", "maxAllowedSubscriptionNumber": "", "alternateHostname": "", "name": "", "showStatusActivities": false, "showErrors": true, "allowAnonymous": true, "individualCerts": false, "isAuditing": false, "serverDiscovery": true, "users": [], "xmlsets": [], "publicCertificateFile": "", "privateCertificateFile": "", "registerServerMethod": "1", "discoveryServerEndpointUrl": "", "capabilitiesForMDNS": "", "maxNodesPerRead": "", "maxNodesPerBrowse": "", "delayToClose": "", "addressSpaceScript": "function constructAlarmAddressSpace(server, addressSpace, eventObjects, done) {\n // server = the created node-opcua server\n // addressSpace = script placeholder\n // eventObjects = to hold event variables in memory from this script\n \n // internal global sandbox objects are \n // node = node of the flex server, \n // coreServer = core iiot server object for debug and access to nodeOPCUA,\n // and scriptObjects to hold variables and functions\n const LocalizedText = opcua.LocalizedText\n const namespace = addressSpace.getOwnNamespace()\n\n coreServer.internalDebugLog('init dynamic address space')\n node.warn('construct new address space for OPC UA')\n \n // from here - see the node-opcua docs how to build address sapces\n let tanks = namespace.addObject({\n browseName: 'Tanks',\n description: 'The Object representing some tanks',\n organizedBy: addressSpace.rootFolder.objects,\n notifierOf: addressSpace.rootFolder.objects.server\n })\n \n let oilTankLevel = namespace.addVariable({\n browseName: 'OilTankLevel',\n displayName: [\n new LocalizedText({text: 'Oil Tank Level', locale: 'en-US'}),\n new LocalizedText({text: 'Öl Tank Füllstand', locale: 'de-DE'})\n ],\n description: 'Fill level in percentage (0% to 100%) of the oil tank',\n propertyOf: tanks,\n dataType: 'Double',\n eventSourceOf: tanks\n })\n \n // ---------------------------------------------------------------------------------\n // Let's create a exclusive Limit Alarm that automatically raise itself\n // when the tank level is out of limit\n // ---------------------------------------------------------------------------------\n let exclusiveLimitAlarmType = addressSpace.findEventType('ExclusiveLimitAlarmType')\n \n let oilTankLevelCondition = namespace.instantiateExclusiveLimitAlarm(exclusiveLimitAlarmType, {\n componentOf: tanks,\n conditionSource: oilTankLevel,\n browseName: 'OilTankLevelCondition',\n displayName: [\n new LocalizedText({text: 'Oil Tank Level Condition', locale: 'en-US'}),\n new LocalizedText({text: 'Öl Tank Füllstand Bedingung', locale: 'de-DE'})\n ],\n description: 'ExclusiveLimitAlarmType Condition',\n conditionName: 'OilLevelCondition',\n optionals: [\n 'ConfirmedState', 'Confirm' // confirm state and confirm Method\n ],\n inputNode: oilTankLevel, // the letiable that will be monitored for change\n highHighLimit: 0.9,\n highLimit: 0.8,\n lowLimit: 0.2\n })\n \n // --------------------------------------------------------------\n // Let's create a second letiable with no Exclusive alarm\n // --------------------------------------------------------------\n let gasTankLevel = namespace.addVariable({\n browseName: 'GasTankLevel',\n displayName: [\n new LocalizedText({text: 'Gas Tank Level', locale: 'en-US'}),\n new LocalizedText({text: 'Gas Tank Füllstand', locale: 'de-DE'})\n ],\n description: 'Fill level in percentage (0% to 100%) of the gas tank',\n propertyOf: tanks,\n dataType: 'Double',\n eventSourceOf: tanks\n })\n \n // byte variable with value\n if(scriptObjects.oilTankNumber === undefined || scriptObjects.oilTankNumber === null) {\n scriptObjects.oilTankNumber = 100\n }\n \n let oilTankNumber = namespace.addVariable({\n nodeId: \"s=OilTankNumber\",\n browseName: 'OilTankNumber',\n displayName: [\n new LocalizedText({text: 'Oil Tank Number', locale: 'en-US'}),\n new LocalizedText({text: 'Öl Tank Nummer', locale: 'de-DE'})\n ],\n description: 'Number of the oil tank',\n propertyOf: tanks,\n dataType: 'Byte',\n value: {\n get: function () {\n return new opcua.Variant({\n dataType: 'Byte',\n value: scriptObjects.oilTankNumber\n })\n },\n set: function (variant) {\n scriptObjects.oilTankNumber = variant.value\n return opcua.StatusCodes.Good\n }\n }\n })\n \n let nonExclusiveLimitAlarmType = addressSpace.findEventType('NonExclusiveLimitAlarmType')\n \n let gasTankLevelCondition = namespace.instantiateNonExclusiveLimitAlarm(nonExclusiveLimitAlarmType, {\n componentOf: tanks,\n conditionSource: gasTankLevel,\n browseName: 'GasTankLevelCondition',\n displayName: [\n new LocalizedText({text: 'Gas Tank Level Condition', locale: 'en-US'}),\n new LocalizedText({text: 'Gas Tank Füllstand Bedingung', locale: 'de-DE'})\n ],\n description: 'NonExclusiveLimitAlarmType Condition',\n conditionName: 'GasLevelCondition',\n optionals: [\n 'ConfirmedState', 'Confirm' // confirm state and confirm Method\n ],\n inputNode: gasTankLevel, // the letiable that will be monitored for change\n highHighLimit: 0.9,\n highLimit: 0.8,\n lowLimit: 0.2\n })\n \n // variable with value\n if(scriptObjects.testReadWrite === undefined || scriptObjects.testReadWrite === null) {\n scriptObjects.testReadWrite = 1000.0\n }\n \n let myVariables = namespace.addObject({\n browseName: 'MyVariables',\n description: 'The Object representing some variables',\n organizedBy: addressSpace.rootFolder.objects,\n notifierOf: addressSpace.rootFolder.objects.server\n })\n \n if(coreServer.core) {\n namespace.addVariable({\n componentOf: myVariables,\n nodeId: 'ns=1;s=TestReadWrite',\n browseName: 'TestReadWrite',\n displayName: [\n new LocalizedText({text: 'Test Read and Write', locale: 'en-US'}),\n new LocalizedText({text: 'Test Lesen Schreiben', locale: 'de-DE'})\n ],\n dataType: 'Double',\n value: {\n get: function () {\n return new opcua.Variant({\n dataType: 'Double',\n value: scriptObjects.testReadWrite\n })\n },\n set: function (variant) {\n scriptObjects.testReadWrite = parseFloat(variant.value)\n return opcua.StatusCodes.Good\n }\n }\n \n })\n \n let memoryVariable = namespace.addVariable({\n componentOf: myVariables,\n nodeId: 'ns=1;s=free_memory',\n browseName: 'FreeMemory',\n displayName: [\n new LocalizedText({text: 'Free Memory', locale: 'en-US'}),\n new LocalizedText({text: 'ungenutzer RAM', locale: 'de-DE'})\n ],\n dataType: 'Double',\n \n value: {\n get: function () {\n return new opcua.Variant({\n dataType: 'Double',\n value: coreServer.core.availableMemory()\n })\n }\n }\n })\n addressSpace.installHistoricalDataNode(memoryVariable)\n \n }\n\n // hold event objects in memory \n eventObjects.oilTankLevel = oilTankLevel\n eventObjects.oilTankLevelCondition = oilTankLevelCondition\n \n eventObjects.gasTankLevel = gasTankLevel\n eventObjects.gasTankLevelCondition = gasTankLevelCondition\n \n done()\n}", "x": 530, "y": 140, "wires": [ [ "96d5b418c0761ba8" ] ] }, { "id": "895e562a824a0479", "type": "catch", "z": "9e98528a1a8ac073", "name": "", "scope": null, "x": 140, "y": 80, "wires": [ [ "63360aecbe74d5b6" ] ] }, { "id": "63360aecbe74d5b6", "type": "debug", "z": "9e98528a1a8ac073", "name": "", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "true", "targetType": "full", "statusVal": "", "statusType": "auto", "x": 290, "y": 80, "wires": [] }, { "id": "eacec11f14c4433f", "type": "OPCUA-IIoT-Response", "z": "9e98528a1a8ac073", "name": "", "compressStructure": true, "showStatusActivities": false, "showErrors": false, "activateFilters": false, "filters": [], "x": 610, "y": 300, "wires": [ [ "2399803ef436a77a" ] ] }, { "id": "d1773b9e76702806", "type": "debug", "z": "9e98528a1a8ac073", "name": "", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "true", "x": 450, "y": 240, "wires": [] }, { "id": "93ba75eb6c9818bc", "type": "OPCUA-IIoT-Write", "z": "9e98528a1a8ac073", "connector": "77fdc29e.3c49ec", "name": "", "justValue": false, "showStatusActivities": false, "showErrors": true, "x": 450, "y": 300, "wires": [ [ "eacec11f14c4433f" ] ] }, { "id": "524dd108ec40ea9f", "type": "OPCUA-IIoT-Inject", "z": "9e98528a1a8ac073", "injectType": "write", "payload": "", "payloadType": "date", "topic": "", "repeat": "", "crontab": "", "once": true, "startDelay": "", "name": "inject", "addressSpaceItems": [ { "name": "", "nodeId": "ns=1;s=OilTankNumber", "datatypeName": "Byte" }, { "name": "", "nodeId": "ns=1;s=TestReadWrite", "datatypeName": "Double" } ], "x": 130, "y": 300, "wires": [ [ "b8470569c6b35699" ] ] }, { "id": "b8470569c6b35699", "type": "function", "z": "9e98528a1a8ac073", "name": "values to", "func": "let uint8 = new Uint8Array([2])\nmsg.valuesToWrite = [uint8[0], 20.33];\nreturn msg;", "outputs": 1, "noerr": 0, "x": 280, "y": 300, "wires": [ [ "93ba75eb6c9818bc", "d1773b9e76702806" ] ] }, { "id": "48e3bf891e6340b4", "type": "OPCUA-IIoT-Inject", "z": "9e98528a1a8ac073", "injectType": "write", "payload": "", "payloadType": "date", "topic": "", "repeat": "", "crontab": "", "once": false, "startDelay": "", "name": "inject", "addressSpaceItems": [ { "name": "", "nodeId": "ns=1;s=OilTankNumber", "datatypeName": "Byte" }, { "name": "", "nodeId": "ns=1;s=TestReadWrite", "datatypeName": "Double" } ], "x": 130, "y": 380, "wires": [ [ "1cdb7115d3474b87" ] ] }, { "id": "1cdb7115d3474b87", "type": "OPCUA-IIoT-Read", "z": "9e98528a1a8ac073", "attributeId": "13", "maxAge": 1, "depth": 1, "connector": "77fdc29e.3c49ec", "name": "", "justValue": true, "showStatusActivities": false, "showErrors": false, "parseStrings": false, "historyDays": 1, "x": 290, "y": 380, "wires": [ [ "735c8353fde5aa91" ] ] }, { "id": "4dc62287dda5244e", "type": "debug", "z": "9e98528a1a8ac073", "name": "", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "true", "x": 630, "y": 380, "wires": [] }, { "id": "2399803ef436a77a", "type": "debug", "z": "9e98528a1a8ac073", "name": "", "active": false, "console": "false", "complete": "false", "x": 770, "y": 300, "wires": [] }, { "id": "735c8353fde5aa91", "type": "OPCUA-IIoT-Response", "z": "9e98528a1a8ac073", "name": "", "compressStructure": true, "showStatusActivities": false, "showErrors": false, "activateUnsetFilter": false, "activateFilters": false, "negateFilter": false, "filters": [], "x": 470, "y": 380, "wires": [ [ "4dc62287dda5244e" ] ] }, { "id": "77fdc29e.3c49ec", "type": "OPCUA-IIoT-Connector", "discoveryUrl": "", "endpoint": "opc.tcp://localhost:55380", "keepSessionAlive": true, "loginEnabled": false, "securityPolicy": "None", "securityMode": "None", "name": "LOCAL FLEX 80", "showErrors": true, "publicCertificateFile": "", "privateKeyFile": "", "defaultSecureTokenLifetime": "", "endpointMustExist": false, "autoSelectRightEndpoint": false, "strategyMaxRetry": "", "strategyInitialDelay": "", "strategyMaxDelay": "", "strategyRandomisationFactor": "", "requestedSessionTimeout": "", "connectionStartDelay": "", "reconnectDelay": "" } ]