@jsgorana/node-red-opcua 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/CONTRIBUTING.md +36 -0
- package/LICENSE +21 -0
- package/README.md +506 -0
- package/docs/assets/client-quickstart-flow.png +0 -0
- package/docs/assets/endpoint-security-config.png +0 -0
- package/docs/assets/node-red-import-examples-menu.png +0 -0
- package/docs/assets/server-client-demo-flow.png +0 -0
- package/docs/assets/server-quickstart-flow.png +0 -0
- package/docs/assets/server-security-config.png +0 -0
- package/docs/assets/subscribe-deadband-config.png +0 -0
- package/examples/client-quickstart.json +146 -0
- package/examples/server-and-client-demo.json +197 -0
- package/examples/server-quickstart.json +83 -0
- package/nodes/lib/connection-manager.js +489 -0
- package/nodes/lib/server-manager.js +343 -0
- package/nodes/opcua-browse.html +46 -0
- package/nodes/opcua-browse.js +59 -0
- package/nodes/opcua-endpoint.html +122 -0
- package/nodes/opcua-endpoint.js +85 -0
- package/nodes/opcua-read.html +47 -0
- package/nodes/opcua-read.js +86 -0
- package/nodes/opcua-server.html +191 -0
- package/nodes/opcua-server.js +105 -0
- package/nodes/opcua-subscribe.html +84 -0
- package/nodes/opcua-subscribe.js +124 -0
- package/nodes/opcua-write.html +63 -0
- package/nodes/opcua-write.js +110 -0
- package/package.json +63 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## 0.1.0 - Unreleased
|
|
6
|
+
|
|
7
|
+
Initial pre-release of `@jsgorana/node-red-opcua`.
|
|
8
|
+
|
|
9
|
+
- Added client nodes: endpoint, read, write, browse, and subscribe.
|
|
10
|
+
- Added bidirectional `opcua-server` node for exposing Node-RED values.
|
|
11
|
+
- Added shared, ref-counted OPC-UA connection management with reconnect handling.
|
|
12
|
+
- Added fail-fast operation timeouts for read/write/browse workflows.
|
|
13
|
+
- Added secure-by-default client certificate validation with persisted PKI storage.
|
|
14
|
+
- Added username/password authentication and Sign/SignAndEncrypt server support.
|
|
15
|
+
- Added batch read/write support.
|
|
16
|
+
- Added shared endpoint subscriptions with per-node monitored items.
|
|
17
|
+
- Added subscribe deadband/data-change filter support.
|
|
18
|
+
- Added polished Node-RED example flows.
|
|
19
|
+
- Added automated tests, linting, and GitHub Actions CI.
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thanks for helping improve `@jsgorana/node-red-opcua`.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
- Node.js 22.9 or newer
|
|
8
|
+
- npm
|
|
9
|
+
|
|
10
|
+
## Local Setup
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install
|
|
14
|
+
npm run lint
|
|
15
|
+
npm test
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The test suite starts local OPC-UA servers as needed; no external OPC-UA server is required.
|
|
19
|
+
|
|
20
|
+
## Development Notes
|
|
21
|
+
|
|
22
|
+
- Keep runtime node files under `nodes/`.
|
|
23
|
+
- Keep shared logic in `nodes/lib/` where it can be tested without Node-RED.
|
|
24
|
+
- Add or update tests for behavioral changes.
|
|
25
|
+
- Preserve secure defaults. Development-only security bypasses should be explicit and logged.
|
|
26
|
+
- Do not publish from feature branches or local experiments.
|
|
27
|
+
|
|
28
|
+
## Before Opening a PR
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm run lint
|
|
32
|
+
npm test
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Include a short description of the change, the reason for it, and any manual OPC-UA or
|
|
36
|
+
Node-RED validation performed.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 jsgorana
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,506 @@
|
|
|
1
|
+
# @jsgorana/node-red-opcua
|
|
2
|
+
|
|
3
|
+
Modern OPC-UA client and server nodes for Node-RED.
|
|
4
|
+
|
|
5
|
+
Use Node-RED to read, write, browse, and subscribe to industrial OPC-UA servers, or expose
|
|
6
|
+
Node-RED values as an OPC-UA server that PLCs, SCADA systems, historians, and test clients
|
|
7
|
+
can read and write.
|
|
8
|
+
|
|
9
|
+
This package is built for Node-RED 5.x and current `node-opcua`. It is intended as a clean,
|
|
10
|
+
maintained alternative to older OPC-UA Node-RED packages that have become difficult to rely
|
|
11
|
+
on in modern IIOT deployments.
|
|
12
|
+
|
|
13
|
+

