2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-01-31 12:49:34 +00:00

fhem.pl: extern SetMagic, add AttrNum and InternalNum (Forum #38276)

git-svn-id: https://svn.fhem.de/fhem/trunk@13904 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
rudolfkoenig 2017-04-05 11:36:44 +00:00
parent 7d5a03f40b
commit 57eb68292f
3 changed files with 115 additions and 20 deletions

View File

@ -1084,10 +1084,26 @@ The following local attributes are used by a wider range of devices:
From featurelevel 5.7 on the set and setreading command replaces: From featurelevel 5.7 on the set and setreading command replaces:
<ul> <ul>
<li>[device:name] with the reading, internal or attribute of the device, if <li>[device:name] with the reading, internal or attribute of the device, if
both device and the reading, internal or attribute exists. You can use the both device and the reading, internal or attribute exists.
r:, i: or a: prefix to restrict the search to one type, analogue to the <ul>
devspec filtering.</li> <li>You can use the r:, i: or a: prefix to restrict the search to one
type, analogue to the devspec filtering.</li>
<li>The suffix :d retrieves the first number and converts it to an
integer.</li>
<li>The suffix :r&lt;n&gt; retrieves the first number and rounds it to
&lt;n&gt; decimal places. If &lt;n&gt; is missing, then rounds it to
one decimal place.</li>
<li>The suffix :t returns the timestamp (works only for readings)</li>
<li>The suffix :sec returns the number of seconds since the reading was
set.</li>
</ul>
Example:
<ul>
set Lamp blink [blinkDummy:number] [r:blinkDummy:duration:d]
</ul>
</li>
<li>[device:name:d] same as above, but only the number is retrieved</li> <li>[device:name:d] same as above, but only the number is retrieved</li>
<li>[device:name:sec] same as above, but only the number is retrieved</li>
<li>{(perlExpression)} with the result of perlExpression. <li>{(perlExpression)} with the result of perlExpression.
The $DEV variable is additionally available, designating the set device The $DEV variable is additionally available, designating the set device
name. name.
@ -1648,8 +1664,10 @@ The following local attributes are used by a wider range of devices:
Return the reading (the value in the Readings section of "list device") Return the reading (the value in the Readings section of "list device")
</li><br> </li><br>
<li> <li>
ReadingsNum(&lt;devicename&gt;,&lt;reading&gt;,&lt;defaultvalue&gt;)<br> ReadingsNum(&lt;devicename&gt;,&lt;reading&gt;,
Return the reading as a number, i.e. delete non-numerical values. &lt;defaultvalue&gt;,&lt;round&gt;)<br>
Return the first number from a reading value.
Round id to &lt;round&gt; devimal places (optional parameter).
</li><br> </li><br>
<li>ReadingsTimestamp(&lt;devicename&gt;,&lt;reading&gt;,&lt; <li>ReadingsTimestamp(&lt;devicename&gt;,&lt;reading&gt;,&lt;
defaultvalue&gt;)<br> defaultvalue&gt;)<br>
@ -1670,12 +1688,24 @@ The following local attributes are used by a wider range of devices:
{ ReadingsTimestamp("wz", "measured-temp", 0)}<br> { ReadingsTimestamp("wz", "measured-temp", 0)}<br>
{ AttrVal("wz", "room", "none") }<br> { AttrVal("wz", "room", "none") }<br>
</li><br> </li><br>
<li>
AttrNum(&lt;devicename&gt;,&lt;attribute&gt;,
&lt;defaultvalue&gt;,&lt;round&gt;)<br>
Return the first number from an attribute value.
Round id to &lt;round&gt; devimal places (optional parameter).
</li><br>
<li> <li>
InternalVal(&lt;devicename&gt;,&lt;property&gt;,&lt;defaultvalue&gt;) InternalVal(&lt;devicename&gt;,&lt;property&gt;,&lt;defaultvalue&gt;)
<br> <br>
Return the internal value (the value in the Internals section of "list Return the internal value (the value in the Internals section of "list
device"). device").
</li><br> </li><br>
<li>
InternalNum(&lt;devicename&gt;,&lt;property&gt;,
&lt;defaultvalue&gt;,&lt;round&gt;)<br>
Return the first number from an internal value.
Round id to &lt;round&gt; devimal places (optional parameter).
</li><br>
</ul> </ul>

View File

@ -1153,10 +1153,23 @@ Die folgenden lokalen Attribute werden von mehreren Ger&auml;ten verwendet:
<ul> <ul>
<li>[device:name] mit dem Wert des Readings, Internals oder Attributes <li>[device:name] mit dem Wert des Readings, Internals oder Attributes
f&uuml;r device, falls sowohl device, als auch Reading, Internal oder f&uuml;r device, falls sowohl device, als auch Reading, Internal oder
Attribut existiert, und nicht leer ist. Man kann einen der Prefixe r:, i: Attribut existiert, und nicht leer ist.
oder a: verwenden, um die Suche einzuschraenken, genau wie im devspec.</li> <ul>
<li>[device:name:d] wie ohne :d, aber alles nicht-numerische wird <li>Man kann einen der Pr&auml;fixe r:, i: oder a: verwenden, um die
entfernt.</li> Suche einzuschr&auml;nken, genau wie im devspec.</li>
<li>Das Suffix :d extrahiert die erste Zahl als Ganzzahl.</li>
<li>Das Suffix :r&lt;n&gt; extrahiert die erste Zahl, und rundet sie auf
&lt;n&gt; Dezimalstellen. Falls &lt;n&gt; fehlt, dann wird auf eine
Dezimalstelle gerundet.</li>
<li>Das Suffix :t liefert den Zeitstempel des Readings</li>
<li>Das Suffix :sec liefert Anzahl der Sekunden seit &Auml;nderung
des Readings.</li>
</ul>
Beispiel:
<ul>
set Lamp blink [blinkDummy:number] [r:blinkDummy:duration:d]
</ul>
</lu>
<li>{(perlExpression)} mit dem Ergebnis der perlExpression. <li>{(perlExpression)} mit dem Ergebnis der perlExpression.
$DEV wird dabei mit dem Namen des vom set betroffenen Ger&auml;tes ersetzt. $DEV wird dabei mit dem Namen des vom set betroffenen Ger&auml;tes ersetzt.
</li> </li>
@ -1784,9 +1797,11 @@ Die folgenden lokalen Attribute werden von mehreren Ger&auml;ten verwendet:
dem &quot;Readings&quot;-Abschnitt von "list device" angezeigt wird) dem &quot;Readings&quot;-Abschnitt von "list device" angezeigt wird)
</li><br> </li><br>
<li> <li>
ReadingsNum(&lt;devicename&gt;,&lt;reading&gt;,&lt;defaultvalue&gt;)<br> ReadingsNum(&lt;devicename&gt;,&lt;reading&gt;,
Wie ReadingsVal, l&ouml;scht aber alles, was kein Zahl ist, um den Wert &lt;defaultvalue&gt;,&lt;round&gt;)<br>
bei Berechnungen verwenden zu k&ouml;nnen. Gibt die erste Zahl aus dem Readingswert zur&uuml;ck.
Falls &lt;round&gt; spezifiziert ist, wird sie auf diese Anzahl von
Dezimalstellen gerundet.
</li><br> </li><br>
<li>ReadingsTimestamp(&lt;devicename&gt;, <li>ReadingsTimestamp(&lt;devicename&gt;,
&lt;reading&gt;,&lt;defaultvalue&gt;)<br> &lt;reading&gt;,&lt;defaultvalue&gt;)<br>
@ -1798,7 +1813,7 @@ Die folgenden lokalen Attribute werden von mehreren Ger&auml;ten verwendet:
</li><br> </li><br>
<li> <li>
AttrVal(&lt;devicename&gt;,&lt;attribute&gt;,&lt;defaultvalue&gt;)<br> AttrVal(&lt;devicename&gt;,&lt;attribute&gt;,&lt;defaultvalue&gt;)<br>
Gibt die gesetzteb Attribute des Ger&auml;tes zur&uuml;ck Gibt das entsprechende Attribut des Ger&auml;tes zur&uuml;ck
<br><br> <br><br>
{ Value("wz") }<br> { Value("wz") }<br>
{ OldValue("wz") }<br> { OldValue("wz") }<br>
@ -1808,10 +1823,25 @@ Die folgenden lokalen Attribute werden von mehreren Ger&auml;ten verwendet:
{ AttrVal("wz", "room", "none") }<br> { AttrVal("wz", "room", "none") }<br>
</li><br> </li><br>
<li> <li>
InternalVal(&lt;devicename&gt;,&lt;reading&gt;,&lt;defaultvalue&gt;)<br> AttrNum(&lt;devicename&gt;,&lt;attribute&gt;,
&lt;defaultvalue&gt;,&lt;round&gt;)<br>
Gibt die erste Zahl aus dem Attributwert zur&uuml;ck.
Falls &lt;round&gt; spezifiziert ist, wird sie auf diese Anzahl von
Dezimalstellen gerundet.
</li><br>
<li>
InternalVal(&lt;devicename&gt;,&lt;internal&gt;,
&lt;defaultvalue&gt;)<br>
Gibt den Inhalt der &quot;internal&quot; zur&uuml;ck (den Inhalt der in Gibt den Inhalt der &quot;internal&quot; zur&uuml;ck (den Inhalt der in
dem &quot;Internals&quot;-Abschnitt von "list device" angezeigt wird) dem &quot;Internals&quot;-Abschnitt von "list device" angezeigt wird)
</li><br> </li><br>
<li>
InternalNum(&lt;devicename&gt;,&lt;internal&gt;,
&lt;defaultvalue&gt;,&lt;round&gt;)<br>
Gibt die erste Zahl aus dem &quot;internal&quot; zur&uuml;ck.
Falls &lt;round&gt; spezifiziert ist, wird sie auf diese Anzahl von
Dezimalstellen gerundet.
</li><br>
</ul> </ul>

