nodejs-poolcontroller 7.4.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.
Files changed (55) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +1 -1
  2. package/Changelog +3 -0
  3. package/README.md +2 -2
  4. package/app.ts +2 -0
  5. package/config/Config.ts +3 -0
  6. package/config/VersionCheck.ts +8 -4
  7. package/controller/Equipment.ts +89 -29
  8. package/controller/Errors.ts +14 -1
  9. package/controller/State.ts +75 -31
  10. package/controller/boards/EasyTouchBoard.ts +81 -36
  11. package/controller/boards/IntelliCenterBoard.ts +96 -32
  12. package/controller/boards/IntelliTouchBoard.ts +103 -29
  13. package/controller/boards/NixieBoard.ts +79 -27
  14. package/controller/boards/SystemBoard.ts +1552 -822
  15. package/controller/comms/Comms.ts +84 -9
  16. package/controller/comms/messages/Messages.ts +10 -4
  17. package/controller/comms/messages/config/ChlorinatorMessage.ts +13 -4
  18. package/controller/comms/messages/config/CircuitGroupMessage.ts +6 -0
  19. package/controller/comms/messages/config/CoverMessage.ts +1 -0
  20. package/controller/comms/messages/config/EquipmentMessage.ts +4 -0
  21. package/controller/comms/messages/config/ExternalMessage.ts +43 -25
  22. package/controller/comms/messages/config/FeatureMessage.ts +8 -1
  23. package/controller/comms/messages/config/GeneralMessage.ts +8 -0
  24. package/controller/comms/messages/config/HeaterMessage.ts +10 -9
  25. package/controller/comms/messages/config/IntellichemMessage.ts +4 -1
  26. package/controller/comms/messages/config/OptionsMessage.ts +13 -1
  27. package/controller/comms/messages/config/PumpMessage.ts +4 -20
  28. package/controller/comms/messages/config/RemoteMessage.ts +4 -0
  29. package/controller/comms/messages/config/ScheduleMessage.ts +11 -0
  30. package/controller/comms/messages/config/SecurityMessage.ts +1 -0
  31. package/controller/comms/messages/config/ValveMessage.ts +12 -2
  32. package/controller/comms/messages/status/ChlorinatorStateMessage.ts +2 -3
  33. package/controller/comms/messages/status/EquipmentStateMessage.ts +74 -22
  34. package/controller/comms/messages/status/HeaterStateMessage.ts +15 -6
  35. package/controller/comms/messages/status/IntelliChemStateMessage.ts +37 -26
  36. package/controller/nixie/Nixie.ts +18 -16
  37. package/controller/nixie/chemistry/ChemController.ts +57 -37
  38. package/controller/nixie/chemistry/Chlorinator.ts +7 -8
  39. package/controller/nixie/circuits/Circuit.ts +17 -0
  40. package/controller/nixie/pumps/Pump.ts +49 -24
  41. package/controller/nixie/schedules/Schedule.ts +1 -1
  42. package/defaultConfig.json +15 -0
  43. package/issue_template.md +1 -1
  44. package/logger/DataLogger.ts +37 -22
  45. package/package.json +3 -1
  46. package/web/Server.ts +515 -27
  47. package/web/bindings/influxDB.json +35 -0
  48. package/web/bindings/mqtt.json +62 -3
  49. package/web/bindings/mqttAlt.json +57 -4
  50. package/web/interfaces/httpInterface.ts +2 -0
  51. package/web/interfaces/influxInterface.ts +3 -2
  52. package/web/interfaces/mqttInterface.ts +12 -1
  53. package/web/services/config/Config.ts +162 -37
  54. package/web/services/state/State.ts +47 -3
  55. package/web/services/state/StateSocket.ts +1 -1
