mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 12:49:34 +00:00
userReadings trigger added, code partially from Andre
git-svn-id: https://svn.fhem.de/fhem/trunk@3190 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
0258d0c84f
commit
680a785275
@ -1,7 +1,9 @@
|
|||||||
# Add changes at the top of the list. Keep it in ASCII
|
# Add changes at the top of the list. Keep it in ASCII
|
||||||
- SVN
|
- SVN
|
||||||
|
- feature: userReadings may have a filter
|
||||||
- feature: HUEBridge: allow starting of bridge firmware update
|
- feature: HUEBridge: allow starting of bridge firmware update
|
||||||
- change: EnOcean: profil PM101 changed, old profiles FAH, FBH, FTF, SR04 removed
|
- change: EnOcean: profil PM101 changed, old profiles FAH, FBH, FTF, SR04
|
||||||
|
removed
|
||||||
- feature: TCM: new attr blockSenderID:
|
- feature: TCM: new attr blockSenderID:
|
||||||
Block receiving telegrams with a TCM SenderID sent by repeaters
|
Block receiving telegrams with a TCM SenderID sent by repeaters
|
||||||
- feature: TCM: For TCM120 Transceiver now the transmission of RPS and 4BS
|
- feature: TCM: For TCM120 Transceiver now the transmission of RPS and 4BS
|
||||||
|
@ -396,29 +396,47 @@ A line ending with \ will be concatenated with the next one, so long lines
|
|||||||
|
|
||||||
<a name="userReadings"></a>
|
<a name="userReadings"></a>
|
||||||
<li>userReadings<br>
|
<li>userReadings<br>
|
||||||
A comma-separated list of definitions of user-defined readings. Each definition has the form
|
A comma-separated list of definitions of user-defined readings. Each
|
||||||
<code><reading> [<modifier>] { <perl code> }</code>. After a single or bulk
|
definition has the form:
|
||||||
readings update, the user-defined readings are set by evaluating the <a href="#perl">
|
<ul>
|
||||||
perl code</a>
|
<code>
|
||||||
<code>{ <perl code> }</code> for all definitions and setting the value of
|
<reading>[:<trigger>] [<modifier>] { <perl code> }
|
||||||
the respective user-defined reading <code><reading></code> to the result.<br><br>
|
</code>
|
||||||
Examples:<br>
|
</ul>
|
||||||
<code>attr myEnergyMeter userReadings energy { ReadingsVal("myEnergyMeter","counters.A",0)/1250.0;; }</code><br>
|
After a single or bulk readings update, the user-defined readings are set
|
||||||
<code>attr myMultiMeter userReadings energy1 { ReadingsVal("myMultiMeter","counters.A",0)/1250.0;; },
|
by evaluating the <a href="#perl">perl code</a><code> { <perl code>
|
||||||
energy2 { ReadingsVal("myMultiMeter","counters.B",0)/1250.0;; }</code>
|
}</code> for all definitions and setting the value of the respective
|
||||||
<br><br>
|
user-defined reading <code><reading></code> to the result. If
|
||||||
|
<trigger> is given, then all processing for this specific user
|
||||||
|
reading is only done if one of the just updated "reading: value"
|
||||||
|
combinations matches <trigger>, which is treated as a regexp.
|
||||||
|
<br>
|
||||||
|
Examples:<br>
|
||||||
|
<ul><code>
|
||||||
|
attr myEnergyMeter userReadings energy
|
||||||
|
{ ReadingsVal("myEnergyMeter","counters.A",0)/1250.0;; }<br>
|
||||||
|
attr myMultiMeter userReadings
|
||||||
|
energy1:counters.A { ReadingsVal("myMultiMeter","counters.A",0)/1250.0;; },
|
||||||
|
energy2:counters.B { ReadingsVal("myMultiMeter","counters.B",0)/1250.0;; }
|
||||||
|
</code></ul>
|
||||||
<code><modifier></code> can take one of these values:
|
<code><modifier></code> can take one of these values:
|
||||||
<ul>
|
<ul>
|
||||||
<li>none: the same as it would not have been given at all.</li>
|
<li>none: the same as it would not have been given at all.</li>
|
||||||
<li>difference: the reading is set to the difference between the current and the previously evaluated value.</li>
|
<li>difference: the reading is set to the difference between the current
|
||||||
<li>differential: the reading is set to the difference between the current and the previously evaluated value divided
|
and the previously evaluated value.</li>
|
||||||
by the time in seconds between the current and the previous evaluation. Granularity of time is one second. No
|
<li>differential: the reading is set to the difference between the
|
||||||
value is calculated if the time past is below one second. Useful to calculate rates.</li>
|
current and the previously evaluated value divided by the time in
|
||||||
</ul><br>
|
seconds between the current and the previous evaluation. Granularity
|
||||||
|
of time is one second. No value is calculated if the time past is
|
||||||
|
below one second. Useful to calculate rates.</li>
|
||||||
|
</ul>
|
||||||
Example:<br>
|
Example:<br>
|
||||||
<code>attr myPowerMeter userReadings power differential { ReadingsVal("myPowerMeter","counters.A",0)/1250.0;; }</code><br><br>
|
<ul><code>attr myPowerMeter userReadings power
|
||||||
Note: user readings with modifiers difference and differential store the calculated values internally. The user reading is
|
differential { ReadingsVal("myPowerMeter","counters.A",0)/1250.0;; }
|
||||||
set earliest at the second evaluation. Beware of stale values when changing definitions!
|
</code></ul>
|
||||||
|
Note: user readings with modifiers difference and differential store the
|
||||||
|
calculated values internally. The user reading is set earliest at the
|
||||||
|
second evaluation. Beware of stale values when changing definitions!
|
||||||
</li><br>
|
</li><br>
|
||||||
</ul>
|
</ul>
|
||||||
<br>
|
<br>
|
||||||
|
@ -398,31 +398,49 @@ Zeilen erstreckende Befehle, indem man keine \ am Zeilenende eingeben muss.</p>
|
|||||||
|
|
||||||
<a name="userReadings"></a>
|
<a name="userReadings"></a>
|
||||||
<li>userReadings<br>
|
<li>userReadings<br>
|
||||||
A comma-separated list of definitions of user-defined readings. Each definition has the form
|
Komma getrennte Liste von benutzerdefinierten Readings. Jede Definition hat
|
||||||
<code><reading> [<modifier>] { <perl code> }</code>. After a single or bulk
|
folgendes Format:
|
||||||
readings update, the user-defined readings are set by evaluating the <a href="#perl">
|
<ul><code>
|
||||||
perl code</a>
|
<reading>[:<trigger>] [<modifier>] { <perl code> }
|
||||||
<code>{ <perl code> }</code> for all definitions and setting the value of
|
</code></ul>
|
||||||
the respective user-defined reading <code><reading></code> to the result.<br><br>
|
Diese benutzerdefinierte Readings werden bei jeder Aktualisierung der
|
||||||
Examples:<br>
|
Gerätereadings gesetzt, indem das spezifizierte <a href="#perl">perl
|
||||||
<code>attr myEnergyMeter userReadings energy { ReadingsVal("myEnergyMeter","counters.A",0)/1250.0;; }</code><br>
|
code</a> <code>{ <perl code> }</code> ausgeführt wird, und
|
||||||
<code>attr myMultiMeter userReadings energy1 { ReadingsVal("myMultiMeter","counters.A",0)/1250.0;; },
|
dessen Wert dem Reading zugewiesen wird.
|
||||||
energy2 { ReadingsVal("myMultiMeter","counters.B",0)/1250.0;; }</code>
|
|
||||||
<br><br>
|
Falls <trigger> spezifiziert ist, dann findet diese Ausführung
|
||||||
<code><modifier></code> can take one of these values:
|
nur dann statt, falls einer der aktualisierten Readings dem regexp
|
||||||
|
<trigger> entspricht (matched). <br>
|
||||||
|
Beispiele:
|
||||||
|
<ul><code>
|
||||||
|
attr myEnergyMeter userReadings energy
|
||||||
|
{ ReadingsVal("myEnergyMeter","counters.A",0)/1250.0;; }<br>
|
||||||
|
attr myMultiMeter userReadings
|
||||||
|
energy1:counters.A {ReadingsVal("myMultiMeter","counters.A",0)/1250.0},
|
||||||
|
energy2:counters.B {ReadingsVal("myMultiMeter","counters.B",0)/1250.0}
|
||||||
|
</code></ul>
|
||||||
|
<code><modifier></code> kann die folgenden Werte haben:
|
||||||
<ul>
|
<ul>
|
||||||
<li>none: the same as it would not have been given at all.</li>
|
<li>none: als ob man es gar nicht spezifiziert hätte.</li>
|
||||||
<li>difference: the reading is set to the difference between the current and the previously evaluated value.</li>
|
<li>difference: das Reading wird auf die Differenz zw. dem aktuellen und
|
||||||
<li>differential: the reading is set to the difference between the current and the previously evaluated value divided
|
dem vorherigen Wert gesetzt.</li>
|
||||||
by the time in seconds between the current and the previous evaluation. Granularity of time is one second. No
|
<li>differential: das Reading wird auf die Differenz zw. dem aktuellen und
|
||||||
value is calculated if the time past is below one second. Useful to calculate rates.</li>
|
dem vorherigen Wert, geteilt durch die Sekunden zw. der aktuellen Zeit
|
||||||
</ul><br>
|
und der letzten Auswertung, sekundengenau. Kein Wert wird berechnet,
|
||||||
Example:<br>
|
falls der Unterschied unter eine Sekunde liegt.
|
||||||
<code>attr myPowerMeter userReadings power differential { ReadingsVal("myPowerMeter","counters.A",0)/1250.0;; }</code><br><br>
|
</li>
|
||||||
Note: user readings with modifiers difference and differential store the calculated values internally. The user reading is
|
</ul>
|
||||||
set earliest at the second evaluation. Beware of stale values when changing definitions!
|
Beispiel:
|
||||||
|
<ul><code>
|
||||||
|
attr myPowerMeter userReadings power differential
|
||||||
|
{ ReadingsVal("myPowerMeter","counters.A",0)/1250.0}
|
||||||
|
</code></ul>
|
||||||
|
Achtung: Falls difference oder differential spezifiziert ist, dann werden
|
||||||
|
für die Berechnung ältere Werte benötigt, d.h. der Wert wird
|
||||||
|
frühestens beim zweiten Änderung gesetzt.
|
||||||
</li><br>
|
</li><br>
|
||||||
|
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
32
fhem/fhem.pl
32
fhem/fhem.pl
@ -1459,7 +1459,6 @@ CommandDeleteAttr($$)
|
|||||||
$a[0] = $sdev;
|
$a[0] = $sdev;
|
||||||
|
|
||||||
if($a[1] eq "userReadings") {
|
if($a[1] eq "userReadings") {
|
||||||
#Debug "Deleting userReadings for $sdev";
|
|
||||||
delete($defs{$sdev}{'.userReadings'});
|
delete($defs{$sdev}{'.userReadings'});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1868,26 +1867,32 @@ CommandAttr($$)
|
|||||||
if($a[1] eq "userReadings") {
|
if($a[1] eq "userReadings") {
|
||||||
|
|
||||||
my %userReadings;
|
my %userReadings;
|
||||||
# myReading1 [modifier1] { codecodecode1 }, myReading2 [modifier2] { codecodecode2 }, ...
|
# myReading1[:trigger1] [modifier1] { codecodecode1 }, ...
|
||||||
my $arg= $a[2];
|
my $arg= $a[2];
|
||||||
|
|
||||||
my $regexi= '\s*(\w+)\s+((\w+)\s+)?({.*?})\s*'; # matches myReading1 { codecode1 }
|
# matches myReading1[:trigger2] { codecode1 }
|
||||||
|
my $regexi= '\s*(\w+)(:\S*)?\s+((\w+)\s+)?({.*?})\s*';
|
||||||
my $regexo= '^(' . $regexi . ')(,\s*(.*))*$';
|
my $regexo= '^(' . $regexi . ')(,\s*(.*))*$';
|
||||||
|
|
||||||
#Debug "arg is $arg";
|
#Log 1, "arg is $arg";
|
||||||
|
|
||||||
while($arg =~ /$regexo/) {
|
while($arg =~ /$regexo/) {
|
||||||
my $userReading= $2;
|
my $userReading= $2;
|
||||||
my $modifier= $4 ? $4 : "none";
|
my $trigger= $3 ? $3 : undef;
|
||||||
my $perlCode= $5;
|
my $modifier= $5 ? $5 : "none";
|
||||||
#Debug sprintf("userReading %s has perlCode %s with modifier %s",$userReading,$perlCode,$modifier);
|
my $perlCode= $6;
|
||||||
|
#Log 1, sprintf("userReading %s has perlCode %s with modifier %s%s",
|
||||||
|
# $userReading,$perlCode,$modifier,$trigger?" and trigger $trigger":"");
|
||||||
if(grep { /$modifier/ } qw(none difference differential)) {
|
if(grep { /$modifier/ } qw(none difference differential)) {
|
||||||
|
$trigger =~ s/^:// if($trigger);
|
||||||
|
$userReadings{$userReading}{trigger}= $trigger;
|
||||||
$userReadings{$userReading}{modifier}= $modifier;
|
$userReadings{$userReading}{modifier}= $modifier;
|
||||||
$userReadings{$userReading}{perlCode}= $perlCode;
|
$userReadings{$userReading}{perlCode}= $perlCode;
|
||||||
} else {
|
} else {
|
||||||
push @rets, "$sdev: unknown modifier $modifier for userReading $userReading, this userReading will be ignored";
|
push @rets, "$sdev: unknown modifier $modifier for ".
|
||||||
|
"userReading $userReading, this userReading will be ignored";
|
||||||
}
|
}
|
||||||
$arg= defined($7) ? $7 : "";
|
$arg= defined($8) ? $8 : "";
|
||||||
}
|
}
|
||||||
$hash->{'.userReadings'}= \%userReadings;
|
$hash->{'.userReadings'}= \%userReadings;
|
||||||
}
|
}
|
||||||
@ -2915,7 +2920,7 @@ addEvent($$)
|
|||||||
sub
|
sub
|
||||||
getInterfaces($) {
|
getInterfaces($) {
|
||||||
my ($hash)= @_;
|
my ($hash)= @_;
|
||||||
#Debug "getInterfaces(" . $hash->{NAME} .")= " . $hash->{internals}{interfaces};
|
#Debug "getInterfaces(" . $hash->{NAME} .")= ".$hash->{internals}{interfaces};
|
||||||
if(defined($hash->{internals}{interfaces})) {
|
if(defined($hash->{internals}{interfaces})) {
|
||||||
return split(/:/, $hash->{internals}{interfaces});
|
return split(/:/, $hash->{internals}{interfaces});
|
||||||
} else {
|
} else {
|
||||||
@ -3133,6 +3138,13 @@ readingsEndUpdate($$)
|
|||||||
if(defined($hash->{'.userReadings'})) {
|
if(defined($hash->{'.userReadings'})) {
|
||||||
my %userReadings= %{$hash->{'.userReadings'}};
|
my %userReadings= %{$hash->{'.userReadings'}};
|
||||||
foreach my $userReading (keys %userReadings) {
|
foreach my $userReading (keys %userReadings) {
|
||||||
|
|
||||||
|
my $trigger = $userReadings{$userReading}{trigger};
|
||||||
|
if(defined($trigger)) {
|
||||||
|
my @fnd = grep { $_ && $_ =~ m/^$trigger/ } @{$hash->{CHANGED}};
|
||||||
|
next if(!@fnd);
|
||||||
|
}
|
||||||
|
|
||||||
my $modifier= $userReadings{$userReading}{modifier};
|
my $modifier= $userReadings{$userReading}{modifier};
|
||||||
my $perlCode= $userReadings{$userReading}{perlCode};
|
my $perlCode= $userReadings{$userReading}{perlCode};
|
||||||
my $oldvalue= $userReadings{$userReading}{value};
|
my $oldvalue= $userReadings{$userReading}{value};
|
||||||
|
Loading…
Reference in New Issue
Block a user