nodejs-poolcontroller 7.2.0 → 7.5.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/.github/ISSUE_TEMPLATE/bug_report.md +1 -1
- package/Changelog +13 -0
- package/Dockerfile +1 -0
- package/README.md +5 -5
- package/app.ts +11 -0
- package/config/Config.ts +3 -0
- package/config/VersionCheck.ts +8 -4
- package/controller/Constants.ts +165 -9
- package/controller/Equipment.ts +186 -65
- package/controller/Errors.ts +22 -1
- package/controller/State.ts +273 -57
- package/controller/boards/EasyTouchBoard.ts +194 -95
- package/controller/boards/IntelliCenterBoard.ts +115 -42
- package/controller/boards/IntelliTouchBoard.ts +104 -30
- package/controller/boards/NixieBoard.ts +155 -53
- package/controller/boards/SystemBoard.ts +1529 -514
- package/controller/comms/Comms.ts +219 -42
- package/controller/comms/messages/Messages.ts +16 -4
- package/controller/comms/messages/config/ChlorinatorMessage.ts +13 -3
- package/controller/comms/messages/config/CircuitGroupMessage.ts +6 -0
- package/controller/comms/messages/config/CircuitMessage.ts +1 -1
- package/controller/comms/messages/config/CoverMessage.ts +1 -0
- package/controller/comms/messages/config/EquipmentMessage.ts +4 -0
- package/controller/comms/messages/config/ExternalMessage.ts +43 -25
- package/controller/comms/messages/config/FeatureMessage.ts +8 -1
- package/controller/comms/messages/config/GeneralMessage.ts +8 -0
- package/controller/comms/messages/config/HeaterMessage.ts +15 -9
- package/controller/comms/messages/config/IntellichemMessage.ts +4 -1
- package/controller/comms/messages/config/OptionsMessage.ts +13 -1
- package/controller/comms/messages/config/PumpMessage.ts +4 -20
- package/controller/comms/messages/config/RemoteMessage.ts +4 -0
- package/controller/comms/messages/config/ScheduleMessage.ts +11 -0
- package/controller/comms/messages/config/SecurityMessage.ts +1 -0
- package/controller/comms/messages/config/ValveMessage.ts +12 -2
- package/controller/comms/messages/status/ChlorinatorStateMessage.ts +14 -6
- package/controller/comms/messages/status/EquipmentStateMessage.ts +78 -24
- package/controller/comms/messages/status/HeaterStateMessage.ts +25 -5
- package/controller/comms/messages/status/IntelliChemStateMessage.ts +55 -26
- package/controller/nixie/Nixie.ts +18 -16
- package/controller/nixie/NixieEquipment.ts +6 -6
- package/controller/nixie/bodies/Body.ts +7 -4
- package/controller/nixie/bodies/Filter.ts +7 -4
- package/controller/nixie/chemistry/ChemController.ts +800 -283
- package/controller/nixie/chemistry/Chlorinator.ts +22 -14
- package/controller/nixie/circuits/Circuit.ts +42 -7
- package/controller/nixie/heaters/Heater.ts +303 -30
- package/controller/nixie/pumps/Pump.ts +57 -30
- package/controller/nixie/schedules/Schedule.ts +10 -7
- package/controller/nixie/valves/Valve.ts +7 -5
- package/defaultConfig.json +32 -1
- package/issue_template.md +1 -1
- package/logger/DataLogger.ts +37 -22
- package/package.json +20 -18
- package/web/Server.ts +529 -31
- package/web/bindings/influxDB.json +157 -5
- package/web/bindings/mqtt.json +112 -13
- package/web/bindings/mqttAlt.json +109 -11
- package/web/interfaces/baseInterface.ts +2 -1
- package/web/interfaces/httpInterface.ts +2 -0
- package/web/interfaces/influxInterface.ts +103 -54
- package/web/interfaces/mqttInterface.ts +16 -5
- package/web/services/config/Config.ts +179 -43
- package/web/services/state/State.ts +51 -5
- package/web/services/state/StateSocket.ts +19 -2
|
@@ -50,7 +50,8 @@ export class NixieBoard extends SystemBoard {
|
|
|
50
50
|
[10, { name: 'colorcascade', desc: 'ColorCascade', isLight: true }],
|
|
51
51
|
[11, { name: 'mastercleaner2', desc: 'Master Cleaner 2' }],
|
|
52
52
|
[12, { name: 'pool', desc: 'Pool', hasHeatSource: true }],
|
|
53
|
-
[13, { name: 'spa', desc: 'Spa', hasHeatSource: true }]
|
|
53
|
+
[13, { name: 'spa', desc: 'Spa', hasHeatSource: true }],
|
|
54
|
+
[14, { name: 'colorlogic', desc: 'ColorLogic', isLight:true }]
|
|
54
55
|
]);
|
|
55
56
|
this.valueMaps.pumpTypes = new byteValueMap([
|
|
56
57
|
[1, { name: 'ss', desc: 'Single Speed', maxCircuits: 0, hasAddress: false, hasBody: true, maxRelays: 1 }],
|
|
@@ -81,6 +82,20 @@ export class NixieBoard extends SystemBoard {
|
|
|
81
82
|
[2, { name: 'off', desc: 'Off' }],
|
|
82
83
|
[3, { name: 'ignore', desc: 'Ignore' }]
|
|
83
84
|
]);
|
|
85
|
+
this.valueMaps.chlorinatorModel = new byteValueMap([
|
|
86
|
+
[0, { name: 'unknown', desc: 'unknown', capacity: 0, chlorinePerDay: 0, chlorinePerSec: 0 }],
|
|
87
|
+
[1, { name: 'intellichlor--15', desc: 'IntelliChlor IC15', capacity: 15000, chlorinePerDay: 0.60, chlorinePerSec: 0.60 / 86400 }],
|
|
88
|
+
[2, { name: 'intellichlor--20', desc: 'IntelliChlor IC20', capacity: 20000, chlorinePerDay: 0.70, chlorinePerSec: 0.70 / 86400 }],
|
|
89
|
+
[3, { name: 'intellichlor--40', desc: 'IntelliChlor IC40', capacity: 40000, chlorinePerDay: 1.40, chlorinePerSec: 1.4 / 86400 }],
|
|
90
|
+
[4, { name: 'intellichlor--60', desc: 'IntelliChlor IC60', capacity: 60000, chlorinePerDay: 2, chlorinePerSec: 2 / 86400 }],
|
|
91
|
+
[5, { name: 'aquarite-t15', desc: 'AquaRite T15', capacity: 40000, chlorinePerDay: 1.47, chlorinePerSec: 1.47 / 86400 }],
|
|
92
|
+
[6, { name: 'aquarite-t9', desc: 'AquaRite T9', capacity: 30000, chlorinePerDay: 0.98, chlorinePerSec: 0.98 / 86400 }],
|
|
93
|
+
[7, { name: 'aquarite-t5', desc: 'AquaRite T5', capacity: 20000, chlorinePerDay: 0.735, chlorinePerSec: 0.735 / 86400 }],
|
|
94
|
+
[8, { name: 'aquarite-t3', desc: 'AquaRite T3', capacity: 15000, chlorinePerDay: 0.53, chlorinePerSec: 0.53 / 86400 }],
|
|
95
|
+
[9, { name: 'aquarite-925', desc: 'AquaRite 925', capacity: 25000, chlorinePerDay: 0.98, chlorinePerSec: 0.98 / 86400 }],
|
|
96
|
+
[10, { name: 'aquarite-940', desc: 'AquaRite 940', capacity: 40000, chlorinePerDay: 1.47, chlorinePerSec: 1.47 / 86400 }]
|
|
97
|
+
]);
|
|
98
|
+
|
|
84
99
|
|
|
85
100
|
// Keep this around for now so I can fart with the custom names array.
|
|
86
101
|
//this.valueMaps.customNames = new byteValueMap(
|
|
@@ -126,7 +141,9 @@ export class NixieBoard extends SystemBoard {
|
|
|
126
141
|
[1, { name: 'sunrise', desc: 'Sunrise' }],
|
|
127
142
|
[2, { name: 'sunset', desc: 'Sunset' }]
|
|
128
143
|
]);
|
|
144
|
+
|
|
129
145
|
this.valueMaps.lightThemes = new byteValueMap([
|
|
146
|
+
// IntelliBrite Themes
|
|
130
147
|
[0, { name: 'white', desc: 'White', type: 'intellibrite', sequence: 11 }],
|
|
131
148
|
[1, { name: 'green', desc: 'Green', type: 'intellibrite', sequence: 9 }],
|
|
132
149
|
[2, { name: 'blue', desc: 'Blue', type: 'intellibrite', sequence: 8 }],
|
|
@@ -139,6 +156,24 @@ export class NixieBoard extends SystemBoard {
|
|
|
139
156
|
[9, { name: 'american', desc: 'American', type: 'intellibrite', sequence: 5 }],
|
|
140
157
|
[10, { name: 'sunset', desc: 'Sunset', type: 'intellibrite', sequence: 6 }],
|
|
141
158
|
[11, { name: 'royal', desc: 'Royal', type: 'intellibrite', sequence: 7 }],
|
|
159
|
+
// ColorLogic Themes
|
|
160
|
+
[20, { name: 'cloudwhite', desc: 'Cloud White', type: 'colorlogic', sequence: 7 }],
|
|
161
|
+
[21, { name: 'deepsea', desc: 'Deep Sea', type: 'colorlogic', sequence: 2 }],
|
|
162
|
+
[22, { name: 'royalblue', desc: 'Royal Blue', type: 'colorlogic', sequence: 3 }],
|
|
163
|
+
[23, { name: 'afternoonskies', desc: 'Afternoon Skies', type: 'colorlogic', sequence: 4 }],
|
|
164
|
+
[24, { name: 'aquagreen', desc: 'Aqua Green', type: 'colorlogic', sequence: 5 }],
|
|
165
|
+
[25, { name: 'emerald', desc: 'Emerald', type: 'colorlogic', sequence: 6 }],
|
|
166
|
+
[26, { name: 'warmred', desc: 'Warm Red', type: 'colorlogic', sequence: 8 }],
|
|
167
|
+
[27, { name: 'flamingo', desc: 'Flamingo', type: 'colorlogic', sequence: 9 }],
|
|
168
|
+
[28, { name: 'vividviolet', desc: 'Vivid Violet', type: 'colorlogic', sequence: 10 }],
|
|
169
|
+
[29, { name: 'sangria', desc: 'Sangria', type: 'colorlogic', sequence: 11 }],
|
|
170
|
+
[30, { name: 'twilight', desc: 'Twilight', type: 'colorlogic', sequence: 12 }],
|
|
171
|
+
[31, { name: 'tranquility', desc: 'Tranquility', type: 'colorlogic', sequence: 13 }],
|
|
172
|
+
[32, { name: 'gemstone', desc: 'Gemstone', type: 'colorlogic', sequence: 14 }],
|
|
173
|
+
[33, { name: 'usa', desc: 'USA', type: 'colorlogic', sequence: 15 }],
|
|
174
|
+
[34, { name: 'mardigras', desc: 'Mardi Gras', type: 'colorlogic', sequence: 16 }],
|
|
175
|
+
[35, { name: 'coolcabaret', desc: 'Cabaret', type: 'colorlogic', sequence: 17 }],
|
|
176
|
+
|
|
142
177
|
[255, { name: 'none', desc: 'None' }]
|
|
143
178
|
]);
|
|
144
179
|
this.valueMaps.lightColors = new byteValueMap([
|
|
@@ -185,6 +220,7 @@ export class NixieBoard extends SystemBoard {
|
|
|
185
220
|
public async initNixieBoard() {
|
|
186
221
|
try {
|
|
187
222
|
this.killStatusCheck();
|
|
223
|
+
let self = this;
|
|
188
224
|
sys.general.options.clockSource = 'server';
|
|
189
225
|
state.status = sys.board.valueMaps.controllerStatus.transform(0, 0);
|
|
190
226
|
// First lets clear out all the messages.
|
|
@@ -224,7 +260,8 @@ export class NixieBoard extends SystemBoard {
|
|
|
224
260
|
sys.equipment.maxCustomNames = 0;
|
|
225
261
|
state.equipment.model = type.desc;
|
|
226
262
|
state.equipment.maxBodies = sys.equipment.maxBodies = type.bodies;
|
|
227
|
-
|
|
263
|
+
let bodyUnits = sys.general.options.units === 0 ? 1 : 2;
|
|
264
|
+
|
|
228
265
|
if (typeof state.temps.units === 'undefined' || state.temps.units < 0) state.temps.units = sys.general.options.units;
|
|
229
266
|
if (type.bodies > 0) {
|
|
230
267
|
let pool = sys.bodies.getItemById(1, true);
|
|
@@ -236,6 +273,7 @@ export class NixieBoard extends SystemBoard {
|
|
|
236
273
|
pool.circuit = 6;
|
|
237
274
|
pool.isActive = true;
|
|
238
275
|
pool.master = 1;
|
|
276
|
+
pool.capacityUnits = bodyUnits;
|
|
239
277
|
sbody.name = pool.name;
|
|
240
278
|
sbody.setPoint = pool.setPoint;
|
|
241
279
|
sbody.circuit = pool.circuit;
|
|
@@ -271,6 +309,7 @@ export class NixieBoard extends SystemBoard {
|
|
|
271
309
|
sbody.setPoint = spa.setPoint;
|
|
272
310
|
sbody.circuit = spa.circuit;
|
|
273
311
|
sbody.type = spa.type;
|
|
312
|
+
spa.capacityUnits = bodyUnits;
|
|
274
313
|
scirc = state.circuits.getItemById(1, true);
|
|
275
314
|
scirc.showInFeatures = circ.showInFeatures;
|
|
276
315
|
scirc.type = circ.type;
|
|
@@ -294,6 +333,7 @@ export class NixieBoard extends SystemBoard {
|
|
|
294
333
|
sys.circuits.removeItemById(6);
|
|
295
334
|
state.circuits.removeItemById(6);
|
|
296
335
|
}
|
|
336
|
+
|
|
297
337
|
sys.equipment.setEquipmentIds();
|
|
298
338
|
sys.board.bodies.initFilters();
|
|
299
339
|
state.status = sys.board.valueMaps.controllerStatus.transform(2, 0);
|
|
@@ -308,6 +348,7 @@ export class NixieBoard extends SystemBoard {
|
|
|
308
348
|
total += sys.valves.length;
|
|
309
349
|
total += sys.schedules.length;
|
|
310
350
|
this.initValves();
|
|
351
|
+
sys.board.heaters.initTempSensors();
|
|
311
352
|
await this.verifySetup();
|
|
312
353
|
await ncp.initAsync(sys);
|
|
313
354
|
sys.board.heaters.updateHeaterServices();
|
|
@@ -315,7 +356,7 @@ export class NixieBoard extends SystemBoard {
|
|
|
315
356
|
logger.info(`${sys.equipment.model} control board initialized`);
|
|
316
357
|
state.status = sys.board.valueMaps.controllerStatus.transform(1, 100);
|
|
317
358
|
// At this point we should have the start of a board so lets check to see if we are ready or if we are stuck initializing.
|
|
318
|
-
setTimeout(() =>
|
|
359
|
+
setTimeout(() => self.processStatusAsync(), 5000);
|
|
319
360
|
} catch (err) { state.status = 255; logger.error(`Error Initializing Nixie Control Panel ${err.message}`); }
|
|
320
361
|
}
|
|
321
362
|
public initValves() {
|
|
@@ -476,15 +517,14 @@ export class NixieCircuitCommands extends CircuitCommands {
|
|
|
476
517
|
else if (id === 1) state.temps.bodies.getItemById(2, true).isOn = val;
|
|
477
518
|
// Let the main nixie controller set the circuit state and affect the relays if it needs to.
|
|
478
519
|
await ncp.circuits.setCircuitStateAsync(circ, newState);
|
|
520
|
+
await sys.board.processStatusAsync();
|
|
479
521
|
return state.circuits.getInterfaceById(circ.id);
|
|
480
522
|
}
|
|
481
523
|
catch (err) { return Promise.reject(`Nixie: Error setCircuitStateAsync ${err.message}`); }
|
|
482
524
|
finally {
|
|
483
525
|
state.emitEquipmentChanges();
|
|
484
|
-
// sys.board.virtualPumpControllers.start();
|
|
485
526
|
ncp.pumps.syncPumpStates();
|
|
486
527
|
sys.board.suspendStatus(false);
|
|
487
|
-
this.board.processStatusAsync();
|
|
488
528
|
}
|
|
489
529
|
}
|
|
490
530
|
public toggleCircuitStateAsync(id: number): Promise<ICircuitState> {
|
|
@@ -493,6 +533,13 @@ export class NixieCircuitCommands extends CircuitCommands {
|
|
|
493
533
|
}
|
|
494
534
|
public async setLightThemeAsync(id: number, theme: number) {
|
|
495
535
|
let cstate = state.circuits.getItemById(id);
|
|
536
|
+
let circ = sys.circuits.getItemById(id);
|
|
537
|
+
let thm = sys.board.valueMaps.lightThemes.findItem(theme);
|
|
538
|
+
if (typeof thm !== 'undefined' && typeof thm.sequence !== 'undefined' && circ.master === 1) {
|
|
539
|
+
logger.info(`Setting light theme for ${circ.name} to ${thm.name} [${thm.sequence}]`);
|
|
540
|
+
await sys.board.circuits.setCircuitStateAsync(id, true);
|
|
541
|
+
await ncp.circuits.sendOnOffSequenceAsync(id, thm.sequence);
|
|
542
|
+
}
|
|
496
543
|
cstate.lightingTheme = theme;
|
|
497
544
|
return Promise.resolve(cstate as ICircuitState);
|
|
498
545
|
}
|
|
@@ -549,7 +596,15 @@ export class NixieCircuitCommands extends CircuitCommands {
|
|
|
549
596
|
}
|
|
550
597
|
return arrRefs;
|
|
551
598
|
}
|
|
552
|
-
public getLightThemes(type?: number) {
|
|
599
|
+
public getLightThemes(type?: number) {
|
|
600
|
+
let tobj = (typeof type === 'undefined') ? sys.board.valueMaps.circuitFunctions.transformByName('intellibrite') : sys.board.valueMaps.circuitFunctions.transform(type);
|
|
601
|
+
let arrThemes = sys.board.valueMaps.lightThemes.toArray();
|
|
602
|
+
let arr = [];
|
|
603
|
+
for (let i = 0; i < arrThemes.length; i++) {
|
|
604
|
+
if (tobj.name === arrThemes[i].type) arr.push(arrThemes[i]);
|
|
605
|
+
}
|
|
606
|
+
return arr;
|
|
607
|
+
}
|
|
553
608
|
public getCircuitFunctions() { return sys.board.valueMaps.circuitFunctions.toArray(); }
|
|
554
609
|
public getCircuitNames() {
|
|
555
610
|
return [...sys.board.valueMaps.circuitNames.toArray(), ...sys.board.valueMaps.customNames.toArray()];
|
|
@@ -564,8 +619,8 @@ export class NixieCircuitCommands extends CircuitCommands {
|
|
|
564
619
|
if (isNaN(id) || !sys.board.equipmentIds.circuits.isInRange(id)) return Promise.reject(new InvalidEquipmentIdError(`Invalid circuit id: ${data.id}`, data.id, 'Circuit'));
|
|
565
620
|
let circuit = sys.circuits.getItemById(id, true);
|
|
566
621
|
let scircuit = state.circuits.getItemById(id, true);
|
|
567
|
-
circuit.isActive = true;
|
|
568
|
-
|
|
622
|
+
scircuit.isActive = circuit.isActive = true;
|
|
623
|
+
circuit.master = 1;
|
|
569
624
|
if (data.name) circuit.name = scircuit.name = data.name;
|
|
570
625
|
else if (!circuit.name && !data.name) circuit.name = scircuit.name = Circuit.getIdName(id);
|
|
571
626
|
if (typeof data.type !== 'undefined' || typeof circuit.type === 'undefined') circuit.type = scircuit.type = parseInt(data.type, 10) || 0;
|
|
@@ -586,8 +641,14 @@ export class NixieCircuitCommands extends CircuitCommands {
|
|
|
586
641
|
let group: CircuitGroup = null;
|
|
587
642
|
let id = typeof obj.id !== 'undefined' ? parseInt(obj.id, 10) : -1;
|
|
588
643
|
if (id <= 0) {
|
|
589
|
-
// We are adding a circuit group.
|
|
590
|
-
|
|
644
|
+
// We are adding a circuit group so we need to get the next equipment id. For circuit groups and light groups, they share ids.
|
|
645
|
+
let range = sys.board.equipmentIds.circuitGroups;
|
|
646
|
+
for (let i = range.start; i <= range.end; i++) {
|
|
647
|
+
if (!sys.lightGroups.find(elem => elem.id === i) && !sys.circuitGroups.find(elem => elem.id === i)) {
|
|
648
|
+
id = i;
|
|
649
|
+
break;
|
|
650
|
+
}
|
|
651
|
+
}
|
|
591
652
|
}
|
|
592
653
|
if (typeof id === 'undefined') return Promise.reject(new InvalidEquipmentIdError(`Max circuit group id exceeded`, id, 'CircuitGroup'));
|
|
593
654
|
if (isNaN(id) || !sys.board.equipmentIds.circuitGroups.isInRange(id)) return Promise.reject(new InvalidEquipmentIdError(`Invalid circuit group id: ${obj.id}`, obj.id, 'CircuitGroup'));
|
|
@@ -619,7 +680,7 @@ export class NixieCircuitCommands extends CircuitCommands {
|
|
|
619
680
|
//RKS: 09-26-20 There is no such thing as a lighting theme on a circuit group circuit. That is what lighGroups are for.
|
|
620
681
|
//if (typeof cobj.lightingTheme !== 'undefined') c.lightingTheme = parseInt(cobj.lightingTheme, 10);
|
|
621
682
|
}
|
|
622
|
-
|
|
683
|
+
group.circuits.length = obj.circuits.length; // RSG - removed as this will delete circuits that were not changed
|
|
623
684
|
}
|
|
624
685
|
resolve(group);
|
|
625
686
|
});
|
|
@@ -629,14 +690,21 @@ export class NixieCircuitCommands extends CircuitCommands {
|
|
|
629
690
|
let group: LightGroup = null;
|
|
630
691
|
let id = typeof obj.id !== 'undefined' ? parseInt(obj.id, 10) : -1;
|
|
631
692
|
if (id <= 0) {
|
|
632
|
-
// We are adding a circuit group.
|
|
633
|
-
|
|
693
|
+
// We are adding a circuit group so we need to get the next equipment id. For circuit groups and light groups, they share ids.
|
|
694
|
+
let range = sys.board.equipmentIds.circuitGroups;
|
|
695
|
+
for (let i = range.start; i <= range.end; i++) {
|
|
696
|
+
if (!sys.lightGroups.find(elem => elem.id === i) && !sys.circuitGroups.find(elem => elem.id === i)) {
|
|
697
|
+
id = i;
|
|
698
|
+
break;
|
|
699
|
+
}
|
|
700
|
+
}
|
|
634
701
|
}
|
|
635
702
|
if (typeof id === 'undefined') return Promise.reject(new InvalidEquipmentIdError(`Max circuit light group id exceeded`, id, 'LightGroup'));
|
|
636
703
|
if (isNaN(id) || !sys.board.equipmentIds.circuitGroups.isInRange(id)) return Promise.reject(new InvalidEquipmentIdError(`Invalid circuit group id: ${obj.id}`, obj.id, 'LightGroup'));
|
|
637
704
|
group = sys.lightGroups.getItemById(id, true);
|
|
705
|
+
let sgroup = state.lightGroups.getItemById(id, true);
|
|
638
706
|
return new Promise<LightGroup>((resolve, reject) => {
|
|
639
|
-
if (typeof obj.name !== 'undefined') group.name = obj.name;
|
|
707
|
+
if (typeof obj.name !== 'undefined') sgroup.name = group.name = obj.name;
|
|
640
708
|
if (typeof obj.dontStop !== 'undefined' && utils.makeBool(obj.dontStop) === true) obj.eggTimer = 1440;
|
|
641
709
|
if (typeof obj.eggTimer !== 'undefined') group.eggTimer = Math.min(Math.max(parseInt(obj.eggTimer, 10), 0), 1440);
|
|
642
710
|
group.dontStop = group.eggTimer === 1440;
|
|
@@ -654,7 +722,11 @@ export class NixieCircuitCommands extends CircuitCommands {
|
|
|
654
722
|
if (typeof cobj.swimDelay !== 'undefined') c.swimDelay = parseInt(cobj.swimDelay, 10);
|
|
655
723
|
if (typeof cobj.position !== 'undefined') c.position = parseInt(cobj.position, 10);
|
|
656
724
|
}
|
|
725
|
+
// RKS: 09-25-21 - This has to be here. Not sure the goal of not setting the entire circuit array when saving the group.
|
|
657
726
|
// group.circuits.length = obj.circuits.length; // RSG - removed as this will delete circuits that were not changed
|
|
727
|
+
group.circuits.length = obj.circuits.length;
|
|
728
|
+
sgroup.emitEquipmentChange();
|
|
729
|
+
|
|
658
730
|
}
|
|
659
731
|
resolve(group);
|
|
660
732
|
});
|
|
@@ -696,24 +768,30 @@ export class NixieCircuitCommands extends CircuitCommands {
|
|
|
696
768
|
return Promise.reject(new InvalidEquipmentIdError('Group id has not been defined', id, 'LightGroup'));
|
|
697
769
|
}
|
|
698
770
|
public async deleteCircuitAsync(data: any): Promise<ICircuit> {
|
|
699
|
-
|
|
700
|
-
|
|
771
|
+
let id = parseInt(data.id, 10);
|
|
772
|
+
if (isNaN(id)) return Promise.reject(new InvalidEquipmentIdError(`Invalid circuit id: ${data.id}`, data.id, 'Circuit'));
|
|
773
|
+
if (!sys.board.equipmentIds.circuits.isInRange(id)) return Promise.reject(new InvalidEquipmentIdError(`Invalid circuit id: ${data.id}`, data.id, 'Circuit'));
|
|
774
|
+
let circuit = sys.circuits.getInterfaceById(id);
|
|
775
|
+
let cstate = state.circuits.getInterfaceById(id);
|
|
701
776
|
if (circuit instanceof Circuit) {
|
|
702
|
-
sys.circuits.removeItemById(
|
|
703
|
-
state.circuits.removeItemById(
|
|
777
|
+
sys.circuits.removeItemById(circuit.id);
|
|
778
|
+
state.circuits.removeItemById(circuit.id);
|
|
779
|
+
cstate.isActive = circuit.isActive = false;
|
|
704
780
|
}
|
|
705
781
|
if (circuit instanceof Feature) {
|
|
706
|
-
sys.features.removeItemById(
|
|
707
|
-
state.features.removeItemById(
|
|
782
|
+
sys.features.removeItemById(circuit.id);
|
|
783
|
+
state.features.removeItemById(circuit.id);
|
|
784
|
+
cstate.isActive = circuit.isActive = false;
|
|
708
785
|
}
|
|
786
|
+
cstate.emitEquipmentChange();
|
|
709
787
|
return new Promise<ICircuit>((resolve, reject) => { resolve(circuit); });
|
|
710
788
|
}
|
|
711
789
|
public deleteCircuit(data: any) {
|
|
712
790
|
if (typeof data.id !== 'undefined') {
|
|
713
791
|
let circuit = sys.circuits.getInterfaceById(data.id);
|
|
714
792
|
if (circuit instanceof Circuit) {
|
|
715
|
-
sys.circuits.removeItemById(
|
|
716
|
-
state.circuits.removeItemById(
|
|
793
|
+
sys.circuits.removeItemById(circuit.id);
|
|
794
|
+
state.circuits.removeItemById(circuit.id);
|
|
717
795
|
return;
|
|
718
796
|
}
|
|
719
797
|
if (circuit instanceof Feature) {
|
|
@@ -800,13 +878,21 @@ export class NixieCircuitCommands extends CircuitCommands {
|
|
|
800
878
|
}
|
|
801
879
|
public async setCircuitGroupStateAsync(id: number, val: boolean): Promise<ICircuitGroupState> {
|
|
802
880
|
let grp = sys.circuitGroups.getItemById(id, false, { isActive: false });
|
|
803
|
-
|
|
881
|
+
if (grp.dataName !== 'circuitGroupConfig') return await sys.board.circuits.setLightGroupStateAsync(id, val);
|
|
882
|
+
let gstate = state.circuitGroups.getItemById(grp.id, grp.isActive !== false);
|
|
804
883
|
let circuits = grp.circuits.toArray();
|
|
884
|
+
sys.board.circuits.setEndTime(sys.circuits.getInterfaceById(gstate.id), gstate, val);
|
|
805
885
|
gstate.isOn = val;
|
|
806
886
|
let arr = [];
|
|
807
887
|
for (let i = 0; i < circuits.length; i++) {
|
|
808
888
|
let circuit = circuits[i];
|
|
809
|
-
|
|
889
|
+
// The desiredState will be as follows.
|
|
890
|
+
// 1 = on, 2 = off, 3 = ignore.
|
|
891
|
+
let cval = true;
|
|
892
|
+
if (circuit.desiredState === 1) cval = val ? true : false;
|
|
893
|
+
else if (circuit.desiredState === 2) cval = val ? false : true;
|
|
894
|
+
else continue;
|
|
895
|
+
arr.push(sys.board.circuits.setCircuitStateAsync(circuit.circuit, cval));
|
|
810
896
|
}
|
|
811
897
|
return new Promise<ICircuitGroupState>(async (resolve, reject) => {
|
|
812
898
|
await Promise.all(arr).catch((err) => { reject(err) });
|
|
@@ -814,16 +900,22 @@ export class NixieCircuitCommands extends CircuitCommands {
|
|
|
814
900
|
});
|
|
815
901
|
}
|
|
816
902
|
public async setLightGroupStateAsync(id: number, val: boolean): Promise<ICircuitGroupState> {
|
|
817
|
-
|
|
903
|
+
let grp = sys.circuitGroups.getItemById(id, false, { isActive: false });
|
|
904
|
+
if (grp.dataName === 'circuitGroupConfig') return await sys.board.circuits.setCircuitGroupStateAsync(id, val);
|
|
905
|
+
let gstate = state.lightGroups.getItemById(grp.id, grp.isActive !== false);
|
|
906
|
+
let circuits = grp.circuits.toArray();
|
|
907
|
+
sys.board.circuits.setEndTime(sys.circuits.getInterfaceById(gstate.id), gstate, val);
|
|
908
|
+
gstate.isOn = val;
|
|
909
|
+
let arr = [];
|
|
910
|
+
for (let i = 0; i < circuits.length; i++) {
|
|
911
|
+
let circuit = circuits[i];
|
|
912
|
+
arr.push(sys.board.circuits.setCircuitStateAsync(circuit.circuit, val));
|
|
913
|
+
}
|
|
914
|
+
return new Promise<ICircuitGroupState>(async (resolve, reject) => {
|
|
915
|
+
await Promise.all(arr).catch((err) => { reject(err) });
|
|
916
|
+
resolve(gstate);
|
|
917
|
+
});
|
|
818
918
|
}
|
|
819
|
-
/* public sequenceIntelliBrite(operation: string) {
|
|
820
|
-
state.intellibrite.hasChanged = true;
|
|
821
|
-
let nop = sys.board.valueMaps.intellibriteActions.getValue(operation);
|
|
822
|
-
if (nop > 0) {
|
|
823
|
-
state.intellibrite.action = nop;
|
|
824
|
-
setTimeout(function() { state.intellibrite.action = 0; state.emitEquipmentChanges(); }, 20000); // It takes 20 seconds to sequence.
|
|
825
|
-
}
|
|
826
|
-
} */
|
|
827
919
|
}
|
|
828
920
|
export class NixieFeatureCommands extends FeatureCommands {
|
|
829
921
|
public async setFeatureAsync(obj: any): Promise<Feature> {
|
|
@@ -864,6 +956,7 @@ export class NixieFeatureCommands extends FeatureCommands {
|
|
|
864
956
|
feature.isActive = false;
|
|
865
957
|
sfeature.isOn = false;
|
|
866
958
|
sfeature.showInFeatures = false;
|
|
959
|
+
sfeature.isActive = false;
|
|
867
960
|
sfeature.emitEquipmentChange();
|
|
868
961
|
return new Promise<Feature>((resolve, reject) => { resolve(feature); });
|
|
869
962
|
}
|
|
@@ -876,9 +969,9 @@ export class NixieFeatureCommands extends FeatureCommands {
|
|
|
876
969
|
if (!sys.board.equipmentIds.features.isInRange(id)) return Promise.reject(new InvalidEquipmentIdError(`Invalid feature id: ${id}`, id, 'Feature'));
|
|
877
970
|
let feature = sys.features.getItemById(id);
|
|
878
971
|
let fstate = state.features.getItemById(feature.id, feature.isActive !== false);
|
|
972
|
+
sys.board.circuits.setEndTime(feature, fstate, val);
|
|
879
973
|
fstate.isOn = val;
|
|
880
974
|
sys.board.valves.syncValveStates();
|
|
881
|
-
// sys.board.virtualPumpControllers.start();
|
|
882
975
|
ncp.pumps.syncPumpStates();
|
|
883
976
|
state.emitEquipmentChanges();
|
|
884
977
|
return fstate;
|
|
@@ -889,39 +982,48 @@ export class NixieFeatureCommands extends FeatureCommands {
|
|
|
889
982
|
return this.setFeatureStateAsync(id, !(feat.isOn || false));
|
|
890
983
|
}
|
|
891
984
|
public syncGroupStates() {
|
|
985
|
+
// The way this should work is that when all of the states are met
|
|
986
|
+
// the group should be on. Otherwise it should be off. That means that if
|
|
987
|
+
// you turned on all the group circuits that should be on individually then
|
|
988
|
+
// the group should be on.
|
|
892
989
|
for (let i = 0; i < sys.circuitGroups.length; i++) {
|
|
893
990
|
let grp: CircuitGroup = sys.circuitGroups.getItemByIndex(i);
|
|
894
991
|
let circuits = grp.circuits.toArray();
|
|
895
|
-
let bIsOn = false;
|
|
896
992
|
if (grp.isActive) {
|
|
897
|
-
|
|
898
|
-
|
|
993
|
+
let bIsOn = true;
|
|
994
|
+
// Iterate the circuits and break out should we find a condition
|
|
995
|
+
// where the group should be off.
|
|
996
|
+
for (let j = 0; j < circuits.length && bIsOn === true; j++) {
|
|
997
|
+
let circuit: CircuitGroupCircuit = grp.circuits.getItemByIndex(j);
|
|
899
998
|
let cstate = state.circuits.getInterfaceById(circuit.circuit);
|
|
900
|
-
if (circuit.desiredState === 1
|
|
901
|
-
if (
|
|
999
|
+
if (circuit.desiredState === 1) { // The circuit should be on.
|
|
1000
|
+
if (!utils.makeBool(cstate.isOn)) bIsOn = false;
|
|
1001
|
+
}
|
|
1002
|
+
else if (circuit.desiredState === 0) { // The circuit should be off.
|
|
1003
|
+
if (utils.makeBool(cstate.isOn)) bIsOn = false;
|
|
902
1004
|
}
|
|
903
1005
|
}
|
|
1006
|
+
let sgrp = state.circuitGroups.getItemById(grp.id);
|
|
1007
|
+
sgrp.isOn = bIsOn;
|
|
904
1008
|
}
|
|
905
|
-
let sgrp = state.circuitGroups.getItemById(grp.id);
|
|
906
|
-
sgrp.isOn = bIsOn && grp.isActive;
|
|
907
|
-
|
|
908
1009
|
sys.board.valves.syncValveStates();
|
|
909
1010
|
}
|
|
910
1011
|
// I am guessing that there will only be one here but iterate
|
|
911
1012
|
// just in case we expand.
|
|
912
1013
|
for (let i = 0; i < sys.lightGroups.length; i++) {
|
|
913
1014
|
let grp: LightGroup = sys.lightGroups.getItemByIndex(i);
|
|
914
|
-
let
|
|
1015
|
+
let circuits = grp.circuits.toArray();
|
|
915
1016
|
if (grp.isActive) {
|
|
916
|
-
let
|
|
917
|
-
for (let j = 0; j < circuits.length; j++) {
|
|
918
|
-
let circuit = grp.circuits.getItemByIndex(j)
|
|
919
|
-
let cstate = state.circuits.getInterfaceById(circuit);
|
|
920
|
-
if (cstate.isOn) bIsOn =
|
|
1017
|
+
let bIsOn = true;
|
|
1018
|
+
for (let j = 0; j < circuits.length && bIsOn === true; j++) {
|
|
1019
|
+
let circuit: LightGroupCircuit = grp.circuits.getItemByIndex(j);
|
|
1020
|
+
let cstate = state.circuits.getInterfaceById(circuit.circuit);
|
|
1021
|
+
if (!utils.makeBool(cstate.isOn)) bIsOn = false;
|
|
921
1022
|
}
|
|
1023
|
+
let sgrp = state.lightGroups.getItemById(grp.id);
|
|
1024
|
+
sgrp.isOn = bIsOn;
|
|
922
1025
|
}
|
|
923
|
-
|
|
924
|
-
sgrp.isOn = bIsOn;
|
|
1026
|
+
sys.board.valves.syncValveStates();
|
|
925
1027
|
}
|
|
926
1028
|
state.emitEquipmentChanges();
|
|
927
1029
|
}
|
|
@@ -946,7 +1048,7 @@ export class NixieValveCommands extends ValveCommands {
|
|
|
946
1048
|
valve.deviceBinding = typeof obj.deviceBinding !== 'undefined' ? obj.deviceBinding : valve.deviceBinding;
|
|
947
1049
|
valve.pinId = typeof obj.pinId !== 'undefined' ? obj.pinId : valve.pinId;
|
|
948
1050
|
await ncp.valves.setValveAsync(valve, obj);
|
|
949
|
-
sys.board.
|
|
1051
|
+
await sys.board.syncEquipmentItems();
|
|
950
1052
|
return valve;
|
|
951
1053
|
} catch (err) { logger.error(`Nixie: Error setting valve definition. ${err.message}`); return Promise.reject(err); }
|
|
952
1054
|
}
|
|
@@ -982,7 +1084,7 @@ export class NixieHeaterCommands extends HeaterCommands {
|
|
|
982
1084
|
let heater: Heater;
|
|
983
1085
|
if (id <= 0) {
|
|
984
1086
|
// We are adding a heater. In this case all heaters are virtual.
|
|
985
|
-
let vheaters = sys.heaters.filter(h => h.
|
|
1087
|
+
let vheaters = sys.heaters.filter(h => h.master === 1);
|
|
986
1088
|
id = vheaters.length + 256;
|
|
987
1089
|
}
|
|
988
1090
|
heater = sys.heaters.getItemById(id, true);
|
|
@@ -993,7 +1095,7 @@ export class NixieHeaterCommands extends HeaterCommands {
|
|
|
993
1095
|
}
|
|
994
1096
|
}
|
|
995
1097
|
let hstate = state.heaters.getItemById(id, true);
|
|
996
|
-
hstate.isVirtual = heater.isVirtual = true;
|
|
1098
|
+
//hstate.isVirtual = heater.isVirtual = true;
|
|
997
1099
|
hstate.name = heater.name;
|
|
998
1100
|
hstate.type = heater.type;
|
|
999
1101
|
heater.master = 1;
|