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

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,619 @@
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 39;
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
+ "debouncing_timeout": {
138
+ "read_index": 21,
139
+ "write_index": 10,
140
+ "descriptions": {
141
+ "title": "Set Input Debounce Time",
142
+ "main_caption": "Configures the debounce time in milliseconds for all inputs. State changes occurring within this debounce period will be ignored."
143
+ },
144
+ "default_value": 10,
145
+ "validator": {
146
+ "type": "uint16be",
147
+ "min": 10,
148
+ "max": 65000,
149
+ "generated": true
150
+ },
151
+ "html_id": "debounce_time_123"
152
+ },
153
+ "input_1_active_edge": {
154
+ "read_index": 23,
155
+ "write_index": 12,
156
+ "descriptions": {
157
+ "title": "Set Input 1 Detection",
158
+ "main_caption": "Configures how the counter increments and how uptime is calculated for Input 1."
159
+ },
160
+ "default_value": 0,
161
+ "validator": {
162
+ "type": "uint8",
163
+ "min": 0,
164
+ "max": 1,
165
+ "generated": true
166
+ },
167
+ "options": {
168
+ "0": "Falling Edge Trigger",
169
+ "1": "Rising Edge Trigger"
170
+ },
171
+ "html_id": "input_one_123"
172
+ },
173
+ "input_2_active_edge": {
174
+ "read_index": 24,
175
+ "write_index": 13,
176
+ "descriptions": {
177
+ "title": "Set Input 2 Detection",
178
+ "main_caption": "Configures how the counter increments and how uptime is calculated for Input 2."
179
+ },
180
+ "default_value": 0,
181
+ "validator": {
182
+ "type": "uint8",
183
+ "min": 0,
184
+ "max": 1,
185
+ "generated": true
186
+ },
187
+ "options": {
188
+ "0": "Falling Edge Trigger",
189
+ "1": "Rising Edge Trigger"
190
+ },
191
+ "html_id": "input_two_123"
192
+ },
193
+ "counter_threshold": {
194
+ "read_index": 25,
195
+ "write_index": 14,
196
+ "descriptions": {
197
+ "title": "Counter Threshold",
198
+ "main_caption": "The sensor will transmit data when any connected counter reaches a multiple of this threshold value."
199
+ },
200
+ "default_value": 0,
201
+ "validator": {
202
+ "type": "uint32be",
203
+ "min": 1,
204
+ "max": 65534,
205
+ "generated": true
206
+ },
207
+ "html_id": "counter_threshold_108"
208
+ },
209
+ "trasnmit_on_change_status": {
210
+ "read_index": 29,
211
+ "write_index": 18,
212
+ "descriptions": {
213
+ "title": "Enable Push Notification",
214
+ "main_caption": "Enables the sensor to immediately transmit data upon detecting a signal change on the specified input(s)."
215
+ },
216
+ "default_value": 0,
217
+ "validator": {
218
+ "type": "uint8",
219
+ "min": 0,
220
+ "max": 7,
221
+ "generated": true
222
+ },
223
+ "options": {
224
+ "0": "Disabled",
225
+ "1": "Enable on IO1",
226
+ "2": "Enable on IO2",
227
+ "3": "Enable on IO3",
228
+ "4": "Enable on IO1 and IO2",
229
+ "5": "Enable on IO1 and IO3",
230
+ "6": "Enable on IO2 and IO3",
231
+ "7": "Enable All"
232
+ },
233
+ "html_id": "push_notification_123"
234
+ },
235
+ "shift_end_one_hours": {
236
+ "read_index": 30,
237
+ "write_index": 19,
238
+ "descriptions": {
239
+ "title": "Shift 1 End Time Hours",
240
+ "main_caption": "Based on the Real-Time Clock (RTC), configures one of four specific daily times (24-hour format) for the sensor to perform an automatic reset."
241
+ },
242
+ "default_value": 0,
243
+ "validator": {
244
+ "type": "uint8",
245
+ "min": 0,
246
+ "max": 24,
247
+ "generated": true
248
+ },
249
+ "html_id": "shift_one_hours_108",
250
+ "html_active_id": "shift_one_108_active"
251
+ },
252
+ "shift_end_one_minutes": {
253
+ "read_index": 31,
254
+ "write_index": 20,
255
+ "descriptions": {
256
+ "title": "Shift 1 End Time Minutes",
257
+ "main_caption": "Based on the Real-Time Clock (RTC), configures one of four specific daily times (24-hour format) for the sensor to perform an automatic reset."
258
+ },
259
+ "default_value": 0,
260
+ "validator": {
261
+ "type": "uint8",
262
+ "min": 0,
263
+ "max": 60,
264
+ "generated": true
265
+ },
266
+ "html_id": "shift_one_minutes_108",
267
+ "html_active_id": "shift_one_108_active"
268
+ },
269
+ "shift_end_two_hours": {
270
+ "read_index": 32,
271
+ "write_index": 21,
272
+ "descriptions": {
273
+ "title": "Shift 2 End Time Hours",
274
+ "main_caption": "Based on the Real-Time Clock (RTC), configures two of four specific daily times (24-hour format) for the sensor to perform an automatic reset."
275
+ },
276
+ "default_value": 0,
277
+ "validator": {
278
+ "type": "uint8",
279
+ "min": 0,
280
+ "max": 24,
281
+ "generated": true
282
+ },
283
+ "html_id": "shift_two_hours_108",
284
+ "html_active_id": "shift_two_108_active"
285
+ },
286
+ "shift_end_two_minutes": {
287
+ "read_index": 33,
288
+ "write_index": 22,
289
+ "descriptions": {
290
+ "title": "Shift 2 End Time Minutes",
291
+ "main_caption": "Based on the Real-Time Clock (RTC), configures two of four specific daily times (24-hour format) for the sensor to perform an automatic reset."
292
+ },
293
+ "default_value": 0,
294
+ "validator": {
295
+ "type": "uint8",
296
+ "min": 0,
297
+ "max": 60,
298
+ "generated": true
299
+ },
300
+ "html_id": "shift_two_minutes_108",
301
+ "html_active_id": "shift_two_108_active"
302
+ },
303
+ "shift_end_three_hours": {
304
+ "read_index": 34,
305
+ "write_index": 23,
306
+ "descriptions": {
307
+ "title": "Shift 3 End Time Hours",
308
+ "main_caption": "Based on the Real-Time Clock (RTC), configures three of four specific daily times (24-hour format) for the sensor to perform an automatic reset."
309
+ },
310
+ "default_value": 0,
311
+ "validator": {
312
+ "type": "uint8",
313
+ "min": 0,
314
+ "max": 24,
315
+ "generated": true
316
+ },
317
+ "html_id": "shift_three_hours_108",
318
+ "html_active_id": "shift_three_108_active"
319
+ },
320
+ "shift_end_three_minutes": {
321
+ "read_index": 35,
322
+ "write_index": 24,
323
+ "descriptions": {
324
+ "title": "Shift 3 End Time Minutes",
325
+ "main_caption": "Based on the Real-Time Clock (RTC), configures three of four specific daily times (24-hour format) for the sensor to perform an automatic reset."
326
+ },
327
+ "default_value": 0,
328
+ "validator": {
329
+ "type": "uint8",
330
+ "min": 0,
331
+ "max": 60,
332
+ "generated": true
333
+ },
334
+ "html_id": "shift_three_minutes_108",
335
+ "html_active_id": "shift_three_108_active"
336
+ },
337
+ "shift_end_four_hours": {
338
+ "read_index": 36,
339
+ "write_index": 25,
340
+ "descriptions": {
341
+ "title": "Shift 4 End Time Hours",
342
+ "main_caption": "Based on the Real-Time Clock (RTC), configures four of four specific daily times (24-hour format) for the sensor to perform an automatic reset."
343
+ },
344
+ "default_value": 0,
345
+ "validator": {
346
+ "type": "uint8",
347
+ "min": 0,
348
+ "max": 24,
349
+ "generated": true
350
+ },
351
+ "html_id": "shift_four_hours_108",
352
+ "html_active_id": "shift_four_108_active"
353
+ },
354
+ "shift_end_four_minutes": {
355
+ "read_index": 37,
356
+ "write_index": 26,
357
+ "descriptions": {
358
+ "title": "Shift 4 End Time Minutes",
359
+ "main_caption": "Based on the Real-Time Clock (RTC), configures four of four specific daily times (24-hour format) for the sensor to perform an automatic reset."
360
+ },
361
+ "default_value": 0,
362
+ "validator": {
363
+ "type": "uint8",
364
+ "min": 0,
365
+ "max": 60,
366
+ "generated": true
367
+ },
368
+ "html_id": "shift_four_minutes_108",
369
+ "html_active_id": "shift_four_108_active"
370
+ },
371
+ "reset_timeout": {
372
+ "read_index": 38,
373
+ "write_index": 27,
374
+ "descriptions": {
375
+ "title": "Reset Timeout",
376
+ "main_caption": "Defines the duration (in seconds) after which the sensor will automatically reset. Before resetting, it will transmit its current data values."
377
+ },
378
+ "default_value": 60,
379
+ "validator": {
380
+ "type": "uint16be",
381
+ "min": 10,
382
+ "max": 65000,
383
+ "generated": true
384
+ },
385
+ "html_id": "reset_timeout_108"
386
+ },
387
+ "counter_reset_mode": {
388
+ "read_index": 40,
389
+ "write_index": 29,
390
+ "descriptions": {
391
+ "title": "Set Reset Mode",
392
+ "main_caption": "This setting specifies which automatic reset option the sensor will utilize."
393
+ },
394
+ "default_value": 0,
395
+ "validator": {
396
+ "type": "uint8",
397
+ "min": 0,
398
+ "max": 2,
399
+ "generated": true
400
+ },
401
+ "options": {
402
+ "0": "Do not reset counters",
403
+ "1": "Based on Shift Ends",
404
+ "2": "Based on the Timeout Provided"
405
+ },
406
+ "html_id": "reset_mode_to_disabled_108"
407
+ },
408
+ "sampling_interval": {
409
+ "read_index": 42,
410
+ "write_index": 30,
411
+ "descriptions": {
412
+ "title": "Data Transmission Interval",
413
+ "main_caption": "Sets the regular interval at which the sensor wakes up and transmits its data. This interval operates independently of any interrupt-driven (Push Notifications or Resets)."
414
+ },
415
+ "default_value": 2,
416
+ "validator": {
417
+ "type": "uint8",
418
+ "min": 0,
419
+ "max": 12,
420
+ "generated": true
421
+ },
422
+ "options": {
423
+ "0": "1 minute",
424
+ "1": "5 minutes",
425
+ "2": "15 minutes",
426
+ "3": "30 minutes",
427
+ "4": "1 hour",
428
+ "5": "2 hours",
429
+ "6": "3 hours",
430
+ "7": "6 hours",
431
+ "8": "12 hours",
432
+ "9": "5 seconds",
433
+ "10": "10 seconds",
434
+ "11": "15 seconds",
435
+ "12": "30 seconds"
436
+ },
437
+ "html_id": "transmission_interval_108"
438
+ },
439
+ "interrupt_timeout": {
440
+ "read_index": 42,
441
+ "write_index": 31,
442
+ "descriptions": {
443
+ "title": "Set Interrupt Timeout",
444
+ "main_caption": "Set the sensor to detect an initial IO (input/output) change and not transmit subsequent IO changes for a specified duration; set the duration value to control how long changes are ignored in milliseconds, set it to 0 to disable ignoring."
445
+ },
446
+ "default_value": 0,
447
+ "validator": {
448
+ "type": "uint16be",
449
+ "min": 0,
450
+ "max": 65000,
451
+ "generated": true
452
+ },
453
+ "html_id": "interrupt_timeout_35"
454
+ },
455
+ "current_sensor_1_ct": {
456
+ "read_index": 44,
457
+ "write_index": 33,
458
+ "descriptions": {
459
+ "title": "Set Sensor One CT",
460
+ "main_caption": "Select the AC Current probe type for Input 1."
461
+ },
462
+ "default_value": 0,
463
+ "validator": {
464
+ "type": "uint8",
465
+ "min": 0,
466
+ "max": 3,
467
+ "generated": true
468
+ },
469
+ "options": {
470
+ "0": "100A",
471
+ "1": "200A",
472
+ "2": "600A",
473
+ "3": "1000A"
474
+ },
475
+ "html_id": "probe_one_126"
476
+ },
477
+ "current_sensor_2_ct": {
478
+ "read_index": 45,
479
+ "write_index": 34,
480
+ "descriptions": {
481
+ "title": "Set Sensor Two CT",
482
+ "main_caption": "Select the AC Current probe type for Input 2."
483
+ },
484
+ "default_value": 0,
485
+ "validator": {
486
+ "type": "uint8",
487
+ "min": 0,
488
+ "max": 3,
489
+ "generated": true
490
+ },
491
+ "options": {
492
+ "0": "100A",
493
+ "1": "200A",
494
+ "2": "600A",
495
+ "3": "1000A"
496
+ },
497
+ "html_id": "probe_two_126"
498
+ },
499
+ "threshold_current_sensor_1": {
500
+ "read_index": 46,
501
+ "write_index": 35,
502
+ "descriptions": {
503
+ "title": "Set AC Current Threshold One",
504
+ "main_caption": "The sensor increments the cycle counter and calculates uptime once the measured AC Current exceeds this threshold."
505
+ },
506
+ "default_value": 3,
507
+ "validator": {
508
+ "type": "uint16be",
509
+ "min": 0,
510
+ "max": 65000,
511
+ "generated": true
512
+ },
513
+ "html_id": "threshold_probe_one_126"
514
+ },
515
+ "threshold_current_sensor_2": {
516
+ "read_index": 48,
517
+ "write_index": 37,
518
+ "descriptions": {
519
+ "title": "Set AC Current Threshold Two",
520
+ "main_caption": "The sensor increments the cycle counter and calculates uptime once the measured AC Current exceeds this threshold."
521
+ },
522
+ "default_value": 3,
523
+ "validator": {
524
+ "type": "uint16be",
525
+ "min": 0,
526
+ "max": 65000,
527
+ "generated": true
528
+ },
529
+ "html_id": "threshold_probe_two_126"
530
+ }
531
+ };
532
+ };
533
+
534
+ const sync_parse = (rep_buffer) => {
535
+ let response = {};
536
+
537
+ // Get the map based on the sensor type byte
538
+ const sync_map = get_config_map(rep_buffer[4]);
539
+
540
+ for (const [key, config] of Object.entries(sync_map)) {
541
+ // Destructure 'type' from inside 'validator' and rename 'read_index' to 'idx'
542
+ const { read_index: idx, length, validator: { type } = {} } = config;
543
+
544
+ // If for some reason a config doesn't have a validator/type, skip it
545
+ if (!type) continue;
546
+
547
+ switch (type) {
548
+ case 'uint8':
549
+ response[key] = rep_buffer[idx];
550
+ break;
551
+ case 'uint16be':
552
+ response[key] = rep_buffer.readUInt16BE(idx);
553
+ break;
554
+ case 'uint32be':
555
+ response[key] = rep_buffer.readUInt32BE(idx);
556
+ break;
557
+ case 'buffer':
558
+ response[key] = rep_buffer.subarray(idx, idx + length);
559
+ break;
560
+ case 'hex':
561
+ response[key] = rep_buffer.subarray(idx, idx + length).toString('hex');
562
+ break;
563
+ case 'mac':
564
+ response[key] = rep_buffer.subarray(idx, idx + length).toString('hex');
565
+ break;
566
+ }
567
+ }
568
+ // if(Object.hasOwn(response, 'destination_address') && response.destination_address.toLowerCase() === '00000000') {
569
+ // console.log('##############################');
570
+ // console.log('#########Dest Override########');
571
+ // console.log('##############################');
572
+ // response.destination_address = "0000ffff";
573
+ // response.auto_raw_destination_address = "0000ffff";
574
+ // };
575
+ return response;
576
+ };
577
+
578
+ const parse = (d, payload) => {
579
+ let report_type = "Regular";
580
+ switch(d[25]){
581
+ case 0:
582
+ report_type = "Regular";
583
+ break;
584
+ case 1:
585
+ report_type = "Shift end";
586
+ break;
587
+ case 2:
588
+ report_type = "Interrupt";
589
+ break;
590
+ case 3:
591
+ report_type = "Threshold";
592
+ break;
593
+ }
594
+ return {
595
+ input_1_counter: d.slice(0, 4).reduce(msbLsb),
596
+ input_1_uptime: d.slice(4, 8).reduce(msbLsb),
597
+ input_2_counter: d.slice(8, 12).reduce(msbLsb),
598
+ input_2_uptime: d.slice(12, 16).reduce(msbLsb),
599
+ input_1: d[16] & 1 ? 1 : 0,
600
+ input_2: d[16] & 2 ? 1 : 0,
601
+ report_type: report_type,
602
+ rtc: [
603
+ String(d[17]).padStart(2, '0'),
604
+ String(d[18]).padStart(2, '0'),
605
+ String(d[19]).padStart(2, '0')
606
+ ].join(':')
607
+ };
608
+ };
609
+
610
+ // --- 2. EXPORT THE MODULE ---
611
+ return {
612
+ type: 125,
613
+ name: '2 Channel OEE AC Current Production Monitor Sensor',
614
+ parse,
615
+ get_write_buffer_size,
616
+ get_config_map,
617
+ sync_parse
618
+ };
619
+ };