iobroker.sprinklecontrol 1.0.5 → 1.0.7

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.
@@ -23,7 +23,19 @@ const threadList = [];
23
23
  * Ventil mit dem größten Durchfluss (pipeFlow) für die Steuerung des Druckentlastungsventils
24
24
  * - wird in der Funktion updateList() ermittelt
25
25
  */
26
- const pressureReliefValve = {enable: false, name: '',wateringTime: 10, ac: {}, controller: {}, control: {idState: undefined, idON_TIME: undefined, idACK: undefined, maker: undefined}};
26
+ const pressureReliefValve = {
27
+ enable: false,
28
+ name: '',
29
+ wateringTime: 10,
30
+ ac: {},
31
+ controller: {},
32
+ control: {
33
+ idState: undefined,
34
+ idON_TIME: undefined,
35
+ idACK: undefined,
36
+ maker: undefined
37
+ }
38
+ };
27
39
 
28
40
  /**
29
41
  * - bereit zum Boost (true: kein Boostventil aktive; false: BoostVentil aktive)
@@ -46,7 +58,12 @@ let boostReady = true,
46
58
  */
47
59
  timeBasedRestrictionEn = false;
48
60
 
49
- const updateListMarker = {funcActive: false, newStart: false, switchingDistance: 5000, cancelSwitchingDistance: {}};
61
+ const updateListMarker = {
62
+ funcActive: false,
63
+ newStart: false,
64
+ switchingDistance: 5000,
65
+ cancelSwitchingDistance: {}
66
+ };
50
67
 
51
68
  /**
52
69
  * aktive Pumpendaten
@@ -64,9 +81,38 @@ const updateListMarker = {funcActive: false, newStart: false, switchingDistance:
64
81
  * - ac: AbortController
65
82
  */
66
83
 
67
- const currentPumpUse = {enable: false, name: '', wateringTime: 0, id: '', pumpCistern: false, intBreak: false, leadTime: 0, cancelLeadTime: {}, pumpPower: 0, restFlow: 0,ac: {},controller: {}, control: {idState: undefined, idON_TIME: undefined, idACK: undefined, maker: undefined}};
68
- let mainPumpControl = {idState: undefined, idON_TIME: undefined, idACK: undefined, maker: undefined};
69
- let cisternPumpControl = {idState: undefined, idON_TIME: undefined, idACK: undefined, maker: undefined};
84
+ const currentPumpUse = {
85
+ enable: false,
86
+ name: '',
87
+ wateringTime: 0,
88
+ id: '',
89
+ pumpCistern: false,
90
+ intBreak: false,
91
+ leadTime: 0,
92
+ cancelLeadTime: {},
93
+ pumpPower: 0,
94
+ restFlow: 0,
95
+ ac: {},
96
+ controller: {},
97
+ control: {
98
+ idState: undefined,
99
+ idON_TIME: undefined,
100
+ idACK: undefined,
101
+ maker: undefined
102
+ }
103
+ };
104
+ let mainPumpControl = {
105
+ idState: undefined,
106
+ idON_TIME: undefined,
107
+ idACK: undefined,
108
+ maker: undefined
109
+ };
110
+ let cisternPumpControl = {
111
+ idState: undefined,
112
+ idON_TIME: undefined,
113
+ idACK: undefined,
114
+ maker: undefined
115
+ };
70
116
 
71
117
  /**
72
118
  * Steuerspannung 24V
@@ -75,7 +121,27 @@ let cisternPumpControl = {idState: undefined, idON_TIME: undefined, idACK: undef
75
121
  * - idState: Aktorerkennung "hm-rpc.0.MEQ1810129.1.STATE"
76
122
  * - controller: controlle von Zeiten und Abbruchsignalen
77
123
  */
78
- const controlVoltage = {enable: false, name: '24V',wateringTime: 0, ac: {}, controller: {}, control: {idState: undefined, idON_TIME: undefined, idACK: undefined, maker: undefined}};
124
+ const controlVoltage = {
125
+ enable: false,
126
+ name: '24V',
127
+ wateringTime: 0,
128
+ ac: {},
129
+ controller: {},
130
+ control: {
131
+ idState: undefined,
132
+ idON_TIME: undefined,
133
+ idACK: undefined,
134
+ maker: undefined
135
+ }
136
+ };
137
+
138
+ const sensorPressure = {
139
+ inadequatePressure: false, // true = Nicht ausreichender Druck, false = ausreichender Druck
140
+ name: 'Sensor Pressure',
141
+ value: 0,
142
+ state: 0,
143
+ ac: null
144
+ };
79
145
 
