iobroker.sprinklecontrol 0.2.16 → 0.2.17

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.
package/README.md CHANGED
@@ -33,6 +33,9 @@ Wetterabhängige automatische Steuerung der Gartenbewässerung
33
33
  Placeholder for the next version (at the beginning of the line):
34
34
  ### **WORK IN PROGRESS**
35
35
  -->
36
+ ### 0.2.17 (2025-06-15)
37
+ * (Dirk-Peter-md) Valve timing corrected
38
+
36
39
  ### 0.2.16 (2025-06-08)
37
40
  * (Dirk-Peter-md) issue #95 Pump lead time added
38
41
 
@@ -52,11 +55,6 @@ Wetterabhängige automatische Steuerung der Gartenbewässerung
52
55
  * (Dirk-Peter-md) various bugs fixed
53
56
  * (Dirk-Peter-md) Preparing the stable release
54
57
 
55
- ### 0.2.12 (2022-07-17)
56
- * (Dirk-Peter-md) fixDay(twoNd,threeRd) => postpone by one day
57
- * (Dirk-Peter-md) Bug fixed => autoOn
58
- * (Dirk-Peter-md) Additional post-watering => in case of high evaporation / switchable externally
59
-
60
58
  ## License
61
59
  MIT License
62
60
 
package/io-package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "sprinklecontrol",
4
- "version": "0.2.16",
4
+ "version": "0.2.17",
5
5
  "titleLang": {
6
6
  "en": "Sprinkler Control",
7
7
  "de": "Sprinklersteuerung",
@@ -19,6 +19,19 @@
19
19
  "Dirk Peter <dirk.peter@freenet.de>"
20
20
  ],
21
21
  "news": {
22
+ "0.2.17": {
23
+ "en": "Valve timing corrected",
24
+ "de": "Ventilzeit korrigiert",
25
+ "ru": "Время клапана скорректировано",
26
+ "pt": "Regulação da válvula",
27
+ "nl": "Gecorrigeerde kleptijd",
28
+ "fr": "Réglage de la vanne",
29
+ "it": "Valvola tempistica corretta",
30
+ "es": "Tiempo de válvula corregido",
31
+ "pl": "Skorygowany czas zaworu",
32
+ "uk": "Терміни клапана, виправлені",
33
+ "zh-cn": "阀门时间得到纠正"
34
+ },
22
35
  "0.2.16": {
23
36
  "en": "issue #95 Pump lead time added",
24
37
  "de": "ausgabe #95 Pumpe Lieferzeit hinzugefügt",
@@ -96,19 +109,6 @@
96
109
  "pl": "Poprawiony błąd => analogowy czujnik wilgotności gleby o charakterystyce ujemnej; Uwaga => maksymalna wilgotność gleby w deszczu teraz w %",
97
110
  "uk": "Виправлено помилку => аналоговий датчик вологості ґрунту з негативною характеристикою; Увага => максимальна вологість ґрунту під час дощу зараз у %",
98
111
  "zh-cn": "错误修复 => 具有负特性的模拟土壤湿度传感器;注意 => 现在雨中的最大土壤水分百分比"
99
- },
100
- "0.2.10": {
101
- "en": "- manual watering limited to a maximum of 100%; - Error whatsapp message fixed",
102
- "de": "- manuelle Bewässerung begrenzt auf maximal 100 %; - Fehler WhatsApp-Nachricht behoben",
103
- "ru": "- ручной полив ограничен максимум 100%; - Исправлено сообщение об ошибке WhatsApp",
104
- "pt": "- rega manual limitada a um máximo de 100%; - Mensagem de erro do whatsapp corrigida",
105
- "nl": "- handmatige bewatering beperkt tot maximaal 100%; - Fout whatsapp-bericht opgelost",
106
- "fr": "- arrosage manuel limité à 100% maximum ; - Message d'erreur WhatsApp corrigé",
107
- "it": "- irrigazione manuale limitata ad un massimo del 100%; - Errore messaggio whatsapp risolto",
108
- "es": "- riego manual limitado a un máximo del 100%; - Mensaje de error de whatsapp arreglado",
109
- "pl": "- nawadnianie ręczne ograniczone do maksymalnie 100%; - Naprawiono błąd wiadomości WhatsApp",
110
- "uk": "- ручний полив обмежений максимум на 100%; - Виправлено повідомлення про помилку WhatsApp",
111
- "zh-cn": "- 手动浇水限制为最大 100%; - 错误whatsapp消息已修复"
112
112
  }
113
113
  },
