DOIF Frage - Event unterdrücken

Begonnen von Waldmensch, 21 Februar 2016, 23:11:50

Vorheriges Thema - Nächstes Thema

Waldmensch

Mir fiel kein besserer Betreff ein. Es geht um die Schaltung eines Hoflichts mit einem PIRI Bewegungssensor. Folgenden Code habe ich jetzt, der funktioniert auch:

DOIF ([move1_chan_0] eq "on-old-for-timer 60" and [licht_hinterhof:state] eq "off")
(set licht_hinterhof on,
define reset_piri0 at +00:00:10 set move1_chan_0 off,
define reset_hoflicht0 at +00:01:00 set licht_hinterhof off )
DOELSEIF ([move1_chan_0] eq "on-old-for-timer 60" and [licht_hinterhof:state] eq "on")
(delete reset_hoflicht0,
define reset_piri0 at +00:00:10 set move1_chan_0 off,
define reset_hoflicht0 at +00:01:00 set licht_hinterhof off)


Meine Frage ist, ob man das Event licht_hinterhof off->on irgendwie ignorieren kann, da das DOIF dadurch gleich nochmal ausgeführt wird. Momentan läuft es so:


  • PIRI (move1_chan_0) feuert off -> on-old-for-timer 60 und schaltet licht_hinterhof auf on
  • licht_hinterhof feuert off -> on dadurch wird unnötigerweise der DOELSEIF ausgeführt da der PIRI noch nicht auf off gesetzt wurde
  • PIRI (move1_chan_0) feuert nach 10 Sekunden on-old-for-timer 60 -> off -  da keine Bedingungen erfüllt sind werden beide Zweige ignoriert
  • licht_hinterhof feuert nach 60 Sekunden on->off - da keine Bedingungen erfüllt sind werden beide Zweige ignoriert
  • Der PIRI kann all 25 Sekunden neu feuern, was über den DOELSEIF entsprechend abgewickelt wird. Dabei wird die die Ausschaltzeit gelöscht und jeweils neu auf 1 Minute gesetzt

Das Event des Aktors licht_hinterhof wird hier überhaupt nicht benötigt, das lesen des readings würde völlig reichen. Hat jemand eine Idee, wie ich das DOIF überlisten kann? Wenn der Aktor nicht feuern würde, bräuchte ich den state des PIRI nicht bruteforce setzen. (define reset_piri0 at +00:00:10 set move1_chan_0 off). Der PIRI sendet nie ein off sondern immer nur das on-old-for-timer XX

igami

Du kannst ein ? an der richtigen stelle setzten um das Event von move_chan_0 auszuwerten. Des weiteren kannst du statt der at auch das wait attribut von DOIF nutzen.

Grüße
igami
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

Waldmensch

Momentan werden ja, ohne Fragezeichen beide Events ausgewertet move1_chan_0 und licht_hinterhof. Das DOIF wird bei jeder Statusänderung beider Elemente gefeuert. Ich will ja vermeiden, das das event von licht_hinterhof das DOIF überhaupt anstößt, es soll nur der aktuelle Wert des Aktors ausgelesen werden.

Das wait ist mir bekannt, das läßt aber einen DOIF Zweig nur vor Ausführung warten. Ich wüßte nicht, wie mir das in dieser speziellen Aufgabenstellung nützen könnte.

Ellert

Zitat(set licht_hinterhof on,
      define reset_piri0 at +00:00:10 set move1_chan_0 off,
      define reset_hoflicht0 at +00:01:00 set licht_hinterhof off )
kannst Du als
(set licht_hinterhof on) (set move1_chan_0 off) (set licht_hinterhof off)
mit
wait 0,10,50
definieren.
Siehe: http://fhem.de/commandref_DE.html#DOIF_wait ab "Sollen Verzögerungen innerhalb von Befehlsfolgen stattfinden ..."

Waldmensch

