[Gelöst] DOIF mit cmdpause funktioniert nur im 2. Anlauf: Lösung mit repeatsame

Begonnen von Gisbert, 12 Februar 2020, 09:07:27

Vorheriges Thema - Nächstes Thema

Gisbert

Hallo,

ich habe eine Kamera, die beim Erkennen einer Bewegung Bilder in einen Ordner auf meinem Server speichert. Das funktioniert mit dem Modul inotify perfekt:
defmod CamWatch inotify /media/USBBackup/Kamera/FI9805W_00626E5818B7/snap MDAlarm_.*.jpg
attr CamWatch group IPCAM
attr CamWatch icon it_camera
attr CamWatch mask IN_CLOSE_WRITE


Jedesmal wenn eine neue Datei gespeichert wird, bekommt das Reading <lastEventMask> einen neuen Zeitstempel, der Inhalt des Readings ist immer derselbe: <IN_CLOSE_WRITE>.

Auf dieses Reading als triggerendes Ereignis habe ich ein DOIF aufgesetzt, welches folgende Zweige hat:

  • triggerendes Reading lastEventMask, Zeitbereich von Sonnenuntergang bis Sonnenaufgang; Einschalten von Licht für knapp 5 Minuten, falls es aus ist
  • triggerendes Reading lastEventMask, Zeitbereich von Sonnenaufgang bis Sonnenuntergang; kein Ausführungsteil
  • Um ein Diagramm ohne Plotabriss zu erzeugen, gibt es einen dritten Zweig, der alle 5 Minuten auf den Timestamp des Readings lastEventMask triggert, auch hier kein Ausführungsteil

Um zu verhindern, dass der 1. und 2. Zweig bei jedem gespeicherten Bild neu triggert, habe ich das Attribut cmdpause mit 295:295:0 definiert.

defmod CamWatchAlarm DOIF ([CamWatch:lastEventMask] eq "IN_CLOSE_WRITE" and [{sunset_abs(-330)} - {sunrise(860)}]) \
(IF ([Haustuer.Licht:state] eq "off") (set Haustuer.Licht on-for-timer 290)) \
(IF ([Terrasse.Licht:state] eq "off") (set Terrasse.Licht on-for-timer 285)) \
DOELSEIF ([CamWatch:lastEventMask] eq "IN_CLOSE_WRITE" and [{sunrise(860)} - {sunset_abs(-330)}]) \
DOELSEIF ([+:05] and [CamWatch:lastEventMask:sec] > 300)
attr CamWatchAlarm cmdpause 295:295:0
attr CamWatchAlarm do always


Um einen Plot zu erzeugen, logge ich das Reading cmd_nr:
defmod FileLog_Kamera FileLog ./log/Kamera-%Y-%m.log CamWatchAlarm:cmd_nr:.*

Nun zu meinem Problem:
Wenn ich einmal kurz vor der Kamera mit der Hand wedele, wird die Bewegungserkennung aktiv und schreibt Files auf meinem Server; das DOIF bleibt aber auf cmd 3 stehen.
Wiederhole ich das ganze, springt das DOIF auf cmd 1 oder 2 (je nach Uhrzeit).

Wie kann ich erreichen, dass das DOIF bei der 1. Bewegungserkennung auf den gewünschten Zweig springt?

Noch ein list des DOIFs nach der 1. Bewegungserkennung:
Internals:
   CFGFN      ./FHEM/WLAN-Kamera.cfg
   DEF        ([CamWatch:lastEventMask] eq "IN_CLOSE_WRITE" and [{sunset_abs(-330)} - {sunrise(860)}])
