nodejs-poolcontroller 7.7.0 → 8.0.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.
- package/.eslintrc.json +26 -35
- package/Changelog +22 -0
- package/README.md +7 -3
- package/anslq25/MessagesMock.ts +218 -0
- package/anslq25/boards/MockBoardFactory.ts +50 -0
- package/anslq25/boards/MockEasyTouchBoard.ts +696 -0
- package/anslq25/boards/MockSystemBoard.ts +217 -0
- package/anslq25/chemistry/MockChlorinator.ts +75 -0
- package/anslq25/pumps/MockPump.ts +84 -0
- package/app.ts +10 -14
- package/config/Config.ts +13 -9
- package/config/VersionCheck.ts +6 -2
- package/controller/Constants.ts +58 -25
- package/controller/Equipment.ts +225 -41
- package/controller/Errors.ts +2 -1
- package/controller/Lockouts.ts +34 -2
- package/controller/State.ts +491 -48
- package/controller/boards/AquaLinkBoard.ts +6 -3
- package/controller/boards/BoardFactory.ts +5 -1
- package/controller/boards/EasyTouchBoard.ts +1971 -1751
- package/controller/boards/IntelliCenterBoard.ts +1311 -1688
- package/controller/boards/IntelliComBoard.ts +7 -1
- package/controller/boards/IntelliTouchBoard.ts +153 -42
- package/controller/boards/NixieBoard.ts +209 -66
- package/controller/boards/SunTouchBoard.ts +393 -0
- package/controller/boards/SystemBoard.ts +1862 -1543
- package/controller/comms/Comms.ts +539 -138
- package/controller/comms/ScreenLogic.ts +1663 -0
- package/controller/comms/messages/Messages.ts +242 -60
- package/controller/comms/messages/config/ChlorinatorMessage.ts +4 -3
- package/controller/comms/messages/config/CircuitGroupMessage.ts +5 -2
- package/controller/comms/messages/config/CircuitMessage.ts +81 -13
- package/controller/comms/messages/config/ConfigMessage.ts +3 -1
- package/controller/comms/messages/config/CoverMessage.ts +2 -1
- package/controller/comms/messages/config/CustomNameMessage.ts +2 -1
- package/controller/comms/messages/config/EquipmentMessage.ts +5 -1
- package/controller/comms/messages/config/ExternalMessage.ts +33 -3
- package/controller/comms/messages/config/FeatureMessage.ts +2 -1
- package/controller/comms/messages/config/GeneralMessage.ts +2 -1
- package/controller/comms/messages/config/HeaterMessage.ts +3 -1
- package/controller/comms/messages/config/IntellichemMessage.ts +2 -1
- package/controller/comms/messages/config/OptionsMessage.ts +12 -6
- package/controller/comms/messages/config/PumpMessage.ts +9 -12
- package/controller/comms/messages/config/RemoteMessage.ts +80 -13
- package/controller/comms/messages/config/ScheduleMessage.ts +43 -3
- package/controller/comms/messages/config/SecurityMessage.ts +2 -1
- package/controller/comms/messages/config/ValveMessage.ts +43 -26
- package/controller/comms/messages/status/ChlorinatorStateMessage.ts +8 -7
- package/controller/comms/messages/status/EquipmentStateMessage.ts +93 -20
- package/controller/comms/messages/status/HeaterStateMessage.ts +24 -5
- package/controller/comms/messages/status/IntelliChemStateMessage.ts +7 -4
- package/controller/comms/messages/status/IntelliValveStateMessage.ts +2 -1
- package/controller/comms/messages/status/PumpStateMessage.ts +72 -4
- package/controller/comms/messages/status/VersionMessage.ts +2 -1
- package/controller/nixie/Nixie.ts +15 -4
- package/controller/nixie/NixieEquipment.ts +1 -0
- package/controller/nixie/chemistry/ChemController.ts +300 -129
- package/controller/nixie/chemistry/ChemDoser.ts +806 -0
- package/controller/nixie/chemistry/Chlorinator.ts +133 -129
- package/controller/nixie/circuits/Circuit.ts +171 -30
- package/controller/nixie/heaters/Heater.ts +337 -173
- package/controller/nixie/pumps/Pump.ts +264 -236
- package/controller/nixie/schedules/Schedule.ts +9 -3
- package/defaultConfig.json +46 -5
- package/logger/Logger.ts +38 -9
- package/package.json +13 -9
- package/web/Server.ts +235 -122
- package/web/bindings/aqualinkD.json +114 -59
- package/web/bindings/homeassistant.json +437 -0
- package/web/bindings/influxDB.json +15 -0
- package/web/bindings/mqtt.json +28 -9
- package/web/bindings/mqttAlt.json +15 -0
- package/web/interfaces/baseInterface.ts +58 -7
- package/web/interfaces/httpInterface.ts +5 -2
- package/web/interfaces/influxInterface.ts +9 -2
- package/web/interfaces/mqttInterface.ts +234 -74
- package/web/interfaces/ruleInterface.ts +87 -0
- package/web/services/config/Config.ts +140 -33
- package/web/services/config/ConfigSocket.ts +2 -1
- package/web/services/state/State.ts +144 -3
- package/web/services/state/StateSocket.ts +65 -14
- 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
|
-
|
|
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
|
-
|
|
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 =
|
|
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.
|
|
310
|
-
|
|
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
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
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
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
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
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
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
|
-
|
|
529
|
-
|
|
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
|
|
580
|
+
protected async requestPumpStatusAsync() {
|
|
536
581
|
if (conn.isPortEnabled(this.pump.portId || 0)) {
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
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
|
|
599
|
+
protected async setPumpToRemoteControlAsync(running: boolean = true) {
|
|
559
600
|
if (conn.isPortEnabled(this.pump.portId || 0)) {
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
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
|
|
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
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
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
|
-
|
|
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
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
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
|
-
|
|
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
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
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
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
this.
|
|
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
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
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
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
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
|
-
|
|
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
|
|
851
|
-
protected
|
|
852
|
-
protected
|
|
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
|
-
|
|
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
|
|
875
|
+
dest: this.pump.address,
|
|
890
876
|
action: 1,
|
|
891
|
-
payload: [
|
|
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
|
-
|
|
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
|
}
|