├── .gitignore ├── .npmignore ├── LICENSE ├── Readme.md ├── examples ├── Browser_contrib_ui_flow.json ├── CODESYS_EXAMPLE.json ├── CUSTOM_OBJECT.json ├── EVENTS.json ├── ExampleFlow.json ├── IGSS_OPCUA.json ├── METHOD.json ├── OPCUA Browser endpointBrowse example.json ├── OPCUA-CONNECT.json ├── OPCUA-FILE.json ├── OPCUA-MULTI-SUB.json ├── OPCUA-RIGHTS.json ├── OPCUA-TEST-NODES.json ├── OPCUA-TEST-UNSUB.json ├── OPCUA-TEST.json ├── OPCUA-UNSUBSRIBE.json ├── OPCUA-VARIABLE.json ├── OPCUAServer_Flow.json ├── OPCUA_AE_TEST.json ├── OPCUA_BROWSE_and_SUBSCRIBE.json ├── OPCUA_READMULTIPLE.json ├── ProsysOpcUaFlow.json ├── TEST_OPCUA.json ├── TestNode.json └── USER-CERT.json ├── images ├── Example.png ├── PROSYS-OPC-UA-EXAMPLE.png ├── PROSYS-OPC-UA-EXAMPLE2.png ├── PROSYS-OPCUA-EVENTS-EXAMPLE.png ├── PROSYS-OPCUA-METHOD-EXAMPLE.png ├── nodeopcua64.png ├── opcuanode.png ├── opcuanodeLogo64.png └── uiBrowseExample.png ├── opcua.conf.js ├── opcua ├── 101-opcuaitem.html ├── 101-opcuaitem.js ├── 102-opcuaclient.html ├── 102-opcuaclient.js ├── 103-opcuabrowser.html ├── 103-opcuabrowser.js ├── 104-opcuaserver.html ├── 104-opcuaserver.js ├── 105-opcuaendpoint.html ├── 105-opcuaendpoint.js ├── 106-opcuaevent.html ├── 106-opcuaevent.js ├── 107-opcuamethod.html ├── 107-opcuamethod.js ├── 108-opcuarights.html ├── 108-opcuarights.js ├── 109-opcuadiscovery.html ├── 109-opcuadiscovery.js ├── dump_certificates.js ├── icons │ ├── opcuanode.png │ └── opcuanodeLogo.png ├── opcua-basics.js ├── public │ └── vendor │ │ └── opc-foundation │ │ ├── binary │ │ ├── OPC.ISA95.Types.bsd.xml │ │ ├── Opc.Ua.Adi.Types.bsd.xml │ │ ├── Opc.Ua.Di.Types.bsd.xml │ │ ├── Opc.Ua.Gds.Types.bsd.xml │ │ └── Opc.Ua.Types.bsd.xml │ │ ├── csv │ │ ├── AttributeIds.csv │ │ ├── NodeIds.csv │ │ ├── Opc.Ua.StatusCodes.csv │ │ ├── OpcUaDiModel.csv │ │ ├── OpcUaGdsModel.csv │ │ ├── ServerCapabilities.csv │ │ ├── ServerCapabilityIdentifiers.csv │ │ ├── StatusCode.csv │ │ └── StatusCodes.csv │ │ ├── schema │ │ ├── OPC.ISA95.Types.xsd │ │ ├── OPCBinarySchema.xsd │ │ ├── Opc.Ua.Types.xsd │ │ ├── SecuredApplication.xsd │ │ └── UANodeSet.xsd │ │ └── xml │ │ ├── OPC.ISA95.NodeSet2.Nov52013.xml │ │ ├── Opc.ISA95.NodeSet2.xml │ │ ├── Opc.Ua.Adi.NodeSet2.xml │ │ ├── Opc.Ua.Adi.Types.bsd.xml │ │ ├── Opc.Ua.Adi.Types.xsd │ │ ├── Opc.Ua.AutoID.NodeSet2.xml │ │ ├── Opc.Ua.Di.NodeSet2.xml │ │ ├── Opc.Ua.Di.PredefinedNodes.xml │ │ ├── Opc.Ua.Di.Types.bsd │ │ ├── Opc.Ua.Di.Types.bsd.xml │ │ ├── Opc.Ua.Di.Types.xsd │ │ ├── Opc.Ua.Gds.NodeSet.xml │ │ ├── Opc.Ua.Gds.NodeSet2.xml │ │ ├── Opc.Ua.Gds.Types.bsd.xml │ │ ├── Opc.Ua.Gds.Types.xsd │ │ ├── Opc.Ua.NodeSet-2.xml │ │ ├── Opc.Ua.NodeSet-3.xml │ │ ├── Opc.Ua.NodeSet.xml │ │ ├── Opc.Ua.NodeSet2.Part10.xml │ │ ├── Opc.Ua.NodeSet2.Part11.xml │ │ ├── Opc.Ua.NodeSet2.Part12.xml │ │ ├── Opc.Ua.NodeSet2.Part13.xml │ │ ├── Opc.Ua.NodeSet2.Part3.xml │ │ ├── Opc.Ua.NodeSet2.Part4.xml │ │ ├── Opc.Ua.NodeSet2.Part5.xml │ │ ├── Opc.Ua.NodeSet2.Part8.xml │ │ ├── Opc.Ua.NodeSet2.Part9.xml │ │ ├── Opc.Ua.NodeSet2.Part999.xml │ │ ├── Opc.Ua.NodeSet2.xml │ │ ├── Opc.Ua.PredefinedNodes.xml │ │ └── OpcUaDiModel.xml └── utils.js ├── package-lock.json ├── package.json ├── test └── opcuaServerSpec.js └── users.json /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.iml 3 | .idea 4 | node_modules 5 | temp 6 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .git 2 | .idea 3 | test 4 | examples 5 | node_modules 6 | .gitignore 7 | *.iml 8 | Example.png 9 | *EXAMPLE.png 10 | *.conf.js 11 | *.log 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Copyright 2015 Valmet Automation Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | 17 | Developer List: 18 | 19 | since 2015 - Mika Karaila - mika.karaila@valmet.com - Valmet Automation Inc. 20 | since 2016 - Klaus Landsdorf - klaus.landsdorf@bianco-royal.de - Bianco Royal -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | [![NPM download](https://img.shields.io/npm/dm/node-red-contrib-opcua.svg)](http://www.npm-stats.com/~packages/node-red-contrib-opcua) 2 | [![NPM version](https://badge.fury.io/js/node-red-contrib-opcua.png)](http://badge.fury.io/js/node-red-contrib-opcua) 3 | 4 | ![Node-RED OPC UA](http://b.repl.ca/v1/Node--RED-OPC_UA-blue.png) 5 | 6 | node-red-contrib-opcua 7 | ======================== 8 | 9 | ![opcuanodeLogo64](images/opcuanodeLogo64.png) 10 | 11 | A [Node-RED][1] nodes to communicate or serve via [OPC UA](https://www.npmjs.com/package/node-opcua). 12 | 13 | based on [node-opcua](http://node-opcua.github.io/) 14 | 15 | ![nodeopcua64](images/nodeopcua64.png) 16 | 17 | Install 18 | ------- 19 | 20 | Run command on Node-RED installation directory. 21 | 22 | npm install node-red-contrib-opcua 23 | 24 | or run command for global installation. 25 | 26 | npm install -g node-red-contrib-opcua 27 | 28 | Usage 29 | ----- 30 | 31 | Use OpcUa-Item to define variables. 32 | Use OpcUa-Client to read / write / subscribe / browse OPC UA server. 33 | 34 | See some flows under folder ![examples]. 35 | Updated server sub-flow example OPCUA-TEST-NODES.json look commands: addFolder, addVariable, addMethod, setFolder. 36 | Added new opcua-rights node to set folder/variable access level and role & permissions. 37 | 38 | Here you got some ready to use examples. 39 | You can use the Import in Node-RED in the right upper corner menu. 40 | 41 | ![node-red-opcua-flow](images/Example.png) 42 | 43 | Examples are available for Schneider IGSS and Prosys Simulation Server as Node-RED flow. 44 | Search for OPC UA on: http://flows.nodered.org/ 45 | 46 | ![node-red-opcua-flow-Prosys](images/PROSYS-OPC-UA-EXAMPLE2.png) 47 | 48 | ![New method node example](images/PROSYS-OPCUA-METHOD-EXAMPLE.png) 49 | 50 | ![Events example](images/PROSYS-OPCUA-EVENTS-EXAMPLE.png) 51 | 52 | Message parameters 53 | ------------------ 54 | 55 | Input message 56 | ---- 57 | 58 | | __**Property**__ | __**Function/Value**__ | __**Notes**__ | 59 | |--------------------|---------------------------|---------------------------| 60 | | payload | set interval for subscription or monitorItem 61 | | interval | Subscription interval | 62 | | queueSize | Subscription queue size | 63 | | deadbandType | "a" abs. or "p" percent | Action monitor 64 | | deadbandValue | integer for deadband | Action monitor 65 | | topic | NodeId and DataType in format ns=3;s=Counter;datatype=Int32 66 | | action | subscribe | nodeId / variable 67 | | | unsubscribe | nodeId / variable 68 | | | deletesubscription | subscription 69 | | | browse | nodeId / folder 70 | | | info | nodeId 71 | | | read | nodeId 72 | | | write | nodeId & value 73 | | | monitor | deadbandtype abs/pro 74 | | | events | nodeId 75 | | | readmultiple | [nodeId + datatype] 76 | | | writemultiple | [nodeId + datatype + value] 77 | 78 | readmultiple to readmultiple items 79 | writemultiple to write multiple items 80 | clearitems to empty multiple items (readmultiple / writemultiple) 81 | 82 | NOTE: With datatype=xxxArray msg.payload.range = "2:4" can used as indexRange to read/write partial array 83 | 84 | Output message 85 | ---- 86 | 87 | | __**Property**__ | __**Function/Value**__ | __**Notes**__ | 88 | |--------------------|---------------------------|---------------------------| 89 | | payload | dataValue.value.value | | 90 | | statusCode | OPC UA StatusCode | | 91 | | sourceTimestamp | Source timestamp | | 92 | | serverTimestamp | Server´s timestamp | | 93 | 94 | Release history (only couple of older releases): 95 | 96 | 97 | **v0.2.223** 98 |

99 | Fixed: Namespace index used with variables (set value).
100 | Enhancements: Initial value can be set to server variable, server returns nodeId as variable created. Added support for StringArray. 101 |

102 | 103 | **v0.2.117** 104 |

105 | Enhancement: Added users to server. Users.json contains username, password and role for each user.
106 |

107 | 108 | **v0.2.116** 109 |

110 | Enhancement: server allow anonymous, added verbose to show trusted/rejected folders.
111 |

112 | 113 | 114 | **v0.2.115** 115 |

116 | Enhancement: server node security settings; mode and policy
117 |

118 | 119 | **v0.2.114** 120 |

121 | Fix: added to client certificate manager
122 |

123 | 124 | **v0.2.113** 125 |

126 | Enhancement: server commands: registerNamespace and getNamespaceIndex, user can addVariables with registered namespaces like ns=5.
127 | Enhancement: msg.topic = readmultiple AND msg.payload = ALL then msg.payload = values
128 |

129 | 130 | **v0.2.112** 131 |

132 | Added DateTime to server.
133 |

134 | 135 | **v0.2.111** 136 |

137 | Fixed DateTime conversion (write).
138 |

139 | 140 | **v0.2.110** 141 |

142 | Added 2D and 3D array support. Examples:
143 | ns=1;s=Float2D;datatype=FloatArray[5,5]
144 | ns=1;s=Float3D;datatype=FloatArray[5,5,5]
145 | NOTE: Write range uses msg.range
146 | New feature msg.payload.range can be used to read part of Array
147 | New feature msg.range can be used to write part of Array
148 | Updated example OPCUA-TEST-NODES.json
149 | 150 |

151 | 152 | **v0.2.109** 153 |

154 | Added array range examples (examples/OPCUA-TEST-NODES.json).
155 | Send only if payload contains something.
156 | Added msg.payload.range usage
157 | New feature msg.payload.range can be used to read/write part of Array
158 | Fix: FQDN -> hostname in makeAplicationUri
159 | EventId and statustext as clear string
160 | EventId as hex string
161 |

162 | 163 | **v0.2.108 and older** 164 |

165 | Fixed support for server Array variables
166 | Browse will create topic and datatype thus output can be connected. Next node can progress output msg.
167 | Refactored browse action fast and simple
168 | Merged event payload fix. Merge pull request #265 from list3f/master
169 | Put OPC UA event data in msg.payload
170 |

171 | # Advanced examples 172 | - needed from users (add links to examples folder) 173 | 174 | 175 | 176 | # Authors 177 | 178 | * since 2015 [Mika Karaila][2] 179 | * since 2016 [Klaus Landsdorf][3] 180 | 181 | Testing 182 | ------ 183 | 184 | karma start opcua.conf.js --log-level debug --single-run 185 | 186 | TBD List 187 | ----- 188 | 189 | | __**Nodes**__ | __**Function**__ | __**Done**__ | 190 | |--------------------|---------------------------|---------------------------| 191 | | All | | | 192 | | | Project structure | :white_check_mark: | 193 | | | Async calls | :waxing_crescent_moon: | 194 | | | UnitTesting | :new_moon: | 195 | | | Documentation | :first_quarter_moon: | 196 | | Item | | :white_check_mark: | 197 | | Browser | | | 198 | | | Browse | :white_check_mark: | 199 | | | Simple UI interface | :first_quarter_moon: | 200 | | Client | | | 201 | | | Read | :white_check_mark: | 202 | | | Read Multiple | :white_check_mark: | 203 | | | Write | :white_check_mark: | 204 | | | Write Multiple | :white_check_mark: | 205 | | | Subscribe | :white_check_mark: | 206 | | | Unsubscribe | :white_check_mark: | 207 | | | DeleteSubscription | :white_check_mark: | 208 | | | Info | :white_check_mark: | 209 | | | Browse | :white_check_mark: | 210 | | | AE | :new_moon: | 211 | | | reconnect on error | :waxing_crescent_moon: | 212 | | Server | | | 213 | | Commands | | | 214 | | | Restart | :white_check_mark: | 215 | | | Add Folder | :white_check_mark: | 216 | | | Set Folder | :white_check_mark: | 217 | | | Add Variable | :white_check_mark: | 218 | | | Add Object | :new_moon: | 219 | | | Add Method | :new_moon: | 220 | | | Add Equipment | :first_quarter_moon: | 221 | | | Add PhysicalAssets | :first_quarter_moon: | 222 | | | | | 223 | | | Delete by NodeId | :white_check_mark: | 224 | | Examples | | | 225 | | | Methods | | 226 | | | Structures | | 227 | | | Variables | | 228 | | | Objects | | 229 | | | AE | | 230 | | | | | 231 | | Alarm and Events | | | 232 | | | Subscribe | :white_check_mark: | 233 | | | | | 234 | 235 | [EMOJI CHEAT SHEET](http://www.emoji-cheat-sheet.com/) 236 | 237 | [1]:http://nodered.org 238 | [2]:https://github.com/mikakaraila 239 | [3]:https://github.com/biancode -------------------------------------------------------------------------------- /examples/Browser_contrib_ui_flow.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "7355c7ff.6875b8", 4 | "type": "tab", 5 | "label": "Flow 1", 6 | "disabled": false, 7 | "info": "" 8 | }, 9 | { 10 | "id": "bcb8bf9d.d874e", 11 | "type": "ui_template", 12 | "z": "7355c7ff.6875b8", 13 | "group": "95b70233.1d5dc", 14 | "name": "Browse", 15 | "order": 0, 16 | "width": "6", 17 | "height": "11", 18 | "format": "
\n \n \n
\n
\n \n
\n", 19 | "storeOutMessages": true, 20 | "fwdInMessages": false, 21 | "templateScope": "local", 22 | "x": 250.49998474121094, 23 | "y": 81.80000305175781, 24 | "wires": [ 25 | [ 26 | "1db890d7.e582cf", 27 | "420195c6.c1d27c" 28 | ] 29 | ] 30 | }, 31 | { 32 | "id": "1db890d7.e582cf", 33 | "type": "ui_toast", 34 | "z": "7355c7ff.6875b8", 35 | "position": "top right", 36 | "displayTime": "2", 37 | "highlight": "", 38 | "outputs": 0, 39 | "ok": "OK", 40 | "cancel": "", 41 | "topic": "Browsing...", 42 | "name": "Action", 43 | "x": 471.49998474121094, 44 | "y": 82.59999084472656, 45 | "wires": [] 46 | }, 47 | { 48 | "id": "420195c6.c1d27c", 49 | "type": "OpcUa-Browser", 50 | "z": "7355c7ff.6875b8", 51 | "endpoint": "b8f39990.157038", 52 | "item": "", 53 | "datatype": "", 54 | "topic": "ns=0;s=85/0:Simulation", 55 | "items": [], 56 | "x": 250.9000244140625, 57 | "y": 187.40000915527344, 58 | "wires": [ 59 | [ 60 | "bcb8bf9d.d874e" 61 | ] 62 | ] 63 | }, 64 | { 65 | "id": "95b70233.1d5dc", 66 | "type": "ui_group", 67 | "z": "", 68 | "name": "Default", 69 | "tab": "eaa395ff.8b6348", 70 | "disp": true, 71 | "width": "6", 72 | "collapse": false 73 | }, 74 | { 75 | "id": "b8f39990.157038", 76 | "type": "OpcUa-Endpoint", 77 | "z": "", 78 | "endpoint": "opc.tcp://TREL16087112.vstage.co:53530/OPCUA/SimulationServer", 79 | "secpol": "None", 80 | "secmode": "None", 81 | "login": false 82 | }, 83 | { 84 | "id": "eaa395ff.8b6348", 85 | "type": "ui_tab", 86 | "z": "", 87 | "name": "Home", 88 | "icon": "dashboard", 89 | "disabled": false, 90 | "hidden": false 91 | } 92 | ] 93 | -------------------------------------------------------------------------------- /examples/CODESYS_EXAMPLE.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "90eca945.1ad888", 4 | "type": "comment", 5 | "z": "2c6fbea3.d39042", 6 | "name": "CODESYS PI OPC-UA", 7 | "info": "using the CODESYS OPC-UA Project on Raspberry PI", 8 | "x": 946, 9 | "y": 109, 10 | "wires": [] 11 | }, 12 | { 13 | "id": "5c0aa8bd.bb60d8", 14 | "type": "comment", 15 | "z": "2c6fbea3.d39042", 16 | "name": "v1.0.0", 17 | "info": "Browse to find out the names from \nthe CODESYS PI OPC UA Model", 18 | "x": 901, 19 | "y": 71, 20 | "wires": [] 21 | }, 22 | { 23 | "id": "5e847ca.9ec4f84", 24 | "type": "inject", 25 | "z": "2c6fbea3.d39042", 26 | "name": "Read DeviceSet on PI Model", 27 | "topic": "ns=2;i=5001", 28 | "payload": "", 29 | "payloadType": "str", 30 | "repeat": "", 31 | "crontab": "", 32 | "once": false, 33 | "x": 173, 34 | "y": 82, 35 | "wires": [ 36 | [ 37 | "edd12196.77d17" 38 | ] 39 | ] 40 | }, 41 | { 42 | "id": "edd12196.77d17", 43 | "type": "OpcUa-Client", 44 | "z": "2c6fbea3.d39042", 45 | "endpoint": "opc.tcp://pinode.local:4840", 46 | "action": "browse", 47 | "time": "", 48 | "name": "Browse CODESYS PI OPC UA Server", 49 | "x": 349, 50 | "y": 185, 51 | "wires": [ 52 | [ 53 | "ecd69f22.5e6a6", 54 | "12bce249.b57b2e" 55 | ] 56 | ] 57 | }, 58 | { 59 | "id": "ecd69f22.5e6a6", 60 | "type": "debug", 61 | "z": "2c6fbea3.d39042", 62 | "name": "Browsed JSON", 63 | "active": true, 64 | "console": "false", 65 | "complete": "true", 66 | "x": 691, 67 | "y": 120, 68 | "wires": [] 69 | }, 70 | { 71 | "id": "12bce249.b57b2e", 72 | "type": "function", 73 | "z": "2c6fbea3.d39042", 74 | "name": "read browseName and topic", 75 | "func": "msg.payload=msg.browseName+\" - \"+msg.topic;\nreturn msg;", 76 | "outputs": 1, 77 | "noerr": 0, 78 | "x": 718, 79 | "y": 210, 80 | "wires": [ 81 | [ 82 | "b394601f.98b12" 83 | ] 84 | ] 85 | }, 86 | { 87 | "id": "b394601f.98b12", 88 | "type": "debug", 89 | "z": "2c6fbea3.d39042", 90 | "name": "browseName", 91 | "active": true, 92 | "console": "false", 93 | "complete": "payload", 94 | "x": 987, 95 | "y": 210, 96 | "wires": [] 97 | } 98 | ] -------------------------------------------------------------------------------- /examples/CUSTOM_OBJECT.json: -------------------------------------------------------------------------------- 1 | [{"id":"7f2a32b3.dbb0ac","type":"tab","label":"Server and Client - Custom Object","disabled":false,"info":""},{"id":"61f749e4.827ac8","type":"OpcUa-Endpoint","z":"","endpoint":"opc.tcp://localhost:53881","secpol":"None","secmode":"None","login":false},{"id":"e792520c.358e8","type":"OpcUa-Server","z":"7f2a32b3.dbb0ac","port":"53881","name":"Server Custom nodesets","endpoint":"","users":"users.json","nodesetDir":"C:\\TEMP\\TEST-CUSTOM","autoAcceptUnknownCertificate":true,"registerToDiscovery":false,"constructDefaultAddressSpace":false,"allowAnonymous":true,"endpointNone":true,"endpointSign":true,"endpointSignEncrypt":true,"endpointBasic128Rsa15":true,"endpointBasic256":true,"endpointBasic256Sha256":true,"maxNodesPerBrowse":0,"maxNodesPerHistoryReadData":0,"maxNodesPerHistoryReadEvents":0,"maxNodesPerHistoryUpdateData":0,"maxNodesPerRead":0,"maxNodesPerWrite":0,"maxNodesPerMethodCall":0,"maxNodesPerRegisterNodes":0,"maxNodesPerNodeManagement":0,"maxMonitoredItemsPerCall":0,"maxNodesPerHistoryUpdateEvents":0,"maxNodesPerTranslateBrowsePathsToNodeIds":0,"x":670,"y":140,"wires":[["29c30e84.2e3582"]]},{"id":"16049b2e.0c48c5","type":"inject","z":"7f2a32b3.dbb0ac","name":"Server Instantiate ExtensionObject","topic":"ns=1;s=Test2;datatype=ExtensionObject;typeId=ns=2;i=3010","payload":"{\"opcuaCommand\":\"addVariable\"}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":140,"wires":[["e792520c.358e8"]]},{"id":"43f40854.4b5cc8","type":"comment","z":"7f2a32b3.dbb0ac","name":"ns=1;s=Test2;datatype=ExtensionObject;typeId=ns=2;i=3010","info":"","x":520,"y":80,"wires":[]},{"id":"29c30e84.2e3582","type":"debug","z":"7f2a32b3.dbb0ac","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":890,"y":140,"wires":[]},{"id":"23c98b80.3b43f4","type":"comment","z":"7f2a32b3.dbb0ac","name":"AutoID: ScanSettings","info":"","x":140,"y":80,"wires":[]},{"id":"dba03f7c.31504","type":"OpcUa-Client","z":"7f2a32b3.dbb0ac","endpoint":"61f749e4.827ac8","action":"build","deadbandtype":"a","deadbandvalue":1,"time":10,"timeUnit":"s","certificate":"n","localfile":"","localkeyfile":"","securitymode":"None","securitypolicy":"None","name":"BUILD EXTENSION OBJ.","x":590,"y":240,"wires":[["97d60b2b.18f6f8","86fb61bc.bb133"]]},{"id":"46b488a6.8fc8d8","type":"OpcUa-Item","z":"7f2a32b3.dbb0ac","item":"ns=2;i=3010","datatype":"Extension Object","value":"","name":"","x":360,"y":240,"wires":[["dba03f7c.31504"]]},{"id":"cc62a0c6.322e5","type":"inject","z":"7f2a32b3.dbb0ac","name":"Client Get ExtensionObject","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":150,"y":240,"wires":[["46b488a6.8fc8d8"]]},{"id":"97d60b2b.18f6f8","type":"debug","z":"7f2a32b3.dbb0ac","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":890,"y":240,"wires":[]},{"id":"86fb61bc.bb133","type":"json","z":"7f2a32b3.dbb0ac","name":"","property":"payload","action":"obj","pretty":false,"x":790,"y":300,"wires":[["b20e0af0.1d2988","5c3039d9.fee838"]]},{"id":"b20e0af0.1d2988","type":"debug","z":"7f2a32b3.dbb0ac","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":930,"y":300,"wires":[]},{"id":"5c3039d9.fee838","type":"function","z":"7f2a32b3.dbb0ac","name":"Set values","func":"var myvar = {};\nmyvar.duration = 1000;\nmyvar.cycles = 5;\nmyvar.dataAvailable = true;\n\nmsg.dataType = \"ExtensionObject\";\n// Merge new values to payload\nObject.assign(msg.payload, myvar);\n\n// NOTE:\n// typeId need to constructExtensionObject\nmsg.topic=\"ns=1;s=Test2;datatype=ExtensionObject;typeId=ns=2;i=3010\";\nreturn msg;","outputs":1,"noerr":0,"x":950,"y":360,"wires":[["acad5c5f.c2a89","19957e89.f09aa1"]]},{"id":"acad5c5f.c2a89","type":"debug","z":"7f2a32b3.dbb0ac","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":1110,"y":360,"wires":[]},{"id":"19957e89.f09aa1","type":"OpcUa-Client","z":"7f2a32b3.dbb0ac","endpoint":"61f749e4.827ac8","action":"write","deadbandtype":"a","deadbandvalue":1,"time":10,"timeUnit":"s","certificate":"n","localfile":"","localkeyfile":"","securitymode":"None","securitypolicy":"None","name":"WRITE","x":1100,"y":420,"wires":[["d2e5abb0.3f5078"]]},{"id":"d2e5abb0.3f5078","type":"debug","z":"7f2a32b3.dbb0ac","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1270,"y":420,"wires":[]}] -------------------------------------------------------------------------------- /examples/EVENTS.json: -------------------------------------------------------------------------------- 1 | [{"id":"1fa0b22.ea7114e","type":"tab","label":"EVENTS","disabled":false,"info":""},{"id":"2e492080.82aa3","type":"OpcUa-Endpoint","z":"","endpoint":"","secpol":"None","secmode":"None","login":false},{"id":"f4ca709e.f1293","type":"OpcUa-Endpoint","z":"","endpoint":"opc.tcp://H7Q8Q13.mshome.net:53530/OPCUA/SimulationServer","secpol":"None","secmode":"None","login":false},{"id":"a0f5e5a3.f043e8","type":"OpcUa-Event","z":"1fa0b22.ea7114e","root":"i=2253","eventtype":"i=2041","name":"","x":440,"y":160,"wires":[["9d0a5ec1.e663b"]]},{"id":"9d0a5ec1.e663b","type":"OpcUa-Client","z":"1fa0b22.ea7114e","endpoint":"f4ca709e.f1293","action":"events","deadbandtype":"a","deadbandvalue":1,"time":10,"timeUnit":"s","certificate":"n","localfile":"","securitymode":"None","securitypolicy":"None","name":"","x":680,"y":160,"wires":[["62b0e35d.fcad8c"]]},{"id":"c026a47f.b45cc8","type":"inject","z":"1fa0b22.ea7114e","name":"Test","topic":"10","payload":"","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":230,"y":160,"wires":[["a0f5e5a3.f043e8"]]},{"id":"62b0e35d.fcad8c","type":"debug","z":"1fa0b22.ea7114e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":840,"y":160,"wires":[]}] -------------------------------------------------------------------------------- /examples/ExampleFlow.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "tab", 4 | "id": "3e32b2a4.2fb10e", 5 | "label": "TEST OPC UA" 6 | }, 7 | { 8 | "id": "7290d8b0.f713d8", 9 | "type": "OpcUa-Endpoint", 10 | "endpoint": "opc.tcp://localhost:62544/Quickstarts/AlarmConditionServer", 11 | "login": false 12 | }, 13 | { 14 | "id": "a49d5667.ad0348", 15 | "type": "OpcUa-Client", 16 | "z": "3e32b2a4.2fb10e", 17 | "endpoint": "7290d8b0.f713d8", 18 | "action": "browse", 19 | "time": "", 20 | "name": "Test server (browse)", 21 | "x": 340, 22 | "y": 120, 23 | "wires": [ 24 | [ 25 | "953a0ae5.f24f18", 26 | "a3410f1c.a3d45" 27 | ] 28 | ] 29 | }, 30 | { 31 | "id": "5a8e289.84101d8", 32 | "type": "OpcUa-Item", 33 | "z": "3e32b2a4.2fb10e", 34 | "item": "ns=4;s=free_memory", 35 | "datatype": "opcua.DataType.Double", 36 | "value": "", 37 | "name": "FreeMemory", 38 | "x": 370, 39 | "y": 340, 40 | "wires": [ 41 | [ 42 | "ed1b127f.79c5a" 43 | ] 44 | ] 45 | }, 46 | { 47 | "id": "d870ab21.de1068", 48 | "type": "OpcUa-Item", 49 | "z": "3e32b2a4.2fb10e", 50 | "item": "ns=1;i=1001", 51 | "datatype": "opcua.DataType.Double", 52 | "value": "66.6", 53 | "x": 360, 54 | "y": 500, 55 | "wires": [ 56 | [ 57 | "51a4a2b5.4fde4c" 58 | ] 59 | ] 60 | }, 61 | { 62 | "id": "fea7ccd.1d4a73", 63 | "type": "inject", 64 | "z": "3e32b2a4.2fb10e", 65 | "name": "Read", 66 | "topic": "", 67 | "payload": "", 68 | "payloadType": "str", 69 | "repeat": "", 70 | "crontab": "", 71 | "once": false, 72 | "x": 190, 73 | "y": 340, 74 | "wires": [ 75 | [ 76 | "5a8e289.84101d8" 77 | ] 78 | ] 79 | }, 80 | { 81 | "id": "cbb7cbd9.057e28", 82 | "type": "inject", 83 | "z": "3e32b2a4.2fb10e", 84 | "name": "Write", 85 | "topic": "", 86 | "payload": "", 87 | "payloadType": "str", 88 | "repeat": "", 89 | "crontab": "", 90 | "once": false, 91 | "x": 190, 92 | "y": 500, 93 | "wires": [ 94 | [ 95 | "d870ab21.de1068" 96 | ] 97 | ] 98 | }, 99 | { 100 | "id": "e067d795.cdf288", 101 | "type": "debug", 102 | "z": "3e32b2a4.2fb10e", 103 | "name": "Write value", 104 | "active": true, 105 | "console": "false", 106 | "complete": "true", 107 | "x": 910, 108 | "y": 500, 109 | "wires": [] 110 | }, 111 | { 112 | "id": "2776cbf5.8748e4", 113 | "type": "debug", 114 | "z": "3e32b2a4.2fb10e", 115 | "name": "Read value", 116 | "active": true, 117 | "console": "false", 118 | "complete": "true", 119 | "x": 910, 120 | "y": 360, 121 | "wires": [] 122 | }, 123 | { 124 | "id": "3d20140c.02bf8c", 125 | "type": "OpcUa-Item", 126 | "z": "3e32b2a4.2fb10e", 127 | "item": "ns=4;b=1020ffaa", 128 | "datatype": "opcua.DataType.Double", 129 | "value": "", 130 | "x": 360, 131 | "y": 380, 132 | "wires": [ 133 | [ 134 | "ed1b127f.79c5a" 135 | ] 136 | ] 137 | }, 138 | { 139 | "id": "12a9bc28.b04744", 140 | "type": "inject", 141 | "z": "3e32b2a4.2fb10e", 142 | "name": "Read", 143 | "topic": "", 144 | "payload": "", 145 | "payloadType": "str", 146 | "repeat": "", 147 | "crontab": "", 148 | "once": false, 149 | "x": 190, 150 | "y": 380, 151 | "wires": [ 152 | [ 153 | "3d20140c.02bf8c" 154 | ] 155 | ] 156 | }, 157 | { 158 | "id": "ed1b127f.79c5a", 159 | "type": "OpcUa-Client", 160 | "z": "3e32b2a4.2fb10e", 161 | "endpoint": "7290d8b0.f713d8", 162 | "action": "read", 163 | "time": "", 164 | "name": "Test server (read items)", 165 | "x": 630, 166 | "y": 360, 167 | "wires": [ 168 | [ 169 | "2776cbf5.8748e4" 170 | ] 171 | ] 172 | }, 173 | { 174 | "id": "7b3b26f.cb9c1d8", 175 | "type": "OpcUa-Item", 176 | "z": "3e32b2a4.2fb10e", 177 | "item": "ns=1;i=1001", 178 | "datatype": "opcua.DataType.Double", 179 | "value": "", 180 | "x": 360, 181 | "y": 460, 182 | "wires": [ 183 | [ 184 | "f9ade43a.99e918" 185 | ] 186 | ] 187 | }, 188 | { 189 | "id": "dafeb7f9.a570e8", 190 | "type": "inject", 191 | "z": "3e32b2a4.2fb10e", 192 | "name": "Subscribe (100ms)", 193 | "topic": "", 194 | "payload": "", 195 | "payloadType": "str", 196 | "repeat": "", 197 | "crontab": "", 198 | "once": false, 199 | "x": 150, 200 | "y": 460, 201 | "wires": [ 202 | [ 203 | "7b3b26f.cb9c1d8" 204 | ] 205 | ] 206 | }, 207 | { 208 | "id": "546cadf.3a79a54", 209 | "type": "inject", 210 | "z": "3e32b2a4.2fb10e", 211 | "name": "Browse", 212 | "topic": "ns=1;i=1000", 213 | "payload": "", 214 | "payloadType": "str", 215 | "repeat": "", 216 | "crontab": "", 217 | "once": false, 218 | "x": 90, 219 | "y": 100, 220 | "wires": [ 221 | [ 222 | "ac505af2.c46cf8", 223 | "a49d5667.ad0348" 224 | ] 225 | ] 226 | }, 227 | { 228 | "id": "29917983.7fe8f6", 229 | "type": "file", 230 | "z": "3e32b2a4.2fb10e", 231 | "name": "Address.txt", 232 | "filename": "./public/Address.txt", 233 | "appendNewline": true, 234 | "overwriteFile": false, 235 | "x": 750, 236 | "y": 120, 237 | "wires": [] 238 | }, 239 | { 240 | "id": "953a0ae5.f24f18", 241 | "type": "function", 242 | "z": "3e32b2a4.2fb10e", 243 | "name": "Items", 244 | "func": "msg.payload=msg.browseName+\"|\"+msg.topic;\nreturn msg;", 245 | "outputs": 1, 246 | "x": 570, 247 | "y": 120, 248 | "wires": [ 249 | [ 250 | "29917983.7fe8f6", 251 | "abe19393.892f8" 252 | ] 253 | ] 254 | }, 255 | { 256 | "id": "ac505af2.c46cf8", 257 | "type": "trigger", 258 | "z": "3e32b2a4.2fb10e", 259 | "op1": "object|address", 260 | "op2": "0", 261 | "op1type": "val", 262 | "op2type": "", 263 | "duration": "0", 264 | "extend": "false", 265 | "units": "ms", 266 | "name": "Clear file", 267 | "x": 380, 268 | "y": 60, 269 | "wires": [ 270 | [ 271 | "c73aab1d.28e818" 272 | ] 273 | ] 274 | }, 275 | { 276 | "id": "c73aab1d.28e818", 277 | "type": "file", 278 | "z": "3e32b2a4.2fb10e", 279 | "name": "Address.txt", 280 | "filename": "./public/Address.txt", 281 | "appendNewline": true, 282 | "overwriteFile": true, 283 | "x": 750, 284 | "y": 60, 285 | "wires": [] 286 | }, 287 | { 288 | "id": "51a4a2b5.4fde4c", 289 | "type": "OpcUa-Client", 290 | "z": "3e32b2a4.2fb10e", 291 | "endpoint": "7290d8b0.f713d8", 292 | "action": "write", 293 | "time": "", 294 | "name": "Test server (write items)", 295 | "x": 630, 296 | "y": 500, 297 | "wires": [ 298 | [ 299 | "e067d795.cdf288" 300 | ] 301 | ] 302 | }, 303 | { 304 | "id": "f9ade43a.99e918", 305 | "type": "OpcUa-Client", 306 | "z": "3e32b2a4.2fb10e", 307 | "endpoint": "7290d8b0.f713d8", 308 | "action": "subscribe", 309 | "time": "6", 310 | "timeUnit": "s", 311 | "name": "Test server (subscribe item)", 312 | "x": 620, 313 | "y": 460, 314 | "wires": [ 315 | [ 316 | "3ea9409a.7a155" 317 | ] 318 | ] 319 | }, 320 | { 321 | "id": "3ea9409a.7a155", 322 | "type": "debug", 323 | "z": "3e32b2a4.2fb10e", 324 | "name": "Subscribed values", 325 | "active": true, 326 | "console": "false", 327 | "complete": "true", 328 | "x": 930, 329 | "y": 460, 330 | "wires": [] 331 | }, 332 | { 333 | "id": "abe19393.892f8", 334 | "type": "debug", 335 | "z": "3e32b2a4.2fb10e", 336 | "name": "Address items", 337 | "active": false, 338 | "console": "false", 339 | "complete": "false", 340 | "x": 760, 341 | "y": 160, 342 | "wires": [] 343 | }, 344 | { 345 | "id": "c4992ccd.8d67", 346 | "type": "comment", 347 | "z": "3e32b2a4.2fb10e", 348 | "name": "v9", 349 | "info": "Browse node allows user to select item:\n- runtime browse\n- select RootFolder -> SubFolder\n- select Item\n\nActions:\nread\nwrite\nbrowse\nsubscribe\n\nNodes:\nclient node for actions\nitem node for defining item\n", 350 | "x": 910, 351 | "y": 60, 352 | "wires": [] 353 | }, 354 | { 355 | "id": "a3410f1c.a3d45", 356 | "type": "template", 357 | "z": "3e32b2a4.2fb10e", 358 | "name": "OpcUa-Item", 359 | "field": "payload", 360 | "template": "[{\"id\":\"4b12ca9b.e7e184\",\"type\":\"OpcUaItem\",\"item\":\"{{topic}}\",\"datatype\":\"opcua.DataType.Double\",\"value\":\"66.6\",\"name\":\"{{browseName}}\",\"x\":251,\"y\":334,\"z\":\"30ffd2ee.59fdd6\",\"wires\":[[\"70dd1397.3c8e44\"]]}]", 361 | "x": 550, 362 | "y": 240, 363 | "wires": [ 364 | [ 365 | "59bdb146.0cb58", 366 | "9180d5b.c8ccd28" 367 | ] 368 | ] 369 | }, 370 | { 371 | "id": "59bdb146.0cb58", 372 | "type": "function", 373 | "z": "3e32b2a4.2fb10e", 374 | "name": "Save to lib", 375 | "func": "msg.filename=\"./lib/templates/OPCUA/\"+msg.browseName+\".js\";\nmsg.payload=\"// name: \"+msg.browseName+\"\\n\"+\"// field: payload\\n\"+msg.payload;\n\nreturn msg;", 376 | "outputs": 1, 377 | "x": 750, 378 | "y": 240, 379 | "wires": [ 380 | [ 381 | "444e63f9.eb3bac", 382 | "4ceed8c1.a2b5a8" 383 | ] 384 | ] 385 | }, 386 | { 387 | "id": "444e63f9.eb3bac", 388 | "type": "debug", 389 | "z": "3e32b2a4.2fb10e", 390 | "name": "Pre-configured library items", 391 | "active": false, 392 | "console": "false", 393 | "complete": "true", 394 | "x": 980, 395 | "y": 260, 396 | "wires": [] 397 | }, 398 | { 399 | "id": "4ceed8c1.a2b5a8", 400 | "type": "file", 401 | "z": "3e32b2a4.2fb10e", 402 | "name": "OPC UA Items", 403 | "filename": "", 404 | "appendNewline": true, 405 | "overwriteFile": true, 406 | "x": 940, 407 | "y": 220, 408 | "wires": [] 409 | }, 410 | { 411 | "id": "9180d5b.c8ccd28", 412 | "type": "debug", 413 | "z": "3e32b2a4.2fb10e", 414 | "name": "", 415 | "active": true, 416 | "console": "false", 417 | "complete": "false", 418 | "x": 750, 419 | "y": 200, 420 | "wires": [] 421 | } 422 | ] -------------------------------------------------------------------------------- /examples/IGSS_OPCUA.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "tab", 4 | "id": "c1e582b2.7e3dc", 5 | "label": "IGSS OPC UA Tests" 6 | }, 7 | { 8 | "id": "7290d8b0.f713d8", 9 | "type": "OpcUa-Endpoint", 10 | "endpoint": "opc.tcp://localhost:62544/Quickstarts/AlarmConditionServer", 11 | "login": false 12 | }, 13 | { 14 | "id": "c5eee587.009a88", 15 | "type": "inject", 16 | "z": "c1e582b2.7e3dc", 17 | "name": "Test without Topic", 18 | "topic": "", 19 | "payload": "", 20 | "payloadType": "date", 21 | "repeat": "", 22 | "crontab": "", 23 | "once": false, 24 | "x": 130, 25 | "y": 180, 26 | "wires": [ 27 | [ 28 | "5f721d20.c74eb4" 29 | ] 30 | ] 31 | }, 32 | { 33 | "id": "470a5816.70d2f8", 34 | "type": "debug", 35 | "z": "c1e582b2.7e3dc", 36 | "name": "Browse", 37 | "active": true, 38 | "console": "false", 39 | "complete": "payload", 40 | "x": 760, 41 | "y": 180, 42 | "wires": [] 43 | }, 44 | { 45 | "id": "486b9c7f.892244", 46 | "type": "OpcUa-Item", 47 | "z": "c1e582b2.7e3dc", 48 | "item": "ns=2;s=1:PST-007-Alarm-Level@Training?VALUE", 49 | "datatype": "double", 50 | "value": "", 51 | "name": "", 52 | "x": 380, 53 | "y": 280, 54 | "wires": [ 55 | [ 56 | "f0864f8a.10649" 57 | ] 58 | ] 59 | }, 60 | { 61 | "id": "f0864f8a.10649", 62 | "type": "OpcUa-Client", 63 | "z": "c1e582b2.7e3dc", 64 | "endpoint": "7290d8b0.f713d8", 65 | "action": "read", 66 | "time": 10000, 67 | "name": "Read", 68 | "x": 590, 69 | "y": 340, 70 | "wires": [ 71 | [ 72 | "6618ad86.b92174" 73 | ] 74 | ] 75 | }, 76 | { 77 | "id": "6618ad86.b92174", 78 | "type": "debug", 79 | "z": "c1e582b2.7e3dc", 80 | "name": "Read", 81 | "active": true, 82 | "console": "false", 83 | "complete": "payload", 84 | "x": 750, 85 | "y": 340, 86 | "wires": [] 87 | }, 88 | { 89 | "id": "b54547b8.f84df8", 90 | "type": "inject", 91 | "z": "c1e582b2.7e3dc", 92 | "name": "Test read", 93 | "topic": "", 94 | "payload": "", 95 | "payloadType": "date", 96 | "repeat": "", 97 | "crontab": "", 98 | "once": false, 99 | "x": 160, 100 | "y": 340, 101 | "wires": [ 102 | [ 103 | "486b9c7f.892244", 104 | "777f4a48.793394", 105 | "a4fe7e50.10f4b", 106 | "ee44e61a.9ef058" 107 | ] 108 | ] 109 | }, 110 | { 111 | "id": "13359d18.d43f23", 112 | "type": "OpcUa-Item", 113 | "z": "c1e582b2.7e3dc", 114 | "item": "ns=2;s=1:PST-007-Alarm-Level@Training?SETPOINT", 115 | "datatype": "Double", 116 | "value": "", 117 | "name": "", 118 | "x": 380, 119 | "y": 440, 120 | "wires": [ 121 | [ 122 | "7baea106.60165" 123 | ] 124 | ] 125 | }, 126 | { 127 | "id": "7baea106.60165", 128 | "type": "OpcUa-Client", 129 | "z": "c1e582b2.7e3dc", 130 | "endpoint": "7290d8b0.f713d8", 131 | "action": "write", 132 | "time": 10000, 133 | "name": "Write", 134 | "x": 590, 135 | "y": 440, 136 | "wires": [ 137 | [ 138 | "f90e6b13.52bad8" 139 | ] 140 | ] 141 | }, 142 | { 143 | "id": "f90e6b13.52bad8", 144 | "type": "debug", 145 | "z": "c1e582b2.7e3dc", 146 | "name": "Write", 147 | "active": true, 148 | "console": "false", 149 | "complete": "true", 150 | "x": 750, 151 | "y": 440, 152 | "wires": [] 153 | }, 154 | { 155 | "id": "fd381405.f82898", 156 | "type": "OpcUa-Client", 157 | "z": "c1e582b2.7e3dc", 158 | "endpoint": "7290d8b0.f713d8", 159 | "action": "subscribe", 160 | "time": "5", 161 | "timeUnit": "s", 162 | "name": "Subscribe", 163 | "x": 580, 164 | "y": 240, 165 | "wires": [ 166 | [ 167 | "807f2a5b.9740c8" 168 | ] 169 | ] 170 | }, 171 | { 172 | "id": "807f2a5b.9740c8", 173 | "type": "debug", 174 | "z": "c1e582b2.7e3dc", 175 | "name": "Subs", 176 | "active": true, 177 | "console": "false", 178 | "complete": "payload", 179 | "x": 750, 180 | "y": 240, 181 | "wires": [] 182 | }, 183 | { 184 | "id": "777f4a48.793394", 185 | "type": "OpcUa-Item", 186 | "z": "c1e582b2.7e3dc", 187 | "item": "ns=2;s=1:PST-007-Alarm-Level@Training?HIGH_SCALE", 188 | "datatype": "double", 189 | "value": "", 190 | "name": "", 191 | "x": 380, 192 | "y": 320, 193 | "wires": [ 194 | [ 195 | "f0864f8a.10649" 196 | ] 197 | ] 198 | }, 199 | { 200 | "id": "a4fe7e50.10f4b", 201 | "type": "OpcUa-Item", 202 | "z": "c1e582b2.7e3dc", 203 | "item": "ns=2;s=1:PST-007-Alarm-Level@Training?LOW_SCALE", 204 | "datatype": "double", 205 | "value": "", 206 | "name": "", 207 | "x": 380, 208 | "y": 360, 209 | "wires": [ 210 | [ 211 | "f0864f8a.10649" 212 | ] 213 | ] 214 | }, 215 | { 216 | "id": "51b76b2e.a38d14", 217 | "type": "OpcUa-Item", 218 | "z": "c1e582b2.7e3dc", 219 | "item": "ns=2;s=1:PST-007-Alarm-Level@Training?SETPOINT", 220 | "datatype": "double", 221 | "value": "4", 222 | "name": "", 223 | "x": 380, 224 | "y": 240, 225 | "wires": [ 226 | [ 227 | "fd381405.f82898" 228 | ] 229 | ] 230 | }, 231 | { 232 | "id": "633b6abc.947534", 233 | "type": "inject", 234 | "z": "c1e582b2.7e3dc", 235 | "name": "Test subs (250ms)", 236 | "topic": "", 237 | "payload": "250", 238 | "payloadType": "num", 239 | "repeat": "", 240 | "crontab": "", 241 | "once": false, 242 | "x": 130, 243 | "y": 240, 244 | "wires": [ 245 | [ 246 | "51b76b2e.a38d14" 247 | ] 248 | ] 249 | }, 250 | { 251 | "id": "38a57fd8.732b3", 252 | "type": "inject", 253 | "z": "c1e582b2.7e3dc", 254 | "name": "Test write 2.5", 255 | "topic": "", 256 | "payload": " 2.5", 257 | "payloadType": "str", 258 | "repeat": "", 259 | "crontab": "", 260 | "once": false, 261 | "x": 150, 262 | "y": 420, 263 | "wires": [ 264 | [ 265 | "13359d18.d43f23" 266 | ] 267 | ] 268 | }, 269 | { 270 | "id": "32ebb557.602eea", 271 | "type": "inject", 272 | "z": "c1e582b2.7e3dc", 273 | "name": "Test write 3.5", 274 | "topic": "", 275 | "payload": " 3.5", 276 | "payloadType": "string", 277 | "repeat": "", 278 | "crontab": "", 279 | "once": false, 280 | "x": 150, 281 | "y": 460, 282 | "wires": [ 283 | [ 284 | "13359d18.d43f23" 285 | ] 286 | ] 287 | }, 288 | { 289 | "id": "ee44e61a.9ef058", 290 | "type": "OpcUa-Item", 291 | "z": "c1e582b2.7e3dc", 292 | "item": "ns=2;s=1:PST-007-Alarm-Level@Training?SETPOINT", 293 | "datatype": "double", 294 | "value": "4", 295 | "name": "", 296 | "x": 380, 297 | "y": 400, 298 | "wires": [ 299 | [ 300 | "f0864f8a.10649" 301 | ] 302 | ] 303 | }, 304 | { 305 | "id": "f4dc2e15.d4872", 306 | "type": "OpcUa-Client", 307 | "z": "c1e582b2.7e3dc", 308 | "endpoint": "7290d8b0.f713d8", 309 | "action": "browse", 310 | "time": 10000, 311 | "name": "Browse", 312 | "x": 580, 313 | "y": 120, 314 | "wires": [ 315 | [ 316 | "8a361383.b5992" 317 | ] 318 | ] 319 | }, 320 | { 321 | "id": "17f810e6.2ef63f", 322 | "type": "inject", 323 | "z": "c1e582b2.7e3dc", 324 | "name": "Test with Topic", 325 | "topic": "ns=2;s=0:IGSS Objects/Area/Cases/Diagram/Boiler@Cases/Template", 326 | "payload": "", 327 | "payloadType": "str", 328 | "repeat": "", 329 | "crontab": "", 330 | "once": false, 331 | "x": 140, 332 | "y": 120, 333 | "wires": [ 334 | [ 335 | "f4dc2e15.d4872" 336 | ] 337 | ] 338 | }, 339 | { 340 | "id": "2dd2de5a.91ff52", 341 | "type": "debug", 342 | "z": "c1e582b2.7e3dc", 343 | "name": "Browse", 344 | "active": true, 345 | "console": "false", 346 | "complete": "payload", 347 | "x": 940, 348 | "y": 120, 349 | "wires": [] 350 | }, 351 | { 352 | "id": "8a361383.b5992", 353 | "type": "template", 354 | "z": "c1e582b2.7e3dc", 355 | "name": "OpcUa-Item", 356 | "field": "payload", 357 | "format": "handlebars", 358 | "template": "[{\"id\":\"4b12ca9b.e7e184\",\"type\":\"OpcUa-Item\",\"item\":\"{{topic}}\",\"datatype\":\"opcua.DataType.Double\",\"value\":\"\",\"name\":\"{{browseName}}\",\"x\":251,\"y\":334,\"z\":\"30ffd2ee.59fdd6\",\"wires\":[[\"70dd1397.3c8e44\"]]}]", 359 | "x": 770, 360 | "y": 120, 361 | "wires": [ 362 | [ 363 | "2dd2de5a.91ff52" 364 | ] 365 | ] 366 | }, 367 | { 368 | "id": "5f721d20.c74eb4", 369 | "type": "OpcUa-Browser", 370 | "z": "c1e582b2.7e3dc", 371 | "endpoint": "", 372 | "item": "", 373 | "datatype": "", 374 | "topic": "ns=2;s=0:IGSS Objects/(All)", 375 | "items": [], 376 | "x": 550, 377 | "y": 180, 378 | "wires": [ 379 | [ 380 | "470a5816.70d2f8" 381 | ] 382 | ] 383 | } 384 | ] -------------------------------------------------------------------------------- /examples/METHOD.json: -------------------------------------------------------------------------------- 1 | [{"id":"4d24eae5.3b9b24","type":"tab","label":"METHOD TESTS","disabled":false,"info":""},{"id":"cd011dd0.e86e","type":"OpcUa-Endpoint","z":"","endpoint":"opc.tcp://H7Q8Q13.mshome.net:53530/OPCUA/SimulationServer","secpol":"None","secmode":"None","login":false},{"id":"9b199c7f.82f47","type":"OpcUa-Method","z":"4d24eae5.3b9b24","endpoint":"cd011dd0.e86e","objectId":"ns=5;s=MyDevice","methodId":"ns=5;s=MyMethod","name":"Prosys MyMethod(sin, 3.3)","inputArguments":[],"arg0name":"Operator","arg0type":"String","arg0value":"sin","arg1name":"Value","arg1type":"Double","arg1value":"3.3","arg2name":"","arg2type":"","arg2value":"","x":760,"y":120,"wires":[["aad9fc2a.a94b4"]]},{"id":"2337d4d6.fd29dc","type":"inject","z":"4d24eae5.3b9b24","name":"","topic":"Test1","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":210,"y":120,"wires":[["9b199c7f.82f47"]]},{"id":"aad9fc2a.a94b4","type":"debug","z":"4d24eae5.3b9b24","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":1010,"y":120,"wires":[]},{"id":"892ea475.154008","type":"function","z":"4d24eae5.3b9b24","name":"pow","func":"msg.objectId=\"ns=5;s=MyDevice\";\nmsg.methodId=\"ns=5;s=MyMethod\";\nmsg.inputArguments=[{dataType: \"String\", value:\"pow\"}, {dataType:\"Double\", value: 3}];\n\nreturn msg;","outputs":1,"noerr":0,"x":450,"y":180,"wires":[["9b199c7f.82f47"]]},{"id":"4d72774f.c4c9a8","type":"inject","z":"4d24eae5.3b9b24","name":"","topic":"Test2","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":210,"y":180,"wires":[["892ea475.154008"]]},{"id":"b55d1c05.9588c","type":"comment","z":"4d24eae5.3b9b24","name":"Call method by node parameters","info":"","x":410,"y":80,"wires":[]},{"id":"80ce9863.0c99f8","type":"comment","z":"4d24eae5.3b9b24","name":"Call method by injecting message","info":"","x":410,"y":220,"wires":[]}] -------------------------------------------------------------------------------- /examples/OPCUA Browser endpointBrowse example.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "58c0065ebdc1d89d", 4 | "type": "tab", 5 | "label": "OPC UA Browser endpointBrowse example", 6 | "disabled": true, 7 | "info": "", 8 | "env": [] 9 | }, 10 | { 11 | "id": "956a4221da6bda1f", 12 | "type": "function", 13 | "z": "58c0065ebdc1d89d", 14 | "name": "browse with specific endpoint", 15 | "func": "msg.payload={\"actiontype\":\"endpointBrowse\"};\nmsg.OpcUaEndpoint = {\n credentials: {},\n endpoint: msg.endpoint,\n securityPolicy: 'None',\n securityMode: 'None',\n login: false,\n user: undefined,\n password: undefined \n}\n\nreturn msg;", 16 | "outputs": 1, 17 | "noerr": 0, 18 | "initialize": "", 19 | "finalize": "", 20 | "libs": [], 21 | "x": 460, 22 | "y": 200, 23 | "wires": [ 24 | [ 25 | "6b17b2da2b942bb4" 26 | ] 27 | ] 28 | }, 29 | { 30 | "id": "3bcd718c7e713c9d", 31 | "type": "inject", 32 | "z": "58c0065ebdc1d89d", 33 | "name": "endpointBrowse", 34 | "props": [ 35 | { 36 | "p": "endpoint", 37 | "v": "opc.tcp://192.168.137.1:53530/OPCUA/SimulationServer", 38 | "vt": "str" 39 | }, 40 | { 41 | "p": "topic", 42 | "vt": "str" 43 | } 44 | ], 45 | "repeat": "", 46 | "crontab": "", 47 | "once": false, 48 | "onceDelay": "0", 49 | "topic": "ns=3;s=85/0:Simulation", 50 | "x": 200, 51 | "y": 200, 52 | "wires": [ 53 | [ 54 | "956a4221da6bda1f" 55 | ] 56 | ] 57 | }, 58 | { 59 | "id": "869acefead40215e", 60 | "type": "debug", 61 | "z": "58c0065ebdc1d89d", 62 | "name": "", 63 | "active": true, 64 | "tosidebar": true, 65 | "console": false, 66 | "tostatus": false, 67 | "complete": "true", 68 | "targetType": "full", 69 | "statusVal": "", 70 | "statusType": "auto", 71 | "x": 890, 72 | "y": 200, 73 | "wires": [] 74 | }, 75 | { 76 | "id": "6b17b2da2b942bb4", 77 | "type": "OpcUa-Browser", 78 | "z": "58c0065ebdc1d89d", 79 | "endpoint": "83439742.083188", 80 | "item": "", 81 | "datatype": "", 82 | "topic": "", 83 | "items": [], 84 | "name": "", 85 | "x": 690, 86 | "y": 200, 87 | "wires": [ 88 | [ 89 | "869acefead40215e" 90 | ] 91 | ] 92 | }, 93 | { 94 | "id": "83439742.083188", 95 | "type": "OpcUa-Endpoint", 96 | "endpoint": "opc.tcp://0.0.0.0:4840/", 97 | "secpol": "None", 98 | "secmode": "None", 99 | "login": false 100 | } 101 | ] -------------------------------------------------------------------------------- /examples/OPCUA-CONNECT.json: -------------------------------------------------------------------------------- 1 | [{"id":"16253f37594af6b7","type":"tab","label":"Flow 1","disabled":false,"info":"","env":[]},{"id":"5e9ff8d62009cce2","type":"OpcUa-Client","z":"16253f37594af6b7","endpoint":"1b1425813f5ea7f6","action":"read","deadbandtype":"a","deadbandvalue":1,"time":10,"timeUnit":"s","certificate":"n","localfile":"","localkeyfile":"","securitymode":"None","securitypolicy":"None","name":"","x":640,"y":200,"wires":[["ee51f9804aed9353"]]},{"id":"ddadebfa90c83c16","type":"OpcUa-Item","z":"16253f37594af6b7","item":"ns=3;i=1001","datatype":"Double","value":"","name":"Counter","x":400,"y":200,"wires":[["5e9ff8d62009cce2"]]},{"id":"37d3f8bb713d74f4","type":"inject","z":"16253f37594af6b7","name":"Read","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payloadType":"date","x":170,"y":200,"wires":[["ddadebfa90c83c16"]]},{"id":"3b25388d1be4453d","type":"inject","z":"16253f37594af6b7","name":"Disconnect","props":[{"p":"action","v":"disconnect","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":240,"y":280,"wires":[["5e9ff8d62009cce2"]]},{"id":"ee51f9804aed9353","type":"debug","z":"16253f37594af6b7","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":880,"y":200,"wires":[]},{"id":"19f724539cac24ae","type":"inject","z":"16253f37594af6b7","name":"Connect","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":220,"y":340,"wires":[["0527d8662773f724"]]},{"id":"f51a14507dc17b69","type":"inject","z":"16253f37594af6b7","name":"Reconnect","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":280,"y":420,"wires":[["1578860caf6ef5e5"]]},{"id":"0527d8662773f724","type":"function","z":"16253f37594af6b7","name":"set options","func":"msg.action = 'connect';\nmsg.OpcUaEndpoint = {}; // Initialize msg.OpcUaEndpoint as an empty object\nmsg.OpcUaEndpoint.endpoint = 'opc.tcp://H7Q8Q13.mshome.net:53530/OPCUA/SimulationServer';\nmsg.OpcUaEndpoint.securityMode = 'None';\nmsg.OpcUaEndpoint.securityPolicy = 'None';\nmsg.OpcUaEndpoint.login = false;\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":370,"y":340,"wires":[["5e9ff8d62009cce2"]]},{"id":"1578860caf6ef5e5","type":"function","z":"16253f37594af6b7","name":"set options","func":"msg.action = 'connect';\nmsg.OpcUaEndpoint = {}; // Initialize msg.OpcUaEndpoint as an empty object\nmsg.OpcUaEndpoint.endpoint = 'opc.tcp://H7Q8Q13.mshome.net:53530/OPCUA/SimulationServer';\nmsg.OpcUaEndpoint.securityMode = 'None';\nmsg.OpcUaEndpoint.securityPolicy = 'None';\nmsg.OpcUaEndpoint.login = false;\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":430,"y":420,"wires":[["5e9ff8d62009cce2"]]},{"id":"1b1425813f5ea7f6","type":"OpcUa-Endpoint","endpoint":"opc.tcp://H7Q8Q13.mshome.net:53530/OPCUA/SimulationServer","secpol":"None","secmode":"None","login":false}] 2 | -------------------------------------------------------------------------------- /examples/OPCUA-FILE.json: -------------------------------------------------------------------------------- 1 | [{"id":"cc9eb060.bb1cc","type":"tab","label":"OPCUA-FILE","disabled":false,"info":"Read file: msg.topic contains file object nodeId.\n msg.payload is buffer to file content.\n\nWrite file: msg.topic contains file object nodeId.\n msg.payload is buffer to write.\n OR\n msg.fileName is fileName to write.\n "},{"id":"823a6f11.f75ab","type":"OpcUa-Endpoint","z":"","endpoint":"opc.tcp://localhost:53881/","secpol":"None","secmode":"None","login":false},{"id":"82ea0973.b4a6f8","type":"OpcUa-Client","z":"cc9eb060.bb1cc","endpoint":"823a6f11.f75ab","action":"readfile","deadbandtype":"a","deadbandvalue":1,"time":10,"timeUnit":"s","certificate":"n","localfile":"","localkeyfile":"","securitymode":"None","securitypolicy":"None","name":"Read file","x":660,"y":160,"wires":[["46740567.08d56c"]]},{"id":"11c3035e.d38a9d","type":"OpcUa-Client","z":"cc9eb060.bb1cc","endpoint":"823a6f11.f75ab","action":"writefile","deadbandtype":"a","deadbandvalue":1,"time":10,"timeUnit":"s","certificate":"n","localfile":"","localkeyfile":"","securitymode":"None","securitypolicy":"None","name":"Write file","x":660,"y":260,"wires":[["fa75a5d4.270ab8"]]},{"id":"cf6248b1.2b8e08","type":"inject","z":"cc9eb060.bb1cc","name":"test.txt","topic":"ns=1;s=test.txt","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":410,"y":160,"wires":[["82ea0973.b4a6f8"]]},{"id":"ee95982.0c49568","type":"debug","z":"cc9eb060.bb1cc","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1050,"y":160,"wires":[]},{"id":"46740567.08d56c","type":"function","z":"cc9eb060.bb1cc","name":"toString()","func":"msg.payload = msg.payload.toString();\nreturn msg;","outputs":1,"noerr":0,"x":860,"y":160,"wires":[["ee95982.0c49568"]]},{"id":"2250e9cf.2ac036","type":"file in","z":"cc9eb060.bb1cc","name":"test.txt","filename":"c:/temp/test.txt","format":"","chunk":false,"sendError":false,"encoding":"none","x":430,"y":260,"wires":[["11c3035e.d38a9d"]]},{"id":"fa75a5d4.270ab8","type":"debug","z":"cc9eb060.bb1cc","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":890,"y":260,"wires":[]},{"id":"d7dc1e74.4f43a","type":"inject","z":"cc9eb060.bb1cc","name":"Upload file","topic":"ns=1;s=test.txt","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":220,"y":260,"wires":[["2250e9cf.2ac036"]]},{"id":"d2f04835.f3a458","type":"inject","z":"cc9eb060.bb1cc","name":"Upload msg to file","topic":"ns=1;s=test.txt","payload":"Test message to server","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":450,"y":340,"wires":[["11c3035e.d38a9d"]]},{"id":"d29d4204.19fdf","type":"OpcUa-Server","z":"cc9eb060.bb1cc","port":"53881","name":"","endpoint":"","users":"users.json","nodesetDir":"","autoAcceptUnknownCertificate":true,"registerToDiscovery":false,"constructDefaultAddressSpace":false,"allowAnonymous":true,"endpointNone":true,"endpointSign":true,"endpointSignEncrypt":true,"endpointBasic128Rsa15":true,"endpointBasic256":true,"endpointBasic256Sha256":true,"maxNodesPerBrowse":0,"maxNodesPerHistoryReadData":0,"maxNodesPerHistoryReadEvents":0,"maxNodesPerHistoryUpdateData":0,"maxNodesPerRead":0,"maxNodesPerWrite":0,"maxNodesPerMethodCall":0,"maxNodesPerRegisterNodes":0,"maxNodesPerNodeManagement":0,"maxMonitoredItemsPerCall":0,"maxNodesPerHistoryUpdateEvents":0,"maxNodesPerTranslateBrowsePathsToNodeIds":0,"x":660,"y":60,"wires":[[]]},{"id":"dc1f80b3.194a4","type":"inject","z":"cc9eb060.bb1cc","name":"addFolder: Files","topic":"ns=1;s=Files","payload":"{\"opcuaCommand\":\"addFolder\"}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":400,"y":60,"wires":[["d29d4204.19fdf"]]},{"id":"7b93ad58.092574","type":"inject","z":"cc9eb060.bb1cc","name":"addFile: c:/temp/test.txt","topic":"ns=1;s=test.txt","payload":"{\"opcuaCommand\":\"addFile\",\"fileName\":\"c:/temp/test.txt\"}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":420,"y":100,"wires":[["d29d4204.19fdf"]]},{"id":"606d3f0e.c064b","type":"file in","z":"cc9eb060.bb1cc","name":"test2.txt","filename":"c:/temp/test2.txt","format":"","chunk":false,"sendError":false,"encoding":"none","x":440,"y":300,"wires":[["11c3035e.d38a9d"]]},{"id":"13898694.94ee89","type":"inject","z":"cc9eb060.bb1cc","name":"Upload file","topic":"ns=1;s=test.txt","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":220,"y":300,"wires":[["606d3f0e.c064b"]]}] -------------------------------------------------------------------------------- /examples/OPCUA-MULTI-SUB.json: -------------------------------------------------------------------------------- 1 | [{"id":"7008401a.b94db","type":"tab","label":"Subscribe Multiple","disabled":false,"info":"Code actually uses monitoredItemGroup"},{"id":"68021f9.ba14de","type":"OpcUa-Endpoint","z":"","endpoint":"opc.tcp://localhost:53530/OPCUA/SimulationServer","secpol":"None","secmode":"None","login":false},{"id":"bbf28314.1321f","type":"function","z":"7008401a.b94db","name":"NodeId Array","func":"// Tested with Prosys\nmsg.topic = \"multiple\";\nmsg.payload = [];\nmsg.payload.push({\n // Counter\n nodeId: \"ns=3;i=1001\"\n});\nmsg.payload.push({\n // Random\n nodeId: \"ns=3;i=1002\",\n});\nmsg.payload.push({\n // Sawtooth\n nodeId: \"ns=3;i=1003\",\n});\nreturn msg;","outputs":1,"noerr":0,"x":600,"y":280,"wires":[["244b0726.cf6e98"]]},{"id":"700c6d99.0e7a84","type":"inject","z":"7008401a.b94db","name":"Subscribe multiple","topic":"multiple","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":310,"y":280,"wires":[["bbf28314.1321f"]]},{"id":"244b0726.cf6e98","type":"OpcUa-Client","z":"7008401a.b94db","endpoint":"68021f9.ba14de","action":"subscribe","deadbandtype":"a","deadbandvalue":1,"time":10,"timeUnit":"s","certificate":"n","localfile":"","localkeyfile":"","securitymode":"None","securitypolicy":"None","name":"","x":900,"y":280,"wires":[["ce737735.8cd168","d0e678a9.503678"]]},{"id":"ce737735.8cd168","type":"debug","z":"7008401a.b94db","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1120,"y":280,"wires":[]},{"id":"d0e678a9.503678","type":"function","z":"7008401a.b94db","name":"Just value","func":"if (msg.payload && msg.payload.value) {\n var value = msg.payload.value.value;\n msg.payload = value;\n return msg;\n}\n","outputs":1,"noerr":0,"x":1130,"y":140,"wires":[["d26bd7f3.ee7fb8"]]},{"id":"d26bd7f3.ee7fb8","type":"debug","z":"7008401a.b94db","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1320,"y":140,"wires":[]},{"id":"93d8a766.c57aa8","type":"function","z":"7008401a.b94db","name":"NodeId Array (Static variables)","func":"// Tested with Prosys static variables\nmsg.topic = \"multiple\";\nmsg.payload = [];\nmsg.payload.push({nodeId: \"ns=5;s=Boolean\"});\nmsg.payload.push({nodeId: \"ns=5;s=Double\"});\nmsg.payload.push({nodeId: \"ns=5;s=Int32\"});\nreturn msg;","outputs":1,"noerr":0,"x":670,"y":520,"wires":[["ba45b808.7ff578"]]},{"id":"2d805dd3.473632","type":"inject","z":"7008401a.b94db","name":"Subscribe multiple","topic":"multiple","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":320,"y":520,"wires":[["93d8a766.c57aa8"]]},{"id":"ba45b808.7ff578","type":"OpcUa-Client","z":"7008401a.b94db","endpoint":"68021f9.ba14de","action":"subscribe","deadbandtype":"a","deadbandvalue":1,"time":10,"timeUnit":"s","certificate":"n","localfile":"","localkeyfile":"","securitymode":"None","securitypolicy":"None","name":"","x":910,"y":520,"wires":[["b47c1a47.beec88","20bed05d.ee2b7"]]},{"id":"b47c1a47.beec88","type":"debug","z":"7008401a.b94db","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1130,"y":520,"wires":[]},{"id":"20bed05d.ee2b7","type":"function","z":"7008401a.b94db","name":"Just value","func":"if (msg.payload && msg.payload.value) {\n var value = msg.payload.value.value;\n msg.payload = value;\n return msg;\n}\n","outputs":1,"noerr":0,"x":1140,"y":380,"wires":[["73a247cf.4ded28"]]},{"id":"73a247cf.4ded28","type":"debug","z":"7008401a.b94db","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1330,"y":380,"wires":[]},{"id":"d7570c98.640e1","type":"comment","z":"7008401a.b94db","name":"Instructions","info":"# topic\nmsg.topic must be \"multiple\"\n\n# payload\nmsg.paylod contains array of nodeId objects\n{\"nodeId\": \"ns=1;s=NodeIdString\"\n","x":270,"y":80,"wires":[]}] -------------------------------------------------------------------------------- /examples/OPCUA-TEST-UNSUB.json: -------------------------------------------------------------------------------- 1 | [{"id":"d182dea9.2173a","type":"tab","label":"Subscribe/unsubscribe","disabled":false,"info":""},{"id":"4874e371.af4abc","type":"OpcUa-Endpoint","z":"","endpoint":"opc.tcp://TREL16087112.vstage.co:53530/OPCUA/SimulationServer","secpol":"None","secmode":"None","login":false},{"id":"9a848d03.e43d58","type":"inject","z":"d182dea9.2173a","name":"Test subscribe","topic":"","payload":"200","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":153.49998474121094,"y":76,"wires":[["5262ca3f.dc949c"]]},{"id":"5262ca3f.dc949c","type":"OpcUa-Item","z":"d182dea9.2173a","item":"ns=5;s=Counter1","datatype":"Int32","value":"","name":"ns=5;s=Counter1","x":354.9000244140625,"y":75.39999389648438,"wires":[["607dc1bd.9d4748"]]},{"id":"389ba094.cf07d","type":"OpcUa-Client","z":"d182dea9.2173a","endpoint":"4874e371.af4abc","action":"subscribe","deadbandtype":"a","deadbandvalue":1,"time":"1","timeUnit":"s","certificate":"n","localfile":"","name":"","x":713.9000854492188,"y":142,"wires":[["a380cc4a.a5ab68"]]},{"id":"a380cc4a.a5ab68","type":"debug","z":"d182dea9.2173a","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":911.5000610351562,"y":139.39999389648438,"wires":[]},{"id":"a253b44e.ae9f6","type":"inject","z":"d182dea9.2173a","name":"Test unsubscribe","topic":"","payload":"200","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":147.1999969482422,"y":208.1999969482422,"wires":[["8e9a8d07.99162"]]},{"id":"8e9a8d07.99162","type":"OpcUa-Item","z":"d182dea9.2173a","item":"ns=5;s=Counter1","datatype":"Int32","value":"","name":"ns=5;s=Counter1","x":343.60003662109375,"y":208.59999084472656,"wires":[["22c6cbe3.b9f9cc"]]},{"id":"22c6cbe3.b9f9cc","type":"function","z":"d182dea9.2173a","name":"Unsubscribe","func":"msg.action=\"unsubscribe\";\nreturn msg;","outputs":1,"noerr":0,"x":525.9000244140625,"y":208.59999084472656,"wires":[["389ba094.cf07d"]]},{"id":"607dc1bd.9d4748","type":"function","z":"d182dea9.2173a","name":"Subscribe","func":"msg.action=\"subscribe\";\nreturn msg;","outputs":1,"noerr":0,"x":532.2000122070312,"y":75.19999694824219,"wires":[["389ba094.cf07d"]]}] -------------------------------------------------------------------------------- /examples/OPCUA-TEST.json: -------------------------------------------------------------------------------- 1 | [{"id":"806988c4.3acf58","type":"tab","label":"OPC UA Server"},{"id":"f8b67141.37c5e","type":"tab","label":"Clients"},{"id":"1ca40846.98b2f8","type":"OpcUa-Endpoint","z":"f8b67141.37c5e","endpoint":"opc.tcp://localhost:53880/UA/SimpleNodeRedServer","login":false},{"id":"37bec949.2f5236","type":"debug","z":"806988c4.3acf58","name":"","active":false,"console":"false","complete":"false","x":840.5000152587891,"y":122,"wires":[]},{"id":"5d7fc3f3.4a71cc","type":"OpcUa-Server","z":"806988c4.3acf58","port":"53880","name":"OPC-UA Server","endpoint":"UA/SimpleNodeRedServer","x":635.5000152587891,"y":119,"wires":[["37bec949.2f5236"]]},{"id":"8618cbf7.780948","type":"inject","z":"806988c4.3acf58","name":"New variable (Int32)","topic":"ns=4;s=TestInt32;datatype=Int32","payload":"{ \"opcuaCommand\": \"addVariable\" }","payloadType":"json","repeat":"","crontab":"","once":false,"x":300.5000762939453,"y":50,"wires":[["5d7fc3f3.4a71cc","2f0bde9a.e8b2e2"]]},{"id":"2f0bde9a.e8b2e2","type":"debug","z":"806988c4.3acf58","name":"","active":false,"console":"false","complete":"true","x":820.5000152587891,"y":47.00000762939453,"wires":[]},{"id":"fe18240c.116f48","type":"inject","z":"806988c4.3acf58","name":"New variable (UInt16)","topic":"ns=4;s=TestInt16;datatype=UInt16","payload":"{ \"opcuaCommand\": \"addVariable\" }","payloadType":"json","repeat":"","crontab":"","once":false,"x":295.2000274658203,"y":91.19999694824219,"wires":[["5d7fc3f3.4a71cc"]]},{"id":"b7f5b56a.f3ba28","type":"inject","z":"806988c4.3acf58","name":"addFolder (DynamicFolder)","topic":"ns=4;s=DynamicFolder","payload":"{ \"opcuaCommand\": \"addFolder\" }","payloadType":"json","repeat":"","crontab":"","once":false,"x":285.2000274658203,"y":133.1999969482422,"wires":[["5d7fc3f3.4a71cc"]]},{"id":"6b0c9e6a.e32e7","type":"inject","z":"806988c4.3acf58","name":"New variable (Boolean)","topic":"ns=4;s=TestBoolean;datatype=Boolean","payload":"{ \"opcuaCommand\": \"addVariable\" }","payloadType":"json","repeat":"","crontab":"","once":false,"x":298.2000274658203,"y":175.1999969482422,"wires":[["5d7fc3f3.4a71cc"]]},{"id":"cbb1c7f4.fddf28","type":"inject","z":"806988c4.3acf58","name":"setFolder (VendorName)","topic":"ns=4;s=VendorName","payload":"{ \"opcuaCommand\": \"setFolder\" }","payloadType":"json","repeat":"","crontab":"","once":false,"x":290.2000274658203,"y":212.1999969482422,"wires":[["5d7fc3f3.4a71cc"]]},{"id":"873463d6.a47cf","type":"inject","z":"806988c4.3acf58","name":"New variable (Counter2)","topic":"ns=4;s=Counter2;datatype=UInt32","payload":"{ \"opcuaCommand\": \"addVariable\" }","payloadType":"json","repeat":"","crontab":"","once":false,"x":288.2000274658203,"y":255.1999969482422,"wires":[["5d7fc3f3.4a71cc"]]},{"id":"1c7511c0.7c6ebe","type":"OpcUa-Client","z":"f8b67141.37c5e","endpoint":"1ca40846.98b2f8","action":"read","time":10,"timeUnit":"s","name":"READ","x":518.3000030517578,"y":145.1999969482422,"wires":[["bfd044f9.5478e8"]]},{"id":"1d08ae16.1b29a2","type":"OpcUa-Item","z":"f8b67141.37c5e","item":"ns=4;s=TestInt32","datatype":"Int32","value":"","name":"","x":303.3000183105469,"y":146.6000213623047,"wires":[["1c7511c0.7c6ebe"]]},{"id":"a4cb0bb3.f48108","type":"inject","z":"f8b67141.37c5e","name":"Read","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"x":150.29998779296875,"y":145.8000946044922,"wires":[["1d08ae16.1b29a2"]]},{"id":"bfd044f9.5478e8","type":"debug","z":"f8b67141.37c5e","name":"","active":true,"console":"false","complete":"false","x":697.3000030517578,"y":114.80003356933594,"wires":[]},{"id":"ad68e5ec.3a26e8","type":"inject","z":"f8b67141.37c5e","name":"","topic":"ns=4;s=TestInt32;datatype=Int32","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"x":238.30003356933594,"y":211.8000946044922,"wires":[["1c7511c0.7c6ebe"]]},{"id":"4e55f0c8.6d41c","type":"OpcUa-Client","z":"f8b67141.37c5e","endpoint":"1ca40846.98b2f8","action":"write","time":10,"timeUnit":"s","name":"WRITE ","x":529.0000152587891,"y":85.20005798339844,"wires":[["bfd044f9.5478e8"]]},{"id":"b2b6a7e1.4c72e8","type":"OpcUa-Item","z":"f8b67141.37c5e","item":"ns=4;s=TestInt32","datatype":"Int32","value":"1234","name":"","x":307.00001525878906,"y":87.80003356933594,"wires":[["4e55f0c8.6d41c"]]},{"id":"1af1665c.5f9b3a","type":"inject","z":"f8b67141.37c5e","name":"Write","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"x":148,"y":88.80003356933594,"wires":[["b2b6a7e1.4c72e8"]]},{"id":"b4ca3322.c00bc","type":"inject","z":"f8b67141.37c5e","name":"","topic":"ns=4;s=TestInt32;datatype=Int32","payload":"5678","payloadType":"str","repeat":"","crontab":"","once":false,"x":354.2000274658203,"y":39.19999694824219,"wires":[["4e55f0c8.6d41c"]]}] -------------------------------------------------------------------------------- /examples/OPCUA-UNSUBSRIBE.json: -------------------------------------------------------------------------------- 1 | [{"id":"912800e7.e00308","type":"tab","label":"Flow 1"},{"id":"f297ec1c.ebdd38","type":"OpcUa-Endpoint","z":"","endpoint":"opc.tcp://TREL16087112:53530/OPCUA/SimulationServer","secpol":"None","secmode":"None","login":false},{"id":"ee4309c5.7839f8","type":"ui_group","z":"","name":"p1","tab":"a66f0712.01682","disp":true,"width":"6"},{"id":"ae65fb20.a3c57","type":"ui_group","z":"","name":"Général page 1","tab":"a66f0712.01682","disp":true,"width":"6"},{"id":"a66f0712.01682","type":"ui_tab","z":"","name":"PIERRET","icon":"dashboard"},{"id":"66e7f60c.d0d538","type":"OpcUa-Item","z":"912800e7.e00308","item":"ns=5;s=Sawtooth1","datatype":"Double","value":"","name":"","x":266.99998474121094,"y":72.49998474121094,"wires":[["65baf697.e60e8"]]},{"id":"4a6ffc33.00a064","type":"OpcUa-Client","z":"912800e7.e00308","endpoint":"f297ec1c.ebdd38","action":"subscribe","time":"1","timeUnit":"s","name":"","x":478,"y":73.49998474121094,"wires":[["db8a58ba.c390a","aba904c5.89006","af164698.4cd7c8"]]},{"id":"db8a58ba.c390a","type":"debug","z":"912800e7.e00308","name":"","active":false,"console":false,"complete":"false","x":679.7666625976562,"y":132.2500457763672,"wires":[]},{"id":"aba904c5.89006","type":"ui_gauge","z":"912800e7.e00308","name":"","group":"ee4309c5.7839f8","order":0,"width":0,"height":0,"gtype":"gage","title":"gauge p1","label":"bar","format":"{{value}}","min":0,"max":"400","colors":["#00b500","#e6e600","#ca3838"],"x":659.7666625976562,"y":85.65000915527344,"wires":[]},{"id":"af164698.4cd7c8","type":"ui_chart","z":"912800e7.e00308","name":"","group":"ee4309c5.7839f8","order":0,"width":0,"height":0,"label":"chart","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"x":658.7666625976562,"y":35.71665954589844,"wires":[[],[]]},{"id":"e0b08ded.95663","type":"ui_button","z":"912800e7.e00308","name":"","group":"ae65fb20.a3c57","order":0,"width":0,"height":0,"label":"Subscribe","color":"","bgcolor":"","icon":"","payload":"","payloadType":"str","topic":"","x":98.99998474121094,"y":71.99998474121094,"wires":[["66e7f60c.d0d538"]]},{"id":"a434f4db.ca9d38","type":"function","z":"912800e7.e00308","name":"Unsubscribe","func":"msg.action=\"unsubscribe\";\nreturn msg;","outputs":1,"noerr":0,"x":435,"y":203.99998474121094,"wires":[["9b25d32c.b536e8","4a6ffc33.00a064"]]},{"id":"b9c9c902.658b48","type":"ui_button","z":"912800e7.e00308","name":"","group":"ee4309c5.7839f8","order":0,"width":0,"height":0,"label":"Unsubscribe","color":"","bgcolor":"","icon":"","payload":"","payloadType":"str","topic":"","x":94.99998474121094,"y":203.99998474121094,"wires":[["a5c3e4a8.864cd"]]},{"id":"a5c3e4a8.864cd","type":"OpcUa-Item","z":"912800e7.e00308","item":"ns=5;s=Sawtooth1","datatype":"Double","value":"","name":"","x":268.99998474121094,"y":203.00001525878906,"wires":[["a434f4db.ca9d38"]]},{"id":"9b25d32c.b536e8","type":"debug","z":"912800e7.e00308","name":"","active":true,"console":false,"complete":"action","x":680,"y":203.99998474121094,"wires":[]},{"id":"6f1ed402.46c5e4","type":"inject","z":"912800e7.e00308","name":"Test","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"x":93.5,"y":116,"wires":[["66e7f60c.d0d538"]]},{"id":"c3d8c91d.491198","type":"inject","z":"912800e7.e00308","name":"Test","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"x":102.19999694824219,"y":249.1999969482422,"wires":[["a5c3e4a8.864cd"]]},{"id":"65baf697.e60e8","type":"function","z":"912800e7.e00308","name":"Subscribe","func":"msg.action=\"subscribe\";\nreturn msg;","outputs":1,"noerr":0,"x":375.20001220703125,"y":27.199996948242188,"wires":[["4a6ffc33.00a064"]]}] -------------------------------------------------------------------------------- /examples/OPCUA-VARIABLE.json: -------------------------------------------------------------------------------- 1 | [{"id":"11a578056fc3d56a","type":"tab","label":"Flow 1","disabled":false,"info":"","env":[]},{"id":"8a4b4e742a3916ec","type":"OpcUa-Server","z":"11a578056fc3d56a","port":"53881","name":"","endpoint":"","users":"users.json","nodesetDir":"","folderName4PKI":"","autoAcceptUnknownCertificate":true,"registerToDiscovery":false,"constructDefaultAddressSpace":true,"allowAnonymous":true,"endpointNone":true,"endpointSign":true,"endpointSignEncrypt":true,"endpointBasic128Rsa15":true,"endpointBasic256":true,"endpointBasic256Sha256":true,"maxNodesPerBrowse":0,"maxNodesPerHistoryReadData":0,"maxNodesPerHistoryReadEvents":0,"maxNodesPerHistoryUpdateData":0,"maxNodesPerRead":0,"maxNodesPerWrite":0,"maxNodesPerMethodCall":0,"maxNodesPerRegisterNodes":0,"maxNodesPerNodeManagement":0,"maxMonitoredItemsPerCall":0,"maxNodesPerHistoryUpdateEvents":0,"maxNodesPerTranslateBrowsePathsToNodeIds":0,"x":640,"y":140,"wires":[["24ece21aaa3a8d8a"]]},{"id":"2f89c79ea33f7976","type":"inject","z":"11a578056fc3d56a","name":"add TestVariable","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"ns=1;s=TestVariable;datatype=Boolean","payload":"{\"opcuaCommand\": \"addVariable\"}","payloadType":"json","x":300,"y":40,"wires":[["8a4b4e742a3916ec"]]},{"id":"24ece21aaa3a8d8a","type":"debug","z":"11a578056fc3d56a","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":940,"y":140,"wires":[]},{"id":"dcd3c29064d3f48c","type":"inject","z":"11a578056fc3d56a","name":"Set TestVariable false","props":[{"p":"payload.messageType","v":"Variable","vt":"str"},{"p":"payload.variableName","v":"TestVariable","vt":"str"},{"p":"payload.datatype","v":"Boolean","vt":"str"},{"p":"payload.namespace","v":"1","vt":"str"},{"p":"payload.variableValue","v":"false","vt":"bool"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":280,"y":100,"wires":[["8a4b4e742a3916ec"]]},{"id":"957057e20f53d587","type":"inject","z":"11a578056fc3d56a","name":"add TestVariable2 (Float)","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"ns=1;s=TestVariable2;datatype=Float","payload":"{\"opcuaCommand\": \"addVariable\"}","payloadType":"json","x":290,"y":460,"wires":[["8a4b4e742a3916ec"]]},{"id":"0b118afe42a49f53","type":"inject","z":"11a578056fc3d56a","name":"Set TestVariable2 12.3 + ts + quality (Number)","props":[{"p":"payload.messageType","v":"Variable","vt":"str"},{"p":"payload.variableName","v":"TestVariable2","vt":"str"},{"p":"payload.datatype","v":"Float","vt":"str"},{"p":"payload.namespace","v":"1","vt":"str"},{"p":"payload.variableValue","v":"12.3","vt":"str"},{"p":"payload.sourceTimestamp","v":"2022-05-25T20:36:00Z","vt":"str"},{"p":"payload.quality","v":"2161770496","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":250,"y":540,"wires":[["8a4b4e742a3916ec"]]},{"id":"8536d55d0424da30","type":"inject","z":"11a578056fc3d56a","name":"Set TestVariable \"true\"","props":[{"p":"payload.messageType","v":"Variable","vt":"str"},{"p":"payload.variableName","v":"TestVariable","vt":"str"},{"p":"payload.datatype","v":"Boolean","vt":"str"},{"p":"payload.namespace","v":"1","vt":"str"},{"p":"payload.variableValue","v":"true","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":280,"y":200,"wires":[["8a4b4e742a3916ec"]]},{"id":"a80b65bac7031056","type":"inject","z":"11a578056fc3d56a","name":"Set TestVariable 0 (false)","props":[{"p":"payload.messageType","v":"Variable","vt":"str"},{"p":"payload.variableName","v":"TestVariable","vt":"str"},{"p":"payload.datatype","v":"Boolean","vt":"str"},{"p":"payload.namespace","v":"1","vt":"str"},{"p":"payload.variableValue","v":"0","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":270,"y":300,"wires":[["8a4b4e742a3916ec"]]},{"id":"8e1d7776f2447bf4","type":"inject","z":"11a578056fc3d56a","name":"Set TestVariable 1 (true)","props":[{"p":"payload.messageType","v":"Variable","vt":"str"},{"p":"payload.variableName","v":"TestVariable","vt":"str"},{"p":"payload.datatype","v":"Boolean","vt":"str"},{"p":"payload.namespace","v":"1","vt":"str"},{"p":"payload.variableValue","v":"1","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":280,"y":340,"wires":[["8a4b4e742a3916ec"]]},{"id":"4dd1d84b6c01f3f3","type":"inject","z":"11a578056fc3d56a","name":"Set TestVariable true","props":[{"p":"payload.messageType","v":"Variable","vt":"str"},{"p":"payload.variableName","v":"TestVariable","vt":"str"},{"p":"payload.datatype","v":"Boolean","vt":"str"},{"p":"payload.namespace","v":"1","vt":"str"},{"p":"payload.variableValue","v":"true","vt":"bool"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":290,"y":140,"wires":[["8a4b4e742a3916ec"]]},{"id":"f427cfa2eb088e8a","type":"inject","z":"11a578056fc3d56a","name":"Set TestVariable \"false\"","props":[{"p":"payload.messageType","v":"Variable","vt":"str"},{"p":"payload.variableName","v":"TestVariable","vt":"str"},{"p":"payload.datatype","v":"Boolean","vt":"str"},{"p":"payload.namespace","v":"1","vt":"str"},{"p":"payload.variableValue","v":"false","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":280,"y":240,"wires":[["8a4b4e742a3916ec"]]},{"id":"eaeea5654fe61dce","type":"inject","z":"11a578056fc3d56a","name":"Set TestVariable2 23.4","props":[{"p":"payload.messageType","v":"Variable","vt":"str"},{"p":"payload.variableName","v":"TestVariable2","vt":"str"},{"p":"payload.datatype","v":"Float","vt":"str"},{"p":"payload.namespace","v":"1","vt":"str"},{"p":"payload.variableValue","v":"23.4","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":280,"y":500,"wires":[["8a4b4e742a3916ec"]]},{"id":"7dd0e0ddd42640ed","type":"comment","z":"11a578056fc3d56a","name":"StatusCodes","info":"Use actual decimal StatusCode value:\nDataLost: 2147483648\nBadAggregateConfigurationRejected: 2161770496\netc.\n\nLook values from Github node-opcua:\nnode-opcua/packages/node-opcua-status-code/source/_generated_status_codes.ts ","x":250,"y":640,"wires":[]},{"id":"d5bc694f4fff3776","type":"inject","z":"11a578056fc3d56a","name":"Set TestVariable2 34.5 + ts + quality (String)","props":[{"p":"payload.messageType","v":"Variable","vt":"str"},{"p":"payload.variableName","v":"TestVariable2","vt":"str"},{"p":"payload.datatype","v":"Float","vt":"str"},{"p":"payload.namespace","v":"1","vt":"str"},{"p":"payload.variableValue","v":"34.5","vt":"str"},{"p":"payload.sourceTimestamp","v":"2022-05-25T23:47:00Z","vt":"str"},{"p":"payload.quality","v":"UncertainInitialValue","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":250,"y":580,"wires":[["8a4b4e742a3916ec"]]}] -------------------------------------------------------------------------------- /examples/OPCUAServer_Flow.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "tab", 4 | "id": "30ded7dc.266628", 5 | "label": "OPC UA Server" 6 | }, 7 | { 8 | "id": "446f5fbe.6a2f5", 9 | "type": "function", 10 | "z": "30ded7dc.266628", 11 | "name": "Translation", 12 | "func": "msg = { payload : { \"messageType\" : \"Variable\", \"variableName\": \"Counter\", \"variableValue\": msg.payload }};\nreturn msg;", 13 | "outputs": 1, 14 | "noerr": 0, 15 | "x": 306.5, 16 | "y": 313, 17 | "wires": [ 18 | [ 19 | "ca2018be.485a88", 20 | "11682102.b5b9af" 21 | ] 22 | ] 23 | }, 24 | { 25 | "id": "2505192d.62a3b6", 26 | "type": "inject", 27 | "z": "30ded7dc.266628", 28 | "name": "restartOPCUAServer", 29 | "topic": "", 30 | "payload": "{ \"opcuaCommand\": \"restartOPCUAServer\" }", 31 | "payloadType": "json", 32 | "repeat": "", 33 | "crontab": "", 34 | "once": false, 35 | "x": 288, 36 | "y": 379, 37 | "wires": [ 38 | [ 39 | "11682102.b5b9af" 40 | ] 41 | ] 42 | }, 43 | { 44 | "id": "bc372e70.a26b9", 45 | "type": "inject", 46 | "z": "30ded7dc.266628", 47 | "name": "addEquipment", 48 | "topic": "", 49 | "payload": "{ \"opcuaCommand\": \"addEquipment\", \"nodeName\": \"Machine\" }", 50 | "payloadType": "json", 51 | "repeat": "", 52 | "crontab": "", 53 | "once": false, 54 | "x": 297, 55 | "y": 421, 56 | "wires": [ 57 | [ 58 | "11682102.b5b9af" 59 | ] 60 | ] 61 | }, 62 | { 63 | "id": "80c2cece.aa922", 64 | "type": "inject", 65 | "z": "30ded7dc.266628", 66 | "name": "deleteNode PhysicalAsset2", 67 | "topic": "", 68 | "payload": "{ \"opcuaCommand\": \"deleteNode\", \"nodeId\": \"ns=1;s=PhysicalAsset2\" }", 69 | "payloadType": "json", 70 | "repeat": "", 71 | "crontab": "", 72 | "once": false, 73 | "x": 257, 74 | "y": 464, 75 | "wires": [ 76 | [ 77 | "11682102.b5b9af" 78 | ] 79 | ] 80 | }, 81 | { 82 | "id": "8e45ca73.8181b8", 83 | "type": "inject", 84 | "z": "30ded7dc.266628", 85 | "name": "addPhysicalAsset", 86 | "topic": "", 87 | "payload": "{ \"opcuaCommand\": \"addPhysicalAsset\", \"nodeName\": \"PhysicalAsset\" }", 88 | "payloadType": "json", 89 | "repeat": "", 90 | "crontab": "", 91 | "once": false, 92 | "x": 285.5, 93 | "y": 505, 94 | "wires": [ 95 | [ 96 | "11682102.b5b9af" 97 | ] 98 | ] 99 | }, 100 | { 101 | "id": "940275a6.743d68", 102 | "type": "inject", 103 | "z": "30ded7dc.266628", 104 | "name": "addPerson", 105 | "topic": "", 106 | "payload": "{ \"opcuaCommand\": \"addPerson\", \"nodeName\": \"Person\" }", 107 | "payloadType": "json", 108 | "repeat": "", 109 | "crontab": "", 110 | "once": false, 111 | "x": 315, 112 | "y": 546, 113 | "wires": [ 114 | [ 115 | "11682102.b5b9af" 116 | ] 117 | ] 118 | }, 119 | { 120 | "id": "ca2018be.485a88", 121 | "type": "debug", 122 | "z": "30ded7dc.266628", 123 | "name": "", 124 | "active": false, 125 | "console": "false", 126 | "complete": "false", 127 | "x": 784.5, 128 | "y": 313, 129 | "wires": [] 130 | }, 131 | { 132 | "id": "11682102.b5b9af", 133 | "type": "OpcUa-Server", 134 | "z": "30ded7dc.266628", 135 | "port": "53880", 136 | "name": "", 137 | "x": 563.5, 138 | "y": 422, 139 | "wires": [ 140 | [ 141 | "ca2018be.485a88" 142 | ] 143 | ] 144 | }, 145 | { 146 | "id": "e84c479e.595818", 147 | "type": "inject", 148 | "z": "30ded7dc.266628", 149 | "name": "", 150 | "topic": "", 151 | "payload": "12", 152 | "payloadType": "num", 153 | "repeat": "", 154 | "crontab": "", 155 | "once": false, 156 | "x": 131.5, 157 | "y": 313, 158 | "wires": [ 159 | [ 160 | "446f5fbe.6a2f5" 161 | ] 162 | ] 163 | } 164 | ] -------------------------------------------------------------------------------- /examples/OPCUA_BROWSE_and_SUBSCRIBE.json: -------------------------------------------------------------------------------- 1 | [{"id":"76fbcb09.74594c","type":"tab","label":"Flow 1"},{"id":"acd2f698.88bd28","type":"OpcUa-Endpoint","z":"7e58ca8c.d78944","endpoint":"opc.tcp://localhost:53530/OPCUA/SimulationServer","login":false},{"id":"c8b446ba.bfa058","type":"OpcUa-Browser","z":"76fbcb09.74594c","endpoint":"acd2f698.88bd28","item":"","datatype":"","topic":"ns=5;s=85/0:Simulation","items":[],"x":460.5000457763672,"y":37.79999542236328,"wires":[["83243287.79201"]]},{"id":"481f49fe.55a3a8","type":"inject","z":"76fbcb09.74594c","name":"Browse","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"x":78.5,"y":35.79999542236328,"wires":[["3eb58696.791f7a"]]},{"id":"83243287.79201","type":"function","z":"76fbcb09.74594c","name":"Decode & filter","func":"var items = msg.payload;\nfor (var i=0; iAddress", 75 | "field": "payload", 76 | "format": "handlebars", 77 | "template": "{{topic}}", 78 | "x": 471, 79 | "y": 99, 80 | "z": "fcc67842.033988", 81 | "wires": [ 82 | [ 83 | "2db1779.fd24e88" 84 | ] 85 | ] 86 | }, 87 | { 88 | "id": "739774d3.8c688c", 89 | "type": "debug", 90 | "name": "Value", 91 | "active": true, 92 | "console": "false", 93 | "complete": "payload", 94 | "x": 733, 95 | "y": 208, 96 | "z": "fcc67842.033988", 97 | "wires": [] 98 | }, 99 | { 100 | "id": "eadad10.f15253", 101 | "type": "inject", 102 | "name": "TEST", 103 | "topic": "", 104 | "payload": "", 105 | "payloadType": "none", 106 | "repeat": "", 107 | "crontab": "", 108 | "once": false, 109 | "x": 123, 110 | "y": 206, 111 | "z": "fcc67842.033988", 112 | "wires": [ 113 | [ 114 | "fd7d7d1f.02828" 115 | ] 116 | ] 117 | }, 118 | { 119 | "id": "bc233d76.43dcc", 120 | "type": "OpcUa-Client", 121 | "endpoint": "opc.tcp://localhost:26543", 122 | "action": "read", 123 | "time": 10000, 124 | "name": "Local", 125 | "x": 582, 126 | "y": 207, 127 | "z": "fcc67842.033988", 128 | "wires": [ 129 | [ 130 | "739774d3.8c688c" 131 | ] 132 | ] 133 | }, 134 | { 135 | "id": "d56a1ce1.2a95e", 136 | "type": "file", 137 | "name": "Clear address cache file", 138 | "filename": ".\\public\\Address.txt", 139 | "appendNewline": true, 140 | "createDir": false, 141 | "overwriteFile": "delete", 142 | "x": 692, 143 | "y": 58, 144 | "z": "fcc67842.033988", 145 | "wires": [] 146 | }, 147 | { 148 | "id": "c23bdff3.3dc42", 149 | "type": "inject", 150 | "name": "Clear cache", 151 | "topic": "", 152 | "payload": "", 153 | "payloadType": "none", 154 | "repeat": "", 155 | "crontab": "", 156 | "once": false, 157 | "x": 473, 158 | "y": 57, 159 | "z": "fcc67842.033988", 160 | "wires": [ 161 | [ 162 | "d56a1ce1.2a95e" 163 | ] 164 | ] 165 | }, 166 | { 167 | "id": "d2109af5.2def68", 168 | "type": "debug", 169 | "name": "Show", 170 | "active": true, 171 | "console": "false", 172 | "complete": "payload", 173 | "x": 460, 174 | "y": 138, 175 | "z": "fcc67842.033988", 176 | "wires": [] 177 | } 178 | ] -------------------------------------------------------------------------------- /examples/TestNode.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "c550b417.772448", 4 | "type": "OpcUa-Item", 5 | "z": "2d7df531.bb6c6a", 6 | "item": "{{topic}}", 7 | "datatype": "opcua.DataType.Double", 8 | "value": "66.6", 9 | "name": "{{browseName}}", 10 | "x": 340, 11 | "y": 420, 12 | "wires": [ 13 | [] 14 | ] 15 | } 16 | ] -------------------------------------------------------------------------------- /examples/USER-CERT.json: -------------------------------------------------------------------------------- 1 | [{"id":"87fa51364aa5e6b9","type":"tab","label":"User certificate","disabled":false,"info":"","env":[]},{"id":"894c6ff183e17d00","type":"OpcUa-Endpoint","endpoint":"opc.tcp://H7Q8Q13.mshome.net:53530/OPCUA/SimulationServer","secpol":"None","secmode":"None","login":false,"usercert":false,"usercertificate":"d:/temp/DNA_client_selfSigned.pem","userprivatekey":"d:/temp/private_key.pem"},{"id":"55fb29f2b0164ca1","type":"OpcUa-Endpoint","endpoint":"opc.tcp://localhost:53888","secpol":"None","secmode":"None","none":false,"login":false,"usercert":true,"usercertificate":"C:/Users/karaimi/AppData/Roaming/node-red-opcua-nodejs/Config/UserPKI/UserCert_certificate.pem","userprivatekey":"C:/Users/karaimi/AppData/Roaming/node-red-opcua-nodejs/Config/UserPKI/own/private/private_key.pem"},{"id":"b89882556eef0530","type":"OpcUa-Client","z":"87fa51364aa5e6b9","endpoint":"55fb29f2b0164ca1","action":"browse","deadbandtype":"a","deadbandvalue":1,"time":10,"timeUnit":"s","certificate":"n","localfile":"","localkeyfile":"","securitymode":"None","securitypolicy":"None","folderName4PKI":"","name":"User certificate ","x":750,"y":260,"wires":[["bef4d9fb1c7d0e8c"]]},{"id":"fd3af161a173cec0","type":"inject","z":"87fa51364aa5e6b9","name":"Browse VendorName","props":[{"p":"payload"},{"p":"topic","vt":"str"},{"p":"collect","v":"true","vt":"bool"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"ns=1;s=VendorName","payloadType":"date","x":470,"y":260,"wires":[["b89882556eef0530"]]},{"id":"bef4d9fb1c7d0e8c","type":"debug","z":"87fa51364aa5e6b9","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1010,"y":260,"wires":[]},{"id":"30ea6f3cacab8803","type":"OpcUa-Server","z":"87fa51364aa5e6b9","port":"53888","name":"","endpoint":"","users":"users.json","nodesetDir":"","folderName4PKI":"","autoAcceptUnknownCertificate":true,"registerToDiscovery":false,"constructDefaultAddressSpace":true,"allowAnonymous":true,"endpointNone":true,"endpointSign":true,"endpointSignEncrypt":true,"endpointBasic128Rsa15":true,"endpointBasic256":true,"endpointBasic256Sha256":true,"maxNodesPerBrowse":0,"maxNodesPerHistoryReadData":0,"maxNodesPerHistoryReadEvents":0,"maxNodesPerHistoryUpdateData":0,"maxNodesPerRead":0,"maxNodesPerWrite":0,"maxNodesPerMethodCall":0,"maxNodesPerRegisterNodes":0,"maxNodesPerNodeManagement":0,"maxMonitoredItemsPerCall":0,"maxNodesPerHistoryUpdateEvents":0,"maxNodesPerTranslateBrowsePathsToNodeIds":0,"x":740,"y":360,"wires":[[]]},{"id":"f02b470a46becf6e","type":"comment","z":"87fa51364aa5e6b9","name":"Openssl commands for user certificate","info":"\n1) Goto to folder UserPKI\n\n2) Use openssl to generate user certificate:\n openssl req -new -x509 -key own/private/private_key.pem -out UserCert_certificate.pem -days 365 -subj \"/CN=user1\" -sha256 -text\n\nNOTE: Certificate is valid 1 year\nNOTE: Username is user1\n\nIn the node-red flow, client node:\n\nCertificate:\nC:/Users/karaimi/AppData/Roaming/node-red-opcua-nodejs/Config/UserPKI/UserCert_certificate.pem\n\nPrivateKey:\nC:/Users/karaimi/AppData/Roaming/node-red-opcua-nodejs/Config/UserPKI/own/private/private_key.pem\n\nUaExpert will need certificate in der format, convert pem to der format:\nopenssl x509 -outform der -in UserCert_certificate.pem -out UserCert_certificate.der\n","x":520,"y":160,"wires":[]}] -------------------------------------------------------------------------------- /images/Example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikakaraila/node-red-contrib-opcua/f43392a2cfb78eeb2b5ef8f8dadcac675fcc73f3/images/Example.png -------------------------------------------------------------------------------- /images/PROSYS-OPC-UA-EXAMPLE.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikakaraila/node-red-contrib-opcua/f43392a2cfb78eeb2b5ef8f8dadcac675fcc73f3/images/PROSYS-OPC-UA-EXAMPLE.png -------------------------------------------------------------------------------- /images/PROSYS-OPC-UA-EXAMPLE2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikakaraila/node-red-contrib-opcua/f43392a2cfb78eeb2b5ef8f8dadcac675fcc73f3/images/PROSYS-OPC-UA-EXAMPLE2.png -------------------------------------------------------------------------------- /images/PROSYS-OPCUA-EVENTS-EXAMPLE.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikakaraila/node-red-contrib-opcua/f43392a2cfb78eeb2b5ef8f8dadcac675fcc73f3/images/PROSYS-OPCUA-EVENTS-EXAMPLE.png -------------------------------------------------------------------------------- /images/PROSYS-OPCUA-METHOD-EXAMPLE.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikakaraila/node-red-contrib-opcua/f43392a2cfb78eeb2b5ef8f8dadcac675fcc73f3/images/PROSYS-OPCUA-METHOD-EXAMPLE.png -------------------------------------------------------------------------------- /images/nodeopcua64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikakaraila/node-red-contrib-opcua/f43392a2cfb78eeb2b5ef8f8dadcac675fcc73f3/images/nodeopcua64.png -------------------------------------------------------------------------------- /images/opcuanode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikakaraila/node-red-contrib-opcua/f43392a2cfb78eeb2b5ef8f8dadcac675fcc73f3/images/opcuanode.png -------------------------------------------------------------------------------- /images/opcuanodeLogo64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikakaraila/node-red-contrib-opcua/f43392a2cfb78eeb2b5ef8f8dadcac675fcc73f3/images/opcuanodeLogo64.png -------------------------------------------------------------------------------- /images/uiBrowseExample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikakaraila/node-red-contrib-opcua/f43392a2cfb78eeb2b5ef8f8dadcac675fcc73f3/images/uiBrowseExample.png -------------------------------------------------------------------------------- /opcua.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration 2 | // Generated on Sun Apr 03 2016 10:10:01 GMT+0200 (CEST) 3 | 4 | module.exports = function(config) { 5 | config.set({ 6 | 7 | // base path that will be used to resolve all patterns (eg. files, exclude) 8 | basePath: '', 9 | 10 | 11 | // frameworks to use 12 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter 13 | frameworks: ['jasmine'], 14 | 15 | 16 | // list of files / patterns to load in the browser 17 | files: [ 18 | 'test/**/*Spec.js' 19 | ], 20 | 21 | 22 | // list of files to exclude 23 | exclude: [ 24 | '**/*.swp' 25 | ], 26 | 27 | 28 | // preprocess matching files before serving them to the browser 29 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor 30 | preprocessors: { 31 | }, 32 | 33 | 34 | // test results reporter to use 35 | // possible values: 'dots', 'progress' 36 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter 37 | reporters: ['progress'], 38 | 39 | 40 | // web server port 41 | port: 9876, 42 | 43 | 44 | // enable / disable colors in the output (reporters and logs) 45 | colors: true, 46 | 47 | 48 | // level of logging 49 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 50 | logLevel: config.LOG_INFO, 51 | 52 | 53 | // enable / disable watching file and executing tests whenever any file changes 54 | autoWatch: true, 55 | 56 | 57 | // start these browsers 58 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher 59 | browsers: ['Chrome', 'Firefox'], 60 | 61 | 62 | // Continuous Integration mode 63 | // if true, Karma captures browsers, runs the tests and exits 64 | singleRun: false, 65 | 66 | // Concurrency level 67 | // how many browser should be started simultaneous 68 | concurrency: Infinity 69 | }) 70 | } 71 | -------------------------------------------------------------------------------- /opcua/101-opcuaitem.html: -------------------------------------------------------------------------------- 1 | 18 | 19 | 41 | 42 | 43 | 44 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /opcua/101-opcuaitem.js: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | Copyright 2015 Valmet Automation Inc. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | 17 | **/ 18 | 19 | module.exports = function (RED) { 20 | "use strict"; 21 | var opcua = require('node-opcua'); 22 | var opcuaBasics = require('./opcua-basics'); 23 | const {parse, stringify} = require('flatted'); 24 | 25 | function OpcUaItemNode(n) { 26 | 27 | RED.nodes.createNode(this, n); 28 | 29 | this.item = n.item; // OPC UA address: ns=2;i=4 OR ns=3;s=MyVariable 30 | this.datatype = n.datatype.replace(/\s/g, ""); // String; need to remove white space from node datatype to be consistent with inputs, i.e. ExtensionObject 31 | this.value = n.value; // 66.6 32 | this.name = n.name; // browseName shall be put here 33 | 34 | var node = this; 35 | 36 | function verbose_warn(logMessage) { 37 | //if (RED.settings.verbose) { 38 | node.warn((node.name) ? node.name + ': ' + logMessage : 'OpcUaClientNode: ' + logMessage); 39 | //} 40 | } 41 | 42 | function verbose_log(logMessage) { 43 | //if (RED.settings.verbose) { 44 | // node.log(logMessage); 45 | node.debug(logMessage); 46 | //} 47 | } 48 | 49 | node.on("input", function (msg) { 50 | 51 | msg.topic = node.item; 52 | msg.datatype = node.datatype; 53 | msg.browseName = node.name; 54 | 55 | // Node contains static value, inject with empty string as payload 56 | if (node.value && msg.payload.length === 0) { 57 | verbose_log('First set value by node value:' + node.value); 58 | if (node.datatype) { 59 | msg.payload = opcuaBasics.build_new_value_by_datatype(node.datatype, node.value); 60 | } 61 | if (msg.datatype) { 62 | msg.payload = opcuaBasics.build_new_value_by_datatype(msg.datatype, node.value); 63 | } 64 | verbose_warn("NODE value, setting value to " + stringify(msg)); 65 | } 66 | // Input msg is dynamic and will overwrite node.value 67 | if (msg.payload && msg.payload.length > 0) { 68 | // verbose_warn("Second set value by Input " + msg.payload); 69 | if (node.datatype) { 70 | msg.payload = opcuaBasics.build_new_value_by_datatype(node.datatype, msg.payload); 71 | } 72 | if (msg.datatype) { 73 | msg.payload = opcuaBasics.build_new_value_by_datatype(msg.datatype, msg.payload); 74 | } 75 | // verbose_warn("Payload value, setting value to " + stringify(msg)); 76 | } 77 | node.send(msg); 78 | }); 79 | } 80 | 81 | RED.nodes.registerType("OpcUa-Item", OpcUaItemNode); 82 | }; 83 | -------------------------------------------------------------------------------- /opcua/103-opcuabrowser.html: -------------------------------------------------------------------------------- 1 | 18 | 19 | 44 | 45 | 59 | 60 | 61 | 62 | 72 | -------------------------------------------------------------------------------- /opcua/103-opcuabrowser.js: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | Copyright 2015 Valmet Automation Inc. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | 17 | **/ 18 | 19 | module.exports = function (RED) { 20 | "use strict"; 21 | var opcua = require('node-opcua'); 22 | var uaclient = require('node-opcua-client'); 23 | var path = require("path"); 24 | 25 | function OpcUaBrowserNode(config) { 26 | 27 | RED.nodes.createNode(this, config); 28 | 29 | this.item = config.item; // OPC UA address: ns=2;i=4 OR ns=3;s=MyVariable 30 | this.datatype = config.datatype; // String; 31 | this.topic = config.topic; 32 | this.items = config.items; 33 | this.name = config.name; 34 | 35 | const objectsFolderNodeId = "ns=0;i=85"; // Default root, server Objects 36 | 37 | var node = this; 38 | // node.name = "OPC UA Browser"; 39 | 40 | var opcuaEndpoint = RED.nodes.getNode(config.endpoint); 41 | 42 | var connectionOption = {}; 43 | var userIdentity = {}; 44 | 45 | if (opcuaEndpoint.securityPolicy) { 46 | connectionOption.securityPolicy = opcua.SecurityPolicy[opcuaEndpoint.securityPolicy]; 47 | } 48 | else { 49 | connectionOption.securityPolicy = opcua.SecurityPolicy.None; 50 | } 51 | if (opcuaEndpoint.securityMode) { 52 | connectionOption.securityMode = opcua.MessageSecurityMode[opcuaEndpoint.securityMode]; 53 | } 54 | else { 55 | connectionOption.securityPolicy = opcua.MessageSecurityMode.None; 56 | } 57 | connectionOption.endpointMustExist = false; 58 | 59 | if (opcuaEndpoint.login) { 60 | userIdentity.userName = opcuaEndpoint.credentials.user; 61 | userIdentity.password = opcuaEndpoint.credentials.password; 62 | userIdentity.type = uaclient.UserTokenType.UserName; // New TypeScript API parameter 63 | } 64 | 65 | node.status({ 66 | fill: "gray", 67 | shape: "dot", 68 | text: "no Items", 69 | source: { id: node.id, type: node.type, name: "OPC UA Browser"} 70 | }); 71 | 72 | node.add_item = function (item) { 73 | if (item) { 74 | if (!node.items) { 75 | node.items = new Array(); 76 | } 77 | node.items.push({ 78 | 'item': item 79 | }); 80 | } 81 | }; 82 | 83 | function node_error(err) { 84 | node.error("Browse node error!", err); 85 | } 86 | 87 | async function setupClient(url, nodeIdToBrowse, callback) { 88 | 89 | if(!nodeIdToBrowse) return; 90 | 91 | // new OPC UA Client and browse from Objects ns=0;s=Objects 92 | const client = opcua.OPCUAClient.create(connectionOption); 93 | try 94 | { 95 | // step 1 : connect to 96 | await client.connect(url); 97 | node.debug("start browse client on " + opcuaEndpoint.endpoint); 98 | 99 | // step 2 : createSession 100 | const session = await client.createSession(userIdentity); 101 | node.debug("start browse session on " + opcuaEndpoint.endpoint); 102 | 103 | // step 3 : browse 104 | node.debug("nodeIdBrowse:" + nodeIdToBrowse); 105 | const browseResult = await session.browse(nodeIdToBrowse); 106 | 107 | 108 | // step 4 : Read Value and Datatypes 109 | for(const reference of browseResult.references) 110 | { 111 | var ref_obj = Object.assign({}, reference); 112 | const dataValue = await session.read({nodeId: ref_obj.nodeId, attributeId: opcua.AttributeIds.Value}); 113 | ref_obj["value"] = dataValue.value.value; 114 | ref_obj["dataType"] = opcua.DataType[dataValue.value.dataType]; 115 | node.add_item(ref_obj); 116 | } 117 | node.status({ 118 | fill: "green", 119 | shape: "dot", 120 | text: "Items: " + node.items.length, 121 | source: { id: node.id, type: node.type, name: "OPC UA Browser"} 122 | }); 123 | 124 | //step 5 close session 125 | node.debug("close browse session"); 126 | await session.close(); 127 | 128 | // Set status notification browse done 129 | node.status({ 130 | fill: "green", 131 | shape: "dot", 132 | text: "Done", 133 | source: { id: node.id, type: node.type, name: "OPC UA Browser"} 134 | }); 135 | 136 | return node.items; 137 | } 138 | catch(err) 139 | { 140 | callback(err); 141 | } 142 | if (client) { 143 | client.disconnect(); 144 | } 145 | } 146 | 147 | setupClient(opcuaEndpoint.endpoint, null, function (err) { 148 | if (err) { 149 | node_error(err); 150 | node.status({ 151 | fill: "red", 152 | shape: "dot", 153 | text: "Error Items: " + node.items.length, 154 | source: { id: node.id, type: node.type, name: "OPC UA Browser"} 155 | }); 156 | } 157 | else { 158 | node.debug("Browse loading Items done..."); 159 | } 160 | }); 161 | 162 | node.on("input", function (msg) { 163 | node.debug("input browser"); 164 | 165 | node.items = []; 166 | 167 | let nodeToBrowse = msg.topic ? msg.topic : node.topic; 168 | if(!nodeToBrowse) nodeToBrowse = objectsFolderNodeId; 169 | 170 | var validNodeId = opcua.isValidNodeId(opcua.resolveNodeId(nodeToBrowse)); 171 | if(!validNodeId) return; 172 | 173 | setupClient(opcuaEndpoint.endpoint, nodeToBrowse, function (err) { 174 | if (err) { 175 | node_error(err); 176 | node.status({ 177 | fill: "red", 178 | shape: "dot", 179 | text: "Error Items: " + node.items.length, 180 | source: { id: node.id, type: node.type, name: "OPC UA Browser"} 181 | }); 182 | } 183 | else { 184 | node.debug("Browse loading Items done ..."); 185 | } 186 | }).then((items) =>{ 187 | node.items = items; 188 | msg.endpoint = opcuaEndpoint.endpoint; 189 | msg.payload = items; 190 | node.send(msg); 191 | }); 192 | }); 193 | } 194 | 195 | RED.nodes.registerType("OpcUa-Browser", OpcUaBrowserNode); 196 | }; 197 | -------------------------------------------------------------------------------- /opcua/105-opcuaendpoint.html: -------------------------------------------------------------------------------- 1 | 18 | 19 | 153 | 154 | 213 | -------------------------------------------------------------------------------- /opcua/105-opcuaendpoint.js: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | Copyright 2015 Valmet Automation Inc. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | 17 | **/ 18 | 19 | module.exports = function (RED) { 20 | "use strict"; 21 | 22 | function OpcUaEndpointNode(n) { 23 | 24 | RED.nodes.createNode(this, n); 25 | 26 | // Used to translate node-opcua old (v0.x.x) secmode strings to new (v2.x.x) secmode strings 27 | const security_mode_map_compat = { 28 | "NONE": "None", 29 | "None": "None", 30 | "SIGN": "Sign", 31 | "Sign": "Sign", 32 | "SIGNANDENCRYPT": "SignAndEncrypt", 33 | "SignAndEncrypt": "SignAndEncrypt" 34 | }; 35 | 36 | this.endpoint = n.endpoint; 37 | this.securityPolicy = n.secpol; 38 | this.securityMode = security_mode_map_compat[n.secmode]; 39 | this.login = n.login; 40 | this.none = n.none; 41 | this.usercert = n.usercert; 42 | this.userCertificate = n.usercertificate; 43 | this.userPrivatekey = n.userprivatekey; 44 | 45 | if (this.credentials) { 46 | // from node-opcua version 2.0.0 and onwards empty strings are not allowed anymore, so use null instead 47 | this.user = this.credentials.user && this.credentials.user.length > 0 ? this.credentials.user : null; 48 | this.password = this.credentials.password && this.credentials.password.length > 0 ? this.credentials.password : null; 49 | } 50 | } 51 | 52 | RED.nodes.registerType("OpcUa-Endpoint", OpcUaEndpointNode, { 53 | 54 | credentials: { 55 | user: { 56 | type: "text" 57 | }, 58 | password: { 59 | type: "password" 60 | } 61 | } 62 | }); 63 | 64 | }; 65 | -------------------------------------------------------------------------------- /opcua/106-opcuaevent.html: -------------------------------------------------------------------------------- 1 | 18 | 19 | 68 | 69 | 100 | 101 | -------------------------------------------------------------------------------- /opcua/106-opcuaevent.js: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | Copyright 2016 Valmet Automation Inc. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | 17 | **/ 18 | 19 | module.exports = function (RED) { 20 | "use strict"; 21 | var opcua = require('node-opcua'); 22 | var opcuaBasic = require('./opcua-basics'); 23 | 24 | function OpcUaEventNode(n) { 25 | 26 | RED.nodes.createNode(this, n); 27 | 28 | this.root = n.root; // OPC UA item nodeID subscription source 29 | this.customeventtype = n.customeventtype; 30 | this.eventtype = n.eventtype; // eventType 31 | this.name = n.name; // Node name 32 | this.activatecustomevent = n.activatecustomevent; 33 | 34 | var node = this; 35 | 36 | node.on("input", function (msg) { 37 | msg.topic = node.root; // example: ns=0;i=85; 38 | 39 | if (node.activatecustomevent) 40 | { 41 | msg.eventTypeIds = node.customeventtype; // example: ns=2;i=1234 42 | } else { 43 | msg.eventTypeIds = node.eventtype; // example: ns=0;i=10751; 44 | } 45 | node.send(msg); 46 | }); 47 | } 48 | 49 | RED.nodes.registerType("OpcUa-Event", OpcUaEventNode); 50 | }; -------------------------------------------------------------------------------- /opcua/108-opcuarights.js: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | Copyright 2022 Valmet Automation Inc. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | 17 | **/ 18 | 19 | 'use strict' 20 | 21 | // const { WellKnownRoles } = require("node-opcua"); 22 | 23 | /** 24 | * OPC UA rights node representation for Node-RED to add msg object OPC UA access rights, role and permissions 25 | * 26 | * @param RED 27 | */ 28 | module.exports = function (RED) { 29 | var opcua = require('node-opcua'); 30 | 31 | function OPCUARightsNode(n) { 32 | RED.nodes.createNode(this, n) 33 | this.name = n.name; 34 | this.accessLevelCurrentRead = n.accessLevelCurrentRead; 35 | this.accessLevelCurrentWrite = n.accessLevelCurrentWrite; 36 | this.accessLevelStatusWrite = n.accessLevelStatusWrite; 37 | this.accessLevelHistoryRead = n.accessLevelHistoryRead; 38 | this.accessLevelHistoryWrite = n.accessLevelHistoryWrite; 39 | this.accessLevelSemanticChange = n.accessLevelSemanticChange; 40 | this.role = n.role; 41 | // TODO Permissions 42 | this.permissionBrowse = n.permissionBrowse; 43 | this.permissionRead = n.permissionRead; 44 | this.permissionWrite = n.permissionWrite; 45 | this.permissionWriteAttribute = n.permissionWriteAttribute; 46 | this.permissionReadRole = n.permissionReadRole; 47 | this.permissionWriteRole = n.permissionWriteRole; 48 | this.permissionReadHistory = n.permissionReadHistory; 49 | this.permissionWriteHistory = n.permissionWriteHistory; 50 | this.permissionInsertHistory = n.permissionInsertHistory; 51 | this.permissionModifyHistory = n.permissionModifyHistory; 52 | this.permissionDeleteHistory = n.permissionDeleteHistory; 53 | this.permissionReceiveEvents = n.permissionReceiveEvents; 54 | this.permissionCall = n.permissionCall; 55 | this.permissionAddReference = n.permissionAddReference; 56 | this.permissionRemoveReference = n.permissionRemoveReference; 57 | this.permissionDeleteNode = n.permissionDeleteNode; 58 | this.permissionAddNode = n.permissionAddNode; 59 | var node = this; 60 | 61 | node.debug("Node parameters: " + JSON.stringify(node)); 62 | 63 | node.on("input", function (msg) { 64 | // This node will extend new field to msg so addVariable can set needed access level and permissions 65 | // From the selected values 66 | // TODO 67 | var levelString = ""; 68 | if (node.accessLevelCurrentRead === true) levelString += "CurrentRead |"; 69 | if (node.accessLevelCurrentWrite === true) levelString += " CurrentWrite |"; 70 | if (node.accessLevelStatusWrite === true) levelString += " StatusWrite |"; 71 | if (node.accessLevelHistoryRead === true) levelString += " HistoryRead |"; 72 | if (node.accessLevelHistoryWrite === true) levelString += " HistoryWrite |"; 73 | if (node.accessLevelSemanticChange === true) levelString += " SemanticChange"; 74 | console.log("Access level string: " + levelString); 75 | var accessLevel = opcua.makeAccessLevelFlag(levelString); 76 | var userAccessLevel = opcua.makeAccessLevelFlag(levelString); 77 | // var accessLevel = opcua.makeAccessLevelFlag("CurrentRead | CurrentWrite | StatusWrite | HistoryRead | HistoryWrite | SemanticChange"); 78 | // var userAccessLevel = opcua.makeAccessLevelFlag("CurrentRead | CurrentWrite | StatusWrite | HistoryRead | HistoryWrite | SemanticChange"); 79 | msg.accessLevel = accessLevel; 80 | msg.userAccessLevel = userAccessLevel; // Uses same, TODO add option to select which one to use 81 | msg.accessRestrictions = opcua.AccessRestrictionsFlag.None; // TODO extend when needed 82 | console.log("Access level: " + msg.accessLevel + " user access level: " + msg.userAccessLevel + " restrictions: " + msg.accessRestrictions); 83 | 84 | // TODO node.role == "a" Anonymous etc. 85 | let role; 86 | if (node.role === "a") { 87 | role = opcua.WellKnownRoles.Anonymous; 88 | } 89 | if (node.role === "u") { 90 | role = opcua.WellKnownRoles.AuthenticatedUser; 91 | } 92 | if (node.role === "e") { 93 | role = opcua.WellKnownRoles.Engineer; 94 | } 95 | if (node.role === "b") { 96 | role = opcua.WellKnownRoles.Observer; 97 | } 98 | if (node.role === "o") { 99 | role = opcua.WellKnownRoles.Operator; 100 | } 101 | if (node.role === "c") { 102 | role = opcua.WellKnownRoles.ConfigureAdmin; 103 | } 104 | if (node.role === "s") { 105 | role = opcua.WellKnownRoles.SecurityAdmin; 106 | } 107 | if (node.role === "v") { 108 | role = opcua.WellKnownRoles.Supervisor; 109 | } 110 | console.log("Role: " + role + " selection was " + node.role); 111 | 112 | // Collect multiple role permissions together 113 | let permissionString = ""; 114 | if (node.permissionBrowse === true) permissionString += "Browse |"; 115 | if (node.permissionRead === true) permissionString += " Read |"; 116 | if (node.permissionWrite === true) permissionString += " Write |"; 117 | if (node.permissionWriteAttribute === true) permissionString += " WriteAttribute |"; 118 | if (node.permissionReadRole === true) permissionString += " ReadRolePermissions |"; 119 | if (node.permissionWriteRole === true) permissionString += " WriteRolePermissions |"; 120 | if (node.permissionReadHistory === true) permissionString += " ReadHistory |"; 121 | if (node.permissionWriteHistory === true) permissionString += " WriteHistorizing |"; 122 | if (node.permissionInsertHistory === true) permissionString += " InsertHistory |"; 123 | if (node.permissionModifyHistory === true) permissionString += " ModifyHistory |"; 124 | if (node.permissionDeleteHistory === true) permissionString += " DeleteHistory |"; 125 | if (node.permissionReceiveEvents === true) permissionString += " ReceiveEvents |"; 126 | if (node.permissionCall === true) permissionString += " Call |"; 127 | if (node.permissionAddReference === true) permissionString += " AddReference |"; 128 | if (node.permissionRemoveReference === true) permissionString += " RemoveReference |"; 129 | if (node.permissionDeleteNode === true) permissionString += " DeleteNode |"; 130 | if (node.permissionAddNode === true) permissionString += " AddNode"; 131 | console.log("Permission string: " + permissionString); 132 | const permissionFlag = opcua. makePermissionFlag(permissionString); 133 | console.log("Permission flag: " + permissionFlag); 134 | if (msg.permissions && Array.isArray(msg.permissions)) { 135 | var merged = msg.permissions.concat([{ roleId: role, permissions: permissionFlag }]); 136 | console.log("Concatenated permissions: " + JSON.stringify(merged)); 137 | msg.permissions = merged; 138 | // msg.permissions.concat([{ roleId: opcua.WellKnownRoles.Anonymous, permissions: opcua.allPermissions }]); 139 | } 140 | else { 141 | // Current node 142 | msg.permissions = [{ roleId: role, permissions: permissionFlag }]; 143 | } 144 | console.log("Permissions: " + JSON.stringify(msg.permissions)); 145 | 146 | node.send(msg); 147 | }); 148 | 149 | node.on("close", function () { 150 | console.log("Closed"); 151 | }); 152 | 153 | } 154 | 155 | RED.nodes.registerType("OpcUa-Rights", OPCUARightsNode); 156 | } -------------------------------------------------------------------------------- /opcua/109-opcuadiscovery.html: -------------------------------------------------------------------------------- 1 | 18 | 19 | 38 | 39 | 45 | 46 | -------------------------------------------------------------------------------- /opcua/109-opcuadiscovery.js: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | Copyright 2023 Valmet Automation Inc. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | 17 | **/ 18 | 19 | 'use strict' 20 | 21 | 22 | /** 23 | * OPC UA Discovery server uses default port 4840 for the discovery 24 | * 25 | * @param RED 26 | */ 27 | module.exports = function (RED) { 28 | const opcua = require('node-opcua'); 29 | const utils = require("./utils"); 30 | const path = require('path'); 31 | const os = require('os'); 32 | const chalk = require("chalk"); 33 | 34 | function OPCUADiscoveryNode(n) { 35 | RED.nodes.createNode(this, n) 36 | this.name = n.name; 37 | var node = this; 38 | var xmlFiles = [path.join(__dirname, 'public/vendor/opc-foundation/xml/Opc.Ua.NodeSet2.xml')]; // Standard & basic types 39 | 40 | const certificateManager = new opcua.OPCUACertificateManager({ 41 | rootFolder: path.join(path.dirname(__dirname), "./Discovery"), // Own PKI storage for discovery LDS certificates 42 | automaticallyAcceptUnknownCertificate: true // TODO implement configuration / argument option to turn this on/off 43 | }); 44 | 45 | const server_options = { 46 | port: 4840, 47 | // resourcePath: "UADiscovery", // Do not use this, most of servers / client expect discovery is on port 4840 directly 48 | nodeset_filename: xmlFiles, 49 | buildInfo: { 50 | buildNumber: "", 51 | buildDate: "" 52 | }, 53 | serverCapabilities: { 54 | maxBrowseContinuationPoints: 10, 55 | maxHistoryContinuationPoints: 10, 56 | maxSessions: 20 57 | }, 58 | serverInfo: { 59 | applicationUri: opcua.makeApplicationUrn(os.hostname(), "Node-Red-OPCUA-Discovery"), 60 | productUri: "Node-Red-OPCUA-Discovery", 61 | applicationName: { 62 | text: "Node-Red-OPCUA-Discovery", 63 | locale: "en" 64 | }, 65 | gatewayServerUri: null, 66 | discoveryProfileUri: null, 67 | discoveryUrls: [] 68 | } 69 | }; 70 | 71 | server_options.buildInfo = { 72 | buildNumber: "0.2.300", 73 | buildDate: "2023-03-13T16:30:00" 74 | }; 75 | const server = new opcua.OPCUADiscoveryServer(server_options); 76 | const hostname = os.hostname(); 77 | node.debug(" server host :" + chalk.cyan(hostname)); 78 | node.debug(" server PID :" + chalk.cyan(process.pid)); 79 | (async () => { 80 | try { 81 | await certificateManager.initialize(); 82 | await server.start(function (err) { 83 | if (err) { 84 | node.status({ 85 | fill: "red", 86 | shape: "ring", 87 | text: "Not running, error: " + err 88 | }); 89 | node.error("Server failed to start... error: ", err); 90 | node.error("In Windows you can check port status with command: netstat -ano | findstr :4840"); 91 | node.error("UaExpert can be running and listening port"); 92 | // process.exit(-3); 93 | return; 94 | } 95 | node.debug(" server on port :" + chalk.cyan(server.endpoints[0].port.toString())); 96 | node.debug(" serverInfo :"); 97 | node.debug(chalk.cyan(JSON.stringify(server.serverInfo))); 98 | node.debug("Discovery server now waiting for server register calls. CTRL+C to stop"); 99 | node.status({ 100 | fill: "green", 101 | shape: "dot", 102 | text: "Discovery on port: " + server.endpoints[0].port.toString() 103 | }); 104 | 105 | server.on("response", (response) => { 106 | node.debug( 107 | // "Time: ", response.responseHeader.timestamp, " handle: ", response.responseHeader.requestHandle, 108 | // Show messages 109 | " request: " + response.schema.name + 110 | " status: " + response.responseHeader.serviceResult.toString() 111 | ); 112 | }); 113 | 114 | server.on( 115 | "request", 116 | (request, channel) => { 117 | node.debug( 118 | // "Time: ", request.requestHeader.timestamp, 119 | // " handle: ", request.requestHeader.requestHandle, 120 | " request: " + request.schema.name, 121 | // " channel ID: ", channel.channelId.toString() 122 | ); 123 | } 124 | ); 125 | }); 126 | } catch (err) { 127 | node.error("Cannot start server, error: ", err); 128 | return; 129 | } 130 | })(); 131 | 132 | // List servers registered to discovery 133 | node.on("input", function (msg) { 134 | const discovery_server_endpointUrl = "opc.tcp://localhost:4840"; 135 | const allservers = []; 136 | node.debug("Interrogating ", discovery_server_endpointUrl); 137 | (async () => { 138 | try { 139 | const { servers, endpoints } = await opcua.findServers(discovery_server_endpointUrl); 140 | // Servers on network 141 | node.debug("--------------------------------------------------------------"); 142 | for (const server of servers) { 143 | node.debug(" applicationUri:", chalk.cyan.bold(server.applicationUri)); 144 | node.debug(" productUri:", chalk.cyan.bold(server.productUri)); 145 | node.debug(" applicationName:", chalk.cyan.bold(server.applicationName.text)); 146 | // node.debug(" type:", chalk.cyan.bold(ApplicationType[server.applicationType])); 147 | node.debug(" gatewayServerUri:", server.gatewayServerUri ? chalk.cyan.bold(server.gatewayServerUri) : ""); 148 | node.debug("discoveryProfileUri:", server.discoveryProfileUri ? chalk.cyan.bold(server.discoveryProfileUri) : ""); 149 | node.debug(" discoveryUrls:"); 150 | for (const discoveryUrl of server.discoveryUrls) { 151 | node.debug(" " + chalk.cyan.bold(discoveryUrl)); 152 | allservers.push(discoveryUrl); 153 | } 154 | node.debug("--------------------------------------------------------------"); 155 | } 156 | // Registered server endpoints 157 | for (const endpoint of endpoints) { 158 | node.debug(endpoint.endpointUrl.toString(), endpoint.securityLevel, endpoint.securityPolicyUri, endpoint.securityMode); 159 | // allservers.push(endpoint); 160 | } 161 | // node.debug("Registered servers: " + JSON.stringify(allservers)); 162 | msg.payload = allservers; 163 | node.send(msg); 164 | } catch (err) { 165 | node.debug("err ", err.message); 166 | // process.exit(-2); 167 | return; 168 | } 169 | })(); 170 | }); 171 | 172 | node.on("close", function () { 173 | server.shutdown(() => { 174 | node.debug(" shutting down completed "); 175 | }); 176 | }); 177 | } 178 | 179 | RED.nodes.registerType("OpcUa-Discovery", OPCUADiscoveryNode); 180 | } -------------------------------------------------------------------------------- /opcua/dump_certificates.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const fs = require("fs"); 3 | const { crypto_utils } = require("node-opcua"); 4 | 5 | exports.dumpCertificates = async function dumpCertificates(client) { 6 | 7 | 8 | try { 9 | 10 | const endpoints = await client.getEndpoints(); 11 | var i = 0; 12 | endpoints.forEach(function (endpoint, i) { 13 | /* 14 | verbose_log("endpoint " + endpoint.endpointUrl + ""); 15 | verbose_log("Application URI " + endpoint.server.applicationUri); 16 | verbose_log("Product URI " + endpoint.server.productUri); 17 | verbose_log("Application Name " + endpoint.server.applicationName.text); 18 | */ 19 | var applicationName = endpoint.server.applicationName.text; 20 | if (!applicationName) { 21 | applicationName = "OPCUA_Server"; 22 | } 23 | /* 24 | verbose_log("Security Mode " + endpoint.securityMode.toString()); 25 | verbose_log("securityPolicyUri " + endpoint.securityPolicyUri); 26 | verbose_log("Type " + endpoint.server.applicationType); 27 | */ 28 | // verbose_log("certificate " + "..." + " endpoint.serverCertificate"); 29 | endpoint.server.discoveryUrls = endpoint.server.discoveryUrls || []; 30 | // verbose_log("discoveryUrls " + endpoint.server.discoveryUrls.join(" - ")); 31 | serverCertificate = endpoint.serverCertificate; 32 | // Use applicationName instead of fixed server_certificate 33 | var certificate_filename = path.join(__dirname, "../../PKI/" + applicationName + i + ".pem"); 34 | if (serverCertificate) { 35 | fs.writeFileSync(certificate_filename, crypto_utils.toPem(serverCertificate, "CERTIFICATE")); 36 | } 37 | }); 38 | 39 | endpoints.forEach(function (endpoint) { 40 | // verbose_log("Identify Token for : Security Mode= " + endpoint.securityMode.toString(), " Policy=", endpoint.securityPolicyUri); 41 | endpoint.userIdentityTokens.forEach(function (token) { 42 | /* 43 | verbose_log("policyId " + token.policyId); 44 | verbose_log("tokenType " + token.tokenType.toString()); 45 | verbose_log("issuedTokenType " + token.issuedTokenType); 46 | verbose_log("issuerEndpointUrl " + token.issuerEndpointUrl); 47 | verbose_log("securityPolicyUri " + token.securityPolicyUri); 48 | */ 49 | }); 50 | }); 51 | } catch(err) { 52 | console.log(err); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /opcua/icons/opcuanode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikakaraila/node-red-contrib-opcua/f43392a2cfb78eeb2b5ef8f8dadcac675fcc73f3/opcua/icons/opcuanode.png -------------------------------------------------------------------------------- /opcua/icons/opcuanodeLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikakaraila/node-red-contrib-opcua/f43392a2cfb78eeb2b5ef8f8dadcac675fcc73f3/opcua/icons/opcuanodeLogo.png -------------------------------------------------------------------------------- /opcua/public/vendor/opc-foundation/binary/OPC.ISA95.Types.bsd.xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /opcua/public/vendor/opc-foundation/binary/Opc.Ua.Adi.Types.bsd.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | Structure defining the information for auxiliary axis for array type variables. 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | Identify on which type of axis the data shall be displayed. 53 | 54 | 55 | 56 | 57 | 58 | 59 | Structure defining XY value like a list of peaks. 60 | 61 | 62 | 63 | 64 | 65 | Structure defining double IEEE 32 bits complex value 66 | 67 | 68 | 69 | 70 | 71 | Structure defining double IEEE 64 bits complex value 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /opcua/public/vendor/opc-foundation/binary/Opc.Ua.Di.Types.bsd.xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /opcua/public/vendor/opc-foundation/binary/Opc.Ua.Gds.Types.bsd.xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /opcua/public/vendor/opc-foundation/csv/AttributeIds.csv: -------------------------------------------------------------------------------- 1 | NodeId,1 2 | NodeClass,2 3 | BrowseName,3 4 | DisplayName,4 5 | Description,5 6 | WriteMask,6 7 | UserWriteMask,7 8 | IsAbstract,8 9 | Symmetric,9 10 | InverseName,10 11 | ContainsNoLoops,11 12 | EventNotifier,12 13 | Value,13 14 | DataType,14 15 | ValueRank,15 16 | ArrayDimensions,16 17 | AccessLevel,17 18 | UserAccessLevel,18 19 | MinimumSamplingInterval,19 20 | Historizing,20 21 | Executable,21 22 | UserExecutable,22 23 | -------------------------------------------------------------------------------- /opcua/public/vendor/opc-foundation/csv/ServerCapabilities.csv: -------------------------------------------------------------------------------- 1 | NA, No capability information is available. Cannot be used in combination with any other capability. 2 | DA, Provides current data. 3 | HD, Provides historical data. 4 | AC, Provides alarms and conditions that may require operator interaction. 5 | HE, Provides historical alarms and events. 6 | GDS, Supports the Global Discovery Server information model. 7 | LDS, Only supports the Discovery Services. Cannot be used in combination with any other capability. 8 | DI, Supports the Device Integration (DI) information model. 9 | ADI, Supports the Analyser Device Integration (ADI) information model. 10 | FDI, Supports the Field Device Integration (FDI) information model. 11 | FDIC, Supports the Field Device Integration (FDI) Communication Server information model. 12 | PLC, Supports the PLCopen information model. 13 | S95, Supports the ISA95 information model. -------------------------------------------------------------------------------- /opcua/public/vendor/opc-foundation/csv/ServerCapabilityIdentifiers.csv: -------------------------------------------------------------------------------- 1 | NA, No capability information is available. Cannot be used in combination with any other capability. 2 | DA, Provides current data. 3 | HD, Provides historical data. 4 | AC, Provides alarms and conditions that may require operator interaction. 5 | HE, Provides historical alarms and events. 6 | GDS, Supports the Global Discovery Server information model. 7 | LDS, Only supports the Discovery Services. Cannot be used in combination with any other capability. 8 | DI, Supports the Device Integration (DI) information model. 9 | ADI, Supports the Analyser Device Integration (ADI) information model. 10 | FDI, Supports the Field Device Integration (FDI) information model. 11 | FDIC, Supports the Field Device Integration (FDI) Communication Server information model. 12 | PLC, Supports the PLCopen information model. 13 | S95, Supports the ISA95 information model. -------------------------------------------------------------------------------- /opcua/public/vendor/opc-foundation/schema/OPC.ISA95.Types.xsd: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | -------------------------------------------------------------------------------- /opcua/public/vendor/opc-foundation/schema/OPCBinarySchema.xsd: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /opcua/public/vendor/opc-foundation/schema/SecuredApplication.xsd: -------------------------------------------------------------------------------- 1 |  2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /opcua/public/vendor/opc-foundation/xml/Opc.Ua.Adi.Types.bsd.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | Structure defining the information for auxiliary axis for array type variables. 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | Identify on which type of axis the data shall be displayed. 53 | 54 | 55 | 56 | 57 | 58 | 59 | Structure defining XY value like a list of peaks. 60 | 61 | 62 | 63 | 64 | 65 | Structure defining double IEEE 32 bits complex value 66 | 67 | 68 | 69 | 70 | 71 | Structure defining double IEEE 64 bits complex value 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /opcua/public/vendor/opc-foundation/xml/Opc.Ua.Adi.Types.xsd: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | Structure defining the information for auxiliary axis for array type variables. 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | Identify on which type of axis the data shall be displayed. 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | Structure defining XY value like a list of peaks. 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | Structure defining double IEEE 32 bits complex value 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | Structure defining double IEEE 64 bits complex value 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | -------------------------------------------------------------------------------- /opcua/public/vendor/opc-foundation/xml/Opc.Ua.Di.Types.bsd: -------------------------------------------------------------------------------- 1 | 2 | 30 | 31 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /opcua/public/vendor/opc-foundation/xml/Opc.Ua.Di.Types.bsd.xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /opcua/public/vendor/opc-foundation/xml/Opc.Ua.Di.Types.xsd: -------------------------------------------------------------------------------- 1 | 2 | 30 | 31 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /opcua/public/vendor/opc-foundation/xml/Opc.Ua.Gds.Types.bsd.xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /opcua/public/vendor/opc-foundation/xml/Opc.Ua.Gds.Types.xsd: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /opcua/public/vendor/opc-foundation/xml/Opc.Ua.NodeSet2.Part999.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | i=1 8 | i=2 9 | i=3 10 | i=4 11 | i=5 12 | i=6 13 | i=7 14 | i=8 15 | i=9 16 | i=10 17 | i=11 18 | i=13 19 | i=12 20 | i=15 21 | i=14 22 | i=16 23 | i=17 24 | i=18 25 | i=20 26 | i=21 27 | i=19 28 | i=22 29 | i=26 30 | i=27 31 | i=28 32 | i=47 33 | i=46 34 | i=35 35 | i=36 36 | i=48 37 | i=45 38 | i=40 39 | i=37 40 | i=38 41 | i=39 42 | 43 | 44 | EnumeratedTestType 45 | A simple enumerated type used for testing. 46 | 47 | i=11886 48 | i=29 49 | 50 | 51 | 52 | Operation has halted. 53 | 54 | 55 | Operation is proceeding with caution. 56 | 57 | 58 | Operation is proceeding normally. 59 | 60 | 61 | 62 | 63 | EnumValues 64 | 65 | i=68 66 | i=78 67 | i=398 68 | 69 | 70 | 71 | 72 | 73 | i=7616 74 | 75 | 76 | 77 | 1 78 | 79 | 80 | 81 | Red 82 | 83 | 84 | 85 | 86 | Operation has halted. 87 | 88 | 89 | 90 | 91 | 92 | 93 | i=7616 94 | 95 | 96 | 97 | 4 98 | 99 | 100 | 101 | Yellow 102 | 103 | 104 | 105 | 106 | Operation is proceeding with caution. 107 | 108 | 109 | 110 | 111 | 112 | 113 | i=7616 114 | 115 | 116 | 117 | 5 118 | 119 | 120 | 121 | Green 122 | 123 | 124 | 125 | 126 | Operation is proceeding normally. 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /opcua/utils.js: -------------------------------------------------------------------------------- 1 | 2 | const opcua = require("node-opcua"); 3 | const path = require("path"); 4 | const envPaths = require("env-paths"); 5 | const config = envPaths("node-red-opcua").config; 6 | 7 | 8 | let _g_CertificateManager = null; // For all clients 9 | 10 | function createCertificateManager() { 11 | if (_g_CertificateManager) return _g_CertificateManager; 12 | let folder = config; 13 | _g_CertificateManager = new opcua.OPCUACertificateManager({ 14 | name: "PKI", 15 | rootFolder: path.join(folder, "PKI"), 16 | automaticallyAcceptUnknownCertificate: true 17 | }); 18 | return _g_CertificateManager; 19 | } 20 | 21 | function createClientCertificateManager() { 22 | return createCertificateManager(); 23 | } 24 | 25 | function createServerCertificateManager() { 26 | return createServerCertificateManager(); 27 | } 28 | 29 | 30 | let _g_userCertificateManager = null; 31 | function createUserCertificateManager() { 32 | if (_g_userCertificateManager) return _g_userCertificateManager; 33 | let folder = config; 34 | _g_userCertificateManager = new opcua.OPCUACertificateManager({ 35 | name: "UserPKI", 36 | rootFolder: path.join(folder, "UserPKI"), 37 | automaticallyAcceptUnknownCertificate: true 38 | }); 39 | return _g_userCertificateManager; 40 | } 41 | 42 | let _g_ServerCertificateManager = null; // For all servers 43 | function createServerCertificateManager() { 44 | if (_g_ServerCertificateManager) return _g_ServerCertificateManager; 45 | let folder = config; 46 | _g_ServerCertificateManager = new opcua.OPCUACertificateManager({ 47 | name: "ServerPKI", 48 | rootFolder: path.join(folder, "ServerPKI"), 49 | automaticallyAcceptUnknownCertificate: true 50 | }); 51 | return _g_ServerCertificateManager; 52 | } 53 | exports.createClientCertificateManager = createClientCertificateManager; 54 | exports.createServerCertificateManager = createServerCertificateManager; 55 | exports.createUserCertificateManager = createUserCertificateManager; 56 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-red-contrib-opcua", 3 | "version": "0.2.339", 4 | "description": "A Node-RED node to communicate via OPC UA based on node-opcua library.", 5 | "repository": { 6 | "type": "git", 7 | "url": "git+https://github.com/mikakaraila/node-red-contrib-opcua.git" 8 | }, 9 | "keywords": [ 10 | "node-red", 11 | "OPC UA", 12 | "opc-ua", 13 | "unified automation", 14 | "opc foundation", 15 | "node-opcua" 16 | ], 17 | "author": { 18 | "name": "Mika Karaila", 19 | "email": "mika.karaila@gmail.com" 20 | }, 21 | "license": "Apache-2.0", 22 | "bugs": { 23 | "url": "https://github.com/mikakaraila/node-red-contrib-opcua/issues" 24 | }, 25 | "node-red": { 26 | "version": ">=1.3", 27 | "nodes": { 28 | "OpcUa-Item": "opcua/101-opcuaitem.js", 29 | "OpcUa-Client": "opcua/102-opcuaclient.js", 30 | "OpcUa-Browser": "opcua/103-opcuabrowser.js", 31 | "OpcUa-Server": "opcua/104-opcuaserver.js", 32 | "OpcUa-Endpoint": "opcua/105-opcuaendpoint.js", 33 | "OpcUa-Event": "opcua/106-opcuaevent.js", 34 | "OpcUa-Method": "opcua/107-opcuamethod.js", 35 | "OpcUa-Rights": "opcua/108-opcuarights.js", 36 | "OpcUa-Discovery": "opcua/109-opcuadiscovery.js" 37 | } 38 | }, 39 | "engines": { 40 | "node": ">=15" 41 | }, 42 | "dependencies": { 43 | "async": "^3.2.1", 44 | "chalk": "4.1.2", 45 | "env-paths": "2.2.1", 46 | "flatted": "^3.2.2", 47 | "get-user-locale": "^2.3.0", 48 | "lodash.clonedeep": "^4.5.0", 49 | "node-opcua": "^2.138.1", 50 | "node-opcua-client-crawler": "2.127.1", 51 | "node-opcua-file-transfer": "^2.138.1", 52 | "os-locale": "^6.0.2" 53 | }, 54 | "directories": { 55 | "example": "examples" 56 | }, 57 | "homepage": "https://github.com/mikakaraila/node-red-contrib-opcua#readme", 58 | "scripts": { 59 | "test": "karma start opcua.conf.js --log-level debug --single-run" 60 | }, 61 | "devDependencies": { 62 | "jasmine-core": "^3.8.0", 63 | "karma": "^6.3.4", 64 | "karma-chrome-launcher": "^3.1.0", 65 | "karma-jasmine": "^4.0.1" 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /test/opcuaServerSpec.js: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | Copyright 2016 Klaus Landsdorf 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | 17 | **/ 18 | 19 | 20 | describe("jasmine.arrayContaining", function() { 21 | var foo; 22 | 23 | beforeEach(function() { 24 | foo = [1, 2, 3, 4]; 25 | }); 26 | 27 | it("matches arrays with some of the values", function() { 28 | expect(foo).toEqual(jasmine.arrayContaining([3, 1])); 29 | expect(foo).not.toEqual(jasmine.arrayContaining([6])); 30 | }); 31 | 32 | describe("when used with a spy", function() { 33 | it("is useful when comparing arguments", function() { 34 | var callback = jasmine.createSpy('callback'); 35 | 36 | callback([1, 2, 3, 4]); 37 | 38 | expect(callback).toHaveBeenCalledWith(jasmine.arrayContaining([4, 2, 3])); 39 | expect(callback).not.toHaveBeenCalledWith(jasmine.arrayContaining([5, 2])); 40 | }); 41 | }); 42 | }); 43 | 44 | 45 | describe("jasmine.any", function() { 46 | it("matches any value", function() { 47 | expect({}).toEqual(jasmine.any(Object)); 48 | expect(12).toEqual(jasmine.any(Number)); 49 | }); 50 | 51 | describe("when used with a spy", function() { 52 | it("is useful for comparing arguments", function() { 53 | var foo = jasmine.createSpy('foo'); 54 | foo(12, function() { 55 | return true; 56 | }); 57 | 58 | expect(foo).toHaveBeenCalledWith(jasmine.any(Number), jasmine.any(Function)); 59 | }); 60 | }); 61 | }); -------------------------------------------------------------------------------- /users.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "username": "visitor", 4 | "password": "qwerty", 5 | "roles": "Guest" 6 | }, 7 | { 8 | "username": "JohnSmith", 9 | "password": "1234", 10 | "roles": "Operator" 11 | }, 12 | { 13 | "username": "James", 14 | "password": "Bond", 15 | "roles": "Observer" 16 | }, 17 | { 18 | "username": "Administrator", 19 | "password": "HardPassword!", 20 | "roles": "Supervisor;ConfigureAdmin;SecurityAdmin" 21 | } 22 | ] 23 | --------------------------------------------------------------------------------