iobroker.sprinklecontrol 1.0.6 → 1.0.8

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
@@ -84,7 +84,7 @@ function startAdapter(options) {
84
84
  // is called if a subscribed state changes
85
85
  stateChange: async (id, state) => {
86
86
  try {
87
- adapter.log.debug(`stateChange: ${id} (${state ? state.val : 'null'}) ack: ${state ? state.ack : 'null'}`);
87
+ // adapter.log.debug(`stateChange: ${id} (${state ? state.val : 'null'}) ack: ${state ? state.ack : 'null'}`);
88
88
  // The state was changed → Der Zustand wurde geändert
89
89
  if(state){
90
90
  // Change in outside temperature → Änderung der Außentemperatur
@@ -115,11 +115,38 @@ function startAdapter(options) {
115
115
  // Windgeschwindigkeit
116
116
  if (id === adapter.config.sensorWindSpeed) {
117
117
  if (!Number.isNaN(Number.parseFloat(state.val))) {
118
- evaporation.setCurWindSpeed(parseFloat(state.val), state.lc);
118
+ if (adapter.config.unitOfWindSpeed === 'm/s') {
119
+ evaporation.setCurWindSpeed(parseFloat(state.val) * 3.6, state.lc);
120
+ } else if (adapter.config.unitOfWindSpeed === 'km/h') { // HomeMatic: km/h
121
+ evaporation.setCurWindSpeed(parseFloat(state.val), state.lc);
122
+ } else {
123
+ adapter.log.warn(`sensorWindSpeed => No unit selected; therefore, ${state.val} km/h is used. Please check your configuration!`);
124
+ }
119
125
  } else {
120
126
  adapter.log.warn(`sensorWindSpeed => Wrong value: ${state.val}, Type: ${typeof state.val}`);
121
127
  }
122
128
  }
129
+ // Drucksensor
130
+ if (id === adapter.config.sensorPressure) {
131
+ adapter.log.debug(`SensorPressure: ${ state?.val }, Type: ${ typeof state.val }`);
132
+ let myPressure;
133
+ if(typeof state.val === 'number') {
134
+ myPressure = parseFloat(state.val);
135
+ }else if(typeof state.val === 'string') {
136
+ myPressure = parseFloat(state.val);
137
+ }else if(typeof state.val === 'boolean') {
138
+ (state.val === true) ? myPressure = 100 : myPressure = 0;
139
+ }
140
+ if(typeof myPressure !== "number"
141
+ || myPressure > 0
142
+ || myPressure < 10
143
+ ) {
144
+ valveControl.setSensorPressure(state.val);
145
+ } else {
146
+ adapter.log.warn(`SensorPressure (0...10 bar || true/false) => Wrong value: ${ state.val }, Type: ${ typeof state.val }`);
147
+ }
148
+ }
149
+
123
150
  // Regencontainer
124
151
  // If the amount of rain is over 20 mm, the 'lastRainCounter' is overwritten and no calculation is carried out. =>
125
152
  // * Wenn die Regenmenge mehr als 20 mm beträgt, wird der 'lastRainCounter' überschrieben und es wird keine Berechnung durchgeführt.
@@ -294,7 +321,7 @@ function startAdapter(options) {
294
321
  const _extBreak = await valveControl.extBreak(_found.sprinkleID, state.val).catch((e) => {
295
322
  adapter.log.warn(`main.extBreak: ${e}`);
296
323
  });
297
- if (_extBreak?.name) adapter.log.info(`_extBreak: ${_extBreak.name}, ${_extBreak.val ? 'on' : 'off'}`);
324
+ if (_extBreak?.name) adapter.log.info(`extBreak: ${_extBreak.name}, ${_extBreak.val ? 'on' : 'off'}`);
298
325
  if (_extBreak?.val === false) {
299
326
  /* Zustand des Ventils im Thread < 0 > off, < 1 > wait, < 2 > on, < 3 > break, < 4 > Boost(on), < 5 > off(Boost), < 6 > Cistern empty, <<< 7 >>> extBreak */
300
327
  adapter.setState(`sprinkle.${_found.objectName}.sprinklerState`, {
@@ -318,7 +345,7 @@ function startAdapter(options) {
318
345
  });
319
346
  }
320
347
  }
321
- // (state.ack === true)
348
+ // (state.ack === true) => Rückmeldung für das Schalten der Ventile, Druckentlastungsventil, Steuerspannung, Pumpen
322
349
  }else if (state.ack === true) {
323
350
  // Bestätigung für das Schalten der Ventile
324
351
  if (myConfig.config) {
@@ -348,7 +375,7 @@ function startAdapter(options) {
348
375
  currentPumpUse.controller.ackTrue(state);
349
376
  }
350
377
  // The state was deleted
351
- adapter.log.debug(`state ${id} deleted`);
378
+ // adapter.log.debug(`state ${id} deleted`);
352
379
  }
353
380
  }
354
381
  } catch (e) {
@@ -546,7 +573,7 @@ async function checkStates() {
546
573
 
547
574
  /* control.autoOnOff */
548
575
  const _autoOnOff = await adapter.getStateAsync('control.autoOnOff');
549
- if (_autoOnOff?.val && typeof _autoOnOff.val === 'boolean') {
576
+ if (typeof _autoOnOff.val === 'boolean') {
550
577
  autoOnOffStr = _autoOnOff.val;
551
578
  } else {
552
579
  autoOnOffStr = true;
@@ -772,7 +799,7 @@ const calcPos = schedule.scheduleJob('calcPosTimer', '5 0 * * *', function() {
772
799
  evaporation.setNewDay();
773
800
 
774
801
  // Startzeit Festlegen → verzögert wegen Daten von SunCalc
775
- setTimeout(() => {
802
+ adapter.setTimeout(() => {
776
803
  startTimeSprinkle();
777
804
  secondStartTimeSprinkle();
778
805
  if (adapter.config.enableTimeBasedRestriction === true) {
@@ -932,7 +959,7 @@ function addStartTimeSprinkle() {
932
959
  // @ts-ignore
933
960
  adapter.log.debug(`greaterETpCurrent: ${(adapter.config.selectAddStartTime === 'greaterETpCurrent')} & ${(adapter.config.triggerAddStartTimeETpCur < evaporation.getETpTodayNum())}, withExternalSignal; ${(adapter.config.selectAddStartTime === 'withExternalSignal')} & ${addStartTimeSwitch}`);
934
961
  }
935
- setTimeout(()=>{
962
+ adapter.setTimeout(()=>{
936
963
  schedule.cancelJob('sprinkleAddStartTime');
937
964
  }, 200);
938
965
  });
@@ -1053,8 +1080,8 @@ function startTimeSprinkle() {
1053
1080
 
1054
1081
  const scheduleStartTime = schedule.scheduleJob('sprinkleStartTime', `${ startTimeSplit[1] } ${ startTimeSplit[0] } * * *`, function() {
1055
1082
  startOfIrrigation("firstStartTime");
1056
- setTimeout (() => {
1057
- setTimeout(()=>{
1083
+ adapter.setTimeout (() => {
1084
+ adapter.setTimeout(()=>{
1058
1085
  nextStartTime();
1059
1086
  }, 800);
1060
1087
  schedule.cancelJob('sprinkleStartTime');
@@ -1062,6 +1089,32 @@ function startTimeSprinkle() {
1062
1089
  });
1063
1090
  }
1064
1091
 
1092
+ /**
1093
+ * Start of irrigation
1094
+ * - selectStartTime: firstStartTime | autoStart
1095
+ * firstStartTime → Startvorgang durch StartTimeSprinkle
1096
+ * autoStart → Startvorgang durch addStartTimeSprinkle
1097
+ * - Zisterne leer → Abbruch
1098
+ * - Filter enabled → Prüfung der Filterkriterien für alle Sprenger, die aktiviert sind (autoOn == true) und zusätzliche Bewässerung aktiviert haben (addWateringTime > 0)
1099
+ * - Test Bodenfeuchte → Prüfung der Bodenfeuchte für die Sprenger, die die automatische Bewässerung aktiviert haben (autoOn == true) und zusätzliche Bewässerung aktiviert haben (addWateringTime > 0)
1100
+ * - bistable: Bodenfeuchte-Sensor mit 2-Punkt-Regler true und false → Wenn true, dann Startvorgang
1101
+ * - analog: Bodenfeuchte-Sensor im Wertebereich von 0 bis 100% → Prozentuale Bodenfeuchte zu gering → Startvorgang
1102
+ * - fixDay: Start an festen Tagen ohne Sensoren → Bewässerungstag erreicht → Startvorgang
1103
+ * - calculation: Berechnung Bodenfeuchte auf Basis von ETpToday und dailyHighTemp → Prozentuale Bodenfeuchte zu gering → Startvorgang
1104
+ * - Wenn in der Config Regenvorhersage aktiviert: Startvorgang abbrechen, wenn der Regen den eingegebenen Schwellwert überschreitet.
1105
+ * - Start der Bewässerung
1106
+ * - Berechnung der Bewässerungszeit
1107
+ * - Start der Bewässerung über valveControl.addList(memAddList)
1108
+ * - Message über startende Bewässerung mit Angabe der Bewässerungszeit
1109
+ * - Log über startende Bewässerung mit Angabe der Bewässerungszeit
1110
+ * - Wenn extBreak == true → Startvorgang abbrechen und extBreak || START => Message und Log
1111
+ * - Wenn in der Config Regenvorhersage aktiviert: Startvorgang abbrechen, wenn der Regen den eingegebenen Schwellwert überschreitet.
1112
+ * - Wenn autoOnOff == false → keine auto Start
1113
+ * - Wenn Zisterne leer → keine zusätzliche Bewässerung möglich
1114
+ * - Wenn in der Config Regenvorhersage aktiviert: Startvorgang abbrechen, wenn der Regen den eingegebenen Schwellwert überschreitet.
1115
+ *
1116
+ * @param {string} selectStartTime - firstStartTime | autoStart
1117
+ */
1065
1118
  const startOfIrrigation = async (selectStartTime) => {
1066
1119
  let messageText = '';
1067
1120
 
@@ -1230,21 +1283,27 @@ const startOfIrrigation = async (selectStartTime) => {
1230
1283
  function secondStartTimeSprinkle() {
1231
1284
  schedule.cancelJob('sprinkleSecondStartTime');
1232
1285
 
1233
- // if (autoOnOff == false) => keine auto Start
1286
+ // if (autoOnOff == false) => keine auto Start
1234
1287
  if (!autoOnOffStr) {
1235
- adapter.log.info(`Sprinkle: autoOnOff === Aus ( ${autoOnOffStr} )`);
1236
- adapter.setState('info.nextAutoStart', {
1237
- val: 'autoOnOff = off(0)',
1238
- ack: true
1239
- });
1240
1288
  return;
1241
1289
  }
1242
-
1243
- const secondStartTimeSplit = adapter.config.secondStartTime.split(':');
1290
+ const curTime = new Date();
1291
+ let myWeekday = curTime.getDay(); // 0 = Sonntag, 1 = Montag, ..., 6 = Samstag
1292
+ let secondStartTime = adapter.config.secondStartTime;
1293
+
1294
+ // Start am Wochenende, an Feiertagen oder Urlaub →, wenn Zeiten des Wochenendes verwendet werden soll
1295
+ if((adapter.config.publicWeekend2 && ((myWeekday === 6) || (myWeekday === 0))) // Start am Wochenende
1296
+ || (adapter.config.publicHolidays2 && ((myWeekday === 6) || (myWeekday === 0)) // heute Feiertag
1297
+ || (holidayStr === true)) // Urlaub
1298
+ ){
1299
+ secondStartTime = adapter.config.weekEndLiving;
1300
+ }
1301
+
1302
+ const secondStartTimeSplit = secondStartTime.split(':');
1244
1303
  // @ts-ignore
1245
1304
  const scheduleSecondStartTime = schedule.scheduleJob('sprinkleSecondStartTime', `${ secondStartTimeSplit[1] } ${ secondStartTimeSplit[0] } * * *`, function() {
1246
1305
  startOfIrrigation("secondStartTime");
1247
- setTimeout(()=>{
1306
+ adapter.setTimeout(()=>{
1248
1307
  schedule.cancelJob('sprinkleSecondStartTime');
1249
1308
  }, 200);
1250
1309
  });
@@ -1289,7 +1348,7 @@ async function createSprinklers() {
1289
1348
  *
1290
1349
  * @param {string} methodControlSM
1291
1350
  * @param {string} objectName
1292
- * @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: {}}}>}
1351
+ * @returns {Promise<{nameMetConSM: string; objMetConSM: {type: string; common: {role: string; name: string; type: string; min?: number; max?: number; states?: Record<string, unknown>; unit?: string; read: boolean; write: boolean; def?: number | string | boolean}; native: Record<string, unknown>}}>}
1293
1352
  */
1294
1353
  const fillMetConSM = async (methodControlSM, objectName) => {
1295
1354
  //adapter.log.debug(JSON.stringify(res));
@@ -1323,7 +1382,7 @@ async function createSprinklers() {
1323
1382
  write: false,
1324
1383
  def: 50
1325
1384
  },
1326
- native: {},
1385
+ native: {}
1327
1386
  }
1328
1387
  };
1329
1388
  }
@@ -2184,8 +2243,8 @@ async function main() {
2184
2243
  * The adapters' config (in the instance object everything under the attribute "native") is accessible via adapter.config:
2185
2244
  * => Auf die Adapterkonfiguration (im Instanz objekt alles unter dem Attribut "native") kann zugegriffen werden über adapter.config:
2186
2245
  *
2187
- * @param {any} err
2188
- * @param {any} obj
2246
+ * @param {objett} err
2247
+ * @param {objekt} obj
2189
2248
  */
2190
2249
  // @ts-ignore
2191
2250
  // @ts-ignore
@@ -2214,6 +2273,7 @@ async function main() {
2214
2273
  //adapter.subscribeStates('info.Elevation');
2215
2274
  //adapter.subscribeStates('info.Azimut');
2216
2275
 
2276
+ // Trigger für die Wettervorhersage abonnieren, wenn in der Config angegeben
2217
2277
  if (adapter.config.weatherForecastService === 'ownDataPoint') {
2218
2278
  weatherForecastTodayPfadStr = adapter.config.pathRainForecast;
2219
2279
  adapter.subscribeForeignStates(weatherForecastTodayPfadStr);
@@ -2231,9 +2291,12 @@ async function main() {
2231
2291
  adapter.subscribeForeignStates(`${ adapter.config.publicHolInstance }.morgen.*`);
2232
2292
  }
2233
2293
 
2294
+ // Trigger für die Bewässerung abonnieren, wenn in der Config angegeben
2234
2295
  if (adapter.config.triggerControlVoltage !== '') {
2235
2296
  await adapter.subscribeForeignStatesAsync(adapter.config.triggerControlVoltage);
2236
2297
  }
2298
+
2299
+ // Trigger für die Pumpe abonnieren, wenn in der Config angegeben
2237
2300
  switch(adapter.config.pumpSelection) {
2238
2301
  case 'noPump':
2239
2302
  break;
@@ -2249,6 +2312,7 @@ async function main() {
2249
2312
  break;
2250
2313
  }
2251
2314
 
2315
+ // Level-Sensor abonnieren, wenn in der Config angegeben
2252
2316
  if (adapter.config.actualValueLevel !== '') {
2253
2317
  await adapter.subscribeForeignStatesAsync(adapter.config.actualValueLevel);
2254
2318
  } else if ((adapter.config.pumpSelection === 'pumpAndCistern') || (adapter.config.pumpSelection === 'cistern')) {
@@ -2258,9 +2322,14 @@ async function main() {
2258
2322
  }).catch((e) => adapter.log.warn(`info.cisternState ${e}`));
2259
2323
  }
2260
2324
 
2325
+ // Bodenfeuchte-Sensoren abonnieren, wenn in der Config angegeben
2326
+ if (adapter.config.sensorPressure.length > 10) {
2327
+ await adapter.subscribeForeignStatesAsync(adapter.config.sensorPressure);
2328
+ }
2329
+
2261
2330
  await checkActualStates().catch((e) => adapter.log.warn(`checkActualStates: ${e}`));
2262
2331
  // @ts-ignore
2263
- timer = setTimeout(() => {
2332
+ timer = adapter.setTimeout(() => {
2264
2333
  startTimeSprinkle();
2265
2334
  secondStartTimeSprinkle();
2266
2335
  addStartTimeSprinkle();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.sprinklecontrol",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "Control of several sprinklers depending on weather conditions and pump performance.",
5
5
  "author": {
6
6
  "name": "Dirk Peter",
@@ -29,18 +29,20 @@
29
29
  "node": ">= 22"
30
30
  },
31
31
  "dependencies": {
32
- "@iobroker/adapter-core": "^3.3.2",
32
+ "@iobroker/adapter-core": "^3.4.1",
33
33
  "node-schedule": "^2.1.1",
34
34
  "suncalc": "^1.9.0"
35
35
  },
36
36
  "devDependencies": {
37
- "@alcalzone/release-script": "^5.2.0",
37
+ "@alcalzone/release-script": "^5.2.1",
38
38
  "@alcalzone/release-script-plugin-iobroker": "^5.2.0",
39
39
  "@alcalzone/release-script-plugin-license": "^5.2.0",
40
40
  "@alcalzone/release-script-plugin-manual-review": "^5.2.0",
41
41
  "@iobroker/adapter-dev": "^1.5.0",
42
42
  "@iobroker/eslint-config": "^2.3.4",
43
- "@iobroker/testing": "^5.2.2"
43
+ "@iobroker/testing": "^5.2.2",
44
+ "@tsconfig/node22": "^22.0.5",
45
+ "@types/node": "^22.19.19"
44
46
  },
45
47
  "main": "main.js",
46
48
  "files": [