nodejs-poolcontroller 7.7.0 → 8.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.
Files changed (82) hide show
  1. package/.eslintrc.json +26 -35
  2. package/Changelog +22 -0
  3. package/README.md +7 -3
  4. package/anslq25/MessagesMock.ts +218 -0
  5. package/anslq25/boards/MockBoardFactory.ts +50 -0
  6. package/anslq25/boards/MockEasyTouchBoard.ts +696 -0
  7. package/anslq25/boards/MockSystemBoard.ts +217 -0
  8. package/anslq25/chemistry/MockChlorinator.ts +75 -0
  9. package/anslq25/pumps/MockPump.ts +84 -0
  10. package/app.ts +10 -14
  11. package/config/Config.ts +13 -9
  12. package/config/VersionCheck.ts +6 -2
  13. package/controller/Constants.ts +58 -25
  14. package/controller/Equipment.ts +224 -41
  15. package/controller/Errors.ts +2 -1
  16. package/controller/Lockouts.ts +34 -2
  17. package/controller/State.ts +491 -48
  18. package/controller/boards/AquaLinkBoard.ts +6 -3
  19. package/controller/boards/BoardFactory.ts +5 -1
  20. package/controller/boards/EasyTouchBoard.ts +1971 -1751
  21. package/controller/boards/IntelliCenterBoard.ts +1311 -1688
  22. package/controller/boards/IntelliComBoard.ts +7 -1
  23. package/controller/boards/IntelliTouchBoard.ts +153 -42
  24. package/controller/boards/NixieBoard.ts +209 -66
  25. package/controller/boards/SunTouchBoard.ts +393 -0
  26. package/controller/boards/SystemBoard.ts +1862 -1543
  27. package/controller/comms/Comms.ts +539 -138
  28. package/controller/comms/ScreenLogic.ts +1663 -0
  29. package/controller/comms/messages/Messages.ts +242 -60
  30. package/controller/comms/messages/config/ChlorinatorMessage.ts +4 -3
  31. package/controller/comms/messages/config/CircuitGroupMessage.ts +5 -2
  32. package/controller/comms/messages/config/CircuitMessage.ts +81 -13
  33. package/controller/comms/messages/config/ConfigMessage.ts +3 -1
  34. package/controller/comms/messages/config/CoverMessage.ts +2 -1
  35. package/controller/comms/messages/config/CustomNameMessage.ts +2 -1
  36. package/controller/comms/messages/config/EquipmentMessage.ts +5 -1
  37. package/controller/comms/messages/config/ExternalMessage.ts +33 -3
  38. package/controller/comms/messages/config/FeatureMessage.ts +2 -1
  39. package/controller/comms/messages/config/GeneralMessage.ts +2 -1
  40. package/controller/comms/messages/config/HeaterMessage.ts +3 -1
  41. package/controller/comms/messages/config/IntellichemMessage.ts +2 -1
  42. package/controller/comms/messages/config/OptionsMessage.ts +12 -6
  43. package/controller/comms/messages/config/PumpMessage.ts +9 -12
  44. package/controller/comms/messages/config/RemoteMessage.ts +80 -13
  45. package/controller/comms/messages/config/ScheduleMessage.ts +43 -3
  46. package/controller/comms/messages/config/SecurityMessage.ts +2 -1
  47. package/controller/comms/messages/config/ValveMessage.ts +43 -26
  48. package/controller/comms/messages/status/ChlorinatorStateMessage.ts +8 -7
  49. package/controller/comms/messages/status/EquipmentStateMessage.ts +93 -20
  50. package/controller/comms/messages/status/HeaterStateMessage.ts +24 -5
  51. package/controller/comms/messages/status/IntelliChemStateMessage.ts +7 -4
  52. package/controller/comms/messages/status/IntelliValveStateMessage.ts +2 -1
  53. package/controller/comms/messages/status/PumpStateMessage.ts +72 -4
  54. package/controller/comms/messages/status/VersionMessage.ts +2 -1
  55. package/controller/nixie/Nixie.ts +15 -4
  56. package/controller/nixie/NixieEquipment.ts +1 -0
  57. package/controller/nixie/chemistry/ChemController.ts +300 -129
  58. package/controller/nixie/chemistry/ChemDoser.ts +806 -0
  59. package/controller/nixie/chemistry/Chlorinator.ts +133 -129
  60. package/controller/nixie/circuits/Circuit.ts +171 -30
  61. package/controller/nixie/heaters/Heater.ts +337 -173
  62. package/controller/nixie/pumps/Pump.ts +264 -236
  63. package/controller/nixie/schedules/Schedule.ts +9 -3
  64. package/defaultConfig.json +45 -5
  65. package/logger/Logger.ts +38 -9
  66. package/package.json +13 -9
  67. package/web/Server.ts +235 -122
  68. package/web/bindings/aqualinkD.json +114 -59
  69. package/web/bindings/homeassistant.json +437 -0
  70. package/web/bindings/influxDB.json +15 -0
  71. package/web/bindings/mqtt.json +28 -9
  72. package/web/bindings/mqttAlt.json +15 -0
  73. package/web/interfaces/baseInterface.ts +58 -7
  74. package/web/interfaces/httpInterface.ts +5 -2
  75. package/web/interfaces/influxInterface.ts +9 -2
  76. package/web/interfaces/mqttInterface.ts +234 -74
  77. package/web/interfaces/ruleInterface.ts +87 -0
  78. package/web/services/config/Config.ts +140 -33
  79. package/web/services/config/ConfigSocket.ts +2 -1
  80. package/web/services/state/State.ts +144 -3
  81. package/web/services/state/StateSocket.ts +65 -14
  82. package/web/services/utilities/Utilities.ts +189 -1