114
114
  "desc": {
@@ -27,6 +27,8 @@ let maxParallel = 0;
27
27
  /** Füllstand der Zisterne */
28
28
  let fillLevelCistern = 0;
29
29
  let statusCistern = '';
30
+ /** Speicherort von setTimeout */
31
+ let idValveDelayTime;
30
32
 
31
33
  const currentPumpUse = {
32
34
  /** Pumpen aktive? */
@@ -39,6 +41,7 @@ const currentPumpUse = {
39
41
  pumpPower: 0
40
42
  };
41
43
 
44
+ const updateListMarker = {funcActive: false, newStart: false};
42
45
 
43
46
  /*==============================================================================================================================================*/
44
47
  /* interne Funktionen */
@@ -181,14 +184,14 @@ function boostKill (sprinkleID) {
181
184
  */
182
185
  const valveDelay = (delay = parseInt(adapter.config.switchingDistance)) => {
183
186
  return new Promise (
184
- resolve => setTimeout (resolve, delay)
187
+ resolve => idValveDelayTime = setTimeout (resolve, delay)
185
188
  );
186
189
  };
187
190
 
188
191
  /**
189
192
  * Ausschalten der Ventile mit Schaltabstand
190
193
  *
191
- * @param threadList Auflistung aller aktiver Sprenger-Kreise
194
+ * @param threadList Auflistung aller aktiven Sprenger-Kreise
192
195
  * @param parallel aktuelle Anzahl der eingeschalteten Ventile
193
196
  * @returns
194
197
  */
@@ -203,24 +206,24 @@ const switchTheValvesOffOn = async (threadList, parallel) => {
203
206
  || entry.killSprinkle) // || Bewässerung erledigt
204
207
  && entry.enabled !== entry.enabledState // && Ventil nicht aktuell
205
208
  ) {
206
- adapter.setForeignState(entry.idState, {
207
- val: false,
208
- ack: false
209
- }, (err) => {
210
- if (err) {
211
- return err;
212
- } else {
213
- adapter.log.info(`Set (${myConfig.config[entry.sprinkleID].methodControlSM}) ID: ${entry.sprinkleName}, value: ${entry.enabled}`);
209
+ try {
210
+ adapter.setForeignStateAsync(entry.idState, {
211
+ val: false,
212
+ ack: false
213
+ });
214
+ entry.enabledState = entry.enabled;
215
+ /* Ventil aus threadList löschen → Aufgabe beendet und sind nicht in der Pause */
216
+ if (entry.killSprinkle) {
217
+ killList.push(entry.sprinkleName);
214
218
  }
215
- });
216
- entry.enabledState = entry.enabled;
217
- /* Ventil aus threadList löschen → Aufgabe beendet und sind nicht in der Pause */
218
- if (entry.killSprinkle) {
219
- killList.push(entry.sprinkleName);
219
+ adapter.log.info(`Set (${myConfig.config[entry.sprinkleID].methodControlSM}) ID: ${entry.sprinkleName}, value: ${entry.enabled}`);
220
+ await valveDelay ();
221
+ } catch (error) {
222
+ adapter.log.error(`Error(ID: ${entry.sprinkleName}): ${error}`);
220
223
  }
221
- await valveDelay ();
222
224
  }
223
225
  }
226
+
224
227
  if (currentPumpUse.pumpName !== '') {
225
228
  await setPumpOnOff(parallel > 0);
226
229
  await valveDelay ();
@@ -230,31 +233,140 @@ const switchTheValvesOffOn = async (threadList, parallel) => {
230
233
  await valveDelay ();
231
234
  }
232
235
 
233
-
234
236
  for (const entry of threadList) { // einschalten der Ventile
235
237
  if (entry.enabled // intern eingeschaltet
236
238
  && !entry.myBreak // && keine Pause
237
239
  && !entry.killSprinkle // Bewässerung noch nicht erledigt
238
240
  && entry.enabled !== entry.enabledState // && Ventil nicht aktuell
239
241
  ) {
240
- adapter.setForeignState(entry.idState, {
241
- val: true,
242
- ack: false
243
- }, (err) => {
244
- if (err) {
245
- return err;
246
- } else {
247
- adapter.log.info(`Set Valve (${myConfig.config[entry.sprinkleID].methodControlSM}) ID: ${entry.sprinkleName}, value: ${entry.enabled}, duration: ${addTime(entry.wateringTime)}`);
242
+ try {
243
+ adapter.setForeignState(entry.idState, {
244
+ val: true,
245
+ ack: false
246
+ });
247
+ entry.enabledState = entry.enabled;
248
+ if (myConfig.config[entry.sprinkleID].booster) {
249
+ boostReady = false;
250
+ adapter.log.debug(`ID: ${entry.sprinkleName}UpdateList sprinkle On: boostReady = ${boostReady}`);
251
+ setTimeout(() => {
252
+ boostList(entry.sprinkleID);
253
+ }, 50);
248
254
  }
249
- });
250
- entry.enabledState = entry.enabled;
251
- await valveDelay ();
255
+ /* Zustand des Ventils im Thread < 0 > off, < 1 > wait, <<< 2 >>> on, < 3 > break, < 4 > Boost(on), < 5 > off(Boost) */
256
+ adapter.setState(`sprinkle.${entry.sprinkleName}.sprinklerState`, {
257
+ val: 2,
258
+ ack: true
259
+ });
260
+ // valveOnOff(entry, true, '#2.7 Set: on, ID: ');
261
+ /* countdown starten */
262
+ if (!entry.startTime) {
263
+ entry.startTime = new Date();
264
+ }
265
+ entry.countdown = setInterval(() => {
266
+ countSprinkleTime(entry);
267
+ }, 1000); // 1000 = 1s
268
+ adapter.log.info(`Set Valve (${myConfig.config[entry.sprinkleID].methodControlSM}) ID: ${entry.sprinkleName}, value: ${entry.enabled}, duration: ${addTime(entry.wateringTime)}`);
269
+ await valveDelay ();
270
+ } catch (error) {
271
+ adapter.log.error(`Error(ID: ${entry.sprinkleName}): ${error}`);
272
+ }
273
+
252
274
  }
253
275
  }
254
276
 
255
277
  delList(killList); // erledigte Bewässerungsaufgaben aus der threadList löschen
256
278
  };
257
279
 
280
+ /**
281
+ * Handling von Ventilen, Zeiten, Verbrauchsmengen im 1s Takt
282
+ *
283
+ * @param entry
284
+ */
285
+ function countSprinkleTime(entry) {
286
+ /* --- function beenden wenn ---*/
287
+ if (boostOn && !(myConfig.config[entry.sprinkleID].booster) // boost-On && kein aktuelles Boost-Ventil
288
+ ) {
289
+ return;
290
+ }
291
+ entry.count ++;
292
+ if ((entry.count < entry.wateringTime) // Zeit noch nicht abgelaufen?
293
+ && (!entry.calcOn // alles ausser Berechnung der Verdunstung
294
+ || !entry.autoOn // Handbetrieb
295
+ || (myConfig.config[entry.sprinkleID].soilMoisture.val < myConfig.config[entry.sprinkleID].soilMoisture.maxIrrigation)) // Bodenfeuchte noch nicht erreicht? (z.B. beim Regen)
296
+ ) { /* Zeit läuft */
297
+ adapter.setState(`sprinkle.${entry.sprinkleName}.countdown`, {
298
+ val: addTime(entry.wateringTime - entry.count),
299
+ ack: true
300
+ });
301
+ /* Alle 15s die Bodenfeuchte anpassen */
302
+ if (entry.calcOn // Vergleich nur bei Berechnung der Verdunstung
303
+ && !(entry.count % 15) // alle 15s ausführen
304
+ ) {
305
+ myConfig.addSoilMoistVal(entry.sprinkleID, entry.soilMoisture15s);
306
+ }
307
+ /* Intervall-Beregnung wenn angegeben (onOffTime > 0) */
308
+ if ((entry.onOffTime > 0) && !(entry.count % entry.onOffTime)) {
309
+ adapter.log.info(`Intervall-Beregnung, onOffTime: ${entry.onOffTime}, count: ${entry.count}`);
310
+ entry.enabled = false;
311
+ entry.myBreak = true;
312
+ /* Zustand des Ventils im Thread < 0 > off, < 1 > wait, < 2 > on, <<< 3 >>> break, < 4 > Boost(on), < 5 > off(Boost) */
313
+ adapter.setState(`sprinkle.${entry.sprinkleName}.sprinklerState`, {
314
+ val: 3,
315
+ ack: true
316
+ });
317
+ updateList();
318
+ clearInterval(entry.countdown);
319
+ entry.onOffTimeoutOff = setTimeout(()=>{
320
+ entry.myBreak = false;
321
+ /* Zustand des Ventils im Thread < 0 > off, <<< 1 >>> wait, < 2 > on, < 3 > break, < 4 > Boost(on), < 5 > off(Boost) */
322
+ adapter.setState(`sprinkle.${entry.sprinkleName}.sprinklerState`, {
323
+ val: 1,
324
+ ack: true
325
+ });
326
+ updateList();
327
+ },1000 * (entry.onOffTime < 600 ? 600 : entry.onOffTime)); // 600 sek Pause (10 min)
328
+ }
329
+ } else { /* zeit abgelaufen => Ventil ausschalten */
330
+ /* Zustand des Ventils im Thread <<< 0 >>> off, < 1 > wait, < 2 > on, < 3 > break, < 4 > Boost(on), < 5 > off(Boost) */
331
+ entry.enabled = false;
332
+ adapter.setState(`sprinkle.${entry.sprinkleName}.sprinklerState`, {
333
+ val: 0,
334
+ ack: true
335
+ });
336
+ adapter.setState(`sprinkle.${entry.sprinkleName}.runningTime`, {
337
+ val: '0',
338
+ ack: true
339
+ });
340
+ adapter.setState(`sprinkle.${entry.sprinkleName}.countdown`, {
341
+ val: '0',
342
+ ack: true
343
+ });
344
+
345
+ /* Wenn in der Konfiguration Bodenfeuchte = 100% gesetzt ist und Auto-Bewässerung aktive, dann Bodenfeuchte = 100% setzen*/
346
+ if (entry.autoOn && entry.calcOn && myConfig.config[entry.sprinkleID].endIrrigation) {
347
+ myConfig.setSoilMoistPct100(entry.sprinkleID);
348
+ }
349
+ /* Verbrauchswerte in der Historie aktualisieren */
350
+ addConsumedAndTime(entry);
351
+ /* Booster zurücksetzen */
352
+ if (myConfig.config[entry.sprinkleID].booster) {
353
+ if (boostOn) {
354
+ boostKill(entry.sprinkleID);
355
+ }
356
+ boostReady = true;
357
+ adapter.log.debug(`ID: ${entry.sprinkleName} UpdateList Sprinkle Off: boostReady = ${boostReady}`);
358
+ }
359
+ /* Zeiten löschen */
360
+ clearInterval(entry.countdown);
361
+ /*clearTimeout(entry.onOffTimeoutOn);*/
362
+ clearTimeout(entry.onOffTimeoutOff);
363
+ /* Ventil aus threadList löschen → Aufgabe beendet */
364
+ //delList(entry.sprinkleName);
365
+ entry.killSprinkle = true;
366
+ updateList();
367
+ }
368
+ }
369
+
258
370
  /*----------------------------------------------------------------------------------------------------------------------------------------------*/
259
371
 
260
372
  /**
@@ -267,6 +379,11 @@ function updateList () {
267
379
  return;
268
380
  }
269
381
 
382
+ if (updateListMarker.funcActive === true) {
383
+ updateListMarker.newStart = true;
384
+ return;
385
+ }
386
+ updateListMarker.funcActive = true;
270
387
  /** aktuelle Rest-Pumpenleistung */
271
388
  let curFlow = currentPumpUse.pumpPower, /* adapter.config.triggerMainPumpPower; */
272
389
  /** aktuelle Anzahl der eingeschalteten Ventile */
@@ -296,95 +413,6 @@ function updateList () {
296
413
  (a.pipeFlow > b.pipeFlow) ? 1 :
297
414
  0;
298
415
  }
299
- /**
300
- * Handling von Ventilen, Zeiten, Verbrauchsmengen im 1s Takt
301
- *
302
- * @param entry
303
- */
304
- function countSprinkleTime(entry) {
305
- /* --- function beenden wenn ---*/
306
- if (boostOn && !(myConfig.config[entry.sprinkleID].booster) // boost-On && kein aktuelles Boost-Ventil
307
- ) {
308
- return;
309
- }
310
- entry.count ++;
311
- if ((entry.count < entry.wateringTime) // Zeit noch nicht abgelaufen?
312
- && (!entry.calcOn // alles ausser Berechnung der Verdunstung
313
- || !entry.autoOn // Handbetrieb
314
- || (myConfig.config[entry.sprinkleID].soilMoisture.val < myConfig.config[entry.sprinkleID].soilMoisture.maxIrrigation)) // Bodenfeuchte noch nicht erreicht? (z.B. beim Regen)
315
- ) { /* Zeit läuft */
316
- adapter.setState(`sprinkle.${entry.sprinkleName}.countdown`, {
317
- val: addTime(entry.wateringTime - entry.count),
318
- ack: true
319
- });
320
- /* Alle 15s die Bodenfeuchte anpassen */
321
- if (entry.calcOn // Vergleich nur bei Berechnung der Verdunstung
322
- && !(entry.count % 15) // alle 15s ausführen
323
- ) {
324
- myConfig.addSoilMoistVal(entry.sprinkleID, entry.soilMoisture15s);
325
- }
326
- /* Intervall-Beregnung wenn angegeben (onOffTime > 0) */
327
- if ((entry.onOffTime > 0) && !(entry.count % entry.onOffTime)) {
328
- adapter.log.info(`Intervall-Beregnung, onOffTime: ${entry.onOffTime}, count: ${entry.count}`);
329
- entry.enabled = false;
330
- entry.myBreak = true;
331
- /* Zustand des Ventils im Thread < 0 > off, < 1 > wait, < 2 > on, <<< 3 >>> break, < 4 > Boost(on), < 5 > off(Boost) */
332
- adapter.setState(`sprinkle.${entry.sprinkleName}.sprinklerState`, {
333
- val: 3,
334
- ack: true
335
- });
336
- updateList();
337
- clearInterval(entry.countdown);
338
- entry.onOffTimeoutOff = setTimeout(()=>{
339
- entry.myBreak = false;
340
- /* Zustand des Ventils im Thread < 0 > off, <<< 1 >>> wait, < 2 > on, < 3 > break, < 4 > Boost(on), < 5 > off(Boost) */
341
- adapter.setState(`sprinkle.${entry.sprinkleName}.sprinklerState`, {
342
- val: 1,
343
- ack: true
344
- });
345
- updateList();
346
- },1000 * (entry.onOffTime < 600 ? 600 : entry.onOffTime)); // 600 sek Pause (10 min)
347
- }
348
- } else { /* zeit abgelaufen => Ventil ausschalten */
349
- /* Zustand des Ventils im Thread <<< 0 >>> off, < 1 > wait, < 2 > on, < 3 > break, < 4 > Boost(on), < 5 > off(Boost) */
350
- entry.enabled = false;
351
- adapter.setState(`sprinkle.${entry.sprinkleName}.sprinklerState`, {
352
- val: 0,
353
- ack: true
354
- });
355
- adapter.setState(`sprinkle.${entry.sprinkleName}.runningTime`, {
356
- val: '0',
357
- ack: true
358
- });
359
- adapter.setState(`sprinkle.${entry.sprinkleName}.countdown`, {
360
- val: '0',
361
- ack: true
362
- });
363
-
364
- /* Wenn in der Konfiguration Bodenfeuchte = 100% gesetzt ist und Auto-Bewässerung aktive, dann Bodenfeuchte = 100% setzen*/
365
- if (entry.autoOn && entry.calcOn && myConfig.config[entry.sprinkleID].endIrrigation) {
366
- myConfig.setSoilMoistPct100(entry.sprinkleID);
367
- }
368
- /* Verbrauchswerte in der Historie aktualisieren */
369
- addConsumedAndTime(entry);
370
- /* Booster zurücksetzen */
371
- if (myConfig.config[entry.sprinkleID].booster) {
372
- if (boostOn) {
373
- boostKill(entry.sprinkleID);
374
- }
375
- boostReady = true;
376
- adapter.log.debug(`ID: ${entry.sprinkleName} UpdateList Sprinkle Off: boostReady = ${boostReady}`);
377
- }
378
- /* Zeiten löschen */
379
- clearInterval(entry.countdown);
380
- /*clearTimeout(entry.onOffTimeoutOn);*/
381
- clearTimeout(entry.onOffTimeoutOff);
382
- /* Ventil aus threadList löschen → Aufgabe beendet */
383
- //delList(entry.sprinkleName);
384
- entry.killSprinkle = true;
385
- updateList();
386
- }
387
- }
388
416
 
389
417
  // ermitteln von curPipe und der anzahl der parallelen Stränge
390
418
  for(const entry of threadList){
@@ -433,28 +461,9 @@ function updateList () {
433
461
  && ((boostReady) || !(myConfig.config[entry.sprinkleID].booster)) // nur einer mit boostFunction darf aktive sein
434
462
  ) {
435
463
  entry.enabled = true; // einschalten merken
436
- if (myConfig.config[entry.sprinkleID].booster) {
437
- boostReady = false;
438
- adapter.log.debug(`ID: ${entry.sprinkleName}UpdateList sprinkle On: boostReady = ${boostReady}`);
439
- setTimeout(() => {
440
- boostList(entry.sprinkleID);
441
- }, 50);
442
- }
464
+
443
465
  curFlow -= entry.pipeFlow; // ermitteln der RestFörderkapazität
444
466
  parallel++; // Anzahl der Bewässerungsstellen um 1 erhöhen
445
- /* Zustand des Ventils im Thread < 0 > off, < 1 > wait, <<< 2 >>> on, < 3 > break, < 4 > Boost(on), < 5 > off(Boost) */
446
- adapter.setState(`sprinkle.${entry.sprinkleName}.sprinklerState`, {
447
- val: 2,
448
- ack: true
449
- });
450
- // valveOnOff(entry, true, '#2.7 Set: on, ID: ');
451
- /* countdown starten */
452
- if (!entry.startTime) {
453
- entry.startTime = new Date();
454
- }
455
- entry.countdown = setInterval(() => {
456
- countSprinkleTime(entry);
457
- }, 1000); // 1000 = 1s
458
467
 
459
468
  }
460
469
  }
@@ -471,9 +480,15 @@ function updateList () {
471
480
  switchTheValvesOffOn(threadList, parallel).then(err => {
472
481
  if (err) {
473
482
  adapter.log.error(`Error - Set (false) err: ${err}`);
474
- sendMessageText.sendMessage(`Error - Set (fase) err: ${err}`);
483
+ sendMessageText.sendMessage(`Error - Set (false) err: ${err}`);
475
484
  }
476
485
  });
486
+
487
+ updateListMarker.funcActive = false;
488
+ if (updateListMarker.newStart === true) {
489
+ updateListMarker.newStart = false;
490
+ setTimeout(updateList(), 50);
491
+ }
477
492
  } // End updateList
478
493
 
479
494
  /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
@@ -575,6 +590,7 @@ function setActualPump () {
575
590
  * @param pumpOnOff ; Pumpe on = true
576
591
  */
577
592
  const setPumpOnOff = async (pumpOnOff) => {
593
+ clearTimeout(idValveDelayTime);
578
594
  if (currentPumpUse.pumpName !== '') {
579
595
  try {
580
596
  const curPumpState = await adapter.getForeignStateAsync(currentPumpUse.pumpName);
@@ -586,7 +602,7 @@ const setPumpOnOff = async (pumpOnOff) => {
586
602
  ack: false
587
603
  });
588
604
  currentPumpUse.enable = true;
589
- adapter.log.info('Set (pump) on');
605
+ adapter.log.info(`Set (pump) on, wait ${currentPumpUse.leadTime}ms`);
590
606
  await valveDelay(currentPumpUse.leadTime);
591
607
  }
592
608
  } else {
@@ -875,6 +891,7 @@ const valveControl = {
875
891
  * => Beim Beenden des adapters alles ausschalten
876
892
  */
877
893
  clearEntireList () {
894
+ clearTimeout(idValveDelayTime);
878
895
  setVoltageOnOff(false);
879
896
  setPumpOnOff(false);
880
897
  if (boostListTimer) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.sprinklecontrol",
3
- "version": "0.2.16",
3
+ "version": "0.2.17",
4
4
  "description": "Control of several sprinklers depending on weather conditions and pump performance.",
5
5
  "author": {
6
6
  "name": "Dirk Peter",
@@ -43,8 +43,8 @@
43
43
  "@iobroker/testing": "^5.0.4",
44
44
  "chai": "^5.2.0",
45
45
  "chai-as-promised": "^8.0.1",
46
- "mocha": "^11.5.0",
47
- "sinon": "^20.0.0",
46
+ "mocha": "^11.6.0",
47
+ "sinon": "^21.0.0",
48
48
  "sinon-chai": "^4.0.0"
49
49
  },
50
50
  "main": "main.js",