(IF ([Haustuer.Licht:state] eq "off") (set Haustuer.Licht on-for-timer 290))
(IF ([Terrasse.Licht:state] eq "off") (set Terrasse.Licht on-for-timer 285))
DOELSEIF ([CamWatch:lastEventMask] eq "IN_CLOSE_WRITE" and [{sunrise(860)} - {sunset_abs(-330)}])
DOELSEIF ([+:05] and [CamWatch:lastEventMask:sec] > 300)
   FUUID      5c912dad-f33f-e986-ec50-4e46b05c4db6606b
   MODEL      FHEM
   NAME       CamWatchAlarm
   NOTIFYDEV  CamWatch,global
   NR         54
   NTFY_ORDER 50-CamWatchAlarm
   STATE      cmd_3
   TYPE       DOIF
   VERSION    20929 2020-01-10 09:44:35
   READINGS:
     2020-02-12 08:56:04   Device          CamWatch
     2020-02-12 08:55:00   cmd             3
     2020-02-12 08:55:00   cmd_event       timer_5
     2020-02-12 08:55:00   cmd_nr          3
     2020-02-12 08:56:04   e_CamWatch_lastEventMask IN_CLOSE_WRITE
     2020-02-10 19:10:07   mode            enabled
     2020-02-12 08:55:00   state           cmd_3
     2020-02-12 07:30:15   timer_01_c01    12.02.2020 18:11:23
     2020-02-12 07:30:15   timer_02_c01    13.02.2020 07:28:31
     2020-02-11 18:08:00   timer_03_c02    12.02.2020 07:30:15
     2020-02-11 18:08:00   timer_04_c02    12.02.2020 18:09:41
     2020-02-12 08:55:00   timer_05_c03    12.02.2020 09:00:00
   Regex:
     accu:
     cond:
       CamWatch:
         0:
           lastEventMask ^CamWatch$:^lastEventMask:
         1:
           lastEventMask ^CamWatch$:^lastEventMask:
         2:
           lastEventMask ^CamWatch$:^lastEventMask:
   attr:
     cmdState:
     cmdpause:
       295
       295
       0
     wait:
     waitdel:
   condition:
     0          ::ReadingValDoIf($hash,'CamWatch','lastEventMask') eq "IN_CLOSE_WRITE" and ::DOIF_time($hash,0,1,$wday,$hms)
     1          ::ReadingValDoIf($hash,'CamWatch','lastEventMask') eq "IN_CLOSE_WRITE" and ::DOIF_time($hash,2,3,$wday,$hms)
     2          ::DOIF_time_once($hash,4,$wday) and ::ReadingSecDoIf('CamWatch','lastEventMask') > 300
   days:
   do:
     0:
       0          IF ([Haustuer.Licht:state] eq "off") (set Haustuer.Licht on-for-timer 290)
       1          IF ([Terrasse.Licht:state] eq "off") (set Terrasse.Licht on-for-timer 285)
     1:
       0         
     2:
       0         
     3:
   helper:
     DEVFILTER  ^global$|^CamWatch$
     NOTIFYDEV  global|CamWatch
     event      lastEventFile: /media/USBBackup/Kamera/FI9805W_00626E5818B7/snap/MDAlarm_20200212-085600.jpg,lastEventMask: IN_CLOSE_WRITE,activity: 2020-02-12 08:56
     globalinit 1
     last_timer 5
     sleeptimer -1
     timerdev   CamWatch
     timerevent lastEventFile: /media/USBBackup/Kamera/FI9805W_00626E5818B7/snap/MDAlarm_20200212-085600.jpg,lastEventMask: IN_CLOSE_WRITE,activity: 2020-02-12 08:56
     triggerDev CamWatch
     bm:
       DOIF_Get:
         cnt        15
         dmx        -1000
         dtot       0
         dtotcnt    0
         mTS        11.02. 20:54:38
         max        4.91142272949219e-05
         tot        0.000336885452270508
         mAr:
           HASH(0x558469dde478)
           CamWatchAlarm
           ?
       DOIF_Notify:
         cnt        51
         dmx        -1000
         dtot       0
         dtotcnt    0
         mTS        11.02. 07:42:31
         max        0.0100409984588623
         tot        0.162260055541992
         mAr:
           HASH(0x558469dde478)
           HASH(0x558469d8b670)
       DOIF_Set:
         cnt        71
         dmx        -1000
         dtot       0
         dtotcnt    0
         mTS        12.02. 08:48:32
         max        0.000309944152832031
         tot        0.00615835189819336
         mAr:
           HASH(0x558469dde478)
           CamWatchAlarm
           ?
     timerevents:
       lastEventFile: /media/USBBackup/Kamera/FI9805W_00626E5818B7/snap/MDAlarm_20200212-085600.jpg
       lastEventMask: IN_CLOSE_WRITE
       activity: 2020-02-12 08:56
     timereventsState:
       lastEventFile: /media/USBBackup/Kamera/FI9805W_00626E5818B7/snap/MDAlarm_20200212-085600.jpg
       lastEventMask: IN_CLOSE_WRITE
       activity: 2020-02-12 08:56
     triggerEvents:
       lastEventFile: /media/USBBackup/Kamera/FI9805W_00626E5818B7/snap/MDAlarm_20200212-085600.jpg
       lastEventMask: IN_CLOSE_WRITE
       activity: 2020-02-12 08:56
     triggerEventsState:
       lastEventFile: /media/USBBackup/Kamera/FI9805W_00626E5818B7/snap/MDAlarm_20200212-085600.jpg
       lastEventMask: IN_CLOSE_WRITE
       activity: 2020-02-12 08:56
   internals:
   interval:
     0          -1
     1          0
     2          -1
     3          2
   intervalfunc:
   intervaltimer:
   localtime:
     0          1581527483
     1          1581575311
     2          1581489015
     3          1581527381
     4          1581494400
   perlblock:
   readings:
     all         CamWatch:lastEventMask
   realtime:
     0          18:11:23
     1          07:28:31
     2          07:30:15
     3          18:09:41
     4          09:00:00
   time:
     0          {sunset_abs(-330)}
     1          {sunrise(860)}
     2          {sunrise(860)}
     3          {sunset_abs(-330)}
     4          +:05
   timeCond:
     0          0
     1          0
     2          1
     3          1
     4          2
   timer:
     0          0
     1          0
     2          0
     3          0
     4          0
   timers:
     0           0  1
     1           2  3
     2           4
   trigger:
   triggertime:
     1581494400:
       localtime  1581494400
       hash:
     1581527381:
       localtime  1581527381
       hash:
     1581527483:
       localtime  1581527483
       hash:
     1581575311:
       localtime  1581575311
       hash:
   uiState:
   uiTable:
Attributes:
   cmdpause   295:295:0
   devStateIcon (cmd_1|cmd_2):it_camera@red (cmd_3):it_camera@gray
   do         always
   icon       it_camera
   room       Network


Viele​ Grüße Gisbert​
Aktuelles FHEM | PROXMOX | Fujitsu Futro S740 | Debian 12 | UniFi | Homematic, VCCU, HMUART | ESP8266 | ATtiny85 | Wasser-, Stromzähler | Wlan-Kamera | SIGNALduino, Flamingo Rauchmelder FA21/22RF | RHASSPY

amenomade

Verscuh mal mit [?CamWatch:lastEventMask:sec] > 300 damit CamWatch nicht mehr zu den Triggern von cmd3 gehört
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

Gisbert

Zitat von: amenomade am 12 Februar 2020, 14:51:44
Verscuh mal mit [?CamWatch:lastEventMask:sec] > 300 damit CamWatch nicht mehr zu den Triggern von cmd3 gehört
Das war's noch nicht.

Es gibt eine Datei namens MDAlarm_20200212-185943.jpg (insgesamt 10 Dateien im Sekundentakt, diese ist die letzte) im entsprechenden Ordner, die durch das Modul inotify registriert wird.
In dem DOIF taucht das folgende Readings auf, man beachte die Zeitgleichheit:
Zitate_CamWatch_lastEventMask IN_CLOSE_WRITE 2020-02-12 18:59:43
Das DOIF bleibt aber trotzdem bei cmd_3 stehen - ich verstehe es nicht !!

Wenn ich für Testzwecke cmdpause auf 5:5:0 setze, dann triggert das DOIF auf cmd_1 (falls 5 Sekunden seit dem letzten Event vorbei sind).
Eigentlich müsste der 1. Zweig bei cmdpause 295:295:0 auch triggern, sofern mehr als 295 Sekunden vergangen sind seit dem letzten Event - was es aber nicht tut.

