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
package/controller/Equipment.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* nodejs-poolController. An application to control pool equipment.
|
|
2
|
-
Copyright (C) 2016, 2017, 2018, 2019, 2020
|
|
2
|
+
Copyright (C) 2016, 2017, 2018, 2019, 2020, 2021, 2022.
|
|
3
|
+
Russell Goldin, tagyoureit. russ.goldin@gmail.com
|
|
3
4
|
|
|
4
5
|
This program is free software: you can redistribute it and/or modify
|
|
5
6
|
it under the terms of the GNU Affero General Public License as
|
|
@@ -31,13 +32,16 @@ import { conn } from './comms/Comms';
|
|
|
31
32
|
import { versionCheck } from "../config/VersionCheck";
|
|
32
33
|
import { NixieControlPanel } from "./nixie/Nixie";
|
|
33
34
|
import { NixieBoard } from 'controller/boards/NixieBoard';
|
|
34
|
-
import {
|
|
35
|
+
import { MockSystemBoard } from "../anslq25/boards/MockSystemBoard";
|
|
36
|
+
import { MockBoardFactory } from "../anslq25/boards/MockBoardFactory";
|
|
37
|
+
import { ScreenLogicComms } from "./comms/ScreenLogic";
|
|
35
38
|
|
|
36
39
|
interface IPoolSystem {
|
|
37
40
|
cfgPath: string;
|
|
38
41
|
data: any;
|
|
39
42
|
stopAsync(): void;
|
|
40
43
|
persist(): void;
|
|
44
|
+
anslq25: Anslq25;
|
|
41
45
|
general: General;
|
|
42
46
|
equipment: Equipment;
|
|
43
47
|
configVersion: ConfigVersion;
|
|
@@ -74,9 +78,9 @@ export class PoolSystem implements IPoolSystem {
|
|
|
74
78
|
constructor() {
|
|
75
79
|
this.cfgPath = path.posix.join(process.cwd(), '/data/poolConfig.json');
|
|
76
80
|
}
|
|
77
|
-
public getAvailableControllerTypes() {
|
|
81
|
+
public getAvailableControllerTypes(include:string[] = ['easytouch', 'intellitouch', 'intellicenter', 'nixie']) {
|
|
78
82
|
let arr = [];
|
|
79
|
-
arr.push({
|
|
83
|
+
if (include.indexOf('easytouch')>=0) arr.push({
|
|
80
84
|
type: 'easytouch', name: 'EasyTouch',
|
|
81
85
|
models: [
|
|
82
86
|
{ val: 0, name: 'ET28', part: 'ET2-8', desc: 'EasyTouch2 8', circuits: 8, bodies: 2, shared: true },
|
|
@@ -89,10 +93,10 @@ export class PoolSystem implements IPoolSystem {
|
|
|
89
93
|
{ val: 128, name: 'ET8', part: 'ET-8', desc: 'EasyTouch 8', circuits: 8, bodies: 2, shared: true },
|
|
90
94
|
{ val: 129, name: 'ET8P', part: 'ET-8P', desc: 'EasyTouch 8', circuits: 8, bodies: 1, shared: false },
|
|
91
95
|
{ val: 130, name: 'ET4', part: 'ET-4', desc: 'EasyTouch 4', circuits: 4, bodies: 2, shared: true },
|
|
92
|
-
{ val:
|
|
96
|
+
{ val: 131, name: 'ET4P', part: 'ET-4P', desc: 'EasyTouch 4P', circuits: 4, bodies: 1, shared: false }
|
|
93
97
|
]
|
|
94
98
|
});
|
|
95
|
-
arr.push({
|
|
99
|
+
if (include.indexOf('intellitouch')>=0) arr.push({
|
|
96
100
|
type: 'intellitouch', name: 'IntelliTouch',
|
|
97
101
|
models: [
|
|
98
102
|
{ val: 0, name: 'IT5', part: 'i5+3', desc: 'IntelliTouch i5+3', bodies: 2, circuits: 6, shared: true },
|
|
@@ -108,7 +112,7 @@ export class PoolSystem implements IPoolSystem {
|
|
|
108
112
|
]
|
|
109
113
|
|
|
110
114
|
});
|
|
111
|
-
arr.push({
|
|
115
|
+
if (include.indexOf('intellicenter')>=0) arr.push({
|
|
112
116
|
type: 'intellicenter', name: 'IntelliCenter',
|
|
113
117
|
models: [
|
|
114
118
|
{ val: 0, name: 'i5P', part: '523125Z', desc: 'IntelliCenter i5P', bodies: 1, valves: 2, circuits: 5, shared: false, dual: false, chlorinators: 1, chemControllers: 1 },
|
|
@@ -120,7 +124,7 @@ export class PoolSystem implements IPoolSystem {
|
|
|
120
124
|
{ val: 7, name: 'i10D', part: '523029Z', desc: 'IntelliCenter i10D', bodies: 2, valves: 2, circuits: 11, shared: false, dual: true, chlorinators: 2, chemControllers: 2 },
|
|
121
125
|
]
|
|
122
126
|
});
|
|
123
|
-
arr.push({
|
|
127
|
+
if (include.indexOf('nixie')>=0) arr.push({
|
|
124
128
|
type: 'nixie', name: 'Nixie', canChange: true,
|
|
125
129
|
models: [
|
|
126
130
|
{ val: 0, name: 'nxp', part: 'NXP', desc: 'Nixie Single Body', bodies: 1, shared: false, dual: false },
|
|
@@ -163,8 +167,15 @@ export class PoolSystem implements IPoolSystem {
|
|
|
163
167
|
EqItemCollection.removeNullIds(cfg.lightGroups);
|
|
164
168
|
EqItemCollection.removeNullIds(cfg.remotes);
|
|
165
169
|
EqItemCollection.removeNullIds(cfg.chemControllers);
|
|
170
|
+
EqItemCollection.removeNullIds(cfg.chemDosers);
|
|
166
171
|
EqItemCollection.removeNullIds(cfg.filters);
|
|
172
|
+
if (typeof cfg.pumps !== 'undefined') {
|
|
173
|
+
for (let i = 0; i < cfg.pumps.length; i++) {
|
|
174
|
+
EqItemCollection.removeNullIds(cfg.pumps[i].circuits);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
167
177
|
this.data = this.onchange(cfg, function () { sys.dirty = true; });
|
|
178
|
+
this.anslq25 = new Anslq25(this.data, 'anslq25');
|
|
168
179
|
this.general = new General(this.data, 'pool');
|
|
169
180
|
this.equipment = new Equipment(this.data, 'equipment');
|
|
170
181
|
this.configVersion = new ConfigVersion(this.data, 'configVersion');
|
|
@@ -184,8 +195,10 @@ export class PoolSystem implements IPoolSystem {
|
|
|
184
195
|
this.customNames = new CustomNameCollection(this.data, 'customNames');
|
|
185
196
|
this.eggTimers = new EggTimerCollection(this.data, 'eggTimers');
|
|
186
197
|
this.chemControllers = new ChemControllerCollection(this.data, 'chemControllers');
|
|
198
|
+
this.chemDosers = new ChemDoserCollection(this.data, 'chemDosers');
|
|
187
199
|
this.filters = new FilterCollection(this.data, 'filters');
|
|
188
200
|
this.board = BoardFactory.fromControllerType(this.controllerType, this);
|
|
201
|
+
this.anslq25Board = MockBoardFactory.fromControllerType(this.data.anslq25.controllerType, this);
|
|
189
202
|
}
|
|
190
203
|
// This performs a safe load of the config file. If the file gets corrupt or actually does not exist
|
|
191
204
|
// it will not break the overall system and allow hardened recovery.
|
|
@@ -214,11 +227,26 @@ export class PoolSystem implements IPoolSystem {
|
|
|
214
227
|
this.board = BoardFactory.fromControllerType(ControllerType.Unknown, this);
|
|
215
228
|
setTimeout(function () { state.status = 0; conn.resumeAll(); }, 0);
|
|
216
229
|
}
|
|
230
|
+
public get anslq25ControllerType(): ControllerType { return this.data.anslq25.controllerType as ControllerType; }
|
|
231
|
+
public set anslq25ControllerType(val: ControllerType) {
|
|
232
|
+
//let self = this;
|
|
233
|
+
if (this.anslq25ControllerType !== val) {
|
|
234
|
+
console.log(`Mock Controller type changed from ${this.anslq25.controllerType} to ${val}`);
|
|
235
|
+
// Only go in here if there is a change to the controller type.
|
|
236
|
+
//this.resetData(); // Clear the configuration data.
|
|
237
|
+
//state.resetData(); // Clear the state data.
|
|
238
|
+
this.data.anslq25.controllerType = val;
|
|
239
|
+
//EquipmentStateMessage.initDefaults();
|
|
240
|
+
// We are actually changing the config so lets clear out all the data.
|
|
241
|
+
this.anslq25Board = MockBoardFactory.fromControllerType(val, this);
|
|
242
|
+
//if (this.data.anslq25.controllerType === ControllerType.Unknown) setTimeout(() => { self.initNixieController(); }, 7500);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
217
245
|
public get controllerType(): ControllerType { return this.data.controllerType as ControllerType; }
|
|
218
246
|
public set controllerType(val: ControllerType) {
|
|
219
247
|
let self = this;
|
|
220
|
-
if (this.controllerType !== val
|
|
221
|
-
console.log(
|
|
248
|
+
if (this.controllerType !== val) {
|
|
249
|
+
console.log(`RESETTING DATA -- Controller type changed from ${this.controllerType} to ${val}`);
|
|
222
250
|
// Only go in here if there is a change to the controller type.
|
|
223
251
|
this.resetData(); // Clear the configuration data.
|
|
224
252
|
state.resetData(); // Clear the state data.
|
|
@@ -226,11 +254,11 @@ export class PoolSystem implements IPoolSystem {
|
|
|
226
254
|
EquipmentStateMessage.initDefaults();
|
|
227
255
|
// We are actually changing the config so lets clear out all the data.
|
|
228
256
|
this.board = BoardFactory.fromControllerType(val, this);
|
|
229
|
-
if (this.data.controllerType === ControllerType.Unknown
|
|
257
|
+
if (this.data.controllerType === ControllerType.Unknown) setTimeout(() => { self.initNixieController(); }, 7500);
|
|
230
258
|
}
|
|
231
259
|
}
|
|
232
260
|
public resetData() {
|
|
233
|
-
if (sys.controllerType !== ControllerType.
|
|
261
|
+
if (sys.controllerType !== ControllerType.Nixie) {
|
|
234
262
|
// Do not clear this out if it is a virtual controller this causes problems.
|
|
235
263
|
this.equipment.reset();
|
|
236
264
|
this.circuitGroups.clear(0);
|
|
@@ -259,7 +287,7 @@ export class PoolSystem implements IPoolSystem {
|
|
|
259
287
|
public async stopAsync() {
|
|
260
288
|
if (this._timerChanges) clearTimeout(this._timerChanges);
|
|
261
289
|
if (this._timerDirty) clearTimeout(this._timerDirty);
|
|
262
|
-
logger.info(`Shut down sys (config) object timers`);
|
|
290
|
+
logger.info(`Shut down sys (config) object timers`);
|
|
263
291
|
return this.board.stopAsync();
|
|
264
292
|
}
|
|
265
293
|
public initNixieController() {
|
|
@@ -267,7 +295,6 @@ export class PoolSystem implements IPoolSystem {
|
|
|
267
295
|
switch (sys.controllerType || ControllerType.Unknown) {
|
|
268
296
|
case ControllerType.Unknown:
|
|
269
297
|
case ControllerType.Nixie:
|
|
270
|
-
case ControllerType.Virtual:
|
|
271
298
|
state.equipment.controllerType = sys.controllerType = ControllerType.Nixie;
|
|
272
299
|
let board = sys.board as NixieBoard;
|
|
273
300
|
(async () => { await board.initNixieBoard(); })();
|
|
@@ -275,6 +302,7 @@ export class PoolSystem implements IPoolSystem {
|
|
|
275
302
|
}
|
|
276
303
|
}
|
|
277
304
|
public board: SystemBoard = new SystemBoard(this);
|
|
305
|
+
public anslq25Board: MockSystemBoard; // = new MockSystemBoard(this);
|
|
278
306
|
public ncp: NixieControlPanel = new NixieControlPanel();
|
|
279
307
|
public processVersionChanges(ver: ConfigVersion) { this.board.requestConfiguration(ver); }
|
|
280
308
|
public checkConfiguration() { this.board.checkConfiguration(); }
|
|
@@ -286,6 +314,7 @@ export class PoolSystem implements IPoolSystem {
|
|
|
286
314
|
protected _timerChanges: NodeJS.Timeout;
|
|
287
315
|
protected _needsChanges: boolean;
|
|
288
316
|
// All the equipment items below.
|
|
317
|
+
public anslq25: Anslq25;
|
|
289
318
|
public general: General;
|
|
290
319
|
public equipment: Equipment;
|
|
291
320
|
public configVersion: ConfigVersion;
|
|
@@ -305,7 +334,9 @@ export class PoolSystem implements IPoolSystem {
|
|
|
305
334
|
public security: Security;
|
|
306
335
|
public customNames: CustomNameCollection;
|
|
307
336
|
public chemControllers: ChemControllerCollection;
|
|
337
|
+
public chemDosers: ChemDoserCollection;
|
|
308
338
|
public filters: FilterCollection;
|
|
339
|
+
public screenlogic: ScreenLogicComms;
|
|
309
340
|
public appVersion: string;
|
|
310
341
|
public get dirty(): boolean { return this._isDirty; }
|
|
311
342
|
public set dirty(val) {
|
|
@@ -527,7 +558,9 @@ class EqItemCollection<T> implements IEqItemCollection {
|
|
|
527
558
|
public static removeNullIds(data: any) {
|
|
528
559
|
if (typeof data !== 'undefined' && Array.isArray(data) && typeof data.length === 'number') {
|
|
529
560
|
for (let i = data.length - 1; i >= 0; i--) {
|
|
530
|
-
if (typeof data[i].id !== 'number')
|
|
561
|
+
if (typeof data[i].id !== 'number') {
|
|
562
|
+
data.splice(i, 1);
|
|
563
|
+
}
|
|
531
564
|
else if (typeof data[i].id === 'undefined' || isNaN(data[i].id)) data.splice(i, 1);
|
|
532
565
|
}
|
|
533
566
|
}
|
|
@@ -601,7 +634,9 @@ class EqItemCollection<T> implements IEqItemCollection {
|
|
|
601
634
|
public get length(): number { return typeof this.data !== 'undefined' ? this.data.length : 0; }
|
|
602
635
|
public set length(val: number) { if (typeof val !== 'undefined' && typeof this.data !== 'undefined') this.data.length = val; }
|
|
603
636
|
public add(obj: any): T { this.data.push(obj); return this.createItem(obj); }
|
|
604
|
-
public get(): any {
|
|
637
|
+
public get(bCopy?: boolean): any {
|
|
638
|
+
return bCopy ? JSON.parse(JSON.stringify(this.data)) : this.data;
|
|
639
|
+
}
|
|
605
640
|
public emitEquipmentChange() { webApp.emitToClients(this.name, this.data); }
|
|
606
641
|
public sortByName() {
|
|
607
642
|
this.sort((a, b) => {
|
|
@@ -615,8 +650,11 @@ class EqItemCollection<T> implements IEqItemCollection {
|
|
|
615
650
|
}
|
|
616
651
|
public sort(fn: (a, b) => number) { this.data.sort(fn); }
|
|
617
652
|
public count(fn: (value: T, index?: any, array?: any[]) => boolean): number { return this.data.filter(fn).length; }
|
|
618
|
-
public getNextEquipmentId(range
|
|
619
|
-
for (
|
|
653
|
+
public getNextEquipmentId(range?: EquipmentIdRange, exclude?: number[]): number {
|
|
654
|
+
// RG 12-4-22 for some reason extend(true, {...}, range) was not evaluating the accessors
|
|
655
|
+
// for range.start & range.end
|
|
656
|
+
let r = extend(true, { start: 1, end: 255 }, {start: range.start }, {end: range.end});
|
|
657
|
+
for (let i = r.start; i <= r.end; i++) {
|
|
620
658
|
let eq = this.data.find(elem => elem.id === i);
|
|
621
659
|
if (typeof eq === 'undefined') {
|
|
622
660
|
if (typeof exclude !== 'undefined' && exclude.indexOf(i) !== -1) continue;
|
|
@@ -645,6 +683,23 @@ class EqItemCollection<T> implements IEqItemCollection {
|
|
|
645
683
|
return typeof minId !== 'undefined' ? minId : defId;
|
|
646
684
|
}
|
|
647
685
|
}
|
|
686
|
+
export class Anslq25 extends EqItem {
|
|
687
|
+
ctor(data: any, name?: any): Anslq25 { return new Anslq25(data, name || 'anslq25'); }
|
|
688
|
+
public initData(){
|
|
689
|
+
if (typeof this.data.isActive === 'undefined') this.data.isActive = false;
|
|
690
|
+
}
|
|
691
|
+
public get controllerType(): ControllerType { return this.data.controllerType; }
|
|
692
|
+
public set controllerType(val: ControllerType) { this.setDataVal('controllerType', val); }
|
|
693
|
+
public get model(): number { return this.data.model; }
|
|
694
|
+
public set model(val: number) { this.setDataVal('model', val); }
|
|
695
|
+
public get isActive(): boolean { return this.data.isActive; }
|
|
696
|
+
public set isActive(val: boolean) { this.setDataVal('isActive', val); }
|
|
697
|
+
public get portId(): number { return this.data.portId; }
|
|
698
|
+
public set portId(val: number) { this.setDataVal('portId', val); }
|
|
699
|
+
public get broadcastComms(): boolean { return this.data.broadcastComms; }
|
|
700
|
+
public set broadcastComms(val: boolean) { this.setDataVal('broadcastComms', val); }
|
|
701
|
+
public get modules(): ExpansionModuleCollection { return new ExpansionModuleCollection(this.data, "modules"); }
|
|
702
|
+
}
|
|
648
703
|
export class General extends EqItem {
|
|
649
704
|
ctor(data: any, name?: any): General { return new General(data, name || 'pool'); }
|
|
650
705
|
public get alias(): string { return this.data.alias; }
|
|
@@ -771,17 +826,6 @@ export class Options extends EqItem {
|
|
|
771
826
|
public set cleanerSolarDelay(val: boolean) { this.setDataVal('cleanerSolarDelay', val); }
|
|
772
827
|
public get cleanerSolarDelayTime(): number { return this.data.cleanerSolarDelayTime; }
|
|
773
828
|
public set cleanerSolarDelayTime(val: number) { this.setDataVal('cleanerSolarDelayTime', val); }
|
|
774
|
-
|
|
775
|
-
//public get airTempAdj(): number { return typeof this.data.airTempAdj === 'undefined' ? 0 : this.data.airTempAdj; }
|
|
776
|
-
//public set airTempAdj(val: number) { this.setDataVal('airTempAdj', val); }
|
|
777
|
-
//public get waterTempAdj1(): number { return typeof this.data.waterTempAdj1 === 'undefined' ? 0 : this.data.waterTempAdj1; }
|
|
778
|
-
//public set waterTempAdj1(val: number) { this.setDataVal('waterTempAdj1', val); }
|
|
779
|
-
//public get solarTempAdj1(): number { return typeof this.data.solarTempAdj1 === 'undefined' ? 0 : this.data.solarTempAdj1; }
|
|
780
|
-
//public set solarTempAdj1(val: number) { this.setDataVal('solarTempAdj1', val); }
|
|
781
|
-
//public get waterTempAdj2(): number { return typeof this.data.waterTempAdj2 === 'undefined' ? 0 : this.data.waterTempAdj2; }
|
|
782
|
-
//public set waterTempAdj2(val: number) { this.setDataVal('waterTempAdj2', val); }
|
|
783
|
-
//public get solarTempAdj2(): number { return typeof this.data.solarTempAdj2 === 'undefined' ? 0 : this.data.solarTempAdj2; }
|
|
784
|
-
//public set solarTempAdj2(val: number) { this.setDataVal('solarTempAd2', val); }
|
|
785
829
|
}
|
|
786
830
|
export class VacationOptions extends ChildEqItem {
|
|
787
831
|
public initData() {
|
|
@@ -874,11 +918,20 @@ export class ExpansionPanel extends EqItem {
|
|
|
874
918
|
export class Equipment extends EqItem {
|
|
875
919
|
public dataName = 'equipmentConfig';
|
|
876
920
|
public initData() {
|
|
921
|
+
if (typeof this.data.single === 'undefined') {
|
|
922
|
+
if (this.data.dual === true || this.data.shared === true) this.data.single = false;
|
|
923
|
+
else if (sys.controllerType !== ControllerType.IntelliTouch) this.data.single = true;
|
|
924
|
+
}
|
|
925
|
+
if (typeof this.data.softwareVersion === 'undefined') this.data.softwareVersion = '';
|
|
926
|
+
if (typeof this.data.bootloaderVersion === 'undefined') this.data.bootloaderVersion = '';
|
|
927
|
+
if (typeof this.data.maxChemDosers === 'undefined') this.data.maxChemDosers = 10;
|
|
877
928
|
}
|
|
878
929
|
public get name(): string { return this.data.name; }
|
|
879
930
|
public set name(val: string) { this.setDataVal('name', val); }
|
|
880
931
|
public get type(): number { return this.data.type; }
|
|
881
932
|
public set type(val: number) { this.setDataVal('type', val); }
|
|
933
|
+
public get single(): boolean { return this.data.single; }
|
|
934
|
+
public set single(val: boolean) { this.setDataVal('single', val); }
|
|
882
935
|
public get shared(): boolean { return this.data.shared; }
|
|
883
936
|
public set shared(val: boolean) { this.setDataVal('shared', val); }
|
|
884
937
|
public get dual(): boolean { return this.data.dual; }
|
|
@@ -913,6 +966,8 @@ export class Equipment extends EqItem {
|
|
|
913
966
|
public set maxIntelliBrites(val: number) { this.setDataVal('maxIntelliBrites', val); }
|
|
914
967
|
public get maxChemControllers(): number { return this.data.maxChemControllers; }
|
|
915
968
|
public set maxChemControllers(val: number) { this.setDataVal('maxChemControllers', val); }
|
|
969
|
+
public get maxChemDosers(): number { return this.data.maxChemDosers; }
|
|
970
|
+
public set maxChemDosers(val: number) { this.setDataVal('maxChemDosers', val); }
|
|
916
971
|
public get expansions(): ExpansionPanelCollection { return new ExpansionPanelCollection(this.data, "expansions"); }
|
|
917
972
|
public get modules(): ExpansionModuleCollection { return new ExpansionModuleCollection(this.data, "modules"); }
|
|
918
973
|
public get maxCustomNames(): number { return this.data.maxCustomNames || 10; }
|
|
@@ -1032,6 +1087,7 @@ export class Body extends EqItem {
|
|
|
1032
1087
|
public initData() {
|
|
1033
1088
|
if (typeof this.data.capacityUnits === 'undefined') this.data.capacityUnits = 1;
|
|
1034
1089
|
if (typeof this.data.showInDashboard === 'undefined') this.data.showInDashboard = true;
|
|
1090
|
+
if (typeof this.data.heatMode === 'undefined') this.data.heatMode = 0;
|
|
1035
1091
|
}
|
|
1036
1092
|
public get id(): number { return this.data.id; }
|
|
1037
1093
|
public set id(val: number) { this.data.id = val; }
|
|
@@ -1248,13 +1304,26 @@ export class Circuit extends EqItem implements ICircuit {
|
|
|
1248
1304
|
}
|
|
1249
1305
|
else return [];
|
|
1250
1306
|
}
|
|
1251
|
-
|
|
1252
1307
|
public static getIdName(id: number) {
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1308
|
+
let defName;
|
|
1309
|
+
// RKS: 07-19-22 I think this is some sort of artifact. The system should not be creating this data as a default because
|
|
1310
|
+
// the board itself should be coming up with these names.
|
|
1311
|
+
switch (sys.controllerType) {
|
|
1312
|
+
case ControllerType.SunTouch:
|
|
1313
|
+
break;
|
|
1314
|
+
default:
|
|
1315
|
+
if (sys.board.equipmentIds.circuitGroups.isInRange(id))
|
|
1316
|
+
defName = `Group ${id - sys.board.equipmentIds.circuitGroups.start + 1}`;
|
|
1317
|
+
else if (sys.board.equipmentIds.features.isInRange(id))
|
|
1318
|
+
defName = `Feature ${id - sys.board.equipmentIds.features.start + 1}`;
|
|
1319
|
+
else if (sys.board.equipmentIds.circuits.isInRange(id)) {
|
|
1320
|
+
if (id <= 1) defName = 'Spa';
|
|
1321
|
+
else if (id === 6) defName = 'Pool';
|
|
1322
|
+
else if (id < 6) defName = `Aux ${id - 1}`;
|
|
1323
|
+
else defName = `Aux ${id - 2}`;
|
|
1324
|
+
}
|
|
1325
|
+
break;
|
|
1326
|
+
}
|
|
1258
1327
|
return defName;
|
|
1259
1328
|
}
|
|
1260
1329
|
}
|
|
@@ -1329,12 +1398,23 @@ export class PumpCollection extends EqItemCollection<Pump> {
|
|
|
1329
1398
|
if (typeof add !== 'undefined' && add) return this.add(data || { id: this.data.length + 1, address: address });
|
|
1330
1399
|
return this.createItem(data || { id: this.data.length + 1, address: address });
|
|
1331
1400
|
}
|
|
1401
|
+
public getNextEquipmentId(range?: EquipmentIdRange, exclude?: number[]): number { return super.getNextEquipmentId(typeof range === 'undefined' ? sys.board.equipmentIds.pumps : range, exclude); }
|
|
1332
1402
|
}
|
|
1333
1403
|
export class Pump extends EqItem {
|
|
1334
1404
|
public dataName = 'pumpConfig';
|
|
1335
1405
|
public initData() {
|
|
1336
1406
|
if (typeof this.data.isVirtual !== 'undefined') delete this.data.isVirtual;
|
|
1337
1407
|
if (typeof this.data.portId === 'undefined') this.data.portId = 0;
|
|
1408
|
+
if (typeof this.data.body === 'number' && this.data.model === 2 && this.data.master === 1){
|
|
1409
|
+
// convert SS from body types to circuit arrays
|
|
1410
|
+
if (this.data.body === 255 || this.data.body === 0 && !this.data.circuits.find(el => el.circuit === 6)) {
|
|
1411
|
+
this.data.circuits.push({"circuit": 6, "relay": 1, "units": 0, "id": this.data.circuits.length + 1, "master": 1})
|
|
1412
|
+
}
|
|
1413
|
+
if (this.data.body === 255 || this.data.body === 101 && !this.data.circuits.find(el => el.circuit === 1)) {
|
|
1414
|
+
this.data.circuits.push({"circuit": 1, "relay": 1, "units": 0, "id": this.data.circuits.length + 1, "master": 1})
|
|
1415
|
+
}
|
|
1416
|
+
this.data.body = undefined;
|
|
1417
|
+
}
|
|
1338
1418
|
}
|
|
1339
1419
|
public get id(): number { return this.data.id; }
|
|
1340
1420
|
public set id(val: number) { this.setDataVal('id', val); }
|
|
@@ -1409,9 +1489,9 @@ export class Pump extends EqItem {
|
|
|
1409
1489
|
public deletePumpCircuit(pumpCircuitId: number) {
|
|
1410
1490
|
return sys.board.pumps.deletePumpCircuit(this, pumpCircuitId);
|
|
1411
1491
|
}
|
|
1412
|
-
public setType(pumpType: number) {
|
|
1413
|
-
|
|
1414
|
-
}
|
|
1492
|
+
//public setType(pumpType: number) {
|
|
1493
|
+
// sys.board.pumps.setType(this, pumpType);
|
|
1494
|
+
//}
|
|
1415
1495
|
public nextAvailablePumpCircuit(): number {
|
|
1416
1496
|
let pumpCircuits = this.circuits;
|
|
1417
1497
|
for (let i = 1; i <= 8; i++) {
|
|
@@ -1498,6 +1578,7 @@ export class Chlorinator extends EqItem {
|
|
|
1498
1578
|
if (typeof this.data.ignoreSaltReading === 'undefined') this.data.ignoreSaltReading = false;
|
|
1499
1579
|
if (typeof this.data.isVirtual !== 'undefined') delete this.data.isVirtual;
|
|
1500
1580
|
if (typeof this.data.portId === 'undefined') this.data.portId = 0;
|
|
1581
|
+
if (typeof this.data.saltTarget === 'undefined') this.data.saltTarget = 3400;
|
|
1501
1582
|
}
|
|
1502
1583
|
public get id(): number { return this.data.id; }
|
|
1503
1584
|
public set id(val: number) { this.setDataVal('id', val); }
|
|
@@ -1513,6 +1594,14 @@ export class Chlorinator extends EqItem {
|
|
|
1513
1594
|
public set spaSetpoint(val: number) { this.setDataVal('spaSetpoint', val); }
|
|
1514
1595
|
public get superChlorHours(): number { return this.data.superChlorHours; }
|
|
1515
1596
|
public set superChlorHours(val: number) { this.setDataVal('superChlorHours', val); }
|
|
1597
|
+
public get saltTarget(): number { return this.data.saltTarget; }
|
|
1598
|
+
public set saltTarget(val: number) {
|
|
1599
|
+
if (this.data.saltTarget !== val) {
|
|
1600
|
+
this.setDataVal('saltTarget', val);
|
|
1601
|
+
let cstate = state.chlorinators.getItemById(this.id, true);
|
|
1602
|
+
cstate.calcSaltRequired(this.saltTarget);
|
|
1603
|
+
}
|
|
1604
|
+
}
|
|
1516
1605
|
public get isActive(): boolean { return this.data.isActive; }
|
|
1517
1606
|
public set isActive(val: boolean) { this.setDataVal('isActive', val); }
|
|
1518
1607
|
public get address(): number { return this.data.address; }
|
|
@@ -1899,6 +1988,9 @@ export class CircuitGroupCollection extends EqItemCollection<CircuitGroup> {
|
|
|
1899
1988
|
}
|
|
1900
1989
|
export class CircuitGroup extends EqItem implements ICircuitGroup, ICircuit {
|
|
1901
1990
|
public dataName = 'circuitGroupConfig';
|
|
1991
|
+
public initData() {
|
|
1992
|
+
if (typeof this.data.showInFeatures === 'undefined') this.data.showInFeatures = true;
|
|
1993
|
+
}
|
|
1902
1994
|
public get id(): number { return this.data.id; }
|
|
1903
1995
|
public set id(val: number) { this.setDataVal('id', val); }
|
|
1904
1996
|
public get name(): string { return this.data.name; }
|
|
@@ -2003,7 +2095,7 @@ export class Security extends EqItem {
|
|
|
2003
2095
|
public get roles(): SecurityRoleCollection { return new SecurityRoleCollection(this.data, "roles"); }
|
|
2004
2096
|
}
|
|
2005
2097
|
export class ChemControllerCollection extends EqItemCollection<ChemController> {
|
|
2006
|
-
constructor(data: any, name?: string) { super(data, name || "
|
|
2098
|
+
constructor(data: any, name?: string) { super(data, name || "chemControllers"); }
|
|
2007
2099
|
public createItem(data: any): ChemController { return new ChemController(data); }
|
|
2008
2100
|
public getItemByAddress(address: number, add?: boolean, data?: any): ChemController {
|
|
2009
2101
|
let itm = this.find(elem => elem.address === address && typeof elem.address !== 'undefined');
|
|
@@ -2027,6 +2119,11 @@ export class ChemControllerCollection extends EqItemCollection<ChemController> {
|
|
|
2027
2119
|
return id + 1;
|
|
2028
2120
|
}
|
|
2029
2121
|
}
|
|
2122
|
+
export class ChemDoserCollection extends EqItemCollection<ChemDoser> {
|
|
2123
|
+
constructor(data: any, name?: string) { super(data, name || "chemDosers"); }
|
|
2124
|
+
public createItem(data: any): ChemDoser { return new ChemDoser(data); }
|
|
2125
|
+
}
|
|
2126
|
+
|
|
2030
2127
|
export class FlowSensor extends ChildEqItem {
|
|
2031
2128
|
public dataName = 'flowSensorConfig';
|
|
2032
2129
|
public initData() {
|
|
@@ -2048,7 +2145,9 @@ export class FlowSensor extends ChildEqItem {
|
|
|
2048
2145
|
return sensor;
|
|
2049
2146
|
}
|
|
2050
2147
|
}
|
|
2051
|
-
export
|
|
2148
|
+
export interface IChemController {
|
|
2149
|
+
}
|
|
2150
|
+
export class ChemController extends EqItem implements IChemController {
|
|
2052
2151
|
public initData() {
|
|
2053
2152
|
//var chemController = {
|
|
2054
2153
|
// id: 'number', // Id of the controller
|
|
@@ -2184,6 +2283,68 @@ export class ChemController extends EqItem {
|
|
|
2184
2283
|
// ORP
|
|
2185
2284
|
// 1. Chlorinator Comms Lost.
|
|
2186
2285
|
}
|
|
2286
|
+
export class ChemDoser extends EqItem implements IChemical {
|
|
2287
|
+
public dataName = 'chemDoserConfig';
|
|
2288
|
+
public initData() {
|
|
2289
|
+
if (typeof this.data.pump === 'undefined') this.data.pump = {};
|
|
2290
|
+
if (typeof this.data.tank === 'undefined') this.data.tank = {};
|
|
2291
|
+
if (typeof this.data.flowSensor === 'undefined') this.data.flowSensor = {};
|
|
2292
|
+
if (typeof this.data.enabled === 'undefined') this.data.enabled = true;
|
|
2293
|
+
if (typeof this.data.dosingMethod === 'undefined') this.data.dosingMethod = 0;
|
|
2294
|
+
if (typeof this.data.startDelay === 'undefined') this.data.startDelay = 1.5;
|
|
2295
|
+
if (typeof this.data.maxDailyVolume === 'undefined') this.data.maxDailyVolume = 500;
|
|
2296
|
+
if (typeof this.data.disableOnFreeze === 'undefined') this.data.disableOnFreeze = true;
|
|
2297
|
+
if (typeof this.data.disableChlorinator === 'undefined') this.data.disableChlorinator = true;
|
|
2298
|
+
if (typeof this.mixingTime === 'undefined') this.data.mixingTime = 3600;
|
|
2299
|
+
if (typeof this.data.setpoint === 'undefined') this.data.setpoint = 100;
|
|
2300
|
+
if (typeof this.data.type === 'undefined') this.data.type = 0;
|
|
2301
|
+
super.initData();
|
|
2302
|
+
}
|
|
2303
|
+
public get id(): number { return this.data.id; }
|
|
2304
|
+
public set id(val: number) { this.setDataVal('id', val); }
|
|
2305
|
+
public get name(): string { return this.data.name; }
|
|
2306
|
+
public set name(val: string) { this.setDataVal('name', val); }
|
|
2307
|
+
public get setpoint(): number { return this.data.setpoint; }
|
|
2308
|
+
public set setpoint(val: number) { this.setDataVal('setpoint', val); }
|
|
2309
|
+
public get body(): number | any { return this.data.body; }
|
|
2310
|
+
public set body(val: number | any) { this.setDataVal('body', sys.board.valueMaps.bodies.encode(val)); }
|
|
2311
|
+
public get isActive(): boolean { return this.data.isActive; }
|
|
2312
|
+
public set isActive(val: boolean) { this.setDataVal('isActive', val); }
|
|
2313
|
+
public get chemType(): string { return this.data.chemType; }
|
|
2314
|
+
public get type(): number | any { return this.data.type; }
|
|
2315
|
+
public set type(val: number | any) {
|
|
2316
|
+
this.setDataVal('type', sys.board.valueMaps.chemDoserTypes.encode(val));
|
|
2317
|
+
let t = sys.board.valueMaps.chemDoserTypes.findItem(val) || { val: 0, name: 'acid', desc: 'Acid' };
|
|
2318
|
+
this.setDataVal('chemType', t.desc);
|
|
2319
|
+
}
|
|
2320
|
+
public get enabled(): boolean { return utils.makeBool(this.data.enabled); }
|
|
2321
|
+
public set enabled(val: boolean) { this.setDataVal('enabled', val); }
|
|
2322
|
+
public get disableChlorinator(): boolean { return utils.makeBool(this.data.disableChlorinator); }
|
|
2323
|
+
public set disableChlorinator(val: boolean) { this.setDataVal('disableChlorinator', val); }
|
|
2324
|
+
public get disableOnFreeze(): boolean { return utils.makeBool(this.data.disableOnFreeze); }
|
|
2325
|
+
public set disableOnFreeze(val: boolean) { this.setDataVal('disableOnFreeze', val); }
|
|
2326
|
+
public get dosingVolume(): number { return this.data.dosingVolume; }
|
|
2327
|
+
public set dosingVolume(val: number) { this.setDataVal('dosingVolume', val); }
|
|
2328
|
+
public get mixingTime(): number { return this.data.mixingTime; }
|
|
2329
|
+
public set mixingTime(val: number) { this.setDataVal('mixingTime', val); }
|
|
2330
|
+
public get maxDailyVolume(): number { return this.data.maxDailyVolume; }
|
|
2331
|
+
public set maxDailyVolume(val: number) { this.setDataVal('maxDailyVolume', val); }
|
|
2332
|
+
public get dosingMethod(): number | any { return this.data.dosingMethod; }
|
|
2333
|
+
public set dosingMethod(val: number | any) { this.setDataVal('dosingMethod', sys.board.valueMaps.chemDosingMethods.encode(val)); }
|
|
2334
|
+
public get startDelay(): number { return this.data.startDelay; }
|
|
2335
|
+
public set startDelay(val: number) { this.setDataVal('startDelay', val); }
|
|
2336
|
+
public get flowSensor(): ChemFlowSensor { return new ChemFlowSensor(this.data, 'flowSensor', this); }
|
|
2337
|
+
public get flowOnlyMixing(): boolean { return utils.makeBool(this.data.flowOnlyMixing); }
|
|
2338
|
+
public set flowOnlyMixing(val: boolean) { this.setDataVal('flowOnlyMixing', val); }
|
|
2339
|
+
public get pump(): ChemicalPump { return new ChemicalPump(this.data, 'pump', this); }
|
|
2340
|
+
public get tank(): ChemicalTank { return new ChemicalTank(this.data, 'tank', this); }
|
|
2341
|
+
public getExtended() {
|
|
2342
|
+
let chem = this.get(true);
|
|
2343
|
+
chem.tank = this.tank.getExtended();
|
|
2344
|
+
chem.pump = this.pump.getExtended();
|
|
2345
|
+
return chem;
|
|
2346
|
+
}
|
|
2347
|
+
}
|
|
2187
2348
|
export class ChemFlowSensor extends FlowSensor {
|
|
2188
2349
|
public dataName = 'flowSensorConfig';
|
|
2189
2350
|
public initData() {
|
|
@@ -2199,7 +2360,13 @@ export class ChemFlowSensor extends FlowSensor {
|
|
|
2199
2360
|
return sensor;
|
|
2200
2361
|
}
|
|
2201
2362
|
}
|
|
2202
|
-
export
|
|
2363
|
+
export interface IChemical {
|
|
2364
|
+
dosingMethod: number;
|
|
2365
|
+
startDelay: number;
|
|
2366
|
+
maxDosingTime?: number;
|
|
2367
|
+
maxDosingVolume?: number;
|
|
2368
|
+
}
|
|
2369
|
+
export class Chemical extends ChildEqItem implements IChemical {
|
|
2203
2370
|
public dataName = 'chemicalConfig';
|
|
2204
2371
|
public initData() {
|
|
2205
2372
|
if (typeof this.data.pump === 'undefined') this.data.pump = {};
|
|
@@ -2482,4 +2649,21 @@ export class AlarmSetting extends ChildEqItem {
|
|
|
2482
2649
|
public get high(): number { return this.data.high; }
|
|
2483
2650
|
public set high(val: number) { this.setDataVal('high', val); }
|
|
2484
2651
|
}
|
|
2652
|
+
export class Screenlogic extends EqItem {
|
|
2653
|
+
ctor(data: any, name?: any): General { return new General(data, name || 'pool'); }
|
|
2654
|
+
public get enabled(): boolean { return this.data.enabled; }
|
|
2655
|
+
public set enabled(val: boolean) { this.setDataVal('enabled', val); }
|
|
2656
|
+
public get type(): 'local'|'remote' { return this.data.type; }
|
|
2657
|
+
public set type(val: 'local'|'remote') { this.setDataVal('type', val); }
|
|
2658
|
+
public get systemName(): string { return this.data.systemName; }
|
|
2659
|
+
public set systemName(val: string) { this.setDataVal('systemName', val); }
|
|
2660
|
+
public get password(): string { return this.data.password; }
|
|
2661
|
+
public set password(val: string) { this.setDataVal('password', val); }
|
|
2662
|
+
|
|
2663
|
+
public clear(master: number = -1) {
|
|
2664
|
+
if (master === -1)
|
|
2665
|
+
super.clear();
|
|
2666
|
+
}
|
|
2667
|
+
|
|
2668
|
+
}
|
|
2485
2669
|
export let sys = new PoolSystem();
|
package/controller/Errors.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* nodejs-poolController. An application to control pool equipment.
|
|
2
|
-
Copyright (C) 2016, 2017, 2018, 2019, 2020
|
|
2
|
+
Copyright (C) 2016, 2017, 2018, 2019, 2020, 2021, 2022.
|
|
3
|
+
Russell Goldin, tagyoureit. russ.goldin@gmail.com
|
|
3
4
|
|
|
4
5
|
This program is free software: you can redistribute it and/or modify
|
|
5
6
|
it under the terms of the GNU Affero General Public License as
|
package/controller/Lockouts.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* nodejs-poolController. An application to control pool equipment.
|
|
2
|
-
Copyright (C) 2016, 2017, 2018, 2019, 2020
|
|
2
|
+
Copyright (C) 2016, 2017, 2018, 2019, 2020, 2021, 2022.
|
|
3
|
+
Russell Goldin, tagyoureit. russ.goldin@gmail.com
|
|
3
4
|
|
|
4
5
|
This program is free software: you can redistribute it and/or modify
|
|
5
6
|
it under the terms of the GNU Affero General Public License as
|
|
@@ -133,6 +134,7 @@ export class ManualPriorityDelay extends EquipmentDelay {
|
|
|
133
134
|
if (typeof this._delayTimer !== 'undefined') clearTimeout(this._delayTimer);
|
|
134
135
|
logger.info(`Manual Operation Priority cancelled for ${this.circuitState.name}`);
|
|
135
136
|
this._delayTimer = undefined;
|
|
137
|
+
this.circuitState.manualPriorityActive = false;
|
|
136
138
|
delayMgr.deleteDelay(this.id);
|
|
137
139
|
}
|
|
138
140
|
public clearDelay() {
|
|
@@ -197,6 +199,13 @@ export class HeaterStartupDelay extends EquipmentDelay {
|
|
|
197
199
|
this._delayTimer = undefined;
|
|
198
200
|
delayMgr.deleteDelay(this.id);
|
|
199
201
|
}
|
|
202
|
+
public clearDelay() {
|
|
203
|
+
this.heaterState.startupDelay = false;
|
|
204
|
+
if (typeof this._delayTimer !== 'undefined') clearTimeout(this._delayTimer);
|
|
205
|
+
logger.info(`Heater Startup delay cancelled for ${this.heaterState.name}`);
|
|
206
|
+
this._delayTimer = undefined;
|
|
207
|
+
delayMgr.deleteDelay(this.id);
|
|
208
|
+
}
|
|
200
209
|
}
|
|
201
210
|
export class HeaterCooldownDelay extends EquipmentDelay {
|
|
202
211
|
public constructor(bsoff: BodyTempState, bson?: BodyTempState, delay?: number) {
|
|
@@ -267,7 +276,24 @@ export class HeaterCooldownDelay extends EquipmentDelay {
|
|
|
267
276
|
delayMgr.deleteDelay(this.id);
|
|
268
277
|
state.emitEquipmentChanges();
|
|
269
278
|
}
|
|
270
|
-
|
|
279
|
+
public clearDelay() {
|
|
280
|
+
let cstateOff = state.circuits.getItemById(this.bodyStateOff.circuit);
|
|
281
|
+
cstateOff.stopDelay = false;
|
|
282
|
+
(async () => {
|
|
283
|
+
await sys.board.circuits.setCircuitStateAsync(cstateOff.id, false);
|
|
284
|
+
if (typeof this.bodyStateOn !== 'undefined') {
|
|
285
|
+
this.bodyStateOn.startDelay = state.circuits.getItemById(this.bodyStateOn.circuit).startDelay = false;
|
|
286
|
+
await sys.board.circuits.setCircuitStateAsync(this.bodyStateOn.circuit, true);
|
|
287
|
+
}
|
|
288
|
+
})();
|
|
289
|
+
this.bodyStateOff.stopDelay = this.bodyStateOff.heaterCooldownDelay = false;
|
|
290
|
+
this.bodyStateOff.heatStatus = sys.board.valueMaps.heatStatus.getValue('off');
|
|
291
|
+
if (typeof this._delayTimer !== 'undefined') clearTimeout(this._delayTimer);
|
|
292
|
+
logger.info(`Heater Cooldown delay cleared for ${this.bodyStateOff.name}`);
|
|
293
|
+
this._delayTimer = undefined;
|
|
294
|
+
delayMgr.deleteDelay(this.id);
|
|
295
|
+
state.emitEquipmentChanges();
|
|
296
|
+
}
|
|
271
297
|
}
|
|
272
298
|
interface ICleanerDelay {
|
|
273
299
|
cleanerState: ICircuitState,
|
|
@@ -351,6 +377,12 @@ export class DelayManager extends Array<EquipmentDelay> {
|
|
|
351
377
|
let del = this.find(x => x.id === id);
|
|
352
378
|
if (typeof del !== 'undefined') del.cancelDelay();
|
|
353
379
|
}
|
|
380
|
+
public clearAllDelays() {
|
|
381
|
+
for (let i = this.length - 1; i >= 0; i--) {
|
|
382
|
+
let del = this[i];
|
|
383
|
+
del.clearDelay();
|
|
384
|
+
}
|
|
385
|
+
}
|
|
354
386
|
public setManualPriorityDelay(cs: ICircuitState) {
|
|
355
387
|
let cds = this.filter(x => x.type === 'manualOperationPriorityDelay');
|
|
356
388
|
for (let i = 0; i < cds.length; i++) {
|