Zitat von: Ellert am 22 Februar 2016, 10:25:01
kannst Du als
(set licht_hinterhof on) (set move1_chan_0 off) (set licht_hinterhof off)
mit
wait 0,10,50
definieren.
Siehe: http://fhem.de/commandref_DE.html#DOIF_wait ab "Sollen Verzögerungen innerhalb von Befehlsfolgen stattfinden ..."

Okay, das mit den Teilanweisungen ist mir echt neu. Allerdings lösche und setze ich das Ausschalten im DOELSEIF Zweig, falls der PIRI weiterhin Bewegung meldet. In Deinem Beispie wüßte ich jetzt nicht, wie ich das DOIF quasi abbrechen und neu +60 sekunden setzen kann. Die Methode über die defines funktioniert soweit auch prima (verlängerung der Leuchtdauer bei PIRI Meldung). Das rücksetzen des PIRI könnte ich mir komplett sparen, wenn nicht das DOIF durch das Event vom licht_hinterhof  gefeuert würde sondern das DOIF nur auf das Event vom PIRI hören würde.

Ich weiß nicht wie ich das Problem noch besser beschreiben könnte


Ellert

Mit "do resetwait" könnte das funktionieren.

Waldmensch

Wenn ich die Kommandos in Einzelklammern setze kriege ich Fehler beim Speichern. Habe aber auch nicht die neuesten Updates.

Das resetwait löst aber auch nicht mein eigentliches Problem  :-[

Ellert

Lösungsansatz des eigentlichen Problems, so wie ich es verstanden habe:

(["<PIRI Event alls 25 s bei Bewegung>"])  (set Lampe:FILTER=STATE=off on) (set Lampe off)

do resetwait
wait 0, 60

Funktion: Wenn alle 25 s ein PIRI Event kommt wird beim ersten Event die Lampe eingeschaltet und bei allen nachfolgenden Events der Timer zurückgesetzt. Wenn 60 s lang ein Event ausbleibt, wird die Lampe ausgeschaltet.

Waldmensch

Ich habe deinen Vorschlag leicht abgewandelt und es scheint zu funktionieren. Das Problem ist, das der PIRI halt immer auf auf dem state on-old-for-timer 60 steht, wenn er einmal gesendet hat. FHEM scheint das nochmalige Senden des gleichen Status dann nicht als Event zu werten. Daher geht es ohne das Rücksetzen des PIRI nicht. Auf jeden Fall sieht das schon viel sportlicher aus, als mein erster Ansatz  :D

([move1_chan_0:state] eq "on-old-for-timer 60") (set licht_hinterhof:FILTER=STATE=off on, set move1_chan_0 off) (set licht_hinterhof off)

hier die ganze config
define hinterhoflicht_auto1 DOIF ([move1_chan_0:state] eq "on-old-for-timer 60") (set licht_hinterhof:FILTER=STATE=off on, set move1_chan_0 off) (set licht_hinterhof off)
attr hinterhoflicht_auto1 do resetwait
attr hinterhoflicht_auto1 room Control
attr hinterhoflicht_auto1 wait 0,60

Ellert

Allerdings sollte das DOIF mit do resetwait auch bei einer Erneuerung des Status ansprechen.

Gibt es wirklich regelmäßige Events  "on-old-for-timer 60"?

Waldmensch

Zitat
Gibt es wirklich regelmäßige Events  "on-old-for-timer 60"?

Ja, die kommen alle durch, im Eventlog sieht man sie und im Log des PIRI auch. [move1_chan_0:state] ist doch die richtige Syntax für event?

Ellert

Du kannst "state" weglassen, wenn Du nur den Status abfragen möchtest. [move1_chan_0] reicht, damit fragst Du den Status ab, wenn es ein Geräteevent gibt. Nur das Event fragst Du mit [move1_chan_0:"<Regex für Event>"] , konkret  [move1_chan_0:"on-old-for-timer 60"] ab