iobroker.sprinklecontrol 0.2.10 → 0.2.13
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 +47 -51
- package/admin/index_m.html +115 -37
- package/admin/index_m.js +108 -12
- package/admin/words.js +131 -118
- package/docs/de/img/E-Mail.jpg +0 -0
- package/docs/de/img/Extraeinstellungen.jpg +0 -0
- package/docs/de/img/Pumpeneinstellung.jpg +0 -0
- package/docs/de/img/Pushover.jpg +0 -0
- package/docs/de/img/Select_ID.jpg +0 -0
- package/docs/de/img/Telegram.jpg +0 -0
- package/docs/de/img/Ventil-Haupteinstellung.jpg +0 -0
- package/docs/de/img/Ventil-Pumpeneinstellung.jpg +0 -0
- package/docs/de/img/WhatsApp.jpg +0 -0
- package/docs/de/img/Zeiteinstellung.jpg +0 -0
- package/docs/de/img/addTime.jpg +0 -0
- package/docs/de/img/analog.jpg +0 -0
- package/docs/de/img/ber-verdunstung.jpg +0 -0
- package/docs/de/img/bew-einstellung.jpg +0 -0
- package/docs/de/img/bew-feste-tage.jpg +0 -0
- package/docs/de/img/bistabil.jpg +0 -0
- package/docs/de/img/bodenf-analog.jpg +0 -0
- package/docs/de/img/bodenf-bistabil.jpg +0 -0
- package/docs/de/img/calculation.jpg +0 -0
- package/docs/de/img/einschaltpunkt-giessen.jpg +0 -0
- package/docs/de/img/festeTage.jpg +0 -0
- package/docs/de/img/main.jpg +0 -0
- package/docs/de/img/main_tab.jpg +0 -0
- package/docs/de/img/max-bodenfeuchtigkeit.jpg +0 -0
- package/docs/de/img/verdunstDiagra.jpg +0 -0
- package/docs/de/img/zus-bew-einstellung.jpg +0 -0
- package/docs/de/sprinklecontrol.md +123 -55
- package/io-package.json +63 -69
- package/lib/evaporation.js +9 -2
- package/lib/myConfig.js +79 -31
- package/lib/tools.js +9 -2
- package/lib/valveControl.js +17 -10
- package/main.js +432 -147
- package/package.json +20 -17
- package/.commitmessage +0 -4
package/main.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
3
|
-
info: log aufbau main.js: #0.*
|
|
4
|
-
*/
|
|
2
|
+
|
|
5
3
|
// Load your modules here, e.g.: => // Laden Sie Ihre Module hier, z.B.
|
|
6
4
|
// const fs = require("fs");
|
|
7
5
|
|
|
@@ -29,19 +27,27 @@ const adapterName = require('./package.json').name.split('.').pop();
|
|
|
29
27
|
let publicHolidayStr;
|
|
30
28
|
/** @type {any} */
|
|
31
29
|
let publicHolidayTomorrowStr;
|
|
32
|
-
/* DasWetter.com */
|
|
30
|
+
/* Regenvorhersage - DasWetter.com */
|
|
31
|
+
/** @type {string}
|
|
32
|
+
* - Pfad zur Regenvorhersage in mm */
|
|
33
|
+
let weatherForecastTodayPfadStr;
|
|
33
34
|
/** @type {number}
|
|
34
35
|
* - heutige Regenvorhersage in mm */
|
|
35
36
|
let weatherForecastTodayNum = 0;
|
|
36
37
|
/** @type {number}
|
|
37
38
|
* - morgige Regenvorhersage in mm */
|
|
38
39
|
let weatherForecastTomorrowNum = 0;
|
|
40
|
+
/** @type {boolean}
|
|
41
|
+
* - Externer Schalter für Zusatzbewässerung */
|
|
42
|
+
let addStartTimeSwitch = false;
|
|
39
43
|
|
|
40
44
|
/** @type {string} */
|
|
41
45
|
let startTimeStr;
|
|
42
46
|
/** @type {string} */
|
|
43
47
|
let sunriseStr;
|
|
44
48
|
/** @type {string} */
|
|
49
|
+
let sunsetStr;
|
|
50
|
+
/** @type {string} */
|
|
45
51
|
let goldenHourEnd;
|
|
46
52
|
/** switch => sprinklecontrol.*.control.Holiday
|
|
47
53
|
* - Wenn (Holiday == true) ist, soll das Wochenendprogramm gefahren werden.
|
|
@@ -73,7 +79,13 @@ function startAdapter(options) {
|
|
|
73
79
|
adapter = new utils.Adapter(options);
|
|
74
80
|
|
|
75
81
|
// start here!
|
|
76
|
-
adapter.on('ready', () =>
|
|
82
|
+
adapter.on('ready', () => {
|
|
83
|
+
// init createConfig
|
|
84
|
+
myConfig.createConfig(adapter);
|
|
85
|
+
// Hauptpumpe zur Bewässerung setzen
|
|
86
|
+
valveControl.initValveControl(adapter);
|
|
87
|
+
main(adapter)
|
|
88
|
+
});
|
|
77
89
|
|
|
78
90
|
/**
|
|
79
91
|
* +++++++++++++++++++++++++ is called when adapter shuts down +++++++++++++++++++++++++
|
|
@@ -94,6 +106,7 @@ function startAdapter(options) {
|
|
|
94
106
|
/*Startzeiten der Timer löschen*/
|
|
95
107
|
schedule.cancelJob('calcPosTimer');
|
|
96
108
|
schedule.cancelJob('sprinkleStartTime');
|
|
109
|
+
schedule.cancelJob('sprinkleAddStartTime');
|
|
97
110
|
/* alle Ventile und Aktoren deaktivieren */
|
|
98
111
|
valveControl.clearEntireList();
|
|
99
112
|
|
|
@@ -108,7 +121,7 @@ function startAdapter(options) {
|
|
|
108
121
|
* -------------- Antwortet bei Aufrufen von getTelegramUser von index_m ---------------
|
|
109
122
|
* @param {object} obj
|
|
110
123
|
*/
|
|
111
|
-
adapter.on('message', (obj) => {
|
|
124
|
+
adapter.on ('message', (obj) => {
|
|
112
125
|
if (obj) {
|
|
113
126
|
switch (obj.command) {
|
|
114
127
|
case 'getTelegramUser':
|
|
@@ -156,14 +169,30 @@ function startAdapter(options) {
|
|
|
156
169
|
adapter.log.debug(`state ${id} changed: ${state.val} (ack = ${state.ack})`);
|
|
157
170
|
|
|
158
171
|
// wenn (Holiday == true) ist, soll das Wochenendprogramm gefahren werden.
|
|
159
|
-
if (id === adapter.namespace + '.control.Holiday') {
|
|
172
|
+
if (id === adapter.namespace + '.control.Holiday' && state.ack === false) {
|
|
160
173
|
holidayStr = state.val;
|
|
174
|
+
adapter.setState(id, {
|
|
175
|
+
val: state.val,
|
|
176
|
+
ack: true
|
|
177
|
+
});
|
|
161
178
|
startTimeSprinkle();
|
|
162
179
|
}
|
|
180
|
+
// wenn (addStartTimeSwitch == true) wird die zusätzliche Bewässerung aktiviert
|
|
181
|
+
if (id === `${adapter.namespace}.control.addStartTimeSwitch` && typeof state.val === 'boolean' && state.ack === false) {
|
|
182
|
+
addStartTimeSwitch = state.val;
|
|
183
|
+
adapter.setState(id, {
|
|
184
|
+
val: state.val,
|
|
185
|
+
ack: true
|
|
186
|
+
});
|
|
187
|
+
}
|
|
163
188
|
// wenn (autoOnOff == false) so werden alle Sprenger nicht mehr automatisch gestartet.
|
|
164
|
-
if (id === adapter.namespace + '.control.autoOnOff') {
|
|
189
|
+
if ((id === adapter.namespace + '.control.autoOnOff') && (state.ack === false)) {
|
|
165
190
|
autoOnOffStr = state.val;
|
|
166
191
|
adapter.log.info(`startAdapter: control.autoOnOff: ${state.val}`);
|
|
192
|
+
adapter.setState(id, {
|
|
193
|
+
val: state.val,
|
|
194
|
+
ack: true
|
|
195
|
+
});
|
|
167
196
|
if (!state.val) {
|
|
168
197
|
valveControl.clearEntireList();
|
|
169
198
|
}
|
|
@@ -182,11 +211,15 @@ function startAdapter(options) {
|
|
|
182
211
|
sprinkleID: found.sprinkleID,
|
|
183
212
|
wateringTime: (state.val <= 0) ? state.val : Math.round(60 * state.val)
|
|
184
213
|
}]);
|
|
214
|
+
adapter.setState(id, {
|
|
215
|
+
val: state.val,
|
|
216
|
+
ack: true
|
|
217
|
+
});
|
|
185
218
|
}
|
|
186
219
|
}
|
|
187
220
|
}
|
|
188
221
|
}
|
|
189
|
-
// wenn in der config unter methodControlSM
|
|
222
|
+
// wenn in der config unter methodControlSM!== 'analog' oder 'bistable' eingegeben wurde, dann Bodenfeuchte-Sensor auslesen
|
|
190
223
|
if (myConfig.config) {
|
|
191
224
|
function filterByID(obj){
|
|
192
225
|
return (((obj.methodControlSM === 'analog') || (obj.methodControlSM === 'bistable')) && (obj.triggerSM === id));
|
|
@@ -205,13 +238,42 @@ function startAdapter(options) {
|
|
|
205
238
|
}
|
|
206
239
|
}
|
|
207
240
|
}
|
|
208
|
-
|
|
209
241
|
// wenn (...sprinkleName.autoOn == false[off]) so wird der aktuelle Sprenger [sprinkleName]
|
|
210
242
|
// bei false nicht automatisch gestartet
|
|
211
|
-
if (myConfig.config && (typeof state.val === 'boolean')) {
|
|
243
|
+
if (myConfig.config && (typeof state.val === 'boolean') && (state.ack === false)) {
|
|
212
244
|
const found = myConfig.config.find(d => d.autoOnID === id);
|
|
213
|
-
if (found && id === myConfig.config[found.sprinkleID].autoOnID) {
|
|
245
|
+
if (found && id === myConfig.config[found.sprinkleID].autoOnID) {
|
|
246
|
+
myConfig.config[found.sprinkleID].autoOn = state.val;
|
|
247
|
+
adapter.setState(id, { // Bestätigung
|
|
248
|
+
val: state.val,
|
|
249
|
+
ack: true
|
|
250
|
+
});
|
|
251
|
+
adapter.log.info(`set ${found.objectName}.autoOn = ${state.val}, id: ${id}`);
|
|
252
|
+
if (state.val === false) {
|
|
253
|
+
valveControl.addList(
|
|
254
|
+
[{
|
|
255
|
+
auto: false,
|
|
256
|
+
sprinkleID: found.sprinkleID,
|
|
257
|
+
wateringTime: 0
|
|
258
|
+
}]
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
214
262
|
}
|
|
263
|
+
|
|
264
|
+
// postponeByOneDay → um einen Tag verschieben bei fixDay (twoNd & threeRd)
|
|
265
|
+
let idSplit = id.split('.', 5);
|
|
266
|
+
if (idSplit[4] === `postponeByOneDay` && state.ack === false) {
|
|
267
|
+
const found = myConfig.config.find(d => d.objectName === idSplit[3]);
|
|
268
|
+
if (found) {
|
|
269
|
+
myConfig.postponeByOneDay(found.sprinkleID).catch((e) => {adapter.log.warn(`postponeByOneDay: ${e}`)});
|
|
270
|
+
adapter.setState(id, {
|
|
271
|
+
val: false,
|
|
272
|
+
ack: true
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
215
277
|
// Change in outside temperature → Änderung der Außentemperatur
|
|
216
278
|
if (id === adapter.config.sensorOutsideTemperature) { /*Temperatur*/
|
|
217
279
|
if (!Number.isNaN(Number.parseFloat(state.val))) {
|
|
@@ -267,7 +329,7 @@ function startAdapter(options) {
|
|
|
267
329
|
}
|
|
268
330
|
// Wettervorhersage
|
|
269
331
|
if (adapter.config.weatherForecast === true) {
|
|
270
|
-
if (id ===
|
|
332
|
+
if (id === weatherForecastTodayPfadStr) {
|
|
271
333
|
if (typeof state.val == 'string') {
|
|
272
334
|
weatherForecastTodayNum = parseFloat(state.val);
|
|
273
335
|
} else if (typeof state.val == 'number') {
|
|
@@ -320,7 +382,7 @@ async function GetSystemData() {
|
|
|
320
382
|
|
|
321
383
|
adapter.log.debug(`longitude: ${adapter.config.longitude} | latitude: ${adapter.config.latitude}`);
|
|
322
384
|
} else {
|
|
323
|
-
adapter.log.error('system settings cannot be called up. Please check
|
|
385
|
+
adapter.log.error('system settings cannot be called up. Please check the geo data');
|
|
324
386
|
}
|
|
325
387
|
} catch (err) {
|
|
326
388
|
adapter.log.warn('system settings cannot be called up. Please check configuration!');
|
|
@@ -340,11 +402,12 @@ function curNextFixDay (sprinkleID, returnOn) {
|
|
|
340
402
|
const weekDayArray = myConfig.config[sprinkleID].startFixDay;
|
|
341
403
|
const objPfad = 'sprinkle.' + myConfig.config[sprinkleID].objectName;
|
|
342
404
|
const weekday = ['Sun','Mon','Tue','Wed','Thur','Fri','Sat'];
|
|
405
|
+
let found = false;
|
|
343
406
|
let curDay = formatTime(adapter, '', 'day');
|
|
344
407
|
for ( let i=0; i<7; i++ ) {
|
|
345
|
-
curDay++;
|
|
346
408
|
if (curDay > 6) {curDay = curDay - 7;}
|
|
347
409
|
if (weekDayArray[curDay] === true) {
|
|
410
|
+
found = true;
|
|
348
411
|
if (returnOn) {
|
|
349
412
|
return weekday[curDay];
|
|
350
413
|
} else {
|
|
@@ -355,7 +418,9 @@ function curNextFixDay (sprinkleID, returnOn) {
|
|
|
355
418
|
}
|
|
356
419
|
break;
|
|
357
420
|
}
|
|
421
|
+
curDay++;
|
|
358
422
|
}
|
|
423
|
+
if (returnOn && found === false) {return 'off'}
|
|
359
424
|
}
|
|
360
425
|
|
|
361
426
|
//
|
|
@@ -364,7 +429,6 @@ function curNextFixDay (sprinkleID, returnOn) {
|
|
|
364
429
|
* → Setzt den Status beim Start auf einen definierten Wert
|
|
365
430
|
*/
|
|
366
431
|
function checkStates() {
|
|
367
|
-
//
|
|
368
432
|
/**
|
|
369
433
|
* control.Holiday
|
|
370
434
|
* @param {string|null} err
|
|
@@ -381,7 +445,9 @@ function checkStates() {
|
|
|
381
445
|
* @param {ioBroker.State|null|undefined} state
|
|
382
446
|
*/
|
|
383
447
|
adapter.getState('control.autoOnOff', (err, state) => {
|
|
384
|
-
if (state && (state.val
|
|
448
|
+
if (state && (typeof state.val === "boolean")) {
|
|
449
|
+
autoOnOffStr = state.val;
|
|
450
|
+
} else {
|
|
385
451
|
autoOnOffStr = true;
|
|
386
452
|
adapter.setState('control.autoOnOff', {
|
|
387
453
|
val: autoOnOffStr,
|
|
@@ -422,21 +488,21 @@ async function checkActualStates () {
|
|
|
422
488
|
try {
|
|
423
489
|
/**
|
|
424
490
|
* switch Holiday
|
|
425
|
-
* @type {ioBroker.
|
|
426
|
-
* @private
|
|
491
|
+
* @type {ioBroker.State | null}
|
|
492
|
+
* @private
|
|
427
493
|
*/
|
|
428
494
|
const _holiday = await adapter.getStateAsync('control.Holiday');
|
|
429
|
-
if (_holiday && _holiday.val) {
|
|
495
|
+
if (_holiday && _holiday.val && typeof _holiday.val === "boolean") {
|
|
430
496
|
holidayStr = _holiday.val;
|
|
431
497
|
}
|
|
432
498
|
|
|
433
499
|
/**
|
|
434
500
|
* switch autoOnOff
|
|
435
|
-
* @type {ioBroker.
|
|
436
|
-
* @private
|
|
501
|
+
* @type {ioBroker.State | null}
|
|
502
|
+
* @private
|
|
437
503
|
*/
|
|
438
504
|
const _autoOnOff = await adapter.getStateAsync('control.autoOnOff');
|
|
439
|
-
if (_autoOnOff && _autoOnOff.val) {
|
|
505
|
+
if (_autoOnOff && _autoOnOff.val && typeof _autoOnOff.val === "boolean") {
|
|
440
506
|
autoOnOffStr = _autoOnOff.val;
|
|
441
507
|
}
|
|
442
508
|
|
|
@@ -472,7 +538,7 @@ async function checkActualStates () {
|
|
|
472
538
|
* @private
|
|
473
539
|
*/
|
|
474
540
|
const _weatherForInstanceToday = await adapter.getForeignStateAsync(
|
|
475
|
-
|
|
541
|
+
weatherForecastTodayPfadStr
|
|
476
542
|
).catch((e) => adapter.log.warn(e));
|
|
477
543
|
if (_weatherForInstanceToday && _weatherForInstanceToday.val) {
|
|
478
544
|
if (typeof _weatherForInstanceToday.val == 'string') {
|
|
@@ -506,16 +572,41 @@ async function checkActualStates () {
|
|
|
506
572
|
);
|
|
507
573
|
}
|
|
508
574
|
}
|
|
575
|
+
|
|
576
|
+
// wenn (...sprinkleName.autoOn == false[off]) so wird der aktuelle Sprenger [sprinkleName]
|
|
577
|
+
// bei false nicht automatisch gestartet
|
|
578
|
+
/**
|
|
579
|
+
* Abfrage von ...sprinkleName.autoOn
|
|
580
|
+
* @type {[myConfig.config]}
|
|
581
|
+
*/
|
|
582
|
+
const result = myConfig.config;
|
|
583
|
+
if (result) {
|
|
584
|
+
for (const res of result) {
|
|
585
|
+
/**
|
|
586
|
+
* Abfrage ... .autoOn beim Start
|
|
587
|
+
* @type {ioBroker.State | void}
|
|
588
|
+
* @private
|
|
589
|
+
*/
|
|
590
|
+
const _autoOn = await adapter.getForeignStateAsync(
|
|
591
|
+
res.autoOnID
|
|
592
|
+
).catch((e) => adapter.log.warn(e));
|
|
593
|
+
if (_autoOn && typeof _autoOn.val === 'boolean') {
|
|
594
|
+
res.autoOn = _autoOn.val;
|
|
595
|
+
if (_autoOn.val === false) {adapter.log.info(`get ${res.objectName}.autoOn = ${res.autoOn}`)}
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
|
|
509
600
|
if (adapter.config.actualValueLevel){
|
|
510
601
|
/**
|
|
511
|
-
* Füllstand der Zisterne in %
|
|
602
|
+
* Füllstand der Zisterne in % holen
|
|
512
603
|
* @type {ioBroker.State | void}
|
|
513
604
|
* @private
|
|
514
605
|
*/
|
|
515
606
|
const _actualValueLevel = await adapter.getForeignStateAsync(
|
|
516
607
|
adapter.config.actualValueLevel
|
|
517
608
|
).catch((e) => adapter.log.warn(e));
|
|
518
|
-
if (_actualValueLevel && typeof _actualValueLevel.val
|
|
609
|
+
if (_actualValueLevel && typeof parseFloat(_actualValueLevel.val) === "number") {
|
|
519
610
|
valveControl.setFillLevelCistern(parseFloat(_actualValueLevel.val));
|
|
520
611
|
}
|
|
521
612
|
}
|
|
@@ -528,9 +619,6 @@ async function checkActualStates () {
|
|
|
528
619
|
const _list = await adapter.getForeignObjectsAsync(adapter.namespace + '.sprinkle.*', 'channel').catch((e) => adapter.log.warn(e));
|
|
529
620
|
if (_list) {
|
|
530
621
|
ObjSprinkle = _list;
|
|
531
|
-
await createSprinklers();
|
|
532
|
-
await sleep(100);
|
|
533
|
-
startTimeSprinkle();
|
|
534
622
|
}
|
|
535
623
|
|
|
536
624
|
} catch (e) {
|
|
@@ -583,6 +671,7 @@ const calcPos = schedule.scheduleJob('calcPosTimer', '5 0 * * *', function() {
|
|
|
583
671
|
// Startzeit Festlegen → verzögert wegen Daten von SunCalc
|
|
584
672
|
setTimeout(() => {
|
|
585
673
|
startTimeSprinkle();
|
|
674
|
+
addStartTimeSprinkle();
|
|
586
675
|
},1000);
|
|
587
676
|
|
|
588
677
|
});
|
|
@@ -595,11 +684,119 @@ function sunPos() {
|
|
|
595
684
|
// format sunrise time from the Date object → Formatieren Sie die Sonnenaufgangszeit aus dem Date-Objekt
|
|
596
685
|
sunriseStr = ('0' + times.sunrise.getHours()).slice(-2) + ':' + ('0' + times.sunrise.getMinutes()).slice(-2);
|
|
597
686
|
|
|
598
|
-
// format golden hour end time from the Date object
|
|
687
|
+
// format golden hour end time from the Date object → Formatiere golden hour end time aus dem Date-Objekt
|
|
599
688
|
goldenHourEnd = ('0' + times.goldenHourEnd.getHours()).slice(-2) + ':' + ('0' + times.goldenHourEnd.getMinutes()).slice(-2);
|
|
689
|
+
|
|
690
|
+
// format sunset time from the Date object → formatieren Sie die Sonnenuntergangszeit aus dem Date-Objekt
|
|
691
|
+
sunsetStr = sunsetStr = ('0' + times.sunset.getHours()).slice(-2) + ':' + ('0' + times.sunset.getMinutes()).slice(-2);
|
|
600
692
|
|
|
601
693
|
}
|
|
602
694
|
|
|
695
|
+
function addStartTimeSprinkle() {
|
|
696
|
+
schedule.cancelJob('sprinkleAddStartTime');
|
|
697
|
+
if (adapter.config.selectAddStartTime === 'greaterETpCurrent' || adapter.config.selectAddStartTime === 'withExternalSignal') {
|
|
698
|
+
let addStartTimeSplit = adapter.config.addWateringStartTime.split(':');
|
|
699
|
+
const scheduleAddStartTime = schedule.scheduleJob('sprinkleAddStartTime', addStartTimeSplit[1] + ' ' + addStartTimeSplit[0] + ' * * *', function() {
|
|
700
|
+
// if (autoOnOff == false) => keine auto Start
|
|
701
|
+
if (!autoOnOffStr) {
|
|
702
|
+
schedule.cancelJob('sprinkleAddStartTime');
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
705
|
+
if (((adapter.config.selectAddStartTime === 'greaterETpCurrent') && (adapter.config.triggerAddStartTimeETpCur < evaporation.getETpTodayNum()))
|
|
706
|
+
|| (adapter.config.selectAddStartTime === 'withExternalSignal' && addStartTimeSwitch)) {
|
|
707
|
+
let messageText = '';
|
|
708
|
+
|
|
709
|
+
// Filter enabled
|
|
710
|
+
const result = myConfig.config.filter(d => d.enabled === true);
|
|
711
|
+
if (result) {
|
|
712
|
+
/**
|
|
713
|
+
* Array zum flüchtigen Sammeln von Bewässerungsaufgaben
|
|
714
|
+
* @type {Array.<{auto: Boolean, sprinkleID: Number, wateringTime: Number}>}
|
|
715
|
+
*/
|
|
716
|
+
const memAddList = [];
|
|
717
|
+
|
|
718
|
+
/**
|
|
719
|
+
* result Rain
|
|
720
|
+
* - (aktuelle Wettervorhersage - Schwellwert der Regenberücksichtigung) wenn Sensor sich im Freien befindet
|
|
721
|
+
* - (> 0) es regnet - Abbruch -
|
|
722
|
+
* - (≤ 0) Start der Bewässerung
|
|
723
|
+
* @param {boolean} inGreenhouse - Sensor befindet sich im Gewächshaus
|
|
724
|
+
* @returns {number} - resultierende Regenmenge
|
|
725
|
+
*/
|
|
726
|
+
function resRain (inGreenhouse) {
|
|
727
|
+
return (adapter.config.weatherForecast && !inGreenhouse) ? (((+ weatherForecastTodayNum) - parseFloat(adapter.config.thresholdRain)).toFixed(1)) : 0;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
for(const res of result) {
|
|
731
|
+
if (res.autoOn // Ventil aktiv
|
|
732
|
+
&& (res.addWateringTime > 0) // zusätzliche Bewässerung aktiv time > 0
|
|
733
|
+
&& (resRain(res.inGreenhouse) <= 0)) { // keine Regenvorhersage
|
|
734
|
+
|
|
735
|
+
switch (res.methodControlSM) {
|
|
736
|
+
case 'bistable':
|
|
737
|
+
if (res.soilMoisture.bool) {
|
|
738
|
+
messageText += `<b>${res.objectName}</b> (${res.soilMoisture.bool})\n`
|
|
739
|
+
+ ` START => ${addTime(res.addWateringTime, '')}\n`;
|
|
740
|
+
memAddList.push({
|
|
741
|
+
auto: true,
|
|
742
|
+
sprinkleID: res.sprinkleID,
|
|
743
|
+
wateringTime: res.addWateringTime
|
|
744
|
+
});
|
|
745
|
+
}
|
|
746
|
+
break;
|
|
747
|
+
case 'fixDay':
|
|
748
|
+
messageText += `<b>${res.objectName}</b>\n`
|
|
749
|
+
+ ` START => ${addTime(Math.round(60 * res.addWateringTime), '')}\n`;
|
|
750
|
+
memAddList.push({
|
|
751
|
+
auto: true,
|
|
752
|
+
sprinkleID: res.sprinkleID,
|
|
753
|
+
wateringTime: Math.round(60 * res.addWateringTime)
|
|
754
|
+
});
|
|
755
|
+
break;
|
|
756
|
+
case 'calculation':
|
|
757
|
+
let addCountdown = res.wateringTime * (res.soilMoisture.maxIrrigation - res.soilMoisture.val) / (res.soilMoisture.maxIrrigation - res.soilMoisture.triggersIrrigation) - res.wateringTime;
|
|
758
|
+
adapter.log.debug(`addCountdown: ${addCountdown}, addWateringTime: ${res.addWateringTime}, if(${(addCountdown - res.addWateringTime) > 0})`);
|
|
759
|
+
if ((addCountdown - res.addWateringTime) > 0) {
|
|
760
|
+
messageText += `<b>${res.objectName}</b> ${res.soilMoisture.pct}% (${res.soilMoisture.pctTriggerIrrigation}%)\n`
|
|
761
|
+
+ ` START => ${addTime(Math.round(60 * addCountdown), '')}\n`;
|
|
762
|
+
memAddList.push({
|
|
763
|
+
auto: true,
|
|
764
|
+
sprinkleID: res.sprinkleID,
|
|
765
|
+
wateringTime: Math.round(60 * addCountdown)
|
|
766
|
+
});
|
|
767
|
+
}
|
|
768
|
+
break;
|
|
769
|
+
case 'analog':
|
|
770
|
+
if (res.soilMoisture.pct < res.soilMoisture.pctAddTriggersIrrigation) {
|
|
771
|
+
messageText += `<b>${res.objectName}</b> ${res.soilMoisture.pct} %(${res.soilMoisture.pctAddTriggersIrrigation}%)\n`
|
|
772
|
+
+ ` START => ${addTime(Math.round(60 * res.addWateringTime), '')}\n`;
|
|
773
|
+
memAddList.push({
|
|
774
|
+
auto: true,
|
|
775
|
+
sprinkleID: res.sprinkleID,
|
|
776
|
+
wateringTime: Math.round(60 * res.addWateringTime)
|
|
777
|
+
});
|
|
778
|
+
}
|
|
779
|
+
break;
|
|
780
|
+
}
|
|
781
|
+
} else {
|
|
782
|
+
adapter.log.debug(`${res.objectName}: autoOn (${res.autoOn}) && addWateringTime (${res.addWateringTime} > 0) && resRain (${resRain(res.inGreenhouse)}) <= 0, if(${res.autoOn && (res.addWateringTime > 0) && (resRain(res.inGreenhouse) <= 0)})`);
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
valveControl.addList(memAddList);
|
|
786
|
+
}
|
|
787
|
+
if(!sendMessageText.onlySendError() && messageText.length > 0){
|
|
788
|
+
sendMessageText.sendMessage(messageText);
|
|
789
|
+
}
|
|
790
|
+
} else {
|
|
791
|
+
adapter.log.debug(`greaterETpCurrent: ${(adapter.config.selectAddStartTime === 'greaterETpCurrent')} & ${(adapter.config.triggerAddStartTimeETpCur < evaporation.getETpTodayNum())}, withExternalSignal; ${(adapter.config.selectAddStartTime === 'withExternalSignal')} & ${addStartTimeSwitch}`);
|
|
792
|
+
}
|
|
793
|
+
setTimeout(()=>{
|
|
794
|
+
schedule.cancelJob('sprinkleAddStartTime');
|
|
795
|
+
}, 200);
|
|
796
|
+
});
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
|
|
603
800
|
// Determination of the irrigation time => Bestimmung der Bewässerungszeit
|
|
604
801
|
function startTimeSprinkle() {
|
|
605
802
|
let startTimeSplit = [];
|
|
@@ -608,9 +805,9 @@ function startTimeSprinkle() {
|
|
|
608
805
|
|
|
609
806
|
schedule.cancelJob('sprinkleStartTime');
|
|
610
807
|
|
|
611
|
-
// if autoOnOff == false => keine auto Start
|
|
808
|
+
// if (autoOnOff == false) => keine auto Start
|
|
612
809
|
if (!autoOnOffStr) {
|
|
613
|
-
adapter.log.info(`Sprinkle: autoOnOff == Aus( ${autoOnOffStr} )`);
|
|
810
|
+
adapter.log.info(`Sprinkle: autoOnOff == Aus ( ${autoOnOffStr} )`);
|
|
614
811
|
adapter.setState('info.nextAutoStart', {
|
|
615
812
|
val: 'autoOnOff = off(0)',
|
|
616
813
|
ack: true
|
|
@@ -654,7 +851,7 @@ function startTimeSprinkle() {
|
|
|
654
851
|
break;
|
|
655
852
|
case 'livingSunrise' : /*Startauswahl = Sonnenaufgang*/
|
|
656
853
|
infoMessage = 'Start mit Sonnenaufgang ';
|
|
657
|
-
// format
|
|
854
|
+
// format sunrise time from the Date object
|
|
658
855
|
newStartTime = addTime(sunriseStr, parseInt(adapter.config.timeShift));
|
|
659
856
|
break;
|
|
660
857
|
case 'livingGoldenHourEnd' : /*Startauswahl = Ende der Golden Hour*/
|
|
@@ -662,9 +859,14 @@ function startTimeSprinkle() {
|
|
|
662
859
|
// format goldenHourEnd time from the Date object
|
|
663
860
|
newStartTime = goldenHourEnd;
|
|
664
861
|
break;
|
|
862
|
+
case 'livingSunset' : /*Startauswahl = Sonnenuntergang*/
|
|
863
|
+
infoMessage = 'Start mit Sonnenuntergang ';
|
|
864
|
+
// format sunset time from the Date object
|
|
865
|
+
newStartTime = addTime(sunsetStr, parseInt(adapter.config.timeShift));
|
|
866
|
+
break;
|
|
665
867
|
}
|
|
666
868
|
// Start am Wochenende →, wenn andere Zeiten verwendet werden soll
|
|
667
|
-
if((adapter.config.publicWeekend) && ((myWeekday
|
|
869
|
+
if((adapter.config.publicWeekend) && ((myWeekday === 6) || (myWeekday === 0))){
|
|
668
870
|
infoMessage = 'Start am Wochenende ';
|
|
669
871
|
newStartTime = adapter.config.weekEndLiving;
|
|
670
872
|
}
|
|
@@ -792,9 +994,10 @@ function startTimeSprinkle() {
|
|
|
792
994
|
// --- fixDay -- Start an festen Tagen ohne Sensoren --- //
|
|
793
995
|
// -- Bewässerungstag erreicht //
|
|
794
996
|
case 'fixDay':
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
997
|
+
/* Wenn in der Config Regenvorhersage aktiviert: Startvorgang abbrechen, wenn der Regen den eingegebenen Schwellwert überschreitet. */
|
|
998
|
+
if (resRain(false) <= 0) {
|
|
999
|
+
// Bewässerungstag erreicht
|
|
1000
|
+
if (res.startFixDay[today]) {
|
|
798
1001
|
const curWateringTime = Math.round(60 * res.wateringTime * evaporation.timeExtension(res.wateringAdd));
|
|
799
1002
|
memAddList.push({
|
|
800
1003
|
auto: true,
|
|
@@ -809,14 +1012,22 @@ function startTimeSprinkle() {
|
|
|
809
1012
|
res.startFixDay[today] = false;
|
|
810
1013
|
res.startFixDay[(+ today + 2 > 6) ? (+ today-5) : (+ today+2)] = true;
|
|
811
1014
|
}
|
|
812
|
-
} else if (adapter.config.weatherForecast){
|
|
813
|
-
messageText += ' ' + '<i>' + 'Start verschoben, da heute ' + weatherForecastTodayNum + 'mm Niederschlag' + '</i> ' + '\n';
|
|
814
|
-
adapter.log.info(`${res.objectName}: Start verschoben, da Regenvorhersage für Heute ${weatherForecastTodayNum} mm [ ${resRain(false)} > 0 ]`);
|
|
815
|
-
res.startFixDay[today] = false;
|
|
816
|
-
res.startFixDay[(+ today + 1 > 6) ? (+ today-6) : (+ today+1)] = true;
|
|
817
1015
|
}
|
|
818
|
-
|
|
1016
|
+
} else if (adapter.config.weatherForecast){
|
|
1017
|
+
messageText += ' ' + '<i>' + 'Start verschoben, da heute ' + weatherForecastTodayNum + 'mm Niederschlag' + '</i> ' + '\n';
|
|
1018
|
+
adapter.log.info(`${res.objectName}: Start verschoben, da Regenvorhersage für Heute ${weatherForecastTodayNum} mm [ ${resRain(false)} > 0 ]`);
|
|
1019
|
+
if ((res.startDay === 'threeRd') || (res.startDay === 'twoNd')) {
|
|
1020
|
+
let startDay = -1;
|
|
1021
|
+
res.startFixDay.forEach((item, index) => {if (item) {startDay = index}});
|
|
1022
|
+
if (startDay !== -1) {
|
|
1023
|
+
res.startFixDay[startDay] = false;
|
|
1024
|
+
res.startFixDay[(+ startDay + 1 > 6) ? (+ startDay-6) : (+ startDay+1)] = true;
|
|
1025
|
+
} else {
|
|
1026
|
+
adapter.log.warn(`${res.objectName}: no start day found`)
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
819
1029
|
}
|
|
1030
|
+
curNextFixDay(res.sprinkleID, false);
|
|
820
1031
|
break;
|
|
821
1032
|
// --- calculation -- Berechnung der Bodenfeuchte --- //
|
|
822
1033
|
// -- Bodenfeuchte zu gering -- //
|
|
@@ -837,7 +1048,7 @@ function startTimeSprinkle() {
|
|
|
837
1048
|
} else if (adapter.config.weatherForecast) {
|
|
838
1049
|
/* Bewässerung unterdrückt da ausreichende Regenvorhersage */
|
|
839
1050
|
messageText += ' ' + '<i>' + 'Start verschoben, da heute ' + weatherForecastTodayNum + 'mm Niederschlag' + '</i> ' + '\n';
|
|
840
|
-
adapter.log.info(`${res.objectName}: Start verschoben, da Regenvorhersage für Heute ${weatherForecastTodayNum} mm [ ${res.soilMoisture.val} (${resMoisture}) <= ${res.soilMoisture.triggersIrrigation} ]`);
|
|
1051
|
+
adapter.log.info(`${res.objectName}: Start verschoben, da Regenvorhersage für Heute ${weatherForecastTodayNum} mm [ ${res.soilMoisture.val.toFixed(1)} (${resMoisture.toFixed(1)}) <= ${res.soilMoisture.triggersIrrigation} ]`);
|
|
841
1052
|
}
|
|
842
1053
|
}
|
|
843
1054
|
break;
|
|
@@ -862,6 +1073,43 @@ function startTimeSprinkle() {
|
|
|
862
1073
|
|
|
863
1074
|
//
|
|
864
1075
|
async function createSprinklers() {
|
|
1076
|
+
/**Creates an Object .control.addStartTimeSwitch, when additional watering has been activated via an external signal
|
|
1077
|
+
* - Erzeugt ein Object .control.addStartTimeSwitch, wenn die Zusatzbewässerung über ein externes Signal aktiviert wurde
|
|
1078
|
+
* @type {{id: string, name: string} | void}
|
|
1079
|
+
* @private
|
|
1080
|
+
*/
|
|
1081
|
+
const _addStartTimeSwitch = await adapter.findForeignObjectAsync(`${adapter.namespace}.control.addStartTimeSwitch`, 'boolean').catch((e) => adapter.log.warn(`.control.addStartTimeSwitch ${e}`));
|
|
1082
|
+
if (_addStartTimeSwitch.id !== `${adapter.namespace}.control.addStartTimeSwitch` && adapter.config.selectAddStartTime === 'withExternalSignal') {
|
|
1083
|
+
adapter.setObjectNotExistsAsync(`${adapter.namespace}.control.addStartTimeSwitch`, {
|
|
1084
|
+
'type': 'state',
|
|
1085
|
+
'common': {
|
|
1086
|
+
"role": "switch",
|
|
1087
|
+
'name': 'additional irrigation enabled',
|
|
1088
|
+
'type': 'boolean',
|
|
1089
|
+
'read': true,
|
|
1090
|
+
'write': true,
|
|
1091
|
+
'def': false
|
|
1092
|
+
},
|
|
1093
|
+
'native': {}
|
|
1094
|
+
}).catch((e) => adapter.log.warn(`.control.addStartTimeSwitch ${e}`));
|
|
1095
|
+
} else if (_addStartTimeSwitch.id === `${adapter.namespace}.control.addStartTimeSwitch`) {
|
|
1096
|
+
if (adapter.config.selectAddStartTime !== 'withExternalSignal') {
|
|
1097
|
+
adapter.delObjectAsync(`${adapter.namespace}.control.addStartTimeSwitch`).catch((e) => adapter.log.warn(`.control.addStartTimeSwitch ${e}`));
|
|
1098
|
+
addStartTimeSwitch = false;
|
|
1099
|
+
} else {
|
|
1100
|
+
/** auslesen .control.addStartTimeSwitch.val
|
|
1101
|
+
* @type {ioBroker.State | void}
|
|
1102
|
+
* @private
|
|
1103
|
+
*/
|
|
1104
|
+
const _state = await adapter.getStateAsync(`${adapter.namespace}.control.addStartTimeSwitch`).catch((e) => adapter.log.warn(`.control.addStartTimeSwitch ${e}`));
|
|
1105
|
+
if (typeof _state.val === 'boolean') {
|
|
1106
|
+
addStartTimeSwitch = _state.val;
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
|
|
1112
|
+
|
|
865
1113
|
const result = adapter.config.events;
|
|
866
1114
|
if (result) {
|
|
867
1115
|
for(const res of result) {
|
|
@@ -880,7 +1128,7 @@ async function createSprinklers() {
|
|
|
880
1128
|
|
|
881
1129
|
let nameMetConSM, objMetConSM;
|
|
882
1130
|
await fillMetConSM(res);
|
|
883
|
-
function fillMetConSM(res) {
|
|
1131
|
+
async function fillMetConSM(res) {
|
|
884
1132
|
//adapter.log.debug(JSON.stringify(res));
|
|
885
1133
|
switch (res.methodControlSM) {
|
|
886
1134
|
case 'calculation':
|
|
@@ -983,7 +1231,7 @@ async function createSprinklers() {
|
|
|
983
1231
|
'name': res.sprinkleName
|
|
984
1232
|
},
|
|
985
1233
|
'native': {},
|
|
986
|
-
})
|
|
1234
|
+
});
|
|
987
1235
|
// Create Object for .history
|
|
988
1236
|
const _historyNotExist = await adapter.setObjectNotExistsAsync('sprinkle.' + objectName + '.history', {
|
|
989
1237
|
'type': 'channel',
|
|
@@ -991,7 +1239,7 @@ async function createSprinklers() {
|
|
|
991
1239
|
'name': res.sprinkleName + ' => History'
|
|
992
1240
|
},
|
|
993
1241
|
'native': {},
|
|
994
|
-
})
|
|
1242
|
+
});
|
|
995
1243
|
// Create Object for .history.curCalWeekConsumed
|
|
996
1244
|
// Sprinkler consumption of the current calendar week => History - Sprinkler-Verbrauch der aktuellen Kalenderwoche (783 Liter)
|
|
997
1245
|
const _curCalWeekConsumedNotExist = adapter.setObjectNotExistsAsync(objPfad + '.history.curCalWeekConsumed', {
|
|
@@ -1006,7 +1254,7 @@ async function createSprinklers() {
|
|
|
1006
1254
|
'def': 0
|
|
1007
1255
|
},
|
|
1008
1256
|
'native': {},
|
|
1009
|
-
})
|
|
1257
|
+
});
|
|
1010
1258
|
// Create Object for .history.curCalWeekRunningTime
|
|
1011
1259
|
// Sprinkler running time of the current calendar week => History - Sprinkler-Laufzeit der aktuellen Kalenderwoche (783 Liter)
|
|
1012
1260
|
const _curCalWeekRunningTimeNotExist = adapter.setObjectNotExistsAsync(objPfad + '.history.curCalWeekRunningTime', {
|
|
@@ -1020,7 +1268,7 @@ async function createSprinklers() {
|
|
|
1020
1268
|
'def': '00:00'
|
|
1021
1269
|
},
|
|
1022
1270
|
'native': {},
|
|
1023
|
-
})
|
|
1271
|
+
});
|
|
1024
1272
|
// Create Object for .history.lastCalWeekConsumed
|
|
1025
1273
|
// Sprinkler consumption of the last calendar week => History - Sprinkler-Verbrauch der letzten Kalenderwoche (783 Liter)
|
|
1026
1274
|
const _lastCalWeekConsumedNotExist = adapter.setObjectNotExistsAsync(objPfad + '.history.lastCalWeekConsumed', {
|
|
@@ -1035,7 +1283,7 @@ async function createSprinklers() {
|
|
|
1035
1283
|
'def': 0
|
|
1036
1284
|
},
|
|
1037
1285
|
'native': {},
|
|
1038
|
-
})
|
|
1286
|
+
});
|
|
1039
1287
|
// Create Object for .history.lastCalWeekRunningTime
|
|
1040
1288
|
// Sprinkler running time of the last calendar week => History - Sprinkler-Laufzeit der letzten Kalenderwoche (783 Liter)
|
|
1041
1289
|
const _lastCalWeekRunningTimeNotExist = adapter.setObjectNotExistsAsync(objPfad + '.history.lastCalWeekRunningTime', {
|
|
@@ -1049,7 +1297,7 @@ async function createSprinklers() {
|
|
|
1049
1297
|
'def': '00:00'
|
|
1050
1298
|
},
|
|
1051
1299
|
'native': {},
|
|
1052
|
-
})
|
|
1300
|
+
});
|
|
1053
1301
|
// Create Object for .history.lastConsumed
|
|
1054
1302
|
// Last consumed of sprinkler => History - Letzte Verbrauchsmenge des Ventils (783 Liter)
|
|
1055
1303
|
const _lastConsumedNotExist = adapter.setObjectNotExistsAsync(objPfad + '.history.lastConsumed', {
|
|
@@ -1064,7 +1312,7 @@ async function createSprinklers() {
|
|
|
1064
1312
|
'def': 0
|
|
1065
1313
|
},
|
|
1066
1314
|
'native': {},
|
|
1067
|
-
})
|
|
1315
|
+
});
|
|
1068
1316
|
// Create Object for .history.lastOn
|
|
1069
1317
|
// Last On of sprinkler => History - Letzter Start des Ventils (30.03 06:30)
|
|
1070
1318
|
const _lastOnNotExist = adapter.setObjectNotExistsAsync(objPfad + '.history.lastOn', {
|
|
@@ -1078,7 +1326,7 @@ async function createSprinklers() {
|
|
|
1078
1326
|
'def': '-'
|
|
1079
1327
|
},
|
|
1080
1328
|
'native': {},
|
|
1081
|
-
})
|
|
1329
|
+
});
|
|
1082
1330
|
// Create Object for .history.lastRunningTime
|
|
1083
1331
|
// Last running time of sprinkler => History - Letzte Laufzeit des Ventils (0 sek, 47:00 min, 1:03:45 )
|
|
1084
1332
|
const _lastRunningTimeNotExist = adapter.setObjectNotExistsAsync(objPfad + '.history.lastRunningTime', {
|
|
@@ -1092,24 +1340,70 @@ async function createSprinklers() {
|
|
|
1092
1340
|
'def': '00:00'
|
|
1093
1341
|
},
|
|
1094
1342
|
'native': {},
|
|
1095
|
-
})
|
|
1343
|
+
});
|
|
1096
1344
|
// Create Object for .autoOn
|
|
1097
|
-
const _autoOnNotExist =
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1345
|
+
const _autoOnNotExist = adapter.setObjectNotExistsAsync(objPfad + '.autoOn', {
|
|
1346
|
+
'type': 'state',
|
|
1347
|
+
'common': {
|
|
1348
|
+
'role': 'Switch',
|
|
1349
|
+
'name': objectName + ' => Switch automatic mode on / off',
|
|
1350
|
+
'type': 'boolean',
|
|
1351
|
+
"states": {
|
|
1352
|
+
"false": "off",
|
|
1353
|
+
"true": "on"
|
|
1354
|
+
},
|
|
1355
|
+
'read': true,
|
|
1356
|
+
'write': true,
|
|
1357
|
+
'def': true
|
|
1358
|
+
},
|
|
1359
|
+
'native': {},
|
|
1360
|
+
}).catch((e) => adapter.log.warn(`setObjectNotExistsAsync ${objectName}.autoOn ${e}`));
|
|
1109
1361
|
// Create Object for .actualSoilMoisture
|
|
1110
|
-
const
|
|
1111
|
-
|
|
1112
|
-
|
|
1362
|
+
const _actualSoilMoistureFind = await adapter.findForeignObjectAsync(`${adapter.namespace}.${objPfad}.actualSoilMoisture`, `${objMetConSM.common.type}`);
|
|
1363
|
+
if (_actualSoilMoistureFind.id !== `${adapter.namespace}.${objPfad}.actualSoilMoisture` || _actualSoilMoistureFind.name !== nameMetConSM) {
|
|
1364
|
+
await adapter.setObjectAsync(
|
|
1365
|
+
objPfad + '.actualSoilMoisture',
|
|
1366
|
+
objMetConSM
|
|
1367
|
+
).catch((e) => adapter.log.warn(e));
|
|
1368
|
+
adapter.log.info(`sprinkleControl [sprinkle.${objectName}.actualSoilMoisture] was updated`);
|
|
1369
|
+
}
|
|
1370
|
+
|
|
1371
|
+
// postponeByOneDay → um einen Tag verschieben bei fixDay (twoNd & threeRd)
|
|
1372
|
+
const _postponeByOneDay = await adapter.findForeignObjectAsync(`${adapter.namespace}.${objPfad}.postponeByOneDay`, `boolean`);
|
|
1373
|
+
if (_postponeByOneDay.id !== `${adapter.namespace}.${objPfad}.postponeByOneDay`
|
|
1374
|
+
&& res.methodControlSM === "fixDay"
|
|
1375
|
+
&& (res.startDay === "twoNd"
|
|
1376
|
+
|| res.startDay === "threeRd")) {
|
|
1377
|
+
await adapter.setObjectNotExistsAsync(objPfad + '.postponeByOneDay', {
|
|
1378
|
+
'type': 'state',
|
|
1379
|
+
'common': {
|
|
1380
|
+
"role": 'button',
|
|
1381
|
+
"name": objectName + 'Postpone start by one day',
|
|
1382
|
+
"type": 'boolean',
|
|
1383
|
+
"read": true,
|
|
1384
|
+
"write": true,
|
|
1385
|
+
"def": false
|
|
1386
|
+
},
|
|
1387
|
+
'native': {
|
|
1388
|
+
"UNIT": "",
|
|
1389
|
+
"TAB_ORDER": 0,
|
|
1390
|
+
"OPERATIONS": 6,
|
|
1391
|
+
"FLAGS": 1,
|
|
1392
|
+
"TYPE": "ACTION",
|
|
1393
|
+
"MIN": false,
|
|
1394
|
+
"MAX": true,
|
|
1395
|
+
"DEFAULT": false
|
|
1396
|
+
}
|
|
1397
|
+
});
|
|
1398
|
+
adapter.subscribeStates(`${adapter.namespace}.${objPfad}.postponeByOneDay`);
|
|
1399
|
+
} else if (res.methodControlSM === "fixDay"
|
|
1400
|
+
&& (res.startDay === "twoNd"
|
|
1401
|
+
|| res.startDay === "threeRd")) {
|
|
1402
|
+
adapter.subscribeStates(`${adapter.namespace}.${objPfad}.postponeByOneDay`);
|
|
1403
|
+
} else {
|
|
1404
|
+
await adapter.delObjectAsync(`${adapter.namespace}.${objPfad}.postponeByOneDay`); // "sprinklecontrol.0.sprinkle.???.actualSoilMoisture"
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1113
1407
|
// Create Object for .countdown => Countdown des Ventils
|
|
1114
1408
|
const _countdownNotExist = adapter.setObjectNotExistsAsync(objPfad + '.countdown', {
|
|
1115
1409
|
'type': 'state',
|
|
@@ -1122,7 +1416,7 @@ async function createSprinklers() {
|
|
|
1122
1416
|
'def': '-'
|
|
1123
1417
|
},
|
|
1124
1418
|
'native': {},
|
|
1125
|
-
})
|
|
1419
|
+
});
|
|
1126
1420
|
// Create Object for .runningTime => Laufzeit des Ventils
|
|
1127
1421
|
const _runningTimeNotExist = await adapter.setObjectNotExistsAsync(objPfad + '.runningTime', {
|
|
1128
1422
|
'type': 'state',
|
|
@@ -1135,7 +1429,7 @@ async function createSprinklers() {
|
|
|
1135
1429
|
'def': '-'
|
|
1136
1430
|
},
|
|
1137
1431
|
'native': {},
|
|
1138
|
-
})
|
|
1432
|
+
});
|
|
1139
1433
|
// Create Object for .sprinklerState => Zustand des Ventils im Thread
|
|
1140
1434
|
// <<< 1 = warten >>> ( 0:off; 1:wait; 2:on; 3:break; 4:Boost(on); 5:off(Boost) )
|
|
1141
1435
|
// Create .sprinklerState
|
|
@@ -1159,8 +1453,8 @@ async function createSprinklers() {
|
|
|
1159
1453
|
'write': false,
|
|
1160
1454
|
'def': 0
|
|
1161
1455
|
},
|
|
1162
|
-
'native': {}
|
|
1163
|
-
})
|
|
1456
|
+
'native': {},
|
|
1457
|
+
});
|
|
1164
1458
|
// Create Object for triggerPoint → Schaltpunkt der Bodenfeuchte
|
|
1165
1459
|
const _triggerPointNotExist = await adapter.setObjectNotExistsAsync(objPfad + '.triggerPoint', {
|
|
1166
1460
|
'type': 'state',
|
|
@@ -1173,10 +1467,10 @@ async function createSprinklers() {
|
|
|
1173
1467
|
'def': '-'
|
|
1174
1468
|
},
|
|
1175
1469
|
'native': {},
|
|
1176
|
-
})
|
|
1470
|
+
});
|
|
1177
1471
|
// Object created
|
|
1178
1472
|
let value = true;
|
|
1179
|
-
(await Promise.all([
|
|
1473
|
+
await (await Promise.all([
|
|
1180
1474
|
_sprinkleNotExist,
|
|
1181
1475
|
_historyNotExist,
|
|
1182
1476
|
_curCalWeekConsumedNotExist,
|
|
@@ -1187,15 +1481,14 @@ async function createSprinklers() {
|
|
|
1187
1481
|
_lastOnNotExist,
|
|
1188
1482
|
_lastRunningTimeNotExist,
|
|
1189
1483
|
_autoOnNotExist,
|
|
1190
|
-
_actualSoilMoistureNotExist,
|
|
1191
1484
|
_countdownNotExist,
|
|
1192
1485
|
_runningTimeNotExist,
|
|
1193
1486
|
_sprinklerStateNotExists,
|
|
1194
1487
|
_triggerPointNotExist
|
|
1195
1488
|
])).forEach((val) => {
|
|
1196
|
-
value
|
|
1489
|
+
value &= val;
|
|
1197
1490
|
});
|
|
1198
|
-
if
|
|
1491
|
+
if(value) {
|
|
1199
1492
|
adapter.log.info(`sprinkleControl [sprinkle.${objectName}] was created`);
|
|
1200
1493
|
}
|
|
1201
1494
|
|
|
@@ -1203,34 +1496,6 @@ async function createSprinklers() {
|
|
|
1203
1496
|
// +++++ zustände der States aktualisieren +++++ //
|
|
1204
1497
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
|
|
1205
1498
|
|
|
1206
|
-
// Abfrage, ob sich die Bewässerungsart geändert hat
|
|
1207
|
-
const _actualSoilMoistureObj = await adapter.getObjectAsync(objPfad + '.actualSoilMoisture').catch((e) => adapter.log.warn(e));
|
|
1208
|
-
if (_actualSoilMoistureObj) {
|
|
1209
|
-
if (typeof _actualSoilMoistureObj.common.name !== 'string' || _actualSoilMoistureObj.common.name !== nameMetConSM) { // Objekt wurde ausgelesen
|
|
1210
|
-
await adapter.setObjectAsync(
|
|
1211
|
-
objPfad + '.actualSoilMoisture',
|
|
1212
|
-
objMetConSM
|
|
1213
|
-
).catch((e) => adapter.log.warn(e));
|
|
1214
|
-
adapter.log.info(`sprinkleControl [sprinkle.${objectName}.actualSoilMoisture] was updated`);
|
|
1215
|
-
|
|
1216
|
-
}
|
|
1217
|
-
}
|
|
1218
|
-
//
|
|
1219
|
-
if (await _autoOnNotExist) {
|
|
1220
|
-
const _autoOn = await adapter.getStateAsync(objPfad + '.autoOn').catch((e) => adapter.log.warn(e));
|
|
1221
|
-
if (_autoOn && _autoOn.val) {
|
|
1222
|
-
if (typeof _autoOn.val === 'boolean' && ((new Date () - _autoOn.ts) > 60000)) {
|
|
1223
|
-
myConfig.config[j].autoOn = _autoOn.val;
|
|
1224
|
-
} else {
|
|
1225
|
-
adapter.setStateAsync(
|
|
1226
|
-
objPfad + '.autoOn',
|
|
1227
|
-
true,
|
|
1228
|
-
true
|
|
1229
|
-
).catch((e) => adapter.log.warn(`${objectName}.autoOn ${e}`));
|
|
1230
|
-
myConfig.config[j].autoOn = true;
|
|
1231
|
-
}
|
|
1232
|
-
}
|
|
1233
|
-
}
|
|
1234
1499
|
//
|
|
1235
1500
|
if(await _countdownNotExist){
|
|
1236
1501
|
const _countdown = await adapter.getStateAsync(objPfad + '.countdown').catch((e) => adapter.log.warn(`${objectName}.countdown ${e}`));
|
|
@@ -1315,7 +1580,7 @@ async function createSprinklers() {
|
|
|
1315
1580
|
* false → Zweitage-modus (twoNd)
|
|
1316
1581
|
*/
|
|
1317
1582
|
async function setNewDay (threeRd) {
|
|
1318
|
-
const today = formatTime(adapter,'', 'day');
|
|
1583
|
+
const today = await formatTime(adapter,'', 'day');
|
|
1319
1584
|
/**
|
|
1320
1585
|
*
|
|
1321
1586
|
* @type {ioBroker.GetStatePromise} _actualSoilMoisture
|
|
@@ -1347,7 +1612,6 @@ async function createSprinklers() {
|
|
|
1347
1612
|
} else if (myConfig.config[j].startDay === 'twoNd') {
|
|
1348
1613
|
await setNewDay(false);
|
|
1349
1614
|
} else if (myConfig.config[j].startDay === 'fixDay') {
|
|
1350
|
-
adapter.log.info(`set Day (fixDay): ${myConfig.config[j].objectName}`);
|
|
1351
1615
|
curNextFixDay(myConfig.config[j].sprinkleID, false);
|
|
1352
1616
|
}
|
|
1353
1617
|
|
|
@@ -1387,7 +1651,7 @@ async function createSprinklers() {
|
|
|
1387
1651
|
).catch((e) => adapter.log.warn(e));
|
|
1388
1652
|
break;
|
|
1389
1653
|
|
|
1390
|
-
|
|
1654
|
+
}
|
|
1391
1655
|
|
|
1392
1656
|
} catch (e) {
|
|
1393
1657
|
adapter.log.warn(`sprinkleControl cannot created ... Please check your sprinkleControl config: ${e}`);
|
|
@@ -1419,27 +1683,44 @@ async function createSprinklers() {
|
|
|
1419
1683
|
if (fullRes.indexOf(resultID) === -1) {
|
|
1420
1684
|
try {
|
|
1421
1685
|
// object deleted
|
|
1686
|
+
/**
|
|
1687
|
+
* del when exist Object Async
|
|
1688
|
+
* @param id - the id of the object
|
|
1689
|
+
* @param type - common.type of the state
|
|
1690
|
+
* @returns {Promise<void>}
|
|
1691
|
+
*/
|
|
1692
|
+
const delWhenExistObjectAsync = async (id, type) => {
|
|
1693
|
+
const _find = await adapter.findForeignObjectAsync(`${id}`, `${type}`);
|
|
1694
|
+
if (_find && _find.id === `${id}`) {
|
|
1695
|
+
await adapter.delObjectAsync(`${id}`).catch((e) => adapter.log.warn(e)); // "sprinklecontrol.0.sprinkle.???.postponeByOneDay"
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
|
|
1422
1699
|
Promise.all([
|
|
1423
|
-
adapter.delObjectAsync(resID + '.actualSoilMoisture'),
|
|
1424
|
-
adapter.delObjectAsync(resID + '.triggerPoint'),
|
|
1425
|
-
adapter.delObjectAsync(resID + '.sprinklerState'),
|
|
1426
|
-
adapter.delObjectAsync(resID + '.runningTime'),
|
|
1427
|
-
|
|
1428
|
-
adapter.delObjectAsync(resID + '.
|
|
1429
|
-
adapter.delObjectAsync(resID + '.
|
|
1430
|
-
adapter.delObjectAsync(resID + '.history.
|
|
1431
|
-
adapter.delObjectAsync(resID + '.history.
|
|
1432
|
-
adapter.delObjectAsync(resID + '.history.
|
|
1433
|
-
adapter.delObjectAsync(resID + '.history.
|
|
1434
|
-
adapter.delObjectAsync(resID + '.history.
|
|
1435
|
-
adapter.delObjectAsync(resID + '.history.
|
|
1700
|
+
adapter.delObjectAsync(resID + '.actualSoilMoisture'), // "sprinklecontrol.0.sprinkle.???.actualSoilMoisture"
|
|
1701
|
+
adapter.delObjectAsync(resID + '.triggerPoint'), // "sprinklecontrol.0.sprinkle.???.triggerPoint"
|
|
1702
|
+
adapter.delObjectAsync(resID + '.sprinklerState'), // "sprinklecontrol.0.sprinkle.???.sprinklerState"
|
|
1703
|
+
adapter.delObjectAsync(resID + '.runningTime'), // "sprinklecontrol.0.sprinkle.???.runningTime"
|
|
1704
|
+
delWhenExistObjectAsync(`${resID}.postponeByOneDay`, `boolean`), // "sprinklecontrol.0.sprinkle.???.postponeByOneDay" wenn vorhanden löschen
|
|
1705
|
+
adapter.delObjectAsync(resID + '.countdown'), // "sprinklecontrol.0.sprinkle.???.countdown"
|
|
1706
|
+
adapter.delObjectAsync(resID + '.autoOn'), // "sprinklecontrol.0.sprinkle.???.autoOn"
|
|
1707
|
+
adapter.delObjectAsync(resID + '.history.lastOn'), // "sprinklecontrol.0.sprinkle.???.history.lastOn"
|
|
1708
|
+
adapter.delObjectAsync(resID + '.history.lastConsumed'), // "sprinklecontrol.0.sprinkle.???.history.lastConsumed"
|
|
1709
|
+
adapter.delObjectAsync(resID + '.history.lastRunningTime'), // "sprinklecontrol.0.sprinkle.???.history.lastRunningTime"
|
|
1710
|
+
adapter.delObjectAsync(resID + '.history.curCalWeekConsumed'), // "sprinklecontrol.0.sprinkle.???.history.curCalWeekConsumed"
|
|
1711
|
+
adapter.delObjectAsync(resID + '.history.lastCalWeekConsumed'), // "sprinklecontrol.0.sprinkle.???.history.lastCalWeekConsumed"
|
|
1712
|
+
adapter.delObjectAsync(resID + '.history.curCalWeekRunningTime'), // "sprinklecontrol.0.sprinkle.???.history.curCalWeekRunningTime"
|
|
1713
|
+
adapter.delObjectAsync(resID + '.history.lastCalWeekRunningTime') // "sprinklecontrol.0.sprinkle.???.history.lastCalWeekRunningTime"
|
|
1714
|
+
]
|
|
1715
|
+
).then(async ()=>{
|
|
1436
1716
|
// History - Objekt(Ordner.history) löschen
|
|
1437
|
-
await adapter.delObjectAsync(resID + '.history')
|
|
1717
|
+
await adapter.delObjectAsync(resID + '.history');
|
|
1718
|
+
}).then(async ()=>{
|
|
1438
1719
|
// Objekt(Ordner) löschen
|
|
1439
|
-
await adapter.delObjectAsync(resID)
|
|
1440
|
-
|
|
1441
|
-
adapter.log.info(`sprinkleControl [${
|
|
1442
|
-
})
|
|
1720
|
+
await adapter.delObjectAsync(resID);
|
|
1721
|
+
}).then(()=>{
|
|
1722
|
+
adapter.log.info(`sprinkleControl [${resID}] was deleted`);
|
|
1723
|
+
});
|
|
1443
1724
|
} catch (e) {
|
|
1444
1725
|
adapter.log.warn(e);
|
|
1445
1726
|
}
|
|
@@ -1448,17 +1729,20 @@ async function createSprinklers() {
|
|
|
1448
1729
|
}
|
|
1449
1730
|
}
|
|
1450
1731
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
1732
|
+
|
|
1451
1733
|
/**
|
|
1452
1734
|
*
|
|
1453
1735
|
* @param {number} ms => Waiting time in ms
|
|
1454
1736
|
* @return {Promise<unknown>}
|
|
1455
1737
|
*/
|
|
1738
|
+
/*
|
|
1456
1739
|
async function sleep(ms) {
|
|
1457
1740
|
return new Promise(async (resolve) => {
|
|
1458
1741
|
// @ts-ignore
|
|
1459
1742
|
timerSleep = setTimeout(async () => resolve(), ms);
|
|
1460
1743
|
});
|
|
1461
1744
|
}
|
|
1745
|
+
*/
|
|
1462
1746
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
1463
1747
|
/**
|
|
1464
1748
|
*
|
|
@@ -1472,31 +1756,26 @@ function main(adapter) {
|
|
|
1472
1756
|
adapter.config:
|
|
1473
1757
|
*/
|
|
1474
1758
|
adapter.log.debug(`adapter.config.events: ${JSON.stringify(adapter.config.events)}`);
|
|
1475
|
-
|
|
1476
1759
|
/**
|
|
1477
1760
|
* The adapters' config (in the instance object everything under the attribute "native") is accessible via adapter.config:
|
|
1478
1761
|
* => Auf die Adapterkonfiguration (im Instanz objekt alles unter dem Attribut "native") kann zugegriffen werden über adapter.config:
|
|
1479
1762
|
* @param {any} err
|
|
1480
1763
|
* @param {any} obj
|
|
1481
1764
|
*/
|
|
1482
|
-
adapter.getForeignObject('system.config', (err) => {
|
|
1483
|
-
if (
|
|
1484
|
-
// init createConfig
|
|
1485
|
-
myConfig.createConfig(adapter);
|
|
1765
|
+
adapter.getForeignObject('system.config', (err, obj) => {
|
|
1766
|
+
if (obj) {
|
|
1486
1767
|
checkStates();
|
|
1487
1768
|
}
|
|
1488
1769
|
});
|
|
1489
|
-
|
|
1490
|
-
GetSystemData().
|
|
1770
|
+
createSprinklers().catch((e) => adapter.log.warn(e));
|
|
1771
|
+
GetSystemData().catch((e) => adapter.log.warn(e));
|
|
1491
1772
|
sendMessageText.initConfigMessage(adapter);
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
valveControl.initValveControl(adapter);
|
|
1499
|
-
sunPos();
|
|
1773
|
+
evaporation.initEvaporation(adapter); // init evaporation
|
|
1774
|
+
checkActualStates().catch((e) => adapter.log.warn(e));
|
|
1775
|
+
sunPos();
|
|
1776
|
+
timer = setTimeout(() => {
|
|
1777
|
+
startTimeSprinkle();
|
|
1778
|
+
addStartTimeSprinkle()
|
|
1500
1779
|
}, 2000);
|
|
1501
1780
|
|
|
1502
1781
|
/*
|
|
@@ -1518,11 +1797,17 @@ function main(adapter) {
|
|
|
1518
1797
|
if (adapter.config.publicHolidays === true && (adapter.config.publicHolInstance + '.morgen.*')) {
|
|
1519
1798
|
adapter.subscribeForeignStates(adapter.config.publicHolInstance + '.morgen.*');
|
|
1520
1799
|
}
|
|
1521
|
-
if (
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1800
|
+
if (adapter.config.weatherForecast === true) {
|
|
1801
|
+
if (adapter.config.weatherForecastService === 'ownDataPoint') {
|
|
1802
|
+
weatherForecastTodayPfadStr = adapter.config.pathRainForecast;
|
|
1803
|
+
adapter.subscribeForeignStates(weatherForecastTodayPfadStr);
|
|
1804
|
+
} else if (adapter.config.weatherForecastService === 'dasWetter' && adapter.config.weatherForInstance) {
|
|
1805
|
+
weatherForecastTodayPfadStr = adapter.config.weatherForInstance + '.NextDaysDetailed.Location_1.Day_1.rain_value';
|
|
1806
|
+
adapter.subscribeForeignStates(weatherForecastTodayPfadStr);
|
|
1807
|
+
adapter.subscribeForeignStates(adapter.config.weatherForInstance + '.NextDaysDetailed.Location_1.Day_2.rain_value');
|
|
1808
|
+
} else {
|
|
1809
|
+
adapter.log.warn('There is no valid data record stored in the weather forecast, please correct it!')
|
|
1810
|
+
}
|
|
1526
1811
|
}
|
|
1527
1812
|
if (adapter.config.actualValueLevel !== '') {
|
|
1528
1813
|
adapter.subscribeForeignStates(adapter.config.actualValueLevel);
|