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
|
@@ -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
|
|
@@ -15,18 +16,19 @@ You should have received a copy of the GNU Affero General Public License
|
|
|
15
16
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
16
17
|
*/
|
|
17
18
|
import * as extend from 'extend';
|
|
18
|
-
import { EventEmitter } from 'events';
|
|
19
19
|
import { ncp } from "../nixie/Nixie";
|
|
20
20
|
import { NixieHeaterBase } from "../nixie/heaters/Heater";
|
|
21
|
-
import { utils
|
|
22
|
-
import {SystemBoard, byteValueMap,
|
|
21
|
+
import { utils } from '../Constants';
|
|
22
|
+
import {SystemBoard, byteValueMap, BodyCommands, FilterCommands, PumpCommands, SystemCommands, CircuitCommands, FeatureCommands, ValveCommands, HeaterCommands, ChlorinatorCommands, ChemControllerCommands, EquipmentIdRange} from './SystemBoard';
|
|
23
23
|
import { logger } from '../../logger/Logger';
|
|
24
|
-
import { state,
|
|
25
|
-
import { sys, Equipment,
|
|
26
|
-
import {
|
|
27
|
-
import { BoardProcessError, EquipmentNotFoundError, InvalidEquipmentDataError, InvalidEquipmentIdError, InvalidOperationError, ParameterOutOfRangeError } from '../Errors';
|
|
28
|
-
import { conn } from '../comms/Comms';
|
|
24
|
+
import { state, CircuitState, ICircuitState, ICircuitGroupState, LightGroupState, ValveState, FilterState, BodyTempState, FeatureState } from '../State';
|
|
25
|
+
import { sys, Equipment, General, PoolSystem, CircuitGroupCircuit, CircuitGroup, ChemController, Circuit, Feature, Valve, ICircuit, Heater, LightGroup, LightGroupCircuit, ControllerType, Filter } from '../Equipment';
|
|
26
|
+
import { BoardProcessError, EquipmentNotFoundError, InvalidEquipmentDataError, InvalidEquipmentIdError, ServiceParameterError } from '../Errors';
|
|
29
27
|
import { delayMgr } from '../Lockouts';
|
|
28
|
+
import { webApp } from "../../web/Server";
|
|
29
|
+
import { setTimeout } from 'timers/promises';
|
|
30
|
+
import { setTimeout as setTimeoutSync } from 'timers';
|
|
31
|
+
|
|
30
32
|
export class NixieBoard extends SystemBoard {
|
|
31
33
|
constructor (system: PoolSystem){
|
|
32
34
|
super(system);
|
|
@@ -34,7 +36,7 @@ export class NixieBoard extends SystemBoard {
|
|
|
34
36
|
this.equipmentIds.circuits = new EquipmentIdRange(1, function () { return this.start + sys.equipment.maxCircuits - 1; });
|
|
35
37
|
this.equipmentIds.features = new EquipmentIdRange(function () { return 129; }, function () { return this.start + sys.equipment.maxFeatures - 1; });
|
|
36
38
|
this.equipmentIds.circuitGroups = new EquipmentIdRange(function () { return this.start; }, function () { return this.start + sys.equipment.maxCircuitGroups - 1; });
|
|
37
|
-
this.equipmentIds.virtualCircuits = new EquipmentIdRange(function () { return this.start; }, function () { return
|
|
39
|
+
this.equipmentIds.virtualCircuits = new EquipmentIdRange(function () { return this.start; }, function () { return 277; });
|
|
38
40
|
this.equipmentIds.features.start = 129;
|
|
39
41
|
this.equipmentIds.circuitGroups.start = 193;
|
|
40
42
|
this.equipmentIds.virtualCircuits.start = 237;
|
|
@@ -42,7 +44,12 @@ export class NixieBoard extends SystemBoard {
|
|
|
42
44
|
[1, { val: 1, name: 'ncp', desc: 'Nixie Control Panel' }],
|
|
43
45
|
[2, { val: 2, name: 'ext', desc: 'External Control Panel'}]
|
|
44
46
|
]);
|
|
45
|
-
|
|
47
|
+
this.valueMaps.panelModes = new byteValueMap([
|
|
48
|
+
[0, { name: 'auto', desc: 'Auto' }],
|
|
49
|
+
[1, { name: 'service', desc: 'Service' }],
|
|
50
|
+
[128, { name: 'timeout', desc: 'Timeout' }],
|
|
51
|
+
[255, { name: 'error', desc: 'System Error' }]
|
|
52
|
+
]);
|
|
46
53
|
this.valueMaps.featureFunctions = new byteValueMap([
|
|
47
54
|
[0, { name: 'generic', desc: 'Generic' }],
|
|
48
55
|
[1, { name: 'spillway', desc: 'Spillway' }],
|
|
@@ -68,7 +75,7 @@ export class NixieBoard extends SystemBoard {
|
|
|
68
75
|
[16, { name: 'pooltone', desc: 'Pool Tone', isLight: true, theme: 'pooltone' }],
|
|
69
76
|
]);
|
|
70
77
|
this.valueMaps.pumpTypes = new byteValueMap([
|
|
71
|
-
[1, { name: 'ss', desc: 'Single Speed', maxCircuits:
|
|
78
|
+
[1, { name: 'ss', desc: 'Single Speed', maxCircuits: 8, hasAddress: false, hasBody: false, maxRelays: 1, relays: [{ id: 1, name: 'Pump On/Off' }]}],
|
|
72
79
|
[2, { name: 'ds', desc: 'Two Speed', maxCircuits: 8, hasAddress: false, hasBody: false, maxRelays: 2, relays: [{ id: 1, name: 'Low Speed' }, { id: 2, name: 'High Speed' }]}],
|
|
73
80
|
[3, { name: 'vs', desc: 'Intelliflo VS', maxPrimingTime: 6, minSpeed: 450, maxSpeed: 3450, maxCircuits: 8, hasAddress: true }],
|
|
74
81
|
[4, { name: 'vsf', desc: 'Intelliflo VSF', minSpeed: 450, maxSpeed: 3450, minFlow: 15, maxFlow: 130, maxCircuits: 8, hasAddress: true }],
|
|
@@ -94,9 +101,11 @@ export class NixieBoard extends SystemBoard {
|
|
|
94
101
|
[7, { name: 'sun', desc: 'Sunday', dow: 0, bitval: 64 }]
|
|
95
102
|
]);
|
|
96
103
|
this.valueMaps.groupCircuitStates = new byteValueMap([
|
|
97
|
-
[1, { name: 'on', desc: 'On' }],
|
|
98
|
-
[2, { name: 'off', desc: 'Off' }],
|
|
99
|
-
[3, { name: 'ignore', desc: 'Ignore' }]
|
|
104
|
+
[1, { name: 'on', desc: 'On/Off' }],
|
|
105
|
+
[2, { name: 'off', desc: 'Off/On' }],
|
|
106
|
+
[3, { name: 'ignore', desc: 'Ignore' }],
|
|
107
|
+
[4, { name: 'on+ignore', desc: 'On/Ignore' }],
|
|
108
|
+
[5, { name: 'off+ignore', desc: 'Off/Ignore' }]
|
|
100
109
|
]);
|
|
101
110
|
this.valueMaps.chlorinatorModel = new byteValueMap([
|
|
102
111
|
[0, { name: 'unknown', desc: 'unknown', capacity: 0, chlorinePerDay: 0, chlorinePerSec: 0 }],
|
|
@@ -134,7 +143,7 @@ export class NixieBoard extends SystemBoard {
|
|
|
134
143
|
return { val: b, days: days };
|
|
135
144
|
};
|
|
136
145
|
this.valueMaps.expansionBoards = new byteValueMap([
|
|
137
|
-
[0, { name: 'nxp', part: 'NXP', desc: 'Nixie Single Body', bodies: 1, valves: 0, shared: false, dual: false }],
|
|
146
|
+
[0, { name: 'nxp', part: 'NXP', desc: 'Nixie Single Body', bodies: 1, valves: 0, single: true, shared: false, dual: false }],
|
|
138
147
|
[1, { name: 'nxps', part: 'NXPS', desc: 'Nixie Shared Body', bodies: 2, valves: 2, shared: true, dual: false, chlorinators: 1, chemControllers: 1 }],
|
|
139
148
|
[2, { name: 'nxpd', part: 'NXPD', desc: 'Nixie Dual Body', bodies: 2, valves: 0, shared: false, dual: true, chlorinators: 2, chemControllers: 2 }],
|
|
140
149
|
[255, { name: 'nxnb', part: 'NXNB', desc: 'Nixie No Body', bodies: 0, valves: 0, shared: false, dual: false, chlorinators: 0, chemControllers: 0 }]
|
|
@@ -155,7 +164,8 @@ export class NixieBoard extends SystemBoard {
|
|
|
155
164
|
[255, { name: 'solar3', desc: 'Solar Body 3' }],
|
|
156
165
|
[256, { name: 'solar4', desc: 'Solar Body 4' }],
|
|
157
166
|
[257, { name: 'poolHeatEnable', desc: 'Pool Heat Enable' }],
|
|
158
|
-
[258, { name: 'anyHeater', desc: 'Any Heater' }]
|
|
167
|
+
[258, { name: 'anyHeater', desc: 'Any Heater' }],
|
|
168
|
+
[259, { name: 'heatpump', desc: 'Heat Pump'}]
|
|
159
169
|
]);
|
|
160
170
|
this.valueMaps.scheduleTimeTypes.merge([
|
|
161
171
|
[1, { name: 'sunrise', desc: 'Sunrise' }],
|
|
@@ -187,29 +197,30 @@ export class NixieBoard extends SystemBoard {
|
|
|
187
197
|
[27, { name: 'flamingo', desc: 'Flamingo', types: ['colorlogic'], sequence: 9 }],
|
|
188
198
|
[28, { name: 'vividviolet', desc: 'Vivid Violet', types: ['colorlogic'], sequence: 10 }],
|
|
189
199
|
[29, { name: 'sangria', desc: 'Sangria', types: ['colorlogic'], sequence: 11 }],
|
|
190
|
-
[30, { name: '
|
|
191
|
-
[31, { name: '
|
|
192
|
-
[32, { name: '
|
|
193
|
-
[33, { name: '
|
|
194
|
-
[34, { name: '
|
|
195
|
-
[35, { name: '
|
|
200
|
+
[30, { name: 'voodoolounge', desc: 'Voodoo Lounge', types: ['colorlogic'], sequence: 1 }],
|
|
201
|
+
[31, { name: 'twilight', desc: 'Twilight', types: ['colorlogic'], sequence: 12 }],
|
|
202
|
+
[32, { name: 'tranquility', desc: 'Tranquility', types: ['colorlogic'], sequence: 13 }],
|
|
203
|
+
[33, { name: 'gemstone', desc: 'Gemstone', types: ['colorlogic'], sequence: 14 }],
|
|
204
|
+
[34, { name: 'usa', desc: 'USA', types: ['colorlogic'], sequence: 15 }],
|
|
205
|
+
[35, { name: 'mardigras', desc: 'Mardi Gras', types: ['colorlogic'], sequence: 16 }],
|
|
206
|
+
[36, { name: 'coolcabaret', desc: 'Cabaret', types: ['colorlogic'], sequence: 17 }],
|
|
196
207
|
// Sunseeker PoolTone Themes
|
|
197
|
-
[
|
|
198
|
-
[
|
|
199
|
-
[
|
|
200
|
-
[
|
|
201
|
-
[
|
|
202
|
-
[
|
|
203
|
-
[
|
|
204
|
-
[
|
|
205
|
-
[
|
|
206
|
-
[
|
|
207
|
-
[
|
|
208
|
-
[
|
|
209
|
-
[
|
|
210
|
-
[
|
|
211
|
-
[
|
|
212
|
-
[
|
|
208
|
+
[40, { name: 'eveningsea', desc: 'Evening Sea', types: ['pooltone'], sequence: 1 }],
|
|
209
|
+
[41, { name: 'eveningrivers', desc: 'Evening Rivers', types: ['pooltone'], sequence: 2 }],
|
|
210
|
+
[42, { name: 'riviera', desc: 'Riviera', types: ['pooltone'], sequence: 3 }],
|
|
211
|
+
[43, { name: 'neutralwhite', desc: 'Neutral White', types: ['pooltone'], sequence: 4 }],
|
|
212
|
+
[44, { name: 'rainbow', desc: 'Rainbow', types: ['pooltone'], sequence: 5 }],
|
|
213
|
+
[45, { name: 'colorriver', desc: 'Color River', types: ['pooltone'], sequence: 6 }],
|
|
214
|
+
[46, { name: 'disco', desc: 'Disco', types: ['pooltone'], sequence: 7 }],
|
|
215
|
+
[47, { name: 'fourseasons', desc: 'Four Seasons', types: ['pooltone'], sequence: 8 }],
|
|
216
|
+
[48, { name: 'Party', desc: 'Party', types: ['pooltone'], sequence: 9 }],
|
|
217
|
+
[49, { name: 'sunwhite', desc: 'Sun White', types: ['pooltone'], sequence: 10 }],
|
|
218
|
+
[50, { name: 'red', desc: 'Red', types: ['pooltone'], sequence: 11 }],
|
|
219
|
+
[51, { name: 'green', desc: 'Green', types: ['pooltone'], sequence: 12 }],
|
|
220
|
+
[52, { name: 'blue', desc: 'Blue', types: ['pooltone'], sequence: 13 }],
|
|
221
|
+
[53, { name: 'greenblue', desc: 'Green-Blue', types: ['pooltone'], sequence: 14 }],
|
|
222
|
+
[54, { name: 'redgreen', desc: 'Red-Green', types: ['pooltone'], sequence: 15 }],
|
|
223
|
+
[55, { name: 'bluered', desc: 'Blue-red', types: ['pooltone'], sequence: 16 }],
|
|
213
224
|
[255, { name: 'none', desc: 'None' }]
|
|
214
225
|
]);
|
|
215
226
|
this.valueMaps.lightColors = new byteValueMap([
|
|
@@ -255,6 +266,12 @@ export class NixieBoard extends SystemBoard {
|
|
|
255
266
|
[4, { name: 'spaCommand', desc: 'Spa Command', maxButtons: 10 }]
|
|
256
267
|
]);
|
|
257
268
|
}
|
|
269
|
+
public async checkConfiguration() {
|
|
270
|
+
state.status = sys.board.valueMaps.controllerStatus.transform(0, 0);
|
|
271
|
+
state.emitControllerChange();
|
|
272
|
+
state.status = sys.board.valueMaps.controllerStatus.transform(1, 100);
|
|
273
|
+
state.emitControllerChange();
|
|
274
|
+
}
|
|
258
275
|
public async initNixieBoard() {
|
|
259
276
|
try {
|
|
260
277
|
this.killStatusCheck();
|
|
@@ -275,8 +292,9 @@ export class NixieBoard extends SystemBoard {
|
|
|
275
292
|
let type = typeof mod.type !== 'undefined' ? this.valueMaps.expansionBoards.transform(mod.type) : this.valueMaps.expansionBoards.transform(0);
|
|
276
293
|
logger.info(`Initializing Nixie Control Panel for ${type.desc}`);
|
|
277
294
|
|
|
278
|
-
sys.equipment.shared = type.shared;
|
|
279
|
-
sys.equipment.dual = type.dual;
|
|
295
|
+
state.equipment.shared = sys.equipment.shared = type.shared;
|
|
296
|
+
state.equipment.dual = sys.equipment.dual = type.dual;
|
|
297
|
+
state.equipment.single = sys.equipment.single = sys.equipment.shared === false && sys.equipment.dual === false;
|
|
280
298
|
sys.equipment.controllerFirmware = '1.0.0';
|
|
281
299
|
mod.type = type.val;
|
|
282
300
|
mod.part = type.part;
|
|
@@ -299,6 +317,7 @@ export class NixieBoard extends SystemBoard {
|
|
|
299
317
|
state.equipment.model = type.desc;
|
|
300
318
|
state.equipment.maxBodies = sys.equipment.maxBodies = type.bodies;
|
|
301
319
|
let bodyUnits = sys.general.options.units === 0 ? 1 : 2;
|
|
320
|
+
sys.equipment.single = typeof type.single !== 'undefined' ? type.single : false;
|
|
302
321
|
|
|
303
322
|
if (typeof state.temps.units === 'undefined' || state.temps.units < 0) state.temps.units = sys.general.options.units;
|
|
304
323
|
if (type.bodies > 0) {
|
|
@@ -393,8 +412,10 @@ export class NixieBoard extends SystemBoard {
|
|
|
393
412
|
state.cleanupState();
|
|
394
413
|
logger.info(`${sys.equipment.model} control board initialized`);
|
|
395
414
|
state.status = sys.board.valueMaps.controllerStatus.transform(1, 100);
|
|
415
|
+
state.mode = sys.board.valueMaps.panelModes.encode('auto');
|
|
396
416
|
// 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.
|
|
397
|
-
setTimeout(
|
|
417
|
+
await setTimeout(5000);
|
|
418
|
+
await self.processStatusAsync();
|
|
398
419
|
} catch (err) { state.status = 255; logger.error(`Error Initializing Nixie Control Panel ${err.message}`); }
|
|
399
420
|
}
|
|
400
421
|
public initValves() {
|
|
@@ -498,6 +519,7 @@ export class NixieFilterCommands extends FilterCommands {
|
|
|
498
519
|
}
|
|
499
520
|
}
|
|
500
521
|
export class NixieSystemCommands extends SystemCommands {
|
|
522
|
+
protected _modeTimer: NodeJS.Timeout;
|
|
501
523
|
public cancelDelay(): Promise<any> {
|
|
502
524
|
delayMgr.cancelPumpValveDelays();
|
|
503
525
|
delayMgr.cancelHeaterCooldownDelays();
|
|
@@ -528,11 +550,74 @@ export class NixieSystemCommands extends SystemCommands {
|
|
|
528
550
|
|
|
529
551
|
} catch (err) { return logger.error(`Error setting Nixie Model: ${err.message}`); }
|
|
530
552
|
}
|
|
553
|
+
public async setPanelModeAsync(data: any): Promise<any> {
|
|
554
|
+
let mode = sys.board.valueMaps.panelModes.findItem(data.mode);
|
|
555
|
+
let timeout = parseInt(data.timeout, 10);
|
|
556
|
+
if (typeof mode === 'undefined') return Promise.reject(new ServiceParameterError(`Invalid mode value cannot set mode`, 'setPanelModeAsync', 'mode', data.mode));
|
|
557
|
+
switch (mode.name) {
|
|
558
|
+
case 'timeout':
|
|
559
|
+
if (isNaN(timeout) || timeout <= 0) return Promise.reject(new ServiceParameterError(`Invalid timeout value cannot set mode`, 'setPanelModeAsync', 'timeout', data.timeout));
|
|
560
|
+
await this.initServiceMode(mode, timeout);
|
|
561
|
+
break;
|
|
562
|
+
case 'service':
|
|
563
|
+
await this.initServiceMode(mode);
|
|
564
|
+
break;
|
|
565
|
+
case 'auto':
|
|
566
|
+
// Ok we are switching back to auto.
|
|
567
|
+
// 1. Kill the timeout timer if it exists.
|
|
568
|
+
// 2. Set the mode to auto.
|
|
569
|
+
if (this._modeTimer) clearTimeout(this._modeTimer);
|
|
570
|
+
this._modeTimer = null;
|
|
571
|
+
state.mode = 0;
|
|
572
|
+
webApp.emitToClients('panelMode', { mode: mode, remaining: 0 });
|
|
573
|
+
break;
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
private checkServiceTimeout(mode: any, start: number, timeout: number, interval?: number) {
|
|
577
|
+
if (this._modeTimer) clearTimeout(this._modeTimer);
|
|
578
|
+
this._modeTimer = null;
|
|
579
|
+
// The timeout is in seconds so we will need to deal with that.
|
|
580
|
+
let elapsed = (new Date().getTime() - start) / 1000;
|
|
581
|
+
let remaining = timeout - elapsed;
|
|
582
|
+
logger.info(`Timeout: ${timeout} Elapsed: ${elapsed}`);
|
|
583
|
+
if (remaining > 0) {
|
|
584
|
+
webApp.emitToClients('panelMode', { mode: mode, remaining: remaining, elapsed: elapsed, timeout: timeout });
|
|
585
|
+
this._modeTimer = setTimeoutSync(() => { this.checkServiceTimeout(mode, start, timeout, interval || 1000); }, interval || 1000);
|
|
586
|
+
}
|
|
587
|
+
else {
|
|
588
|
+
webApp.emitToClients('panelMode', { mode: sys.board.valueMaps.panelModes.transform(0), remaining: 0 });
|
|
589
|
+
state.mode = 0;
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
public async initServiceMode(mode, timeout?: number) {
|
|
593
|
+
if (this._modeTimer) clearTimeout(this._modeTimer);
|
|
594
|
+
for (let i = 0; i < sys.circuits.length; i++) {
|
|
595
|
+
let circ = sys.circuits.getItemByIndex(i);
|
|
596
|
+
if (circ.master === 1) {
|
|
597
|
+
let cstate = state.circuits.getItemById(circ.id);
|
|
598
|
+
if (cstate.isOn) await sys.board.circuits.setCircuitStateAsync(circ.id, false, true);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
delayMgr.clearAllDelays();
|
|
602
|
+
state.mode = mode.val;
|
|
603
|
+
// Shut everything down.
|
|
604
|
+
await ncp.setServiceModeAsync();
|
|
605
|
+
if (timeout > 0) {
|
|
606
|
+
let start = new Date().getTime();
|
|
607
|
+
this.checkServiceTimeout(mode, start, timeout, 1000);
|
|
608
|
+
webApp.emitToClients('panelMode', { mode: mode, remaining: timeout, elapsed: 0, timeout: timeout });
|
|
609
|
+
}
|
|
610
|
+
else {
|
|
611
|
+
webApp.emitToClients('panelMode', { mode: mode });
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
}
|
|
531
615
|
}
|
|
532
616
|
export class NixieCircuitCommands extends CircuitCommands {
|
|
533
617
|
// This is our poll loop for circuit relay states.
|
|
534
618
|
public async syncCircuitRelayStates() {
|
|
535
619
|
try {
|
|
620
|
+
if (state.mode !== 0) return;
|
|
536
621
|
for (let i = 0; i < sys.circuits.length; i++) {
|
|
537
622
|
// Run through all the controlled circuits to see whether they should be triggered or not.
|
|
538
623
|
let circ = sys.circuits.getItemByIndex(i);
|
|
@@ -557,6 +642,7 @@ export class NixieCircuitCommands extends CircuitCommands {
|
|
|
557
642
|
let circuit: ICircuit = sys.circuits.getInterfaceById(id, false, { isActive: false });
|
|
558
643
|
if (isNaN(id)) return Promise.reject(new InvalidEquipmentIdError(`Circuit or Feature id ${id} not valid`, id, 'Circuit'));
|
|
559
644
|
let circ = state.circuits.getInterfaceById(id, circuit.isActive !== false);
|
|
645
|
+
if (state.mode !== 0) return circ;
|
|
560
646
|
if (circ.stopDelay) {
|
|
561
647
|
// Send this off so that the relays are properly set. In the end we cannot change right now. If this
|
|
562
648
|
// happens to be a body circuit then the relay state will be skipped anyway.
|
|
@@ -672,6 +758,8 @@ export class NixieCircuitCommands extends CircuitCommands {
|
|
|
672
758
|
let cstate = state.circuits.getItemById(id);
|
|
673
759
|
let circuit = sys.circuits.getItemById(id);
|
|
674
760
|
let bstate = state.temps.bodies.getBodyByCircuitId(id);
|
|
761
|
+
if (cstate.isOn === val) return; // If body is already in desired state, don't do anything.
|
|
762
|
+
// https://github.com/tagyoureit/nodejs-poolController/issues/361#issuecomment-1186087763
|
|
675
763
|
if (val) {
|
|
676
764
|
// We are turning on a body circuit.
|
|
677
765
|
logger.verbose(`Turning on a body circuit ${bstate.name}`);
|
|
@@ -781,7 +869,6 @@ export class NixieCircuitCommands extends CircuitCommands {
|
|
|
781
869
|
if (sys.equipment.shared && bstate.id === 2) await this.turnOffDrainCircuits(ignoreDelays);
|
|
782
870
|
logger.verbose(`Turning off a body circuit ${circuit.name}`);
|
|
783
871
|
if (cstate.isOn) {
|
|
784
|
-
|
|
785
872
|
// Check to see if we have any heater cooldown delays that need to take place.
|
|
786
873
|
let heaters = sys.board.heaters.getHeatersByCircuitId(circuit.id);
|
|
787
874
|
let cooldownTime = 0;
|
|
@@ -799,6 +886,9 @@ export class NixieCircuitCommands extends CircuitCommands {
|
|
|
799
886
|
bstate.isOn = val;
|
|
800
887
|
}
|
|
801
888
|
}
|
|
889
|
+
else {
|
|
890
|
+
bstate.isOn = val;
|
|
891
|
+
}
|
|
802
892
|
}
|
|
803
893
|
return cstate;
|
|
804
894
|
} catch (err) { logger.error(`Nixie: Error setBodyCircuitStateAsync ${err.message}`); return Promise.reject(new BoardProcessError(`Nixie: Error setBodyCircuitStateAsync ${err.message}`, 'setBodyCircuitStateAsync')); }
|
|
@@ -875,7 +965,7 @@ export class NixieCircuitCommands extends CircuitCommands {
|
|
|
875
965
|
logger.verbose(`Turning ${val ? 'on' : 'off'} a drain circuit ${cstate.name}`);
|
|
876
966
|
await ncp.circuits.setCircuitStateAsync(cstate, val);
|
|
877
967
|
return cstate;
|
|
878
|
-
} catch (err) { logger.error(`Nixie: Error
|
|
968
|
+
} catch (err) { logger.error(`Nixie: Error setDrainCircuitStateAsync ${err.message}`); return Promise.reject(new BoardProcessError(`Nixie: Error setDrainCircuitStateAsync ${err.message}`, 'setDrainCircuitStateAsync')); }
|
|
879
969
|
}
|
|
880
970
|
|
|
881
971
|
public toggleCircuitStateAsync(id: number): Promise<ICircuitState> {
|
|
@@ -888,12 +978,12 @@ export class NixieCircuitCommands extends CircuitCommands {
|
|
|
888
978
|
return Promise.resolve(state.lightGroups.getItemById(id));
|
|
889
979
|
}
|
|
890
980
|
let cstate = state.circuits.getItemById(id);
|
|
981
|
+
if (state.mode !== 0) return cstate;
|
|
891
982
|
let circ = sys.circuits.getItemById(id);
|
|
892
983
|
let thm = sys.board.valueMaps.lightThemes.findItem(theme);
|
|
893
984
|
if (typeof thm !== 'undefined' && typeof thm.sequence !== 'undefined' && circ.master === 1) {
|
|
894
985
|
logger.info(`Setting light theme for ${circ.name} to ${thm.name} [${thm.sequence}]`);
|
|
895
|
-
await
|
|
896
|
-
await ncp.circuits.sendOnOffSequenceAsync(id, thm.sequence);
|
|
986
|
+
await ncp.circuits.setLightThemeAsync(id, thm);
|
|
897
987
|
}
|
|
898
988
|
cstate.lightingTheme = theme;
|
|
899
989
|
return Promise.resolve(cstate as ICircuitState);
|
|
@@ -1185,7 +1275,7 @@ export class NixieCircuitCommands extends CircuitCommands {
|
|
|
1185
1275
|
await sys.board.circuits.setLightThemeAsync(c.circuit, theme);
|
|
1186
1276
|
await sys.board.circuits.setCircuitStateAsync(c.circuit, false);
|
|
1187
1277
|
}
|
|
1188
|
-
await
|
|
1278
|
+
await setTimeout(5000);
|
|
1189
1279
|
// Turn the circuits all back on again.
|
|
1190
1280
|
for (let i = 0; i < grp.circuits.length; i++) {
|
|
1191
1281
|
let c = grp.circuits.getItemByIndex(i);
|
|
@@ -1231,6 +1321,7 @@ export class NixieCircuitCommands extends CircuitCommands {
|
|
|
1231
1321
|
//}
|
|
1232
1322
|
public async sequenceLightGroupAsync(id: number, operation: string): Promise<LightGroupState> {
|
|
1233
1323
|
let sgroup = state.lightGroups.getItemById(id);
|
|
1324
|
+
if (state.mode !== 0) return sgroup;
|
|
1234
1325
|
let grp = sys.lightGroups.getItemById(id);
|
|
1235
1326
|
let nop = sys.board.valueMaps.circuitActions.getValue(operation);
|
|
1236
1327
|
try {
|
|
@@ -1242,7 +1333,7 @@ export class NixieCircuitCommands extends CircuitCommands {
|
|
|
1242
1333
|
let c = grp.circuits.getItemByIndex(i);
|
|
1243
1334
|
await sys.board.circuits.setCircuitStateAsync(c.circuit, false);
|
|
1244
1335
|
}
|
|
1245
|
-
await
|
|
1336
|
+
await setTimeout(10000);
|
|
1246
1337
|
// Turn the circuits all back on again.
|
|
1247
1338
|
for (let i = 0; i < grp.circuits.length; i++) {
|
|
1248
1339
|
let c = grp.circuits.getItemByIndex(i);
|
|
@@ -1252,12 +1343,12 @@ export class NixieCircuitCommands extends CircuitCommands {
|
|
|
1252
1343
|
case 'colorset':
|
|
1253
1344
|
sgroup.action = nop;
|
|
1254
1345
|
sgroup.emitEquipmentChange();
|
|
1255
|
-
await
|
|
1346
|
+
await setTimeout(5000);
|
|
1256
1347
|
break;
|
|
1257
1348
|
case 'colorswim':
|
|
1258
1349
|
sgroup.action = nop;
|
|
1259
1350
|
sgroup.emitEquipmentChange();
|
|
1260
|
-
await
|
|
1351
|
+
await setTimeout(5000);
|
|
1261
1352
|
break;
|
|
1262
1353
|
}
|
|
1263
1354
|
return sgroup;
|
|
@@ -1268,18 +1359,29 @@ export class NixieCircuitCommands extends CircuitCommands {
|
|
|
1268
1359
|
let grp = sys.circuitGroups.getItemById(id, false, { isActive: false });
|
|
1269
1360
|
if (grp.dataName !== 'circuitGroupConfig') return await sys.board.circuits.setLightGroupStateAsync(id, val);
|
|
1270
1361
|
let gstate = state.circuitGroups.getItemById(grp.id, grp.isActive !== false);
|
|
1362
|
+
if (state.mode !== 0) return gstate;
|
|
1271
1363
|
let circuits = grp.circuits.toArray();
|
|
1272
1364
|
sys.board.circuits.setEndTime(sys.circuits.getInterfaceById(gstate.id), gstate, val);
|
|
1273
1365
|
gstate.isOn = val;
|
|
1274
1366
|
let arr = [];
|
|
1275
1367
|
for (let i = 0; i < circuits.length; i++) {
|
|
1276
|
-
let circuit = circuits[i];
|
|
1368
|
+
let circuit:CircuitGroupCircuit = circuits[i];
|
|
1277
1369
|
// The desiredState will be as follows.
|
|
1278
1370
|
// 1 = on, 2 = off, 3 = ignore.
|
|
1279
1371
|
let cval = true;
|
|
1280
1372
|
if (circuit.desiredState === 1) cval = val ? true : false;
|
|
1281
1373
|
else if (circuit.desiredState === 2) cval = val ? false : true;
|
|
1282
|
-
else continue;
|
|
1374
|
+
else if (circuit.desiredState === 3) continue;
|
|
1375
|
+
else if (circuit.desiredState === 4){
|
|
1376
|
+
// on/ignore
|
|
1377
|
+
if (val) cval = true;
|
|
1378
|
+
else continue;
|
|
1379
|
+
}
|
|
1380
|
+
else if (circuit.desiredState === 5){
|
|
1381
|
+
// off/ignore
|
|
1382
|
+
if (val) cval = false;
|
|
1383
|
+
else continue;
|
|
1384
|
+
}
|
|
1283
1385
|
await sys.board.circuits.setCircuitStateAsync(circuit.circuit, cval);
|
|
1284
1386
|
//arr.push(sys.board.circuits.setCircuitStateAsync(circuit.circuit, cval));
|
|
1285
1387
|
}
|
|
@@ -1293,6 +1395,7 @@ export class NixieCircuitCommands extends CircuitCommands {
|
|
|
1293
1395
|
let grp = sys.circuitGroups.getItemById(id, false, { isActive: false });
|
|
1294
1396
|
if (grp.dataName === 'circuitGroupConfig') return await sys.board.circuits.setCircuitGroupStateAsync(id, val);
|
|
1295
1397
|
let gstate = state.lightGroups.getItemById(grp.id, grp.isActive !== false);
|
|
1398
|
+
if (state.mode !== 0) return gstate;
|
|
1296
1399
|
let circuits = grp.circuits.toArray();
|
|
1297
1400
|
sys.board.circuits.setEndTime(grp, gstate, val);
|
|
1298
1401
|
gstate.isOn = val;
|
|
@@ -1362,6 +1465,7 @@ export class NixieFeatureCommands extends FeatureCommands {
|
|
|
1362
1465
|
let feature = sys.features.getItemById(id);
|
|
1363
1466
|
let fstate = state.features.getItemById(feature.id, feature.isActive !== false);
|
|
1364
1467
|
feature.master = 1;
|
|
1468
|
+
if (state.mode !== 0) return fstate;
|
|
1365
1469
|
let ftype = sys.board.valueMaps.featureFunctions.getName(feature.type);
|
|
1366
1470
|
if(val && !fstate.isOn) sys.board.circuits.setEndTime(feature, fstate, val);
|
|
1367
1471
|
switch (ftype) {
|
|
@@ -1441,11 +1545,11 @@ export class NixieFeatureCommands extends FeatureCommands {
|
|
|
1441
1545
|
if (!ignoreDelays && sys.general.options.pumpDelay && sys.general.options.valveDelayTime > 0) sys.board.pumps.setPumpValveDelays([id, 1, 6]);
|
|
1442
1546
|
}
|
|
1443
1547
|
}
|
|
1444
|
-
logger.verbose(`Turning ${val ? 'on' : 'off'} a spa drain
|
|
1548
|
+
logger.verbose(`Turning ${val ? 'on' : 'off'} a spa drain feature ${cstate.name}`);
|
|
1445
1549
|
cstate.isOn = val;
|
|
1446
1550
|
}
|
|
1447
1551
|
return cstate;
|
|
1448
|
-
} catch (err) { logger.error(`Nixie: Error
|
|
1552
|
+
} catch (err) { logger.error(`Nixie: Error setDrainFeatureStateAsync ${err.message}`); return Promise.reject(new BoardProcessError(`Nixie: Error setDrainFeatureStateAsync ${err.message}`, 'setDrainFeatureStateAsync')); }
|
|
1449
1553
|
}
|
|
1450
1554
|
|
|
1451
1555
|
public async toggleFeatureStateAsync(id: number): Promise<ICircuitState> {
|
|
@@ -1467,10 +1571,14 @@ export class NixieFeatureCommands extends FeatureCommands {
|
|
|
1467
1571
|
for (let j = 0; j < circuits.length && bIsOn === true; j++) {
|
|
1468
1572
|
let circuit: CircuitGroupCircuit = grp.circuits.getItemByIndex(j);
|
|
1469
1573
|
let cstate = state.circuits.getInterfaceById(circuit.circuit);
|
|
1470
|
-
|
|
1574
|
+
// RSG: desiredState for Nixie is 1=on, 2=off, 3=ignore
|
|
1575
|
+
if (circuit.desiredState === 1 || circuit.desiredState === 4) {
|
|
1576
|
+
// The circuit should be on if the value is 1.
|
|
1577
|
+
// If we are on 'ignore' we should still only treat the circuit as
|
|
1578
|
+
// desiredstate = 1.
|
|
1471
1579
|
if (!utils.makeBool(cstate.isOn)) bIsOn = false;
|
|
1472
1580
|
}
|
|
1473
|
-
else if (circuit.desiredState ===
|
|
1581
|
+
else if (circuit.desiredState === 2 || circuit.desiredState === 5) { // The circuit should be off.
|
|
1474
1582
|
if (utils.makeBool(cstate.isOn)) bIsOn = false;
|
|
1475
1583
|
}
|
|
1476
1584
|
}
|
|
@@ -1521,23 +1629,28 @@ export class NixiePumpCommands extends PumpCommands {
|
|
|
1521
1629
|
let pstate = state.pumps.getItemById(pump.id);
|
|
1522
1630
|
let pt = sys.board.valueMaps.pumpTypes.get(pump.type);
|
|
1523
1631
|
|
|
1524
|
-
// [1, { name: 'ss', desc: 'Single Speed', maxCircuits: 0, hasAddress: false, hasBody: true, maxRelays: 1 }],
|
|
1632
|
+
// Old - [1, { name: 'ss', desc: 'Single Speed', maxCircuits: 0, hasAddress: false, hasBody: true, maxRelays: 1 }],
|
|
1633
|
+
// New 07/22 - [1, { name: 'ss', desc: 'Single Speed', maxCircuits: 8, hasAddress: false, hasBody: false, maxRelays: 1, relays: [{ id: 1, name: 'Pump On/Off' }]}],
|
|
1525
1634
|
// [2, { name: 'ds', desc: 'Two Speed', maxCircuits: 8, hasAddress: false, hasBody: false, maxRelays: 2 }],
|
|
1526
1635
|
// [3, { name: 'vs', desc: 'Intelliflo VS', maxPrimingTime: 6, minSpeed: 450, maxSpeed: 3450, maxCircuits: 8, hasAddress: true }],
|
|
1527
1636
|
// [4, { name: 'vsf', desc: 'Intelliflo VSF', minSpeed: 450, maxSpeed: 3450, minFlow: 15, maxFlow: 130, maxCircuits: 8, hasAddress: true }],
|
|
1528
1637
|
// [5, { name: 'vf', desc: 'Intelliflo VF', minFlow: 15, maxFlow: 130, maxCircuits: 8, hasAddress: true }],
|
|
1529
1638
|
// [100, { name: 'sf', desc: 'SuperFlo VS', hasAddress: false, maxCircuits: 8, maxRelays: 4, equipmentMaster: 1 }]
|
|
1530
1639
|
switch (pt.name) {
|
|
1531
|
-
case 'ss':
|
|
1532
|
-
//
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1640
|
+
case 'ss':{
|
|
1641
|
+
// rsg - ss now has circuit assignments. will check but still leave existing code
|
|
1642
|
+
if (pt.maxCircuits === 0 || typeof pump.body !== 'undefined'){
|
|
1643
|
+
// If a single speed pump is designated it will be the filter pump but we need to map any settings
|
|
1644
|
+
// to bodies.
|
|
1645
|
+
console.log(`Body: ${pump.body} Pump: ${pump.name} Pool: ${circuitIds.includes(6)} `);
|
|
1646
|
+
if ((pump.body === 255 && (circuitIds.includes(6) || circuitIds.includes(1))) ||
|
|
1536
1647
|
(pump.body === 0 && circuitIds.includes(6)) ||
|
|
1537
1648
|
(pump.body === 101 && circuitIds.includes(1))) {
|
|
1538
|
-
|
|
1649
|
+
delayMgr.setPumpValveDelay(pstate);
|
|
1650
|
+
}
|
|
1651
|
+
break;
|
|
1539
1652
|
}
|
|
1540
|
-
|
|
1653
|
+
}
|
|
1541
1654
|
default:
|
|
1542
1655
|
if (pt.maxCircuits > 0) {
|
|
1543
1656
|
for (let j = 0; j < pump.circuits.length; j++) {
|
|
@@ -1650,6 +1763,7 @@ export class NixieHeaterCommands extends HeaterCommands {
|
|
|
1650
1763
|
let gasHeaterInstalled = htypes.gas > 0;
|
|
1651
1764
|
let ultratempInstalled = htypes.ultratemp > 0;
|
|
1652
1765
|
let mastertempInstalled = htypes.mastertemp > 0;
|
|
1766
|
+
let hybridInstalled = htypes.hybrid > 0;
|
|
1653
1767
|
// The heat mode options are
|
|
1654
1768
|
// 1 = Off
|
|
1655
1769
|
// 2 = Gas Heater
|
|
@@ -1669,8 +1783,37 @@ export class NixieHeaterCommands extends HeaterCommands {
|
|
|
1669
1783
|
// 3 = Solar Heater
|
|
1670
1784
|
// 4 = Solar Preferred
|
|
1671
1785
|
// 5 = Heat Pump
|
|
1672
|
-
|
|
1673
1786
|
if (sys.heaters.length > 0) sys.board.valueMaps.heatSources = new byteValueMap([[1, { name: 'off', desc: 'Off' }]]);
|
|
1787
|
+
sys.board.valueMaps.heatModes = new byteValueMap([[1, { name: 'off', desc: 'Off' }]]);
|
|
1788
|
+
if (hybridInstalled) {
|
|
1789
|
+
sys.board.valueMaps.heatModes.merge([
|
|
1790
|
+
[7, { name: 'hybheat', desc: 'Gas Only' }],
|
|
1791
|
+
[8, { name: 'hybheatpump', desc: 'Heat Pump Only' }],
|
|
1792
|
+
[9, { name: 'hybhybrid', desc: 'Hybrid' }],
|
|
1793
|
+
[10, { name: 'hybdual', desc: 'Dual Heat' }]
|
|
1794
|
+
]);
|
|
1795
|
+
sys.board.valueMaps.heatSources.merge([
|
|
1796
|
+
[7, { name: 'hybheat', desc: 'Gas Only' }],
|
|
1797
|
+
[8, { name: 'hybheatpump', desc: 'Heat Pump Only' }],
|
|
1798
|
+
[9, { name: 'hybhybrid', desc: 'Hybrid' }],
|
|
1799
|
+
[10, { name: 'hybdual', desc: 'Dual Heat' }]
|
|
1800
|
+
]);
|
|
1801
|
+
// RKS: 08-24-22 The heat modes and sources for the hybrid heater are unique. Turns out that
|
|
1802
|
+
// these should be available if there is a gas heater ganged to the body as well.
|
|
1803
|
+
// types cannot be ignored since they are specific to the heater.
|
|
1804
|
+
//sys.board.valueMaps.heatModes.merge([
|
|
1805
|
+
// [9, { name: 'heatpump', desc: 'Heat Pump' }],
|
|
1806
|
+
// [2, { name: 'heater', desc: 'Heater' }],
|
|
1807
|
+
// [25, { name: 'heatpumppref', desc: 'Hybrid' }],
|
|
1808
|
+
// [26, { name: 'dual', desc: 'Dual Heat' }]
|
|
1809
|
+
//]);
|
|
1810
|
+
//sys.board.valueMaps.heatSources.merge([
|
|
1811
|
+
// [2, { name: 'heater', desc: 'Gas Heat' }],
|
|
1812
|
+
// [9, { name: 'heatpump', desc: 'Heat Pump' }],
|
|
1813
|
+
// [20, { name: 'heatpumppref', desc: 'Hybrid' }],
|
|
1814
|
+
// [21, { name: 'dual', desc: 'Dual Heat' }]
|
|
1815
|
+
//]);
|
|
1816
|
+
}
|
|
1674
1817
|
if (gasHeaterInstalled) sys.board.valueMaps.heatSources.merge([[2, { name: 'heater', desc: 'Heater' }]]);
|
|
1675
1818
|
if (mastertempInstalled) sys.board.valueMaps.heatSources.merge([[11, { name: 'mtheater', desc: 'MasterTemp' }]]);
|
|
1676
1819
|
if (solarInstalled && (gasHeaterInstalled || heatPumpInstalled)) sys.board.valueMaps.heatSources.merge([[3, { name: 'solar', desc: 'Solar Only', hasCoolSetpoint: htypes.hasCoolSetpoint }], [4, { name: 'solarpref', desc: 'Solar Preferred', hasCoolSetpoint: htypes.hasCoolSetpoint }]]);
|
|
@@ -1681,7 +1824,7 @@ export class NixieHeaterCommands extends HeaterCommands {
|
|
|
1681
1824
|
else if (ultratempInstalled) sys.board.valueMaps.heatSources.merge([[5, { name: 'ultratemp', desc: 'UltraTemp', hasCoolSetpoint: htypes.hasCoolSetpoint }]]);
|
|
1682
1825
|
sys.board.valueMaps.heatSources.merge([[0, { name: 'nochange', desc: 'No Change' }]]);
|
|
1683
1826
|
|
|
1684
|
-
|
|
1827
|
+
|
|
1685
1828
|
if (gasHeaterInstalled) sys.board.valueMaps.heatModes.merge([[2, { name: 'heater', desc: 'Heater' }]]);
|
|
1686
1829
|
if (mastertempInstalled) sys.board.valueMaps.heatModes.merge([[11, { name: 'mtheater', desc: 'MasterTemp' }]]);
|
|
1687
1830
|
if (solarInstalled && (gasHeaterInstalled || heatPumpInstalled || mastertempInstalled)) sys.board.valueMaps.heatModes.merge([[3, { name: 'solar', desc: 'Solar Only' }], [4, { name: 'solarpref', desc: 'Solar Preferred' }]]);
|