mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-28 11:01:59 +00:00
fhem.pl/devspec: removed range, added :=FILTER=, the = operator is more general
git-svn-id: https://svn.fhem.de/fhem/trunk@4333 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
a32f1b58a7
commit
211c4e09ea
@ -1,6 +1,7 @@
|
|||||||
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
# 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.
|
# Do not insert empty lines here, update check depends on it.
|
||||||
- SVN
|
- SVN
|
||||||
|
- feature: devspec: removed range, added :FILTER and more general search
|
||||||
- feature: HUEBridge,HUEDevice: support for groups added
|
- feature: HUEBridge,HUEDevice: support for groups added
|
||||||
- feature: YAMAHA_AVR: new argument "toggle" for mute command
|
- feature: YAMAHA_AVR: new argument "toggle" for mute command
|
||||||
- feature: FB_CALLMONITOR: replace & to & at reverse search
|
- feature: FB_CALLMONITOR: replace & to & at reverse search
|
||||||
|
@ -279,34 +279,33 @@ A line ending with \ will be concatenated with the next one, so long lines
|
|||||||
<ul>
|
<ul>
|
||||||
<li>a single device name. This is the most common case.</li>
|
<li>a single device name. This is the most common case.</li>
|
||||||
<li>a list of devices, separated by comma (,)</li>
|
<li>a list of devices, separated by comma (,)</li>
|
||||||
<li>a range of devices, separated by dash (-)</li>
|
<li>a regular expression</li>
|
||||||
<li>a regular expression, if the the spec contains on e of the following
|
<li>a NAME=VALUE pair, where NAME can be an Internal value like TYPE, a
|
||||||
characters: ^*[]$</li>
|
Reading-Name or an attribute. VALUE is a regexp. To negate the
|
||||||
<li>an attribute of the device, followed by an equal sign (=) and then a
|
comparison, use NAME!=VALUE</li>
|
||||||
regexp for this attribute. As attribute you can specify either attributes
|
<li>if the spec is followed by the expression :FILTER=NAME=VALUE, then the
|
||||||
set with the attr command or one of the "internal" attributes DEF, STATE
|
values found in the first round are filtered by the second expression.
|
||||||
and TYPE.</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
Example:
|
Examples:
|
||||||
<ul>
|
<ul>
|
||||||
<code>set lamp1 on</code><br>
|
<code>set lamp1 on</code><br>
|
||||||
<code>set lamp1,lamp2,lamp3 on</code><br>
|
<code>set lamp1,lamp2,lamp3 on</code><br>
|
||||||
<code>set lamp[1-3] on</code><br>
|
|
||||||
<code>set lamp.* on</code><br>
|
<code>set lamp.* on</code><br>
|
||||||
<code>set lamp1-lamp3 on</code><br>
|
|
||||||
<code>set lamp1-lamp3,lamp3 on</code><br>
|
|
||||||
<code>set room=kitchen off</code><br>
|
<code>set room=kitchen off</code><br>
|
||||||
|
<code>set room=kitchen:FILTER=STATE=on off</code><br>
|
||||||
|
<code>set room=kitchen:FILTER=STATE!=off off</code><br>
|
||||||
<code>list disabled=</code><br>
|
<code>list disabled=</code><br>
|
||||||
<code>list TYPE=FS20</code><br>
|
<code>list TYPE=FS20 STATE</code><br>
|
||||||
</ul>
|
</ul>
|
||||||
Notes:
|
Notes:
|
||||||
<ul>
|
<ul>
|
||||||
<li>first the spec is separated by komma, then the range or the regular
|
<li>the spec may not contain space characters.</n>
|
||||||
expression operations are executed.</li>
|
|
||||||
<li>if there is a device which exactly corresponds to the spec, then
|
<li>if there is a device which exactly corresponds to the spec, then
|
||||||
no special processing is done.</li>
|
no special processing is done.</li>
|
||||||
|
<li>first the spec is separated by komma, then the regular expression and
|
||||||
|
filter operations are executed.</li>
|
||||||
<li>the returned list can contain the same device more than once, so
|
<li>the returned list can contain the same device more than once, so
|
||||||
"set lamp1-lamp3,lamp3 on" switches lamp3 twice.</li>
|
"set lamp3,lamp3 on" switches lamp3 twice.</li>
|
||||||
<li>for more complex structuring demands see the <a href="#structure">
|
<li>for more complex structuring demands see the <a href="#structure">
|
||||||
structure</a> device.
|
structure</a> device.
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -265,56 +265,59 @@ Zeilen erstreckende Befehle, indem man keine \ am Zeilenende eingeben muss.</p>
|
|||||||
<a name="devspec"></a>
|
<a name="devspec"></a>
|
||||||
<h3>Geräte-Spezifikation (devspec)</h3>
|
<h3>Geräte-Spezifikation (devspec)</h3>
|
||||||
<ul>
|
<ul>
|
||||||
Befehle wie
|
Die Befehle
|
||||||
<a href="#attr">attr</a>,
|
<a href="#attr">attr</a>,
|
||||||
<a href="#set">set</a>,
|
<a href="#set">set</a>,
|
||||||
<a href="#get">get</a>, usw.
|
<a href="#get">get</a>, usw.
|
||||||
|
<a href="#attr">attr</a>,
|
||||||
|
<a href="#deleteattr">deleteattr</a>,
|
||||||
|
<a href="#displayattr">displayattr</a>,
|
||||||
|
<a href="#delete">delete</a>,
|
||||||
|
<a href="#get">get</a>,
|
||||||
|
<a href="#list">list</a>,
|
||||||
|
<a href="#set">set</a>,
|
||||||
|
<a href="#setreading">setreading</a>,
|
||||||
|
<a href="#setstate">setstate</a>,
|
||||||
|
<a href="#trigger">trigger</a>
|
||||||
können eine komplexere Gerätespezifikation als Argumente enthalten,
|
können eine komplexere Gerätespezifikation als Argumente enthalten,
|
||||||
die auch eine Anzahl von Geräten betreffen kann. Eine
|
die auch eine Anzahl von Geräten betreffen kann. Eine
|
||||||
Gerätespezifikation (Kurzfassung) kann z.B. so aussehen:
|
Gerätespezifikation kann folgendes sein:
|
||||||
<ul>
|
<ul>
|
||||||
<li>ein einzelner Gerätename. Dies ist der
|
<li>ein einzelner Gerätename. Dies ist der Normalfall</li>
|
||||||
meist vorkommende Fall.</li>
|
<li>eine durch Komma(,) getrennte Liste von Gerätenamen</li>
|
||||||
<li>
|
<li>ein regulärer Ausdruck</li>
|
||||||
eine Liste von Gerätenamen, durch Kommata (,) getrennt</li>
|
<li>ein NAME=WERT Ausdruck, wo NAME ein "Internal" Wert wie TYPE ist, ein
|
||||||
<li>
|
Reading-Name oder ein Attribut. WERT ist ein regulärer Ausdruck.
|
||||||
ein Bereich, durch ein Minuszeichen getrennt (-)</li>
|
Um die Bedingung zu negieren, sollte NAME!=WERT verwendet werden.
|
||||||
<li>ein regulärer Ausdruck der eines der
|
</li>
|
||||||
folgenden Zeichen enthält: ^*[]$</li>
|
<li>Falls die Spezifikation von :FILTER=NAME=WERT gefolgt wird,
|
||||||
<li>
|
dann wird die zuvor gefundene Liste durch diesen neuen Ausdruck
|
||||||
ein Geräteattribut, gefolgt von einem Gleichheitszeichen (=) und einem
|
gefiltert.
|
||||||
regulären Ausdruck für dieses Attribut.
|
|
||||||
Als Attribut können Sie entweder Attribute die mittels "attr"-Befehl oder
|
|
||||||
eines der "internen" Attribute wie DEF, STATE oder TYPE angeben.</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
Beispiele:
|
Beispiele:
|
||||||
<ul>
|
<ul>
|
||||||
<code>set lamp1 on</code><br>
|
<code>set lamp1 on</code><br>
|
||||||
<code>set lamp1,lamp2,lamp3 on</code><br>
|
<code>set lamp1,lamp2,lamp3 on</code><br>
|
||||||
<code>set lamp[1-3] on</code><br>
|
|
||||||
<code>set lamp.* on</code><br>
|
<code>set lamp.* on</code><br>
|
||||||
<code>set lamp1-lamp3 on</code><br>
|
|
||||||
<code>set lamp1-lamp3,lamp3 on</code><br>
|
|
||||||
<code>set room=kitchen off</code><br>
|
<code>set room=kitchen off</code><br>
|
||||||
|
<code>set room=kitchen:FILTER=STATE=on off</code><br>
|
||||||
|
<code>set room=kitchen:FILTER=STATE!=off off</code><br>
|
||||||
<code>list disabled=</code><br>
|
<code>list disabled=</code><br>
|
||||||
<code>list TYPE=FS20</code><br>
|
<code>list TYPE=FS20 STATE</code><br>
|
||||||
</ul>
|
</ul>
|
||||||
Bemerkungen:
|
Bemerkungen:
|
||||||
<ul>
|
<ul>
|
||||||
<li>zuerst wird die durch Kommata getrennte
|
<li>die Spezifikation kann keine Leerzeichen enthalten.</li>
|
||||||
Spezifikation abgearbeitet, dann folgen die Bereichsspezifikationen und die
|
<li>falls ein Gerätename exakt dem Spezifikation entspricht, dann werden
|
||||||
regulären Ausdrücke</li>
|
keine reguläre Ausdrücke oder Filter ausgewertet.
|
||||||
<li>
|
<li>zuerst wird die durch Komma getrennte Spezifikation abgearbeitet, dann
|
||||||
wenn für ein Gerät eine Spezifikation exakt zutrifft, werden keine weiteren
|
folgen die regulären Ausdrücke und die Filter</li>
|
||||||
Vergleiche vorgenommen.</li>
|
<li>die Befehlszeile kann die selbe Gerätebezeichnung mehrfach enthalten
|
||||||
<li>
|
z.B.: "set lamp3,lamp3 on". Lamp3 wird hier zwei Mal
|
||||||
die Befehlszeile kann die selbe Gerätebezeichnung mehrfach enthalten z.B.: "set
|
eingeschalten.</li>
|
||||||
lamp1-lamp3, lamp3 on".
|
<li>um Strukturen mit komplexeren Anforderungen zu realisieren lesen Sie
|
||||||
Lamp3 wird hier zwei Mal eingeschalten.</li>
|
bitte den Abschnitt zu <a href="#structure"> structure</a>.
|
||||||
<li>um Strukturen mit komplexeren Anforderungen zu realisieren lesen Sie bitte
|
</ul>
|
||||||
den Abschnitt zu <a href="#structure">
|
|
||||||
structure</a>.
|
|
||||||
</li></ul>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<a name="help"></a>
|
<a name="help"></a>
|
||||||
|
71
fhem/fhem.pl
71
fhem/fhem.pl
@ -862,8 +862,6 @@ AnalyzeCommand($$)
|
|||||||
sub
|
sub
|
||||||
devspec2array($)
|
devspec2array($)
|
||||||
{
|
{
|
||||||
my %knownattr = ( "DEF"=>1, "STATE"=>1, "TYPE"=>1 );
|
|
||||||
|
|
||||||
my ($name) = @_;
|
my ($name) = @_;
|
||||||
|
|
||||||
return "" if(!defined($name));
|
return "" if(!defined($name));
|
||||||
@ -872,59 +870,44 @@ devspec2array($)
|
|||||||
return "FHEM2FHEM_FAKE_$name" if($defs{$name}{FAKEDEVICE});
|
return "FHEM2FHEM_FAKE_$name" if($defs{$name}{FAKEDEVICE});
|
||||||
return $name;
|
return $name;
|
||||||
}
|
}
|
||||||
# FAKE is set by FHEM2FHEM LOG
|
|
||||||
|
|
||||||
my ($isattr, @ret);
|
my @ret;
|
||||||
|
foreach my $l (split(",", $name)) { # List of elements
|
||||||
|
my @names = sort keys %defs;
|
||||||
|
my @res;
|
||||||
|
foreach my $dName (split(":FILTER=", $name)) {
|
||||||
|
my ($n,$op,$re) = ("NAME","=",$dName);
|
||||||
|
($n,$op,$re) = ($1,$2,$3) if($dName =~ m/^([^!]*)(=|!=)(.*)$/);
|
||||||
|
|
||||||
foreach my $l (split(",", $name)) { # List
|
@res=();
|
||||||
|
foreach my $d (@names) {
|
||||||
if($l =~ m/(.*)=(.*)/) {
|
next if($attr{$d} && $attr{$d}{ignore});
|
||||||
my ($lattr,$re) = ($1, $2);
|
my $hash = $defs{$d};
|
||||||
if($knownattr{$lattr}) {
|
my $val = $hash->{$n};
|
||||||
eval { # a bad regexp may shut down fhem.pl
|
if(!defined($val)) {
|
||||||
foreach my $l (sort keys %defs) {
|
my $r = $hash->{READINGS};
|
||||||
push @ret, $l
|
$val = $r->{$n}{VAL} if($r && $r->{$n});
|
||||||
if($defs{$l}{$lattr} && (!$re || $defs{$l}{$lattr}=~m/^$re$/));
|
}
|
||||||
|
if(!defined($val)) {
|
||||||
|
$val = $attr{$d}{$n} if($attr{$d});
|
||||||
|
}
|
||||||
|
next if(!defined($val));
|
||||||
|
eval { # a bad regexp is deadly
|
||||||
|
if(($op eq "=" && $val =~ m/^$re$/) ||
|
||||||
|
($op eq "!=" && $val !~ m/^$re$/)) {
|
||||||
|
push @res, $d
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if($@) {
|
if($@) {
|
||||||
Log 1, "devspec2array $name: $@";
|
Log 1, "devspec2array $name: $@";
|
||||||
return $name;
|
return $name;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
foreach my $l (sort keys %attr) {
|
|
||||||
push @ret, $l
|
|
||||||
if($attr{$l}{$lattr} && (!$re || $attr{$l}{$lattr} =~ m/$re/));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
$isattr = 1;
|
@names = @res;
|
||||||
next;
|
|
||||||
}
|
}
|
||||||
|
push @ret,@res;
|
||||||
my $regok;
|
|
||||||
eval { # a bad regexp may shut down fhem.pl
|
|
||||||
if($l =~ m/[*\[\]^\$]/) { # Regexp
|
|
||||||
push @ret, grep($_ =~ m/^$l$/, sort keys %defs);
|
|
||||||
$regok = 1;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if($@) {
|
|
||||||
Log 1, "devspec2array $name: $@";
|
|
||||||
return $name;
|
|
||||||
}
|
|
||||||
next if($regok);
|
|
||||||
|
|
||||||
if($l =~ m/-/) { # Range
|
|
||||||
my ($lower, $upper) = split("-", $l, 2);
|
|
||||||
push @ret, grep($_ ge $lower && $_ le $upper, sort keys %defs);
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
push @ret, $l;
|
|
||||||
}
|
}
|
||||||
|
return $name if(!@ret);
|
||||||
return $name if(!@ret && !$isattr); # No match, return the input
|
|
||||||
@ret = grep { !$attr{$_} || !$attr{$_}{ignore} } @ret
|
|
||||||
if($name !~ m/^ignore=/);
|
|
||||||
return @ret;
|
return @ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user