node-red-contrib-uos-nats 0.1.64 → 0.1.66

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.
Files changed (2) hide show
  1. package/README.md +216 -163
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -2,16 +2,16 @@
2
2
 
3
3
  **Unofficial Node-RED Package for u-OS Data Hub**
4
4
 
5
- Built and maintained by [IoTUeli](https://www.linkedin.com/in/iotueli/). This is **not** an official Weidmüller product.
5
+ Built and maintained by [IoTUeli](https://iotueli.ch). This is **not** an official Weidmüller product.
6
6
  Repository: <https://github.com/uiff/nats-NodeRed-Node-uc20>
7
7
 
8
8
  ---
9
9
 
10
10
  ## What is this?
11
11
 
12
- Node-RED nodes to **read** and **write** variables from the **u-OS Data Hub** via NATS protocol.
12
+ Node-RED nodes to **read** and **write** variables from the **Weidmüller u-OS Data Hub** via NATS protocol.
13
13
 
14
- ### The Three Nodes:
14
+ ### The Three Nodes
15
15
 
16
16
  1. **u-OS Config** – Connection settings (Host, OAuth credentials, NATS connection)
17
17
  2. **DataHub - IN** – Read variables from Data Hub providers
@@ -36,164 +36,224 @@ Restart Node-RED. The nodes appear in the **"u-OS DataHub NATS"** category in th
36
36
 
37
37
  ---
38
38
 
39
- ## 1. u-OS Config Node
39
+ ## Why NATS Instead of REST API?
40
40
 
41
- ### Purpose
42
- Stores connection details and OAuth credentials. All DataHub nodes share this configuration.
41
+ The u-OS Data Hub offers both **NATS** (this package) and **REST API** access. Here's why NATS is the better choice for Node-RED:
43
42
 
44
- ### Setup Steps
43
+ ### Feature Comparison
45
44
 
46
- 1. **Add a Config Node:**
47
- - Open any DataHub node (IN or OUT)
48
- - Click the pencil icon next to "Config"
49
- - Click "Add new uos-config..."
45
+ | Feature | NATS Protocol | REST API |
46
+ |---------|---------------|----------|
47
+ | **Real-time Updates** | Event-driven (instant) | ❌ Polling required (delays) |
48
+ | **Performance** | ✅ Binary protocol, high-throughput | HTTP/JSON overhead |
49
+ | **Communication** | ✅ Bidirectional (Pub/Sub + Request/Reply) | ❌ Client-initiated only |
50
+ | **Provider Registration** | ✅ Dynamic discovery & auto-registration | ❌ Static endpoints |
51
+ | **Scalability** | ✅ Many-to-many connections | ❌ Point-to-point requests |
52
+ | **Network Efficiency** | ✅ Push notifications (no polling waste) | ❌ Repeated GET requests |
50
53
 
51
- 2. **Fill in the Fields:**
54
+ ### Event-Driven Architecture
52
55
 
53
- | Field | Example | Description |
54
- |-------|---------|-------------|
55
- | **Host** | `192.168.10.100` | IP address of your u-Control device |
56
- | **Port** | `49360` | NATS port (default: 49360) |
57
- | **Client Name** | `nodered` | Unique name for this Node-RED instance |
58
- | **Client ID** | `my-oauth-client` | OAuth2 Client ID (from Control Center) |
59
- | **Client Secret** | `****************` | OAuth2 Client Secret (from Control Center) |
60
- | **Scopes** | `hub.variables.*` | Leave default or customize (see below) |
61
-
62
- 3. **Create OAuth Client in Control Center:**
63
- - Open the u-Control Web Interface
64
- - Go to **System** → **Access Control** → **OAuth Clients**
65
- - Click **"Add Client"**
66
- - **Name:** `nodered`
67
- - **Scopes:** Select all `hub.variables.*` (provide, readonly, readwrite)
68
- - **Copy the Client ID and Secret** into Node-RED
56
+ **NATS enables true event-driven workflows:**
57
+
58
+ ```
59
+ Sensor changes value
60
+
61
+ Data Hub publishes event via NATS
62
+
63
+ Node-RED receives update INSTANTLY (0ms delay)
64
+
65
+ Process & forward to other systems
66
+ ```
67
+
68
+ **With REST API you'd need:**
69
+ - Constant polling (e.g., every 100ms)
70
+ - Increased network traffic
71
+ - Delayed reactions
72
+ - Higher CPU usage
73
+
74
+ ### Use NATS when
69
75
 
70
- 4. **Test Connection:**
71
- - Click **"Test Connection"** button
72
- - Success: Shows "Connected" + granted scopes
73
- - Error: Check Host/Port/Credentials
76
+ You need **real-time reactions** to value changes
77
+ You want to **create providers** (publish data to Data Hub)
78
+ You need **event subscriptions** (get notified on changes)
79
+ You're building **scalable industrial workflows**
80
+
81
+ ### Use REST API when
82
+
83
+ ⚠️ You only need **occasional manual reads**
84
+ ⚠️ You're debugging or doing one-time queries
85
+ ⚠️ NATS port (49360) is blocked in your network
74
86
 
75
87
  ---
76
88
 
77
- ## 2. DataHub - IN Node (Read Variables)
89
+ ## Quick Start Guide
78
90
 
79
- ### Purpose
80
- Subscribe to variables from a Data Hub provider and output their values as JSON messages.
91
+ ### Step 1: Create OAuth Client in u-OS
81
92
 
82
- ### Setup Steps
93
+ Before configuring Node-RED, create an OAuth client on your u-OS device:
83
94
 
84
- #### Step 1: Select Config
85
- - Choose your **u-OS Config** node
95
+ 1. Open the **u-OS Web Interface** (e.g., `http://192.168.10.100`)
96
+ 2. Go to **System** **Access Control** → **OAuth Clients**
97
+ 3. Click **"Add Client"**
98
+ 4. Enter:
99
+ - **Name:** `nodered`
100
+ - **Scopes:** Select **all** `hub.variables.*` scopes:
101
+ - `hub.variables.provide` (for creating providers)
102
+ - `hub.variables.readonly` (for reading)
103
+ - `hub.variables.readwrite` (for writing)
104
+ 5. **Save** and copy the **Client ID** and **Client Secret**
86
105
 
87
- #### Step 2: Enter Provider ID
88
- - **What is it?** The name of the data source (e.g., `u_os_sbm`, `hub`, `custom-provider`)
89
- - **Where to find it?**
90
- - u-Control Web Interface → **Data Hub** → **Providers**
91
- - Or use the Python sample's `PROVIDER_ID`
106
+ ### Step 2: Configure u-OS Config Node in Node-RED
92
107
 
93
- **Example:** `u_os_sbm`
108
+ 1. Drag any **DataHub - IN** or **DataHub - OUT** node onto the canvas
109
+ 2. Double-click it to open settings
110
+ 3. Click the **pencil icon** next to "Config"
111
+ 4. Select **"Add new uos-config..."**
112
+ 5. Fill in:
94
113
 
95
- #### Step 3: Add Variables (Manual Table)
96
- Since auto-discovery often fails due to permissions, you **manually map** variable names to their IDs.
114
+ | Field | Example | Description |
115
+ |-------|---------|-------------|
116
+ | **Host** | `192.168.10.100` | IP of your u-OS device |
117
+ | **Port** | `49360` | NATS port (default) |
118
+ | **Client Name** | `nodered` | Unique name for this instance |
119
+ | **Client ID** | `my-oauth-client` | From Step 1 |
120
+ | **Client Secret** | `****************` | From Step 1 |
97
121
 
98
- **How to find Variable IDs:**
122
+ 6. Click **"Test Connection"** to verify
123
+ 7. On success, click **"Add"** then **"Done"**
99
124
 
100
- **Option A: From Python Config**
101
- ```python
102
- # Your working Python config.py
103
- VARIABLE_DEFINITIONS = [
104
- {"id": 0, "key": "manufacturer_name", ...},
105
- {"id": 2, "key": "machine.details.temp", ...}
106
- ]
125
+ ### Step 3: Deploy Your First Flow
126
+
127
+ Import this example flow to test both reading and writing:
128
+
129
+ ```json
130
+ [{"id":"cdad2fa96dc6eeec","type":"datahub-input","z":"c221537c994b056a","name":"","connection":"a0ba0e15c8dad779","providerId":"u_os_adm","manualVariables":"digital_nameplate.address_information.zipcode:2","triggerMode":"poll","pollingInterval":"100","x":110,"y":40,"wires":[["315d179d66bf9b93"]]},{"id":"315d179d66bf9b93","type":"debug","z":"c221537c994b056a","name":"debug 7","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":740,"y":40,"wires":[]},{"id":"09f29f6bfc4e1be2","type":"inject","z":"c221537c994b056a","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":120,"y":140,"wires":[["43b2fcf73c370f7c"]]},{"id":"43b2fcf73c370f7c","type":"function","z":"c221537c994b056a","name":"Random Data","func":"function randomBetween(min, max) {\n return Math.random() * (max - min) + min;\n}\n\nmsg.payload = {\n machine: {\n status: \"running\",\n details: {\n temp: randomBetween(30, 80)\n }\n }\n};\n\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":300,"y":140,"wires":[["a90304487fe19b3a"]]},{"id":"a90304487fe19b3a","type":"datahub-output","z":"c221537c994b056a","name":"","connection":"a0ba0e15c8dad779","providerId":"","x":500,"y":140,"wires":[["e53fa58e4c1987ba"]]},{"id":"e53fa58e4c1987ba","type":"debug","z":"c221537c994b056a","name":"debug 6","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":740,"y":140,"wires":[]},{"id":"a0ba0e15c8dad779","type":"uos-config","host":"127.0.0.1","port":49360,"clientName":"hub","scope":"hub.variables.provide hub.variables.readwrite hub.variables.readonly"}]
107
131
  ```
108
- → Use these IDs!
109
132
 
110
- **Option B: From u-Control Web UI**
111
- 1. Open **Data Hub** → **Providers** → Select your provider
112
- 2. Click on **Variables**
113
- 3. Note the **ID** column (usually 0, 1, 2, ...)
133
+ **What this flow does:**
134
+
135
+ **Top Row** (Reading):
136
+ - **DataHub - IN** reads `zipcode` variable from provider `u_os_adm`
137
+ - Polls every 100ms
138
+ - Outputs to Debug node
139
+
140
+ **Bottom Row** (Writing):
141
+ - **Inject** node triggers data generation
142
+ - **Function** node creates random temperature data
143
+ - **DataHub - OUT** publishes to Data Hub as provider `hub`
144
+ - Creates variables: `machine.status` and `machine.details.temp`
145
+
146
+ **To customize:**
147
+ 1. Edit the **DataHub - IN** node:
148
+ - Change `Provider ID` to match your system
149
+ - Update variable mappings in the table
150
+ 2. Edit the **Function** node to generate your data structure
151
+ 3. Click **Deploy**
152
+
153
+ ---
154
+
155
+ ## Finding Variable IDs
156
+
157
+ The **DataHub - IN** node requires variable IDs (numbers). Here's how to find them:
158
+
159
+ ### Option 1: u-OS Web Interface
160
+
161
+ 1. Open **Data Hub** → **Providers**
162
+ 2. Click on your target provider (e.g., `u_os_adm`)
163
+ 3. Click **Variables** tab
164
+ 4. Note the **ID** column (e.g., `0`, `1`, `2`)
165
+
166
+ ### Option 2: REST API Query
114
167
 
115
- **Option C: From REST API**
116
168
  ```bash
117
169
  curl -H "Authorization: Bearer $TOKEN" \
118
- http://192.168.10.100/datahub/v1/providers/u_os_sbm/variables
170
+ http://192.168.10.100/datahub/v1/providers/u_os_adm/variables
171
+ ```
172
+
173
+ Response shows variable definitions with IDs:
174
+ ```json
175
+ {
176
+ "variables": [
177
+ {"id": 0, "key": "manufacturer_name", ...},
178
+ {"id": 2, "key": "digital_nameplate.address_information.zipcode", ...}
179
+ ]
180
+ }
119
181
  ```
120
182
 
121
- **Fill the Table:**
183
+ ### Option 3: Check Other Apps
184
+
185
+ If you have other Data Hub clients (apps, PLCs), check their variable definitions to find the IDs.
186
+
187
+ ---
188
+
189
+ ## DataHub - IN Node (Read Variables)
190
+
191
+ ### Purpose
192
+ Subscribe to variables from a Data Hub provider and output their values as JSON messages.
193
+
194
+ ### Configuration
195
+
196
+ 1. **Config Node:** Select your u-OS connection
197
+ 2. **Provider ID:** Enter the provider name (e.g., `u_os_adm`, `hub`, `u_os_sbm`)
198
+ 3. **Variables Table:** Manually map variable names to IDs
122
199
 
123
200
  | Variable Name | ID |
124
201
  |--------------|-----|
125
202
  | `manufacturer_name` | `0` |
126
- | `machine.details.temp` | `2` |
203
+ | `zipcode` | `2` |
127
204
 
128
205
  Click **"Add Variable"** for each entry.
129
206
 
130
- #### Step 4: Choose Trigger Mode
131
-
132
- | Mode | When to Use |
133
- |------|-------------|
134
- | **Event (on change)** | Default. Efficient. Outputs only when values change. |
135
- | **Poll (interval)** | Forces periodic reads (e.g., every 1000ms). Less efficient. |
136
-
137
- #### Step 5: Deploy & Test
138
- 1. Click **Deploy**
139
- 2. Connect a **Debug** node to the output
140
- 3. Send a message to the **Input Port** (using an **Inject** node) to trigger a read
141
- 4. Check the Debug panel for output:
142
- ```json
143
- {
144
- "type": "snapshot",
145
- "variables": [
146
- {"providerId": "u_os_sbm", "id": 0, "key": "manufacturer_name", "value": "Weidmüller", ...}
147
- ]
148
- }
149
- ```
150
-
151
- ### Troubleshooting
152
-
153
- | Problem | Solution |
154
- |---------|----------|
155
- | No output | Check: (1) Config deployed? (2) Provider ID correct? (3) Variable IDs correct? (4) Inject signal sent? |
156
- | "Variable not found" | Double-check IDs in the table. Use Python config or Web UI to verify. |
157
- | Permission errors | This is expected! That's why we use the manual table. |
207
+ 4. **Trigger Mode:**
208
+ - **Event (on change):** Efficient. Outputs only when values change.
209
+ - **Poll (interval):** Forces periodic reads (e.g., every 100ms).
210
+
211
+ ### Output Format
212
+
213
+ ```json
214
+ {
215
+ "type": "snapshot",
216
+ "variables": [
217
+ {
218
+ "providerId": "u_os_adm",
219
+ "id": 2,
220
+ "key": "zipcode",
221
+ "value": "12345",
222
+ "quality": "GOOD",
223
+ "timestampNs": 1234567890000000000
224
+ }
225
+ ]
226
+ }
227
+ ```
228
+
229
+ ### Triggering Reads
230
+
231
+ Connect an **Inject** node to the input port to trigger manual reads.
158
232
 
159
233
  ---
160
234
 
161
- ## 3. DataHub - OUT Node (Write Variables)
235
+ ## DataHub - OUT Node (Write Variables)
162
236
 
163
237
  ### Purpose
164
- **Creates a real Data Hub provider** that publishes variables to the u-OS Data Hub. Other applications, devices, or even other Node-RED instances can **subscribe to your data in real-time**.
238
+ Creates a real Data Hub provider that publishes variables. Other applications can subscribe to your data in real-time.
165
239
 
166
240
  ### How It Works
167
241
 
168
242
  The OUT node:
169
- 1. **Registers as a Provider** on the Data Hub (e.g., provider ID: `nodered`)
243
+ 1. **Registers as a Provider** on the Data Hub (uses `Client Name` from Config)
170
244
  2. **Publishes variable definitions** automatically when new variables are sent
171
245
  3. **Sends value updates** via NATS when you send JSON messages
172
- 4. **Answers read requests** from other consumers (apps can query your latest values)
173
- 5. **Supports event-driven subscriptions** - other apps get updates **instantly** when values change
174
-
175
- **Important:** This provider only exists **while Node-RED is running**. When you restart Node-RED, the provider re-registers automatically.
246
+ 4. **Answers read requests** from other consumers
247
+ 5. **Supports event-driven subscriptions** - other apps get updates **instantly**
176
248
 
177
- ### Real-World Use Cases
249
+ ### Configuration
178
250
 
179
- **IoT Data Collection:** Node-RED reads sensor data (Modbus, MQTT, etc.) and publishes it to the Data Hub
180
- **Edge Processing:** Process data locally in Node-RED, then share results with other apps
181
- ✅ **System Integration:** Bridge between different protocols (e.g., OPC UA → Data Hub)
182
- ✅ **Custom Dashboards:** Other apps can subscribe to Node-RED's variables for visualization
251
+ 1. **Config Node:** Select your u-OS connection
252
+ 2. **Provider ID:** Leave **empty** to use `Client Name` (recommended)
183
253
 
184
- ### Setup Steps
254
+ ### Send Data
185
255
 
186
- #### Step 1: Select Config
187
- - Choose your **u-OS Config** node
188
-
189
- #### Step 2: Provider ID (Optional)
190
- - **Leave EMPTY** to use the `Client Name` from your Config (recommended)
191
- - Or enter a custom provider ID (e.g., `my-machine-data`)
192
-
193
- **Example:** If your Config's Client Name is `nodered`, the provider will be `nodered`
194
-
195
- #### Step 3: Send JSON Messages
196
- Send a JSON object with your data:
256
+ Send JSON to the input:
197
257
 
198
258
  ```json
199
259
  {
@@ -205,66 +265,65 @@ Send a JSON object with your data:
205
265
  }
206
266
  ```
207
267
 
208
- This creates variables:
209
- - `temperature` → ID 0
210
- - `machine.status` → ID 1
211
- - `machine.speed` → ID 2
268
+ This creates:
269
+ - `temperature` → Variable ID 0
270
+ - `machine.status` → Variable ID 1
271
+ - `machine.speed` → Variable ID 2
212
272
 
213
- **The variables are INSTANTLY available to other apps via:**
214
- - **Event subscriptions** (other apps get updates when values change)
215
- - **Read queries** (other apps can request current values)
216
- - **u-Control Web UI** (visible in Data Hub → Providers → `nodered`)
273
+ **Other apps can now:**
274
+ - Subscribe to value changes (event-driven, instant updates)
275
+ - Query current values (on-demand reads)
276
+ - View in u-OS Web UI (**Data Hub****Providers** → `nodered`)
217
277
 
218
278
  ### Event-Driven Communication
219
279
 
220
- When you send a message to the OUT node:
221
-
222
280
  ```
223
- [Function: {"temp": 22.5}] → [DataHub - OUT]
224
-
225
- ┌───────────────────────────────┐
226
- │ u-OS Data Hub (NATS) │
227
- └───────────────────────────────┘
228
- ↓ ↓ ↓
229
- [Python App] [Dashboard] [Other Node-RED]
230
- (subscribes) (subscribes) (subscribes)
281
+ [Node-RED: DataHub - OUT] → [u-OS Data Hub (NATS)]
282
+
283
+ ┌─────────────┼─────────────┐
284
+ ↓ ↓ ↓
285
+ [Other Apps] [Dashboards] [PLCs]
286
+ (subscribe) (subscribe) (subscribe)
231
287
  ```
232
288
 
233
- **All subscribers receive the update IMMEDIATELY** - no polling needed!
234
-
235
- #### Step 4: Deploy & Test
236
- 1. Connect a **Function** or **Inject** node
237
- 2. Click **Deploy**
238
- 3. Check the u-Control Web Interface → **Data Hub** → Your Provider
289
+ **All subscribers receive updates IMMEDIATELY** - no polling needed!
239
290
 
240
291
  ---
241
292
 
242
- ## Example Flow
293
+ ## Troubleshooting
243
294
 
244
- ```
245
- [Inject] → [DataHub - IN] → [Debug]
246
- (u_os_sbm)
295
+ ### No Output from IN Node
247
296
 
248
- [Inject: {"temp": 22}] → [DataHub - OUT]
249
- (nodered)
250
- ```
297
+ Config node deployed?
298
+ ✓ Provider ID correct? (check u-OS Web UI → Data Hub → Providers)
299
+ ✓ Variable IDs correct? (check u-OS Web UI → Variables)
300
+ ✓ Inject signal sent to input port?
251
301
 
252
- **Copy this flow:**
253
- ```json
254
- [{"id":"inject1","type":"inject","name":"Trigger Read"},
255
- {"id":"datahub-in","type":"datahub-input","connection":"config1","providerId":"u_os_sbm","manualVariables":"manufacturer_name:0"},
256
- {"id":"debug1","type":"debug"}]
257
- ```
302
+ ### "Variable not found" Error
303
+
304
+ - Double-check IDs in the Variables table
305
+ - Verify IDs match those in u-OS Web UI
306
+
307
+ ### Connection Test Fails
308
+
309
+ - Check Host/Port are correct and device is reachable
310
+ - Verify Client ID/Secret match exactly
311
+ - Ensure OAuth client exists in u-OS
312
+ - Verify all `hub.variables.*` scopes are granted
313
+
314
+ ### Why Manual IDs?
315
+
316
+ Auto-discovery requires special permissions on the provider definition endpoint, which are often restricted for security. The manual table works **without** this permission by querying specific IDs directly.
258
317
 
259
318
  ---
260
319
 
261
320
  ## FAQ
262
321
 
263
- ### Q: Why manual IDs? Can't it auto-discover?
264
- **A:** Auto-discovery requires `hub.variables.readonly` permission on the **provider definition** endpoint, which is often restricted. The manual table works **without** this permission because it queries specific IDs directly.
322
+ ### Q: Can I use the provider created by OUT node in the IN node?
323
+ **A:** **No, don't do this!** The OUT provider only exists while Node-RED runs. On restart, it disappears and the IN node fails. Read from **system providers** (`u_os_sbm`, `u_os_adm`) or other persistent apps instead.
265
324
 
266
325
  ### Q: Where do I get Client ID/Secret?
267
- **A:** u-Control Web Interface → **System** → **Access Control** → **OAuth Clients** → **Add Client**
326
+ **A:** u-OS Web Interface → **System** → **Access Control** → **OAuth Clients** → **Add Client**
268
327
 
269
328
  ### Q: What are the required OAuth scopes?
270
329
  **A:**
@@ -273,23 +332,17 @@ When you send a message to the OUT node:
273
332
  - **Recommended:** Select all `hub.variables.*` scopes when creating the client
274
333
 
275
334
  ### Q: Can I use this outside the local network?
276
- **A:** Yes, if your u-Control device is reachable over the network and you configure the correct Host/Port.
335
+ **A:** Yes, if your u-OS device is reachable over the network and you configure the correct Host/Port.
277
336
 
278
337
  ### Q: Event vs Poll - which is better?
279
338
  **A:** **Event** (default) is more efficient. Use **Poll** only if you need guaranteed periodic readings regardless of value changes.
280
339
 
281
340
  ---
282
341
 
283
- ## Changelog
284
-
285
- See [GitHub Releases](https://github.com/uiff/nats-NodeRed-Node-uc20/releases)
286
-
287
- ---
288
-
289
342
  ## Support
290
343
 
291
344
  **Issues, Questions, or Feature Requests:**
292
- Contact [IoTUeli](https://www.linkedin.com/in/iotueli/) or open an issue on [GitHub](https://github.com/uiff/nats-NodeRed-Node-uc20)
345
+ Contact [IoTUeli](https://iotueli.ch) or open an issue on [GitHub](https://github.com/uiff/nats-NodeRed-Node-uc20)
293
346
 
294
347
  ---
295
348
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-red-contrib-uos-nats",
3
- "version": "0.1.64",
3
+ "version": "0.1.66",
4
4
  "description": "Node-RED nodes for Weidmüller u-OS Data Hub. Read and write variables via NATS protocol with OAuth2 authentication. Supports event-based subscriptions and manual variable mapping.",
5
5
  "author": {
6
6
  "name": "IoTUeli",