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/lib/myConfig.js CHANGED
@@ -1,242 +1,160 @@
1
+ /* @ts-nocheck */
1
2
  'use strict';
2
3
 
3
4
  /*
4
5
  info: log aufbau myConfig.js: #1.*
5
6
  */
6
- const {formatTime} = require('./tools');
7
7
  const trend = require('./tools').trend; // tools => laden von Hilfsfunktionen
8
- // const formatTime = require('./tools').formatTime; // tools => laden von Hilfsfunktionen
9
-
10
- let adapter;
8
+ const formatTime = require('./tools').formatTime; // tools => laden von Hilfsfunktionen
11
9
 
12
10
  /**
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)}}
11
+ * The adapter instance
31
12
  */
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
- }
13
+ let adapter;
126
14
 
127
15
  const myConfig = {
128
-
16
+ /*
17
+ * @type {{enabled:boolean; state:{val:boolean; ack:boolean}; booster:boolean; autoOn:boolean; autoOnID:string; extBreak:boolean; extBreakID:string; objectName:string; objectID:string; idState:string; triggerSM:string;
18
+ * updateStateTimerID:any; sprinkleID:number; wateringTime:number; wateringAdd:number; wateringIntervalOff:number; wateringIntervalOn:number; addWateringTime:number; pipeFlow:number;
19
+ * methodControlSM:'calculation'|'bistable'|'analog'|'fixDay'; inGreenhouse:boolean;
20
+ * calculation:{pct:number; val:number; min:number; maxIrrigation:number; maxRain:number; triggersIrrigation:number; pctTriggerIrrigation:number; pctAddTriggersIrrigation:number; endIrrigation:boolean};
21
+ * bistable:{bool:boolean};
22
+ * analog:{pctTriggerIrrigation:number; pctAddTriggersIrrigation:number; pct:number; analogZPct:number; analogOHPct:number};
23
+ * fixDay:{startDay:'threeRd'|'twoNd'|'fixDay'; startFixDay:boolean[]};
24
+ * }[] | []}
25
+ */
129
26
  config: [],
130
27
  /**
131
28
  *
132
- * @param myAdapter - Kopie von Adapter main.js
29
+ * @param {ioBroker.Adapter} myAdapter - Kopie von Adapter main.js
133
30
  */
134
- createConfig: (myAdapter) => {
31
+ createConfig: async (myAdapter) => {
135
32
  adapter = myAdapter;
136
33
  const result = adapter.config.events;
137
34
  if (result) {
138
35
  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)
36
+ /* Bewässerungskreis in der Config "enabled" aktiviert */
37
+ if (res.enabled) {
38
+ /* Name des Bewässerungskreises */
39
+ const objectName = (res.sprinkleName !== '') ? res.sprinkleName.replace(/[.;, ]/g, '_') : res.name.replace(/[.;, ]/g, '_');
40
+
41
+ const newEntry = {
42
+ enabled: res.enabled || false, // Schaltzustand des Ventils
43
+ booster: res.booster,
44
+ autoOn: true,
45
+ autoOnID: `${ adapter.namespace }.sprinkle.${ objectName }.autoOn`, // sprinklecontrol.0.sprinkle.Rasenumrandung.autoOnID
46
+ extBreak: false, // extern break single (unterbrechung eines Kanals)
47
+ extBreakID: `${ adapter.namespace }.sprinkle.${ objectName }.extBreak`, // sprinklecontrol.0.sprinkle.Rasenumrandung.breakID
48
+ objectName: objectName, // z.B. Rasenumrandung
49
+ objectID: `${ adapter.namespace }.sprinkle.${ objectName }.runningTime`, // sprinklecontrol.0.sprinkle.Rasenumrandung.runningTime
50
+ idState: res.name, // "hm-rpc.0.MEQ1234567.3.STATE"
51
+ triggerSM: res.triggerSM, // Sensor für die Bodenfeuchte
52
+ updateStateTimerID: null, // Timer wird gelöscht wenn Rückmeldung erfolgte
53
+ sprinkleID: myConfig.config.length, // Array[0...]
54
+ wateringTime: parseInt(res.wateringTime), // ...min
55
+ wateringAdd: parseInt(res.wateringAdd), // 0 ... 200%
56
+ wateringIntervalOff: ((60 * parseInt(res.wateringIntervalOff)) || 0), // 5,10,15min Ausschaltzeit
57
+ wateringIntervalOn: ((60 * parseInt(res.wateringIntervalOn)) || 0), // 5,10,15min Einschaltzeit
58
+ addWateringTime: (parseInt(res.addWateringTime) || 0), // ...min Zusatzbewässerung bei hohen Temperaturen
59
+ pipeFlow: parseInt(res.pipeFlow), // Wasserverbrauch des sprinkler-Kreises
60
+ methodControlSM: res.methodControlSM, // Art der Kontrolle der Bodenfeuchte ('calculation'; 'bistable'; 'analog'; fixDay)
61
+ inGreenhouse: res.inGreenhouse || false // keine Wettervorhersage verwenden (Gewächshaus)
62
+ };
63
+ switch (res.methodControlSM) {
64
+ case 'calculation': {
65
+ newEntry.calculation = {
66
+ pct: 50, // Bodenfeuchte in % zB. 50% = maxSoilMoistureIrrigation) / 2
67
+ val: parseFloat(res.maxSoilMoistureIrrigation) / 2, // Bodenfeuchte / Wassergehalt der oberen Bodenschicht (zB. 5 mm == 50%)
68
+ min: parseFloat(res.maxSoilMoistureIrrigation) / 100, // (zB. 0,02 mm)
69
+ maxIrrigation: parseFloat(res.maxSoilMoistureIrrigation), // (zB. 10 mm)
70
+ maxRain: parseFloat(res.maxSoilMoistureIrrigation) /100 * (parseFloat(res.maxSoilMoistureRainPct) || 120), // (zB. 12 mm)
71
+ triggersIrrigation: parseFloat(res.maxSoilMoistureIrrigation) * parseInt(res.triggersIrrigation) / 100, // (zB. 50 % ==> 5 mm)
72
+ pctTriggerIrrigation: parseFloat(res.triggersIrrigation), // Auslöser der Bewässerung in % (zB. 50%)
73
+ pctAddTriggersIrrigation: (parseFloat(res.addTriggersIrrigation) < parseFloat(res.triggersIrrigation)) ? parseFloat(res.addTriggersIrrigation) : parseFloat(res.triggersIrrigation),
74
+ endIrrigation: res.endIrrigation // nach der Bewässerung 100%
75
+ };
76
+ break;
77
+ }
78
+ case 'bistable': { // bistable (Bodenfeuchte-Sensor)
79
+ //newEntry.triggerSM = res.triggerSM; // Sensor für die Bodenfeuchte
80
+ adapter.subscribeForeignStates(res.triggerSM);
81
+ newEntry.bistable = {
82
+ bool: false // Bodenfeuchtezustand trocken/feucht === true/false
83
+ };
84
+ break;
85
+ }
86
+ case 'analog': {
87
+ //newEntry.triggerSM = res.triggerSM; // Sensor für die Bodenfeuchte
88
+ adapter.subscribeForeignStates(res.triggerSM);
89
+ newEntry.analog = {
90
+ pctTriggerIrrigation: parseFloat(res.triggersIrrigation), // Schaltpunkt Bodenfeuchte (30%...80%)
91
+ pctAddTriggersIrrigation: (parseFloat(res.addTriggersIrrigation) < parseFloat(res.triggersIrrigation)) ? parseFloat(res.addTriggersIrrigation) : parseFloat(res.triggersIrrigation),
92
+ pct: 0, // Bodenfeuchte vom Sensor in %
93
+ analogZPct: parseFloat(res.analogZPct), // analoger Sensor Wert bei 0% (analog zero percent)
94
+ analogOHPct: parseFloat(res.analogOHPct) // analoger Sensor Wert bei 100% (analog one hundert percent)
95
+ };
96
+ break;
97
+ }
98
+ case 'fixDay': {
99
+ const startFixDay = [false, false, false, false, false, false, false]; // Sun, Mon, Tue, Wed, Thur, Fri, Sat
100
+ if (res.startDay === 'fixDay') {
101
+ startFixDay[0] = res.sun;
102
+ startFixDay[1] = res.mon;
103
+ startFixDay[2] = res.tue;
104
+ startFixDay[3] = res.wed;
105
+ startFixDay[4] = res.thur;
106
+ startFixDay[5] = res.fri;
107
+ startFixDay[6] = res.sat;
108
+ }
109
+ newEntry.fixDay = {
110
+ startDay: res.startDay, // Auswahl (threeRd = Start im 3-Tages-Rhythmus,twoNd = Start im 2-Tages-Rhythmus, fixDay = Start an festen Tagen Sun-Sat)
111
+ startFixDay: startFixDay // Sontag, Sunday (Sun)// Montag, Monday (Mon)// Dienstag, Tuesday (Tue) (Tues)// Mittwoch, Wednesday (Wed)// Donnerstag, Thursday (Thur) (Thurs)// Freitag, Friday (Fri)// Samstag, Saturday (Sat)
112
+ };
113
+ break;
114
+ }
115
+ default: {adapter.log.error(`No watering type was selected in the "${objectName}" watering circuit.`);}
193
116
  }
194
- };
195
- myConfig.config.push(newEntry);
196
117
 
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])}`);
118
+ // @ts-ignore
119
+ myConfig.config.push(newEntry);
204
120
 
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})`);
121
+ if (newEntry.enabled) {
122
+ // Report a change in the status of the trigger IDs (.runningTime; .name) => Melden einer Änderung des Status der Trigger-IDs
123
+ adapter.subscribeStates(newEntry.objectID); // abonnieren der Statusänderungen des Objekts (reagieren auf 'runningTime' der einzelnen Bewässerungskreise)
124
+ adapter.subscribeStates(newEntry.autoOnID); // abonnieren der Statusänderungen des Objekts (reagieren auf 'autoOn' der einzelnen Bewässerungskreise)
125
+ adapter.subscribeStates(newEntry.extBreakID); // abonnieren der Statusänderungen des Objekts (reagieren auf 'autoOn' der einzelnen Bewässerungskreise)
126
+ adapter.subscribeForeignStates(newEntry.idState); // abonnieren der Statusänderungen des Objekts (reagiert auf Änderung des 'Ventils' der einzelnen Bewässerungskreise zur Fehlerkontrolle bzw. Verbrauchsermittlung)
127
+ }
128
+ adapter.log.debug(`Config ${objectName} created (${newEntry.sprinkleID}) - ${JSON.stringify(myConfig.config[newEntry.sprinkleID])}`);
212
129
  }
