Automatisch Gartenbewässerung / Beregnung mit openHAB und Sonoff

Für welche Projekte verwendet Ihr OpenHAB? Was habt Ihr automatisiert? Stellt eure Projekte hier vor.

Moderatoren: Cyrelian, seppy

Gesperrt
Benutzeravatar
Romel
Beiträge: 42
Registriert: 21. Mai 2020 15:32

Re: Automatisch Gartenbewässerung / Beregnung mit openHAB und Sonoff

Beitrag von Romel »

Das war es !!! :D
So funktioniert es !!!

Code: Alles auswählen

var Timer tRegner = null
var int iRegner = 0
var Timer tStartRegner = null



rule "Startzeit einstellen"
when
    Member of gWeekdays changed or                                                                                         // Wochentag geändert
    Item Startzeit_Minuten changed or                                                                                      // Minuten geändert
    Item Startzeit_Stunden changed or                                                                                      // Stunden geändert
    Time cron "1 0 0 * * ?"                                                                                                // täglich um 00:00:01 Uhr
then
    // Alle Wochentag-Items müssen in der Gruppe gWeekdays zusammengefasst sein, damit der Trigger oben funktioniert
    var dayOfWeekSetting = newArrayList(
        Monday.state, 
        Tuesday.state, 
        Wednesday.state, 
        Thursday.state, 
        Friday.state, 
        Saturday.state, 
        Sunday.state
    )
    var int minutes = 0                                                                                     // Initialwert für Minuten definieren
    if(Startzeit_Minuten.state instanceof Number) {                                                         // Falls das Item eine gültige Zahl enthält
        minutes = (Startzeit_Minuten.state as Number).intValue                                                         // Setze minutes auf diese Zahl
        if(minutes > 59) minutes = 0                                                                         // Falls Obergrenze überschritten setze auf 0
        if(minutes < 0) minutes = 59                                                                         // Falls Untergrente unterschritten setze auf 59
    }
    Startzeit_Minuten.postUpdate(minutes)                                                                   // Schreibe Wert in das Item
    var int hours = 0                                                                                       // Initialwert für Sunden definieren
    if(Startzeit_Stunden.state instanceof Number) {                                                        // Falls das Item eine gültige Zahl enthält
        hours = (Startzeit_Stunden.state as Number).intValue                                                          // Setze hours auf diese Zahl
        if(hours > 23) hours = 0                                                                            // Falls Obergrenze überschritten setze auf 0
        if(hours < 0) hours = 23                                                                            // Falls Untergrente unterschritten setze auf 23
    }
    Startzeit_Stunden.postUpdate(hours)                                                                     // Schreibe Wert in das Item
    val int startMinutes = hours * 60 + minutes                                                           // Zeit in Minuten
    tStartRegner?.cancel                                                                                  // geplante Beregnung canceln
    if(dayOfWeekSetting.get(now.getDayOfWeek-1) == ON) { 
        logInfo("watering","Kontrolliere Wochentag")                                                   // Falls heute Beregnung gewünscht
        if(now.getMinuteOfDay < startMinutes) {
            logInfo("watering","Warte auf Startzeit")                                                             // Falls Startzeit noch nicht erreicht
            tStartRegner = createTimer(now.withTimeAtStartOfDay.plusMinutes(startMinutes),[|                // Setze einen Timer auf gewünschte Startzeit
                Beregnung.sendCommand(ON)                                                                   // Starte zur gewünschten Zeit
            ])
        }
    }
end

rule "Beregnung EIN"
when
    Item Beregnung received command
