node-red-contrib-uos-nats 0.2.8 → 0.2.10

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/lib/payloads.js CHANGED
@@ -89,6 +89,8 @@ export function encodeWriteVariablesCommand(variables) {
89
89
  varT.timestamp = nowNs();
90
90
 
91
91
  // Encode value based on type
92
+ // Explicitly handle null/undefined by defaulting to safe empty values based on type
93
+ // This prevents "Field 6 must be set" error
92
94
  const val = v.value;
93
95
  if (typeof val === 'boolean') {
94
96
  const boolVal = new VariableValueBooleanT();
@@ -111,7 +113,17 @@ export function encodeWriteVariablesCommand(variables) {
111
113
  varT.value = strVal;
112
114
  varT.valueType = VariableValue.String;
113
115
  } else {
114
- throw new Error(`Unsupported value type: ${typeof val}`);
116
+ // Fallback for objects/arrays: try stringify?
117
+ // Or just fail? The user reported "Unsupported value type: object" before.
118
+ // If it is an object (unexpected), we should probably fail or stringify.
119
+ try {
120
+ const strVal = new VariableValueStringT();
121
+ strVal.value = JSON.stringify(val);
122
+ varT.value = strVal;
123
+ varT.valueType = VariableValue.String;
124
+ } catch (e) {
125
+ throw new Error(`Unsupported value type: ${typeof val}`);
126
+ }
115
127
  }
116
128
 
117
129
  return varT;
@@ -229,6 +241,12 @@ function encodeVariableState(def, state) {
229
241
  } else {
230
242
  varT.timestamp = nowNs();
231
243
  }
244
+ // Field 6 (value) MUST be set if valueType is not NONE
245
+ // We default to String empty if value is null/undefined to satisfy schema if needed,
246
+ // or we must ensure valueType is handled correctly.
247
+ // However, for defining variables (initial state), value IS required properly.
248
+
249
+ // Explicitly handle null/undefined by defaulting to safe empty values based on type
232
250
  const value = state?.value;
233
251
  switch (def.dataType) {
234
252
  case 'INT64': {
@@ -254,10 +272,21 @@ function encodeVariableState(def, state) {
254
272
  }
255
273
  case 'STRING':
256
274
  default: {
257
- const strVal = new VariableValueStringT();
258
- strVal.value = (value !== null && value !== undefined) ? String(value) : '';
259
- varT.value = strVal;
260
- varT.valueType = VariableValue.String;
275
+ try {
276
+ const strVal = new VariableValueStringT();
277
+ const valStr = (value !== null && value !== undefined) ?
278
+ (typeof value === 'object' ? JSON.stringify(value) : String(value))
279
+ : '';
280
+ strVal.value = valStr;
281
+ varT.value = strVal;
282
+ varT.valueType = VariableValue.String;
283
+ } catch (e) {
284
+ // Last resort fallback
285
+ const strVal = new VariableValueStringT();
286
+ strVal.value = "";
287
+ varT.value = strVal;
288
+ varT.valueType = VariableValue.String;
289
+ }
261
290
  break;
262
291
  }
263
292
  }
@@ -12,7 +12,7 @@
12
12
  },
13
13
  inputs: 1,
14
14
  outputs: 1,
15
- icon: "white/datahub-read.svg",
15
+ icon: "datahub-read.svg",
16
16
  label: function () {
17
17
  if (this.name) return this.name;
18
18
  return "DataHub - Read";
@@ -9,7 +9,7 @@
9
9
  },
10
10
  inputs: 1,
11
11
  outputs: 1,
12
- icon: "white/datahub-provider.svg",
12
+ icon: "datahub-provider.svg",
13
13
  oneditprepare: function () { },
14
14
  label: function () {
15
15
  return this.name || `DataHub - Provider ${this.providerId || ''}`;
@@ -104,8 +104,13 @@ module.exports = function (RED) {
104
104
  const handleRead = async (payloads, msg) => {
105
105
  if (!msg.reply)
106
106
  return;
107
- const snapshot = Array.from(stateMap.values());
108
- const response = payloads.buildReadVariablesResponse(definitions, snapshot, fingerprint);
107
+
108
+ // Convert stateMap to ID-indexed Object for correct lookup in payloads.js
109
+ const stateObj = {};
110
+ for (const s of stateMap.values()) {
111
+ stateObj[s.id] = s;
112
+ }
113
+ const response = payloads.buildReadVariablesResponse(definitions, stateObj, fingerprint);
109
114
  await nc.publish(msg.reply, response);
110
115
  };
111
116
 
@@ -159,14 +164,20 @@ module.exports = function (RED) {
159
164
  quality: 'GOOD',
160
165
  };
161
166
  states.push(state);
162
- stateMap.set(def.id, state);
167
+ // states.push(state); // No longer pushing to a temporary 'states' array
168
+ stateMap.set(def.id, state); // Update the global stateMap
163
169
  });
164
170
  if (definitionsChanged) {
165
171
  await sendDefinitionUpdate(payloadsMod, subjectsMod);
166
172
  // Give Data Hub a moment to process the new definition before sending values
167
173
  await new Promise(r => setTimeout(r, 100));
168
174
  }
169
- const payload = payloadsMod.buildVariablesChangedEvent(definitions, states, fingerprint);
175
+ // Convert stateMap to Object for payload builder
176
+ const stateObj = {};
177
+ for (const s of stateMap.values()) {
178
+ stateObj[s.id] = s;
179
+ }
180
+ const payload = payloadsMod.buildVariablesChangedEvent(definitions, stateObj, fingerprint);
170
181
  await nc.publish(subjectsMod.varsChangedEvent(this.providerId), payload);
171
182
  send(msg);
172
183
  done();
@@ -11,7 +11,7 @@
11
11
  },
12
12
  inputs: 1,
13
13
  outputs: 1,
14
- icon: "white/datahub-write.svg",
14
+ icon: "datahub-write.svg",
15
15
  label: function () {
16
16
  return this.name || "DataHub - Write";
17
17
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-red-contrib-uos-nats",
3
- "version": "0.2.8",
3
+ "version": "0.2.10",
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",