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.
Files changed (82) hide show
  1. package/.eslintrc.json +26 -35
  2. package/Changelog +22 -0
  3. package/README.md +7 -3
  4. package/anslq25/MessagesMock.ts +218 -0
  5. package/anslq25/boards/MockBoardFactory.ts +50 -0
  6. package/anslq25/boards/MockEasyTouchBoard.ts +696 -0
  7. package/anslq25/boards/MockSystemBoard.ts +217 -0
  8. package/anslq25/chemistry/MockChlorinator.ts +75 -0
  9. package/anslq25/pumps/MockPump.ts +84 -0
  10. package/app.ts +10 -14
  11. package/config/Config.ts +13 -9
  12. package/config/VersionCheck.ts +6 -2
  13. package/controller/Constants.ts +58 -25
  14. package/controller/Equipment.ts +224 -41
  15. package/controller/Errors.ts +2 -1
  16. package/controller/Lockouts.ts +34 -2
  17. package/controller/State.ts +491 -48
  18. package/controller/boards/AquaLinkBoard.ts +6 -3
  19. package/controller/boards/BoardFactory.ts +5 -1
  20. package/controller/boards/EasyTouchBoard.ts +1971 -1751
  21. package/controller/boards/IntelliCenterBoard.ts +1311 -1688
  22. package/controller/boards/IntelliComBoard.ts +7 -1
  23. package/controller/boards/IntelliTouchBoard.ts +153 -42
  24. package/controller/boards/NixieBoard.ts +209 -66
  25. package/controller/boards/SunTouchBoard.ts +393 -0
  26. package/controller/boards/SystemBoard.ts +1862 -1543
  27. package/controller/comms/Comms.ts +539 -138
  28. package/controller/comms/ScreenLogic.ts +1663 -0
  29. package/controller/comms/messages/Messages.ts +242 -60
  30. package/controller/comms/messages/config/ChlorinatorMessage.ts +4 -3
  31. package/controller/comms/messages/config/CircuitGroupMessage.ts +5 -2
  32. package/controller/comms/messages/config/CircuitMessage.ts +81 -13
  33. package/controller/comms/messages/config/ConfigMessage.ts +3 -1
  34. package/controller/comms/messages/config/CoverMessage.ts +2 -1
  35. package/controller/comms/messages/config/CustomNameMessage.ts +2 -1
  36. package/controller/comms/messages/config/EquipmentMessage.ts +5 -1
  37. package/controller/comms/messages/config/ExternalMessage.ts +33 -3
  38. package/controller/comms/messages/config/FeatureMessage.ts +2 -1
  39. package/controller/comms/messages/config/GeneralMessage.ts +2 -1
  40. package/controller/comms/messages/config/HeaterMessage.ts +3 -1
  41. package/controller/comms/messages/config/IntellichemMessage.ts +2 -1
  42. package/controller/comms/messages/config/OptionsMessage.ts +12 -6
  43. package/controller/comms/messages/config/PumpMessage.ts +9 -12
  44. package/controller/comms/messages/config/RemoteMessage.ts +80 -13
  45. package/controller/comms/messages/config/ScheduleMessage.ts +43 -3
  46. package/controller/comms/messages/config/SecurityMessage.ts +2 -1
  47. package/controller/comms/messages/config/ValveMessage.ts +43 -26
  48. package/controller/comms/messages/status/ChlorinatorStateMessage.ts +8 -7
  49. package/controller/comms/messages/status/EquipmentStateMessage.ts +93 -20
  50. package/controller/comms/messages/status/HeaterStateMessage.ts +24 -5
  51. package/controller/comms/messages/status/IntelliChemStateMessage.ts +7 -4
  52. package/controller/comms/messages/status/IntelliValveStateMessage.ts +2 -1
  53. package/controller/comms/messages/status/PumpStateMessage.ts +72 -4
  54. package/controller/comms/messages/status/VersionMessage.ts +2 -1
  55. package/controller/nixie/Nixie.ts +15 -4
  56. package/controller/nixie/NixieEquipment.ts +1 -0
  57. package/controller/nixie/chemistry/ChemController.ts +300 -129
  58. package/controller/nixie/chemistry/ChemDoser.ts +806 -0
  59. package/controller/nixie/chemistry/Chlorinator.ts +133 -129
  60. package/controller/nixie/circuits/Circuit.ts +171 -30
  61. package/controller/nixie/heaters/Heater.ts +337 -173
  62. package/controller/nixie/pumps/Pump.ts +264 -236
  63. package/controller/nixie/schedules/Schedule.ts +9 -3
  64. package/defaultConfig.json +45 -5
  65. package/logger/Logger.ts +38 -9
  66. package/package.json +13 -9
  67. package/web/Server.ts +235 -122
  68. package/web/bindings/aqualinkD.json +114 -59
  69. package/web/bindings/homeassistant.json +437 -0
  70. package/web/bindings/influxDB.json +15 -0
  71. package/web/bindings/mqtt.json +28 -9
  72. package/web/bindings/mqttAlt.json +15 -0
  73. package/web/interfaces/baseInterface.ts +58 -7
  74. package/web/interfaces/httpInterface.ts +5 -2
  75. package/web/interfaces/influxInterface.ts +9 -2
  76. package/web/interfaces/mqttInterface.ts +234 -74
  77. package/web/interfaces/ruleInterface.ts +87 -0
  78. package/web/services/config/Config.ts +140 -33
  79. package/web/services/config/ConfigSocket.ts +2 -1
  80. package/web/services/state/State.ts +144 -3
  81. package/web/services/state/StateSocket.ts +65 -14
  82. 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. Russell Goldin, tagyoureit. russ.goldin@gmail.com
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
@@ -29,6 +30,10 @@ export class IntelliComBoard extends EasyTouchBoard {
29
30
  ]);
30
31
  }
31
32
  public initExpansionModules(byte1: number, byte2: number) {
33
+ switch (byte1) {
34
+ case 40: // This is a SunTouch
35
+ break;
36
+ }
32
37
  console.log(`Pentair IntelliCom System Detected!`);
33
38
 
34
39
  sys.equipment.model = 'Suntouch/Intellicom';
@@ -49,6 +54,7 @@ export class IntelliComBoard extends EasyTouchBoard {
49
54
  eq.maxPumps = md.maxPumps = typeof mt.pumps !== 'undefined' ? mt.pumps : 2;
50
55
  eq.shared = mt.shared;
51
56
  eq.dual = false;
57
+ eq.single = true;
52
58
  eq.maxChlorinators = md.chlorinators = 1;
53
59
  eq.maxChemControllers = md.chemControllers = 1;
54
60
  eq.maxCustomNames = 10;
@@ -1,5 +1,6 @@
1
1
  /* nodejs-poolController. An application to control pool equipment.
2
- Copyright (C) 2016, 2017, 2018, 2019, 2020. Russell Goldin, tagyoureit. russ.goldin@gmail.com
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
@@ -14,7 +15,7 @@ GNU Affero General Public License for more details.
14
15
  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
- import { byteValueMap } from './SystemBoard';
18
+ import { byteValueMap, EquipmentIdRange, } from './SystemBoard';
18
19
  import { logger } from '../../logger/Logger';
19
20
  import { EasyTouchBoard, TouchConfigQueue, GetTouchConfigCategories, TouchCircuitCommands } from './EasyTouchBoard';
20
21
  import { state, ICircuitGroupState } from '../State';
@@ -22,24 +23,98 @@ import { PoolSystem, sys, ExpansionPanel, Equipment } from '../Equipment';
22
23
 
23
24
  import { conn } from '../comms/Comms';
24
25
  import { InvalidEquipmentDataError } from '../Errors';
26
+ import { log } from 'winston';
25
27
 
26
28
  export class IntelliTouchBoard extends EasyTouchBoard {
27
29
  constructor(system: PoolSystem) {
28
30
  super(system);
31
+ // Circuits even in single body IntelliTouch always start at 1.
32
+ this.equipmentIds.circuits.start = 1;
29
33
  this.equipmentIds.features.start = 41;
30
34
  this.equipmentIds.features.end = 50;
35
+ this.equipmentIds.virtualCircuits = new EquipmentIdRange(154, 162);
31
36
  this._configQueue = new ITTouchConfigQueue();
32
37
  this.valueMaps.expansionBoards = new byteValueMap([
33
38
  [0, { name: 'IT5', part: 'i5+3', desc: 'IntelliTouch i5+3', circuits: 6, shared: true }],
34
39
  [1, { name: 'IT7', part: 'i7+3', desc: 'IntelliTouch i7+3', circuits: 8, shared: true }],
35
40
  [2, { name: 'IT9', part: 'i9+3', desc: 'IntelliTouch i9+3', circuits: 10, shared: true }],
36
- [3, { name: 'IT5S', part: 'i5+3S', desc: 'IntelliTouch i5+3S', circuits: 5, shared: false, bodies: 2, intakeReturnValves: false }],
37
- [4, { name: 'IT9S', part: 'i9+3S', desc: 'IntelliTouch i9+3S', circuits: 9, shared: false, bodies: 2, intakeReturnValves: false }],
38
- [5, { name: 'IT10D', part: 'i10D', desc: 'IntelliTouch i10D', circuits: 10, shared: false, dual: true }],
41
+ [3, { name: 'IT5S', part: 'i5+3S', desc: 'IntelliTouch i5+3S', circuits: 5, single: true, shared: true, bodies: 2, intakeReturnValves: false }],
42
+ [4, { name: 'IT9S', part: 'i9+3S', desc: 'IntelliTouch i9+3S', circuits: 9, single: true, shared: true, bodies: 2, intakeReturnValves: false }],
43
+ [5, { name: 'IT10D', part: 'i10D', desc: 'IntelliTouch i10D', circuits: 10, single: true, shared: false, dual: true }],
39
44
  [32, { name: 'IT5X', part: 'i5X', desc: 'IntelliTouch i5X', circuits: 5 }],
40
45
  [33, { name: 'IT10X', part: 'i10X', desc: 'IntelliTouch i10X', circuits: 10 }],
41
46
  [64, { name: 'Valve Exp', part: '520285', desc: 'Valve Expansion Module', valves: 3 }]
42
47
  ]);
48
+ // I don't think these have ever been right.
49
+ // So far I have seen below based on discussion #436
50
+ // 155 = heater
51
+ // 156 = poolheater
52
+ // 157 = spaheater
53
+ this.valueMaps.virtualCircuits = new byteValueMap([
54
+ [154, { name: 'freeze', desc: 'Freeze', assignableToPumpCircuit: true }],
55
+ [155, { name: 'spaHeater', desc: 'Spa Heater', assignableToPumpCircuit: true }],
56
+ [156, { name: 'poolHeater', desc: 'Pool Heater', assignableToPumpCircuit: true }],
57
+ [157, { name: 'heater', desc: 'Either Heater', assignableToPumpCircuit: true }],
58
+ [158, { name: 'solar', desc: 'Solar', assignableToPumpCircuit: true }],
59
+ [159, { name: 'heatBoost', desc: 'Heat Boost', assignableToPumpCircuit: false }],
60
+ [160, { name: 'heatEnable', desc: 'Heat Enable', assignableToPumpCircuit: false }],
61
+ [161, { name: 'pumpSpeedUp', desc: 'Pump Speed +', assignableToPumpCircuit: false }],
62
+ [162, { name: 'pumpSpeedDown', desc: 'Pump Speed -', assignableToPumpCircuit: false }],
63
+ [255, { name: 'notused', desc: 'NOT USED', assignableToPumpCircuit: true }],
64
+ [258, { name: 'anyHeater', desc: 'Any Heater' }]
65
+ ]);
66
+ }
67
+ public initVirtualCircuits() {
68
+ for (let i = state.virtualCircuits.length - 1; i >= 0; i--) {
69
+ let vc = state.virtualCircuits.getItemByIndex(i);
70
+ if (vc.id > this.equipmentIds.virtualCircuits.end ||
71
+ vc.id < this.equipmentIds.virtualCircuits.start) state.virtualCircuits.removeItemByIndex(i);
72
+ }
73
+ // Now that we removed all the virtual circuits that should not be there we need
74
+ // to update them based upon the data.
75
+ }
76
+ public initValves(eq) {
77
+ if (typeof sys.valves.find((v) => v.id === 1) === 'undefined') {
78
+ let valve = sys.valves.getItemById(1, true);
79
+ valve.isIntake = false;
80
+ valve.isReturn = false;
81
+ valve.type = 0;
82
+ valve.master = 0;
83
+ valve.isActive = true;
84
+ valve.name = 'Valve A';
85
+ logger.info(`Initializing IntelliTouch Valve A`);
86
+
87
+ }
88
+ if (typeof sys.valves.find((v) => v.id === 2) === 'undefined') {
89
+ let valve = sys.valves.getItemById(1, true);
90
+ valve.isIntake = false;
91
+ valve.isReturn = false;
92
+ valve.type = 0;
93
+ valve.master = 0;
94
+ valve.isActive = true;
95
+ valve.name = 'Valve B';
96
+ logger.info(`Initializing IntelliTouch Valve B`);
97
+ }
98
+ if (eq.intakeReturnValves) {
99
+ logger.info(`Initializing IntelliTouch Intake/Return Valves`);
100
+ let valve = sys.valves.getItemById(3, true);
101
+ valve.isIntake = true;
102
+ valve.isReturn = false;
103
+ valve.circuit = 6;
104
+ valve.type = 0;
105
+ valve.master = 0;
106
+ valve.isActive = true;
107
+ valve.name = 'Intake';
108
+
109
+ valve = sys.valves.getItemById(4, true);
110
+ valve.isIntake = false;
111
+ valve.isReturn = true;
112
+ valve.circuit = 6;
113
+ valve.type = 0;
114
+ valve.master = 0;
115
+ valve.isActive = true;
116
+ valve.name = 'Return';
117
+ }
43
118
  }
44
119
  public initExpansionModules(byte1: number, byte2: number) {
45
120
  console.log(`Pentair IntelliTouch System Detected!`);
@@ -57,30 +132,30 @@ export class IntelliTouchBoard extends EasyTouchBoard {
57
132
  let eq = sys.equipment;
58
133
  let md = mod.get();
59
134
 
60
- eq.maxBodies = md.bodies = typeof mt.bodies !== 'undefined' ? mt.bodies : mt.shared || mt.dual ? 2 : 1;
135
+ //eq.maxBodies = md.bodies = typeof mt.bodies !== 'undefined' ? mt.bodies : mt.shared || mt.dual ? 2 : 1;
136
+ // There are always 2 bodies on an IntelliTouch even the single body models.
137
+ eq.maxBodies = 2;
61
138
  eq.maxCircuits = md.circuits = typeof mt.circuits !== 'undefined' ? mt.circuits : 6;
62
139
  eq.maxFeatures = md.features = typeof mt.features !== 'undefined' ? mt.features : 8;
63
140
  eq.maxValves = md.valves = typeof mt.valves !== 'undefined' ? mt.valves : mt.shared ? 4 : 2;
64
141
  eq.maxPumps = md.maxPumps = typeof mt.pumps !== 'undefined' ? mt.pumps : 8;
65
142
  eq.shared = mt.shared;
66
143
  eq.dual = typeof mt.dual !== 'undefined' ? mt.dual : false;
67
- eq.intakeReturnValves = md.intakeReturnValves = typeof mt.intakeReturnValves !== 'undefined' ? mt.intakeReturnValves : false;
144
+ eq.single = typeof mt.single !== 'undefined' ? mt.single : false;
145
+ eq.intakeReturnValves = eq.single ? false : true;
68
146
  eq.maxChlorinators = md.chlorinators = 1;
69
147
  eq.maxChemControllers = md.chemControllers = 1;
70
148
  eq.maxCustomNames = 20;
149
+ eq.maxSchedules = 99;
71
150
  eq.maxCircuitGroups = 10; // Not sure why this is 10 other than to allow for those that we are in control of.
72
- if (!eq.shared && !eq.dual) {
151
+ if (eq.single) {
73
152
  // Replace the body types with Hi-Temp and Lo-Temp
74
153
  sys.board.valueMaps.bodyTypes.merge([[0, { name: 'pool', desc: 'Lo-Temp' }],
75
- [1, { name: 'spa', desc: 'Hi-Temp' }]]);
154
+ [1, { name: 'spa', desc: 'Hi-Temp' }]]);
76
155
  }
77
156
  // Calculate out the invalid ids.
78
- // sys.board.equipmentIds.invalidIds.set([]);
79
157
  // Add in all the invalid ids from the base personality board.
80
158
  sys.board.equipmentIds.invalidIds.set([16, 17, 18]); // These appear to alway be invalid in IntelliTouch.
81
- // RGS 10-7-21: Since single bodies have hi-temp/lo-temp we will always want ID 1.
82
- // if (!eq.shared) sys.board.equipmentIds.invalidIds.merge([1]);
83
- //if (eq.maxCircuits < 9) sys.board.equipmentIds.invalidIds.merge([9]);
84
159
  for (let i = 7; i <= 10; i++) {
85
160
  // This will add all the invalid ids between 7 and 10 that are omitted for IntelliTouch models.
86
161
  // For instance an i7+3 can have up to 8 circuits since 1 and 6 are shared but an i7+3S will only have 7.
@@ -136,7 +211,6 @@ export class IntelliTouchBoard extends EasyTouchBoard {
136
211
  if (byte1 !== 14) sys.board.equipmentIds.invalidIds.merge([10, 19]);
137
212
  state.equipment.model = sys.equipment.model = mt.desc;
138
213
  state.equipment.controllerType = 'intellitouch';
139
- sys.equipment.shared ? sys.board.equipmentIds.circuits.start = 1 : sys.board.equipmentIds.circuits.start = 2;
140
214
  this.initBodyDefaults();
141
215
  this.initHeaterDefaults();
142
216
  (async () => {
@@ -152,10 +226,22 @@ export class IntelliTouchBoard extends EasyTouchBoard {
152
226
  let v = sys.valves.getItemByIndex(i);
153
227
  if (v.id < 50) v.master = 0;
154
228
  }
155
- for (let i = 0; i < sys.bodies.length; i++) {
156
- let b = sys.bodies.getItemByIndex(i);
157
- b.master = 0;
229
+ // Clean up any schedules that shouldn't be there.
230
+ for (let i = sys.schedules.length - 1; i > 0; i--) {
231
+ let sched = sys.schedules.getItemByIndex(i);
232
+ if (sched.id < 1) {
233
+ sys.schedules.removeItemByIndex(i);
234
+ state.schedules.removeItemById(sched.id);
235
+ }
236
+ if (sched.id < eq.maxSchedules) sched.master = 0;
237
+ else if (sched.id > eq.maxSchedules && (sched.master === 0 || typeof sched.master === 'undefined')) {
238
+ sys.schedules.removeItemByIndex(i);
239
+ state.schedules.removeItemById(sched.id);
240
+ }
158
241
  }
242
+ eq.setEquipmentIds();
243
+ this.initVirtualCircuits();
244
+ this.initValves(eq);
159
245
  state.equipment.maxBodies = sys.equipment.maxBodies;
160
246
  state.equipment.maxCircuitGroups = sys.equipment.maxCircuitGroups;
161
247
  state.equipment.maxCircuits = sys.equipment.maxCircuits;
@@ -165,9 +251,12 @@ export class IntelliTouchBoard extends EasyTouchBoard {
165
251
  state.equipment.maxPumps = sys.equipment.maxPumps;
166
252
  state.equipment.maxSchedules = sys.equipment.maxSchedules;
167
253
  state.equipment.maxValves = sys.equipment.maxValves;
254
+ state.equipment.single = sys.equipment.single;
168
255
  state.equipment.shared = sys.equipment.shared;
169
256
  state.equipment.dual = sys.equipment.dual;
257
+
170
258
  state.emitControllerChange();
259
+
171
260
  }
172
261
  public circuits: ITTouchCircuitCommands = new ITTouchCircuitCommands(this);
173
262
  public async setControllerType(obj): Promise<Equipment> {
@@ -223,35 +312,57 @@ export class IntelliTouchBoard extends EasyTouchBoard {
223
312
  logger.error(`Error setting expansion panels: ${err.message}`);
224
313
  }
225
314
  }
315
+ public initBodyDefaults() {
316
+ // Initialize the bodies. We will need these very soon.
317
+ for (let i = 1; i <= sys.equipment.maxBodies; i++) {
318
+ // Add in the bodies for the configuration. These need to be set.
319
+ let cbody = sys.bodies.getItemById(i, true);
320
+ let tbody = state.temps.bodies.getItemById(i, true);
321
+ cbody.isActive = true;
322
+ // If the body doesn't represent a spa then we set the type.
323
+ tbody.type = cbody.type = i - 1; // This will set the first body to pool/Lo-Temp and the second body to spa/Hi-Temp.
324
+ if (typeof cbody.name === 'undefined') {
325
+ let bt = sys.board.valueMaps.bodyTypes.transform(cbody.type);
326
+ tbody.name = cbody.name = bt.desc;
327
+ }
328
+ }
329
+ sys.bodies.removeItemById(3);
330
+ sys.bodies.removeItemById(4);
331
+ state.temps.bodies.removeItemById(3);
332
+ state.temps.bodies.removeItemById(4);
333
+ for (let i = 0; i < sys.bodies.length; i++) {
334
+ let b = sys.bodies.getItemByIndex(i);
335
+ b.master = 0;
336
+ }
337
+ sys.board.heaters.initTempSensors();
338
+ sys.general.options.clockMode = sys.general.options.clockMode || 12;
339
+ sys.general.options.clockSource = sys.general.options.clockSource || 'manual';
340
+ }
226
341
  }
227
342
  class ITTouchConfigQueue extends TouchConfigQueue {
228
343
  public queueChanges() {
229
344
  this.reset();
230
- if (conn.mockPort) {
231
- logger.info(`Skipping configuration request from OCP because MockPort enabled.`);
232
- } else {
233
- logger.info(`Requesting ${sys.controllerType} configuration`);
234
- this.queueItems(GetTouchConfigCategories.dateTime, [0]);
235
- this.queueItems(GetTouchConfigCategories.heatTemperature, [0]);
236
- this.queueItems(GetTouchConfigCategories.solarHeatPump, [0]);
237
- this.queueRange(GetTouchConfigCategories.customNames, 0, sys.equipment.maxCustomNames - 1);
238
- this.queueRange(GetTouchConfigCategories.circuits, 1, sys.equipment.maxCircuits); // circuits
239
- this.queueRange(GetTouchConfigCategories.circuits, 41, 41 + sys.equipment.maxFeatures); // features
240
- this.queueRange(GetTouchConfigCategories.schedules, 1, sys.equipment.maxSchedules);
241
- this.queueItems(GetTouchConfigCategories.delays, [0]);
242
- this.queueItems(GetTouchConfigCategories.settings, [0]);
243
- this.queueItems(GetTouchConfigCategories.intellifloSpaSideRemotes, [0]);
244
- this.queueItems(GetTouchConfigCategories.is4is10, [0]);
245
- this.queueItems(GetTouchConfigCategories.spaSideRemote, [0]);
246
- this.queueItems(GetTouchConfigCategories.valves, [0]);
247
- this.queueItems(GetTouchConfigCategories.lightGroupPositions);
248
- this.queueItems(GetTouchConfigCategories.highSpeedCircuits, [0]);
249
- this.queueRange(GetTouchConfigCategories.pumpConfig, 1, sys.equipment.maxPumps);
250
- this.queueRange(GetTouchConfigCategories.circuitGroups, 0, sys.equipment.maxFeatures - 1);
251
- // items not required by ScreenLogic
252
- if (sys.chlorinators.getItemById(1).isActive)
253
- this.queueItems(GetTouchConfigCategories.intellichlor, [0]);
254
- }
345
+ logger.info(`Requesting ${sys.controllerType} configuration`);
346
+ this.queueItems(GetTouchConfigCategories.dateTime, [0]);
347
+ this.queueItems(GetTouchConfigCategories.heatTemperature, [0]);
348
+ this.queueItems(GetTouchConfigCategories.solarHeatPump, [0]);
349
+ this.queueRange(GetTouchConfigCategories.customNames, 0, sys.equipment.maxCustomNames - 1);
350
+ this.queueRange(GetTouchConfigCategories.circuits, 1, sys.equipment.maxCircuits); // circuits
351
+ this.queueRange(GetTouchConfigCategories.circuits, 41, 41 + sys.equipment.maxFeatures); // features
352
+ this.queueRange(GetTouchConfigCategories.schedules, 1, sys.equipment.maxSchedules);
353
+ this.queueItems(GetTouchConfigCategories.delays, [0]);
354
+ this.queueItems(GetTouchConfigCategories.settings, [0]);
355
+ this.queueItems(GetTouchConfigCategories.intellifloSpaSideRemotes, [0]);
356
+ this.queueItems(GetTouchConfigCategories.is4is10, [0]);
357
+ this.queueItems(GetTouchConfigCategories.quickTouchRemote, [0]);
358
+ this.queueItems(GetTouchConfigCategories.valves, [0]);
359
+ this.queueItems(GetTouchConfigCategories.lightGroupPositions);
360
+ this.queueItems(GetTouchConfigCategories.highSpeedCircuits, [0]);
361
+ this.queueRange(GetTouchConfigCategories.pumpConfig, 1, sys.equipment.maxPumps);
362
+ this.queueRange(GetTouchConfigCategories.circuitGroups, 0, sys.equipment.maxFeatures - 1);
363
+ // items not required by ScreenLogic
364
+ if (sys.chlorinators.getItemById(1).isActive)
365
+ this.queueItems(GetTouchConfigCategories.intellichlor, [0]);
255
366
  if (this.remainingItems > 0) {
256
367
  var self = this;
257
368
  setTimeout(() => { self.processNext(); }, 50);