80
146
  /**
81
147
  * Schaltabstand in ms
@@ -154,7 +220,7 @@ const setValve = async (thread, val) => {
154
220
 
155
221
  //adapter.log.info(`Set Valve (async () => {...}`);
156
222
  try {
157
- // Ventil ansteuern
223
+ // ON_Time setzen wenn angegeben, damit das Ventil nach der angegebenen Zeit automatisch ausgeschaltet wird (z.B. wenn der Ausschaltbefehl nicht ausgeführt werden kann, z.B Funkstörung)
158
224
  if (thread.control.idON_TIME !== null) {
159
225
  await adapter.setForeignStateAsync(thread.control.idON_TIME, {
160
226
  val: val ? Math.ceil(thread.wateringTime + 5) : 0,
@@ -162,7 +228,7 @@ const setValve = async (thread, val) => {
162
228
  });
163
229
  await asyncTime.setTimeout(200, undefined, undefined);
164
230
  }
165
-
231
+ // Ventil ansteuern
166
232
  const _setValve = await adapter.setForeignStateAsync(thread.control.idState, {
167
233
  val: val,
168
234
  ack: false
@@ -205,16 +271,21 @@ const setValve = async (thread, val) => {
205
271
  if (thread.ac.acSetValveCancelTimeout.aborted === false) thread.ac.acSetValveCancelTimeout.abort();
206
272
  }
207
273
 
208
- if (thread.name !== 'Cistern pump' && thread.name !== 'Main pump' && thread.name !== '24V' && thread.name !== 'no Pump') {
209
- adapter.setStateAsync(`sprinkle.${thread.name}.sprinklerState`, {
210
- val: thread.state,
211
- ack: true
212
- });
213
- adapter.setStateAsync(`sprinkle.${thread.name}.valveOn`, {
214
- val: thread.enable,
215
- ack: true
216
- });
274
+ try {
275
+ if (thread.name !== 'Cistern pump' && thread.name !== 'Main pump' && thread.name !== '24V' && thread.name !== 'no Pump') {
276
+ await adapter.setStateAsync(`sprinkle.${thread.name}.sprinklerState`, {
277
+ val: thread.state,
278
+ ack: true
279
+ });
280
+ adapter.setStateAsync(`sprinkle.${thread.name}.valveOn`, {
281
+ val: thread.enable,
282
+ ack: true
283
+ });
284
+ }
285
+ } catch (error) {
286
+ adapter.log.error(`setValve ${thread.name} => Error setting sprinklerState or valveOn: ${error}`);
217
287
  }
288
+
218
289
  return result;
219
290
  };
220
291
 
@@ -258,6 +329,9 @@ const delList = async (killList) => {
258
329
 
259
330
  /**
260
331
  * currentConsumption aktueller Verbrauch ermitteln
332
+ * - curFlow: aktuelle Restfördertleistung der Pumpe
333
+ * - parallel: aktuelle Anzahl der eingeschalteten Ventile
334
+ * - pumpRequired: Pumpe erforderlich (true/false)
261
335
  *
262
336
  * @param {boolean} write
263
337
  * @returns {Promise<{curFlow:number, parallel:number, pumpRequired:boolean}>}
@@ -269,13 +343,15 @@ const currentConsumption = async (write) => {
269
343
  parallel = 0,
270
344
  pumpRequired = false;
271
345
  adapter.log.debug(`currentConsumption curFlow: ${curFlow}, ${currentPumpUse.intBreak} => ${currentPumpUse.intBreak ? 0 : currentPumpUse.pumpPower}`);
272
- if (!currentPumpUse.intBreak) {
346
+ if (!currentPumpUse.intBreak
347
+ && !sensorPressure.inadequatePressure
348
+ ) {
273
349
  // ermitteln von curPipe und der Anzahl der parallelen Stränge
274
350
  for (const entry of threadList){
275
351
  if (entry.state === 'wait') pumpRequired = true; // state => wait
276
- if (entry.enable === true
277
- && entry.extBreak === false
278
- && timeBasedRestrictionEn === false
352
+ if (entry.enable === true // Ventil eingeschaltet
353
+ && entry.extBreak === false // && nicht in der externen Pause (extBreak)
354
+ && timeBasedRestrictionEn === false // && nicht in der zeitlichen Bewässerungspause
279
355
  ) {
280
356
  curFlow -= entry.pipeFlow; // // ermitteln der RestFörderkapazität
281
357
  parallel ++; // Anzahl der Bewässerungsstellen um 1 erhöhen
@@ -451,7 +527,7 @@ const countSprinkleTime = async (entry) => {
451
527
  /**
452
528
  * Timer zum ausschalten des Boost
453
529
  *
454
- * @param {*} entry
530
+ * @param {object} entry
455
531
  */
456
532
  const boostOnTimer = async (entry) => {
457
533
  entry.ac.acBoostOnTimer = new AbortController;
@@ -533,7 +609,7 @@ const updateList = async () => {
533
609
  : false;
534
610
 
535
611
  /**
536
- * Druckentlastungsventil Steuerung
612
+ * Find das Ventil mit dem größten Durchfluss (pipeFlow) für die Steuerung des Druckentlastungsventils
537
613
  * - Wenn die Bewässerung beendet wird, soll der Druck in den Leitungen durch kurzes Öffnen eines Druckentlastungsventils abgebaut werden,
538
614
  * um die Lebensdauer des Systems zu erhöhen. Hierzu wird das Ventil mit dem Größten Durchfluss (pipeFlow) für 10 Sekunden angesteuert.
539
615
  */
@@ -546,9 +622,22 @@ const updateList = async () => {
546
622
  }, myConfig.config[0]
547
623
  );
548
624
  }
