diff --git a/fhem/CHANGED b/fhem/CHANGED
index c173bfb72..01d847b63 100644
--- a/fhem/CHANGED
+++ b/fhem/CHANGED
@@ -1,5 +1,6 @@
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
# Do not insert empty lines here, update check depends on it.
+ - feature: global ATTR/DELETEATTR/MODIFIED events
- feature: 55_GDS.pm - attr disable added
- bugfix: SYSMON: prevent endless loop at startup with 'disable' attribute
- feature: SYSMON: added FritzBox informations: DSL rate, DSLAM sync time, count of CRC an FEC
diff --git a/fhem/docs/commandref_frame.html b/fhem/docs/commandref_frame.html
index de53fb2b7..bb5a79c0e 100644
--- a/fhem/docs/commandref_frame.html
+++ b/fhem/docs/commandref_frame.html
@@ -593,6 +593,7 @@ The following local attributes are used by a wider range of devices:
Use "attr <name> ?" to get a list of possible attributes.
See the Device specification section for details on
<devspec>.
+ After setting the attribute, the global event "ATTR" will be generated.
Examples:
@@ -688,6 +689,7 @@ The following local attributes are used by a wider range of devices:
or all attributes for a device (if no <attrname> is defined).
See the Device specification section for details on
<devspec>.
+ After deleting the attribute, the global event "DELETEATTR" will be generated.
Examples:
@@ -891,6 +893,7 @@ The following local attributes are used by a wider range of devices:
one argument to an at type definition, only the time part will be changed. In
case of a notify type definition, only the regex part will be changed. All
other values (state, attributes, etc) will remain intact.
+ After modify, the global event "MODIFIED" will be generated.
Example:
diff --git a/fhem/docs/commandref_frame_DE.html b/fhem/docs/commandref_frame_DE.html
index 0ce7fb664..360157d79 100644
--- a/fhem/docs/commandref_frame_DE.html
+++ b/fhem/docs/commandref_frame_DE.html
@@ -623,6 +623,7 @@ Die folgenden lokalen Attribute werden von mehreren Geräte verwendet:
Gerätespezifische Attribute sind in der Beschreibung zum jeweiligen
Gerät aufgeführt.
+ Nach der Durchführung das globale Ereignis "ATTR" wird generiert.
Beispiele:
@@ -687,8 +688,7 @@ Die folgenden lokalen Attribute werden von mehreren Geräte verwendet:
"lamp off" anstatt "Device 5673, Button 00, Code 00 (off)" als Text enthält.
Geben Sie an der Befehlszeile "define <name> ?" ein, um eine Liste der
verfügbaren "types" zu erhalten.
- Nach der Definition, wird das globale Ereignis "DEFINED" genriert. Genauere
- Beschreibung erhalten Sie im Abschnitt "notify".
+ Nach der Durchführung das globale Ereignis "MODIFIED" wird generiert.
Jedes Gerät besitzt unterschiedliche hinzufügbare Argumente per Definition,
@@ -727,6 +727,7 @@ Die folgenden lokalen Attribute werden von mehreren Geräte verwendet:
kein <attrname> angegeben wird).
Siehe den Abschnitt über Geräte-Spezifikation
für Details der <devspec>.
+ Nach der Durchführung das globale Ereignis "DELETEATTR" wird generiert.
Beispiele:
@@ -937,7 +938,10 @@ Die folgenden lokalen Attribute werden von mehreren Geräte verwendet:
verändern, dann wird nur der für die Zeit zuständige Teil
geändert. Im Falle der Veränderung einer Definition vom Typ
"notify" wird nur der regex Teil geändert. Alle anderen
- Werte (Stati, Attribute, etc) bleiben erhalten.
+ Werte (Stati, Attribute, etc) bleiben erhalten.
+ After modify, the global event "MODIFIED" will be generated.
+ Nach der Durchführung das globale Ereignis "MODIFIED" wird generiert.
+
Beispiel:
diff --git a/fhem/fhem.pl b/fhem/fhem.pl
index 02c3be1d7..9ef33eb17 100755
--- a/fhem/fhem.pl
+++ b/fhem/fhem.pl
@@ -1193,6 +1193,7 @@ CommandRereadCfg($$)
%attr = ();
%selectlist = ();
%readyfnlist = ();
+ my $informMe = $inform{$name};
%inform = ();
doGlobalDef($cfgfile);
@@ -1211,8 +1212,9 @@ CommandRereadCfg($$)
}
}
- DoTrigger("global", "REREADCFG", 1);
$defs{$name} = $selectlist{$name} = $cl if($name && $name ne "__anonymous__");
+ $inform{$name} = $informMe if($informMe);
+ DoTrigger("global", "REREADCFG", 1);
$init_done = 1;
$reread_active=0;
@@ -1613,7 +1615,12 @@ CommandModify($$)
$hash->{DEF} = $a[1];
my $ret = CallFn($a[0], "DefFn", $hash,
"$a[0] $hash->{TYPE}".(defined($a[1]) ? " $a[1]" : ""));
- $hash->{DEF} = $hash->{OLDDEF} if($ret);
+ if($ret) {
+ $hash->{DEF} = $hash->{OLDDEF};
+ } else {
+ DoTrigger("global", "MODIFIED $a[0]", 1) if($init_done);
+ }
+
delete($hash->{OLDDEF});
$lastDefChange++ if(!$hash->{TEMPORARY});
return $ret;
@@ -1752,8 +1759,12 @@ CommandDeleteAttr($$)
if(@a == 1) {
delete($attr{$sdev});
+ DoTrigger("global", "DELETEATTR $sdev", 1) if($init_done);
+
} else {
delete($attr{$sdev}{$a[1]}) if(defined($attr{$sdev}));
+ DoTrigger("global", "DELETEATTR $sdev $a[1]", 1) if($init_done);
+
}
}
@@ -2205,34 +2216,35 @@ CommandAttr($$)
my @rets;
foreach my $sdev (devspec2array($a[0])) {
- my $hash = $defs{$sdev};
+ my $hash = $defs{$sdev};
+ my $attrName = $a[1];
if(!defined($hash)) {
push @rets, "Please define $sdev first";
next;
}
my $list = getAllAttr($sdev);
- if($a[1] eq "?") {
- push @rets, "$sdev: unknown attribute $a[1], choose one of $list";
+ if($attrName eq "?") {
+ push @rets, "$sdev: unknown attribute $attrName, choose one of $list";
next;
}
- if(" $list " !~ m/ ${a[1]}[ :;]/) {
+ if(" $list " !~ m/ ${attrName}[ :;]/) {
my $found = 0;
foreach my $atr (split("[ \t]", $list)) { # is it a regexp?
- if(${a[1]} =~ m/^$atr$/) {
+ if(${attrName} =~ m/^$atr$/) {
$found++;
last;
}
}
if(!$found) {
- push @rets, "$sdev: unknown attribute $a[1]. ".
+ push @rets, "$sdev: unknown attribute $attrName. ".
"Type 'attr $a[0] ?' for a detailed list.";
next;
}
}
- if($a[1] eq "userReadings") {
+ if($attrName eq "userReadings") {
my %userReadings;
# myReading1[:trigger1] [modifier1] { codecodecode1 }, ...
@@ -2265,7 +2277,7 @@ CommandAttr($$)
$hash->{'.userReadings'}= \%userReadings;
}
- if($a[1] eq "IODev" && (!$a[2] || !defined($defs{$a[2]}))) {
+ if($attrName eq "IODev" && (!$a[2] || !defined($defs{$a[2]}))) {
push @rets,"$sdev: unknown IODev specified";
next;
}
@@ -2279,21 +2291,21 @@ CommandAttr($$)
next;
}
- if(defined($a[2])) {
- $attr{$sdev}{$a[1]} = $a[2];
- } else {
- $attr{$sdev}{$a[1]} = "1";
- }
- if($a[1] eq "IODev") {
+ my $val = $a[2];
+ $val = 1 if(!defined($val));
+ $attr{$sdev}{$attrName} = $val;
+
+ if($attrName eq "IODev") {
my $ioname = $a[2];
$hash->{IODev} = $defs{$ioname};
$hash->{NR} = $devcount++
if($defs{$ioname}{NR} > $hash->{NR});
delete($defs{$ioname}{".clientArray"}); # Force a recompute
}
- if($a[1] eq "stateFormat" && $init_done) {
+ if($attrName eq "stateFormat" && $init_done) {
evalStateFormat($hash);
}
+ DoTrigger("global", "ATTR $sdev $attrName $val", 1) if($init_done);
}