2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-01-31 06:39:11 +00:00

fhem.pl: second eventMap Syntax added.

git-svn-id: https://svn.fhem.de/fhem/trunk@8690 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
rudolfkoenig 2015-06-04 16:47:20 +00:00
parent e63ba7018d
commit 34f65d5a83
3 changed files with 131 additions and 18 deletions

View File

@ -436,6 +436,24 @@ Device specific attributes are documented in the corresponding device section.
attr store eventMap /on-for-timer 10:open/off:closed/<br>
set store open
</code></ul>
The explicit variant of this attribute has the following syntax:
<ul><code>
attr store eventMap { dev=>{"on"=>"open"}, usr=>{"open"=>"on"} }<br>
attr store eventMap { dev=>{"^on(-for-timer)?(.*)"=>"open$2"},
usr=>{"^open(.*)"=>"on$1"},
fw=>{"^open(.*)"=>"open"} }
</code></ul>
This variant must be used, if the mapping is not symmetrical, the first
part (dev) representing the device to user mapping, i.e. if the device
reports on 100 or on-for-timer 100, the user will see open 100. The
second part (usr) is the other direction, if the user specified open
10, the device will receive on 10. On both occasions the key will be
first compared directly with the text, and if it is not equal, then it
will be tried to match it as a regexp. When using regexps in the usr
part with wildcards, the fw part must be filled with the exact same
keys to enable a correct display in the FHEMWEB set dropdown list in
the detail view.
</li><br>

View File

@ -453,6 +453,25 @@ Ger&auml;t dokumentiert.
attr store eventMap /on-for-timer 10:open/off:closed/<br>
set store open
</code></ul>
Die explizite Variante dieses Attributes hat folgenden Syntax:
<ul><code>
attr store eventMap { dev=>{"on"=>"open"}, usr=>{"open"=>"on"} }<br>
attr store eventMap { dev=>{"^on(-for-timer)?(.*)"=>"open$2"},
usr=>{"^open(.*)"=>"on$1"},
fw=>{"^open(.*)"=>"open"} }
</code></ul>
Diese Variante muss dann verwendet werden, falls das Mapping nicht
symmetrisch ist. Der erste Teil (dev) spezifiziert dabei die Richtung
Ger&auml;t zu Benutzer, d.h. falls das Ger&auml;t on 100 oder
on-for-timer 100 meldet, dann wird der Benutzer open 100 zu sehen
bekommen. Der zweite Teil (usr) spezifiziert die Richtung Benutzer zu
Ger&auml;t, d.h. wenn man "set XX open 100" eingibt, dann wird das
Kommando "on 100" an das Ger&auml;t gesendet. In beiden F&auml;llen wird
der Schl&uuml;ssel zuerst direkt, und dann als Regexp mit dem Wert
verglichen. Falls man Regexps mit Wildcards im usr Teil verwendet, dann
muss man den fw Teil mit dem exakt gleichen Schl&uuml;sseln
ausf&uuml;llen, damit FHEMWEB in der Detail-Ansicht den set-Auswahl
richtig anzeigen kann.
</li><br>
</ul>
@ -1211,7 +1230,7 @@ Die folgenden lokalen Attribute werden von mehreren Ger&auml;ten verwendet:
<ul>
<code>setstate &lt;devspec&gt; &lt;value&gt;</code>
<br><br>
Der Befehl setzt den STATE Eintrag des Ger&aauml;tes direkt, ohne Ereignisse
Der Befehl setzt den STATE Eintrag des Ger&auml;tes direkt, ohne Ereignisse
zu generieren oder ein Signal an das Ger&auml;t zu senden. Dieser Eintrag ist
ma&szlig;gebend f&uuml;r die Status-Anzeige in diversen Frontends. Dieser
Befehl wird auch im <a href="#statefile">statefile</a> benutzt.<br> Siehe den

View File