Mit dieser Konstruktion will ich ja zweierlei:

  • cmd_nr loggen, um anhand einer Grafik zu sehen, wann es Bewegungsalarm gab
  • Verhindern, dass im Sekundentakt getriggert wird (es werden 10 Bilder pro Bewegungserkennung gespeichert), sowie verhindern, dass innerhalb der Zeit, in der die Außenbeleuchtung an ist, bei erneuter Bewegung die Lampen wieder ein Anschaltbefehl bekommen

Ich habe es jetzt mal folgender Konstruktion versucht:
attr CamWatchAlarm do always
attr CamWatchAlarm repeatsame 1:1:0

Damit habe ich schon mein erstes und zweites Ziel erreicht, dass nicht endlos neu getriggert wird, sondern nur einmal, und dann erst wieder, wenn zwischendurch ein anderer Zweig dran war.
Und anscheinend reagiert jetzt das DOIF sofort auf ein neues Event zum 1. Zweig.

So richtig verstehen tue ich es nicht, warum es mit cmdpause reproduzierbar nicht wie gewünscht geht.
Mit cmdpause scheine ich wohl auf Kriegsfuß zu stehen; wir werden keine Freunde mehr >:(

Viele Grüße Gisbert
Aktuelles FHEM | PROXMOX | Fujitsu Futro S740 | Debian 12 | UniFi | Homematic, VCCU, HMUART | ESP8266 | ATtiny85 | Wasser-, Stromzähler | Wlan-Kamera | SIGNALduino, Flamingo Rauchmelder FA21/22RF | RHASSPY

Gisbert

Hallo zusammen,

noch ein kleines Update für diejenigen, die mir evtl. helfen können.
Mit repeatsame 1:1:0 wird der 1. Zweig anscheinend nicht einmal durchgeführt, sondern einmal wiederholt, d.h. also insgesamt zweimal. Ich finde es natürlich in der log-Datei, aber auch um ganz sicher zu gehen, habe ich mir das auch im Eventmonitor angeschaut:
2020-02-12 20:12:00 DOIF CamWatchAlarm cmd_nr: 3
2020-02-12 20:12:12 DOIF CamWatchAlarm cmd_nr: 1
2020-02-12 20:12:12 DOIF CamWatchAlarm cmd_nr: 1

Kann man diese doppelte Ausführung verhindern?
Ist repeatsame das richtige Attribut für mein Vorhaben?

Viele Grüße Gisbert
Aktuelles FHEM | PROXMOX | Fujitsu Futro S740 | Debian 12 | UniFi | Homematic, VCCU, HMUART | ESP8266 | ATtiny85 | Wasser-, Stromzähler | Wlan-Kamera | SIGNALduino, Flamingo Rauchmelder FA21/22RF | RHASSPY

amenomade

#4
Zur 1. Version deines DOIFs:

Ich glaube, das hängt an cmdpause. Laut CommandRef:
ZitatMit dem Attribut cmdpause <Sekunden für cmd_1>:<Sekunden für cmd_2>:... wird die Zeitspanne in Sekunden angegeben für eine Zwangspause seit der letzten Zustandsänderung. In der angegebenen Zeitspanne wird ein Kommando nicht ausgeführt, auch wenn die dazugehörige Bedingung wahr wird.
Der Wechsel von cmd1 auf cmd2 beim Zeittrigger ist eine Zustandsänderung. Das heisst, innerhalb 295 Sekunden nach diesem Wechsel wird das Kommando 1 nicht ausgeführt, auch wenn die Bedingung 1 wahr wird.

Zur 2. Version:
Was sind jetzt alle Attribute, die Du nutzt? Ist cmdpause noch da oder nicht mehr? Ich vermute nicht mehr.
Lieber ein "list" vom DOIF, so hat man alles.

Ich würde einfach alle attr weg nehmen, inkl do always und nur repeatcmd 0:300 setzen.
Somit wird bei erneutem IN_CLOSE_WRITE nicht wieder geschaltet (und cmd_nr auch nicht wieder geloggt), so lange er nicht inzwischen auf cmd2 gewechselt hat. Und cmd2 wird beliebig jede 5. Minute wiederholt, solange er nicht wieder auf cmd1 geht. Schlimmsten Fall, wenn IN_CLOSE_WRITE kurz vor :05 kommt, wird es einmal vor :05 und einmal nach :05 wiederholt.

Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

Gisbert

Hallo amenomade,

karnevalsbedingt muss ich heute einen Ausfall vermelden ;)
Deshalb nur kurz:
der 1. Zweig hat 2 Anweisungen bei Bewegungserkennung
der 2. Zweig hat keine Anweisung bei Bewegungserkennung
der 3. Zweig dient dem Loggen: keine Bewegung

