2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-13 17:26:34 +00:00

SolarView: event-on-*-reading

git-svn-id: https://svn.fhem.de/fhem/trunk@1587 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
to-be 2012-05-26 07:06:57 +00:00
parent 7a8652f2c7
commit 32f51a02a6

View File

@ -87,7 +87,7 @@ SolarView_Initialize($)
$hash->{DefFn} = "SolarView_Define"; $hash->{DefFn} = "SolarView_Define";
$hash->{UndefFn} = "SolarView_Undef"; $hash->{UndefFn} = "SolarView_Undef";
$hash->{GetFn} = "SolarView_Get"; $hash->{GetFn} = "SolarView_Get";
$hash->{AttrList} = "loglevel:0,1,2,3,4,5"; $hash->{AttrList} = "loglevel:0,1,2,3,4,5 event-on-update-reading event-on-change-reading";
} }
sub sub
@ -107,43 +107,41 @@ SolarView_Define($$)
$hash->{Port} = $args[3]; $hash->{Port} = $args[3];
# collect the set of inverters which are to be read # collect the set of inverters which are to be read
@{$hash->{WRs2Read}} = (0); @{$hash->{Inverters}} = (0);
while ((int(@args) >= 5) && ($args[4] =~ /^[Ww][Rr](\d+)$/)) while ((int(@args) >= 5) && ($args[4] =~ /^[Ww][Rr](\d+)$/))
{ {
push @{$hash->{WRs2Read}}, $1 if int($1); push @{$hash->{Inverters}}, $1 if int($1);
splice(@args, 4, 1); splice(@args, 4, 1);
} }
# remove WR0 if exactly one inverter has been specified # remove WR0 if exactly one inverter has been specified
shift @{$hash->{WRs2Read}} if (int(@{$hash->{WRs2Read}}) == 2); shift @{$hash->{Inverters}} if (int(@{$hash->{Inverters}}) == 2);
$hash->{Interval} = int(@args) >= 5 ? int($args[4]) : 300; $hash->{Interval} = int(@args) >= 5 ? int($args[4]) : 300;
$hash->{Timeout} = int(@args) >= 6 ? int($args[5]) : 4; $hash->{Timeout} = int(@args) >= 6 ? int($args[5]) : 4;
# config variables # config variables
$hash->{Invalid} = -1; # default value for invalid readings $hash->{Invalid} = -1; # default value for invalid readings
$hash->{Sleep} = 0; # seconds to sleep before connect
$hash->{Debounce} = 50; # minimum level for debouncing (0 to disable) $hash->{Debounce} = 50; # minimum level for debouncing (0 to disable)
$hash->{Rereads} = 2; # number of retries when reading curPwr of 0 $hash->{NightOff} = 'yes'; # skip reading at night? No sun, no power :-/
$hash->{NightOff} = 'yes'; # skip connection to SV at night?
$hash->{UseSVNight} = 'yes'; # use the on/off timings from SV (else: SUNRISE_EL) $hash->{UseSVNight} = 'yes'; # use the on/off timings from SV (else: SUNRISE_EL)
$hash->{UseSVTime} = ''; # use the SV time as timestamp (else: TimeNow())
$hash->{STATE} = 'Initializing'; $hash->{STATE} = 'Initializing';
my $timenow = TimeNow(); readingsBeginUpdate($hash);
# initialization # initialization
for my $wr (@{$hash->{WRs2Read}}) for my $wr (@{$hash->{Inverters}})
{ {
$hash->{SolarView_WR($hash, 'Debounced', $wr)} = 0; $hash->{SolarView_WR($hash, 'Debounced', $wr)} = 0;
for my $get (@gets) for my $get (@gets)
{ {
$hash->{READINGS}{SolarView_WR($hash, $get, $wr)}{VAL} = $hash->{Invalid}; readingsUpdate($hash, SolarView_WR($hash, $get, $wr), $hash->{Invalid});
$hash->{READINGS}{SolarView_WR($hash, $get, $wr)}{TIME} = $timenow;
} }
} }
readingsEndUpdate($hash, $init_done);
SolarView_Update($hash); SolarView_Update($hash);
Log 2, "$hash->{NAME} will read from solarview at $hash->{Host}:$hash->{Port} " . Log 2, "$hash->{NAME} will read from solarview at $hash->{Host}:$hash->{Port} " .
@ -168,20 +166,19 @@ SolarView_Update($)
$hash->{READINGS}{currentPower}{VAL} != $hash->{Invalid}) $hash->{READINGS}{currentPower}{VAL} != $hash->{Invalid})
{ {
$hash->{STATE} = '0 W, '.$hash->{READINGS}{totalEnergyDay}{VAL}.' kWh (Night)'; $hash->{STATE} = '0 W, '.$hash->{READINGS}{totalEnergyDay}{VAL}.' kWh (Night)';
return undef; return undef;
} }
sleep($hash->{Sleep}) if $hash->{Sleep};
Log 4, "$hash->{NAME} tries to contact solarview at $hash->{Host}:$hash->{Port}"; Log 4, "$hash->{NAME} tries to contact solarview at $hash->{Host}:$hash->{Port}";
my $success = 0; my $success = 0;
my $timenow = TimeNow();
for my $wr (@{$hash->{WRs2Read}}) # loop over all inverters
for my $wr (@{$hash->{Inverters}})
{ {
my %readings = (); my %readings = ();
my $rereads = $hash->{Rereads}; my $retries = 2;
eval { eval {
local $SIG{ALRM} = sub { die 'timeout'; }; local $SIG{ALRM} = sub { die 'timeout'; };
@ -195,19 +192,16 @@ SolarView_Update($)
if ($socket and $socket->connected()) if ($socket and $socket->connected())
{ {
$socket->autoflush(1); $socket->autoflush(1);
printf $socket "%02d*\r\n", int($wr); printf $socket "%02d*\r\n", int($wr);
my $res = <$socket>; my $res = <$socket>;
close($socket); close($socket);
if ($res and $res =~ /^\{(\d\d,[\d\.,]+)\},/) if ($res and $res =~ /^\{(\d\d,[^\}]+)\},/)
{ {
my @vals = split(/,/, $1); my @vals = split(/,/, $1);
if ($hash->{UseSVTime}) readingsBeginUpdate($hash);
{
$timenow = sprintf("%04d-%02d-%02d %02d:%02d:00",
$vals[3], $vals[2], $vals[1], $vals[4], $vals[5]);
}
# parse the result from SV to dedicated values # parse the result from SV to dedicated values
for my $i (6..19) for my $i (6..19)
@ -218,11 +212,11 @@ SolarView_Update($)
} }
} }
# need to reread? # need to retry?
if ($rereads and $readings{currentPower} == 0) if ($retries > 0 and $readings{currentPower} == 0)
{ {
sleep(1); sleep(1);
$rereads = $rereads - 1; $retries = $retries - 1;
goto READ_SV; goto READ_SV;
} }
@ -240,19 +234,14 @@ SolarView_Update($)
$hash->{SolarView_WR($hash, 'Debounced', $wr)} = 0; $hash->{SolarView_WR($hash, 'Debounced', $wr)} = 0;
} }
# copy the values to the READINGS # update Readings
for my $get (@gets) for my $get (@gets)
{ {
# update and notify readings if they have changed readingsUpdate($hash, SolarView_WR($hash, $get, $wr), $readings{$get});
if ($hash->{READINGS}{SolarView_WR($hash, $get, $wr)}{VAL} != $readings{$get})
{
$hash->{READINGS}{SolarView_WR($hash, $get, $wr)}{VAL} = $readings{$get};
$hash->{READINGS}{SolarView_WR($hash, $get, $wr)}{TIME} = $timenow;
#
push @{$hash->{CHANGED}}, sprintf("%s: %s (wr%s)", $get, $readings{$get}, $wr);
}
} }
readingsEndUpdate($hash, $init_done);
alarm 0; alarm 0;
$success = 1; $success = 1;
@ -264,13 +253,9 @@ SolarView_Update($)
$hash->{STATE} = $hash->{READINGS}{currentPower}{VAL}.' W, '.$hash->{READINGS}{totalEnergyDay}{VAL}.' kWh'; $hash->{STATE} = $hash->{READINGS}{currentPower}{VAL}.' W, '.$hash->{READINGS}{totalEnergyDay}{VAL}.' kWh';
if ($success) if ($success) {
{
DoTrigger($hash->{NAME}, undef) if ($init_done);
Log 4, "$hash->{NAME} got fresh values from solarview"; Log 4, "$hash->{NAME} got fresh values from solarview";
} } else {
else
{
$hash->{STATE} .= ' (Fail)'; $hash->{STATE} .= ' (Fail)';
Log 4, "$hash->{NAME} was unable to get fresh values from solarview"; Log 4, "$hash->{NAME} was unable to get fresh values from solarview";
} }
@ -323,31 +308,30 @@ SolarView_IsNight($)
# reset totalEnergyX at midnight # reset totalEnergyX at midnight
if ($hour == 0) if ($hour == 0)
{ {
my $timenow = TimeNow(); readingsBeginUpdate($hash);
for my $wr (@{$hash->{WRs2Read}}) for my $wr (@{$hash->{Inverters}})
{ {
$hash->{READINGS}{SolarView_WR($hash, 'totalEnergyDay', $wr)}{VAL} = 0; readingsUpdate($hash, SolarView_WR($hash, 'totalEnergyDay', $wr), 0);
$hash->{READINGS}{SolarView_WR($hash, 'totalEnergyDay', $wr)}{TIME} = $timenow;
} }
#
if ($mday == 1) if ($mday == 1)
{ {
for my $wr (@{$hash->{WRs2Read}}) for my $wr (@{$hash->{Inverters}})
{ {
$hash->{READINGS}{SolarView_WR($hash, 'totalEnergyMonth', $wr)}{VAL} = 0; readingsUpdate($hash, SolarView_WR($hash, 'totalEnergyMonth', $wr), 0);
$hash->{READINGS}{SolarView_WR($hash, 'totalEnergyMonth', $wr)}{TIME} = $timenow;
} }
#
if ($mon == 0) if ($mon == 0)
{ {
for my $wr (@{$hash->{WRs2Read}}) for my $wr (@{$hash->{Inverters}})
{ {
$hash->{READINGS}{SolarView_WR($hash, 'totalEnergyYear', $wr)}{VAL} = 0; readingsUpdate($hash, SolarView_WR($hash, 'totalEnergyYear', $wr), 0);
$hash->{READINGS}{SolarView_WR($hash, 'totalEnergyYear', $wr)}{TIME} = $timenow;
} }
} }
} }
readingsEndUpdate($hash, $init_done);
} }
if ($hash->{UseSVNight}) if ($hash->{UseSVNight})
@ -393,7 +377,7 @@ SolarView_WR($$$)
{ {
my ($hash, $reading, $wr) = @_; my ($hash, $reading, $wr) = @_;
if ((int(@{$hash->{WRs2Read}}) > 1) && (int($wr) > 0)) if ((int(@{$hash->{Inverters}}) > 1) && (int($wr) > 0))
{ {
return sprintf("wr%s_%s", $wr, $reading); return sprintf("wr%s_%s", $wr, $reading);
} }