@ -2202,17 +2202,7 @@ getAllSets($)
$a2 = "" if($a2 =~ /^No set implemented for/);
return "" if($a2 eq "");
my $em = AttrVal($d, "eventMap", undef);
if($em) {
# Delete the first word of the translation (.*:), else it will be
# interpreted as the single possible value for a dropdown
# Why is the .*= deleted?
$em = join(" ", grep { !/ / }
map { $_ =~ s/.*?=//s;
$_ =~ s/.*?://s; $_ }
attrSplit($em));
$a2 = "$em $a2";
}
$a2 = $defs{$d}{".eventMapCmd"}." $a2" if(defined($defs{$d}{".eventMapCmd"}));
return $a2;
}
@ -2370,6 +2360,17 @@ CommandAttr($$)
next;
}
if($attrName eq "eventMap") {
delete $hash->{".eventMapHash"};
delete $hash->{".eventMapCmd"};
$attr{$sdev}{eventMap} = (defined $a[2] ? $a[2] : 1);
my $r = ReplaceEventMap($sdev, "test", 1); # refresh eventMapCmd
if($r =~ m/^ERROR in eventMap for /) {
delete($attr{$sdev}{eventMap});
return $r;
}
}
$a[0] = $sdev;
my $oVal = ($attr{$sdev} ? $attr{$sdev}{$attrName} : "");
$ret = CallFn($sdev, "AttrFn", "set", @a);
@ -3345,24 +3346,37 @@ attrSplit($)
}
#######################
# $dir: 0 = User to Fhem (i.e. set), 1 = Fhem to User (i.e trigger)
# $dir: 0: User to Device (i.e. set) 1: Device to Usr (i.e trigger)
# $dir: 0: $str is an array pointer 1: $str is a a string
sub
ReplaceEventMap($$$)
{
my ($dev, $str, $dir) = @_;
my $em = $attr{$dev}{eventMap};
return $str if($dir && !$em);
return @{$str} if(!$dir && (!$em || int(@{$str}) < 2 || $str->[1] eq "?"));
my $dname = shift @{$str} if(!$dir);
my $nstr = join(" ", @{$str}) if(!$dir);
my $changed;
return ReplaceEventMap2($dev, $str, $dir, $em) if($em =~ m/^{.*}$/);
my @emList = attrSplit($em);
if(!defined $defs{$dev}{".eventMapCmd"}) {
# Delete the first word of the translation (.*:), else it will be
# interpreted as the single possible value for a dropdown
# Why is the .*= deleted?
$defs{$dev}{".eventMapCmd"} = join(" ", grep { !/ / }
map { $_ =~ s/.*?=//s; $_ =~ s/.*?://s; "$_:noArg" } @emList);
}
my $dname = shift @{$str} if(!$dir);
my $nstr = join(" ", @{$str}) if(!$dir);
my $changed;
foreach my $rv (@emList) {
# Real-Event-Regexp:GivenName[:modifier]
my ($re, $val, $modifier) = split(":", $rv, 3);
next if(!defined($val));
if($dir) { # event -> GivenName
if($dir) { # dev -> usr
my $reIsWord = ($re =~ m/^\w*$/); # dim100% is not \w only, cant use \b
if($reIsWord) {
if($str =~ m/\b$re\b/) {
@ -3376,7 +3390,7 @@ ReplaceEventMap($$$)
}
}
} else { # GivenName -> set command
} else { # usr -> dev
if($nstr eq $val) { # for special translations like <> and <<
$nstr = $re;
$changed = 1;
@ -3408,6 +3422,68 @@ ReplaceEventMap($$$)
}
}
# $dir: 0:usr,$str is array pointer, 1:dev, $str is string
# perl notation: { dev=>{"re1"=>"Evt1",...}, dpy=>{"re2"=>"Set 1",...}}
sub
ReplaceEventMap2($$$)
{
my ($dev, $str, $dir) = @_;
my $hash = $defs{$dev};
my $emh = $hash->{".eventMapHash"};
if(!$emh) {
eval "\$emh = $attr{$dev}{eventMap}";
if($@) {
my $msg = "ERROR in eventMap for $dev: $@";
Log 1, $msg;
return $msg;
}
$hash->{".eventMapHash"} = $emh;
$defs{$dev}{".eventMapCmd"} = "";
if($emh->{usr}) {
my @cmd;
my $fw = $emh->{fw};
$defs{$dev}{".eventMapCmd"} = join(" ",
map { ($fw && $fw->{$_}) ? $fw->{$_}:$_} sort keys %{$emh->{usr} });
}
}
if($dir == 1) {
$emh = $emh->{dev};
if($emh) {
foreach my $k (keys %{$emh}) {
return $emh->{$k} if($str eq $k);
return eval '"'.$emh->{$k}.'"' if($str =~ m/$k/);
}
}
return $str;
}
$emh = $emh->{usr};
return @{$str} if(!$emh);
my $dname = shift @{$str};
my $nstr = join(" ", @{$str});
foreach my $k (keys %{$emh}) {
my $nv;
if($nstr eq $k) {
$nv = $emh->{$k};
} elsif($nstr =~ m/$k/) {
$nv = eval '"'.$emh->{$k}.'"';
}
if($nv) {
my @arr = split(" ",$nv);
unshift @arr, $dname;
return @arr;
}
}
unshift @{$str}, $dname;
return @{$str};
}
sub
setGlobalAttrBeforeFork($)
{