Garagentor Rule mit Zeitraum

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

freeman121083
Beiträge: 111
Registriert: 16. Jul 2018 06:32

Re: Garagentor Rule mit Zeitraum

Beitrag von freeman121083 »

Hi,

na viel gibt es nicht zu sagen es ist ein Magnetkontakt oder auch Rolltorkontakt und dieser liegt auf einem knx mdt Binäreingang.

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

Re: Garagentor Rule mit Zeitraum

Beitrag von udo1toni »

Das wichtige Stichwort ist hier knx :)
Es geht also nur darum, wie ein Kontakt im knx2 Bindging zu konfigurieren ist...

Code: Alles auswählen

Type contact : ch1 "Garage" [ ga="<1/2/3" ]
Alternativ könnte es natürlich auch contact-control sein, was Dich weiter bringt.

Letztlich konfigurierst Du das exakt so, wie alle anderen knx2 Channel.
Um auf den Status zugreifen zu können, brauchst Du anschließend natürlich noch ein Item, wahlweise vom Typ Contact oder Switch, wobei Contact dann entweder OPEN oder CLOSED sein kann, Switch wäre entweder OFF oder ON (was beim Anlegen von Rules berücksichtigt werden muss).

Zur Visualisierung reicht dann ein Text Widget (damit kein Schalter dazu gemalt wird.)
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

freeman121083
Beiträge: 111
Registriert: 16. Jul 2018 06:32

Re: Garagentor Rule mit Zeitraum

Beitrag von freeman121083 »

Ach super besten Dank für die Unterstützung.

Den Rest Bau ich mir schon zusammen. Wenn die Rule fertig ist würde ich Sie gerne noch einmal posten, dann könnt ihr als Experten noch einmal drüber schauen. Gibt es eigentlich Lesestoff zum Thema rules erstellen? Irgenwie muss ich mir das besser aneignen.

Vielen Dank
Gruß Dennis

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

Re: Garagentor Rule mit Zeitraum

Beitrag von udo1toni »

Leider gibt es bisher keine Dokumentation zur Rule Engine, dafür aber tonnenweise Rules in zwei Foren sowie github plus jede Menge Code auf anderen Seiten, die sich mit openHAB beschäftigen (inclusive dieses Forum)
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

freeman121083
Beiträge: 111
Registriert: 16. Jul 2018 06:32

Re: Garagentor Rule mit Zeitraum

Beitrag von freeman121083 »

Hi,

doch noch nicht geschafft :-(

ich habe den KNX Kontakt folgendermaßen angelegt

items:

Code: Alles auswählen

 Contact Garage_kontakt         			"Garage Status" 		(gGaragentor)	 		["Contact"]         	{ channel="knx:device:bridge:generic:Garage_kontakt" }
things:

Code: Alles auswählen

Type contact : Garage_kontakt			"Contact" 		[ ga="1/4/1" ]
in der Paper UI unter Control bekomme ich aber keinen Status angezeigt? Bevor ich meine rule für das Garagentor teste, muss ich natürlich sicher gehen das der Kontakt richtig ausgewertet wird.

freeman121083
Beiträge: 111
Registriert: 16. Jul 2018 06:32

Re: Garagentor Rule mit Zeitraum

Beitrag von freeman121083 »

Hat sich erledigt!


einfach mal in das event.log schauen: :-)

Code: Alles auswählen

2018-07-19 21:49:07.774 [vent.ItemStateChangedEvent] - Garage_kontakt changed from OPEN to CLOSED

Trotzdem Danke!

freeman121083
Beiträge: 111
Registriert: 16. Jul 2018 06:32

Re: Garagentor Rule mit Zeitraum

Beitrag von freeman121083 »

So wie versprochen jetzt kappt es!
Garagentor zwischen 19:00 - 05:00 Uhr prüfen auf; "länger als 15min." geöffnet, wenn ja dann nach Ablauf des Timers noch einmal prüfen ob es immer noch auf ist. wenn ja dann Push nachricht, wenn nein timer löschen und keine Push nachricht.

Ist das soweit korrekt?

Code: Alles auswählen

import org.openhab.model.script.actions.*

var Timer timer = null

    rule "Garage Timer"
    when
    	Item Garage_kontakt changed from CLOSED to OPEN
    then
    	if(now.getHourOfDay >= 19 || now.getHourOfDay <=5) {
    		if(Garage_kontakt.state==OPEN) {
			logInfo("Garage_kontakt", "Garage ist auf")
      			timer = createTimer(now.plusMinutes(15)) [|
    		if(Garage_kontakt.state==OPEN) 
    			sendTelegram("Dennis", "Garage ist laenger als 15min. auf! ")
                        timer = null
    			]
    		} 
    	}
 	else {
            if(timer!=null) {
                timer.cancel
                timer = null
	}
	}
end

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

Re: Garagentor Rule mit Zeitraum

Beitrag von udo1toni »

Prima :)

Ein paar Anmerkungen:
  1. now.getHourOfDay <=5 gilt auch für 05:59:59 Uhr, die Rule wird also bis 6 Uhr den Timer anlegen, nicht bis 5 Uhr
  2. Anstatt innerhalb des Timers nachzuschauen, ob die Tür noch offen ist, wäre es eleganter, wenn die Tür geschlossen wird, den Timer zu löschen. Das kann man auch von einer zweiten Rule aus machen, die dann halt auf changed to CLOSED triggern muss. Wenn man es in einer Rule abwickelt, bleibt der Zusammenhang der Funktionen erhalten.
  3. Den Timer auf null zu setzen, ist nicht zwingend notwendig, wenn Du dieses Kriterium nicht abfragst.
  4. Du solltest sicherstellen, dass immer nur ein Timer angelegt ist. Das müsstest Du vor dem createTimer() prüfen, sonst könnte es passieren, dass mehrere Timer gleichzeitig scharf sind. Dabei hast Du nur für den zuletzt angelegten Timer einen Handle, so dass Du auch nur diesen abbrechen kannst.
  5. Falls Du außerhalb des Zeitfensters das Tor öffnest, wird die Rule immer versuchen, einen laufenden Timer zu löschen. Der kann aber eigentlich nicht existieren, es sei denn, Du hast kurz vor 6 Uhr das Tor geöffnet, dann geschlossen und kurz nach 6 Uhr wieder geöffnet.
  6. Die Prüfung if(timer!=null) sollte eine Warnung ergeben.
    Die Prüfung auf null (das ist etwas anderes als NULL!) sollte so aussehen: if(timer !== null). Der Operator === bzw. !== prüft, ob beide Seiten identisch bzw. nicht identisch sind (identisch ist etwas anderes als gleich).
So als Idee: eventuell wäre es einfacher, den Timer immer zu starten, und dann innerhalb des Timers zu prüfen, ob man sich im fraglichen Zeitraum befindet. Was dann natürlich bedeutet, dass der Alarm schon anschlägt, wenn man die Tür knapp eine Viertelstunde vorher geöffnet hat, aber das kann man ja bei der Wahl des Zeitraums berücksichtigen: if(now.getMinuteOfDay > 19 * 60 + 14 || now.getMinuteOfDay < 5 * 60). Dann kann sich die Rule einfach um die zwei Fälle "Tür auf" und "Tür zu" kümmern, im einen Fall wird der Timer angelegt, im anderen Fall wird der Timer gecancelt.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

freeman121083
Beiträge: 111
Registriert: 16. Jul 2018 06:32

Re: Garagentor Rule mit Zeitraum

Beitrag von freeman121083 »

erst einmal vielen Dank für die ausführliche Antwort.

Ich denke ich hab grundsätzlich ein Verständnis Problem.

1.) OK aber 06:00 Uhr wäre auch OK, sonst würde ich es ändern auf 04:00 Uhr

2.) Der Sinn meiner seits war das ich NACH Ablauf des Timers prüfen möchte ob das Garagentor noch offen ist und wenn ja dann soll eine Push Nachricht gesendet werden. Was meinst Du mit innerhalb des Timers? Wenn das Garagentor innerhalb der 15min geschlossen wurde soll der Timer gelöscht werden.
3.) OK
4.) Warum sollten mehrer Timer laufen? Der Timer soll gestartet werden 15min. laufen ab - wenn die Zeit abgelaufen ist was passiert dann mit dem Timer? Der ist doch dann "aus/gecancelt" oder?
5.) Warum läuft die Rule überhaupt weiter? Sie soll doch nur weiter laufen im entsprechendem Zeitraum.
6.) Hier komme ich noch nicht so ganz mit? Wäre nicht besser den Timer dann zu löschen?



Danke

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

Re: Garagentor Rule mit Zeitraum

Beitrag von udo1toni »

Deine Rule ist momentan so ausgelegt, dass sie, wenn sie ausgelöst wird, prüft, ob der Zeitraum für die Benachrichtigung gegeben ist. Ist das der Fall, startest Du den Timer.

Jetzt stelle Dir folgendes vor: es ist 19:00 Uhr. Du öffnest die Garage. Der Timer wird angelegt. Um 19:02 schließt Du die Garage. Um 19:05 fällt Dir ein, dass Du noch etwas aus der Garage brauchst, Du öffnest die Garage. Ein zweiter Timer wird angelegt. Der Handle auf den ersten Timer wird mit dem Handle auf den zweiten Timer überschrieben, der erste Timer ist aber immer noch vorhanden und aktiv, nur halt ohne Handle. Um 19:07 schließt Du die Garage. Dummerweise hast Du noch etwas vergessen, Du öffnest die Garage nochmals, um 19:13. Ein dritter Timer wird angelegt (das gleiche Spiel wie beim 2. Timer).
Du brauchst diesmal etwas länger, nämlich 10 Minuten, bis Du die Garage wieder schließt. In der Zwischenzeit hast Du um 19:15 eine Nachricht bekommen, denn der 1. Timer läuft ab, und das Tor ist um 19:15 geöffnet. Um 19:20 bekommst Du eine zweite Nachricht, denn da läuft der 2. Timer ab und das Tor ist immer noch offen, trotzdem war das Tor nie mehr als 10 Minuten geöffnet.
Es reicht also nicht, beim Ablauf des Timer zu prüfen, ob das Tor geöffnet ist, Du müsstest dann schon prüfen, ob das Tor ohne Unterbrechung immer noch geöffnet ist. Also ist ein anderer Aufbau eleganter:

Code: Alles auswählen

var Timer tGarage = null                                                        //vermeide unspezifische Variablen

rule "Garage Timer"
when
    Item Garage_kontakt changed
then
    if(Garage_kontakt.state == OPEN) {                                          //falls Garage geöffnet wurde
        tGarage?cancel                                                          // falls noch ein Timer existiert, löschen
        tGarage = createTimer(now.plusMinutes(15), [|
            if(now.getMinuteOfDay > 19 * 60 + 14 || now.getHourOfDay < 5)       // Falls Uhrzeit 19:15:00 - 04:59:59
                sendTelegram("Dennis", "Garage ist laenger als 15min. auf! ")
            tGarage = null                                                      // nur der Ordnung halber...
        ])
    }
    else {                                                                      //falls Garage geschlossen wurde
        tGarage.cancel
        tGarage = null                                                          // nur der Ordnung halber...
    }
end
Der Unterschied ist: Der Timer wird immer angelegt, wenn das Garagentor geöffnet wird. Der Timer wird immer gelöscht, wenn das Garagentor geschlossen wird (die Rule triggert für beide Events und entscheidet anhand des Zustands, was zu tun ist). Wenn der Timer abläuft, wird die Uhrzeit geprüft und gegebenenfalls die Meldung ausgegeben.
Wenn wir auf unnötigen Code verzichten wollen, verkürzt sich die Rule nochmals:

Code: Alles auswählen

var Timer tGarage = null                                                       //vermeide unspezifische Variablen

rule "Garage Timer"
when
    Item Garage_kontakt changed
then
    tGarage?cancel                                                             // falls noch ein Timer existiert, löschen - unabhängig vom Zustand!
    if(Garage_kontakt.state == OPEN)                                           //nur falls Garage geöffnet wurde den Timer erstellen
        tGarage = createTimer(now.plusMinutes(15), [|
            if(now.getMinuteOfDay > 1154 || now.getHourOfDay < 5)      // Falls Uhrzeit 19:15:00 - 04:59:59 (19*60 + 14 = 1154)
                sendTelegram("Dennis", "Garage ist laenger als 15min. auf! ")
        ])
end
der Codeschnipsel

Code: Alles auswählen

tGarage?.cancel
ist funktionsgleich zu

Code: Alles auswählen

if(tGarage !== null) tGarage.cancel
Wie oben erwähnt, ist es nicht notwendig, die Timer-Variable wieder auf null zu initialisieren. Bei der Definition könnte man auch darauf verzichten, aber das ist besserer Stil :)
Es ist in der DSL egal, ob man nun das Lambda (der Teil innerhalb []) als Teil des Funktionsaufrufs createTimer() oder dahinter schreibt, logisch gehört es aber zum Timer, so dass man besser createTimer(timestamp,lambda) schreibt statt createTimer(timestamp) lambda.

Der Import sollte unter OH2 übrigens nicht nötig sein. Der Code sollte (dann mit passenden Imports) uneingeschränkt auch unter OH1.x laufen (eigentlich sogar schon unter OH0.8 oder OH0.9, aber die müssen wir, glaube ich, nicht mehr berücksichtigen :) )
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

Antworten