Seite 1 von 1

Rule mit zwei Bewegungsmelder Verbraucher schalten

Verfasst: 24. Sep 2020 17:37
von djuscha
möchte mit zwei Bewegungsmelder um die reichweite zu erhöhen Eho Dot schalten
Mit einem Bewegungsmelder ging das so

Code: Alles auswählen


var Timer Alexa_Timer = null
val Integer Alexa_TimeOut = 70


rule "Alexa Garage"  //schalten Alexa Garage
when
Item AqaraBew changed from OFF to ON 
then
	 
		if (Alexa_Timer !== null) {
		Echo_Garage_Radio.sendCommand(ON)
			logInfo("Alexa","Einschalten  " + Alexa_TimeOut + " Seconds")
			Alexa_Timer.reschedule(now.plusSeconds(Alexa_TimeOut))
			

		} else {
			logInfo("Alexa", "Alexa Bewegung erkannt! Schalte Sie Alexa ein")
			Echo_Garage_Radio.sendCommand(ON)
			logInfo("Alexa","Einschalten   " + Alexa_TimeOut + " Seconds")
			Alexa_Timer= createTimer(now.plusSeconds(Alexa_TimeOut))
			[|
				if (AqaraBew.state ==  ON) 
				
				 {
					logInfo("Alexa","Einschalten  Timer ausgelöst, aber erneut für angefangen " + Alexa_TimeOut + " Seconds")
					Alexa_Timer.reschedule(now.plusSeconds(Alexa_TimeOut))
				} else {
					logInfo("Alexa", "Alexa Keine Bewegung erkannt!   ausschalten")
					Echo_Garage_Radio.sendCommand(OFF)
					Alexa_Timer = null
				}
			]
		}
	
wie mache ich das mit zwei Bewegungsmelder
so?

Code: Alles auswählen

rule "Alexa Garage"  //schalten Alexa Garage 2 Bewegungsmelder
when


Item AqaraBew changed from OFF to ON or
Item AqaraBew1 changed from OFF to ON
then
	 
		if (Alexa_Timer !== null) {
		Echo_Garage_Radio.sendCommand(ON)
			logInfo("Alexa","Einschalten  " + Alexa_TimeOut + " Seconds")
			Alexa_Timer.reschedule(now.plusSeconds(Alexa_TimeOut))
			

		} else {
			logInfo("Alexa", "Alexa Bewegung erkannt! Schalte Sie Alexa ein")
			Echo_Garage_Radio.sendCommand(ON)
			logInfo("Alexa","Einschalten   " + Alexa_TimeOut + " Seconds")
			Alexa_Timer= createTimer(now.plusSeconds(Alexa_TimeOut))
			[|
				if (AqaraBew.state ==  ON) 
				if (AqaraBew1.state ==  ON)
				 {
					logInfo("Alexa","Einschalten  Timer ausgelöst, aber erneut für angefangen " + Alexa_TimeOut + " Seconds")
					Alexa_Timer.reschedule(now.plusSeconds(Alexa_TimeOut))
				} else {
					logInfo("Alexa", "Alexa Keine Bewegung erkannt!   ausschalten")
					Echo_Garage_Radio.sendCommand(OFF)
					Alexa_Timer = null
				}
			]
		}
	
 

Code: Alles auswählen

if (AqaraBew.state ==  ON) 
if (AqaraBew1.state ==  ON)
die Abfrage ist aber und ??
wie mache ich das mit oder?

Oder gibt es noch besere Lösung?

Re: Rule mit zwei Bewegungsmelder Verbraucher schalten

Verfasst: 24. Sep 2020 21:36
von udo1toni
Ich habe die Rule etwas umgebaut. Deine Rule ist unnötig komplex.

Code: Alles auswählen

var Timer Alexa_Timer = null
val Integer Alexa_TimeOut = 70

rule "Alexa Garage"  //schalten Alexa Garage
when
    Item AqaraBew received update ON or
    Item AqaraBew1 received update ON
then
    logInfo("Alexa", "Alexa Bewegung erkannt!")
    Alexa_Timer?.cancel                                          // Timer abbrechen
    if(Echo_Garage_Radio.state != ON) {                          // falls nicht eingeschaltet
        logInfo("Alexa", "Schalte Alexa ein")
        Echo_Garage_Radio.sendCommand(ON)                        // Einschalten
    }
    logInfo("Alexa","Timeout {} Seconds", Alexa_TimeOut)
    Alexa_Timer = createTimer(now.plusSeconds(Alexa_TimeOut), [| // Timer anlegen
        logInfo("Alexa", "Timeout erreicht! Ausschalten")
        Echo_Garage_Radio.sendCommand(OFF)                       // und Aus
        Alexa_Timer = null                                       // kann bei dieser Variante auch entfallen!
    ])
