@ncd-io/node-red-enterprise-sensors 2.0.1 → 2.0.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.
@@ -0,0 +1,461 @@
1
+ const { toMac, signInt, msbLsb } = require('../utils');
2
+
3
+ // --- 1. DEFINE LOCAL FUNCTIONS ---
4
+ // These are defined as local variables so they can call each other easily.
5
+ module.exports = (globalDevices) => {
6
+
7
+ const get_write_buffer_size = (firmware) => {
8
+ return 33;
9
+ };
10
+
11
+ const get_config_map = (firmware) => {
12
+ console.log('Generating sync map for firmware version', firmware);
13
+
14
+ return {
15
+ "core_version": {
16
+ "read_index": 3,
17
+ "descriptions": {
18
+ "title": "Core Version",
19
+ "main_caption": "The version of the core communication stack."
20
+ },
21
+ "validator": {
22
+ "type": "uint8"
23
+ },
24
+ "tags": [
25
+ "system"
26
+ ]
27
+ },
28
+ "firmware_version": {
29
+ "read_index": 4,
30
+ "descriptions": {
31
+ "title": "Firmware Version",
32
+ "main_caption": "The application-specific firmware version."
33
+ },
34
+ "validator": {
35
+ "type": "uint8"
36
+ },
37
+ "tags": [
38
+ "system"
39
+ ]
40
+ },
41
+ "sensor_type": {
42
+ "read_index": 5,
43
+ "descriptions": {
44
+ "title": "Sensor Type",
45
+ "main_caption": "The hardware identifier for the specific sensor model."
46
+ },
47
+ "validator": {
48
+ "type": "uint16be"
49
+ },
50
+ "tags": [
51
+ "system"
52
+ ]
53
+ },
54
+ "tx_lifetime_counter": {
55
+ "read_index": 7,
56
+ "descriptions": {
57
+ "title": "Sampling Interval",
58
+ "main_caption": "Set how often will the sensor transmit measurement data. Note: For this sensor, this value functions as the sampling interval rather than a traditional delay.",
59
+ "sub_caption": "Default value: 20 milliseconds."
60
+ },
61
+ "validator": {
62
+ "type": "uint32be"
63
+ },
64
+ "tags": [
65
+ "diagnostics"
66
+ ]
67
+ },
68
+ "hardware_id": {
69
+ "read_index": 11,
70
+ "length": 3,
71
+ "descriptions": {
72
+ "title": "Hardware ID",
73
+ "main_caption": "A unique 3-byte hardware identifier."
74
+ },
75
+ "validator": {
76
+ "type": "buffer"
77
+ },
78
+ "tags": [
79
+ "system"
80
+ ]
81
+ },
82
+ "network_id": {
83
+ "read_index": 14,
84
+ "write_index": 3,
85
+ "length": 2,
86
+ "descriptions": {
87
+ "title": "Network ID",
88
+ "main_caption": ""
89
+ },
90
+ "default_value": "7fff",
91
+ "validator": {
92
+ "type": "hex",
93
+ "length": 4
94
+ },
95
+ "html_id": "pan_id",
96
+ "tags": [
97
+ "communications"
98
+ ]
99
+ },
100
+ "destination_address": {
101
+ "read_index": 16,
102
+ "write_index": 5,
103
+ "length": 4,
104
+ "descriptions": {
105
+ "title": "Destination Address",
106
+ "main_caption": ""
107
+ },
108
+ "default_value": "0000ffff",
109
+ "validator": {
110
+ "type": "mac",
111
+ "length": 8
112
+ },
113
+ "html_id": "destination",
114
+ "tags": [
115
+ "communications"
116
+ ]
117
+ },
118
+ "node_id": {
119
+ "read_index": 20,
120
+ "write_index": 9,
121
+ "descriptions": {
122
+ "title": "Node ID",
123
+ "main_caption": ""
124
+ },
125
+ "default_value": "0",
126
+ "validator": {
127
+ "type": "uint8",
128
+ "min": 0,
129
+ "max": 255,
130
+ "generated": true
131
+ },
132
+ "html_id": "node_id",
133
+ "tags": [
134
+ "generic"
135
+ ]
136
+ },
137
+ "report_rate": {
138
+ "read_index": 21,
139
+ "write_index": 10,
140
+ "descriptions": {
141
+ "title": "Delay",
142
+ "main_caption": ""
143
+ },
144
+ "default_value": 3,
145
+ "validator": {
146
+ "type": "uint32be"
147
+ },
148
+ "html_id": "delay"
149
+ },
150
+ "fsr": {
151
+ "read_index": 25,
152
+ "write_index": 14,
153
+ "descriptions": {
154
+ "title": "Set FSR",
155
+ "main_caption": ""
156
+ },
157
+ "default_value": 0,
158
+ "validator": {
159
+ "type": "uint8",
160
+ "min": 0,
161
+ "max": 5,
162
+ "generated": true
163
+ },
164
+ "options": {
165
+ "0": "6.114",
166
+ "1": "4.096",
167
+ "2": "2.048",
168
+ "3": "1.024",
169
+ "4": "0.512",
170
+ "5": "0.256"
171
+ },
172
+ "html_id": "fsr_420ma"
173
+ },
174
+ "boot_up_time": {
175
+ "read_index": 26,
176
+ "write_index": 27,
177
+ "descriptions": {
178
+ "title": "Sensor Boot Time",
179
+ "main_caption": ""
180
+ },
181
+ "default_value": 0,
182
+ "validator": {
183
+ "type": "uint8",
184
+ "min": 0,
185
+ "max": 255
186
+ },
187
+ "html_id": "sensor_boot_time_420ma"
188
+ },
189
+ "auto_check_interval": {
190
+ "read_index": 29,
191
+ "write_index": 28,
192
+ "descriptions": {
193
+ "title": "Auto Check Interval",
194
+ "main_caption": "To disable the auto check interval feature make this setting active and use a value of 0."
195
+ },
196
+ "default_value": 60,
197
+ "validator": {
198
+ "type": "uint16be",
199
+ "min": 0,
200
+ "max": 65535
201
+ },
202
+ "html_id": "auto_check_interval_88"
203
+ },
204
+ "auto_check_threshold": {
205
+ "read_index": 31,
206
+ "write_index": 30,
207
+ "descriptions": {
208
+ "title": "Auto Check Threshold",
209
+ "main_caption": "This is a percent value. It will dictate a new transmission if the percentage change since last transmission exceeds the percentage set in this field."
210
+ },
211
+ "default_value": 20,
212
+ "validator": {
213
+ "type": "uint16be",
214
+ "min": 0,
215
+ "max": 65535
216
+ },
217
+ "html_id": "auto_check_threshold_88"
218
+ },
219
+ "always_on": {
220
+ "read_index": 33,
221
+ "write_index": 32,
222
+ "descriptions": {
223
+ "title": "Set Sensor Always On",
224
+ "main_caption": "This command will keep the external power to the sensor always enabled."
225
+ },
226
+ "default_value": 0,
227
+ "validator": {
228
+ "type": "uint8",
229
+ "min": 0,
230
+ "max": 1,
231
+ "generated": true
232
+ },
233
+ "options": {
234
+ "0": "Disable",
235
+ "1": "Enable"
236
+ },
237
+ "html_id": "always_on_420ma"
238
+ },
239
+ "calibration_one": {
240
+ "read_index": 34,
241
+ "write_index": 15,
242
+ "descriptions": {
243
+ "title": "Low Calibration Point",
244
+ "main_caption": ""
245
+ },
246
+ "default_value": 68805,
247
+ "validator": {
248
+ "type": "uint32be",
249
+ "min": 0,
250
+ "max": 4294967295
251
+ },
252
+ "html_id": "low_calibration_420ma"
253
+ },
254
+ "calibration_two": {
255
+ "read_index": 38,
256
+ "write_index": 19,
257
+ "descriptions": {
258
+ "title": "Mid Calibration Point",
259
+ "main_caption": ""
260
+ },
261
+ "default_value": 68724,
262
+ "validator": {
263
+ "type": "uint32be",
264
+ "min": 0,
265
+ "max": 4294967295
266
+ },
267
+ "html_id": "mid_calibration_420ma"
268
+ },
269
+ "calibration_three": {
270
+ "read_index": 42,
271
+ "write_index": 23,
272
+ "descriptions": {
273
+ "title": "High Calibration Point",
274
+ "main_caption": ""
275
+ },
276
+ "default_value": 68714,
277
+ "validator": {
278
+ "type": "uint32be",
279
+ "min": 0,
280
+ "max": 4294967295
281
+ },
282
+ "html_id": "high_calibration_420ma"
283
+ }
284
+ };
285
+ };
286
+
287
+ const sync_parse = (rep_buffer) => {
288
+ let response = {
289
+ 'human_readable': {},
290
+ 'machine_values': {}
291
+ };
292
+
293
+ // Get the map based on the sensor type byte
294
+ const sync_map = get_config_map(rep_buffer[4]);
295
+
296
+ for (const [key, config] of Object.entries(sync_map)) {
297
+ // Destructure 'type' from inside 'validator' and rename 'read_index' to 'idx'
298
+ const { read_index: idx, length, validator: { type } = {}, converter, options } = config;
299
+
300
+ // If for some reason a config doesn't have a validator/type, skip it
301
+ if (!type) continue;
302
+
303
+ switch (type) {
304
+ case 'uint8':
305
+ response.machine_values[key] = rep_buffer[idx];
306
+ break;
307
+ case 'uint16be':
308
+ response.machine_values[key] = rep_buffer.readUInt16BE(idx);
309
+ break;
310
+ case 'uint32be':
311
+ response.machine_values[key] = rep_buffer.readUInt32BE(idx);
312
+ break;
313
+ case 'buffer':
314
+ response.machine_values[key] = rep_buffer.subarray(idx, idx + length);
315
+ break;
316
+ case 'hex':
317
+ response.machine_values[key] = rep_buffer.subarray(idx, idx + length).toString('hex');
318
+ break;
319
+ case 'mac':
320
+ response.machine_values[key] = rep_buffer.subarray(idx, idx + length).toString('hex');
321
+ break;
322
+ }
323
+ let human_value = response.machine_values[key];
324
+ if(options && options[response.machine_values[key]]){
325
+ human_value = options[response.machine_values[key]];
326
+ }else{
327
+ if(converter && converter.multiplier){
328
+ human_value = human_value * converter.multiplier;
329
+ }
330
+ if(converter && converter.units){
331
+ human_value = human_value + converter.units;
332
+ }
333
+ }
334
+ response.human_readable[key] = human_value;
335
+ }
336
+ if (Object.hasOwn(response.machine_values, 'destination_address') && response.machine_values.destination_address.toLowerCase() === '00000000') {
337
+ console.log('##############################');
338
+ console.log('#########Dest Override########');
339
+ console.log('##############################');
340
+ response.destination_address = "0000ffff";
341
+ // response.auto_raw_destination_address = "0000ffff";
342
+ };
343
+ return response;
344
+ };
345
+
346
+ const parse_fly = (frame) => {
347
+ let frame_data = {};
348
+ switch(frame[16]){
349
+ case 0:
350
+ frame_data.fsr = "+-6.114 V";
351
+ break;
352
+ case 1:
353
+ frame_data.fsr = "+-4.096 V";
354
+ break;
355
+ case 2:
356
+ frame_data.fsr = "+-2.048 V";
357
+ break;
358
+ case 3:
359
+ frame_data.fsr = "+-1.024 V";
360
+ break;
361
+ case 4:
362
+ frame_data.fsr = "+-0.512 V";
363
+ break;
364
+ case 5:
365
+ frame_data.fsr = "+-0.256 V";
366
+ break;
367
+ }
368
+ if(frame[2]>13){ // firmware 14 and above
369
+ let auto_check_interval = frame.slice(20, 22).reduce(msbLsb);
370
+ if(!auto_check_interval){
371
+ frame_data.auto_check_interval = 'Disabled';
372
+ }else{
373
+ frame_data.auto_check_interval = auto_check_interval + " sec";
374
+ }
375
+ return {
376
+ 'firmware': frame[2],
377
+ 'fsr': frame_data.fsr,
378
+ 'boot_up_time': frame[17] + " sec",
379
+ 'adc_pin_reading': frame.slice(18, 20).reduce(msbLsb),
380
+ 'auto_check_interval': frame_data.auto_check_interval,
381
+ 'auto_check_threshold': frame.slice(22, 24).reduce(msbLsb),
382
+ 'always_on': frame_data[24] ? 'Enabled' : 'Disabled',
383
+ 'calibration_one': frame.slice(25, 29).reduce(msbLsb),
384
+ 'calibration_two':frame.slice(29, 33).reduce(msbLsb),
385
+ 'calibration_three':frame.slice(33, 37).reduce(msbLsb),
386
+ 'hardware_id': frame.slice(37, 40),
387
+ 'report_rate': frame.slice(40, 44).reduce(msbLsb) + " sec",
388
+ 'tx_life_counter': frame.slice(44, 48).reduce(msbLsb),
389
+ 'machine_values': {
390
+ 'firmware': frame[2],
391
+ 'fsr': frame[16],
392
+ 'boot_up_time': frame[17],
393
+ 'adc_pin_reading': frame.slice(18, 20),
394
+ 'auto_check_interval': frame.slice(20, 22),
395
+ 'auto_check_percentage': frame.slice(22, 24),
396
+ 'always_on': frame[24],
397
+ 'calibration_one': frame.slice(25, 29),
398
+ 'calibration_two':frame.slice(29, 33),
399
+ 'calibration_three':frame.slice(33, 37),
400
+ 'hardware_id': frame.slice(37, 40),
401
+ 'report_rate': frame.slice(40, 44),
402
+ 'tx_life_counter': frame.slice(44, 48)
403
+ }
404
+ }
405
+ }else if(frame[2]>12){
406
+ return {
407
+ 'firmware': frame[2],
408
+ 'report_rate': frame.slice(12, 16).reduce(msbLsb),
409
+ 'fsr':frame_data.fsr,
410
+ 'boot_up_time': frame[17],
411
+ 'adc_pin_reading': frame.slice(18, 20).reduce(msbLsb),
412
+ 'machine_values': {
413
+ 'firmware': frame[2],
414
+ 'report_rate': frame.slice(12, 16),
415
+ 'fsr':frame[16],
416
+ 'boot_up_time': frame[17],
417
+ 'adc_pin_reading': frame.slice(18, 20),
418
+ 'frame': frame
419
+ }
420
+ }
421
+ }else{
422
+ return {
423
+ 'firmware': frame[2],
424
+ 'report_rate': frame.slice(12, 16).reduce(msbLsb),
425
+ 'fsr':frame_data.fsr,
426
+ 'boot_up_time': frame[17],
427
+ 'machine_values': {
428
+ 'firmware': frame[2],
429
+ 'report_rate': frame.slice(12, 16),
430
+ 'fsr':frame[16],
431
+ 'boot_up_time': frame[17],
432
+ 'frame': frame
433
+ }
434
+ }
435
+ }
436
+ };
437
+
438
+ const parse = (d) => {
439
+ var adc1 = signInt(d.slice(0, 2).reduce(msbLsb));
440
+ var adc2 = signInt(d.slice(2, 4).reduce(msbLsb));
441
+ return {
442
+ adc1: adc1,
443
+ adc2: adc2,
444
+ mA1: signInt(d.slice(4, 6).reduce(msbLsb))/100,
445
+ mA2: signInt(d.slice(6, 8).reduce(msbLsb))/100
446
+ };
447
+ };
448
+
449
+ // --- 2. EXPORT THE MODULE ---
450
+ // Export the module with all the necessary functions and properties
451
+ // that need to be called from outside the scrip
452
+ return {
453
+ type: 122,
454
+ name: 'Wireless 4-20mA Current Splitter',
455
+ parse,
456
+ get_write_buffer_size,
457
+ get_config_map,
458
+ sync_parse,
459
+ parse_fly
460
+ };
461
+ };
@@ -582,7 +582,7 @@ module.exports = (globalDevices) => {
582
582
  console.log('#########Dest Override########');
583
583
  console.log('##############################');
584
584
  response.destination_address = "0000ffff";
585
- response.auto_raw_destination_address = "0000ffff";
585
+ //response.auto_raw_destination_address = "0000ffff";
586
586
  };
587
587
  return response;
588
588
  };
@@ -643,7 +643,7 @@ module.exports = (globalDevices) => {
643
643
  console.log('#########Dest Override########');
644
644
  console.log('##############################');
645
645
  response.destination_address = "0000ffff";
646
- response.auto_raw_destination_address = "0000ffff";
646
+ //response.auto_raw_destination_address = "0000ffff";
647
647
  };
648
648
  return response;
649
649
  };
@@ -255,7 +255,7 @@ module.exports = (globalDevices) => {
255
255
  console.log('#########Dest Override########');
256
256
  console.log('##############################');
257
257
  response.destination_address = "0000ffff";
258
- response.auto_raw_destination_address = "0000ffff";
258
+ // response.auto_raw_destination_address = "0000ffff";
259
259
  };
260
260
  return response;
261
261
  };