Kann es sein, dass beim 1. Zweig cmd_nr 2mal geloggt wird wegen den 2 Anweisungen?
Bei dem 2. und 3. Zweig wird cmd_nr nur 1mal geloggt.

Viele​  Grüße​ Gisbert​
Aktuelles FHEM | PROXMOX | Fujitsu Futro S740 | Debian 12 | UniFi | Homematic, VCCU, HMUART | ESP8266 | ATtiny85 | Wasser-, Stromzähler | Wlan-Kamera | SIGNALduino, Flamingo Rauchmelder FA21/22RF | RHASSPY

amenomade

Zitat von: Gisbert am 13 Februar 2020, 18:35:08
Hallo amenomade,

karnevalsbedingt muss ich heute einen Ausfall vermelden ;)
Deshalb nur kurz:
der 1. Zweig hat 2 Anweisungen bei Bewegungserkennung
der 2. Zweig hat keine Anweisung bei Bewegungserkennung
der 3. Zweig dient dem Loggen: keine Bewegung

Kann es sein, dass beim 1. Zweig cmd_nr 2mal geloggt wird wegen den 2 Anweisungen?
Bei dem 2. und 3. Zweig wird cmd_nr nur 1mal geloggt.

Viele​  Grüße​ Gisbert​
Ja, das kann sein, und das hatte ich überlesen. Ich habe nur die Bedingungen geguckt, die Befehle waren mir egal.
Grunsätzlich solltest Du es bei cmdpause 295,0:295:0 schreiben. Bei repeatcmd weiss ich nicht
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

Gisbert

Hallo amenomade,

ich glaube, dass ich jetzt eine funktionierende Lösung gefunden habe, die zuverlässig die Bewegungserkennung einmalig registriert und das mehrfache Loggen verhindert.
defmod CamWatchAlarm DOIF ([CamWatch:lastEventMask] eq "IN_CLOSE_WRITE" and [{sunset_abs(-330)} - {sunrise(860)}]) \
(IF ([Haustuer.Licht:state] eq "off") (set Haustuer.Licht on-for-timer 290)) \
(IF ([Terrasse.Licht:state] eq "off") (set Terrasse.Licht on-for-timer 285)) \
DOELSEIF ([CamWatch:lastEventMask] eq "IN_CLOSE_WRITE" and [{sunrise(860)} - {sunset_abs(-330)}]) \
DOELSEIF ([+:01] and [?CamWatch:lastEventMask:sec] > 300)
attr CamWatchAlarm do always
attr CamWatchAlarm event-min-interval cmd_nr:15
attr CamWatchAlarm event-on-update-reading cmd_nr
attr CamWatchAlarm repeatsame 1:1:0


Das Attribut repeatsame (Werte 1:1:0) arbeitet so, dass der Zweig insgesamt nur einmal ausgeführt wird. Damit ist die Bedingung, dass bei Bewegungserkennung dieser Zweig nur einmal ausgeführt wird erfüllt. Die Kamera nimmt ja noch laufend weiter Bilder in den nächsten Sekunden nach der 1. Bewegunsgerkennung auf.

Im 1. Zweig wurde cmd_nr zweimal geloggt, was an den beiden Ausführungsbefehlen liegt. Hier hilft die Kombination aus event-min-interval und event-on-update-reading auf das Reading cmd_nr; damit wird bei dem 1. Zweig nur ein Logeintrag erzeugt.

