Seite 1 von 1

Bewegungsmelder - Timer

Verfasst: 11. Okt 2019 15:19
von JPH
Moin,

ich habe "eigentlich" eine sehr einfache und auch wahrscheinlich alltägliche Anforderung.

Ein Bewegungsmelder soll bei Bewegung Lampen einschalten
Nach 6 Minuten soll die Lampe wieder ausgestellt werden, es sei denn es gab weitere Bewegungen. Sollte es weitere Bewegungen geben, dann wird die Zeit einfach wieder verlängert und wieder auf 6 Minuten gestellt.

Code: Alles auswählen


var Elternbad_Timer = null


rule "Bewegungsmelder ElternBad"
   when 
      Item ElternBadBewegung received command ON 
   then	
   {
      LCNElternbad.sendCommand("ON")

      if	(Elternbad_Timer === null)	
      {
	      Elternbad_Timer = createTimer(now.plusSeconds(360)) 
         [| sendCommand (LCNElternbad, OFF) Elternbad_Timer = null]
	   }	
      else	
      { 
         Elternbad_Timer.reschedule(now.plusSeconds(360))	
      }

Leider erhalte ich bei dem Befehl: Elternbad_Timer.reschedule(now.plusSeconds(60)) folgende Fehlermeldung:

"message": "The method reschedule(DateTime) is undefined for the type Object" bei der Zeile Elternbad_Timer.reschedule(now.plusSeconds(360))

Hat jemand eine Erklärung? Oder ist der Ansatz vom Grundsatz schon falsch? Für eine Hilfe wäre ich sehr dankbar.

Re: Bewegungsmelder - Timer

Verfasst: 11. Okt 2019 17:54
von eiGelbGeek
Irgendwie fehlt da was an Code ..... und wofür ist die { nach then ?

Im Timer sitzt eine Klammer ) falsch

Versuche es mal so :-)

Code: Alles auswählen

var Elternbad_Timer = null

rule "Bewegungsmelder ElternBad"
when 
  Item ElternBadBewegung received command ON 
then	
  LCNElternbad.sendCommand("ON")
  if (Elternbad_Timer === null) {
    Elternbad_Timer = createTimer(now.plusMinutes(6)[|
      sendCommand (LCNElternbad, OFF) 
      Elternbad_Timer = null
    ])
  } else {
      Elternbad_Timer.reschedule(now.plusMinutes(6))
  }
end

Re: Bewegungsmelder - Timer

Verfasst: 11. Okt 2019 21:11
von JPH
Hm,

habe ich natürlich gleich umgesetzt..... :-)

