nodejs-poolcontroller 7.5.1 → 7.7.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/.github/ISSUE_TEMPLATE/1-bug-report.yml +84 -0
- package/.github/ISSUE_TEMPLATE/2-docs.md +12 -0
- package/.github/ISSUE_TEMPLATE/3-proposal.md +28 -0
- package/.github/ISSUE_TEMPLATE/config.yml +8 -0
- package/Changelog +19 -0
- package/Dockerfile +3 -3
- package/README.md +13 -8
- package/app.ts +1 -1
- package/config/Config.ts +38 -2
- package/config/VersionCheck.ts +27 -12
- package/controller/Constants.ts +2 -1
- package/controller/Equipment.ts +193 -9
- package/controller/Errors.ts +10 -0
- package/controller/Lockouts.ts +503 -0
- package/controller/State.ts +269 -64
- package/controller/boards/AquaLinkBoard.ts +1000 -0
- package/controller/boards/BoardFactory.ts +4 -0
- package/controller/boards/EasyTouchBoard.ts +468 -144
- package/controller/boards/IntelliCenterBoard.ts +466 -307
- package/controller/boards/IntelliTouchBoard.ts +37 -5
- package/controller/boards/NixieBoard.ts +671 -141
- package/controller/boards/SystemBoard.ts +1397 -641
- package/controller/comms/Comms.ts +462 -362
- package/controller/comms/messages/Messages.ts +174 -30
- package/controller/comms/messages/config/ChlorinatorMessage.ts +6 -3
- package/controller/comms/messages/config/CircuitMessage.ts +1 -0
- package/controller/comms/messages/config/ExternalMessage.ts +10 -8
- package/controller/comms/messages/config/HeaterMessage.ts +141 -29
- package/controller/comms/messages/config/OptionsMessage.ts +9 -2
- package/controller/comms/messages/config/PumpMessage.ts +53 -35
- package/controller/comms/messages/config/ScheduleMessage.ts +33 -25
- package/controller/comms/messages/config/ValveMessage.ts +2 -2
- package/controller/comms/messages/status/ChlorinatorStateMessage.ts +38 -86
- package/controller/comms/messages/status/EquipmentStateMessage.ts +59 -23
- package/controller/comms/messages/status/HeaterStateMessage.ts +57 -3
- package/controller/comms/messages/status/IntelliChemStateMessage.ts +56 -8
- package/controller/comms/messages/status/PumpStateMessage.ts +23 -1
- package/controller/nixie/Nixie.ts +1 -1
- package/controller/nixie/bodies/Body.ts +3 -0
- package/controller/nixie/chemistry/ChemController.ts +164 -51
- package/controller/nixie/chemistry/Chlorinator.ts +137 -88
- package/controller/nixie/circuits/Circuit.ts +51 -19
- package/controller/nixie/heaters/Heater.ts +241 -31
- package/controller/nixie/pumps/Pump.ts +488 -206
- package/controller/nixie/schedules/Schedule.ts +91 -35
- package/controller/nixie/valves/Valve.ts +1 -1
- package/defaultConfig.json +20 -0
- package/package.json +21 -21
- package/web/Server.ts +94 -49
- package/web/bindings/aqualinkD.json +505 -0
- package/web/bindings/influxDB.json +71 -1
- package/web/bindings/mqtt.json +98 -39
- package/web/bindings/mqttAlt.json +59 -1
- package/web/interfaces/baseInterface.ts +1 -0
- package/web/interfaces/httpInterface.ts +23 -2
- package/web/interfaces/influxInterface.ts +45 -10
- package/web/interfaces/mqttInterface.ts +114 -54
- package/web/services/config/Config.ts +55 -132
- package/web/services/state/State.ts +81 -4
- package/web/services/state/StateSocket.ts +4 -4
- package/web/services/utilities/Utilities.ts +8 -6
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -52
- package/config copy.json +0 -300
- package/issue_template.md +0 -52
|
@@ -8,7 +8,7 @@ import { CircuitState, PumpState, state, } from "../../State";
|
|
|
8
8
|
import { setTimeout, clearTimeout } from 'timers';
|
|
9
9
|
import { NixieControlPanel } from '../Nixie';
|
|
10
10
|
import { webApp, InterfaceServerResponse } from "../../../web/Server";
|
|
11
|
-
import { Outbound, Protocol } from '../../comms/messages/Messages';
|
|
11
|
+
import { Outbound, Protocol, Response } from '../../comms/messages/Messages';
|
|
12
12
|
import { conn } from '../../comms/Comms';
|
|
13
13
|
|
|
14
14
|
export class NixiePumpCollection extends NixieEquipmentCollection<NixiePump> {
|
|
@@ -117,6 +117,10 @@ export class NixiePumpCollection extends NixieEquipmentCollection<NixiePump> {
|
|
|
117
117
|
return new NixiePumpSF(this.controlPanel, pump);
|
|
118
118
|
case 'vs':
|
|
119
119
|
return new NixiePumpVS(this.controlPanel, pump);
|
|
120
|
+
case 'hwvs':
|
|
121
|
+
return new NixiePumpHWVS(this.controlPanel, pump);
|
|
122
|
+
case 'hwrly':
|
|
123
|
+
return new NixiePumpHWRLY(this.controlPanel, pump);
|
|
120
124
|
default:
|
|
121
125
|
throw new EquipmentNotFoundError(`NCP: Cannot create pump ${pump.name}.`, type);
|
|
122
126
|
}
|
|
@@ -180,13 +184,34 @@ export class NixiePump extends NixieEquipment {
|
|
|
180
184
|
if (typeof type.maxCircuits !== 'undefined' && type.maxCircuits > 0 && typeof data.circuits !== 'undefined') { // This pump type supports circuits
|
|
181
185
|
for (let i = 1; i <= data.circuits.length && i <= type.maxCircuits; i++) {
|
|
182
186
|
let c = data.circuits[i - 1];
|
|
187
|
+
let circuit = parseInt(c.circuit, 10);
|
|
188
|
+
let cd = this.pump.circuits.find(elem => elem.circuit === circuit);
|
|
183
189
|
let speed = parseInt(c.speed, 10);
|
|
184
190
|
let relay = parseInt(c.relay, 10);
|
|
185
191
|
let flow = parseInt(c.flow, 10);
|
|
192
|
+
let units = typeof c.units !== 'undefined' ? sys.board.valueMaps.pumpUnits.encode(c.units) : undefined;
|
|
193
|
+
switch (type.name) {
|
|
194
|
+
case 'vf':
|
|
195
|
+
units = sys.board.valueMaps.pumpUnits.getValue('gpm');
|
|
196
|
+
break;
|
|
197
|
+
case 'hwvs':
|
|
198
|
+
case 'vssvrs':
|
|
199
|
+
case 'vs':
|
|
200
|
+
c.units = sys.board.valueMaps.pumpUnits.getValue('rpm');
|
|
201
|
+
break;
|
|
202
|
+
case 'ss':
|
|
203
|
+
case 'ds':
|
|
204
|
+
case 'sf':
|
|
205
|
+
case 'hwrly':
|
|
206
|
+
c.units = 'undefined';
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
if (isNaN(units)) units = typeof cd !== 'undefined' ? cd.units : sys.board.valueMaps.pumpUnits.getValue('rpm');
|
|
186
210
|
if (isNaN(speed)) speed = type.minSpeed;
|
|
187
211
|
if (isNaN(flow)) flow = type.minFlow;
|
|
188
212
|
if (isNaN(relay)) relay = 1;
|
|
189
|
-
c.units =
|
|
213
|
+
c.units = units;
|
|
214
|
+
//c.units = parseInt(c.units, 10) || type.name === 'vf' ? sys.board.valueMaps.pumpUnits.getValue('gpm') : sys.board.valueMaps.pumpUnits.getValue('rpm');
|
|
190
215
|
if (typeof type.minSpeed !== 'undefined' && c.units === sys.board.valueMaps.pumpUnits.getValue('rpm')) {
|
|
191
216
|
c.speed = speed;
|
|
192
217
|
}
|
|
@@ -215,8 +240,8 @@ export class NixiePump extends NixieEquipment {
|
|
|
215
240
|
if (typeof this._pollTimer !== 'undefined' || this._pollTimer) clearTimeout(this._pollTimer);
|
|
216
241
|
this._pollTimer = null;
|
|
217
242
|
// let success = false;
|
|
218
|
-
this.setTargetSpeed();
|
|
219
243
|
let pstate = state.pumps.getItemById(this.pump.id);
|
|
244
|
+
this.setTargetSpeed(pstate);
|
|
220
245
|
await this.setPumpStateAsync(pstate);
|
|
221
246
|
}
|
|
222
247
|
catch (err) { logger.error(`Nixie Error running pump sequence - ${err}`); }
|
|
@@ -239,7 +264,10 @@ export class NixiePump extends NixieEquipment {
|
|
|
239
264
|
this._pollTimer = null;
|
|
240
265
|
this._targetSpeed = 0;
|
|
241
266
|
let pstate = state.pumps.getItemById(this.pump.id);
|
|
242
|
-
|
|
267
|
+
try {
|
|
268
|
+
await this.setPumpStateAsync(pstate);
|
|
269
|
+
// Since we are closing we need to not reject.
|
|
270
|
+
} catch (err) { logger.error(`Nixie Closing pump closeAsync: ${err.message}`); }
|
|
243
271
|
// This will make sure the timer is dead and we are completely closed.
|
|
244
272
|
this.closing = true;
|
|
245
273
|
if (typeof this._pollTimer !== 'undefined' || this._pollTimer) clearTimeout(this._pollTimer);
|
|
@@ -248,19 +276,43 @@ export class NixiePump extends NixieEquipment {
|
|
|
248
276
|
catch (err) { logger.error(`Nixie Pump closeAsync: ${err.message}`); return Promise.reject(err); }
|
|
249
277
|
}
|
|
250
278
|
public logData(filename: string, data: any) { this.controlPanel.logData(filename, data); }
|
|
251
|
-
protected setTargetSpeed() { };
|
|
279
|
+
protected setTargetSpeed(pstate: PumpState) { };
|
|
280
|
+
protected isBodyOn(bodyCode: number) {
|
|
281
|
+
let assoc = sys.board.valueMaps.pumpBodies.transform(bodyCode);
|
|
282
|
+
switch (assoc.name) {
|
|
283
|
+
case 'body1':
|
|
284
|
+
case 'pool':
|
|
285
|
+
return state.temps.bodies.getItemById(1).isOn;
|
|
286
|
+
case 'body2':
|
|
287
|
+
case 'spa':
|
|
288
|
+
return state.temps.bodies.getItemById(2).isOn;
|
|
289
|
+
case 'body3':
|
|
290
|
+
return state.temps.bodies.getItemById(3).isOn;
|
|
291
|
+
case 'body4':
|
|
292
|
+
return state.temps.bodies.getItemById(4).isOn;
|
|
293
|
+
case 'poolspa':
|
|
294
|
+
if (sys.equipment.shared && sys.equipment.maxBodies >= 2) {
|
|
295
|
+
return state.temps.bodies.getItemById(1).isOn === true || state.temps.bodies.getItemById(2).isOn === true;
|
|
296
|
+
}
|
|
297
|
+
else
|
|
298
|
+
return state.temps.bodies.getItemById(1).isOn;
|
|
299
|
+
}
|
|
300
|
+
return false;
|
|
301
|
+
}
|
|
252
302
|
}
|
|
253
303
|
export class NixiePumpSS extends NixiePump {
|
|
254
|
-
public setTargetSpeed() {
|
|
304
|
+
public setTargetSpeed(pState: PumpState) {
|
|
255
305
|
// Turn on ss pumps.
|
|
256
306
|
let _newSpeed = 0;
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
307
|
+
if (!pState.pumpOnDelay) {
|
|
308
|
+
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}`);
|
|
311
|
+
}
|
|
312
|
+
if (this._targetSpeed !== _newSpeed) logger.info(`NCP: Setting Pump ${this.pump.name} to ${_newSpeed > 0 ? 'on' : 'off'}. ${sys.board.bodies.isBodyOn(this.pump.body)}`);
|
|
260
313
|
if (isNaN(_newSpeed)) _newSpeed = 0;
|
|
261
314
|
this._targetSpeed = _newSpeed;
|
|
262
315
|
}
|
|
263
|
-
|
|
264
316
|
public async setPumpStateAsync(pstate: PumpState) {
|
|
265
317
|
let relays: PumpRelay[] = this.pump.relays.get();
|
|
266
318
|
let relayState = 0;
|
|
@@ -301,16 +353,20 @@ export class NixiePumpSS extends NixiePump {
|
|
|
301
353
|
}
|
|
302
354
|
}
|
|
303
355
|
export class NixiePumpDS extends NixiePumpSS {
|
|
304
|
-
public setTargetSpeed() {
|
|
356
|
+
public setTargetSpeed(pState: PumpState) {
|
|
305
357
|
// Turn on sf pumps. The new speed will be the relays associated with the pump. I believe when this comes out in the final
|
|
306
358
|
// wash it should engage all the relays for all speeds associated with the pump. The pump logic will determine which program is
|
|
307
359
|
// the one to engage.
|
|
308
360
|
let _newSpeed = 0;
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
361
|
+
if (!pState.pumpOnDelay) {
|
|
362
|
+
let pumpCircuits: PumpCircuit[] = this.pump.circuits.get();
|
|
363
|
+
if (!pState.pumpOnDelay) {
|
|
364
|
+
for (let i = 0; i < pumpCircuits.length; i++) {
|
|
365
|
+
let circ = state.circuits.getInterfaceById(pumpCircuits[i].circuit);
|
|
366
|
+
// relay speeds are bit-shifted 'or' based on 1,2,4,8
|
|
367
|
+
if (circ.isOn) _newSpeed |= (1 << pumpCircuits[i].relay - 1);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
314
370
|
}
|
|
315
371
|
if (isNaN(_newSpeed)) _newSpeed = 0;
|
|
316
372
|
this.logSpeed(_newSpeed);
|
|
@@ -327,6 +383,100 @@ export class NixiePumpSF extends NixiePumpDS {
|
|
|
327
383
|
if (this._targetSpeed !== _newSpeed) logger.info(`NCP: Setting Pump ${this.pump.name} relays to Relay 1: ${_newSpeed & 1 ? 'on' : 'off'}, Relay 2: ${_newSpeed & 2 ? 'on' : 'off'}, Relay 3: ${_newSpeed & 4 ? 'on' : 'off'}, and Relay 4: ${_newSpeed & 8 ? 'on' : 'off'}.`);
|
|
328
384
|
}
|
|
329
385
|
}
|
|
386
|
+
export class NixiePumpHWRLY extends NixiePumpDS {
|
|
387
|
+
// This operates as a relay pump with up to 8 speeds. The speeds are defined as follows. The override
|
|
388
|
+
// relay should be defined as being normally closed. When it opens then the pump will turn on to the speed.
|
|
389
|
+
// +-------+---------+---------+---------+---------+
|
|
390
|
+
// + Speed | Relay 1 | Relay 2 | Relay 3 | OVRD |
|
|
391
|
+
// +-------+---------+---------+---------+---------+
|
|
392
|
+
// | OFF | OFF | OFF | OFF | OFF |
|
|
393
|
+
// +-------+---------+---------+---------+---------+
|
|
394
|
+
// | 1 | OFF | OFF | OFF | ON |
|
|
395
|
+
// +-------+---------+---------+---------+---------+
|
|
396
|
+
// | 2 | ON | OFF | OFF | ON |
|
|
397
|
+
// +-------+---------+---------+---------+---------+
|
|
398
|
+
// | 3 | OFF | ON | OFF | ON |
|
|
399
|
+
// +-------+---------+---------+---------+---------+
|
|
400
|
+
// | 4 | ON | ON | OFF | ON |
|
|
401
|
+
// +-------+---------+---------+---------+---------+
|
|
402
|
+
// | 5 | OFF | OFF | ON | ON |
|
|
403
|
+
// +-------+---------+---------+---------+---------+
|
|
404
|
+
// | 6 | ON | OFF | ON | ON |
|
|
405
|
+
// +-------+---------+---------+---------+---------+
|
|
406
|
+
// | 7 | OFF | ON | ON | ON |
|
|
407
|
+
// +-------+---------+---------+---------+---------+
|
|
408
|
+
// | 8 | ON | ON | ON | ON |
|
|
409
|
+
// +-------+---------+---------+---------+---------+
|
|
410
|
+
|
|
411
|
+
public setTargetSpeed(pState: PumpState) {
|
|
412
|
+
let _newSpeed = 0;
|
|
413
|
+
if (!pState.pumpOnDelay) {
|
|
414
|
+
let pumpCircuits = this.pump.circuits.get();
|
|
415
|
+
for (let i = 0; i < pumpCircuits.length; i++) {
|
|
416
|
+
let circ = state.circuits.getInterfaceById(pumpCircuits[i].circuit);
|
|
417
|
+
let pc = pumpCircuits[i];
|
|
418
|
+
if (circ.isOn) {
|
|
419
|
+
_newSpeed = Math.max(_newSpeed, pc.relay);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
if (isNaN(_newSpeed)) _newSpeed = 0;
|
|
424
|
+
this._targetSpeed = _newSpeed;
|
|
425
|
+
if (this._targetSpeed !== 0) Math.min(Math.max(this.pump.minSpeed, this._targetSpeed), this.pump.maxSpeed);
|
|
426
|
+
if (this._targetSpeed !== _newSpeed) logger.info(`NCP: Setting Pump ${this.pump.name} to ${_newSpeed}.`);
|
|
427
|
+
}
|
|
428
|
+
public async setPumpStateAsync(pstate: PumpState) {
|
|
429
|
+
// Don't poll while we are seting the state.
|
|
430
|
+
this.suspendPolling = true;
|
|
431
|
+
try {
|
|
432
|
+
let relays: PumpRelay[] = this.pump.relays.get();
|
|
433
|
+
let relayState = 0;
|
|
434
|
+
let targetState = 0;
|
|
435
|
+
for (let i = 0; i < relays.length; i++) {
|
|
436
|
+
let pr = relays[i];
|
|
437
|
+
if (typeof pr.id === 'undefined') pr.id = i + 1; // remove when id is added to dP relays upon save.
|
|
438
|
+
// If we are turning on the pump relay #4 needs to be on. NOTE: It is expected that the OVRD relay is hooked up in a normally closed
|
|
439
|
+
// configuration so that whenever the pump is off the relay terminals are closed.
|
|
440
|
+
let isOn = this._targetSpeed > 0 ? i === 3 ? true : (this._targetSpeed - 1 & (1 << i)) > 0 : false;
|
|
441
|
+
let bit = isOn ? (1 << i) : 0;
|
|
442
|
+
targetState |= bit;
|
|
443
|
+
if (utils.isNullOrEmpty(pr.connectionId) || utils.isNullOrEmpty(pr.deviceBinding)) {
|
|
444
|
+
// Determine whether the relay should be on.
|
|
445
|
+
relayState |= bit;
|
|
446
|
+
}
|
|
447
|
+
else {
|
|
448
|
+
try {
|
|
449
|
+
let res = await NixieEquipment.putDeviceService(pr.connectionId, `/state/device/${pr.deviceBinding}`, { isOn, latch: isOn ? 5000 : undefined });
|
|
450
|
+
if (res.status.code === 200) {
|
|
451
|
+
relayState |= bit;
|
|
452
|
+
}
|
|
453
|
+
else pstate.status = 16;
|
|
454
|
+
}
|
|
455
|
+
catch (err) {
|
|
456
|
+
logger.error(`NCP: Error setting pump ${this.pump.name} relay ${pr.id} to ${isOn ? 'on' : 'off'}. Error ${err.message}}`);
|
|
457
|
+
pstate.status = 16;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
pstate.command = this._targetSpeed;
|
|
462
|
+
if (targetState === relayState) {
|
|
463
|
+
pstate.status = relayState > 0 ? 1 : 0;
|
|
464
|
+
pstate.driveState = relayState > 0 ? 2 : 0;
|
|
465
|
+
pstate.relay = relayState;
|
|
466
|
+
}
|
|
467
|
+
else {
|
|
468
|
+
pstate.driveState = 0;
|
|
469
|
+
}
|
|
470
|
+
return new InterfaceServerResponse(200, 'Success');
|
|
471
|
+
}
|
|
472
|
+
catch (err) {
|
|
473
|
+
logger.error(`Error running pump sequence for ${this.pump.name}: ${err.message}`);
|
|
474
|
+
return Promise.reject(err);
|
|
475
|
+
}
|
|
476
|
+
finally { this.suspendPolling = false; }
|
|
477
|
+
};
|
|
478
|
+
|
|
479
|
+
}
|
|
330
480
|
export class NixiePumpRS485 extends NixiePump {
|
|
331
481
|
public async setPumpStateAsync(pstate: PumpState) {
|
|
332
482
|
// Don't poll while we are seting the state.
|
|
@@ -336,15 +486,16 @@ export class NixiePumpRS485 extends NixiePump {
|
|
|
336
486
|
// Since these process are async the closing flag can be set
|
|
337
487
|
// between calls. We need to check it in between each call.
|
|
338
488
|
try { if (!this.closing) await this.setDriveStateAsync(); } catch (err) {}
|
|
339
|
-
try {
|
|
340
|
-
if (this.
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
try { if(!this.closing) await
|
|
346
|
-
try { if(!this.closing) await
|
|
347
|
-
try { if(!this.closing) await this.
|
|
489
|
+
try {
|
|
490
|
+
if (!this.closing) {
|
|
491
|
+
if (this._targetSpeed >= pt.minFlow && this._targetSpeed <= pt.maxFlow) await this.setPumpGPMAsync();
|
|
492
|
+
else if (this._targetSpeed >= pt.minSpeed && this._targetSpeed <= pt.maxSpeed) await this.setPumpRPMAsync();
|
|
493
|
+
}
|
|
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) { };
|
|
348
499
|
return new InterfaceServerResponse(200, 'Success');
|
|
349
500
|
}
|
|
350
501
|
catch (err) {
|
|
@@ -352,132 +503,160 @@ export class NixiePumpRS485 extends NixiePump {
|
|
|
352
503
|
return Promise.reject(err);
|
|
353
504
|
}
|
|
354
505
|
finally { this.suspendPolling = false; }
|
|
355
|
-
|
|
356
506
|
};
|
|
357
507
|
protected async setDriveStateAsync(running: boolean = true) {
|
|
358
508
|
return new Promise<void>((resolve, reject) => {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
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();
|
|
370
524
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
}
|
|
374
|
-
|
|
525
|
+
});
|
|
526
|
+
conn.queueSendMessage(out);
|
|
527
|
+
}
|
|
528
|
+
else {
|
|
529
|
+
let pstate = state.pumps.getItemById(this.pump.id);
|
|
530
|
+
pstate.command = pstate.rpm > 0 || pstate.flow > 0 ? 10 : 0;
|
|
531
|
+
resolve();
|
|
532
|
+
}
|
|
375
533
|
});
|
|
376
534
|
};
|
|
377
535
|
protected async requestPumpStatus() {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
536
|
+
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();
|
|
390
552
|
}
|
|
391
|
-
|
|
392
|
-
|
|
553
|
+
});
|
|
554
|
+
conn.queueSendMessage(out);
|
|
393
555
|
});
|
|
394
|
-
|
|
395
|
-
})
|
|
556
|
+
}
|
|
396
557
|
};
|
|
397
558
|
protected setPumpToRemoteControl(running: boolean = true) {
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
559
|
+
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();
|
|
411
576
|
}
|
|
412
|
-
|
|
413
|
-
|
|
577
|
+
});
|
|
578
|
+
conn.queueSendMessage(out);
|
|
414
579
|
});
|
|
415
|
-
|
|
416
|
-
});
|
|
580
|
+
}
|
|
417
581
|
}
|
|
418
582
|
protected setPumpFeature(feature?: number) {
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
583
|
+
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();
|
|
433
601
|
}
|
|
434
|
-
|
|
435
|
-
|
|
602
|
+
});
|
|
603
|
+
conn.queueSendMessage(out);
|
|
436
604
|
});
|
|
437
|
-
|
|
438
|
-
|
|
605
|
+
}
|
|
606
|
+
else {
|
|
607
|
+
|
|
608
|
+
}
|
|
439
609
|
};
|
|
440
610
|
protected async setPumpRPMAsync() {
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
611
|
+
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();
|
|
454
628
|
}
|
|
455
|
-
|
|
456
|
-
|
|
629
|
+
});
|
|
630
|
+
conn.queueSendMessage(out);
|
|
457
631
|
});
|
|
458
|
-
|
|
459
|
-
|
|
632
|
+
}
|
|
633
|
+
else {
|
|
634
|
+
|
|
635
|
+
}
|
|
460
636
|
};
|
|
461
637
|
protected async setPumpGPMAsync() {
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
638
|
+
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();
|
|
475
655
|
}
|
|
476
|
-
|
|
477
|
-
|
|
656
|
+
});
|
|
657
|
+
conn.queueSendMessage(out);
|
|
478
658
|
});
|
|
479
|
-
|
|
480
|
-
});
|
|
659
|
+
}
|
|
481
660
|
};
|
|
482
661
|
public async closeAsync() {
|
|
483
662
|
try {
|
|
@@ -503,75 +682,82 @@ export class NixiePumpRS485 extends NixiePump {
|
|
|
503
682
|
}
|
|
504
683
|
}
|
|
505
684
|
export class NixiePumpVS extends NixiePumpRS485 {
|
|
506
|
-
public setTargetSpeed() {
|
|
685
|
+
public setTargetSpeed(pState: PumpState) {
|
|
507
686
|
let _newSpeed = 0;
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
let
|
|
512
|
-
|
|
687
|
+
if (!pState.pumpOnDelay) {
|
|
688
|
+
let pumpCircuits = this.pump.circuits.get();
|
|
689
|
+
|
|
690
|
+
for (let i = 0; i < pumpCircuits.length; i++) {
|
|
691
|
+
let circ = state.circuits.getInterfaceById(pumpCircuits[i].circuit);
|
|
692
|
+
let pc = pumpCircuits[i];
|
|
693
|
+
if (circ.isOn) _newSpeed = Math.max(_newSpeed, pc.speed);
|
|
694
|
+
}
|
|
513
695
|
}
|
|
514
696
|
if (isNaN(_newSpeed)) _newSpeed = 0;
|
|
697
|
+
this._targetSpeed = _newSpeed;
|
|
515
698
|
if (this._targetSpeed !== 0) Math.min(Math.max(this.pump.minSpeed, this._targetSpeed), this.pump.maxSpeed);
|
|
516
699
|
if (this._targetSpeed !== _newSpeed) logger.info(`NCP: Setting Pump ${this.pump.name} to ${_newSpeed} RPM.`);
|
|
517
|
-
this._targetSpeed = _newSpeed;
|
|
518
700
|
}
|
|
519
701
|
}
|
|
520
702
|
export class NixiePumpVF extends NixiePumpRS485 {
|
|
521
|
-
public setTargetSpeed() {
|
|
703
|
+
public setTargetSpeed(pState: PumpState) {
|
|
522
704
|
let _newSpeed = 0;
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
let
|
|
526
|
-
|
|
527
|
-
|
|
705
|
+
if (!pState.pumpOnDelay) {
|
|
706
|
+
let pumpCircuits = this.pump.circuits.get();
|
|
707
|
+
for (let i = 0; i < pumpCircuits.length; i++) {
|
|
708
|
+
let circ = state.circuits.getInterfaceById(pumpCircuits[i].circuit);
|
|
709
|
+
let pc = pumpCircuits[i];
|
|
710
|
+
if (circ.isOn) _newSpeed = Math.max(_newSpeed, pc.flow);
|
|
711
|
+
}
|
|
528
712
|
}
|
|
529
713
|
if (isNaN(_newSpeed)) _newSpeed = 0;
|
|
714
|
+
this._targetSpeed = _newSpeed;
|
|
530
715
|
if (this._targetSpeed !== 0) Math.min(Math.max(this.pump.minFlow, this._targetSpeed), this.pump.maxFlow);
|
|
531
716
|
if (this._targetSpeed !== _newSpeed) logger.info(`NCP: Setting Pump ${this.pump.name} to ${_newSpeed} GPM.`);
|
|
532
|
-
this._targetSpeed = _newSpeed;
|
|
533
717
|
}
|
|
534
718
|
}
|
|
535
719
|
export class NixiePumpVSF extends NixiePumpRS485 {
|
|
536
|
-
public setTargetSpeed() {
|
|
720
|
+
public setTargetSpeed(pState: PumpState) {
|
|
537
721
|
let _newSpeed = 0;
|
|
538
|
-
let pumpCircuits = this.pump.circuits.get();
|
|
539
|
-
let pt = sys.board.valueMaps.pumpTypes.get(this.pump.type);
|
|
540
|
-
// VSF pumps present a problem. In fact they do not currently operate properly on Touch panels. On touch these need to either be all in RPM or GPM
|
|
541
|
-
// if there is a mix in the circuit array then they will not work. In IntelliCenter if there is an RPM setting in the mix it will use RPM by converting
|
|
542
|
-
// the GPM to RPM but if there is none then it will use GPM.
|
|
543
722
|
let maxRPM = 0;
|
|
544
723
|
let maxGPM = 0;
|
|
545
724
|
let flows = 0;
|
|
546
725
|
let speeds = 0;
|
|
547
|
-
|
|
548
|
-
let
|
|
549
|
-
let
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
let
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
let
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
726
|
+
if (!pState.pumpOnDelay) {
|
|
727
|
+
let pumpCircuits = this.pump.circuits.get();
|
|
728
|
+
let pt = sys.board.valueMaps.pumpTypes.get(this.pump.type);
|
|
729
|
+
// VSF pumps present a problem. In fact they do not currently operate properly on Touch panels. On touch these need to either be all in RPM or GPM
|
|
730
|
+
// if there is a mix in the circuit array then they will not work. In IntelliCenter if there is an RPM setting in the mix it will use RPM by converting
|
|
731
|
+
// the GPM to RPM but if there is none then it will use GPM.
|
|
732
|
+
let toRPM = (flowRate: number, minSpeed: number = 450, maxSpeed: number = 3450) => {
|
|
733
|
+
let eff = .03317 * maxSpeed;
|
|
734
|
+
let rpm = Math.min((flowRate * maxSpeed) / eff, maxSpeed);
|
|
735
|
+
return rpm > 0 ? Math.max(rpm, minSpeed) : 0;
|
|
736
|
+
};
|
|
737
|
+
let toGPM = (speed: number, maxSpeed: number = 3450, minFlow: number = 15, maxFlow: number = 140) => {
|
|
738
|
+
let eff = .03317 * maxSpeed;
|
|
739
|
+
let gpm = Math.min((eff * speed) / maxSpeed, maxFlow);
|
|
740
|
+
return gpm > 0 ? Math.max(gpm, minFlow) : 0;
|
|
741
|
+
}
|
|
742
|
+
for (let i = 0; i < pumpCircuits.length; i++) {
|
|
743
|
+
let circ = state.circuits.getInterfaceById(pumpCircuits[i].circuit);
|
|
744
|
+
let pc = pumpCircuits[i];
|
|
745
|
+
if (circ.isOn) {
|
|
746
|
+
if (pc.units > 0) {
|
|
747
|
+
maxGPM = Math.max(maxGPM, pc.flow);
|
|
748
|
+
// Calculate an RPM from this flow.
|
|
749
|
+
maxRPM = Math.max(maxGPM, toRPM(pc.flow, pt.minSpeed, pt.maxSpeed));
|
|
750
|
+
flows++;
|
|
751
|
+
}
|
|
752
|
+
else {
|
|
753
|
+
maxRPM = Math.max(maxRPM, pc.speed);
|
|
754
|
+
maxGPM = Math.max(maxGPM, toGPM(pc.speed, pt.maxSpeed, pt.minFlow, pt.maxFlow));
|
|
755
|
+
speeds++;
|
|
756
|
+
}
|
|
571
757
|
}
|
|
572
758
|
}
|
|
759
|
+
_newSpeed = speeds > 0 || flows === 0 ? maxRPM : maxGPM;
|
|
573
760
|
}
|
|
574
|
-
_newSpeed = speeds > 0 || flows === 0 ? maxRPM : maxGPM;
|
|
575
761
|
if (isNaN(_newSpeed)) _newSpeed = 0;
|
|
576
762
|
// Send the flow message if it is flow and the rpm message if it is rpm.
|
|
577
763
|
if (this._targetSpeed !== _newSpeed) logger.info(`NCP: Setting Pump ${this.pump.name} to ${_newSpeed} ${flows > 0 ? 'GPM' : 'RPM'}.`);
|
|
@@ -579,46 +765,142 @@ export class NixiePumpVSF extends NixiePumpRS485 {
|
|
|
579
765
|
}
|
|
580
766
|
protected async setPumpRPMAsync() {
|
|
581
767
|
// vsf action is 10 for rpm
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
768
|
+
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();
|
|
595
785
|
}
|
|
596
|
-
|
|
597
|
-
|
|
786
|
+
});
|
|
787
|
+
conn.queueSendMessage(out);
|
|
598
788
|
});
|
|
599
|
-
|
|
600
|
-
});
|
|
789
|
+
}
|
|
601
790
|
};
|
|
602
791
|
protected async setPumpGPMAsync() {
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
792
|
+
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
|
|
616
810
|
}
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
}
|
|
811
|
+
});
|
|
812
|
+
conn.queueSendMessage(out);
|
|
620
813
|
});
|
|
621
|
-
|
|
622
|
-
});
|
|
814
|
+
}
|
|
623
815
|
};
|
|
624
816
|
};
|
|
817
|
+
export class NixiePumpHWVS extends NixiePumpRS485 {
|
|
818
|
+
public setTargetSpeed(pState: PumpState) {
|
|
819
|
+
let _newSpeed = 0;
|
|
820
|
+
if (!pState.pumpOnDelay) {
|
|
821
|
+
let pumpCircuits = this.pump.circuits.get();
|
|
822
|
+
|
|
823
|
+
for (let i = 0; i < pumpCircuits.length; i++) {
|
|
824
|
+
let circ = state.circuits.getInterfaceById(pumpCircuits[i].circuit);
|
|
825
|
+
let pc = pumpCircuits[i];
|
|
826
|
+
if (circ.isOn) _newSpeed = Math.max(_newSpeed, pc.speed);
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
if (isNaN(_newSpeed)) _newSpeed = 0;
|
|
830
|
+
this._targetSpeed = _newSpeed;
|
|
831
|
+
if (this._targetSpeed !== 0) Math.min(Math.max(this.pump.minSpeed, this._targetSpeed), this.pump.maxSpeed);
|
|
832
|
+
if (this._targetSpeed !== _newSpeed) logger.info(`NCP: Setting Pump ${this.pump.name} to ${_newSpeed} RPM.`);
|
|
833
|
+
}
|
|
834
|
+
public async setPumpStateAsync(pstate: PumpState) {
|
|
835
|
+
// Don't poll while we are seting the state.
|
|
836
|
+
this.suspendPolling = true;
|
|
837
|
+
try {
|
|
838
|
+
let pt = sys.board.valueMaps.pumpTypes.get(this.pump.type);
|
|
839
|
+
// Since these process are async the closing flag can be set
|
|
840
|
+
// between calls. We need to check it in between each call.
|
|
841
|
+
try { if (!this.closing) { await this.setPumpRPMAsync(); } } catch (err) { }
|
|
842
|
+
return new InterfaceServerResponse(200, 'Success');
|
|
843
|
+
}
|
|
844
|
+
catch (err) {
|
|
845
|
+
logger.error(`Error running pump sequence for ${this.pump.name}: ${err.message}`);
|
|
846
|
+
return Promise.reject(err);
|
|
847
|
+
}
|
|
848
|
+
finally { this.suspendPolling = false; }
|
|
849
|
+
};
|
|
850
|
+
protected async requestPumpStatus() { return Promise.resolve(); };
|
|
851
|
+
protected setPumpFeature(feature?: number) { return Promise.resolve(); }
|
|
852
|
+
protected setPumpToRemoteControl(running: boolean = true) {
|
|
853
|
+
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);
|
|
885
|
+
let out = Outbound.create({
|
|
886
|
+
portId: this.pump.portId || 0,
|
|
887
|
+
protocol: Protocol.Hayward,
|
|
888
|
+
source: 12, // Use the broadcast address
|
|
889
|
+
dest: this.pump.address - 96,
|
|
890
|
+
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
|
|
892
|
+
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
|
+
}
|
|
901
|
+
});
|
|
902
|
+
conn.queueSendMessage(out);
|
|
903
|
+
});
|
|
904
|
+
}
|
|
905
|
+
};
|
|
906
|
+
}
|