iobroker.sprinklecontrol 0.2.13 → 0.2.14

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.
Files changed (71) hide show
  1. package/{Lizenz → LICENSE} +21 -21
  2. package/README.md +60 -110
  3. package/admin/i18n/de/translations.json +134 -0
  4. package/admin/i18n/en/translations.json +134 -0
  5. package/admin/i18n/es/translations.json +134 -0
  6. package/admin/i18n/fr/translations.json +134 -0
  7. package/admin/i18n/it/translations.json +134 -0
  8. package/admin/i18n/nl/translations.json +134 -0
  9. package/admin/i18n/pl/translations.json +134 -0
  10. package/admin/i18n/pt/translations.json +134 -0
  11. package/admin/i18n/ru/translations.json +134 -0
  12. package/admin/i18n/uk/translations.json +134 -0
  13. package/admin/i18n/zh-cn/translations.json +134 -0
  14. package/admin/index_m.html +904 -907
  15. package/admin/index_m.js +779 -779
  16. package/admin/style.css +453 -158
  17. package/admin/words.js +143 -136
  18. package/io-package.json +256 -189
  19. package/lib/adapter-config.d.ts +19 -16
  20. package/lib/evaporation.js +443 -412
  21. package/lib/myConfig.js +373 -359
  22. package/lib/sendMessageText.js +162 -199
  23. package/lib/tools.js +148 -125
  24. package/lib/valveControl.js +918 -887
  25. package/main.js +2041 -1828
  26. package/package.json +50 -32
  27. package/.gitattributes +0 -2
  28. package/admin/admin.d.ts +0 -1
  29. package/docs/de/img/E-Mail.jpg +0 -0
  30. package/docs/de/img/Extraeinstellungen.jpg +0 -0
  31. package/docs/de/img/Pumpeneinstellung.jpg +0 -0
  32. package/docs/de/img/Pushover.jpg +0 -0
  33. package/docs/de/img/Select_ID.jpg +0 -0
  34. package/docs/de/img/Telegram.jpg +0 -0
  35. package/docs/de/img/Ventil-Haupteinstellung.jpg +0 -0
  36. package/docs/de/img/Ventil-Pumpeneinstellung.jpg +0 -0
  37. package/docs/de/img/WhatsApp.jpg +0 -0
  38. package/docs/de/img/Zeiteinstellung.jpg +0 -0
  39. package/docs/de/img/addTime.jpg +0 -0
  40. package/docs/de/img/analog.jpg +0 -0
  41. package/docs/de/img/ber-verdunstung.jpg +0 -0
  42. package/docs/de/img/bew-einstellung.jpg +0 -0
  43. package/docs/de/img/bew-feste-tage.jpg +0 -0
  44. package/docs/de/img/bistabil.jpg +0 -0
  45. package/docs/de/img/bodenf-analog.jpg +0 -0
  46. package/docs/de/img/bodenf-bistabil.jpg +0 -0
  47. package/docs/de/img/calculation.jpg +0 -0
  48. package/docs/de/img/control.jpg +0 -0
  49. package/docs/de/img/einschaltpunkt-giessen.jpg +0 -0
  50. package/docs/de/img/festeTage.jpg +0 -0
  51. package/docs/de/img/main.jpg +0 -0
  52. package/docs/de/img/main_tab.jpg +0 -0
  53. package/docs/de/img/max-bodenfeuchtigkeit.jpg +0 -0
  54. package/docs/de/img/schaltverhalten.jpg +0 -0
  55. package/docs/de/img/sprinklecontrol.png +0 -0
  56. package/docs/de/img/verdunstDiagra.jpg +0 -0
  57. package/docs/de/img/verdunstung.jpg +0 -0
  58. package/docs/de/img/zus-bew-einstellung.jpg +0 -0
  59. package/docs/de/sprinklecontrol.md +0 -656
  60. package/docs/en/img/schaltverhalten.jpg +0 -0
  61. package/docs/en/img/screenshot1.jpg +0 -0
  62. package/docs/en/img/screenshot2.jpg +0 -0
  63. package/docs/en/img/screenshot3.jpg +0 -0
  64. package/docs/en/img/screenshot4.jpg +0 -0
  65. package/docs/en/img/screenshot5.jpg +0 -0
  66. package/docs/en/img/screenshot6.jpg +0 -0
  67. package/docs/en/img/screenshot7.jpg +0 -0
  68. package/docs/en/img/screenshot8.jpg +0 -0
  69. package/docs/en/img/sprinklecontrol.png +0 -0
  70. package/docs/en/sprinklecontrol.md +0 -230
  71. package/main.test.js +0 -30