end
Der Trigger received update ON triggert auch, wenn der Bewegungsmelder mehrfach ein ON-Signal schickt ohne zwischendurch auf OFF zu wechseln.
Die Rule löscht einen eventuell laufenden Timer, schaltet Echo_Garage_Radio an (nur, falls es noch nicht eingeschaltet ist) und legt den Timer neu an.
Falls der Timer nicht durch einen Retrigger der Rule gelöscht und neu angelegt wird, bedeutet dies, dass mit dem Ablauf des Timeouts das Gerät einfach ausgeschaltet werden kann (ohne vorherige Prüfung!)

Nebenbei löst sich damit Dein Problem auf ;), das könntest Du natürlich auch lösen, indem Du beide Bedingungen veroderst (nur ein Bewegungsmelder muss ON melden), also so: if (AqaraBew.state == ON || AqaraBew1.state == ON) aber das ist halt viel zu kompliziert.

Achte bitte auch auf die Formatierung. Die spielt zwar für die Ausführung der Rule kein Rolle, aber sie erleichtert die Zuordnung. Allgemein wird eine Einrückung um jeweilse vier Leerzeichen verwendet (ein Tab erzeugt im Forum acht Leerzeichen)
Leerzeilen innerhalb des Codes sind für die Lesbarkeit allgemein prima, aber sie vergrößern den Codeblock im Forum. Deshalb sind sie hier fehl am Platz.
Um in log Befehlen Variablen auszugeben, bietet sich die Substitution an ({} wird durch die jeweils nächste durch Komma abgetrennte Variable ersetzt)
Beachte bitte auch die andere Schreibweise des Timers. Es ist sinnvoll, das Lambda als Parameter der createTimer() Funktion zu betrachten, auch wenn die separate Schreibweise ebenfalls möglich ist.

Re: Rule mit zwei Bewegungsmelder Verbraucher schalten

Verfasst: 24. Sep 2020 23:20
von djuscha
Vielen Dank Udo!! Werde ich morgen nach der Arbeit ausprobrobieren und berichten .Ich hab mir schon gedacht das du die Rule einfacher machst als ich..:)

Re: Rule mit zwei Bewegungsmelder Verbraucher schalten

Verfasst: 25. Sep 2020 17:50
von djuscha
Vielen Dank!
Alles getestet alles gut
hab gleich meine andere Rule geändert gleiche Bewegungsmelder sollen bei Bewegung und Lichtintensität unter 5 Licht für 70sec schalten und wenn keine Bewegung mehr da ausschalten ,70 sec weil der Bewegungsmelder von Xiaomi eine Minute Status Bewegung meldet
hoffentlich hab ich alles richtig verstanden was du erklärt hast :)

Code: Alles auswählen

var Timer LGS_Timer = null
val Integer LGS_TimeOut = 70

rule "Licht Bewegung Garage"    //Einschalten Hue Strip  in der Garage
when
    Item AqaraBew received update ON or
    Item AqaraBew1 received update ON
then
    logInfo("Licht Garage", "Lcht Bewegung erkannt!")
     LGS_Timer?.cancel                                    // Timer abbrechen
  if (AqaraBew_Illu.state < 5 ) {                        //Illuminance unter 5 Bewegungsmelder 1
  if (AqaraBew_Illu1.state < 5 ) {                    //oder Illuminance unter 5 Bewegungsmelder 2
  if(Light9_Toggle.state != ON) {                          // falls nicht eingeschaltet
        logInfo("Licht", "Schalte Lichtstrip ein")
        Light9_Color.sendCommand ("227,30,100")                       // Einschalten Hue kaltweiss
    }
    logInfo("Licht","Timeout {} Seconds", LGS_TimeOut)
    LGS_Timer = createTimer(now.plusSeconds(LGS_TimeOut), [| // Timer anlegen
        logInfo("Alexa", "Timeout erreicht! Ausschalten")
        Light9_Toggle.sendCommand ("OFF")                       // und Aus
        LGS_Timer = null                                       // kann bei dieser Variante auch entfallen!
    ])
  }}
end


Re: Rule mit zwei Bewegungsmelder Verbraucher schalten

Verfasst: 25. Sep 2020 19:45
von Boris099
und nur zur Absicherung, habe eine ähnliche Situation aber ohne dieses Alexa Zeugs :D und ohne log, könnte das dann so aussehen, korrekt?
Noch eine Frage zu ZWave items, die muß man ja gar nicht in der .items Datei definieren, wenn ich die nun gruppieren möchte, mache ich das dann trotzdem in der .items Datei?

Code: Alles auswählen

var Timer LampenUG = null
val Integer Lampen_TimeOut = 10

rule "Lampen im UG"
when
    Item ZWAVE1 received update ON or
    Item ZWAVE2 received update ON