213
130
  }
131
+
214
132
  }
215
133
  },
216
134
  /**
217
135
  * apply Evaporation
218
136
  * → Verdunstung anwenden auf die einzelnen Sprenger kreise
219
- *
220
- * @param eTP - pot. Evapotranspiration nach Penman ETp in mm/d
137
+ *
138
+ * @param {number} eTP - pot. Evapotranspiration nach Penman ETp in mm/d
221
139
  */
222
- applyEvaporation: (eTP) => {
140
+ applyEvaporation: async (eTP) => {
223
141
  if (myConfig.config) {
224
142
  for(const entry of myConfig.config) {
225
143
  if (entry.methodControlSM === 'calculation'
226
144
  && !(entry.inGreenhouse && (eTP < 0))) { // nicht anwenden im Gewächshaus und Regen
227
145
  const objectName = entry.objectName;
228
- const pfadActSoiMoi = `sprinkle.${ objectName }.actualSoilMoisture`;
146
+ const pfadActSoiMoi = `sprinkle.${ objectName }.actualSoilMoisture`;
229
147
 
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;
148
+ entry.calculation.val -= eTP; // Abfrage => entry.calculation.val
149
+ if (entry.calculation.val < entry.calculation.min) {
150
+ entry.calculation.val = entry.calculation.min;
151
+ } else if (entry.calculation.val > entry.calculation.maxRain) {
152
+ entry.calculation.val = entry.calculation.maxRain;
235
153
  }
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} %`);
154
+ entry.calculation.pct = Math.round(1000 * entry.calculation.val / entry.calculation.maxIrrigation) / 10; // Berechnung in %
155
+ adapter.log.debug(`apply Evaporation: ${objectName} => soilMoisture: ${entry.calculation.val} soilMoisture: ${entry.calculation.pct} %`);
238
156
  adapter.setState(pfadActSoiMoi, {
239
- val: entry.soilMoisture.pct,
157
+ val: entry.calculation.pct,
240
158
  ack: true
241
159
  });
242
160
  }
@@ -245,29 +163,29 @@ const myConfig = {
245
163
  },
246
164
  /**
247
165
  * Bodenfeuchte (soilMoisture) setzen auf: => pct = 100%; val = maxIrrigation
248
- *
249
- * @param mySprinkleID - ID des Bewässerungskreises
166
+ *
167
+ * @param {number} mySprinkleID - ID des Bewässerungskreises
250
168
  */
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,
169
+ setSoilMoistPct100: async (mySprinkleID) => {
170
+ myConfig.config[mySprinkleID].calculation.val = myConfig.config[mySprinkleID].calculation.maxIrrigation;
171
+ myConfig.config[mySprinkleID].calculation.pct = 100;
172
+ adapter.setState(`sprinkle.${ myConfig.config[mySprinkleID].objectName }.actualSoilMoisture`, {
173
+ val: myConfig.config[mySprinkleID].calculation.pct,
256
174
  ack: true
257
175
  });
258
176
  },
259
177
  /**
260
178
  * Speichern der Bodenfeuchtigkeit = bistabil (Bodenfeuchte-Sensor)
261
- *
262
- * @param mySprinkleID - ID des Bewässerungskreis
263
- * @param newVal - neuer Wert vom Bodenfeuchte-Sensor
179
+ *
180
+ * @param {number} mySprinkleID - ID des Bewässerungskreis
181
+ * @param {boolean} newVal - neuer Wert vom Bodenfeuchte-Sensor
264
182
  */
265
- setSoilMoistBool: (mySprinkleID, newVal) => {
183
+ setSoilMoistBool: async (mySprinkleID, newVal) => {
266
184
  if (myConfig.config[mySprinkleID].methodControlSM === 'bistable') {
267
185
  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,
186
+ myConfig.config[mySprinkleID].bistable.bool = newVal;
187
+ adapter.setState(`sprinkle.${ [myConfig.config[mySprinkleID].objectName] }.actualSoilMoisture`, {
188
+ val: myConfig.config[mySprinkleID].bistable.bool,
271
189
  ack: true
272
190
  });
273
191
  } else {
@@ -279,13 +197,16 @@ const myConfig = {
279
197
  },
280
198
  /**
281
199
  * Speichern der Bodenfeuchtigkeit = analog (Bodenfeuchte-Sensor)
282
- *
283
- * @param mySprinkleID - ID des Bewässerungskreis
284
- * @param newVal - neuer Wert vom Bodenfeuchte-Sensor
200
+ *
201
+ * @param {number} mySprinkleID - ID des Bewässerungskreis
202
+ * @param {string|number} newVal - neuer Wert vom Bodenfeuchte-Sensor
285
203
  */
286
- setSoilMoistPct: (mySprinkleID, newVal) => {
204
+ setSoilMoistPct: async (mySprinkleID, newVal) => {
205
+ if (typeof newVal === 'string') {
206
+ newVal = parseFloat(newVal);
207
+ }
287
208
  if (myConfig.config[mySprinkleID].methodControlSM === 'analog') {
288
- if (typeof parseFloat(newVal) === 'number') {
209
+ if (typeof newVal === 'number') {
289
210
  /**aktueller Wert des Bodenfeuchte-Sensor
290
211
  * @type {number} myVal
291
212
  */
@@ -294,27 +215,26 @@ const myConfig = {
294
215
  * @type {boolean} reverse -Eingang analogOHPct < analogZPct
295
216
  *
296
217
  */
297
- const reverse = (myConfig.config[mySprinkleID].analogOHPct < myConfig.config[mySprinkleID].analogZPct);
298
- if (myConfig.config[mySprinkleID].analogOHPct === myConfig.config[mySprinkleID].analogZPct) {
218
+ const reverse = (myConfig.config[mySprinkleID].analog.analogOHPct < myConfig.config[mySprinkleID].analog.analogZPct);
219
+ if (myConfig.config[mySprinkleID].analog.analogOHPct === myConfig.config[mySprinkleID].analog.analogZPct) {
299
220
  adapter.log.warn(`${myConfig.config[mySprinkleID].objectName}: analog soil moisture sensor at 0% and at 100% => the values are the same`);
300
221
  }
301
- newVal = parseFloat(newVal);
302
222
 
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'}`);
223
+ if ((!reverse && newVal < myConfig.config[mySprinkleID].analog.analogZPct)
224
+ || (reverse && myConfig.config[mySprinkleID].analog.analogZPct < newVal)) {
225
+ myVal = myConfig.config[mySprinkleID].analog.analogZPct;
226
+ 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'}`);
227
+ } else if ((!reverse && newVal > myConfig.config[mySprinkleID].analog.analogOHPct)
228
+ || (reverse && myConfig.config[mySprinkleID].analog.analogOHPct > newVal)) {
229
+ myVal = myConfig.config[mySprinkleID].analog.analogOHPct;
230
+ 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
231
  } else {
312
232
  myVal = newVal;
313
233
  }
314
234
 
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,
235
+ myConfig.config[mySprinkleID].analog.pct = Math.round(10 * trend(myConfig.config[mySprinkleID].analog.analogZPct, myConfig.config[mySprinkleID].analog.analogOHPct, 0, 100, myVal)) / 10;
236
+ adapter.setState(`sprinkle.${ [myConfig.config[mySprinkleID].objectName] }.actualSoilMoisture`, {
237
+ val: myConfig.config[mySprinkleID].analog.pct,
318
238
  ack: true
319
239
  });
320
240
  } else {
@@ -326,46 +246,50 @@ const myConfig = {
326
246
  },
327
247
  /**
328
248
  * 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
249
+ *
250
+ * @param {number} mySprinkleID - ID des Bewässerungskreis
251
+ * @param {number} addVal - soilMoisture.val wird um den Wert addVal erhöht
332
252
  */
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;
253
+ addSoilMoistVal: async (mySprinkleID, addVal) => {
254
+ if (myConfig.config[mySprinkleID].calculation.val < myConfig.config[mySprinkleID].calculation.maxIrrigation) {
255
+ myConfig.config[mySprinkleID].calculation.val += addVal;
256
+ if (myConfig.config[mySprinkleID].calculation.val > myConfig.config[mySprinkleID].calculation.maxIrrigation) {
257
+ myConfig.config[mySprinkleID].calculation.val = myConfig.config[mySprinkleID].calculation.maxIrrigation;
338
258
  }
339
259
  }
340
260
 
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,
261
+ myConfig.config[mySprinkleID].calculation.pct = Math.round(1000 * myConfig.config[mySprinkleID].calculation.val
262
+ / myConfig.config[mySprinkleID].calculation.maxIrrigation) / 10; // Berechnung in %
263
+ adapter.setState(`sprinkle.${ myConfig.config[mySprinkleID].objectName }.actualSoilMoisture`, {
264
+ val: myConfig.config[mySprinkleID].calculation.pct,
345
265
  ack: true
346
266
  });
347
267
  },
348
268
  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(`${id}`, {
365
- val: nextDay,
366
- ack: true
367
- }).catch((e) => adapter.log.warn(`postponeByOneDay setStateAsync: ${e}`));
368
- }
269
+ if (myConfig.config[mySprinkleID].fixDay.startDay === 'threeRd' || // Next Start in 3 Tagen
270
+ myConfig.config[mySprinkleID].fixDay.startDay === 'twoNd') { // Next Start in 2 Tagen
271
+ try {
272
+ const today = await formatTime().day;
273
+ const id = `${adapter.namespace}.sprinkle.${myConfig.config[mySprinkleID].objectName}.actualSoilMoisture`;
274
+ let curDay, nextDay;
275
+ /** Wert von actualSoilMoisture auslesen */
276
+ const _curDay = await adapter.getStateAsync(id);
277
+ if (_curDay) {
278
+ curDay = ((+_curDay.val >= 0) && (+_curDay.val <= 6) && (typeof _curDay.val === 'number') ? _curDay.val : today);
279
+ myConfig.config[mySprinkleID].fixDay.startFixDay[curDay] = false;
280
+ nextDay = (+ curDay + 1 > 6) ? (+ curDay-6) : (+ curDay + 1);
281
+ myConfig.config[mySprinkleID].fixDay.startFixDay[nextDay] = true;
282
+ adapter.setStateAsync(`${id}`, {
283
+ val: nextDay,
284
+ ack: true
285
+ });
286
+ } else {
287
+ adapter.log.warn(`postponeByOneDay: ${id} => current day: ${_curDay.val} - No value found`);
288
+ }
289
+ } catch (error) {
290
+ adapter.log.warn(`postponeByOneDay setStateAsync: ${error}`);
291
+ }
292
+
369
293
  }
370
294
  }
371
295
  };