then
    if(receivedCommand == OFF) {
        logInfo("watering","Beregnung wird abgebrochen!")
        tRegner?.cancel                                                                                                                                         // Timer stoppen
        tRegner = null                                                                                                                                          // Variable leeren
        gRegner.members.filter[i|i.name.contains("Power")].filter[j| j.state != OFF].forEach[r|r.sendCommand(OFF)]                                              // alle Regner abschalten
        //Pumpe.sendCommand(OFF)                                                                                                                                  // Pumpe abschalten
        Sperre.postUpdate(OFF)                                                                                                                                  // Bediensperre aufheben
    } else {
    logInfo("watering","Beregnung gestartet.")
    if(tRegner !== null) {
        logInfo("watering","Regner scheint noch zu laufen! Abbruch")
        return;
    }
    iRegner = 0
    Sperre.postUpdate(ON)
    //Pumpe.sendCommand(ON)
    tRegner = createTimer(now.plusMillis(10),[|
        iRegner++                                // nächsten Regener anwählen
        logInfo("regner","{}. Durchlauf",iRegner)
        gRegner.members.filter[i|i.name.contains("Power")].filter[j| j.state != OFF].forEach[r|r.sendCommand(OFF)] // alle Regner abschalten
        val maxRegner = gRegner.members.filter[i|i.name.contains("Sperre")].filter[j| j.state == OFF].size             // wieviele Regner sollen insgesamt beregnen?
        logInfo("regner","{}. Durchlauf von {} Durchläufen.",iRegner,maxRegner)
        if(iRegner > maxRegner) {                // letzten Regner schon erreicht?
            logInfo("regner","Alle Regner sind schon gelaufen!")
            tRegner = null                       // Dann Schluss!
            Sperre.postUpdate(OFF)
            Beregnung.postUpdate(OFF)
            Berwgnung_manuell.postUpdate(OFF)                                                                                                                       // Item zurücksetzen
            //Pumpe.sendCommand(OFF)  
            return;
        }
        Thread::sleep(500)                       // kleine(!) Pause einlegen
        val strRegner = gRegner.members.filter[i|i.name.contains("Sperre")].filter[j| j.state == OFF].sortBy[name].get(iRegner-1).name.split("_").get(2) //Namen des Regner ermitteln
        logInfo("regner","Nächster Regner: {}",strRegner)
        gRegner.members.filter[i|i.name.contains("Power") && i.name.contains(strRegner)].head.sendCommand(ON)  // Regner einschalten
        val Dauer =(gRegner.members.filter[i|i.name.contains("Dauer") && i.name.contains(strRegner)].head.state as Number).intValue
        logInfo("regner","Regenr wird nach {} Minuten wieder abgeschaltet.",Dauer)
        tRegner.reschedule(now.plusMinutes(Dauer)) // Nächste Ausführung planen
    ])
    }
end
Vielen Dank !!!

Benutzeravatar
Romel
Beiträge: 42
Registriert: 21. Mai 2020 15:32

Re: Automatisch Gartenbewässerung / Beregnung mit openHAB und Sonoff

Beitrag von Romel »

Hallo

Mein nächster schritt ist die Beregnung mit dem Wetter zu verbinden. Dazu habe ich eine Rule für den Wind gemacht.

Code: Alles auswählen

rule "Wetter einbinden"
when 
    Item WetterPrognose received command
then 
    var int wind = 0
    var int maxwind = 0                                                                                    
    if(WetterAktuellWindgesch.state instanceof Number) {                                                        
        wind = (WetterAktuellWindgesch.state as Number).intValue
        maxwind = (maxWind.state as Number).intValue                                                         
        if(wind >= maxwind)                                                                           
        tRegner?.cancel                                                                                                                                         
        tRegner = null                                                                                                                                         
        gRegner.members.filter[i|i.name.contains("Power")].filter[j| j.state != OFF].forEach[r|r.sendCommand(OFF)]                                             
        //Pumpe.sendCommand(OFF)                                                                                                                                 
        Sperre.postUpdate(OFF)
        Beregnung.postUpdate(OFF)
        logInfo("watering","Derzeit ist es zu windig! {} km/h: Abbruch !", wind)
    }
    else 
    {   
        Beregnung.sendCommand(ON)
    }
end 
Aber jetzt mein Problem:

Der Wert wind ist von openweather und ist z.b. 18 km/h.
Der Wert maxwind ist von einem item und hat z.b. 20 km/h.

Also wenn der wind Wert unter 20 ist soll es Beregnen.
Macht es aber nicht.

log:

Code: Alles auswählen

==> /var/log/openhab2/events.log <==

2020-06-05 14:01:20.854 [ome.event.ItemCommandEvent] - Item 'Startzeit_Stunden' received command 14

