notify mit NOTIFYDEV

Begonnen von igami, 07 Februar 2018, 22:28:31

Vorheriges Thema - Nächstes Thema

igami

Manchmal wünsche ich mir einem notify auch eine NOTIFYDEV mitgeben zu können.
Ein patch dafür könnte folgendermaßen aussehen:

Index: FHEM/91_notify.pm
===================================================================
--- FHEM/91_notify.pm (Revision 16108)
+++ FHEM/91_notify.pm (Arbeitskopie)
@@ -16,7 +16,8 @@
   $hash->{NotifyFn} = "notify_Exec";
   $hash->{AttrFn}   = "notify_Attr";
   $hash->{AttrList} ="disable:1,0 disabledForIntervals forwardReturnValue:1,0 ".
-                     "readLog:1,0 showtime:1,0 addStateEvent:1,0 ignoreRegexp";
+                     "notifydef readLog:1,0 showtime:1,0 addStateEvent:1,0 ".
+                     "ignoreRegexp";
   $hash->{SetFn}    = "notify_Set";
   $hash->{StateFn}  = "notify_State";
   $hash->{FW_detailFn} = "notify_fhemwebFn";
@@ -108,7 +109,7 @@
         AttrVal($ln,'showtime',1) ? $dev->{NTFY_TRIGGERTIME} : 'active';
     }
   }

+
   return $ret if(AttrVal($ln, "forwardReturnValue", 0));
   return undef;
}
@@ -141,6 +142,17 @@
     return $@;
   }

+  if($a[0] eq "set" && $a[2] eq "notifydef") {
+    return "Missing argument for $a[2]" if(!defined($a[3]));
+    eval { "HALLO" =~ m/$a[3]/ };
+    notifyRegexpChanged($hash, $a[3]);
+    return $@;
+  }
+  if($a[0] eq "del" && $a[2] eq "notifydef") {
+    delete($hash->{NOTIFYDEV});
+    return $@;
+  }
+
   if($a[0] eq "set" && $a[2] eq "disable") {
     $do = (!defined($a[3]) || $a[3]) ? 1 : 2;
   }
@@ -161,7 +173,7 @@

   return "no set argument specified" if(int(@a) < 2);
   my %sets = (addRegexpPart=>2, removeRegexpPart=>1, inactive=>0, active=>0);

+
   my $cmd = $a[1];
   if(!defined($sets{$cmd})) {
     my $ret ="Unknown argument $cmd, choose one of ".join(" ", sort keys %sets);
@@ -182,7 +194,7 @@
     $hash->{REGEXP} = $re;
     $hash->{DEF} = "$re ".$hash->{".COMMAND"};
     notifyRegexpChanged($hash, $re);
-   
+
   } elsif($cmd eq "removeRegexpPart") {
     my %h;
     map { $h{$_} = 1 } split(/\|/, $hash->{REGEXP});
@@ -205,7 +217,7 @@
     readingsSingleUpdate($hash, "state", "active", 1)
         if(!AttrVal($me, "disable", undef));
   }

+
   return undef;
}

@@ -290,7 +302,7 @@
                 "Change the executed command:</td></tr>";
   $ret .= "<tr class='".(($row++&1)?"odd":"even")."'><td colspan='2'>";

-  my @list = grep { !$defs{$_}{TEMPORARY} && $_ ne $d &&
+  my @list = grep { !$defs{$_}{TEMPORARY} && $_ ne $d &&
                     $modules{$defs{$_}{TYPE}}{SetFn} } sort keys %defs;
   $ret .= "<input class='set' id='modCmd' type='submit' value='modify' ".
              "data-d='$d' data-p='$param'>";
@@ -344,7 +356,7 @@
               $("#modArg :selected").text()+" "+$("[name=modVal]").val();
     location=FW_root+"?cmd="+addcsrf(encodeURIComponent(cmd))+"&detail="+d;
   }