549
- // Implementation for pressure relief valve control
550
-
625
+ /**
626
+ * Druckentlastungsventil ein wenn alle Ventile ihre Laufzeit beendet haben
627
+ * .killSprinkle = true
628
+ */
629
+ function pressureReliefIO() {
630
+ return threadList.reduce((count, entry) => {
631
+ return (entry.myBreak === true // Intervall-Beregnung on
632
+ && entry.killSprinkle === false // && Aufgabe noch nicht erledigt
633
+ ) ? (count + 1) : count;
634
+ }, 0
635
+ );
636
+ }
551
637
 
638
+ /**
639
+ * Start der Steuerung der Pumpen und Ventile
640
+ */
552
641
  consumption = await currentConsumption(true);
553
642
  if (consumption.pumpRequired === true) { // Pumpe erforderlich
554
643
 
@@ -556,7 +645,7 @@ const updateList = async () => {
556
645
  try {
557
646
  if (adapter.config.triggerControlVoltage
558
647
  && controlVoltage.enable === false
559
- || adjustment === true
648
+ || adjustment === true // Anpassung ON_Time wenn Laufzeit zu kurz, damit die 24V Versorgung während der Laufzeit nicht ausgeschaltet wird
560
649
  ) {
561
650
  controlVoltage.wateringTime = sumOfWateringTime > controlVoltage.wateringTime ? sumOfWateringTime + 5 : controlVoltage.wateringTime; // Schaltzeit der 24V Versorgung entsprechend der maximalen Laufzeit aller Ventile in der threadList anpassen
562
651
  const _controlVoltage = await setValve(controlVoltage, true);
@@ -576,7 +665,7 @@ const updateList = async () => {
576
665
  try {
577
666
  if (adapter.config.pumpSelection !== 'noPump'
578
667
  && currentPumpUse.enable === false
579
- || adjustment === true
668
+ || adjustment === true // Anpassung ON_Time wenn Laufzeit zu kurz, damit die Pumpe während der Laufzeit nicht ausgeschaltet wird
580
669
  ) {
581
670
  currentPumpUse.wateringTime = sumOfWateringTime > currentPumpUse.wateringTime ? sumOfWateringTime : currentPumpUse.wateringTime; // Schaltzeit der Pumpe entsprechend der maximalen Laufzeit aller Ventile in der threadList anpassen
582
671
  const _currentPumpUse = await setValve(currentPumpUse, true);
@@ -725,7 +814,8 @@ const updateList = async () => {
725
814
  ) {
726
815
  try {
727
816
  const empty = await findPressureReliefValve();
728
- if (empty) {
817
+ const _pressureReliefIO = await pressureReliefIO();
818
+ if (empty && _pressureReliefIO === 0) { // Ventil gefunden und alle Ventile haben ihre Laufzeit beendet
729
819
  pressureReliefValve.name = empty.objectName;
730
820
  pressureReliefValve.wateringTime = 10;
731
821
  pressureReliefValve.pipeFlow = empty.pipeFlow;
@@ -796,8 +886,8 @@ const setActualPump = async () => {
796
886
  case 'mainPump': {
797
887
  /* Pumpe AUS => Zisternen-Bewässerung nicht aktiviert */
798
888
  if (adapter.config.triggerCisternPump) {
799
- adapter.setState('info.cisternState', {
800
- val: `Cistern settings are not active! ${(fillLevelCistern > 0) ? (`level sensor: ${fillLevelCistern}% ${(adapter.config.triggerMinCisternLevel !== '') ? (` ${adapter.config.triggerMinCisternLevel}%`) : ('')}`):('')}`,
889
+ await adapter.setStateAsync('info.cisternState', {
890
+ val: `Cistern settings are not active! ${(fillLevelCistern > 0) ? (` ${fillLevelCistern}% ${(adapter.config.triggerMinCisternLevel !== '') ? (` ${adapter.config.triggerMinCisternLevel}%`) : ('')}`):('')}`,
801
891
  ack: true
802
892
  });
803
893
  }
@@ -805,48 +895,37 @@ const setActualPump = async () => {
805
895
  }
806
896
 
807
897
  case 'cistern': {
808
- if (fillLevelCistern < parseFloat(adapter.config.triggerMinCisternLevel)) { // (Zisterne unter Minimum)
898
+ // Zisterne unter Minimum
899
+ if (fillLevelCistern < parseFloat(adapter.config.triggerMinCisternLevel)) {
809
900
  if (!currentPumpUse.intBreak) {
810
901
  currentPumpUse.intBreak = true;
811
- adapter.log.warn('Cistern empty => irrigation no longer possible');
902
+ adapter.log.info('Cistern empty => irrigation no longer possible');
812
903
  if(!sendMessageText.onlySendError()){
813
904
  sendMessageText.sendMessage('Cistern empty => irrigation no longer possible'); // Zisterne leer => Bewässerung nicht mehr möglich
814
905
  }
815
906
  }
816
- adapter.setState('info.cisternState', {
817
- val: `Cistern empty: ${fillLevelCistern} % (${adapter.config.triggerMinCisternLevel} %)`,
818
- ack: true
819
- });
820
907
  // Pumpe ist eingeschaltet => ausschalten
821
908
  if (currentPumpUse.enable) {
822
909
  await setValve(currentPumpUse, false);
823
910
  updateList(); // Wasserverbrauch an Pumpenleistung anpassen
824
911
  }
912
+ // Zisterne über Minimum
825
913
  } else if (fillLevelCistern > parseFloat(adapter.config.triggerOnCisternLevel)) {
826
914
  if (currentPumpUse.intBreak) {
827
915
  currentPumpUse.intBreak = false;
828
- adapter.log.warn('Cistern filled => irrigation can begin again'); // Zisterne gefüllt => Bewässerung kann wieder beginnen
916
+ adapter.log.info('Cistern filled => irrigation can begin again'); // Zisterne gefüllt => Bewässerung kann wieder beginnen
829
917
  if(!sendMessageText.onlySendError()){
830
918
  sendMessageText.sendMessage('Cistern filled => irrigation can begin again');
831
919
  }
832
920
  }
833
- currentPumpUse.intBreak = false;
834
- adapter.setState('info.cisternState', {
835
- val: `Cistern filled: ${fillLevelCistern} % (${adapter.config.triggerMinCisternLevel} %)`,
836
- ack: true
837
- });
838
- updateList(); // Wasserverbrauch an Pumpenleistung anpassen
839
- } else if (currentPumpUse.intBreak === true) {
840
- adapter.setState('info.cisternState', {
841
- val: `Cistern empty: ${fillLevelCistern} % (${adapter.config.triggerMinCisternLevel} %)`,
842
- ack: true
843
- });
844
- } else {
845
- adapter.setState('info.cisternState', {
846
- val: `Cistern filled: ${fillLevelCistern} % (${adapter.config.triggerMinCisternLevel} %)`,
847
- ack: true
848
- });
921
+ // Wasserverbrauch an Pumpenleistung anpassen
922
+ updateList();
849
923
  }
924
+ /* Info aktualisieren */
925
+ await adapter.setStateAsync('info.cisternState', {
926
+ val: `${ (currentPumpUse.intBreak === true) ? 'Cistern empty: ' : 'Cistern filled: ' } ${ fillLevelCistern } % (${ adapter.config.triggerMinCisternLevel } %)`,
927
+ ack: true
928
+ });
850
929
  break;
851
930
  }
852
931
 
@@ -861,6 +940,8 @@ const setActualPump = async () => {
861
940
  val: currentPumpUse.enable,
862
941
  ack: true
863
942
  });
943
+ } else {
944
+ throw new Error(`Error trigger cistern Pump off [${currentPumpUse.control.idState}]`);
864
945
  }
865
946
  currentPumpUse.pumpCistern = false;
866
947
  currentPumpUse.name = 'Main pump';
@@ -874,6 +955,8 @@ const setActualPump = async () => {
874
955
  val: currentPumpUse.enable,
875
956
  ack: true
876
957
  });
958
+ } else {
959
+ throw new Error(`Error trigger main Pump on [${currentPumpUse.control.idState}]`);
877
960
  }
878
961
  adapter.log.info('Pump change (cistern empty) Cistern pump off => main pump on');
879
962
  if(!sendMessageText.onlySendError()){
@@ -883,45 +966,39 @@ const setActualPump = async () => {
883
966
  }
884
967
  } else {
885
968
  /* Bewässerungspumpen inaktiv */
886
- if ((fillLevelCistern > parseFloat(adapter.config.triggerOnCisternLevel)) && (adapter.config.triggerCisternPump) && (adapter.config.triggerCisternPumpPower)) {
887
- /* Zisterne voll && triggerCisternPump && triggerCisternPumpPower vorhanden*/
888
- adapter.setState('info.cisternState', {
889
- val: `Cistern filled: ${fillLevelCistern} % (${adapter.config.triggerMinCisternLevel} %)`,
890
- ack: true
891
- });
892
- currentPumpUse.pumpCistern = true;
893
- currentPumpUse.name = 'Cistern pump';
894
- currentPumpUse.id = 'info.cisternPump';
895
- currentPumpUse.control = { ...cisternPumpControl };
896
- currentPumpUse.pumpPower = parseInt(adapter.config.triggerCisternPumpPower);
897
-
898
- } else {
899
- adapter.setState('info.cisternState', {
900
- val: `Cistern empty: ${fillLevelCistern} % (adapter.config.triggerMinCisternLevel %)`,
901
- ack: true
902
- });
903
- currentPumpUse.pumpCistern = false;
904
- currentPumpUse.name = 'Main pump';
905
- currentPumpUse.id = 'info.mainPump';
906
- currentPumpUse.control = { ...mainPumpControl };
907
- currentPumpUse.pumpPower = parseInt(adapter.config.triggerMainPumpPower);
969
+ if (fillLevelCistern > parseFloat(adapter.config.triggerOnCisternLevel)) {
970
+ /* Zisterne voll */
971
+ if (currentPumpUse.pumpCistern === false) {
972
+ currentPumpUse.pumpCistern = true;
973
+ currentPumpUse.name = 'Cistern pump';
974
+ currentPumpUse.id = 'info.cisternPump';
975
+ currentPumpUse.control = { ...cisternPumpControl };
976
+ currentPumpUse.pumpPower = parseInt(adapter.config.triggerCisternPumpPower);
977
+ await adapter.setStateAsync('control.restFlow', {
978
+ val: `${currentPumpUse.pumpPower} (${currentPumpUse.pumpPower} | ${currentPumpUse.name})`,
979
+ ack: true
980
+ });
981
+ }
982
+ } else if (fillLevelCistern < parseFloat(adapter.config.triggerMinCisternLevel)) {
983
+ /* Zisterne leer */
984
+ if (currentPumpUse.pumpCistern === true) {
985
+ currentPumpUse.pumpCistern = false;
986
+ currentPumpUse.name = 'Main pump';
987
+ currentPumpUse.id = 'info.mainPump';
988
+ currentPumpUse.control = { ...mainPumpControl };
989
+ currentPumpUse.pumpPower = parseInt(adapter.config.triggerMainPumpPower);
990
+ await adapter.setStateAsync('control.restFlow', {
991
+ val: `${currentPumpUse.pumpPower} (${currentPumpUse.pumpPower} | ${currentPumpUse.name})`,
992
+ ack: true
993
+ });
994
+ }
908
995
  }
909
- adapter.setState('control.restFlow', {
910
- val: `${currentPumpUse.pumpPower} (${currentPumpUse.pumpPower} | ${currentPumpUse.name})`,
911
- ack: true
912
- });
913
- }
914
- if (currentPumpUse.pumpCistern) {
915
- adapter.setState('info.cisternState', {
916
- val: `Cistern filled: ${fillLevelCistern} % (${adapter.config.triggerMinCisternLevel} %)`,
917
- ack: true
918
- });
919
- } else {
920
- adapter.setState('info.cisternState', {
921
- val: `Cistern empty: ${fillLevelCistern} % (${adapter.config.triggerMinCisternLevel} %)`,
922
- ack: true
923
- });
924
996
  }
997
+ /* Info aktualisieren */
998
+ await adapter.setStateAsync('info.cisternState', {
999
+ val: `${ (currentPumpUse.pumpCistern === false) ? 'Cistern empty: ' : 'Cistern filled: ' } ${ fillLevelCistern } % (${ adapter.config.triggerMinCisternLevel } %)`,
1000
+ ack: true
1001
+ });
925
1002
  break;
926
1003
  }
927
1004
  }
@@ -1135,8 +1212,8 @@ const valveControl = {
1135
1212
  const _actualValueLevel = await adapter.getForeignStateAsync(adapter.config.actualValueLevel);
1136
1213
  if (_actualValueLevel && _actualValueLevel.val) {
1137
1214
  if (typeof _actualValueLevel.val === 'number') {
1138
- fillLevelCistern = _actualValueLevel.val;
1139
- (_actualValueLevel.val > parseInt(adapter.config.triggerMinCisternLevel)) ? currentPumpUse.intBreak = false : currentPumpUse.intBreak = true;
1215
+ fillLevelCistern = parseInt(_actualValueLevel.val);
1216
+ (fillLevelCistern > parseInt(adapter.config.triggerMinCisternLevel)) ? currentPumpUse.intBreak = false : currentPumpUse.intBreak = true;
1140
1217
  } else if (typeof _actualValueLevel.val === 'boolean') {
1141
1218
  if (_actualValueLevel.val) {
1142
1219
  currentPumpUse.intBreak = false;
@@ -1163,6 +1240,19 @@ const valveControl = {
1163
1240
  currentPumpUse.leadTime = (parseInt(adapter.config.cisternPumpLeadTime) || 5) * 1000;
1164
1241
  currentPumpUse.pumpPower = parseInt(adapter.config.triggerCisternPumpPower) || 0;
1165
1242
  currentPumpUse.restFlow = parseInt(adapter.config.triggerCisternPumpPower) || 0;
1243
+ if (isNaN(parseInt(adapter.config.triggerMinCisternLevel))
1244
+ || (parseInt(adapter.config.triggerMinCisternLevel) <= 1)
1245
+ || (parseInt(adapter.config.triggerMinCisternLevel) > 100)
1246
+ ) {
1247
+ adapter.log.error(`Pump selection "cistern" is selected, but the minimum cistern level is set to ${adapter.config.triggerMinCisternLevel}%. Please set the minimum cistern level to 1...100% or select another pump selection!`);
1248
+ }
1249
+ if (isNaN(parseInt(adapter.config.triggerOnCisternLevel))
1250
+ || (parseInt(adapter.config.triggerOnCisternLevel) <= parseInt(adapter.config.triggerMinCisternLevel))
1251
+ || (parseInt(adapter.config.triggerOnCisternLevel) > 100)
1252
+ || (parseInt(adapter.config.triggerOnCisternLevel) < 5)
1253
+ ) {
1254
+ adapter.log.error(`Pump selection "cistern" is selected, but the trigger on cistern level is set to ${adapter.config.triggerOnCisternLevel}%. Please set the trigger on cistern level to ${parseInt(adapter.config.triggerMinCisternLevel) + 5}...100% or select another pump selection!`);
1255
+ }
1166
1256
  // @ts-ignore
1167
1257
  await adapter.setObjectNotExistsAsync(`info.cisternPump`, objCisternPump);
1168
1258
  const _mainPump = await adapter.getObjectAsync(`info.mainPump`);
@@ -1176,12 +1266,26 @@ const valveControl = {
1176
1266
  cisternPumpControl = await tools.idStateControl(adapter, adapter.config.triggerCisternPump);
1177
1267
  if (mainPumpControl?.idACK) adapter.subscribeForeignStates(mainPumpControl.idACK);
1178
1268
  if (cisternPumpControl?.idACK) adapter.subscribeForeignStates(cisternPumpControl.idACK);
1269
+ /* Kontrolle der Konfiguration CisternLevel */
1270
+ if (isNaN(parseInt(adapter.config.triggerMinCisternLevel))
1271
+ || (parseInt(adapter.config.triggerMinCisternLevel) <= 1)
1272
+ || (parseInt(adapter.config.triggerMinCisternLevel) > 100)
1273
+ ) {
1274
+ adapter.log.error(`Pump selection "mainpump & cistern" is selected, but the minimum cistern level is set to ${adapter.config.triggerMinCisternLevel}%. Please set the minimum cistern level to 1...100% or select another pump selection!`);
1275
+ }
1276
+ if (isNaN(parseInt(adapter.config.triggerOnCisternLevel))
1277
+ || (parseInt(adapter.config.triggerOnCisternLevel) <= parseInt(adapter.config.triggerMinCisternLevel))
1278
+ || (parseInt(adapter.config.triggerOnCisternLevel) > 100)
1279
+ || (parseInt(adapter.config.triggerOnCisternLevel) < 5)
1280
+ ) {
1281
+ adapter.log.error(`Pump selection "cistern" is selected, but the trigger on cistern level is set to ${adapter.config.triggerOnCisternLevel}%. Please set the trigger on cistern level to ${parseInt(adapter.config.triggerMinCisternLevel) + 5}...100% or select another pump selection!`);
1282
+ }
1179
1283
  if (adapter.config.actualValueLevel) {
1180
1284
  /* Füllstand der Zisterne in % holen */
1181
1285
  const _actualValueLevel = await adapter.getForeignStateAsync(adapter.config.actualValueLevel);
1182
- if (_actualValueLevel && _actualValueLevel.val) {
1286
+ if (_actualValueLevel?.val) {
1183
1287
  if (typeof _actualValueLevel.val === 'number') {
1184
- fillLevelCistern = _actualValueLevel.val;
1288
+ fillLevelCistern = parseInt(_actualValueLevel.val);
1185
1289
  } else if (typeof _actualValueLevel.val === 'boolean') {
1186
1290
  _actualValueLevel.val ? fillLevelCistern = 100 : fillLevelCistern = 0;
1187
1291
  } else {
@@ -1229,7 +1333,7 @@ const valveControl = {
1229
1333
  }
1230
1334
  }
1231
1335
  /* Objekt control.restFlow befüllen */
1232
- adapter.setStateAsync('control.restFlow', {
1336
+ await adapter.setStateAsync('control.restFlow', {
1233
1337
  val: `${currentPumpUse.pumpPower} (${currentPumpUse.pumpPower} | ${currentPumpUse.name})`,
1234
1338
  ack: true
1235
1339
  });
@@ -1291,6 +1395,63 @@ const valveControl = {
1291
1395
  }
1292
1396
  }
1293
1397
  }
1398
+
1399
+ /**
1400
+ * Objekt sensorPressure anlegen und abonnieren, wenn benötigt
1401
+ */
1402
+
1403
+ if (typeof adapter.config.sensorPressure === 'string'
1404
+ && adapter.config.sensorPressure.length > 5
1405
+ && adapter.config.pumpSelection !== 'noPump'
1406
+ ) {
1407
+ const _sensorPressure = await adapter.getForeignStateAsync(adapter.config.sensorPressure);
1408
+ if (_sensorPressure) {
1409
+ adapter.subscribeForeignStates(adapter.config.sensorPressure);
1410
+ const _waterPressure = await adapter.getObjectAsync(`info.waterPressure`);
1411
+ if (_waterPressure) {
1412
+ await adapter.setStateAsync(`info.waterPressure`, {
1413
+ val: `${ _sensorPressure.val }`,
1414
+ ack: true
1415
+ });
1416
+ } else {
1417
+ await adapter.setObjectNotExistsAsync(`info.waterPressure`, {
1418
+ type: 'state',
1419
+ common: {
1420
+ role: 'state',
1421
+ name: 'Water pressure',
1422
+ desc: {
1423
+ en: 'Water pressure',
1424
+ de: 'Wasserdruck',
1425
+ ru: 'Давление воды',
1426
+ pt: 'Pressão da água',
1427
+ nl: 'Waterdruk',
1428
+ fr: "Pression de l'eau",
1429
+ it: "Pressione dell'acqua",
1430
+ es: 'Presión del agua',
1431
+ pl: 'Ciśnienie wody',
1432
+ uk: 'Тиск води',
1433
+ 'zh-cn': '水压'
1434
+ },
1435
+ type: 'string',
1436
+ read: true,
1437
+ write: false,
1438
+ def: ' --- ',
1439
+ unit: 'bar'
1440
+ },
1441
+ native: {},
1442
+ });
1443
+ await adapter.setStateAsync(`info.waterPressure`, {
1444
+ val: `${ _sensorPressure.val }`,
1445
+ ack: true
1446
+ });
1447
+ }
1448
+ } else {
1449
+ adapter.log.warn(`The configured pressure sensor "${ adapter.config.sensorPressure }" could not be found. Please check the configuration of the pressure sensor!`);
1450
+ }
1451
+ } else {
1452
+ const _waterPressure = await adapter.getObjectAsync(`info.waterPressure`);
1453
+ if (_waterPressure) await adapter.delObjectAsync(`info.waterPressure`);
1454
+ }
1294
1455
  } catch (error) {
1295
1456
  adapter.log.error(`initValveControl ERROR: ${error}`);
1296
1457
  }
@@ -1308,6 +1469,7 @@ const valveControl = {
1308
1469
  */
1309
1470
  addList: async function (sprinkleList) {
1310
1471
  try {
1472
+ sensorPressure.inadequatePressure = false; // Kontrolle Drucksensorwert zurücksetzen, damit die Bewässerungsbeschränkung korrekt funktioniert, wenn der Drucksensorwert während der Bewässerungsbeschränkung unter dem Minimum lag
1311
1473
  // kontrolle bei ausgeschalteter Pumpe, ob die Zisterne zur Bewässerung genutzt werden kann
1312
1474
  if (adapter.config.pumpSelection === 'pumpAndCistern'
1313
1475
  && currentPumpUse.enable === false
@@ -1377,7 +1539,7 @@ const valveControl = {
1377
1539
  /** 0:"off", 1:"wait", 2:"on", 3:"break", 4:"Boost(on)", 5:"off(Boost)", 6:"Cistern empty", 7:"extBreak" */
1378
1540
  newThread.state = 'wait'; // zustand des Ventils Softwaremäßig
1379
1541
  newThread.enable = false; // zustand des Ventil softwaremäßig
1380
- newThread.myBreak = false; // meine interne Pause
1542
+ newThread.myBreak = false; // meine interne Pause Intervallberegnung
1381
1543
  newThread.extBreak = myConfig.config[res.sprinkleID].extBreak; // extBreak wird über .sprinkle.*.extBreak geschaltet
1382
1544
  newThread.killSprinkle = false; // Löschauftrag ausführen am Ende in threadList
1383
1545
  newThread.litersPerSecond = myConfig.config[res.sprinkleID].pipeFlow / 3600; // Wasserverbrauchsmenge pro Sekunde
@@ -1410,7 +1572,8 @@ const valveControl = {
1410
1572
  }, // End addList
1411
1573
 
1412
1574
  timeBasedRestriction: async function (enable) { //Irrigation ban => zeitliche Bewässerungsbeschränkung noch zu bearbeiten ! ! !
1413
- try {
1575
+ try {
1576
+ sensorPressure.inadequatePressure = false; // Kontrolle Drucksensorwert zurücksetzen, damit die Bewässerungsbeschränkung korrekt funktioniert, wenn der Drucksensorwert während der Bewässerungsbeschränkung unter dem Minimum lag
1414
1577
  timeBasedRestrictionEn = enable;
1415
1578
  if (threadList) {
1416
1579
  if (timeBasedRestrictionEn === true) { // zeitliche Bewässerungsbeschränkung aktiv
@@ -1591,15 +1754,26 @@ const valveControl = {
1591
1754
  * @param {number|string|boolean} levelCistern
1592
1755
  */
1593
1756
  setFillLevelCistern: function (levelCistern) {
1594
- adapter.log.debug(`setFillLevelCistern: ${levelCistern}`);
1757
+ let myFillLevelCistern = 0;
1758
+ adapter.log.debug(`setFillLevelCistern: ${ levelCistern }`);
1595
1759
  if(typeof levelCistern === 'number') {
1596
- fillLevelCistern = levelCistern;
1760
+ myFillLevelCistern = parseInt(levelCistern);
1597
1761
  }else if(typeof levelCistern === 'string') {
1598
- fillLevelCistern = parseFloat(levelCistern);
1762
+ myFillLevelCistern = parseInt(levelCistern);
1599
1763
  }else if(typeof levelCistern === 'boolean') {
1600
- (levelCistern === true) ? fillLevelCistern = 100 : fillLevelCistern = 0;
1764
+ (levelCistern === true) ? myFillLevelCistern = 100 : myFillLevelCistern = 0;
1765
+ }
1766
+ if(typeof myFillLevelCistern !== "number"
1767
+ || myFillLevelCistern < 0
1768
+ || myFillLevelCistern > 100
1769
+ ) {
1770
+ adapter.log.warn(`setFillLevelCistern (0...100% || true/false) => Wrong value: ${ levelCistern }, Type: ${ typeof levelCistern }`);
1771
+ return;
1772
+ }
1773
+ if (myFillLevelCistern != fillLevelCistern) {
1774
+ fillLevelCistern = myFillLevelCistern;
1775
+ setActualPump();
1601
1776
  }
1602
- setActualPump();
1603
1777
  }, // End setFillLevelCistern
1604
1778
 
1605
1779
  /**
@@ -1609,8 +1783,72 @@ const valveControl = {
1609
1783
  */
1610
1784
  getIntBreakCisternPump: function () {
1611
1785
  return (adapter.config.pumpSelection === 'cistern') ? currentPumpUse.intBreak : false;
1612
- }
1786
+ },
1613
1787
 
1788
+ /**
1789
+ * Setzt den Drucksensorwert
1790
+ * https://blog.logrocket.com/complete-guide-abortcontroller/
1791
+ *
1792
+ * @param {number} pressure
1793
+ */
1794
+ setSensorPressure: async function (pressure) {
1795
+ let alteredPressure = false; // Veränderter Druck => updateList starten um Verbrauch anzupassen / Ventile ausschalten
1796
+ let reviews = '';
1797
+ try {
1798
+ sensorPressure.value = parseFloat(pressure).toFixed(1);
1799
+ if (currentPumpUse.enable === true && adapter.config.minimumPressure > pressure) {
1800
+ if (sensorPressure.ac === null) {
1801
+ sensorPressure.ac = new AbortController();
1802
+ await asyncTime.setTimeout(60000, undefined, { signal: sensorPressure.ac.signal }); // max. 60s warten und Drucksensorwert erneut prüfen, bevor die Pumpe ausgeschaltet wird
1803
+ const _currentPressure = await adapter.getForeignStateAsync(adapter.config.sensorPressure);
1804
+ if (_currentPressure?.val
1805
+ && currentPumpUse.enable === true
1806
+ && adapter.config.minimumPressure > parseFloat(_currentPressure.val)
1807
+ ) {
1808
+ reviews = 'Not Okay'
1809
+ if (sensorPressure.inadequatePressure === false) {
1810
+ alteredPressure = true;
1811
+ sensorPressure.inadequatePressure = true;
1812
+ }
1813
+ sensorPressure.value = parseFloat(_currentPressure.val).toFixed(1);
1814
+ adapter.log.warn(`Pressure sensor value ${ pressure } bar is below the minimum pressure ${ adapter.config.minimumPressure } bar. The pump will be turned off to prevent damage. Please check the pressure sensor and the configuration of the minimum pressure!`);
1815
+ if (adapter.config.notificationEnabled) {
1816
+ sendMessageText.sendMessage(`Pressure sensor value ${ pressure } bar is below the minimum pressure ${ adapter.config.minimumPressure } bar. The pump will be turned off to prevent damage. Please check the pressure sensor and the configuration of the minimum pressure!`);
1817
+ }
1818
+ sensorPressure.ac.abort(); // setTimeout abbrechen, da die Pumpe bereits ausgeschaltet wird
1819
+ sensorPressure.ac = null; // AbortController zurücksetzen
1820
+ } else if (_currentPressure?.val) {
1821
+ reviews = 'Okay';
1822
+ }
1823
+ sensorPressure.ac = null; // AbortController zurücksetzen
1824
+ } else {
1825
+ reviews = 'I don\'t know';
1826
+ }
1827
+ } else if (currentPumpUse.enable === false || adapter.config.minimumPressure <= pressure) {
1828
+ reviews = 'Okay'
1829
+ if (sensorPressure?.ac !== null) {
1830
+ await sensorPressure.ac.abort(); // AbortController zurücksetzen
1831
+ sensorPressure.ac = null;
1832
+ }
1833
+ } else {
1834
+ reviews = 'Okay'
1835
+ }
1836
+ } catch (error) {
1837
+ if (error.name === 'AbortError') {
1838
+ adapter.log.debug(`setSensorPressure(${pressure}): The shutdown process was aborted because the operating pressure was restored.`);
1839
+ if (sensorPressure?.ac !== null) {
1840
+ sensorPressure.ac.abort(); // AbortController zurücksetzen
1841
+ sensorPressure.ac = null;
1842
+ }
1843
+ }
1844
+ } finally {
1845
+ await adapter.setStateAsync(`info.waterPressure`, {
1846
+ val: `${ reviews } ( ${ sensorPressure.value } bar )`,
1847
+ ack: true
1848
+ });
1849
+ if (alteredPressure) updateList();
1850
+ }
1851
+ }
1614
1852
  }; // End valveControl
1615
1853
 
1616
1854
  /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/