diff --git a/fhem/CHANGED b/fhem/CHANGED index 33faf34d4..d232a669f 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,6 +1,7 @@ # Add changes at the top of the list. - SVN + - feature: notify supports $NAME/$EVENT/$EVTPART0/etc. @/% is deprecated. - feature: 93_DbLog extended to give more functions for the charting frontend. This includes new queries for raw table data and also statistics, which get sum/max/min/avg values from the database. diff --git a/fhem/FHEM/91_notify.pm b/fhem/FHEM/91_notify.pm index c4c099238..ca82015f7 100755 --- a/fhem/FHEM/91_notify.pm +++ b/fhem/FHEM/91_notify.pm @@ -127,44 +127,62 @@ notify_Attr(@) Examples:
define b3lampV1 notify btn3 set lamp %define b3lampV2 notify btn3 { fhem "set lamp %" }define b3lampV3 notify btn3 "/usr/local/bin/setlamp "%""define b3lampV3 notify btn3 set lamp1 %;;set lamp2 %define wzMessLg notify wz:measured.* "/usr/local/bin/logfht @ "%""define LogUndef notify global:UNDEFINED.* "send-me-mail.sh "%""define b3lampV1 notify btn3 set lamp $EVENTdefine b3lampV2 notify btn3 { fhem "set lamp $EVENT" }define b3lampV3 notify btn3 "/usr/local/bin/setlamp "$EVENT""define b3lampV3 notify btn3 set lamp1 $EVENT;;set lamp2 $EVENTdefine wzMessLg notify wz:measured.* "/usr/local/bin/logfht $NAME "$EVENT""define LogUndef notify global:UNDEFINED.* "send-me-mail.sh "$EVENT""% will be replaced with the received event,
- e.g. with on or off or measured-temp: 21.7
- (Celsius)% into double
- quotes, else the shell may get a syntax error.@ will be replaced with the device
- name.% and @, the parameters
- %EVENT (same as %), %NAME (same as
- @) and %TYPE (contains the device type, e.g.
- FHT) can be used. The space separated event "parts" are
- available as %EVTPART0, %EVTPART1, etc. A single % looses
- its special meaning if any of these parameters appears in the
- definition.<pattern> may also be a compound of
- definition:event to filter for events.<pattern> is either the name of the triggering
+ device, or devicename:event.<pattern> must completely (!)
- match either the device name, or the compound of the device name and the
- event. The event is either the string you see in the list output in paranthesis after the device name, or the
- string you see when you do a detailed list of the device.measured-temp: 21.7 (Celsius)$EVTPART0="measured-temp:", $EVTPART1="21.7",
+ $EVTPART2="(Celsius)". This data is available as a local
+ variable in perl, as environment variable for shell scripts, and will
+ be textually replaced for FHEM commands.myFht% will be replaced with the received
+ event, e.g. with on or off or
+ measured-temp: 21.7 (Celsius)% into double quotes, else the shell may get a syntax
+ error.@ will be replaced with the device
+ name.% and @, the parameters
+ %EVENT (same as %), %NAME (same
+ as @) and %TYPE (contains the device type,
+ e.g. FHT) can be used. The space separated event "parts"
+ are available as %EVTPART0, %EVTPART1, etc. A single %
+ looses its special meaning if any of these parameters appears in the
+ definition. Formatting\n";
-# $l =~ s/<.?pre>//g;
-# }
print OUT $l;
$docCount++;
$hasLink = ($l =~ m//) if(!$hasLink);
diff --git a/fhem/fhem.pl b/fhem/fhem.pl
index 1ea3969a3..29bbf44e4 100755
--- a/fhem/fhem.pl
+++ b/fhem/fhem.pl
@@ -53,6 +53,7 @@ sub CheckDuplicate($$);
sub CommandChain($$);
sub Dispatch($$$);
sub DoTrigger($$@);
+sub EvalSpecials($%);
sub EventMapAsList($);
sub FmtDateTime($);
sub FmtTime($);
@@ -194,6 +195,7 @@ my $namedef =
my $stt_sec; # Used by SecondsTillTomorrow()
my $stt_day; # Used by SecondsTillTomorrow()
my @cmdList; # Remaining commands in a chain. Used by sleep
+my $evalSpecials; # Used by EvalSpecials->AnalyzeCommand parameter passing
$init_done = 0;
@@ -651,6 +653,7 @@ AnalyzeCommandChain($$)
push(@ret, $lret) if(defined($lret));
}
@cmdList = @saveCmdList;
+ $evalSpecials = undef;
return join("\n", @ret) if(@ret);
return undef;
}
@@ -662,6 +665,7 @@ AnalyzePerlCommand($$)
my ($cl, $cmd) = @_;
$cmd =~ s/\\ *\n/ /g; # Multi-line
+
# Make life easier for oneliners:
%value = ();
foreach my $d (keys %defs) {
@@ -675,6 +679,19 @@ AnalyzePerlCommand($$)
}
$month++;
$year+=1900;
+
+ if($evalSpecials) {
+ $cmd = join("", map { my $n = substr($_,1);
+ my $v = $evalSpecials->{$_};
+ $v =~ s/(['\\])/\\$1/g;
+ "my \$$n='$v';";
+ } keys %{$evalSpecials})
+ . $cmd;
+ # Normally this is deleted in AnalyzeCommandChain, but ECMDDevice calls us
+ # directly, and combining perl with something else isnt allowed anyway.
+ $evalSpecials = undef;
+ }
+
my $ret = eval $cmd;
$ret = $@ if($@);
return $ret;
@@ -696,6 +713,9 @@ AnalyzeCommand($$)
}
if($cmd =~ m/^"(.*)"$/s) { # Shell code in bg, to be able to call us from it
+ if($evalSpecials) {
+ map { $ENV{substr($_,1)} = $evalSpecials->{$_}; } keys %{$evalSpecials};
+ }
my $out = "";
$out = ">> $currlogfile 2>&1" if($currlogfile ne "-" && $^O ne "MSWin32");
system("$1 $out &");
@@ -703,6 +723,10 @@ AnalyzeCommand($$)
}
$cmd =~ s/^[ \t]*//;
+ if($evalSpecials) {
+ map { my $n = substr($_,1); my $v = $evalSpecials->{$_};
+ $cmd =~ s/\$$n/$v/g; } keys %{$evalSpecials};
+ }
my ($fn, $param) = split("[ \t][ \t]*", $cmd, 2);
return undef if(!$fn);
@@ -710,7 +734,7 @@ AnalyzeCommand($$)
# Search for abbreviation
if(!defined($cmds{$fn})) {
foreach my $f (sort keys %cmds) {
- if(length($f) > length($fn) && lc(substr($f, 0, length($fn))) eq lc($fn)) {
+ if(length($f) > length($fn) && lc(substr($f,0,length($fn))) eq lc($fn)) {
Log 5, "$fn => $f";
$fn = $f;
last;
@@ -2008,7 +2032,8 @@ CommandSleep($$)
Log 4, "sleeping for $param";
if(!$cl && @cmdList && $param && $init_done) {
- InternalTimer(gettimeofday()+$param, "WakeUpFn", join(";", @cmdList), 0);
+ my %h = (cmd=>join(";", @cmdList), evalSpecials=>$evalSpecials);
+ InternalTimer(gettimeofday()+$param, "WakeUpFn", \%h, 0);
@cmdList=();
} else {
@@ -2021,8 +2046,9 @@ CommandSleep($$)
sub
WakeUpFn($)
{
- my $param = shift;
- my $ret = AnalyzeCommandChain(undef, $param);
+ my $h = shift;
+ $evalSpecials = $h->{evalSpecials};
+ my $ret = AnalyzeCommandChain(undef, $h->{cmd});
Log 2, "After sleep: $ret" if($ret);
}
@@ -2193,8 +2219,6 @@ EvalSpecials($%)
my ($exec, %specials)= @_;
$exec = SemicolonEscape($exec);
- $exec =~ s/%%/____/g;
-
# %EVTPART due to HM remote logic
my $idx = 0;
if(defined($specials{"%EVENT"})) {
@@ -2204,6 +2228,16 @@ EvalSpecials($%)
}
}
+ my $re = join("|", keys %specials);
+ $re =~ s/%//g;
+ if($exec =~ m/\$($re)\b/) {
+ $evalSpecials = \%specials;
+ return $exec;
+ }
+
+ $exec =~ s/%%/____/g;
+
+
# perform macro substitution
my $extsyntax= 0;
foreach my $special (keys %specials) {