package/lib/myConfig.js CHANGED
@@ -1,360 +1,374 @@
1
- 'use strict';
2
-
3
- /*
4
- info: log aufbau myConfig.js: #1.*
5
- */
6
- const {formatTime} = require("./tools");
7
- const trend = require('./tools').trend; // tools => laden von Hilfsfunktionen
8
- // const formatTime = require('./tools').formatTime; // tools => laden von Hilfsfunktionen
9
-
10
- /**
11
- * The adapter instance
12
- * @type {ioBroker.Adapter}
13
- */
14
- let adapter;
15
-
16
- /**
17
- * Ermittlung der Bewässerungsmethode und der dazugehörigen Parameter
18
- * Sensorabfrage für Bodenfeuchte-Sensoren beantragen (subscribeStates)
19
- * @param {Object} res - Objekt mit den Ventildaten aus der Config
20
- * @param {string} res.methodControlSM - methodControlSM [Auswahlfeld in der Config]
21
- * @param {string} res.triggerSM - triggerSM [Bodenfeuchte-Sensor in der Config]
22
- * @param {string} res.analogZPct - analog Zero Percent [Auswahlfeld in der Config des Sprinklers > Bodenfeuchte-Sensor > analog > Wert bei 0 %]
23
- * @param {string} res.analogOHPct - analog One Hundert Percent [Auswahlfeld in der Config des Sprinklers > Bodenfeuchte-Sensor > analog > Wert bei 100 %]
24
- * @param {string} res.maxSoilMoistureIrrigation - maximale Bodenfeuchte nach der Bewässerung [Auswahlfeld in der Config des Sprinklers]
25
- * @param {string} res.startDay - Auswahl (threeRd = Start im 3-Tages-Rhythmus,twoNd = Start im 2-Tages-Rhythmus, fixDay = Start an festen Tagen Sun-Sat)
26
- * @param {boolean} res.sun - Sontag, Sunday (Sun)
27
- * @param {boolean} res.mon - Montag, Monday (Mon)
28
- * @param {boolean} res.tue - Dienstag, Tuesday (Tue) (Tues)
29
- * @param {boolean} res.wed - Mittwoch, Wednesday (Wed)
30
- * @param {boolean} res.thur - Donnerstag, Thursday (Thur) (Thurs)
31
- * @param {boolean} res.fri - Freitag, Friday (Fri)
32
- * @param {boolean} res.sat - Samstag, Saturday (Sat)
33
- * @returns {{setMetConSM: string, setPct: (number|null), setStartDay: (string|null), setStartFixDay: boolean[], setAnalogZPct: (number|null), setAnalogOHPct: (number|null), setTrigSM: (string|null), setVal: (number|null), setBool: (boolean|null)}}
34
- */
35
- function getMetConSM(res) {
36
-
37
- if (res.methodControlSM === 'bistable') {
38
- // bistable (Bodenfeuchte-Sensor)
39
- adapter.subscribeForeignStates(res.triggerSM);
40
- return {
41
- setStartDay: null,
42
- setStartFixDay: null,
43
- setMetConSM: 'bistable',
44
- setTrigSM: res.triggerSM,
45
- setAnalogZPct: null,
46
- setAnalogOHPct: null,
47
- setPct: null,
48
- setVal: null,
49
- setBool: null
50
- };
51
-
52
-
53
- } else if (res.methodControlSM === 'analog') {
54
- // analog (Bodenfeuchte-Sensor)
55
- adapter.subscribeForeignStates(res.triggerSM);
56
- return {
57
- setStartDay: null,
58
- setStartFixDay: null,
59
- setMetConSM: 'analog',
60
- setTrigSM: res.triggerSM,
61
- setAnalogZPct: parseFloat(res.analogZPct),
62
- setAnalogOHPct: parseFloat(res.analogOHPct),
63
- setPct: null,
64
- setVal: null,
65
- setBool: null
66
- };
67
- } else if (res.methodControlSM === 'fixDay') {
68
- // start zur festen Zeit und Wochentag (ohne-Sensoren)
69
- /**
70
- * Wochentage an denen gestartet wird
71
- * @type {boolean[]}
72
- */
73
- const startFixDay = [false, false, false, false, false, false, false]; // Sun, Mon, Tue, Wed, Thur, Fri, Sat
74
-
75
- if(res.startDay === 'threeRd' || res.startDay === 'twoNd') {
76
- /** @type {number} */
77
- //let today = formatTime(adapter,'', 'day');
78
- /** @type {number} */
79
- //let nextStartDay = ((today + 1) > 6) ? 0 : (today + 1);
80
- //startFixDay[nextStartDay] = true; // Start am nächsten Tag
81
- } else if (res.startDay === 'fixDay') {
82
- startFixDay[0] = res.sun;
83
- startFixDay[1] = res.mon;
84
- startFixDay[2] = res.tue;
85
- startFixDay[3] = res.wed;
86
- startFixDay[4] = res.thur;
87
- startFixDay[5] = res.fri;
88
- startFixDay[6] = res.sat;
89
- }
90
- return {
91
- setStartDay: res.startDay,
92
- setStartFixDay: startFixDay,
93
- setMetConSM: 'fixDay',
94
- setTrigSM: '',
95
- setAnalogZPct: null,
96
- setAnalogOHPct: null,
97
- setPct: null,
98
- setVal: null,
99
- setBool: null
100
- };
101
- } else if (res.methodControlSM === 'calculation') {
102
- // interne (Berechnung der Verdunstung)
103
- return {
104
- setStartDay: null,
105
- setStartFixDay: null,
106
- setMetConSM: 'calculation',
107
- setTrigSM: '',
108
- setAnalogZPct: null,
109
- setAnalogOHPct: null,
110
- setPct: 50,
111
- setVal: parseFloat(res.maxSoilMoistureIrrigation) / 2,
112
- setBool: null
113
- };
114
- } else {
115
- adapter.log.warn('Emergency program! No irrigation type is selected in the SprinkleControl configuration! Please adjust.');
116
- return {
117
- setStartDay: 'twoNd',
118
- setStartFixDay: [false, false, false, false, false, false, false], // Sun, Mon, Tue, Wed, Thur, Fri, Sat
119
- setMetConSM: 'fixDay',
120
- setTrigSM: '',
121
- setAnalogZPct: null,
122
- setAnalogOHPct: null,
123
- setPct: null,
124
- setVal: null,
125
- setBool: null
126
- };
127
- }
128
- }
129
-
130
- const myConfig = {
131
- config: [],
132
- /**
133
- *
134
- * @param {ioBroker.Adapter} myAdapter - Kopie von Adapter main.js
135
- */
136
- createConfig: (myAdapter) => {
137
- adapter = myAdapter;
138
- const result = adapter.config.events;
139
- if (result) {
140
- for (const res of result) {
141
- /** Name des Bewässerungskreises
142
- * @type {string}
143
- */
144
- let objectName
145
- if(res.sprinkleName !== '') {
146
- objectName = res.sprinkleName.replace(/[.;, ]/g, '_');
147
- } else if (res.sprinkleName === '') {
148
- objectName = res.name.replace(/[.;, ]/g, '_');
149
- }
150
- const metConSM = getMetConSM(res);
151
- const newEntry = {
152
- /** Starttage in der Woche
153
- * - 0(Sun); 1(Mon); 2(Tue); 3(Wed); 4(Thur); 5(Fri); 6(Sat)
154
- * @type {Array.<boolean>}
155
- * startFixDay */
156
- startFixDay: metConSM.setStartFixDay, // Sontag, Sunday (Sun)// Montag, Monday (Mon)// Dienstag, Tuesday (Tue) (Tues)// Mittwoch, Wednesday (Wed)// Donnerstag, Thursday (Thur) (Thurs)// Freitag, Friday (Fri)// Samstag, Saturday (Sat)
157
- /** - Auswahl:
158
- * - threeRd = Start im 3 Tages Rhythmus,
159
- * - twoNd = Start im 2 Tages Rhythmus
160
- * - fixDay = Start an festen Tagen Sun-Sat
161
- * @type {string} */ startDay: metConSM.setStartDay,
162
- /** @type {boolean} */ enabled: res.enabled || false,
163
- /** @type {boolean} */ booster: res.booster,
164
- /** @type {number} */ endIrrigation: res.endIrrigation,
165
- /** @type {boolean} */ autoOn: true,
166
- /** @type {string} */ autoOnID: adapter.namespace + '.sprinkle.' + objectName + '.autoOn', // sprinklecontrol.0.sprinkle.Rasenumrandung.autoOnID
167
- /** @type {string} */ objectName: objectName, // z.B. Rasenumrandung
168
- /** @type {string} */ objectID: adapter.namespace + '.sprinkle.' + objectName + '.runningTime', // sprinklecontrol.0.sprinkle.Rasenumrandung.runningTime
169
- /** @type {string} */ idState: res.name, // "hm-rpc.0.MEQ1234567.3.STATE"
170
- /** @type {any} */ updateStateTimerID: null, // Timer wird gelöscht wenn Rückmeldung erfolgte
171
- /** @type {number} */ sprinkleID: myConfig.config.length, // Array[0...]
172
- /** @type {number} */ wateringTime: parseInt(res.wateringTime), // ...min
173
- /** @type {number} */ wateringAdd: parseInt(res.wateringAdd), // 0 ... 200%
174
- /** @type {number} */ wateringInterval: ((60 * parseInt(res.wateringInterval)) || 0), // 5,10,15min
175
- /** @type {number} */ addWateringTime: (parseInt(res.addWateringTime) || 0), // ...min Zusatzbewässerung bei hohen Temperaturen
176
- /** @type {number} */ pipeFlow: parseInt(res.pipeFlow), // Wasserverbrauch des sprinkler-Kreises
177
- /** @type {string} */ methodControlSM: metConSM.setMetConSM, // Art der Kontrolle der Bodenfeuchte ('calculation'; 'bistable'; 'analog'; fixDay)
178
- /** @type {string} */ triggerSM: metConSM.setTrigSM, // Sensor für die Bodenfeuchte
179
- /** @type {boolean} */ inGreenhouse: res.inGreenhouse || false, // keine Wettervorhersage verwenden (Gewächshaus)
180
- /** @type {number} */ analogZPct: metConSM.setAnalogZPct, // analoger Sensor Wert bei 0% (analog zero percent)
181
- /** @type {number} */ analogOHPct: metConSM.setAnalogOHPct, // analoger Sensor Wert bei 100% (analog one hundert percent)
182
- 'soilMoisture': {
183
- /** @type {number} */ val: metConSM.setVal, // Bodenfeuchte / Wassergehalt der oberen Bodenschicht (zB. 5 mm == 50%)
184
- /** @type {number} */ pct: metConSM.setPct, // Bodenfeuchte in % zB. 50% = maxSoilMoistureIrrigation) / 2
185
- /** @type {boolean} */ bool: metConSM.setBool, // Bodenfeuchtezustand trocken/feucht === true/false
186
- /** @type {number} */ min: parseFloat(res.maxSoilMoistureIrrigation) / 100, // (zB. 0,02 mm)
187
- /** @type {number} */ maxIrrigation: parseFloat(res.maxSoilMoistureIrrigation), // (zB. 10 mm)
188
- /** @type {number} */ maxRain: parseFloat(res.maxSoilMoistureIrrigation) /100 * (parseFloat(/** @type {string} */ res.maxSoilMoistureRainPct) || 120), // (zB. 12 mm)
189
- /** @type {number} */ triggersIrrigation: parseFloat(res.maxSoilMoistureIrrigation) * parseInt(res.triggersIrrigation) / 100, // (zB. 50 % ==> 5 mm)
190
- /** @type {number} */ pctTriggerIrrigation: parseFloat(res.triggersIrrigation), // Auslöser der Bewässerung in % (zB. 50%)
191
- /** @type {number} */ pctAddTriggersIrrigation: (parseFloat(/** @type {string} */ res.addTriggersIrrigation) < parseFloat(res.triggersIrrigation)) ? parseFloat(res.addTriggersIrrigation) : parseFloat(res.triggersIrrigation)
192
- }
193
- };
194
- myConfig.config.push(newEntry);
195
-
196
- if (newEntry.enabled) {
197
- // Report a change in the status of the trigger IDs (.runningTime; .name) => Melden einer Änderung des Status der Trigger-IDs
198
- adapter.subscribeStates(newEntry.objectID); // abonnieren der Statusänderungen des Objekts (reagieren auf 'runningTime' der einzelnen Bewässerungskreise)
199
- adapter.subscribeStates(newEntry.autoOnID); // abonnieren der Statusänderungen des Objekts (reagieren auf 'autoOn' der einzelnen Bewässerungskreise)
200
- // adapter.subscribeForeignStates(newEntry.idState); // abonnieren der Statusänderungen des Objekts (reagiert auf Änderung des 'Ventils' der einzelnen Bewässerungskreise zur Fehlerkontrolle bzw. Verbrauchsermittlung)
201
- }
202
- adapter.log.debug(`Config ${objectName} created (${newEntry.sprinkleID}) - ${JSON.stringify(myConfig.config[newEntry.sprinkleID])}`);
203
- }
204
- }
205
- },
206
- /**
207
- * apply Evaporation
208
- * → Verdunstung anwenden auf die einzelnen Sprenger kreise
209
- * @param {number} eTP - pot. Evapotranspiration nach Penman ETp in mm/d
210
- */
211
- applyEvaporation: (eTP) => {
212
- if (myConfig.config) {
213
- for(const entry of myConfig.config) {
214
- if (entry.methodControlSM === 'calculation'
215
- && !(entry.inGreenhouse && (eTP < 0))) { // nicht anwenden im Gewächshaus und Regen
216
- const objectName = entry.objectName;
217
- const pfadActSoiMoi = 'sprinkle.' + objectName + '.actualSoilMoisture';
218
-
219
- entry.soilMoisture.val -= eTP; // Abfrage => entry.soilMoisture.val
220
- if (entry.soilMoisture.val < entry.soilMoisture.min) {
221
- entry.soilMoisture.val = entry.soilMoisture.min;
222
- } else if (entry.soilMoisture.val > entry.soilMoisture.maxRain) {
223
- entry.soilMoisture.val = entry.soilMoisture.maxRain;
224
- }
225
- entry.soilMoisture.pct = Math.round(1000 * entry.soilMoisture.val / entry.soilMoisture.maxIrrigation) / 10; // Berechnung in %
226
- adapter.log.debug(`apply Evaporation: ${objectName} => soilMoisture: ${entry.soilMoisture.val} soilMoisture: ${entry.soilMoisture.pct} %`);
227
- adapter.setState(pfadActSoiMoi, {
228
- val: entry.soilMoisture.pct,
229
- ack: true
230
- });
231
- }
232
- }
233
- }
234
- },
235
- /**
236
- * Bodenfeuchte (soilMoisture) setzen auf: => pct = 100%; val = maxIrrigation
237
- * @param {number} mySprinkleID - ID des Bewässerungskreises
238
- */
239
- setSoilMoistPct100: (mySprinkleID) => {
240
- myConfig.config[mySprinkleID].soilMoisture.val = myConfig.config[mySprinkleID].soilMoisture.maxIrrigation;
241
- myConfig.config[mySprinkleID].soilMoisture.pct = 100;
242
- adapter.setState('sprinkle.' + myConfig.config[mySprinkleID].objectName + '.actualSoilMoisture', {
243
- val: myConfig.config[mySprinkleID].soilMoisture.pct,
244
- ack: true
245
- });
246
- },
247
- /**
248
- * Speichern der Bodenfeuchtigkeit = bistabil (Bodenfeuchte-Sensor)
249
- * @param {number} mySprinkleID - ID des Bewässerungskreis
250
- * @param {boolean} newVal - neuer Wert vom Bodenfeuchte-Sensor
251
- */
252
- setSoilMoistBool: (mySprinkleID, newVal) => {
253
- if (myConfig.config[mySprinkleID].methodControlSM === 'bistable') {
254
- if (typeof newVal === "boolean") {
255
- myConfig.config[mySprinkleID].soilMoisture.bool = newVal;
256
- adapter.setState('sprinkle.' + [myConfig.config[mySprinkleID].objectName] + '.actualSoilMoisture', {
257
- val: myConfig.config[mySprinkleID].soilMoisture.bool,
258
- ack: true
259
- });
260
- } else {
261
- adapter.log.warn(`The ${myConfig.config[mySprinkleID].objectName} soil moisture sensor does not provide a Boolean signal`);
262
- }
263
- } else {
264
- adapter.log.warn(`Please check the signals and settings of the ${myConfig.config[mySprinkleID].objectName} soil moisture sensor`);
265
- }
266
- },
267
- /**
268
- * Speichern der Bodenfeuchtigkeit = analog (Bodenfeuchte-Sensor)
269
- * @param {number} mySprinkleID - ID des Bewässerungskreis
270
- * @param {string|number} newVal - neuer Wert vom Bodenfeuchte-Sensor
271
- */
272
- setSoilMoistPct: (mySprinkleID, newVal) => {
273
- if (myConfig.config[mySprinkleID].methodControlSM === 'analog') {
274
- if (typeof parseFloat(newVal) === 'number') {
275
- /**aktueller Wert des Bodenfeuchte-Sensor
276
- * @type {number} myVal
277
- */
278
- let myVal;
279
- /**Reversible Eingang des Bodenfeuchte sensors
280
- * @type {boolean} reverse -Eingang analogOHPct < analogZPct
281
- *
282
- */
283
- const reverse = (myConfig.config[mySprinkleID].analogOHPct < myConfig.config[mySprinkleID].analogZPct);
284
- if (myConfig.config[mySprinkleID].analogOHPct === myConfig.config[mySprinkleID].analogZPct) {
285
- adapter.log.warn(`${myConfig.config[mySprinkleID].objectName}: analog soil moisture sensor at 0% and at 100% => the values are the same`);
286
- }
287
- newVal = parseFloat(newVal);
288
-
289
- if ((!reverse && newVal < myConfig.config[mySprinkleID].analogZPct)
290
- || (reverse && myConfig.config[mySprinkleID].analogZPct < newVal)) {
291
- myVal = myConfig.config[mySprinkleID].analogZPct;
292
- adapter.log.warn(`${myConfig.config[mySprinkleID].objectName} (${newVal}): analog soil moisture sensor at 0 % => ${reverse ? "The range of values has been exceeded (reverse)" : "The value range was undercut"}`);
293
- } else if ((!reverse && newVal > myConfig.config[mySprinkleID].analogOHPct)
294
- || (reverse && myConfig.config[mySprinkleID].analogOHPct > newVal)) {
295
- myVal = myConfig.config[mySprinkleID].analogOHPct;
296
- adapter.log.warn(`${myConfig.config[mySprinkleID].objectName} (${newVal}): analog soil moisture sensor at 100 % => ${reverse ? "The value range was undercut (reverse)" : "The range of values has been exceeded"}`);
297
- } else {
298
- myVal = newVal;
299
- }
300
-
301
- myConfig.config[mySprinkleID].soilMoisture.pct = Math.round(10 * trend(myConfig.config[mySprinkleID].analogZPct, myConfig.config[mySprinkleID].analogOHPct, 0, 100, myVal)) / 10;
302
- adapter.setState('sprinkle.' + [myConfig.config[mySprinkleID].objectName] + '.actualSoilMoisture', {
303
- val: myConfig.config[mySprinkleID].soilMoisture.pct,
304
- ack: true
305
- });
306
- } else {
307
- adapter.log.warn(`The ${myConfig.config[mySprinkleID].objectName} soil moisture sensor does not provide a Number signal`);
308
- }
309
- } else {
310
- adapter.log.warn(`Please check the signals and settings of the ${myConfig.config[mySprinkleID].objectName} soil moisture sensor`);
311
- }
312
- },
313
- /**
314
- * Bodenfeuchte (soilMoisture) erhöhen bis maxIrrigation (100%)
315
- * @param {number} mySprinkleID - ID des Bewässerungskreis
316
- * @param {number} addVal - soilMoisture.val wird um den Wert addVal erhöht
317
- */
318
- addSoilMoistVal: (mySprinkleID, addVal) => {
319
- if (myConfig.config[mySprinkleID].soilMoisture.val < myConfig.config[mySprinkleID].soilMoisture.maxIrrigation) {
320
- myConfig.config[mySprinkleID].soilMoisture.val += addVal;
321
- if (myConfig.config[mySprinkleID].soilMoisture.val > myConfig.config[mySprinkleID].soilMoisture.maxIrrigation) {
322
- myConfig.config[mySprinkleID].soilMoisture.val = myConfig.config[mySprinkleID].soilMoisture.maxIrrigation;
323
- }
324
- }
325
-
326
- myConfig.config[mySprinkleID].soilMoisture.pct = Math.round(1000 * myConfig.config[mySprinkleID].soilMoisture.val
327
- / myConfig.config[mySprinkleID].soilMoisture.maxIrrigation) / 10; // Berechnung in %
328
- adapter.setState('sprinkle.' + myConfig.config[mySprinkleID].objectName + '.actualSoilMoisture', {
329
- val: myConfig.config[mySprinkleID].soilMoisture.pct,
330
- ack: true
331
- });
332
- },
333
- postponeByOneDay: async (mySprinkleID) => {
334
- if (myConfig.config[mySprinkleID].startDay === 'threeRd' || // Next Start in 3 Tagen
335
- myConfig.config[mySprinkleID].startDay === 'twoNd') { // Next Start in 2 Tagen
336
- let today = await formatTime(adapter,'', 'day');
337
- let id = `${adapter.namespace}.sprinkle.${myConfig.config[mySprinkleID].objectName}.actualSoilMoisture`;
338
- let curDay, nextDay;
339
- /**
340
- * Wert von actualSoilMoisture auslesen
341
- * @type {ioBroker.State | void}
342
- * @private
343
- */
344
- const _curDay = await adapter.getStateAsync(id).catch((e) => adapter.log.warn(`postponeByOneDay getStateAsync: ${e}`));
345
- if (_curDay) {
346
- curDay = ((_curDay.val >= 0) && (_curDay.val <= 6) && (typeof _curDay.val === 'number') ? _curDay.val : today);
347
- myConfig.config[mySprinkleID].startFixDay[curDay] = false;
348
- nextDay = (+ curDay + 1 > 6) ? (+ curDay-6) : (+ curDay+1);
349
- myConfig.config[mySprinkleID].startFixDay[nextDay] = true;
350
- adapter.setStateAsync(
351
- `${id}`,
352
- nextDay,
353
- true
354
- ).catch((e) => adapter.log.warn(`postponeByOneDay setStateAsync: ${e}`));
355
- }
356
- }
357
- }
358
- };
359
-
1
+ 'use strict';
2
+
3
+ /*
4
+ info: log aufbau myConfig.js: #1.*
5
+ */
6
+ const {formatTime} = require('./tools');
7
+ const trend = require('./tools').trend; // tools => laden von Hilfsfunktionen
8
+ // const formatTime = require('./tools').formatTime; // tools => laden von Hilfsfunktionen
9
+
10
+ let adapter;
11
+
12
+ /**
13
+ * Ermittlung der Bewässerungsmethode und der dazugehörigen Parameter
14
+ * Sensorabfrage für Bodenfeuchte-Sensoren beantragen (subscribeStates)
15
+ *
16
+ * @param {object} res - Objekt mit den Ventildaten aus der Config
17
+ * @param {string} res.methodControlSM - methodControlSM [Auswahlfeld in der Config].
18
+ * @param {string} res.triggerSM - triggerSM [Bodenfeuchte-Sensor in der Config].
19
+ * @param {string} res.analogZPct - analog Zero Percent [Auswahlfeld in der Config des Sprinklers > Bodenfeuchte-Sensor > analog > Wert bei 0 %].
20
+ * @param {string} res.analogOHPct - analog One Hundert Percent [Auswahlfeld in der Config des Sprinklers > Bodenfeuchte-Sensor > analog > Wert bei 100 %].
21
+ * @param {string} res.maxSoilMoistureIrrigation - maximale Bodenfeuchte nach der Bewässerung [Auswahlfeld in der Config des Sprinklers].
22
+ * @param {string} res.startDay - Auswahl (threeRd = Start im 3-Tages-Rhythmus,twoNd = Start im 2-Tages-Rhythmus, fixDay = Start an festen Tagen Sun-Sat).
23
+ * @param {boolean} res.sun - Sontag, Sunday (Sun).
24
+ * @param {boolean} res.mon - Montag, Monday (Mon).
25
+ * @param {boolean} res.tue - Dienstag, Tuesday (Tue) (Tues).
26
+ * @param {boolean} res.wed - Mittwoch, Wednesday (Wed).
27
+ * @param {boolean} res.thur - Donnerstag, Thursday (Thur) (Thurs).
28
+ * @param {boolean} res.fri - Freitag, Friday (Fri).
29
+ * @param {boolean} res.sat - Samstag, Saturday (Sat).
30
+ * @returns {{setMetConSM: string, setPct: (number|null), setStartDay: (string|null), setStartFixDay: boolean[]|null, setAnalogZPct: (number|null), setAnalogOHPct: (number|null), setTrigSM: (string|null), setVal: (number|null), setBool: (boolean|null)}}
31
+ */
32
+
33
+ function getMetConSM(res) {
34
+
35
+ if (res.methodControlSM === 'bistable') {
36
+ // bistable (Bodenfeuchte-Sensor)
37
+ adapter.subscribeForeignStates(res.triggerSM);
38
+ return {
39
+ setStartDay: null,
40
+ setStartFixDay: null,
41
+ setMetConSM: 'bistable',
42
+ setTrigSM: res.triggerSM,
43
+ setAnalogZPct: null,
44
+ setAnalogOHPct: null,
45
+ setPct: null,
46
+ setVal: null,
47
+ setBool: null
48
+ };
49
+
50
+
51
+ } else if (res.methodControlSM === 'analog') {
52
+ // analog (Bodenfeuchte-Sensor)
53
+ adapter.subscribeForeignStates(res.triggerSM);
54
+ return {
55
+ setStartDay: null,
56
+ setStartFixDay: null,
57
+ setMetConSM: 'analog',
58
+ setTrigSM: res.triggerSM,
59
+ setAnalogZPct: parseFloat(res.analogZPct),
60
+ setAnalogOHPct: parseFloat(res.analogOHPct),
61
+ setPct: null,
62
+ setVal: null,
63
+ setBool: null
64
+ };
65
+ } else if (res.methodControlSM === 'fixDay') {
66
+ // start zur festen Zeit und Wochentag (ohne-Sensoren)
67
+ /**
68
+ * Wochentage an denen gestartet wird
69
+ *
70
+ */
71
+ const startFixDay = [false, false, false, false, false, false, false]; // Sun, Mon, Tue, Wed, Thur, Fri, Sat
72
+
73
+ if(res.startDay === 'threeRd' || res.startDay === 'twoNd') {
74
+ //let today = formatTime(adapter,'', 'day');
75
+ //let nextStartDay = ((today + 1) > 6) ? 0 : (today + 1);
76
+ //startFixDay[nextStartDay] = true; // Start am nächsten Tag
77
+ } else if (res.startDay === 'fixDay') {
78
+ startFixDay[0] = res.sun;
79
+ startFixDay[1] = res.mon;
80
+ startFixDay[2] = res.tue;
81
+ startFixDay[3] = res.wed;
82
+ startFixDay[4] = res.thur;
83
+ startFixDay[5] = res.fri;
84
+ startFixDay[6] = res.sat;
85
+ }
86
+ return {
87
+ setStartDay: res.startDay,
88
+ setStartFixDay: startFixDay,
89
+ setMetConSM: 'fixDay',
90
+ setTrigSM: '',
91
+ setAnalogZPct: null,
92
+ setAnalogOHPct: null,
93
+ setPct: null,
94
+ setVal: null,
95
+ setBool: null
96
+ };
97
+ } else if (res.methodControlSM === 'calculation') {
98
+ // interne (Berechnung der Verdunstung)
99
+ return {
100
+ setStartDay: null,
101
+ setStartFixDay: null,
102
+ setMetConSM: 'calculation',
103
+ setTrigSM: '',
104
+ setAnalogZPct: null,
105
+ setAnalogOHPct: null,
106
+ setPct: 50,
107
+ setVal: parseFloat(res.maxSoilMoistureIrrigation) / 2,
108
+ setBool: null
109
+ };
110
+ } else {
111
+ // Notprogramm! In der SprinkleControl Konfiguration ist keine Bewässerungsart ausgewählt! Bitte anpassen.
112
+ adapter.log.warn('Emergency program! No irrigation type is selected in the SprinkleControl configuration! Please adjust.');
113
+ return {
114
+ setStartDay: 'twoNd',
115
+ setStartFixDay: [false, false, false, false, false, false, false], // Sun, Mon, Tue, Wed, Thur, Fri, Sat
116
+ setMetConSM: 'fixDay',
117
+ setTrigSM: '',
118
+ setAnalogZPct: null,
119
+ setAnalogOHPct: null,
120
+ setPct: null,
121
+ setVal: null,
122
+ setBool: null
123
+ };
124
+ }
125
+ }
126
+
127
+ const myConfig = {
128
+
129
+ config: [],
130
+ /**
131
+ *
132
+ * @param myAdapter - Kopie von Adapter main.js
133
+ */
134
+ createConfig: (myAdapter) => {
135
+ adapter = myAdapter;
136
+ const result = adapter.config.events;
137
+ if (result) {
138
+ for (const res of result) {
139
+ /** Name des Bewässerungskreises */
140
+ let objectName = '';
141
+ if(res.sprinkleName !== '') {
142
+ objectName = res.sprinkleName.replace(/[.;, ]/g, '_');
143
+ } else if (res.sprinkleName === '') {
144
+ objectName = res.name.replace(/[.;, ]/g, '_');
145
+ }
146
+ const metConSM = getMetConSM(res);
147
+ /**
148
+ * Spränger hinzufügen
149
+ */
150
+ const newEntry = {
151
+ /**
152
+ * Starttage in der Woche
153
+ * - 0(Sun); 1(Mon); 2(Tue); 3(Wed); 4(Thur); 5(Fri); 6(Sat)
154
+ */
155
+ startFixDay: metConSM.setStartFixDay, // Sontag, Sunday (Sun)// Montag, Monday (Mon)// Dienstag, Tuesday (Tue) (Tues)// Mittwoch, Wednesday (Wed)// Donnerstag, Thursday (Thur) (Thurs)// Freitag, Friday (Fri)// Samstag, Saturday (Sat)
156
+ /**
157
+ * - Auswahl:
158
+ * - threeRd = Start im 3 Tages Rhythmus,
159
+ * - twoNd = Start im 2 Tages Rhythmus
160
+ * - fixDay = Start an festen Tagen Sun-Sat
161
+ */
162
+ startDay: metConSM.setStartDay,
163
+ enabled: res.enabled || false,
164
+ booster: res.booster,
165
+ endIrrigation: res.endIrrigation,
166
+ autoOn: true,
167
+ autoOnID: `${adapter.namespace }.sprinkle.${ objectName }.autoOn`, // sprinklecontrol.0.sprinkle.Rasenumrandung.autoOnID
168
+ objectName: objectName, // z.B. Rasenumrandung
169
+ objectID: `${adapter.namespace }.sprinkle.${ objectName }.runningTime`, // sprinklecontrol.0.sprinkle.Rasenumrandung.runningTime
170
+ idState: res.name, // "hm-rpc.0.MEQ1234567.3.STATE"
171
+ updateStateTimerID: null, // Timer wird gelöscht wenn Rückmeldung erfolgte
172
+ sprinkleID: myConfig.config.length, // Array[0...]
173
+ wateringTime: parseInt(res.wateringTime), // ...min
174
+ wateringAdd: parseInt(res.wateringAdd), // 0 ... 200%
175
+ wateringInterval: ((60 * parseInt(res.wateringInterval)) || 0), // 5,10,15min
176
+ addWateringTime: (parseInt(res.addWateringTime) || 0), // ...min Zusatzbewässerung bei hohen Temperaturen
177
+ pipeFlow: parseInt(res.pipeFlow), // Wasserverbrauch des sprinkler-Kreises
178
+ methodControlSM: metConSM.setMetConSM, // Art der Kontrolle der Bodenfeuchte ('calculation'; 'bistable'; 'analog'; fixDay)
179
+ triggerSM: metConSM.setTrigSM, // Sensor für die Bodenfeuchte
180
+ inGreenhouse: res.inGreenhouse || false, // keine Wettervorhersage verwenden (Gewächshaus)
181
+ analogZPct: metConSM.setAnalogZPct, // analoger Sensor Wert bei 0% (analog zero percent)
182
+ analogOHPct: metConSM.setAnalogOHPct, // analoger Sensor Wert bei 100% (analog one hundert percent)
183
+ soilMoisture: {
184
+ val: metConSM.setVal, // Bodenfeuchte / Wassergehalt der oberen Bodenschicht (zB. 5 mm == 50%)
185
+ pct: metConSM.setPct, // Bodenfeuchte in % zB. 50% = maxSoilMoistureIrrigation) / 2
186
+ bool: metConSM.setBool, // Bodenfeuchtezustand trocken/feucht === true/false
187
+ min: parseFloat(res.maxSoilMoistureIrrigation) / 100, // (zB. 0,02 mm)
188
+ maxIrrigation: parseFloat(res.maxSoilMoistureIrrigation), // (zB. 10 mm)
189
+ maxRain: parseFloat(res.maxSoilMoistureIrrigation) /100 * (parseFloat(res.maxSoilMoistureRainPct) || 120), // (zB. 12 mm)
190
+ triggersIrrigation: parseFloat(res.maxSoilMoistureIrrigation) * parseInt(res.triggersIrrigation) / 100, // (zB. 50 % ==> 5 mm)
191
+ pctTriggerIrrigation: parseFloat(res.triggersIrrigation), // Auslöser der Bewässerung in % (zB. 50%)
192
+ pctAddTriggersIrrigation: (parseFloat(res.addTriggersIrrigation) < parseFloat(res.triggersIrrigation)) ? parseFloat(res.addTriggersIrrigation) : parseFloat(res.triggersIrrigation)
193
+ }
194
+ };
195
+ myConfig.config.push(newEntry);
196
+
197
+ if (newEntry.enabled) {
198
+ // Report a change in the status of the trigger IDs (.runningTime; .name) => Melden einer Änderung des Status der Trigger-IDs
199
+ adapter.subscribeStates(newEntry.objectID); // abonnieren der Statusänderungen des Objekts (reagieren auf 'runningTime' der einzelnen Bewässerungskreise)
200
+ adapter.subscribeStates(newEntry.autoOnID); // abonnieren der Statusänderungen des Objekts (reagieren auf 'autoOn' der einzelnen Bewässerungskreise)
201
+ // adapter.subscribeForeignStates(newEntry.idState); // abonnieren der Statusänderungen des Objekts (reagiert auf Änderung des 'Ventils' der einzelnen Bewässerungskreise zur Fehlerkontrolle bzw. Verbrauchsermittlung)
202
+ }
203
+ adapter.log.debug(`Config ${objectName} created (${newEntry.sprinkleID}) - ${JSON.stringify(myConfig.config[newEntry.sprinkleID])}`);
204
+
205
+ // kann nicht bewässern! Verbrauch höher als Hauptpumpenleistung
206
+ if (newEntry.pipeFlow > adapter.config.triggerMainPumpPower) {
207
+ adapter.log.warn(`${newEntry.objectName} cannot irrigate! Consumption (${newEntry.pipeFlow}) higher than pump capacity (${adapter.config.triggerMainPumpPower})`);
208
+ }
209
+ // kann nicht bewässern! Verbrauch höher als Zisternenpumpenleistung
210
+ if (adapter.config.cisternSettings && newEntry.pipeFlow > adapter.config.triggerCisternPumpPower) {
211
+ adapter.log.warn(`${newEntry.objectName} can not irrigate! Consumption (${newEntry.pipeFlow}) higher than cistern pump capacity (${adapter.config.triggerCisternPumpPower})`);
212
+ }
213
+ }
214
+ }
215
+ },
216
+ /**
217
+ * apply Evaporation
218
+ * → Verdunstung anwenden auf die einzelnen Sprenger kreise
219
+ *
220
+ * @param eTP - pot. Evapotranspiration nach Penman ETp in mm/d
221
+ */
222
+ applyEvaporation: (eTP) => {
223
+ if (myConfig.config) {
224
+ for(const entry of myConfig.config) {
225
+ if (entry.methodControlSM === 'calculation'
226
+ && !(entry.inGreenhouse && (eTP < 0))) { // nicht anwenden im Gewächshaus und Regen
227
+ const objectName = entry.objectName;
228
+ const pfadActSoiMoi = `sprinkle.${ objectName }.actualSoilMoisture`;
229
+
230
+ entry.soilMoisture.val -= eTP; // Abfrage => entry.soilMoisture.val
231
+ if (entry.soilMoisture.val < entry.soilMoisture.min) {
232
+ entry.soilMoisture.val = entry.soilMoisture.min;
233
+ } else if (entry.soilMoisture.val > entry.soilMoisture.maxRain) {
234
+ entry.soilMoisture.val = entry.soilMoisture.maxRain;
235
+ }
236
+ entry.soilMoisture.pct = Math.round(1000 * entry.soilMoisture.val / entry.soilMoisture.maxIrrigation) / 10; // Berechnung in %
237
+ adapter.log.debug(`apply Evaporation: ${objectName} => soilMoisture: ${entry.soilMoisture.val} soilMoisture: ${entry.soilMoisture.pct} %`);
238
+ adapter.setState(pfadActSoiMoi, {
239
+ val: entry.soilMoisture.pct,
240
+ ack: true
241
+ });
242
+ }
243
+ }
244
+ }
245
+ },
246
+ /**
247
+ * Bodenfeuchte (soilMoisture) setzen auf: => pct = 100%; val = maxIrrigation
248
+ *
249
+ * @param mySprinkleID - ID des Bewässerungskreises
250
+ */
251
+ setSoilMoistPct100: (mySprinkleID) => {
252
+ myConfig.config[mySprinkleID].soilMoisture.val = myConfig.config[mySprinkleID].soilMoisture.maxIrrigation;
253
+ myConfig.config[mySprinkleID].soilMoisture.pct = 100;
254
+ adapter.setState(`sprinkle.${ myConfig.config[mySprinkleID].objectName }.actualSoilMoisture`, {
255
+ val: myConfig.config[mySprinkleID].soilMoisture.pct,
256
+ ack: true
257
+ });
258
+ },
259
+ /**
260
+ * Speichern der Bodenfeuchtigkeit = bistabil (Bodenfeuchte-Sensor)
261
+ *
262
+ * @param mySprinkleID - ID des Bewässerungskreis
263
+ * @param newVal - neuer Wert vom Bodenfeuchte-Sensor
264
+ */
265
+ setSoilMoistBool: (mySprinkleID, newVal) => {
266
+ if (myConfig.config[mySprinkleID].methodControlSM === 'bistable') {
267
+ if (typeof newVal === 'boolean') {
268
+ myConfig.config[mySprinkleID].soilMoisture.bool = newVal;
269
+ adapter.setState(`sprinkle.${ [myConfig.config[mySprinkleID].objectName] }.actualSoilMoisture`, {
270
+ val: myConfig.config[mySprinkleID].soilMoisture.bool,
271
+ ack: true
272
+ });
273
+ } else {
274
+ adapter.log.warn(`The ${myConfig.config[mySprinkleID].objectName} soil moisture sensor does not provide a Boolean signal`);
275
+ }
276
+ } else {
277
+ adapter.log.warn(`Please check the signals and settings of the ${myConfig.config[mySprinkleID].objectName} soil moisture sensor`);
278
+ }
279
+ },
280
+ /**
281
+ * Speichern der Bodenfeuchtigkeit = analog (Bodenfeuchte-Sensor)
282
+ *
283
+ * @param mySprinkleID - ID des Bewässerungskreis
284
+ * @param newVal - neuer Wert vom Bodenfeuchte-Sensor
285
+ */
286
+ setSoilMoistPct: (mySprinkleID, newVal) => {
287
+ if (myConfig.config[mySprinkleID].methodControlSM === 'analog') {
288
+ if (typeof parseFloat(newVal) === 'number') {
289
+ /**aktueller Wert des Bodenfeuchte-Sensor
290
+ * @type {number} myVal
291
+ */
292
+ let myVal;
293
+ /**Reversible Eingang des Bodenfeuchte sensors
294
+ * @type {boolean} reverse -Eingang analogOHPct < analogZPct
295
+ *
296
+ */
297
+ const reverse = (myConfig.config[mySprinkleID].analogOHPct < myConfig.config[mySprinkleID].analogZPct);
298
+ if (myConfig.config[mySprinkleID].analogOHPct === myConfig.config[mySprinkleID].analogZPct) {
299
+ adapter.log.warn(`${myConfig.config[mySprinkleID].objectName}: analog soil moisture sensor at 0% and at 100% => the values are the same`);
300
+ }
301
+ newVal = parseFloat(newVal);
302
+
303
+ if ((!reverse && newVal < myConfig.config[mySprinkleID].analogZPct)
304
+ || (reverse && myConfig.config[mySprinkleID].analogZPct < newVal)) {
305
+ myVal = myConfig.config[mySprinkleID].analogZPct;
306
+ adapter.log.warn(`${myConfig.config[mySprinkleID].objectName} (${newVal}): analog soil moisture sensor at 0 % => ${reverse ? 'The range of values has been exceeded (reverse)' : 'The value range was undercut'}`);
307
+ } else if ((!reverse && newVal > myConfig.config[mySprinkleID].analogOHPct)
308
+ || (reverse && myConfig.config[mySprinkleID].analogOHPct > newVal)) {
309
+ myVal = myConfig.config[mySprinkleID].analogOHPct;
310
+ adapter.log.warn(`${myConfig.config[mySprinkleID].objectName} (${newVal}): analog soil moisture sensor at 100 % => ${reverse ? 'The value range was undercut (reverse)' : 'The range of values has been exceeded'}`);
311
+ } else {
312
+ myVal = newVal;
313
+ }
314
+
315
+ myConfig.config[mySprinkleID].soilMoisture.pct = Math.round(10 * trend(myConfig.config[mySprinkleID].analogZPct, myConfig.config[mySprinkleID].analogOHPct, 0, 100, myVal)) / 10;
316
+ adapter.setState(`sprinkle.${ [myConfig.config[mySprinkleID].objectName] }.actualSoilMoisture`, {
317
+ val: myConfig.config[mySprinkleID].soilMoisture.pct,
318
+ ack: true
319
+ });
320
+ } else {
321
+ adapter.log.warn(`The ${myConfig.config[mySprinkleID].objectName} soil moisture sensor does not provide a Number signal`);
322
+ }
323
+ } else {
324
+ adapter.log.warn(`Please check the signals and settings of the ${myConfig.config[mySprinkleID].objectName} soil moisture sensor`);
325
+ }
326
+ },
327
+ /**
328
+ * Bodenfeuchte (soilMoisture) erhöhen bis maxIrrigation (100%)
329
+ *
330
+ * @param mySprinkleID - ID des Bewässerungskreis
331
+ * @param addVal - soilMoisture.val wird um den Wert addVal erhöht
332
+ */
333
+ addSoilMoistVal: (mySprinkleID, addVal) => {
334
+ if (myConfig.config[mySprinkleID].soilMoisture.val < myConfig.config[mySprinkleID].soilMoisture.maxIrrigation) {
335
+ myConfig.config[mySprinkleID].soilMoisture.val += addVal;
336
+ if (myConfig.config[mySprinkleID].soilMoisture.val > myConfig.config[mySprinkleID].soilMoisture.maxIrrigation) {
337
+ myConfig.config[mySprinkleID].soilMoisture.val = myConfig.config[mySprinkleID].soilMoisture.maxIrrigation;
338
+ }
339
+ }
340
+
341
+ myConfig.config[mySprinkleID].soilMoisture.pct = Math.round(1000 * myConfig.config[mySprinkleID].soilMoisture.val
342
+ / myConfig.config[mySprinkleID].soilMoisture.maxIrrigation) / 10; // Berechnung in %
343
+ adapter.setState(`sprinkle.${ myConfig.config[mySprinkleID].objectName }.actualSoilMoisture`, {
344
+ val: myConfig.config[mySprinkleID].soilMoisture.pct,
345
+ ack: true
346
+ });
347
+ },
348
+ postponeByOneDay: async (mySprinkleID) => {
349
+ if (myConfig.config[mySprinkleID].startDay === 'threeRd' || // Next Start in 3 Tagen
350
+ myConfig.config[mySprinkleID].startDay === 'twoNd') { // Next Start in 2 Tagen
351
+ const today = await formatTime(adapter,'', 'day');
352
+ const id = `${adapter.namespace}.sprinkle.${myConfig.config[mySprinkleID].objectName}.actualSoilMoisture`;
353
+ let curDay, nextDay;
354
+ /**
355
+ * Wert von actualSoilMoisture auslesen
356
+ *
357
+ */
358
+ const _curDay = await adapter.getStateAsync(id).catch((e) => adapter.log.warn(`postponeByOneDay getStateAsync: ${e}`));
359
+ if (_curDay) {
360
+ curDay = ((_curDay.val >= 0) && (_curDay.val <= 6) && (typeof _curDay.val === 'number') ? _curDay.val : today);
361
+ myConfig.config[mySprinkleID].startFixDay[curDay] = false;
362
+ nextDay = (+ curDay + 1 > 6) ? (+ curDay-6) : (+ curDay+1);
363
+ myConfig.config[mySprinkleID].startFixDay[nextDay] = true;
364
+ adapter.setStateAsync(
365
+ `${id}`,
366
+ nextDay,
367
+ true
368
+ ).catch((e) => adapter.log.warn(`postponeByOneDay setStateAsync: ${e}`));
369
+ }
370
+ }
371
+ }
372
+ };
373
+
360
374
  module.exports = myConfig;