mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-03 16:56:54 +00:00
19_Revolt.pm: cumulative patch from mumpitzstuff to filter implausible
values, allow adjustment of energy value (cumulative counter in devices, can't be reset), use stateFormat instead of state reading (Forum: #71840) git-svn-id: https://svn.fhem.de/fhem/trunk@17439 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
76fa542287
commit
4617a49fb2
@ -1,5 +1,7 @@
|
||||
# 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.
|
||||
- change: 19_Revolt: allow adjustment of energy value, filtering of
|
||||
implausible values
|
||||
- bugfix: 72_XiaomiDevice: better handling of definition w/ missing token
|
||||
- change: 32_withings: add in_bed for sleep trackers, ignore inactive users
|
||||
- change: 57_Calendar: new attribute quirks with ignoreDtStamp value.
|
||||
|
@ -14,53 +14,52 @@ use Date::Parse;
|
||||
|
||||
|
||||
#####################################
|
||||
sub
|
||||
Revolt_Initialize($)
|
||||
sub Revolt_Initialize($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
|
||||
# r00C5E100303203C85921FF
|
||||
$hash->{Match} = "^r......................\$";
|
||||
$hash->{DefFn} = "Revolt_Define";
|
||||
$hash->{UndefFn} = "Revolt_Undef";
|
||||
$hash->{ParseFn} = "Revolt_Parse";
|
||||
$hash->{AttrList} = "IODev ".
|
||||
"EnergyAdjustValue ".
|
||||
$readingFnAttributes;
|
||||
}
|
||||
|
||||
#####################################
|
||||
sub
|
||||
Revolt_Define($$)
|
||||
sub Revolt_Define($$)
|
||||
{
|
||||
my ($hash, $def) = @_;
|
||||
my @a = split("[ \t][ \t]*", $def);
|
||||
|
||||
return "wrong syntax: define <name> Revolt <id>" if(int(@a) != 3);
|
||||
$a[2] = lc($a[2]);
|
||||
return "Define $a[0]: wrong <id> format: specify a 4 digit hex value"
|
||||
if($a[2] !~ m/^[a-f0-9][a-f0-9][a-f0-9][a-f0-9]$/);
|
||||
return "Define $a[0]: wrong <id> format: specify a 4 digit hex value" if($a[2] !~ m/^[a-f0-9][a-f0-9][a-f0-9][a-f0-9]$/);
|
||||
|
||||
$hash->{ID} = $a[2];
|
||||
#$hash->{STATE} = "Initialized";
|
||||
$modules{REVOLT}{defptr}{$a[2]} = $hash;
|
||||
AssignIoPort($hash);
|
||||
|
||||
my $name = $a[0];
|
||||
$attr{$name}{"event-aggregator"} = "power::none:median:120,energy::none:median:120,avgpower::none:median:120" if(!defined($attr{$name}{"event-aggregator"}));
|
||||
$attr{$name}{"stateFormat"} = "P: power E: energy V: voltage C: current Pf: pf" if(!defined($attr{$name}{"stateFormat"}));
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
#####################################
|
||||
sub
|
||||
Revolt_Undef($$)
|
||||
sub Revolt_Undef($$)
|
||||
{
|
||||
my ($hash, $name) = @_;
|
||||
delete($modules{REVOLT}{defptr}{$hash->{ID}})
|
||||
if(defined($hash->{ID}) &&
|
||||
delete($modules{REVOLT}{defptr}{$hash->{ID}}) if(defined($hash->{ID}) &&
|
||||
defined($modules{REVOLT}{defptr}{$hash->{ID}}));
|
||||
return undef;
|
||||
}
|
||||
|
||||
#####################################
|
||||
sub
|
||||
Revolt_Parse($$)
|
||||
sub Revolt_Parse($$)
|
||||
{
|
||||
my ($hash, $msg) = @_;
|
||||
|
||||
@ -76,10 +75,9 @@ Revolt_Parse($$)
|
||||
my $power = hex(substr($msg, 13, 4)) * 0.1;
|
||||
my $pf = hex(substr($msg, 17, 2)) * 0.01;
|
||||
my $energy = hex(substr($msg, 19, 4)) * 0.01;
|
||||
my $lastval;
|
||||
my $avg;
|
||||
|
||||
my $lastval = 0.0;
|
||||
my $type = "";
|
||||
my $energyAdj = $energy;
|
||||
|
||||
if(!defined($modules{REVOLT}{defptr}{$id})) {
|
||||
Log3 undef,3, "Unknown Revolt device $id, please define it";
|
||||
@ -91,38 +89,59 @@ Revolt_Parse($$)
|
||||
my $name = $def->{NAME};
|
||||
return "" if(IsIgnored($name));
|
||||
|
||||
my $state;
|
||||
$state="P: ".sprintf("%5.1f",$power)." E: ".sprintf("%6.2f",$energy)." V: ".sprintf("%3d",$voltage)." C: ".sprintf("%6.2f",$current)." F: $freq Pf: ".sprintf("%4.2f",$pf);
|
||||
# check if data is invalid
|
||||
if (defined($def->{READINGS}{".lastenergy"})) {
|
||||
$lastval = $def->{READINGS}{".lastenergy"}{VAL};
|
||||
}
|
||||
else {
|
||||
readingsSingleUpdate($def,".lastenergy", $energy, 1);
|
||||
}
|
||||
|
||||
# adjust energy value
|
||||
$energy -= AttrVal($name, "EnergyAdjustValue", 0);
|
||||
|
||||
my $isInvalid = 0;
|
||||
my $energydiff = 0;
|
||||
my $maxenergy = 0;
|
||||
|
||||
if (defined($def->{READINGS}{"energy"})) {
|
||||
my $timediff = gettimeofday() - str2time($def->{READINGS}{"energy"}{TIME});
|
||||
$energydiff = $energy - $def->{READINGS}{"energy"}{VAL};
|
||||
$maxenergy = 3.65 * ($timediff / 3600.0);
|
||||
}
|
||||
|
||||
if (0 == $pf) {
|
||||
$pf = 0.0001;
|
||||
}
|
||||
if (($freq > 55) || ($power > 3650) || ($current > 16) ||
|
||||
((($power / $voltage / $pf) > 0.00999) && (0 == $current)) ||
|
||||
($energydiff > $maxenergy)) {
|
||||
$isInvalid = 1;
|
||||
}
|
||||
|
||||
if (0 == $isInvalid) {
|
||||
#my $state = "P: ".sprintf("%5.1f", $power)." E: ".sprintf("%6.2f", $energy)." V: ".sprintf("%3d", $voltage)." C: ".sprintf("%6.2f", $current)." F: $freq Pf: ".sprintf("%4.2f", $pf);
|
||||
|
||||
readingsBeginUpdate($def);
|
||||
|
||||
if (defined($def->{READINGS}{".lastenergy"})) {
|
||||
$lastval=$def->{READINGS}{".lastenergy"}{VAL};
|
||||
if ($lastval != $energy) {
|
||||
$avg=(($lastval-$energy)*1000.0*3600.0)/(str2time($def->{READINGS}{".lastenergy"}{TIME})-gettimeofday());
|
||||
my $timediff = gettimeofday() - str2time($def->{READINGS}{".lastenergy"}{TIME});
|
||||
if (($lastval != $energy) && (($energy - $lastval) < (3.65 * ($timediff / 3600.0)))) {
|
||||
my $avg = (($energy - $lastval) * 1000.0 * 3600.0) / $timediff;
|
||||
readingsBulkUpdate($def, ".lastenergy", $energy, 1);
|
||||
readingsBulkUpdate($def, "avgpower", sprintf("%.2f", $avg), 1);
|
||||
}
|
||||
} else {
|
||||
readingsBulkUpdate($def,".lastenergy", $energy,1);
|
||||
#Log3 $def,3, "$name:timediff $timediff, lastval $lastval, energy $energy, avg $avg";
|
||||
}
|
||||
|
||||
readingsBulkUpdate($def,"state", $state,1);
|
||||
Log3 $name,4, "$name: $state";
|
||||
readingsBulkUpdate($def, "state", "active", 0);
|
||||
readingsBulkUpdate($def, "voltage", $voltage, 1);
|
||||
#Log3 $def,3, "$name:voltage $voltage";
|
||||
readingsBulkUpdate($def, "current", $current, 1);
|
||||
#Log3 $def,3, "$name:current $current";
|
||||
readingsBulkUpdate($def, "frequency", $freq, 1);
|
||||
#Log3 $def,3, "$name:frequency $freq";
|
||||
readingsBulkUpdate($def, "power", $power, 1);
|
||||
#Log3 $def,3, "$name:power $power";
|
||||
readingsBulkUpdate($def, "pf", $pf, 1);
|
||||
#Log3 $def,3, "$name:Pf $pf";
|
||||
readingsBulkUpdate($def, "energy", $energy, 1);
|
||||
#Log3 $def,3, "$name:energy $energy";
|
||||
|
||||
readingsEndUpdate($def, 1);
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
@ -150,9 +169,16 @@ Revolt_Parse($$)
|
||||
Note: devices are autocreated on reception of the first message.<br>
|
||||
</ul>
|
||||
<br>
|
||||
<a name="RevoltAttributes"></a>
|
||||
<b>Attributes</b>
|
||||
<ul>
|
||||
<li>EnergyAdjustValue: adjust the energy reading (energy = energy - EnergyAdjustValue)</li>
|
||||
</ul>
|
||||
<br>
|
||||
<a name="RevoltReadings"></a>
|
||||
<b>Readings</b>
|
||||
<ul>
|
||||
<li>avgpower [W]</li>
|
||||
<li>energy [kWh]</li>
|
||||
<li>power [W]</li>
|
||||
<li>voltage [V]</li>
|
||||
|
Loading…
x
Reference in New Issue
Block a user