nodejs-poolcontroller 7.2.0 → 7.5.1

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.
Files changed (64) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +1 -1
  2. package/Changelog +13 -0
  3. package/Dockerfile +1 -0
  4. package/README.md +5 -5
  5. package/app.ts +11 -0
  6. package/config/Config.ts +3 -0
  7. package/config/VersionCheck.ts +8 -4
  8. package/controller/Constants.ts +165 -9
  9. package/controller/Equipment.ts +186 -65
  10. package/controller/Errors.ts +22 -1
  11. package/controller/State.ts +273 -57
  12. package/controller/boards/EasyTouchBoard.ts +194 -95
  13. package/controller/boards/IntelliCenterBoard.ts +115 -42
  14. package/controller/boards/IntelliTouchBoard.ts +104 -30
  15. package/controller/boards/NixieBoard.ts +155 -53
  16. package/controller/boards/SystemBoard.ts +1529 -514
  17. package/controller/comms/Comms.ts +219 -42
  18. package/controller/comms/messages/Messages.ts +16 -4
  19. package/controller/comms/messages/config/ChlorinatorMessage.ts +13 -3
  20. package/controller/comms/messages/config/CircuitGroupMessage.ts +6 -0
  21. package/controller/comms/messages/config/CircuitMessage.ts +1 -1
  22. package/controller/comms/messages/config/CoverMessage.ts +1 -0
  23. package/controller/comms/messages/config/EquipmentMessage.ts +4 -0
  24. package/controller/comms/messages/config/ExternalMessage.ts +43 -25
  25. package/controller/comms/messages/config/FeatureMessage.ts +8 -1
  26. package/controller/comms/messages/config/GeneralMessage.ts +8 -0
  27. package/controller/comms/messages/config/HeaterMessage.ts +15 -9
  28. package/controller/comms/messages/config/IntellichemMessage.ts +4 -1
  29. package/controller/comms/messages/config/OptionsMessage.ts +13 -1
  30. package/controller/comms/messages/config/PumpMessage.ts +4 -20
  31. package/controller/comms/messages/config/RemoteMessage.ts +4 -0
  32. package/controller/comms/messages/config/ScheduleMessage.ts +11 -0
  33. package/controller/comms/messages/config/SecurityMessage.ts +1 -0
  34. package/controller/comms/messages/config/ValveMessage.ts +12 -2
  35. package/controller/comms/messages/status/ChlorinatorStateMessage.ts +14 -6
  36. package/controller/comms/messages/status/EquipmentStateMessage.ts +78 -24
  37. package/controller/comms/messages/status/HeaterStateMessage.ts +25 -5
  38. package/controller/comms/messages/status/IntelliChemStateMessage.ts +55 -26
  39. package/controller/nixie/Nixie.ts +18 -16
  40. package/controller/nixie/NixieEquipment.ts +6 -6
  41. package/controller/nixie/bodies/Body.ts +7 -4
  42. package/controller/nixie/bodies/Filter.ts +7 -4
  43. package/controller/nixie/chemistry/ChemController.ts +800 -283
  44. package/controller/nixie/chemistry/Chlorinator.ts +22 -14
  45. package/controller/nixie/circuits/Circuit.ts +42 -7
  46. package/controller/nixie/heaters/Heater.ts +303 -30
  47. package/controller/nixie/pumps/Pump.ts +57 -30
  48. package/controller/nixie/schedules/Schedule.ts +10 -7
  49. package/controller/nixie/valves/Valve.ts +7 -5
  50. package/defaultConfig.json +32 -1
  51. package/issue_template.md +1 -1
  52. package/logger/DataLogger.ts +37 -22
  53. package/package.json +20 -18
  54. package/web/Server.ts +529 -31
  55. package/web/bindings/influxDB.json +157 -5
  56. package/web/bindings/mqtt.json +112 -13
  57. package/web/bindings/mqttAlt.json +109 -11
  58. package/web/interfaces/baseInterface.ts +2 -1
  59. package/web/interfaces/httpInterface.ts +2 -0
  60. package/web/interfaces/influxInterface.ts +103 -54
  61. package/web/interfaces/mqttInterface.ts +16 -5
  62. package/web/services/config/Config.ts +179 -43
  63. package/web/services/state/State.ts +51 -5
  64. package/web/services/state/StateSocket.ts +19 -2
