@ncd-io/node-red-enterprise-sensors 0.1.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/wireless.js ADDED
@@ -0,0 +1,1208 @@
1
+ const wireless = require("./index.js");
2
+ const comms = require('ncd-red-comm');
3
+ const sp = require('serialport');
4
+ const Queue = require("promise-queue");
5
+ const events = require("events");
6
+
7
+ module.exports = function(RED) {
8
+ var gateway_pool = {};
9
+ function NcdGatewayConfig(config){
10
+ RED.nodes.createNode(this,config);
11
+
12
+ this.port = config.comm_type == 'serial' ? config.port : config.tcp_port;
13
+ this.baudRate = parseInt(config.baudRate);
14
+
15
+ this.listeners = [];
16
+ this.sensor_pool = [];
17
+ this._emitter = new events.EventEmitter();
18
+ this.on = (e,c) => this._emitter.on(e, c);
19
+
20
+ if(config.comm_type == 'serial'){
21
+ this.key = config.port;
22
+ }
23
+ else{
24
+ this.key = config.ip_address+":"+config.tcp_port;
25
+ }
26
+
27
+ var node = this;
28
+
29
+ node.is_config = 3;
30
+ node.open_comms = function(cb){
31
+ if(typeof gateway_pool[this.key] == 'undefined'){
32
+ if(config.comm_type == 'serial'){
33
+ var comm = new comms.NcdSerial(this.port, this.baudRate);
34
+ comm._emitter.on('error', (err) => {
35
+ console.log('gateway config serial error', err);
36
+ });
37
+ }else{
38
+ if(!config.ip_address){
39
+ return;
40
+ }
41
+ var comm = new comms.NcdTCP(config.ip_address, this.port);
42
+ comm._emitter.on('error', (err) => {
43
+ console.log('tcp init error', err);
44
+ });
45
+ }
46
+ var modem = new wireless.Modem(comm);
47
+ gateway_pool[this.key] = new wireless.Gateway(modem);
48
+ gateway_pool[this.key].pan_id = false;
49
+
50
+ this.gateway = gateway_pool[this.key];
51
+ this.gateway.digi.report_rssi = config.rssi;
52
+
53
+ if(config.comm_type == 'serial'){
54
+ node.gateway.digi.serial.setupSerial();
55
+ }else{
56
+ node.gateway.digi.serial.setupClient();
57
+ }
58
+ node.gateway.digi.serial.on('ready', () => {
59
+ node.check_mode((mode) => {
60
+ var pan_id = parseInt(config.pan_id, 16);
61
+ // if(!mode && node.gateway.pan_id != pan_id){
62
+ if(node.gateway.pan_id != pan_id){
63
+ node.gateway.digi.send.at_command("ID", [pan_id >> 8, pan_id & 255]).then((res) => {
64
+ node.gateway.pan_id = pan_id;
65
+ }).catch((err) => {
66
+ console.log(err);
67
+ node.gateway.digi.serial.reconnect();
68
+ });
69
+ }
70
+ });
71
+ node.gateway.digi.send.at_command('SL').then((res) => {
72
+ node.gateway.modem_mac = '00:13:A2:00:'+toMac(res.data);
73
+ }).catch((err) => {
74
+ console.log(err);
75
+ node.gateway.digi.serial.reconnect();
76
+ });
77
+ });
78
+ node.gateway.digi.serial.on('closed_comms', () => {
79
+ node.is_config = 3;
80
+ node._emitter.emit('mode_change', node.is_config);
81
+ });
82
+ }
83
+ };
84
+ node.check_mode = function(cb){
85
+ node.gateway.digi.send.at_command("ID").then((res) => {
86
+ var pan_id = (res.data[0] << 8) | res.data[1];
87
+ if(pan_id == 0x7BCD && parseInt(config.pan_id, 16) != 0x7BCD){
88
+ node.is_config = 1;
89
+ }else{
90
+ node.gateway.pan_id = pan_id;
91
+ node.is_config = 0;
92
+ }
93
+ if(cb) cb(node.is_config);
94
+ return node.is_config;
95
+ }).catch((err) => {
96
+ console.log(err);
97
+ node.is_config = 2;
98
+ node.gateway.digi.serial.reconnect();
99
+ if(cb) cb(node.is_config);
100
+ return node.is_config;
101
+ }).then((mode) => {
102
+ node._emitter.emit('mode_change', mode);
103
+ });
104
+ };
105
+
106
+
107
+ node.close_comms = function(){
108
+ // node.gateway._emitter.removeAllListeners('sensor_data');
109
+ if(typeof gateway_pool[this.key] != 'undefined'){
110
+ if(config.comm_type == 'serial'){
111
+ node.gateway.digi.serial.close();
112
+ // node.gateway.digi.serial.close(() => {
113
+ delete gateway_pool[this.key];
114
+ // });
115
+ }else{
116
+ node.gateway.digi.serial.close();
117
+ // node.gateway.digi.serial.close(() => {
118
+ delete gateway_pool[this.key];
119
+ // });
120
+ }
121
+ }
122
+
123
+ }
124
+ }
125
+
126
+ RED.nodes.registerType("ncd-gateway-config", NcdGatewayConfig);
127
+
128
+ function NcdGatewayNode(config){
129
+ RED.nodes.createNode(this,config);
130
+
131
+ this._gateway_node = RED.nodes.getNode(config.connection);
132
+
133
+ this._gateway_node.open_comms();
134
+ this.gateway = this._gateway_node.gateway;
135
+
136
+ var node = this;
137
+
138
+ node.on('close', function(){
139
+ this._gateway_node.close_comms();
140
+ });
141
+
142
+ node.is_config = false;
143
+ var statuses =[
144
+ {fill:"green",shape:"dot",text:"Ready"},
145
+ {fill:"yellow",shape:"ring",text:"Configuring"},
146
+ {fill:"red",shape:"dot",text:"Failed to Connect"},
147
+ {fill:"green",shape:"ring",text:"Connecting..."}
148
+ ];
149
+
150
+ node.set_status = function(){
151
+ node.status(statuses[node._gateway_node.is_config]);
152
+ };
153
+
154
+ node.on('input', function(msg){
155
+ node.gateway.control_send(msg.payload.address, msg.payload.data, msg.payload.options).then().catch(console.log);
156
+ });
157
+
158
+ node.gateway.on('sensor_data', (d) => {
159
+ node.set_status();
160
+ node.send({topic: 'sensor_data', payload: d, time: Date.now()});
161
+ });
162
+ node.gateway.on('sensor_mode', (d) => {
163
+ node.set_status();
164
+ node.send({topic: 'sensor_mode', payload: d, time: Date.now()});
165
+ });
166
+ node.gateway.on('receive_packet-unknown_device',(d)=>{
167
+ node.set_status();
168
+ msg1 = {topic:'somethingTopic',payload:"something"};
169
+ node.send([null,{topic: 'unknown_data', payload:d, time: Date.now()}]);
170
+ });
171
+
172
+ node.set_status();
173
+ node._gateway_node.on('mode_change', (mode) => {
174
+ node.set_status();
175
+ if(this.gateway.modem_mac && this._gateway_node.is_config == 0 || this.gateway.modem_mac && this._gateway_node.is_config == 1){
176
+ node.send({topic: 'modem_mac', payload: this.gateway.modem_mac, time: Date.now()});
177
+ }else{
178
+ node.send({topic: 'error', payload: {code: 1, description: 'Wireless module did not respond'}, time: Date.now()});
179
+ }
180
+ });
181
+ }
182
+ RED.nodes.registerType("ncd-gateway-node", NcdGatewayNode);
183
+
184
+
185
+ function NcdWirelessNode(config){
186
+ RED.nodes.createNode(this,config);
187
+ this.gateway_node = RED.nodes.getNode(config.connection);
188
+ this.gateway_node.open_comms();
189
+ this.gateway = this.gateway_node.gateway;
190
+ var dedicated_config = false;
191
+ this.config_gateway = this.gateway;
192
+
193
+ if(config.config_comm){
194
+ this.config_gateway_node = RED.nodes.getNode(config.config_comm);
195
+ this.config_gateway_node.open_comms();
196
+ this.config_gateway = this.config_gateway_node.gateway;
197
+ dedicated_config = true;
198
+ }
199
+ this.queue = new Queue(1);
200
+ var node = this;
201
+ var modes = {
202
+ PGM: {fill:"red",shape:"dot",text:"Config Mode"},
203
+ PGM_NOW: {fill:"red",shape:"dot",text:"Configuring..."},
204
+ READY: {fill: "green", shape: "ring", text:"Config Complete"},
205
+ PGM_ERR: {fill:"red", shape:"ring", text:"Config Error"},
206
+ RUN: {fill:"green",shape:"dot",text:"Running"},
207
+ PUM: {fill:"yellow",shape:"ring",text:"Module was factory reset"},
208
+ ACK: {fill:"green",shape:"ring",text:"Configuration Acknowledged"},
209
+ // FLY: {fill:"yellow",shape:"ring",text:"FLY notification received"},
210
+ // OTN: {fill:"yellow",shape:"ring",text:"OTN Received, OTF Configuration Initiated"},
211
+ // OFF: {fill:"green",shape:"dot",text:"OFF Recieved, OTF Configuration Completed"}
212
+ FLY: {fill:"yellow",shape:"ring",text:"FLY"},
213
+ OTN: {fill:"yellow",shape:"ring",text:"OTN Received, Config Entered"},
214
+ OTF: {fill:"green",shape:"dot",text:"OTF Received, Config Complete"}
215
+ };
216
+ var events = {};
217
+ var pgm_events = {};
218
+ this.gtw_on = (event, cb) => {
219
+ events[event] = cb;
220
+ this.gateway.on(event, cb);
221
+ };
222
+ this.pgm_on = (event, cb) => {
223
+ events[event] = cb;
224
+ this.config_gateway.on(event, cb);
225
+ };
226
+ function _send_otn_request(sensor){
227
+ return new Promise((top_fulfill, top_reject) => {
228
+ var msg = {};
229
+ setTimeout(() => {
230
+ var tout = setTimeout(() => {
231
+ node.status(modes.PGM_ERR);
232
+ node.send({topic: 'OTN Request Results', payload: msg, time: Date.now()});
233
+ }, 10000);
234
+
235
+ var promises = {};
236
+ // This command is used for OTF on types 53, 80,81,82,83,84, 101, 102 , 518,519
237
+ let original_otf_devices = [53, 80, 81, 82, 83, 84, 101, 102 , 518, 519, 520];
238
+ if(original_otf_devices.includes(sensor.type)){
239
+ // This command is used for OTF on types 53, 80,81,82,83,84, 101, 102 , 518,519
240
+ promises.config_enter_otn_mode = node.config_gateway.config_enter_otn_mode(sensor.mac);
241
+ }else{
242
+ // This command is used for OTF on types not 53, 80,81,82,83,84, 101, 102 , 518,519
243
+ promises.config_enter_otn_mode = node.config_gateway.config_enter_otn_mode_common(sensor.mac);
244
+ }
245
+ promises.finish = new Promise((fulfill, reject) => {
246
+ node.config_gateway.queue.add(() => {
247
+ return new Promise((f, r) => {
248
+ clearTimeout(tout);
249
+ node.status(modes.FLY);
250
+ fulfill();
251
+ f();
252
+ });
253
+ });
254
+ });
255
+ for(var i in promises){
256
+ (function(name){
257
+ promises[name].then((f) => {
258
+ if(name != 'finish') msg[name] = true;
259
+ else{
260
+ // #OTF
261
+ node.send({topic: 'OTN Request Results', payload: msg, time: Date.now()});
262
+ top_fulfill(msg);
263
+ }
264
+ }).catch((err) => {
265
+ msg[name] = err;
266
+ });
267
+ })(i);
268
+ }
269
+ });
270
+ });
271
+ };
272
+ function _broadcast_rtc(sensor){
273
+ return new Promise((top_fulfill, top_reject) => {
274
+ var msg = {};
275
+ setTimeout(() => {
276
+ var tout = setTimeout(() => {
277
+ node.status(modes.PGM_ERR);
278
+ node.send({topic: 'RTC Broadcast', payload: msg, time: Date.now()});
279
+ }, 10000);
280
+
281
+ var promises = {};
282
+
283
+ promises.broadcast_rtc = node.config_gateway.config_set_rtc_101('00:00:00:00:00:00:FF:FF');
284
+
285
+ promises.finish = new Promise((fulfill, reject) => {
286
+ node.config_gateway.queue.add(() => {
287
+ return new Promise((f, r) => {
288
+ clearTimeout(tout);
289
+ node.status(modes.FLY);
290
+ fulfill();
291
+ f();
292
+ });
293
+ });
294
+ });
295
+ for(var i in promises){
296
+ (function(name){
297
+ promises[name].then((f) => {
298
+ if(name != 'finish') msg[name] = true;
299
+ else{
300
+ // #OTF
301
+ this.gateway.fly_101_in_progress = false;
302
+ node.send({topic: 'RTC Broadcast', payload: msg, time: Date.now()});
303
+ top_fulfill(msg);
304
+ }
305
+ }).catch((err) => {
306
+ msg[name] = err;
307
+ });
308
+ })(i);
309
+ }
310
+ });
311
+ });
312
+ }
313
+ function _config(sensor, otf = false){
314
+ return new Promise((top_fulfill, top_reject) => {
315
+ var success = {};
316
+ setTimeout(() => {
317
+ var tout = setTimeout(() => {
318
+ node.status(modes.PGM_ERR);
319
+ node.send({topic: 'Config Results', payload: success, time: Date.now()});
320
+ }, 60000);
321
+ node.status(modes.PGM_NOW);
322
+ if(parseInt(config.sensor_type) >= 10000){
323
+ if(sensor) return;
324
+ var dest = parseInt(config.destination, 16);
325
+ if(dest == 65535){
326
+ dest = [0,0,0,0,0,0,255,255];
327
+ }else{
328
+ dest = [0, 0x13, 0xa2, 0, ...int2Bytes(dest, 4)];
329
+ }
330
+ var promises = {
331
+ destination: node.gateway.config_powered_device(config.addr, 'destination', ...dest),
332
+ network_id: node.gateway.config_powered_device(config.addr, 'network_id', ...int2Bytes(parseInt(config.pan_id, 16), 2)),
333
+ power: node.gateway.config_powered_device(config.addr, 'power', parseInt(config.power)),
334
+ retries: node.gateway.config_powered_device(config.addr, 'retries', parseInt(config.retries)),
335
+ node_id: node.gateway.config_powered_device(config.addr, 'node_id', parseInt(config.node_id)),
336
+ delay: node.gateway.config_powered_device(config.addr, 'delay', ...int2Bytes(parseInt(config.delay), 2))
337
+ };
338
+ }else{
339
+ var mac = sensor.mac;
340
+ var promises = {};
341
+ var reboot = false;
342
+ if(config.form_network){
343
+ promises.establish_config_network_1 = node.config_gateway.config_get_pan_id('00:00:00:00:00:00:FF:FF');
344
+ promises.establish_config_network_2 = node.config_gateway.config_get_pan_id('00:00:00:00:00:00:FF:FF');
345
+ promises.establish_config_network_3 = node.config_gateway.config_get_pan_id('00:00:00:00:00:00:FF:FF');
346
+ }
347
+ if(config.destination_active){
348
+ promises.destination = node.config_gateway.config_set_destination(mac, parseInt(config.destination, 16));
349
+ }
350
+ if(config.pan_id_active){
351
+ reboot = true;
352
+ promises.network_id = node.config_gateway.config_set_pan_id(mac, parseInt(config.pan_id, 16));
353
+ }
354
+ // var promises = {
355
+ // // NOTE: establish_config_network_x commands added to force XBee network to form before sending commands.
356
+ // establish_config_network_1: node.config_gateway.config_get_pan_id('00:00:00:00:00:00:FF:FF'),
357
+ // establish_config_network_2: node.config_gateway.config_get_pan_id('00:00:00:00:00:00:FF:FF'),
358
+ // establish_config_network_3: node.config_gateway.config_get_pan_id('00:00:00:00:00:00:FF:FF'),
359
+ //
360
+ // destination: node.config_gateway.config_set_destination(mac, parseInt(config.destination, 16)),
361
+ // network_id: node.config_gateway.config_set_pan_id(mac, parseInt(config.pan_id, 16))
362
+ // };
363
+ if(config.node_id_delay_active){
364
+ promises.id_and_delay = node.config_gateway.config_set_id_delay(mac, parseInt(config.node_id), parseInt(config.delay));
365
+ }
366
+ if(config.power_active){
367
+ promises.power = node.config_gateway.config_set_power(mac, parseInt(config.power));
368
+ }
369
+ if(config.retries_active){
370
+ promises.retries = node.config_gateway.config_set_retries(mac, parseInt(config.retries));
371
+ }
372
+ var change_detection = [13, 10, 3];
373
+ if(change_detection.indexOf(sensor.type) > -1){
374
+ promises.change_detection = node.config_gateway.config_set_change_detection(mac, config.change_enabled ? 1 : 0, parseInt(config.change_pr), parseInt(config.change_interval));
375
+ }
376
+ switch(sensor.type){
377
+ case 5:
378
+ promises.acceleration_range = node.config_gateway.config_set_amgt_accel(mac, parseInt(config.amgt_accel));
379
+ promises.magnetometer_gain = node.config_gateway.config_set_amgt_magnet(mac, parseInt(config.amgt_mag));
380
+ promises.gyroscope_scale = node.config_gateway.config_set_amgt_gyro(mac, parseInt(config.amgt_gyro));
381
+ break;
382
+ case 6:
383
+ promises.altitude = node.config_gateway.config_set_bp_altitude(mac, parseInt(config.bp_altitude));
384
+ promises.pressure = node.config_gateway.config_set_bp_pressure(mac, parseInt(config.bp_pressure));
385
+ promises.temp_precision = node.config_gateway.config_set_bp_temp_precision(mac, parseInt(config.bp_temp_prec));
386
+ promises.pressure_precision = node.config_gateway.config_set_bp_press_precision(mac, parseInt(config.bp_press_prec));
387
+ break;
388
+ case 7:
389
+ promises.acceleration_range = node.config_gateway.config_set_impact_accel(mac, parseInt(config.impact_accel));
390
+ promises.data_rate = node.config_gateway.config_set_impact_data_rate(mac, parseInt(config.impact_data_rate));
391
+ promises.impact_threshold = node.config_gateway.config_set_impact_threshold(mac, parseInt(config.impact_threshold));
392
+ promises.impact_duration = node.config_gateway.config_set_impact_duration(mac, parseInt(config.impact_duration));
393
+ break;
394
+ case 13:
395
+ var cali = parseFloat(config.cm_calibration);
396
+ if(cali == 0) break;
397
+ promises.calibration = node.config_gateway.config_set_cm_calibration(mac, cali);
398
+ break;
399
+ case 14:
400
+ if(config.sensor_boot_time_420ma_active){
401
+ promises.sensor_boot_time_420ma = node.config_gateway.config_set_sensor_boot_time_420ma(mac, parseInt(config.sensor_boot_time_420ma));
402
+ }
403
+ break;
404
+ case 24:
405
+ var interr = parseInt(config.activ_interr_x) | parseInt(config.activ_interr_y) | parseInt(config.activ_interr_z) | parseInt(config.activ_interr_op);
406
+ promises.activity_interrupt = node.config_gateway.config_set_activ_interr(mac, interr);
407
+ case 35:
408
+ if(config.counter_threshold_35_active){
409
+ promises.config_set_counter_threshold_35 = node.config_gateway.config_set_counter_threshold_35(mac, parseInt(config.counter_threshold_35));
410
+ }
411
+ break;
412
+ case 36:
413
+ if(config.counter_threshold_35_active){
414
+ promises.config_set_counter_threshold_35 = node.config_gateway.config_set_counter_threshold_35(mac, parseInt(config.counter_threshold_35));
415
+ }
416
+ break;
417
+ case 40:
418
+ promises.filtering = node.config_gateway.config_set_filtering(mac, parseInt(config.filtering));
419
+ promises.data_rate = node.config_gateway.config_set_data_rate(mac, parseInt(config.data_rate));
420
+ promises.time_series = node.config_gateway.config_set_time_series(mac, parseInt(config.time_series));
421
+ promises.reading_type = node.config_gateway.config_set_reading_type(mac, parseInt(config.reading_type));
422
+ break;
423
+ case 44:
424
+ if(config.force_calibration_co2_auto_config){
425
+ promises.sensor_forced_calibration = node.config_gateway.config_set_sensor_forced_calibration(mac, parseInt(config.force_calibration_co2));
426
+ }
427
+ break;
428
+ case 45:
429
+ if(config.sensor_boot_time_420ma_active){
430
+ promises.sensor_boot_time_420ma = node.config_gateway.config_set_sensor_boot_time_420ma(mac, parseInt(config.sensor_boot_time_420ma));
431
+ }
432
+ break;
433
+ case 47:
434
+ if(config.roll_angle_threshold_47_active){
435
+ promises.roll_angle_threshold_47 = node.config_gateway.config_set_roll_threshold_47(mac, parseInt(config.roll_angle_threshold_47));
436
+ }
437
+ if(config.pitch_angle_threshold_47_active){
438
+ promises.pitch_angle_threshold_47 = node.config_gateway.config_set_pitch_threshold_47(mac, parseInt(config.pitch_angle_threshold_47));
439
+ }
440
+ break;
441
+ case 48:
442
+ if(config.sensor_boot_time_420ma_active){
443
+ promises.sensor_boot_time_420ma = node.config_gateway.config_set_sensor_boot_time_420ma(mac, parseInt(config.sensor_boot_time_420ma));
444
+ }
445
+ break;
446
+ case 52:
447
+ if(config.sensor_boot_time_420ma_active){
448
+ promises.sensor_boot_time_420ma = node.config_gateway.config_set_sensor_boot_time_420ma(mac, parseInt(config.sensor_boot_time_420ma));
449
+ }
450
+ break;
451
+ case 80:
452
+ if(config.current_calibration_c1_80_active){
453
+ promises.current_calibration_c1_80 = node.config_gateway.config_set_current_calibration_individual_80(mac, parseInt(config.current_calibration_c1_80), 1);
454
+ }
455
+ if(config.output_data_rate_101_active){
456
+ promises.output_data_rate_101 = node.config_gateway.config_set_output_data_rate_101(mac, parseInt(config.output_data_rate_101));
457
+ }
458
+ if(config.sampling_duration_101_active){
459
+ promises.sampling_duration_101 = node.config_gateway.config_set_sampling_duration_101(mac, parseInt(config.sampling_duration_101));
460
+ }
461
+ if(config.x_axis_101 || config.y_axis_101 || config.z_axis_101){
462
+ 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);
463
+ }
464
+ if(config.sampling_interval_101_active){
465
+ promises.sampling_interval_101 = node.config_gateway.config_set_sampling_interval_101(mac, parseInt(config.sampling_interval_101));
466
+ }
467
+ if(config.full_scale_range_101_active){
468
+ promises.full_scale_range_101 = node.config_gateway.config_set_full_scale_range_101(mac, parseInt(config.full_scale_range_101));
469
+ }
470
+ if(config.mode_80_active){
471
+ promises.mode = node.config_gateway.config_set_operation_mode_80(mac, parseInt(config.mode_80));
472
+ }
473
+ if(config.filter_80_active){
474
+ promises.filter = node.config_gateway.config_set_filters_80(mac, parseInt(config.filter_80));
475
+ }
476
+ if(config.low_pass_filter_80_active){
477
+ promises.low_pass_filter = node.config_gateway.config_set_low_pass_filter_80(mac, parseInt(config.low_pass_filter_80));
478
+ }
479
+ if(config.high_pass_filter_80_active){
480
+ promises.high_pass_filter = node.config_gateway.config_set_high_pass_filter_80(mac, parseInt(config.high_pass_filter_80));
481
+ }
482
+ if(config.measurement_mode_80_active){
483
+ promises.measurement_mode = node.config_gateway.config_set_measurement_mode_80(mac, parseInt(config.measurement_mode_80));
484
+ }
485
+ if(config.on_request_timeout_80_active){
486
+ promises.on_request_timeout = node.config_gateway.config_set_filters_80(mac, parseInt(config.on_request_timeout_80));
487
+ }
488
+ if(config.deadband_80_active){
489
+ promises.deadband = node.config_gateway.config_set_deadband_80(mac, parseInt(config.deadband_80));
490
+ }
491
+ if(config.payload_length_80_active){
492
+ promises.payload_length_80 = node.config_gateway.config_set_payload_length_80(mac, parseInt(config.payload_length_80));
493
+ }
494
+ if(config.set_rtc_101){
495
+ promises.set_rtc_101 = node.config_gateway.config_set_rtc_101(mac);
496
+ }
497
+ break;
498
+ case 81:
499
+ if(config.current_calibration_c1_80_active){
500
+ promises.current_calibration_c1_80_active = node.config_gateway.config_set_current_calibration_individual_80(mac, parseInt(config.current_calibration_c1_80), 1);
501
+ }
502
+ if(config.current_calibration_c2_80_active){
503
+ promises.current_calibration_c2_80 = node.config_gateway.config_set_current_calibration_individual_80(mac, parseInt(config.current_calibration_c2_80), 3);
504
+ }
505
+ if(config.output_data_rate_p1_81_active){
506
+ promises.output_data_rate_p1_81 = node.config_gateway.config_set_output_data_rate_101(mac, parseInt(config.output_data_rate_p1_81));
507
+ }
508
+ if(config.output_data_rate_p2_81_active){
509
+ promises.output_data_rate_p2_81 = node.config_gateway.config_set_output_data_rate_p2_81(mac, parseInt(config.output_data_rate_p2_81));
510
+ }
511
+ if(config.sampling_duration_p1_81_active){
512
+ promises.sampling_duration_p1_81 = node.config_gateway.config_set_sampling_duration_101(mac, parseInt(config.sampling_duration_p1_81));
513
+ }
514
+ if(config.sampling_duration_p2_81_active){
515
+ promises.sampling_duration_p2_81 = node.config_gateway.config_set_sampling_duration_p2_81(mac, parseInt(config.sampling_duration_p2_81));
516
+ }
517
+ if(config.x_axis_101 || config.y_axis_101 || config.z_axis_101){
518
+ 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);
519
+ }
520
+ if(config.sampling_interval_101_active){
521
+ promises.sampling_interval_101 = node.config_gateway.config_set_sampling_interval_101(mac, parseInt(config.sampling_interval_101));
522
+ }
523
+ if(config.full_scale_range_101_active){
524
+ promises.full_scale_range_101 = node.config_gateway.config_set_full_scale_range_101(mac, parseInt(config.full_scale_range_101));
525
+ }
526
+ if(config.mode_80_active){
527
+ promises.mode = node.config_gateway.config_set_operation_mode_80(mac, parseInt(config.mode_80));
528
+ }
529
+ if(config.filter_80_active){
530
+ promises.filter = node.config_gateway.config_set_filters_80(mac, parseInt(config.filter_80));
531
+ }
532
+ if(config.low_pass_filter_80_active){
533
+ promises.low_pass_filter = node.config_gateway.config_set_low_pass_filter_80(mac, parseInt(config.low_pass_filter_80));
534
+ }
535
+ if(config.high_pass_filter_80_active){
536
+ promises.high_pass_filter = node.config_gateway.config_set_high_pass_filter_80(mac, parseInt(config.high_pass_filter_80));
537
+ }
538
+ if(config.low_pass_filter_81_p2_active){
539
+ promises.low_pass_filter_p2 = node.config_gateway.config_set_low_pass_filter_81_p2(mac, parseInt(config.low_pass_filter_81_p2));
540
+ }
541
+ if(config.high_pass_filter_81_p2_active){
542
+ promises.high_pass_filter_p2 = node.config_gateway.config_set_high_pass_filter_81_p2(mac, parseInt(config.high_pass_filter_81_p2));
543
+ }
544
+ if(config.measurement_mode_80_active){
545
+ promises.measurement_mode = node.config_gateway.config_set_measurement_mode_80(mac, parseInt(config.measurement_mode_80));
546
+ }
547
+ if(config.on_request_timeout_80_active){
548
+ promises.on_request_timeout = node.config_gateway.config_set_on_request_timeout_80(mac, parseInt(config.on_request_timeout_80));
549
+ }
550
+ if(config.deadband_80_active){
551
+ promises.deadband = node.config_gateway.config_set_deadband_80(mac, parseInt(config.deadband_80));
552
+ }
553
+ if(config.payload_length_80_active){
554
+ promises.payload_length_80 = node.config_gateway.config_set_payload_length_80(mac, parseInt(config.payload_length_80));
555
+ }
556
+ if(config.set_rtc_101){
557
+ promises.set_rtc_101 = node.config_gateway.config_set_rtc_101(mac);
558
+ }
559
+ break;
560
+ case 82:
561
+ if(config.current_calibration_82_active){
562
+ promises.current_calibration_82 = node.config_gateway.config_set_current_calibration_82(mac, parseInt(config.current_calibration_82));
563
+ }
564
+ if(config.output_data_rate_101_active){
565
+ promises.output_data_rate_101 = node.config_gateway.config_set_output_data_rate_101(mac, parseInt(config.output_data_rate_101));
566
+ }
567
+ if(config.sampling_duration_101_active){
568
+ promises.sampling_duration_101 = node.config_gateway.config_set_sampling_duration_101(mac, parseInt(config.sampling_duration_101));
569
+ }
570
+ if(config.x_axis_101 || config.y_axis_101 || config.z_axis_101){
571
+ 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);
572
+ }
573
+ if(config.sampling_interval_101_active){
574
+ promises.sampling_interval_101 = node.config_gateway.config_set_sampling_interval_101(mac, parseInt(config.sampling_interval_101));
575
+ }
576
+ if(config.full_scale_range_101_active){
577
+ promises.full_scale_range_101 = node.config_gateway.config_set_full_scale_range_101(mac, parseInt(config.full_scale_range_101));
578
+ }
579
+ if(config.mode_80_active){
580
+ promises.mode = node.config_gateway.config_set_operation_mode_80(mac, parseInt(config.mode_80));
581
+ }
582
+ if(config.filter_80_active){
583
+ promises.filter = node.config_gateway.config_set_filters_80(mac, parseInt(config.filter_80));
584
+ }
585
+ if(config.low_pass_filter_80_active){
586
+ promises.low_pass_filter = node.config_gateway.config_set_low_pass_filter_80(mac, parseInt(config.low_pass_filter_80));
587
+ }
588
+ if(config.high_pass_filter_80_active){
589
+ promises.high_pass_filter = node.config_gateway.config_set_high_pass_filter_80(mac, parseInt(config.high_pass_filter_80));
590
+ }
591
+ if(config.measurement_mode_80_active){
592
+ promises.measurement_mode = node.config_gateway.config_set_measurement_mode_80(mac, parseInt(config.measurement_mode_80));
593
+ }
594
+ if(config.on_request_timeout_80_active){
595
+ promises.on_request_timeout = node.config_gateway.config_set_filters_80(mac, parseInt(config.on_request_timeout_80));
596
+ }
597
+ if(config.deadband_80_active){
598
+ promises.deadband = node.config_gateway.config_set_deadband_80(mac, parseInt(config.deadband_80));
599
+ }
600
+ if(config.payload_length_80_active){
601
+ promises.payload_length_80 = node.config_gateway.config_set_payload_length_80(mac, parseInt(config.payload_length_80));
602
+ }
603
+ if(config.set_rtc_101){
604
+ promises.set_rtc_101 = node.config_gateway.config_set_rtc_101(mac);
605
+ }
606
+ break;
607
+ case 84:
608
+ if(config.output_data_rate_101_active){
609
+ promises.output_data_rate_101 = node.config_gateway.config_set_output_data_rate_101(mac, parseInt(config.output_data_rate_101));
610
+ }
611
+ if(config.sampling_duration_101_active){
612
+ promises.sampling_duration_101 = node.config_gateway.config_set_sampling_duration_101(mac, parseInt(config.sampling_duration_101));
613
+ }
614
+ if(config.x_axis_101 || config.y_axis_101 || config.z_axis_101){
615
+ 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);
616
+ }
617
+ if(config.sampling_interval_101_active){
618
+ promises.sampling_interval_101 = node.config_gateway.config_set_sampling_interval_101(mac, parseInt(config.sampling_interval_101));
619
+ }
620
+ if(config.full_scale_range_101_active){
621
+ promises.full_scale_range_101 = node.config_gateway.config_set_full_scale_range_101(mac, parseInt(config.full_scale_range_101));
622
+ }
623
+ if(config.mode_80_active){
624
+ promises.mode = node.config_gateway.config_set_operation_mode_80(mac, parseInt(config.mode_80));
625
+ }
626
+ if(config.filter_80_active){
627
+ promises.filter = node.config_gateway.config_set_filters_80(mac, parseInt(config.filter_80));
628
+ }
629
+ if(config.low_pass_filter_80_active){
630
+ promises.low_pass_filter = node.config_gateway.config_set_low_pass_filter_80(mac, parseInt(config.low_pass_filter_80));
631
+ }
632
+ if(config.high_pass_filter_80_active){
633
+ promises.high_pass_filter = node.config_gateway.config_set_high_pass_filter_80(mac, parseInt(config.high_pass_filter_80));
634
+ }
635
+ if(config.measurement_mode_80_active){
636
+ promises.measurement_mode = node.config_gateway.config_set_measurement_mode_80(mac, parseInt(config.measurement_mode_80));
637
+ }
638
+ if(config.on_request_timeout_80_active){
639
+ promises.on_request_timeout = node.config_gateway.config_set_filters_80(mac, parseInt(config.on_request_timeout_80));
640
+ }
641
+ if(config.deadband_80_active){
642
+ promises.deadband = node.config_gateway.config_set_deadband_80(mac, parseInt(config.deadband_80));
643
+ }
644
+ if(config.led_alert_mode_84_active){
645
+ promises.led_alert_mode_84 = node.config_gateway.config_set_led_alert_mode_84(mac, parseInt(config.led_alert_mode_84));
646
+ }
647
+ if(config.led_accelerometer_threshold_84_active){
648
+ promises.led_accelerometer_threshold_84 = node.config_gateway.config_set_led_accelerometer_threshold_84(mac, parseInt(config.led_accelerometer_threshold_84));
649
+ }
650
+ if(config.led_velocity_threshold_84_active){
651
+ promises.led_velocity_threshold_84 = node.config_gateway.config_set_led_velocity_threshold_84(mac, parseInt(config.led_velocity_threshold_84));
652
+ }
653
+ if(config.acceleration_interrupt_threshold_84_active){
654
+ promises.acceleration_interrupt_threshold_84 = node.config_gateway.config_set_acceleration_interrupt_threshold_84(mac, parseInt(config.acceleration_interrupt_threshold_84));
655
+ }
656
+ if(config.payload_length_80_active){
657
+ promises.payload_length_80 = node.config_gateway.config_set_payload_length_80(mac, parseInt(config.payload_length_80));
658
+ }
659
+ if(config.set_rtc_101){
660
+ promises.set_rtc_101 = node.config_gateway.config_set_rtc_101(mac);
661
+ }
662
+ break;
663
+ case 101:
664
+ if(config.output_data_rate_101_m2_active){
665
+ promises.output_data_rate_101_m2 = node.config_gateway.config_set_output_data_rate_101(mac, parseInt(config.output_data_rate_101_m2));
666
+ }
667
+ if(config.sampling_duration_101_active){
668
+ promises.sampling_duration_101 = node.config_gateway.config_set_sampling_duration_101(mac, parseInt(config.sampling_duration_101));
669
+ }
670
+ if(config.x_axis_101 || config.y_axis_101 || config.z_axis_101){
671
+ 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);
672
+ }
673
+ if(config.sampling_interval_101_active){
674
+ promises.sampling_interval_101 = node.config_gateway.config_set_sampling_interval_101(mac, parseInt(config.sampling_interval_101));
675
+ }
676
+ if(config.full_scale_range_101_m2_active){
677
+ promises.full_scale_range_101_m2 = node.config_gateway.config_set_full_scale_range_101(mac, parseInt(config.full_scale_range_101_m2));
678
+ }
679
+ // promises.set_rtc_101 = node.config_gateway.config_set_rtc_101(mac);
680
+ break;
681
+ case 102:
682
+ if(config.output_data_rate_101_active){
683
+ promises.output_data_rate_101 = node.config_gateway.config_set_output_data_rate_101(mac, parseInt(config.output_data_rate_101));
684
+ }
685
+ if(config.sampling_duration_101_active){
686
+ promises.sampling_duration_101 = node.config_gateway.config_set_sampling_duration_101(mac, parseInt(config.sampling_duration_101));
687
+ }
688
+
689
+ // 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);
690
+ if(config.sampling_interval_101_active){
691
+ promises.sampling_interval_101 = node.config_gateway.config_set_sampling_interval_101(mac, parseInt(config.sampling_interval_101));
692
+ }
693
+ // if(config.full_scale_range_101_active){
694
+ // promises.full_scale_range_101 = node.config_gateway.config_set_full_scale_range_101(mac, parseInt(config.full_scale_range_101));
695
+ // }
696
+ // promises.set_rtc_101 = node.config_gateway.config_set_rtc_101(mac);
697
+ break;
698
+ case 505:
699
+ if(config.current_calibration_c1_80_active){
700
+ promises.current_calibration_c1_80_active = node.config_gateway.config_set_current_calibration_individual_80(mac, parseInt(config.current_calibration_c1_80), 1);
701
+ }
702
+ break;
703
+ case 506:
704
+ if(config.current_calibration_c1_80_active){
705
+ promises.current_calibration_c1_80_active = node.config_gateway.config_set_current_calibration_individual_80(mac, parseInt(config.current_calibration_c1_80), 1);
706
+ }
707
+ if(config.current_calibration_c2_80_active){
708
+ promises.current_calibration_c2_80 = node.config_gateway.config_set_current_calibration_individual_80(mac, parseInt(config.current_calibration_c2_80), 3);
709
+ }
710
+ if(config.current_calibration_c3_80_active){
711
+ promises.current_calibration_c3_80 = node.config_gateway.config_set_current_calibration_individual_80(mac, parseInt(config.current_calibration_c3_80), 5);
712
+ }
713
+ break;
714
+ case 519:
715
+ if(config.output_data_rate_101_active){
716
+ promises.output_data_rate_101 = node.config_gateway.config_set_output_data_rate_101(mac, parseInt(config.output_data_rate_101));
717
+ }
718
+ if(config.sampling_duration_101_active){
719
+ promises.sampling_duration_101 = node.config_gateway.config_set_sampling_duration_101(mac, parseInt(config.sampling_duration_101));
720
+ }
721
+ if(config.x_axis_101 || config.y_axis_101 || config.z_axis_101){
722
+ 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);
723
+ }
724
+ if(config.sampling_interval_101_active){
725
+ promises.sampling_interval_101 = node.config_gateway.config_set_sampling_interval_101(mac, parseInt(config.sampling_interval_101));
726
+ }
727
+ if(config.full_scale_range_101_active){
728
+ promises.full_scale_range_101 = node.config_gateway.config_set_full_scale_range_101(mac, parseInt(config.full_scale_range_101));
729
+ }
730
+ if(config.mode_80_active){
731
+ promises.mode = node.config_gateway.config_set_operation_mode_80(mac, parseInt(config.mode_80));
732
+ }
733
+ if(config.filter_80_active){
734
+ promises.filter = node.config_gateway.config_set_filters_80(mac, parseInt(config.filter_80));
735
+ }
736
+ if(config.low_pass_filter_80_active){
737
+ promises.low_pass_filter = node.config_gateway.config_set_low_pass_filter_80(mac, parseInt(config.low_pass_filter_80));
738
+ }
739
+ if(config.high_pass_filter_80_active){
740
+ promises.high_pass_filter = node.config_gateway.config_set_high_pass_filter_80(mac, parseInt(config.high_pass_filter_80));
741
+ }
742
+ if(config.measurement_mode_80_active){
743
+ promises.measurement_mode = node.config_gateway.config_set_measurement_mode_80(mac, parseInt(config.measurement_mode_80));
744
+ }
745
+ if(config.on_request_timeout_80_active){
746
+ promises.on_request_timeout = node.config_gateway.config_set_filters_80(mac, parseInt(config.on_request_timeout_80));
747
+ }
748
+ if(config.deadband_80_active){
749
+ promises.deadband = node.config_gateway.config_set_deadband_80(mac, parseInt(config.deadband_80));
750
+ }
751
+ if(config.led_alert_mode_84_active){
752
+ promises.led_alert_mode_84 = node.config_gateway.config_set_led_alert_mode_84(mac, parseInt(config.led_alert_mode_84));
753
+ }
754
+ if(config.led_accelerometer_threshold_84_active){
755
+ promises.led_accelerometer_threshold_84 = node.config_gateway.config_set_led_accelerometer_threshold_84(mac, parseInt(config.led_accelerometer_threshold_84));
756
+ }
757
+ if(config.led_velocity_threshold_84_active){
758
+ promises.led_velocity_threshold_84 = node.config_gateway.config_set_led_velocity_threshold_84(mac, parseInt(config.led_velocity_threshold_84));
759
+ }
760
+ if(config.acceleration_interrupt_threshold_84_active){
761
+ promises.acceleration_interrupt_threshold_84 = node.config_gateway.config_set_acceleration_interrupt_threshold_84(mac, parseInt(config.acceleration_interrupt_threshold_84));
762
+ }
763
+ if(config.payload_length_80_active){
764
+ promises.payload_length_80 = node.config_gateway.config_set_payload_length_80(mac, parseInt(config.payload_length_80));
765
+ }
766
+ if(config.set_rtc_101){
767
+ promises.set_rtc_101 = node.config_gateway.config_set_rtc_101(mac);
768
+ }
769
+ break;
770
+ }
771
+ }
772
+ // These sensors listed in original_otf_devices use a different OTF code.
773
+ let original_otf_devices = [53, 80, 81, 82, 83, 84, 101, 102 , 518, 519, 520];
774
+ // If we changed the network ID reboot the sensor to take effect.
775
+ // TODO if we add the encryption key command to node-red we need to reboot for it as well.
776
+ if(reboot){
777
+ promises.reboot_sensor = node.config_gateway.config_reboot_sensor(mac);
778
+ } else if(otf){
779
+ if(original_otf_devices.includes(sensor.type)){
780
+ promises.exit_otn_mode = node.config_gateway.config_exit_otn_mode(mac);
781
+ }else{
782
+ promises.config_exit_otn_mode_common = node.config_gateway.config_exit_otn_mode_common(mac);
783
+ }
784
+ }
785
+ promises.finish = new Promise((fulfill, reject) => {
786
+ node.config_gateway.queue.add(() => {
787
+ return new Promise((f, r) => {
788
+ clearTimeout(tout);
789
+ node.status(modes.READY);
790
+ fulfill();
791
+ f();
792
+ });
793
+ });
794
+ });
795
+ for(var i in promises){
796
+ (function(name){
797
+ promises[name].then((f) => {
798
+ if(name != 'finish') success[name] = true;
799
+ else{
800
+ // #OTF
801
+ node.send({topic: 'Config Results', payload: success, time: Date.now()});
802
+ top_fulfill(success);
803
+ }
804
+ }).catch((err) => {
805
+ success[name] = err;
806
+ });
807
+ })(i);
808
+ }
809
+ }, 1000);
810
+ });
811
+ }
812
+ node._sensor_config = _config;
813
+ if(config.addr){
814
+ config.addr = config.addr.toLowerCase();
815
+
816
+ RED.nodes.getNode(config.connection).sensor_pool.push(config.addr);
817
+ this.gtw_on('sensor_data-'+config.addr, (data) => {
818
+ node.status(modes.RUN);
819
+ data.modem_mac = this.gateway.modem_mac;
820
+ node.send({
821
+ topic: 'sensor_data',
822
+ data: data,
823
+ payload: data.sensor_data,
824
+ time: Date.now()
825
+ });
826
+ });
827
+ this.gtw_on('set_destination_address'+config.addr, (d) => {
828
+ if(config.auto_config){
829
+ node.warn('Setting destination address');
830
+ return new Promise((top_fulfill, top_reject) => {
831
+ var msg = {};
832
+ setTimeout(() => {
833
+ var tout = setTimeout(() => {
834
+ node.status(modes.PGM_ERR);
835
+ node.send({topic: 'FLY Set Destination Address', payload: msg, time: Date.now()});
836
+ }, 10000);
837
+
838
+ var promises = {};
839
+
840
+ promises.config_dest_address_fly = node.config_gateway.config_set_destination(d, parseInt(config.destination, 16));
841
+
842
+ promises.finish = new Promise((fulfill, reject) => {
843
+ node.config_gateway.queue.add(() => {
844
+ return new Promise((f, r) => {
845
+ clearTimeout(tout);
846
+ fulfill();
847
+ f();
848
+ });
849
+ });
850
+ });
851
+ for(var i in promises){
852
+ (function(name){
853
+ promises[name].then((f) => {
854
+ if(name != 'finish') msg[name] = true;
855
+ else{
856
+ node.send({topic: 'FLY Set Destination Address', payload: msg, time: Date.now()});
857
+ top_fulfill(msg);
858
+ }
859
+ }).catch((err) => {
860
+ msg[name] = err;
861
+ });
862
+ })(i);
863
+ }
864
+ });
865
+ });
866
+ }
867
+ });
868
+ this.pgm_on('sensor_mode-'+config.addr, (sensor) => {
869
+ if(sensor.mode in modes){
870
+ node.status(modes[sensor.mode]);
871
+ }
872
+ else{
873
+ console.log('Error: unrecognized sensor mode packet');
874
+ }
875
+ if(config.auto_config && sensor.mode == "PGM"){
876
+ _config(sensor);
877
+ }else if(config.auto_config && config.on_the_fly_enable && sensor.mode == "FLY"){
878
+ // _send_otn_request(sensor);
879
+ // Sensors having issues seeing OTN request sent too quickly
880
+ // Added timeout to fix issue
881
+ var tout = setTimeout(() => {
882
+ _send_otn_request(sensor);
883
+ }, 100);
884
+ }else if(sensor.mode == "FLY" && config.sensor_type == 101 || sensor.mode == "FLY" && config.sensor_type == 102){
885
+ // send broadcast rtc to 101 and 102 regardless of settings
886
+ if(this.gateway.hasOwnProperty('fly_101_in_progress') && this.gateway.fly_101_in_progress == false || !this.gateway.hasOwnProperty('fly_101_in_progress')){
887
+ var broadcast_tout = setTimeout(() => {
888
+ _send_otn_request(sensor);
889
+ }, 100);
890
+ }
891
+ }else if(config.auto_config && config.on_the_fly_enable && sensor.mode == "OTN"){
892
+ if(config.sensor_type == 101 || config.sensor_type == 102){
893
+ if(this.gateway.hasOwnProperty('fly_101_in_progress') && this.gateway.fly_101_in_progress == false || !this.gateway.hasOwnProperty('fly_101_in_progress')){
894
+ this.gateway.fly_101_in_progress = true;
895
+ node.warn('start timer 2 ' + Date.now());
896
+ var broadcast_tout = setTimeout(() => {
897
+ node.warn('broadcast timer expired ' + Date.now());
898
+ _broadcast_rtc(sensor);
899
+ }, 2000);
900
+ }else{
901
+ node.warn('Attempted to start a new rtc broadcast, but denied rightly at ' + Date.now());
902
+ }
903
+ if(config.auto_config && config.on_the_fly_enable){
904
+ var tout = setTimeout(() => {
905
+ node.warn('config timer expired' + Date.now());
906
+ _config(sensor, true);
907
+ }, 3500);
908
+ }
909
+ }else{
910
+ _config(sensor, true);
911
+ }
912
+ } else if(config.sensor_type == 101 && sensor.mode == "OTN" || config.sensor_type == 102 && sensor.mode == "OTN"){
913
+ if(this.gateway.hasOwnProperty('fly_101_in_progress') && this.gateway.fly_101_in_progress == false || !this.gateway.hasOwnProperty('fly_101_in_progress')){
914
+ this.gateway.fly_101_in_progress = true;
915
+ node.warn('start timer 2 ' + Date.now());
916
+ var broadcast_tout = setTimeout(() => {
917
+ node.warn('broadcast timer expired ' + Date.now());
918
+ _broadcast_rtc(sensor);
919
+ var otf_timeout = setTimeout(() => {
920
+ node.warn('Sending OTF request ' + Date.now());
921
+ this.config_gateway.config_exit_otn_mode(sensor.mac);
922
+ }, 1000);
923
+ }, 2000);
924
+ }else{
925
+ node.warn('Attempted to start a new rtc broadcast, but denied rightly at ' + Date.now());
926
+ var otf_timeout = setTimeout(() => {
927
+ node.warn('Sending OTF request ' + Date.now());
928
+ this.config_gateway.config_exit_otn_mode(sensor.mac);
929
+ }, 3000);
930
+ }
931
+ }
932
+ });
933
+ }else if(config.sensor_type){
934
+ this.gtw_on('sensor_data-'+config.sensor_type, (data) => {
935
+ node.status(modes.RUN);
936
+ data.modem_mac = this.gateway.modem_mac;
937
+ node.send({
938
+ topic: 'sensor_data',
939
+ data: data,
940
+ payload: data.sensor_data,
941
+ time: Date.now()
942
+ });
943
+ });
944
+ this.gtw_on('set_destination_address'+config.sensor_type, (d) => {
945
+ if(config.auto_config){
946
+ node.warn('Setting destination address');
947
+ return new Promise((top_fulfill, top_reject) => {
948
+ var msg = {};
949
+ setTimeout(() => {
950
+ var tout = setTimeout(() => {
951
+ node.status(modes.PGM_ERR);
952
+ node.send({topic: 'FLY Set Destination Address', payload: msg, time: Date.now()});
953
+ }, 10000);
954
+
955
+ var promises = {};
956
+
957
+ promises.config_dest_address_fly = node.config_gateway.config_set_destination(d, parseInt(config.destination, 16));
958
+
959
+ promises.finish = new Promise((fulfill, reject) => {
960
+ node.config_gateway.queue.add(() => {
961
+ return new Promise((f, r) => {
962
+ clearTimeout(tout);
963
+ fulfill();
964
+ f();
965
+ });
966
+ });
967
+ });
968
+ for(var i in promises){
969
+ (function(name){
970
+ promises[name].then((f) => {
971
+ if(name != 'finish') msg[name] = true;
972
+ else{
973
+ node.send({topic: 'FLY Set Destination Address', payload: msg, time: Date.now()});
974
+ top_fulfill(msg);
975
+ }
976
+ }).catch((err) => {
977
+ msg[name] = err;
978
+ });
979
+ })(i);
980
+ }
981
+ });
982
+ });
983
+ }
984
+ });
985
+ this.pgm_on('sensor_mode', (sensor) => {
986
+ if(sensor.type == config.sensor_type){
987
+ if(sensor.mode in modes){
988
+ node.status(modes[sensor.mode]);
989
+ }
990
+ else{
991
+ console.log('Error: unrecognized sensor mode packet');
992
+ }
993
+ if(config.auto_config && sensor.mode == 'PGM'){
994
+ _config(sensor);
995
+ }else if(config.auto_config && config.on_the_fly_enable && sensor.mode == "FLY"){
996
+ // _send_otn_request(sensor);
997
+ // Sensors having issues seeing OTN request sent too quickly
998
+ // Added timeout to fix issue
999
+ var tout = setTimeout(() => {
1000
+ _send_otn_request(sensor);
1001
+ }, 100);
1002
+ }else if(sensor.mode == "FLY" && config.sensor_type == 101 || sensor.mode == "FLY" && config.sensor_type == 102){
1003
+ // send broadcast rtc to 101 and 102 regardless of settings
1004
+ if(this.gateway.hasOwnProperty('fly_101_in_progress') && this.gateway.fly_101_in_progress == false || !this.gateway.hasOwnProperty('fly_101_in_progress')){
1005
+ var broadcast_tout = setTimeout(() => {
1006
+ _send_otn_request(sensor);
1007
+ }, 100);
1008
+ }
1009
+ }else if(config.auto_config && config.on_the_fly_enable && sensor.mode == "OTN"){
1010
+ if(config.sensor_type == 101 || config.sensor_type == 102){
1011
+ if(this.gateway.hasOwnProperty('fly_101_in_progress') && this.gateway.fly_101_in_progress == false || !this.gateway.hasOwnProperty('fly_101_in_progress')){
1012
+ this.gateway.fly_101_in_progress = true;
1013
+ node.warn('start timer 2 ' + Date.now());
1014
+ var broadcast_tout = setTimeout(() => {
1015
+ node.warn('broadcast timer expired ' + Date.now());
1016
+ _broadcast_rtc(sensor);
1017
+ }, 2000);
1018
+ }else{
1019
+ node.warn('Attempted to start a new rtc broadcast, but denied rightly at ' + Date.now());
1020
+ }
1021
+ if(config.auto_config && config.on_the_fly_enable){
1022
+ var tout = setTimeout(() => {
1023
+ node.warn('config timer expired' + Date.now());
1024
+ _config(sensor, true);
1025
+ }, 3500);
1026
+ }
1027
+ }else{
1028
+ _config(sensor, true);
1029
+ }
1030
+
1031
+ }else if(config.sensor_type == 101 && sensor.mode == "OTN" || config.sensor_type == 102 && sensor.mode == "OTN"){
1032
+ if(this.gateway.hasOwnProperty('fly_101_in_progress') && this.gateway.fly_101_in_progress == false || !this.gateway.hasOwnProperty('fly_101_in_progress')){
1033
+ this.gateway.fly_101_in_progress = true;
1034
+ node.warn('start timer 2 ' + Date.now());
1035
+ var broadcast_tout = setTimeout(() => {
1036
+ node.warn('broadcast timer expired ' + Date.now());
1037
+ _broadcast_rtc(sensor);
1038
+ var otf_timeout = setTimeout(() => {
1039
+ node.warn('Sending OTF request ' + Date.now());
1040
+ this.config_gateway.config_exit_otn_mode(sensor.mac);
1041
+ }, 1000);
1042
+ }, 2000);
1043
+ }else{
1044
+ node.warn('Attempted to start a new rtc broadcast, but denied rightly at ' + Date.now());
1045
+ var otf_timeout = setTimeout(() => {
1046
+ node.warn('Sending OTF request ' + Date.now());
1047
+ this.config_gateway.config_exit_otn_mode(sensor.mac);
1048
+ }, 3000);
1049
+ }
1050
+ }
1051
+ }
1052
+ });
1053
+ }
1054
+ this.on('input', (msg) => {
1055
+ if(msg.topic == 'config'){
1056
+ _config();
1057
+ }else{
1058
+ node.gateway.send_arbitrary(config.addr, msg).then((m) => {
1059
+ console.log("complete");
1060
+ }).catch((err) => {
1061
+ console.log("error", err);
1062
+ });
1063
+ }
1064
+ });
1065
+ this.on('close', () => {
1066
+ for(var e in events){
1067
+ node.gateway._emitter.removeAllListeners(e);
1068
+ }
1069
+ for(var p in pgm_events){
1070
+ node.config_gateway._emitter.removeAllListeners(p);
1071
+ }
1072
+ node.gateway_node.close_comms();
1073
+ if(typeof node.config_gateway_node != 'undefined'){
1074
+ node.config_gateway_node.close_comms();
1075
+ }
1076
+ });
1077
+ }
1078
+ RED.nodes.registerType("ncd-wireless-node", NcdWirelessNode);
1079
+
1080
+ RED.httpAdmin.post("/ncd/wireless/gateway/config/:id", RED.auth.needsPermission("serial.read"), function(req,res) {
1081
+ var node = RED.nodes.getNode(req.params.id);
1082
+ if (node != null) {
1083
+ try {
1084
+ var _pan = node._gateway_node.gateway.pan_id;
1085
+ var pan = node._gateway_node.is_config ? [_pan >> 8, _pan & 255] : [0x7b, 0xcd];
1086
+ var msgs = [
1087
+ 'In listening mode',
1088
+ 'In config mode',
1089
+ 'Failed to connect'
1090
+ ];
1091
+ node.gateway.digi.send.at_command("ID", pan).then().catch().then(() => {
1092
+ node._gateway_node.check_mode((m) => {
1093
+ node.set_status();
1094
+ res.send(msgs[m]);
1095
+ });
1096
+ });
1097
+ } catch(err) {
1098
+ console.log(err);
1099
+ res.sendStatus(500);
1100
+ node.error(RED._("gateway.update failed",{error:err.toString()}));
1101
+ }
1102
+ } else {
1103
+ res.sendStatus(404);
1104
+ }
1105
+ });
1106
+
1107
+ RED.httpAdmin.get("/ncd/wireless/sensors/configure/:id", RED.auth.needsPermission('serial.read'), function(req,res) {
1108
+ var node = RED.nodes.getNode(req.params.id);
1109
+ if (node != null) {
1110
+ node._sensor_config().then((s) => {
1111
+ res.json(s);
1112
+ });
1113
+ }
1114
+ });
1115
+
1116
+ RED.httpAdmin.get("/ncd/wireless/modems/list", RED.auth.needsPermission('serial.read'), function(req,res) {
1117
+ getSerialDevices(true, res);
1118
+ });
1119
+ RED.httpAdmin.get("/ncd/wireless/modem/info/:port/:baudRate", RED.auth.needsPermission('serial.read'), function(req,res) {
1120
+ var port = decodeURIComponent(req.params.port);
1121
+ if(typeof gateway_pool[port] == 'undefined'){
1122
+ var serial = new comms.NcdSerial(port, parseInt(req.params.baudRate));
1123
+ var modem = new wireless.Modem(serial);
1124
+ gateway_pool[port] = new wireless.Gateway(modem);
1125
+ serial.on('ready', ()=>{
1126
+ serial._emitter.removeAllListeners('ready');
1127
+ modem.send.at_command("ID").then((bytes) => {
1128
+ pan_id = (bytes.data[0] << 8) | bytes.data[1];
1129
+ serial.close();
1130
+ delete gateway_pool[port];
1131
+ res.json({pan_id: pan_id.toString(16)});
1132
+ }).catch((err) => {
1133
+ console.log(err);
1134
+ serial.close();
1135
+ delete gateway_pool[port];
1136
+ res.json(false);
1137
+ });
1138
+ });
1139
+ }else if(gateway_pool[port].pan_id){
1140
+ res.json({pan_id: gateway_pool[port].pan_id.toString(16)});
1141
+ }else{
1142
+ res.json({error: "no network ID"});
1143
+ }
1144
+ });
1145
+ RED.httpAdmin.get("/ncd/wireless/sensors/list/:id", RED.auth.needsPermission('serial.read'), function(req,res) {
1146
+ var node = RED.nodes.getNode(req.params.id);
1147
+ if (node != null) {
1148
+ try {
1149
+ var sensors = [];
1150
+
1151
+ for(var i in node.gateway.sensor_pool){
1152
+ if(node.sensor_pool.indexOf(node.gateway.sensor_pool[i].mac) > -1) continue;
1153
+ sensors.push(node.gateway.sensor_pool[i]);
1154
+ }
1155
+ res.json(sensors);
1156
+ } catch(err) {
1157
+ res.sendStatus(500);
1158
+ node.error(RED._("sensor_list.failed",{error:err.toString()}));
1159
+ }
1160
+ } else {
1161
+ res.json({});
1162
+ }
1163
+ });
1164
+ RED.httpAdmin.get("/ncd/wireless/needs_input/:id", RED.auth.needsPermission('tcp.read'), function(req,res) {
1165
+ var node = RED.nodes.getNode(req.params.id);
1166
+ if (node != null) {
1167
+ return {needs_input: node.raw_input};
1168
+ } else {
1169
+ res.json({needs_input: false});
1170
+ }
1171
+ });
1172
+ };
1173
+ function getSerialDevices(ftdi, res){
1174
+ var busses = [];
1175
+ sp.list().then((ports) => {
1176
+ ports.forEach((p) => {
1177
+ busses.push(p.path);
1178
+ });
1179
+ }).catch((err) => {
1180
+
1181
+ }).then(() => {
1182
+ res.json(busses);
1183
+ });
1184
+ }
1185
+ function chunkString1(str, len) {
1186
+ var _length = str.length,
1187
+ _size = Math.ceil(_length/len),
1188
+ _ret = [];
1189
+ for(var _i=0; _i<_length; _i+=len) {
1190
+ _ret.push(str.substring(_i, _i + len));
1191
+ }
1192
+ return _ret;
1193
+ }
1194
+ function int2Bytes(i, l){
1195
+ var bits = i.toString(2);
1196
+ if(bits.length % 8) bits = ('00000000' + bits).substr(bits.length % 8);
1197
+ var bytes = chunkString1(bits, 8).map((v) => parseInt(v, 2));
1198
+ if(bytes.length < l){
1199
+ while(bytes.length < l){
1200
+ bytes.unshift(0);
1201
+ }
1202
+ }
1203
+ return bytes;
1204
+ }
1205
+ function toHex(n){return ('00' + n.toString(16)).substr(-2);}
1206
+ function toMac(arr){
1207
+ return arr.reduce((h,c,i) => {return ((i==1?toHex(h):h)+':'+toHex(c)).toUpperCase();});
1208
+ }