/* im Zusammenhang mit dem Gartenbewässerungssystem */ import java.util.Date val SystemStart = "OFF" var int maxNoWtrDays = 2 // maximale Anzahl von Tagen ohne Niederschlag var ZonedDateTime lastWtrDate // das Datum der letzten Bewässerung oder wann es geregnet hat var minimumReqRainfall = 6 // minimaler erwarteter Niederschlag, der die Bewässerung stoppt var rainfallMm = 0.0 // erwartete Niederschlagsmenge während der nächsten 24 Stunden var missingRainfall = 0.0 // Menge in mm, wie viel es am nächsten Tag bekommen soll (wie viele Angriffe - wie viel sollte es) var isWatering = false // ob der Bewässerungsprozess ausgeführt wird val telegramAction = getActions("telegram","telegram:telegramBot:patrick") // Bewässerungstimer // In der vorherigen Version gab es eine Hashmap mit Timern, leider aufgrund eines Fehlers in OH manchmal // hashmapa wurde auf null gesetzt und konnte nicht geändert werden var Timer enocean_centralCommand_83d50a27_generalSwitch_StartTimer var Timer enocean_centralCommand_83d50a27_generalSwitch_StopTimer var Timer WtrValveBack_StartTimer var Timer WtrValveBack_StopTimer var Timer WtrValveLine_StartTimer var Timer WtrValveLine_StopTimer var Timer Wtr_StopTimer // Ermöglicht es Ihnen ständig, Kontakte mit entgegengesetzter Logik zu steuern var OnOffType ON_R var OnOffType OFF_R // === Daten, die zum Herunterladen von Wetterdaten von OpenWeatherMap benötigt werden === val APPID = "xxxx" // WARNUNG! Dies sollte nicht außerhalb geteilt werden val cityId = 2905457 // Ihre Stadt val cnt = 8 // Anzahl der 3h-Segmente, für die wir Daten herunterladen möchten, 8 ist 24h val openwheatherUrl = "http://api.openweathermap.org/data/2.5/" // ============================================================================= // Debug - zu Testzwecken val checkUserStartTime = true // Wenn true die Bewässerungszeit überprüft, wird die Regel zum Testen verwendet //val checkWtrRainSensor = true // Wenn true, wird der Regensensor überprüft // Alle Magnetventile beim Systemstart ausschalten rule "Wtr_garden_startup" when System started then Thread::sleep(5000) //WtrAuto.sendCommand(OFF) //set system to automatic irrigation on startup 14.10.2020 WtrStartBtn.sendCommand(OFF) if(WtrAuto.state == ON){ logInfo("FILE","WtrAuto = ON") //debug } logInfo( "FILE", "Wtr_garden_startup: -START-") // Pseudo-permanente Initialisierung ON_R = ON //war OFF OFF_R = OFF //war ON isWatering = false logInfo( "FILE", "Wtr_garden_startup: Setting default values to valves") // Relais voreingestellt auf Aus (hauptsächlich zu Anzeigezwecken) enocean_centralCommand_83d50a27_generalSwitch.sendCommand(OFF_R) WtrValveBack.sendCommand(OFF_R) WtrValveLine.sendCommand(OFF_R) // oli enocean_centralCommand_83d50a27_generalSwitch.sendCommand(OFF) // oli WtrValveBack.sendCommand(OFF) // oli WtrValveLine.sendCommand(OFF) if(WtrStartTime.state==NULL) { WtrStartTime.sendCommand("05:00") logInfo( "FILE", "Wtr_garden_startup: WtrStartTime SET TO [05:00]") } else { logInfo( "FILE", "Wtr_garden_startup: WtrStartTime [" + WtrStartTime.state + "]") } if(WtrDurationFront.state==NULL) { WtrDurationFront.sendCommand(15) logInfo( "FILE", "Wtr_garden_startup: WtrDurationFront SET TO [15]") } else { logInfo( "FILE", "Wtr_garden_startup: WtrDurationFront [" + WtrDurationFront.state + "]") } if(WtrDurationBack.state==NULL) { WtrDurationBack.sendCommand(15) logInfo( "FILE", "Wtr_garden_startup: WtrDurationBack SET TO [15]") } else { logInfo( "FILE", "Wtr_garden_startup: WtrDurationBack [" + WtrDurationBack.state + "]") } if(WtrDurationLine.state==NULL) { WtrDurationLine.sendCommand(20) logInfo( "FILE", "Wtr_garden_startup: WtrDurationLine SET TO [20]") } else { logInfo( "FILE", "Wtr_garden_startup: WtrDurationLine [" + WtrDurationLine.state + "]") } if(WtrScaleFactor.state==NULL) { WtrScaleFactor.sendCommand(100) logInfo( "FILE", "Wtr_garden_startup: WtrScaleFactor SET TO [10]") } else { logInfo( "FILE", "Wtr_garden_startup: WtrScaleFactor [" + WtrScaleFactor.state + "]") } if(MinimumReqRainfallCfg.state==NULL) { MinimumReqRainfallCfg.sendCommand(5) logInfo( "FILE", "Wtr_garden_startup: MinimumReqRainfallCfg SET TO [10]") } else { logInfo( "FILE", "Wtr_garden_startup: MinimumReqRainfallCfg [" + MinimumReqRainfallCfg.state + "]") } // Ich zeige nach 80 an, weil das Einstellen von Variablen Momente dauert logInfo( "FILE", "Wtr_garden_startup: ================ Wtr param initialization ================") logInfo( "FILE", "Wtr_garden_startup: WtrAuto [" + WtrAuto.state + "]") //logInfo( "FILE", "Wtr_garden_startup: WtrRainSensor [" + WtrRainSensor.state + "]") //logInfo( "FILE", "Wtr_garden_startup: checkWtrRainSensor [" + checkWtrRainSensor + "]") logInfo( "FILE", "Wtr_garden_startup: checkUserStartTime [" + checkUserStartTime + "]") logInfo( "FILE", "Wtr_garden_startup: isWatering [" + isWatering + "]") end // czujnik deszczu zarejestrowal podlewanie przerywa podlewanie jesli aktualnie ma miejsce /*rule "Wtr_Rain_sensor_rain_activated" when Item WtrRainSensor changed to OPEN then logInfo( "FILE", "Wtr_Rain_sensor_rain_activated: Rain detected, stopping watering if running") EventHist.sendCommand("Czujnik jest mokry - zaczelo padac") Notification_Proxy_Wtr.sendCommand("STOP") end rule "Wtr_Rain_sensor_rain_deactivated" when Item WtrRainSensor changed to CLOSED then logInfo( "FILE", "Wtr_Rain_sensor_rain_deactivated: Rain detected is dry") EventHist.sendCommand("Czujnik jest suchy") end*/ // Bewässerungseinstellung auf automatisch rule "Wtr_auto_ON" when Item WtrAuto changed to ON then logInfo( "FILE","Wtr_auto_OFF: Automatic watering set") EventHist.sendCommand("Bewässerungsmodus eingestellt automatisch") telegramAction.sendTelegram("Automatischer Bewässerungsmodus eingestellt") end //Bewässerung auf manuell eingestellt rule "Wtr_auto_OFF" when Item WtrAuto changed to OFF then logInfo( "FILE","Wtr_auto_OFF: Manual watering set") EventHist.sendCommand("Bewässerungsmodus eingestellt manuell") telegramAction.sendTelegram("Manueller Bewässerungsmodus eingestellt") end // Manuelles Ein- und Ausschalten der Bewässerung (Taste auf dem Bedienfeld) rule "Wtr_manual_start_stop" when Item WtrStartBtn received update then logInfo( "FILE", "Wtr_manual_start_stop: isWatering[" +isWatering+ "]" ) // Wenn die Bewässerung aktiviert ist, wird die Bewässerung ansonsten beendet if (WtrStartBtn.state == ON && isWatering == false ) { logInfo( "FILE", "Wtr_manual_start_stop: Start watering, manual activation") EventHist.sendCommand("Die Bewässerungsstarttaste wurde gedrückt") telegramAction.sendTelegram("Die Bewässerungsstarttaste wurde gedrückt") Notification_Proxy_Wtr.sendCommand("START") } else if(WtrStartBtn.state == OFF && isWatering == true){ logInfo( "FILE", "Wtr_manual_start_stop: Stoping watering, manual activation") EventHist.sendCommand("Die Bewässerungs-STOP-Taste wurde gedrückt") Notification_Proxy_Wtr.sendCommand("STOP") telegramAction.sendTelegram("Die Bewässerungs-STOP-Taste wurde gedrückt") } end // Eine Regel, die die Bewässerung startet / stoppt rule "Wtr_starting_stoping" when Item Notification_Proxy_Wtr received update then logInfo( "FILE", "Wtr_starting_stoping:============== Watering starting/stoping ==========") var String msg = Notification_Proxy_Wtr.state.toString logInfo( "FILE", "Wtr_starting_stoping: Stoping watering if already started") logInfo( "FILE", "Wtr_starting_stoping: msg [" + msg + "]") // hört auf zu wässern, wenn es eingeschaltet ist, ich überprüfe nicht, ob es dauert oder nicht // Dies schützt uns vor einer Situation, in der beispielsweise eine bestimmte Zone von der Ebene aus manuell eingeschaltet wurde // grafische Oberfläche // Timer stoppen logInfo( "FILE", "Wtr_starting_stoping: WtrTimers") if(enocean_centralCommand_83d50a27_generalSwitch_StartTimer !== null) enocean_centralCommand_83d50a27_generalSwitch_StartTimer.cancel if(enocean_centralCommand_83d50a27_generalSwitch_StopTimer !== null) enocean_centralCommand_83d50a27_generalSwitch_StopTimer.cancel if(WtrValveBack_StartTimer !== null) WtrValveBack_StartTimer.cancel if(WtrValveBack_StopTimer !== null) WtrValveBack_StopTimer.cancel if(WtrValveLine_StartTimer !== null) WtrValveLine_StartTimer.cancel if(WtrValveLine_StopTimer !== null) WtrValveLine_StopTimer.cancel if(Wtr_StopTimer !== null) Wtr_StopTimer.cancel logInfo( "FILE", "Wtr_starting_stoping: WtrTimers-end") logInfo( "FILE", "debug6") ON_R = ON OFF_R = OFF enocean_centralCommand_83d50a27_generalSwitch.sendCommand(OFF_R) WtrValveBack.sendCommand(OFF_R) WtrValveLine.sendCommand(OFF_R) logInfo( "FILE", "Drei mal OFF_R and Ventile geschickt") WtrLED.sendCommand(OFF) // Der Bewässerungsprozess wurde ausgeschaltet isWatering = false // Überprüfung, ob ich Bewässerung beginnen soll if (msg == "START") { logInfo( "FILE", "Wtr_starting_stoping: starting watering") // Bewässerungslicht an WtrLED.sendCommand(ON) WtrStartBtn.sendCommand(ON) // zum späteren ausschalten nötig // Der Bewässerungsprozess wurde gestartet isWatering = true telegramAction.sendTelegram("[AUTO]Der Bewässerungsprozess wurde gestartet") // Bewässerungszeiten einstellen - von Artikeln herunterladen var Number durationFront = WtrDurationFront.state as DecimalType var Number durationBack = WtrDurationBack.state as DecimalType var Number durationLine = WtrDurationLine.state as DecimalType var ZonedDateTime startTime = now var ZonedDateTime endTime = now // Einstellen des letzten Bewässerungsdatums für die Anzeige in der Sitemap var String NowTime = String::format( "%1$td.%1$tm.%1$tY %1$tH:%1$tM", new Date() ) logInfo( "FILE","Wtr_starting_stoping: NowTime[" + NowTime + "]") WtrLastDate.sendCommand(NowTime) // Korrekturfaktor bis zum Gießen var Number scaleFactor = WtrScaleFactor.state as DecimalType // unter Berücksichtigung des Korrekturfaktors var int wtrFrontTime = ((durationFront * scaleFactor) / 100).intValue var int wtrBackTime = ((durationBack * scaleFactor) / 100).intValue var int wtrLineTime = ((durationLine * scaleFactor) / 100).intValue logInfo( "FILE","Wtr_starting_stoping: durationFront[" + durationFront + "]") logInfo( "FILE","Wtr_starting_stoping: durationBack [" + durationBack + "]") logInfo( "FILE","Wtr_starting_stoping: durationLine [" + durationLine + "]") logInfo( "FILE","Wtr_starting_stoping: scaleFactor [" + scaleFactor + "]") logInfo( "FILE","Wtr_starting_stoping: wtrFrontTime [" + wtrFrontTime + "]") logInfo( "FILE","Wtr_starting_stoping: wtrBackTime [" + wtrBackTime + "]") logInfo( "FILE","Wtr_starting_stoping: wtrLineTime [" + wtrLineTime + "]") //logInfo( "FILE","Wtr_starting_stoping: WtrRainSensor[" + WtrRainSensor.state + "]") // Ich fange an zu gießen - vorne if (wtrFrontTime > 0) { endTime = startTime.plusMinutes(wtrFrontTime) logInfo( "FILE", "Wtr_starting_stoping: Watering front starts [" + startTime + "] finish [" + endTime + "]") enocean_centralCommand_83d50a27_generalSwitch_StartTimer= createTimer(startTime) [| logInfo( "FILE", "Wtr_starting_stoping: enocean_centralCommand_83d50a27_generalSwitch[ON_R]") enocean_centralCommand_83d50a27_generalSwitch.sendCommand(ON_R) telegramAction.sendTelegram("[AUTO] Ich fange an zu gießen mit Wasserleitung 1") ] enocean_centralCommand_83d50a27_generalSwitch_StopTimer= createTimer(endTime) [| logInfo( "FILE", "Wtr_starting_stoping: enocean_centralCommand_83d50a27_generalSwitch[OFF_R]") enocean_centralCommand_83d50a27_generalSwitch.sendCommand(OFF_R) telegramAction.sendTelegram("[AUTO] Ich stoppe Wasserleitung 1") ] startTime = endTime.plusSeconds(10) } // Ich fange an zu gießen - hinten if (wtrBackTime > 0) { endTime = startTime.plusMinutes(wtrBackTime) logInfo( "FILE", "Wtr_starting_stoping: Watering back start [" + startTime + "] finish [" + endTime + "]") WtrValveBack_StartTimer= createTimer(startTime) [| logInfo( "FILE", "Wtr_starting_stoping: WtrValveBack[ON_R]") WtrValveBack.sendCommand(ON_R) telegramAction.sendTelegram("[AUTO] Ich fange an zu gießen mit Wasserleitung 2") ] WtrValveBack_StopTimer= createTimer(endTime) [| logInfo( "FILE", "Wtr_starting_stoping: WtrValveBack[OFF_R]") WtrValveBack.sendCommand(OFF_R) telegramAction.sendTelegram("[AUTO] Ich stoppe Wasserleitung 2") ] startTime = endTime.plusSeconds(10) } // Ich fange an zu gießen - Wasserleitung 3 if (wtrLineTime > 0) { endTime = startTime.plusMinutes(wtrLineTime) logInfo( "FILE", "Wtr_starting_stoping: Watering line starts [" + startTime + "] finish [" + endTime + "]") WtrValveLine_StartTimer= createTimer(startTime) [| logInfo( "FILE", "Wtr_starting_stoping: WtrValveLine[ON_R]") WtrValveLine.sendCommand(ON_R) telegramAction.sendTelegram("[AUTO] Ich fange an zu gießen mit Wasserleitung 3") ] WtrValveLine_StopTimer= createTimer(endTime) [| logInfo( "FILE", "Wtr_starting_stoping: WtrValveLine[OFF_R]") WtrValveLine.sendCommand(OFF_R) telegramAction.sendTelegram("[AUTO] Ich stoppe Wasserleitung 3") ] startTime = endTime.plusSeconds(10) } telegramAction.sendTelegram("(2)Gartenbewässerung begann, endet st [" + endTime + "]") // führt Operationen nach Abschluss des gesamten Bewässerungszyklus durch Wtr_StopTimer = createTimer(startTime) [| lastWtrDate = now logInfo( "FILE", "Wtr_starting_stoping: ==== Watering ended ====") WtrLED.sendCommand(OFF) WtrStartBtn.sendCommand(OFF) // PK setzt den Buttonststatus zurück isWatering = false EventHist.sendCommand("Die Bewässerung ist abgeschlossen") telegramAction.sendTelegram("Die Bewässerung ist abgeschlossen") ] logDebug( "FILE", "Wtr_starting_stoping: Wtr_StopTimer[" + Wtr_StopTimer + "]") } end // Der Hauptbewässerungsalgorithmus rule "Wtr_algorithm" when //Time cron "0 * * * * ?" http://www.cronmaker.com/?0 //Time cron "0 0/15 * 1/1 * ? *" //alle 15 Minuten //Time cron "0 0/30 * 1/1 * ? *" // alle 30 Minuten Time cron "0 0 0/1 1/1 * ? *" //Der stündliche Lauf kann auf alle 15 Minuten geändert werden //Time cron "0 0/5 * 1/1 * ? *" // Zu Testzwecken alle 5 Minuten aufgerufen //Time cron "0 0/1 * 1/1 * ? *" // Jede Minute then logInfo( "FILE", "Wtr_algorithm: -START- ") logInfo("FILE", "message1") logInfo("ONOFF", "[" + ON_R + "]") // Überprüfen Sie, ob die aktuelle Zeit die Bewässerungszeit ist und ob das System auf automatische Bewässerung eingestellt ist // und ob die tatsächliche Bewässerungszeit überprüft werden soll (checkUserStartTime) //var userStartTime = ZonedDateTime.now() //var LocalDate stAdvent = ZonedDateTime.parse(year + "-12-25T00:00:00.000Z").minusDays(ZonedDateTime.parse(year + "-12-25T00:00:00.000Z").getDayOfWeek.getValue + 21).toLocalDate() //PKval userStartTime = ZonedDateTime.parse(now.getYear() + "-0" + now.getMonthValue().toString() + "-" + now.getDayOfMonth() + "T" + WtrStartTime.state + ":00.000+01:00").withZoneSameInstant(ZoneId.systemDefault()).toString() //var ZonedDateTime userStartTime = parse(now.getYear() + "-" + now.getMonth.getValue() + "-" + now.getDayOfWeek.getValue() + "T" + WtrStartTime.state + ":00") logInfo("FILE", "############## debug 01 ##########") logInfo("FILE", "userStartTime.hour [" + WtrStartTime.state + "]") var NowMonth = String::format("%02d", now.getMonthValue()) var NowDay = String::format("%02d", now.getDayOfMonth()) val userStartTime = parse(now.getYear() + "-" + NowMonth + "-" + NowDay + "T" + WtrStartTime.state + ":00.000+02:00[Europe/Brussels]").withZoneSameInstant(ZoneId.systemDefault()) logInfo("FILE", "message") logInfo( "FILE", " ======= Wheather algorithm ======= ") logInfo( "FILE", "Wtr_algorithm: now [" + now + "]") logInfo( "FILE", "Wtr_algorithm: userStartTime [" + userStartTime + "]") logInfo( "FILE", "Wtr_algorithm: checkUserStartTime [" + checkUserStartTime + "]") logInfo( "FILE", "Wtr_algorithm: isWatering [" + isWatering + "]") logInfo( "FILE", "Wtr_algorithm: WtrAuto.state [" + WtrAuto.state + "]") logInfo("FILE", "message3") logInfo("FILE", "############## debug 02##########") logInfo("FILE", "userStartTime.hour [" + String::format("%02d", userStartTime.hour) + "]") logInfo("FILE", "now.getHour() [" + now.getHour() + "]") logInfo("FILE", "userStartTime.minute [" + userStartTime.minute + "]") logInfo("FILE", "now.getMinute() [" + now.getMinute() + "]") logInfo("FILE", "checkUserStartTime [" + checkUserStartTime + "]") logInfo("FILE", "lastWtrDate [" + lastWtrDate + "]") logInfo("FILE", "############# debug end ############") //StelegramAction.sendTelegram("Vor dem Zeit Check") // überprüfe die Zeit Stunde für Stunde Minute für Minute, überprüfen wir die eingestellte Zeit?Wenn das System bereits bewässert, überprüft es die Bedingungen nicht und bewässert nicht. /*if ( (( userStartTime.getHourOfDay == now.getHourOfDay() && userStartTime.getMinuteOfHour() == now.getMinuteOfHour() ) || checkUserStartTime == false ) && WtrAuto.state == CLOSED && (isWatering == false))*/ //if ( WtrStartTime.state == now.getHour() && userStartTime.getMinute() == now.getMinute() && WtrAuto.state==ON && isWatering==false ) if ( ( ( userStartTime.hour == now.getHour() && userStartTime.minute == now.getMinute() ) || checkUserStartTime == false ) && WtrAuto.state == ON && (isWatering == false) ) //if ( userStartTime.getHour == now.getHour() && userStartTime.getMinute() == now.getMinute() && WtrAuto.state==ON && isWatering==false ) { //logInfo( "FILE", "Wtr_algorithm: WtrRainSensor.state [" + WtrRainSensor.state + "]") logInfo( "FILE", "Wtr_algorithm: lastWtrDate [" + lastWtrDate + "]") logInfo( "FILE", "Wtr_algorithm: maxNoWtrDays [" + maxNoWtrDays + "]") //logInfo( "FILE", "Wtr_algorithm: checkWtrRainSensor [" + checkWtrRainSensor + "]") logInfo( "FILE", "Wtr_algorithm: checkUserStartTime [" + checkUserStartTime + "]") logInfo( "FILE", "Wtr_algorithm: MinimumReqRainfallCfg [" + (MinimumReqRainfallCfg.state as DecimalType).intValue + "]") //telegramAction.sendTelegram("Vor Wettervorhersage") /* * Nehmen Sie die Menge mm Wasser, die möglicherweise bis zum nächsten Morgen fallen wird, in mm */ var forecastUrl = openwheatherUrl + "forecast?id=" + cityId + "&APPID=" + APPID + "&units=metric&cnt=" + cnt logInfo( "FILE", "Wtr_algorithm: Getting wheather forecast [" + forecastUrl + "]") // Ich versuche, die Wettervorhersage bis zu dreimal herunterzuladen var forecastJson="" try { forecastJson = sendHttpGetRequest(forecastUrl) Thread::sleep(5000) var getCounter=0 while ( (forecastJson===null) && (getCounter<3)) { forecastJson = sendHttpGetRequest(forecastUrl) getCounter++ logInfo( "FILE", "Wtr_algorithm: getCounter[" + getCounter + "]") Thread::sleep(5000) } } catch(Throwable t) { logInfo("FILE", "Wtr_algorithm: Exception happen during getting heather data") forecastJson = null } logInfo( "FILE", "Wtr_algorithm: forecastJson[" + forecastJson + "]") rainfallMm = 0 if ( !(forecastJson === null)) { // Wenn der Fehler NULL ist if( ! (forecastJson=="NULL")) { // Ich habe eine Liste geschnitten - es sollte nur 3 Stunden Niederschlag geben/\ // https://community.openhab.org/t/solved-smhi-weather/22300/20 // Testwerkzeug http://www.jsonquerytool.com/ // forecastJson="{\"cod\":\"200\",\"message\":0.0025,\"cnt\":8,\"list\":[{\"dt\":1534572000,\"main\":{\"temp\":18.32,\"temp_min\":18.32,\"temp_max\":19.62,\"pressure\":1021.48,\"sea_level\":1031.67,\"grnd_level\":1021.48,\"humidity\":83,\"temp_kf\":-1.31},\"weather\":[{\"id\":803,\"main\":\"Clouds\",\"description\":\"broken clouds\",\"icon\":\"04d\"}],\"clouds\":{\"all\":68},\"wind\":{\"speed\":2.71,\"deg\":337.008},\"sys\":{\"pod\":\"d\"},\"dt_txt\":\"2018-08-18 06:00:00\"},{\"dt\":1534582800,\"main\":{\"temp\":22.64,\"temp_min\":22.64,\"temp_max\":23.51,\"pressure\":1022.21,\"sea_level\":1032.39,\"grnd_level\":1022.21,\"humidity\":74,\"temp_kf\":-0.87},\"weather\":[{\"id\":801,\"main\":\"Clouds\",\"description\":\"few clouds\",\"icon\":\"02d\"}],\"clouds\":{\"all\":24},\"wind\":{\"speed\":3.02,\"deg\":354.507},\"sys\":{\"pod\":\"d\"},\"dt_txt\":\"2018-08-18 09:00:00\"},{\"dt\":1534593600,\"main\":{\"temp\":24.32,\"temp_min\":24.32,\"temp_max\":24.76,\"pressure\":1022.01,\"sea_level\":1032.15,\"grnd_level\":1022.01,\"humidity\":74,\"temp_kf\":-0.44},\"weather\":[{\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10d\"}],\"clouds\":{\"all\":20},\"wind\":{\"speed\":2.51,\"deg\":350.5},\"rain\":{\"3h\":0.495},\"sys\":{\"pod\":\"d\"},\"dt_txt\":\"2018-08-18 12:00:00\"},{\"dt\":1534604400,\"main\":{\"temp\":24.38,\"temp_min\":24.38,\"temp_max\":24.38,\"pressure\":1021.82,\"sea_level\":1032.09,\"grnd_level\":1021.82,\"humidity\":66,\"temp_kf\":0},\"weather\":[{\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10d\"}],\"clouds\":{\"all\":0},\"wind\":{\"speed\":3.06,\"deg\":348.503},\"rain\":{\"3h\":2.1},\"sys\":{\"pod\":\"d\"},\"dt_txt\":\"2018-08-18 15:00:00\"},{\"dt\":1534615200,\"main\":{\"temp\":21.07,\"temp_min\":21.07,\"temp_max\":21.07,\"pressure\":1021.97,\"sea_level\":1032.35,\"grnd_level\":1021.97,\"humidity\":56,\"temp_kf\":0},\"weather\":[{\"id\":800,\"main\":\"Clear\",\"description\":\"clear sky\",\"icon\":\"01d\"}],\"clouds\":{\"all\":0},\"wind\":{\"speed\":2.81,\"deg\":325.002},\"rain\":{},\"sys\":{\"pod\":\"d\"},\"dt_txt\":\"2018-08-18 18:00:00\"},{\"dt\":1534626000,\"main\":{\"temp\":15.67,\"temp_min\":15.67,\"temp_max\":15.67,\"pressure\":1023.38,\"sea_level\":1033.67,\"grnd_level\":1023.38,\"humidity\":68,\"temp_kf\":0},\"weather\":[{\"id\":800,\"main\":\"Clear\",\"description\":\"clear sky\",\"icon\":\"01n\"}],\"clouds\":{\"all\":0},\"wind\":{\"speed\":2.56,\"deg\":333.501},\"rain\":{},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2018-08-18 21:00:00\"},{\"dt\":1534636800,\"main\":{\"temp\":12.21,\"temp_min\":12.21,\"temp_max\":12.21,\"pressure\":1023.52,\"sea_level\":1033.85,\"grnd_level\":1023.52,\"humidity\":89,\"temp_kf\":0},\"weather\":[{\"id\":800,\"main\":\"Clear\",\"description\":\"clear sky\",\"icon\":\"01n\"}],\"clouds\":{\"all\":0},\"wind\":{\"speed\":1.28,\"deg\":157.002},\"rain\":{},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2018-08-19 00:00:00\"},{\"dt\":1534647600,\"main\":{\"temp\":11.15,\"temp_min\":11.15,\"temp_max\":11.15,\"pressure\":1023,\"sea_level\":1033.33,\"grnd_level\":1023,\"humidity\":87,\"temp_kf\":0},\"weather\":[{\"id\":800,\"main\":\"Clear\",\"description\":\"clear sky\",\"icon\":\"01n\"}],\"clouds\":{\"all\":0},\"wind\":{\"speed\":1.72,\"deg\":177.001},\"rain\":{},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2018-08-19 03:00:00\"}],\"city\":{\"id\":3092909,\"name\":\"Lublewo Gdanskie\",\"coord\":{\"lat\":54.2846,\"lon\":18.5039},\"country\":\"PL\"}}" var String[] rainValues = transform("JS","rainvalues.js",forecastJson).replace("[", "").replace("]", "").split(",") rainfallMm = 0 // Überprüfen Sie, ob der Regenabschnitt mindestens einmal aufgetreten ist // Wenn es in JSON keinen Regenabschnitt gibt, gab es einen Wert und eine leere Zeichenfolge try { for (var i = 0; i < rainValues.length; i++) { rainfallMm = rainfallMm + (Double::parseDouble(rainValues.get(i))) } telegramAction.sendTelegram("Vorhergesagte Regenmenge(8h): "+ rainfallMm +"") } catch(Throwable t) { // Es war nicht möglich, die Niederschlagsvorhersage herunterzuladen. Ich habe sie auf keinen Niederschlag eingestellt logInfo( "FILE", "Wtr_algorithm: Cannot find rain section - rainfallMm is 0mm ") rainfallMm = 0 telegramAction.sendTelegram("Keine Regenvorhersage gefunden!") } } else { logInfo( "FILE", "Wtr_algorithm: Wheather forecast is NULL - rainfallMm is 0mm ") telegramAction.sendTelegram("Keine Regenvorhersage gefunden(NULL)!") } } // aktualisierte Niederschlagsvorhersage und Prognosedatum - werden in der Benutzeroberfläche angezeigt WtrRainfallForecast.sendCommand(rainfallMm) var String NowTimeF = String::format( "%1$td.%1$tm.%1$tY %1$tH:%1$tM", new Date() ) WtrRainfallForecastDate.sendCommand(NowTimeF) minimumReqRainfall = (MinimumReqRainfallCfg.state as DecimalType).intValue logInfo( "FILE", " ======= Wheather forecast ======= ") logInfo( "FILE", "Wtr_algorithm: rainfallMm [" + rainfallMm + "]") logInfo( "FILE", "Wtr_algorithm: minimumReqRainfall [" + minimumReqRainfall + "]") // Überprüfung des Zustands des Regensensors //if ( WtrRainSensor.state == CLOSED || checkWtrRainSensor==false ) { // logInfo( "FILE", "Wtr_algorithm: RainSensor is dry, check other conditions") //Überprüfen Sie, ob die erwartete Niederschlagsmenge ausreicht if (rainfallMm > minimumReqRainfall) { telegramAction.sendTelegram("rainfallMm größe als mindestmenge") telegramAction.sendTelegram("Mindestmenge = " + minimumReqRainfall + "") telegramAction.sendTelegram("Datum letzte = " + lastWtrDate + "") telegramAction.sendTelegram("Niederschlag in den nächsten 24 Stunden sollte ausreichen") // aber ich überprüfe, wie viele Tage nicht bewässert wurden, wenn ich mehr als maxNoWtrDays gieße if(lastWtrDate===null) { logInfo( "FILE", "Wtr_algorithm: lastWtrDate is null, for safety starting watering") EventHist.sendCommand("Die automatische Bewässerung wurde aktiviert (S1a)") telegramAction.sendTelegram("Die automatische Bewässerung wurde aktiviert (S1a) -> Letzte Bewässerung unbekannt!!") Notification_Proxy_Wtr.sendCommand("START") } else if(lastWtrDate.isBefore(now.minusDays(maxNoWtrDays))) { logInfo( "FILE", "Wtr_algorithm: lastWtrDate[" +lastWtrDate+ "] is later than now-maxNoWtrDays[" +maxNoWtrDays+ "]") EventHist.sendCommand("Die automatische Bewässerung (S1b) wurde aktiviert") telegramAction.sendTelegram("Die automatische Bewässerung wurde aktiviert (S1b)") Notification_Proxy_Wtr.sendCommand("START") } else { telegramAction.sendTelegram("Ich gieße nicht - erwarteter Niederschlag " + rainfallMm + "mm in den nächsten 24 Stunden") } } else { // Die erwartete Niederschlagsmenge innerhalb von 24 Stunden ist unzureichend missingRainfall = minimumReqRainfall - rainfallMm logInfo( "FILE", "Wtr_algorithm: Missing [" + missingRainfall + "] mm rainfall") EventHist.sendCommand("Die automatische Bewässerung (S2) wurde aktiviert") telegramAction.sendTelegram("Die automatische Bewässerung (S2) wurde aktiviert") Notification_Proxy_Wtr.sendCommand("START") } logInfo( "FILE", " ======= End of Watering algorithm ======= ") //} else { // Regensensor ist bei Regen oder Regen eingeschaltet // lastWtrDate = now // Ich stellte ein, es war Regen / Bewässerung // logInfo( "FILE", "Wtr_algorithm: watering not started, RainSensor is wet - watering is not needed") // telegramAction.sendTelegram("(2)Ich gieße nicht - der Regensensor ist nass") //} } else { logInfo( "FILE", "Wtr_algorithm: not started. checkUserStartTime[" +checkUserStartTime+ "] WtrAuto.state[" +WtrAuto.state + "] isWatering[" +isWatering+ "] WtrRainSensor.state[" + WtrRainSensor.state + "]" ) } end