@@ -61,14 +61,15 @@ export class NixiePumpCollection extends NixieEquipmentCollection<NixiePump> {
61
61
  }
62
62
  public async initAsync(pumps: PumpCollection) {
63
63
  try {
64
- this.length = 0;
65
64
  for (let i = 0; i < pumps.length; i++) {
66
65
  let pump = pumps.getItemByIndex(i);
67
66
  if (pump.master === 1) {
68
- let type = sys.board.valueMaps.pumpTypes.getName(pump.type);
69
- let npump = this.pumpFactory(pump);
70
- logger.info(`Initializing Nixie Pump ${npump.id}-${pump.name}`);
71
- this.push(npump);
67
+ if (typeof this.find(elem => elem.id === pump.id) === 'undefined') {
68
+ let type = sys.board.valueMaps.pumpTypes.getName(pump.type);
69
+ let npump = this.pumpFactory(pump);
70
+ logger.info(`Initializing Nixie Pump ${npump.id}-${pump.name}`);
71
+ this.push(npump);
72
+ }
72
73
  }
73
74
  }
74
75
  }
@@ -208,6 +209,7 @@ export class NixiePump extends NixieEquipment {
208
209
  catch (err) { logger.error(`Nixie setPumpAsync: ${err.message}`); return Promise.reject(err); }
209
210
  }
210
211
  public async pollEquipmentAsync() {
212
+ let self = this;
211
213
  try {
212
214
  if (this.suspendPolling || this.closing) return;
213
215
  if (typeof this._pollTimer !== 'undefined' || this._pollTimer) clearTimeout(this._pollTimer);
@@ -218,7 +220,7 @@ export class NixiePump extends NixieEquipment {
218
220
  await this.setPumpStateAsync(pstate);
219
221
  }
220
222
  catch (err) { logger.error(`Nixie Error running pump sequence - ${err}`); }
221
- finally { if (!this.closing) this._pollTimer = setTimeout(async () => await this.pollEquipmentAsync(), this.pollingInterval || 2000); }
223
+ finally { if (!this.closing) this._pollTimer = setTimeout(async () => await self.pollEquipmentAsync(), this.pollingInterval || 2000); }
222
224
  }
223
225
  private async checkHardwareStatusAsync(connectionId: string, deviceBinding: string) {
224
226
  try {
@@ -333,15 +335,16 @@ export class NixiePumpRS485 extends NixiePump {
333
335
  let pt = sys.board.valueMaps.pumpTypes.get(this.pump.type);
334
336
  // Since these process are async the closing flag can be set
335
337
  // between calls. We need to check it in between each call.
336
- if (!this.closing) await this.setDriveStateAsync(pstate);
337
- if (!this.closing) {
338
- if (this._targetSpeed >= pt.minFlow && this._targetSpeed <= pt.maxFlow) await this.setPumpGPMAsync(pstate);
339
- else if (this._targetSpeed >= pt.minSpeed && this._targetSpeed <= pt.maxSpeed) await this.setPumpRPMAsync(pstate);
340
- }
338
+ try { if (!this.closing) await this.setDriveStateAsync(); } catch (err) {}
339
+ try { if (!this.closing) {
340
+ if (this._targetSpeed >= pt.minFlow && this._targetSpeed <= pt.maxFlow) await this.setPumpGPMAsync();
341
+ else if (this._targetSpeed >= pt.minSpeed && this._targetSpeed <= pt.maxSpeed) await this.setPumpRPMAsync();
342
+ } } catch (err) {}
341
343
 
342
- if(!this.closing) await utils.sleep(2000);
343
- if(!this.closing) await this.requestPumpStatus(pstate);
344
- if(!this.closing) await this.setPumpToRemoteControl(pstate);
344
+ try { if(!this.closing) await this.setPumpFeature(6); } catch (err) {};
345
+ try { if(!this.closing) await utils.sleep(1000); } catch (err) {};
346
+ try { if(!this.closing) await this.requestPumpStatus(); } catch (err) {};
347
+ try { if(!this.closing) await this.setPumpToRemoteControl(); } catch (err) {};
345
348
  return new InterfaceServerResponse(200, 'Success');
346
349
  }
347
350
  catch (err) {
@@ -351,7 +354,7 @@ export class NixiePumpRS485 extends NixiePump {
351
354
  finally { this.suspendPolling = false; }
352
355
 
353
356
  };
354
- protected async setDriveStateAsync(pstate: PumpState, running: boolean = true) {
357
+ protected async setDriveStateAsync(running: boolean = true) {
355
358
  return new Promise<void>((resolve, reject) => {
356
359
  let out = Outbound.create({
357
360
  protocol: Protocol.Pump,
@@ -371,7 +374,7 @@ export class NixiePumpRS485 extends NixiePump {
371
374
  conn.queueSendMessage(out);
372
375
  });
373
376
  };
374
- protected async requestPumpStatus(pstate: PumpState) {
377
+ protected async requestPumpStatus() {
375
378
  return new Promise<void>((resolve, reject) => {
376
379
  let out = Outbound.create({
377
380
  protocol: Protocol.Pump,
@@ -391,7 +394,7 @@ export class NixiePumpRS485 extends NixiePump {
391
394
  conn.queueSendMessage(out);
392
395
  })
393
396
  };
394
- protected setPumpToRemoteControl(spump: PumpState, running: boolean = true) {
397
+ protected setPumpToRemoteControl(running: boolean = true) {
395
398
  return new Promise<void>((resolve, reject) => {
396
399
  let out = Outbound.create({
397
400
  protocol: Protocol.Pump,
@@ -412,13 +415,15 @@ export class NixiePumpRS485 extends NixiePump {
412
415
  conn.queueSendMessage(out);
413
416
  });
414
417
  }
415
- protected setPumpManual(pstate: PumpState) {
418
+ protected setPumpFeature(feature?: number) {
419
+ // empty payload (possibly 0?, too) is no feature
420
+ // 6: Feature 1
416
421
  return new Promise<void>((resolve, reject) => {
417
422
  let out = Outbound.create({
418
423
  protocol: Protocol.Pump,
419
424
  dest: this.pump.address,
420
425
  action: 5,
421
- payload: [],
426
+ payload: typeof feature === 'undefined' ? [] : [ feature ],
422
427
  retries: 2,
423
428
  repsonse: true,
424
429
  onComplete: (err, msg: Outbound) => {
@@ -432,7 +437,7 @@ export class NixiePumpRS485 extends NixiePump {
432
437
  conn.queueSendMessage(out);
433
438
  });
434
439
  };
435
- protected async setPumpRPMAsync(pstate: PumpState) {
440
+ protected async setPumpRPMAsync() {
436
441
  return new Promise<void>((resolve, reject) => {
437
442
  let out = Outbound.create({
438
443
  protocol: Protocol.Pump,
@@ -453,14 +458,14 @@ export class NixiePumpRS485 extends NixiePump {
453
458
  conn.queueSendMessage(out);
454
459
  });
455
460
  };
456
- protected async setPumpGPMAsync(pstate: PumpState) {
461
+ protected async setPumpGPMAsync() {
457
462
  // packet for vf; vsf will override
458
463
  return new Promise<void>((resolve, reject) => {
459
464
  let out = Outbound.create({
460
465
  protocol: Protocol.Pump,
461
466
  dest: this.pump.address,
462
- action: 10,
463
- payload: [1, 4, 2, 228, this._targetSpeed, 0],
467
+ action: 1,
468
+ payload: [2, 228, 0, this._targetSpeed],
464
469
  retries: 1,
465
470
  response: true,
466
471
  onComplete: (err, msg) => {
@@ -482,10 +487,10 @@ export class NixiePumpRS485 extends NixiePump {
482
487
  this._pollTimer = null;
483
488
  let pstate = state.pumps.getItemById(this.pump.id);
484
489
  this._targetSpeed = 0;
485
- try { await this.setDriveStateAsync(pstate, false); } catch (err) { logger.error(`Error closing pump ${this.pump.name}: ${err.message}`) }
486
- try { await this.setPumpManual(pstate); } catch (err) { logger.error(`Error closing pump ${this.pump.name}: ${err.message}`) }
487
- try { await this.setDriveStateAsync(pstate, false); } catch (err) { logger.error(`Error closing pump ${this.pump.name}: ${err.message}`) }
488
- try { await this.setPumpToRemoteControl(pstate, false); } catch (err) { logger.error(`Error closing pump ${this.pump.name}: ${err.message}`) }
490
+ try { await this.setDriveStateAsync(false); } catch (err) { logger.error(`Error closing pump ${this.pump.name}: ${err.message}`) }
491
+ try { await this.setPumpFeature(); } catch (err) { logger.error(`Error closing pump ${this.pump.name}: ${err.message}`) }
492
+ try { await this.setDriveStateAsync(false); } catch (err) { logger.error(`Error closing pump ${this.pump.name}: ${err.message}`) }
493
+ try { await this.setPumpToRemoteControl(false); } catch (err) { logger.error(`Error closing pump ${this.pump.name}: ${err.message}`) }
489
494
  this.closing = true;
490
495
  // Make sure the polling timer is dead after we have closted this all off. That way we do not
491
496
  // have another process that revives it from the dead.
@@ -572,14 +577,36 @@ export class NixiePumpVSF extends NixiePumpRS485 {
572
577
  if (this._targetSpeed !== _newSpeed) logger.info(`NCP: Setting Pump ${this.pump.name} to ${_newSpeed} ${flows > 0 ? 'GPM' : 'RPM'}.`);
573
578
  this._targetSpeed = _newSpeed;
574
579
  }
575
- protected async setPumpGPMAsync(pstate: PumpState) {
576
- // vsf payload; different from vf payload
580
+ protected async setPumpRPMAsync() {
581
+ // vsf action is 10 for rpm
577
582
  return new Promise<void>((resolve, reject) => {
578
583
  let out = Outbound.create({
579
584
  protocol: Protocol.Pump,
580
585
  dest: this.pump.address,
581
586
  action: 10,
582
- payload: [1, 4, 2, 196, this._targetSpeed, 0],
587
+ payload: [2, 196, Math.floor(this._targetSpeed / 256), this._targetSpeed % 256],
588
+ retries: 1,
589
+ // timeout: 250,
590
+ response: true,
591
+ onComplete: (err, msg) => {
592
+ if (err) {
593
+ logger.error(`Error sending setPumpRPMAsync for ${this.pump.name}: ${err.message}`);
594
+ reject(err);
595
+ }
596
+ else resolve();
597
+ }
598
+ });
599
+ conn.queueSendMessage(out);
600
+ });
601
+ };
602
+ protected async setPumpGPMAsync() {
603
+ // vsf payload; different from vf payload
604
+ return new Promise<void>((resolve, reject) => {
605
+ let out = Outbound.create({
606
+ protocol: Protocol.Pump,
607
+ dest: this.pump.address,
608
+ action: 9,
609
+ payload: [2, 196, 0, this._targetSpeed],
583
610
  retries: 1,
584
611
  response: true,
585
612
  onComplete: (err, msg) => {
@@ -29,13 +29,14 @@ export class NixieScheduleCollection extends NixieEquipmentCollection<NixieSched
29
29
  }
30
30
  public async initAsync(schedules: ScheduleCollection) {
31
31
  try {
32
- this.length = 0;
33
32
  for (let i = 0; i < schedules.length; i++) {
34
33
  let schedule = schedules.getItemByIndex(i);
35
34
  if (schedule.master === 1) {
36
- logger.info(`Initializing Schedule ${schedule.id}`);
37
- let nSchedule = new NixieSchedule(this.controlPanel, schedule);
38
- this.push(nSchedule);
35
+ if (typeof this.find(elem => elem.id === schedule.id) === 'undefined') {
36
+ logger.info(`Initializing Schedule ${schedule.id}`);
37
+ let nSchedule = new NixieSchedule(this.controlPanel, schedule);
38
+ this.push(nSchedule);
39
+ }
39
40
  }
40
41
  }
41
42
  }
@@ -82,13 +83,14 @@ export class NixieSchedule extends NixieEquipment {
82
83
  catch (err) { logger.error(`Nixie setScheduleAsync: ${err.message}`); return Promise.reject(err); }
83
84
  }
84
85
  public async pollEquipmentAsync() {
86
+ let self = this;
85
87
  try {
86
88
  if (typeof this._pollTimer !== 'undefined' || this._pollTimer) clearTimeout(this._pollTimer);
87
89
  this._pollTimer = null;
88
90
  let success = false;
89
91
  }
90
92
  catch (err) { logger.error(`Nixie Error polling Schedule - ${err}`); }
91
- finally { this._pollTimer = setTimeout(async () => await this.pollEquipmentAsync(), this.pollingInterval || 10000); }
93
+ finally { this._pollTimer = setTimeout(async () => await self.pollEquipmentAsync(), this.pollingInterval || 10000); }
92
94
  }
93
95
  public async validateSetupAsync(Schedule: Schedule, temp: ScheduleState) {
94
96
  try {
@@ -139,8 +141,9 @@ export class NixieSchedule extends NixieEquipment {
139
141
  let body = sys.bodies.find(elem => elem.circuit === circuit.id);
140
142
  if (typeof body !== 'undefined') {
141
143
  let heatSource = sys.board.valueMaps.heatSources.transform(this.schedule.heatSource);
142
- if (heatSource !== 'nochange') {
144
+ if (heatSource.name !== 'nochange') {
143
145
  switch (heatSource.name) {
146
+ case 'nochange':
144
147
  case 'dontchange':
145
148
  break;
146
149
  case 'off':
@@ -231,7 +234,7 @@ export class NixieSchedule extends NixieEquipment {
231
234
  }
232
235
  public logData(filename: string, data: any) { this.controlPanel.logData(filename, data); }
233
236
  }
234
- class NixieScheduleContext {
237
+ class NixieScheduleContext {
235
238
  constructor() {
236
239
 
237
240
  }
@@ -50,13 +50,14 @@ export class NixieValveCollection extends NixieEquipmentCollection<NixieValve> {
50
50
  }
51
51
  public async initAsync(valves: ValveCollection) {
52
52
  try {
53
- this.length = 0;
54
53
  for (let i = 0; i < valves.length; i++) {
55
54
  let valve = valves.getItemByIndex(i);
56
55
  if (valve.master === 1) {
57
- let nvalve = new NixieValve(this.controlPanel, valve);
58
- logger.info(`Initializing Nixie Valve ${nvalve.id}-${valve.name}`);
59
- this.push(nvalve);
56
+ if (typeof this.find(elem => elem.id === valve.id) === 'undefined') {
57
+ let nvalve = new NixieValve(this.controlPanel, valve);
58
+ logger.info(`Initializing Nixie Valve ${nvalve.id}-${valve.name}`);
59
+ this.push(nvalve);
60
+ }
60
61
  }
61
62
  }
62
63
  }
@@ -125,13 +126,14 @@ export class NixieValve extends NixieEquipment {
125
126
  catch (err) { logger.error(`Nixie setValveAsync: ${err.message}`); return Promise.reject(err); }
126
127
  }
127
128
  public async pollEquipmentAsync() {
129
+ let self = this;
128
130
  try {
129
131
  if (typeof this._pollTimer !== 'undefined' || this._pollTimer) clearTimeout(this._pollTimer);
130
132
  this._pollTimer = null;
131
133
  let success = false;
132
134
  }
133
135
  catch (err) { logger.error(`Nixie Error polling valve - ${err}`); }
134
- finally { this._pollTimer = setTimeout(async () => await this.pollEquipmentAsync(), this.pollingInterval || 10000); }
136
+ finally { this._pollTimer = setTimeout(async () => await self.pollEquipmentAsync(), this.pollingInterval || 10000); }
135
137
  }
136
138
  private async checkHardwareStatusAsync(connectionId: string, deviceBinding: string) {
137
139
  try {
@@ -17,7 +17,18 @@
17
17
  "autoOpen": false,
18
18
  "lock": false
19
19
  }
20
+ },
21
+ "backups": {
22
+ "automatic": false,
23
+ "interval": {
24
+ "days": 30,
25
+ "hours": 0
26
+ },
27
+ "keepCount": 5,
28
+ "njsPC": true,
29
+ "servers": []
20
30
  }
31
+
21
32
  },
22
33
  "web": {
23
34
  "servers": {
@@ -52,6 +63,7 @@
52
63
  "interfaces": {
53
64
  "smartThings": {
54
65
  "name": "SmartThings",
66
+ "type": "rest",
55
67
  "enabled": false,
56
68
  "fileName": "smartThings-Hubitat.json",
57
69
  "globals": {},
@@ -62,6 +74,7 @@
62
74
  },
63
75
  "hubitat": {
64
76
  "name": "Hubitat",
77
+ "type": "rest",
65
78
  "enabled": false,
66
79
  "fileName": "smartThings-Hubitat.json",
67
80
  "globals": {},
@@ -72,6 +85,7 @@
72
85
  },
73
86
  "vera": {
74
87
  "name": "Vera",
88
+ "type": "rest",
75
89
  "enabled": false,
76
90
  "fileName": "vera.json",
77
91
  "vars": {
@@ -83,6 +97,7 @@
83
97
  }
84
98
  },
85
99
  "valveRelay": {
100
+ "type": "rest",
86
101
  "name": "Valve Relays",
87
102
  "enabled": false,
88
103
  "fileName": "valveRelays.json",
@@ -100,15 +115,31 @@
100
115
  "enabled": false,
101
116
  "fileName": "influxDB.json",
102
117
  "options": {
118
+ "version": 1,
103
119
  "protocol": "http",
104
120
  "host": "192.168.0.1",
105
- "port": 32770,
121
+ "port": 9999,
106
122
  "username": "",
107
123
  "password": "",
108
124
  "database": "pool",
109
125
  "retentionPolicy": "autogen"
110
126
  }
111
127
  },
128
+ "influxDBv2": {
129
+ "name": "InfluxDBv2",
130
+ "type": "influx",
131
+ "enabled": false,
132
+ "fileName": "influxDB.json",
133
+ "options": {
134
+ "version": 2,
135
+ "protocol": "http",
136
+ "host": "192.168.0.1",
137
+ "port": 9999,
138
+ "token": "...LuyM84JJx93Qvc7tfaXPbI_mFFjRBjaA==",
139
+ "org": "example-org",
140
+ "bucket": "57ec4eed2d90a50b"
141
+ }
142
+ },
112
143
  "mqtt": {
113
144
  "name": "MQTT",
114
145
  "type": "mqtt",
package/issue_template.md CHANGED
@@ -33,7 +33,7 @@ Follow the instructions to complete a [packet capture](https://github.com/tagyou
33
33
  - Pump(s) manufacturer and model: [e.g. IntelliFlow 2 VST 011056]
34
34
  - Chlorinator: [e.g. iChlor, IntelliChlor-40]
35
35
  - Heater(s): [e.g. gas, solar, heatpump, ultratemp]
36
- - Chemical controller: [e.g. IntelliChem, homegrown]
36
+ - Chemical controller: [e.g. IntelliChem, Relay Equipment Manager (REM)]
37
37
  - Valves: [e.g. Intellivalve]
38
38
  - Any other relevant equipment:
39
39
 
@@ -29,8 +29,10 @@ export class DataLogger {
29
29
  }
30
30
  let arr: T[] = [];
31
31
  for (let i = 0; i < lines.length; i++) {
32
- let entry = DataLogger.createEntry<T>(type, lines[i]);
33
- arr.push(entry);
32
+ try {
33
+ let entry = DataLogger.createEntry<T>(type, lines[i]);
34
+ arr.push(entry);
35
+ } catch (err) { logger.error(`Skipping invalid dose history entry: ${err.message}`); }
34
36
  }
35
37
  return arr;
36
38
  } catch (err) { logger.error(err); }
@@ -47,6 +49,7 @@ export class DataLogger {
47
49
  let newLines = ['\r', '\n'];
48
50
  let arr: T[] = [];
49
51
  if (fs.existsSync(logPath)) {
52
+ console.log(`Reading logfile ${logPath}`);
50
53
  // Alright what we have created here is a method to read the data from the end of
51
54
  // a log file in reverse order (tail) that works for all os implementations. It is
52
55
  // really dumb that this isn't part of the actual file processing.
@@ -81,15 +84,16 @@ export class DataLogger {
81
84
  // record then we shoud save off the line and read the next record.
82
85
  if (newLines.includes(char) || pos === 0) {
83
86
  if (chars.length > 0) {
84
- let entry = DataLogger.createEntry<T>(type, chars.join(''));
85
- if (typeof fn === 'function') {
86
- let rc = fn(arr.length + 1, entry, arr);
87
- console.log(rc);
88
- if (rc === true) arr.push(entry);
89
- else if (rc === false) break;
90
- }
91
- else
92
- arr.push(entry);
87
+ try {
88
+ let entry = DataLogger.createEntry<T>(type, chars.join(''));
89
+ if (typeof fn === 'function') {
90
+ let rc = fn(arr.length + 1, entry, arr);
91
+ if (rc === true) arr.push(entry);
92
+ else if (rc === false) break;
93
+ }
94
+ else
95
+ arr.push(entry);
96
+ } catch (err) { logger.error(`Skipping invalid dose history entry: ${err.message}`); }
93
97
  }
94
98
  chars = [];
95
99
  }
@@ -142,14 +146,16 @@ export class DataLogger {
142
146
  // record then we shoud save off the line and read the next record.
143
147
  if (newLines.includes(char) || pos === 0) {
144
148
  if (chars.length > 0) {
145
- let entry = DataLogger.createEntry<T>(type, chars.join(''));
146
- if (typeof fn === 'function') {
147
- let rc = fn(arr.length + 1, entry, arr);
148
- if (rc === true) arr.push(entry);
149
- else if (rc === false) break;
150
- }
151
- else
152
- arr.push(entry);
149
+ try {
150
+ let entry = DataLogger.createEntry<T>(type, chars.join(''));
151
+ if (typeof fn === 'function') {
152
+ let rc = fn(arr.length + 1, entry, arr);
153
+ if (rc === true) arr.push(entry);
154
+ else if (rc === false) break;
155
+ }
156
+ else
157
+ arr.push(entry);
158
+ } catch (err) { logger.error(`Skipping invalid dose history entry: ${err.message}`); }
153
159
  }
154
160
  chars = [];
155
161
  }
@@ -276,7 +282,6 @@ export class DataLogger {
276
282
  let entry = DataLogger.createEntry<T>(type, chars.join(''));
277
283
  if (typeof fn === 'function') {
278
284
  let rc = fn(arr.length + 1, entry, arr);
279
- console.log(rc);
280
285
  if (rc === true) arr.push(entry);
281
286
  else if (rc === false) break;
282
287
  }
@@ -399,11 +404,21 @@ export class DataLoggerEntry {
399
404
  // Parse the data from the log entry if it exists.
400
405
  if (typeof entry === 'object') entry = JSON.stringify(entry);
401
406
  if (typeof entry === 'string') this.parse(entry);
407
+ else {
408
+ //console.log(`A DATALOGGER ENTRY DOES NOT HAVE A PROPER TYPE ${typeof entry} *************************************`);
409
+ //console.log(entry);
410
+ }
402
411
  }
403
- public createInstance(entry?: string) { return new DataLoggerEntry(entry); }
412
+ public static createInstance(entry?: string) { return new DataLoggerEntry(entry); }
404
413
  public parse(entry: string) {
405
414
  let obj = typeof entry !== 'undefined' ? JSON.parse(entry, this.dateParser) : {};
406
- extend(true, this, obj);
415
+ if (typeof entry === 'undefined') {
416
+ console.log(`A DATALOGGER ENTRY WAS NOT DEFINED *************************`);
417
+ }
418
+ else if (entry === '') {
419
+ console.log(`THE INCOMING DATALOGGER ENTRY WAS EMPTY ***************************`)
420
+ }
421
+ let o = extend(true, this, obj);
407
422
  }
408
423
  protected dateParser(key, value) {
409
424
  if (typeof value === 'string') {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodejs-poolcontroller",
3
- "version": "7.2.0",
3
+ "version": "7.5.1",
4
4
  "description": "nodejs-poolController",
5
5
  "main": "app.js",
6
6
  "author": {
@@ -19,36 +19,38 @@
19
19
  "watch": "tsc -w"
20
20
  },
21
21
  "dependencies": {
22
- "@influxdata/influxdb-client": "^1.12.0",
22
+ "@influxdata/influxdb-client": "^1.17.0",
23
23
  "eslint-config-promise": "^2.0.2",
24
24
  "express": "^4.17.1",
25
25
  "extend": "^3.0.2",
26
- "jszip": "^3.6.0",
27
- "mqtt": "^4.2.6",
28
- "multicast-dns": "^7.2.0",
26
+ "jszip": "^3.7.1",
27
+ "mqtt": "^4.2.8",
28
+ "multer": "^1.4.3",
29
+ "multicast-dns": "^7.2.3",
29
30
  "node-ssdp": "^4.0.1",
30
- "serialport": "^9.0.7",
31
- "socket.io": "^4.0.1",
32
- "socket.io-client": "^4.0.1",
31
+ "serialport": "^9.2.1",
32
+ "socket.io": "^4.2.0",
33
+ "socket.io-client": "^4.2.0",
33
34
  "source-map-support": "^0.5.13",
34
35
  "winston": "^3.3.3"
35
36
  },
36
37
  "devDependencies": {
37
- "@types/express": "^4.17.11",
38
+ "@types/express": "^4.17.13",
38
39
  "@types/extend": "^3.0.1",
39
- "@types/node": "^12.20.7",
40
- "@typescript-eslint/eslint-plugin": "^4.21.0",
41
- "@typescript-eslint/parser": "^4.21.0",
42
- "eslint": "^7.24.0",
40
+ "@types/multer": "^1.4.7",
41
+ "@types/node": "^12.20.23",
42
+ "@typescript-eslint/eslint-plugin": "^4.30.0",
43
+ "@typescript-eslint/parser": "^4.30.0",
44
+ "eslint": "^7.32.0",
43
45
  "eslint-config-defaults": "^9.0.0",
44
- "eslint-config-standard": "^16.0.2",
45
- "eslint-plugin-import": "^2.22.1",
46
+ "eslint-config-standard": "^16.0.3",
47
+ "eslint-plugin-import": "^2.24.2",
46
48
  "eslint-plugin-node": "^11.1.0",
47
49
  "eslint-plugin-promise": "^5.1.0",
48
50
  "eslint-plugin-standard": "^5.0.0",
49
- "grunt": "^1.3.0",
51
+ "grunt": "^1.4.1",
50
52
  "grunt-banner": "^0.6.0",
51
- "ts-node": "^9.1.1",
52
- "typescript": "^4.2.4"
53
+ "ts-node": "^10.2.1",
54
+ "typescript": "^4.4.2"
53
55
  }
54
56
  }