iobroker.sprinklecontrol 0.2.16 → 0.2.18
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 +6 -9
- package/io-package.json +27 -27
- package/lib/valveControl.js +169 -145
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -33,6 +33,12 @@ 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.18 (2025-06-30)
|
|
37
|
+
* (Dirk-Peter-md) Hysteresis switch-on value of the cistern changed to 20%
|
|
38
|
+
|
|
39
|
+
### 0.2.17 (2025-06-15)
|
|
40
|
+
* (Dirk-Peter-md) Valve timing corrected
|
|
41
|
+
|
|
36
42
|
### 0.2.16 (2025-06-08)
|
|
37
43
|
* (Dirk-Peter-md) issue #95 Pump lead time added
|
|
38
44
|
|
|
@@ -48,15 +54,6 @@ Wetterabhängige automatische Steuerung der Gartenbewässerung
|
|
|
48
54
|
* (Dirk-Peter-md) issue #92 Sprinkler im Gewächshaus solved
|
|
49
55
|
* (Dirk-Peter-md) add Button control.autoStart
|
|
50
56
|
|
|
51
|
-
### 0.2.13 (2022-09-06)
|
|
52
|
-
* (Dirk-Peter-md) various bugs fixed
|
|
53
|
-
* (Dirk-Peter-md) Preparing the stable release
|
|
54
|
-
|
|
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
57
|
## License
|
|
61
58
|
MIT License
|
|
62
59
|
|
package/io-package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "sprinklecontrol",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.18",
|
|
5
5
|
"titleLang": {
|
|
6
6
|
"en": "Sprinkler Control",
|
|
7
7
|
"de": "Sprinklersteuerung",
|
|
@@ -19,6 +19,32 @@
|
|
|
19
19
|
"Dirk Peter <dirk.peter@freenet.de>"
|
|
20
20
|
],
|
|
21
21
|
"news": {
|
|
22
|
+
"0.2.18": {
|
|
23
|
+
"en": "Hysteresis switch-on value of the cistern changed to 20%",
|
|
24
|
+
"de": "Hysterese Einschaltwert der Zisterne auf 20% geändert",
|
|
25
|
+
"ru": "Значение Hysteresis switch-on цистерны изменилось до 20%",
|
|
26
|
+
"pt": "O valor da histerese da cisterna mudou para 20%",
|
|
27
|
+
"nl": "Hysterese schakelaar waarde van de cisterne veranderd in 20%",
|
|
28
|
+
"fr": "La valeur d'activation de l'hystérie de la citerne est passée à 20%",
|
|
29
|
+
"it": "Il valore di commutazione della cisterna di Hysteresis è cambiato al 20%",
|
|
30
|
+
"es": "El valor de conmutación de la histeria cambió al 20%",
|
|
31
|
+
"pl": "Zmiana wartości hysterezy cysterny na 20%",
|
|
32
|
+
"uk": "Гістерез змінився на 20%",
|
|
33
|
+
"zh-cn": "贮器的开关值改为20%"
|
|
34
|
+
},
|
|
35
|
+
"0.2.17": {
|
|
36
|
+
"en": "Valve timing corrected",
|
|
37
|
+
"de": "Ventilzeit korrigiert",
|
|
38
|
+
"ru": "Время клапана скорректировано",
|
|
39
|
+
"pt": "Regulação da válvula",
|
|
40
|
+
"nl": "Gecorrigeerde kleptijd",
|
|
41
|
+
"fr": "Réglage de la vanne",
|
|
42
|
+
"it": "Valvola tempistica corretta",
|
|
43
|
+
"es": "Tiempo de válvula corregido",
|
|
44
|
+
"pl": "Skorygowany czas zaworu",
|
|
45
|
+
"uk": "Терміни клапана, виправлені",
|
|
46
|
+
"zh-cn": "阀门时间得到纠正"
|
|
47
|
+
},
|
|
22
48
|
"0.2.16": {
|
|
23
49
|
"en": "issue #95 Pump lead time added",
|
|
24
50
|
"de": "ausgabe #95 Pumpe Lieferzeit hinzugefügt",
|
|
@@ -83,32 +109,6 @@
|
|
|
83
109
|
"pl": "fixDay(twoNd, tripleRd) =>. Odroczony przez jeden dzień; Bug fixed => autoOn; dodatkowy post-watering => w przypadku dużego odparowania i przełącznika zewnętrznego",
|
|
84
110
|
"uk": "fixDay(twoNd,threeRd) => відкласти на один день; Виправлено помилку => autoOn; Додатковий дополив => у разі високого випаровування / перемикається зовні",
|
|
85
111
|
"zh-cn": "fix Day(两名Nd,三Rd)=> 一天推迟;Bug固定=汽车;额外的水事后=在高度疏散/外部可转换的情况下。"
|
|
86
|
-
},
|
|
87
|
-
"0.2.11": {
|
|
88
|
-
"en": "Bug fixed => analogue soil moisture sensor with negative characteristic; Attention => maximum soil moisture in rain now in %",
|
|
89
|
-
"de": "Fehler behoben => analoger Bodenfeuchtesensor mit negativer Kennlinie; Achtung => maximale Bodenfeuchte bei Regen jetzt in %",
|
|
90
|
-
"ru": "Исправлена ошибка => аналоговый датчик влажности почвы с отрицательной характеристикой; Внимание => максимальная влажность почвы в дождь теперь в %",
|
|
91
|
-
"pt": "Bug corrigido => sensor analógico de umidade do solo com característica negativa; Atenção => umidade máxima do solo na chuva agora em %",
|
|
92
|
-
"nl": "Bug opgelost => analoge bodemvochtsensor met negatieve karakteristiek; Let op => maximale bodemvochtigheid bij regen nu in %",
|
|
93
|
-
"fr": "Bug corrigé => capteur d'humidité du sol analogique avec caractéristique négative ; Attention => humidité maximale du sol sous la pluie maintenant en %",
|
|
94
|
-
"it": "Bug risolto => sensore di umidità del suolo analogico con caratteristica negativa; Attenzione => umidità massima del suolo sotto la pioggia ora in %",
|
|
95
|
-
"es": "Error solucionado => sensor de humedad del suelo analógico con característica negativa; Atención => humedad máxima del suelo en lluvia ahora en %",
|
|
96
|
-
"pl": "Poprawiony błąd => analogowy czujnik wilgotności gleby o charakterystyce ujemnej; Uwaga => maksymalna wilgotność gleby w deszczu teraz w %",
|
|
97
|
-
"uk": "Виправлено помилку => аналоговий датчик вологості ґрунту з негативною характеристикою; Увага => максимальна вологість ґрунту під час дощу зараз у %",
|
|
98
|
-
"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": {
|
package/lib/valveControl.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
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
|
-
|
|
217
|
-
|
|
218
|
-
|
|
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
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
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
|
-
|
|
251
|
-
|
|
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
|
-
|
|
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 (
|
|
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
|
/* --------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
|
|
@@ -487,7 +502,9 @@ function setActualPump () {
|
|
|
487
502
|
/* Zisternen-Bewässerung Einstellung in der config (2. Pumpe) aktiviert */
|
|
488
503
|
if (currentPumpUse.enable === true) {
|
|
489
504
|
/* Bewässerungspumpen aktiv */
|
|
490
|
-
if ((fillLevelCistern < parseFloat(adapter.config.triggerMinCisternLevel))
|
|
505
|
+
if ((fillLevelCistern < parseFloat(adapter.config.triggerMinCisternLevel))
|
|
506
|
+
&& (currentPumpUse.pumpCistern === true)
|
|
507
|
+
) {
|
|
491
508
|
/* (Zisterne unter Minimum) && (ZisternenPumpe läuft) */
|
|
492
509
|
adapter.setForeignState(currentPumpUse.pumpName, {
|
|
493
510
|
val: false,
|
|
@@ -508,7 +525,7 @@ function setActualPump () {
|
|
|
508
525
|
updateList(); // Wasserverbrauch an Pumpenleistung anpassen
|
|
509
526
|
}
|
|
510
527
|
if (fillLevelCistern < parseFloat(adapter.config.triggerMinCisternLevel)) {
|
|
511
|
-
statusCistern = `Cistern empty: ${fillLevelCistern} % (${adapter.config.triggerMinCisternLevel +
|
|
528
|
+
statusCistern = `Cistern empty: ${fillLevelCistern} % (${adapter.config.triggerMinCisternLevel + 20} %)`;
|
|
512
529
|
adapter.setState('info.cisternState', {
|
|
513
530
|
val: statusCistern,
|
|
514
531
|
ack: true
|
|
@@ -522,14 +539,19 @@ function setActualPump () {
|
|
|
522
539
|
}
|
|
523
540
|
} else {
|
|
524
541
|
/* Bewässerungspumpen inaktiv */
|
|
525
|
-
if ((fillLevelCistern >= (parseFloat(adapter.config.triggerMinCisternLevel) +
|
|
542
|
+
if ((fillLevelCistern >= (parseFloat(adapter.config.triggerMinCisternLevel) + 20))
|
|
543
|
+
&& (adapter.config.triggerCisternPump)
|
|
544
|
+
&& (adapter.config.triggerCisternPumpPower)
|
|
545
|
+
) {
|
|
526
546
|
/* Zisterne voll && triggerCisternPump && triggerCisternPumpPower vorhanden*/
|
|
527
547
|
statusCistern = `Cistern filled: ${fillLevelCistern} % (${adapter.config.triggerMinCisternLevel} %)`;
|
|
528
548
|
adapter.setState('info.cisternState', {
|
|
529
549
|
val: statusCistern,
|
|
530
550
|
ack: true
|
|
531
551
|
});
|
|
532
|
-
if (currentPumpUse.pumpCistern === false
|
|
552
|
+
if (currentPumpUse.pumpCistern === false
|
|
553
|
+
&& !sendMessageText.onlySendError()
|
|
554
|
+
) {
|
|
533
555
|
sendMessageText.sendMessage(`Cistern filled: ${fillLevelCistern} % (${adapter.config.triggerMinCisternLevel} %)`);
|
|
534
556
|
}
|
|
535
557
|
currentPumpUse.pumpCistern = true;
|
|
@@ -541,7 +563,7 @@ function setActualPump () {
|
|
|
541
563
|
ack: true
|
|
542
564
|
});
|
|
543
565
|
} else {
|
|
544
|
-
statusCistern = `Cistern empty: ${fillLevelCistern} % (${adapter.config.triggerMinCisternLevel +
|
|
566
|
+
statusCistern = `Cistern empty: ${fillLevelCistern} % (${adapter.config.triggerMinCisternLevel + 20} %)`;
|
|
545
567
|
adapter.setState('info.cisternState', {
|
|
546
568
|
val: statusCistern,
|
|
547
569
|
ack: true
|
|
@@ -559,7 +581,7 @@ function setActualPump () {
|
|
|
559
581
|
} else {
|
|
560
582
|
/* Pumpe AUS => Zisternen-Bewässerung nicht aktiviert */
|
|
561
583
|
if (adapter.config.triggerCisternPump) {
|
|
562
|
-
statusCistern = `Cistern settings are not active!${(fillLevelCistern > 0)?(` level sensor: ${fillLevelCistern}
|
|
584
|
+
statusCistern = `Cistern settings are not active!${(fillLevelCistern > 0)?(` level sensor: ${fillLevelCistern} % ${(adapter.config.triggerMinCisternLevel !== '')?(`${adapter.config.triggerMinCisternLevel} %`):('')}`):('')}`;
|
|
563
585
|
adapter.setState('info.cisternState', {
|
|
564
586
|
val: statusCistern,
|
|
565
587
|
ack: true
|
|
@@ -575,6 +597,7 @@ function setActualPump () {
|
|
|
575
597
|
* @param pumpOnOff ; Pumpe on = true
|
|
576
598
|
*/
|
|
577
599
|
const setPumpOnOff = async (pumpOnOff) => {
|
|
600
|
+
clearTimeout(idValveDelayTime);
|
|
578
601
|
if (currentPumpUse.pumpName !== '') {
|
|
579
602
|
try {
|
|
580
603
|
const curPumpState = await adapter.getForeignStateAsync(currentPumpUse.pumpName);
|
|
@@ -586,7 +609,7 @@ const setPumpOnOff = async (pumpOnOff) => {
|
|
|
586
609
|
ack: false
|
|
587
610
|
});
|
|
588
611
|
currentPumpUse.enable = true;
|
|
589
|
-
adapter.log.info(
|
|
612
|
+
adapter.log.info(`Set (pump) on, wait ${currentPumpUse.leadTime}ms`);
|
|
590
613
|
await valveDelay(currentPumpUse.leadTime);
|
|
591
614
|
}
|
|
592
615
|
} else {
|
|
@@ -875,6 +898,7 @@ const valveControl = {
|
|
|
875
898
|
* => Beim Beenden des adapters alles ausschalten
|
|
876
899
|
*/
|
|
877
900
|
clearEntireList () {
|
|
901
|
+
clearTimeout(idValveDelayTime);
|
|
878
902
|
setVoltageOnOff(false);
|
|
879
903
|
setPumpOnOff(false);
|
|
880
904
|
if (boostListTimer) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.sprinklecontrol",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.18",
|
|
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.
|
|
47
|
-
"sinon": "^
|
|
46
|
+
"mocha": "^11.6.0",
|
|
47
|
+
"sinon": "^21.0.0",
|
|
48
48
|
"sinon-chai": "^4.0.0"
|
|
49
49
|
},
|
|
50
50
|
"main": "main.js",
|