2020-06-05 14:01:20.866 [vent.ItemStateChangedEvent] - Startzeit_Stunden changed from 13 to 14

==> /var/log/openhab2/openhab.log <==

2020-06-05 14:01:20.884 [INFO ] [ipse.smarthome.model.script.watering] - Kontrolliere Wochentag

2020-06-05 14:01:20.889 [INFO ] [ipse.smarthome.model.script.watering] - Warte auf Startzeit

==> /var/log/openhab2/events.log <==

2020-06-05 14:03:00.007 [ome.event.ItemCommandEvent] - Item 'WetterPrognose' received command ON

==> /var/log/openhab2/openhab.log <==

2020-06-05 14:03:00.085 [INFO ] [ipse.smarthome.model.script.watering] - Derzeit ist es zu windig! 16 km/h: Abbruch !

Darkwin101
Beiträge: 424
Registriert: 6. Mär 2019 11:19
Answers: 14

Re: Automatisch Gartenbewässerung / Beregnung mit openHAB und Sonoff

Beitrag von Darkwin101 »

Versuche mal bei wind und Maxwind
((maxWind.state as Number).floatValue).intValue

Es kann sein das die Km/h nicht entfernt werden

Benutzeravatar
Romel
Beiträge: 42
Registriert: 21. Mai 2020 15:32

Re: Automatisch Gartenbewässerung / Beregnung mit openHAB und Sonoff

Beitrag von Romel »

Keine Änderung.

Jetzt hab ich auch maxWind auf 26 km/h gesetzt.

log:

Code: Alles auswählen

2020-06-05 15:09:14.503 [INFO ] [ipse.smarthome.model.script.watering] - Kontrolliere Wochentag

2020-06-05 15:09:14.508 [INFO ] [ipse.smarthome.model.script.watering] - Warte auf Startzeit

==> /var/log/openhab2/events.log <==

2020-06-05 15:10:00.006 [ome.event.ItemCommandEvent] - Item 'WetterPrognose' received command ON

==> /var/log/openhab2/openhab.log <==

2020-06-05 15:10:00.091 [INFO ] [ipse.smarthome.model.script.watering] - Derzeit ist es zu windig! 20 km/h: Abbruch !

==> /var/log/openhab2/events.log <==

2020-06-05 15:10:00.092 [ome.event.ItemCommandEvent] - Item 'Beregnung' received command OFF

==> /var/log/openhab2/openhab.log <==

2020-06-05 15:10:00.096 [INFO ] [ipse.smarthome.model.script.watering] - Beregnung wird abgebrochen!
UPDATE:

Selbst wenn ich so mache, bricht es ab.

Code: Alles auswählen

rule "Wetter einbinden"
when 
    Item WetterPrognose received command
then 
    var int wind = 0
    var int maxwind = 0                                                                                    
    if(WetterAktuellWindgesch.state instanceof Number) { 
    	wind = 10                                                        
        maxwind = 25                                                       
        if(wind >= maxwind)                                                                           
        tRegner?.cancel                                                                                                                                        
        tRegner = null                                                                                                                                         
        gRegner.members.filter[i|i.name.contains("Power")].filter[j| j.state != OFF].forEach[r|r.sendCommand(OFF)]               
        //Pumpe.sendCommand(OFF)                                                                                                                                
        Sperre.postUpdate(OFF)
        Beregnung.sendCommand(OFF)
        logInfo("watering","Derzeit ist es zu windig! {} km/h: Abbruch !", wind)
    }
    else 
    {   
        Beregnung.sendCommand(ON)
    }
end        

Darkwin101
Beiträge: 424
Registriert: 6. Mär 2019 11:19
Answers: 14

Re: Automatisch Gartenbewässerung / Beregnung mit openHAB und Sonoff

Beitrag von Darkwin101 »

Alles was für if(wind >= maxwind) relevant ist muss in geschweiften Klammern stehen um der If Anweisung zu geordnet werden zu Können
Also
if(wind >= maxwind) {
Kommandos
}

Code: Alles auswählen

rule "Wetter einbinden"
when 
    Item WetterPrognose received command
then 
    var int wind = 0
    var int maxwind = 0                                                                                    
    if(WetterAktuellWindgesch.state instanceof Number) { 
    	wind = 10                                                        
        maxwind = 25                                                       
        if(wind >= maxwind){                                                                           
        tRegner?.cancel                                                                                                                                        
        tRegner = null                                                                                                                                         
        gRegner.members.filter[i|i.name.contains("Power")].filter[j| j.state != OFF].forEach[r|r.sendCommand(OFF)]               
        //Pumpe.sendCommand(OFF)                                                                                                                                
        Sperre.postUpdate(OFF)
        Beregnung.sendCommand(OFF)
        logInfo("watering","Derzeit ist es zu windig! {} km/h: Abbruch !", wind)
    }
    else 
    {   
        Beregnung.sendCommand(ON)
    }
    }
end 
Zuletzt geändert von Darkwin101 am 5. Jun 2020 16:11, insgesamt 1-mal geändert.

Benutzeravatar
Romel
Beiträge: 42
Registriert: 21. Mai 2020 15:32

Re: Automatisch Gartenbewässerung / Beregnung mit openHAB und Sonoff

Beitrag von Romel »

Geht auch nicht.
Keine Ahnung mehr.

EmptySoft
Beiträge: 188
Registriert: 7. Jan 2020 14:45
Answers: 2
Kontaktdaten:

Re: Automatisch Gartenbewässerung / Beregnung mit openHAB und Sonoff

Beitrag von EmptySoft »

Mache Dir for das if... ein LogInfo rein, amit Du siehst, welche Werte sind, dann kann man die Rule leichter debuggen

Code: Alles auswählen

if(WetterAktuellWindgesch.state instanceof Number) {
logInfo("Wetter.rules","WetterAktuellWindgesch: " + WetterAktuellWindgesch.state)
BYe
Harald

Benutzeravatar
Romel
Beiträge: 42
Registriert: 21. Mai 2020 15:32

Re: Automatisch Gartenbewässerung / Beregnung mit openHAB und Sonoff

Beitrag von Romel »

Danke an Darkwin101.

So geht´s:

Code: Alles auswählen

rule "Wetter Einbindung"
when
    Item WetterPrognose received command  
then
    var int wind = 0
    var int maxwind = 0                                                                                       
    if(WetterAktuellWindgesch.state instanceof Number) {                                                         
        wind = (WetterAktuellWindgesch.state as Number).intValue
        maxwind = (maxWind.state as Number).intValue                                                         
        if(wind >= maxwind){                                                                          
        tRegner?.cancel                                                                                                                                         
        tRegner = null                                                                                                                                         
        gRegner.members.filter[i|i.name.contains("Power")].filter[j| j.state != OFF].forEach[r|r.sendCommand(OFF)]                                             
        //Pumpe.sendCommand(OFF)                                                                                                                                  
        Sperre.postUpdate(OFF)
        Beregnung.postUpdate(OFF)
        logInfo("watering","Derzeit ist es zu windig! {} km/h: Abbruch !", wind)
    }
    else
    {
        Beregnung.sendCommand(ON)
        logInfo("watering","Derzeitiger Wind {} km/h: Beregnung gestartet !", wind)
    }
    }
end
Die {} sind am falschen Platz gewesen.

Benutzeravatar
udo1toni
Beiträge: 13859
Registriert: 11. Apr 2018 18:05
Answers: 222
Wohnort: Darmstadt

Re: Automatisch Gartenbewässerung / Beregnung mit openHAB und Sonoff

Beitrag von udo1toni »

Also erst mal möchte ich vorschlagen, dass Du, wenn die Abbruchbedingung zutrifft (also Wind > maxwind) einfach Beregnung OFF sendest. Deshalb sind diese beiden Funktionen (Zeit und Regnersteuerung) getrennt.
Das Zweite ist die Übernahme von Zahlenwerten aus Items. Ein Number Item kann auch Werte enthalten, die nicht vom Typ Number sind. Deshalb der Test mit instanceof Number. Dieser Test muss aber für jedes Item einzeln durchgeführt werden, es reicht nicht, eines der Number Items zu testen.
Im Fall der Windgeschwindigkeit möchtest Du zwei Zahlen miteinander Vergleichen, die evtl. nicht vom Typ Integer sind. Es ist aber auhc nicht notwendig, die Variable auf int festzulegen (anders sieht das bei der Startzeit aus, weil die Funktion plusMinutes() ein Integer als Argument verlangt.

Die Rule sollte also eher so aussehen:

Code: Alles auswählen

rule "Wetter einbinden"
when
    Item WetterPrognose received command
then 
    var wind = 0
    if(WetterAktuellWindgesch.state instanceof Number)
        wind = (WetterAktuellWindgesch.state as Number).floatValue
    var maxwind = 0
    if(maxWind.state instanceof Number)
        maxwind = (maxWind.state as Number).floatValue
    if(wind >= maxwind)                                                                           
        Beregnung.sendCommand(OFF)
        logInfo("watering","Derzeit ist es zu windig! {} km/h: Abbruch!", wind)
    }
end
Ganz wichtig: Keinesfalls darf die Rule bei geringerer Windgeschwindigkeit die Beregnung starten! Du möchtest ja nicht, dass jedes Mal, wenn die Prognose abgerufen wurde, die Beregnung startet (es sei denn, es ist zu windig).
Das wäre auch noch eine Frage... solche Wetterdaten sind eigentlich nur als forecast sinnvoll, und dann müssen sie halt in der Rule abgefragt werden, wie die Beregnung auslöst, also innerhalb des Timers, der die Beregnung auslöst.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

Benutzeravatar
Romel
Beiträge: 42
Registriert: 21. Mai 2020 15:32

Re: Automatisch Gartenbewässerung / Beregnung mit openHAB und Sonoff

Beitrag von Romel »

So geht´s bei mir:

Code: Alles auswählen

var Timer tRegner = null
var int iRegner = 0
var Timer tStartRegner = null


rule "Startzeit einstellen"
when
    Member of gWeekdays changed or                                                                                         // Wochentag geändert
    Item Startzeit_Minuten changed or                                                                                      // Minuten geändert
    Item Startzeit_Stunden changed or                                                                                      // Stunden geändert
    Time cron "1 0 0 * * ?"                                                                                                // täglich um 00:00:01 Uhr
then
    // Alle Wochentag-Items müssen in der Gruppe gWeekdays zusammengefasst sein, damit der Trigger oben funktioniert
    var dayOfWeekSetting = newArrayList(
        Monday.state, 
        Tuesday.state, 
        Wednesday.state, 
        Thursday.state, 
        Friday.state, 
        Saturday.state, 
        Sunday.state
    )
    var int minutes = 0                                                                                     // Initialwert für Minuten definieren
    if(Startzeit_Minuten.state instanceof Number) {                                                         // Falls das Item eine gültige Zahl enthält
        minutes = (Startzeit_Minuten.state as Number).intValue                                                         // Setze minutes auf diese Zahl
        if(minutes > 59) minutes = 0                                                                         // Falls Obergrenze überschritten setze auf 0
        if(minutes < 0) minutes = 59                                                                         // Falls Untergrente unterschritten setze auf 59
    }
    Startzeit_Minuten.postUpdate(minutes)                                                                   // Schreibe Wert in das Item
    var int hours = 0                                                                                       // Initialwert für Sunden definieren
    if(Startzeit_Stunden.state instanceof Number) {                                                        // Falls das Item eine gültige Zahl enthält
        hours = (Startzeit_Stunden.state as Number).intValue                                                          // Setze hours auf diese Zahl
        if(hours > 23) hours = 0                                                                            // Falls Obergrenze überschritten setze auf 0
        if(hours < 0) hours = 23                                                                            // Falls Untergrente unterschritten setze auf 23
    }
    Startzeit_Stunden.postUpdate(hours)                                                                     // Schreibe Wert in das Item
    val int startMinutes = hours * 60 + minutes                                                           // Zeit in Minuten
    tStartRegner?.cancel
    logInfo("watering","Kontrolliere Wochentag")                                                                                  // geplante Beregnung canceln
    if(dayOfWeekSetting.get(now.getDayOfWeek-1) == ON) {                                                    // Falls heute Beregnung gewünscht
        if(now.getMinuteOfDay < startMinutes) {
            logInfo("watering","Warte auf Startzeit")                                                             // Falls Startzeit noch nicht erreicht
            tStartRegner = createTimer(now.withTimeAtStartOfDay.plusMinutes(startMinutes),[|                // Setze einen Timer auf gewünschte Startzeit
                WetterPrognose.sendCommand(ON)                                                                   // Starte zur gewünschten Zeit
            ])
        }
    }
    else logInfo("watering","Wochentag ist Ausgeschaltet")
end

rule "Wetter einbinden"
when
    Item WetterPrognose received command
then 
    var wind = 0
    if(WetterAktuellWindgesch.state instanceof Number){
        wind = ((WetterAktuellWindgesch.state as Number).floatValue).intValue
    var maxwind = 0
    if(maxWind.state instanceof Number)
        maxwind = ((maxWind.state as Number).floatValue).intValue
    if(wind >= maxwind){                                                                           
        Beregnung.sendCommand(OFF)
        logInfo("watering","Derzeit ist es zu windig! {} km/h: Abbruch!", wind)
    }
    else
    {
        Beregnung.sendCommand(ON)
        logInfo("watering","Derzeitiger Wind {} km/h: Beregnung wird gestartet", wind)
    }
    }
end       

rule "Beregnung EIN"
when
    Item Beregnung received command
then
    if(receivedCommand == OFF) {
        logInfo("watering","Beregnung wird abgebrochen!")
        tRegner?.cancel                                                                                                                                         // Timer stoppen
        tRegner = null                                                                                                                                          // Variable leeren
        gRegner.members.filter[i|i.name.contains("Power")].filter[j| j.state != OFF].forEach[r|r.sendCommand(OFF)]                                              // alle Regner abschalten
        //Pumpe.sendCommand(OFF)                                                                                                                                  // Pumpe abschalten
        Sperre.postUpdate(OFF)                                                                                                                                  // Bediensperre aufheben
    }
    else 
    {
    if(tRegner !== null) {
        logInfo("watering","Regner scheint noch zu laufen! Abbruch")
        return;
    }
    iRegner = 0
    Sperre.postUpdate(ON)
    //Pumpe.sendCommand(ON)
    tRegner = createTimer(now.plusMillis(10),[|
        iRegner++                                // nächsten Regener anwählen
        logInfo("regner","{}. Durchlauf",iRegner)
        gRegner.members.filter[i|i.name.contains("Power")].filter[j| j.state != OFF].forEach[r|r.sendCommand(OFF)] // alle Regner abschalten
        val maxRegner = gRegner.members.filter[i|i.name.contains("Sperre")].filter[j| j.state == OFF].size             // wieviele Regner sollen insgesamt beregnen?
        logInfo("regner","{}. Durchlauf von {} Durchläufen.",iRegner,maxRegner)
        if(iRegner > maxRegner) {                // letzten Regner schon erreicht?
            logInfo("regner","Alle Regner sind schon gelaufen!")
            tRegner = null                       // Dann Schluss!
            Sperre.postUpdate(OFF)
            Beregnung.postUpdate(OFF)                                                                                                                       // Item zurücksetzen
            //Pumpe.sendCommand(OFF)  
            return;
        }
        Thread::sleep(500)                       // kleine(!) Pause einlegen
        val strRegner = gRegner.members.filter[i|i.name.contains("Sperre")].filter[j| j.state == OFF].sortBy[name].get(iRegner-1).name.split("_").get(2) //Namen des Regner ermitteln
        logInfo("regner","Nächster Regner: {}",strRegner)
        gRegner.members.filter[i|i.name.contains("Power") && i.name.contains(strRegner)].head.sendCommand(ON)  // Regner einschalten
        val Dauer =(gRegner.members.filter[i|i.name.contains("Dauer") && i.name.contains(strRegner)].head.state as Number).intValue
        logInfo("regner","Regenr wird nach {} Minuten wieder abgeschaltet.",Dauer)
        tRegner.reschedule(now.plusMinutes(Dauer)) // Nächste Ausführung planen
    ])
    }
end 
Die Rule liegt zwischen "Startzeit einstellen" und "Beregnung EIN".

Gesperrt