@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,1320 @@
1
+ const { toMac, signInt, msbLsb } = require('../utils');
2
+
3
+ module.exports = (globalDevices, emitter) => {
4
+
5
+ const clear_globalDevices_stream = (deviceAddr) => {
6
+ if (Object.hasOwn(globalDevices, deviceAddr)) {
7
+ if (Object.hasOwn(globalDevices[deviceAddr], 'packet_stream_timeout')) {
8
+ clearTimeout(globalDevices[deviceAddr].packet_stream_timeout);
9
+ }
10
+ delete globalDevices[deviceAddr];
11
+ }
12
+ };
13
+
14
+ const init_globalDevices_stream = (deviceAddr, payload, expected_packets, parsed, msg_type) => {
15
+ globalDevices[deviceAddr] = {
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].packet_stream_timeout = setTimeout(() => {
26
+ // Calling sibling function directly
27
+ parsed.sensor_data = concat_fft_data(deviceAddr, payload[8], msg_type);
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-110', parsed);
32
+ emitter.emit('sensor_data' + '-' + deviceAddr, parsed);
33
+ }, 60000);
34
+ };
35
+
36
+ const concat_fft_data = (deviceAddr, mode, msg_type) => {
37
+ var raw_data = new Array();
38
+ for (const packet in globalDevices[deviceAddr].data) {
39
+ raw_data = raw_data.concat(globalDevices[deviceAddr].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].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].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
+ time_id: [
82
+ String(globalDevices[deviceAddr].hour).padStart(2, '0'),
83
+ String(globalDevices[deviceAddr].minute).padStart(2, '0'),
84
+ ].join(':'),
85
+ mac_address: deviceAddr,
86
+ fsr: fsr_text,
87
+ odr: globalDevices[deviceAddr].odr,
88
+ temperature: globalDevices[deviceAddr].temperature,
89
+ total_samples: label,
90
+ fft_confidence: ((Object.keys(globalDevices[deviceAddr].data).length / globalDevices[deviceAddr].expected_packets) * 100).toFixed(2) + '%',
91
+ data: fft_concat
92
+ };
93
+ return fft_concat_obj;
94
+ };
95
+
96
+ const get_write_buffer_size = (firmware) => {
97
+ return 41;
98
+ };
99
+
100
+ const get_config_map = (firmware) => {
101
+ console.log('Generating sync map for firmware version', firmware);
102
+
103
+ return {
104
+ "core_version": {
105
+ "read_index": 3,
106
+ "descriptions": {
107
+ "title": "Core Version",
108
+ "main_caption": "The version of the core communication stack."
109
+ },
110
+ "validator": {
111
+ "type": "uint8"
112
+ },
113
+ "tags": [
114
+ "system"
115
+ ]
116
+ },
117
+ "firmware_version": {
118
+ "read_index": 4,
119
+ "descriptions": {
120
+ "title": "Firmware Version",
121
+ "main_caption": "The application-specific firmware version."
122
+ },
123
+ "validator": {
124
+ "type": "uint8"
125
+ },
126
+ "tags": [
127
+ "system"
128
+ ],
129
+ "old_fly_id": "firmware"
130
+ },
131
+ "sensor_type": {
132
+ "read_index": 5,
133
+ "descriptions": {
134
+ "title": "Sensor Type",
135
+ "main_caption": "The hardware identifier for the specific sensor model."
136
+ },
137
+ "validator": {
138
+ "type": "uint16be"
139
+ },
140
+ "tags": [
141
+ "system"
142
+ ]
143
+ },
144
+ "tx_lifetime_counter": {
145
+ "read_index": 7,
146
+ "descriptions": {
147
+ "title": "Transmission Lifetime Counter",
148
+ "main_caption": "Total number of transmissions since the device was manufactured."
149
+ },
150
+ "validator": {
151
+ "type": "uint32be"
152
+ },
153
+ "tags": [
154
+ "diagnostics"
155
+ ]
156
+ },
157
+ "hardware_id": {
158
+ "read_index": 11,
159
+ "length": 3,
160
+ "descriptions": {
161
+ "title": "Hardware ID",
162
+ "main_caption": "A unique 3-byte hardware identifier."
163
+ },
164
+ "validator": {
165
+ "type": "buffer"
166
+ },
167
+ "tags": [
168
+ "system"
169
+ ]
170
+ },
171
+ "network_id": {
172
+ "read_index": 14,
173
+ "write_index": 3,
174
+ "length": 2,
175
+ "descriptions": {
176
+ "title": "Network ID",
177
+ "main_caption": ""
178
+ },
179
+ "default_value": "7fff",
180
+ "validator": {
181
+ "type": "hex",
182
+ "length": 4
183
+ },
184
+ "html_id": "pan_id",
185
+ "tags": [
186
+ "Communications"
187
+ ]
188
+ },
189
+ "destination_address": {
190
+ "read_index": 16,
191
+ "write_index": 5,
192
+ "length": 4,
193
+ "descriptions": {
194
+ "title": "Destination Address",
195
+ "main_caption": ""
196
+ },
197
+ "default_value": "0000ffff",
198
+ "validator": {
199
+ "type": "mac",
200
+ "length": 8
201
+ },
202
+ "html_id": "destination",
203
+ "tags": [
204
+ "Communications"
205
+ ]
206
+ },
207
+ "node_id": {
208
+ "read_index": 20,
209
+ "write_index": 9,
210
+ "descriptions": {
211
+ "title": "Node ID",
212
+ "main_caption": ""
213
+ },
214
+ "default_value": "0",
215
+ "validator": {
216
+ "type": "uint8",
217
+ "min": 0,
218
+ "max": 255,
219
+ "generated": true
220
+ },
221
+ "html_id": "node_id",
222
+ "tags": [
223
+ "generic"
224
+ ],
225
+ "tags": [
226
+ "Communications"
227
+ ]
228
+ },
229
+ "odr": {
230
+ "read_index": 21,
231
+ "write_index": 10,
232
+ "descriptions": {
233
+ "title": "Probe 1: Output Data Rate",
234
+ "main_caption": "<p>This would determine how many samples the output data has...</p>"
235
+ },
236
+ "default_value": 0,
237
+ "validator": {
238
+ "type": "uint8",
239
+ "min": 7,
240
+ "max": 15,
241
+ "generated": true
242
+ },
243
+ "options": {
244
+ "7": "100Hz",
245
+ "8": "200Hz",
246
+ "9": "400Hz",
247
+ "10": "800Hz",
248
+ "11": "1600Hz",
249
+ "12": "3200Hz",
250
+ "13": "6400Hz",
251
+ "14": "12800Hz",
252
+ "15": "25600Hz"
253
+ },
254
+ "tags": [
255
+ "Vibration Sampling"
256
+ ],
257
+ "html_id": "odr_p1_110"
258
+ },
259
+ "sampling_duration": {
260
+ "read_index": 22,
261
+ "write_index": 11,
262
+ "descriptions": {
263
+ "title": "Probe 1: Sampling Duration",
264
+ "main_caption": "<p>Set the amount of time which the samples are taken...</p>"
265
+ },
266
+ "default_value": 1,
267
+ "validator": {
268
+ "type": "uint8",
269
+ "min": 1,
270
+ "max": 100,
271
+ "generated": true
272
+ },
273
+ "tags": [
274
+ "Vibration Sampling"
275
+ ],
276
+ "html_id": "sampling_duration_p1_110"
277
+ },
278
+ "lpf_coefficient": {
279
+ "read_index": 23,
280
+ "write_index": 12,
281
+ "descriptions": {
282
+ "title": "Probe 1: Set Low Pass Filter",
283
+ "main_caption": "<p>This setting will set the LPF freq to ODR divided by Selected Value...</p>"
284
+ },
285
+ "default_value": 0,
286
+ "validator": {
287
+ "type": "uint8",
288
+ "min": 0,
289
+ "max": 9,
290
+ "generated": true
291
+ },
292
+ "options": {
293
+ "10": "2",
294
+ "0": "4",
295
+ "1": "8",
296
+ "2": "16",
297
+ "3": "32",
298
+ "4": "64",
299
+ "5": "128",
300
+ "6": "256",
301
+ "7": "512",
302
+ "8": "1024",
303
+ "9": "2048"
304
+ },
305
+ "html_id": "low_pass_filter_p1_110",
306
+ "old_fly_id": "lpf_coeff"
307
+ },
308
+ "hpf_coefficient": {
309
+ "read_index": 24,
310
+ "write_index": 13,
311
+ "descriptions": {
312
+ "title": "Probe 1: Set High Pass Filter",
313
+ "main_caption": "<p>This setting will set the HPF freq to ODR divided by Selected Value...</p>"
314
+ },
315
+ "default_value": 0,
316
+ "validator": {
317
+ "type": "uint8",
318
+ "min": 0,
319
+ "max": 9,
320
+ "generated": true
321
+ },
322
+ "options": {
323
+ "0": "4",
324
+ "1": "8",
325
+ "2": "16",
326
+ "3": "32",
327
+ "4": "64",
328
+ "5": "128",
329
+ "6": "256",
330
+ "7": "512",
331
+ "8": "1024",
332
+ "9": "2048"
333
+ },
334
+ "html_id": "high_pass_filter_p1_110",
335
+ "old_fly_id": "hpf_coeff"
336
+ },
337
+ "full_scale_range": {
338
+ "read_index": 25,
339
+ "write_index": 14,
340
+ "descriptions": {
341
+ "title": "Full Scale Range",
342
+ "main_caption": "<p>Set how large of a range the device can measure acceleration in.</p>"
343
+ },
344
+ "default_value": 1,
345
+ "validator": {
346
+ "type": "uint8",
347
+ "min": 0,
348
+ "max": 5,
349
+ "generated": true
350
+ },
351
+ "options": {
352
+ "0": "+/- 2g",
353
+ "1": "+/- 4g",
354
+ "2": "+/- 8g",
355
+ "3": "+/- 16g",
356
+ "4": "+/- 32g",
357
+ "5": "+/- 64g"
358
+ },
359
+ "tags": [
360
+ "Vibration Sampling"
361
+ ],
362
+ "html_id": "full_scale_range_101",
363
+ "old_fly_id": "fsr"
364
+ },
365
+ "axes_enabled": {
366
+ "read_index": 26,
367
+ "write_index": 15,
368
+ "descriptions": {
369
+ "title": "Axes Enabled",
370
+ "main_caption": "New Command"
371
+ },
372
+ "validator": {
373
+ "type": "uint8"
374
+ },
375
+ "read_only": true,
376
+ },
377
+ "sampling_interval": {
378
+ "read_index": 27,
379
+ "write_index": 16,
380
+ "descriptions": {
381
+ "title": "Sampling Interval",
382
+ "main_caption": "<p>Set how often will the sensor transmit measurement data.</p>"
383
+ },
384
+ "default_value": 1,
385
+ "validator": {
386
+ "type": "uint8",
387
+ "min": 0,
388
+ "max": 8,
389
+ "generated": true
390
+ },
391
+ "options": {
392
+ "0": "5 Minutes",
393
+ "1": "10 Minutes",
394
+ "2": "15 Minutes",
395
+ "3": "20 Minutes",
396
+ "4": "30 Minutes",
397
+ "5": "60 Minutes",
398
+ "6": "120 Minutes",
399
+ "7": "180 Minutes",
400
+ "8": "1 Minute"
401
+ },
402
+ "tags": [
403
+ "Communications"
404
+ ],
405
+ "html_id": "sampling_interval_110"
406
+ },
407
+ "filter_status": {
408
+ "read_index": 28,
409
+ "write_index": 17,
410
+ "descriptions": {
411
+ "title": "Set Filtering",
412
+ "main_caption": "<p>Enable/Disable built-in filters</p>"
413
+ },
414
+ "default_value": 0,
415
+ "validator": {
416
+ "type": "uint8",
417
+ "min": 0,
418
+ "max": 1,
419
+ "generated": true
420
+ },
421
+ "options": {
422
+ "0": "Enabled",
423
+ "1": "Disabled"
424
+ },
425
+ "html_id": "enable_filtering_110"
426
+ },
427
+ "operation_mode": {
428
+ "read_index": 29,
429
+ "write_index": 18,
430
+ "descriptions": {
431
+ "title": "Mode",
432
+ "main_caption": "<p>• <strong>Processed:</strong> FFT is performed...</p>"
433
+ },
434
+ "default_value": 0,
435
+ "validator": {
436
+ "type": "uint8",
437
+ "min": 0,
438
+ "max": 3,
439
+ "generated": true
440
+ },
441
+ "options": {
442
+ "0": "Processed",
443
+ "1": "Raw",
444
+ "2": "Processed + Raw on demand",
445
+ "3": "Smart"
446
+ },
447
+ "html_id": "mode_110",
448
+ "old_fly_id": "mode"
449
+ },
450
+ "measurement_mode": {
451
+ "read_index": 30,
452
+ "write_index": 19,
453
+ "descriptions": {
454
+ "title": "Measurement Mode",
455
+ "main_caption": "Changing this value does not do anything. Only give one option."
456
+ },
457
+ "validator": {
458
+ "type": "uint8"
459
+ },
460
+ "read_only": true
461
+ },
462
+ "on_request_timeout": {
463
+ "read_index": 31,
464
+ "write_index": 20,
465
+ "descriptions": {
466
+ "title": "Set On Request Timeout",
467
+ "main_caption": "<p>Set how long device will stay awake...</p>"
468
+ },
469
+ "default_value": 1,
470
+ "validator": {
471
+ "type": "uint8",
472
+ "min": 1,
473
+ "max": 10,
474
+ "generated": true
475
+ },
476
+ "depends_on": {
477
+ "operation_mode": [
478
+ 2,
479
+ 3
480
+ ]
481
+ },
482
+ "html_id": "on_request_timeout_80"
483
+ },
484
+ "deadband": {
485
+ "read_index": 32,
486
+ "write_index": 21,
487
+ "descriptions": {
488
+ "title": "Set Dead Band in mg",
489
+ "main_caption": "<p>Filters out acceleration values below the dead band threshold...</p>"
490
+ },
491
+ "default_value": 0,
492
+ "validator": {
493
+ "type": "uint8",
494
+ "min": 0,
495
+ "max": 255,
496
+ "generated": true
497
+ },
498
+ "html_id": "deadband_80"
499
+ },
500
+ "motion_detection_threshold": {
501
+ "read_index": 33,
502
+ "write_index": 22,
503
+ "descriptions": {
504
+ "title": "Probe 1: Set Acceleration Wake/Interrupt Threshold",
505
+ "main_caption": "<div><p>Set a breakpoint for sensor to wake up...</p></div>"
506
+ },
507
+ "default_value": 0,
508
+ "validator": {
509
+ "type": "uint8",
510
+ "min": 0,
511
+ "max": 40,
512
+ "generated": true
513
+ },
514
+ "html_id": "motion_detect_threshold_p1_110"
515
+ },
516
+ "led_acceleration_alert_threshold": {
517
+ "read_index": 34,
518
+ "write_index": 23,
519
+ "descriptions": {
520
+ "title": "LED Accelerometer Threshold",
521
+ "main_caption": "<div><p>Set the minimum acceleration value...</p></div>"
522
+ },
523
+ "default_value": 10,
524
+ "validator": {
525
+ "type": "uint8",
526
+ "min": 0,
527
+ "max": 255,
528
+ "generated": true
529
+ },
530
+ "depends_on": {
531
+ "led_alert_mode": 0
532
+ },
533
+ "html_id": "led_accelerometer_threshold_84"
534
+ },
535
+ "led_velocity_alert_threshold": {
536
+ "read_index": 35,
537
+ "write_index": 24,
538
+ "descriptions": {
539
+ "title": "LED Velocity Threshold",
540
+ "main_caption": "<div><p>Set the minimum velocity value...</p></div>"
541
+ },
542
+ "default_value": 10,
543
+ "validator": {
544
+ "type": "uint8",
545
+ "min": 0,
546
+ "max": 255,
547
+ "generated": true
548
+ },
549
+ "depends_on": {
550
+ "led_alert_mode": 1
551
+ },
552
+ "html_id": "led_velocity_threshold_84"
553
+ },
554
+ "smart_accelerometer_threshold": {
555
+ "read_index": 36,
556
+ "write_index": 25,
557
+ "descriptions": {
558
+ "title": "Probe 1: Set Smart Mode Threshold",
559
+ "main_caption": "<p>If RMS acceleration is above this in any axis...</p>"
560
+ },
561
+ "default_value": 1,
562
+ "validator": {
563
+ "type": "uint8",
564
+ "min": 1,
565
+ "max": 40
566
+ },
567
+ "depends_on": {
568
+ "operation_mode": 3
569
+ },
570
+ "html_id": "smart_threshold_110",
571
+ "old_fly_id": "smart_mode_acc_threshold"
572
+ },
573
+ "led_alert_mode": {
574
+ "read_index": 37,
575
+ "write_index": 26,
576
+ "descriptions": {
577
+ "title": "LED Alert Mode",
578
+ "main_caption": "<p>Choose whether the LED indicator should be based on Acceleration or Velocity</p>"
579
+ },
580
+ "default_value": 0,
581
+ "validator": {
582
+ "type": "uint8",
583
+ "min": 0,
584
+ "max": 1,
585
+ "generated": true
586
+ },
587
+ "options": {
588
+ "0": "Acceleration",
589
+ "1": "Velocity"
590
+ },
591
+ "html_id": "led_alert_mode_84"
592
+ },
593
+ "raw_packet_length": {
594
+ "read_index": 38,
595
+ "write_index": 27,
596
+ "descriptions": {
597
+ "title": "Payload Length",
598
+ "main_caption": "<p>Set the size of the data payload...</p>",
599
+ "sub_caption": "<p class=\"caption\"><i>Note: For the 2.4GHz version you need to operate with a 55 Byte payload.</i></p>"
600
+ },
601
+ "default_value": 3,
602
+ "validator": {
603
+ "type": "uint8",
604
+ "min": 0,
605
+ "max": 3,
606
+ "generated": true
607
+ },
608
+ "options": {
609
+ "0": "55 Bytes",
610
+ "1": "100 Bytes",
611
+ "2": "150 Bytes",
612
+ "3": "180 Bytes"
613
+ },
614
+ "tags": [
615
+ "Communications"
616
+ ],
617
+ "html_id": "payload_length_80",
618
+ "old_fly_id": "payload_length"
619
+ },
620
+ "auto_raw_interval": {
621
+ "read_index": 39,
622
+ "write_index": 28,
623
+ "descriptions": {
624
+ "title": "Set Auto Raw Interval",
625
+ "main_caption": "<p>Set the Auto Time Domain (Raw) data transmission Interval...</p>",
626
+ "sub_caption": "<p class=\"caption\"><i>Note: Auto Raw Transmission is disabled by default.</i></p>"
627
+ },
628
+ "default_value": 0,
629
+ "validator": {
630
+ "type": "uint8",
631
+ "min": 0,
632
+ "max": 255,
633
+ "generated": true
634
+ },
635
+ "depends_on": {
636
+ "operation_mode": 3
637
+ },
638
+ "tags": [
639
+ "Communications"
640
+ ],
641
+ "html_id": "auto_raw_interval_110"
642
+ },
643
+ "auto_raw_destination_address": {
644
+ "read_index": 40,
645
+ "write_index": 29,
646
+ "length": 4,
647
+ "descriptions": {
648
+ "title": "Set Auto Raw Destination Address",
649
+ "main_caption": "<p>Set the address where the Auto Time Domain (Raw) data will be transmitted...</p>",
650
+ "sub_caption": "<p class=\"caption\">Default value: 0000FFFF for Broadcast Mode</p>"
651
+ },
652
+ "default_value": "0000FFFF",
653
+ "validator": {
654
+ "type": "mac",
655
+ "length": 8,
656
+ "generated": true
657
+ },
658
+ "depends_on": {
659
+ "operation_mode": 3
660
+ },
661
+ "html_id": "auto_raw_destination_110"
662
+ },
663
+ "smart_mode_skip_count": {
664
+ "read_index": 44,
665
+ "write_index": 33,
666
+ "descriptions": {
667
+ "title": "Set Smart Mode Skip Interval",
668
+ "main_caption": "<p>Sensor will skip sending data this many times if vibration is below the smart threshold.</p>"
669
+ },
670
+ "default_value": 0,
671
+ "validator": {
672
+ "type": "uint8",
673
+ "min": 0,
674
+ "max": 255,
675
+ "generated": true
676
+ },
677
+ "depends_on": {
678
+ "operation_mode": 3
679
+ },
680
+ "html_id": "smart_interval_110"
681
+ },
682
+ "sync_interval": {
683
+ "read_index": 45,
684
+ "write_index": 34,
685
+ "descriptions": {
686
+ "title": "Set FLY Interval",
687
+ "main_caption": "<p>Set the interval at which the sensor will transmit FLY packets...</p>"
688
+ },
689
+ "default_value": 60,
690
+ "validator": {
691
+ "type": "uint16be",
692
+ "min": 0,
693
+ "max": 1440,
694
+ "generated": true
695
+ },
696
+ "options": {
697
+ "60": "1 Hour",
698
+ "120": "2 Hours",
699
+ "240": "4 Hours",
700
+ "480": "8 Hours",
701
+ "720": "12 Hours",
702
+ "1080": "18 Hours",
703
+ "1440": "24 Hours"
704
+ },
705
+ "tags": [
706
+ "Communications"
707
+ ],
708
+ "html_id": "fly_interval_110"
709
+ },
710
+ "rpm_compute_status": {
711
+ "read_index": 47,
712
+ "write_index": 36,
713
+ "descriptions": {
714
+ "title": "RPM Calculate Status",
715
+ "main_caption": "<p>Enable/Disable Revolutions Per Minute Calculate Status</p>"
716
+ },
717
+ "default_value": 0,
718
+ "validator": {
719
+ "type": "uint8",
720
+ "min": 0,
721
+ "max": 1,
722
+ "generated": true
723
+ },
724
+ "options": {
725
+ "0": "Disabled",
726
+ "1": "Enabled"
727
+ },
728
+ "html_id": "enable_rpm_calculate_status_110"
729
+ },
730
+ "max_raw_samples": {
731
+ "read_index": 48,
732
+ "write_index": 37,
733
+ "descriptions": {
734
+ "title": "Set Max Raw Sample",
735
+ "main_caption": "<p>Set the maximum number of samples...</p>"
736
+ },
737
+ "default_value": 0,
738
+ "validator": {
739
+ "type": "uint16be",
740
+ "min": 1024,
741
+ "max": 8100
742
+ },
743
+ "options": {
744
+ "1024": "1024 Samples",
745
+ "2048": "2048 Samples",
746
+ "4096": "4096 Samples",
747
+ "6400": "6400 Samples",
748
+ "8100": "8100 Samples"
749
+ },
750
+ "html_id": "max_raw_sample_110",
751
+ "old_fly_id": "max_tx_raw_samples"
752
+ },
753
+ "motion_to_sampling_delay": {
754
+ "read_index": 50,
755
+ "write_index": 39,
756
+ "descriptions": {
757
+ "title": "Set Motion to Sampling Delay",
758
+ "main_caption": "<p>Once motion is detected, the sensor will wait...</p>"
759
+ },
760
+ "default_value": 100,
761
+ "validator": {
762
+ "type": "uint8",
763
+ "min": 0,
764
+ "max": 255,
765
+ "generated": true
766
+ },
767
+ "html_id": "motion_to_sampling_delay_110"
768
+ },
769
+ "max_motion_tx_per_interval": {
770
+ "read_index": 51,
771
+ "write_index": 40,
772
+ "descriptions": {
773
+ "title": "Set Max Number Motion Tx Per Interval",
774
+ "main_caption": "<p>Set Number of times it will send data due to motion triggers.</p>"
775
+ },
776
+ "default_value": 1,
777
+ "validator": {
778
+ "type": "uint8",
779
+ "min": 1,
780
+ "max": 255,
781
+ "generated": true
782
+ },
783
+ "html_id": "max_num_motion_tx_delay_110",
784
+ "old_fly_id": "max_num_of_motion_tx_per_interval"
785
+ }
786
+ };
787
+ };
788
+
789
+ const sync_parse = (rep_buffer) => {
790
+ let response = {
791
+ 'human_readable': {},
792
+ 'machine_values': {}
793
+ };
794
+
795
+ // Get the map based on the sensor type byte
796
+ const sync_map = get_config_map(rep_buffer[4]);
797
+
798
+ for (const [key, config] of Object.entries(sync_map)) {
799
+ // Destructure 'type' from inside 'validator' and rename 'read_index' to 'idx'
800
+ const { read_index: idx, length, validator: { type } = {}, converter, options } = config;
801
+
802
+ // If for some reason a config doesn't have a validator/type, skip it
803
+ if (!type) continue;
804
+
805
+ switch (type) {
806
+ case 'uint8':
807
+ response.machine_values[key] = rep_buffer[idx];
808
+ break;
809
+ case 'uint16be':
810
+ response.machine_values[key] = rep_buffer.readUInt16BE(idx);
811
+ break;
812
+ case 'uint32be':
813
+ response.machine_values[key] = rep_buffer.readUInt32BE(idx);
814
+ break;
815
+ case 'buffer':
816
+ response.machine_values[key] = rep_buffer.subarray(idx, idx + length);
817
+ break;
818
+ case 'hex':
819
+ response.machine_values[key] = rep_buffer.subarray(idx, idx + length).toString('hex');
820
+ break;
821
+ case 'mac':
822
+ response.machine_values[key] = rep_buffer.subarray(idx, idx + length).toString('hex');
823
+ break;
824
+ }
825
+ let human_value = response.machine_values[key];
826
+ if(options && options[response.machine_values[key]]){
827
+ human_value = options[response.machine_values[key]];
828
+ }else{
829
+ if(converter && converter.multiplier){
830
+ human_value = human_value * converter.multiplier;
831
+ }
832
+ if(converter && converter.units){
833
+ human_value = human_value + converter.units;
834
+ }
835
+ }
836
+ response.human_readable[key] = human_value;
837
+ }
838
+ if (Object.hasOwn(response.machine_values, 'destination_address') && response.machine_values.destination_address.toLowerCase() === '00000000') {
839
+ console.log('##############################');
840
+ console.log('#########Dest Override########');
841
+ console.log('##############################');
842
+ response.destination_address = "0000ffff";
843
+ response.auto_raw_destination_address = "0000ffff";
844
+ };
845
+ return response;
846
+ };
847
+
848
+ const parse_fly = (frame) => {
849
+ let frame_data = {};
850
+ switch(frame[16]){
851
+ case 0:
852
+ frame_data.mode = "Processed";
853
+ break;
854
+ case 1:
855
+ frame_data.mode = "Raw";
856
+ break;
857
+ case 2:
858
+ frame_data.mode = "Processed + Raw on demand";
859
+ break;
860
+ case 3:
861
+ frame_data.mode = "Smart";
862
+ break;
863
+ }
864
+ switch(frame[17]){
865
+ case 6:
866
+ frame_data.odr_1 = 50;
867
+ break;
868
+ case 7:
869
+ frame_data.odr_1 = 100;
870
+ break;
871
+ case 8:
872
+ frame_data.odr_1 = 200;
873
+ break;
874
+ case 9:
875
+ frame_data.odr_1 = 400;
876
+ break;
877
+ case 10:
878
+ frame_data.odr_1 = 800;
879
+ break;
880
+ case 11:
881
+ frame_data.odr_1 = 1600;
882
+ break;
883
+ case 12:
884
+ frame_data.odr_1 = 3200;
885
+ break;
886
+ case 13:
887
+ frame_data.odr_1 = 6400;
888
+ break;
889
+ case 14:
890
+ frame_data.odr_1 = 12800;
891
+ break;
892
+ case 15:
893
+ frame_data.odr_1 = 25600;
894
+ break;
895
+ }
896
+ frame_data.sampling_duration_1 = frame[18]*50 + "ms";
897
+ switch(frame[19]){
898
+ case 0:
899
+ frame_data.filter_status = "Disabled";
900
+ break;
901
+ case 1:
902
+ frame_data.filter_status = "Enabled";
903
+ break;
904
+ }
905
+ switch(frame[20]){
906
+ case 0:
907
+ frame_data.lpf_coeff_1 = 4;
908
+ break;
909
+ case 1:
910
+ frame_data.lpf_coeff_1 = 8;
911
+ break;
912
+ case 2:
913
+ frame_data.lpf_coeff_1 = 16;
914
+ break;
915
+ case 2:
916
+ frame_data.lpf_coeff_1 = 32;
917
+ break;
918
+ case 4:
919
+ frame_data.lpf_coeff_1 = 64;
920
+ break;
921
+ case 5:
922
+ frame_data.lpf_coeff_1 = 128;
923
+ break;
924
+ case 6:
925
+ frame_data.lpf_coeff_1 = 256;
926
+ break;
927
+ case 7:
928
+ frame_data.lpf_coeff_1 = 512;
929
+ break;
930
+ case 8:
931
+ frame_data.lpf_coeff_1 = 1024;
932
+ break;
933
+ case 9:
934
+ frame_data.lpf_coeff_1 = 2048;
935
+ break;
936
+ }
937
+ frame_data.lpf_freq_1 = frame_data.odr_1 / frame_data.lpf_coeff_1;
938
+ switch(frame[21]){
939
+ case 0:
940
+ frame_data.hpf_coeff_1 = 4;
941
+ break;
942
+ case 1:
943
+ frame_data.hpf_coeff_1 = 8;
944
+ break;
945
+ case 2:
946
+ frame_data.hpf_coeff_1 = 16;
947
+ break;
948
+ case 2:
949
+ frame_data.hpf_coeff_1 = 32;
950
+ break;
951
+ case 4:
952
+ frame_data.hpf_coeff_1 = 64;
953
+ break;
954
+ case 5:
955
+ frame_data.hpf_coeff_1 = 128;
956
+ break;
957
+ case 6:
958
+ frame_data.hpf_coeff_1 = 256;
959
+ break;
960
+ case 7:
961
+ frame_data.hpf_coeff_1 = 512;
962
+ break;
963
+ case 8:
964
+ frame_data.hpf_coeff_1 = 1024;
965
+ break;
966
+ case 9:
967
+ frame_data.hpf_coeff_1 = 2048;
968
+ break;
969
+ }
970
+ frame_data.hpf_freq_1 = frame_data.odr_1 / frame_data.hpf_coeff_1;
971
+ switch(frame[22]){
972
+ case 0:
973
+ frame_data.sampling_interval = "5 Minutes";
974
+ frame_data.sampling_interval_number = 5;
975
+ break;
976
+ case 1:
977
+ frame_data.sampling_interval = "10 Minutes";
978
+ frame_data.sampling_interval_number = 10;
979
+ break;
980
+ case 2:
981
+ frame_data.sampling_interval = "15 Minutes";
982
+ frame_data.sampling_interval_number = 15;
983
+ break;
984
+ case 2:
985
+ frame_data.sampling_interval = "20 Minutes";
986
+ frame_data.sampling_interval_number = 20;
987
+ break;
988
+ case 4:
989
+ frame_data.sampling_interval = "30 Minutes";
990
+ frame_data.sampling_interval_number = 30;
991
+ break;
992
+ case 5:
993
+ frame_data.sampling_interval = "60 Minutes";
994
+ frame_data.sampling_interval_number = 60;
995
+ break;
996
+ case 6:
997
+ frame_data.sampling_interval = "120 Minutes";
998
+ frame_data.sampling_interval_number = 120;
999
+ break;
1000
+ case 7:
1001
+ frame_data.sampling_interval = "180 Minutes";
1002
+ frame_data.sampling_interval_number = 180;
1003
+ break;
1004
+ case 8:
1005
+ frame_data.sampling_interval = "1 Minute";
1006
+ frame_data.sampling_interval_number = 1;
1007
+ break;
1008
+ }
1009
+ frame_data.on_request_timeout = frame[23] + " Seconds";
1010
+ frame_data.deadband = frame[24] + "mg";
1011
+
1012
+ switch(frame[25]){
1013
+ case 0:
1014
+ frame_data.payload_length = "50 Bytes";
1015
+ break;
1016
+ case 1:
1017
+ frame_data.payload_length = "100 Bytes";
1018
+ break;
1019
+ case 2:
1020
+ frame_data.payload_length = "150 Bytes";
1021
+ break;
1022
+ case 3:
1023
+ frame_data.payload_length = "180 Bytes";
1024
+ break;
1025
+ }
1026
+ switch(frame[26]){
1027
+ case 0:
1028
+ frame_data.fsr_text = "2g";
1029
+ break;
1030
+ case 1:
1031
+ frame_data.fsr_text = "4g";
1032
+ break;
1033
+ case 2:
1034
+ frame_data.fsr_text = "8g";
1035
+ break;
1036
+ case 3:
1037
+ frame_data.fsr_text = "16g";
1038
+ break;
1039
+ }
1040
+ frame_data.rpm_status = frame[27]? 'Enabled': 'Disabled';
1041
+ frame_data.auto_raw_interval = frame[32] * frame_data.sampling_interval_number || 'disabled';
1042
+ frame_data.auto_raw_interval = typeof frame_data.auto_raw_interval === 'number' ? frame_data.auto_raw_interval+'min' : frame_data.auto_raw_interval;
1043
+ frame_data.smart_mode_threshold = frame[34] * 50;
1044
+ if(frame[2] > 5){ // for Firmware v6 and above
1045
+ frame_data.motion_to_delay = frame[41] * 50;
1046
+ return {
1047
+ 'firmware': frame[2],
1048
+ 'destination_address': toMac(frame.slice(12, 16)),
1049
+ 'mode': frame_data.mode,
1050
+ 'odr': frame_data.odr_1+'Hz',
1051
+ 'sampling_duration': frame_data.sampling_duration_1,
1052
+ 'filter_status': frame_data.filter_status,
1053
+ 'lpf_coeff': frame_data.lpf_coeff_1,
1054
+ 'lpf_freq': frame_data.lpf_freq_1+'Hz',
1055
+ 'hpf_coeff': frame_data.hpf_coeff_1,
1056
+ 'hpf_freq': frame_data.hpf_freq_1+'Hz',
1057
+ 'sampling_interval': frame_data.sampling_interval,
1058
+ 'on_request_timeout': frame_data.on_request_timeout,
1059
+ 'deadband': frame_data.deadband,
1060
+ 'payload_length': frame_data.payload_length,
1061
+ 'fsr': frame_data.fsr_text,
1062
+ 'rpm_compute_status': frame_data.rpm_status,
1063
+ 'auto_raw_destination_address': toMac(frame.slice(28 , 32)),
1064
+ 'auto_raw_interval': frame_data.auto_raw_interval,
1065
+ 'smart_mode_skip_count': frame[33],
1066
+ 'smart_mode_acc_threshold':frame_data.smart_mode_threshold+'mg',
1067
+ 'uptime_counter': frame.slice(35, 39).reduce(msbLsb)+'sec',
1068
+ 'max_tx_raw_samples': frame.slice(39, 41).reduce(msbLsb),
1069
+ 'motion_to_sampling_delay': frame_data.motion_to_delay +'msec',
1070
+ 'max_num_of_motion_tx_per_interval': frame[42],
1071
+ 'hardware_id': frame.slice(43, 46),
1072
+ 'reserved': frame.slice(46, 50),
1073
+ 'tx_lifetime_counter': frame.slice(50, 54).reduce(msbLsb),
1074
+ 'machine_values': {
1075
+ 'firmware': frame[2],
1076
+ 'destination_address': toMac(frame.slice(12, 16), false),
1077
+ 'mode': frame[16],
1078
+ 'odr': frame[17],
1079
+ 'sampling_duration': frame[18],
1080
+ 'filter_status': frame[19],
1081
+ 'lpf_coeff': frame[20],
1082
+ 'hpf_coeff': frame[21],
1083
+ 'sampling_interval': frame[22],
1084
+ 'on_request_timeout': frame[23],
1085
+ 'deadband': frame[24],
1086
+ 'payload_length': frame[25],
1087
+ 'fsr': frame[26],
1088
+ 'rpm_compute_status': frame[27],
1089
+ 'auto_raw_destination_address': toMac(frame.slice(28 , 32), false),
1090
+ 'auto_raw_interval': frame[32],
1091
+ 'smart_mode_skip_count': frame[33],
1092
+ 'smart_mode_acc_threshold':frame[34],
1093
+ 'uptime_counter': frame.slice(35, 39),
1094
+ 'max_tx_raw_samples': frame.slice(39, 41),
1095
+ 'motion_to_sampling_delay': frame[41],
1096
+ 'max_num_of_motion_tx_per_interval': frame[42],
1097
+ 'hardware_id': frame.slice(43, 46),
1098
+ 'reserved': frame.slice(46, 50),
1099
+ 'tx_lifetime_counter': frame.slice(50, 54)
1100
+ }
1101
+ }
1102
+ } else if(frame[2] > 4){ // for Firmware v5 and above
1103
+ return {
1104
+ 'firmware': frame[2],
1105
+ 'destination_address': toMac(frame.slice(12, 16)),
1106
+ 'mode': frame_data.mode,
1107
+ 'odr': frame_data.odr_1+'Hz',
1108
+ 'sampling_duration': frame_data.sampling_duration_1,
1109
+ 'filter_status': frame_data.filter_status,
1110
+ 'lpf_coeff': frame_data.lpf_coeff_1,
1111
+ 'lpf_freq': frame_data.lpf_freq_1+'Hz',
1112
+ 'hpf_coeff': frame_data.hpf_coeff_1,
1113
+ 'hpf_freq': frame_data.hpf_freq_1+'Hz',
1114
+ 'sampling_interval': frame_data.sampling_interval,
1115
+ 'on_request_timeout': frame_data.on_request_timeout,
1116
+ 'deadband': frame_data.deadband,
1117
+ 'payload_length': frame_data.payload_length,
1118
+ 'fsr': frame_data.fsr_text,
1119
+ 'rpm_compute_status': frame_data.rpm_status,
1120
+ 'auto_raw_destination_address': toMac(frame.slice(28 , 32)),
1121
+ 'auto_raw_interval': frame_data.auto_raw_interval,
1122
+ 'smart_mode_skip_count': frame[33],
1123
+ 'smart_mode_acc_threshold':frame_data.smart_mode_threshold+'mg',
1124
+ 'uptime_counter': frame.slice(35, 39).reduce(msbLsb)+'sec',
1125
+ 'max_tx_raw_samples': frame.slice(39, 41).reduce(msbLsb),
1126
+ 'hardware_id': frame.slice(41, 44),
1127
+ 'reserved': frame.slice(44, 48),
1128
+ 'tx_lifetime_counter': frame.slice(48, 52).reduce(msbLsb),
1129
+ 'machine_values': {
1130
+ 'firmware': frame[2],
1131
+ 'destination_address': toMac(frame.slice(12, 16), false),
1132
+ 'mode': frame[16],
1133
+ 'odr': frame[17],
1134
+ 'sampling_duration': frame[18],
1135
+ 'filter_status': frame[19],
1136
+ 'lpf_coeff': frame[20],
1137
+ 'hpf_coeff': frame[21],
1138
+ 'sampling_interval': frame[22],
1139
+ 'on_request_timeout': frame[23],
1140
+ 'deadband': frame[24],
1141
+ 'payload_length': frame[25],
1142
+ 'fsr': frame[26],
1143
+ 'rpm_compute_status': frame[27],
1144
+ 'auto_raw_destination_address': toMac(frame.slice(28 , 32), false),
1145
+ 'auto_raw_interval': frame[32],
1146
+ 'smart_mode_skip_count': frame[33],
1147
+ 'smart_mode_acc_threshold':frame[34],
1148
+ 'uptime_counter': frame.slice(35, 39),
1149
+ 'max_tx_raw_samples': frame.slice(39, 41),
1150
+ 'hardware_id': frame.slice(41, 44),
1151
+ 'reserved': frame.slice(44, 48),
1152
+ 'tx_lifetime_counter': frame.slice(48, 52)
1153
+ }
1154
+ }
1155
+ }else{
1156
+ return {
1157
+ 'firmware': frame[2],
1158
+ 'destination_address': toMac(frame.slice(12, 16)),
1159
+ 'mode': frame_data.mode,
1160
+ 'odr': frame_data.odr_1+'Hz',
1161
+ 'sampling_duration': frame_data.sampling_duration_1,
1162
+ 'filter_status': frame_data.filter_status,
1163
+ 'lpf_coeff': frame_data.lpf_coeff_1,
1164
+ 'lpf_freq': frame_data.lpf_freq_1+'Hz',
1165
+ 'hpf_coeff': frame_data.hpf_coeff_1,
1166
+ 'hpf_freq': frame_data.hpf_freq_1+'Hz',
1167
+ 'sampling_interval': frame_data.sampling_interval,
1168
+ 'on_request_timeout': frame_data.on_request_timeout,
1169
+ 'deadband': frame_data.deadband,
1170
+ 'payload_length': frame_data.payload_length,
1171
+ 'fsr': frame_data.fsr_text,
1172
+ 'rpm_compute_status': frame_data.rpm_status,
1173
+ 'auto_raw_destination_address': toMac(frame.slice(28 , 32)),
1174
+ 'auto_raw_interval': frame_data.auto_raw_interval,
1175
+ 'smart_mode_skip_count': frame[33],
1176
+ 'smart_mode_acc_threshold':frame_data.smart_mode_threshold+'mg',
1177
+ 'uptime_counter': frame.slice(35, 39).reduce(msbLsb)+'sec',
1178
+ 'hardware_id': frame.slice(39, 42),
1179
+ 'reserved': frame.slice(42, 46),
1180
+ 'tx_lifetime_counter': frame.slice(46, 50).reduce(msbLsb),
1181
+ 'machine_values': {
1182
+ 'firmware': frame[2],
1183
+ 'destination_address': toMac(frame.slice(12, 16), false),
1184
+ 'mode': frame[16],
1185
+ 'odr': frame[17],
1186
+ 'sampling_duration': frame[18],
1187
+ 'filter_status': frame[19],
1188
+ 'lpf_coeff': frame[20],
1189
+ 'hpf_coeff': frame[21],
1190
+ 'sampling_interval': frame[22],
1191
+ 'on_request_timeout': frame[23],
1192
+ 'deadband': frame[24],
1193
+ 'payload_length': frame[25],
1194
+ 'fsr': frame[26],
1195
+ 'rpm_compute_status': frame[27],
1196
+ 'auto_raw_destination_address': toMac(frame.slice(28 , 32), false),
1197
+ 'auto_raw_interval': frame[32],
1198
+ 'smart_mode_skip_count': frame[33],
1199
+ 'smart_mode_acc_threshold':frame[34],
1200
+ 'uptime_counter': frame.slice(35, 39),
1201
+ 'hardware_id': frame.slice(39, 42),
1202
+ 'reserved': frame.slice(42, 46),
1203
+ 'tx_lifetime_counter': frame.slice(46, 50)
1204
+ }
1205
+ }
1206
+ }
1207
+ };
1208
+
1209
+ const parse = (payload, parsed, mac) => {
1210
+ if (payload[7] & 2) {
1211
+ console.log('Error found');
1212
+ parsed.data = { error: 'Error found, Sensor Probe may be unattached' };
1213
+ return parsed;
1214
+ }
1215
+ let msg_type = (payload[7] & 16) ? 'motion' : 'regular';
1216
+ if (payload[8] === 1) {
1217
+
1218
+ var deviceAddr = mac;
1219
+ var expected_packets = msbLsb(payload[16], payload[17]);
1220
+ var current_packet = msbLsb(payload[18], payload[19]);
1221
+ var sdata_start = 20;
1222
+
1223
+ if (globalDevices.hasOwnProperty(deviceAddr) || expected_packets == 1) {
1224
+ if (expected_packets != 1) {
1225
+ if (globalDevices[deviceAddr].last_packet_counter == current_packet) {
1226
+ console.log('Duplicated message');
1227
+ return;
1228
+ }
1229
+ if (current_packet == 1 || (globalDevices[deviceAddr].last_packet_counter > current_packet)) {
1230
+ console.log('Recovering bad packet');
1231
+ clear_globalDevices_stream(deviceAddr);
1232
+ init_globalDevices_stream(deviceAddr, payload, expected_packets, parsed, msg_type);
1233
+ globalDevices[deviceAddr].last_packet_counter = current_packet;
1234
+ globalDevices[deviceAddr].data[current_packet] = payload.slice(sdata_start);
1235
+ return;
1236
+ }
1237
+ else {
1238
+ globalDevices[deviceAddr].last_packet_counter = current_packet;
1239
+ globalDevices[deviceAddr].data[current_packet] = payload.slice(sdata_start);
1240
+ }
1241
+ }
1242
+ else {
1243
+ clear_globalDevices_stream(deviceAddr);
1244
+ init_globalDevices_stream(deviceAddr, payload, expected_packets, parsed, msg_type);
1245
+ globalDevices[deviceAddr].last_packet_counter = current_packet;
1246
+ globalDevices[deviceAddr].data[current_packet] = payload.slice(sdata_start);
1247
+ }
1248
+ }
1249
+ else {
1250
+ clear_globalDevices_stream(deviceAddr);
1251
+ init_globalDevices_stream(deviceAddr, payload, expected_packets, parsed, msg_type);
1252
+ globalDevices[deviceAddr].last_packet_counter = current_packet;
1253
+ globalDevices[deviceAddr].data[current_packet] = payload.slice(sdata_start);
1254
+ }
1255
+ if (current_packet == expected_packets) {
1256
+ sensor_data = concat_fft_data(deviceAddr, payload[8], msg_type);
1257
+ clear_globalDevices_stream(deviceAddr);
1258
+ return sensor_data;
1259
+ }
1260
+ else {
1261
+ return;
1262
+ }
1263
+ }
1264
+ else if (payload[8] === 0 || payload[8] === 2 || payload[8] === 3) {
1265
+ var odr;
1266
+ switch (payload[9]) {
1267
+ case 6: odr = "50Hz"; break;
1268
+ case 7: odr = "100Hz"; break;
1269
+ case 8: odr = "200Hz"; break;
1270
+ case 9: odr = "400Hz"; break;
1271
+ case 10: odr = "800Hz"; break;
1272
+ case 11: odr = "1600Hz"; break;
1273
+ case 12: odr = "3200Hz"; break;
1274
+ case 13: odr = "6400Hz"; break;
1275
+ case 14: odr = "12800Hz"; break;
1276
+ case 15: odr = "25600Hz"; break;
1277
+ }
1278
+ return {
1279
+ mode: payload[8],
1280
+ msg_type: msg_type,
1281
+ odr: odr,
1282
+ temperature: signInt(payload.slice(10, 12).reduce(msbLsb), 16) / 100,
1283
+ x_rms_ACC_G: payload.slice(12, 14).reduce(msbLsb) / 1000,
1284
+ x_max_ACC_G: payload.slice(14, 16).reduce(msbLsb) / 1000,
1285
+ x_velocity_mm_sec: payload.slice(16, 18).reduce(msbLsb) / 100,
1286
+ x_displacement_mm: payload.slice(18, 20).reduce(msbLsb) / 100,
1287
+ x_peak_one_Hz: payload.slice(20, 22).reduce(msbLsb),
1288
+ x_peak_two_Hz: payload.slice(22, 24).reduce(msbLsb),
1289
+ x_peak_three_Hz: payload.slice(24, 26).reduce(msbLsb),
1290
+ y_rms_ACC_G: payload.slice(26, 28).reduce(msbLsb) / 1000,
1291
+ y_max_ACC_G: payload.slice(28, 30).reduce(msbLsb) / 1000,
1292
+ y_velocity_mm_sec: payload.slice(30, 32).reduce(msbLsb) / 100,
1293
+ y_displacement_mm: payload.slice(32, 34).reduce(msbLsb) / 100,
1294
+ y_peak_one_Hz: payload.slice(34, 36).reduce(msbLsb),
1295
+ y_peak_two_Hz: payload.slice(36, 38).reduce(msbLsb),
1296
+ y_peak_three_Hz: payload.slice(38, 40).reduce(msbLsb),
1297
+ z_rms_ACC_G: payload.slice(40, 42).reduce(msbLsb) / 1000,
1298
+ z_max_ACC_G: payload.slice(42, 44).reduce(msbLsb) / 1000,
1299
+ z_velocity_mm_sec: payload.slice(44, 46).reduce(msbLsb) / 100,
1300
+ z_displacement_mm: payload.slice(46, 48).reduce(msbLsb) / 100,
1301
+ z_peak_one_Hz: payload.slice(48, 50).reduce(msbLsb),
1302
+ z_peak_two_Hz: payload.slice(50, 52).reduce(msbLsb),
1303
+ z_peak_three_Hz: payload.slice(52, 54).reduce(msbLsb),
1304
+ rpm: payload.slice(54, 56).reduce(msbLsb)
1305
+ };
1306
+ }
1307
+ };
1308
+
1309
+ // Export the module with all the necessary functions and properties
1310
+ // that need to be called from outside the scrip
1311
+ return {
1312
+ type: 110,
1313
+ name: 'One Channel Vibration Plus v4',
1314
+ parse,
1315
+ get_write_buffer_size,
1316
+ get_config_map,
1317
+ sync_parse,
1318
+ parse_fly,
1319
+ };
1320
+ };