node-red-contrib-uos-nats 0.2.2 → 0.2.4
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/nodes/datahub-write.js +56 -41
- package/package.json +1 -1
package/nodes/datahub-write.js
CHANGED
|
@@ -1,56 +1,58 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const { pathToFileURL } = require('url');
|
|
3
|
+
|
|
4
|
+
const payloadModuleUrl = pathToFileURL(path.join(__dirname, '..', 'lib', 'payloads.js')).href;
|
|
3
5
|
|
|
4
6
|
// Simple cache for provider definitions (5 min TTL)
|
|
5
7
|
const providerCache = new Map();
|
|
6
8
|
const CACHE_TTL = 5 * 60 * 1000; // 5 minutes
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
10
|
+
module.exports = function (RED) {
|
|
11
|
+
async function resolveVariableKey(nc, providerId, key, node, payloads) {
|
|
12
|
+
const cacheKey = `${providerId}`;
|
|
13
|
+
const cached = providerCache.get(cacheKey);
|
|
14
|
+
|
|
15
|
+
// Check cache
|
|
16
|
+
if (cached && (Date.now() - cached.timestamp < CACHE_TTL)) {
|
|
17
|
+
const variable = cached.definition.variables.find(v => v.key === key);
|
|
18
|
+
if (variable) {
|
|
19
|
+
node.debug && node.debug(`Key '${key}' resolved to ID ${variable.id} (cached)`);
|
|
20
|
+
return variable.id;
|
|
21
|
+
}
|
|
18
22
|
}
|
|
19
|
-
}
|
|
20
23
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
// Query provider definition
|
|
25
|
+
try {
|
|
26
|
+
const query = payloads.buildReadProviderDefinitionQuery();
|
|
27
|
+
const subject = `v1.loc.${providerId}.def.query`;
|
|
25
28
|
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
const response = await nc.request(subject, query, { timeout: 3000 });
|
|
30
|
+
const definition = payloads.decodeProviderDefinition(response.data);
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
if (!definition) {
|
|
33
|
+
throw new Error(`Provider ${providerId} not found or no definition returned`);
|
|
34
|
+
}
|
|
32
35
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
// Cache the definition
|
|
37
|
+
providerCache.set(cacheKey, {
|
|
38
|
+
definition,
|
|
39
|
+
timestamp: Date.now()
|
|
40
|
+
});
|
|
38
41
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
// Find variable by key
|
|
43
|
+
const variable = definition.variables.find(v => v.key === key);
|
|
44
|
+
if (!variable) {
|
|
45
|
+
throw new Error(`Variable key '${key}' not found in provider ${providerId}`);
|
|
46
|
+
}
|
|
44
47
|
|
|
45
|
-
|
|
46
|
-
|
|
48
|
+
node.debug && node.debug(`Key '${key}' resolved to ID ${variable.id}`);
|
|
49
|
+
return variable.id;
|
|
47
50
|
|
|
48
|
-
|
|
49
|
-
|
|
51
|
+
} catch (err) {
|
|
52
|
+
throw new Error(`Failed to resolve key '${key}': ${err.message}`);
|
|
53
|
+
}
|
|
50
54
|
}
|
|
51
|
-
}
|
|
52
55
|
|
|
53
|
-
export default function (RED) {
|
|
54
56
|
function DataHubWriteNode(config) {
|
|
55
57
|
RED.nodes.createNode(this, config);
|
|
56
58
|
const node = this;
|
|
@@ -68,6 +70,7 @@ export default function (RED) {
|
|
|
68
70
|
this.variableId = config.variableId ? parseInt(config.variableId, 10) : null;
|
|
69
71
|
this.variableKey = config.variableKey?.trim();
|
|
70
72
|
this.resolvedId = null; // Cached resolved ID
|
|
73
|
+
this.payloads = null; // Will be loaded dynamically
|
|
71
74
|
|
|
72
75
|
if (!this.providerId) {
|
|
73
76
|
node.error('Provider ID is required');
|
|
@@ -95,6 +98,13 @@ export default function (RED) {
|
|
|
95
98
|
return;
|
|
96
99
|
}
|
|
97
100
|
|
|
101
|
+
// Load payloads module dynamically
|
|
102
|
+
import(payloadModuleUrl).then(payloads => {
|
|
103
|
+
node.payloads = payloads;
|
|
104
|
+
}).catch(err => {
|
|
105
|
+
node.error(`Failed to load payloads module: ${err.message}`);
|
|
106
|
+
});
|
|
107
|
+
|
|
98
108
|
// Handle incoming messages
|
|
99
109
|
node.on('input', async function (msg) {
|
|
100
110
|
const value = msg.payload;
|
|
@@ -104,6 +114,11 @@ export default function (RED) {
|
|
|
104
114
|
return;
|
|
105
115
|
}
|
|
106
116
|
|
|
117
|
+
if (!node.payloads) {
|
|
118
|
+
node.error('Payloads module not loaded yet');
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
107
122
|
try {
|
|
108
123
|
// Get NATS connection from config node
|
|
109
124
|
const nc = await configNode.acquire();
|
|
@@ -117,13 +132,13 @@ export default function (RED) {
|
|
|
117
132
|
let varId = node.resolvedId;
|
|
118
133
|
if (!varId && node.variableKey) {
|
|
119
134
|
node.status({ fill: 'yellow', shape: 'dot', text: 'resolving key...' });
|
|
120
|
-
varId = await resolveVariableKey(nc, node.providerId, node.variableKey, node);
|
|
135
|
+
varId = await resolveVariableKey(nc, node.providerId, node.variableKey, node, node.payloads);
|
|
121
136
|
node.resolvedId = varId; // Cache for future messages
|
|
122
137
|
node.status({ fill: 'green', shape: 'ring', text: 'ready' });
|
|
123
138
|
}
|
|
124
139
|
|
|
125
140
|
// Build write command
|
|
126
|
-
const writeCommand = encodeWriteVariablesCommand([
|
|
141
|
+
const writeCommand = node.payloads.encodeWriteVariablesCommand([
|
|
127
142
|
{
|
|
128
143
|
id: varId,
|
|
129
144
|
value: value
|
|
@@ -161,4 +176,4 @@ export default function (RED) {
|
|
|
161
176
|
}
|
|
162
177
|
|
|
163
178
|
RED.nodes.registerType('datahub-write', DataHubWriteNode);
|
|
164
|
-
}
|
|
179
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-red-contrib-uos-nats",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "Node-RED nodes for Weidmüller u-OS Data Hub. Read, write, and provide variables via NATS protocol with OAuth2 authentication. Features: Variable Key resolution, custom icons, example flows, and provider definition caching.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "IoTUeli",
|