node-red-contrib-uos-nats 0.1.1 → 0.1.3

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/README.md CHANGED
@@ -1,27 +1,25 @@
1
1
  # node-red-contrib-uos-nats
2
2
 
3
- **Note:** This custom Node-RED package is built and maintained by [IoTUeli](https://www.iotueli.ch) and is **not** an official Weidmüller product. For questions, feature requests, or support please contact IoTUeli directly.
3
+ **Note:** This custom Node-RED package is built and maintained by [IoTUeli](https://www.linkedin.com/in/iotueli/) and is **not** an official Weidmüller product. For questions, feature requests, or support please contact IoTUeli directly. Repository: <https://github.com/uiff/nats-NodeRed-Node-uc20>
4
4
 
5
5
  Node-RED nodes to read and write u-OS Data Hub variables via NATS. This package exposes three building blocks:
6
6
 
7
7
  1. **u-OS Config** – stores host, OAuth client credentials and manages the shared NATS connection.
8
- 2. **DataHub Input** – subscribes to an existing provider, lets you pick individual variables and emits JSON messages.
8
+ 2. **DataHub Input** – subscribes to an existing provider and emits JSON messages. Enter the provider ID and optional comma-separated variable names.
9
9
  3. **DataHub Output** – automatically registers a provider (default `nodered`), flattens incoming JSON structures and publishes them to the Data Hub.
10
10
 
11
11
  The nodes reuse the FlatBuffer helpers from the standalone Node sample, so they speak the native NATS API.
12
12
 
13
13
  ## Installation
14
14
 
15
+ ### From npm (recommended)
15
16
  ```bash
16
- cd ~/App/NATS-NodeRED
17
- npm install
17
+ cd ~/.node-red
18
+ npm install node-red-contrib-uos-nats
18
19
  ```
19
-
20
- Then install the nodes into your Node-RED user directory (e.g. `~/.node-red`):
21
-
20
+ ### From local folder (if you want to test before publishing)
22
21
  ```bash
23
- cd ~/.node-red
24
- npm install ~/App/NATS-NodeRED
22
+ npm install /path/to/local/NATS-NodeRED
25
23
  ```
26
24
 
27
25
  Restart Node-RED. You will find the nodes under the *u-OS Data Hub* category.
@@ -40,8 +38,8 @@ The config node automatically fetches tokens via Client Credentials flow and exp
40
38
 
41
39
  ## DataHub Input Node
42
40
 
43
- - Select the u-OS config node and pick a provider from the drop-down. The node queries `/datahub/v1/providers` and lists all registry entries.
44
- - Choose whether you want **all variables**, **single variable**, or **multi selection**. The variable selector is populated from `/datahub/v1/providers/<provider>/variables`.
41
+ - Select the u-OS config node and enter the provider ID (e.g. `u_os_adm`).
42
+ - Optionally provide a comma-separated list of variable keys (leave empty to receive all).
45
43
  - The node outputs messages with the structure:
46
44
  ```json
47
45
  {
@@ -70,7 +68,7 @@ The config node automatically fetches tokens via Client Credentials flow and exp
70
68
  ## Example Flow
71
69
 
72
70
  1. Drop a **u-OS Config** node, fill in host/port and OAuth credentials from the Control Center.
73
- 2. Add a **DataHub Input** node, select the config, pick an existing provider (e.g. `u_os_adm`) and choose the variables you want to observe. Connect the output to a Debug node.
71
+ 2. Add a **DataHub Input** node, select the config, enter the provider ID and optional comma-separated variable list. Connect the output to a Debug node.
74
72
  3. Add a **DataHub Output** node, leave provider ID = `nodered` and send structured JSON (e.g. from a Function node). The values instantly appear in the Data Hub under the provider `nodered`.
75
73
 
76
74
  > Tip: Because both nodes rely on the Control Center HTTP API for metadata they inherit the same permissions as your OAuth client. Make sure the client has at least `hub.variables.readonly` for the input node and `hub.variables.provide hub.variables.readwrite` for the output node.
@@ -1,131 +1,37 @@
1
1
  <script type="text/javascript">
2
- (function() {
3
- function fetchProviders(configId) {
4
- if (!configId) return Promise.resolve([]);
5
- return $.getJSON(`uos/providers/${configId}`);
6
- }
7
- function fetchVariables(configId, providerId) {
8
- if (!configId || !providerId) return Promise.resolve([]);
9
- return $.getJSON(`uos/providers/${configId}/${providerId}/variables`);
10
- }
11
-
12
2
  RED.nodes.registerType('datahub-input', {
13
- category: 'input',
3
+ category: 'DataHub-NATS',
14
4
  color: '#ff9f43',
15
5
  defaults: {
16
6
  name: { value: '' },
17
7
  connection: { type: 'uos-config', required: true },
18
- providerId: { value: '', required: true },
19
- variableMode: { value: 'all' },
20
- variables: { value: '[]' }
8
+ providerId: { value: 'sampleprovider', required: true },
9
+ variablesText: { value: '' }
21
10
  },
22
11
  inputs: 0,
23
12
  outputs: 1,
24
- icon: 'white/datahub-input.svg',
25
- label: function() {
26
- return this.name || `DataHub Input ${this.providerId || ''}`;
27
- },
28
- labelStyle: function() {
29
- return this.name ? 'node_label_italic' : '';
30
- },
13
+ icon: "white/datahub-input.svg",
31
14
  oneditprepare: function() {
32
- const providerField = $('#node-input-providerId');
33
- const modeField = $('#node-input-variableMode');
34
- const singleField = $('#node-input-variableSingle');
35
- const multiField = $('#node-input-variableMulti');
36
- const multiContainer = $('#node-input-variableMulti-container');
37
- const singleContainer = $('#node-input-variableSingle-container');
38
- const configField = $('#node-input-connection');
39
- let cachedVariables = [];
40
-
41
- function applyMode() {
42
- const mode = modeField.val();
43
- if (mode === 'single') {
44
- singleContainer.show();
45
- multiContainer.hide();
46
- } else if (mode === 'multi') {
47
- singleContainer.hide();
48
- multiContainer.show();
49
- } else {
50
- singleContainer.hide();
51
- multiContainer.hide();
52
- }
53
- }
54
-
55
- function populateVariables(list) {
56
- cachedVariables = list;
57
- singleField.empty();
58
- multiField.empty();
59
- list.forEach(v => {
60
- $('<option>').val(v.key).text(v.key).appendTo(singleField);
61
- $('<option>').val(v.key).text(v.key).appendTo(multiField);
62
- });
63
- const stored = [];
64
- try { stored.push(...JSON.parse($('#node-input-variables').val() || '[]')); } catch(e) {}
65
- if (stored.length) {
66
- singleField.val(stored[0] || '');
67
- multiField.val(stored);
68
- }
69
- }
70
-
71
- function loadVariables() {
72
- const cfg = configField.val();
73
- const provider = providerField.val();
74
- if (!cfg || !provider) {
75
- populateVariables([]);
76
- return;
77
- }
78
- fetchVariables(cfg, provider).then((vars) => {
79
- const normalized = (vars || []).map(v => ({ key: v.key || v.id }));
80
- populateVariables(normalized);
81
- }).catch(() => populateVariables([]));
82
- }
83
-
84
- function loadProviders() {
85
- const node = this;
86
- const cfg = configField.val();
87
- providerField.empty();
88
- if (!cfg) {
89
- providerField.append('<option value="">-- select config first --</option>');
90
- return;
91
- }
92
- fetchProviders(cfg).then((providers) => {
93
- providerField.append('<option value="">-- choose provider --</option>');
94
- (providers || []).forEach((p) => {
95
- $('<option>').val(p.id).text(p.id).appendTo(providerField);
96
- });
97
- if (node.providerId) {
98
- providerField.val(node.providerId);
99
- }
100
- loadVariables();
101
- }).catch(() => {
102
- providerField.append('<option value="">(error loading providers)</option>');
103
- });
104
- }
105
-
106
- modeField.on('change', applyMode);
107
- providerField.on('change', loadVariables);
108
- configField.on('change', loadProviders.bind(this));
109
-
110
- applyMode();
111
- loadProviders.call(this);
15
+ const help = `
16
+ <b>DataHub Input node</b><br>
17
+ <ul>
18
+ <li><b>u-OS Config</b>: choose the config node with host and OAuth credentials.</li>
19
+ <li><b>Provider ID</b>: e.g. <code>sampleprovider</code> or <code>u_os_adm</code>.</li>
20
+ <li><b>Variables</b>: leave empty for all variables or enter comma-separated keys like <code>diagnostics.status_text,diagnostics.error_count</code>.</li>
21
+ </ul>
22
+ The node outputs messages of the form <code>{ type: 'snapshot'|'change', variables: [...] }</code>.
23
+ `;
24
+ $('#datahub-input-help').html(help);
25
+ },
26
+ label: function () {
27
+ return this.name || `Input ${this.providerId || ''}`;
112
28
  },
113
- oneditsave: function() {
114
- const mode = $('#node-input-variableMode').val();
115
- let selected = [];
116
- if (mode === 'single') {
117
- const val = $('#node-input-variableSingle').val();
118
- if (val) selected = [val];
119
- } else if (mode === 'multi') {
120
- selected = $('#node-input-variableMulti').val() || [];
121
- }
122
- $('#node-input-variables').val(JSON.stringify(selected));
29
+ labelStyle: function () {
30
+ return this.name ? 'node_label_italic' : '';
123
31
  }
124
32
  });
125
- })();
126
33
  </script>
127
34
 
128
- <input type="hidden" id="node-input-variables">
129
35
  <div class="form-row">
130
36
  <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
131
37
  <input type="text" id="node-input-name">
@@ -135,23 +41,11 @@
135
41
  <input type="text" id="node-input-connection">
136
42
  </div>
137
43
  <div class="form-row">
138
- <label for="node-input-providerId"><i class="fa fa-list"></i> Provider</label>
139
- <select id="node-input-providerId"></select>
44
+ <label for="node-input-providerId"><i class="fa fa-id-badge"></i> Provider ID</label>
45
+ <input type="text" id="node-input-providerId" placeholder="sampleprovider">
140
46
  </div>
141
47
  <div class="form-row">
142
- <label for="node-input-variableMode"><i class="fa fa-filter"></i> Variables</label>
143
- <select id="node-input-variableMode">
144
- <option value="all">All variables</option>
145
- <option value="single">Single variable</option>
146
- <option value="multi">Multi selection</option>
147
- </select>
148
- </div>
149
- <div class="form-row" id="node-input-variableSingle-container" style="display:none;">
150
- <label><i class="fa fa-bullseye"></i> Variable</label>
151
- <select id="node-input-variableSingle" style="width:100%"></select>
152
- </div>
153
- <div class="form-row" id="node-input-variableMulti-container" style="display:none;">
154
- <label><i class="fa fa-list-ul"></i> Variables</label>
155
- <select id="node-input-variableMulti" multiple size="8" style="width:100%"> </select>
48
+ <label for="node-input-variablesText"><i class="fa fa-list"></i> Variables (comma separated)</label>
49
+ <input type="text" id="node-input-variablesText" placeholder="diagnostics.status_text,diagnostics.error_count">
156
50
  </div>
157
- <p>Outputs messages with <code>{{payload.type}}</code> = <code>snapshot</code> or <code>change</code> and a <code>variables</code> array containing the selected Data Hub values.</p>
51
+ <div id="datahub-input-help" class="form-tips"></div>
@@ -27,13 +27,11 @@ module.exports = function (RED) {
27
27
  }
28
28
 
29
29
  this.providerId = config.providerId || 'sampleprovider';
30
- this.variableMode = config.variableMode || 'all';
31
- try {
32
- this.variables = JSON.parse(config.variables || '[]').map(normalizeKey).filter((k) => k);
33
- }
34
- catch (err) {
35
- this.variables = [];
36
- }
30
+ const text = config.variablesText || '';
31
+ this.variables = text
32
+ .split(',')
33
+ .map((entry) => (entry ? String(entry).trim() : ''))
34
+ .filter((entry) => entry.length > 0);
37
35
 
38
36
  let nc;
39
37
  let sub;
@@ -41,13 +39,10 @@ module.exports = function (RED) {
41
39
  const defMap = new Map();
42
40
 
43
41
  const shouldInclude = (key) => {
44
- if (this.variableMode === 'all' || !this.variables.length) {
42
+ if (!this.variables.length) {
45
43
  return true;
46
44
  }
47
45
  const needle = normalizeKey(key);
48
- if (this.variableMode === 'single') {
49
- return needle === this.variables[0];
50
- }
51
46
  return this.variables.includes(needle);
52
47
  };
53
48
 
@@ -1,7 +1,6 @@
1
1
  <script type="text/javascript">
2
- (function() {
3
2
  RED.nodes.registerType('datahub-output', {
4
- category: 'output',
3
+ category: 'DataHub-NATS',
5
4
  color: '#ff9f43',
6
5
  defaults: {
7
6
  name: { value: '' },
@@ -10,15 +9,25 @@
10
9
  },
11
10
  inputs: 1,
12
11
  outputs: 1,
13
- icon: 'white/datahub-output.svg',
14
- label: function() {
15
- return this.name || `DataHub Output ${this.providerId || ''}`;
12
+ icon: "white/datahub-output.svg",
13
+ oneditprepare: function() {
14
+ const help = `
15
+ <b>DataHub Output node</b><br>
16
+ <ul>
17
+ <li><b>u-OS Config</b>: select the config node.</li>
18
+ <li><b>Provider ID</b>: defaults to <code>nodered</code> (will be registered automatically).</li>
19
+ </ul>
20
+ Send any JSON payload → nested objects become dot-separated keys (e.g. <code>{ diagnostics: { status_text: 'ok' } }</code> ⇢ <code>diagnostics.status_text</code>).
21
+ `;
22
+ $('#datahub-output-help').html(help);
16
23
  },
17
- labelStyle: function() {
24
+ label: function () {
25
+ return this.name || `Output ${this.providerId || ''}`;
26
+ },
27
+ labelStyle: function () {
18
28
  return this.name ? 'node_label_italic' : '';
19
29
  }
20
30
  });
21
- })();
22
31
  </script>
23
32
 
24
33
  <div class="form-row">
@@ -33,4 +42,4 @@
33
42
  <label for="node-input-providerId"><i class="fa fa-id-badge"></i> Provider ID</label>
34
43
  <input type="text" id="node-input-providerId" placeholder="nodered">
35
44
  </div>
36
- <p>Send JSON payloads (including nested structures). The node auto-registers variables based on the object keys and publishes them to the configured provider. Nested objects become dot-separated keys (e.g. <code>folder.status</code>).</p>
45
+ <div id="datahub-output-help" class="form-tips"></div>
package/package.json CHANGED
@@ -1,7 +1,15 @@
1
1
  {
2
2
  "name": "node-red-contrib-uos-nats",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Node-RED nodes for u-OS Data Hub via NATS",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/uiff/nats-NodeRed-Node-uc20.git"
8
+ },
9
+ "homepage": "https://github.com/uiff/nats-NodeRed-Node-uc20",
10
+ "bugs": {
11
+ "url": "https://github.com/uiff/nats-NodeRed-Node-uc20/issues"
12
+ },
5
13
  "license": "MIT",
6
14
  "main": "nodes/uos-provider.js",
7
15
  "keywords": [