|
|
14
|
+
|
|
15
|
+
## What You Get
|
|
16
|
+
|
|
17
|
+
| Node | Use it for |
|
|
18
|
+
| --- | --- |
|
|
19
|
+
| `opcua-endpoint` | Shared OPC-UA client endpoint configuration: URL, security, authentication, timeout, PKI trust behavior |
|
|
20
|
+
| `opcua-read` | Read one or many OPC-UA node values |
|
|
21
|
+
| `opcua-write` | Write one or many OPC-UA node values with explicit data types |
|
|
22
|
+
| `opcua-browse` | Browse an address space from a starting NodeId |
|
|
23
|
+
| `opcua-subscribe` | Subscribe to value changes with sampling, publishing, queue, trigger, and deadband settings |
|
|
24
|
+
| `opcua-server` | Serve Node-RED values as OPC-UA variables and emit messages when OPC-UA clients write |
|
|
25
|
+
|
|
26
|
+
Core behavior:
|
|
27
|
+
|
|
28
|
+
- One shared, ref-counted OPC-UA connection per endpoint config node.
|
|
29
|
+
- Automatic reconnect and subscription re-arm after outages.
|
|
30
|
+
- Fail-fast read/write/browse operation timeout so flows do not hang forever.
|
|
31
|
+
- Secure-by-default certificate validation for encrypted client connections.
|
|
32
|
+
- Username/password authentication for client and server use cases.
|
|
33
|
+
- Server-side `None`, `Sign`, and `SignAndEncrypt` endpoint options.
|
|
34
|
+
- Three bundled example flows that are ready to import from the Node-RED Examples menu.
|
|
35
|
+
|
|
36
|
+
## Requirements
|
|
37
|
+
|
|
38
|
+
- Node.js `>=22.9.0`
|
|
39
|
+
- Node-RED 5.x recommended
|
|
40
|
+
- Node-RED 4.x is supported by package metadata, but Node-RED 5.x is the primary target
|
|
41
|
+
|
|
42
|
+
## Installation
|
|
43
|
+
|
|
44
|
+
### Palette Manager
|
|
45
|
+
|
|
46
|
+
In Node-RED:
|
|
47
|
+
|
|
48
|
+
1. Open **Menu -> Manage palette**.
|
|
49
|
+
2. Go to **Install**.
|
|
50
|
+
3. Search for `@jsgorana/node-red-opcua`.
|
|
51
|
+
4. Click **Install**.
|
|
52
|
+
|
|
53
|
+
### npm
|
|
54
|
+
|
|
55
|
+
From your Node-RED user directory:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npm install @jsgorana/node-red-opcua
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Then restart Node-RED if your runtime does not automatically reload installed nodes.
|
|
62
|
+
|
|
63
|
+
## Fastest Start: Self-Contained Demo
|
|
64
|
+
|
|
65
|
+
The quickest way to prove the package is working is the bundled **Server + Client Demo**.
|
|
66
|
+
It runs an OPC-UA server and OPC-UA client in the same Node-RED instance, so no PLC,
|
|
67
|
+
simulator, or external server is required.
|
|
68
|
+
|
|
69
|
+
1. In Node-RED, open **Menu -> Import**.
|
|
70
|
+
2. Select the **Examples** tab.
|
|
71
|
+
3. Open `@jsgorana/node-red-opcua`.
|
|
72
|
+
4. Import **Server + Client Demo**.
|
|
73
|
+
5. Click **Deploy**.
|
|
74
|
+
6. Click **Simulate sensor**.
|
|
75
|
+
7. Watch the read/subscription/debug nodes update.
|
|
76
|
+
|
|
77
|
+

