@ncd-io/node-red-enterprise-sensors 0.1.22 → 1.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.
package/lib/DigiParser.js CHANGED
@@ -122,6 +122,7 @@ module.exports = class DigiComm{
122
122
  that.serial.write(packet, (err) => {
123
123
  that.lastSent = packet;
124
124
  if(err){
125
+ console.log('_send frame error');
125
126
  console.log(err);
126
127
  }
127
128
  });
@@ -172,8 +173,8 @@ class outgoingFrame{
172
173
  var config = this.transmissionOptions(opts);
173
174
  var frame = [17, this.master.getId()];
174
175
  frame.push(...mac);
175
- var stuff = [255, 254, source, destination, cluster[0], cluster[1], profile[0], profile[1], (config >> 8), (config & 255)];
176
- frame.push(...stuff);
176
+ var payload = [255, 254, source, destination, cluster[0], cluster[1], profile[0], profile[1], (config >> 8), (config & 255)];
177
+ frame.push(...payload);
177
178
  if(data.constructor != Array) data = [data];
178
179
  frame.push(...data);
179
180
  return this.master._send(frame);
@@ -136,8 +136,13 @@ module.exports = class WirelessSensor{
136
136
  var is_new = typeof this.sensor_pool[frame.mac] == 'undefined';
137
137
  var new_mode = is_new;
138
138
  var mode = (type == 'power_up') ? data.mode : ((type == 'sensor_data') ? 'RUN' : ((type == 'config_ack') ? 'ACK' : 'PGM'));
139
+ if(mode == 'ACK'){
140
+ if(data.data.length == 37){
141
+ this._emitter.emit('manifest_received', data);
142
+ }
143
+ }
139
144
  // #OTF
140
- var otf_devices = [23,26,39,45,48,52,76,78,79,80,81,82,84,88,89,90,91,101,102,107,108,519,520,521,531,535,537];
145
+ var otf_devices = [23,26,39,45,48,52,76,78,79,80,81,82,84,88,89,90,91,101,102,107,108,180,181,519,520,521,531,535,537];
141
146
  var device_type = msbLsb(frame.data[6], frame.data[7]);
142
147
  // var device_type = frame.data[7];
143
148
 
@@ -289,7 +294,7 @@ module.exports = class WirelessSensor{
289
294
  };
290
295
 
291
296
  // #OTF
292
- var otf_devices = [23,26,39,45,48,52,76,78,79,80,81,82,84,88,89,90,91,101,102,107,108,519,520,521,531,535,537];
297
+ var otf_devices = [23,26,39,45,48,52,76,78,79,80,81,82,84,88,89,90,91,101,102,107,108,180,181,519,520,521,531,535,537];
293
298
  if(otf_devices.includes(parsed.sensor_type)){
294
299
  // If the message says FLY and there is not FLY timer in progress.
295
300
  if(payload[8] == 70 && payload[9] == 76 && payload[10] == 89) {
@@ -492,18 +497,6 @@ module.exports = class WirelessSensor{
492
497
  if('z_offset' in en_axis_data){
493
498
  fft_concat[label].z = parseFloat((signInt(((raw_data[i+en_axis_data.z_offset]<<8)+(raw_data[i+en_axis_data.z_offset+1])), 16)*fsr_mult).toFixed(5));
494
499
  }
495
-
496
-
497
- // fft.push(fft_data);
498
- // if(label< 40){
499
- // fft_concat[label] = {
500
- // // label: label,
501
- // x: parseFloat((signInt(((raw_data[i]<<8)+(raw_data[i+1]&255)), 16)*.00006).toFixed(5)),
502
- // y: parseFloat((signInt(((raw_data[i+2]<<8)+(raw_data[i+3]&255)), 16)*.00006).toFixed(5)),
503
- // z: parseFloat((signInt(((raw_data[i+4]<<8)+(raw_data[i+5]&255)), 16)*.00006).toFixed(5)),
504
- // };
505
- // }
506
-
507
500
  }
508
501
  var fft_concat_obj = {
509
502
  time_id: globalDevices[deviceAddr].hour +':'+ globalDevices[deviceAddr].minute,
@@ -719,7 +712,7 @@ module.exports = class WirelessSensor{
719
712
  data: payload.slice(8)
720
713
  };
721
714
  // #OTF
722
- }else if(parsed.sensor_type == 80 || parsed.sensor_type == 81 || parsed.sensor_type == 82 || parsed.sensor_type == 84 || parsed.sensor_type == 515 || parsed.sensor_type == 519 || parsed.sensor_type == 537){
715
+ }else if(parsed.sensor_type == 80 || parsed.sensor_type == 81 || parsed.sensor_type == 82 || parsed.sensor_type == 84 || parsed.sensor_type == 180 || parsed.sensor_type == 181 || parsed.sensor_type == 515 || parsed.sensor_type == 519 || parsed.sensor_type == 537){
723
716
  parsed.sensor_data = this.sensor_types[parsed.sensor_type].parse(payload, parsed, frame.mac);
724
717
  if(!parsed.sensor_data){
725
718
  return;
@@ -733,6 +726,41 @@ module.exports = class WirelessSensor{
733
726
  }
734
727
  return parsed;
735
728
  }
729
+ firmware_set_to_ota_mode(sensor_mac){
730
+ console.log('firmware_set_to_ota_mode');
731
+ var packet = [245, 56, 0, 0, 0];
732
+ return this.config_send(sensor_mac, packet);
733
+ }
734
+ // TODO no code basis
735
+ firmware_exit_ota_mode(sensor_mac){
736
+ console.log('firmware_exit_ota_mode');
737
+ var packet = [245, 57, 0, 0, 0];
738
+ return this.config_send(sensor_mac, packet);
739
+ }
740
+ firmware_request_manifest(sensor_mac){
741
+ console.log('firmware_request_manifest');
742
+ var packet = [245, 60, 0, 0, 0];
743
+ return this.config_send(sensor_mac, packet);
744
+ }
745
+ firmware_send_manifest(sensor_mac, manifest){
746
+ console.log('firmware_send_manifest');
747
+ // sensor_mac = "00:00:00:00:00:00:ff:ff";
748
+ let packet = [245, 58, 0, 0, 0].concat(Array.prototype.slice.call(manifest));
749
+ return this.config_send(sensor_mac, packet);
750
+ }
751
+ firmware_send_chunk(sensor_mac, offset, chunk){
752
+ console.log('firmware_send_chunk');
753
+ // sensor_mac = "00:00:00:00:00:00:ff:ff";
754
+ let packet = [245, 59, 0, 0, 0].concat(offset, Array.prototype.slice.call(chunk));
755
+ // console.log(packet);
756
+ return this.config_send(sensor_mac, packet);
757
+ }
758
+ firmware_request_last_segment(sensor_mac){
759
+ console.log('firmware_request_last_segment');
760
+ let packet = [245, 61, 0, 0, 0];
761
+ // console.log(packet);
762
+ return this.config_send(sensor_mac, packet);
763
+ }
736
764
  config_reboot_sensor(sensor_mac){
737
765
  console.log('config_reboot_sensor: '+sensor_mac)
738
766
  var packet = [247, 64, 0, 0, 0];
@@ -916,7 +944,6 @@ module.exports = class WirelessSensor{
916
944
  console.log('config_set_sensor_forced_calibration_535');
917
945
  // convert before processing
918
946
  var packet = [244, 32, 0, 0, 0];
919
- console.log(packet);
920
947
  return this.config_send(sensor_mac, packet);
921
948
  }
922
949
  config_set_sensor_temperature_offset_44(sensor_mac, value){
@@ -1136,7 +1163,7 @@ module.exports = class WirelessSensor{
1136
1163
  return this.config_send(sensor_mac, packet);
1137
1164
  }
1138
1165
  config_set_roll_threshold_47(sensor_mac, threshold){
1139
- console.log('config_set_pitch_threshold_47');
1166
+ console.log('config_set_roll_threshold_47');
1140
1167
  var packet = [244, 1, 0, 0, 47, 0, threshold];
1141
1168
  console.log(packet);
1142
1169
  return this.config_send(sensor_mac, packet);
@@ -1147,7 +1174,6 @@ module.exports = class WirelessSensor{
1147
1174
  console.log(packet);
1148
1175
  return this.config_send(sensor_mac, packet);
1149
1176
  }
1150
-
1151
1177
  config_set_accelerometer_threshold_108(sensor_mac, value){
1152
1178
  console.log('config_set_accelerometer_threshold_108');
1153
1179
  var packet = [244, 32, 0, 0, 0, 1, value];
@@ -1172,7 +1198,6 @@ module.exports = class WirelessSensor{
1172
1198
  console.log(packet);
1173
1199
  return this.config_send(sensor_mac, packet);
1174
1200
  }
1175
-
1176
1201
  config_set_sensor_boot_time_420ma(sensor_mac, value){
1177
1202
  console.log('sensor_boot_time_420ma');
1178
1203
  var packet = [244, 68, 0, 0, 45, value];
@@ -1249,7 +1274,64 @@ module.exports = class WirelessSensor{
1249
1274
  console.log(packet);
1250
1275
  return this.config_send(sensor_mac, packet);
1251
1276
  }
1252
-
1277
+ config_set_debounce_time_2(sensor_mac, value){
1278
+ console.log('config_set_debounce_time_2');
1279
+ var packet = [244, 66, 0, 0, 2, value];
1280
+ console.log(packet);
1281
+ return this.config_send(sensor_mac, packet);
1282
+ }
1283
+ config_enable_stay_on_mode_539(sensor_mac, value){
1284
+ console.log('config_enable_stay_on_mode_539');
1285
+ var packet = [247, 50, 0, 0, 0, value];
1286
+ console.log(packet);
1287
+ return this.config_send(sensor_mac, packet);
1288
+ }
1289
+ config_set_baudrate_539(sensor_mac, value){
1290
+ console.log('config_set_baudrate_539');
1291
+ var packet = [244, 32, 0, 0, 23, 0];
1292
+ let baudrate = int2Bytes((value), 3);
1293
+ packet.push(...baudrate);
1294
+ console.log(packet);
1295
+ return this.config_send(sensor_mac, packet);
1296
+ }
1297
+ config_set_rx_timeout_539(sensor_mac, value){
1298
+ console.log('config_set_rx_timeout_539');
1299
+ var packet = [244, 34, 0, 0, 23, value];
1300
+ console.log(packet);
1301
+ return this.config_send(sensor_mac, packet);
1302
+ }
1303
+ config_set_bootup_time_539(sensor_mac, value){
1304
+ console.log('config_set_bootup_time_539');
1305
+ var packet = [244, 36, 0, 0, 23, value];
1306
+ console.log(packet);
1307
+ return this.config_send(sensor_mac, packet);
1308
+ }
1309
+ config_set_sensor_add_539(sensor_mac, value){
1310
+ console.log('config_set_sensor_add_539');
1311
+ var packet = [244, 38, 0, 0, 23, value];
1312
+ console.log(packet);
1313
+ return this.config_send(sensor_mac, packet);
1314
+ }
1315
+ config_set_rs_node_id_539(sensor_mac, value){
1316
+ console.log('config_set_rs_node_id_539');
1317
+ var packet = [244, 40, 0, 0, 23, value];
1318
+ console.log(packet);
1319
+ return this.config_send(sensor_mac, packet);
1320
+ }
1321
+ config_set_number_of_regs_to_rd_539(sensor_mac, value){
1322
+ console.log('config_set_number_of_regs_to_rd_539');
1323
+ var packet = [244, 51, 0, 0, 23, value];
1324
+ console.log(packet);
1325
+ return this.config_send(sensor_mac, packet);
1326
+ }
1327
+ config_set_reg_539(sensor_mac, value, register){
1328
+ console.log('config_set_reg_539');
1329
+ var packet = [244, 30 + register, 0, 0, 23];
1330
+ let value_reg = int2Bytes((value), 2);
1331
+ packet.push(...value_reg);
1332
+ console.log(packet);
1333
+ return this.config_send(sensor_mac, packet);
1334
+ }
1253
1335
  config_get_delay(sensor_mac){
1254
1336
  return new Promise((fulfill, reject) => {
1255
1337
  this.config_send(sensor_mac, [247, 21, 0, 0, 0]).then((res) => {
@@ -1442,6 +1524,11 @@ module.exports = class WirelessSensor{
1442
1524
  };
1443
1525
  return this.config_send(sensor_mac, [(data ? 247 : 248), params[param], ...data]);
1444
1526
  }
1527
+ clear_queue(){
1528
+ this.queue.queue = new Array;
1529
+ delete this.queue;
1530
+ this.queue = new Queue(1);
1531
+ }
1445
1532
  config_send(sensor_mac, data, opts){
1446
1533
  var that = this;
1447
1534
  return new Promise((fulfill, reject) => {
@@ -4037,7 +4124,6 @@ function sensor_types(parent){
4037
4124
  }
4038
4125
  }
4039
4126
  },
4040
-
4041
4127
  '82': {
4042
4128
  name: 'Condition Based/Predictive Maintenance Sensor',
4043
4129
  parse: (payload, parsed, mac) => {
@@ -5385,6 +5471,18 @@ function sensor_types(parent){
5385
5471
  };
5386
5472
  }
5387
5473
  },
5474
+ '180': {
5475
+ name: 'C1D2 One Channel Vibration Plus',
5476
+ parse: (payload, parsed, mac) => {
5477
+ return parent.sensor_types[80].parse(payload, parsed, mac);
5478
+ }
5479
+ },
5480
+ '181': {
5481
+ name: 'C1D2 Two Channel Vibration Plus',
5482
+ parse: (payload, parsed, mac) => {
5483
+ return parent.sensor_types[81].parse(payload, parsed, mac);
5484
+ }
5485
+ },
5388
5486
  '200': {
5389
5487
  name: '4-20mA Pass Through',
5390
5488
  parse: (d) => {
@@ -6971,6 +7069,14 @@ function sensor_types(parent){
6971
7069
  }
6972
7070
  }
6973
7071
  },
7072
+ '539': {
7073
+ name: 'RS-485 Modbus Wireless Converter',
7074
+ parse: (d) => {
7075
+ return {
7076
+ data: d
7077
+ };
7078
+ },
7079
+ },
6974
7080
  '10000': {
6975
7081
  name: '4-Relay',
6976
7082
  parse: (d) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ncd-io/node-red-enterprise-sensors",
3
- "version": "0.1.22",
3
+ "version": "1.0.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/wireless.html CHANGED
@@ -344,6 +344,7 @@
344
344
 
345
345
  accelerometer_state_108:{value:0},
346
346
  accelerometer_state_108_active:{value:""},
347
+
347
348
  clear_all_counters_108:{value:0},
348
349
  accelerometer_threshold_108:{value:10, validate: NCD_validators.number_range(0, 255)},
349
350
  accelerometer_threshold_108_active:{value:""},
@@ -368,6 +369,33 @@
368
369
 
369
370
  thermocouple_type_23_active:{value:""},
370
371
  thermocouple_type_23:{value: 0},
372
+
373
+ debounce_time_2_active:{value:""},
374
+ debounce_time_2:{value: 10, validate: NCD_validators.number_range(0, 255)},
375
+
376
+ stay_on_mode_539_active: {value:""},
377
+ stay_on_mode_539: {value:0},
378
+
379
+ baudrate_539_active:{value:""},
380
+ baudrate_539:{value: 9600},
381
+
382
+ rx_timeout_539_active:{value:""},
383
+ rx_timeout_539:{value: 10, validate: NCD_validators.number_range(0, 255)},
384
+
385
+ bootup_time_539_active:{value:""},
386
+ bootup_time_539:{value: 10, validate: NCD_validators.number_range(0, 255)},
387
+
388
+ sensor_add_539_active:{value:""},
389
+ sensor_add_539:{value: 10, validate: NCD_validators.number_range(0, 255)},
390
+
391
+ rs_node_id_539_active:{value:""},
392
+ rs_node_id_539:{value: 10, validate: NCD_validators.number_range(0, 255)},
393
+
394
+ number_of_regs_to_rd_539_active:{value:""},
395
+ number_of_regs_to_rd_539:{value: 10, validate: NCD_validators.number_range(0, 255)},
396
+
397
+ config_set_reg_active_539:{value:""},
398
+ config_set_reg_539:{value:50, validate: NCD_validators.number_range(0, 65534)},
371
399
  },
372
400
  inputs: 0,
373
401
  outputs: 1,
@@ -461,6 +489,8 @@
461
489
  "102": "102 - Strain Gauge",
462
490
  "107": "107 - 4 Channel 4-20mA Receiver",
463
491
  "108": "108 - Machine Uptime Monitoring Sensor",
492
+ "180": "180 - C1D2 One Channel Vibration Plus",
493
+ "181": "181 - C1D2 Two Channel Vibration Plus",
464
494
  "200": "200 - 4-20mA Pass Through",
465
495
  "202": "202 - Weather Station",
466
496
  "502": "502 - C_50-27",
@@ -476,6 +506,7 @@
476
506
  "531": "531 - Custom Noise Sensor",
477
507
  "535": "535 - Custom CO2 Sensor",
478
508
  "537": "537 - Custom Standalone Smart Vibration Sensor",
509
+ "539": "539 - RS-485 Modbus Wireless Converter",
479
510
  "10000": "10000 - 4-Channel Relay",
480
511
  "10006": "10006 - 4-Channel 4-20 mA Input",
481
512
  "10007": "10007 - 4-Channel Current Monitor",
@@ -715,6 +746,8 @@
715
746
  <option value="102">102 - Strain Gauge</option>
716
747
  <option value="107">107 - 4 Channel 4-20mA Receiver</option>
717
748
  <option value="108">108 - Machine Uptime Monitoring Sensor</option>
749
+ <option value="180">180 - C1D2 One Channel Vibration Plus</option>
750
+ <option value="181">181 - C1D2 Two Channel Vibration Plus</option>
718
751
  <option value="200">200 - 4-20mA Pass Through</option>
719
752
  <option value="202">202 - Weather Station</option>
720
753
  <option value="502">502 - C_50-27</option>
@@ -730,6 +763,7 @@
730
763
  <option value="531">531 - Custom Noise Sensor</option>
731
764
  <option value="535">535 - Custom CO2 Sensor</option>
732
765
  <option value="537">537 - Custom Standalone Smart Vibration Sensor</option>
766
+ <option value="539">539 - RS-485 Modbus Wireless Converter</option>
733
767
  <option value="10000">10000 - 4-Channel Relay</option>
734
768
  <option value="10006">10006 - 4-Channel 4-20 mA Input</option>
735
769
  <option value="10007">10007 - 4-Channel Current Monitor</option>
@@ -743,7 +777,7 @@
743
777
  <label for="node-input-auto_config"><i class="icon-tag"></i> Auto Config</label>
744
778
  <input class="section-control" type="checkbox" id="node-input-auto_config" value="1">
745
779
  </div>
746
- <div class="form-row ncd-dependent" data-sensor-23 data-sensor-26 data-sensor-39 data-sensor-45 data-sensor-48 data-sensor-52 data-sensor-76 data-sensor-78 data-sensor-79 data-sensor-80 data-sensor-81 data-sensor-82 data-sensor-84 data-sensor-88 data-sensor-89 data-sensor-90 data-sensor-91 data-sensor-101 data-sensor-102 data-sensor-107 data-sensor-108 data-sensor-519 data-sensor-520 data-sensor-521 data-sensor-531 data-sensor-535 data-sensor-537>
780
+ <div class="form-row ncd-dependent" data-sensor-23 data-sensor-26 data-sensor-39 data-sensor-45 data-sensor-48 data-sensor-52 data-sensor-76 data-sensor-78 data-sensor-79 data-sensor-80 data-sensor-81 data-sensor-82 data-sensor-84 data-sensor-88 data-sensor-89 data-sensor-90 data-sensor-91 data-sensor-101 data-sensor-102 data-sensor-107 data-sensor-108 data-sensor-180 data-sensor-181 data-sensor-519 data-sensor-520 data-sensor-521 data-sensor-531 data-sensor-535 data-sensor-537>
747
781
  <hr>
748
782
  <label for="node-input-on_the_fly_enable"><i class="icon-tag"></i> OTF Config*</label>
749
783
  <input type="checkbox" id="node-input-on_the_fly_enable" value="1">
@@ -919,7 +953,7 @@
919
953
  </select>
920
954
  </div>
921
955
  </div>
922
- <div class="ncd-dependent" data-sensor-7 data-sensor-24>
956
+ <div class="ncd-dependent" data-sensor-7 data-sensor-24 data-sensor-25>
923
957
  <hr>
924
958
  <div class="form-row ncd-active-check">
925
959
  <div>
@@ -992,7 +1026,7 @@
992
1026
  </div>
993
1027
  </div>
994
1028
  </div>
995
- <div class="ncd-dependent" data-sensor-24>
1029
+ <div class="ncd-dependent" data-sensor-24 data-sensor-25>
996
1030
  <div class="form-row">
997
1031
  <label for="node-input-activ_interr_x"><i class="icon-tag"></i> Interrupt X-Axis</label>
998
1032
  <select id="node-input-activ_interr_x">
@@ -1164,7 +1198,7 @@
1164
1198
  </div>
1165
1199
  </div>
1166
1200
 
1167
- <div class="ncd-dependent" data-sensor-80 data-sensor-81 data-sensor-82 data-sensor-84 data-sensor-519 data-sensor-537>
1201
+ <div class="ncd-dependent" data-sensor-80 data-sensor-81 data-sensor-82 data-sensor-84 data-sensor-180 data-sensor-181 data-sensor-519 data-sensor-537>
1168
1202
  <hr>
1169
1203
  <div class="form-row ncd-active-check">
1170
1204
  <strong>Mode</strong>
@@ -1209,7 +1243,7 @@
1209
1243
  </div>
1210
1244
  </div>
1211
1245
 
1212
- <div class="ncd-dependent" data-sensor-80 data-sensor-82 data-sensor-84 data-sensor-101 data-sensor-102 data-sensor-519 data-sensor-537>
1246
+ <div class="ncd-dependent" data-sensor-80 data-sensor-82 data-sensor-84 data-sensor-101 data-sensor-102 data-sensor-180 data-sensor-519 data-sensor-537>
1213
1247
  <hr>
1214
1248
  <div class="form-row ncd-active-check">
1215
1249
  <strong>Set Sampling Duration 1= 50msec, 2= 100msec</strong>
@@ -1224,7 +1258,7 @@
1224
1258
  </div>
1225
1259
  </div>
1226
1260
 
1227
- <div class="ncd-dependent" data-sensor-80 data-sensor-81 data-sensor-82 data-sensor-84 data-sensor-101 data-sensor-102 data-sensor-519 data-sensor-537>
1261
+ <div class="ncd-dependent" data-sensor-80 data-sensor-81 data-sensor-82 data-sensor-84 data-sensor-101 data-sensor-102 data-sensor-180 data-sensor-181 data-sensor-519 data-sensor-537>
1228
1262
  <hr>
1229
1263
  <div class="form-row ncd-active-check">
1230
1264
  <strong>Sampling Interval</strong>
@@ -1256,7 +1290,7 @@
1256
1290
  </div>
1257
1291
  </div>
1258
1292
 
1259
- <div class="ncd-dependent" data-sensor-81>
1293
+ <div class="ncd-dependent" data-sensor-81 data-sensor-181>
1260
1294
  <hr>
1261
1295
  <div class="form-row ncd-active-check">
1262
1296
  <strong>Probe 1: Output Data Rate</strong>
@@ -1325,7 +1359,7 @@
1325
1359
  </div>
1326
1360
  </div>
1327
1361
  </div>
1328
- <div class="ncd-dependent" data-sensor-80 data-sensor-82 data-sensor-84 data-sensor-102 data-sensor-519 data-sensor-537>
1362
+ <div class="ncd-dependent" data-sensor-80 data-sensor-82 data-sensor-84 data-sensor-102 data-sensor-180 data-sensor-519 data-sensor-537>
1329
1363
  <hr>
1330
1364
  <div class="form-row ncd-active-check">
1331
1365
  <strong>Output Data Rate</strong>
@@ -1422,7 +1456,7 @@
1422
1456
  </div>
1423
1457
  </div>
1424
1458
  </div>
1425
- <div class="ncd-dependent" data-sensor-80 data-sensor-81 data-sensor-82 data-sensor-84 data-sensor-519 data-sensor-537>
1459
+ <div class="ncd-dependent" data-sensor-80 data-sensor-81 data-sensor-82 data-sensor-84 data-sensor-180 data-sensor-181 data-sensor-519 data-sensor-537>
1426
1460
  <div class="form-row ncd-active-check">
1427
1461
  <strong>Set Filtering</strong>
1428
1462
  <div>
@@ -1492,7 +1526,7 @@
1492
1526
  </div>
1493
1527
  </div>
1494
1528
  </div>
1495
- <div class="ncd-dependent" data-sensor-81>
1529
+ <div class="ncd-dependent" data-sensor-81 data-sensor-181>
1496
1530
  <div class="form-row ncd-active-check">
1497
1531
  <strong>Set Low Pass Filter Probe 2</strong>
1498
1532
  <p>
@@ -1549,7 +1583,7 @@
1549
1583
  </div>
1550
1584
  </div>
1551
1585
 
1552
- <div class="ncd-dependent" data-sensor-80 data-sensor-81 data-sensor-82 data-sensor-84 data-sensor-519 data-sensor-537>
1586
+ <div class="ncd-dependent" data-sensor-80 data-sensor-81 data-sensor-82 data-sensor-84 data-sensor-180 data-sensor-181 data-sensor-519 data-sensor-537>
1553
1587
  <div class="form-row ncd-active-check">
1554
1588
  <strong>Full Scale Range</strong>
1555
1589
  <div>
@@ -1586,7 +1620,7 @@
1586
1620
  </div>
1587
1621
  </div>
1588
1622
  </div>
1589
- <div class="ncd-dependent" data-sensor-80 data-sensor-81 data-sensor-82 data-sensor-84 data-sensor-101 data-sensor-519 data-sensor-537>
1623
+ <div class="ncd-dependent" data-sensor-80 data-sensor-81 data-sensor-82 data-sensor-84 data-sensor-101 data-sensor-180 data-sensor-181 data-sensor-519 data-sensor-537>
1590
1624
  <div class="form-row ncd-active-check">
1591
1625
  <strong>Set Dead Band in mg</strong>
1592
1626
  <div>
@@ -1700,7 +1734,7 @@
1700
1734
  </div>
1701
1735
  </div>
1702
1736
 
1703
- <div class="ncd-dependent" data-sensor-80 data-sensor-81 data-sensor-505 data-sensor-506>
1737
+ <div class="ncd-dependent" data-sensor-80 data-sensor-81 data-sensor-180 data-sensor-181 data-sensor-505 data-sensor-506>
1704
1738
  <div class="form-row ncd-active-check">
1705
1739
  <strong>Channel 1 Current Calibration Value</strong>
1706
1740
  <p class="caption">
@@ -1718,7 +1752,7 @@
1718
1752
  </div>
1719
1753
  </div>
1720
1754
 
1721
- <div class="ncd-dependent" data-sensor-81 data-sensor-506>
1755
+ <div class="ncd-dependent" data-sensor-81 data-sensor-181 data-sensor-506>
1722
1756
  <div class="form-row ncd-active-check">
1723
1757
  <strong>Channel 2 Current Calibration Value</strong>
1724
1758
  <p class="caption">
@@ -1786,7 +1820,6 @@
1786
1820
  </div>
1787
1821
  </div>
1788
1822
  </div>
1789
-
1790
1823
  <div class="ncd-dependent" data-sensor-108>
1791
1824
  <div class="form-row ncd-active-check">
1792
1825
  <strong>Enable Accelerometer Error Reporting</strong>
@@ -1838,7 +1871,6 @@
1838
1871
  </div>
1839
1872
  </div>
1840
1873
  </div>
1841
-
1842
1874
  <div class="ncd-dependent" data-sensor-35 data-sensor-36>
1843
1875
  <hr>
1844
1876
  <div class="form-row ncd-active-check">
@@ -1853,7 +1885,7 @@
1853
1885
  </div>
1854
1886
  </div>
1855
1887
  </div>
1856
- <div class="ncd-dependent" data-sensor-80 data-sensor-81 data-sensor-82 data-sensor-84 data-sensor-519 data-sensor-537>
1888
+ <div class="ncd-dependent" data-sensor-80 data-sensor-81 data-sensor-82 data-sensor-84 data-sensor-180 data-sensor-181 data-sensor-519 data-sensor-537>
1857
1889
  <hr>
1858
1890
  <div class="form-row ncd-active-check">
1859
1891
  <strong>Payload Length</strong>
@@ -1915,6 +1947,110 @@
1915
1947
  <div id="config_response"></div>
1916
1948
  </div>
1917
1949
  </div>
1950
+ <div class="ncd-dependent" data-sensor-2>
1951
+ <div class="form-row ncd-active-check">
1952
+ <strong>Set Input Debounce Time</strong>
1953
+ <p class="caption">
1954
+ Sets the debounce time in milliseconds on inputs. State changes to the input during this debounce time will be ignored. Generally recommended for mechanically triggered state changes such as button or relay/contactor outputs.
1955
+ </p>
1956
+ <div>
1957
+ <label for="node-input-debounce_time_2_active">Active:</label>
1958
+ <input type="checkbox" id="node-input-debounce_time_2_active" class="ncd-config-toggle" data-target-id="node-input-debounce_time_2" value="1">
1959
+ </div>
1960
+ <div>
1961
+ <label for="node-input-debounce_time_2"><i class="icon-tag"></i>Value:</label>
1962
+ <input type="text" id="node-input-debounce_time_2" placeholder="10" value="10">
1963
+ </div>
1964
+ </div>
1965
+ </div>
1966
+ <div class="ncd-dependent" data-sensor-539>
1967
+ <div class="form-row ncd-active-check">
1968
+ <strong>Set Stay On Mode</strong>
1969
+ <div>
1970
+ <label for="node-input-stay_on_mode_539_active">Active:</label>
1971
+ <input type="checkbox" id="node-input-stay_on_mode_539_active" class="ncd-config-toggle" data-target-id="node-input-stay_on_mode_539" value="1">
1972
+ </div>
1973
+ <div>
1974
+ <label for="node-input-stay_on_mode_539"><i class="icon-tag"></i>Value:</label>
1975
+ <select id="node-input-stay_on_mode_539">
1976
+ <option value="0">Disabled</option>
1977
+ <option value="1">Enabled</option>
1978
+ </select>
1979
+ </div>
1980
+ </div>
1981
+ <div class="form-row ncd-active-check">
1982
+ <strong>Set Baudrate</strong>
1983
+ <div>
1984
+ <label for="node-input-baudrate_539_active">Active:</label>
1985
+ <input type="checkbox" id="node-input-baudrate_539_active" class="ncd-config-toggle" data-target-id="node-input-baudrate_539" value="1">
1986
+ </div>
1987
+ <div>
1988
+ <label for="node-input-baudrate_539"><i class="icon-tag"></i>Value:</label>
1989
+ <select id="node-input-baudrate_539">
1990
+ <option selected="selected" value="9600">9600</option>
1991
+ <option value="19200">19200</option>
1992
+ <option value="38400">38400</option>
1993
+ <option value="57600">57600</option>
1994
+ <option value="115200">115200</option>
1995
+ </select>
1996
+ </div>
1997
+ </div>
1998
+ <div class="form-row ncd-active-check">
1999
+ <strong>Set Rx Timeout</strong>
2000
+ <div>
2001
+ <label for="node-input-rx_timeout_539_active">Active:</label>
2002
+ <input type="checkbox" id="node-input-rx_timeout_539_active" class="ncd-config-toggle" data-target-id="node-input-rx_timeout_539" value="1">
2003
+ </div>
2004
+ <div>
2005
+ <label for="node-input-rx_timeout_539"><i class="icon-tag"></i>Value:</label>
2006
+ <input type="text" id="node-input-rx_timeout_539" placeholder="10" value="10">
2007
+ </div>
2008
+ </div>
2009
+ <div class="form-row ncd-active-check">
2010
+ <strong>Set Bootup Time</strong>
2011
+ <div>
2012
+ <label for="node-input-bootup_time_539_active">Active:</label>
2013
+ <input type="checkbox" id="node-input-bootup_time_539_active" class="ncd-config-toggle" data-target-id="node-input-bootup_time_539" value="1">
2014
+ </div>
2015
+ <div>
2016
+ <label for="node-input-bootup_time_539"><i class="icon-tag"></i>Value:</label>
2017
+ <input type="text" id="node-input-bootup_time_539" placeholder="10" value="10">
2018
+ </div>
2019
+ </div>
2020
+ <div class="form-row ncd-active-check">
2021
+ <strong>Set Slave ID</strong>
2022
+ <div>
2023
+ <label for="node-input-sensor_add_539_active">Active:</label>
2024
+ <input type="checkbox" id="node-input-sensor_add_539_active" class="ncd-config-toggle" data-target-id="node-input-sensor_add_539" value="1">
2025
+ </div>
2026
+ <div>
2027
+ <label for="node-input-sensor_add_539"><i class="icon-tag"></i>Value:</label>
2028
+ <input type="text" id="node-input-sensor_add_539" placeholder="10" value="10">
2029
+ </div>
2030
+ </div>
2031
+ <div class="form-row ncd-active-check">
2032
+ <strong>Set Sub Device Type</strong>
2033
+ <div>
2034
+ <label for="node-input-rs_node_id_539_active">Active:</label>
2035
+ <input type="checkbox" id="node-input-rs_node_id_539_active" class="ncd-config-toggle" data-target-id="node-input-rs_node_id_539" value="1">
2036
+ </div>
2037
+ <div>
2038
+ <label for="node-input-rs_node_id_539"><i class="icon-tag"></i>Value:</label>
2039
+ <input type="text" id="node-input-rs_node_id_539" placeholder="10" value="10">
2040
+ </div>
2041
+ </div>
2042
+ <div class="form-row ncd-active-check">
2043
+ <strong>Set Number of Registers to RD</strong>
2044
+ <div>
2045
+ <label for="node-input-number_of_regs_to_rd_539_active">Active:</label>
2046
+ <input type="checkbox" id="node-input-number_of_regs_to_rd_539_active" class="ncd-config-toggle" data-target-id="node-input-number_of_regs_to_rd_539" value="1">
2047
+ </div>
2048
+ <div>
2049
+ <label for="node-input-number_of_regs_to_rd_539"><i class="icon-tag"></i>Value:</label>
2050
+ <input type="text" id="node-input-number_of_regs_to_rd_539" placeholder="10" value="10">
2051
+ </div>
2052
+ </div>
2053
+ </div>
1918
2054
  </div>
1919
2055
  </div>
1920
2056
  </script>
package/wireless.js CHANGED
@@ -3,7 +3,8 @@ const comms = require('ncd-red-comm');
3
3
  const sp = require('serialport');
4
4
  const Queue = require("promise-queue");
5
5
  const events = require("events");
6
-
6
+ const fs = require('fs');
7
+ const home_dir = require('os').homedir
7
8
  module.exports = function(RED) {
8
9
  var gateway_pool = {};
9
10
  function NcdGatewayConfig(config){
@@ -14,6 +15,8 @@ module.exports = function(RED) {
14
15
 
15
16
  this.listeners = [];
16
17
  this.sensor_pool = [];
18
+ // TODO sensor_list is a temporary property, should be combined with sensor_pool
19
+ this.sensor_list = {};
17
20
  this._emitter = new events.EventEmitter();
18
21
  this.on = (e,c) => this._emitter.on(e, c);
19
22
 
@@ -72,6 +75,67 @@ module.exports = function(RED) {
72
75
  node.gateway.digi.serial.reconnect();
73
76
  });
74
77
  }
78
+ // Event listener to make sure this only triggers once no matter how many gateway nodes there are
79
+ node.gateway.on('sensor_mode', (d) => {
80
+ if(d.mode == "FLY"){
81
+ if(Object.hasOwn(node.sensor_list, d.mac) && Object.hasOwn(node.sensor_list[d.mac], 'update_request')){
82
+ node.request_manifest(d.mac);
83
+ };
84
+ };
85
+ });
86
+ node.gateway.on('manifest_received', (manifest_data) => {
87
+ // read manifest length is 37. Could use the same event for both
88
+ if(Object.hasOwn(node.sensor_list, manifest_data.addr) && Object.hasOwn(node.sensor_list[manifest_data.addr], 'update_request')){
89
+ // TODO check manifest data and start update process
90
+ }
91
+ manifest_data.data = node._parse_manifest_read(manifest_data.data);
92
+ node._emitter.emit('send_manifest', manifest_data);
93
+ let firmware_data = node._compare_manifest(manifest_data);
94
+ if(!firmware_data){
95
+ delete node.sensor_list[manifest_data.addr].update_request;
96
+ return;
97
+ }
98
+
99
+ // TODO Right now assume everything is good
100
+ // node.gateway.firmware_set_to_ota_mode(manifest_data.addr);
101
+
102
+ setTimeout(() => {
103
+ var tout = setTimeout(() => {
104
+ console.log('Start OTA Timed Out');
105
+ }, 10000);
106
+
107
+ var promises = {};
108
+ promises.firmware_set_to_ota_mode = node.gateway.firmware_set_to_ota_mode(manifest_data.addr);
109
+ promises.finish = new Promise((fulfill, reject) => {
110
+ node.gateway.queue.add(() => {
111
+ return new Promise((f, r) => {
112
+ clearTimeout(tout);
113
+ // node.status(modes.FLY);
114
+ fulfill();
115
+ f();
116
+ });
117
+ });
118
+ });
119
+ for(var i in promises){
120
+ (function(name){
121
+ promises[name].then((f) => {
122
+ if(name != 'finish'){
123
+ console.log(name);
124
+ }
125
+ else{
126
+ // enter ota mode
127
+ node.gateway.digi.send.at_command("ID", [0x7a, 0xaa]).then().catch().then(() => {
128
+ node.start_firmware_update(manifest_data, firmware_data);
129
+ });
130
+ }
131
+ }).catch((err) => {
132
+ console.log(err);
133
+ // msg[name] = err;
134
+ });
135
+ })(i);
136
+ }
137
+ });
138
+ });
75
139
  }));
76
140
  });
77
141
  node.gateway.digi.serial.on('closed_comms', () => {
@@ -102,6 +166,81 @@ module.exports = function(RED) {
102
166
  });
103
167
  };
104
168
 
169
+ node.start_firmware_update = function(manifest_data, firmware_data){
170
+ return new Promise((top_fulfill, top_reject) => {
171
+ var success = {};
172
+
173
+ setTimeout(() => {
174
+ let chunk_size = 128;
175
+ let image_start = firmware_data.firmware.slice(1, 5).reduce(msbLsb)+6;
176
+
177
+ var promises = {};
178
+ promises.manifest = node.gateway.firmware_send_manifest(manifest_data.addr, firmware_data.firmware.slice(5, image_start-1));
179
+ firmware_data.firmware = firmware_data.firmware.slice(image_start+4);
180
+
181
+ var index = 0;
182
+ if(Object.hasOwn(node.sensor_list[manifest_data.addr], 'last_chunk_success')){
183
+ index = node.sensor_list[manifest_data.addr].last_chunk_success;
184
+ }
185
+ var temp_count = 0;
186
+ while(index*chunk_size < firmware_data.manifest.image_size){
187
+ let offset = index*chunk_size;
188
+ // console.log(index);
189
+ // let packet = [254, 59, 0, 0, 0];
190
+ let offset_bytes = int2Bytes(offset, 4);
191
+ let firmware_chunk = firmware_data.firmware.slice(index*chunk_size, index*chunk_size+chunk_size);
192
+ temp_count += 1;
193
+ // packet = packet.concat(offset_bytes, firmware_chunk);
194
+ promises[index] = node.gateway.firmware_send_chunk(manifest_data.addr, offset_bytes, firmware_chunk);
195
+ index++;
196
+ }
197
+
198
+ promises.reboot = node.gateway.config_reboot_sensor(manifest_data.addr);
199
+
200
+ for(var i in promises){
201
+ (function(name){
202
+ promises[name].then((f) => {
203
+ if(name == 'manifest'){
204
+ // delete node.sensor_list[manifest_data.addr].promises[name];
205
+ node.sensor_list[manifest_data.addr].test_check = {name: true};
206
+ node.sensor_list[manifest_data.addr].update_in_progress = true;
207
+ }else {
208
+ success[name] = true;
209
+ node.sensor_list[manifest_data.addr].test_check[name] = true;
210
+ node.sensor_list[manifest_data.addr].last_chunk_success = name;
211
+ // delete node.sensor_list[manifest_data.addr].promises[name];
212
+ }
213
+ }).catch((err) => {
214
+ if(name != 'reboot'){
215
+ node.gateway.clear_queue();
216
+ success[name] = err;
217
+ }else{
218
+ delete node.sensor_list[manifest_data.addr].last_chunk_success;
219
+ delete node.sensor_list[manifest_data.addr].update_request;
220
+ node._emitter.emit('send_firmware_stats', {state: success, addr: manifest_data.addr});
221
+ // #OTF
222
+ // node.send({topic: 'Config Results', payload: success, time: Date.now(), addr: manifest_data.addr});
223
+ top_fulfill(success);
224
+ }
225
+ node._emitter.emit('send_firmware_stats', {state: success, addr: manifest_data.addr});
226
+ node.resume_normal_operation();
227
+ });
228
+ })(i);
229
+ }
230
+ }, 1000);
231
+ });
232
+ }
233
+ node.resume_normal_operation = function(){
234
+ let pan_id = parseInt(config.pan_id, 16);
235
+ node.gateway.digi.send.at_command("ID", [pan_id >> 8, pan_id & 255]).then().catch().then(() => {
236
+ console.log('Set Pan ID to: '+pan_id);
237
+ });
238
+ }
239
+
240
+ node.request_manifest = function(sensor_addr){
241
+ // Request Manifest
242
+ node.gateway.firmware_request_manifest(sensor_addr);
243
+ };
105
244
 
106
245
  node.close_comms = function(){
107
246
  // node.gateway._emitter.removeAllListeners('sensor_data');
@@ -118,7 +257,55 @@ module.exports = function(RED) {
118
257
  // });
119
258
  }
120
259
  }
260
+ }
261
+ node._compare_manifest = function(sensor_manifest){
262
+ let firmware_dir = home_dir()+'/.node-red/node_modules/@ncd-io/node-red-enterprise-sensors/firmware_files';
263
+ let filename = '/' + sensor_manifest.data.device_type + '-' + sensor_manifest.data.hardware_id[0] + '_' + sensor_manifest.data.hardware_id[1] + '_' + sensor_manifest.data.hardware_id[2] + '.ncd';
264
+
265
+ try {
266
+ let firmware_file = fs.readFileSync(firmware_dir+filename,)
267
+ let stored_manifest = node._parse_manifest(firmware_file);
268
+ if(stored_manifest.firmware_version === sensor_manifest.data.firmware_version){
269
+ console.log('firmware versions SAME');
270
+ return false;
271
+ }
121
272
 
273
+ if(stored_manifest.max_image_size < sensor_manifest.data.image_size){
274
+ console.log('firmware image too large');
275
+ return false;
276
+ }
277
+ return {manifest: stored_manifest, firmware: firmware_file};
278
+ } catch(err){
279
+ console.log(err);
280
+ return err;
281
+ }
282
+ }
283
+ node._parse_manifest = function(bin_data){
284
+ return {
285
+ manifest_check: bin_data[0] == 0x01,
286
+ manifest_size: bin_data.slice(1, 5).reduce(msbLsb),
287
+ firmware_version: bin_data[5],
288
+ image_start_address: bin_data.slice(6, 10).reduce(msbLsb),
289
+ image_size: bin_data.slice(10, 14).reduce(msbLsb),
290
+ max_image_size: bin_data.slice(14, 18).reduce(msbLsb),
291
+ image_digest: bin_data.slice(18, 34),
292
+ device_type: bin_data.slice(34, 36).reduce(msbLsb),
293
+ hardware_id: bin_data.slice(36, 39),
294
+ reserve_bytes: bin_data.slice(39, 42)
295
+ }
296
+ };
297
+ node._parse_manifest_read = function(bin_data){
298
+ return {
299
+ // manifest_size: bin_data.slice(0,4).reduce(msbLsb),
300
+ firmware_version: bin_data[0],
301
+ image_start_address: bin_data.slice(1, 5).reduce(msbLsb),
302
+ image_size: bin_data.slice(5, 9).reduce(msbLsb),
303
+ max_image_size: bin_data.slice(9, 13).reduce(msbLsb),
304
+ image_digest: bin_data.slice(13, 29),
305
+ device_type: bin_data.slice(29, 31).reduce(msbLsb),
306
+ hardware_id: bin_data.slice(31, 34),
307
+ reserve_bytes: bin_data.slice(34, 37)
308
+ }
122
309
  }
123
310
  }
124
311
 
@@ -149,7 +336,17 @@ module.exports = function(RED) {
149
336
  node.set_status = function(){
150
337
  node.status(statuses[node._gateway_node.is_config]);
151
338
  };
152
-
339
+ node._gateway_node.on('send_manifest', (manifest_data) => {
340
+ node.send({
341
+ topic: 'sensor_manifest',
342
+ payload: {
343
+ addr: manifest_data.addr,
344
+ sensor_type: manifest_data.sensor_type,
345
+ manifest: manifest_data.data
346
+ },
347
+ time: Date.now()
348
+ });
349
+ });
153
350
  node.on('input', function(msg){
154
351
  switch(msg.topic){
155
352
  case "route_trace":
@@ -187,7 +384,133 @@ module.exports = function(RED) {
187
384
  // if(msg.topic == "fidelity_test"){
188
385
  // }
189
386
  });
387
+ node._gateway_node.on('send_firmware_stats', (data) => {
388
+ node.send({
389
+ topic: 'update_stats',
390
+ payload: data.state,
391
+ addr: data.addr,
392
+ time: Date.now()
393
+ });
394
+ });
395
+ node.on('input', function(msg){
396
+ switch(msg.topic){
397
+ case "route_trace":
398
+ var opts = {trace:1};
399
+ node.gateway.route_discover(msg.payload.address,opts).then().catch(console.log);
400
+ break;
401
+ case "link_test":
402
+ node.gateway.link_test(msg.payload.source_address,msg.payload.destination_address,msg.payload.options);
403
+ break;
404
+ case "fidelity_test":
405
+ break;
406
+ case "add_firmware_file":
407
+ // Parse Manifest to grab information and store it for later use
408
+ // msg.payload = [0x01, 0x00, ...]
409
+ let new_msg = {
410
+ topic: 'add_firmware_file_response',
411
+ payload: node._gateway_node._parse_manifest(msg.payload)
412
+ }
413
+ let firmware_dir = home_dir()+'/.node-red/node_modules/@ncd-io/node-red-enterprise-sensors/firmware_files';
414
+ if (!fs.existsSync(firmware_dir)) {
415
+ fs.mkdirSync(firmware_dir);
416
+ };
417
+ let filename = '/' + new_msg.payload.device_type + '-' + new_msg.payload.hardware_id[0] + '_' + new_msg.payload.hardware_id[1] + '_' + new_msg.payload.hardware_id[2] + '.ncd';
418
+ fs.writeFile(firmware_dir+filename, msg.payload, function(err){
419
+ if(err){
420
+ console.log(err);
421
+ };
422
+ console.log('Success');
423
+ });
424
+ node.send(new_msg);
425
+ break;
426
+ // case "get_firmware_file":
427
+ // Commented out as I'd rather use a flow to request the file. More robust. Maybe more complicated, wait for feedback.
428
+ // // This input makes a request to the specified url and downloads a firmware file at that location
429
+ // // msg.payload = "https://github.com/ncd-io/WiFi_MQTT_Temperature_Firmware/raw/main/v1.0.3/firmware.bin"
190
430
 
431
+ case "check_firmware_file":
432
+ // Read file that should be at location and spit out the binary
433
+ // Example msg.payload
434
+ // msg.payload = {
435
+ // device_type: 80,
436
+ // hardware_id: [88, 88, 88]
437
+ // }
438
+ break;
439
+ case "ota_firmware_update_single":
440
+ // msg.payload = {
441
+ // 'address': "00:13:a2:00:42:2c:d2:aa"
442
+ // }
443
+ if(!Object.hasOwn(node._gateway_node.sensor_list, msg.payload)){
444
+ node._gateway_node.sensor_list[msg.payload] = {};
445
+ };
446
+ if(!Object.hasOwn(node._gateway_node.sensor_list[msg.payload], 'update_request')){
447
+ node._gateway_node.sensor_list[msg.payload].update_request = true;
448
+ };
449
+ break;
450
+ case "ota_firmware_update_multiple":
451
+ // set the devices user wants to upload new firmware to
452
+ // msg.payload = {
453
+ // 'addresses': [
454
+ // "00:13:a2:00:42:2c:d2:aa",
455
+ // "00:13:a2:00:42:2c:d2:ab"
456
+ // ];
457
+ // }
458
+ // TODO unfinished
459
+ msg.payload.addresses.forEach((address) => {
460
+ if(!Object.hasOwn(node._gateway_node.sensor_list, msg.payload.address)){
461
+ node._gateway_node.sensor_list[address] = {};
462
+ };
463
+ if(!Object.hasOwn(node._gateway_node.sensor_list[msg.payload.address], 'update_request')){
464
+ node._gateway_node.sensor_list[address].update_request = true;
465
+ };
466
+ });
467
+ break;
468
+ case "get_manifest":
469
+ // Allows user to request manifest from one or more devices
470
+ // Primarily envisioned used for troubleshooting or engineer determination
471
+ // msg.payload = {
472
+ // 'addresses': [
473
+ // "00:13:a2:00:42:2c:d2:aa",
474
+ // "00:13:a2:00:42:2c:d2:ab"
475
+ // ];
476
+ // }
477
+ // OR
478
+ // msg.payload = {
479
+ // 'address': "00:13:a2:00:42:2c:d2:aa"
480
+ // }
481
+ break;
482
+ default:
483
+ const byteArrayToHexString = byteArray => Array.from(msg.payload.address, byte => ('0' + (byte & 0xFF).toString(16)).slice(-2)).join('');
484
+ node.gateway.control_send(msg.payload.address, msg.payload.data, msg.payload.options).then().catch(console.log);
485
+ }
486
+
487
+
488
+ // console.log("input triggered, topic:"+msg.topic);
489
+ // if(msg.topic == "transmit"){
490
+ // const byteArrayToHexString = byteArray => Array.from(msg.payload.address, byte => ('0' + (byte & 0xFF).toString(16)).slice(-2)).join('');
491
+ // node.gateway.control_send(msg.payload.address, msg.payload.data, msg.payload.options).then().catch(console.log);
492
+ // }
493
+ // if(msg.topic == "route_trace"){
494
+ // var opts = {trace:1};
495
+ // node.gateway.route_discover(msg.payload.address,opts).then().catch(console.log);
496
+ // }
497
+ // if(msg.topic == "link_test"){
498
+ // node.gateway.link_test(msg.payload.source_address,msg.payload.destination_address,msg.payload.options);
499
+ // }
500
+ // if(msg.topic == "fft_request"){
501
+
502
+ // }
503
+ // if(msg.topic == "fidelity_test"){
504
+ // }
505
+ });
506
+ node.gateway.on('ncd_error', (data) => {
507
+ node.send({
508
+ topic: 'ncd_error',
509
+ data: data,
510
+ payload: data.error,
511
+ time: Date.now()
512
+ });
513
+ });
191
514
  node.gateway.on('sensor_data', (d) => {
192
515
  node.set_status();
193
516
  node.send({topic: 'sensor_data', payload: d, time: Date.now()});
@@ -237,7 +560,7 @@ module.exports = function(RED) {
237
560
  this.config_gateway = this.config_gateway_node.gateway;
238
561
  dedicated_config = true;
239
562
  }
240
- this.queue = new Queue(1);
563
+ // this.queue = new Queue(1);
241
564
  var node = this;
242
565
  var modes = {
243
566
  PGM: {fill:"red",shape:"dot",text:"Config Mode"},
@@ -247,6 +570,7 @@ module.exports = function(RED) {
247
570
  RUN: {fill:"green",shape:"dot",text:"Running"},
248
571
  PUM: {fill:"yellow",shape:"ring",text:"Module was factory reset"},
249
572
  ACK: {fill:"green",shape:"ring",text:"Configuration Acknowledged"},
573
+ STREAM_ERR: {fill:"red",shape:"ring",text:"Multi-Packet Stream Error"},
250
574
  // FLY: {fill:"yellow",shape:"ring",text:"FLY notification received"},
251
575
  // OTN: {fill:"yellow",shape:"ring",text:"OTN Received, OTF Configuration Initiated"},
252
576
  // OFF: {fill:"green",shape:"dot",text:"OFF Recieved, OTF Configuration Completed"}
@@ -275,7 +599,7 @@ module.exports = function(RED) {
275
599
 
276
600
  var promises = {};
277
601
  // This command is used for OTF on types 53, 80,81,82,83,84, 101, 102 , 518,519
278
- let original_otf_devices = [53, 80, 81, 82, 83, 84, 101, 102 , 518, 519, 520];
602
+ let original_otf_devices = [53, 80, 81, 82, 83, 84, 101, 102, 180, 181, 518, 519, 520];
279
603
  if(original_otf_devices.includes(sensor.type)){
280
604
  // This command is used for OTF on types 53, 80,81,82,83,84, 101, 102 , 518,519
281
605
  promises.config_enter_otn_mode = node.config_gateway.config_enter_otn_mode(sensor.mac);
@@ -415,6 +739,11 @@ module.exports = function(RED) {
415
739
  promises.change_detection = node.config_gateway.config_set_change_detection(mac, config.change_enabled ? 1 : 0, parseInt(config.change_pr), parseInt(config.change_interval));
416
740
  }
417
741
  switch(sensor.type){
742
+ case 2:
743
+ if(config.debounce_time_2_active){
744
+ promises.debounce_time_2 = node.config_gateway.config_set_debounce_time_2(mac, parseInt(config.debounce_time_2));
745
+ }
746
+ break;
418
747
  case 3:
419
748
  if(config.low_calibration_420ma_active){
420
749
  promises.low_calibration_420ma = node.config_gateway.config_set_low_calibration_420ma(mac, parseInt(config.low_calibration_420ma));
@@ -493,6 +822,21 @@ module.exports = function(RED) {
493
822
  }
494
823
  var interr = parseInt(config.activ_interr_x) | parseInt(config.activ_interr_y) | parseInt(config.activ_interr_z) | parseInt(config.activ_interr_op);
495
824
  promises.activity_interrupt = node.config_gateway.config_set_interrupt_24(mac, interr);
825
+ case 25:
826
+ if(config.impact_accel_active){
827
+ promises.impact_accel = node.config_gateway.config_set_acceleration_range_24(mac, parseInt(config.impact_accel));
828
+ }
829
+ if(config.impact_data_rate_active){
830
+ promises.impact_data_rate = node.config_gateway.config_set_data_rate_24(mac, parseInt(config.impact_data_rate));
831
+ }
832
+ if(config.impact_threshold_active){
833
+ promises.impact_threshold = node.config_gateway.config_set_threshold_24(mac, parseInt(config.impact_threshold));
834
+ }
835
+ if(config.impact_duration_active){
836
+ promises.impact_duration = node.config_gateway.config_set_duration_24(mac, parseInt(config.impact_duration));
837
+ }
838
+ var interr = parseInt(config.activ_interr_x) | parseInt(config.activ_interr_y) | parseInt(config.activ_interr_z) | parseInt(config.activ_interr_op);
839
+ promises.activity_interrupt = node.config_gateway.config_set_interrupt_24(mac, interr);
496
840
  case 35:
497
841
  if(config.counter_threshold_35_active){
498
842
  promises.config_set_counter_threshold_35 = node.config_gateway.config_set_counter_threshold_35(mac, parseInt(config.counter_threshold_35));
@@ -628,7 +972,7 @@ module.exports = function(RED) {
628
972
  promises.measurement_mode = node.config_gateway.config_set_measurement_mode_80(mac, parseInt(config.measurement_mode_80));
629
973
  }
630
974
  if(config.on_request_timeout_80_active){
631
- promises.on_request_timeout = node.config_gateway.config_set_filters_80(mac, parseInt(config.on_request_timeout_80));
975
+ promises.on_request_timeout = node.config_gateway.config_set_on_request_timeout_80(mac, parseInt(config.on_request_timeout_80));
632
976
  }
633
977
  if(config.deadband_80_active){
634
978
  promises.deadband = node.config_gateway.config_set_deadband_80(mac, parseInt(config.deadband_80));
@@ -737,7 +1081,7 @@ module.exports = function(RED) {
737
1081
  promises.measurement_mode = node.config_gateway.config_set_measurement_mode_80(mac, parseInt(config.measurement_mode_80));
738
1082
  }
739
1083
  if(config.on_request_timeout_80_active){
740
- promises.on_request_timeout = node.config_gateway.config_set_filters_80(mac, parseInt(config.on_request_timeout_80));
1084
+ promises.on_request_timeout = node.config_gateway.config_set_on_request_timeout_80(mac, parseInt(config.on_request_timeout_80));
741
1085
  }
742
1086
  if(config.deadband_80_active){
743
1087
  promises.deadband = node.config_gateway.config_set_deadband_80(mac, parseInt(config.deadband_80));
@@ -781,7 +1125,7 @@ module.exports = function(RED) {
781
1125
  promises.measurement_mode = node.config_gateway.config_set_measurement_mode_80(mac, parseInt(config.measurement_mode_80));
782
1126
  }
783
1127
  if(config.on_request_timeout_80_active){
784
- promises.on_request_timeout = node.config_gateway.config_set_filters_80(mac, parseInt(config.on_request_timeout_80));
1128
+ promises.on_request_timeout = node.config_gateway.config_set_on_request_timeout_80(mac, parseInt(config.on_request_timeout_80));
785
1129
  }
786
1130
  if(config.deadband_80_active){
787
1131
  promises.deadband = node.config_gateway.config_set_deadband_80(mac, parseInt(config.deadband_80));
@@ -901,6 +1245,115 @@ module.exports = function(RED) {
901
1245
  promises.debounce_time_108 = node.config_gateway.config_set_debounce_time_108(mac, parseInt(config.debounce_time_108));
902
1246
  }
903
1247
  break;
1248
+ case 180:
1249
+ if(config.current_calibration_c1_80_active){
1250
+ promises.current_calibration_c1_80 = node.config_gateway.config_set_current_calibration_individual_80(mac, parseInt(config.current_calibration_c1_80), 1);
1251
+ }
1252
+ if(config.output_data_rate_101_active){
1253
+ promises.output_data_rate_101 = node.config_gateway.config_set_output_data_rate_101(mac, parseInt(config.output_data_rate_101));
1254
+ }
1255
+ if(config.sampling_duration_101_active){
1256
+ promises.sampling_duration_101 = node.config_gateway.config_set_sampling_duration_101(mac, parseInt(config.sampling_duration_101));
1257
+ }
1258
+ if(config.x_axis_101 || config.y_axis_101 || config.z_axis_101){
1259
+ promises.axis_enabled_101 = node.config_gateway.config_set_axis_enabled_101(mac, config.x_axis_101, config.y_axis_101, config.z_axis_101);
1260
+ }
1261
+ if(config.sampling_interval_101_active){
1262
+ promises.sampling_interval_101 = node.config_gateway.config_set_sampling_interval_101(mac, parseInt(config.sampling_interval_101));
1263
+ }
1264
+ if(config.full_scale_range_101_active){
1265
+ promises.full_scale_range_101 = node.config_gateway.config_set_full_scale_range_101(mac, parseInt(config.full_scale_range_101));
1266
+ }
1267
+ if(config.mode_80_active){
1268
+ promises.mode = node.config_gateway.config_set_operation_mode_80(mac, parseInt(config.mode_80));
1269
+ }
1270
+ if(config.filter_80_active){
1271
+ promises.filter = node.config_gateway.config_set_filters_80(mac, parseInt(config.filter_80));
1272
+ }
1273
+ if(config.low_pass_filter_80_active){
1274
+ promises.low_pass_filter = node.config_gateway.config_set_low_pass_filter_80(mac, parseInt(config.low_pass_filter_80));
1275
+ }
1276
+ if(config.high_pass_filter_80_active){
1277
+ promises.high_pass_filter = node.config_gateway.config_set_high_pass_filter_80(mac, parseInt(config.high_pass_filter_80));
1278
+ }
1279
+ if(config.measurement_mode_80_active){
1280
+ promises.measurement_mode = node.config_gateway.config_set_measurement_mode_80(mac, parseInt(config.measurement_mode_80));
1281
+ }
1282
+ if(config.on_request_timeout_80_active){
1283
+ promises.on_request_timeout = node.config_gateway.config_set_on_request_timeout_80(mac, parseInt(config.on_request_timeout_80));
1284
+ }
1285
+ if(config.deadband_80_active){
1286
+ promises.deadband = node.config_gateway.config_set_deadband_80(mac, parseInt(config.deadband_80));
1287
+ }
1288
+ if(config.payload_length_80_active){
1289
+ promises.payload_length_80 = node.config_gateway.config_set_payload_length_80(mac, parseInt(config.payload_length_80));
1290
+ }
1291
+ if(config.set_rtc_101){
1292
+ promises.set_rtc_101 = node.config_gateway.config_set_rtc_101(mac);
1293
+ }
1294
+ break;
1295
+ case 181:
1296
+ if(config.current_calibration_c1_80_active){
1297
+ promises.current_calibration_c1_80_active = node.config_gateway.config_set_current_calibration_individual_80(mac, parseInt(config.current_calibration_c1_80), 1);
1298
+ }
1299
+ if(config.current_calibration_c2_80_active){
1300
+ promises.current_calibration_c2_80 = node.config_gateway.config_set_current_calibration_individual_80(mac, parseInt(config.current_calibration_c2_80), 3);
1301
+ }
1302
+ if(config.output_data_rate_p1_81_active){
1303
+ promises.output_data_rate_p1_81 = node.config_gateway.config_set_output_data_rate_101(mac, parseInt(config.output_data_rate_p1_81));
1304
+ }
1305
+ if(config.output_data_rate_p2_81_active){
1306
+ promises.output_data_rate_p2_81 = node.config_gateway.config_set_output_data_rate_p2_81(mac, parseInt(config.output_data_rate_p2_81));
1307
+ }
1308
+ if(config.sampling_duration_p1_81_active){
1309
+ promises.sampling_duration_p1_81 = node.config_gateway.config_set_sampling_duration_101(mac, parseInt(config.sampling_duration_p1_81));
1310
+ }
1311
+ if(config.sampling_duration_p2_81_active){
1312
+ promises.sampling_duration_p2_81 = node.config_gateway.config_set_sampling_duration_p2_81(mac, parseInt(config.sampling_duration_p2_81));
1313
+ }
1314
+ if(config.x_axis_101 || config.y_axis_101 || config.z_axis_101){
1315
+ promises.axis_enabled_101 = node.config_gateway.config_set_axis_enabled_101(mac, config.x_axis_101, config.y_axis_101, config.z_axis_101);
1316
+ }
1317
+ if(config.sampling_interval_101_active){
1318
+ promises.sampling_interval_101 = node.config_gateway.config_set_sampling_interval_101(mac, parseInt(config.sampling_interval_101));
1319
+ }
1320
+ if(config.full_scale_range_101_active){
1321
+ promises.full_scale_range_101 = node.config_gateway.config_set_full_scale_range_101(mac, parseInt(config.full_scale_range_101));
1322
+ }
1323
+ if(config.mode_80_active){
1324
+ promises.mode = node.config_gateway.config_set_operation_mode_80(mac, parseInt(config.mode_80));
1325
+ }
1326
+ if(config.filter_80_active){
1327
+ promises.filter = node.config_gateway.config_set_filters_80(mac, parseInt(config.filter_80));
1328
+ }
1329
+ if(config.low_pass_filter_80_active){
1330
+ promises.low_pass_filter = node.config_gateway.config_set_low_pass_filter_80(mac, parseInt(config.low_pass_filter_80));
1331
+ }
1332
+ if(config.high_pass_filter_80_active){
1333
+ promises.high_pass_filter = node.config_gateway.config_set_high_pass_filter_80(mac, parseInt(config.high_pass_filter_80));
1334
+ }
1335
+ if(config.low_pass_filter_81_p2_active){
1336
+ promises.low_pass_filter_p2 = node.config_gateway.config_set_low_pass_filter_81_p2(mac, parseInt(config.low_pass_filter_81_p2));
1337
+ }
1338
+ if(config.high_pass_filter_81_p2_active){
1339
+ promises.high_pass_filter_p2 = node.config_gateway.config_set_high_pass_filter_81_p2(mac, parseInt(config.high_pass_filter_81_p2));
1340
+ }
1341
+ if(config.measurement_mode_80_active){
1342
+ promises.measurement_mode = node.config_gateway.config_set_measurement_mode_80(mac, parseInt(config.measurement_mode_80));
1343
+ }
1344
+ if(config.on_request_timeout_80_active){
1345
+ promises.on_request_timeout = node.config_gateway.config_set_on_request_timeout_80(mac, parseInt(config.on_request_timeout_80));
1346
+ }
1347
+ if(config.deadband_80_active){
1348
+ promises.deadband = node.config_gateway.config_set_deadband_80(mac, parseInt(config.deadband_80));
1349
+ }
1350
+ if(config.payload_length_80_active){
1351
+ promises.payload_length_80 = node.config_gateway.config_set_payload_length_80(mac, parseInt(config.payload_length_80));
1352
+ }
1353
+ if(config.set_rtc_101){
1354
+ promises.set_rtc_101 = node.config_gateway.config_set_rtc_101(mac);
1355
+ }
1356
+ break;
904
1357
  case 200:
905
1358
  if(config.low_calibration_420ma_active){
906
1359
  promises.low_calibration_420ma = node.config_gateway.config_set_low_calibration_420ma(mac, parseInt(config.low_calibration_420ma));
@@ -960,7 +1413,7 @@ module.exports = function(RED) {
960
1413
  promises.measurement_mode = node.config_gateway.config_set_measurement_mode_80(mac, parseInt(config.measurement_mode_80));
961
1414
  }
962
1415
  if(config.on_request_timeout_80_active){
963
- promises.on_request_timeout = node.config_gateway.config_set_filters_80(mac, parseInt(config.on_request_timeout_80));
1416
+ promises.on_request_timeout = node.config_gateway.config_set_on_request_timeout_80(mac, parseInt(config.on_request_timeout_80));
964
1417
  }
965
1418
  if(config.deadband_80_active){
966
1419
  promises.deadband = node.config_gateway.config_set_deadband_80(mac, parseInt(config.deadband_80));
@@ -1024,7 +1477,7 @@ module.exports = function(RED) {
1024
1477
  promises.measurement_mode = node.config_gateway.config_set_measurement_mode_80(mac, parseInt(config.measurement_mode_80));
1025
1478
  }
1026
1479
  if(config.on_request_timeout_80_active){
1027
- promises.on_request_timeout = node.config_gateway.config_set_filters_80(mac, parseInt(config.on_request_timeout_80));
1480
+ promises.on_request_timeout = node.config_gateway.config_set_on_request_timeout_80(mac, parseInt(config.on_request_timeout_80));
1028
1481
  }
1029
1482
  if(config.deadband_80_active){
1030
1483
  promises.deadband = node.config_gateway.config_set_deadband_80(mac, parseInt(config.deadband_80));
@@ -1048,10 +1501,33 @@ module.exports = function(RED) {
1048
1501
  promises.set_rtc_101 = node.config_gateway.config_set_rtc_101(mac);
1049
1502
  }
1050
1503
  break;
1504
+ case 537:
1505
+ if(config.stay_on_mode_539_active){
1506
+ promises.stay_on_mode_539 = node.config_gateway.config_set_stay_on_mode_539(mac, parseInt(config.stay_on_mode_539));
1507
+ }
1508
+ if(config.baudrate_539_active){
1509
+ promises.baudrate_539 = node.config_gateway.config_set_baudrate_539(mac, parseInt(config.baudrate_539));
1510
+ }
1511
+ if(config.rx_timeout_539_active){
1512
+ promises.rx_timeout_539 = node.config_gateway.config_set_rx_timeout_539(mac, parseInt(config.rx_timeout_539));
1513
+ }
1514
+ if(config.bootup_time_539_active){
1515
+ promises.bootup_time_539 = node.config_gateway.config_set_bootup_time_539(mac, parseInt(config.bootup_time_539));
1516
+ }
1517
+ if(config.sensor_add_539_active){
1518
+ promises.sensor_add_539 = node.config_gateway.config_set_sensor_add_539(mac, parseInt(config.sensor_add_539));
1519
+ }
1520
+ if(config.rs_node_id_539_active){
1521
+ promises.rs_node_id_539 = node.config_gateway.config_set_rs_node_id_539(mac, parseInt(config.rs_node_id_539));
1522
+ }
1523
+ if(config.number_of_regs_to_rd_539_active){
1524
+ promises.number_of_regs_to_rd_539 = node.config_gateway.config_set_number_of_regs_to_rd_539(mac, parseInt(config.number_of_regs_to_rd_539));
1525
+ }
1526
+ break;
1051
1527
  }
1052
1528
  }
1053
1529
  // These sensors listed in original_otf_devices use a different OTF code.
1054
- let original_otf_devices = [53, 80, 81, 82, 83, 84, 101, 102 , 518, 519, 520];
1530
+ let original_otf_devices = [53, 80, 81, 82, 83, 84, 101, 102, 180, 181, 518, 519, 520];
1055
1531
  // If we changed the network ID reboot the sensor to take effect.
1056
1532
  // TODO if we add the encryption key command to node-red we need to reboot for it as well.
1057
1533
  if(reboot){
@@ -1463,3 +1939,4 @@ function toHex(n){return ('00' + n.toString(16)).substr(-2);}
1463
1939
  function toMac(arr){
1464
1940
  return arr.reduce((h,c,i) => {return ((i==1?toHex(h):h)+':'+toHex(c)).toUpperCase();});
1465
1941
  }
1942
+ function msbLsb(m,l){return (m<<8)+l;};