iobroker.sprinklecontrol 0.2.18 → 1.0.0
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/LICENSE +1 -1
- package/README.md +11 -13
- package/admin/i18n/de/translations.json +13 -3
- package/admin/i18n/en/translations.json +13 -3
- package/admin/i18n/es/translations.json +13 -3
- package/admin/i18n/fr/translations.json +13 -3
- package/admin/i18n/it/translations.json +13 -3
- package/admin/i18n/nl/translations.json +13 -3
- package/admin/i18n/pl/translations.json +13 -3
- package/admin/i18n/pt/translations.json +13 -3
- package/admin/i18n/ru/translations.json +13 -3
- package/admin/i18n/uk/translations.json +13 -3
- package/admin/i18n/zh-cn/translations.json +13 -3
- package/admin/index_m.html +941 -914
- package/admin/index_m.js +807 -779
- package/admin/words.js +12 -2
- package/io-package.json +231 -186
- package/lib/evaporation.js +497 -455
- package/lib/myConfig.js +190 -266
- package/lib/sendMessageText.js +196 -162
- package/lib/tools.js +211 -148
- package/lib/valveControl.js +1414 -974
- package/main.js +1416 -1245
- package/package.json +9 -14
package/lib/evaporation.js
CHANGED
|
@@ -1,456 +1,498 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
/*
|
|
3
|
-
info: log aufbau evaporation.js: #3.*
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
let adapter;
|
|
10
|
-
|
|
11
|
-
/* calcEvaporation */
|
|
12
|
-
/**
|
|
13
|
-
* akt. Temperatur °C
|
|
14
|
-
* - -20 bis 55°C
|
|
15
|
-
* - ts Zeitstempel, wann der Wert aktualisiert wurde (auch ohne Wertänderung)
|
|
16
|
-
*/
|
|
17
|
-
const curTemperature = {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*/
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
lowerLatitude,
|
|
122
|
-
upperLatitude,
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
lowerLatitude,
|
|
130
|
-
upperLatitude,
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
lowerLatitude,
|
|
138
|
-
upperLatitude,
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
adapter.
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
curIllumination.val = (parseFloat(state.val));
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
adapter.
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
if (
|
|
311
|
-
adapter.
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
curHumidity.val =
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
},
|
|
414
|
-
/**
|
|
415
|
-
*
|
|
416
|
-
*
|
|
417
|
-
*
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
*
|
|
441
|
-
* @param
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
/*
|
|
3
|
+
info: log aufbau evaporation.js: #3.*
|
|
4
|
+
*/
|
|
5
|
+
const myConfig = require('./myConfig.js'); // myConfig → Speichern und abrufen von Konfigurationsdaten der Ventile
|
|
6
|
+
const formatTime = require('./tools').formatTime; // tools => laden von Hilfsfunktionen
|
|
7
|
+
const trend = require('./tools').trend; // tools => laden von Hilfsfunktionen
|
|
8
|
+
|
|
9
|
+
let adapter;
|
|
10
|
+
|
|
11
|
+
/* calcEvaporation */
|
|
12
|
+
/**
|
|
13
|
+
* akt. Temperatur °C
|
|
14
|
+
* - -20 bis 55°C
|
|
15
|
+
* - ts Zeitstempel, wann der Wert aktualisiert wurde (auch ohne Wertänderung)
|
|
16
|
+
*/
|
|
17
|
+
const curTemperature = {val: undefined, ts: undefined},
|
|
18
|
+
/**
|
|
19
|
+
* akt. LuftFeuchtigkeit in %
|
|
20
|
+
* - 1 bis 99%
|
|
21
|
+
* - lc: Zeitstempel, wann der Wert geändert wurde
|
|
22
|
+
*/
|
|
23
|
+
curHumidity = {val: undefined, lc: undefined},
|
|
24
|
+
/**
|
|
25
|
+
* akt. Helligkeit (relativ)
|
|
26
|
+
* - 0 bis 100000
|
|
27
|
+
* - intern Begrenzung 100...7000
|
|
28
|
+
* - lc: Zeitstempel, wann der Wert geändert wurde
|
|
29
|
+
*/
|
|
30
|
+
curIllumination = {val: undefined, lc: undefined},
|
|
31
|
+
/**
|
|
32
|
+
* akt. WindGeschwindigkeit in km/h
|
|
33
|
+
* - 0 bis 200 km/h
|
|
34
|
+
* - lc: Zeitstempel, wann der Wert geändert wurde
|
|
35
|
+
*/
|
|
36
|
+
curWindSpeed = {val: undefined, lc: undefined};
|
|
37
|
+
/**
|
|
38
|
+
* max. Temperatur des Tages (für Auswertung der zusätzlichen Bewässerung
|
|
39
|
+
*/
|
|
40
|
+
let curTemperatureMax = 0,
|
|
41
|
+
/**
|
|
42
|
+
* last rain container => letzter Regencontainer in mm
|
|
43
|
+
*/
|
|
44
|
+
lastRainCounter = 0,
|
|
45
|
+
/**
|
|
46
|
+
* letzte Aktualisierungszeit des Temperaturwertes
|
|
47
|
+
*/
|
|
48
|
+
lastChangeEvaPor = new Date();
|
|
49
|
+
|
|
50
|
+
let ETpTodayNum = 0,
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Extraterrestrische Tagesstrahlung in W/m²
|
|
54
|
+
* - berechneter tabellarischer Tageswert
|
|
55
|
+
*/
|
|
56
|
+
toDayExtraTerStr,
|
|
57
|
+
/**
|
|
58
|
+
* kleinste extraterrestrische Tagesstrahlung im Jahr in W/m²
|
|
59
|
+
* - berechneter tabellarischer Mindestwert
|
|
60
|
+
*/
|
|
61
|
+
minExtraTerStr,
|
|
62
|
+
/**
|
|
63
|
+
* größter extraterrestrische Tagesstrahlung im Jahr in W/m²
|
|
64
|
+
* - berechneter tabellarischer Maximalwert
|
|
65
|
+
*/
|
|
66
|
+
maxExtraTerStr;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Extraterrestrische Strahlung (kurzwelliger Strahlungseinfluss von der Sonne an der Obergrenze der Erdatmosphäre) in W/m²
|
|
70
|
+
* als Tagesmittel, Nordhalbkugel (IQBAL. 1983)
|
|
71
|
+
*/
|
|
72
|
+
const ExtraTerStrTab = {
|
|
73
|
+
Tag:[ 21, 52, 80, 111, 141, 172, 202, 233, 264, 294, 325, 355],
|
|
74
|
+
46: [135, 198, 289, 382, 452, 483, 467, 409, 324, 230, 153, 117],
|
|
75
|
+
47: [128, 191, 283, 378, 450, 482, 466, 406, 319, 224, 146, 110],
|
|
76
|
+
48: [121, 184, 277, 375, 449, 482, 465, 403, 314, 217, 139, 103],
|
|
77
|
+
49: [114, 177, 271, 371, 447, 481, 464, 400, 309, 211, 132, 96],
|
|
78
|
+
50: [107, 170, 265, 367, 445, 481, 463, 398, 304, 204, 125, 89],
|
|
79
|
+
51: [100, 163, 259, 363, 443, 480, 462, 394, 298, 197, 118, 83],
|
|
80
|
+
52: [ 93, 156, 253, 358, 441, 480, 461, 391, 293, 191, 111, 76],
|
|
81
|
+
53: [ 86, 149, 247, 354, 439, 479, 459, 388, 287, 184, 104, 70],
|
|
82
|
+
54: [ 79, 142, 240, 350, 437, 478, 458, 384, 282, 177, 97, 63],
|
|
83
|
+
55: [ 73, 135, 234, 345, 435, 478, 457, 381, 276, 170, 90, 56]
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/*----------------------------------------------------------- interne Funktionen -----------------------------------------------------------*/
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Ermittlung der heutigen extraterrestrischen Strahlung
|
|
90
|
+
* anhand der Tabelle "ExtraTerStrTab"
|
|
91
|
+
*/
|
|
92
|
+
function extraTerStr () { // latitude Breitengrad
|
|
93
|
+
const dayNr = formatTime().dayNr;
|
|
94
|
+
/**
|
|
95
|
+
* - unterer Tabellenwert der Latitude
|
|
96
|
+
*/
|
|
97
|
+
const lowerLatitude = ((parseInt(adapter.config.latitude, 10) < 46 ) ? 46 : ((parseInt(adapter.config.latitude, 10) > 55) ? 55 : (parseInt(adapter.config.latitude, 10)))) || 52,
|
|
98
|
+
/**
|
|
99
|
+
* - oberer Tabellenwert der Latitude
|
|
100
|
+
*/
|
|
101
|
+
upperLatitude = ((lowerLatitude + 1) > 55) ? 55 : (lowerLatitude + 1);
|
|
102
|
+
|
|
103
|
+
let currentMonth = 0,
|
|
104
|
+
followMonth = 0;
|
|
105
|
+
|
|
106
|
+
for(let i = 0; i < 12; i++) {
|
|
107
|
+
if (ExtraTerStrTab.Tag[i] > dayNr) {
|
|
108
|
+
followMonth = i;
|
|
109
|
+
currentMonth = (i === 0) ? 11 : (i - 1);
|
|
110
|
+
break;
|
|
111
|
+
} else if (i === 11) {
|
|
112
|
+
followMonth = 0;
|
|
113
|
+
currentMonth = 11;
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
toDayExtraTerStr = trend(
|
|
119
|
+
lowerLatitude,
|
|
120
|
+
upperLatitude,
|
|
121
|
+
trend(ExtraTerStrTab.Tag[currentMonth], ExtraTerStrTab.Tag[followMonth], ExtraTerStrTab[lowerLatitude.toString()][currentMonth], ExtraTerStrTab[lowerLatitude.toString()][followMonth], dayNr),
|
|
122
|
+
trend(ExtraTerStrTab.Tag[currentMonth], ExtraTerStrTab.Tag[followMonth], ExtraTerStrTab[upperLatitude.toString()][currentMonth], ExtraTerStrTab[upperLatitude.toString()][followMonth], dayNr),
|
|
123
|
+
+adapter.config.latitude
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
minExtraTerStr = trend(
|
|
127
|
+
lowerLatitude,
|
|
128
|
+
upperLatitude,
|
|
129
|
+
ExtraTerStrTab[lowerLatitude.toString()][11], //alter Wert 11
|
|
130
|
+
ExtraTerStrTab[upperLatitude.toString()][11], //alter Wert 11
|
|
131
|
+
+adapter.config.latitude
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
maxExtraTerStr = trend(
|
|
135
|
+
lowerLatitude,
|
|
136
|
+
upperLatitude,
|
|
137
|
+
ExtraTerStrTab[lowerLatitude.toString()][5],
|
|
138
|
+
ExtraTerStrTab[upperLatitude.toString()][5],
|
|
139
|
+
+adapter.config.latitude
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* evaporation calculation
|
|
145
|
+
* => Berechnung der Verdunstung
|
|
146
|
+
*
|
|
147
|
+
* @param {number} timeDifference
|
|
148
|
+
*/
|
|
149
|
+
function calcEvaporation (timeDifference) {
|
|
150
|
+
if (!Number.isFinite(curIllumination.val) || !Number.isFinite(curTemperature.val) || !Number.isFinite(curHumidity.val) || !Number.isFinite(curWindSpeed.val)) {
|
|
151
|
+
adapter.log.warn(`calcEvaporation => berechnung nicht möglich! Es fehlen Werte. ( ${curTemperature.val} °C | ${curIllumination.val} | ${curHumidity.val} % | ${curWindSpeed.val} km/h )`);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
adapter.log.debug(`calcEvaporation => gestartet TimeDifferenz: ${timeDifference}`);
|
|
155
|
+
// Sonnenscheindauer in %
|
|
156
|
+
const curSunshineDuration = (curIllumination.val < 100) ? (0) : (curIllumination.val > 7000) ? (1) : ((curIllumination.val - 100) / (6900));
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Sättigungsdampfdruck 'Es' in hPa
|
|
160
|
+
* m1
|
|
161
|
+
*/
|
|
162
|
+
const m1 = 6.11 * ( 10 ** (( 7.48 * curTemperature.val ) / ( 237 + curTemperature.val )));
|
|
163
|
+
/**
|
|
164
|
+
* Dampfdruck Ea
|
|
165
|
+
* m2
|
|
166
|
+
*/
|
|
167
|
+
const m2 = m1 * curHumidity.val / 100;
|
|
168
|
+
/**
|
|
169
|
+
* Globalstrahlung RG
|
|
170
|
+
* m3
|
|
171
|
+
*/
|
|
172
|
+
const m3 = (0.19 + 0.55 * curSunshineDuration) * toDayExtraTerStr;
|
|
173
|
+
/**
|
|
174
|
+
* Abstrahlung I in W/m²
|
|
175
|
+
* m4
|
|
176
|
+
*/
|
|
177
|
+
const m4 = 5.67E-8 * (( curSunshineDuration + 273 ) ** 4 ) * ( 0.56 - 0.08 * ( m2 ** 0.5 )) * ( 0.1 + ( 0.9 * curSunshineDuration));
|
|
178
|
+
/**
|
|
179
|
+
* Strahlungsäquivalent EH in mm/d
|
|
180
|
+
* m5
|
|
181
|
+
*/
|
|
182
|
+
const m5 = ( m3 * ( 1 - 0.2 ) - m4 ) / 28.3;
|
|
183
|
+
/**
|
|
184
|
+
* Steigung der Sättigungsdampfdruckkurve Delta in hPa/K
|
|
185
|
+
* m6
|
|
186
|
+
*/
|
|
187
|
+
const m6 = ( m1 * 4032 ) / (( 237 + curTemperature.val ) ** 2 );
|
|
188
|
+
/**
|
|
189
|
+
* Windfunktion f(v) in mm/d hPa
|
|
190
|
+
* m7
|
|
191
|
+
*/
|
|
192
|
+
const m7 = 0.13 + 0.14 * curWindSpeed.val / 3.6;
|
|
193
|
+
/**
|
|
194
|
+
* pot. Evapotranspiration nach Penman ETp in mm/d
|
|
195
|
+
* eTp
|
|
196
|
+
*/
|
|
197
|
+
const eTp = (( m6 * m5 + 0.65 * m7 * ( m1 - m2 )) / ( m6 + 0.65 )) - 0.5;
|
|
198
|
+
|
|
199
|
+
adapter.setState('evaporation.ETpCurrent', { val: Math.round(eTp * 10000) / 10000, ack: true });
|
|
200
|
+
|
|
201
|
+
addEvaporation(eTp * timeDifference);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function addEvaporation (value) {
|
|
205
|
+
if (value < 2) { // um Fehler in der Auswertung beim Neustart zu löschen
|
|
206
|
+
ETpTodayNum += value;
|
|
207
|
+
}
|
|
208
|
+
adapter.setState('evaporation.ETpToday', { val: Math.round(ETpTodayNum * 10000) / 10000, ack: true });
|
|
209
|
+
|
|
210
|
+
myConfig.applyEvaporation (value);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/*
|
|
214
|
+
----------------------------------------------------------- externe Funktionen -----------------------------------------------------------
|
|
215
|
+
*/
|
|
216
|
+
|
|
217
|
+
const evaporation = {
|
|
218
|
+
/**
|
|
219
|
+
* Initialisierung von evaporation
|
|
220
|
+
* - Bereitstellen von Umweltdaten
|
|
221
|
+
*
|
|
222
|
+
* @param {ioBroker.Adapter} myAdapter
|
|
223
|
+
*/
|
|
224
|
+
initEvaporation (myAdapter) {
|
|
225
|
+
adapter = myAdapter;
|
|
226
|
+
/**
|
|
227
|
+
* - Sensors to calculate the evaporation are required
|
|
228
|
+
* - Sensoren zur Berechnung der Evaporation werden benötigt
|
|
229
|
+
*
|
|
230
|
+
* @returns {boolean}
|
|
231
|
+
*/
|
|
232
|
+
function fCalculationOn () {
|
|
233
|
+
const found = myConfig.config.find(d => d.methodControlSM === 'calculation');
|
|
234
|
+
return (!(typeof found === 'undefined'));
|
|
235
|
+
}
|
|
236
|
+
const calculationOn = fCalculationOn();
|
|
237
|
+
extraTerStr();
|
|
238
|
+
if (adapter.config.sensorOutsideTemperature !== '') {
|
|
239
|
+
adapter.subscribeForeignStates(adapter.config.sensorOutsideTemperature);
|
|
240
|
+
adapter.getForeignState(adapter.config.sensorOutsideTemperature, (err, state) => {
|
|
241
|
+
if (state && state.val) {
|
|
242
|
+
// @ts-ignore
|
|
243
|
+
if (!Number.isNaN(Number.parseFloat(state.val))) {
|
|
244
|
+
// @ts-ignore
|
|
245
|
+
curTemperature.val = (parseFloat(state.val));
|
|
246
|
+
// @ts-ignore
|
|
247
|
+
curTemperature.ts = state.ts;
|
|
248
|
+
} else {
|
|
249
|
+
adapter.log.warn(`sensorOutsideTemperature => Wrong value: ${state.val}, Type: ${typeof state.val}`);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
} else if (calculationOn) {
|
|
254
|
+
adapter.log.warn('The sensor "sensorOutsideTemperature" is not saved in the configuration! The adapter cannot work like this!');
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (adapter.config.sensorOutsideHumidity !== '') {
|
|
258
|
+
adapter.subscribeForeignStates(adapter.config.sensorOutsideHumidity);
|
|
259
|
+
adapter.getForeignState(adapter.config.sensorOutsideHumidity, (err, state) => {
|
|
260
|
+
if (state && state.val) {
|
|
261
|
+
// @ts-ignore
|
|
262
|
+
if (!Number.isNaN(Number.parseFloat(state.val))) {
|
|
263
|
+
// @ts-ignore
|
|
264
|
+
curHumidity.val = (parseFloat(state.val));
|
|
265
|
+
// @ts-ignore
|
|
266
|
+
curHumidity.lc = state.lc;
|
|
267
|
+
} else {
|
|
268
|
+
adapter.log.warn(`sensorOutsideHumidity => Wrong value: ${state.val}, Type: ${typeof state.val}`);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
} else if (calculationOn) {
|
|
273
|
+
adapter.log.warn('The sensor "sensorOutsideHumidity" is not saved in the configuration! The adapter cannot work like this!');
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (adapter.config.sensorBrightness !== '') {
|
|
277
|
+
adapter.subscribeForeignStates(adapter.config.sensorBrightness);
|
|
278
|
+
adapter.getForeignState(adapter.config.sensorBrightness, (err, state) => {
|
|
279
|
+
if (state && state.val) {
|
|
280
|
+
// @ts-ignore
|
|
281
|
+
if (!Number.isNaN(Number.parseFloat(state.val))) {
|
|
282
|
+
// @ts-ignore
|
|
283
|
+
curIllumination.val = (parseFloat(state.val));
|
|
284
|
+
// @ts-ignore
|
|
285
|
+
curIllumination.lc = state.lc;
|
|
286
|
+
} else {
|
|
287
|
+
adapter.log.warn(`sensorBrightness => Wrong value: ${ state.val }, Type: ${ typeof state.val }`);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
} else if (calculationOn) {
|
|
292
|
+
adapter.log.warn('The sensor "sensorBrightness" is not saved in the configuration! The adapter cannot work like this!');
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
if (adapter.config.sensorWindSpeed !== '') {
|
|
296
|
+
adapter.subscribeForeignStates(adapter.config.sensorWindSpeed);
|
|
297
|
+
adapter.getForeignState(adapter.config.sensorWindSpeed, (err, state) => {
|
|
298
|
+
if (state && state.val) {
|
|
299
|
+
// @ts-ignore
|
|
300
|
+
if (!Number.isNaN(Number.parseFloat(state.val))) {
|
|
301
|
+
// @ts-ignore
|
|
302
|
+
curWindSpeed.val = (parseFloat(state.val));
|
|
303
|
+
// @ts-ignore
|
|
304
|
+
curWindSpeed.lc = state.lc;
|
|
305
|
+
} else {
|
|
306
|
+
adapter.log.warn(`sensorWindSpeed => Wrong value: ${state.val}, Type: ${typeof state.val}`);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
} else if (calculationOn) {
|
|
311
|
+
adapter.log.warn('The sensor "sensorWindSpeed" is not saved in the configuration! The adapter cannot work like this!');
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
if (adapter.config.sensorRainfall !== '') {
|
|
315
|
+
adapter.subscribeForeignStates(adapter.config.sensorRainfall);
|
|
316
|
+
adapter.getForeignState(adapter.config.sensorRainfall, (err, state) => {
|
|
317
|
+
if (state && state.val) {
|
|
318
|
+
// @ts-ignore
|
|
319
|
+
if (!Number.isNaN(Number.parseFloat(state.val))) {
|
|
320
|
+
// @ts-ignore
|
|
321
|
+
lastRainCounter = (parseFloat(state.val));
|
|
322
|
+
} else {
|
|
323
|
+
adapter.log.warn(`sensorRainfall => Wrong value: ${state.val}, Type: ${typeof state.val}`);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
},
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* akt. Temperatur
|
|
332
|
+
*
|
|
333
|
+
* @param {number} value curTemperature
|
|
334
|
+
* @param {Date} curTime ts (akt. Zeit)
|
|
335
|
+
*/
|
|
336
|
+
setCurTemperature (value, curTime) {
|
|
337
|
+
curTemperature.val = value;
|
|
338
|
+
curTemperature.ts = curTime;
|
|
339
|
+
if (curTemperature.val > curTemperatureMax) {
|
|
340
|
+
curTemperatureMax = curTemperature.val;
|
|
341
|
+
adapter.setState('evaporation.dailyHighTemp', {
|
|
342
|
+
val: curTemperatureMax,
|
|
343
|
+
ack: true
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Abbruch bei inkorrekten Umweltdaten
|
|
349
|
+
*/
|
|
350
|
+
let abbruch = false;
|
|
351
|
+
if((curTemperature.val < -20) || (curTemperature.val > 55)){
|
|
352
|
+
adapter.log.warn('Temperature outside the range of -20 ... 55 [°C]');
|
|
353
|
+
abbruch = true;
|
|
354
|
+
}
|
|
355
|
+
if(curHumidity.val && (curHumidity.val < 1) || (curHumidity.val > 99)) {
|
|
356
|
+
adapter.log.warn('Humidity outside the range of 1 ... 99 [%]');
|
|
357
|
+
abbruch = true;
|
|
358
|
+
}
|
|
359
|
+
if(curIllumination.val && (curIllumination.val < 0) || (curIllumination.val > 100000)) {
|
|
360
|
+
adapter.log.warn('Brightness out of range von 0 ... 100.000');
|
|
361
|
+
abbruch = true;
|
|
362
|
+
}
|
|
363
|
+
if(curWindSpeed.val && (curWindSpeed.val < 0) || (+curWindSpeed > 200)) {
|
|
364
|
+
adapter.log.warn('Wind speed outside the range of 0 ... 200 km/h');
|
|
365
|
+
abbruch = true;
|
|
366
|
+
}
|
|
367
|
+
if (abbruch) {
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Zeitdifferenz in ms
|
|
373
|
+
*/
|
|
374
|
+
const timeDifference = (+curTime - +lastChangeEvaPor) / 86400000; // 1Tag === 24/h * 60/min * 60/s * 1000/ms === 86400000 ms
|
|
375
|
+
adapter.log.debug(`${curTemperature.val}°C | ${curHumidity.val}% | ${curIllumination.val} | ${curWindSpeed.val}km/h | ts: ${curTime} - lastChangeEvaPor: ${lastChangeEvaPor} = timeDifference: ${timeDifference}`);
|
|
376
|
+
|
|
377
|
+
if (timeDifference) {
|
|
378
|
+
setTimeout(() => {
|
|
379
|
+
calcEvaporation(timeDifference);
|
|
380
|
+
}, 100);
|
|
381
|
+
}
|
|
382
|
+
lastChangeEvaPor = curTime;
|
|
383
|
+
},
|
|
384
|
+
/**
|
|
385
|
+
* akt. LuftFeuchtigkeit in %
|
|
386
|
+
*
|
|
387
|
+
* @param {number} value
|
|
388
|
+
* @param {any} lc
|
|
389
|
+
*/
|
|
390
|
+
setCurHumidity (value, lc) {
|
|
391
|
+
curHumidity.val = value;
|
|
392
|
+
curHumidity.lc =lc;
|
|
393
|
+
},
|
|
394
|
+
/**
|
|
395
|
+
* akt. Helligkeit wird auf 0 bis 7000 begrenzt
|
|
396
|
+
*
|
|
397
|
+
* @param {number} value
|
|
398
|
+
* @param {any} lc
|
|
399
|
+
*/
|
|
400
|
+
setCurIllumination (value, lc) {
|
|
401
|
+
curIllumination.val = value;
|
|
402
|
+
curIllumination.lc = lc;
|
|
403
|
+
},
|
|
404
|
+
/**
|
|
405
|
+
* akt. Windgeschwindigkeit
|
|
406
|
+
*
|
|
407
|
+
* @param {number} value Windgeschwindigkeit in km/h
|
|
408
|
+
* @param {any} lc
|
|
409
|
+
*/
|
|
410
|
+
setCurWindSpeed (value, lc) {
|
|
411
|
+
curWindSpeed.val = value;
|
|
412
|
+
curWindSpeed.lc = lc;
|
|
413
|
+
},
|
|
414
|
+
/**
|
|
415
|
+
* akt. Regenmengenzähler
|
|
416
|
+
* → Bei einer Änderung über 20 mm wird der Wert nur intern gespeichert,
|
|
417
|
+
* es findet aber keine Anwendung statt!
|
|
418
|
+
*
|
|
419
|
+
* @param {number} value current rain counter → aktueller Regencontainer in mm
|
|
420
|
+
*/
|
|
421
|
+
setCurAmountOfRain (value) {
|
|
422
|
+
if ((value > lastRainCounter) // es regnet
|
|
423
|
+
&& ((value - lastRainCounter) < 20) // && Plausibilitätskontrolle (Regenmenge unter 10mm)
|
|
424
|
+
) {
|
|
425
|
+
addEvaporation(lastRainCounter - value);
|
|
426
|
+
}
|
|
427
|
+
lastRainCounter = value;
|
|
428
|
+
adapter.log.debug(`lastRainCounter: ${lastRainCounter} curAmountOfRain: ${(lastRainCounter - value)} state.val: ${value}`);
|
|
429
|
+
},
|
|
430
|
+
/**
|
|
431
|
+
* Summe der heutigen Verdunstung
|
|
432
|
+
*
|
|
433
|
+
* @param {number} value
|
|
434
|
+
*/
|
|
435
|
+
setETpTodayNum (value) {
|
|
436
|
+
ETpTodayNum = value;
|
|
437
|
+
},
|
|
438
|
+
/**
|
|
439
|
+
* Tageshöchstwert der Temperatur (für Auswertung der zusätzlichen Bewässerung)
|
|
440
|
+
*
|
|
441
|
+
* @param {number} value
|
|
442
|
+
*/
|
|
443
|
+
setCurTemperatureMax (value) {
|
|
444
|
+
curTemperatureMax = value;
|
|
445
|
+
},
|
|
446
|
+
/**
|
|
447
|
+
* ETpToday und ETpYesterday in evaporation aktualisieren da ein neuer Tag beginnt
|
|
448
|
+
*/
|
|
449
|
+
setNewDay () {
|
|
450
|
+
extraTerStr();
|
|
451
|
+
setTimeout(() => {
|
|
452
|
+
adapter.setState('evaporation.ETpYesterday', {
|
|
453
|
+
val: Math.round(ETpTodayNum * 10000) / 10000,
|
|
454
|
+
ack: true
|
|
455
|
+
});
|
|
456
|
+
ETpTodayNum = 0;
|
|
457
|
+
adapter.setState('evaporation.ETpToday', {
|
|
458
|
+
val: ETpTodayNum,
|
|
459
|
+
ack: true
|
|
460
|
+
});
|
|
461
|
+
curTemperatureMax = 0;
|
|
462
|
+
adapter.setState('evaporation.dailyHighTemp', {
|
|
463
|
+
val: curTemperatureMax,
|
|
464
|
+
ack: true
|
|
465
|
+
});
|
|
466
|
+
}, 100);
|
|
467
|
+
},
|
|
468
|
+
/**
|
|
469
|
+
*
|
|
470
|
+
* @param {number} maxExtension - Wert aus der Konfiguration (wateringAdd 100...300%) des Bewässerungskreises
|
|
471
|
+
* @returns {number} - Erweiterung/Multiplikator (1...3) der Bewässerungszeit
|
|
472
|
+
*/
|
|
473
|
+
timeExtension (maxExtension) {
|
|
474
|
+
if (ETpTodayNum < 136) { // 16. Mai
|
|
475
|
+
return 1;
|
|
476
|
+
}else if (ETpTodayNum < 171) { // 20. Juni
|
|
477
|
+
return trend(136, 170,1, maxExtension / 100, ETpTodayNum);
|
|
478
|
+
} else if (ETpTodayNum < 186) { // 5. Juli
|
|
479
|
+
return maxExtension / 100;
|
|
480
|
+
}else if (ETpTodayNum < 241) { // 29. August
|
|
481
|
+
return trend(186, 240,maxExtension / 100, 1, ETpTodayNum);
|
|
482
|
+
}else {
|
|
483
|
+
return 1;
|
|
484
|
+
}
|
|
485
|
+
},
|
|
486
|
+
/**Output of the current evaporation =>
|
|
487
|
+
* Ausgabe der aktuellen Verdunstung
|
|
488
|
+
* @returns {number}
|
|
489
|
+
*/
|
|
490
|
+
getETpTodayNum () {
|
|
491
|
+
return ETpTodayNum;
|
|
492
|
+
},
|
|
493
|
+
getCurTemperatureMax () {
|
|
494
|
+
return curTemperatureMax;
|
|
495
|
+
}
|
|
496
|
+
};
|
|
497
|
+
|
|
456
498
|
module.exports = evaporation;
|