Der letzte / 3. Zweig dient nur dazu einen Plot ohne Abriss zu erzeugen. Leider muss man ein triggerendes Element haben, was aber [CamWatch:lastEventMask:sec] nicht ist. Dieser Zweig setzt voraus, dass mindestens 5 Minuten keine Bewegung erfolgt ist, triggert aber auf die Zeit [+:01].

Die Konstruktion mit cmdpause 295,0:295:0 schaue ich mir auch nochmal an, ob die ggf. Vorteile gegenüber repeatsame 1:1:0 hat.

Viele Grüße Gisbert
Aktuelles FHEM | PROXMOX | Fujitsu Futro S740 | Debian 12 | UniFi | Homematic, VCCU, HMUART | ESP8266 | ATtiny85 | Wasser-, Stromzähler | Wlan-Kamera | SIGNALduino, Flamingo Rauchmelder FA21/22RF | RHASSPY

Gisbert

Hallo amenomade,

ich habe jetzt die Konstruktion mit cmdpause getestet, stelle aber fest, dass sie nicht das macht, was ich möchte, nämlich nur einmal bei Bewegungserkennung triggern, sondern mehrfach im definierten Zeitraum. Mit cmdpause gebe ich jetzt mein Vorhaben auf. Ich ändere den Titel des Threads im 1. Beitrag.

Viele Grüße Gisbert
Aktuelles FHEM | PROXMOX | Fujitsu Futro S740 | Debian 12 | UniFi | Homematic, VCCU, HMUART | ESP8266 | ATtiny85 | Wasser-, Stromzähler | Wlan-Kamera | SIGNALduino, Flamingo Rauchmelder FA21/22RF | RHASSPY

Gisbert

Hallo,

es ist noch eine leichte Modifizierung notwendig, damit bei erneuter Bewegungsmeldung das Licht wieder eingeschaltet werden kann. In der im vorigen Beitrag geposteten Definition ist es möglich, dass der 3. Zweig gar nicht zum Zuge kommt, wenn immer wieder innerhalb von 5 Minuten eine Bewegungserkennung registriert wird. Dann würde nur einmal die Lichter angehen, aber wegen on-for-timer nach knapp 5 Minuten ausgehen. Bei wiederholter Bewegungserkennung wird der 3. Zweig nicht ausgeführt, und der 1. Zweig nicht, weil dieser nur ausgeführt wird, wenn zuvor der 3. Zweig dran war.
Mit anderern Worten, wenn sich ein Dieb nicht durch Licht abschrecken lässt, dann wird er nur einmal durch Licht gestört, anschließend kann er im Dunkeln weiter sein böses Werk verrichten.

Ich habe deshalb im 3. Zweig die Abfrage zur Bewegunsgerkennung rausgenommen, und es wird jetzt auf nur auf eine feste Zeit [+:05] getriggert. Damit ist sichergestellt, dass nach 5 Minuten und bei erneuter Bewegunsgerkennung der 1. Zweig wieder erfüllt ist und die Lichter angehen, bzw. anbleiben.

defmod CamWatchAlarm DOIF ([CamWatch:lastEventMask] eq "IN_CLOSE_WRITE" and [{sunset_abs(-330)} - {sunrise(860)}]) \
(IF ([Haustuer.Licht:state] eq "off") (set Haustuer.Licht on-for-timer 290)) \
(IF ([Terrasse.Licht:state] eq "off") (set Terrasse.Licht on-for-timer 285)) \
DOELSEIF ([CamWatch:lastEventMask] eq "IN_CLOSE_WRITE" and [{sunrise(860)} - {sunset_abs(-330)}]) \
DOELSEIF ([+:05])
attr CamWatchAlarm do always
attr CamWatchAlarm event-min-interval cmd_nr:15
attr CamWatchAlarm event-on-update-reading cmd_nr
attr CamWatchAlarm repeatsame 1:1:0


Viele Grüße Gisbert
Aktuelles FHEM | PROXMOX | Fujitsu Futro S740 | Debian 12 | UniFi | Homematic, VCCU, HMUART | ESP8266 | ATtiny85 | Wasser-, Stromzähler | Wlan-Kamera | SIGNALduino, Flamingo Rauchmelder FA21/22RF | RHASSPY