then
    LampenUG?.cancel                                          // Timer abbrechen
    if(gLampenUG.state != ON) {                          // falls nicht eingeschaltet
        gLampenUG.sendCommand(ON)                        // Einschalten
    }
    LampenUG = createTimer(now.plusMinutes(Lampen_TimeOut), [| // Timer anlegen
        gLampenUG.sendCommand(OFF)                       // und Aus
        LampenUG = null                                       // kann bei dieser Variante auch entfallen!
    ])
end

Re: Rule mit zwei Bewegungsmelder Verbraucher schalten

Verfasst: 25. Sep 2020 21:03
von udo1toni
Wenn Du mehrere Rules mit identischen Triggern hast, solltest Du daraus jeweils eine Rule machen.
Identische Trigger -> Rules werden immer gleichzeitig ausgeführt -> Unnötiges Belegen mehrerer Threads.
Ansonsten ist die Abfrage der Helligkeit falsch. Ein wichtiger Schlüssel zum Verständnis von Rules ist, den Code korrekt zu formatieren. Dein Code sieht, korrekt eingerückt, so aus:

Code: Alles auswählen

var Timer LGS_Timer = null
val Integer LGS_TimeOut = 70

rule "Licht Bewegung Garage"    //Einschalten Hue Strip  in der Garage
when
    Item AqaraBew received update ON or
    Item AqaraBew1 received update ON
then
    logInfo("Licht Garage", "Lcht Bewegung erkannt!")
    LGS_Timer?.cancel                                                       // Timer abbrechen
    if (AqaraBew_Illu.state < 5 ) {                                         //nur falls Illuminance unter 5 Bewegungsmelder 1
        if (AqaraBew_Illu1.state < 5 ) {                                    //nur falls Illuminance unter 5 Bewegungsmelder 2
            if(Light9_Toggle.state != ON) {                                 // nur falls nicht eingeschaltet
                logInfo("Licht", "Schalte Lichtstrip ein")
                Light9_Color.sendCommand ("227,30,100")                     // Einschalten Hue kaltweiss
            }
            logInfo("Licht","Timeout {} Seconds", LGS_TimeOut)
            LGS_Timer = createTimer(now.plusSeconds(LGS_TimeOut), [|        //Timer anlegen
                logInfo("Alexa", "Timeout erreicht! Ausschalten")
                Light9_Toggle.sendCommand ("OFF")                           // und Aus
                LGS_Timer = null                                            // kann bei dieser Variante auch entfallen!
            ])
        }
    }
end
Wobei ich die Kommentare etwas angepasst habe, damit sie der Realität entsprechen ;)
Das Ineinanderschachteln von Bedingungen ist immer eine logische UND-Verknüpfung, Du möchtest aber, das lediglich eine der beiden Bedingungen zutreffen muss. Dafür gibt es die Bool'sche Algebra.

Code: Alles auswählen

var Timer LGS_Timer = null
val Integer LGS_TimeOut = 70

rule "Licht Bewegung Garage"                                        // Einschalten Hue Strip in der Garage
when
    Item AqaraBew  received update ON or
    Item AqaraBew1 received update ON
then
    logInfo("Licht Garage", "Lcht Bewegung erkannt!")
    LGS_Timer?.cancel                                               // Timer abbrechen
    if (AqaraBew_Illu.state < 5 || AqaraBew_Illu1.state < 5 ) {     // nur falls Bewegungsmelder 1 oder 2 Illuminance unter 5
        if(Light9_Toggle.state != ON) {                             // nur falls nicht eingeschaltet
            logInfo("Licht", "Schalte Lichtstrip ein")
            Light9_Color.sendCommand ("227,30,100")                 // Einschalten Hue kaltweiss
        }
        logInfo("Licht","Timeout {} Seconds", LGS_TimeOut)
        LGS_Timer = createTimer(now.plusSeconds(LGS_TimeOut), [|    // Timer anlegen
            logInfo("Alexa", "Timeout erreicht! Ausschalten")
            Light9_Toggle.sendCommand ("OFF")                       // und Aus
        ])
    }
end
Symbole der Bool'schen Algebra:

Code: Alles auswählen

&& -> UND
|| -> ODER
!  -> NICHT
Vergleiche:

Code: Alles auswählen

== -> ist gleich
>  -> ist größer als
<  -> ist kleiner als
>= -> ist größer oder gleich
<= -> ist kleiner oder gleich
!= -> ist ungleich
Du kannst damit verschiedenste Verknüpfungen bilden, z.B.

Code: Alles auswählen

