iobroker.sprinklecontrol 1.0.1 → 1.0.2

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.
@@ -5,11 +5,7 @@ const asyncTime = require('timers/promises');
5
5
  // import {setTimeout} from 'timers/promises';
6
6
 
7
7
  const myConfig = require('./myConfig.js');
8
- //const sleep = require('./tools.js').sleep;
9
- const addTime = require('./tools.js').addTime;
10
- const formatTime = require('./tools').formatTime;
11
- const findAsync = require('./tools.js').findAsync;
12
- const idStateControl = require('./tools.js').idStateControl;
8
+ const tools = require('./tools.js').tools;
13
9
  const sendMessageText = require('./sendMessageText.js'); // sendMessageText
14
10
 
15
11
  /**
@@ -35,11 +31,15 @@ let boostReady = true,
35
31
  * maximal zulässige Anzahl der eingeschalteten Ventile
36
32
  */
37
33
  maxParallel = 0,
38
- /* Control of the cistern pump */
39
34
  /**
40
35
  * Füllstand der Zisterne
41
36
  */
42
- fillLevelCistern = 0;
37
+ fillLevelCistern = 0,
38
+ /**
39
+ * Zeitliche Bewässerungseinschränkung EIN/AUS
40
+ */
41
+ timeBasedRestrictionEn = false;
42
+
43
43
  const updateListMarker = {funcActive: false, newStart: false, switchingDistance: 5000, cancelSwitchingDistance: {}};
44
44
 
45
45
  /**
@@ -98,7 +98,7 @@ const setValve = async (thread, val) => {
98
98
  ack: false
99
99
  });
100
100
  thread.enable = val;
101
- adapter.log.info(`setValve ${ thread.name }: ${ val }, ${ thread.wateringTime > 0 && val === true ? `${ addTime(thread.wateringTime,'') }, ` : '' }`);
101
+ adapter.log.info(`setValve ${ thread.name }: ${ val }, ${ thread.wateringTime > 0 && val === true ? `${ tools.addTime(thread.wateringTime,'') }, ` : '' }`);
102
102
  return thread.control.idState;
103
103
  } catch (error) {
104
104
  thread.enable = false;
@@ -144,7 +144,7 @@ const setValve = async (thread, val) => {
144
144
  val: val ? Math.ceil(thread.wateringTime + 5) : 0,
145
145
  ack: false
146
146
  });
147
- await asyncTime.setTimeout(100, undefined, undefined);
147
+ await asyncTime.setTimeout(200, undefined, undefined);
148
148
  }
149
149
 
150
150
  const _setValve = await adapter.setForeignStateAsync(thread.control.idState, {
@@ -159,7 +159,7 @@ const setValve = async (thread, val) => {
159
159
  thread.enable === val ? updateStr = ' (update)' : thread.enable = val;;
160
160
  return thread.control.idState;
161
161
  } else {
162
- throw new Error(` was not switched`);
162
+ throw new Error(` > was not switched! (${val}) Check the device! Reply: ${JSON.stringify(_getValve)}`);
163
163
  }
164
164
  } else {
165
165
  throw new Error(` command could not be sent`);
@@ -176,11 +176,15 @@ const setValve = async (thread, val) => {
176
176
  if (adapter.config.notificationEnabled) {
177
177
  sendMessageText.sendMessage(`setValve ${thread.name} (${thread.control.idState}) ${error}`);
178
178
  }
179
- throw new Error(`set Valve ${thread.name}${error}`);
179
+ throw new Error(` > set Valve ${error}`);
180
180
  }
181
181
  } finally {
182
- adapter.log.info(`setValve ${thread.name}: ${val}, ${thread.control.maker !== 'standard' ? `${thread.control.maker}, ` : ''}
183
- ${thread.wateringTime > 0 && val === true ? `${ addTime(thread.wateringTime,'') }${ updateStr }, ` : ''}processing time: ${(+new Date()) - +startTime}ms
182
+ adapter.log.info(`setValve ${thread.name}:
183
+ ${val},
184
+ ${thread.control.maker !== 'standard' ? `${thread.control.maker}, ` : ''}
185
+ ${ (thread.wateringTime > 0 && val === true && thread.name !== 'Cistern pump' && thread.name !== 'Main pump' && thread.name !== '24V')
186
+ ? `${ tools.addTime(thread.wateringTime,'') }${ updateStr }, ` : ''}
187
+ processing time: ${(+new Date()) - +startTime}ms
184
188
  `);
185
189
  if (thread.ac.acSetValveCancelTimeout.aborted === false) thread.ac.acSetValveCancelTimeout.abort();
186
190
  }
@@ -254,6 +258,7 @@ const currentConsumption = async (write) => {
254
258
  if (entry.state === 'wait') pumpRequired = true; // state => wait
255
259
  if (entry.enable === true
256
260
  && entry.extBreak === false
261
+ && timeBasedRestrictionEn === false
257
262
  ) {
258
263
  curFlow -= entry.pipeFlow; // // ermitteln der RestFörderkapazität
259
264
  parallel ++; // Anzahl der Bewässerungsstellen um 1 erhöhen
@@ -324,7 +329,9 @@ const countSprinkleTime = async (entry) => {
324
329
  try {
325
330
  /* --- function beenden wenn ---*/
