iobroker.sprinklecontrol 0.2.19 → 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/main.js CHANGED
@@ -1,366 +1,397 @@
1
1
  'use strict';
2
2
 
3
- // Load your modules here, e.g.: => // Laden Sie Ihre Module hier, z.B.
4
- // const fs = require("fs");
3
+ /* Created with @iobroker/create-adapter v2.2.1 */
5
4
 
5
+ // The adapter-core module gives you access to the core ioBroker functions
6
+ // you need to create an adapter
6
7
  const utils = require('@iobroker/adapter-core');
7
- const schedule = require('node-schedule');
8
+ const schedule = require('node-schedule');
8
9
  const SunCalc = require('suncalc');
9
10
 
11
+ // Load your modules here, e.g.:
10
12
  const sendMessageText = require('./lib/sendMessageText.js'); // sendMessageText
11
- const valveControl = require('./lib/valveControl.js'); // Steuerung der einzelnen Ventile
13
+ const valveControl = require('./lib/valveControl.js').valveControl; // Steuerung der einzelnen Ventile
14
+ const controlVoltage = require('./lib/valveControl.js').controlVoltage; // state der Steuerspannung
15
+ const currentPumpUse = require('./lib/valveControl.js').currentPumpUse; // state der Pumpen
16
+ const threadList = require('./lib/valveControl.js').threadList; // Auflistung aller aktiver Sprenger-Kreise
12
17
  const myConfig = require('./lib/myConfig.js'); // myConfig → Speichern und abrufen von Konfigurationsdaten der Ventile
13
18
  const evaporation = require('./lib/evaporation.js');
14
19
  const addTime = require('./lib/tools.js').addTime;
15
20
  const formatTime = require('./lib/tools.js').formatTime;
16
- //const trend = require('./lib/tools').trend;
17
21
 
22
+ /**
23
+ * The adapter instance
24
+ */
18
25
  let adapter;
19
- const adapterName = require('./package.json').name.split('.').pop();
20
-
21
- let publicHolidayStr = false; // Feiertag heute?
22
- let publicHolidayTomorrowStr = false; // Feiertag morgen?
23
- let weatherForecastTodayPfadStr = ''; // Pfad zur Regenvorhersage in mm
24
- let weatherForecastTodayNum = 0; // heutige Regenvorhersage in mm
25
- let weatherForecastTomorrowNum = 0; // morgige Regenvorhersage in mm
26
- let addStartTimeSwitch = false; // Externer Schalter für Zusatzbewässerung
27
- let startTimeStr = ''; // 06:00
28
- let sunriseStr = '';
29
- let sunsetStr = '';
30
- let goldenHourEnd = '';
31
- let holidayStr = false; // switch => sprinklecontrol.*.control.Holiday | (Holiday == true) => Wochenendprogramm
32
- let autoOnOffStr = true;
33
- let kwStr = ''; // akt. KW der Woche
26
+
27
+ let publicHolidayStr; // ext. Adapter → Deutsche Feiertage
28
+ let publicHolidayTomorrowStr;
29
+ let weatherForecastTodayPfadStr; // Pfad zur Regenvorhersage in mm (Regenvorhersage - DasWetter.com)
30
+ let weatherForecastTodayNum = 0; // heutige Regenvorhersage in mm
31
+ let weatherForecastTomorrowNum = 0; // morgige Regenvorhersage in mm
32
+ let addStartTimeSwitch = false; // Externer Schalter für Zusatzbewässerung
33
+
34
+ let startTimeStr;
35
+ let sunriseStr;
36
+ let sunsetStr;
37
+ let goldenHourEnd;
38
+ let holidayStr; // switch => sprinklecontrol.*.control.Holiday (Holiday == true)=>Wochenendprogramm
39
+ let autoOnOffStr;
40
+ let kw; // akt. KW der Woche
34
41
  let timer, timerSleep;
35
- let today = 0; // heutige Tag 0:So;1:Mo...6:Sa
42
+ let today; // heutige Tag 0:So;1:Mo...6:Sa
43
+
36
44
  /* memo */
37
45
  let ObjSprinkle = {};
38
46
 
39
47
 
