Hauptmenü

Zählen von Ereignissen

Begonnen von hackepeter, 21 Januar 2020, 11:52:12

Vorheriges Thema - Nächstes Thema

hackepeter

Hallo,

ich bekomme von meinen Kameras eine Mail wenn eine Bewegung erkannt wird. Postfix führt dann ein Script aus und setzt ein Reading in einem Dummy.
Bei schlechtem Wetter oder Spinnweben vor der Kamera kommt es leider zu vielen Fehlalarmen. Diese würde ich gerne erkennen.

Dazu habe ich folgenden code, den ich irgendwo in den Untiefen des Forums gefunden habe, etwas modifiziert, sodass er bei bei Fehlalarmen eine Pushnachricht senden soll:


{                         
  if ([camAlarm:192.168.178.12] eq "alarm" or [camAlarm:192.168.178.13] eq "alarm" and !get_Exec("counter")) {                                        # wenn Ereignis (hier "camAlarm") eintritt und kein Timer läuft
    $_count=1;                                                                     # setze count-Variable auf 1
    set_Exec("counter",300,'Log (3,"count: $_count action") if ($_count > 5)' FHEMControlPush_Send({'alert' => "Schlechtwetter" }));  # setze Timer auf 5min zum Protokollieren der Anzahl der Ereignisse, wenn sie über 5 ist
  } else {
    $_count++;                                                                     # wenn Timer bereits läuft zähle Ereignis
  }
}


Leider funktioniert das nicht, im Log erscheint folgender Fehler:

2020.01.21 09:01:19 1: PERL WARNING: Bareword found where operator expected at (eval 355308) line 4, near "'Log (3,"count: $hash->{var}{count} action") if ($hash->{var}{count} > 5)' FHEMControlPush_Send"
2020.01.21 09:01:19 3: eval: cam_count: warning in condition c01


amenomade

Syntax:
Zitat von: CommandRefset_Exec(<timerName>, <seconds>, <perlCode>, <parameter>)

timerName => "counter" => OK
seconds => 300 => OK
perlCode => 'Log (3,"count: $_count action") if ($_count > 5)' FHEMControlPush_Send({'alert' => "Schlechtwetter" }) => KO

Was willst Du genau machen?
Log Nachricht wenn count > 5, OK. Aber dann? Mit dem single quote hast Du schon perlCode geschlossen.
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

hackepeter

Vielen Dank für die Antwort!
In anderen DOIFs verwende ich diese Funktion um eine Push Nachricht zu versenden:
([20:00] and [rpi2rel3:state] eq "Offen") ({FHEMControlPush_Send({'alert' => "Garagentor ist noch offen!" })})

Das wollte ich hier nur zum testen nehmen.

Wenn ich es wie folgt ändere:

