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