@ncd-io/node-red-enterprise-sensors 2.0.3 → 2.0.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.
@@ -0,0 +1,454 @@
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 32;
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
+ "adc_pin_reading": {
151
+ "read_index": 25,
152
+ "validator": {
153
+ "type": "uint16be"
154
+ },
155
+ "tags": [
156
+ "diagnostics"
157
+ ]
158
+ },
159
+ "fsr": {
160
+ "read_index": 27,
161
+ "write_index": 14,
162
+ "descriptions": {
163
+ "title": "Set FSR",
164
+ "main_caption": ""
165
+ },
166
+ "default_value": 3,
167
+ "validator": {
168
+ "type": "uint8",
169
+ "min": 0,
170
+ "max": 5,
171
+ "generated": true
172
+ },
173
+ "options": {
174
+ "0": "6.114",
175
+ "1": "4.096",
176
+ "2": "2.048",
177
+ "3": "1.024",
178
+ "4": "0.512",
179
+ "5": "0.256"
180
+ },
181
+ "html_id": "fsr_420ma"
182
+ },
183
+ "calibration_one": {
184
+ "read_index": 28,
185
+ "write_index": 15,
186
+ "descriptions": {
187
+ "title": "Low Calibration Point",
188
+ "main_caption": ""
189
+ },
190
+ "default_value": 68805,
191
+ "validator": {
192
+ "type": "uint32be",
193
+ "min": 0,
194
+ "max": 4294967295
195
+ },
196
+ "html_id": "low_calibration_420ma"
197
+ },
198
+ "calibration_two": {
199
+ "read_index": 32,
200
+ "write_index": 19,
201
+ "descriptions": {
202
+ "title": "Mid Calibration Point",
203
+ "main_caption": ""
204
+ },
205
+ "default_value": 68724,
206
+ "validator": {
207
+ "type": "uint32be",
208
+ "min": 0,
209
+ "max": 4294967295
210
+ },
211
+ "html_id": "mid_calibration_420ma"
212
+ },
213
+ "calibration_three": {
214
+ "read_index": 36,
215
+ "write_index": 23,
216
+ "descriptions": {
217
+ "title": "High Calibration Point",
218
+ "main_caption": ""
219
+ },
220
+ "default_value": 68714,
221
+ "validator": {
222
+ "type": "uint32be",
223
+ "min": 0,
224
+ "max": 4294967295
225
+ },
226
+ "html_id": "high_calibration_420ma"
227
+ },
228
+ "boot_up_time": {
229
+ "read_index": 40,
230
+ "write_index": 27,
231
+ "descriptions": {
232
+ "title": "Sensor Boot Time",
233
+ "main_caption": ""
234
+ },
235
+ "default_value": 8,
236
+ "validator": {
237
+ "type": "uint8",
238
+ "min": 0,
239
+ "max": 255
240
+ },
241
+ "html_id": "sensor_boot_time_420ma"
242
+ },
243
+ "always_on": {
244
+ "read_index": 41,
245
+ "write_index": 28,
246
+ "descriptions": {
247
+ "title": "Set Sensor Always On",
248
+ "main_caption": "This command will keep the external power to the sensor always enabled."
249
+ },
250
+ "default_value": 0,
251
+ "validator": {
252
+ "type": "uint8",
253
+ "min": 0,
254
+ "max": 1,
255
+ "generated": true
256
+ },
257
+ "options": {
258
+ "0": "Disable",
259
+ "1": "Enable"
260
+ },
261
+ "html_id": "always_on_420ma"
262
+ },
263
+ "friction_noise_level": {
264
+ "read_index": 42,
265
+ "write_index": 29,
266
+ "descriptions": {
267
+ "title": "Set Friction Noise Level",
268
+ "main_caption": ""
269
+ },
270
+ "default_value": 35,
271
+ "validator": {
272
+ "type": "uint8",
273
+ "min": 1,
274
+ "max": 255
275
+ },
276
+ "html_id": "friction_level_105"
277
+ },
278
+ "faulty_noise_level": {
279
+ "read_index": 43,
280
+ "write_index": 30,
281
+ "descriptions": {
282
+ "title": "Set Faulty Noise Level",
283
+ "main_caption": ""
284
+ },
285
+ "default_value": 45,
286
+ "validator": {
287
+ "type": "uint8",
288
+ "min": 0,
289
+ "max": 255
290
+ },
291
+ "html_id": "faulty_level_105"
292
+ },
293
+ "lube_1_on_time": {
294
+ "read_index": 44,
295
+ "write_index": 31,
296
+ "descriptions": {
297
+ "title": "Set Lube On Time 1",
298
+ "main_caption": ""
299
+ },
300
+ "default_value": 10,
301
+ "validator": {
302
+ "type": "uint8",
303
+ "min": 0,
304
+ "max": 255
305
+ },
306
+ "html_id": "lube_on_time_1_105"
307
+ }
308
+ };
309
+ };
310
+
311
+ const sync_parse = (rep_buffer) => {
312
+ let response = {
313
+ 'human_readable': {},
314
+ 'machine_values': {}
315
+ };
316
+
317
+ // Get the map based on the sensor type byte
318
+ const sync_map = get_config_map(rep_buffer[4]);
319
+
320
+ for (const [key, config] of Object.entries(sync_map)) {
321
+ // Destructure 'type' from inside 'validator' and rename 'read_index' to 'idx'
322
+ const { read_index: idx, length, validator: { type } = {}, converter, options } = config;
323
+
324
+ // If for some reason a config doesn't have a validator/type, skip it
325
+ if (!type) continue;
326
+
327
+ switch (type) {
328
+ case 'uint8':
329
+ response.machine_values[key] = rep_buffer[idx];
330
+ break;
331
+ case 'uint16be':
332
+ response.machine_values[key] = rep_buffer.readUInt16BE(idx);
333
+ break;
334
+ case 'uint32be':
335
+ response.machine_values[key] = rep_buffer.readUInt32BE(idx);
336
+ break;
337
+ case 'buffer':
338
+ response.machine_values[key] = rep_buffer.subarray(idx, idx + length);
339
+ break;
340
+ case 'hex':
341
+ response.machine_values[key] = rep_buffer.subarray(idx, idx + length).toString('hex');
342
+ break;
343
+ case 'mac':
344
+ response.machine_values[key] = rep_buffer.subarray(idx, idx + length).toString('hex');
345
+ break;
346
+ }
347
+ let human_value = response.machine_values[key];
348
+ if(options && options[response.machine_values[key]]){
349
+ human_value = options[response.machine_values[key]];
350
+ }else{
351
+ if(converter && converter.multiplier){
352
+ human_value = human_value * converter.multiplier;
353
+ }
354
+ if(converter && converter.units){
355
+ human_value = human_value + converter.units;
356
+ }
357
+ }
358
+ response.human_readable[key] = human_value;
359
+ }
360
+ if (Object.hasOwn(response.machine_values, 'destination_address') && response.machine_values.destination_address.toLowerCase() === '00000000') {
361
+ console.log('##############################');
362
+ console.log('#########Dest Override########');
363
+ console.log('##############################');
364
+ response.destination_address = "0000ffff";
365
+ // response.auto_raw_destination_address = "0000ffff";
366
+ };
367
+ return response;
368
+ };
369
+
370
+ const parse_fly = (frame) => {
371
+ let firmware = frame[2];
372
+ if(firmware > 13){ // firmware 14 and above
373
+ let frame_data = {};
374
+ let auto_check_interval = frame.slice(20, 22).reduce(msbLsb);
375
+ if(!auto_check_interval){
376
+ frame_data.auto_check_interval = 'Disabled';
377
+ }else{
378
+ frame_data.auto_check_interval = auto_check_interval + " sec";
379
+ }
380
+ frame_data.always_on = frame[24]?"Enabled":"Disabled";
381
+ switch(frame[16]){
382
+ case 0:
383
+ frame_data.fsr = "+-6.114 V";
384
+ break;
385
+ case 1:
386
+ frame_data.fsr = "+-4.096 V";
387
+ break;
388
+ case 2:
389
+ frame_data.fsr = "+-2.048 V";
390
+ break;
391
+ case 3:
392
+ frame_data.fsr = "+-1.024 V";
393
+ break;
394
+ case 4:
395
+ frame_data.fsr = "+-0.512 V";
396
+ break;
397
+ case 5:
398
+ frame_data.fsr = "+-0.256 V";
399
+ break;
400
+ }
401
+ return {
402
+ 'firmware': frame[2],
403
+ 'fsr': frame_data.fsr,
404
+ 'boot_up_time': frame[17] + " sec",
405
+ 'adc_pin_reading': frame.slice(18, 20).reduce(msbLsb),
406
+ 'auto_check_interval': frame_data.auto_check_interval,
407
+ 'auto_check_threshold': frame.slice(22, 24).reduce(msbLsb),
408
+ 'always_on': frame_data.always_on,
409
+ 'calibration_one': frame.slice(25, 29).reduce(msbLsb),
410
+ 'calibration_two':frame.slice(29, 33).reduce(msbLsb),
411
+ 'calibration_three':frame.slice(33, 37).reduce(msbLsb),
412
+ 'hardware_id': frame.slice(37, 40),
413
+ 'report_rate': frame.slice(40, 44).reduce(msbLsb) + " sec",
414
+ 'tx_life_counter': frame.slice(44, 48).reduce(msbLsb),
415
+ 'machine_values': {
416
+ 'firmware': frame[2],
417
+ 'fsr': frame[16],
418
+ 'boot_up_time': frame[17],
419
+ 'adc_pin_reading': frame.slice(18, 20),
420
+ 'auto_check_interval': frame.slice(20, 22),
421
+ 'auto_check_percentage': frame.slice(22, 24),
422
+ 'always_on': frame[24],
423
+ 'calibration_one': frame.slice(25, 29),
424
+ 'calibration_two':frame.slice(29, 33),
425
+ 'calibration_three':frame.slice(33, 37),
426
+ 'hardware_id': frame.slice(37, 40),
427
+ 'report_rate': frame.slice(40, 44),
428
+ 'tx_life_counter': frame.slice(44, 48)
429
+ }
430
+ }
431
+ }
432
+ };
433
+
434
+ const parse = (d) => {
435
+ return {
436
+ raw_adc: d.slice(0, 2).reduce(msbLsb),
437
+ ma: d.slice(2, 4).reduce(msbLsb) / 100,
438
+ db: d.slice(4, 6).reduce(msbLsb) / 100
439
+ };
440
+ };
441
+
442
+ // --- 2. EXPORT THE MODULE ---
443
+ // Export the module with all the necessary functions and properties
444
+ // that need to be called from outside the scrip
445
+ return {
446
+ type: 105,
447
+ name: '1 Channel Automatic Luber With Ultrasound Vibration Sensor',
448
+ parse,
449
+ get_write_buffer_size,
450
+ get_config_map,
451
+ sync_parse,
452
+ parse_fly
453
+ };
454
+ };