40
- /* +++++++++++++++++++++++++++ Starts the adapter instance ++++++++++++++++++++++++++++++++ */
41
-
48
+ /**
49
+ * Starts the adapter instance
50
+ *
51
+ * @param {Partial<utils.AdapterOptions>} [options]
52
+ */
42
53
  function startAdapter(options) {
54
+ // Create the adapter and define its methods
55
+ return adapter = utils.adapter(Object.assign({}, options, {
56
+ name: 'sprinklecontrol',
57
+
58
+ // The ready callback is called when databases are connected and adapter received configuration.
59
+ // start here!
60
+ ready: main, // Main method defined below for readability
61
+
62
+ // is called when adapter shuts down - callback has to be called under any circumstances!
63
+ unload: (callback) => {
64
+ try {
65
+ adapter.log.info('cleaned everything up...');
66
+ clearTimeout(timer);
67
+ clearTimeout(timerSleep);
68
+ /*Startzeiten der Timer löschen*/
69
+ schedule.cancelJob('calcPosTimer');
70
+ schedule.cancelJob('sprinkleStartTime');
71
+ schedule.cancelJob('sprinkleAddStartTime');
72
+ /* alle Ventile und Aktoren deaktivieren */
73
+ valveControl.clearEntireList();
74
+ callback();
75
+ } catch (e) {
76
+ callback();
77
+ }
78
+ },
79
+
80
+ // is called if a subscribed state changes
81
+ stateChange: async (id, state) => {
82
+ adapter.log.debug(`stateChange: ${id} (${state ? state.val : 'null'}) ack: ${state ? state.ack : 'null'}`);
83
+ // The state was changed → Der Zustand wurde geändert
84
+ if(state){
85
+ // Change in outside temperature → Änderung der Außentemperatur
86
+ if (id === adapter.config.sensorOutsideTemperature) { /*Temperatur*/
87
+ if (!Number.isNaN(Number.parseFloat(state.val))) {
88
+ // @ts-ignore
89
+ evaporation.setCurTemperature(parseFloat(state.val), state.ts);
90
+ } else {
91
+ adapter.log.warn(`sensorOutsideTemperature => Wrong value: ${state.val}, Type: ${typeof state.val}`);
92
+ }
93
+ }
94
+ // LuftFeuchtigkeit
95
+ if (id === adapter.config.sensorOutsideHumidity) {
96
+ if (!Number.isNaN(Number.parseFloat(state.val))) {
97
+ evaporation.setCurHumidity(parseFloat(state.val), state.lc);
98
+ } else {
99
+ adapter.log.warn(`sensorOutsideHumidity => Wrong value: ${state.val}, Type: ${typeof state.val}`);
100
+ }
101
+ }
102
+ // Helligkeit
103
+ if (id === adapter.config.sensorBrightness) {
104
+ if (!Number.isNaN(Number.parseFloat(state.val))) {
105
+ evaporation.setCurIllumination(parseFloat(state.val), state.lc);
106
+ } else {
107
+ adapter.log.warn(`sensorBrightness => Wrong value: ${state.val}, Type: ${typeof state.val}`);
108
+ }
109
+ }
110
+ // Windgeschwindigkeit
111
+ if (id === adapter.config.sensorWindSpeed) {
112
+ if (!Number.isNaN(Number.parseFloat(state.val))) {
113
+ evaporation.setCurWindSpeed(parseFloat(state.val), state.lc);
114
+ } else {
115
+ adapter.log.warn(`sensorWindSpeed => Wrong value: ${state.val}, Type: ${typeof state.val}`);
116
+ }
117
+ }
118
+ // Regencontainer
119
+ // If the amount of rain is over 20 mm, the 'lastRainCounter' is overwritten and no calculation is carried out. =>
120
+ // * Wenn die Regenmenge mehr als 20 mm beträgt, wird der 'lastRainCounter' überschrieben und es wird keine Berechnung durchgeführt.
121
+ if (id === adapter.config.sensorRainfall) {
122
+ if (!Number.isNaN(Number.parseFloat(state.val))) {
123
+ evaporation.setCurAmountOfRain(parseFloat(state.val));
124
+ } else {
125
+ adapter.log.warn(`sensorRainfall => Wrong value: ${state.val}, Type: ${typeof state.val}`);
126
+ }
127
+ }
128
+ // Feiertagskalender
129
+ if (adapter.config.publicHolidays === true) {
130
+ if (id === `${adapter.config.publicHolInstance}.heute.boolean`) {
131
+ publicHolidayStr = state.val;
132
+ startTimeSprinkle();
133
+ }
134
+ if (id === `${adapter.config.publicHolInstance}.morgen.boolean`) {
135
+ publicHolidayTomorrowStr = state.val;
136
+ startTimeSprinkle();
137
+ }
138
+ }
139
+ // Wettervorhersage
140
+ if (adapter.config.weatherForecast === true) {
141
+ if (id === weatherForecastTodayPfadStr) {
142
+ if (typeof state.val == 'string') {
143
+ weatherForecastTodayNum = parseFloat(state.val);
144
+ } else if (typeof state.val == 'number') {
145
+ weatherForecastTodayNum = state.val;
146
+ } else {
147
+ weatherForecastTodayNum = 0;
148
+ adapter.log.info(`StateChange => Wettervorhersage state.val ( ${ state.val }; ${ typeof state.val } ) kann nicht als Number verarbeitet werden`);
149
+ }
150
+ adapter.setState('info.rainToday', {
151
+ val: weatherForecastTodayNum,
152
+ ack: true
153
+ });
154
+ }
155
+ if (id === `${adapter.config.weatherForInstance}.location_1.ForecastDaily.Day_2.Rain`) {
156
+ weatherForecastTomorrowNum = parseFloat(state.val);
157
+ adapter.setState('info.rainTomorrow', {
158
+ val: weatherForecastTomorrowNum,
159
+ ack: true
160
+ });
161
+ }
162
+ }
163
+ // Füllstand der Zisterne bei Statusänderung
164
+ if (adapter.config.actualValueLevel && (id === adapter.config.actualValueLevel)) {
165
+ valveControl.setFillLevelCistern(parseFloat(state.val) || 0);
166
+ //fillLevelCistern = state.val || 0;
167
+ }
168
+ // Rückmeldungen mit ack === False
169
+ if(state.ack === false){
170
+ // wenn (Holiday == true) ist, soll das Wochenendprogramm gefahren werden.
171
+ if (id === `${adapter.namespace}.control.Holiday`) {
172
+ holidayStr = state.val;
173
+ adapter.setState(id, {
174
+ val: state.val,
175
+ ack: true
176
+ });
177
+ startTimeSprinkle();
178
+ }
179
+ // wenn (addStartTimeSwitch == true) wird die zusätzliche Bewässerung aktiviert
180
+ if (id === `${adapter.namespace}.control.addStartTimeSwitch`) {
181
+ addStartTimeSwitch = state.val;
182
+ adapter.setState(id, {
183
+ val: state.val,
184
+ ack: true
185
+ });
186
+ }
187
+ // wenn (autoOnOff == false) so werden alle Sprenger nicht mehr automatisch gestartet.
188
+ if (id === `${adapter.namespace}.control.autoOnOff`) {
189
+ autoOnOffStr = state.val;
190
+ adapter.log.info(`startAdapter: control.autoOnOff: ${state.val}`);
191
+ adapter.setState(id, {
192
+ val: state.val,
193
+ ack: true
194
+ });
195
+ if (state.val === false) {
196
+ valveControl.clearEntireList();
197
+ }
198
+ startTimeSprinkle();
199
+ }
200
+ // wenn (autoStart == true) so die automatische Bewässerung von Hand gestartet
201
+ if (id === `${adapter.namespace}.control.autoStart`) {
202
+ adapter.setState(id, {
203
+ val: false,
204
+ ack: true
205
+ });
206
+ if (state.val === true) {
207
+ // auto Start;
208
+ startOfIrrigation();
209
+ }
210
+ }
211
+ // wenn (...sprinkleName.runningTime sich ändert) so wird der aktuelle Sprenger [sprinkleName]
212
+ // bei == 0 gestoppt, > 1 gestartet || Zeit abgeändert
213
+ if (myConfig.config && state.val !== '00:00') {
214
+ const found = myConfig.config.find((d) => d.objectID === id);
215
+ if (found) {
216
+ if (id === myConfig.config[found.sprinkleID].objectID) {
217
+ if (!isNaN(state.val)) {
218
+ valveControl.addList(
219
+ [{
220
+ auto: false, // Handbetrieb
221
+ sprinkleID: found.sprinkleID,
222
+ wateringTime: (state.val <= 0) ? state.val : Math.round(60 * state.val)
223
+ }]);
224
+ adapter.setState(id, {
225
+ val: state.val,
226
+ ack: true
227
+ });
228
+ }
229
+ }
230
+ }
231
+ }
232
+ // wenn in der config unter methodControlSM!== 'analog' oder 'bistable' eingegeben wurde, dann Bodenfeuchte-Sensor auslesen
233
+ if (myConfig.config) {
43
234
 
44
- options = options || {};
45
- Object.assign(options, { name: adapterName });
46
-
47
- adapter = new utils.Adapter(options);
48
-
49
- // start here!
50
- adapter.on('ready', () => {
51
- // init createConfig
52
- myConfig.createConfig(adapter);
53
- // Hauptpumpe zur Bewässerung setzen
54
- valveControl.initValveControl(adapter);
55
- main(adapter);
56
- });
57
-
58
- /**
59
- * +++++++++++++++++++++++++ is called when adapter shuts down +++++++++++++++++++++++++
60
- *
61
- * @param {() => void}callback
62
- */
63
- adapter.on('unload', (callback) => {
64
- /* Wird beim Stoppen nicht ausgeführt - Warum?
65
- if(adapter.config.notificationEnabled){
66
- sendMessageText.sendMessage('sprinklerControl is shutting down');
67
- adapter.log.info('sprinklerControl is shutting down');
68
- }
69
- */
70
- try {
71
- adapter.log.info('cleaned everything up...');
72
- clearTimeout(timer);
73
- clearTimeout(timerSleep);
74
- /*Startzeiten der Timer löschen*/
75
- schedule.cancelJob('calcPosTimer');
76
- schedule.cancelJob('sprinkleStartTime');
77
- schedule.cancelJob('sprinkleAddStartTime');
78
- /* alle Ventile und Aktoren deaktivieren */
79
- valveControl.clearEntireList();
80
- callback();
81
- } catch (err) {
82
- callback(err);
83
- }
84
- });
85
-
86
- /**
87
- * ++++++++++++++++++ Answers when getTelegramUser calls from index_m ++++++++++++++++++
88
- * -------------- Antwortet bei Aufrufen von getTelegramUser von index_m ---------------
89
- */
90
- adapter.on ('message', (obj) => {
91
- if (obj) {
92
- switch (obj.command) {
93
- case 'getTelegramUser':
94
- adapter.getForeignState(`${adapter.config.telegramInstance }.communicate.users`, (err, state) => {
95
- err && adapter.log.error(err);
96
- if (state && state.val) {
97
- try {
98
- adapter.log.debug(`getTelegramUser: ${state.val}`);
99
- adapter.sendTo(obj.from, obj.command, JSON.parse(state.val), obj.callback);
100
- } catch (err) {
101
- err && adapter.log.error(err);
102
- adapter.log.error('Cannot parse stored user IDs from Telegram!');
235
+ // @ts-ignore
236
+ function filterByID(obj){
237
+ return (((obj.methodControlSM === 'analog') || (obj.methodControlSM === 'bistable')) && (obj.triggerSM === id));
238
+ }
239
+ const filter = myConfig.config.filter(filterByID);
240
+ if (filter) {
241
+ for (const fil of filter) {
242
+ if (id === myConfig.config[fil.sprinkleID].triggerSM){
243
+ // analog
244
+ if (fil.methodControlSM === 'analog') {
245
+ myConfig.setSoilMoistPct(fil.sprinkleID, state.val);
246
+ } else if (fil.methodControlSM === 'bistable') { // bistable
247
+ myConfig.setSoilMoistBool(fil.sprinkleID, state.val);
248
+ }
249
+ }
103
250
  }
104
251
  }
105
- });
106
- break;
107
- }
108
- }
109
- });
252
+ }
110
253
 
111
- /**
112
- * ++++++++++++++++++ is called if a subscribed object changes ++++++++++++++++++
113
- * ---------- wird aufgerufen, wenn sich ein abonniertes Objekt ändert ----------
114
- */
115
- adapter.on('objectChange', (id, obj) => {
116
- if (obj) {
117
- adapter.log.info(`object ${id} changed: ${JSON.stringify(obj)}`);
118
- } else {
119
- // The object was deleted
120
- adapter.log.info(`object ${id} deleted`);
121
- }
122
- });
254
+ const idSplit = id.split('.', 5);
255
+ const _found = myConfig.config.find((d) => d.objectName === idSplit[3]);
256
+ if (_found) {
257
+ // wenn (...sprinkleName.autoOn == false[off]) so wird der aktuelle Sprenger [sprinkleName]
258
+ // bei false nicht automatisch gestartet
259
+ if (idSplit[4] === 'autoOn' && id === myConfig.config[_found.sprinkleID].autoOnID) {
260
+ myConfig.config[_found.sprinkleID].autoOn = state.val;
261
+ adapter.setState(id, { // Bestätigung
262
+ val: state.val,
263
+ ack: true
264
+ });
265
+ adapter.log.info(`set ${_found.objectName}.autoOn = ${state.val}, id: ${id}`);
266
+ if (state.val === false) {
267
+ valveControl.addList(
268
+ [{
269
+ auto: false,
270
+ sprinkleID: _found.sprinkleID,
271
+ wateringTime: 0
272
+ }]
273
+ );
274
+ adapter.setState(`sprinkle.${_found.objectName}.sprinklerState`, {
275
+ val: 'off',
276
+ ack: true
277
+ });
278
+ } else if (_found.methodControlSM === 'fixDay') {
279
+ await curNextFixDay(myConfig.config[_found.sprinkleID].sprinkleID, false).catch((e) => {
280
+ adapter.log.warn(`main.autoOn: (${myConfig.config[_found.sprinkleID].sprinkleID}, false) ${e}`);
281
+ });
282
+ }
283
+ }
123
284
 
124
- /**
125
- * ++++++++++++++++++ is called if a subscribed state changes ++++++++++++++++++
126
- * --------- wird aufgerufen, wenn sich ein abonnierter Status ändert ----------
127
- */
128
- adapter.on('stateChange', (id, state) => {
129
- // The state was changed → Der Zustand wurde geändert
130
- adapter.log.debug(`state ${id} changed: ${state.val} (ack = ${state.ack})`);
131
-
132
- // Signale zum bestätigen (ack = true) - signals for confirmation
133
- if (state?.ack === false) {
134
- // wenn (Holiday == true) ist, soll das Wochenendprogramm gefahren werden.
135
- if (id === `${adapter.namespace}.control.Holiday`) {
136
- // @ts-ignore
137
- holidayStr = state.val;
138
- adapter.setState(id, {
139
- val: state.val,
140
- ack: true
141
- });
142
- startTimeSprinkle();
143
- }
144
- // wenn (addStartTimeSwitch == true) wird die zusätzliche Bewässerung aktiviert
145
- if (id === `${adapter.namespace}.control.addStartTimeSwitch` && typeof state.val === 'boolean') {
146
- addStartTimeSwitch = state.val;
147
- adapter.setState(id, {
148
- val: state.val,
149
- ack: true
150
- });
151
- }
152
- // wenn (autoOnOff == false) so werden alle Sprenger nicht mehr automatisch gestartet.
153
- if ((id === `${adapter.namespace}.control.autoOnOff`)) {
154
- autoOnOffStr = state.val;
155
- adapter.log.info(`startAdapter: control.autoOnOff: ${state.val}`);
156
- adapter.setState(id, {
157
- val: state.val,
158
- ack: true
159
- });
160
- if (!state.val) {
161
- valveControl.clearEntireList();
162
- }
163
- startTimeSprinkle();
164
- }
165
- // wenn (autoStart == true) so die automatische Bewässerung von Hand gestartet
166
- if (id === `${adapter.namespace}.control.autoStart`) {
167
- adapter.setState(id, {
168
- val: false,
169
- ack: true
170
- });
171
- if (state.val === true) {
172
- // auto Start;
173
- startOfIrrigation();
174
- }
175
- }
176
- // wenn (...sprinkleName.runningTime sich ändert) so wird der aktuelle Sprenger [sprinkleName]
177
- // bei == 0 gestoppt, > 1 gestartet
178
- if (myConfig.config) {
179
- const found = myConfig.config.find(d => d.objectID === id);
180
- if (found) {
181
- if (id === myConfig.config[found.sprinkleID].objectID) {
182
- if (!isNaN(state.val)) {
183
- valveControl.addList(
184
- [{
185
- auto: false, // Handbetrieb
186
- sprinkleID: found.sprinkleID,
187
- wateringTime: (state.val <= 0) ? 0 : Math.round(60 * state.val)
188
- }]);
189
- adapter.setState(id, {
190
- val: (state.val <= 0) ? 0 : addTime(Math.round(60 * state.val)),
285
+ // extBreak → Pause für den Spränger bis 0:05
286
+ if (idSplit[4] === `extBreak`) {
287
+ _found.extBreak = state.val; // speichern unter myConfig.config.*.extBreak
288
+ const _extBreak = await valveControl.extBreak(_found.sprinkleID, state.val).catch((e) => {
289
+ adapter.log.warn(`main.extBreak: ${e}`);
290
+ });
291
+ adapter.log.info(`_extBreake: ${_extBreak}, ${JSON.stringify(_extBreak)}`);
292
+ if (_extBreak?.val === false) {
293
+ /* Zustand des Ventils im Thread < 0 > off, < 1 > wait, < 2 > on, < 3 > break, < 4 > Boost(on), < 5 > off(Boost), < 6 > Cistern empty, <<< 7 >>> extBreak */
294
+ adapter.setState(`sprinkle.${_found.objectName}.sprinklerState`, {
295
+ val: state.val ? 'extBreak' : 'off',
296
+ ack: true
297
+ });
298
+ }
299
+ adapter.setState(id, { // Bestätigung
300
+ val: state.val,
301
+ ack: true
302
+ });
303
+ }
304
+ // postponeByOneDay → um einen Tag verschieben bei fixDay (twoNd & threeRd)
305
+ if (idSplit[4] === `postponeByOneDay`) {
306
+ myConfig.postponeByOneDay(_found.sprinkleID).catch((e) => {
307
+ adapter.log.warn(`.postponeByOneDay: ${e}`);
308
+ });
309
+ adapter.setState(id, { // Bestätigung
310
+ val: false,
191
311
  ack: true
192
312
  });
193
313
  }
194
314
  }
195
- }
196
- }
197
- // wenn (...sprinkleName.autoOn == false[off]) so wird der aktuelle Sprenger [sprinkleName]
198
- // bei false nicht automatisch gestartet
199
- if (myConfig.config && (typeof state.val === 'boolean')) {
200
- const found = myConfig.config.find(d => d.autoOnID === id);
201
- if (found && id === myConfig.config[found.sprinkleID].autoOnID) {
202
- myConfig.config[found.sprinkleID].autoOn = state.val;
203
- adapter.setState(id, { // Bestätigung
204
- val: state.val,
205
- ack: true
206
- });
207
- adapter.log.info(`set ${found.objectName}.autoOn = ${state.val}, id: ${id}`);
208
- if (state.val === false) {
209
- valveControl.addList(
210
- [{
211
- auto: false,
212
- sprinkleID: found.sprinkleID,
213
- wateringTime: 0
214
- }]
215
- );
315
+ // (state.ack === true)
316
+ }else if (state.ack === true) {
317
+ // Bestätigung für das Schalten der Ventile
318
+ if (myConfig.config) {
319
+ //adapter.log.info(`vor found: ${id} (${state.val}) => ack === ${state.ack}`);
320
+ const found = myConfig.config.find((d) => d.idState === id);
321
+ //adapter.log.info(`nach found: ${id} => ${JSON.stringify(found)}`);
322
+ if (found && (id === myConfig.config[found.sprinkleID].idState)) {
323
+ found.state = state;
324
+ }
216
325
  }
217
- }
218
- }
219
- // postponeByOneDay um einen Tag verschieben bei fixDay (twoNd & threeRd)
220
- const idSplit = id.split('.', 5);
221
- if (idSplit[4] === `postponeByOneDay`) {
222
- const found = myConfig.config.find(d => d.objectName === idSplit[3]);
223
- if (found) {
224
- myConfig.postponeByOneDay(found.sprinkleID).catch((e) => {
225
- adapter.log.warn(`postponeByOneDay: ${e}`);
226
- });
227
- adapter.setState(id, {
228
- val: false,
229
- ack: true
230
- });
231
- }
232
- }
233
- }
234
- // Signale ohne Bestätigung - signals without confirmation
235
-
236
- // wenn in der config unter methodControlSM!== 'analog' oder 'bistable' eingegeben wurde, dann Bodenfeuchte-Sensor auslesen
237
- if (myConfig.config) {
238
- function filterByID(obj){
239
- return (((obj.methodControlSM === 'analog') || (obj.methodControlSM === 'bistable')) && (obj.triggerSM === id));
240
- }
241
- const filter = myConfig.config.filter(filterByID);
242
- if (filter) {
243
- for (const fil of filter) {
244
- if (id === myConfig.config[fil.sprinkleID].triggerSM){
245
- // analog
246
- if (fil.methodControlSM === 'analog') {
247
- myConfig.setSoilMoistPct(fil.sprinkleID, state.val);
248
- } else if (fil.methodControlSM === 'bistable') { // bistable
249
- myConfig.setSoilMoistBool(fil.sprinkleID, state.val);
326
+ if (threadList) {
327
+ const found = threadList.find((d) => d.idState === id);
328
+ if (found !== undefined && typeof found.controller.ackTrue === 'function') {
329
+ found.controller.ackTrue(state);
250
330
  }
251
331
  }
332
+ // 24V Steuerspannung
333
+ if (id === adapter.config.triggerControlVoltage && typeof controlVoltage.controller.ackTrue === 'function') {
334
+ controlVoltage.controller.ackTrue(state);
335
+ }
336
+ // Pumpe (aktuell verwendete Pumpe)
337
+ if (id === currentPumpUse.idState && typeof currentPumpUse.controller.ackTrue === 'function') {
338
+ currentPumpUse.controller.ackTrue(state);
339
+ }
340
+ // The state was deleted
341
+ adapter.log.debug(`state ${id} deleted`);
252
342
  }
253
343
  }
254
- }
255
- // Change in outside temperature → Änderung der Außentemperatur
256
- if (id === adapter.config.sensorOutsideTemperature) { /*Temperatur*/
257
- if (!Number.isNaN(Number.parseFloat(state.val))) {
258
- evaporation.setCurTemperature(parseFloat(state.val), state.ts);
259
- } else {
260
- adapter.log.warn(`sensorOutsideTemperature => Wrong value: ${state.val}, Type: ${typeof state.val}`);
261
- }
262
- }
263
- // LuftFeuchtigkeit
264
- if (id === adapter.config.sensorOutsideHumidity) {
265
- if (!Number.isNaN(Number.parseFloat(state.val))) {
266
- evaporation.setCurHumidity(parseFloat(state.val), state.lc);
267
- } else {
268
- adapter.log.warn(`sensorOutsideHumidity => Wrong value: ${state.val}, Type: ${typeof state.val}`);
269
- }
270
- }
271
- // Helligkeit
272
- if (id === adapter.config.sensorBrightness) {
273
- if (!Number.isNaN(Number.parseFloat(state.val))) {
274
- evaporation.setCurIllumination(parseFloat(state.val), state.lc);
275
- } else {
276
- adapter.log.warn(`sensorBrightness => Wrong value: ${state.val}, Type: ${typeof state.val}`);
277
- }
278
- }
279
- // Windgeschwindigkeit
280
- if (id === adapter.config.sensorWindSpeed) {
281
- if (!Number.isNaN(Number.parseFloat(state.val))) {
282
- evaporation.setCurWindSpeed(parseFloat(state.val), state.lc);
283
- } else {
284
- adapter.log.warn(`sensorWindSpeed => Wrong value: ${state.val}, Type: ${typeof state.val}`);
285
- }
286
- }
287
- // Regencontainer
288
- // If the amount of rain is over 20 mm, the 'lastRainCounter' is overwritten and no calculation is carried out. =>
289
- // * Wenn die Regenmenge mehr als 20 mm beträgt, wird der 'lastRainCounter' überschrieben und es wird keine Berechnung durchgeführt.
290
- if (id === adapter.config.sensorRainfall) {
291
- if (!Number.isNaN(Number.parseFloat(state.val))) {
292
- evaporation.setCurAmountOfRain(parseFloat(state.val));
293
- } else {
294
- adapter.log.warn(`sensorRainfall => Wrong value: ${state.val}, Type: ${typeof state.val}`);
295
- }
296
- }
297
- // Feiertagskalender
298
- if (adapter.config.publicHolidays === true) {
299
- if (id === `${adapter.config.publicHolInstance }.heute.boolean`) {
300
- publicHolidayStr = state.val;
301
- startTimeSprinkle();
302
- }
303
- if (id === `${adapter.config.publicHolInstance }.morgen.boolean`) {
304
- // @ts-ignore
305
- publicHolidayTomorrowStr = state.val;
306
- startTimeSprinkle();
307
- }
308
- }
309
- // Wettervorhersage
310
- if (adapter.config.weatherForecast === true) {
311
- if (id === weatherForecastTodayPfadStr) {
312
- if (typeof state.val == 'string') {
313
- weatherForecastTodayNum = parseFloat(state.val);
314
- } else if (typeof state.val == 'number') {
315
- weatherForecastTodayNum = state.val;
316
- } else {
317
- weatherForecastTodayNum = 0;
318
- adapter.log.info(`StateChange => Wettervorhersage state.val ( ${state.val}; ${typeof state.val} ) kann nicht als Number verarbeitet werden`);
344
+ },
345
+
346
+ // Wenn Sie Nachrichten in Ihrem Adapter akzeptieren müssen, entkommentieren Sie den folgenden Block.
347
+ // /**
348
+ // * Über das Nachrichtenfeld wurde eine Nachricht an diese Instanz gesendet. Wird von E-Mail, Pushover, Text2Speech usw. verwendet.
349
+ // * Für die Verwendung dieser Methode muss die Eigenschaft „common.messagebox“ in io-package.json auf true gesetzt sein
350
+ // */
351
+ message: (obj) => {
352
+ if (obj) {
353
+ switch (obj.command) {
354
+ case 'getTelegramUser':
355
+ adapter.getForeignState(`${adapter.config.telegramInstance}.communicate.users`, (err, state) => {
356
+ // @ts-ignore
357
+ err && adapter.log.error(err);
358
+ if (state && state.val) {
359
+ try {
360
+ adapter.log.debug(`getTelegramUser:${state.val}`);
361
+ // @ts-ignore
362
+ adapter.sendTo(obj.from, obj.command, JSON.parse(state.val), obj.callback);
363
+ } catch (err) {
364
+ err && adapter.log.error(err);
365
+ adapter.log.error('Cannot parse stored user IDs from Telegram!');
366
+ }
367
+ }
368
+ });
369
+ break;
319
370
  }
320
- adapter.setState('info.rainToday', {
321
- val: weatherForecastTodayNum,
322
- ack: true
323
- });
324
371
  }
325
- if (id === `${adapter.config.weatherForInstance }.NextDaysDetailed.Location_1.Day_2.rain_value`) {
326
- weatherForecastTomorrowNum = parseFloat(state.val);
327
- adapter.setState('info.rainTomorrow', {
328
- val: weatherForecastTomorrowNum,
329
- ack: true
330
- });
331
- }
332
- }
333
- // Füllstand der Zisterne bei Statusänderung
334
- if (adapter.config.actualValueLevel && (id === adapter.config.actualValueLevel)) {
335
- valveControl.setFillLevelCistern(parseFloat(state.val) || 0);
336
- //fillLevelCistern = state.val || 0;
337
372
  }
338
- });
373
+ }));
339
374
  }
340
375
 
341
376
  // +++++++++++++++++ Get longitude an latitude from system config ++++++++++++++++++++
342
- /**get longitude/latitude from system if not set or not valid
343
- * do not change if we have already a valid value
344
- * so we could use different settings compared to system if necessary
345
- * >>>
346
- * Längen- / Breitengrad vom System abrufen, falls nicht festgelegt oder ungültig
377
+ /**Längen- / Breitengrad vom System abrufen, falls nicht festgelegt oder ungültig
347
378
  * wird nicht geändert, wenn bereits ein gültiger Wert vorhanden ist,
348
379
  * daher können wir bei Bedarf andere Einstellungen als das System verwenden
349
380
  */
350
381
  async function GetSystemData() {
351
- if (typeof adapter.config.longitude === undefined || adapter.config.longitude == null || adapter.config.longitude.length === 0 || isNaN(adapter.config.longitude)
352
- || typeof adapter.config.latitude === undefined || adapter.config.latitude == null || adapter.config.latitude.length === 0 || isNaN(adapter.config.latitude)) {
382
+ if (typeof adapter.config.longitude === 'undefined' || adapter.config.longitude === null || adapter.config.longitude.length === 0 || isNaN(+adapter.config.longitude)
383
+ || typeof adapter.config.latitude === 'undefined' || adapter.config.latitude === null || adapter.config.latitude.length === 0 || isNaN(+adapter.config.latitude)) {
353
384
 
354
385
  try {
355
- const obj = await adapter.getForeignObjectAsync('system.config');
386
+ const obj = await adapter.getForeignObjectAsync('system.config', 'state');
356
387
 
357
- if (obj && obj.common && obj.common.longitude && obj.common.latitude) {
358
- adapter.config.longitude = obj.common.longitude;
359
- adapter.config.latitude = obj.common.latitude;
388
+ if (obj?.common?.longitude && obj?.common?.latitude) {
389
+ adapter.config.longitude = obj.common.longitude.toString();
390
+ adapter.config.latitude = obj.common.latitude.toString();
360
391
 
361
392
  adapter.log.debug(`longitude: ${adapter.config.longitude} | latitude: ${adapter.config.latitude}`);
362
393
  } else {
363
- adapter.log.error('system settings cannot be called up. Please check the geo data');
394
+ adapter.log.error('system settings cannot be called up. Please check configuration!');
364
395
  }
365
396
  } catch (err) {
366
397
  adapter.log.warn('system settings cannot be called up. Please check configuration!');
@@ -368,24 +399,35 @@ async function GetSystemData() {
368
399
  }
369
400
  }
370
401
 
371
-
372
402
  /**
373
403
  * Schreiben des nächsten Starts in '.actualSoilMoisture'
374
404
  * oder Rückgabe des DayName für den nächsten Start
405
+ * - sprinkleID - Number of Array[0...]
406
+ * - returnOn - true = Rückgabe des Wochentags; false = Schreiben in State /.actualSoilMoisture
407
+ * - nextStart ['Sun','Mon','Tue','Wed','Thur','Fri','Sat']
375
408
  *
376
- * @param sprinkleID - Number of Array[0...]
377
- * @param returnOn - true = Rückgabe des Wochentags; false = Schreiben in State /.actualSoilMoisture
378
- * @returns nextStart ['Sun','Mon','Tue','Wed','Thur','Fri','Sat']
409
+ * @param sprinkleID
410
+ * @param returnOn
379
411
  */
380
- function curNextFixDay (sprinkleID, returnOn) {
381
- const weekDayArray = myConfig.config[sprinkleID].startFixDay;
412
+ async function curNextFixDay (sprinkleID, returnOn) {
413
+ const weekDayArray = myConfig.config[sprinkleID].fixDay.startFixDay;
382
414
  const objPfad = `sprinkle.${myConfig.config[sprinkleID].objectName}`;
383
415
  const weekday = ['Sun','Mon','Tue','Wed','Thur','Fri','Sat'];
384
416
  let found = false;
385
- let curDay = formatTime(adapter, '', 'day');
386
- if (startTimeStr <= formatTime(adapter, '', 'hh:mm')) {
387
- curDay++
417
+ let curDay = formatTime().day;
418
+ const d = new Date();
419
+ const curTime = `${zweiStellen(d.getHours())}:${zweiStellen(d.getMinutes())}`;
420
+
421
+ function zweiStellen (s) {
422
+ while (s.toString().length < 2) {
423
+ s = `0${s}`;
424
+ }
425
+ return s;
388
426
  }
427
+ if (curTime >= startTimeStr) {
428
+ curDay++;
429
+ }
430
+
389
431
  for ( let i=0; i<7; i++ ) {
390
432
  if (curDay > 6) {
391
433
  curDay = curDay - 7;
@@ -409,66 +451,128 @@ function curNextFixDay (sprinkleID, returnOn) {
409
451
  }
410
452
  }
411
453
 
412
- //
413
454
  /**
414
- * Sets the status at start to a defined value
415
- * → Setzt den Status beim Start auf einen definierten Wert
455
+ * Neuen Start-Tag für Dreitage- und Zweitage-modus setzen
456
+ *
457
+ * @param {number} indexNr
458
+ * @param {boolean} threeRd - Dreitage-modus Ja/Nein
459
+ * true → Dreitage-modus (treeRD)
460
+ * false → Zweitage-modus (twoNd)
416
461
  */
417
- function checkStates() {
418
- /**
419
- * control.Holiday
420
- *
421
- * @param {string|null} err
422
- * @param {ioBroker.State|null|undefined} state
423
- */
424
- adapter.getState('control.Holiday', (err, state) => {
425
- if (state && (state.val == null)) {
426
- adapter.setState('control.Holiday', {
462
+ async function setNewDay (indexNr, threeRd) {
463
+ const today = formatTime().day;
464
+ const nextStartDay = ((today + 1) > 6 ? 0 : (today + 1));
465
+ const objectName = myConfig.config[indexNr].objectName;
466
+ const _actualSoilMoisture = await adapter.getStateAsync(
467
+ `sprinkle.${objectName}.actualSoilMoisture`
468
+ ).catch((e) => adapter.log.warn(`${objectName}.actualSoilMoisture fixDay setState ${e}`));
469
+ if (_actualSoilMoisture && (typeof _actualSoilMoisture.val === 'number')) {
470
+ if ((_actualSoilMoisture.val >= 0) && (_actualSoilMoisture.val <= 6)) {
471
+ if ((threeRd)
472
+ && (_actualSoilMoisture.val === (((today + 3) > 6) ? 2 : (today + 3)))
473
+ || (_actualSoilMoisture.val === (((today + 2) > 6) ? 1 : (today + 2)))
474
+ || (_actualSoilMoisture.val === (((today + 1) > 6) ? 0 : (today + 1)))
475
+ || (_actualSoilMoisture.val === today)) {
476
+ myConfig.config[indexNr].fixDay.startFixDay[_actualSoilMoisture.val] = true;
477
+ } else {
478
+ myConfig.config[indexNr].fixDay.startFixDay[nextStartDay] = true;
479
+ }
480
+ } else {
481
+ myConfig.config[indexNr].fixDay.startFixDay[nextStartDay] = true;
482
+ }
483
+ curNextFixDay(myConfig.config[indexNr].sprinkleID, false);
484
+ }
485
+ }
486
+
487
+ /**
488
+ * result Rain
489
+ * - (aktuelle Wettervorhersage - Schwellwert der Regenberücksichtigung) wenn Sensor sich im Freien befindet
490
+ * - (> 0) es regnet - Abbruch -
491
+ * - (≤ 0) Start der Bewässerung
492
+ *
493
+ * @param {boolean} inGreenhouse - Sensor befindet sich im Gewächshaus
494
+ * @returns {number} - resultierende Regenmenge
495
+ */
496
+ function resRain (inGreenhouse) {
497
+ return +((adapter.config.weatherForecast && !inGreenhouse) ? (((+ weatherForecastTodayNum) - parseFloat(adapter.config.thresholdRain)).toFixed(1)) : 0);
498
+ }
499
+
500
+ /**
501
+ * Sets the status (of “instanceObjects” from io-package.json) to a defined value at startup
502
+ * → Setzt den Status (von "instanceObjects" aus io-package.json) beim Start auf einen definierten Wert
503
+ */
504
+ async function checkStates() {
505
+ try {
506
+ /**
507
+ * return the saved objects under sprinkle.*
508
+ * rückgabe der gespeicherten Objekte unter sprinkle.*
509
+ */
510
+ const _list = await adapter.getForeignObjectsAsync(`${adapter.namespace}.sprinkle.*`, 'channel');
511
+ if (_list) {
512
+ ObjSprinkle = _list;
513
+ }
514
+
515
+ /* control.Holiday */
516
+ const _holiday = await adapter.getStateAsync('control.Holiday');
517
+ if (!(_holiday?.val)) {
518
+ adapter.setStateAsync('control.Holiday', {
427
519
  val: false,
428
520
  ack: true
429
521
  });
430
522
  }
431
- });
432
- /**
433
- * control.autoOnOff
434
- *
435
- * @param {string|null} err
436
- * @param {ioBroker.State|null|undefined} state
437
- */
438
- adapter.getState('control.autoOnOff', (err, state) => {
439
- if (state && (typeof state.val === 'boolean')) {
440
- autoOnOffStr = state.val;
523
+
524
+ /* control.autoOnOff */
525
+ const _autoOnOff = await adapter.getStateAsync('control.autoOnOff');
526
+ if (_autoOnOff?.val && typeof _autoOnOff.val === 'boolean') {
527
+ autoOnOffStr = _autoOnOff.val;
441
528
  } else {
442
529
  autoOnOffStr = true;
443
- adapter.setState('control.autoOnOff', {
530
+ adapter.setStateAsync('control.autoOnOff', {
444
531
  val: autoOnOffStr,
445
532
  ack: true
446
533
  });
447
534
  }
448
- });
449
- adapter.getState('evaporation.ETpToday', (err, state) => {
450
- if (state && (state.val == null)) {
535
+
536
+ /* evaporation.ETpToday */
537
+ const _ETpToday = await adapter.getStateAsync('evaporation.ETpToday');
538
+ if (_ETpToday?.val) {
539
+ evaporation.setETpTodayNum(+_ETpToday.val);
540
+ } else {
451
541
  evaporation.setETpTodayNum(0);
452
- adapter.setState('evaporation.ETpToday', {
542
+ adapter.setStateAsync('evaporation.ETpToday', {
453
543
  val: 0,
454
544
  ack: true
455
545
  });
456
- } else if (state) {
457
- evaporation.setETpTodayNum(parseFloat(state.val));
458
546
  }
459
- });
460
- adapter.getState('evaporation.ETpYesterday', (err, state) => {
461
- if (state && (state.val == null || state.val === false)) {
462
- adapter.setState('evaporation.ETpYesterday', {
547
+
548
+ /* evaporation.ETpYesterday */
549
+ const _ETpYesterday = await adapter.getStateAsync('evaporation.ETpYesterday');
550
+ if (_ETpYesterday?.val && typeof _ETpYesterday.val !== 'number') {
551
+ adapter.setStateAsync('evaporation.ETpYesterday', {
463
552
  val: 0,
464
553
  ack: true
465
554
  });
466
555
  }
467
- });
468
556
 
469
- // akt. kW ermitteln für history last week
470
- kwStr = formatTime(adapter, '','kW');
471
- today = formatTime(adapter,'', 'day');
557
+ /* evaporation.dailyHighTemp */
558
+ const _dailyHighTemp = await adapter.getStateAsync('evaporation.dailyHighTemp');
559
+ if (_dailyHighTemp?.val) {
560
+ evaporation.setCurTemperatureMax(+_dailyHighTemp.val);
561
+ } else {
562
+ evaporation.setCurTemperatureMax(0);
563
+ adapter.setStateAsync('evaporation.dailyHighTemp', {
564
+ val: 0,
565
+ ack: true
566
+ });
567
+ }
568
+
569
+ /* akt. kW ermitteln für history last week */
570
+ const _formatTime = formatTime();
571
+ kw = _formatTime.kW;
572
+ today = _formatTime.day;
573
+ } catch (e) {
574
+ adapter.log.error(`Error checkStates: ${e}`);
575
+ }
472
576
  }
473
577
 
474
578
  /**
@@ -477,56 +581,51 @@ function checkStates() {
477
581
  async function checkActualStates () {
478
582
 
479
583
  try {
480
- /**
481
- * switch Holiday
482
- *
483
- */
584
+ /* switch Holiday */
484
585
  const _holiday = await adapter.getStateAsync('control.Holiday');
485
- if (_holiday && _holiday.val && typeof _holiday.val === 'boolean') {
586
+ if (_holiday?.val && typeof _holiday.val === 'boolean') {
486
587
  holidayStr = _holiday.val;
487
588
  }
488
589
 
489
- /**
490
- * switch autoOnOff
491
- *
492
- */
590
+ /* switch autoOnOff */
493
591
  const _autoOnOff = await adapter.getStateAsync('control.autoOnOff');
494
- if (_autoOnOff && _autoOnOff.val && typeof _autoOnOff.val === 'boolean') {
592
+ if (_autoOnOff?.val && typeof _autoOnOff.val === 'boolean') {
495
593
  autoOnOffStr = _autoOnOff.val;
496
594
  }
497
595
 
498
- if (adapter.config.publicHolidays === true && (adapter.config.publicHolInstance !== 'none' || adapter.config.publicHolInstance !== '')) {
499
- /**
500
- * Feiertag Heute
501
- *
502
- */
596
+ /* wenn (addStartTimeSwitch == true) wird die zusätzliche Bewässerung aktiviert */
597
+ if (adapter.config.selectAddStartTime === 'withExternalSignal') {
598
+ await adapter.subscribeStatesAsync('control.addStartTimeSwitch');
599
+ const _addStartTimeSwitch = await adapter.getStateAsync('control.addStartTimeSwitch');
600
+ if (_addStartTimeSwitch?.val && typeof _addStartTimeSwitch.val === 'boolean') {
601
+ addStartTimeSwitch = _addStartTimeSwitch.val;
602
+ }
603
+ }
604
+
605
+ /* Feiertage */
606
+ if (adapter.config.publicHolidays === true && (adapter.config.publicHolInstance !== undefined || adapter.config.publicHolInstance !== '')) {
607
+ /* Feiertag Heute */
503
608
  const _publicHolInstanceHeute = await adapter.getForeignStateAsync(
504
- `${adapter.config.publicHolInstance }.heute.boolean`
505
- ).catch((e) => adapter.log.warn(e));
506
- if (_publicHolInstanceHeute && _publicHolInstanceHeute.val) {
609
+ `${adapter.config.publicHolInstance}.heute.boolean`
610
+ );//.catch((e) => adapter.log.warn(`publicHolInstanceHeute: ${e}`));
611
+ if (_publicHolInstanceHeute?.val) {
507
612
  publicHolidayStr = _publicHolInstanceHeute.val;
508
613
  }
509
- /**
510
- * Feiertag MORGEN
511
- *
512
- */
614
+ /* Feiertag MORGEN */
513
615
  const _publicHolInstanceMorgen = await adapter.getForeignStateAsync(
514
- `${adapter.config.publicHolInstance }.morgen.boolean`
515
- ).catch((e) => adapter.log.warn(e));
516
- if (_publicHolInstanceMorgen && _publicHolInstanceMorgen.val) {
616
+ `${adapter.config.publicHolInstance}.morgen.boolean`
617
+ );//.catch((e) => adapter.log.warn(`publicHolInstanceMorgen: ${e}`));
618
+ if (_publicHolInstanceMorgen?.val) {
517
619
  publicHolidayTomorrowStr = _publicHolInstanceMorgen.val;
518
620
  }
519
621
  }
520
622
 
521
- if (adapter.config.weatherForecast === true && (adapter.config.weatherForInstance !== 'none' || adapter.config.weatherForInstance !== '')) {
522
- /**
523
- * Niederschlagsmenge HEUTE in mm
524
- *
525
- */
623
+ if (adapter.config.weatherForecast === true && (weatherForecastTodayPfadStr !== undefined || weatherForecastTodayPfadStr !== '')) {
624
+ /* Niederschlagsmenge HEUTE in mm */
526
625
  const _weatherForInstanceToday = await adapter.getForeignStateAsync(
527
626
  weatherForecastTodayPfadStr
528
- ).catch((e) => adapter.log.warn(e));
529
- if (_weatherForInstanceToday && _weatherForInstanceToday.val) {
627
+ ).catch((e) => adapter.log.warn(`weatherForInstanceToday(Pfad:${weatherForecastTodayPfadStr}): ${e}`));
628
+ if (_weatherForInstanceToday?.val) {
530
629
  if (typeof _weatherForInstanceToday.val == 'string') {
531
630
  weatherForecastTodayNum = parseFloat(_weatherForInstanceToday.val);
532
631
  } else if (typeof _weatherForInstanceToday.val == 'number') {
@@ -540,96 +639,66 @@ async function checkActualStates () {
540
639
  ack: true
541
640
  });
542
641
  }
543
-
544
- /**
545
- * Niederschlagsmenge MORGEN in mm
546
- *
547
- */
548
- const _weatherForInstance = await adapter.getForeignStateAsync(
549
- `${adapter.config.weatherForInstance }.NextDaysDetailed.Location_1.Day_2.rain_value`
550
- ).catch((e) => adapter.log.warn(e));
551
- if (_weatherForInstance && _weatherForInstance.val) {
552
- weatherForecastTomorrowNum = _weatherForInstance.val;
553
- await adapter.setStateAsync('info.rainTomorrow', {
554
- val: weatherForecastTomorrowNum,
555
- ack: true
556
- });
642
+ if (adapter.config.weatherForInstance.length > 10) {
643
+ /* Niederschlagsmenge MORGEN in mm */
644
+ const _weatherForInstance = await adapter.getForeignStateAsync(
645
+ `${adapter.config.weatherForInstance}.location_1.ForecastDaily.Day_2.Rain`
646
+ );//.catch((e) => adapter.log.warn(`weatherForInstance: ${e}`));
647
+ if (_weatherForInstance?.val) {
648
+ weatherForecastTomorrowNum = + _weatherForInstance.val;
649
+ await adapter.setStateAsync('info.rainTomorrow', {
650
+ val: weatherForecastTomorrowNum,
651
+ ack: true
652
+ });
653
+ }
557
654
  }
558
655
  }
559
656
 
560
657
  // wenn (...sprinkleName.autoOn == false[off]) so wird der aktuelle Sprenger [sprinkleName]
561
658
  // bei false nicht automatisch gestartet
562
- /**
563
- * Abfrage von ...sprinkleName.autoOn
564
- *
565
- */
659
+ /* Abfrage von ...sprinkleName.autoOn */
566
660
  const result = myConfig.config;
567
661
  if (result) {
568
662
  for (const res of result) {
569
- /**
570
- * Abfrage ... .autoOn beim Start
571
- *
572
- */
663
+ let _sprinklerState = 'off';
664
+ const _extBreak = await adapter.getForeignStateAsync(res.extBreakID);
665
+ if (_extBreak && typeof _extBreak.val === 'boolean') {
666
+ res.extBreak = _extBreak.val;
667
+ if (_extBreak.val === true) {
668
+ adapter.log.info(`get ${res.objectName}.extBreak = ${res.extBreak}`);
669
+ }
670
+ _sprinklerState = 'extBreak';
671
+ }
573
672
  const _autoOn = await adapter.getForeignStateAsync(
574
673
  res.autoOnID
575
- );
674
+ );//.catch((e) => adapter.log.warn(`autoOn: ${e}`));
576
675
  if (_autoOn && typeof _autoOn.val === 'boolean') {
577
676
  res.autoOn = _autoOn.val;
578
677
  if (_autoOn.val === false) {
579
678
  adapter.log.info(`get ${res.objectName}.autoOn = ${res.autoOn}`);
580
679
  }
680
+ _sprinklerState = 'off';
581
681
  }
582
-
583
- // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
584
- // +++++ Zustände der States aktualisieren +++++ //
585
- // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
586
-
587
- // .countdown beim Start auf '0' setzen
588
- adapter.setStateAsync(`sprinkle.${res.objectName}.countdown`,{
589
- val:'0',
590
- ack:true
591
- });
592
-
593
- // .runningTime beim Start auf '00:00' setzen
594
- adapter.setStateAsync(`sprinkle.${res.objectName}.runningTime`,{
595
- val:'00:00',
596
- ack:true
597
- });
598
-
599
- // .countdown beim Start auf '0' für (off) setzen
600
- adapter.setStateAsync(`sprinkle.${res.objectName}.sprinklerState`,{
601
- val:0,
602
- ack:true
682
+ await adapter.setStateAsync(`sprinkle.${res.objectName}.sprinklerState`, {
683
+ val: _sprinklerState,
684
+ ack: true
603
685
  });
604
686
  }
605
687
  }
606
688
 
689
+ /* Füllstand der Zisterne in % holen */
607
690
  if (adapter.config.actualValueLevel){
608
- /**
609
- * Füllstand der Zisterne in % holen
610
- *
611
- */
612
691
  const _actualValueLevel = await adapter.getForeignStateAsync(
613
692
  adapter.config.actualValueLevel
614
- ).catch((e) => adapter.log.warn(e));
615
- if (_actualValueLevel && typeof parseFloat(_actualValueLevel.val) === 'number') {
616
- valveControl.setFillLevelCistern(parseFloat(_actualValueLevel.val));
693
+ );//.catch((e) => adapter.log.warn(`actualValueLevel: ${e}`));
694
+ if (_actualValueLevel?.val) {
695
+ valveControl.setFillLevelCistern(_actualValueLevel.val);
617
696
  }
618
697
  }
619
- /**
620
- * return the saved objects under sprinkle.*
621
- * rückgabe der gespeicherten Objekte unter sprinkle.*
622
- *
623
- */
624
- const _list = await adapter.getForeignObjectsAsync(`${adapter.namespace }.sprinkle.*`, 'channel').catch((e) => adapter.log.warn(e));
625
- if (_list) {
626
- ObjSprinkle = _list;
627
- }
628
698
 
629
699
  } catch (e) {
630
700
  adapter.log.warn(`sprinkleControl cannot check actual States ... Please check your sprinkleControl states: ${e}`);
631
701
  }
632
-
633
702
  }
634
703
 
635
704
 
@@ -638,51 +707,45 @@ async function checkActualStates () {
638
707
  * => um 0:05 start von StartTimeSprinkle
639
708
  * (..., '(s )m h d m wd')
640
709
  */
710
+ // @ts-ignore
711
+
641
712
  const calcPos = schedule.scheduleJob('calcPosTimer', '5 0 * * *', function() {
642
713
  // Berechnungen mittels SunCalc
643
714
  sunPos();
644
- today = formatTime(adapter,'', 'day');
715
+ const _curTime = formatTime();
716
+ today = _curTime.day;
645
717
 
646
718
  // History Daten aktualisieren, wenn eine neue Woche beginnt
647
- adapter.log.debug(`calcPos 0:05 old-KW: ${kwStr} new-KW: ${formatTime(adapter, '','kW')} if: ${(kwStr !== formatTime(adapter, '','kW'))}`);
648
- if (kwStr !== formatTime(adapter, '','kW')) {
719
+ adapter.log.debug(`calcPos 0:05 old-KW: ${kw} new-KW: ${_curTime.kW} if: ${(kw !== _curTime.kW)}`);
720
+ if (kw !== _curTime.kW) {
649
721
  const result = myConfig.config;
650
722
  if (result) {
651
723
  for(const i in result) {
652
- if (Object.hasOwn(result, i)) {
724
+ // eslint-disable-next-line no-prototype-builtins
725
+ if (result.hasOwnProperty(i)) {
653
726
  const objectName = result[i].objectName;
654
- adapter.getState(`sprinkle.${objectName}.history.curCalWeekConsumed`, (err, state) => {
727
+ // @ts-ignore
728
+ adapter.getState(`sprinkle.${ objectName }.history.curCalWeekConsumed`, (err, state) => {
655
729
  if (state) {
656
- adapter.setState(`sprinkle.${objectName}.history.lastCalWeekConsumed`, {
657
- val: state.val,
658
- ack: true
659
- });
660
- adapter.setState(`sprinkle.${objectName}.history.curCalWeekConsumed`, {
661
- val: 0,
662
- ack: true
663
- });
730
+ adapter.setState(`sprinkle.${ objectName }.history.lastCalWeekConsumed`, { val: state.val, ack: true });
731
+ adapter.setState(`sprinkle.${ objectName }.history.curCalWeekConsumed`, { val: 0, ack: true });
664
732
  }
665
733
  });
666
- adapter.getState(`sprinkle.${objectName}.history.curCalWeekRunningTime`, (err, state) => {
734
+ // @ts-ignore
735
+ adapter.getState(`sprinkle.${ objectName }.history.curCalWeekRunningTime`, (err, state) => {
667
736
  if (state) {
668
- adapter.setState(`sprinkle.${objectName}.history.lastCalWeekRunningTime`, {
669
- val: state.val,
670
- ack: true
671
- });
672
- adapter.setState(`sprinkle.${objectName}.history.curCalWeekRunningTime`, {
673
- val: '00:00',
674
- ack: true
675
- });
737
+ adapter.setState(`sprinkle.${ objectName }.history.lastCalWeekRunningTime`, { val: state.val, ack: true });
738
+ adapter.setState(`sprinkle.${ objectName }.history.curCalWeekRunningTime`, { val: '00:00', ack: true });
676
739
  }
677
740
  });
678
741
  }
679
742
 
680
743
  }
681
744
  }
682
- kwStr = formatTime(adapter, '','kW');
745
+ kw = _curTime.kW;
683
746
  }
684
747
 
685
- // ETpToday und ETpYesterday in evaporation aktualisieren da ein neuer Tag
748
+ // ETpToday, ETpYesterday, curTemperatureMax in evaporation aktualisieren da ein neuer Tag
686
749
  evaporation.setNewDay();
687
750
 
688
751
  // Startzeit Festlegen → verzögert wegen Daten von SunCalc
@@ -695,56 +758,66 @@ const calcPos = schedule.scheduleJob('calcPosTimer', '5 0 * * *', function() {
695
758
 
696
759
  // Berechnung mittels sunCalc
697
760
  function sunPos() {
698
- // get today's sunlight times → Holen Sie sich die heutige Sonnenlichtzeit
699
- const times = SunCalc.getTimes(new Date(), adapter.config.latitude, adapter.config.longitude);
761
+ let times;
700
762
 
701
- // format sunrise time from the Date object → Formatieren Sie die Sonnenaufgangszeit aus dem Date-Objekt
702
- sunriseStr = `${(`0${times.sunrise.getHours()}`).slice(-2)}:${(`0${times.sunrise.getMinutes()}`).slice(-2)}`;
763
+ try{
764
+ // get today's sunlight times → Holen Sie sich die heutige Sonnenlichtzeit
765
+ times = SunCalc.getTimes(new Date(), +adapter.config.latitude, +adapter.config.longitude);
766
+ adapter.log.debug('calculate astrodata ...');
767
+ } catch (e) {
768
+ adapter.log.error('cannot calculate astrodata ... please check your config for latitude und longitude!!');
769
+ }
703
770
 
704
- // format golden hour end time from the Date object → Formatiere golden hour end time aus dem Date-Objekt
705
- goldenHourEnd = `${(`0${times.goldenHourEnd.getHours()}`).slice(-2)}:${(`0${times.goldenHourEnd.getMinutes()}`).slice(-2)}`;
771
+ if (times) {
772
+ // format sunrise time from the Date object → Formatieren Sie die Sonnenaufgangszeit aus dem Date-Objekt
773
+ sunriseStr = `${ (`0${ times.sunrise.getHours() }`).slice(-2) }:${ (`0${ times.sunrise.getMinutes() }`).slice(-2) }`;
706
774
 
707
- // format sunset time from the Date object → formatieren Sie die Sonnenuntergangszeit aus dem Date-Objekt
708
- sunsetStr = sunsetStr = `${(`0${times.sunset.getHours()}`).slice(-2)}:${(`0${times.sunset.getMinutes()}`).slice(-2)}`;
775
+ // format golden hour end time from the Date object → Formatiere golden hour end time aus dem Date-Objekt
776
+ goldenHourEnd = `${(`0${ times.goldenHourEnd.getHours()}`).slice(-2) }:${ (`0${ times.goldenHourEnd.getMinutes()}`).slice(-2)}`;
709
777
 
778
+ // format sunset time from the Date object → formatieren Sie die Sonnenuntergangszeit aus dem Date-Objekt
779
+ sunsetStr = sunsetStr = `${(`0${ times.sunset.getHours()}`).slice(-2) }:${ (`0${ times.sunset.getMinutes()}`).slice(-2)}`;
780
+ }
710
781
  }
711
782
 
712
783
  function addStartTimeSprinkle() {
713
784
  schedule.cancelJob('sprinkleAddStartTime');
714
- if (adapter.config.selectAddStartTime === 'greaterETpCurrent' || adapter.config.selectAddStartTime === 'withExternalSignal') {
785
+ if (adapter.config.selectAddStartTime === 'greaterETpCurrent'
786
+ || adapter.config.selectAddStartTime === 'greaterDailyMaxTemp'
787
+ || adapter.config.selectAddStartTime === 'withExternalSignal'
788
+ ) {
715
789
  const addStartTimeSplit = adapter.config.addWateringStartTime.split(':');
716
- const scheduleAddStartTime = schedule.scheduleJob('sprinkleAddStartTime', `${addStartTimeSplit[1]} ${addStartTimeSplit[0]} * * *`, function() {
790
+ // @ts-ignore
791
+
792
+ const scheduleAddStartTime = schedule.scheduleJob('sprinkleAddStartTime', `${ addStartTimeSplit[1] } ${ addStartTimeSplit[0] } * * *`, function() {
717
793
  // if (autoOnOff == false) => keine auto Start
718
794
  if (!autoOnOffStr) {
795
+ sendMessageText.sendMessage('Irrigation not possible!\n (autoOnOff == false)');
719
796
  schedule.cancelJob('sprinkleAddStartTime');
720
797
  return;
721
798
  }
799
+ // Zisterne leer → Abbruch
800
+ if(valveControl.getIntBreakCisternPump()) {
801
+ adapter.log.warn('Additional irrigation is not possible! The cistern is empty.');
802
+ sendMessageText.sendMessage('Additional irrigation is not possible!\n The cistern is empty.');
803
+ schedule.cancelJob('sprinkleAddStartTime');
804
+ return;
805
+ }
806
+ // @ts-ignore
722
807
  if (((adapter.config.selectAddStartTime === 'greaterETpCurrent') && (adapter.config.triggerAddStartTimeETpCur < evaporation.getETpTodayNum()))
723
- || (adapter.config.selectAddStartTime === 'withExternalSignal' && addStartTimeSwitch)) {
808
+ || ((adapter.config.selectAddStartTime === 'greaterDailyMaxTemp') && (adapter.config.triggerAddStartTimeTempMax < evaporation.getCurTemperatureMax()))
809
+ || ((adapter.config.selectAddStartTime === 'withExternalSignal') && addStartTimeSwitch)
810
+ ) {
724
811
  let messageText = '';
725
812
 
726
813
  // Filter enabled
727
- const result = myConfig.config.filter(d => d.enabled === true);
814
+ const result = myConfig.config.filter((d) => d.enabled === true);
728
815
  if (result) {
729
816
  /**
730
817
  * Array zum flüchtigen Sammeln von Bewässerungsaufgaben
731
- *
732
818
  */
733
819
  const memAddList = [];
734
820
 
735
- /**
736
- * result Rain
737
- * - (aktuelle Wettervorhersage - Schwellwert der Regenberücksichtigung) wenn Sensor sich im Freien befindet
738
- * - (> 0) es regnet - Abbruch -
739
- * - (≤ 0) Start der Bewässerung
740
- *
741
- * @param inGreenhouse - Sensor befindet sich im Gewächshaus
742
- * @returns - resultierende Regenmenge
743
- */
744
- function resRain (inGreenhouse) {
745
- return (adapter.config.weatherForecast && !inGreenhouse) ? (((+ weatherForecastTodayNum) - parseFloat(adapter.config.thresholdRain)).toFixed(1)) : 0;
746
- }
747
-
748
821
  for(const res of result) {
749
822
  if (res.autoOn // Ventil aktiv
750
823
  && (res.addWateringTime > 0) // zusätzliche Bewässerung aktiv time > 0
@@ -752,60 +825,52 @@ function addStartTimeSprinkle() {
752
825
 
753
826
  switch (res.methodControlSM) {
754
827
  case 'bistable': {
755
- if (res.soilMoisture.bool) {
756
- messageText += `<b>${res.objectName}</b> (${res.soilMoisture.bool})\n`
757
- + ` START => ${addTime(Math.round(60 * res.addWateringTime), '')}\n`;
828
+ if (res.bistable.bool) {
829
+ messageText += `<b>${res.objectName}</b> (${res.bistable.bool})\n`
830
+ + ` ${res.extBreak ? 'extBreak ||' : 'START =>'} ${addTime(Math.round(60 * res.addWateringTime), '')}\n`;
758
831
  memAddList.push({
759
- auto: true,
832
+ auto: false,
760
833
  sprinkleID: res.sprinkleID,
761
834
  wateringTime: Math.round(60 * res.addWateringTime)
762
835
  });
763
836
  }
764
837
  break;
765
838
  }
766
-
767
839
  case 'fixDay': {
768
840
  messageText += `<b>${res.objectName}</b>\n`
769
- + ` START => ${addTime(Math.round(60 * res.addWateringTime), '')}\n`;
841
+ + ` ${res.extBreak ? 'extBreak ||' : 'START =>'} ${addTime(Math.round(60 * res.addWateringTime), '')}\n`;
770
842
  memAddList.push({
771
- auto: true,
843
+ auto: false,
772
844
  sprinkleID: res.sprinkleID,
773
845
  wateringTime: Math.round(60 * res.addWateringTime)
774
846
  });
775
847
  break;
776
848
  }
777
-
778
849
  case 'calculation': {
779
- const addCountdown = res.wateringTime * (res.soilMoisture.maxIrrigation - res.soilMoisture.val) / (res.soilMoisture.maxIrrigation - res.soilMoisture.triggersIrrigation) - res.wateringTime;
780
- adapter.log.debug(`addCountdown: ${addCountdown}, addWateringTime: ${res.addWateringTime}, if(${(addCountdown - res.addWateringTime) > 0})`);
781
- if ((addCountdown - res.addWateringTime) > 0) {
782
- messageText += `<b>${res.objectName}</b> ${res.soilMoisture.pct}% (${res.soilMoisture.pctTriggerIrrigation}%)\n`
783
- + ` START => ${addTime(Math.round(60 * addCountdown), '')}\n`;
784
- memAddList.push({
785
- auto: true,
786
- sprinkleID: res.sprinkleID,
787
- wateringTime: Math.round(60 * addCountdown)
788
- });
789
- }
850
+ messageText += `<b>${res.objectName}</b> ${res.calculation.pct}% (${res.calculation.pctTriggerIrrigation}%)\n`
851
+ + ` ${res.extBreak ? 'extBreak ||' : 'START =>'} ${addTime(Math.round(60 * res.addWateringTime), '')}\n`;
852
+ memAddList.push({
853
+ auto: false,
854
+ sprinkleID: res.sprinkleID,
855
+ wateringTime: Math.round(60 * res.addWateringTime)
856
+ });
790
857
  break;
791
858
  }
792
-
793
859
  case 'analog': {
794
- if (res.soilMoisture.pct < res.soilMoisture.pctAddTriggersIrrigation) {
795
- messageText += `<b>${res.objectName}</b> ${res.soilMoisture.pct} %(${res.soilMoisture.pctAddTriggersIrrigation}%)\n`
796
- + ` START => ${addTime(Math.round(60 * res.addWateringTime), '')}\n`;
860
+ if (res.analog.pct < res.analog.pctAddTriggersIrrigation) {
861
+ messageText += `<b>${res.objectName}</b> ${res.analog.pct} %(${res.analog.pctAddTriggersIrrigation}%)\n`
862
+ + ` ${res.extBreak ? 'extBreak ||' : 'START =>'} ${addTime(Math.round(60 * res.addWateringTime), '')}\n`;
797
863
  memAddList.push({
798
- auto: true,
864
+ auto: false,
799
865
  sprinkleID: res.sprinkleID,
800
866
  wateringTime: Math.round(60 * res.addWateringTime)
801
867
  });
802
868
  }
803
869
  break;
804
870
  }
805
-
806
871
  }
807
872
  } else {
808
- adapter.log.debug(`${res.objectName}: autoOn (${res.autoOn}) && addWateringTime (${res.addWateringTime} > 0) && resRain (${resRain(res.inGreenhouse)}) <= 0, if(${res.autoOn && (res.addWateringTime > 0) && (resRain(res.inGreenhouse) <= 0)})`);
873
+ adapter.log.debug(`${res.objectName}: autoOn (${res.autoOn}) && addWateringTime (${60 * res.addWateringTime} > 0) && resRain (${resRain(res.inGreenhouse)}) <= 0, if(${res.autoOn && (60 * res.addWateringTime > 0) && (resRain(res.inGreenhouse) <= 0)})`);
809
874
  }
810
875
  }
811
876
  valveControl.addList(memAddList);
@@ -814,6 +879,7 @@ function addStartTimeSprinkle() {
814
879
  sendMessageText.sendMessage(messageText);
815
880
  }
816
881
  } else {
882
+ // @ts-ignore
817
883
  adapter.log.debug(`greaterETpCurrent: ${(adapter.config.selectAddStartTime === 'greaterETpCurrent')} & ${(adapter.config.triggerAddStartTimeETpCur < evaporation.getETpTodayNum())}, withExternalSignal; ${(adapter.config.selectAddStartTime === 'withExternalSignal')} & ${addStartTimeSwitch}`);
818
884
  }
819
885
  setTimeout(()=>{
@@ -827,13 +893,12 @@ function addStartTimeSprinkle() {
827
893
  function startTimeSprinkle() {
828
894
  let startTimeSplit = [];
829
895
  let infoMessage;
830
- let messageText = '';
831
896
 
832
897
  schedule.cancelJob('sprinkleStartTime');
833
898
 
834
899
  // if (autoOnOff == false) => keine auto Start
835
900
  if (!autoOnOffStr) {
836
- adapter.log.info(`Sprinkle: autoOnOff == Aus ( ${autoOnOffStr} )`);
901
+ adapter.log.info(`Sprinkle: autoOnOff === Aus ( ${autoOnOffStr} )`);
837
902
  adapter.setState('info.nextAutoStart', {
838
903
  val: 'autoOnOff = off(0)',
839
904
  ack: true
@@ -845,10 +910,10 @@ function startTimeSprinkle() {
845
910
  * next start time (automatic)
846
911
  * → Berechnung des nächsten Starts (Automatik)
847
912
  *
848
- * @returns
913
+ * @returns {string}
849
914
  */
850
915
  function nextStartTime () {
851
- let newStartTime;
916
+ let newStartTime = adapter.config.weekLiving;
852
917
  let run = 0;
853
918
  const curTime = new Date();
854
919
  const myHours = checkTime(curTime.getHours());
@@ -860,11 +925,11 @@ function startTimeSprinkle() {
860
925
  /**
861
926
  * aus 0...9 wird String 00...09
862
927
  *
863
- * @param i
864
- * @returns
928
+ * @param {string|number} i
929
+ * @returns {string}
865
930
  */
866
931
  function checkTime(i) {
867
- return (+i < 10) ? `0${i}` : i;
932
+ return (+i < 10) ? `0${ i}` : i.toString();
868
933
  }
869
934
 
870
935
  do {
@@ -910,13 +975,9 @@ function startTimeSprinkle() {
910
975
  }
911
976
  } while ((newStartTime <= myTime) && (run === 1));
912
977
 
913
- const newStartTimeLong = `${myWeekdayStr[myWeekday]} ${newStartTime}`;
914
- /**
915
- * next Auto-Start
916
- *
917
- * @param {string|null} err
918
- * @param {ioBroker.State|null|undefined} state
919
- */
978
+ const newStartTimeLong = `${ myWeekdayStr[myWeekday] } ${ newStartTime }`;
979
+ /* next Auto-Start */
980
+ // @ts-ignore
920
981
  adapter.getState('info.nextAutoStart', (err, state) =>{
921
982
  if (state) {
922
983
  if (state.val !== newStartTimeLong) {
@@ -926,7 +987,7 @@ function startTimeSprinkle() {
926
987
  });
927
988
  // next Start Message
928
989
  if(!sendMessageText.onlySendError){
929
- sendMessageText.sendMessage(`${infoMessage}(${myWeekdayStr[myWeekday]}) um ${newStartTime}`);
990
+ sendMessageText.sendMessage(`${ infoMessage }(${ myWeekdayStr[myWeekday] }) um ${ newStartTime }`);
930
991
  }
931
992
  adapter.log.info(`${infoMessage} (${myWeekdayStr[myWeekday]}) um ${newStartTime}`);
932
993
  }
@@ -938,7 +999,9 @@ function startTimeSprinkle() {
938
999
  startTimeStr = nextStartTime();
939
1000
  startTimeSplit = startTimeStr.split(':');
940
1001
 
941
- const scheduleStartTime = schedule.scheduleJob('sprinkleStartTime', `${startTimeSplit[1]} ${startTimeSplit[0]} * * *`, function() {
1002
+ // @ts-ignore
1003
+
1004
+ const scheduleStartTime = schedule.scheduleJob('sprinkleStartTime', `${ startTimeSplit[1] } ${ startTimeSplit[0] } * * *`, function() {
942
1005
  startOfIrrigation();
943
1006
  setTimeout (() => {
944
1007
  setTimeout(()=>{
@@ -949,186 +1012,175 @@ function startTimeSprinkle() {
949
1012
  });
950
1013
  }
951
1014
 
952
- const startOfIrrigation = () => {
1015
+ const startOfIrrigation = async () => {
953
1016
  let messageText = '';
954
1017
 
955
- // Filter enabled
956
- const result = myConfig.config.filter(d => d.enabled === true);
957
- if (result) {
1018
+ try {
1019
+ // Zisterne leer Abbruch
1020
+ if(valveControl.getIntBreakCisternPump()) {
1021
+ adapter.log.warn('Additional irrigation is not possible! The cistern is empty.');
1022
+ sendMessageText.sendMessage('Irrigation not possible!\n The cistern is empty.');
1023
+ schedule.cancelJob('sprinkleAddStartTime');
1024
+ }
1025
+ // Filter enabled
1026
+ const result = myConfig.config.filter((d) => d.enabled === true);
1027
+ if (result) {
958
1028
  /**
959
1029
  * Array zum flüchtigen Sammeln von Bewässerungsaufgaben
960
- *
961
1030
  */
962
- const memAddList = [];
1031
+ const memAddList = [];
963
1032
 
964
- /**
965
- * result Rain
966
- * - (aktuelle Wettervorhersage - Schwellwert der Regenberücksichtigung) wenn Sensor sich im Freien befindet
967
- * - (> 0) es regnet - Abbruch -
968
- * - (≤ 0) Start der Bewässerung
969
- *
970
- * @param inGreenhouse - Sensor befindet sich im Gewächshaus
971
- * @returns - resultierende Regenmenge
972
- */
973
- function resRain (inGreenhouse) {
974
- return (adapter.config.weatherForecast && !inGreenhouse) ? (((+ weatherForecastTodayNum) - parseFloat(adapter.config.thresholdRain)).toFixed(1)) : 0;
975
- }
976
- // Bewässerung mit Zisterne? Füllstand anzeigen
977
- if (adapter.config.cisternSettings === true) messageText += `${valveControl.getStatusCistern()}\n`;
978
-
979
- for(const res of result) {
980
- let messageTextZeile1 = '';
981
- let messageTextZeile2 = '';
982
- messageTextZeile1 = `<b>${res.objectName}</b>`;
983
- switch (res.methodControlSM) {
984
- case 'bistable':
985
- messageTextZeile1 += ` (${res.soilMoisture.bool})`;
986
- break;
987
- case 'analog':
988
- messageTextZeile1 += ` ${res.soilMoisture.pct}% (${res.soilMoisture.pctTriggerIrrigation}%)`;
989
- break;
990
- case 'fixDay':
991
- //messageTextZeile1 += ` (${curNextFixDay(res.sprinkleID, true)})`;
992
- break;
993
- case 'calculation':
994
- messageTextZeile1 += ` ${res.soilMoisture.pct}% (${res.soilMoisture.pctTriggerIrrigation}%)`;
995
- break;
996
- }
997
-
998
- // Test Bodenfeuchte
999
- adapter.log.debug(`Bodenfeuchte: ${res.soilMoisture.val} <= ${res.soilMoisture.triggersIrrigation} AutoOn: ${res.autoOn}`);
1000
- if (res.autoOn) {
1033
+ for(const res of result) {
1034
+ messageText += `<b>${ res.objectName }</b>`;
1001
1035
  switch (res.methodControlSM) {
1002
- // -- bistable -- Bodenfeuchte-Sensor mit 2-Punkt-Regler true und false -- //
1003
1036
  case 'bistable':
1004
- if(res.soilMoisture.bool) {
1005
- /* Wenn in der Config Regenvorhersage aktiviert: Startvorgang abbrechen, wenn der Regen den eingegebenen Schwellwert überschreitet. */
1006
- if (resRain(res.inGreenhouse) <= 0) {
1007
- const curWateringTime = Math.round(60 * res.wateringTime * evaporation.timeExtension(res.wateringAdd));
1008
- memAddList.push({
1009
- auto: true,
1010
- sprinkleID: res.sprinkleID,
1011
- wateringTime: curWateringTime
1012
- });
1013
- messageTextZeile2 += `START => ${addTime(curWateringTime, '')}`;
1014
- } else if (adapter.config.weatherForecast) {
1015
- /* Bewässerung unterdrückt da ausreichende Regenvorhersage */
1016
- messageTextZeile2 += `<i>Start verschoben, da heute ${weatherForecastTodayNum}mm Niederschlag</i>`;
1017
- adapter.log.info(`${res.objectName}: Start verschoben, da Regenvorhersage für Heute ${weatherForecastTodayNum} mm [ ${resRain(res.inGreenhouse)} > 0 ]`);
1018
- }
1019
- }
1037
+ messageText += ` (${res.bistable.bool})\n`;
1020
1038
  break;
1021
- // --- analog -- Bodenfeuchte-Sensor im Wertebereich von 0 bis 100% --- //
1022
- // -- Prozentuale Bodenfeuchte zu gering -- //
1023
1039
  case 'analog':
1024
- if(res.soilMoisture.pct <= res.soilMoisture.pctTriggerIrrigation) {
1040
+ messageText += ` ${res.analog.pct}% (${res.analog.pctTriggerIrrigation}%`;
1041
+ break;
1042
+ case 'fixDay':
1043
+ messageText += ` (${await curNextFixDay(res.sprinkleID, true)})\n`;
1044
+ break;
1045
+ case 'calculation':
1046
+ messageText += ` ${res.calculation.pct}% (${res.calculation.pctTriggerIrrigation}%)\n`;
1047
+ break;
1048
+ }
1049
+
1050
+ // Test Bodenfeuchte
1051
+ if (res.autoOn) {
1052
+ switch (res.methodControlSM) {
1053
+ // -- bistable -- Bodenfeuchte-Sensor mit 2-Punkt-Regler true und false -- //
1054
+ case 'bistable':
1055
+ if(res.bistable.bool) {
1025
1056
  /* Wenn in der Config Regenvorhersage aktiviert: Startvorgang abbrechen, wenn der Regen den eingegebenen Schwellwert überschreitet. */
1026
- if (resRain(res.inGreenhouse) <= 0) {
1027
- let countdown = res.wateringTime * (100 - res.soilMoisture.pct) / (100 - res.soilMoisture.pctTriggerIrrigation); // in min
1028
- // Begrenzung der Bewässerungszeit auf dem in der Config eingestellten Überschreitung (in Prozent)
1029
- if (countdown > (res.wateringTime * res.wateringAdd / 100)) {
1030
- countdown = res.wateringTime * res.wateringAdd / 100;
1057
+ if (resRain(res.inGreenhouse) <= 0) {
1058
+ const curWateringTime = Math.round(60 * res.wateringTime * evaporation.timeExtension(res.wateringAdd));
1059
+ memAddList.push({
1060
+ auto: true,
1061
+ sprinkleID: res.sprinkleID,
1062
+ wateringTime: curWateringTime
1063
+ });
1064
+ messageText += ` ${res.extBreak ? 'extBreak ||' : 'START =>'} ${addTime(curWateringTime, '')}\n`;
1065
+ } else if (adapter.config.weatherForecast) {
1066
+ /* Bewässerung unterdrückt da ausreichende Regenvorhersage */
1067
+ messageText += ` <i>Start verschoben, da heute ${weatherForecastTodayNum}mm Niederschlag</i> \n`;
1068
+ adapter.log.info(`${res.objectName}: Start verschoben, da Regenvorhersage für Heute ${weatherForecastTodayNum} mm [ ${resRain(res.inGreenhouse)} > 0 ]`);
1031
1069
  }
1032
- memAddList.push({
1033
- auto: true,
1034
- sprinkleID: res.sprinkleID,
1035
- wateringTime: Math.round(60* countdown)
1036
- });
1037
- messageTextZeile2 += `START => ${addTime(Math.round(60*countdown), '')}`;
1038
- } else if (adapter.config.weatherForecast) {
1070
+ }
1071
+ break;
1072
+ // --- analog -- Bodenfeuchte-Sensor im Wertebereich von 0 bis 100% --- //
1073
+ // -- Prozentuale Bodenfeuchte zu gering -- //
1074
+ case 'analog':
1075
+ if(res.analog.pct <= res.analog.pctTriggerIrrigation) {
1076
+ /* Wenn in der Config Regenvorhersage aktiviert: Startvorgang abbrechen, wenn der Regen den eingegebenen Schwellwert überschreitet. */
1077
+ if (resRain(res.inGreenhouse) <= 0) {
1078
+ let countdown = res.wateringTime * (100 - res.analog.pct) / (100 - res.analog.pctTriggerIrrigation); // in min
1079
+ // Begrenzung der Bewässerungszeit auf dem in der Config eingestellten Überschreitung (in Prozent)
1080
+ if (countdown > (res.wateringTime * res.wateringAdd / 100)) {
1081
+ countdown = res.wateringTime * res.wateringAdd / 100;
1082
+ }
1083
+ memAddList.push({
1084
+ auto: true,
1085
+ sprinkleID: res.sprinkleID,
1086
+ wateringTime: Math.round(60* countdown)
1087
+ });
1088
+ messageText += ` ${res.extBreak ? 'extBreak ||' : 'START =>'} ${addTime(Math.round(60*countdown), '')}\n}`;
1089
+ } else if (adapter.config.weatherForecast) {
1039
1090
  /* Bewässerung unterdrückt da ausreichende Regenvorhersage */
1040
- messageTextZeile2 += `<i>Start verschoben, da heute ${weatherForecastTodayNum}mm Niederschlag</i> `;
1041
- adapter.log.info(`${res.objectName}: Start verschoben, da Regenvorhersage für Heute ${weatherForecastTodayNum} mm [ ${resRain(res.inGreenhouse)} > 0 ]`);
1091
+ messageText += ` <i>Start verschoben, da heute ${weatherForecastTodayNum}mm Niederschlag</i> \n`;
1092
+ adapter.log.info(`${res.objectName}: Start verschoben, da Regenvorhersage für Heute ${weatherForecastTodayNum}mm [ ${resRain(res.inGreenhouse)} > 0 ]`);
1093
+ }
1042
1094
  }
1043
- }
1044
- break;
1045
- // --- fixDay -- Start an festen Tagen ohne Sensoren --- //
1046
- // -- Bewässerungstag erreicht //
1047
- case 'fixDay':
1095
+ break;
1096
+ // --- fixDay -- Start an festen Tagen ohne Sensoren --- //
1097
+ // -- Bewässerungstag erreicht //
1098
+ case 'fixDay':
1048
1099
  /* Wenn in der Config Regenvorhersage aktiviert: Startvorgang abbrechen, wenn der Regen den eingegebenen Schwellwert überschreitet. */
1049
- if (resRain(res.inGreenhouse) <= 0) {
1100
+ if (resRain(res.inGreenhouse) <= 0) {
1050
1101
  // Bewässerungstag erreicht
1051
- if (res.startFixDay[today]) {
1052
- const curWateringTime = Math.round(60 * res.wateringTime * evaporation.timeExtension(res.wateringAdd));
1053
- memAddList.push({
1054
- auto: true,
1055
- sprinkleID: res.sprinkleID,
1056
- wateringTime: curWateringTime
1057
- });
1058
- messageTextZeile2 += `START => ${addTime(curWateringTime, '')}`;
1059
- if (res.startDay === 'threeRd'){ // Next Start in 3 Tagen
1060
- res.startFixDay[today] = false;
1061
- res.startFixDay[(+ today + 3 > 6) ? (+ today-4) : (+ today+3)] = true;
1062
- }else if (res.startDay === 'twoNd') { // Next Start in 2 Tagen
1063
- res.startFixDay[today] = false;
1064
- res.startFixDay[(+ today + 2 > 6) ? (+ today-5) : (+ today+2)] = true;
1102
+ if (res.fixDay.startFixDay[today]) {
1103
+ const curWateringTime = Math.round(60 * res.wateringTime * evaporation.timeExtension(res.wateringAdd));
1104
+ memAddList.push({
1105
+ auto: true,
1106
+ sprinkleID: res.sprinkleID,
1107
+ wateringTime: curWateringTime
1108
+ });
1109
+ messageText += ` ${res.extBreak ? 'extBreak ||' : 'START =>'} ${addTime(curWateringTime, '')}\n`;
1110
+ if (res.fixDay.startDay === 'threeRd'){ // Next Start in 3 Tagen
1111
+ res.fixDay.startFixDay[today] = false;
1112
+ res.fixDay.startFixDay[(+ today + 3 > 6) ? (+ today-4) : (+ today+3)] = true;
1113
+ }else if (res.fixDay.startDay === 'twoNd') { // Next Start in 2 Tagen
1114
+ res.fixDay.startFixDay[today] = false;
1115
+ res.fixDay.startFixDay[(+ today + 2 > 6) ? (+ today-5) : (+ today+2)] = true;
1116
+ }
1065
1117
  }
1066
- }
1067
- } else if (adapter.config.weatherForecast){
1068
- messageTextZeile2 += `<i>Start verschoben, da heute ${weatherForecastTodayNum}mm Niederschlag</i>`;
1069
- adapter.log.info(`${res.objectName}: Start verschoben, da Regenvorhersage für Heute ${weatherForecastTodayNum} mm [ ${resRain(false)} > 0 ]`);
1070
- if ((res.startDay === 'threeRd') || (res.startDay === 'twoNd')) {
1071
- let startDay = -1;
1072
- res.startFixDay.forEach((item, index) => {
1073
- if (item) {
1074
- startDay = index;
1118
+ } else if (adapter.config.weatherForecast){
1119
+ messageText += ` <i>Start verschoben, da heute ${weatherForecastTodayNum}mm Niederschlag</i> \n`;
1120
+ adapter.log.info(`${res.objectName}: Start verschoben, da Regenvorhersage für Heute ${weatherForecastTodayNum} mm [ ${resRain(res.inGreenhouse)} > 0 ]`);
1121
+ if ((res.fixDay.startDay === 'threeRd') || (res.fixDay.startDay === 'twoNd')) {
1122
+ let startDay = -1;
1123
+ res.fixDay.startFixDay.forEach((item, index) => {
1124
+ if (item) {
1125
+ startDay = index;
1126
+ }
1127
+ });
1128
+ if (startDay !== -1) {
1129
+ res.fixDay.startFixDay[startDay] = false;
1130
+ res.fixDay.startFixDay[(+ startDay + 1 > 6) ? (+ startDay-6) : (+ startDay+1)] = true;
1131
+ } else {
1132
+ adapter.log.warn(`${res.objectName}: no start day found`);
1075
1133
  }
1076
- });
1077
- if (startDay !== -1) {
1078
- res.startFixDay[startDay] = false;
1079
- res.startFixDay[(+ startDay + 1 > 6) ? (+ startDay-6) : (+ startDay+1)] = true;
1080
- } else {
1081
- adapter.log.warn(`${res.objectName}: no start day found`);
1082
1134
  }
1083
1135
  }
1084
- }
1085
- curNextFixDay(res.sprinkleID, false);
1086
- messageTextZeile1 += ` (${curNextFixDay(res.sprinkleID, true)})`;
1087
- break;
1088
- // --- calculation -- Berechnung der Bodenfeuchte --- //
1089
- // -- Bodenfeuchte zu gering -- //
1090
- case 'calculation':
1091
- if (res.soilMoisture.val <= res.soilMoisture.triggersIrrigation) {
1136
+ await curNextFixDay(res.sprinkleID, false);
1137
+ break;
1138
+ // --- calculation -- Berechnung der Bodenfeuchte --- //
1139
+ // -- Bodenfeuchte zu gering -- //
1140
+ case 'calculation':
1141
+ if (res.calculation.val <= res.calculation.triggersIrrigation) {
1092
1142
  /* Wenn in der Config Regenvorhersage aktiviert: Startvorgang abbrechen, wenn es heute ausreichend regnen sollte. */
1093
- const resMoisture = (adapter.config.weatherForecast)?((+ res.soilMoisture.val) + (+ weatherForecastTodayNum) - parseFloat(adapter.config.thresholdRain)):(res.soilMoisture.val); // aktualisierte Bodenfeuchte mit Regenvorhersage
1094
- if ((resMoisture <= res.soilMoisture.triggersIrrigation) || res.inGreenhouse) { // Kontrolle ob Regenvorhersage ausreicht || Bewässerung inGreenhouse
1095
- let countdown = res.wateringTime * (res.soilMoisture.maxIrrigation - res.soilMoisture.val) / (res.soilMoisture.maxIrrigation - res.soilMoisture.triggersIrrigation); // in min
1096
- // Begrenzung der Bewässerungszeit auf dem in der Config eingestellten Überschreitung (in Prozent)
1097
- if (countdown > (res.wateringTime * res.wateringAdd / 100)) {
1098
- countdown = res.wateringTime * res.wateringAdd / 100;
1099
- }
1100
- memAddList.push({
1101
- auto: true,
1102
- sprinkleID: res.sprinkleID,
1103
- wateringTime: Math.round(60*countdown)
1104
- });
1105
- messageTextZeile2 += `START => ${addTime(Math.round(60*countdown), '')}`;
1106
- } else if (adapter.config.weatherForecast) {
1143
+ const resMoisture = (adapter.config.weatherForecast)?((+ res.calculation.val) + (+ weatherForecastTodayNum) - parseFloat(adapter.config.thresholdRain)):(res.calculation.val); // aktualisierte Bodenfeuchte mit Regenvorhersage
1144
+ if ((resMoisture <= res.calculation.triggersIrrigation) || res.inGreenhouse) { // Kontrolle ob Regenvorhersage ausreicht || Bewässerung inGreenhouse
1145
+ let countdown = res.wateringTime * (res.calculation.maxIrrigation - res.calculation.val) / (res.calculation.maxIrrigation - res.calculation.triggersIrrigation); // in min
1146
+ // Begrenzung der Bewässerungszeit auf dem in der Config eingestellten Überschreitung (in Prozent)
1147
+ if (countdown > (res.wateringTime * res.wateringAdd / 100)) {
1148
+ countdown = res.wateringTime * res.wateringAdd / 100;
1149
+ }
1150
+ memAddList.push({
1151
+ auto: true,
1152
+ sprinkleID: res.sprinkleID,
1153
+ wateringTime: Math.round(60*countdown)
1154
+ });
1155
+ messageText += ` ${res.extBreak ? 'extBreak ||' : 'START =>'} ${addTime(Math.round(60*countdown), '')}\n`;
1156
+ } else if (adapter.config.weatherForecast) {
1107
1157
  /* Bewässerung unterdrückt da ausreichende Regenvorhersage */
1108
- messageTextZeile2 += `<i>Start verschoben, da heute ${weatherForecastTodayNum}mm Niederschlag</i>`;
1109
- adapter.log.info(`${res.objectName}: Start verschoben, da Regenvorhersage für Heute ${weatherForecastTodayNum} mm [ ${res.soilMoisture.val.toFixed(1)} (${resMoisture.toFixed(1)}) <= ${res.soilMoisture.triggersIrrigation} ]`);
1158
+ messageText += ` <i>Start verschoben, da heute ${weatherForecastTodayNum}mm Niederschlag</i> \n`;
1159
+ adapter.log.info(`${res.objectName}: Start verschoben, da Regenvorhersage für Heute ${weatherForecastTodayNum} mm [ ${res.calculation.val.toFixed(1)} (${resMoisture.toFixed(1)}) <= ${res.calculation.triggersIrrigation} ]`);
1160
+ }
1110
1161
  }
1111
- }
1112
- break;
1162
+ break;
1163
+ }
1164
+ } else {
1165
+ messageText += ` <i>Ventil auf Handbetrieb</i> \n`;
1113
1166
  }
1114
- } else {
1115
- messageTextZeile2 += `<i>Ventil auf Handbetrieb</i> `;
1116
1167
  }
1117
- messageText += (messageTextZeile2.length > 0) ? (`${messageTextZeile1}\n ${messageTextZeile2}\n`) : (`${messageTextZeile1}\n`);
1168
+ valveControl.addList(memAddList);
1118
1169
  }
1119
- valveControl.addList(memAddList);
1120
- }
1121
- if(!sendMessageText.onlySendError()){
1122
- sendMessageText.sendMessage(messageText);
1170
+ if(!sendMessageText.onlySendError()){
1171
+ sendMessageText.sendMessage(messageText);
1172
+ }
1173
+
1174
+ } catch (error) {
1175
+ adapter.log.error(`startOfIrrigation ERROR: ${error}`);
1123
1176
  }
1124
- }
1177
+ };
1178
+
1125
1179
 
1126
1180
  //
1127
1181
  async function createSprinklers() {
1128
- /**Creates an Object .control.addStartTimeSwitch, when additional watering has been activated via an external signal
1182
+ /* Creates an Object .control.addStartTimeSwitch, when additional watering has been activated via an external signal
1129
1183
  * - Erzeugt ein Object .control.addStartTimeSwitch, wenn die Zusatzbewässerung über ein externes Signal aktiviert wurde
1130
- * @type {{id: string, name: string} | void}
1131
- * @private
1132
1184
  */
1133
1185
  const _addStartTimeSwitch = await adapter.findForeignObjectAsync(`${adapter.namespace}.control.addStartTimeSwitch`, 'boolean').catch((e) => adapter.log.warn(`.control.addStartTimeSwitch ${e}`));
1134
1186
  if (_addStartTimeSwitch.id !== `${adapter.namespace}.control.addStartTimeSwitch` && adapter.config.selectAddStartTime === 'withExternalSignal') {
@@ -1136,19 +1188,7 @@ async function createSprinklers() {
1136
1188
  type: 'state',
1137
1189
  common: {
1138
1190
  role: 'switch',
1139
- name: {
1140
- en: "additional irrigation enabled",
1141
- de: "weitere Bewässerung aktiviert",
1142
- ru: "включено дополнительное орошение",
1143
- pt: "irrigação adicional ativada",
1144
- nl: "extra irrigatie mogelijk",
1145
- fr: "arrosage supplémentaire activé",
1146
- it: "irrigazione extra abilitata",
1147
- es: "riego adicional habilitado",
1148
- pl: "włączone dodatkowe nawadnianie",
1149
- uk: "додаткове зрошення включено",
1150
- "zh-cn": "已启用额外灌溉"
1151
- },
1191
+ name: 'additional irrigation enabled',
1152
1192
  type: 'boolean',
1153
1193
  read: true,
1154
1194
  write: true,
@@ -1156,243 +1196,255 @@ async function createSprinklers() {
1156
1196
  },
1157
1197
  native: {}
1158
1198
  }).catch((e) => adapter.log.warn(`.control.addStartTimeSwitch ${e}`));
1199
+ // @ts-ignore
1159
1200
  } else if (_addStartTimeSwitch.id === `${adapter.namespace}.control.addStartTimeSwitch`) {
1160
1201
  if (adapter.config.selectAddStartTime !== 'withExternalSignal') {
1161
1202
  adapter.delObjectAsync(`${adapter.namespace}.control.addStartTimeSwitch`).catch((e) => adapter.log.warn(`.control.addStartTimeSwitch ${e}`));
1162
1203
  addStartTimeSwitch = false;
1163
1204
  } else {
1164
- /**
1165
- * auslesen .control.addStartTimeSwitch.val
1166
- */
1205
+ /* */
1167
1206
  const _state = await adapter.getStateAsync(`${adapter.namespace}.control.addStartTimeSwitch`).catch((e) => adapter.log.warn(`.control.addStartTimeSwitch ${e}`));
1168
- if (typeof _state.val === 'boolean') {
1207
+ if (_state && typeof _state.val === 'boolean') {
1169
1208
  addStartTimeSwitch = _state.val;
1170
1209
  }
1171
1210
  }
1172
1211
  }
1173
1212
 
1174
1213
 
1175
-
1176
- const result = adapter.config.events;
1177
- if (result) {
1178
- for(const res of result) {
1179
- let objectName;
1180
-
1181
- if(res.sprinkleName !== '') {
1182
- objectName = res.sprinkleName.replace(/[.;, ]/g, '_');
1183
- } else if (res.sprinkleName === '') {
1184
- objectName = res.name.replace(/[.;, ]/g, '_');
1185
- }
1186
-
1187
- const objPfad = `sprinkle.${objectName}`;
1188
- const j = myConfig.config.findIndex(d => d.objectName === objectName);
1189
-
1190
- // Create bzw. update .actualSoilMoisture
1191
-
1192
- let nameMetConSM, objMetConSM;
1193
- await fillMetConSM(res);
1194
- async function fillMetConSM(res) {
1195
- //adapter.log.debug(JSON.stringify(res));
1196
- switch (res.methodControlSM) {
1197
- case 'calculation':
1198
- nameMetConSM = {
1199
- en: `${objectName} => Calculated soil moisture in %`,
1200
- de: `${objectName} => Berechnete Bodenfeuchte in%`,
1201
- ru: `${objectName} => Расчетная влажность почвы в%`,
1202
- pt: `${objectName} => Umidade do solo calculada em%`,
1203
- nl: `${objectName} => Berekend bodemvocht in%`,
1204
- fr: `${objectName} => Humidité du sol calculée en %`,
1205
- it: `${objectName} => Umidità del suolo in%`,
1206
- es: `${objectName} => Humedad del suelo calculada en%`,
1207
- pl: `${objectName} => Obliczona wilgotność gleby w%`,
1208
- uk: `${objectName} => Розрахована вологість ґрунту в%`,
1209
- "zh-cn": `${objectName} => 计算出的土壤湿度百分比`
1210
- };
1211
- objMetConSM = {
1212
- type: 'state',
1213
- common: {
1214
- role: 'state',
1215
- name: nameMetConSM,
1216
- type: 'number',
1217
- min: 0,
1218
- max: 150,
1219
- unit: '%',
1220
- read: true,
1221
- write: false,
1222
- def: 50
1214
+ /**
1215
+ * Bereitstellen des Objekts .actualSoilMoisture für die einzelnen Bewässerungsverfahren
1216
+ *
1217
+ * @param {string} methodControlSM
1218
+ * @param {string} objectName
1219
+ * @returns {Promise<{nameMetConSM: string; objMetConSM: {type: string, common: {role: string, name: string, type: string, min?: number, max?: number, states?: {}, unit?: string, read: boolean, write: boolean, def?: number | string | boolean}, native: {}}}>}
1220
+ */
1221
+ const fillMetConSM = async (methodControlSM, objectName) => {
1222
+ //adapter.log.debug(JSON.stringify(res));
1223
+ switch (methodControlSM) {
1224
+ case 'calculation': {
1225
+ return {
1226
+ nameMetConSM: `${objectName} => Calculated soil moisture in %`,
1227
+ objMetConSM: {
1228
+ type: 'state',
1229
+ common: {
1230
+ role: 'state',
1231
+ name: `${objectName} => Calculated soil moisture in %`,
1232
+ desc: {
1233
+ en: "Calculated soil moisture in %",
1234
+ de: "Berechnete Bodenfeuchte in %",
1235
+ ru: "Рассчитанная влажность почвы в %",
1236
+ pt: "Umidade do solo calculada em %",
1237
+ nl: "Berekenend bodemvochtigheid in %",
1238
+ fr: "Humidité du sol calculée en %",
1239
+ it: "Umidità del suolo calcolata in %",
1240
+ es: "Humedad del suelo calculada en %",
1241
+ pl: "Obliczana wilgotność gleby w %",
1242
+ uk: "Рассчитанная влажность почвы в %",
1243
+ 'zh-cn': "计算土壤湿度(%)"
1223
1244
  },
1224
- native: {},
1225
- };
1226
- break;
1227
- case 'bistable':
1228
- nameMetConSM = {
1229
- en: `${objectName} => bistable soil moisture sensor`,
1230
- de: `${objectName} => Bistabiler Bodenfeuchtesensor`,
1231
- ru: `${objectName} => бистабильный датчик влажности почвы`,
1232
- pt: `${objectName} => sensor biestável de umidade`,
1233
- nl: `${objectName} => bistabiele bodemvochtsensor`,
1234
- fr: `${objectName} => capteur d'humidité du sol bistable`,
1235
- it: `${objectName} => sensore di umidità bistabile`,
1236
- es: `${objectName} => sensor biestable de humedad`,
1237
- pl: `${objectName} => bistabilny czujnik wilgotności gleby`,
1238
- uk: `${objectName} => бістабільний датчик вологості ґрунту`,
1239
- "zh-cn": `${objectName} => 双稳态土壤湿度传感器`
1240
- };
1241
- objMetConSM = {
1242
- type: 'state',
1243
- common: {
1244
- role: 'state',
1245
- name: nameMetConSM,
1246
- type: 'boolean',
1247
- read: true,
1248
- write: false,
1249
- def: false
1245
+ type: 'number',
1246
+ min: 0,
1247
+ max: 150,
1248
+ unit: '%',
1249
+ read: true,
1250
+ write: false,
1251
+ def: 50
1252
+ },
1253
+ native: {},
1254
+ }
1255
+ };
1256
+ }
1257
+ case 'bistable': {
1258
+ return {
1259
+ nameMetConSM: `${objectName} => bistable soil moisture sensor`,
1260
+ objMetConSM: {
1261
+ type: 'state',
1262
+ common: {
1263
+ role: 'state',
1264
+ name: `${objectName} => bistable soil moisture sensor`,
1265
+ desc: {
1266
+ en: "bistable soil moisture sensor",
1267
+ de: "bistabiler Bodenfeuchtesensor",
1268
+ ru: "бистабильный датчик влажности почвы",
1269
+ pt: "sensor de umidade do solo biescalar",
1270
+ nl: "bistabiele bodemvochtigheidssensor",
1271
+ fr: "capteur d'humidité du sol bistable",
1272
+ it: "sensore di umidità del suolo bistabile",
1273
+ es: "sensor de humedad del suelo biescalar",
1274
+ pl: "bistabilny czujnik wilgotności gleby",
1275
+ uk: "бістабільний датчик вологості грунту",
1276
+ 'zh-cn': "双稳态土壤湿度传感器"
1250
1277
  },
1251
- native: {},
1252
- };
1253
- break;
1254
- case 'analog':
1255
- nameMetConSM = {
1256
- en: `${objectName} => analog soil moisture sensor in %`,
1257
- de: `${objectName} => analoger Bodenfeuchtesensor in%`,
1258
- ru: `${objectName} => аналоговый датчик влажности почвы в%`,
1259
- pt: `${objectName} => sensor analógico de umidade em%`,
1260
- nl: `${objectName} => analoge bodemvochtsensor in%`,
1261
- fr: `${objectName} => capteur d'humidité du sol analogique en %`,
1262
- it: `${objectName} => sensore umidità analogico in%`,
1263
- es: `${objectName} => sensor analógico de humedad en%`,
1264
- pl: `${objectName} => analogowy czujnik wilgotności gleby w%`,
1265
- uk: `${objectName} => аналоговий датчик вологості ґрунту в%`,
1266
- "zh-cn": `${objectName} => 模拟土壤湿度传感器,单位为%`
1267
- };
1268
- objMetConSM = {
1269
- type: 'state',
1270
- common: {
1271
- role: 'state',
1272
- name: nameMetConSM,
1273
- type: 'number',
1274
- min: 0,
1275
- max: 150,
1276
- unit: '%',
1277
- read: true,
1278
- write: false
1278
+ type: 'boolean',
1279
+ read: true,
1280
+ write: false,
1281
+ def: false
1282
+ },
1283
+ native: {},
1284
+ }
1285
+ };
1286
+ }
1287
+ case 'analog': {
1288
+ return {
1289
+ nameMetConSM: `${objectName} => analog soil moisture sensor in %`,
1290
+ objMetConSM: {
1291
+ type: 'state',
1292
+ common: {
1293
+ role: 'state',
1294
+ name: `${objectName} => analog soil moisture sensor in %`,
1295
+ desc: {
1296
+ en: "analog soil moisture sensor in %",
1297
+ de: "analoger Bodenfeuchtesensor in %",
1298
+ ru: "аналоговый датчик влажности почвы в %",
1299
+ pt: "sensor de umidade do solo analógico em %",
1300
+ nl: "analoge bodemvochtigheidssensor in %",
1301
+ fr: "capteur d'humidité du sol analogique en %",
1302
+ it: "sensore di umidità del suolo analogico in %",
1303
+ es: "sensor de humedad del suelo analógico en %",
1304
+ pl: "analogowy czujnik wilgotności gleby w %",
1305
+ uk: "аналоговый датчик влажности почвы в %",
1306
+ 'zh-cn': "模拟土壤湿度传感器(%)"
1279
1307
  },
1280
- native: {},
1281
- };
1282
- break;
1283
- case 'fixDay':
1284
- nameMetConSM = {
1285
- en: `${objectName} => start on a fixed day`,
1286
- de: `${objectName} => start an einem festen Tag`,
1287
- ru: `${objectName} => начните в определенный день`,
1288
- pt: `${objectName} => começa em dia fixo`,
1289
- nl: `${objectName} => start op een vaste dag`,
1290
- fr: `${objectName} => commence un jour fixe`,
1291
- it: `${objectName} => inizio a un giorno`,
1292
- es: `${objectName} => empezar un día fijo`,
1293
- pl: `${objectName} => zacznij w ustalonym dniu`,
1294
- uk: `${objectName} => початок у фіксований день`,
1295
- "zh-cn": `${objectName} => 在固定的日期开始`
1296
- };
1297
- objMetConSM = {
1298
- type: 'state',
1299
- common: {
1300
- role: 'state',
1301
- name: nameMetConSM,
1302
- type: 'number',
1303
- min: 0,
1304
- max: 7,
1305
- states: {0:'Sun', 1:'Mon', 2:'Tue', 3:'Wed', 4:'Thur', 5:'Fri', 6:'Sat', 7:'off'},
1306
- read: true,
1307
- write: false,
1308
- def: 7
1308
+ type: 'number',
1309
+ min: 0,
1310
+ max: 150,
1311
+ unit: '%',
1312
+ read: true,
1313
+ write: false,
1314
+ def: 50
1315
+ },
1316
+ native: {},
1317
+ }
1318
+ };
1319
+ }
1320
+ case 'fixDay': {
1321
+ return {
1322
+ nameMetConSM: `${objectName} => start on a fixed day`,
1323
+ objMetConSM: {
1324
+ type: 'state',
1325
+ common: {
1326
+ role: 'state',
1327
+ name: `${objectName} => start on a fixed day`,
1328
+ desc: {
1329
+ en: "start on a fixed day",
1330
+ de: "Start an einem festgelegten Tag",
1331
+ ru: "Начало в назначенный день.",
1332
+ pt: "Iniciar em um dia fixo",
1333
+ nl: "Start op een vaste dag.",
1334
+ fr: "Démarrer à une date fixe !",
1335
+ it: "Inizia in un giorno fisso",
1336
+ es: "¡Comienza en un día fijo!",
1337
+ pl: "Start w ustalonym dniu",
1338
+ uk: "початок у визначений день",
1339
+ 'zh-cn': "从固定日期开始"
1309
1340
  },
1310
- native: {},
1311
- };
1312
- break;
1313
- default:
1314
- adapter.log.warn(`sprinkleControl cannot created ... Please check your sprinkleControl config ${objectName} methodControl`);
1315
- nameMetConSM = {
1316
- en: `${objectName} => Emergency program! start on a fixed day`,
1317
- de: `${objectName} => Notfallprogramm! start an einem festen Tag`,
1318
- ru: `${objectName} => Экстренная программа! начните в определенный день`,
1319
- pt: `${objectName} => Programa urgente! comece em dia fixo`,
1320
- nl: `${objectName} => Noodprogramma! op een vaste dag beginnen`,
1321
- fr: `${objectName} => Programme d'urgence ! commencer un jour fixe`,
1322
- it: `${objectName} => Emergenze! inizio a data fissa`,
1323
- es: `${objectName} => ¡Programa de emergencia! empezar un día fijo`,
1324
- pl: `${objectName} => Program awaryjny! zacznij w ustalonym dniu`,
1325
- uk: `${objectName} => Екстрена програма! початок у визначений день`,
1326
- "zh-cn": `${objectName} => 紧急计划!从固定的日子开始`
1327
- };
1328
- objMetConSM = {
1329
- type: 'state',
1330
- common: {
1331
- role: 'state',
1332
- name: nameMetConSM,
1333
- type: 'number',
1334
- min: 0,
1335
- max: 7,
1336
- states: {0:'Sun', 1:'Mon', 2:'Tue', 3:'Wed', 4:'Thur', 5:'Fri', 6:'Sat', 7:'off'},
1337
- read: true,
1338
- write: false,
1339
- def: 7
1341
+ type: 'number',
1342
+ min: 0,
1343
+ max: 7,
1344
+ states: {0:'Sun', 1:'Mon', 2:'Tue', 3:'Wed', 4:'Thur', 5:'Fri', 6:'Sat', 7:'off'},
1345
+ read: true,
1346
+ write: false,
1347
+ def: 7
1348
+ },
1349
+ native: {},
1350
+ }
1351
+ };
1352
+ }
1353
+ default: {
1354
+ adapter.log.warn(`sprinkleControl cannot created ... Please select an irrigation type in the configuration. ${objectName}`);
1355
+ return {
1356
+ nameMetConSM: `${objectName} => Emergency program! start on a fixed day`,
1357
+ objMetConSM: {
1358
+ type: 'state',
1359
+ common: {
1360
+ role: 'state',
1361
+ name: `${objectName} => Emergency program! start on a fixed day`,
1362
+ desc: {
1363
+ en: "Emergency program! start on a fixed day",
1364
+ de: "Notfallprogramm! Start an einem festgelegten Tag",
1365
+ ru: "Экстренная программа! Начало в назначенный день.",
1366
+ pt: "Programa de emergência! Início em dia fixo",
1367
+ nl: "Noodprogramma! Start op een vaste dag.",
1368
+ fr: "Programme d'urgence ! Début à une date fixe",
1369
+ it: "Programma di emergenza! Inizia in un giorno fisso",
1370
+ es: "¡Programa de emergencia! Comienza en un día fijo",
1371
+ pl: "Program awaryjny! Start w ustalonym dniu",
1372
+ uk: "Екстрена програма! початок у визначений день",
1373
+ 'zh-cn': "紧急预案!从固定日期开始"
1340
1374
  },
1341
- native: {},
1342
- };
1343
- }
1375
+ type: 'number',
1376
+ min: 0,
1377
+ max: 7,
1378
+ states: {0:'Sun', 1:'Mon', 2:'Tue', 3:'Wed', 4:'Thur', 5:'Fri', 6:'Sat', 7:'off'},
1379
+ read: true,
1380
+ write: false,
1381
+ def: 7
1382
+ },
1383
+ native: {},
1384
+ }
1385
+ };
1344
1386
  }
1345
- // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
1346
- // +++++ Objekte erstellen +++++ //
1347
- // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
1348
- if (objectName && objectName !== '') {
1349
- try {
1387
+ }
1388
+ };
1389
+
1390
+
1391
+ const result = adapter.config.events;
1392
+ if (result) {
1393
+ for(const res of result) {
1394
+ try {
1395
+ if (res.enabled !== true) {
1396
+ continue;
1397
+ }
1398
+ /* Name des Bewässerungskreises */
1399
+ const objectName = (res.sprinkleName !== '') ? res.sprinkleName.replace(/[.;, ]/g, '_') : res.name.replace(/[.;, ]/g, '_');
1400
+ const objPfad = `sprinkle.${ objectName }`;
1401
+ const j = myConfig.config.findIndex((d) => d.objectName === objectName);
1402
+ if (objectName && objectName !== ''){
1403
+ // Create bzw. update .actualSoilMoisture
1404
+ const _fillMetConSM = await fillMetConSM(res.methodControlSM, objectName);
1405
+
1406
+ // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
1407
+ // +++++ Objekte erstellen +++++ //
1408
+ // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
1409
+
1350
1410
  // Create Object for sprinkle. (ID)
1351
- const _sprinkleNotExist = await adapter.setObjectNotExistsAsync(`sprinkle.${objectName}`, {
1411
+ const _sprinkleNotExist = await adapter.setObjectNotExistsAsync(`sprinkle.${ objectName }`, {
1352
1412
  type: 'channel',
1353
1413
  common: {
1354
- name: res.sprinkleName
1355
- },
1356
- native: {},
1414
+ name: res.sprinkleName,
1415
+ statusStates: {
1416
+ onlineId: `valveOn`
1417
+ },
1418
+ native: {},
1419
+ }
1357
1420
  });
1358
1421
  // Create Object for .history
1359
- const _historyNotExist = await adapter.setObjectNotExistsAsync(`sprinkle.${objectName}.history`, {
1422
+ const _historyNotExist = await adapter.setObjectNotExistsAsync(`sprinkle.${ objectName }.history`, {
1360
1423
  type: 'channel',
1361
1424
  common: {
1362
- name: {
1363
- en: `${res.sprinkleName} => History`,
1364
- de: `${res.sprinkleName} => Verlauf`,
1365
- ru: `${res.sprinkleName} => История`,
1366
- pt: `${res.sprinkleName} => História`,
1367
- nl: `${res.sprinkleName} => Geschiedenis`,
1368
- fr: `${res.sprinkleName} => Histoire`,
1369
- it: `${res.sprinkleName} => Storia`,
1370
- es: `${res.sprinkleName} => Historia`,
1371
- pl: `${res.sprinkleName} => Historia`,
1372
- uk: `${res.sprinkleName} => Історія`,
1373
- "zh-cn": `${res.sprinkleName} => 历史`
1374
- }
1425
+ name: `${ res.sprinkleName } => History`
1375
1426
  },
1376
1427
  native: {},
1377
1428
  });
1378
1429
  // Create Object for .history.curCalWeekConsumed
1379
1430
  // Sprinkler consumption of the current calendar week => History - Sprinkler-Verbrauch der aktuellen Kalenderwoche (783 Liter)
1380
- const _curCalWeekConsumedNotExist = adapter.setObjectNotExistsAsync(`${objPfad}.history.curCalWeekConsumed`, {
1431
+ const _curCalWeekConsumedNotExist = adapter.setObjectNotExistsAsync(`${ objPfad }.history.curCalWeekConsumed`, {
1381
1432
  type: 'state',
1382
1433
  common: {
1383
1434
  role: 'state',
1384
- name: {
1385
- en: `${objectName} => History - Sprinkler consumption of the current calendar week`,
1386
- de: `${objectName} => Verlauf Sprinklerverbrauch der aktuellen Woche`,
1387
- ru: `${objectName} => История - потребление спринклеров за текущую календарную неделю`,
1388
- pt: `${objectName} => Histórico - Consumo de sprinklers na semana atual`,
1389
- nl: `${objectName} => Geschiedenis - Sprinklerverbruik van de huidige kalenderweek`,
1390
- fr: `${objectName} => Historique - Consommation de gicleurs de la semaine en cours`,
1391
- it: `${objectName} => Cronologia - Consumo di irrigatori nella settimana corrente`,
1392
- es: `${objectName} => Historial: consumo de rociadores en la semana natural actual`,
1393
- pl: `${objectName} => Historia - Zużycie tryskaczy w bieżącym tygodniu kalendarzowym`,
1394
- uk: `${objectName} => Історія - Споживання спринклерів поточного календарного тижня`,
1395
- "zh-cn": `${objectName} => 历史-当前日历周的洒水消耗量`
1435
+ name: `${ objectName } => History - Sprinkler consumption of the current calendar week`,
1436
+ desc: {
1437
+ en: "Sprinkler consumption of the current calendar week",
1438
+ de: "Sprinkler-Verbrauch der aktuellen Kalenderwoche",
1439
+ ru: "Расход полива текущей календарной недели",
1440
+ pt: "Consumo de aspersão da semana calendárica atual",
1441
+ nl: "Verbruik van spuiting van de huidige kalenderweek",
1442
+ fr: "Consommation d'arrosage de la semaine calendrier actuelle",
1443
+ it: "Consumo di irrigazione della settimana calendario corrente",
1444
+ es: "Consumo de riego de la semana calendario actual",
1445
+ pl: "Zużycie nawadniania w bieżącym tygodniu kalendarzowym",
1446
+ uk: "Витрата поливу поточної календарної тижня",
1447
+ 'zh-cn': "当前日历周的喷灌消耗量"
1396
1448
  },
1397
1449
  type: 'number',
1398
1450
  unit: 'Liter',
@@ -1404,22 +1456,23 @@ async function createSprinklers() {
1404
1456
  });
1405
1457
  // Create Object for .history.curCalWeekRunningTime
1406
1458
  // Sprinkler running time of the current calendar week => History - Sprinkler-Laufzeit der aktuellen Kalenderwoche (783 Liter)
1407
- const _curCalWeekRunningTimeNotExist = adapter.setObjectNotExistsAsync(`${objPfad}.history.curCalWeekRunningTime`, {
1459
+ const _curCalWeekRunningTimeNotExist = adapter.setObjectNotExistsAsync(`${ objPfad }.history.curCalWeekRunningTime`, {
1408
1460
  type: 'state',
1409
1461
  common: {
1410
1462
  role: 'state',
1411
- name: {
1412
- en: `${objectName} => History - Sprinkler running time of the current calendar week`,
1413
- de: `${objectName} => Verlauf Sprinklerlaufzeit der aktuellen Woche`,
1414
- ru: `${objectName} => История - время работы спринклеров на текущей календарной неделе`,
1415
- pt: `${objectName} => Histórico - Tempo de operação do sprinkler na semana atual`,
1416
- nl: `${objectName} => Geschiedenis - De looptijd van de sprinkler in de huidige kalenderweek`,
1417
- fr: `${objectName} => Historique - Durée du gicleur pour la semaine civile en cours`,
1418
- it: `${objectName} => Cronologia - Durata dell'irrigatore nella settimana corrente`,
1419
- es: `${objectName} => Historia: duración de los rociadores de la semana actual`,
1420
- pl: `${objectName} => Historia - Czas pracy tryskacza bieżącego tygodnia kalendarzowego`,
1421
- uk: `${objectName} => Історія - Час роботи спринклера поточного календарного тижня`,
1422
- "zh-cn": `${objectName} => 历史-当前日历周的洒水器运行时间`
1463
+ name: `${ objectName } => History - Sprinkler running time of the current calendar week`,
1464
+ desc: {
1465
+ en: "Sprinkler running time of the current calendar week",
1466
+ de: "Sprinkler-Laufzeit der aktuellen Kalenderwoche",
1467
+ ru: "Время работы спринклера текущей календарной недели",
1468
+ pt: "Tempo de execução do aspersor da semana calendárica atual",
1469
+ nl: "Draaitijd van de sprinkler van de huidige kalenderweek",
1470
+ fr: "Temps de fonctionnement de l'arroseur de la semaine calendrier actuelle",
1471
+ it: "Tempo di funzionamento dell'irrigatore della settimana calendario corrente",
1472
+ es: "Tiempo de funcionamiento del aspersor de la semana calendario actual",
1473
+ pl: "Czas pracy zraszacza w bieżącym tygodniu kalendarzowym",
1474
+ uk: "Время работы спринклера текущей календарной недели",
1475
+ 'zh-cn': "当前日历周的喷灌运行时间"
1423
1476
  },
1424
1477
  type: 'string',
1425
1478
  read: true,
@@ -1430,22 +1483,23 @@ async function createSprinklers() {
1430
1483
  });
1431
1484
  // Create Object for .history.lastCalWeekConsumed
1432
1485
  // Sprinkler consumption of the last calendar week => History - Sprinkler-Verbrauch der letzten Kalenderwoche (783 Liter)
1433
- const _lastCalWeekConsumedNotExist = adapter.setObjectNotExistsAsync(`${objPfad}.history.lastCalWeekConsumed`, {
1486
+ const _lastCalWeekConsumedNotExist = adapter.setObjectNotExistsAsync(`${ objPfad }.history.lastCalWeekConsumed`, {
1434
1487
  type: 'state',
1435
1488
  common: {
1436
1489
  role: 'state',
1437
- name: {
1438
- en: `${objectName} => History - Sprinkler consumption of the last calendar week`,
1439
- de: `${objectName} => Verlauf Sprinklerverbrauch der letzten Woche`,
1440
- ru: `${objectName} => История - потребление спринклеров за последнюю календарную неделю`,
1441
- pt: `${objectName} => Histórico - Consumo de sprinklers na última semana`,
1442
- nl: `${objectName} => Geschiedenis - Sprinklerverbruik van de laatste kalenderweek`,
1443
- fr: `${objectName} => Historique - Consommation de gicleurs la semaine dernière`,
1444
- it: `${objectName} => Cronologia - Consumo di irrigatori nell'ultima settimana`,
1445
- es: `${objectName} => Historia: consumo de rociadores de la última semana natural`,
1446
- pl: `${objectName} => Historia - Zużycie tryskaczy w ostatnim tygodniu kalendarzowym`,
1447
- uk: `${objectName} => Історія - Споживання спринклерів за останній календарний тиждень`,
1448
- "zh-cn": `${objectName} => 历史-上个日历周的洒水消耗量`
1490
+ name: `${ objectName } => History - Sprinkler consumption of the last calendar week`,
1491
+ desc: {
1492
+ en: "Sprinkler consumption of the last calendar week",
1493
+ de: "Sprinkler-Verbrauch der letzten Kalenderwoche",
1494
+ ru: "Расход полива последней календарной недели",
1495
+ pt: "Consumo de aspersão da última semana calendárica",
1496
+ nl: "Verbruik van spuiting van de laatste kalenderweek",
1497
+ fr: "Consommation d'arrosage de la dernière semaine calendrier",
1498
+ it: "Consumo di irrigazione dell'ultima settimana calendario",
1499
+ es: "Consumo de riego de la última semana calendario",
1500
+ pl: "Zużycie nawadniania w ostatnim tygodniu kalendarzowym",
1501
+ uk: "Витрата поливу последней календарной недели",
1502
+ 'zh-cn': "上一个日历周的喷灌消耗量"
1449
1503
  },
1450
1504
  type: 'number',
1451
1505
  unit: 'Liter',
@@ -1457,22 +1511,23 @@ async function createSprinklers() {
1457
1511
  });
1458
1512
  // Create Object for .history.lastCalWeekRunningTime
1459
1513
  // Sprinkler running time of the last calendar week => History - Sprinkler-Laufzeit der letzten Kalenderwoche (783 Liter)
1460
- const _lastCalWeekRunningTimeNotExist = adapter.setObjectNotExistsAsync(`${objPfad}.history.lastCalWeekRunningTime`, {
1514
+ const _lastCalWeekRunningTimeNotExist = adapter.setObjectNotExistsAsync(`${ objPfad }.history.lastCalWeekRunningTime`, {
1461
1515
  type: 'state',
1462
1516
  common: {
1463
1517
  role: 'state',
1464
- name: {
1465
- en: `${objectName} => History - Sprinkler running time of the last calendar week`,
1466
- de: `${objectName} => Verlauf Sprinklerlaufzeit der letzten Woche`,
1467
- ru: `${objectName} => История - Время работы спринклеров за последнюю календарную неделю`,
1468
- pt: `${objectName} => Histórico - Tempo de operação do sprinkler na última semana`,
1469
- nl: `${objectName} => Geschiedenis - De looptijd van de sprinkler van de laatste kalenderweek`,
1470
- fr: `${objectName} => Historique - Durée de fonctionnement du gicleur la semaine dernière`,
1471
- it: `${objectName} => Storia - Durata dell'irrigatore nell'ultima settimana`,
1472
- es: `${objectName} => Historia: funcionamiento de los rociadores de la última semana`,
1473
- pl: `${objectName} => Historia - Czas pracy tryskacza w ostatnim tygodniu kalendarzowym`,
1474
- uk: `${objectName} => Історія - Час роботи спринклерів за останній календарний тиждень`,
1475
- "zh-cn": `${objectName} => 历史-上个日历周的洒水器运行时间`
1518
+ name: `${ objectName } => History - Sprinkler running time of the last calendar week`,
1519
+ desc: {
1520
+ en: "Sprinkler running time of the last calendar week",
1521
+ de: "Sprinkler-Laufzeit der letzten Kalenderwoche",
1522
+ ru: "Время работы спринклера последней календарной недели",
1523
+ pt: "Tempo de execução do aspersor da última semana calendárica",
1524
+ nl: "Draaitijd van de sprinkler van de laatste kalenderweek",
1525
+ fr: "Temps de fonctionnement de l'arroseur de la dernière semaine calendrier",
1526
+ it: "Tempo di funzionamento dell'irrigatore dell'ultima settimana calendario",
1527
+ es: "Tiempo de funcionamiento del aspersor de la última semana calendario",
1528
+ pl: "Czas pracy zraszacza w ostatnim tygodniu kalendarzowym",
1529
+ uk: "Время работы спринклера последней календарной недели",
1530
+ 'zh-cn': "上一个日历周的喷灌运行时间"
1476
1531
  },
1477
1532
  type: 'string',
1478
1533
  read: true,
@@ -1483,22 +1538,23 @@ async function createSprinklers() {
1483
1538
  });
1484
1539
  // Create Object for .history.lastConsumed
1485
1540
  // Last consumed of sprinkler => History - Letzte Verbrauchsmenge des Ventils (783 Liter)
1486
- const _lastConsumedNotExist = adapter.setObjectNotExistsAsync(`${objPfad}.history.lastConsumed`, {
1541
+ const _lastConsumedNotExist = adapter.setObjectNotExistsAsync(`${ objPfad }.history.lastConsumed`, {
1487
1542
  type: 'state',
1488
1543
  common: {
1489
1544
  role: 'state',
1490
- name: {
1491
- en: `${objectName} => History - Last consumed of sprinkler`,
1492
- de: `${objectName} => Historie — Letzter Sprinklerverbrauch`,
1493
- ru: `${objectName} => История - Последнее потребление спринклера`,
1494
- pt: `${objectName} => Histórico - Último consumo do aspersor`,
1495
- nl: `${objectName} => Geschiedenis - Sprinkler voor het laatst verbruikt`,
1496
- fr: `${objectName} => Historique - Dernier gicleur consommé`,
1497
- it: `${objectName} => Storia - Ultimo uso di irrigatore`,
1498
- es: `${objectName} => Historia: rociador consumido por última vez`,
1499
- pl: `${objectName} => Historia - Ostatnie zużycie tryskacza`,
1500
- uk: `${objectName} => Історія - Останнє споживання спринклера`,
1501
- "zh-cn": `${objectName} => 历史-上次消耗的洒水器`
1545
+ name: `${ objectName } => History - Last consumed of sprinkler`,
1546
+ desc: {
1547
+ en: "Last consumed of sprinkler",
1548
+ de: "Letzte Verbrauchsmenge des Ventils",
1549
+ ru: "Последнее потребление спринклера",
1550
+ pt: "Último consumo do aspersor",
1551
+ nl: "Laatste verbruik van de sprinkler",
1552
+ fr: "Dernier consommé de l'arroseur",
1553
+ it: "Ultimo consumo dell'irrigatore",
1554
+ es: "Último consumo del aspersor",
1555
+ pl: "Ostatnie zużycie zraszacza",
1556
+ uk: "Останній витрата спринклера",
1557
+ 'zh-cn': "喷灌器的最后消耗量"
1502
1558
  },
1503
1559
  type: 'number',
1504
1560
  unit: 'Liter',
@@ -1510,22 +1566,23 @@ async function createSprinklers() {
1510
1566
  });
1511
1567
  // Create Object for .history.lastOn
1512
1568
  // Last On of sprinkler => History - Letzter Start des Ventils (30.03 06:30)
1513
- const _lastOnNotExist = adapter.setObjectNotExistsAsync(`${objPfad}.history.lastOn`, {
1569
+ const _lastOnNotExist = adapter.setObjectNotExistsAsync(`${ objPfad }.history.lastOn`, {
1514
1570
  type: 'state',
1515
1571
  common: {
1516
1572
  role: 'state',
1517
- name: {
1518
- en: `${objectName} => History - Last On of sprinkler`,
1519
- de: `${objectName} => Historie — Letzter Start des Sprinkler`,
1520
- ru: `${objectName} => История - Последний включитель спринклера`,
1521
- pt: `${objectName} => História - Último aspersor`,
1522
- nl: `${objectName} => Geschiedenis - De laatste sprinkler`,
1523
- fr: `${objectName} => Histoire - Dernier gicleur`,
1524
- it: `${objectName} => Storia - Ultimo irrigatore`,
1525
- es: `${objectName} => Historia: el último rociador`,
1526
- pl: `${objectName} => Historia - Ostatnie włączenie tryskacza`,
1527
- uk: `${objectName} => Історія - Остання увімкнення спринклера`,
1528
- "zh-cn": `${objectName} => 历史-洒水器的最后一次`
1573
+ name: `${ objectName } => History - Last On of sprinkler`,
1574
+ desc: {
1575
+ en: "Last On of sprinkler",
1576
+ de: "Letzter Start des Ventils",
1577
+ ru: "Последний запуск спринклера",
1578
+ pt: "Última Ativação do aspersor",
1579
+ nl: "Laatste start van de sprinkler",
1580
+ fr: "Dernier démarrage de l'arroseur",
1581
+ it: "Ultimo avvio dell'irrigatore",
1582
+ es: "Último encendido del aspersor",
1583
+ pl: "Ostatnie włączenie zraszacza",
1584
+ uk: "Останній запуск спринклера",
1585
+ 'zh-cn': "喷灌器的最后启动时间"
1529
1586
  },
1530
1587
  type: 'string',
1531
1588
  read: true,
@@ -1536,22 +1593,23 @@ async function createSprinklers() {
1536
1593
  });
1537
1594
  // Create Object for .history.lastRunningTime
1538
1595
  // Last running time of sprinkler => History - Letzte Laufzeit des Ventils (0 sek, 47:00 min, 1:03:45 )
1539
- const _lastRunningTimeNotExist = adapter.setObjectNotExistsAsync(`${objPfad}.history.lastRunningTime`, {
1596
+ const _lastRunningTimeNotExist = adapter.setObjectNotExistsAsync(`${ objPfad }.history.lastRunningTime`, {
1540
1597
  type: 'state',
1541
1598
  common: {
1542
1599
  role: 'state',
1543
- name: {
1544
- en: `${objectName} => History - Last running time`,
1545
- de: `${objectName} => Verlauf Letzte Laufzeit`,
1546
- ru: `${objectName} => История - время последнего запуска`,
1547
- pt: `${objectName} => Histórico - Última execução`,
1548
- nl: `${objectName} => Geschiedenis - Laatste speeltijd`,
1549
- fr: `${objectName} => Historique - Dernière diffusion`,
1550
- it: `${objectName} => Storia - Ultima durata`,
1551
- es: `${objectName} => Historia: última edición`,
1552
- pl: `${objectName} => Historia - Ostatni czas trwania`,
1553
- uk: `${objectName} => Історія - Останній час роботи`,
1554
- "zh-cn": `${objectName} => 历史-上次运行时间`
1600
+ name: `${ objectName } => History - Last running time`,
1601
+ desc: {
1602
+ en: "Last running time of sprinkler",
1603
+ de: "Letzte Laufzeit des Ventils",
1604
+ ru: "Последнее время работы спринклера",
1605
+ pt: "Último tempo de funcionamento do aspersor",
1606
+ nl: "Laatste draaitijd van de sprinkler",
1607
+ fr: "Dernier temps de fonctionnement de l'arroseur",
1608
+ it: "Ultimo tempo di funzionamento dell'irrigatore",
1609
+ es: "Último tiempo de funcionamiento del aspersor",
1610
+ pl: "Ostatni czas pracy zraszacza",
1611
+ uk: "Останній час роботи спринклера",
1612
+ 'zh-cn': "喷灌器的最后运行时间"
1555
1613
  },
1556
1614
  type: 'string',
1557
1615
  read: true,
@@ -1561,22 +1619,23 @@ async function createSprinklers() {
1561
1619
  native: {},
1562
1620
  });
1563
1621
  // Create Object for .autoOn
1564
- const _autoOnNotExist = adapter.setObjectNotExistsAsync(`${objPfad}.autoOn`, {
1622
+ const _autoOnNotExist = adapter.setObjectNotExistsAsync(`${ objPfad }.autoOn`, {
1565
1623
  type: 'state',
1566
1624
  common: {
1567
1625
  role: 'Switch',
1568
- name: {
1569
- en: `${objectName} => Switch automatic mode on / off`,
1570
- de: `${objectName} => Automatik ein-/ausschalten`,
1571
- ru: `${objectName} => Включить/выключить автоматический режим`,
1572
- pt: `${objectName} => Liga/desliga o modo automático`,
1573
- nl: `${objectName} => Automatische modus in- en uitschakelen`,
1574
- fr: `${objectName} => Activer/désactiver le mode automatique`,
1575
- it: `${objectName} => Attiva/spegne automaticamente`,
1576
- es: `${objectName} => Activar/desactivar el modo automático`,
1577
- pl: `${objectName} => Włączanie/wyłączanie trybu automatycznego`,
1578
- uk: `${objectName} => Увімкнути/вимкнути автоматичний режим`,
1579
- "zh-cn": `${objectName} => 开启/关闭自动模式`
1626
+ name: `${ objectName } => Switch automatic mode on / off`,
1627
+ desc: {
1628
+ en: "Switch automatic mode on / off",
1629
+ de: "Automatikmodus ein / aus schalten",
1630
+ ru: "Включить / отключить автоматический режим",
1631
+ pt: "Alternar modo automático ligado / desligado",
1632
+ nl: "Automatische modus aan / uit schakelen",
1633
+ fr: "Basculer le mode automatique activé / désactivé",
1634
+ it: "Attiva/disattiva modalità automatica",
1635
+ es: "Cambiar modo automático encendido / apagado",
1636
+ pl: "Przełącz tryb automatyczny włączony / wyłączony",
1637
+ uk: "Увімкнути / вимкнути автоматичний режим",
1638
+ 'zh-cn': "切换自动模式开启/关闭"
1580
1639
  },
1581
1640
  type: 'boolean',
1582
1641
  states: {
@@ -1589,13 +1648,52 @@ async function createSprinklers() {
1589
1648
  },
1590
1649
  native: {},
1591
1650
  }).catch((e) => adapter.log.warn(`setObjectNotExistsAsync ${objectName}.autoOn ${e}`));
1651
+ // Create Object for .break
1652
+ const _extBreakNotExist = adapter.setObjectNotExistsAsync(`${ objPfad }.extBreak`, {
1653
+ type: 'state',
1654
+ common: {
1655
+ role: 'Switch',
1656
+ name: `${ objectName } => Switch extBreak mode on / off`,
1657
+ desc: {
1658
+ en: "Switch external break mode on / off",
1659
+ de: "Externer Brechmodus ein / aus schalten",
1660
+ ru: "Включить / отключить внешний режим прерывания",
1661
+ pt: "Alternar modo de interrupção externa ligado / desligado",
1662
+ nl: "Externe onderbrekingsmodus aan / uit schakelen",
1663
+ fr: "Basculer le mode de coupure externe activé / désactivé",
1664
+ it: "Attiva/disattiva modalità di interruzione esterna",
1665
+ es: "Cambiar modo de interrupción externa encendido / apagado",
1666
+ pl: "Przełącz tryb zewnętrznego przerwania włączony / wyłączony",
1667
+ uk: "Увімкнути / вимкнути зовнішній режим переривання",
1668
+ 'zh-cn': "切换外部中断模式开启/关闭"
1669
+ },
1670
+ type: 'boolean',
1671
+ states: {
1672
+ false: 'off',
1673
+ true: 'on'
1674
+ },
1675
+ read: true,
1676
+ write: true,
1677
+ def: false
1678
+ },
1679
+ native: {},
1680
+ }).catch((e) => adapter.log.warn(`setObjectNotExistsAsync ${objectName}.extBreak ${e}`));
1592
1681
  // Create Object for .actualSoilMoisture
1593
- const _actualSoilMoistureFind = await adapter.findForeignObjectAsync(`${adapter.namespace}.${objPfad}.actualSoilMoisture`, `${objMetConSM.common.type}`);
1594
- if (_actualSoilMoistureFind.id !== `${adapter.namespace}.${objPfad}.actualSoilMoisture` || _actualSoilMoistureFind.name !== nameMetConSM) {
1682
+ const _actualSoilMoistureFind = await adapter.findForeignObjectAsync(`${ adapter.namespace }.${ objPfad }.actualSoilMoisture`, `${ _fillMetConSM.objMetConSM.common.type }`);
1683
+ if (_fillMetConSM && _actualSoilMoistureFind
1684
+ && _actualSoilMoistureFind.id !== `${ adapter.namespace }.${ objPfad }.actualSoilMoisture`
1685
+ || _actualSoilMoistureFind.name !== _fillMetConSM.nameMetConSM) {
1595
1686
  await adapter.setObjectAsync(
1596
- `${objPfad}.actualSoilMoisture`,
1597
- objMetConSM
1598
- ).catch((e) => adapter.log.warn(e));
1687
+ `${ objPfad }.actualSoilMoisture`,
1688
+ //@ts-ignore
1689
+ _fillMetConSM.objMetConSM
1690
+ ).catch((e) => adapter.log.warn(`.actualSoilMoisture: ${e}`));
1691
+ if (_fillMetConSM.objMetConSM.common.def) {
1692
+ await adapter.setStateAsync(`${ objPfad }.actualSoilMoisture`, {
1693
+ val: _fillMetConSM.objMetConSM.common.def,
1694
+ ack: true
1695
+ }).catch((e) => adapter.log.warn(`.actualSoilMoisture: ${e}`));
1696
+ }
1599
1697
  adapter.log.info(`sprinkleControl [sprinkle.${objectName}.actualSoilMoisture] was updated`);
1600
1698
  }
1601
1699
 
@@ -1605,22 +1703,23 @@ async function createSprinklers() {
1605
1703
  && res.methodControlSM === 'fixDay'
1606
1704
  && (res.startDay === 'twoNd'
1607
1705
  || res.startDay === 'threeRd')) {
1608
- await adapter.setObjectNotExistsAsync(`${objPfad}.postponeByOneDay`, {
1706
+ await adapter.setObjectNotExistsAsync(`${ objPfad }.postponeByOneDay`, {
1609
1707
  type: 'state',
1610
1708
  common: {
1611
1709
  role: 'button',
1612
- name: {
1613
- en: `${objectName} Postpone start by one day`,
1614
- de: `${objectName} Start um einen Tag verschieben`,
1615
- ru: `${objectName} Отложите начало на один день`,
1616
- pt: `${objectName} Adie o início em um dia`,
1617
- nl: `${objectName} Start met een dag uitstellen`,
1618
- fr: `${objectName} Reporter le début d'un jour`,
1619
- it: `${objectName} Rinviare l'inizio di un giorno`,
1620
- es: `${objectName} Posponer un día el inicio`,
1621
- pl: `${objectName} Odłóż początek o jeden dzień`,
1622
- uk: `${objectName} Відкладіть початок на один день`,
1623
- "zh-cn": `${objectName} 推迟一天开始`
1710
+ name: `${ objectName }Postpone start by one day`,
1711
+ desc: {
1712
+ en: "Postpone start by one day",
1713
+ de: "Start um einen Tag verschieben",
1714
+ ru: "Отложить запуск на один день",
1715
+ pt: "Adiar o início por um dia",
1716
+ nl: "Start met een dag vertraging",
1717
+ fr: "Reporter le démarrage d'un jour",
1718
+ it: "Ritarda l'avvio di un giorno",
1719
+ es: "Retrasar el inicio por un día",
1720
+ pl: "Opóźnij start o jeden dzień",
1721
+ uk: "Відкласти запуск на один день",
1722
+ 'zh-cn': "推迟一天开始"
1624
1723
  },
1625
1724
  type: 'boolean',
1626
1725
  read: true,
@@ -1648,22 +1747,23 @@ async function createSprinklers() {
1648
1747
  }
1649
1748
 
1650
1749
  // Create Object for .countdown => Countdown des Ventils
1651
- const _countdownNotExist = adapter.setObjectNotExistsAsync(`${objPfad}.countdown`, {
1750
+ const _countdownNotExist = await adapter.setObjectNotExistsAsync(`${ objPfad }.countdown`, {
1652
1751
  type: 'state',
1653
1752
  common: {
1654
1753
  role: 'state',
1655
- name: {
1656
- en: `${objectName} => countdown of sprinkler`,
1657
- de: `${objectName} => Sprinkler-Countdown`,
1658
- ru: `${objectName} => обратный отсчет времени спринклера`,
1659
- pt: `${objectName} => contagem do aspersor`,
1660
- nl: `${objectName} => aftellen van de sprinkler`,
1661
- fr: `${objectName} => compte à rebours`,
1662
- it: `${objectName} => conto alla rovescia`,
1663
- es: `${objectName} => cuenta atrás del aspersor`,
1664
- pl: `${objectName} => odliczanie tryskacza`,
1665
- uk: `${objectName} => зворотний відлік спринклера`,
1666
- "zh-cn": `${objectName} => 洒水器倒计时`
1754
+ name: `${ objectName } => countdown of sprinkler`,
1755
+ desc: {
1756
+ en: "Countdown of sprinkler",
1757
+ de: "Countdown des Ventils",
1758
+ ru: "Отсчет времени до запуска",
1759
+ pt: "Contagem regressiva do aspersor",
1760
+ nl: "Aftellen van sprinkler",
1761
+ fr: "Compte à rebours du pulvérisateur",
1762
+ it: "Conto alla rovescia dell'aspersore",
1763
+ es: "Cuenta regresiva del rociador",
1764
+ pl: "Odliczanie czasu do włączenia",
1765
+ uk: "Зворотній відлік до запуску",
1766
+ 'zh-cn': "喷头倒计时"
1667
1767
  },
1668
1768
  type: 'string',
1669
1769
  read: true,
@@ -1673,22 +1773,23 @@ async function createSprinklers() {
1673
1773
  native: {},
1674
1774
  });
1675
1775
  // Create Object for .runningTime => Laufzeit des Ventils
1676
- const _runningTimeNotExist = await adapter.setObjectNotExistsAsync(`${objPfad}.runningTime`, {
1776
+ const _runningTimeNotExist = await adapter.setObjectNotExistsAsync(`${ objPfad }.runningTime`, {
1677
1777
  type: 'state',
1678
1778
  common: {
1679
1779
  role: 'state',
1680
- name: {
1681
- en: `${objectName} => running time of sprinkler`,
1682
- de: `${objectName} => Laufzeit des Sprinklers`,
1683
- ru: `${objectName} => время работы спринклера`,
1684
- pt: `${objectName} => duração do aspersor`,
1685
- nl: `${objectName} => looptijd van de sprinkler`,
1686
- fr: `${objectName} => durée de fonctionnement du gicleur`,
1687
- it: `${objectName} => durata dell'irrigatore`,
1688
- es: `${objectName} => duración del rociador`,
1689
- pl: `${objectName} => czas pracy zraszacza`,
1690
- uk: `${objectName} => час роботи спринклера`,
1691
- "zh-cn": `${objectName} => 洒水器的运行时间`
1780
+ name: `${ objectName } => running time of sprinkler`,
1781
+ desc: {
1782
+ en: "Running time of sprinkler",
1783
+ de: "Laufzeit des Ventils",
1784
+ ru: "Время работы спринклера",
1785
+ pt: "Tempo de funcionamento do aspersor",
1786
+ nl: "Draaitijd van de sprinkler",
1787
+ fr: "Temps de fonctionnement de l'arroseur",
1788
+ it: "Tempo di funzionamento dell'irrigatore",
1789
+ es: "Tiempo de funcionamiento del aspersor",
1790
+ pl: "Czas pracy zraszacza",
1791
+ uk: "Время работы спринклера",
1792
+ 'zh-cn': "喷头运行时间"
1692
1793
  },
1693
1794
  type: 'string',
1694
1795
  read: true,
@@ -1698,60 +1799,79 @@ async function createSprinklers() {
1698
1799
  native: {},
1699
1800
  });
1700
1801
  // Create Object for .sprinklerState => Zustand des Ventils im Thread
1701
- // <<< 1 = warten >>> ( 0:off; 1:wait; 2:on; 3:break; 4:Boost(on); 5:off(Boost) )
1802
+ // <<< 1 = warten >>> (0:off; 1:wait; 2:on; 3:break; 4:Boost(on); 5:off(Boost); 6:Cistern empty; 7:extBreak)
1702
1803
  // Create .sprinklerState
1703
- const _sprinklerStateNotExists = await adapter.setObjectNotExistsAsync(`${objPfad}.sprinklerState`, {
1804
+ const _sprinklerStateNotExists = await adapter.setObjectNotExistsAsync(`${ objPfad }.sprinklerState`, {
1704
1805
  type: 'state',
1705
1806
  common: {
1706
1807
  role: 'state',
1707
- name: {
1708
- en: `${objectName} => actual state of sprinkler`,
1709
- de: `${objectName} => Stand der Sprinkleranlage`,
1710
- ru: `${objectName} => фактическое состояние спринклера`,
1711
- pt: `${objectName} => estado real do aspersor`,
1712
- nl: `${objectName} => werkelijke toestand van de sprinkler`,
1713
- fr: `${objectName} => état actuel du gicleur`,
1714
- it: `${objectName} => stato attuale dell'irrigatore`,
1715
- es: `${objectName} => estado actual del rociador`,
1716
- pl: `${objectName} => rzeczywisty stan tryskacza`,
1717
- uk: `${objectName} => фактичний стан спринклера`,
1718
- "zh-cn": `${objectName} => 洒水器的实际状态`
1808
+ name: `${ objectName } => actual state of sprinkler`,
1809
+ desc: {
1810
+ en: "Actual state of sprinkler",
1811
+ de: "Aktueller Zustand des Ventils",
1812
+ ru: "Текущее состояние спринклера",
1813
+ pt: "Estado atual do aspersor",
1814
+ nl: "Huidige staat van de sprinkler",
1815
+ fr: "État actuel du pulvérisateur",
1816
+ it: "Stato attuale dell'aspersore",
1817
+ es: "Estado actual del rociador",
1818
+ pl: "Aktualny stan zraszacza",
1819
+ uk: "Поточний стан спринклера",
1820
+ 'zh-cn': "喷头当前状态"
1719
1821
  },
1720
- type: 'number',
1721
- min: 0,
1722
- max: 5,
1723
- states: {
1724
- 0: 'off',
1725
- 1: 'wait',
1726
- 2: 'on',
1727
- 3: 'break',
1728
- 4: 'Boost(on)',
1729
- 5: 'off(Boost)'
1822
+ type: 'string',
1823
+ read: true,
1824
+ write: false,
1825
+ def: 'off'
1826
+ },
1827
+ native: {},
1828
+ });
1829
+ // Create Object for .valveOn => Zustand des Ventils (on/off)
1830
+ const _valveOnNotExist = await adapter.setObjectNotExistsAsync(`${ objPfad }.valveOn`, {
1831
+ type: 'state',
1832
+ common: {
1833
+ role: 'state',
1834
+ name: `${ objectName } => actual valve state on/off`,
1835
+ desc: {
1836
+ en: "Actual valve state on/off",
1837
+ de: "Aktueller Ventilzustand an/aus",
1838
+ ru: "Текущее состояние клапана вкл/выкл",
1839
+ pt: "Estado atual da válvula ligado/desligado",
1840
+ nl: "Huidige staat van de klep aan/uit",
1841
+ fr: "État actuel de la vanne ouverte/fermée",
1842
+ it: "Stato attuale della valvola acceso/spento",
1843
+ es: "Estado actual de la válvula encendida/apagada",
1844
+ pl: "Aktualny stan zaworu włączony/wyłączony",
1845
+ uk: "Поточний стан клапана увімкнено/вимкнено",
1846
+ 'zh-cn': "阀门当前开/关状态"
1730
1847
  },
1848
+ type: 'boolean',
1731
1849
  read: true,
1732
1850
  write: false,
1733
- def: 0
1851
+ def: false
1734
1852
  },
1735
1853
  native: {},
1736
1854
  });
1855
+
1737
1856
  // Create Object for triggerPoint → Schaltpunkt der Bodenfeuchte
1738
- const _triggerPointNotExist = await adapter.setObjectNotExistsAsync(`${objPfad}.triggerPoint`, {
1857
+ const _triggerPointNotExist = await adapter.setObjectNotExistsAsync(`${ objPfad }.triggerPoint`, {
1739
1858
  type: 'state',
1740
1859
  common: {
1741
1860
  role: 'state',
1742
- name: {
1743
- en: `${objectName} => Trigger point of sprinkler`,
1744
- de: `${objectName} => Schaltpunkt des Sprinklers`,
1745
- ru: `${objectName} => Точка срабатывания спринклера`,
1746
- pt: `${objectName} => Ponto de gatilho do aspersor`,
1747
- nl: `${objectName} => Triggerpunt van de sprinkler`,
1748
- fr: `${objectName} => Point de déclenchement du gicleur`,
1749
- it: `${objectName} => Punto di innesco`,
1750
- es: `${objectName} => Punto de activación del aspersor`,
1751
- pl: `${objectName} => Punkt spustowy zraszacza`,
1752
- uk: `${objectName} => Тригерна точка спринклера`,
1753
- "zh-cn": `${objectName} => 洒水器的触发点`
1754
- },
1861
+ name: `${ objectName } => Trigger point of sprinkler`,
1862
+ desc: {
1863
+ en: "Trigger point of sprinkler",
1864
+ de: "Schaltpunkt des Ventils",
1865
+ ru: "Точка срабатывания спринклера",
1866
+ pt: "Ponto de acionamento do aspersor",
1867
+ nl: "Triggerpunt van de sprinkler",
1868
+ fr: "Point déclenchement du pulvérisateur",
1869
+ it: "Punto di attivazione dell'aspersore",
1870
+ es: "Punto de activación del rociador",
1871
+ pl: "Punkt wyzwalania zraszacza",
1872
+ uk: "Точка срабатывания спринклера",
1873
+ 'zh-cn': "喷头触发点"
1874
+ },
1755
1875
  type: 'string',
1756
1876
  read: true,
1757
1877
  write: false,
@@ -1761,7 +1881,7 @@ async function createSprinklers() {
1761
1881
  });
1762
1882
  // Object created
1763
1883
  let value = true;
1764
- (await Promise.all([
1884
+ await Promise.all([
1765
1885
  _sprinkleNotExist,
1766
1886
  _historyNotExist,
1767
1887
  _curCalWeekConsumedNotExist,
@@ -1772,17 +1892,58 @@ async function createSprinklers() {
1772
1892
  _lastOnNotExist,
1773
1893
  _lastRunningTimeNotExist,
1774
1894
  _autoOnNotExist,
1895
+ _extBreakNotExist,
1775
1896
  _countdownNotExist,
1776
1897
  _runningTimeNotExist,
1777
1898
  _sprinklerStateNotExists,
1899
+ _valveOnNotExist,
1778
1900
  _triggerPointNotExist
1779
- ])).forEach((val) => {
1780
- value &= val;
1901
+ ]).then((values) => {
1902
+ values.forEach(val => {
1903
+ if (!val) {
1904
+ value = false;
1905
+ }
1906
+ });
1781
1907
  });
1908
+
1782
1909
  if(value) {
1783
1910
  adapter.log.info(`sprinkleControl [sprinkle.${objectName}] was created`);
1784
1911
  }
1785
1912
 
1913
+ // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
1914
+ // +++++ zustände der States auf Startposition +++++ //
1915
+ // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
1916
+ //
1917
+ adapter.log.debug(`_countdownNotExist: ${_countdownNotExist}`);
1918
+ if(_countdownNotExist == undefined){
1919
+ const _countdown = await adapter.getStateAsync(`${objPfad}.countdown`).catch((e) => adapter.log.warn(`${objectName}.countdown ${e}`));
1920
+ if (_countdown?.val !== '0') {
1921
+ adapter.setStateAsync(`${objPfad}.countdown`, {
1922
+ val: '0',
1923
+ ack: true
1924
+ }).catch((e) => adapter.log.warn(e));
1925
+ }
1926
+ }
1927
+ //
1928
+ if (_runningTimeNotExist == undefined) {
1929
+ const _runningTime = await adapter.getStateAsync(`${objPfad}.runningTime`).catch((e) => adapter.log.warn(`${objectName}.runningTime ${e}`));
1930
+ if (_runningTime?.val !== '00:00') {
1931
+ adapter.setStateAsync(`${objPfad}.runningTime`, {
1932
+ val: '00:00',
1933
+ ack: true
1934
+ }).catch((e) => adapter.log.warn(e));
1935
+ }
1936
+ }
1937
+ //
1938
+ if (_sprinklerStateNotExists == undefined){
1939
+ const _sprinklerState = await adapter.getStateAsync(`${objPfad}.sprinklerState`).catch((e) => adapter.log.warn(`${objectName}.sprinklerState ${e}`));
1940
+ if (_sprinklerState?.val !== 'off') {
1941
+ await adapter.setStateAsync(`${objPfad}.sprinklerState`, {
1942
+ val: 'off',
1943
+ ack: true
1944
+ }).catch((e) => adapter.log.warn(`${objectName}.sprinklerState ${e}`));
1945
+ }
1946
+ }
1786
1947
  // Festlegen des Schaltpunktes für den nächsten Start
1787
1948
  switch (myConfig.config[j].methodControlSM) {
1788
1949
  case 'bistable': {
@@ -1795,251 +1956,261 @@ async function createSprinklers() {
1795
1956
  adapter.log.warn(`The bistable sensor ${myConfig.config[j].triggerSM} in ${objectName} does not deliver correct values!`);
1796
1957
  }
1797
1958
 
1798
- adapter.setStateAsync(`${objPfad}.triggerPoint`, {
1959
+ adapter.setStateAsync(`${ objPfad }.triggerPoint`, {
1799
1960
  val: '-',
1800
- ack: true
1961
+ ack: true
1801
1962
  }).catch((e) => adapter.log.warn(`${objectName}.triggerPoint ${e}`));
1802
1963
  break;
1803
1964
  }
1804
-
1805
1965
  case 'analog': {
1806
1966
  // Sensor soil moisture => Sensor Bodenfeuchte
1807
1967
  const _triggerSMAnalog = await adapter.getForeignStateAsync(myConfig.config[j].triggerSM).catch((e) => adapter.log.warn(`${objectName}.triggerSMAnalog ${e}`));
1808
1968
  if (_triggerSMAnalog && (typeof _triggerSMAnalog.val === 'number' || typeof _triggerSMAnalog.val === 'string')) {
1809
1969
  myConfig.setSoilMoistPct(myConfig.config[j].sprinkleID, _triggerSMAnalog.val);
1810
1970
  } else {
1811
- await adapter.setStateAsync(`${objPfad}.actualSoilMoisture`, {
1971
+ await adapter.setStateAsync(`${ objPfad }.actualSoilMoisture`, {
1812
1972
  val: 50,
1813
1973
  ack: true
1814
1974
  });
1815
1975
  adapter.log.warn(`The analoge sensor ${myConfig.config[j].triggerSM} in ${objectName} does not deliver correct values!`);
1816
1976
  }
1817
- adapter.setStateAsync(`${objPfad}.triggerPoint`, {
1818
- val: (myConfig.config[j].soilMoisture.pctTriggerIrrigation).toString(),
1977
+ adapter.setStateAsync(`${ objPfad }.triggerPoint`, {
1978
+ val: `${myConfig.config[j].analog.pctTriggerIrrigation}`,
1819
1979
  ack: true
1820
1980
  }).catch((e) => adapter.log.warn(`${objectName}.triggerPoint setState ${e}`));
1821
1981
  break;
1822
1982
  }
1823
-
1824
1983
  case 'fixDay': {
1825
- const nextStartDay = ((today + 1) > 6 ? 0 : (today + 1));
1826
-
1827
- /**
1828
- * Neuen Start-Tag für Dreitage- und Zweitage-modus setzen
1829
- *
1830
- * @param threeRd - Dreitage-modus Ja/Nein
1831
- * true → Dreitage-modus (treeRD)
1832
- * false → Zweitage-modus (twoNd)
1833
- */
1834
- async function setNewDay (threeRd) {
1835
- const today = await formatTime(adapter,'', 'day');
1836
- const _actualSoilMoisture = await adapter.getStateAsync(
1837
- `${objPfad}.actualSoilMoisture`
1838
- ).catch((e) => adapter.log.warn(`${objectName}.actualSoilMoisture fixDay setState ${e}`));
1839
- if (_actualSoilMoisture && (typeof _actualSoilMoisture.val === 'number')) {
1840
- if ((_actualSoilMoisture.val >= 0) && (_actualSoilMoisture.val <= 6)) {
1841
- if ((threeRd)
1842
- && (_actualSoilMoisture.val === (((today + 3) > 6) ? 2 : (today + 3)))
1843
- || (_actualSoilMoisture.val === (((today + 2) > 6) ? 1 : (today + 2)))
1844
- || (_actualSoilMoisture.val === (((today + 1) > 6) ? 0 : (today + 1)))
1845
- || (_actualSoilMoisture.val === today)) {
1846
- myConfig.config[j].startFixDay[_actualSoilMoisture.val] = true;
1847
- } else {
1848
- myConfig.config[j].startFixDay[nextStartDay] = true;
1849
- }
1850
- } else {
1851
- myConfig.config[j].startFixDay[nextStartDay] = true;
1852
- }
1853
- curNextFixDay(myConfig.config[j].sprinkleID, false);
1854
- }
1855
- }
1856
1984
 
1857
- if (myConfig.config[j].startDay === 'threeRd') {
1858
- await setNewDay(true);
1859
- } else if (myConfig.config[j].startDay === 'twoNd') {
1860
- await setNewDay(false);
1861
- } else if (myConfig.config[j].startDay === 'fixDay') {
1985
+ if (myConfig.config[j].fixDay.startDay === 'threeRd') {
1986
+ await setNewDay(j, true);
1987
+ } else if (myConfig.config[j].fixDay.startDay === 'twoNd') {
1988
+ await setNewDay(j, false);
1989
+ } else if (myConfig.config[j].fixDay.startDay === 'fixDay') {
1862
1990
  curNextFixDay(myConfig.config[j].sprinkleID, false);
1863
1991
  }
1864
1992
 
1865
- adapter.setStateAsync(`${objPfad}.triggerPoint`, {
1993
+ adapter.setStateAsync(`${ objPfad }.triggerPoint`, {
1866
1994
  val: '-',
1867
1995
  ack: true
1868
1996
  }).catch((e) => adapter.log.warn(`${objectName}.triggerPoint fixDay setState ${e}`));
1869
1997
  break;
1870
1998
  }
1871
-
1872
1999
  case 'calculation': {
1873
- const _actualSoilMoisture = await adapter.getStateAsync(`${objPfad}.actualSoilMoisture`).catch((e) => adapter.log.warn(e));
1874
- if (_actualSoilMoisture) {
1875
- if (await _actualSoilMoisture && typeof _actualSoilMoisture.val !== 'number' || _actualSoilMoisture.val === 0) {
1876
- adapter.setStateAsync(`${objPfad}.actualSoilMoisture`, {
1877
- val: myConfig.config[j].soilMoisture.pct,
1878
- ack: true
1879
- }).catch((e) => adapter.log.warn(e));
1880
- } else {
2000
+
2001
+ const _actualSoilMoisture = await adapter.getStateAsync(`${ objPfad }.actualSoilMoisture`).catch((e) => adapter.log.warn(e));
2002
+ if (_actualSoilMoisture && _actualSoilMoisture.val) {
2003
+ if (typeof _actualSoilMoisture.val === 'number' && _actualSoilMoisture.val !== 0) {
1881
2004
  // num Wert der Bodenfeuchte berechnen und in der config speichern, wenn Wert zwischen 0 und max liegt
1882
- if ((0 < _actualSoilMoisture.val) && (_actualSoilMoisture.val <= (myConfig.config[j]).soilMoisture.maxRain*100/myConfig.config[j].soilMoisture.maxIrrigation)) {
1883
- myConfig.config[j].soilMoisture.val = _actualSoilMoisture.val * myConfig.config[j].soilMoisture.maxIrrigation / 100;
1884
- myConfig.config[j].soilMoisture.pct = _actualSoilMoisture.val;
2005
+ if ((0 < _actualSoilMoisture.val) && (_actualSoilMoisture.val <= (myConfig.config[j]).calculation.maxRain*100/myConfig.config[j].calculation.maxIrrigation)) {
2006
+ myConfig.config[j].calculation.val = _actualSoilMoisture.val * myConfig.config[j].calculation.maxIrrigation / 100;
2007
+ myConfig.config[j].calculation.pct = _actualSoilMoisture.val;
1885
2008
  } else {
1886
2009
  // Wert aus config übernehmen
1887
2010
  adapter.setStateAsync(`${objPfad}.actualSoilMoisture`, {
1888
- val: myConfig.config[j].soilMoisture.pct,
2011
+ val: myConfig.config[j].calculation.pct,
1889
2012
  ack: true
1890
2013
  }).catch((e) => adapter.log.warn(e));
1891
2014
  }
2015
+ } else {
2016
+ adapter.setStateAsync(`${ objPfad }.actualSoilMoisture`, {
2017
+ val: myConfig.config[j].calculation.pct,
2018
+ ack: true
2019
+ }).catch((e) => adapter.log.warn(e));
1892
2020
  }
1893
2021
  }
1894
2022
 
1895
- adapter.setStateAsync(`${objPfad}.triggerPoint`, {
1896
- val: (myConfig.config[j].soilMoisture.pctTriggerIrrigation).toString(),
2023
+ adapter.setStateAsync(`${ objPfad }.triggerPoint`, {
2024
+ val: `${myConfig.config[j].calculation.pctTriggerIrrigation}`,
1897
2025
  ack: true
1898
2026
  }).catch((e) => adapter.log.warn(e));
1899
2027
  break;
1900
2028
  }
1901
2029
  }
1902
-
1903
- } catch (e) {
1904
- adapter.log.warn(`sprinkleControl cannot created ... Please check your sprinkleControl config: ${e}`);
2030
+ } else {
2031
+ adapter.log.warn('sprinkleControl cannot created ... Please check in your config the sprinkle Name');
1905
2032
  }
1906
- } else {
1907
- adapter.log.warn('sprinkleControl cannot created ... Please check in your config the sprinkle Name');
2033
+ } catch (e) {
2034
+ adapter.log.warn(`sprinkleControl cannot created. Please check your sprinkleControl config: ${JSON.stringify(e)}, ${e}`);
1908
2035
  }
1909
2036
  }
2037
+ await delOldSprinklers(result);
2038
+ }
2039
+ }
1910
2040
 
1911
- // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
1912
- // +++++ Objekte löschen +++++ //
1913
- // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
1914
- for(const i in ObjSprinkle) {
2041
+ // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
2042
+ // +++++ Objekte löschen +++++ //
2043
+ // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
2044
+ async function delOldSprinklers(result) {
1915
2045
 
1916
- const resID = ObjSprinkle[i]._id;
1917
- const objectID = resID.split('.');
1918
- const resultID = objectID[3];
2046
+ for(const i in ObjSprinkle) {
1919
2047
 
1920
- const resultName = result.map(({ sprinkleName }) => ({ sprinkleName }));
1921
- const fullRes = [];
2048
+ const resID = ObjSprinkle[i]._id;
2049
+ const objectID = resID.split('.');
2050
+ const resultID = objectID[3];
1922
2051
 
1923
- for(const i in resultName) {
1924
- // @ts-ignore
1925
- if (Object.hasOwn(resultName,i)) {
1926
- const res = resultName[i].sprinkleName.replace(/[.;, ]/g, '_');
1927
- fullRes.push(res);
1928
- }
2052
+ const resultName = result.map(({ sprinkleName }) => ({ sprinkleName }));
2053
+ const fullRes = [];
2054
+
2055
+ for(const i in resultName) {
2056
+ // eslint-disable-next-line no-prototype-builtins
2057
+ if (resultName.hasOwnProperty(i)) {
2058
+ const res = resultName[i].sprinkleName.replace(/[.;, ]/g, '_');
2059
+ fullRes.push(res);
1929
2060
  }
2061
+ }
1930
2062
 
1931
- if (fullRes.indexOf(resultID) === -1) {
1932
- try {
1933
- // object deleted
1934
- /* del when exist Object Async */
1935
- const delWhenExistObjectAsync = async (id, type) => {
1936
- const _find = await adapter.findForeignObjectAsync(`${id}`, `${type}`);
1937
- if (_find && _find.id === `${id}`) {
1938
- await adapter.delObjectAsync(`${id}`).catch((e) => adapter.log.warn(e)); // "sprinklecontrol.0.sprinkle.???.postponeByOneDay"
1939
- }
1940
- };
1941
-
1942
- Promise.all([
1943
- adapter.delObjectAsync(`${resID}.actualSoilMoisture`), // "sprinklecontrol.0.sprinkle.???.actualSoilMoisture"
1944
- adapter.delObjectAsync(`${resID}.triggerPoint`), // "sprinklecontrol.0.sprinkle.???.triggerPoint"
1945
- adapter.delObjectAsync(`${resID}.sprinklerState`), // "sprinklecontrol.0.sprinkle.???.sprinklerState"
1946
- adapter.delObjectAsync(`${resID}.runningTime`), // "sprinklecontrol.0.sprinkle.???.runningTime"
1947
- delWhenExistObjectAsync(`${resID}.postponeByOneDay`, `boolean`), // "sprinklecontrol.0.sprinkle.???.postponeByOneDay" wenn vorhanden löschen
1948
- adapter.delObjectAsync(`${resID}.countdown`), // "sprinklecontrol.0.sprinkle.???.countdown"
1949
- adapter.delObjectAsync(`${resID}.autoOn`), // "sprinklecontrol.0.sprinkle.???.autoOn"
1950
- adapter.delObjectAsync(`${resID}.history.lastOn`), // "sprinklecontrol.0.sprinkle.???.history.lastOn"
1951
- adapter.delObjectAsync(`${resID}.history.lastConsumed`), // "sprinklecontrol.0.sprinkle.???.history.lastConsumed"
1952
- adapter.delObjectAsync(`${resID}.history.lastRunningTime`), // "sprinklecontrol.0.sprinkle.???.history.lastRunningTime"
1953
- adapter.delObjectAsync(`${resID}.history.curCalWeekConsumed`), // "sprinklecontrol.0.sprinkle.???.history.curCalWeekConsumed"
1954
- adapter.delObjectAsync(`${resID}.history.lastCalWeekConsumed`), // "sprinklecontrol.0.sprinkle.???.history.lastCalWeekConsumed"
1955
- adapter.delObjectAsync(`${resID}.history.curCalWeekRunningTime`), // "sprinklecontrol.0.sprinkle.???.history.curCalWeekRunningTime"
1956
- adapter.delObjectAsync(`${resID}.history.lastCalWeekRunningTime`) // "sprinklecontrol.0.sprinkle.???.history.lastCalWeekRunningTime"
1957
- ]
1958
- ).then(async ()=>{
1959
- // History - Objekt(Ordner.history) löschen
1960
- await adapter.delObjectAsync(`${resID}.history`);
1961
- }).then(async ()=>{
1962
- // Objekt(Ordner) löschen
1963
- await adapter.delObjectAsync(resID);
1964
- }).then(()=>{
1965
- adapter.log.info(`sprinkleControl [${resID}] was deleted`);
1966
- });
1967
- } catch (e) {
1968
- adapter.log.warn(e);
1969
- }
2063
+ if (fullRes.indexOf(resultID) === -1) {
2064
+ try {
2065
+ // object deleted
2066
+ /**
2067
+ * del when exist Object Async
2068
+ *
2069
+ * @param id - the id of the object
2070
+ * @param type - common.type of the state
2071
+ * @returns {Promise<void>}
2072
+ */
2073
+ const delWhenExistObjectAsync = async (id, type) => {
2074
+ const _find = await adapter.findForeignObjectAsync(`${id}`, `${type}`);
2075
+ if (_find && _find.id === `${id}`) {
2076
+ await adapter.delObjectAsync(`${id}`).catch((e) => adapter.log.warn(e)); // "sprinklecontrol.0.sprinkle.???.postponeByOneDay"
2077
+ }
2078
+ };
2079
+
2080
+ await Promise.all([
2081
+ adapter.delObjectAsync(`${resID}.history.curCalWeekConsumed`), // "sprinklecontrol.0.sprinkle.???.history.curCalWeekConsumed"
2082
+ adapter.delObjectAsync(`${resID}.history.curCalWeekRunningTime`), // "sprinklecontrol.0.sprinkle.???.history.curCalWeekRunningTime"
2083
+ adapter.delObjectAsync(`${resID}.history.lastCalWeekConsumed`), // "sprinklecontrol.0.sprinkle.???.history.lastCalWeekConsumed"
2084
+ adapter.delObjectAsync(`${resID}.history.lastCalWeekRunningTime`), // "sprinklecontrol.0.sprinkle.???.history.lastCalWeekRunningTime"
2085
+ adapter.delObjectAsync(`${resID}.history.lastConsumed`), // "sprinklecontrol.0.sprinkle.???.history.lastConsumed"
2086
+ adapter.delObjectAsync(`${resID}.history.lastOn`), // "sprinklecontrol.0.sprinkle.???.history.lastOn"
2087
+ adapter.delObjectAsync(`${resID}.history.lastRunningTime`), // "sprinklecontrol.0.sprinkle.???.history.lastRunningTime"
2088
+ adapter.delObjectAsync(`${resID}.actualSoilMoisture`), // "sprinklecontrol.0.sprinkle.???.actualSoilMoisture"
2089
+ adapter.delObjectAsync(`${resID}.autoOn`), // "sprinklecontrol.0.sprinkle.???.autoOn"
2090
+ adapter.delObjectAsync(`${resID}.countdown`), // "sprinklecontrol.0.sprinkle.???.countdown"
2091
+ adapter.delObjectAsync(`${resID}.extBreak`), // "sprinklecontrol.0.sprinkle.???.break"
2092
+ adapter.delObjectAsync(`${resID}.runningTime`), // "sprinklecontrol.0.sprinkle.???.runningTime"
2093
+ adapter.delObjectAsync(`${resID}.sprinklerState`), // "sprinklecontrol.0.sprinkle.???.sprinklerState"
2094
+ adapter.delObjectAsync(`${resID}.triggerPoint`), // "sprinklecontrol.0.sprinkle.???.triggerPoint"
2095
+ delWhenExistObjectAsync(`${resID}.postponeByOneDay`, `boolean`), // "sprinklecontrol.0.sprinkle.???.postponeByOneDay" wenn vorhanden löschen
2096
+ ]);//.then(async ()=>{
2097
+ // History - Objekt(Ordner.history) löschen
2098
+ await adapter.delObjectAsync(`${ resID }.history`);
2099
+ //}).then(async ()=>{
2100
+ // Objekt(Ordner) löschen
2101
+ await adapter.delObjectAsync(resID);
2102
+ //}).then(()=>{
2103
+ adapter.log.info(`sprinkleControl [${resID}] was deleted`);
2104
+ //});
2105
+ } catch (e) {
2106
+ adapter.log.warn(`sprinkle cannot deleted: ${e}`);
1970
2107
  }
1971
2108
  }
1972
2109
  }
1973
2110
  }
1974
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1975
2111
 
1976
- function main(adapter) {
1977
2112
 
1978
- /* Auf die Adapterkonfiguration (im Instanz objekt alles unter dem Attribut "native") kann zugegriffen werden über adapter.config: */
2113
+
2114
+ async function main() {
2115
+ /* The adapters' config (in the instance object everything under the attribute "native") is accessible via
2116
+ * adapter.config:
2117
+ * => Auf die Adapterkonfiguration (im Instanz objekt alles unter dem Attribut "native") kann zugegriffen werden über
2118
+ adapter.config:
2119
+ */
1979
2120
  adapter.log.debug(`adapter.config.events: ${JSON.stringify(adapter.config.events)}`);
1980
- /* Auf die Adapterkonfiguration (im Instanz objekt alles unter dem Attribut "native") kann zugegriffen werden über adapter.config */
2121
+ /**
2122
+ * The adapters' config (in the instance object everything under the attribute "native") is accessible via adapter.config:
2123
+ * => Auf die Adapterkonfiguration (im Instanz objekt alles unter dem Attribut "native") kann zugegriffen werden über adapter.config:
2124
+ *
2125
+ * @param {any} err
2126
+ * @param {any} obj
2127
+ */
2128
+ // @ts-ignore
2129
+ // @ts-ignore
1981
2130
  adapter.getForeignObject('system.config', (err, obj) => {
1982
2131
  if (obj) {
1983
2132
  checkStates();
1984
2133
  }
1985
2134
  });
1986
- createSprinklers().catch((e) => adapter.log.warn(e));
1987
- GetSystemData().catch((e) => adapter.log.warn(e));
1988
- sendMessageText.initConfigMessage(adapter);
1989
- evaporation.initEvaporation(adapter); // init evaporation
1990
- checkActualStates().catch((e) => adapter.log.warn(e));
2135
+
2136
+ await myConfig.createConfig(adapter).catch((e) => adapter.log.warn(e));
2137
+ await createSprinklers().catch((e) => adapter.log.warn(e));
2138
+ await GetSystemData().catch((e) => adapter.log.warn(e));
2139
+ await sendMessageText.initConfigMessage(adapter);
2140
+ await evaporation.initEvaporation(adapter); // init evaporation
2141
+ await valveControl.initValveControl(adapter).catch((e) => adapter.log.warn(e));
1991
2142
  sunPos();
1992
- timer = setTimeout(() => {
1993
- startTimeSprinkle();
1994
- addStartTimeSprinkle();
1995
- }, 2000);
1996
2143
 
1997
2144
  /*
1998
2145
  * in this template all states changes inside the adapters namespace are subscribed
1999
2146
  * => In dieser Vorlage werden alle Statusänderungen im Namensraum des Adapters abonniert
2000
2147
  * adapter.subscribeStates('*');
2001
2148
  */
2002
-
2003
- adapter.subscribeStates('control.autoOnOff');
2004
- adapter.subscribeStates('control.autoStart');
2005
- adapter.subscribeStates('control.Holiday');
2006
-
2007
- // Request a notification from a third-party adapter => Fordern Sie eine Benachrichtigung von einem Drittanbieter-Adapter an
2008
- if (adapter.config.publicHolidays === true && (`${adapter.config.publicHolInstance}.heute.*`)) {
2009
- adapter.subscribeForeignStates(`${adapter.config.publicHolInstance}.heute.*`);
2010
- }
2011
- if (adapter.config.publicHolidays === true && (`${adapter.config.publicHolInstance}.morgen.*`)) {
2012
- adapter.subscribeForeignStates(`${adapter.config.publicHolInstance}.morgen.*`);
2013
- }
2149
+ await adapter.subscribeStatesAsync('control.autoOnOff');
2150
+ await adapter.subscribeStatesAsync('control.autoStart');
2151
+ await adapter.subscribeStatesAsync('control.Holiday');
2152
+ //adapter.subscribeStates('info.Elevation');
2153
+ //adapter.subscribeStates('info.Azimut');
2014
2154
  if (adapter.config.weatherForecast === true) {
2015
2155
  if (adapter.config.weatherForecastService === 'ownDataPoint') {
2016
2156
  weatherForecastTodayPfadStr = adapter.config.pathRainForecast;
2017
2157
  adapter.subscribeForeignStates(weatherForecastTodayPfadStr);
2018
- } else if (adapter.config.weatherForecastService === 'dasWetter' && adapter.config.weatherForInstance) {
2019
- weatherForecastTodayPfadStr = `${adapter.config.weatherForInstance}.NextDaysDetailed.Location_1.Day_1.rain_value`;
2158
+ } else if (adapter.config.weatherForecastService === 'dasWetter' && (adapter.config.weatherForInstance.length > 10)) {
2159
+ weatherForecastTodayPfadStr = `${ adapter.config.weatherForInstance }.location_1.ForecastDaily.Day_1.Rain`;
2020
2160
  adapter.subscribeForeignStates(weatherForecastTodayPfadStr);
2021
- adapter.subscribeForeignStates(`${adapter.config.weatherForInstance}.NextDaysDetailed.Location_1.Day_2.rain_value`);
2161
+ adapter.subscribeForeignStates(`${ adapter.config.weatherForInstance }.location_1.ForecastDaily.Day_2.Rain`);
2022
2162
  } else {
2023
2163
  adapter.log.warn('There is no valid data record stored in the weather forecast, please correct it!');
2024
2164
  }
2025
2165
  }
2166
+ // Request a notification from a third-party adapter => Fordern Sie eine Benachrichtigung von einem Drittanbieter-Adapter an
2167
+ if (adapter.config.publicHolidays === true && (`${ adapter.config.publicHolInstance }.heute.*`)) {
2168
+ adapter.subscribeForeignStates(`${ adapter.config.publicHolInstance }.heute.*`);
2169
+ }
2170
+ if (adapter.config.publicHolidays === true && (`${ adapter.config.publicHolInstance }.morgen.*`)) {
2171
+ adapter.subscribeForeignStates(`${ adapter.config.publicHolInstance }.morgen.*`);
2172
+ }
2173
+
2174
+ if (adapter.config.triggerControlVoltage !== '') {
2175
+ await adapter.subscribeForeignStatesAsync(adapter.config.triggerControlVoltage);
2176
+ }
2177
+ switch(adapter.config.pumpSelection) {
2178
+ case 'noPump':
2179
+ break;
2180
+ case 'mainPump':
2181
+ await adapter.subscribeForeignStatesAsync(adapter.config.triggerMainPump);
2182
+ break;
2183
+ case 'cistern':
2184
+ await adapter.subscribeForeignStatesAsync(adapter.config.triggerCisternPump);
2185
+ break;
2186
+ case 'pumpAndCistern':
2187
+ await adapter.subscribeForeignStatesAsync(adapter.config.triggerMainPump);
2188
+ await adapter.subscribeForeignStatesAsync(adapter.config.triggerCisternPump);
2189
+ break;
2190
+ }
2191
+
2026
2192
  if (adapter.config.actualValueLevel !== '') {
2027
- adapter.subscribeForeignStates(adapter.config.actualValueLevel);
2028
- } else {
2029
- adapter.setState('info.cisternState', {
2193
+ await adapter.subscribeForeignStatesAsync(adapter.config.actualValueLevel);
2194
+ } else if ((adapter.config.pumpSelection === 'pumpAndCistern') || (adapter.config.pumpSelection === 'cistern')) {
2195
+ await adapter.setStateAsync('info.cisternState', {
2030
2196
  val: 'The level sensor of the water cistern is not specified',
2031
2197
  ack: true
2032
- });
2198
+ }).catch((e) => adapter.log.warn(`info.cisternState ${e}`));
2033
2199
  }
2200
+
2201
+ await checkActualStates().catch((e) => adapter.log.warn(`checkActualStates: ${e}`));
2202
+ // @ts-ignore
2203
+ timer = setTimeout(() => {
2204
+ startTimeSprinkle();
2205
+ addStartTimeSprinkle();
2206
+ }, 1000);
2034
2207
  }
2035
2208
 
2036
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2037
2209
 
2038
- // ++++++++++++++++++ start option of Adapter ++++++++++++++++++++++
2039
- // If started as allInOne/compact mode => return function to create instance
2040
- if (module && module.parent) {
2210
+ if (require.main !== module) {
2211
+ // Export startAdapter in compact mode
2041
2212
  module.exports = startAdapter;
2042
2213
  } else {
2043
- // or start the instance directly
2214
+ // otherwise start the instance directly
2044
2215
  startAdapter();
2045
- }
2216
+ }