@@ -5,11 +5,12 @@ import { logger } from '../../../logger/Logger';
5
5
  import { NixieEquipment, NixieChildEquipment, NixieEquipmentCollection, INixieControlPanel } from "../NixieEquipment";
6
6
  import { Pump, PumpCircuit, PumpCollection, PumpRelay, sys } from "../../../controller/Equipment";
7
7
  import { CircuitState, PumpState, state, } from "../../State";
8
- import { setTimeout, clearTimeout } from 'timers';
8
+ import { setTimeout as setTimeoutSync, clearTimeout } from 'timers';
9
9
  import { NixieControlPanel } from '../Nixie';
10
10
  import { webApp, InterfaceServerResponse } from "../../../web/Server";
11
11
  import { Outbound, Protocol, Response } from '../../comms/messages/Messages';
12
12
  import { conn } from '../../comms/Comms';
13
+ import { setTimeout } from 'timers/promises';
13
14
 
14
15
  export class NixiePumpCollection extends NixieEquipmentCollection<NixiePump> {
15
16
  public async deletePumpAsync(id: number) {
@@ -69,6 +70,7 @@ export class NixiePumpCollection extends NixieEquipmentCollection<NixiePump> {
69
70
  let npump = this.pumpFactory(pump);
70
71
  logger.info(`Initializing Nixie Pump ${npump.id}-${pump.name}`);
71
72
  this.push(npump);
73
+ await npump.initAsync();
72
74
  }
73
75
  }
74
76
  }
@@ -85,7 +87,16 @@ export class NixiePumpCollection extends NixieEquipmentCollection<NixiePump> {
85
87
  }
86
88
  } catch (err) { } // Don't bail if we have an errror.
87
89
  }
