@ncd-io/node-red-enterprise-sensors 2.0.0 → 2.0.2

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,1623 @@
1
+ const { toMac, signInt, msbLsb } = require('../utils');
2
+
3
+ module.exports = (globalDevices, emitter) => {
4
+
5
+ const clear_globalDevices_stream = (deviceAddr, probe) => {
6
+ if (Object.hasOwn(globalDevices, deviceAddr) && Object.hasOwn(globalDevices[deviceAddr], probe)){
7
+ if (Object.hasOwn(globalDevices[deviceAddr][probe], 'packet_stream_timeout')) {
8
+ clearTimeout(globalDevices[deviceAddr][probe].packet_stream_timeout);
9
+ }
10
+ delete globalDevices[deviceAddr][probe];
11
+ }
12
+ };
13
+
14
+ const init_globalDevices_stream = (deviceAddr, payload, expected_packets, parsed, msg_type, probe) => {
15
+ globalDevices[deviceAddr][probe] = {
16
+ data: {},
17
+ odr: msbLsb(payload[9], payload[10]),
18
+ mo: payload[8],
19
+ fsr: payload[11] >> 5,
20
+ hour: payload[12],
21
+ minute: payload[13],
22
+ temperature: msbLsb(payload[14], payload[15]) / 100,
23
+ expected_packets: expected_packets
24
+ };
25
+ globalDevices[deviceAddr][probe].packet_stream_timeout = setTimeout(() => {
26
+ // Calling sibling function directly
27
+ parsed.sensor_data = concat_fft_data(deviceAddr, payload[8], msg_type, probe);
28
+ parsed.sensor_data.error = 'Time Series Data Stream Timeout - incomplete data received';
29
+
30
+ emitter.emit('sensor_data', parsed);
31
+ emitter.emit('sensor_data-111', parsed);
32
+ emitter.emit('sensor_data' + '-' + deviceAddr, parsed);
33
+ }, 60000);
34
+ };
35
+
36
+ const concat_fft_data = (deviceAddr, mode, msg_type, probe) => {
37
+ var raw_data = new Array();
38
+ for (const packet in globalDevices[deviceAddr][probe].data) {
39
+ raw_data = raw_data.concat(globalDevices[deviceAddr][probe].data[packet]);
40
+ }
41
+ var label = 0;
42
+ var fft_concat = { x: [], y: [], z: [] };
43
+
44
+ var en_axis_data = {};
45
+ en_axis_data.x_offset = 0;
46
+ en_axis_data.y_offset = 2;
47
+ en_axis_data.z_offset = 4;
48
+ en_axis_data.increment = 6;
49
+
50
+ var fsr_mult = .00006;
51
+ var fsr_text = "";
52
+
53
+ switch (globalDevices[deviceAddr][probe].fsr) {
54
+ case 0: fsr_mult = 0.00006; break;
55
+ case 1: fsr_mult = 0.00012; break;
56
+ case 2: fsr_mult = 0.00024; break;
57
+ case 3: fsr_mult = 0.00049; break;
58
+ }
59
+ switch (globalDevices[deviceAddr][probe].fsr) {
60
+ case 0: fsr_text = "2g"; break;
61
+ case 1: fsr_text = "4g"; break;
62
+ case 2: fsr_text = "8g"; break;
63
+ case 3: fsr_text = "16g"; break;
64
+ }
65
+
66
+ for (var i = 0; i < raw_data.length; i += en_axis_data.increment) {
67
+ label++;
68
+ if ('x_offset' in en_axis_data) {
69
+ fft_concat.x.push(parseFloat((signInt(((raw_data[i + en_axis_data.x_offset] << 8) + (raw_data[i + en_axis_data.x_offset + 1])), 16) * fsr_mult).toFixed(3)));
70
+ }
71
+ if ('y_offset' in en_axis_data) {
72
+ fft_concat.y.push(parseFloat((signInt(((raw_data[i + en_axis_data.y_offset] << 8) + (raw_data[i + en_axis_data.y_offset + 1])), 16) * fsr_mult).toFixed(3)));
73
+ }
74
+ if ('z_offset' in en_axis_data) {
75
+ fft_concat.z.push(parseFloat((signInt(((raw_data[i + en_axis_data.z_offset] << 8) + (raw_data[i + en_axis_data.z_offset + 1])), 16) * fsr_mult).toFixed(3)));
76
+ }
77
+ }
78
+ var fft_concat_obj = {
79
+ mode: mode,
80
+ msg_type: msg_type,
81
+ probe: probe,
82
+ time_id: [
83
+ String(globalDevices[deviceAddr][probe].hour).padStart(2, '0'),
84
+ String(globalDevices[deviceAddr][probe].minute).padStart(2, '0'),
85
+ ].join(':'),
86
+ mac_address: deviceAddr,
87
+ fsr: fsr_text,
88
+ odr: globalDevices[deviceAddr][probe].odr,
89
+ temperature: globalDevices[deviceAddr][probe].temperature,
90
+ total_samples: label,
91
+ fft_confidence: ((Object.keys(globalDevices[deviceAddr][probe].data).length / globalDevices[deviceAddr][probe].expected_packets) * 100).toFixed(2) + '%',
92
+ data: fft_concat
93
+ };
94
+ return fft_concat_obj;
95
+ };
96
+
97
+ const get_write_buffer_size = (firmware) => {
98
+ return 49;
99
+ };
100
+
101
+ const get_config_map = (firmware) => {
102
+ console.log('Generating sync map for firmware version', firmware);
103
+
104
+ return {
105
+ "core_version": {
106
+ "read_index": 3,
107
+ "descriptions": {
108
+ "title": "Core Version",
109
+ "main_caption": "The version of the core communication stack."
110
+ },
111
+ "validator": {
112
+ "type": "uint8"
113
+ },
114
+ "tags": [
115
+ "system"
116
+ ]
117
+ },
118
+ "firmware_version": {
119
+ "read_index": 4,
120
+ "descriptions": {
121
+ "title": "Firmware Version",
122
+ "main_caption": "The application-specific firmware version."
123
+ },
124
+ "validator": {
125
+ "type": "uint8"
126
+ },
127
+ "tags": [
128
+ "system"
129
+ ],
130
+ "old_fly_id": "firmware"
131
+ },
132
+ "sensor_type": {
133
+ "read_index": 5,
134
+ "descriptions": {
135
+ "title": "Sensor Type",
136
+ "main_caption": "The hardware identifier for the specific sensor model."
137
+ },
138
+ "validator": {
139
+ "type": "uint16be"
140
+ },
141
+ "tags": [
142
+ "system"
143
+ ]
144
+ },
145
+ "tx_lifetime_counter": {
146
+ "read_index": 7,
147
+ "descriptions": {
148
+ "title": "Transmission Lifetime Counter",
149
+ "main_caption": "Total number of transmissions since the device was manufactured."
150
+ },
151
+ "validator": {
152
+ "type": "uint32be"
153
+ },
154
+ "tags": [
155
+ "diagnostics"
156
+ ]
157
+ },
158
+ "hardware_id": {
159
+ "read_index": 11,
160
+ "length": 3,
161
+ "descriptions": {
162
+ "title": "Hardware ID",
163
+ "main_caption": "A unique 3-byte hardware identifier."
164
+ },
165
+ "validator": {
166
+ "type": "buffer"
167
+ },
168
+ "tags": [
169
+ "system"
170
+ ]
171
+ },
172
+ "network_id": {
173
+ "read_index": 14,
174
+ "write_index": 3,
175
+ "length": 2,
176
+ "descriptions": {
177
+ "title": "Network ID",
178
+ "main_caption": ""
179
+ },
180
+ "default_value": "7fff",
181
+ "validator": {
182
+ "type": "hex",
183
+ "length": 4
184
+ },
185
+ "html_id": "pan_id",
186
+ "tags": [
187
+ "Communications"
188
+ ]
189
+ },
190
+ "destination_address": {
191
+ "read_index": 16,
192
+ "write_index": 5,
193
+ "length": 4,
194
+ "descriptions": {
195
+ "title": "Destination Address",
196
+ "main_caption": ""
197
+ },
198
+ "default_value": "0000ffff",
199
+ "validator": {
200
+ "type": "mac",
201
+ "length": 8
202
+ },
203
+ "html_id": "destination",
204
+ "tags": [
205
+ "Communications"
206
+ ]
207
+ },
208
+ "node_id": {
209
+ "read_index": 20,
210
+ "write_index": 9,
211
+ "descriptions": {
212
+ "title": "Node ID",
213
+ "main_caption": ""
214
+ },
215
+ "default_value": "0",
216
+ "validator": {
217
+ "type": "uint8",
218
+ "min": 0,
219
+ "max": 255,
220
+ "generated": true
221
+ },
222
+ "html_id": "node_id",
223
+ "tags": [
224
+ "generic"
225
+ ],
226
+ "tags": [
227
+ "Communications"
228
+ ]
229
+ },
230
+ "odr_1": {
231
+ "read_index": 21,
232
+ "write_index": 10,
233
+ "descriptions": {
234
+ "title": "Probe 1: Output Data Rate",
235
+ "main_caption": "<p>This would determine how many samples the output data has...</p>"
236
+ },
237
+ "default_value": 0,
238
+ "validator": {
239
+ "type": "uint8",
240
+ "min": 7,
241
+ "max": 15,
242
+ "generated": true
243
+ },
244
+ "options": {
245
+ "7": "100Hz",
246
+ "8": "200Hz",
247
+ "9": "400Hz",
248
+ "10": "800Hz",
249
+ "11": "1600Hz",
250
+ "12": "3200Hz",
251
+ "13": "6400Hz",
252
+ "14": "12800Hz",
253
+ "15": "25600Hz"
254
+ },
255
+ "tags": [
256
+ "Vibration Sampling"
257
+ ],
258
+ "html_id": "odr_p1_110"
259
+ },
260
+ "odr_2": {
261
+ "read_index": 22,
262
+ "write_index": 11,
263
+ "descriptions": {
264
+ "title": "Probe 2: Output Data Rate",
265
+ "main_caption": "<p>This would determine how many samples the output data has...</p>"
266
+ },
267
+ "default_value": 0,
268
+ "validator": {
269
+ "type": "uint8",
270
+ "min": 7,
271
+ "max": 15,
272
+ "generated": true
273
+ },
274
+ "options": {
275
+ "7": "100Hz",
276
+ "8": "200Hz",
277
+ "9": "400Hz",
278
+ "10": "800Hz",
279
+ "11": "1600Hz",
280
+ "12": "3200Hz",
281
+ "13": "6400Hz",
282
+ "14": "12800Hz",
283
+ "15": "25600Hz"
284
+ },
285
+ "tags": [
286
+ "Vibration Sampling"
287
+ ],
288
+ "html_id": "odr_p2_110"
289
+ },
290
+ "sampling_duration_1": {
291
+ "read_index": 23,
292
+ "write_index": 12,
293
+ "descriptions": {
294
+ "title": "Probe 1: Sampling Duration",
295
+ "main_caption": "<p>Set the amount of time which the samples are taken...</p>"
296
+ },
297
+ "default_value": 1,
298
+ "validator": {
299
+ "type": "uint8",
300
+ "min": 1,
301
+ "max": 100,
302
+ "generated": true
303
+ },
304
+ "tags": [
305
+ "Vibration Sampling"
306
+ ],
307
+ "html_id": "sampling_duration_p1_110"
308
+ },
309
+ "sampling_duration_2": {
310
+ "read_index": 24,
311
+ "write_index": 13,
312
+ "descriptions": {
313
+ "title": "Probe 2: Sampling Duration",
314
+ "main_caption": "<p>Set the amount of time which the samples are taken...</p>"
315
+ },
316
+ "default_value": 1,
317
+ "validator": {
318
+ "type": "uint8",
319
+ "min": 1,
320
+ "max": 100,
321
+ "generated": true
322
+ },
323
+ "tags": [
324
+ "Vibration Sampling"
325
+ ],
326
+ "html_id": "sampling_duration_p2_110"
327
+ },
328
+ "lpf_coefficient_1": {
329
+ "read_index": 25,
330
+ "write_index": 14,
331
+ "descriptions": {
332
+ "title": "Probe 1: Set Low Pass Filter",
333
+ "main_caption": "<p>This setting will set the LPF freq to ODR divided by Selected Value...</p>"
334
+ },
335
+ "default_value": 0,
336
+ "validator": {
337
+ "type": "uint8",
338
+ "min": 0,
339
+ "max": 9,
340
+ "generated": true
341
+ },
342
+ "options": {
343
+ "10": "2",
344
+ "0": "4",
345
+ "1": "8",
346
+ "2": "16",
347
+ "3": "32",
348
+ "4": "64",
349
+ "5": "128",
350
+ "6": "256",
351
+ "7": "512",
352
+ "8": "1024",
353
+ "9": "2048"
354
+ },
355
+ "html_id": "low_pass_filter_p1_110",
356
+ "old_fly_id": "lpf_coeff_1"
357
+
358
+ },
359
+ "lpf_coefficient_2": {
360
+ "read_index": 26,
361
+ "write_index": 15,
362
+ "descriptions": {
363
+ "title": "Probe 2: Set Low Pass Filter",
364
+ "main_caption": "<p>This setting will set the LPF freq to ODR divided by Selected Value...</p>"
365
+ },
366
+ "default_value": 0,
367
+ "validator": {
368
+ "type": "uint8",
369
+ "min": 0,
370
+ "max": 9,
371
+ "generated": true
372
+ },
373
+ "options": {
374
+ "10": "2",
375
+ "0": "4",
376
+ "1": "8",
377
+ "2": "16",
378
+ "3": "32",
379
+ "4": "64",
380
+ "5": "128",
381
+ "6": "256",
382
+ "7": "512",
383
+ "8": "1024",
384
+ "9": "2048"
385
+ },
386
+ "html_id": "low_pass_filter_p2_110",
387
+ "old_fly_id": "lpf_coeff_2"
388
+ },
389
+ "hpf_coefficient_1": {
390
+ "read_index": 27,
391
+ "write_index": 16,
392
+ "descriptions": {
393
+ "title": "Probe 1: Set High Pass Filter",
394
+ "main_caption": "<p>This setting will set the HPF freq to ODR divided by Selected Value...</p>"
395
+ },
396
+ "default_value": 0,
397
+ "validator": {
398
+ "type": "uint8",
399
+ "min": 0,
400
+ "max": 9,
401
+ "generated": true
402
+ },
403
+ "options": {
404
+ "0": "4",
405
+ "1": "8",
406
+ "2": "16",
407
+ "3": "32",
408
+ "4": "64",
409
+ "5": "128",
410
+ "6": "256",
411
+ "7": "512",
412
+ "8": "1024",
413
+ "9": "2048"
414
+ },
415
+ "html_id": "high_pass_filter_p1_110",
416
+ "old_fly_id": "hpf_coeff_1"
417
+ },
418
+ "hpf_coefficient_2": {
419
+ "read_index": 28,
420
+ "write_index": 17,
421
+ "descriptions": {
422
+ "title": "Probe 2: Set High Pass Filter",
423
+ "main_caption": "<p>This setting will set the HPF freq to ODR divided by Selected Value...</p>"
424
+ },
425
+ "default_value": 0,
426
+ "validator": {
427
+ "type": "uint8",
428
+ "min": 0,
429
+ "max": 9,
430
+ "generated": true
431
+ },
432
+ "options": {
433
+ "0": "4",
434
+ "1": "8",
435
+ "2": "16",
436
+ "3": "32",
437
+ "4": "64",
438
+ "5": "128",
439
+ "6": "256",
440
+ "7": "512",
441
+ "8": "1024",
442
+ "9": "2048"
443
+ },
444
+ "html_id": "high_pass_filter_p2_110",
445
+ "old_fly_id": "hpf_coeff_2"
446
+ },
447
+ "full_scale_range": {
448
+ "read_index": 29,
449
+ "write_index": 18,
450
+ "descriptions": {
451
+ "title": "Full Scale Range",
452
+ "main_caption": "<p>Set how large of a range the device can measure acceleration in.</p>"
453
+ },
454
+ "default_value": 1,
455
+ "validator": {
456
+ "type": "uint8",
457
+ "min": 0,
458
+ "max": 5,
459
+ "generated": true
460
+ },
461
+ "options": {
462
+ "0": "+/- 2g",
463
+ "1": "+/- 4g",
464
+ "2": "+/- 8g",
465
+ "3": "+/- 16g",
466
+ "4": "+/- 32g",
467
+ "5": "+/- 64g"
468
+ },
469
+ "tags": [
470
+ "Vibration Sampling"
471
+ ],
472
+ "html_id": "full_scale_range_101",
473
+ "old_fly_id": "fsr"
474
+ },
475
+ "axes_enabled": {
476
+ "read_index": 30,
477
+ "write_index": 19,
478
+ "descriptions": {
479
+ "title": "Axes Enabled",
480
+ "main_caption": "New Command"
481
+ },
482
+ "validator": {
483
+ "type": "uint8"
484
+ },
485
+ "read_only": true,
486
+ },
487
+ "sampling_interval": {
488
+ "read_index": 31,
489
+ "write_index": 20,
490
+ "descriptions": {
491
+ "title": "Sampling Interval",
492
+ "main_caption": "<p>Set how often will the sensor transmit measurement data.</p>"
493
+ },
494
+ "default_value": 1,
495
+ "validator": {
496
+ "type": "uint8",
497
+ "min": 0,
498
+ "max": 8,
499
+ "generated": true
500
+ },
501
+ "options": {
502
+ "0": "5 Minutes",
503
+ "1": "10 Minutes",
504
+ "2": "15 Minutes",
505
+ "3": "20 Minutes",
506
+ "4": "30 Minutes",
507
+ "5": "60 Minutes",
508
+ "6": "120 Minutes",
509
+ "7": "180 Minutes",
510
+ "8": "1 Minute"
511
+ },
512
+ "tags": [
513
+ "Communications"
514
+ ],
515
+ "html_id": "sampling_interval_110"
516
+ },
517
+ "filter_status": {
518
+ "read_index": 32,
519
+ "write_index": 21,
520
+ "descriptions": {
521
+ "title": "Set Filtering",
522
+ "main_caption": "<p>Enable/Disable built-in filters</p>"
523
+ },
524
+ "default_value": 0,
525
+ "validator": {
526
+ "type": "uint8",
527
+ "min": 0,
528
+ "max": 1,
529
+ "generated": true
530
+ },
531
+ "options": {
532
+ "0": "Enabled",
533
+ "1": "Disabled"
534
+ },
535
+ "html_id": "enable_filtering_110"
536
+ },
537
+ "operation_mode": {
538
+ "read_index": 33,
539
+ "write_index": 22,
540
+ "descriptions": {
541
+ "title": "Mode",
542
+ "main_caption": "<p>• <strong>Processed:</strong> FFT is performed...</p>"
543
+ },
544
+ "default_value": 0,
545
+ "validator": {
546
+ "type": "uint8",
547
+ "min": 0,
548
+ "max": 3,
549
+ "generated": true
550
+ },
551
+ "options": {
552
+ "0": "Processed",
553
+ "1": "Raw",
554
+ "2": "Processed + Raw on demand",
555
+ "3": "Smart"
556
+ },
557
+ "html_id": "mode_110",
558
+ "old_fly_id": "mode"
559
+ },
560
+ "measurement_mode": {
561
+ "read_index": 34,
562
+ "write_index": 23,
563
+ "descriptions": {
564
+ "title": "Measurement Mode",
565
+ "main_caption": "Changing this value does not do anything. Only give one option."
566
+ },
567
+ "validator": {
568
+ "type": "uint8"
569
+ },
570
+ "read_only": true
571
+ },
572
+ "on_request_timeout": {
573
+ "read_index": 35,
574
+ "write_index": 24,
575
+ "descriptions": {
576
+ "title": "Set On Request Timeout",
577
+ "main_caption": "<p>Set how long device will stay awake...</p>"
578
+ },
579
+ "default_value": 1,
580
+ "validator": {
581
+ "type": "uint8",
582
+ "min": 1,
583
+ "max": 10,
584
+ "generated": true
585
+ },
586
+ "depends_on": {
587
+ "operation_mode": [
588
+ 2,
589
+ 3
590
+ ]
591
+ },
592
+ "html_id": "on_request_timeout_80"
593
+ },
594
+ "deadband": {
595
+ "read_index": 36,
596
+ "write_index": 25,
597
+ "descriptions": {
598
+ "title": "Set Dead Band in mg",
599
+ "main_caption": "<p>Filters out acceleration values below the dead band threshold...</p>"
600
+ },
601
+ "default_value": 0,
602
+ "validator": {
603
+ "type": "uint8",
604
+ "min": 0,
605
+ "max": 255,
606
+ "generated": true
607
+ },
608
+ "html_id": "deadband_80"
609
+ },
610
+ "motion_detection_threshold_probe_1": {
611
+ "read_index": 37,
612
+ "write_index": 26,
613
+ "descriptions": {
614
+ "title": "Probe 1: Set Acceleration Wake/Interrupt Threshold",
615
+ "main_caption": "<div><p>Set a breakpoint for sensor to wake up...</p></div>"
616
+ },
617
+ "default_value": 0,
618
+ "validator": {
619
+ "type": "uint8",
620
+ "min": 0,
621
+ "max": 40,
622
+ "generated": true
623
+ },
624
+ "html_id": "motion_detect_threshold_p1_110"
625
+ },
626
+ "smart_mode_acc_threshold_probe_1": {
627
+ "read_index": 40,
628
+ "write_index": 29,
629
+ "descriptions": {
630
+ "title": "Probe 1: Set Smart Mode Threshold",
631
+ "main_caption": "<p>If RMS acceleration is above this in any axis...</p>"
632
+ },
633
+ "default_value": 1,
634
+ "validator": {
635
+ "type": "uint8",
636
+ "min": 1,
637
+ "max": 40
638
+ },
639
+ "depends_on": {
640
+ "operation_mode": 3
641
+ },
642
+ "html_id": "smart_threshold_110"
643
+ },
644
+ "motion_detection_threshold_probe_2": {
645
+ "read_index": 41,
646
+ "write_index": 30,
647
+ "descriptions": {
648
+ "title": "Probe 2: Set Acceleration Wake/Interrupt Threshold",
649
+ "main_caption": "<div><p>Set a breakpoint for sensor to wake up...</p></div>"
650
+ },
651
+ "default_value": 0,
652
+ "validator": {
653
+ "type": "uint8",
654
+ "min": 0,
655
+ "max": 40,
656
+ "generated": true
657
+ },
658
+ "html_id": "motion_detect_threshold_p2_110",
659
+ },
660
+ "smart_mode_acc_threshold_probe_2": {
661
+ "read_index": 44,
662
+ "write_index": 33,
663
+ "descriptions": {
664
+ "title": "Probe 2: Set Smart Mode Threshold",
665
+ "main_caption": "<p>If RMS acceleration is above this in any axis...</p>"
666
+ },
667
+ "default_value": 1,
668
+ "validator": {
669
+ "type": "uint8",
670
+ "min": 1,
671
+ "max": 40
672
+ },
673
+ "depends_on": {
674
+ "operation_mode": 3
675
+ },
676
+ "html_id": "smart_threshold_p2_110"
677
+ },
678
+ "raw_packet_length": {
679
+ "read_index": 46,
680
+ "write_index": 35,
681
+ "descriptions": {
682
+ "title": "Payload Length",
683
+ "main_caption": "<p>Set the size of the data payload...</p>",
684
+ "sub_caption": "<p class=\"caption\"><i>Note: For the 2.4GHz version you need to operate with a 55 Byte payload.</i></p>"
685
+ },
686
+ "default_value": 3,
687
+ "validator": {
688
+ "type": "uint8",
689
+ "min": 0,
690
+ "max": 3,
691
+ "generated": true
692
+ },
693
+ "options": {
694
+ "0": "55 Bytes",
695
+ "1": "100 Bytes",
696
+ "2": "150 Bytes",
697
+ "3": "180 Bytes"
698
+ },
699
+ "tags": [
700
+ "Communications"
701
+ ],
702
+ "html_id": "payload_length_80",
703
+ "old_fly_id": "payload_length"
704
+ },
705
+ "auto_raw_interval": {
706
+ "read_index": 47,
707
+ "write_index": 36,
708
+ "descriptions": {
709
+ "title": "Set Auto Raw Interval",
710
+ "main_caption": "<p>Set the Auto Time Domain (Raw) data transmission Interval...</p>",
711
+ "sub_caption": "<p class=\"caption\"><i>Note: Auto Raw Transmission is disabled by default.</i></p>"
712
+ },
713
+ "default_value": 0,
714
+ "validator": {
715
+ "type": "uint8",
716
+ "min": 0,
717
+ "max": 255,
718
+ "generated": true
719
+ },
720
+ "depends_on": {
721
+ "operation_mode": 3
722
+ },
723
+ "tags": [
724
+ "Communications"
725
+ ],
726
+ "html_id": "auto_raw_interval_110"
727
+ },
728
+ "auto_raw_destination_address": {
729
+ "read_index": 48,
730
+ "write_index": 37,
731
+ "length": 4,
732
+ "descriptions": {
733
+ "title": "Set Auto Raw Destination Address",
734
+ "main_caption": "<p>Set the address where the Auto Time Domain (Raw) data will be transmitted...</p>",
735
+ "sub_caption": "<p class=\"caption\">Default value: 0000FFFF for Broadcast Mode</p>"
736
+ },
737
+ "default_value": "0000FFFF",
738
+ "validator": {
739
+ "type": "mac",
740
+ "length": 8,
741
+ "generated": true
742
+ },
743
+ "depends_on": {
744
+ "operation_mode": 3
745
+ },
746
+ "html_id": "auto_raw_destination_110"
747
+ },
748
+ "smart_mode_skip_count": {
749
+ "read_index": 52,
750
+ "write_index": 41,
751
+ "descriptions": {
752
+ "title": "Set Smart Mode Skip Interval",
753
+ "main_caption": "<p>Sensor will skip sending data this many times if vibration is below the smart threshold.</p>"
754
+ },
755
+ "default_value": 0,
756
+ "validator": {
757
+ "type": "uint8",
758
+ "min": 0,
759
+ "max": 255,
760
+ "generated": true
761
+ },
762
+ "depends_on": {
763
+ "operation_mode": 3
764
+ },
765
+ "html_id": "smart_interval_110"
766
+ },
767
+ "sync_interval": {
768
+ "read_index": 53,
769
+ "write_index": 42,
770
+ "descriptions": {
771
+ "title": "Set FLY Interval",
772
+ "main_caption": "<p>Set the interval at which the sensor will transmit FLY packets...</p>"
773
+ },
774
+ "default_value": 60,
775
+ "validator": {
776
+ "type": "uint16be",
777
+ "min": 0,
778
+ "max": 1440,
779
+ "generated": true
780
+ },
781
+ "options": {
782
+ "60": "1 Hour",
783
+ "120": "2 Hours",
784
+ "240": "4 Hours",
785
+ "480": "8 Hours",
786
+ "720": "12 Hours",
787
+ "1080": "18 Hours",
788
+ "1440": "24 Hours"
789
+ },
790
+ "tags": [
791
+ "Communications"
792
+ ],
793
+ "html_id": "fly_interval_110"
794
+ },
795
+ "rpm_compute_status": {
796
+ "read_index": 55,
797
+ "write_index": 44,
798
+ "descriptions": {
799
+ "title": "RPM Calculate Status",
800
+ "main_caption": "<p>Enable/Disable Revolutions Per Minute Calculate Status</p>"
801
+ },
802
+ "default_value": 0,
803
+ "validator": {
804
+ "type": "uint8",
805
+ "min": 0,
806
+ "max": 1,
807
+ "generated": true
808
+ },
809
+ "options": {
810
+ "0": "Disabled",
811
+ "1": "Enabled"
812
+ },
813
+ "html_id": "enable_rpm_calculate_status_110"
814
+ },
815
+ "max_raw_samples": {
816
+ "read_index": 56,
817
+ "write_index": 45,
818
+ "descriptions": {
819
+ "title": "Set Max Raw Sample",
820
+ "main_caption": "<p>Set the maximum number of samples...</p>"
821
+ },
822
+ "default_value": 0,
823
+ "validator": {
824
+ "type": "uint16be",
825
+ "min": 1024,
826
+ "max": 8100
827
+ },
828
+ "options": {
829
+ "1024": "1024 Samples",
830
+ "2048": "2048 Samples",
831
+ "4096": "4096 Samples",
832
+ "6400": "6400 Samples",
833
+ "8100": "8100 Samples"
834
+ },
835
+ "html_id": "max_raw_sample_110",
836
+ "old_fly_id": "max_tx_raw_samples"
837
+ },
838
+ "motion_to_sampling_delay": {
839
+ "read_index": 58,
840
+ "write_index": 47,
841
+ "descriptions": {
842
+ "title": "Set Motion to Sampling Delay",
843
+ "main_caption": "<p>Once motion is detected, the sensor will wait...</p>"
844
+ },
845
+ "default_value": 100,
846
+ "validator": {
847
+ "type": "uint8",
848
+ "min": 0,
849
+ "max": 255,
850
+ "generated": true
851
+ },
852
+ "html_id": "motion_to_sampling_delay_110"
853
+ },
854
+ "max_motion_tx_per_interval": {
855
+ "read_index": 59,
856
+ "write_index": 48,
857
+ "descriptions": {
858
+ "title": "Set Max Number Motion Tx Per Interval",
859
+ "main_caption": "<p>Set Number of times it will send data due to motion triggers.</p>"
860
+ },
861
+ "default_value": 1,
862
+ "validator": {
863
+ "type": "uint8",
864
+ "min": 1,
865
+ "max": 255,
866
+ "generated": true
867
+ },
868
+ "html_id": "max_num_motion_tx_delay_110",
869
+ "old_fly_id": "max_num_of_motion_tx_per_interval"
870
+ },
871
+ "uptime_counter_probe_1": {
872
+ "read_index": 60,
873
+ "descriptions": {
874
+ "title": "Probe Uptime 2",
875
+ "main_caption": ""
876
+ },
877
+ "validator": {
878
+ "type": "uint32be"
879
+ },
880
+ "tags": [
881
+ "diagnostics"
882
+ ]
883
+ },
884
+ "uptime_counter_probe_2": {
885
+ "read_index": 64,
886
+ "descriptions": {
887
+ "title": "Probe Uptime 1",
888
+ "main_caption": ""
889
+ },
890
+ "validator": {
891
+ "type": "uint32be"
892
+ },
893
+ "tags": [
894
+ "diagnostics"
895
+ ]
896
+ }
897
+ };
898
+ };
899
+
900
+ const sync_parse = (rep_buffer) => {
901
+ let response = {
902
+ 'human_readable': {},
903
+ 'machine_values': {}
904
+ };
905
+
906
+ // Get the map based on the sensor type byte
907
+ const sync_map = get_config_map(rep_buffer[4]);
908
+
909
+ for (const [key, config] of Object.entries(sync_map)) {
910
+ // Destructure 'type' from inside 'validator' and rename 'read_index' to 'idx'
911
+ const { read_index: idx, length, validator: { type } = {}, converter, options } = config;
912
+
913
+ // If for some reason a config doesn't have a validator/type, skip it
914
+ if (!type) continue;
915
+
916
+ switch (type) {
917
+ case 'uint8':
918
+ response.machine_values[key] = rep_buffer[idx];
919
+ break;
920
+ case 'uint16be':
921
+ response.machine_values[key] = rep_buffer.readUInt16BE(idx);
922
+ break;
923
+ case 'uint32be':
924
+ response.machine_values[key] = rep_buffer.readUInt32BE(idx);
925
+ break;
926
+ case 'buffer':
927
+ response.machine_values[key] = rep_buffer.subarray(idx, idx + length);
928
+ break;
929
+ case 'hex':
930
+ response.machine_values[key] = rep_buffer.subarray(idx, idx + length).toString('hex');
931
+ break;
932
+ case 'mac':
933
+ response.machine_values[key] = rep_buffer.subarray(idx, idx + length).toString('hex');
934
+ break;
935
+ }
936
+ let human_value = response.machine_values[key];
937
+ if(options && options[response.machine_values[key]]){
938
+ human_value = options[response.machine_values[key]];
939
+ }else{
940
+ if(converter && converter.multiplier){
941
+ human_value = human_value * converter.multiplier;
942
+ }
943
+ if(converter && converter.units){
944
+ human_value = human_value + converter.units;
945
+ }
946
+ }
947
+ response.human_readable[key] = human_value;
948
+ }
949
+ if (Object.hasOwn(response.machine_values, 'destination_address') && response.machine_values.destination_address.toLowerCase() === '00000000') {
950
+ console.log('##############################');
951
+ console.log('#########Dest Override########');
952
+ console.log('##############################');
953
+ response.destination_address = "0000ffff";
954
+ response.auto_raw_destination_address = "0000ffff";
955
+ };
956
+ return response;
957
+ };
958
+
959
+ const parse_fly = (frame) => {
960
+ let frame_data = {};
961
+ switch(frame[16]){
962
+ case 0:
963
+ frame_data.mode = "Processed";
964
+ break;
965
+ case 1:
966
+ frame_data.mode = "Raw";
967
+ break;
968
+ case 2:
969
+ frame_data.mode = "Processed + Raw on demand";
970
+ break;
971
+ case 3:
972
+ frame_data.mode = "Smart";
973
+ break;
974
+ }
975
+ switch(frame[17]){
976
+ case 6:
977
+ frame_data.odr_1 = 50;
978
+ break;
979
+ case 7:
980
+ frame_data.odr_1 = 100;
981
+ break;
982
+ case 8:
983
+ frame_data.odr_1 = 200;
984
+ break;
985
+ case 9:
986
+ frame_data.odr_1 = 400;
987
+ break;
988
+ case 10:
989
+ frame_data.odr_1 = 800;
990
+ break;
991
+ case 11:
992
+ frame_data.odr_1 = 1600;
993
+ break;
994
+ case 12:
995
+ frame_data.odr_1 = 3200;
996
+ break;
997
+ case 13:
998
+ frame_data.odr_1 = 6400;
999
+ break;
1000
+ case 14:
1001
+ frame_data.odr_1 = 12800;
1002
+ break;
1003
+ case 15:
1004
+ frame_data.odr_1 = 25600;
1005
+ break;
1006
+ }
1007
+ switch(frame[18]){
1008
+ case 6:
1009
+ frame_data.odr_2 = 50;
1010
+ break;
1011
+ case 7:
1012
+ frame_data.odr_2 = 100;
1013
+ break;
1014
+ case 8:
1015
+ frame_data.odr_2 = 200;
1016
+ break;
1017
+ case 9:
1018
+ frame_data.odr_2 = 400;
1019
+ break;
1020
+ case 10:
1021
+ frame_data.odr_2 = 800;
1022
+ break;
1023
+ case 11:
1024
+ frame_data.odr_2 = 1600;
1025
+ break;
1026
+ case 12:
1027
+ frame_data.odr_2 = 3200;
1028
+ break;
1029
+ case 13:
1030
+ frame_data.odr_2 = 6400;
1031
+ break;
1032
+ case 14:
1033
+ frame_data.odr_2 = 12800;
1034
+ break;
1035
+ case 15:
1036
+ frame_data.odr_2 = 25600;
1037
+ break;
1038
+ }
1039
+ frame_data.sampling_duration_1 = frame[19]*50 + "ms";
1040
+ frame_data.sampling_duration_2 = frame[20]*50 + "ms";
1041
+ switch(frame[21]){
1042
+ case 0:
1043
+ frame_data.filter_status = "Disabled";
1044
+ break;
1045
+ case 1:
1046
+ frame_data.filter_status = "Enabled";
1047
+ break;
1048
+ }
1049
+ switch(frame[22]){
1050
+ case 0:
1051
+ frame_data.lpf_coeff_1 = 4;
1052
+ break;
1053
+ case 1:
1054
+ frame_data.lpf_coeff_1 = 8;
1055
+ break;
1056
+ case 2:
1057
+ frame_data.lpf_coeff_1 = 16;
1058
+ break;
1059
+ case 2:
1060
+ frame_data.lpf_coeff_1 = 32;
1061
+ break;
1062
+ case 4:
1063
+ frame_data.lpf_coeff_1 = 64;
1064
+ break;
1065
+ case 5:
1066
+ frame_data.lpf_coeff_1 = 128;
1067
+ break;
1068
+ case 6:
1069
+ frame_data.lpf_coeff_1 = 256;
1070
+ break;
1071
+ case 7:
1072
+ frame_data.lpf_coeff_1 = 512;
1073
+ break;
1074
+ case 8:
1075
+ frame_data.lpf_coeff_1 = 1024;
1076
+ break;
1077
+ case 9:
1078
+ frame_data.lpf_coeff_1 = 2048;
1079
+ break;
1080
+ }
1081
+ frame_data.lpf_freq_1 = frame_data.odr_1 / frame_data.lpf_coeff_1;
1082
+ switch(frame[23]){
1083
+ case 0:
1084
+ frame_data.lpf_coeff_2 = 4;
1085
+ break;
1086
+ case 1:
1087
+ frame_data.lpf_coeff_2 = 8;
1088
+ break;
1089
+ case 2:
1090
+ frame_data.lpf_coeff_2 = 16;
1091
+ break;
1092
+ case 2:
1093
+ frame_data.lpf_coeff_2 = 32;
1094
+ break;
1095
+ case 4:
1096
+ frame_data.lpf_coeff_2 = 64;
1097
+ break;
1098
+ case 5:
1099
+ frame_data.lpf_coeff_2 = 128;
1100
+ break;
1101
+ case 6:
1102
+ frame_data.lpf_coeff_2 = 256;
1103
+ break;
1104
+ case 7:
1105
+ frame_data.lpf_coeff_2 = 512;
1106
+ break;
1107
+ case 8:
1108
+ frame_data.lpf_coeff_2 = 1024;
1109
+ break;
1110
+ case 9:
1111
+ frame_data.lpf_coeff_2 = 2048;
1112
+ break;
1113
+ }
1114
+ frame_data.lpf_freq_2 = frame_data.odr_2 / frame_data.lpf_coeff_2;
1115
+ switch(frame[24]){
1116
+ case 0:
1117
+ frame_data.hpf_coeff_1 = 4;
1118
+ break;
1119
+ case 1:
1120
+ frame_data.hpf_coeff_1 = 8;
1121
+ break;
1122
+ case 2:
1123
+ frame_data.hpf_coeff_1 = 16;
1124
+ break;
1125
+ case 2:
1126
+ frame_data.hpf_coeff_1 = 32;
1127
+ break;
1128
+ case 4:
1129
+ frame_data.hpf_coeff_1 = 64;
1130
+ break;
1131
+ case 5:
1132
+ frame_data.hpf_coeff_1 = 128;
1133
+ break;
1134
+ case 6:
1135
+ frame_data.hpf_coeff_1 = 256;
1136
+ break;
1137
+ case 7:
1138
+ frame_data.hpf_coeff_1 = 512;
1139
+ break;
1140
+ case 8:
1141
+ frame_data.hpf_coeff_1 = 1024;
1142
+ break;
1143
+ case 9:
1144
+ frame_data.hpf_coeff_1 = 2048;
1145
+ break;
1146
+ }
1147
+ frame_data.hpf_freq_1 = frame_data.odr_1 / frame_data.hpf_coeff_1;
1148
+ switch(frame[25]){
1149
+ case 0:
1150
+ frame_data.hpf_coeff_2 = 4;
1151
+ break;
1152
+ case 1:
1153
+ frame_data.hpf_coeff_2 = 8;
1154
+ break;
1155
+ case 2:
1156
+ frame_data.hpf_coeff_2 = 16;
1157
+ break;
1158
+ case 2:
1159
+ frame_data.hpf_coeff_2 = 32;
1160
+ break;
1161
+ case 4:
1162
+ frame_data.hpf_coeff_2 = 64;
1163
+ break;
1164
+ case 5:
1165
+ frame_data.hpf_coeff_2 = 128;
1166
+ break;
1167
+ case 6:
1168
+ frame_data.hpf_coeff_2 = 256;
1169
+ break;
1170
+ case 7:
1171
+ frame_data.hpf_coeff_2 = 512;
1172
+ break;
1173
+ case 8:
1174
+ frame_data.hpf_coeff_2 = 1024;
1175
+ break;
1176
+ case 9:
1177
+ frame_data.hpf_coeff_2 = 2048;
1178
+ break;
1179
+ }
1180
+ frame_data.hpf_freq_2 = frame_data.odr_2 / frame_data.hpf_coeff_2;
1181
+ switch(frame[26]){
1182
+ case 0:
1183
+ frame_data.sampling_interval = "5 Minutes";
1184
+ frame_data.sampling_interval_number = 5;
1185
+ break;
1186
+ case 1:
1187
+ frame_data.sampling_interval = "10 Minutes";
1188
+ frame_data.sampling_interval_number = 10;
1189
+ break;
1190
+ case 2:
1191
+ frame_data.sampling_interval = "15 Minutes";
1192
+ frame_data.sampling_interval_number = 15;
1193
+ break;
1194
+ case 2:
1195
+ frame_data.sampling_interval = "20 Minutes";
1196
+ frame_data.sampling_interval_number = 20;
1197
+ break;
1198
+ case 4:
1199
+ frame_data.sampling_interval = "30 Minutes";
1200
+ frame_data.sampling_interval_number = 30;
1201
+ break;
1202
+ case 5:
1203
+ frame_data.sampling_interval = "60 Minutes";
1204
+ frame_data.sampling_interval_number = 60;
1205
+ break;
1206
+ case 6:
1207
+ frame_data.sampling_interval = "120 Minutes";
1208
+ frame_data.sampling_interval_number = 120;
1209
+ break;
1210
+ case 7:
1211
+ frame_data.sampling_interval = "180 Minutes";
1212
+ frame_data.sampling_interval_number = 180;
1213
+ break;
1214
+ case 8:
1215
+ frame_data.sampling_interval = "1 Minute";
1216
+ frame_data.sampling_interval_number = 1;
1217
+ break;
1218
+ }
1219
+ frame_data.on_request_timeout = frame[27] + " Seconds";
1220
+ frame_data.deadband = frame[28] + "mg";
1221
+
1222
+ switch(frame[29]){
1223
+ case 0:
1224
+ frame_data.payload_length = "50 Bytes";
1225
+ break;
1226
+ case 1:
1227
+ frame_data.payload_length = "100 Bytes";
1228
+ break;
1229
+ case 2:
1230
+ frame_data.payload_length = "150 Bytes";
1231
+ break;
1232
+ case 3:
1233
+ frame_data.payload_length = "180 Bytes";
1234
+ break;
1235
+ }
1236
+ switch(frame[30]){
1237
+ case 0:
1238
+ frame_data.fsr_text = "2g";
1239
+ break;
1240
+ case 1:
1241
+ frame_data.fsr_text = "4g";
1242
+ break;
1243
+ case 2:
1244
+ frame_data.fsr_text = "8g";
1245
+ break;
1246
+ case 3:
1247
+ frame_data.fsr_text = "16g";
1248
+ break;
1249
+ }
1250
+ frame_data.rpm_status = frame[31]? 'Enabled': 'Disabled';
1251
+ frame_data.auto_raw_interval = frame[36] * frame_data.sampling_interval_number || 'disabled';
1252
+ frame_data.auto_raw_interval = typeof frame_data.auto_raw_interval === 'number' ? frame_data.auto_raw_interval+'min' : frame_data.auto_raw_interval;
1253
+ frame_data.p1_smart_mode_threshold = frame[38] * 50;
1254
+ frame_data.p2_smart_mode_threshold = frame[39] * 50;
1255
+ if(frame[2] > 5){ // for Firmware v6 and above
1256
+ frame_data.motion_to_delay = frame[50] * 50;
1257
+ return {
1258
+ 'firmware': frame[2],
1259
+ 'destination_address': toMac(frame.slice(12, 16)),
1260
+ 'mode': frame_data.mode,
1261
+ 'odr_1': frame_data.odr_1+'Hz',
1262
+ 'odr_2': frame_data.odr_2+'Hz',
1263
+ 'sampling_duration_1': frame_data.sampling_duration_1,
1264
+ 'sampling_duration_2': frame_data.sampling_duration_2,
1265
+ 'filter_status': frame_data.filter_status,
1266
+ 'lpf_coeff_1': frame_data.lpf_coeff_1,
1267
+ 'lpf_freq_1': frame_data.lpf_freq_1+'Hz',
1268
+ 'lpf_coeff_2': frame_data.lpf_coeff_2,
1269
+ 'lpf_freq_2': frame_data.lpf_freq_2+'Hz',
1270
+ 'hpf_coeff_1': frame_data.hpf_coeff_1,
1271
+ 'hpf_freq_1': frame_data.hpf_freq_1+'Hz',
1272
+ 'hpf_coeff_2': frame_data.hpf_coeff_2,
1273
+ 'hpf_freq_2': frame_data.hpf_freq_2+'Hz',
1274
+ 'sampling_interval': frame_data.sampling_interval,
1275
+ 'on_request_timeout': frame_data.on_request_timeout,
1276
+ 'deadband': frame_data.deadband,
1277
+ 'payload_length': frame_data.payload_length,
1278
+ 'fsr': frame_data.fsr_text,
1279
+ 'rpm_compute_status': frame_data.rpm_status,
1280
+ 'auto_raw_destination_address': toMac(frame.slice(32 , 36)),
1281
+ 'auto_raw_interval': frame_data.auto_raw_interval,
1282
+ 'smart_mode_skip_count': frame[37],
1283
+ 'smart_mode_acc_threshold_probe_1': frame_data.p1_smart_mode_threshold+'mg',
1284
+ 'smart_mode_acc_threshold_probe_2': frame_data.p2_smart_mode_threshold+'mg',
1285
+ 'uptime_counter_probe_1': frame.slice(40, 44).reduce(msbLsb)+'sec',
1286
+ 'uptime_counter_probe_2': frame.slice(44, 48).reduce(msbLsb)+'sec',
1287
+ 'max_tx_raw_samples': frame.slice(48, 50).reduce(msbLsb),
1288
+ 'motion_to_sampling_delay': frame_data.motion_to_delay +'msec',
1289
+ 'max_num_of_motion_tx_per_interval': frame[51],
1290
+ 'hardware_id': frame.slice(52, 55),
1291
+ 'reserved': frame.slice(55, 59),
1292
+ 'tx_lifetime_counter': frame.slice(59, 63).reduce(msbLsb),
1293
+ 'machine_values': {
1294
+ 'firmware': frame[2],
1295
+ 'destination_address': toMac(frame.slice(12, 16), false),
1296
+ 'mode': frame[16],
1297
+ 'odr_1': frame[17],
1298
+ 'odr_2': frame[18],
1299
+ 'sampling_duration_1': frame[19],
1300
+ 'sampling_duration_2': frame[20],
1301
+ 'filter_status': frame[21],
1302
+ 'lpf_coeff_1': frame[22],
1303
+ 'lpf_coeff_2': frame[23],
1304
+ 'hpf_coeff_1': frame[24],
1305
+ 'hpf_coeff_2': frame[25],
1306
+ 'sampling_interval': frame[26],
1307
+ 'on_request_timeout': frame[27],
1308
+ 'deadband': frame[28],
1309
+ 'payload_length': frame[29],
1310
+ 'fsm': frame[30],
1311
+ 'rpm_compute_status': frame[31],
1312
+ 'auto_raw_destination_address': toMac(frame.slice(32 , 36), false),
1313
+ 'auto_raw_interval': frame[36],
1314
+ 'smart_mode_skip_count': frame[37],
1315
+ 'smart_mode_acc_threshold_probe_1':frame[38],
1316
+ 'smart_mode_acc_threshold_probe_2':frame[39],
1317
+ 'uptime_counter_probe_1': frame.slice(40, 44),
1318
+ 'uptime_counter_probe_2': frame.slice(44, 48),
1319
+ 'max_tx_raw_samples': frame.slice(48, 50),
1320
+ 'motion_to_sampling_delay': frame[50],
1321
+ 'max_num_of_motion_tx_per_interval': frame[51],
1322
+ 'hardware_id': frame.slice(52, 55),
1323
+ 'reserved': frame.slice(55, 59),
1324
+ 'tx_lifetime_counter': frame.slice(59, 63)
1325
+ }
1326
+ }
1327
+ } else if (frame[2] > 4){ // for Firmware v5 and above
1328
+ return {
1329
+ 'firmware': frame[2],
1330
+ 'destination_address': toMac(frame.slice(12, 16)),
1331
+ 'mode': frame_data.mode,
1332
+ 'odr_1': frame_data.odr_1+'Hz',
1333
+ 'odr_2': frame_data.odr_2+'Hz',
1334
+ 'sampling_duration_1': frame_data.sampling_duration_1,
1335
+ 'sampling_duration_2': frame_data.sampling_duration_2,
1336
+ 'filter_status': frame_data.filter_status,
1337
+ 'lpf_coeff_1': frame_data.lpf_coeff_1,
1338
+ 'lpf_freq_1': frame_data.lpf_freq_1+'Hz',
1339
+ 'lpf_coeff_2': frame_data.lpf_coeff_2,
1340
+ 'lpf_freq_2': frame_data.lpf_freq_2+'Hz',
1341
+ 'hpf_coeff_1': frame_data.hpf_coeff_1,
1342
+ 'hpf_freq_1': frame_data.hpf_freq_1+'Hz',
1343
+ 'hpf_coeff_2': frame_data.hpf_coeff_2,
1344
+ 'hpf_freq_2': frame_data.hpf_freq_2+'Hz',
1345
+ 'sampling_interval': frame_data.sampling_interval,
1346
+ 'on_request_timeout': frame_data.on_request_timeout,
1347
+ 'deadband': frame_data.deadband,
1348
+ 'payload_length': frame_data.payload_length,
1349
+ 'fsr': frame_data.fsr_text,
1350
+ 'rpm_compute_status': frame_data.rpm_status,
1351
+ 'auto_raw_destination_address': toMac(frame.slice(32 , 36)),
1352
+ 'auto_raw_interval': frame_data.auto_raw_interval,
1353
+ 'smart_mode_skip_count': frame[37],
1354
+ 'smart_mode_acc_threshold_probe_1': frame_data.p1_smart_mode_threshold+'mg',
1355
+ 'smart_mode_acc_threshold_probe_2': frame_data.p2_smart_mode_threshold+'mg',
1356
+ 'uptime_counter_probe_1': frame.slice(40, 44).reduce(msbLsb)+'sec',
1357
+ 'uptime_counter_probe_2': frame.slice(44, 48).reduce(msbLsb)+'sec',
1358
+ 'max_tx_raw_samples': frame.slice(48, 50).reduce(msbLsb),
1359
+ 'hardware_id': frame.slice(50, 53),
1360
+ 'reserved': frame.slice(53, 57),
1361
+ 'tx_lifetime_counter': frame.slice(57, 61).reduce(msbLsb),
1362
+ 'machine_values': {
1363
+ 'firmware': frame[2],
1364
+ 'destination_address': toMac(frame.slice(12, 16), false),
1365
+ 'mode': frame[16],
1366
+ 'odr_1': frame[17],
1367
+ 'odr_2': frame[18],
1368
+ 'sampling_duration_1': frame[19],
1369
+ 'sampling_duration_2': frame[20],
1370
+ 'filter_status': frame[21],
1371
+ 'lpf_coeff_1': frame[22],
1372
+ 'lpf_coeff_2': frame[23],
1373
+ 'hpf_coeff_1': frame[24],
1374
+ 'hpf_coeff_2': frame[25],
1375
+ 'sampling_interval': frame[26],
1376
+ 'on_request_timeout': frame[27],
1377
+ 'deadband': frame[28],
1378
+ 'payload_length': frame[29],
1379
+ 'fsm': frame[30],
1380
+ 'rpm_compute_status': frame[31],
1381
+ 'auto_raw_destination_address': toMac(frame.slice(32 , 36), false),
1382
+ 'auto_raw_interval': frame[36],
1383
+ 'smart_mode_skip_count': frame[37],
1384
+ 'smart_mode_acc_threshold_probe_1':frame[38],
1385
+ 'smart_mode_acc_threshold_probe_2':frame[39],
1386
+ 'uptime_counter_probe_1': frame.slice(40, 44),
1387
+ 'uptime_counter_probe_2': frame.slice(44, 48),
1388
+ 'max_tx_raw_samples': frame.slice(48, 50),
1389
+ 'hardware_id': frame.slice(50, 53),
1390
+ 'reserved': frame.slice(53, 57),
1391
+ 'tx_lifetime_counter': frame.slice(57, 61)
1392
+ }
1393
+ }
1394
+ }else{
1395
+ return {
1396
+ 'firmware': frame[2],
1397
+ 'destination_address': toMac(frame.slice(12, 16)),
1398
+ 'mode': frame_data.mode,
1399
+ 'odr_1': frame_data.odr_1+'Hz',
1400
+ 'odr_2': frame_data.odr_2+'Hz',
1401
+ 'sampling_duration_1': frame_data.sampling_duration_1,
1402
+ 'sampling_duration_2': frame_data.sampling_duration_2,
1403
+ 'filter_status': frame_data.filter_status,
1404
+ 'lpf_coeff_1': frame_data.lpf_coeff_1,
1405
+ 'lpf_freq_1': frame_data.lpf_freq_1+'Hz',
1406
+ 'lpf_coeff_2': frame_data.lpf_coeff_2,
1407
+ 'lpf_freq_2': frame_data.lpf_freq_2+'Hz',
1408
+ 'hpf_coeff_1': frame_data.hpf_coeff_1,
1409
+ 'hpf_freq_1': frame_data.hpf_freq_1+'Hz',
1410
+ 'hpf_coeff_2': frame_data.hpf_coeff_2,
1411
+ 'hpf_freq_2': frame_data.hpf_freq_2+'Hz',
1412
+ 'sampling_interval': frame_data.sampling_interval,
1413
+ 'on_request_timeout': frame_data.on_request_timeout,
1414
+ 'deadband': frame_data.deadband,
1415
+ 'payload_length': frame_data.payload_length,
1416
+ 'fsr': frame_data.fsr_text,
1417
+ 'rpm_compute_status': frame_data.rpm_status,
1418
+ 'auto_raw_destination_address': toMac(frame.slice(32 , 36)),
1419
+ 'auto_raw_interval': frame_data.auto_raw_interval,
1420
+ 'smart_mode_skip_count': frame[37],
1421
+ 'smart_mode_acc_threshold_probe_1': frame_data.p1_smart_mode_threshold+'mg',
1422
+ 'smart_mode_acc_threshold_probe_2': frame_data.p2_smart_mode_threshold+'mg',
1423
+ 'uptime_counter_probe_1': frame.slice(40, 44).reduce(msbLsb)+'sec',
1424
+ 'uptime_counter_probe_2': frame.slice(44, 48).reduce(msbLsb)+'sec',
1425
+ 'hardware_id': frame.slice(48, 51),
1426
+ 'reserved': frame.slice(51, 55),
1427
+ 'tx_lifetime_counter': frame.slice(55, 59).reduce(msbLsb),
1428
+ 'machine_values': {
1429
+ 'firmware': frame[2],
1430
+ 'destination_address': toMac(frame.slice(12, 16), false),
1431
+ 'mode': frame[16],
1432
+ 'odr_1': frame[17],
1433
+ 'odr_2': frame[18],
1434
+ 'sampling_duration_1': frame[19],
1435
+ 'sampling_duration_2': frame[20],
1436
+ 'filter_status': frame[21],
1437
+ 'lpf_coeff_1': frame[22],
1438
+ 'lpf_coeff_2': frame[23],
1439
+ 'hpf_coeff_1': frame[24],
1440
+ 'hpf_coeff_2': frame[25],
1441
+ 'sampling_interval': frame[26],
1442
+ 'on_request_timeout': frame[27],
1443
+ 'deadband': frame[28],
1444
+ 'payload_length': frame[29],
1445
+ 'fsm': frame[30],
1446
+ 'rpm_compute_status': frame[31],
1447
+ 'auto_raw_destination_address': toMac(frame.slice(32 , 36), false),
1448
+ 'auto_raw_interval': frame[36],
1449
+ 'smart_mode_skip_count': frame[37],
1450
+ 'smart_mode_acc_threshold_probe_1':frame[38],
1451
+ 'smart_mode_acc_threshold_probe_2':frame[39],
1452
+ 'uptime_counter_probe_1': frame.slice(40, 44),
1453
+ 'uptime_counter_probe_2': frame.slice(44, 48),
1454
+ 'hardware_id': frame.slice(48, 51),
1455
+ 'reserved': frame.slice(51, 55),
1456
+ 'tx_lifetime_counter': frame.slice(55, 59)
1457
+ }
1458
+ }
1459
+ }
1460
+ };
1461
+
1462
+ const parse = (payload, parsed, mac) => {
1463
+ parsed.data = {};
1464
+ if(payload[7] & 2){
1465
+ parsed.data['probe_1_error'] = true;
1466
+ }
1467
+ if(payload[7] & 4){
1468
+ parsed.data['probe_2_error'] = true;
1469
+ }
1470
+ if(payload[7] & 2 && payload[7] & 4){
1471
+ return parsed;
1472
+ }
1473
+ let msg_type = (payload[7] & 16) ? 'motion' : 'regular';
1474
+ if (payload[8] === 1) {
1475
+
1476
+ var deviceAddr = mac;
1477
+ var expected_packets = msbLsb(payload[16], payload[17]);
1478
+ var current_packet = msbLsb(payload[18], payload[19]);
1479
+ var sdata_start = 20;
1480
+ var probe;
1481
+ if (payload[7] & 8) {
1482
+ probe = 2;
1483
+ } else {
1484
+ probe = 1;
1485
+ }
1486
+ if(!Object.hasOwn(globalDevices, deviceAddr)){
1487
+ globalDevices[deviceAddr] = {};
1488
+ }
1489
+ if (globalDevices[deviceAddr].hasOwnProperty(probe) || expected_packets == 1) {
1490
+ if (expected_packets != 1) {
1491
+ if (globalDevices[deviceAddr][probe].last_packet_counter == current_packet) {
1492
+ console.log('Duplicated message');
1493
+ return;
1494
+ }
1495
+ if (current_packet == 1 || (globalDevices[deviceAddr][probe].last_packet_counter > current_packet)) {
1496
+ console.log('Recovering bad packet');
1497
+ clear_globalDevices_stream(deviceAddr, probe);
1498
+ init_globalDevices_stream(deviceAddr, payload, expected_packets, parsed, msg_type, probe);
1499
+ globalDevices[deviceAddr][probe].last_packet_counter = current_packet;
1500
+ globalDevices[deviceAddr][probe].data[current_packet] = payload.slice(sdata_start);
1501
+ return;
1502
+ }
1503
+ else {
1504
+ globalDevices[deviceAddr][probe].last_packet_counter = current_packet;
1505
+ globalDevices[deviceAddr][probe].data[current_packet] = payload.slice(sdata_start);
1506
+ }
1507
+ }
1508
+ else {
1509
+ clear_globalDevices_stream(deviceAddr, probe);
1510
+ init_globalDevices_stream(deviceAddr, payload, expected_packets, parsed, msg_type, probe);
1511
+ globalDevices[deviceAddr][probe].last_packet_counter = current_packet;
1512
+ globalDevices[deviceAddr][probe].data[current_packet] = payload.slice(sdata_start);
1513
+ }
1514
+ }
1515
+ else {
1516
+ clear_globalDevices_stream(deviceAddr, probe);
1517
+ init_globalDevices_stream(deviceAddr, payload, expected_packets, parsed, msg_type, probe);
1518
+ globalDevices[deviceAddr][probe].last_packet_counter = current_packet;
1519
+ globalDevices[deviceAddr][probe].data[current_packet] = payload.slice(sdata_start);
1520
+ }
1521
+ if (current_packet == expected_packets) {
1522
+ sensor_data = concat_fft_data(deviceAddr, payload[8], msg_type, probe);
1523
+ clear_globalDevices_stream(deviceAddr, probe);
1524
+ return sensor_data;
1525
+ }
1526
+ else {
1527
+ return;
1528
+ }
1529
+ }
1530
+ else if (payload[8] === 0 || payload[8] === 2 || payload[8] === 3) {
1531
+ var odr1;
1532
+ switch (payload[9]) {
1533
+ case 6: odr1 = "50Hz"; break;
1534
+ case 7: odr1 = "100Hz"; break;
1535
+ case 8: odr1 = "200Hz"; break;
1536
+ case 9: odr1 = "400Hz"; break;
1537
+ case 10: odr1 = "800Hz"; break;
1538
+ case 11: odr1 = "1600Hz"; break;
1539
+ case 12: odr1 = "3200Hz"; break;
1540
+ case 13: odr1 = "6400Hz"; break;
1541
+ case 14: odr1 = "12800Hz"; break;
1542
+ case 15: odr1 = "25600Hz"; break;
1543
+ }
1544
+ var odr2;
1545
+ switch (payload[56]) {
1546
+ case 6: odr2 = "50Hz"; break;
1547
+ case 7: odr2 = "100Hz"; break;
1548
+ case 8: odr2 = "200Hz"; break;
1549
+ case 9: odr2 = "400Hz"; break;
1550
+ case 10: odr2 = "800Hz"; break;
1551
+ case 11: odr2 = "1600Hz"; break;
1552
+ case 12: odr2 = "3200Hz"; break;
1553
+ case 13: odr2 = "6400Hz"; break;
1554
+ case 14: odr2 = "12800Hz"; break;
1555
+ case 15: odr2 = "25600Hz"; break;
1556
+ }
1557
+ return {
1558
+ mode: payload[8],
1559
+ msg_type: msg_type,
1560
+ s1_odr: odr1,
1561
+ s1_temperature: signInt(payload.slice(10, 12).reduce(msbLsb), 16) / 100,
1562
+ x1_rms_ACC_G: payload.slice(12, 14).reduce(msbLsb)/1000,
1563
+ x1_max_ACC_G: payload.slice(14, 16).reduce(msbLsb)/1000,
1564
+ x1_velocity_mm_sec: payload.slice(16, 18).reduce(msbLsb) / 100,
1565
+ x1_displacement_mm: payload.slice(18, 20).reduce(msbLsb) / 100,
1566
+ x1_peak_one_Hz: payload.slice(20, 22).reduce(msbLsb),
1567
+ x1_peak_two_Hz: payload.slice(22, 24).reduce(msbLsb),
1568
+ x1_peak_three_Hz: payload.slice(24, 26).reduce(msbLsb),
1569
+ y1_rms_ACC_G: payload.slice(26, 28).reduce(msbLsb)/1000,
1570
+ y1_max_ACC_G: payload.slice(28, 30).reduce(msbLsb)/1000,
1571
+ y1_velocity_mm_sec: payload.slice(30, 32).reduce(msbLsb) / 100,
1572
+ y1_displacement_mm: payload.slice(32, 34).reduce(msbLsb) / 100,
1573
+ y1_peak_one_Hz: payload.slice(34, 36).reduce(msbLsb),
1574
+ y1_peak_two_Hz: payload.slice(36, 38).reduce(msbLsb),
1575
+ y1_peak_three_Hz: payload.slice(38, 40).reduce(msbLsb),
1576
+ z1_rms_ACC_G: payload.slice(40, 42).reduce(msbLsb)/1000,
1577
+ z1_max_ACC_G: payload.slice(42, 44).reduce(msbLsb)/1000,
1578
+ z1_velocity_mm_sec: payload.slice(44, 46).reduce(msbLsb) / 100,
1579
+ z1_displacement_mm: payload.slice(46, 48).reduce(msbLsb) / 100,
1580
+ z1_peak_one_Hz: payload.slice(48, 50).reduce(msbLsb),
1581
+ z1_peak_two_Hz: payload.slice(50, 52).reduce(msbLsb),
1582
+ z1_peak_three_Hz: payload.slice(52, 54).reduce(msbLsb),
1583
+ rpm_1: payload.slice(54, 56).reduce(msbLsb),
1584
+ s2_odr: odr2,
1585
+ s2_temperature: signInt(payload.slice(57, 59).reduce(msbLsb), 16) / 100,
1586
+ x2_rms_ACC_G: payload.slice(59, 61).reduce(msbLsb)/1000,
1587
+ x2_max_ACC_G: payload.slice(61, 63).reduce(msbLsb)/1000,
1588
+ x2_velocity_mm_sec: payload.slice(63, 65).reduce(msbLsb) / 100,
1589
+ x2_displacement_mm: payload.slice(65, 67).reduce(msbLsb) / 100,
1590
+ x2_peak_one_Hz: payload.slice(67, 69).reduce(msbLsb),
1591
+ x2_peak_two_Hz: payload.slice(69, 71).reduce(msbLsb),
1592
+ x2_peak_three_Hz: payload.slice(71, 73).reduce(msbLsb),
1593
+ y2_rms_ACC_G: payload.slice(73, 75).reduce(msbLsb)/1000,
1594
+ y2_max_ACC_G: payload.slice(75, 77).reduce(msbLsb)/1000,
1595
+ y2_velocity_mm_sec: payload.slice(77, 79).reduce(msbLsb) / 100,
1596
+ y2_displacement_mm: payload.slice(79, 81).reduce(msbLsb) / 100,
1597
+ y2_peak_one_Hz: payload.slice(81, 83).reduce(msbLsb),
1598
+ y2_peak_two_Hz: payload.slice(83, 85).reduce(msbLsb),
1599
+ y2_peak_three_Hz: payload.slice(85, 87).reduce(msbLsb),
1600
+ z2_rms_ACC_G: payload.slice(87, 89).reduce(msbLsb)/1000,
1601
+ z2_max_ACC_G: payload.slice(89, 91).reduce(msbLsb)/1000,
1602
+ z2_velocity_mm_sec: payload.slice(91, 93).reduce(msbLsb) / 100,
1603
+ z2_displacement_mm: payload.slice(93, 95).reduce(msbLsb) / 100,
1604
+ z2_peak_one_Hz: payload.slice(95, 97).reduce(msbLsb),
1605
+ z2_peak_two_Hz: payload.slice(97, 99).reduce(msbLsb),
1606
+ z2_peak_three_Hz: payload.slice(99, 101).reduce(msbLsb),
1607
+ rpm_2: payload.slice(101, 103).reduce(msbLsb)
1608
+ };
1609
+ }
1610
+ };
1611
+
1612
+ // Export the module with all the necessary functions and properties
1613
+ // that need to be called from outside the scrip
1614
+ return {
1615
+ type: 111,
1616
+ name: 'Two Channel Vibration Plus v4',
1617
+ parse,
1618
+ get_write_buffer_size,
1619
+ get_config_map,
1620
+ sync_parse,
1621
+ parse_fly,
1622
+ };
1623
+ };