{                         
  if ([camAlarm:192.168.178.12] eq "alarm" or [camAlarm:192.168.178.13] eq "alarm" and !get_Exec("counter")) {                                        # wenn Ereignis (hier "camAlarm") eintritt und kein Timer läuft
    $_count=1;                                                                     # setze count-Variable auf 1
    set_Exec("counter",300,'Log (3,"count: $_count action") if ($_count > 5) ({FHEMControlPush_Send({'alert' => "Test" })})  # setze Timer auf 5min zum Protokollieren der Anzahl der Ereignisse, wenn sie über 5 ist
  } else {
    $_count++;                                                                     # wenn Timer bereits läuft zähle Ereignis
  }
}


bekomme ich:

   
condition c01: Bad name after alert', line 4.

Damian

Du willst vermutlich deinen Send absetzen, wenn der Counter bei fünf angekommen ist.

Dann eher so:

set_Exec("counter",300,'FHEMControlPush_Send({"alert" => "Test" }) if ($_count > 5)');
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

hackepeter

#4
Zitat von: Damian am 22 Januar 2020, 08:15:52
Du willst vermutlich deinen Send absetzen, wenn der Counter bei fünf angekommen ist.

Dann eher so:

set_Exec("counter",300,'FHEMControlPush_Send({"alert" => "Test" }) if ($_count > 5)');

Richtig. Jetzt kommen auch keine Meldungen mehr wegen falscher Syntax.

Allerdings kommt keine Pushnachricht an, wenn das DOIF mehr als 5x in 300sek. angetriggert wird.
Ein manuelles versenden der Push funktioniert:
{FHEMControlPush_Send({"alert" => "Test" })}

Hier nochmal das gesamte DOIF:
{                         
  if ([camAlarm:192.168.178.12] eq "alarm" or [camAlarm:192.168.178.13] eq "alarm" and !get_Exec("counter")) {
    $_count=1;
    set_Exec("counter",300,'FHEMControlPush_Send({"alert" => "Test" }) if ($_count > 5)');
  } else {
    $_count++;
  }
}

Damian

OK. FHEMControlPush_Send befindet sich wohl im main-package, daher muss man das so angeben, weil im Perl-Modus DOIF im eigenen package gekapselt ist:

set_Exec("counter",300,'::FHEMControlPush_Send({"alert" => "Test" }) if ($_count > 5)');
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

hackepeter

Zitat von: Damian am 22 Januar 2020, 08:15:52
Du willst vermutlich deinen Send absetzen, wenn der Counter bei fünf angekommen ist.

Dann eher so:

set_Exec("counter",300,'FHEMControlPush_Send({"alert" => "Test" }) if ($_count > 5)');

Funktioniert leider auch nicht, Logs gibts auch keine. Liegt es vielleicht am Trigger? Im Device camAlarm wird das Reading 192.168.178.12 für eine Sekunde auf Alarm gesetzt, anschließend wieder auf NoAlarm.

Hier auch mal ein list:

Internals:
   DEF        {                         
  if ([camAlarm:192.168.178.12] eq "alarm" or [camAlarm:192.168.178.13] eq "alarm" and !get_Exec("counter")) {
    $_count=1;
    set_Exec("counter",300,'::FHEMControlPush_Send({"alert" => "Test" }) if ($_count > 5)');
  } else {
    $_count++;
  }
}
   FUUID      5e221f09-f33f-cd6f-5def-5bd4a8c94eb3f5c9
   MODEL      Perl
   NAME       cam_count
   NOTIFYDEV  global,camAlarm
   NR         319
   NTFY_ORDER 50-cam_count
   STATE      ???
   TYPE       DOIF
   VERSION    20929 2020-01-10 09:44:35
   READINGS:
     2020-01-22 08:55:06   Device          camAlarm
     2020-01-22 08:55:06   block_01        executed
     2020-01-22 08:55:06   e_camAlarm_192.168.178.12 NoAlarm
     2020-01-22 08:48:43   mode            enabled
     2020-01-22 08:55:05   timer_counter   22.01.2020 09:00:05
   Regex:
     accu:
     cond:
       camAlarm:
         0:
           192.168.178.12 ^camAlarm$:^192.168.178.12:
           192.168.178.13 ^camAlarm$:^192.168.178.13:
   condition:
     0                                   
  if (::ReadingValDoIf($hash,'camAlarm','192.168.178.12') eq "alarm" or ::ReadingValDoIf($hash,'camAlarm','192.168.178.13') eq "alarm" and !get_Exec("counter")) {
    $hash->{var}{count}=1;
    set_Exec("counter",300,'::FHEMControlPush_Send({"alert" => "Test" }) if ($hash->{var}{count} > 5)');
  } else {
    $hash->{var}{count}++;
  }

   helper:
     DEVFILTER  ^global$|^camAlarm$
     NOTIFYDEV  global|camAlarm
     event      192.168.178.12: NoAlarm
     globalinit 1
     last_timer 0
     sleeptimer -1
     triggerDev camAlarm
     triggerEvents:
       192.168.178.12: NoAlarm
     triggerEventsState:
       192.168.178.12: NoAlarm
   internals:
   perlblock:
     0         
   ptimer:
     counter:
       name       counter
       subname    ::FHEMControlPush_Send({"alert" => "Test" }) if ($hash->{var}{count} > 5)
       time       1579680005.94926
       hash:
   readings:
     all         camAlarm:192.168.178.12 camAlarm:192.168.178.13
   trigger:
   uiState:
   uiTable:
   var:
     count      2
Attributes:
   room       Rules

Damian

Klar, wenn der Zustand sich ändert, dann wird das Modul getriggert - die Bedingung ist nicht mehr wahr, der Counter wird zurückgesetzt.

Du kannst reine Eventtrigger nehmen, allerdings musst du dann definieren, wann der Counter wieder zurück gesetzt werden soll.


["^camAlarm:192.168.178.12: alarm"] or ["^camAlarm:192.168.178.13: alarm"]
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

hackepeter

#8
Zitat von: Damian am 22 Januar 2020, 09:13:13
Du kannst reine Eventtrigger nehmen, allerdings musst du dann definieren, wann der Counter wieder zurück gesetzt werden soll.

Das ist eine Herausforderung für mich.  Am Ende soll einfach bei mehr als 5 Triggern in 300 Sekunden z.B. ein reading im Dummy gesetzt werden (zum Testen stattdessen die Push Nachricht). Den wollte ich dann z.B. bei nächsten Sonnenaufgang (dafür habe ich ein Device) zurücksetzen.

Verstehe ich es richtig, dass in diesem Fall die Lösung wäre, den Timer bei Sonnenaufgang zurückzusetzen, quasi so?:


{                         
  if (["^camAlarm:192.168.178.12: alarm"] or ["^camAlarm:192.168.178.13: alarm"] and !get_Exec("counter")) {
    $_count=1;
    Log 1, $_count;
    set_Exec("counter",300,'{fhem "setreading test state on"}) if ($_count > 5)');
  } else {
    Log 2, $_count;
    $_count++;
    my $InfrarotState = ReadingsVal("camgarage2_status","infraLedState","9");
    if (Value($InfrarotState) eq "1")  {del_Exec("counter");}
  }
}


Der Einfachheit halber bin ich von der Push Message nun auf einen Dummy gewechselt.
Leider wird der nicht auf "on" geschaltet, obwohl das reading infraLedState vom Device camgarage2_status auf 1 steht.

kroman

Es gibt Probleme in der condition. Das Leerzeichen vor dem reading Wert ist nicht gut.
Weiters fehlen Klammern ohne die nur Kamera2 hochzählt.
Bei set_Exec hat der fhem Aufruf nicht gepasst.
Probier mal so:


{                         
  if ((["^camAlarm:192.168.178.12:alarm"] or ["^camAlarm:192.168.178.13:alarm"]) and !get_Exec("counter")) {
    $_count=1;
    Log 1, $_count;
    set_Exec("counter",300,'fhem("setreading test state on")) if ($_count > 5)');
  } else {
    Log 2, $_count;
    $_count++;
    my $InfrarotState = ReadingsVal("camgarage2_status","infraLedState","9");
    if (Value($InfrarotState) eq "1")  {del_Exec("counter");}
  }
}

Damian

Du brauchst noch einen Trigger für deinen Sonnenaufgang:

{                         
  if ((["^camAlarm:192.168.178.12:alarm"] or ["^camAlarm:192.168.178.13:alarm"]) and !get_Exec("counter")) {
    $_count=1;
    Log 1, $_count;
    set_Exec("counter",300,'fhem("setreading test state on")) if ($_count > 5)');
  } else {
    Log 2, $_count;
    $_count++;
  }
}
{ if ([camgarage2_status:infraLedState,9] == 1) {$_count=0}}


Als nächstes stellt sich die Frage, ob man am Tage überhaupt zählen will und ob die Meldung nachts wiederholt kommen soll.

Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

hackepeter

Irgendwie reagiert jetzt die Condition überhaupt nicht mehr :( Mit den Leerzeichen hatte es noch funktioniert.

Damian

Zitat von: hackepeter am 23 Januar 2020, 14:53:48
Irgendwie reagiert jetzt die Condition überhaupt nicht mehr :( Mit den Leerzeichen hatte es noch funktioniert.

ja, da gehört wohl auch ein Leerzeichen hin, wie im ersten Vorschlag von mir.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

hackepeter

Mit Leerzeichen funktioniert die Condition wieder. Jetzt zählt er auch $_count hochgezählt, allerdings setzt er den testdummy nicht auf on, sollte er aber, wenn das Reading innerhalb der 300Sekunden öfter als 5 mal kommt, oder?

{ if ([camgarage2_status:infraLedState] == 1) {$_count=0}} Müsste stattdessen nicht der Counter ala {del_Exec("counter");} zurück gesetzt werden?

Damian

Zitat von: hackepeter am 23 Januar 2020, 15:56:48
Mit Leerzeichen funktioniert die Condition wieder. Jetzt zählt er auch $_count hochgezählt, allerdings setzt er den testdummy nicht auf on, sollte er aber, wenn das Reading innerhalb der 300Sekunden öfter als 5 mal kommt, oder?

{ if ([camgarage2_status:infraLedState] == 1) {$_count=0}} Müsste stattdessen nicht der Counter ala {del_Exec("counter");} zurück gesetzt werden?

kannst du noch dran setzen, falls gerade einer in den letzten fünf Minuten vor Sonnenaufgang angelaufen ist:

{ if ([camgarage2_status:infraLedState] == 1) {$_count=0;del_Exec("counter")}}


und hier ist noch eine Klammer zu viel:

    set_Exec("counter",300,'fhem("setreading test state on")) if ($_count > 5)');
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF