nodejs-poolcontroller 7.3.0 → 7.6.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 (60) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +1 -1
  2. package/Changelog +23 -0
  3. package/README.md +5 -5
  4. package/app.ts +2 -0
  5. package/config/Config.ts +3 -0
  6. package/config/VersionCheck.ts +8 -4
  7. package/controller/Constants.ts +88 -0
  8. package/controller/Equipment.ts +246 -66
  9. package/controller/Errors.ts +24 -1
  10. package/controller/Lockouts.ts +423 -0
  11. package/controller/State.ts +314 -54
  12. package/controller/boards/EasyTouchBoard.ts +107 -59
  13. package/controller/boards/IntelliCenterBoard.ts +186 -125
  14. package/controller/boards/IntelliTouchBoard.ts +104 -30
  15. package/controller/boards/NixieBoard.ts +721 -159
  16. package/controller/boards/SystemBoard.ts +2370 -1108
  17. package/controller/comms/Comms.ts +85 -10
  18. package/controller/comms/messages/Messages.ts +10 -4
  19. package/controller/comms/messages/config/ChlorinatorMessage.ts +13 -4
  20. package/controller/comms/messages/config/CircuitGroupMessage.ts +6 -0
  21. package/controller/comms/messages/config/CoverMessage.ts +1 -0
  22. package/controller/comms/messages/config/EquipmentMessage.ts +4 -0
  23. package/controller/comms/messages/config/ExternalMessage.ts +44 -26
  24. package/controller/comms/messages/config/FeatureMessage.ts +8 -1
  25. package/controller/comms/messages/config/GeneralMessage.ts +8 -0
  26. package/controller/comms/messages/config/HeaterMessage.ts +15 -9
  27. package/controller/comms/messages/config/IntellichemMessage.ts +4 -1
  28. package/controller/comms/messages/config/OptionsMessage.ts +13 -1
  29. package/controller/comms/messages/config/PumpMessage.ts +4 -20
  30. package/controller/comms/messages/config/RemoteMessage.ts +4 -0
  31. package/controller/comms/messages/config/ScheduleMessage.ts +11 -0
  32. package/controller/comms/messages/config/SecurityMessage.ts +1 -0
  33. package/controller/comms/messages/config/ValveMessage.ts +13 -3
  34. package/controller/comms/messages/status/ChlorinatorStateMessage.ts +2 -3
  35. package/controller/comms/messages/status/EquipmentStateMessage.ts +78 -24
  36. package/controller/comms/messages/status/HeaterStateMessage.ts +42 -9
  37. package/controller/comms/messages/status/IntelliChemStateMessage.ts +37 -26
  38. package/controller/nixie/Nixie.ts +18 -16
  39. package/controller/nixie/bodies/Body.ts +4 -1
  40. package/controller/nixie/chemistry/ChemController.ts +80 -77
  41. package/controller/nixie/chemistry/Chlorinator.ts +9 -8
  42. package/controller/nixie/circuits/Circuit.ts +55 -6
  43. package/controller/nixie/heaters/Heater.ts +192 -32
  44. package/controller/nixie/pumps/Pump.ts +146 -84
  45. package/controller/nixie/schedules/Schedule.ts +3 -2
  46. package/controller/nixie/valves/Valve.ts +1 -1
  47. package/defaultConfig.json +32 -1
  48. package/issue_template.md +1 -1
  49. package/logger/DataLogger.ts +37 -22
  50. package/package.json +20 -18
  51. package/web/Server.ts +520 -29
  52. package/web/bindings/influxDB.json +96 -8
  53. package/web/bindings/mqtt.json +151 -40
  54. package/web/bindings/mqttAlt.json +114 -4
  55. package/web/interfaces/httpInterface.ts +2 -0
  56. package/web/interfaces/influxInterface.ts +36 -19
  57. package/web/interfaces/mqttInterface.ts +14 -3
  58. package/web/services/config/Config.ts +171 -44
  59. package/web/services/state/State.ts +49 -5
  60. package/web/services/state/StateSocket.ts +18 -1
@@ -14,16 +14,17 @@ GNU Affero General Public License for more details.
14
14
  You should have received a copy of the GNU Affero General Public License
15
15
  along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
  */
17
- import {byteValueMap} from './SystemBoard';
18
- import {logger} from '../../logger/Logger';
17
+ import { byteValueMap } from './SystemBoard';
18
+ import { logger } from '../../logger/Logger';
19
19
  import { EasyTouchBoard, TouchConfigQueue, GetTouchConfigCategories, TouchCircuitCommands } from './EasyTouchBoard';