|
|
78
|
+
|
|
79
|
+
The demo exposes:
|
|
80
|
+
|
|
81
|
+
- `ns=1;s=Temperature`
|
|
82
|
+
- `ns=1;s=Setpoint`
|
|
83
|
+
|
|
84
|
+
The client nodes connect to:
|
|
85
|
+
|
|
86
|
+
```text
|
|
87
|
+
opc.tcp://localhost:4840/UA/NodeRED
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Use `localhost` only when the client and server are in the same runtime/container/host.
|
|
91
|
+
For remote systems, use the OPC-UA server host name or IP address that is reachable from
|
|
92
|
+
Node-RED.
|
|
93
|
+
|
|
94
|
+
## Example Flows
|
|
95
|
+
|
|
96
|
+
Import examples from **Menu -> Import -> Examples -> @jsgorana/node-red-opcua**.
|
|
97
|
+
|
|
98
|
+
### Server + Client Demo
|
|
99
|
+
|
|
100
|
+
Self-contained flow for first validation. The orange group serves values; the blue group
|
|
101
|
+
reads, writes, and subscribes to the server above it.
|
|
102
|
+
|
|
103
|
+

|
|
104
|
+
|
|
105
|
+
### Client Quickstart
|
|
106
|
+
|
|
107
|
+
Client-only patterns for connecting to your own OPC-UA server:
|
|
108
|
+
|
|
109
|
+
- Read a value on demand.
|
|
110
|
+
- Write a value.
|
|
111
|
+
- Browse the address space.
|
|
112
|
+
- Subscribe to live value changes.
|
|
113
|
+
|
|
114
|
+

|
|
115
|
+
|
|
116
|
+
### Server Quickstart
|
|
117
|
+
|
|
118
|
+
Server-only pattern for exposing Node-RED data outward:
|
|
119
|
+
|
|
120
|
+
- Feed Node-RED values into served OPC-UA variables.
|
|
121
|
+
- Receive messages when an OPC-UA client writes a variable.
|
|
122
|
+
|
|
123
|
+

|
|
124
|
+
|
|
125
|
+
## Client Endpoint Configuration
|
|
126
|
+
|
|
127
|
+
All client operation nodes use an `opcua-endpoint` config node. Multiple read/write/browse/
|
|
128
|
+
subscribe nodes that point at the same endpoint share one connection and session.
|
|
129
|
+
|
|
130
|
+

|
|
131
|
+
|
|
132
|
+
Important fields:
|
|
133
|
+
|
|
134
|
+
| Field | Meaning |
|
|
135
|
+
| --- | --- |
|
|
136
|
+
| Endpoint | OPC-UA endpoint URL, for example `opc.tcp://192.168.1.20:4840/UA/MyServer` |
|
|
137
|
+
| Security Mode | `None`, `Sign`, or `SignAndEncrypt` |
|
|
138
|
+
| Security Policy | `None`, `Basic256Sha256`, `Aes128_Sha256_RsaOaep`, `Aes256_Sha256_RsaPss`, or legacy policies |
|
|
139
|
+
| Authentication | Anonymous or username/password |
|
|
140
|
+
| Op timeout | Maximum time a read/write/browse operation waits before failing |
|
|
141
|
+
|
|
142
|
+
For production systems, prefer:
|
|
143
|
+
|
|
144
|
+
- `Security Mode`: `SignAndEncrypt`
|
|
145
|
+
- `Security Policy`: `Basic256Sha256` or stronger
|
|
146
|
+
- Authentication: username/password if your server supports it
|
|
147
|
+
- Server certificate trusted in the Node-RED PKI store
|
|
148
|
+
|
|
149
|
+
## Reading Values
|
|
150
|
+
|
|
151
|
+
### Single Read
|
|
152
|
+
|
|
153
|
+
Configure `Node ID` on the node, or pass it with `msg.nodeId`.
|
|
154
|
+
|
|
155
|
+
Input:
|
|
156
|
+
|
|
157
|
+
```json
|
|
158
|
+
{
|
|
159
|
+
"nodeId": "ns=1;s=Temperature"
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Output:
|
|
164
|
+
|
|
165
|
+
```json
|
|
166
|
+
{
|
|
167
|
+
"payload": 23.7,
|
|
168
|
+
"nodeId": "ns=1;s=Temperature",
|
|
169
|
+
"statusCode": "Good (0x00000000)"
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Batch Read
|
|
174
|
+
|
|
175
|
+
Send an array as `msg.nodeIds` or `msg.payload`.
|
|
176
|
+
|
|
177
|
+
Input:
|
|
178
|
+
|
|
179
|
+
```json
|
|
180
|
+
{
|
|
181
|
+
"nodeIds": [
|
|
182
|
+
"ns=1;s=Temperature",
|
|
183
|
+
"ns=1;s=Setpoint"
|
|
184
|
+
]
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Output:
|
|
189
|
+
|
|
190
|
+
```json
|
|
191
|
+
{
|
|
192
|
+
"payload": [
|
|
193
|
+
{
|
|
194
|
+
"nodeId": "ns=1;s=Temperature",
|
|
195
|
+
"payload": 23.7,
|
|
196
|
+
"statusCode": "Good (0x00000000)"
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
"nodeId": "ns=1;s=Setpoint",
|
|
200
|
+
"payload": 50,
|
|
201
|
+
"statusCode": "Good (0x00000000)"
|
|
202
|
+
}
|
|
203
|
+
],
|
|
204
|
+
"nodeIds": [
|
|
205
|
+
"ns=1;s=Temperature",
|
|
206
|
+
"ns=1;s=Setpoint"
|
|
207
|
+
],
|
|
208
|
+
"statusCodes": [
|
|
209
|
+
"Good (0x00000000)",
|
|
210
|
+
"Good (0x00000000)"
|
|
211
|
+
]
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Writing Values
|
|
216
|
+
|
|
217
|
+
### Single Write
|
|
218
|
+
|
|
219
|
+
Configure `Node ID` and `Data Type` on the node, or override with `msg.nodeId` and
|
|
220
|
+
`msg.dataType`.
|
|
221
|
+
|
|
222
|
+
Input:
|
|
223
|
+
|
|
224
|
+
```json
|
|
225
|
+
{
|
|
226
|
+
"nodeId": "ns=1;s=Setpoint",
|
|
227
|
+
"dataType": "Double",
|
|
228
|
+
"payload": 50
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Output:
|
|
233
|
+
|
|
234
|
+
```json
|
|
235
|
+
{
|
|
236
|
+
"nodeId": "ns=1;s=Setpoint",
|
|
237
|
+
"statusCode": "Good (0x00000000)"
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Batch Write
|
|
242
|
+
|
|
243
|
+
Use an array of write descriptors:
|
|
244
|
+
|
|
245
|
+
```json
|
|
246
|
+
{
|
|
247
|
+
"payload": [
|
|
248
|
+
{
|
|
249
|
+
"nodeId": "ns=1;s=Setpoint",
|
|
250
|
+
"dataType": "Double",
|
|
251
|
+
"value": 50
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
"nodeId": "ns=1;s=Label",
|
|
255
|
+
"dataType": "String",
|
|
256
|
+
"value": "line running"
|
|
257
|
+
}
|
|
258
|
+
]
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
Output:
|
|
263
|
+
|
|
264
|
+
```json
|
|
265
|
+
{
|
|
266
|
+
"nodeIds": [
|
|
267
|
+
"ns=1;s=Setpoint",
|
|
268
|
+
"ns=1;s=Label"
|
|
269
|
+
],
|
|
270
|
+
"statusCodes": [
|
|
271
|
+
"Good (0x00000000)",
|
|
272
|
+
"Good (0x00000000)"
|
|
273
|
+
]
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Supported data type names are the `node-opcua` `DataType` enum names, including:
|
|
278
|
+
`Boolean`, `SByte`, `Byte`, `Int16`, `UInt16`, `Int32`, `UInt32`, `Float`, `Double`,
|
|
279
|
+
`String`, and `DateTime`.
|
|
280
|
+
|
|
281
|
+
## Browsing
|
|
282
|
+
|
|
283
|
+
`opcua-browse` browses from a configured `Node ID`, or from `msg.nodeId`.
|
|
284
|
+
|
|
285
|
+
Common starting points:
|
|
286
|
+
|
|
287
|
+
```text
|
|
288
|
+
RootFolder
|
|
289
|
+
ObjectsFolder
|
|
290
|
+
ns=1;s=SomeObject
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
Output payload is an array of references:
|
|
294
|
+
|
|
295
|
+
```json
|
|
296
|
+
[
|
|
297
|
+
{
|
|
298
|
+
"nodeId": "ns=1;s=Temperature",
|
|
299
|
+
"browseName": "1:Temperature",
|
|
300
|
+
"displayName": "Temperature",
|
|
301
|
+
"nodeClass": 2,
|
|
302
|
+
"typeDefinition": "i=63"
|
|
303
|
+
}
|
|
304
|
+
]
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
## Subscribing To Changes
|
|
308
|
+
|
|
309
|
+
`opcua-subscribe` automatically connects and arms its monitored item when the flow starts.
|
|
310
|
+
It has no input. It emits a message each time the server reports a value change.
|
|
311
|
+
|
|
312
|
+

|
|
313
|
+
|
|
314
|
+
Output:
|
|
315
|
+
|
|
316
|
+
```json
|
|
317
|
+
{
|
|
318
|
+
"payload": 23.9,
|
|
319
|
+
"nodeId": "ns=1;s=Temperature",
|
|
320
|
+
"statusCode": "Good (0x00000000)",
|
|
321
|
+
"sourceTimestamp": "2026-06-28T12:00:00.000Z"
|
|
322
|
+
}
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
Subscription settings:
|
|
326
|
+
|
|
327
|
+
| Field | Meaning |
|
|
328
|
+
| --- | --- |
|
|
329
|
+
| Sampling (ms) | How often the server samples the value |
|
|
330
|
+
| Publishing (ms) | How often the subscription publishes notifications |
|
|
331
|
+
| Queue Size | Number of changes to queue if the client cannot process them immediately |
|
|
332
|
+
| Trigger | Status only, status + value, or status + value + timestamp |
|
|
333
|
+
| Deadband | `None`, `Absolute`, or `Percent` |
|
|
334
|
+
| Deadband Value | Threshold for absolute or percent deadband |
|
|
335
|
+
|
|
336
|
+
All subscribe nodes that share the same endpoint use one OPC-UA subscription with separate
|
|
337
|
+
monitored items. This is friendlier to servers that limit subscription counts.
|
|
338
|
+
|
|
339
|
+
## Exposing Node-RED As An OPC-UA Server
|
|
340
|
+
|
|
341
|
+
Use `opcua-server` when you want other OPC-UA clients to read or write data owned by
|
|
342
|
+
Node-RED.
|
|
343
|
+
|
|
344
|
+

|
|
345
|
+
|
|
346
|
+
Input message:
|
|
347
|
+
|
|
348
|
+
```json
|
|
349
|
+
{
|
|
350
|
+
"topic": "Temperature",
|
|
351
|
+
"payload": 24.2,
|
|
352
|
+
"dataType": "Double"
|
|
353
|
+
}
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
The server exposes that as:
|
|
357
|
+
|
|
358
|
+
```text
|
|
359
|
+
ns=1;s=Temperature
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
If an OPC-UA client writes to a served variable, the node emits:
|
|
363
|
+
|
|
364
|
+
```json
|
|
365
|
+
{
|
|
366
|
+
"topic": "Setpoint",
|
|
367
|
+
"payload": 50,
|
|
368
|
+
"nodeId": "ns=1;s=Setpoint",
|
|
369
|
+
"source": "client"
|
|
370
|
+
}
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
Server security options:
|
|
374
|
+
|
|
375
|
+
- Offer `None`, `Sign`, and/or `SignAndEncrypt` endpoints.
|
|
376
|
+
- Require username/password, allow anonymous, or support both.
|
|
377
|
+
- Validate client certificates in the server PKI trust store.
|
|
378
|
+
- Use `SignAndEncrypt` plus credentials for production-facing servers.
|
|
379
|
+
|
|
380
|
+
## OPC-UA Security And Certificates
|
|
381
|
+
|
|
382
|
+
### Client Certificate Trust
|
|
383
|
+
|
|
384
|
+
For secure client connections (`Sign` or `SignAndEncrypt`), server certificate validation is
|
|
385
|
+
enabled by default.
|
|
386
|
+
|
|
387
|
+
The client PKI store is created under:
|
|
388
|
+
|
|
389
|
+
```text
|
|
390
|
+
<Node-RED userDir>/opcua-pki
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
Important folders:
|
|
394
|
+
|
|
395
|
+
| Folder | Purpose |
|
|
396
|
+
| --- | --- |
|
|
397
|
+
| `own/certs` | Node-RED client's own application certificate |
|
|
398
|
+
| `trusted/certs` | Server certificates explicitly trusted by this Node-RED instance |
|
|
399
|
+
| `rejected` | Unknown certificates rejected during connection attempts |
|
|
400
|
+
|
|
401
|
+
If a secure connection fails with `BadCertificateUntrusted`, copy the server certificate
|
|
402
|
+
from `rejected` into `trusted/certs`, then reconnect.
|
|
403
|
+
|
|
404
|
+
The **Accept untrusted server cert** option is for development only. It disables the trust
|
|
405
|
+
decision and should not be used in production.
|
|
406
|
+
|
|
407
|
+
### Username And Password
|
|
408
|
+
|
|
409
|
+
Credentials are stored using Node-RED credentials storage. For production systems, combine
|
|
410
|
+
username/password with `SignAndEncrypt`.
|
|
411
|
+
|
|
412
|
+
### Server Certificate Trust
|
|
413
|
+
|
|
414
|
+
The `opcua-server` node stores server-side PKI material under:
|
|
415
|
+
|
|
416
|
+
```text
|
|
417
|
+
<Node-RED userDir>/opcua-pki/server
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
When client certificate validation is enabled, unknown client certificates are rejected
|
|
421
|
+
until trusted.
|
|
422
|
+
|
|
423
|
+
## Docker And Network Notes
|
|
424
|
+
|
|
425
|
+
`localhost` means "inside this runtime".
|
|
426
|
+
|
|
427
|
+
Common cases:
|
|
428
|
+
|
|
429
|
+
- Node-RED and OPC-UA server on the same host: `opc.tcp://localhost:4840/...`
|
|
430
|
+
- Node-RED in Docker, server on host machine: use the host name/IP reachable from the
|
|
431
|
+
container, not `localhost`.
|
|
432
|
+
- Node-RED in Docker Compose: use the service name if both containers share a network.
|
|
433
|
+
- Remote PLC/server: use the PLC/server IP or DNS name and ensure the OPC-UA port is open.
|
|
434
|
+
|
|
435
|
+
## Troubleshooting
|
|
436
|
+
|
|
437
|
+
### Node status says `error` or operation times out
|
|
438
|
+
|
|
439
|
+
- Confirm the endpoint URL, port, and resource path.
|
|
440
|
+
- Confirm Node-RED can reach the server from its runtime environment.
|
|
441
|
+
- Increase `Op timeout` if the network is slow.
|
|
442
|
+
- Check whether the server requires security or credentials.
|
|
443
|
+
|
|
444
|
+
### Secure connection fails with `BadCertificateUntrusted`
|
|
445
|
+
|
|
446
|
+
- Look in `<userDir>/opcua-pki/rejected`.
|
|
447
|
+
- Move the server certificate to `<userDir>/opcua-pki/trusted/certs`.
|
|
448
|
+
- Restart/reconnect the flow.
|
|
449
|
+
- Avoid **Accept untrusted server cert** outside development.
|
|
450
|
+
|
|
451
|
+
### Username/password fails
|
|
452
|
+
|
|
453
|
+
- Check whether the server requires `SignAndEncrypt`.
|
|
454
|
+
- Confirm the username and password in the endpoint credentials.
|
|
455
|
+
- Confirm the server supports username/password user tokens for the selected endpoint.
|
|
456
|
+
|
|
457
|
+
### Browse works but read/write fails
|
|
458
|
+
|
|
459
|
+
- Confirm the exact NodeId.
|
|
460
|
+
- Confirm the node exposes the `Value` attribute.
|
|
461
|
+
- For writes, confirm the server allows writing and the selected data type matches.
|
|
462
|
+
|
|
463
|
+
### Subscribe emits nothing
|
|
464
|
+
|
|
465
|
+
- Confirm the node value actually changes.
|
|
466
|
+
- Check sampling/publishing intervals.
|
|
467
|
+
- Remove deadband while testing.
|
|
468
|
+
- Confirm the server permits subscriptions.
|
|
469
|
+
|
|
470
|
+
### Node-RED does not show the nodes
|
|
471
|
+
|
|
472
|
+
- Confirm Node.js is `>=22.9.0`.
|
|
473
|
+
- Confirm the package is installed in the Node-RED user directory or through Palette Manager.
|
|
474
|
+
- Restart Node-RED after installing if needed.
|
|
475
|
+
|
|
476
|
+
## Development
|
|
477
|
+
|
|
478
|
+
```bash
|
|
479
|
+
npm install
|
|
480
|
+
npm run lint
|
|
481
|
+
npm test
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
Run a local test server:
|
|
485
|
+
|
|
486
|
+
```bash
|
|
487
|
+
node test/helpers/standalone-server.js 4841
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
It exposes:
|
|
491
|
+
|
|
492
|
+
```text
|
|
493
|
+
ns=1;s=Temperature
|
|
494
|
+
ns=1;s=Label
|
|
495
|
+
ns=1;s=Setpoint
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
## Project Status
|
|
499
|
+
|
|
500
|
+
`0.1.0` is the first public release. The core client/server workflows are implemented and
|
|
501
|
+
tested. Deferred items include OPC-UA method calls, X.509 user authentication, and richer
|
|
502
|
+
server-side address-space modeling.
|
|
503
|
+
|
|
504
|
+
## License
|
|
505
|
+
|
|
506
|
+
MIT © jsgorana
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|