View File

@ -48,6 +48,7 @@ sub AnalyzeInput($);
sub AnalyzePerlCommand($$;$); sub AnalyzePerlCommand($$;$);
sub AssignIoPort($;$); sub AssignIoPort($;$);
sub AttrVal($$$); sub AttrVal($$$);
sub AttrNum($$$;$);
sub CallFn(@); sub CallFn(@);
sub CallInstanceFn(@); sub CallInstanceFn(@);
sub CheckDuplicate($$@); sub CheckDuplicate($$@);
@ -70,6 +71,7 @@ sub HandleTimeout();
sub IOWrite($@); sub IOWrite($@);
sub InternalTimer($$$;$); sub InternalTimer($$$;$);
sub InternalVal($$$); sub InternalVal($$$);
sub InternalNum($$$;$);
sub IsDevice($;$); sub IsDevice($;$);
sub IsDisabled($); sub IsDisabled($);
sub IsDummy($); sub IsDummy($);
@ -82,7 +84,7 @@ sub OldTimestamp($);
sub OldValue($); sub OldValue($);
sub OpenLogfile($); sub OpenLogfile($);
sub PrintHash($$); sub PrintHash($$);
sub ReadingsNum($$$); sub ReadingsNum($$$;$);
sub ReadingsTimestamp($$$); sub ReadingsTimestamp($$$);
sub ReadingsVal($$$); sub ReadingsVal($$$);
sub RefreshAuthList(); sub RefreshAuthList();
@ -1660,16 +1662,28 @@ ReplaceSetMagic($$@) # Forum #38276
return $all if(!$hash); return $all if(!$hash);
if(!$t || $t eq "r:") { if(!$t || $t eq "r:") {
my $r = $hash->{READINGS}; my $r = $hash->{READINGS};
if($s && ($s eq ":t" || $s eq ":sec")) {
return $all if (!$r || !$r->{$n});
$val = $r->{$n}{TIME};
$val = time() - time_str2num($val) if($s eq ":sec");
return $val;
}
$val = $r->{$n}{VAL} if($r && $r->{$n}); $val = $r->{$n}{VAL} if($r && $r->{$n});
} }
$val = $hash->{$n} if(!defined($val) && (!$t || $t eq "i:")); $val = $hash->{$n} if(!defined($val) && (!$t || $t eq "i:"));
$val = $attr{$d}{$n} if(!defined($val) && (!$t || $t eq "a:") && $attr{$d}); $val = $attr{$d}{$n} if(!defined($val) && (!$t || $t eq "a:") && $attr{$d});
return $all if(!defined($val)); return $all if(!defined($val));
$val =~ s/[^-\.\d]//g if($s);
if($s && $val =~ /(-?\d+(\.\d+)?)/) {
$val = $1;
$s = ":r0" if($s eq ":d");
$val = round($val, defined($1) ? $1 : 1) if($s =~ /^:r(\d)?/);
}
return $val; return $val;
} }
$a=~s/(\[(.:)?([a-z0-9._]+):([a-z0-9._-]+)(:d)?\])/rsmVal($1,$2,$3,$4,$5)/egi; $a =~ s/(\[([ari]:)?([a-z0-9._]+):([a-z0-9._-]+)(:(t|sec|d|r|r\d))?\])/
rsmVal($1,$2,$3,$4,$5)/egi;
$evalSpecials->{'%DEV'} = $hash->{NAME}; $evalSpecials->{'%DEV'} = $hash->{NAME};
$a =~ s/{\((.*?)\)}/AnalyzePerlCommand($hash->{CL},$1,1)/egs; $a =~ s/{\((.*?)\)}/AnalyzePerlCommand($hash->{CL},$1,1)/egs;
@ -3938,6 +3952,16 @@ InternalVal($$$)
return $default; return $default;
} }
sub
InternalNum($$$;$)
{
my ($d,$n,$default,$round) = @_;
my $val = InternalVal($d,$n,$default);
$val = ($val =~ /(-?\d+(\.\d+)?)/ ? $1 : "");
$val = round($val,$round) if($round);
return $val;
}
sub sub
ReadingsVal($$$) ReadingsVal($$$)
{ {
@ -3952,11 +3976,12 @@ ReadingsVal($$$)
} }
sub sub
ReadingsNum($$$) ReadingsNum($$$;$)
{ {
my ($d,$n,$default) = @_; my ($d,$n,$default,$round) = @_;
my $val = ReadingsVal($d,$n,$default); my $val = ReadingsVal($d,$n,$default);
$val =~ s/[^-\.\d]//g; $val = ($val =~ /(-?\d+(\.\d+)?)/ ? $1 : "");
$val = round($val,$round) if($round);
return $val; return $val;
} }
@ -4017,6 +4042,16 @@ AttrVal($$$)
return $default; return $default;
} }
sub
AttrNum($$$;$)
{
my ($d,$n,$default,$round) = @_;
my $val = AttrVal($d,$n,$default);
$val = ($val =~ /(-?\d+(\.\d+)?)/ ? $1 : "");
$val = round($val,$round) if($round);
return $val;
}
################################################################ ################################################################
# Functions used by modules. # Functions used by modules.
sub sub