if((Bedingung1 || Bedingung2) && !Bedingung3)
Bedeutet: Mindestens Bedingung1 ODER Bedingung2 muss zutreffen. Bedingung3 darf nicht zutreffen. Klammern sind hier enorm wichtig. Lässt man sie weg, so ändert sich die Bedeutung (ENTWEDER Bedinung1 trifft zu, ODER Bedingung2 trifft zu UND Bedingung3 trifft nicht zu).

Re: Rule mit zwei Bewegungsmelder Verbraucher schalten

Verfasst: 25. Sep 2020 22:53
von djuscha
udo1toni hat geschrieben: 25. Sep 2020 21:03 Wenn Du mehrere Rules mit identischen Triggern hast, solltest Du daraus jeweils eine Rule machen.
I
ja das ist ja klar ist aber ..einmal nur Bewegung ...und zweite mal dazu noch Lichtintensität.. wie gehe ich dann vor?

Re: Rule mit zwei Bewegungsmelder Verbraucher schalten

Verfasst: 26. Sep 2020 06:27
von udo1toni
Nein, es geht nicht darum, was Du im Code der Rules machst, es kommt allein auf die Trigger an. In diesem Fall sind es ja die gleichen Bewegungsmelder.
Du musst einfach den Code beider Rules untereinander kopieren. Oder Du machst es etwas hübscher ;) so:

Code: Alles auswählen

// Globale Variablen
var Timer Alexa_Timer = null                                                // Timer für autoamtische Abschaltung Alexa Garage 
var Timer LGS_Timer = null                                                  // Timer für automatisch Abschaltung Licht Garage

// Globale Konstanten
val Integer Alexa_TimeOut = 70                                              // Timeout Alexa Garage Abschaltung
val Integer LGS_TimeOut   = 70                                              // Timeout Licht Garage Abschaltung


rule "Bewegung Garage"                                                      // Bewegungsmelder Garage
when
    Item AqaraBew received update ON or
    Item AqaraBew1 received update ON
then
    logInfo("presence.garage", "Bewegung in der Garage erkannt!")
    Alexa_Timer?.cancel                                                     // Alexa Timer abbrechen
    LGS_Timer?.cancel                                                       // Licht Timer abbrechen
    if(Echo_Garage_Radio.state != ON) {                                     // falls Alexa nicht eingeschaltet
        logInfo("presence.garage", "Schalte Alexa ein")
        Echo_Garage_Radio.sendCommand(ON)                                   // Alexa einschalten
    }
    logInfo("presence.garage","Alexa Timeout {} Seconds", Alexa_TimeOut)
    Alexa_Timer = createTimer(now.plusSeconds(Alexa_TimeOut), [|            // Alexa Timer anlegen
        logInfo("presence.garage", "Alexa Timeout erreicht! Ausschalten")
        Echo_Garage_Radio.sendCommand(OFF)                                  // und Alexa ausschalten
    ])
    if (AqaraBew_Illu.state < 5 || AqaraBew_Illu1.state < 5 ) {             // falls Helligkeit Bewegungsmelder1 oder Bewegungsmelder2 unter 5
        if(Light9_Toggle.state != ON) {                                     // falls Licht nicht eingeschaltet
            logInfo("presence.garage", "Schalte Lichtstrip ein")
            Light9_Color.sendCommand ("227,30,100")                         // Hue kaltweiss einschalten
        }
        logInfo("presence.garage","Licht Timeout {} Seconds", LGS_TimeOut)
        LGS_Timer = createTimer(now.plusSeconds(LGS_TimeOut), [|            // Licht Timer anlegen
            logInfo("presence.garage", "Timeout erreicht! Ausschalten")
            Light9_Toggle.sendCommand(OFF)                                  // Licht ausschalten
        ])
    }
end
Du hast für die Hue mehrere Items angelegt. Ich gehe davon aus, dass diese trotzdem alle direkt mit der Hue verbunden sind. In diesem Fall wäre das so nicht notwendig. Das Color Item kann ohne weiteres mit dem Befehlen ON und OFF umgehen, Du kannst also auch statt Light9_Toggle.sendCommand(OFF) einfach Light9_Color.sendCommand(OFF) nutzen (man beachte die fehlenden Anführungszeichen, OFF ist vom Typ OnOff, nicht vom Typ String).
Etwas komplizierter wird es lediglich bei der Abfrage des Status, da der Color Channel erstmal HSBType zurückliefert. Dennoch kann man auch if(Light9_Toggle.state != ON) ersetzen, nämlich mit if(Light9_Color.getStateAs(OnOffType) != ON)

Re: Rule mit zwei Bewegungsmelder Verbraucher schalten

Verfasst: 26. Sep 2020 15:16
von djuscha
ooo Mann das ist ja richtig geil :) Udo du sollst langsam Wiki für Openhab auf deutsch machen !! mit Beispielen und Erklärungen. Das machst du richtig Klasse!
Vielen Dank!