fhem-mirror/FHEM/98_average.pm
rudolfkoenig 561cff81de Adding Id: to the modules
git-svn-id: https://svn.fhem.de/fhem/trunk/fhem@1098 2b470e98-0d58-463d-a4d8-8e2adae1ed80
2011-11-12 07:51:08 +00:00

131 lines
3.0 KiB
Perl

##############################################
# $Id$
# Avarage computing
package main;
use strict;
use warnings;
##########################
sub
average_Initialize($)
{
my ($hash) = @_;
$hash->{DefFn} = "average_Define";
$hash->{NotifyFn} = "average_Notify";
$hash->{AttrList} = "disable:0,1";
}
##########################
sub
average_Define($$$)
{
my ($hash, $def) = @_;
my ($name, $type, $re, $rest) = split("[ \t]+", $def, 4);
if(!$re || $rest) {
my $msg = "wrong syntax: define <name> average device[:event]";
return $msg;
}
# Checking for misleading regexps
eval { "Hallo" =~ m/^$re$/ };
return "Bad regexp: $@" if($@);
$hash->{REGEXP} = $re;
$hash->{STATE} = "active";
return undef;
}
##########################
sub
average_Notify($$)
{
my ($avg, $dev) = @_;
my $avgName = $avg->{NAME};
return "" if(AttrVal($avgName, "disable", undef));
my $devName = $dev->{NAME};
my $re = $avg->{REGEXP};
my $max = int(@{$dev->{CHANGED}});
my $tn;
my $trigger = "";
for (my $i = 0; $i < $max; $i++) {
my $s = $dev->{CHANGED}[$i];
################
# Filtering
next if(!defined($s));
my ($evName, $val) = split(" ", $s, 2); # resets $1
next if($devName !~ m/^$re$/ && "$devName:$s" !~ m/^$re$/ || $s =~ m/_avg_/);
$val = $1 if(defined($1));
next if(!defined($val) || $val !~ m/^(\d+\.?\d*)/);
$val = $1;
################
# Avg computing
$evName =~ s/[^A-Za-z_-].*//;
$tn = TimeNow() if(!$tn);
my $r = $dev->{READINGS};
my @dNow = split("[ :-]", $tn);
for(my $idx = 0; $idx <= 1; $idx++) {
my $secNow = 3600*$dNow[3] + 60*$dNow[4] + $dNow[5];
$secNow += $dNow[2]*86400 if($idx);
my $cumName = "${evName}_cum_" . ($idx ? "month" : "day");
my $avgName = "${evName}_avg_" . ($idx ? "month" : "day");
if(!$r->{$cumName}) {
$r->{$cumName}{VAL} = $secNow*$val;
$r->{$avgName}{VAL} = $val;
$r->{$cumName}{TIME} = $r->{$avgName}{TIME} = $tn;
next;
}
my @dLast = split("[ :-]", $r->{$cumName}{TIME});
my $secLast = 3600*$dLast[3] + 60*$dLast[4] + $dLast[5];
$secLast += $dLast[2]*86400 if($idx);
if($idx == 0 && ($dLast[2] == $dNow[2]) ||
$idx == 1 && ($dLast[1] == $dNow[1])) {
my $cum = $r->{$cumName}{VAL} + ($secNow-$secLast) * $val;
$r->{$cumName}{VAL} = $cum;
$r->{$avgName}{VAL} = sprintf("%0.1f", $cum/$secNow);
} else {
$trigger .= " $avgName:".$r->{$avgName}{VAL};
$r->{$cumName}{VAL} = $secNow*$val;
$r->{$avgName}{VAL} = $val;
}
$r->{$cumName}{TIME} = $r->{$avgName}{TIME} = $tn;
}
}
$addNotifyCB{"avg:$devName"} = "average_Callback $devName $trigger"
if($trigger);
return undef;
}
sub
average_Callback($)
{
my ($arg) = @_;
my ($dev, @list) = split(" ", $arg);
my $n = 0;
for(my $n = 0; $n < @list; $n++) {
my ($name, $value) = split(":", $list[$n]);
$defs{$dev}{CHANGED}[$n] = "$name: $value";
}
DoTrigger($dev, undef);
}
1;