@@ -260,7 +260,8 @@ export class NixieBoard extends SystemBoard {
260
260
  sys.equipment.maxCustomNames = 0;
261
261
  state.equipment.model = type.desc;
262
262
  state.equipment.maxBodies = sys.equipment.maxBodies = type.bodies;
263
-
263
+ let bodyUnits = sys.general.options.units === 0 ? 1 : 2;
264
+
264
265
  if (typeof state.temps.units === 'undefined' || state.temps.units < 0) state.temps.units = sys.general.options.units;
265
266
  if (type.bodies > 0) {
266
267
  let pool = sys.bodies.getItemById(1, true);
@@ -272,6 +273,7 @@ export class NixieBoard extends SystemBoard {
272
273
  pool.circuit = 6;
273
274
  pool.isActive = true;
274
275
  pool.master = 1;
276
+ pool.capacityUnits = bodyUnits;
275
277
  sbody.name = pool.name;
276
278
  sbody.setPoint = pool.setPoint;
277
279
  sbody.circuit = pool.circuit;
@@ -307,6 +309,7 @@ export class NixieBoard extends SystemBoard {
307
309
  sbody.setPoint = spa.setPoint;
308
310
  sbody.circuit = spa.circuit;
309
311
  sbody.type = spa.type;
312
+ spa.capacityUnits = bodyUnits;
310
313
  scirc = state.circuits.getItemById(1, true);
311
314
  scirc.showInFeatures = circ.showInFeatures;
312
315
  scirc.type = circ.type;
@@ -330,6 +333,7 @@ export class NixieBoard extends SystemBoard {
330
333
  sys.circuits.removeItemById(6);
331
334
  state.circuits.removeItemById(6);
332
335
  }
336
+
333
337
  sys.equipment.setEquipmentIds();
334
338
  sys.board.bodies.initFilters();
335
339
  state.status = sys.board.valueMaps.controllerStatus.transform(2, 0);
@@ -637,8 +641,14 @@ export class NixieCircuitCommands extends CircuitCommands {
637
641
  let group: CircuitGroup = null;
638
642
  let id = typeof obj.id !== 'undefined' ? parseInt(obj.id, 10) : -1;
639
643
  if (id <= 0) {
640
- // We are adding a circuit group.
641
- id = sys.circuitGroups.getNextEquipmentId(sys.board.equipmentIds.circuitGroups);
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
+ }
642
652
  }
643
653
  if (typeof id === 'undefined') return Promise.reject(new InvalidEquipmentIdError(`Max circuit group id exceeded`, id, 'CircuitGroup'));
644
654
  if (isNaN(id) || !sys.board.equipmentIds.circuitGroups.isInRange(id)) return Promise.reject(new InvalidEquipmentIdError(`Invalid circuit group id: ${obj.id}`, obj.id, 'CircuitGroup'));
@@ -670,7 +680,7 @@ export class NixieCircuitCommands extends CircuitCommands {
670
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.
671
681
  //if (typeof cobj.lightingTheme !== 'undefined') c.lightingTheme = parseInt(cobj.lightingTheme, 10);
672
682
  }
673
- // group.circuits.length = obj.circuits.length; // RSG - removed as this will delete circuits that were not changed
683
+ group.circuits.length = obj.circuits.length; // RSG - removed as this will delete circuits that were not changed
674
684
  }
675
685
  resolve(group);
676
686
  });
@@ -680,14 +690,21 @@ export class NixieCircuitCommands extends CircuitCommands {
680
690
  let group: LightGroup = null;
681
691
  let id = typeof obj.id !== 'undefined' ? parseInt(obj.id, 10) : -1;
682
692
  if (id <= 0) {
683
- // We are adding a circuit group.
684
- id = sys.circuitGroups.getNextEquipmentId(sys.board.equipmentIds.circuitGroups);
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
+ }
685
701
  }
686
702
  if (typeof id === 'undefined') return Promise.reject(new InvalidEquipmentIdError(`Max circuit light group id exceeded`, id, 'LightGroup'));
687
703
  if (isNaN(id) || !sys.board.equipmentIds.circuitGroups.isInRange(id)) return Promise.reject(new InvalidEquipmentIdError(`Invalid circuit group id: ${obj.id}`, obj.id, 'LightGroup'));
688
704
  group = sys.lightGroups.getItemById(id, true);
705
+ let sgroup = state.lightGroups.getItemById(id, true);
689
706
  return new Promise<LightGroup>((resolve, reject) => {
690
- if (typeof obj.name !== 'undefined') group.name = obj.name;
707
+ if (typeof obj.name !== 'undefined') sgroup.name = group.name = obj.name;
691
708
  if (typeof obj.dontStop !== 'undefined' && utils.makeBool(obj.dontStop) === true) obj.eggTimer = 1440;
692
709
  if (typeof obj.eggTimer !== 'undefined') group.eggTimer = Math.min(Math.max(parseInt(obj.eggTimer, 10), 0), 1440);
693
710
  group.dontStop = group.eggTimer === 1440;
@@ -705,7 +722,11 @@ export class NixieCircuitCommands extends CircuitCommands {
705
722
  if (typeof cobj.swimDelay !== 'undefined') c.swimDelay = parseInt(cobj.swimDelay, 10);
706
723
  if (typeof cobj.position !== 'undefined') c.position = parseInt(cobj.position, 10);
707
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.
708
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
+
709
730
  }
710
731
  resolve(group);
711
732
  });
@@ -857,13 +878,21 @@ export class NixieCircuitCommands extends CircuitCommands {
857
878
  }
858
879
  public async setCircuitGroupStateAsync(id: number, val: boolean): Promise<ICircuitGroupState> {
859
880
  let grp = sys.circuitGroups.getItemById(id, false, { isActive: false });
860
- let gstate = (grp.dataName === 'circuitGroupConfig') ? state.circuitGroups.getItemById(grp.id, grp.isActive !== false) : state.lightGroups.getItemById(grp.id, grp.isActive !== false);
881
+ if (grp.dataName !== 'circuitGroupConfig') return await sys.board.circuits.setLightGroupStateAsync(id, val);
882
+ let gstate = state.circuitGroups.getItemById(grp.id, grp.isActive !== false);
861
883
  let circuits = grp.circuits.toArray();
884
+ sys.board.circuits.setEndTime(sys.circuits.getInterfaceById(gstate.id), gstate, val);
862
885
  gstate.isOn = val;
863
886
  let arr = [];
864
887
  for (let i = 0; i < circuits.length; i++) {
865
888
  let circuit = circuits[i];
866
- arr.push(sys.board.circuits.setCircuitStateAsync(circuit.circuit, val));
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));
867
896
  }
