nodejs-poolcontroller 7.7.0 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +224 -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 +45 -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
|
}
|
|
@@ -1335,6 +1404,16 @@ export class Pump extends EqItem {
|
|
|
1335
1404
|
public initData() {
|
|
1336
1405
|
if (typeof this.data.isVirtual !== 'undefined') delete this.data.isVirtual;
|
|
1337
1406
|
if (typeof this.data.portId === 'undefined') this.data.portId = 0;
|
|
1407
|
+
if (typeof this.data.body === 'number' && this.data.model === 2 && this.data.master === 1){
|
|
1408
|
+
// convert SS from body types to circuit arrays
|
|
1409
|
+
if (this.data.body === 255 || this.data.body === 0 && !this.data.circuits.find(el => el.circuit === 6)) {
|
|
1410
|
+
this.data.circuits.push({"circuit": 6, "relay": 1, "units": 0, "id": this.data.circuits.length + 1, "master": 1})
|
|
1411
|
+
}
|
|
1412
|
+
if (this.data.body === 255 || this.data.body === 101 && !this.data.circuits.find(el => el.circuit === 1)) {
|
|
1413
|
+
this.data.circuits.push({"circuit": 1, "relay": 1, "units": 0, "id": this.data.circuits.length + 1, "master": 1})
|
|
1414
|
+
}
|
|
1415
|
+
this.data.body = undefined;
|
|
1416
|
+
}
|
|
1338
1417
|
}
|
|
1339
1418
|
public get id(): number { return this.data.id; }
|
|
1340
1419
|
public set id(val: number) { this.setDataVal('id', val); }
|
|
@@ -1409,9 +1488,9 @@ export class Pump extends EqItem {
|
|
|
1409
1488
|
public deletePumpCircuit(pumpCircuitId: number) {
|
|
1410
1489
|
return sys.board.pumps.deletePumpCircuit(this, pumpCircuitId);
|
|
1411
1490
|
}
|
|
1412
|
-
public setType(pumpType: number) {
|
|
1413
|
-
|
|
1414
|
-
}
|
|
1491
|
+
//public setType(pumpType: number) {
|
|
1492
|
+
// sys.board.pumps.setType(this, pumpType);
|
|
1493
|
+
//}
|
|
1415
1494
|
public nextAvailablePumpCircuit(): number {
|
|
1416
1495
|
let pumpCircuits = this.circuits;
|
|
1417
1496
|
for (let i = 1; i <= 8; i++) {
|
|
@@ -1498,6 +1577,7 @@ export class Chlorinator extends EqItem {
|
|
|
1498
1577
|
if (typeof this.data.ignoreSaltReading === 'undefined') this.data.ignoreSaltReading = false;
|
|
1499
1578
|
if (typeof this.data.isVirtual !== 'undefined') delete this.data.isVirtual;
|
|
1500
1579
|
if (typeof this.data.portId === 'undefined') this.data.portId = 0;
|
|
1580
|
+
if (typeof this.data.saltTarget === 'undefined') this.data.saltTarget = 3400;
|
|
1501
1581
|
}
|
|
1502
1582
|
public get id(): number { return this.data.id; }
|
|
1503
1583
|
public set id(val: number) { this.setDataVal('id', val); }
|
|
@@ -1513,6 +1593,14 @@ export class Chlorinator extends EqItem {
|
|
|
1513
1593
|
public set spaSetpoint(val: number) { this.setDataVal('spaSetpoint', val); }
|
|
1514
1594
|
public get superChlorHours(): number { return this.data.superChlorHours; }
|
|
1515
1595
|
public set superChlorHours(val: number) { this.setDataVal('superChlorHours', val); }
|
|
1596
|
+
public get saltTarget(): number { return this.data.saltTarget; }
|
|
1597
|
+
public set saltTarget(val: number) {
|
|
1598
|
+
if (this.data.saltTarget !== val) {
|
|
1599
|
+
this.setDataVal('saltTarget', val);
|
|
1600
|
+
let cstate = state.chlorinators.getItemById(this.id, true);
|
|
1601
|
+
cstate.calcSaltRequired(this.saltTarget);
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1516
1604
|
public get isActive(): boolean { return this.data.isActive; }
|
|
1517
1605
|
public set isActive(val: boolean) { this.setDataVal('isActive', val); }
|
|
1518
1606
|
public get address(): number { return this.data.address; }
|
|
@@ -1899,6 +1987,9 @@ export class CircuitGroupCollection extends EqItemCollection<CircuitGroup> {
|
|
|
1899
1987
|
}
|
|
1900
1988
|
export class CircuitGroup extends EqItem implements ICircuitGroup, ICircuit {
|
|
1901
1989
|
public dataName = 'circuitGroupConfig';
|
|
1990
|
+
public initData() {
|
|
1991
|
+
if (typeof this.data.showInFeatures === 'undefined') this.data.showInFeatures = true;
|
|
1992
|
+
}
|
|
1902
1993
|
public get id(): number { return this.data.id; }
|
|
1903
1994
|
public set id(val: number) { this.setDataVal('id', val); }
|
|
1904
1995
|
public get name(): string { return this.data.name; }
|
|
@@ -2003,7 +2094,7 @@ export class Security extends EqItem {
|
|
|
2003
2094
|
public get roles(): SecurityRoleCollection { return new SecurityRoleCollection(this.data, "roles"); }
|
|
2004
2095
|
}
|
|
2005
2096
|
export class ChemControllerCollection extends EqItemCollection<ChemController> {
|
|
2006
|
-
constructor(data: any, name?: string) { super(data, name || "
|
|
2097
|
+
constructor(data: any, name?: string) { super(data, name || "chemControllers"); }
|
|
2007
2098
|
public createItem(data: any): ChemController { return new ChemController(data); }
|
|
2008
2099
|
public getItemByAddress(address: number, add?: boolean, data?: any): ChemController {
|
|
2009
2100
|
let itm = this.find(elem => elem.address === address && typeof elem.address !== 'undefined');
|
|
@@ -2027,6 +2118,11 @@ export class ChemControllerCollection extends EqItemCollection<ChemController> {
|
|
|
2027
2118
|
return id + 1;
|
|
2028
2119
|
}
|
|
2029
2120
|
}
|
|
2121
|
+
export class ChemDoserCollection extends EqItemCollection<ChemDoser> {
|
|
2122
|
+
constructor(data: any, name?: string) { super(data, name || "chemDosers"); }
|
|
2123
|
+
public createItem(data: any): ChemDoser { return new ChemDoser(data); }
|
|
2124
|
+
}
|
|
2125
|
+
|
|
2030
2126
|
export class FlowSensor extends ChildEqItem {
|
|
2031
2127
|
public dataName = 'flowSensorConfig';
|
|
2032
2128
|
public initData() {
|
|
@@ -2048,7 +2144,9 @@ export class FlowSensor extends ChildEqItem {
|
|
|
2048
2144
|
return sensor;
|
|
2049
2145
|
}
|
|
2050
2146
|
}
|
|
2051
|
-
export
|
|
2147
|
+
export interface IChemController {
|
|
2148
|
+
}
|
|
2149
|
+
export class ChemController extends EqItem implements IChemController {
|
|
2052
2150
|
public initData() {
|
|
2053
2151
|
//var chemController = {
|
|
2054
2152
|
// id: 'number', // Id of the controller
|
|
@@ -2184,6 +2282,68 @@ export class ChemController extends EqItem {
|
|
|
2184
2282
|
// ORP
|
|
2185
2283
|
// 1. Chlorinator Comms Lost.
|
|
2186
2284
|
}
|
|
2285
|
+
export class ChemDoser extends EqItem implements IChemical {
|
|
2286
|
+
public dataName = 'chemDoserConfig';
|
|
2287
|
+
public initData() {
|
|
2288
|
+
if (typeof this.data.pump === 'undefined') this.data.pump = {};
|
|
2289
|
+
if (typeof this.data.tank === 'undefined') this.data.tank = {};
|
|
2290
|
+
if (typeof this.data.flowSensor === 'undefined') this.data.flowSensor = {};
|
|
2291
|
+
if (typeof this.data.enabled === 'undefined') this.data.enabled = true;
|
|
2292
|
+
if (typeof this.data.dosingMethod === 'undefined') this.data.dosingMethod = 0;
|
|
2293
|
+
if (typeof this.data.startDelay === 'undefined') this.data.startDelay = 1.5;
|
|
2294
|
+
if (typeof this.data.maxDailyVolume === 'undefined') this.data.maxDailyVolume = 500;
|
|
2295
|
+
if (typeof this.data.disableOnFreeze === 'undefined') this.data.disableOnFreeze = true;
|
|
2296
|
+
if (typeof this.data.disableChlorinator === 'undefined') this.data.disableChlorinator = true;
|
|
2297
|
+
if (typeof this.mixingTime === 'undefined') this.data.mixingTime = 3600;
|
|
2298
|
+
if (typeof this.data.setpoint === 'undefined') this.data.setpoint = 100;
|
|
2299
|
+
if (typeof this.data.type === 'undefined') this.data.type = 0;
|
|
2300
|
+
super.initData();
|
|
2301
|
+
}
|
|
2302
|
+
public get id(): number { return this.data.id; }
|
|
2303
|
+
public set id(val: number) { this.setDataVal('id', val); }
|
|
2304
|
+
public get name(): string { return this.data.name; }
|
|
2305
|
+
public set name(val: string) { this.setDataVal('name', val); }
|
|
2306
|
+
public get setpoint(): number { return this.data.setpoint; }
|
|
2307
|
+
public set setpoint(val: number) { this.setDataVal('setpoint', val); }
|
|
2308
|
+
public get body(): number | any { return this.data.body; }
|
|
2309
|
+
public set body(val: number | any) { this.setDataVal('body', sys.board.valueMaps.bodies.encode(val)); }
|
|
2310
|
+
public get isActive(): boolean { return this.data.isActive; }
|
|
2311
|
+
public set isActive(val: boolean) { this.setDataVal('isActive', val); }
|
|
2312
|
+
public get chemType(): string { return this.data.chemType; }
|
|
2313
|
+
public get type(): number | any { return this.data.type; }
|
|
2314
|
+
public set type(val: number | any) {
|
|
2315
|
+
this.setDataVal('type', sys.board.valueMaps.chemDoserTypes.encode(val));
|
|
2316
|
+
let t = sys.board.valueMaps.chemDoserTypes.findItem(val) || { val: 0, name: 'acid', desc: 'Acid' };
|
|
2317
|
+
this.setDataVal('chemType', t.desc);
|
|
2318
|
+
}
|
|
2319
|
+
public get enabled(): boolean { return utils.makeBool(this.data.enabled); }
|
|
2320
|
+
public set enabled(val: boolean) { this.setDataVal('enabled', val); }
|
|
2321
|
+
public get disableChlorinator(): boolean { return utils.makeBool(this.data.disableChlorinator); }
|
|
2322
|
+
public set disableChlorinator(val: boolean) { this.setDataVal('disableChlorinator', val); }
|
|
2323
|
+
public get disableOnFreeze(): boolean { return utils.makeBool(this.data.disableOnFreeze); }
|
|
2324
|
+
public set disableOnFreeze(val: boolean) { this.setDataVal('disableOnFreeze', val); }
|
|
2325
|
+
public get dosingVolume(): number { return this.data.dosingVolume; }
|
|
2326
|
+
public set dosingVolume(val: number) { this.setDataVal('dosingVolume', val); }
|
|
2327
|
+
public get mixingTime(): number { return this.data.mixingTime; }
|
|
2328
|
+
public set mixingTime(val: number) { this.setDataVal('mixingTime', val); }
|
|
2329
|
+
public get maxDailyVolume(): number { return this.data.maxDailyVolume; }
|
|
2330
|
+
public set maxDailyVolume(val: number) { this.setDataVal('maxDailyVolume', val); }
|
|
2331
|
+
public get dosingMethod(): number | any { return this.data.dosingMethod; }
|
|
2332
|
+
public set dosingMethod(val: number | any) { this.setDataVal('dosingMethod', sys.board.valueMaps.chemDosingMethods.encode(val)); }
|
|
2333
|
+
public get startDelay(): number { return this.data.startDelay; }
|
|
2334
|
+
public set startDelay(val: number) { this.setDataVal('startDelay', val); }
|
|
2335
|
+
public get flowSensor(): ChemFlowSensor { return new ChemFlowSensor(this.data, 'flowSensor', this); }
|
|
2336
|
+
public get flowOnlyMixing(): boolean { return utils.makeBool(this.data.flowOnlyMixing); }
|
|
2337
|
+
public set flowOnlyMixing(val: boolean) { this.setDataVal('flowOnlyMixing', val); }
|
|
2338
|
+
public get pump(): ChemicalPump { return new ChemicalPump(this.data, 'pump', this); }
|
|
2339
|
+
public get tank(): ChemicalTank { return new ChemicalTank(this.data, 'tank', this); }
|
|
2340
|
+
public getExtended() {
|
|
2341
|
+
let chem = this.get(true);
|
|
2342
|
+
chem.tank = this.tank.getExtended();
|
|
2343
|
+
chem.pump = this.pump.getExtended();
|
|
2344
|
+
return chem;
|
|
2345
|
+
}
|
|
2346
|
+
}
|
|
2187
2347
|
export class ChemFlowSensor extends FlowSensor {
|
|
2188
2348
|
public dataName = 'flowSensorConfig';
|
|
2189
2349
|
public initData() {
|
|
@@ -2199,7 +2359,13 @@ export class ChemFlowSensor extends FlowSensor {
|
|
|
2199
2359
|
return sensor;
|
|
2200
2360
|
}
|
|
2201
2361
|
}
|
|
2202
|
-
export
|
|
2362
|
+
export interface IChemical {
|
|
2363
|
+
dosingMethod: number;
|
|
2364
|
+
startDelay: number;
|
|
2365
|
+
maxDosingTime?: number;
|
|
2366
|
+
maxDosingVolume?: number;
|
|
2367
|
+
}
|
|
2368
|
+
export class Chemical extends ChildEqItem implements IChemical {
|
|
2203
2369
|
public dataName = 'chemicalConfig';
|
|
2204
2370
|
public initData() {
|
|
2205
2371
|
if (typeof this.data.pump === 'undefined') this.data.pump = {};
|
|
@@ -2482,4 +2648,21 @@ export class AlarmSetting extends ChildEqItem {
|
|
|
2482
2648
|
public get high(): number { return this.data.high; }
|
|
2483
2649
|
public set high(val: number) { this.setDataVal('high', val); }
|
|
2484
2650
|
}
|
|
2651
|
+
export class Screenlogic extends EqItem {
|
|
2652
|
+
ctor(data: any, name?: any): General { return new General(data, name || 'pool'); }
|
|
2653
|
+
public get enabled(): boolean { return this.data.enabled; }
|
|
2654
|
+
public set enabled(val: boolean) { this.setDataVal('enabled', val); }
|
|
2655
|
+
public get type(): 'local'|'remote' { return this.data.type; }
|
|
2656
|
+
public set type(val: 'local'|'remote') { this.setDataVal('type', val); }
|
|
2657
|
+
public get systemName(): string { return this.data.systemName; }
|
|
2658
|
+
public set systemName(val: string) { this.setDataVal('systemName', val); }
|
|
2659
|
+
public get password(): string { return this.data.password; }
|
|
2660
|
+
public set password(val: string) { this.setDataVal('password', val); }
|
|
2661
|
+
|
|
2662
|
+
public clear(master: number = -1) {
|
|
2663
|
+
if (master === -1)
|
|
2664
|
+
super.clear();
|
|
2665
|
+
}
|
|
2666
|
+
|
|
2667
|
+
}
|
|
2485
2668
|
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++) {
|