Allerdings bekomme ich jetzt noch mehr Fehlermeldungen:
Elternbad_Timer = createTimer(now.plusMinutes(6)
--> "message": "Invalid number of arguments. The method createTimer(AbstractInstant, Procedure0) is not applicable for the arguments (DateTime)"
--> "message": "Invalid number of arguments. The method plusMinutes(int) is not applicable for the arguments (int,()=>Object)"

Elternbad_Timer.reschedule(now.plusMinutes(6))
--> "message": "The method reschedule(DateTime) is undefined for the type Object",

Es scheint irgendwie an der Variablenanlage zu liegen.

Re: Bewegungsmelder - Timer

Verfasst: 11. Okt 2019 22:19
von KellerK1nd

Code: Alles auswählen

 var Timer Elternbad_Timer = null
So sollte die Variable aussehen.

Re: Bewegungsmelder - Timer

Verfasst: 11. Okt 2019 23:43
von udo1toni
Ein paar Hinweise hierzu:
  • Sollte LCNElternbad ein Switch Item sein, so solltest Du besser OnOffType verwenden (das heißt, weg mit den Anführungszeichen)
  • Bitte verwende bevorzugt die Methode Item.sendCommand(Befehl) anstatt der Action sendCommand(Item,Befehl)
    Die Action kann nur mit Strings umgehen (Objekte werden automatisch als String interpretiert, wenn dies möglich ist), sobald Du mit Primitives arbeitest, wird es zu Problemen kommen. Die Methode kann alle sinnvollen Datentypen verarbeiten (vom Itemtyp abhängig).
  • Timer.reschedule() funktioniert nur, solange der Timer noch nicht abgelaufen ist (bzw. solange das Lambda noch nicht ausgeführt wurde). Normalerweise sollte das kein Problem sein, man sollte das aber im Hinterkopf behalten, falls die Rules (insbesondere das Lambda) komplexer werden.
Eine Variante der Rule:

Code: Alles auswählen

var Timer Elternbad_Timer = null

rule "Bewegungsmelder ElternBad"
when 
    Item ElternBadBewegung received command ON 
then	
    LCNElternbad.sendCommand(ON)
    Elternbad_Timer?.cancel
    Elternbad_Timer = createTimer(now.plusMinutes(6), [|
        LCNElternbad.sendCommand(OFF) 
    ])
end
Der Timer wird gelöscht, falls er existiert und anschließend mit neuer Startzeit wieder angelegt. In diesem Fall spielt der Zustand der Variablen keine Rolle mehr.

Re: Bewegungsmelder - Timer

Verfasst: 13. Okt 2019 09:24
von JPH
Super! Klappt jetzt alles. Dankeschön

Re: Bewegungsmelder - Timer

Verfasst: 3. Jan 2021 14:08
von Thor4x
Hallo zusammen,

ich habe ein ähnliches Vorhaben und die Regel vermeintlich auch schon fertig.

Ich beschreibe kurz, was beabsichtigt ist:
Manchmal wird vergessen, im Badezimmer die Heizung wieder auszuschalten. Ich will daher, dass die Heizung spätestens 2 Stunden nachdem sie angeschaltet wurde, wieder ausgeschaltet wird.
Sie soll aber nur dann ausgeschaltet werden, wenn sie ununterbrochen seit dem 1. Anschalten noch lief (weshalb ich den Timer im Else-Zweig zurücksetze falls es einen gibt).

Code: Alles auswählen

rule "Heizung im Badezimmer nach 2 Stunden ausschalten"
when 
	Item HEIZ_SET_Badezimmer changed		// Wenn sich der Wert des Badezimmer-Thermostats ändert
then
	if (HEIZ_SET_Badezimmer.state > 10) {		// Falls Thermostat auf > 10 Grad C. eingestellt
		Badezimmer_Timer = createTimer(now.plusMinutes(120), [|	// Dann starte einen 120-Minuten Timer
		HEIZ_SET_Badezimmer.sendCommand(5)	// Setze nach Timerablauf die Temperatur wieder auf 5 Grad C.
		])
	}
	else (HEIZ_SET_Badezimmer.state <= 10) {	// Falls Thermostat auf <= 10 Grad C. eingestellt
		Badezimmer_Timer?.cancel		// Dann lösche den Timer falls vorhanden
	}
end
Was denkt ihr, passt das so?

Re: Bewegungsmelder - Timer

Verfasst: 3. Jan 2021 17:01
von udo1toni
Ja und nein. Grundsätzlich sieht die Regel erst mal gut aus, allerdings musst Du auch wenn Du den Timer anlegst, sicherstellen, dass der Timer nicht schon existiert. Die Rule kann also erheblich vereinfacht werden:

Code: Alles auswählen

rule "Heizung im Badezimmer nach 2 Stunden ausschalten"
when 
    Item HEIZ_SET_Badezimmer changed                            // Wenn sich der Wert des Badezimmer-Thermostats ändert
then
    Badezimmer_Timer?.cancel                                    // lösche den Timer falls vorhanden
    if (HEIZ_SET_Badezimmer.state > 10)                         // Falls Thermostat auf > 10 Grad C. eingestellt
        Badezimmer_Timer = createTimer(now.plusMinutes(120), [|	// Dann starte einen 120-Minuten Timer
            HEIZ_SET_Badezimmer.sendCommand(5)	                // Setze nach Timerablauf die Temperatur wieder auf 5 Grad C.
        ])
end

Re: Bewegungsmelder - Timer

Verfasst: 3. Jan 2021 22:30
von Thor4x
Ja, das macht Sinn. Danke für deine Korrektur!