868
897
  return new Promise<ICircuitGroupState>(async (resolve, reject) => {
869
898
  await Promise.all(arr).catch((err) => { reject(err) });
@@ -871,7 +900,21 @@ export class NixieCircuitCommands extends CircuitCommands {
871
900
  });
872
901
  }
873
902
  public async setLightGroupStateAsync(id: number, val: boolean): Promise<ICircuitGroupState> {
874
- return sys.board.circuits.setCircuitGroupStateAsync(id, val);
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
+ });
875
918
  }
876
919
  }
877
920
  export class NixieFeatureCommands extends FeatureCommands {
@@ -939,39 +982,48 @@ export class NixieFeatureCommands extends FeatureCommands {
939
982
  return this.setFeatureStateAsync(id, !(feat.isOn || false));
940
983
  }
941
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.
942
989
  for (let i = 0; i < sys.circuitGroups.length; i++) {
943
990
  let grp: CircuitGroup = sys.circuitGroups.getItemByIndex(i);
944
991
  let circuits = grp.circuits.toArray();
945
- let bIsOn = false;
946
992
  if (grp.isActive) {
947
- for (let j = 0; j < circuits.length; j++) {
948
- let circuit: CircuitGroupCircuit = grp.circuits.getItemById(j);
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);
949
998
  let cstate = state.circuits.getInterfaceById(circuit.circuit);
950
- if (circuit.desiredState === 1 || circuit.desiredState === 0) {
951
- if (cstate.isOn === utils.makeBool(circuit.desiredState)) bIsOn = true;
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;
952
1004
  }
953
1005
  }
1006
+ let sgrp = state.circuitGroups.getItemById(grp.id);
1007
+ sgrp.isOn = bIsOn;
954
1008
  }
955
- let sgrp = state.circuitGroups.getItemById(grp.id);
956
- sgrp.isOn = bIsOn && grp.isActive;
957
-
958
1009
  sys.board.valves.syncValveStates();
959
1010
  }
960
1011
  // I am guessing that there will only be one here but iterate
961
1012
  // just in case we expand.
962
1013
  for (let i = 0; i < sys.lightGroups.length; i++) {
963
1014
  let grp: LightGroup = sys.lightGroups.getItemByIndex(i);
964
- let bIsOn = false;
1015
+ let circuits = grp.circuits.toArray();
965
1016
  if (grp.isActive) {
966
- let circuits = grp.circuits.toArray();
967
- for (let j = 0; j < circuits.length; j++) {
968
- let circuit = grp.circuits.getItemByIndex(j).circuit;
969
- let cstate = state.circuits.getInterfaceById(circuit);
970
- if (cstate.isOn) bIsOn = true;
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;
971
1022
  }
1023
+ let sgrp = state.lightGroups.getItemById(grp.id);
1024
+ sgrp.isOn = bIsOn;
972
1025
  }
973
- let sgrp = state.lightGroups.getItemById(grp.id);
974
- sgrp.isOn = bIsOn;
1026
+ sys.board.valves.syncValveStates();
975
1027
  }
976
1028
  state.emitEquipmentChanges();
977
1029
  }
@@ -1032,7 +1084,7 @@ export class NixieHeaterCommands extends HeaterCommands {
1032
1084
  let heater: Heater;
1033
1085
  if (id <= 0) {
1034
1086
  // We are adding a heater. In this case all heaters are virtual.
1035
- let vheaters = sys.heaters.filter(h => h.isVirtual === true);
1087
+ let vheaters = sys.heaters.filter(h => h.master === 1);
1036
1088
  id = vheaters.length + 256;
1037
1089
  }
1038
1090
  heater = sys.heaters.getItemById(id, true);