20
20
  import { state, ICircuitGroupState } from '../State';
21
- import { PoolSystem, sys, ExpansionPanel, ExpansionModule } from '../Equipment';
22
- import { Protocol, Outbound, Message, Response } from '../comms/messages/Messages';
21
+ import { PoolSystem, sys, ExpansionPanel, Equipment } from '../Equipment';
22
+
23
+ import { conn } from '../comms/Comms';
24
+ import { InvalidEquipmentDataError } from '../Errors';
23
25
 
24
- import {conn} from '../comms/Comms';
25
26
  export class IntelliTouchBoard extends EasyTouchBoard {
26
- constructor (system: PoolSystem){
27
+ constructor(system: PoolSystem) {
27
28
  super(system);
28
29
  this.equipmentIds.features.start = 41;
29
30
  this.equipmentIds.features.end = 50;
@@ -32,10 +33,11 @@ export class IntelliTouchBoard extends EasyTouchBoard {
32
33
  [0, { name: 'IT5', part: 'i5+3', desc: 'IntelliTouch i5+3', circuits: 6, shared: true }],
33
34
  [1, { name: 'IT7', part: 'i7+3', desc: 'IntelliTouch i7+3', circuits: 8, shared: true }],
34
35
  [2, { name: 'IT9', part: 'i9+3', desc: 'IntelliTouch i9+3', circuits: 10, shared: true }],
35
- [3, { name: 'IT5S', part: 'i5+3S', desc: 'IntelliTouch i5+3S', circuits: 5, shared: false }],
36
- [4, { name: 'IT9S', part: 'i9+3S', desc: 'IntelliTouch i9+3S', circuits: 9, shared: false }],
36
+ [3, { name: 'IT5S', part: 'i5+3S', desc: 'IntelliTouch i5+3S', circuits: 5, shared: false, bodies: 1, intakeReturnValves: false }],
37
+ [4, { name: 'IT9S', part: 'i9+3S', desc: 'IntelliTouch i9+3S', circuits: 9, shared: false, bodies: 1, intakeReturnValves: false }],
37
38
  [5, { name: 'IT10D', part: 'i10D', desc: 'IntelliTouch i10D', circuits: 10, shared: false, dual: true }],
38
- [32, { name: 'IT10X', part: 'i10X', desc: 'IntelliTouch i10X', circuits: 10, shared: false }]
39
+ [32, { name: 'IT5X', part: 'i5X', desc: 'IntelliTouch i5X', circuits: 5 }],
40
+ [33, { name: 'IT10X', part: 'i10X', desc: 'IntelliTouch i10X', circuits: 10 }]
39
41
  ]);
40
42
  }
41
43
  public initExpansionModules(byte1: number, byte2: number) {
@@ -48,25 +50,28 @@ export class IntelliTouchBoard extends EasyTouchBoard {
48
50
  mod.type = byte1;
49
51
  mod.part = mt.part;
50
52
  let eq = sys.equipment;
53
+ let bd = sys.board;
51
54
  let md = mod.get();
52
55
 
53
56
  eq.maxBodies = md.bodies = typeof mt.bodies !== 'undefined' ? mt.bodies : mt.shared || mt.dual ? 2 : 1;
54
57
  eq.maxCircuits = md.circuits = typeof mt.circuits !== 'undefined' ? mt.circuits : 6;
55
- eq.maxFeatures = md.features = typeof mt.features !== 'undefined' ? mt.features : 10
58
+ eq.maxFeatures = md.features = typeof mt.features !== 'undefined' ? mt.features : 8;
56
59
  eq.maxValves = md.valves = typeof mt.valves !== 'undefined' ? mt.valves : mt.shared ? 4 : 2;
57
60
  eq.maxPumps = md.maxPumps = typeof mt.pumps !== 'undefined' ? mt.pumps : 8;
58
61
  eq.shared = mt.shared;
59
62
  eq.dual = typeof mt.dual !== 'undefined' ? mt.dual : false;
63
+ eq.intakeReturnValves = md.intakeReturnValves = typeof mt.intakeReturnValves !== 'undefined' ? mt.intakeReturnValves : false;
60
64
  eq.maxChlorinators = md.chlorinators = 1;
61
65
  eq.maxChemControllers = md.chemControllers = 1;
62
66
  eq.maxCustomNames = 20;
63
67
  eq.maxCircuitGroups = 10; // Not sure why this is 10 other than to allow for those that we are in control of.
64
68
 
65
69
  // Calculate out the invalid ids.
66
- sys.board.equipmentIds.invalidIds.set([]);
67
- if (!eq.shared) sys.board.equipmentIds.invalidIds.merge([1]);
70
+ // sys.board.equipmentIds.invalidIds.set([]);
68
71
  // Add in all the invalid ids from the base personality board.
69
72
  sys.board.equipmentIds.invalidIds.set([16, 17, 18]); // These appear to alway be invalid in IntelliTouch.
73
+ // RGS 10-7-21: Since single bodies have hi-temp/lo-temp we will always want ID 1.
74
+ // if (!eq.shared) sys.board.equipmentIds.invalidIds.merge([1]);
70
75
  //if (eq.maxCircuits < 9) sys.board.equipmentIds.invalidIds.merge([9]);
71
76
  for (let i = 7; i <= 10; i++) {
72
77
  // This will add all the invalid ids between 7 and 10 that are omitted for IntelliTouch models.
@@ -74,26 +79,42 @@ export class IntelliTouchBoard extends EasyTouchBoard {
74
79
  if (i > eq.maxCircuits) sys.board.equipmentIds.invalidIds.merge([i]);
75
80
  }
76
81
  // This code should be repeated if we ever see a panel with more than one expansion panel.
77
- let pnl: ExpansionPanel;
78
- pnl = sys.equipment.expansions.getItemById(1, true);
79
- pnl.type = byte2 & 0x20;
80
- pnl.name = pnl.type === 32 ? 'i10X' : 'none';
81
- pnl.isActive = pnl.type !== 0;
82
- // if type is i9 or i10 we can have up to 3 expansion boards. These expansion boards only add
83
- // circuits.
84
- if (pnl.isActive) {
85
- let emt = this.valueMaps.expansionBoards.transform(pnl.type);
86
- let emd = pnl.modules.getItemById(1, true).get();
87
- eq.maxCircuits += emd.circuits = typeof emt.circuits !== 'undefined' ? emt.circuits : 0;
82
+ let pnl1: ExpansionPanel;
83
+ if ((byte2 & 0x40) === 64) {
84
+ // 64 indicates one expansion panel; SL defaults to i10x but it could also be i5x until we know better
85
+ pnl1 = sys.equipment.expansions.getItemById(1, true);
86
+ pnl1.type = 32;
87
+ let emt = this.valueMaps.expansionBoards.transform(pnl1.type);
88
+ pnl1.name = emt.desc;
89
+ pnl1.isActive = true;
90
+ eq.maxCircuits += emt.circuits;
88
91
  }
89
- else pnl.modules.removeItemById(1);
90
-
92
+ else sys.equipment.expansions.removeItemById(1);
93
+ let pnl2: ExpansionPanel;
94
+ if ((byte2 & 0x80) === 128) {
95
+ // SL defaults to i5x but it could also be i10x until we know better
96
+ pnl2 = sys.equipment.expansions.getItemById(2, true);
97
+ pnl2.type = 32;
98
+ let emt = this.valueMaps.expansionBoards.transform(pnl2.type);
99
+ pnl2.name = emt.desc;
100
+ pnl2.isActive = true;
101
+ eq.maxCircuits += emt.circuits;
102
+ }
103
+ else sys.equipment.expansions.removeItemById(2);
104
+ let pnl3: ExpansionPanel;
105
+ if ((byte2 & 0xC0) === 192) {
106
+ // SL defaults to i5x but it could also be i10x until we know better
107
+ pnl3 = sys.equipment.expansions.getItemById(3, true);
108
+ pnl3.type = 32;
109
+ let emt = this.valueMaps.expansionBoards.transform(pnl3.type);
110
+ pnl3.name = emt.desc;
111
+ pnl3.isActive = true;
112
+ eq.maxCircuits += emt.circuits;
113
+ }
114
+ else sys.equipment.expansions.removeItemById(3);
91
115
  if (byte1 !== 14) sys.board.equipmentIds.invalidIds.merge([10, 19]);
92
116
  state.equipment.model = sys.equipment.model = mt.desc;
93
117
  state.equipment.controllerType = 'intellitouch';
94
- // The code above should be repeated if we ever see a panel with more than one expansion panel.
95
- sys.equipment.expansions.getItemById(2, true).isActive = false;
96
- sys.equipment.expansions.getItemById(3, true).isActive = false;
97
118
  sys.equipment.shared ? sys.board.equipmentIds.circuits.start = 1 : sys.board.equipmentIds.circuits.start = 2;
98
119
  this.initBodyDefaults();
99
120
  this.initHeaterDefaults();
@@ -117,6 +138,59 @@ export class IntelliTouchBoard extends EasyTouchBoard {
117
138
  state.emitControllerChange();
118
139
  }
119
140
  public circuits: ITTouchCircuitCommands = new ITTouchCircuitCommands(this);
141
+ public async setControllerType(obj): Promise<Equipment> {
142
+ try {
143
+ if (obj.controllerType !== sys.controllerType) {
144
+ return Promise.reject(new InvalidEquipmentDataError(`You may not change the controller type data for ${sys.controllerType} controllers`, 'controllerType', obj.controllerType));
145
+ }
146
+
147
+ let mod = sys.equipment.modules.getItemById(0);
148
+ let mt = this.valueMaps.expansionBoards.get(mod.type);
149
+ let _circuits = mt.circuits;
150
+ let pnl1 = sys.equipment.expansions.getItemById(1);
151
+ if (typeof obj.expansion1 !== 'undefined' && obj.expansion1 !== pnl1.type) {
152
+ let emt = this.valueMaps.expansionBoards.transform(obj.expansion1);
153
+ logger.info(`Changing expansion 1 to ${emt.desc}.`);
154
+ pnl1.type = emt.val;
155
+ pnl1.name = emt.desc;
156
+ pnl1.isActive = true;
157
+ }
158
+ let pnl2 = sys.equipment.expansions.getItemById(2);
159
+ if (typeof obj.expansion2 !== 'undefined' && obj.expansion2 !== pnl2.type) {
160
+ let emt = this.valueMaps.expansionBoards.transform(obj.expansion2);
161
+ logger.info(`Changing expansion 2 to ${emt.desc}.`);
162
+ pnl2.type = emt.val;
163
+ pnl2.name = emt.desc;
164
+ pnl2.isActive = true;
165
+ }
166
+ let pnl3 = sys.equipment.expansions.getItemById(3);
167
+ if (typeof obj.expansion3 !== 'undefined' && obj.expansion3 !== pnl3.type) {
168
+ let emt = this.valueMaps.expansionBoards.transform(obj.expansion3);
169
+ logger.info(`Changing expansion 3 to ${emt.desc}.`);
170
+ pnl3.type = emt.val;
171
+ pnl3.name = emt.desc;
172
+ pnl3.isActive = true;
173
+ }
174
+ let prevMaxCircuits = sys.equipment.maxCircuits;
175
+ if (pnl1.isActive) _circuits += this.valueMaps.expansionBoards.get(pnl1.type).circuits;
176
+ if (pnl2.isActive) _circuits += this.valueMaps.expansionBoards.get(pnl2.type).circuits;
177
+ if (pnl3.isActive) _circuits += this.valueMaps.expansionBoards.get(pnl3.type).circuits;
178
+ if (_circuits < prevMaxCircuits) {
179
+ // if we downsize expansions, remove circuits
180
+ for (let i = _circuits + 1; i <= prevMaxCircuits; i++) {
181
+ sys.circuits.removeItemById(i);
182
+ state.circuits.removeItemById(i);
183
+ }
184
+ }
185
+ else if (_circuits > prevMaxCircuits) {
186
+ this._configQueue.queueChanges();
187
+ }
188
+ sys.equipment.maxCircuits = _circuits;
189
+ return sys.equipment;
190
+ } catch (err) {
191
+ logger.error(`Error setting expansion panels: ${err.message}`);
192
+ }
193
+ }
120
194
  }
121
195
  class ITTouchConfigQueue extends TouchConfigQueue {
122
196
  public queueChanges() {
@@ -148,7 +222,7 @@ class ITTouchConfigQueue extends TouchConfigQueue {
148
222
  }
149
223
  if (this.remainingItems > 0) {
150
224
  var self = this;
151
- setTimeout(() => {self.processNext();}, 50);
225
+ setTimeout(() => { self.processNext(); }, 50);
152
226
  } else state.status = 1;
153
227
  state.emitControllerChange();
154
228
  }
@@ -164,5 +238,5 @@ class ITTouchCircuitCommands extends TouchCircuitCommands {
164
238
  }
165
239
  catch (err) { reject(err); }
166
240
  });
167
- }
241
+ }
168
242
  }