326
331
  if ((boostOn && !(myConfig.config[entry.sprinkleID].booster) // boost-On && kein aktuelles Boost-Ventil
327
- || entry.extBreak) // extBreak aktive
332
+ || entry.extBreak === true // extBreak aktive
333
+ || timeBasedRestrictionEn === true // zeitliche Bewässerungsbeschränkung aktiv
334
+ )
328
335
  ) {
329
336
  return;
330
337
  }
@@ -337,7 +344,7 @@ const countSprinkleTime = async (entry) => {
337
344
  || (myConfig.config[entry.sprinkleID].calculation.val < myConfig.config[entry.sprinkleID].calculation.maxIrrigation)) // Bodenfeuchte noch nicht erreicht? (z.B. beim Regen)
338
345
  ) { /* Zeit läuft */
339
346
  adapter.setStateAsync(`sprinkle.${entry.name}.countdown`, {
340
- val: addTime(entry.wateringTime - entry.count, ''),
347
+ val: tools.addTime(entry.wateringTime - entry.count, ''),
341
348
  ack: true
342
349
  });
343
350
 
@@ -595,6 +602,7 @@ const updateList = async () => {
595
602
  && !entry.killSprinkle // && Aufgabe noch nicht erledigt
596
603
  && !entry.myBreak // && nicht in der Pause Interval-Beregnung
597
604
  && !entry.extBreak // && nicht in der externen Pause (extBreak)
605
+ && !timeBasedRestrictionEn // && nicht in der zeitlichen Bewässerungsbeschränkung
598
606
  && (consumption.curFlow >= entry.pipeFlow) // && noch genügend Förderleistung der Pumpe
599
607
  && (consumption.parallel < maxParallel) // && maxParallel noch nicht erreicht
600
608
  && !boostOn // && Ventile nur einschalten, wenn kein Boost aktive
@@ -878,10 +886,10 @@ function addConsumedAndTime(entry) {
878
886
  ack: true
879
887
  });
880
888
  adapter.setState(`sprinkle.${entry.name}.history.lastRunningTime`, {
881
- val: addTime(entry.count, ''),
889
+ val: tools.addTime(entry.count, ''),
882
890
  ack: true
883
891
  });
884
- const _formatTime = formatTime(entry.startTime);
892
+ const _formatTime = tools.formatTime(entry.startTime);
885
893
  adapter.setState(`sprinkle.${entry.name}.history.lastOn`, {
886
894
  val: _formatTime.dayTime,
887
895
  ack: true
@@ -897,7 +905,7 @@ function addConsumedAndTime(entry) {
897
905
  adapter.getState(`sprinkle.${entry.name}.history.curCalWeekRunningTime`, (err, state) => {
898
906
  if (state && state.val) {
899
907
  adapter.setState(`sprinkle.${entry.name}.history.curCalWeekRunningTime`, {
900
- val: addTime(+state.val, entry.count),
908
+ val: tools.addTime(+state.val, entry.count),
901
909
  ack: true
902
910
  });
903
911
  }
@@ -936,7 +944,7 @@ const valveControl = {
936
944
  /* Object supplyVoltage (VersorgungsSpannung) anlegen */
937
945
  if (adapter.config.triggerControlVoltage.length > 5) {
938
946
 
939
- controlVoltage.control = await idStateControl(adapter, adapter.config.triggerControlVoltage);
947
+ controlVoltage.control = await tools.idStateControl(adapter, adapter.config.triggerControlVoltage);
940
948
  if (controlVoltage?.control?.idACK) adapter.subscribeForeignStates(controlVoltage.control.idACK);
941
949
 
942
950
  await adapter.setObjectNotExistsAsync(`info.supplyVoltage`, {
@@ -1048,7 +1056,7 @@ const valveControl = {
1048
1056
  }
1049
1057
 
1050
1058
  case 'mainPump': {
1051
- mainPumpControl = await idStateControl(adapter, adapter.config.triggerMainPump);
1059
+ mainPumpControl = await tools.idStateControl(adapter, adapter.config.triggerMainPump);
1052
1060
  currentPumpUse.control = mainPumpControl;
1053
1061
  if (currentPumpUse?.control?.idACK) adapter.subscribeForeignStates(currentPumpUse.control.idACK);
1054
1062
  currentPumpUse.pumpCistern = false;
@@ -1089,7 +1097,7 @@ const valveControl = {
1089
1097
  currentPumpUse.intBreak = true;
1090
1098
  }
1091
1099
 
1092
- cisternPumpControl = await idStateControl(adapter, adapter.config.triggerCisternPump);
1100
+ cisternPumpControl = await tools.idStateControl(adapter, adapter.config.triggerCisternPump);
1093
1101
  currentPumpUse.control = cisternPumpControl;
1094
1102
  if (currentPumpUse?.control?.idACK) adapter.subscribeForeignStates(currentPumpUse.control.idACK);
1095
1103
  currentPumpUse.pumpCistern = false;
@@ -1107,8 +1115,8 @@ const valveControl = {
1107
1115
 
1108
1116
  case 'pumpAndCistern': {
1109
1117
  currentPumpUse.enable = false;
1110
- mainPumpControl = await idStateControl(adapter, adapter.config.triggerMainPump);
1111
- cisternPumpControl = await idStateControl(adapter, adapter.config.triggerCisternPump);
1118
+ mainPumpControl = await tools.idStateControl(adapter, adapter.config.triggerMainPump);
1119
+ cisternPumpControl = await tools.idStateControl(adapter, adapter.config.triggerCisternPump);
1112
1120
  if (mainPumpControl?.idACK) adapter.subscribeForeignStates(mainPumpControl.idACK);
1113
1121
  if (cisternPumpControl?.idACK) adapter.subscribeForeignStates(cisternPumpControl.idACK);
1114
1122
  if (adapter.config.actualValueLevel) {
@@ -1275,11 +1283,11 @@ const valveControl = {
1275
1283
  if (_setValve2 !== entry.control.idState) throw new Error(`update ID: ${entry.name} => An error occurred while updating the irrigation time for Homematic devices. Please check the connection to the device and the configuration of the switching behavior.`);
1276
1284
  } else {
1277
1285
  entry.wateringTime = res.wateringTime;
1278
- adapter.log.debug(`update ID: ${entry.name} new time: ${addTime(res.wateringTime, '')}`);
1286
+ adapter.log.debug(`update ID: ${entry.name} new time: ${tools.addTime(res.wateringTime, '')}`);
1279
1287
  }
1280
1288
  entry.autoOn = res.auto; // auto: = true autostart; = false Handbetrieb
1281
1289
  await adapter.setStateAsync(`sprinkle.${name}.runningTime`, {
1282
- val: addTime(res.wateringTime, ''),
1290
+ val: tools.addTime(res.wateringTime, ''),
1283
1291
  ack: true
1284
1292
  });
1285
1293
  addDone = true; // Sprinkle found
@@ -1324,13 +1332,13 @@ const valveControl = {
1324
1332
  newThread.id = threadList.length || 0;
1325
1333
  threadList.push(newThread);
1326
1334
  /* Zustand des Ventils im Thread < 0 > off, <<< 1 >>> wait, < 2 > on, < 3 > break, < 4 > Boost(on), < 5 > off(Boost), < 6 > Cistern empty, < 7 > extBreak */
1327
- newThread.extBreak ? (newThread.state = 'extBreak') : (newThread.state = 'wait');
1335
+ newThread.extBreak ? (newThread.state = 'extBreak') : timeBasedRestrictionEn === true ? (newThread.state = 'Irrigation ban') : (newThread.state = 'wait');
1328
1336
  adapter.setState(`sprinkle.${name}.sprinklerState`, {
1329
1337
  val: newThread.state,
1330
1338
  ack: true
1331
1339
  });
1332
1340
  adapter.setState(`sprinkle.${name}.runningTime`, {
1333
- val: addTime(res.wateringTime, ''),
1341
+ val: tools.addTime(res.wateringTime, ''),
1334
1342
  ack: true
1335
1343
  });
1336
1344
 
@@ -1344,6 +1352,57 @@ const valveControl = {
1344
1352
 
1345
1353
  }, // End addList
1346
1354
 
1355
+ timeBasedRestriction: async function (enable) { //Irrigation ban => zeitliche Bewässerungsbeschränkung noch zu bearbeiten ! ! !
1356
+ try {
1357
+ timeBasedRestrictionEn = enable;
1358
+ if (threadList) {
1359
+ if (timeBasedRestrictionEn === true) { // zeitliche Bewässerungsbeschränkung aktiv
1360
+ for await (const entry of threadList) {
1361
+ if (entry.enable === true) { // Ventil ist aktiv, dann Ventil ausschalten
1362
+ const _setValve = await setValve(entry, false);
1363
+ if (_setValve === entry.control.idState) {
1364
+ entry.state = 'Irrigation ban';
1365
+ clearInterval(entry.countdown); // Timer Countdown löschen
1366
+ entry.countdown = null;
1367
+ /* Booster zurücksetzen falls aktiv*/
1368
+ if (myConfig.config[entry.sprinkleID].booster) {
1369
+ entry.ac.acBoostOnTimer.abort(entry.extBreak);
1370
+ boostReady = true;
1371
+ boostOn = false;
1372
+ adapter.log.debug(`ID: ${entry.name} UpdateList Sprinkle Off: boostReady = ${boostReady}`);
1373
+ }
1374
+ } else {
1375
+ if(!sendMessageText.onlySendError()){
1376
+ sendMessageText.sendMessage(`The valve, ${entry.name}, could not be deactivated. Please turn it off manually.`);
1377
+ }
1378
+ adapter.log.warn(`The valve, ${entry.name}, could not be deactivated. Please turn it off manually.`);
1379
+ entry.state = 'undefined';
1380
+ }
1381
+ } else {
1382
+ entry.state = 'Irrigation ban';
1383
+ }
1384
+ adapter.setStateAsync(`sprinkle.${entry.name}.sprinklerState`, {
1385
+ val: entry.state,
1386
+ ack: true
1387
+ });
1388
+ }
1389
+ } else {
1390
+ for await (const entry of threadList) { // zeitliche Bewässerungsbeschränkung beendet
1391
+ entry.state = (entry.extBreak === true) ? 'extBreak' : 'wait';
1392
+ adapter.setStateAsync(`sprinkle.${entry.name}.sprinklerState`, {
1393
+ val: entry.state,
1394
+ ack: true
1395
+ });
1396
+ }
1397
+ }
1398
+ }
1399
+ updateList();
1400
+ return true;
1401
+ } catch (error) {
1402
+ adapter.log.warn(`TimeBasedRestriction: ${error}`);
1403
+ return false;
1404
+ }
1405
+ },
1347
1406
  /**
1348
1407
  * extBreak => Spränger unterbrechen bei extBreak
1349
1408
  *
@@ -1353,7 +1412,7 @@ const valveControl = {
1353
1412
  */
1354
1413
  extBreak: async function (sprinkleID, extBreak) {
1355
1414
  try {
1356
- const _found = await findAsync(threadList, async (d) => {
1415
+ const _found = await tools.findAsync(threadList, async (d) => {
1357
1416
  return Promise.resolve (d.sprinkleID === sprinkleID);
1358
1417
  });
1359
1418
 
package/main.js CHANGED
@@ -15,9 +15,8 @@ const controlVoltage = require('./lib/valveControl.js').controlVoltage; // state
15
15
  const currentPumpUse = require('./lib/valveControl.js').currentPumpUse; // state der Pumpen
16
16
  const threadList = require('./lib/valveControl.js').threadList; // Auflistung aller aktiver Sprenger-Kreise
17
17
  const myConfig = require('./lib/myConfig.js'); // myConfig → Speichern und abrufen von Konfigurationsdaten der Ventile
18
- const evaporation = require('./lib/evaporation.js');
19
- const addTime = require('./lib/tools.js').addTime;
20
- const formatTime = require('./lib/tools.js').formatTime;
18
+ const evaporation = require('./lib/evaporation.js'); // Berechnung der Verdunstung, Ermittlung der täglichen Höchsttemperatur, Speicherung der aktuellen Werte von Temperatur, Luftfeuchtigkeit, Helligkeit, Windgeschwindigkeit und Regenmenge
19
+ const tools = require('./lib/tools.js').tools; // tools => laden von Hilfsfunktionen
21
20
 
22
21
  /**
23
22
  * The adapter instance
@@ -30,6 +29,7 @@ let weatherForecastTodayPfadStr; // Pfad zur Regenvorhersage in mm (Regenvorh
30
29
  let weatherForecastTodayNum = 0; // heutige Regenvorhersage in mm
31
30
  let weatherForecastTomorrowNum = 0; // morgige Regenvorhersage in mm
32
31
  let addStartTimeSwitch = false; // Externer Schalter für Zusatzbewässerung
32
+ let irrigationRestriction = false; // Schalter für Bewässerungseinschränkung
33
33
 
34
34
  let startTimeStr;
35
35
  let sunriseStr;
@@ -68,6 +68,8 @@ function startAdapter(options) {
68
68
  /*Startzeiten der Timer löschen*/
69
69
  schedule.cancelJob('calcPosTimer');
70
70
  schedule.cancelJob('sprinkleStartTime');
71
+ schedule.cancelJob('irrigationRestrictionOn');
72
+ schedule.cancelJob('irrigationRestrictionOff');
71
73
  schedule.cancelJob('sprinkleAddStartTime');
72
74
  /* alle Ventile und Aktoren deaktivieren */
73
75
  valveControl.clearEntireList();
@@ -414,7 +416,7 @@ async function curNextFixDay (sprinkleID, returnOn) {
414
416
  const objPfad = `sprinkle.${myConfig.config[sprinkleID].objectName}`;
415
417
  const weekday = ['Sun','Mon','Tue','Wed','Thur','Fri','Sat'];
416
418
  let found = false;
417
- let curDay = formatTime().day;
419
+ let curDay = tools.formatTime().day;
418
420
  const d = new Date();
419
421
  const curTime = `${zweiStellen(d.getHours())}:${zweiStellen(d.getMinutes())}`;
420
422
 
@@ -460,7 +462,7 @@ async function curNextFixDay (sprinkleID, returnOn) {
460
462
  * false → Zweitage-modus (twoNd)
461
463
  */
462
464
  async function setNewDay (indexNr, threeRd) {
463
- const today = formatTime().day;
465
+ const today = tools.formatTime().day;
464
466
  const nextStartDay = ((today + 1) > 6 ? 0 : (today + 1));
465
467
  const objectName = myConfig.config[indexNr].objectName;
466
468
  const _actualSoilMoisture = await adapter.getStateAsync(
@@ -567,7 +569,7 @@ async function checkStates() {
567
569
  }
568
570
 
569
571
  /* akt. kW ermitteln für history last week */
570
- const _formatTime = formatTime();
572
+ const _formatTime = tools.formatTime();
571
573
  kw = _formatTime.kW;
572
574
  today = _formatTime.day;
573
575
  } catch (e) {
@@ -712,7 +714,7 @@ async function checkActualStates () {
712
714
  const calcPos = schedule.scheduleJob('calcPosTimer', '5 0 * * *', function() {
713
715
  // Berechnungen mittels SunCalc
714
716
  sunPos();
715
- const _curTime = formatTime();
717
+ const _curTime = tools.formatTime();
716
718
  today = _curTime.day;
717
719
 
718
720
  // History Daten aktualisieren, wenn eine neue Woche beginnt
@@ -751,6 +753,10 @@ const calcPos = schedule.scheduleJob('calcPosTimer', '5 0 * * *', function() {
751
753
  // Startzeit Festlegen → verzögert wegen Daten von SunCalc
752
754
  setTimeout(() => {
753
755
  startTimeSprinkle();
756
+ if (adapter.config.enableTimeBasedRestriction === true) {
757
+ irrigationRestrictionOn();
758
+ irrigationRestrictionOff();
759
+ }
754
760
  addStartTimeSprinkle();
755
761
  },1000);
756
762
 
@@ -780,6 +786,28 @@ function sunPos() {
780
786
  }
781
787
  }
782
788
 
789
+ function irrigationRestrictionOn() {
790
+ schedule.cancelJob('irrigationRestrictionOn');
791
+ if (adapter.config.enableTimeBasedRestriction === true) {
792
+ const startOfInterruptionSplit = adapter.config.startOfInterruption.split(':');
793
+ const scheduleStartOfInterruption = schedule.scheduleJob('irrigationRestrictionOn', `${ startOfInterruptionSplit[1] } ${ startOfInterruptionSplit[0] } * * *`, function() {
794
+ irrigationRestriction = true;
795
+ valveControl.timeBasedRestriction(true);
796
+ adapter.log.info(`Time-based irrigation restriction is enabled! (${adapter.config.startOfInterruption} - ${adapter.config.endOfInterruption})`);
797
+ });
798
+ }
799
+ }
800
+
801
+ function irrigationRestrictionOff() {
802
+ schedule.cancelJob('irrigationRestrictionOff');
803
+ const endOfInterruptionSplit = adapter.config.endOfInterruption.split(':');
804
+ const scheduleEndOfInterruption = schedule.scheduleJob('irrigationRestrictionOff', `${ endOfInterruptionSplit[1] } ${ endOfInterruptionSplit[0] } * * *`, function() {
805
+ irrigationRestriction = false;
806
+ valveControl.timeBasedRestriction(false);
807
+ adapter.log.info('Time-based irrigation restrictions have been disabled!');
808
+ });
809
+ }
810
+
783
811
  function addStartTimeSprinkle() {
784
812
  schedule.cancelJob('sprinkleAddStartTime');
785
813
  if (adapter.config.selectAddStartTime === 'greaterETpCurrent'
@@ -827,7 +855,7 @@ function addStartTimeSprinkle() {
827
855
  case 'bistable': {
828
856
  if (res.bistable.bool) {
829
857
  messageText += `<b>${res.objectName}</b> (${res.bistable.bool})\n`
830
- + ` ${res.extBreak ? 'extBreak ||' : 'START =>'} ${addTime(Math.round(60 * res.addWateringTime), '')}\n`;
858
+ + ` ${res.extBreak ? 'extBreak ||' : 'START =>'} ${tools.addTime(Math.round(60 * res.addWateringTime), '')}\n`;
831
859
  memAddList.push({
832
860
  auto: false,
833
861
  sprinkleID: res.sprinkleID,
@@ -838,7 +866,7 @@ function addStartTimeSprinkle() {
838
866
  }
839
867
  case 'fixDay': {
840
868
  messageText += `<b>${res.objectName}</b>\n`
841
- + ` ${res.extBreak ? 'extBreak ||' : 'START =>'} ${addTime(Math.round(60 * res.addWateringTime), '')}\n`;
869
+ + ` ${res.extBreak ? 'extBreak ||' : 'START =>'} ${tools.addTime(Math.round(60 * res.addWateringTime), '')}\n`;
842
870
  memAddList.push({
843
871
  auto: false,
844
872
  sprinkleID: res.sprinkleID,
@@ -848,7 +876,7 @@ function addStartTimeSprinkle() {
848
876
  }
849
877
  case 'calculation': {
850
878
  messageText += `<b>${res.objectName}</b> ${res.calculation.pct}% (${res.calculation.pctTriggerIrrigation}%)\n`
851
- + ` ${res.extBreak ? 'extBreak ||' : 'START =>'} ${addTime(Math.round(60 * res.addWateringTime), '')}\n`;
879
+ + ` ${res.extBreak ? 'extBreak ||' : 'START =>'} ${tools.addTime(Math.round(60 * res.addWateringTime), '')}\n`;
852
880
  memAddList.push({
853
881
  auto: false,
854
882
  sprinkleID: res.sprinkleID,
@@ -859,7 +887,7 @@ function addStartTimeSprinkle() {
859
887
  case 'analog': {
860
888
  if (res.analog.pct < res.analog.pctAddTriggersIrrigation) {
861
889
  messageText += `<b>${res.objectName}</b> ${res.analog.pct} %(${res.analog.pctAddTriggersIrrigation}%)\n`
862
- + ` ${res.extBreak ? 'extBreak ||' : 'START =>'} ${addTime(Math.round(60 * res.addWateringTime), '')}\n`;
890
+ + ` ${res.extBreak ? 'extBreak ||' : 'START =>'} ${tools.addTime(Math.round(60 * res.addWateringTime), '')}\n`;
863
891
  memAddList.push({
864
892
  auto: false,
865
893
  sprinkleID: res.sprinkleID,
@@ -947,7 +975,7 @@ function startTimeSprinkle() {
947
975
  case 'livingSunrise' : /*Startauswahl = Sonnenaufgang*/
948
976
  infoMessage = 'Start mit Sonnenaufgang ';
949
977
  // format sunrise time from the Date object
950
- newStartTime = addTime(sunriseStr, parseInt(adapter.config.timeShift));
978
+ newStartTime = tools.addTime(sunriseStr, parseInt(adapter.config.timeShift));
951
979
  break;
952
980
  case 'livingGoldenHourEnd' : /*Startauswahl = Ende der Golden Hour*/
953
981
  infoMessage = 'Start zum Ende der Golden Hour ';
@@ -957,7 +985,7 @@ function startTimeSprinkle() {
957
985
  case 'livingSunset' : /*Startauswahl = Sonnenuntergang*/
958
986
  infoMessage = 'Start mit Sonnenuntergang ';
959
987
  // format sunset time from the Date object
960
- newStartTime = addTime(sunsetStr, parseInt(adapter.config.timeShift));
988
+ newStartTime = tools.addTime(sunsetStr, parseInt(adapter.config.timeShift));
961
989
  break;
962
990
  }
963
991
  // Start am Wochenende →, wenn andere Zeiten verwendet werden soll
@@ -1061,7 +1089,7 @@ const startOfIrrigation = async () => {
1061
1089
  sprinkleID: res.sprinkleID,
1062
1090
  wateringTime: curWateringTime
1063
1091
  });
1064
- messageText += ` ${res.extBreak ? 'extBreak ||' : 'START =>'} ${addTime(curWateringTime, '')}\n`;
1092
+ messageText += ` ${res.extBreak ? 'extBreak ||' : 'START =>'} ${tools.addTime(curWateringTime, '')}\n`;
1065
1093
  } else if (adapter.config.weatherForecastService !== 'noWeatherData') {
1066
1094
  /* Bewässerung unterdrückt da ausreichende Regenvorhersage */
1067
1095
  messageText += ` <i>Start verschoben, da heute ${weatherForecastTodayNum}mm Niederschlag</i> \n`;
@@ -1085,7 +1113,7 @@ const startOfIrrigation = async () => {
1085
1113
  sprinkleID: res.sprinkleID,
1086
1114
  wateringTime: Math.round(60* countdown)
1087
1115
  });
1088
- messageText += ` ${res.extBreak ? 'extBreak ||' : 'START =>'} ${addTime(Math.round(60*countdown), '')}\n}`;
1116
+ messageText += ` ${res.extBreak ? 'extBreak ||' : 'START =>'} ${tools.addTime(Math.round(60*countdown), '')}\n}`;
1089
1117
  } else if (adapter.config.weatherForecastService !== 'noWeatherData') {
1090
1118
  /* Bewässerung unterdrückt da ausreichende Regenvorhersage */
1091
1119
  messageText += ` <i>Start verschoben, da heute ${weatherForecastTodayNum}mm Niederschlag</i> \n`;
@@ -1106,7 +1134,7 @@ const startOfIrrigation = async () => {
1106
1134
  sprinkleID: res.sprinkleID,
1107
1135
  wateringTime: curWateringTime
1108
1136
  });
1109
- messageText += ` ${res.extBreak ? 'extBreak ||' : 'START =>'} ${addTime(curWateringTime, '')}\n`;
1137
+ messageText += ` ${res.extBreak ? 'extBreak ||' : 'START =>'} ${tools.addTime(curWateringTime, '')}\n`;
1110
1138
  if (res.fixDay.startDay === 'threeRd'){ // Next Start in 3 Tagen
1111
1139
  res.fixDay.startFixDay[today] = false;
1112
1140
  res.fixDay.startFixDay[(+ today + 3 > 6) ? (+ today-4) : (+ today+3)] = true;
@@ -1152,7 +1180,7 @@ const startOfIrrigation = async () => {
1152
1180
  sprinkleID: res.sprinkleID,
1153
1181
  wateringTime: Math.round(60*countdown)
1154
1182
  });
1155
- messageText += ` ${res.extBreak ? 'extBreak ||' : 'START =>'} ${addTime(Math.round(60*countdown), '')}\n`;
1183
+ messageText += ` ${res.extBreak ? 'extBreak ||' : 'START =>'} ${tools.addTime(Math.round(60*countdown), '')}\n`;
1156
1184
  } else if (adapter.config.weatherForecastService !== 'noWeatherData') {
1157
1185
  /* Bewässerung unterdrückt da ausreichende Regenvorhersage */
1158
1186
  messageText += ` <i>Start verschoben, da heute ${weatherForecastTodayNum}mm Niederschlag</i> \n`;
@@ -2203,6 +2231,20 @@ async function main() {
2203
2231
  timer = setTimeout(() => {
2204
2232
  startTimeSprinkle();
2205
2233
  addStartTimeSprinkle();
2234
+ if (adapter.config.enableTimeBasedRestriction === true) {
2235
+ if(tools.laterThanTime(adapter.config.startOfInterruption) === true){ // Bewässerungsverbot wird heute noch aktiviert
2236
+ irrigationRestriction = false
2237
+ irrigationRestrictionOn();
2238
+ irrigationRestrictionOff();
2239
+ } else if (tools.laterThanTime(adapter.config.endOfInterruption) === true){ // Bewässerungsverbot aktiv
2240
+ irrigationRestriction = true;
2241
+ irrigationRestrictionOff();
2242
+ valveControl.timeBasedRestriction(true);
2243
+ adapter.log.info(`Time-based irrigation restriction is enabled! (${adapter.config.startOfInterruption} - ${adapter.config.endOfInterruption})`);
2244
+ } else {
2245
+ irrigationRestriction = false; // Bewässerungsverbot war schon aktiv, wird heute nicht mehr aktiviert
2246
+ }
2247
+ }
2206
2248
  }, 1000);
2207
2249
  }
2208
2250
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.sprinklecontrol",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Control of several sprinklers depending on weather conditions and pump performance.",
5
5
  "author": {
6
6
  "name": "Dirk Peter",