+
   $(document).ready(function(){
     $("#modDev").change(ntfyCmd);
     $("#modArg").change(ntfyArg);
@@ -534,6 +546,12 @@
         argument. The syntax is the same as for the original regexp.
         </li>

+    <a name="notifydef"></a>
+    <li>notifydef <br>
+        If you wish to execute the notify only for specific devices, you could
+        use a devspec. For example all lights: "genericDeviceType=light".
+        </li>
+
     <a name="readLog"></a>
     <li>readLog<br>
         Execute the notify for messages appearing in the FHEM Log. The device
@@ -759,6 +777,13 @@
         Definition.
         </li>

+    <a name="notifydef"></a>
+    <li>notifydef <br>
+        Sollen nur Events von einer bestimmten Definition ausgewertet werden,
+        so kann man diese in Form einer devspec angeben. Ein Beispiel wäre alle
+        Lampen: "genericDeviceType=light".
+        </li>
+
     <a name="readLog"></a>
     <li>readLog<br>
         Das notify wird f&uuml;r Meldungen, die im FHEM-Log erscheinen,
@@ -773,7 +798,7 @@

     <a name="perlSyntaxCheck"></a>
     <li>perlSyntaxCheck<br>
-        nach setzen des <b>global</b> Attributes perlSyntaxCheck wird eine
+        nach setzen des <b>global</b> Attributes perlSyntaxCheck wird eine
         Syntax-Pr&uuml;fung der Anweisung durchgef&uuml;hrt bei jeder
         &Auml;nderung (define oder modify), falls die Anweisung Perl ist, und
         FHEM bereits gestartet ist.  </li>


Edit: mit commandref
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

rudolfkoenig

ZitatManchmal wünsche ich mir einem notify auch eine NOTIFYDEV mitgeben zu können.
NOTIFYDEV entscheidet darueber, ob und wann eine FHEM-Geraete-Instanz benachrichtigt wird. Durch deinen Patch wird ermoeglicht, dass trotz anderslautender Definition eine Notify-Instanz nicht, oder fuer eine ganz andere Sache benachrichtigt wird, und erschwert dadurch das debugging.

Kannst du mir erklaeren, warum du meinst, das wuenschen zu muessen?

betateilchen

und der Attributname notifydef ist supergut dazu geeignet, totale Verwirrung zu stiften.

Und da Attribute ja dem Benutzer gehören (sollen) und nicht dem Entwickler, muss man sich als Entwickler sowas auch überhaupt nicht wünschen.

*dagegen*
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

igami

Zitat von: rudolfkoenig am 08 Februar 2018, 10:13:02
Kannst du mir erklaeren, warum du meinst, das wuenschen zu muessen?
Letztens hatte ich noch ein notify um readings für HUE LightGroups zu erstellen. Das hat erstmal auf alles was pct sendet reagiert.

defmod HUE_LightGroup_Status notify .+:(pct:..+|state:.unreachable) {\
  my $ID = InternalVal($NAME, "ID", "");;\
  \
  return unless($TYPE eq "HUEDevice" && looks_like_number($ID));;\
  \
  foreach my $group (\
    devspec2array(\
      "TYPE=HUEDevice".\
      ":FILTER=type=(LightGroup|Room)".\
      ":FILTER=lights=(^|.+\\D)$ID(\\D.+|\$)"\
    )\
  ){\
    next unless($group);;\
  \
    my $hash = $defs{$group};;\
    my $lights = InternalVal($group, "lights", "");;\
    my $count = int(split(",", $lights));;\
    $lights =~ s/,/|/g;;\
    my $pct = 0;;\
    my $state = "unreachable";;\
    my $onoff = 0;;\
    my %dim_values = (\
      0 => "dim06%",\
      1 => "dim12%",\
      2 => "dim18%",\
      3 => "dim25%",\
      4 => "dim31%",\
      5 => "dim37%",\
      6 => "dim43%",\
      7 => "dim50%",\
      8 => "dim56%",\
      9 => "dim62%",\
      10 => "dim68%",\
      11 => "dim75%",\
      12 => "dim81%",\
      13 => "dim87%",\
      14 => "dim93%",\
    );;\
\
    if(devspec2array("TYPE=HUEDevice:FILTER=ID=$lights:FILTER=state!=unreachable")){\
      $pct += (split(/[\s]+/, $_))[3]\
        foreach (split("\n", fhem("list TYPE=HUEDevice:FILTER=ID=$lights pct", 1)));;\
      $pct /= $count;;\
      $state = ($pct == 0 ? "off" : $pct == 100 ? "on" : $dim_values{int($pct/7)});;\
      $onoff = 1 if($state ne "off");;\
    }\
\
    readingsBeginUpdate($hash);;\
    readingsBulkUpdate($hash, "onoff", $onoff);;\
    readingsBulkUpdate($hash, "pct", $pct);;\
    readingsBulkUpdate($hash, "state", $state);;\
    readingsEndUpdate($hash, 1);;\
  }\
  \
  return;;\
}
attr HUE_LightGroup_Status addStateEvent 1


Momentan arbeite ich an einem notify für das Umschalten von Verstärkern zu passenden Lautsprechern. Die Lautsprecher sind bei mir aber nur dummy devices mit dem genericDeviceType speaker. Nun könnte ich sie alle einheitlich benennen, aber betateilchen hat ja schon festgestellt, dass mir schnell Flüchtigkeitsfehler passieren.

Zitat von: rudolfkoenig am 08 Februar 2018, 10:13:02
NOTIFYDEV entscheidet darueber, ob und wann eine FHEM-Geraete-Instanz benachrichtigt wird. Durch deinen Patch wird ermoeglicht, dass trotz anderslautender Definition eine Notify-Instanz nicht, oder fuer eine ganz andere Sache benachrichtigt wird, und erschwert dadurch das debugging.
Auf das pattern in der DEF wird ja weiterhin geprüft und das nicht benachrichtigen lässt sich ja auch mit ignoreRegexp einschränken.
man könnte ignoreRegexp auch als Blacklist sehen und das neue Attribut als Whitelist, nur dass eben eine devspec anstelle einer regex angegeben wird. Idealerweise sollte beides möglich sein.

Zitat von: betateilchen am 08 Februar 2018, 10:43:03
Und da Attribute ja dem Benutzer gehören (sollen) und nicht dem Entwickler, muss man sich als Entwickler sowas auch überhaupt nicht wünschen.
Den Satz verstehe ich nicht. Ich bin auch dagegen, dass Module Attribute vorbelegen. Hier ist es doch aber nur eine weitere Möglichkeit für den Benutzer das Verhalten vom notify zu steuern.
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

rudolfkoenig

Sorry, ich sehe immer noch keine Begruendung.

ZitatAuf das pattern in der DEF wird ja weiterhin geprüft und das nicht benachrichtigen lässt sich ja auch mit ignoreRegexp einschränken.
Das mag sein, aber wenn man NOTIFYDEV falsch setzt, dann wird notify gar nicht aufgerufen. Es ist nicht so, dass ohne NOTIFYDEV ein notify nicht funktioniert, nur dass seine Regexp-Pruef-Funktion moeglicherweise haeufiger als theoretisch notwendig aufgerufen wird.