Seite 1 von 1

Rule mit Verzögerung

Verfasst: 27. Jan 2020 13:17
von ollis112
Hallo,
ich lasse meine Heizkörper abschalten sobald die Tüt oder das Fenster geöffnet wird.
DAs klappt auch prima.
Nun möchte ich aber gerne, dass hier eine Verzögerung greift, damit nicht das Thermostat gleich auf "OFF" geht wenn ich mal kurz auf der Terrasse bin.
Kann mir bitte jemand helfen?
Hier meine Rule.

Code: Alles auswählen

rule"Heizung Ess- und Wohnzimmer"
when 
    Item Terassentuer changed or
    Item WZ_Fenster_S changed or
    Item Temperatur_aussen changed
then
    var Number soll = 0
    if((Temperatur_aussen.state as Number) < 15 && WZ_Fenster_S.state == CLOSED && Terassentuer.state == CLOSED) 
        soll = 2
    else if((Temperatur_aussen.state as Number) > 17 || WZ_Fenster_S.state == OPEN || Terassentuer.state == OPEN) 
        soll = 1
    if(soll > 0) {
        soll = soll -1
        if(Termostat_Wohn.state != soll) 
            Termostat_Wohn.sendCommand(soll)
        if(Termostat_Ess.state != soll) 
            Termostat_Ess.sendCommand(soll)
    } 
end
Vielen Dank schonmal.

Re: Rule mit Verzögerung

Verfasst: 27. Jan 2020 21:33
von bastler
hi olli,
schau dir dazu mal mein rule an, ich hab so was ähnliches in verwendung:

Code: Alles auswählen

import java.util.Map
var Map<String, Timer> fensterOffenTimer = newHashMap

// bei einer Außentemperatur von weniger als 13 Grad erfolgt eine Meldung wenn ein Fenster / eine Türe länger als 20 Minuten offen ist
rule "Fenster_offen_Meldung"
    when
        Member of iG_FensterTuerKontakte changed
    then
        val Number ZeitMinuten = 20

        if((iOwTemp_KWL_Aussen.state as QuantityType<Number>).intValue >= 13){
            logInfo("Fenster_offen_Meldung", "(" + transform("MAP", "bticino.map", triggeringItem.name) + ") Fenster_offen_Meldung inaktiv weil draußen warm genug")
            fensterOffenTimer.get(triggeringItem.name)?.cancel
            fensterOffenTimer.remove(triggeringItem.name)
            return;
        }
        switch(triggeringItem.state){
            case ON:{
                logInfo("Fenster_offen_Meldung", "neuer Timer für: " + transform("MAP", "bticino.map", triggeringItem.name))
                fensterOffenTimer.put(triggeringItem.name, createTimer(now.plusMinutes(ZeitMinuten.intValue), [|
                    logInfo("Fenster_offen_Meldung", transform("MAP", "bticino.map", triggeringItem.name) + " seit " + ZeitMinuten)
                    if(iVi_Fenster_offen_MeldungMail.state == ON){
                        sendMail("mail@meine-adresse.de","Fenster_offen_Meldung", transform("MAP", "bticino.map", triggeringItem.name) + " seit " + TimerLength)
                    }
                    //fensterOffenTimer.get(triggeringItem.name).reschedule(now.plusMinutes(1))
                    if (fensterOffenTimer.get(triggeringItem.name) !== null){
                        fensterOffenTimer.get(triggeringItem.name).cancel();
                        fensterOffenTimer.remove(triggeringItem.name)
                    }
                ]))
            }
            case OFF:{
                if (fensterOffenTimer.get(triggeringItem.name) !== null){
                    fensterOffenTimer.get(triggeringItem.name).cancel();
                    fensterOffenTimer.remove(triggeringItem.name)
                    logInfo("Fenster_offen_Meldung", transform("MAP", "bticino.map", triggeringItem.name) + " wurde geschlossen")
                }
            }
        }
    end
das item iG_FensterTuerKontakte ist in der *.items datei definiert (gruppe - einfach bei jedem fenster dazuschreiben)

Code: Alles auswählen

Group:Switch:OR(ON,OFF) iG_FensterTuerKontakte "Fenster und Türen" <alarm>

Switch iEGFlur_TreppeFenster_Kt "Treppe Fenster geöffnet" <error> (iG_FensterTuerKontakte) { channel=blabla... }
... alle weiteren fenster und türen 
hoffe damit kommst du weiter.

vg stefan

Re: Rule mit Verzögerung

Verfasst: 28. Jan 2020 09:57
von eiGelbGeek
Eine relativ einfache Lösung wäre z.b. ein Timer :D

Hier mal auf 5 Minuten gesetzt :)

Code: Alles auswählen

var Timer timerHeizung = null

rule"Heizung Ess- und Wohnzimmer"
when 
    Item Terassentuer changed or
    Item WZ_Fenster_S changed or
    Item Temperatur_aussen changed
then
if (timerHeizung === null) {
	timerHeizung = createTimer(now.plusMinutes(5))[|
		var Number soll = 0
		if((Temperatur_aussen.state as Number) < 15 && WZ_Fenster_S.state == CLOSED && Terassentuer.state == CLOSED) 
				soll = 2
		else if((Temperatur_aussen.state as Number) > 17 || WZ_Fenster_S.state == OPEN || Terassentuer.state == OPEN) 
				soll = 1
		if(soll > 0) {
				soll = soll -1
				if(Termostat_Wohn.state != soll) 
						Termostat_Wohn.sendCommand(soll)
				if(Termostat_Ess.state != soll) 
						Termostat_Ess.sendCommand(soll)
		}
	]
} else {
		timerHeizung.reschedule(now.plusMillis(5))
}
end
Das ganze würde ich persönlich noch etwas erweitern..... Bei Open würde ich die 5 Minuten warten bei Close die Heizung sofort wieder anwerfen, sofern sie aus war und eingeschaltet werden soll ;-) Könnte dann vermutlich wie folgt aussehen, einfach mal testen (hoffe habe keine Fehler eingebaut ;-) ) Kannst zum testen das ganze ja auch auf 1 Minute setzen und ggf. noch paar LOG Infos einbauen, damit du siehst was passiert :-)

Code: Alles auswählen

var Timer timerHeizung = null

rule"Heizung Ess- und Wohnzimmer"
when 
    Item Terassentuer changed or
    Item WZ_Fenster_S changed or
    Item Temperatur_aussen changed
then
if (Terassentuer.state == OPEN || WZ_Fenster_S.state == OPEN) {
	if (timerHeizung === null) {
		timerHeizung = createTimer(now.plusMinutes(5))[|
			var Number soll = 0
			if((Temperatur_aussen.state as Number) > 17) 
					soll = 1
			if(soll = 1) {
					soll = soll -1
					if(Termostat_Wohn.state != soll) 
							Termostat_Wohn.sendCommand(soll)
					if(Termostat_Ess.state != soll) 
							Termostat_Ess.sendCommand(soll)
			}
		]
	} else {
			timerHeizung.reschedule(now.plusMillis(5))
	}
} else if (Terassentuer.state == CLOSED && WZ_Fenster_S.state == CLOSED) {
		if (timerHeizung !== null) timerHeizung.cancel()
		var Number soll = 0
		if((Temperatur_aussen.state as Number) < 15) 
				soll = 2
		if(soll = 2) {
				soll = soll -1
				if(Termostat_Wohn.state != soll) 
						Termostat_Wohn.sendCommand(soll)
				if(Termostat_Ess.state != soll) 
						Termostat_Ess.sendCommand(soll)
		}
end