88
-
90
+ public async setServiceModeAsync() {
91
+ try {
92
+ for (let i = this.length - 1; i >= 0; i--) {
93
+ try {
94
+ let p = this[i] as NixiePump;
95
+ await p.setServiceModeAsync();
96
+ } catch (err) { logger.error(`Error setting service mode for Nixie Pump ${err}`); }
97
+ }
98
+ } catch (err) { } // Don't bail if we have an errror.
99
+ }
89
100
  public async initPumpAsync(pump: Pump): Promise<NixiePump> {
90
101
  try {
91
102
  let c: NixiePump = this.find(elem => elem.id === pump.id) as NixiePump;
@@ -129,7 +140,7 @@ export class NixiePumpCollection extends NixieEquipmentCollection<NixiePump> {
129
140
  // loop through all pumps and update rates based on circuit changes
130
141
  // this would happen in <2s anyway based on pollAsync but this is immediate.
131
142
  for (let i = this.length - 1; i >= 0; i--) {
132
- setTimeout(async () => {
143
+ setTimeoutSync(async () => {
133
144
  let pump = this[i] as NixiePump;
134
145
  try {
135
146
  if (!pump.closing) await pump.pollEquipmentAsync();
@@ -148,7 +159,10 @@ export class NixiePump extends NixieEquipment {
148
159
  public get suspendPolling(): boolean { return this._suspendPolling > 0; }
149
160
  public set suspendPolling(val: boolean) { this._suspendPolling = Math.max(0, this._suspendPolling + (val ? 1 : -1)); }
150
161
  public closing = false;
151
-
162
+ public async setServiceModeAsync() {
163
+ let pstate = state.pumps.getItemById(this.pump.id);
164
+ await this.setPumpStateAsync(pstate);
165
+ }
152
166
  /*
153
167
  _targetSpeed will hold values as follows:
154
168
  vs/vsf/vf: rpm/gpm;
@@ -159,6 +173,14 @@ export class NixiePump extends NixieEquipment {
159
173
  super(ncp);
160
174
  this.pump = pump;
161
175
  this._targetSpeed = 0;
176
+ }
177
+ public async initAsync() {
178
+ if (this._pollTimer) {
179
+ clearTimeout(this._pollTimer);
180
+ this._pollTimer = undefined;
181
+ }
182
+ this.closing = false;
183
+ this._suspendPolling = 0;
162
184
  this.pollEquipmentAsync();
163
185
  }
164
186
  public get id(): number { return typeof this.pump !== 'undefined' ? this.pump.id : -1; }
@@ -184,6 +206,7 @@ export class NixiePump extends NixieEquipment {
184
206
  if (typeof type.maxCircuits !== 'undefined' && type.maxCircuits > 0 && typeof data.circuits !== 'undefined') { // This pump type supports circuits
185
207
  for (let i = 1; i <= data.circuits.length && i <= type.maxCircuits; i++) {
186
208
  let c = data.circuits[i - 1];
209
+ c.id = i;
187
210
  let circuit = parseInt(c.circuit, 10);
188
211
  let cd = this.pump.circuits.find(elem => elem.circuit === circuit);
189
212
  let speed = parseInt(c.speed, 10);
@@ -229,6 +252,8 @@ export class NixiePump extends NixieEquipment {
229
252
  spump.type = this.pump.type;
230
253
  sys.pumps.sortById();
231
254
  state.pumps.sortById();
255
+ this.pump.hasChanged = true;
256
+ this.pollEquipmentAsync();
232
257
  return Promise.resolve(new InterfaceServerResponse(200, 'Ok'));
233
258
  }
234
259
  catch (err) { logger.error(`Nixie setPumpAsync: ${err.message}`); return Promise.reject(err); }
@@ -236,7 +261,10 @@ export class NixiePump extends NixieEquipment {
236
261
  public async pollEquipmentAsync() {
237
262
  let self = this;
238
263
  try {
239
- if (this.suspendPolling || this.closing) return;
264
+ // RSG 8-2022. Refactored to add initasync. With this.pollEquipmentAsync inside the
265
+ // constructor we could get here before the pump is initialized. The added check
266
+ // for the 112 address prevented that previously, but now is just a final fail safe.
267
+ if (this.suspendPolling || this.closing || this.pump.address > 112) return;
240
268
  if (typeof this._pollTimer !== 'undefined' || this._pollTimer) clearTimeout(this._pollTimer);
241
269
  this._pollTimer = null;
242
270
  // let success = false;
@@ -245,7 +273,7 @@ export class NixiePump extends NixieEquipment {
245
273
  await this.setPumpStateAsync(pstate);
246
274
  }
247
275
  catch (err) { logger.error(`Nixie Error running pump sequence - ${err}`); }
248
- finally { if (!this.closing) this._pollTimer = setTimeout(async () => await self.pollEquipmentAsync(), this.pollingInterval || 2000); }
276
+ finally { if (!this.closing) this._pollTimer = setTimeoutSync(async () => await self.pollEquipmentAsync(), this.pollingInterval || 2000); }
249
277
  }
250
278
  private async checkHardwareStatusAsync(connectionId: string, deviceBinding: string) {
251
279
  try {
@@ -306,13 +334,29 @@ export class NixiePumpSS extends NixiePump {
306
334
  let _newSpeed = 0;
307
335
  if (!pState.pumpOnDelay) {
308
336
  let pt = sys.board.valueMaps.pumpTypes.get(this.pump.type);
309
- if (pt.hasBody) _newSpeed = this.isBodyOn(this.pump.body) ? 1 : 0;
310
- //console.log(`BODY: ${sys.board.bodies.isBodyOn(this.pump.body)} CODE: ${this.pump.body}`);
337
+ if (pt.maxCircuits === 0 || pt.hasBody) {
338
+ _newSpeed = this.isBodyOn(this.pump.body) ? 1 : 0;
339
+ //console.log(`BODY: ${sys.board.bodies.isBodyOn(this.pump.body)} CODE: ${this.pump.body}`);
340
+ }
341
+ else if (!pState.pumpOnDelay) {
342
+ let pumpCircuits: PumpCircuit[] = this.pump.circuits.get();
343
+ if (!pState.pumpOnDelay) {
344
+ for (let i = 0; i < pumpCircuits.length; i++) {
345
+ let circ = state.circuits.getInterfaceById(pumpCircuits[i].circuit);
346
+ if (circ.isOn) _newSpeed = 1;
347
+ }
348
+ }
349
+ }
311
350
  }
312
351
  if (this._targetSpeed !== _newSpeed) logger.info(`NCP: Setting Pump ${this.pump.name} to ${_newSpeed > 0 ? 'on' : 'off'}. ${sys.board.bodies.isBodyOn(this.pump.body)}`);
313
352
  if (isNaN(_newSpeed)) _newSpeed = 0;
314
353
  this._targetSpeed = _newSpeed;
315
354
  }
355
+ public async setServiceModeAsync() {
356
+ let pstate = state.pumps.getItemById(this.pump.id);
357
+ pstate.targetSpeed = this._targetSpeed = 0;
358
+ await this.setPumpStateAsync(pstate);
359
+ }
316
360
  public async setPumpStateAsync(pstate: PumpState) {
317
361
  let relays: PumpRelay[] = this.pump.relays.get();
318
362
  let relayState = 0;
@@ -478,24 +522,30 @@ export class NixiePumpHWRLY extends NixiePumpDS {
478
522
 
479
523
  }
480
524
  export class NixiePumpRS485 extends NixiePump {
525
+ public async setServiceModeAsync() {
526
+ this._targetSpeed = 0;
527
+ await this.setDriveStateAsync(false);
528
+ await this.setPumpToRemoteControlAsync(false);
529
+ }
481
530
  public async setPumpStateAsync(pstate: PumpState) {
482
531
  // Don't poll while we are seting the state.
483
532
  this.suspendPolling = true;
484
533
  try {
485
534
  let pt = sys.board.valueMaps.pumpTypes.get(this.pump.type);
486
- // Since these process are async the closing flag can be set
487
- // between calls. We need to check it in between each call.
488
- try { if (!this.closing) await this.setDriveStateAsync(); } catch (err) {}
489
- try {
535
+ if (state.mode === 0) {
536
+ // Since these process are async the closing flag can be set
537
+ // between calls. We need to check it in between each call.
538
+ if (!this.closing) await this.setDriveStateAsync();
490
539
  if (!this.closing) {
491
540
  if (this._targetSpeed >= pt.minFlow && this._targetSpeed <= pt.maxFlow) await this.setPumpGPMAsync();
492
541
  else if (this._targetSpeed >= pt.minSpeed && this._targetSpeed <= pt.maxSpeed) await this.setPumpRPMAsync();
493
542
  }
494
- } catch (err) { };
495
- try { if (!this.closing && pt.name !== 'vsf') await this.setPumpFeature(6); } catch (err) { };
496
- try { if(!this.closing) await utils.sleep(1000); } catch (err) { };
497
- try { if (!this.closing) await this.requestPumpStatus(); } catch (err) { };
498
- try { if (!this.closing) await this.setPumpToRemoteControl(); } catch (err) { };
543
+ ;
544
+ if (!this.closing && pt.name !== 'vsf' && pt.name !== 'vs') await this.setPumpFeatureAsync(6);;
545
+ if (!this.closing) await setTimeout(1000);;
546
+ if (!this.closing) await this.requestPumpStatusAsync();;
547
+ if (!this.closing) await this.setPumpToRemoteControlAsync();;
548
+ }
499
549
  return new InterfaceServerResponse(200, 'Success');
500
550
  }
501
551
  catch (err) {
@@ -505,157 +555,125 @@ export class NixiePumpRS485 extends NixiePump {
505
555
  finally { this.suspendPolling = false; }
506
556
  };
507
557
  protected async setDriveStateAsync(running: boolean = true) {
508
- return new Promise<void>((resolve, reject) => {
509
- if (conn.isPortEnabled(this.pump.portId || 0)) {
510
- let out = Outbound.create({
511
- portId: this.pump.portId || 0,
512
- protocol: Protocol.Pump,
513
- dest: this.pump.address,
514
- action: 6,
515
- payload: running && this._targetSpeed > 0 ? [10] : [4],
516
- retries: 1,
517
- response: true,
518
- onComplete: (err, msg: Outbound) => {
519
- if (err) {
520
- logger.error(`Error sending setDriveState for ${this.pump.name} : ${err.message}`);
521
- reject(err);
522
- }
523
- else resolve();
524
- }
525
- });
526
- conn.queueSendMessage(out);
558
+ if (conn.isPortEnabled(this.pump.portId || 0)) {
559
+ let out = Outbound.create({
560
+ portId: this.pump.portId || 0,
561
+ protocol: Protocol.Pump,
562
+ dest: this.pump.address,
563
+ action: 6,
564
+ payload: running && this._targetSpeed > 0 ? [10] : [4],
565
+ retries: 1,
566
+ response: true
567
+ });
568
+ try {
569
+ await out.sendAsync();
527
570
  }
528
- else {
529
- let pstate = state.pumps.getItemById(this.pump.id);
530
- pstate.command = pstate.rpm > 0 || pstate.flow > 0 ? 10 : 0;
531
- resolve();
571
+ catch (err) {
572
+ logger.error(`Error sending setDriveState for ${this.pump.name}: ${err.message}`);
532
573
  }
533
- });
574
+ }
575
+ else {
576
+ let pstate = state.pumps.getItemById(this.pump.id);
577
+ pstate.command = pstate.rpm > 0 || pstate.flow > 0 ? 10 : 0;
578
+ }
534
579
  };
535
- protected async requestPumpStatus() {
580
+ protected async requestPumpStatusAsync() {
536
581
  if (conn.isPortEnabled(this.pump.portId || 0)) {
537
- return new Promise<void>((resolve, reject) => {
538
- let out = Outbound.create({
539
- portId: this.pump.portId || 0,
540
- protocol: Protocol.Pump,
541
- dest: this.pump.address,
542
- action: 7,
543
- payload: [],
544
- retries: 2,
545
- response: true,
546
- onComplete: (err, msg) => {
547
- if (err) {
548
- logger.error(`Error sending requestPumpStatus for ${this.pump.name}: ${err.message}`);
549
- reject(err);
550
- }
551
- else resolve();
552
- }
553
- });
554
- conn.queueSendMessage(out);
582
+ let out = Outbound.create({
583
+ portId: this.pump.portId || 0,
584
+ protocol: Protocol.Pump,
585
+ dest: this.pump.address,
586
+ action: 7,
587
+ payload: [],
588
+ retries: 2,
589
+ response: true,
555
590
  });
591
+ try {
592
+ await out.sendAsync();
593
+ }
594
+ catch (err) {
595
+ logger.error(`Error sending requestPumpStatus for ${this.pump.name}: ${err.message}`);
596
+ }
556
597
  }
557
598
  };
558
- protected setPumpToRemoteControl(running: boolean = true) {
599
+ protected async setPumpToRemoteControlAsync(running: boolean = true) {
559
600
  if (conn.isPortEnabled(this.pump.portId || 0)) {
560
- return new Promise<void>((resolve, reject) => {
561
- let out = Outbound.create({
562
- portId: this.pump.portId || 0,
563
- protocol: Protocol.Pump,
564
- dest: this.pump.address,
565
- action: 4,
566
- payload: running ? [255] : [0], // when stopAsync is called, pass false to return control to pump panel
567
- // payload: spump.virtualControllerStatus === sys.board.valueMaps.virtualControllerStatus.getValue('running') ? [255] : [0],
568
- retries: 1,
569
- response: true,
570
- onComplete: (err) => {
571
- if (err) {
572
- logger.error(`Error sending setPumpToRemoteControl for ${this.pump.name}: ${err.message}`);
573
- reject(err);
574
- }
575
- else resolve();
576
- }
577
- });
578
- conn.queueSendMessage(out);
601
+ let out = Outbound.create({
602
+ portId: this.pump.portId || 0,
603
+ protocol: Protocol.Pump,
604
+ dest: this.pump.address,
605
+ action: 4,
606
+ payload: running ? [255] : [0], // when stopAsync is called, pass false to return control to pump panel
607
+ retries: 1,
608
+ response: true
579
609
  });
610
+ try {
611
+ await out.sendAsync();
612
+ }
613
+ catch (err) {
614
+ logger.error(`Error sending setPumpToRemoteControl for ${this.pump.name}: ${err.message}`);
615
+ }
580
616
  }
581
617
  }
582
- protected setPumpFeature(feature?: number) {
618
+ protected async setPumpFeatureAsync(feature?: number) {
619
+ // empty payload (possibly 0?, too) is no feature
620
+ // 6: Feature 1
583
621
  if (conn.isPortEnabled(this.pump.portId || 0)) {
584
- // empty payload (possibly 0?, too) is no feature
585
- // 6: Feature 1
586
- return new Promise<void>((resolve, reject) => {
587
- let out = Outbound.create({
588
- portId: this.pump.portId || 0,
589
- protocol: Protocol.Pump,
590
- dest: this.pump.address,
591
- action: 5,
592
- payload: typeof feature === 'undefined' ? [] : [feature],
593
- retries: 2,
594
- response: true,
595
- onComplete: (err, msg: Outbound) => {
596
- if (err) {
597
- logger.error(`Error sending setPumpManual for ${this.pump.name}: ${err.message}`);
598
- reject(err);
599
- }
600
- else resolve();
601
- }
602
- });
603
- conn.queueSendMessage(out);
622
+ let out = Outbound.create({
623
+ portId: this.pump.portId || 0,
624
+ protocol: Protocol.Pump,
625
+ dest: this.pump.address,
626
+ action: 5,
627
+ payload: typeof feature === 'undefined' ? [] : [feature],
628
+ retries: 2,
629
+ response: true
604
630
  });
605
- }
606
- else {
607
-
631
+ try {
632
+ await out.sendAsync();
633
+ }
634
+ catch (err) {
635
+ logger.error(`Error sending setPumpFeature for ${this.pump.name}: ${err.message}`);
636
+ }
608
637
  }
609
638
  };
610
639
  protected async setPumpRPMAsync() {
611
640
  if (conn.isPortEnabled(this.pump.portId || 0)) {
612
- return new Promise<void>((resolve, reject) => {
613
- let out = Outbound.create({
614
- portId: this.pump.portId || 0,
615
- protocol: Protocol.Pump,
616
- dest: this.pump.address,
617
- action: 1,
618
- payload: [2, 196, Math.floor(this._targetSpeed / 256), this._targetSpeed % 256],
619
- retries: 1,
620
- // timeout: 250,
621
- response: true,
622
- onComplete: (err, msg) => {
623
- if (err) {
624
- logger.error(`Error sending setPumpRPMAsync for ${this.pump.name}: ${err.message}`);
625
- reject(err);
626
- }
627
- else resolve();
628
- }
629
- });
630
- conn.queueSendMessage(out);
641
+ let out = Outbound.create({
642
+ portId: this.pump.portId || 0,
643
+ protocol: Protocol.Pump,
644
+ dest: this.pump.address,
645
+ action: 1,
646
+ payload: [2, 196, Math.floor(this._targetSpeed / 256), this._targetSpeed % 256],
647
+ retries: 1,
648
+ // timeout: 250,
649
+ response: true
631
650
  });
632
- }
633
- else {
634
-
651
+ try {
652
+ await out.sendAsync();
653
+ }
654
+ catch (err) {
655
+ logger.error(`Error sending setPumpRPMAsync for ${this.pump.name}: ${err.message}`);
656
+ }
635
657
  }
636
658
  };
637
659
  protected async setPumpGPMAsync() {
660
+ // packet for vf; vsf will override
638
661
  if (conn.isPortEnabled(this.pump.portId || 0)) {
639
- // packet for vf; vsf will override
640
- return new Promise<void>((resolve, reject) => {
641
- let out = Outbound.create({
642
- portId: this.pump.portId || 0,
643
- protocol: Protocol.Pump,
644
- dest: this.pump.address,
645
- action: 1,
646
- payload: [2, 228, 0, this._targetSpeed],
647
- retries: 1,
648
- response: true,
649
- onComplete: (err, msg) => {
650
- if (err) {
651
- logger.error(`Error sending setPumpGPMAsync for ${this.pump.name}: ${err.message}`);
652
- reject(err);
653
- }
654
- else resolve();
655
- }
656
- });
657
- conn.queueSendMessage(out);
662
+ let out = Outbound.create({
663
+ portId: this.pump.portId || 0,
664
+ protocol: Protocol.Pump,
665
+ dest: this.pump.address,
666
+ action: 1,
667
+ payload: [2, 228, 0, this._targetSpeed],
668
+ retries: 1,
669
+ response: true
658
670
  });
671
+ try {
672
+ await out.sendAsync();
673
+ }
674
+ catch (err) {
675
+ logger.error(`Error sending setPumpGPMAsync for ${this.pump.name}: ${err.message}`);
676
+ }
659
677
  }
660
678
  };
661
679
  public async closeAsync() {
@@ -664,13 +682,15 @@ export class NixiePumpRS485 extends NixiePump {
664
682
  logger.info(`Nixie Pump closing ${this.pump.name}.`)
665
683
  if (typeof this._pollTimer !== 'undefined' || this._pollTimer) clearTimeout(this._pollTimer);
666
684
  this._pollTimer = null;
685
+ this.closing = true;
686
+ let pt = sys.board.valueMaps.pumpTypes.get(this.pump.type);
667
687
  let pstate = state.pumps.getItemById(this.pump.id);
668
688
  this._targetSpeed = 0;
669
- try { await this.setDriveStateAsync(false); } catch (err) { logger.error(`Error closing pump ${this.pump.name}: ${err.message}`) }
670
- try { await this.setPumpFeature(); } catch (err) { logger.error(`Error closing pump ${this.pump.name}: ${err.message}`) }
671
- try { await this.setDriveStateAsync(false); } catch (err) { logger.error(`Error closing pump ${this.pump.name}: ${err.message}`) }
672
- try { await this.setPumpToRemoteControl(false); } catch (err) { logger.error(`Error closing pump ${this.pump.name}: ${err.message}`) }
673
- this.closing = true;
689
+ await this.setDriveStateAsync(false);
690
+ if (!this.closing && pt.name !== 'vsf' && pt.name !== 'vs') await this.setPumpFeatureAsync();
691
+ //await this.setPumpFeature();
692
+ //await this.setDriveStateAsync(false);
693
+ await this.setPumpToRemoteControlAsync(false);
674
694
  // Make sure the polling timer is dead after we have closted this all off. That way we do not
675
695
  // have another process that revives it from the dead.
676
696
  if (typeof this._pollTimer !== 'undefined' || this._pollTimer) clearTimeout(this._pollTimer);
@@ -766,51 +786,42 @@ export class NixiePumpVSF extends NixiePumpRS485 {
766
786
  protected async setPumpRPMAsync() {
767
787
  // vsf action is 10 for rpm
768
788
  if (conn.isPortEnabled(this.pump.portId || 0)) {
769
- return new Promise<void>((resolve, reject) => {
770
- let out = Outbound.create({
771
- portId: this.pump.portId || 0,
772
- protocol: Protocol.Pump,
773
- dest: this.pump.address,
774
- action: 10,
775
- payload: [2, 196, Math.floor(this._targetSpeed / 256), this._targetSpeed % 256],
776
- retries: 1,
777
- // timeout: 250,
778
- response: true,
779
- onComplete: (err, msg) => {
780
- if (err) {
781
- logger.error(`Error sending setPumpRPMAsync for ${this.pump.name}: ${err.message}`);
782
- reject(err);
783
- }
784
- else resolve();
785
- }
786
- });
787
- conn.queueSendMessage(out);
789
+ let out = Outbound.create({
790
+ portId: this.pump.portId || 0,
791
+ protocol: Protocol.Pump,
792
+ dest: this.pump.address,
793
+ action: 10,
794
+ payload: [2, 196, Math.floor(this._targetSpeed / 256), this._targetSpeed % 256],
795
+ retries: 1,
796
+ // timeout: 250,
797
+ response: true
788
798
  });
799
+ try {
800
+ await out.sendAsync();
801
+ }
802
+ catch (err) {
803
+ logger.error(`Error sending setPumpRPMAsync for ${this.pump.name}: ${err.message}`);
804
+ }
789
805
  }
790
806
  };
791
807
  protected async setPumpGPMAsync() {
808
+ // vsf payload; different from vf payload
792
809
  if (conn.isPortEnabled(this.pump.portId || 0)) {
793
- // vsf payload; different from vf payload
794
- return new Promise<void>((resolve, reject) => {
795
- let out = Outbound.create({
796
- portId: this.pump.portId || 0,
797
- protocol: Protocol.Pump,
798
- dest: this.pump.address,
799
- action: 9,
800
- payload: [2, 196, 0, this._targetSpeed],
801
- retries: 1,
802
- response: true,
803
- onComplete: (err, msg) => {
804
- if (err) {
805
- logger.error(`Error sending setPumpGPMAsync for ${this.pump.name}: ${err.message}`);
806
- reject(err);
807
- }
808
- else resolve();
809
- return
810
- }
811
- });
812
- conn.queueSendMessage(out);
810
+ let out = Outbound.create({
811
+ portId: this.pump.portId || 0,
812
+ protocol: Protocol.Pump,
813
+ dest: this.pump.address,
814
+ action: 9,
815
+ payload: [2, 196, 0, this._targetSpeed],
816
+ retries: 1,
817
+ response: true
813
818
  });
819
+ try {
820
+ await out.sendAsync();
821
+ }
822
+ catch (err) {
823
+ logger.error(`Error sending setPumpGPMAsync for ${this.pump.name}: ${err.message}`);
824
+ }
814
825
  }
815
826
  };
816
827
  };
@@ -831,14 +842,18 @@ export class NixiePumpHWVS extends NixiePumpRS485 {
831
842
  if (this._targetSpeed !== 0) Math.min(Math.max(this.pump.minSpeed, this._targetSpeed), this.pump.maxSpeed);
832
843
  if (this._targetSpeed !== _newSpeed) logger.info(`NCP: Setting Pump ${this.pump.name} to ${_newSpeed} RPM.`);
833
844
  }
845
+ public async setServiceModeAsync() {
846
+ this._targetSpeed = 0;
847
+ await this.setPumpRPMAsync();
848
+ }
849
+ public async setDriveStateAsync(running: boolean = false) { }
834
850
  public async setPumpStateAsync(pstate: PumpState) {
835
851
  // Don't poll while we are seting the state.
836
852
  this.suspendPolling = true;
837
853
  try {
838
- let pt = sys.board.valueMaps.pumpTypes.get(this.pump.type);
839
854
  // Since these process are async the closing flag can be set
840
855
  // between calls. We need to check it in between each call.
841
- try { if (!this.closing) { await this.setPumpRPMAsync(); } } catch (err) { }
856
+ if (!this.closing) { await this.setPumpRPMAsync(); }
842
857
  return new InterfaceServerResponse(200, 'Success');
843
858
  }
844
859
  catch (err) {
@@ -847,60 +862,73 @@ export class NixiePumpHWVS extends NixiePumpRS485 {
847
862
  }
848
863
  finally { this.suspendPolling = false; }
849
864
  };
850
- protected async requestPumpStatus() { return Promise.resolve(); };
851
- protected setPumpFeature(feature?: number) { return Promise.resolve(); }
852
- protected setPumpToRemoteControl(running: boolean = true) {
865
+ protected async requestPumpStatusAsync() { return Promise.resolve(); };
866
+ protected setPumpFeatureAsync(feature?: number) { return Promise.resolve(); }
867
+ protected async setPumpToRemoteControlAsync(running: boolean = true) {
868
+ // We do nothing on this pump to set it to remote control. That is unless we are turning it off.
853
869
  if (conn.isPortEnabled(this.pump.portId || 0)) {
854
- // We do nothing on this pump to set it to remote control. That is unless we are turning it off.
855
- return new Promise<void>((resolve, reject) => {
856
- if (!running) {
857
- let out = Outbound.create({
858
- portId: this.pump.portId || 0,
859
- protocol: Protocol.Hayward,
860
- source: 12, // Use the broadcast address
861
- dest: this.pump.address,
862
- action: 1,
863
- payload: [0], // when stopAsync is called, pass false to return control to pump panel
864
- // payload: spump.virtualControllerStatus === sys.board.valueMaps.virtualControllerStatus.getValue('running') ? [255] : [0],
865
- retries: 1,
866
- response: Response.create({ protocol: Protocol.Hayward, action: 12, source: this.pump.address }),
867
- onComplete: (err) => {
868
- if (err) {
869
- logger.error(`Error sending setPumpToRemoteControl for ${this.pump.name}: ${err.message}`);
870
- reject(err);
871
- }
872
- else resolve();
873
- }
874
- });
875
- conn.queueSendMessage(out);
876
- }
877
- else resolve();
878
- });
879
- }
880
- }
881
- protected async setPumpRPMAsync() {
882
- if (conn.isPortEnabled(this.pump.portId || 0)) {
883
- return new Promise<void>((resolve, reject) => {
884
- let pt = sys.board.valueMaps.pumpTypes.get(this.pump.type);
870
+ if (!running) {
885
871
  let out = Outbound.create({
886
872
  portId: this.pump.portId || 0,
887
873
  protocol: Protocol.Hayward,
888
874
  source: 12, // Use the broadcast address
889
- dest: this.pump.address - 96,
875
+ dest: this.pump.address,
890
876
  action: 1,
891
- payload: [Math.min(Math.round((this._targetSpeed / pt.maxSpeed) * 100), 100)], // when stopAsync is called, pass false to return control to pump panel
877
+ payload: [0], // when stopAsync is called, pass false to return control to pump panel
878
+ // payload: spump.virtualControllerStatus === sys.board.valueMaps.virtualControllerStatus.getValue('running') ? [255] : [0],
892
879
  retries: 1,
893
- response: Response.create({ protocol: Protocol.Hayward, action: 12, source: this.pump.address }),
894
- onComplete: (err) => {
895
- if (err) {
896
- logger.error(`Error sending setPumpRPM for ${this.pump.name}: ${err.message}`);
897
- reject(err);
898
- }
899
- else resolve();
900
- }
880
+ response: Response.create({ protocol: Protocol.Hayward, action: 12, source: this.pump.address - 96 })
901
881
  });
902
- conn.queueSendMessage(out);
882
+ try {
883
+ await out.sendAsync();
884
+ }
885
+ catch (err) {
886
+ logger.error(`Error sending setPumpToRemoteControl for ${this.pump.name}: ${err.message}`);
887
+
888
+ }
889
+ }
890
+ }
891
+ }
892
+ protected async setPumpRPMAsync() {
893
+ // Address 1
894
+ //[][16, 2, 12, 1, 0][41][0, 72, 16, 3] out
895
+ //[][16, 2, 0, 12, 0][0, 41, 0, 135][0, 206, 16, 3] In
896
+ // Address 2
897
+ //[][16, 2, 12, 1, 1][100][0, 132, 16, 3] out
898
+ //[][16, 2, 0, 12, 1][0, 96, 21, 64][0, 212, 16, 3] in
899
+ // Note that action 12 is in a different position for the outbound than the inbound. The source and destination are kind
900
+ // of a misnomer in that it identifies the equipment address in byte(4) of the header and flips the command address around.
901
+ // So in essence for equipment item 0-16 (pump addresses) the outbound is really a broadcast on 12 (broadcast) from 1 and the inbound is
902
+ // broadcast from the equipment item to 0 (anybody).
903
+ if (conn.isPortEnabled(this.pump.portId || 0)) {
904
+ let pt = sys.board.valueMaps.pumpTypes.get(this.pump.type);
905
+ let out = Outbound.create({
906
+ portId: this.pump.portId || 0,
907
+ protocol: Protocol.Hayward,
908
+ source: 1, // Use the broadcast address
909
+ dest: this.pump.address - 96,
910
+ action: 12,
911
+ payload: [Math.min(Math.round((this._targetSpeed / pt.maxSpeed) * 100), 100)], // when stopAsync is called, pass false to return control to pump panel
912
+ retries: 1,
913
+ response: Response.create({ protocol: Protocol.Hayward, action: 12, source: this.pump.address - 96 })
903
914
  });
915
+ try {
916
+ await out.sendAsync();
917
+ }
918
+ catch (err) {
919
+ logger.error(`Error sending setPumpRPM for ${this.pump.name}: ${err.message}`);
920
+ let pstate = state.pumps.getItemById(this.pump.id);
921
+ pstate.command = 0;
922
+ pstate.rpm = 0;
923
+ pstate.watts = 0;
924
+ }
904
925
  }
926
+ else {
927
+ let pstate = state.pumps.getItemById(this.pump.id);
928
+ pstate.command = 0;
929
+ pstate.rpm = 0;
930
+ pstate.watts = 0;
931
+ }
932
+
905
933
  };
906
934
  }