2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-22 20:24:36 +00:00

98_HourCounter.pm : cyclic upate for pulse/pause time; minor changes

git-svn-id: https://svn.fhem.de/fhem/trunk@7035 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
john99sr 2014-11-21 21:55:29 +00:00
parent 6dfe6d3b00
commit dd1b612d22

View File

@ -1,4 +1,4 @@
# $Id: 98_HourCounter.pm 6802 2014-10-23 18:00:00Z john $ # $Id: 98_HourCounter.pm 7035 2014-11-21 22:00:00Z john $
#################################################################################################### ####################################################################################################
# #
# 98_HourCounter.pm # 98_HourCounter.pm
@ -45,7 +45,11 @@
# 14.11.14 - 1.0.0.5 # 14.11.14 - 1.0.0.5
# minor fixes for logging in HourCounter_Set: thanks kubuntufan # minor fixes for logging in HourCounter_Set: thanks kubuntufan
# reformating # reformating
# 17.11.14 - 1.0.0.6
# cyclic calculation of pulse/pause-duration
# correctly restores correctly counter values after restart
#################################################################################################### ####################################################################################################
package main; package main;
use strict; use strict;
use warnings; use warnings;
@ -53,8 +57,12 @@ use vars qw(%defs);
use vars qw($readingFnAttributes); use vars qw($readingFnAttributes);
use vars qw(%attr); use vars qw(%attr);
use vars qw(%modules); use vars qw(%modules);
my $HourCounter_Version = "1.0.0.5 - 14.11.2014"; my $HourCounter_Version = "1.0.0.6 - 20.11.2014";
my @HourCounter_cmdQeue = (); my @HourCounter_cmdQeue = ();
my $DEBUG = 1;
########################## ##########################
sub HourCounter_Log($$$) sub HourCounter_Log($$$)
{ {
@ -195,7 +203,8 @@ sub HourCounter_Initialize($)
$hash->{SetFn} = "HourCounter_Set"; $hash->{SetFn} = "HourCounter_Set";
$hash->{GetFn} = "HourCounter_Get"; $hash->{GetFn} = "HourCounter_Get";
$hash->{NotifyFn} = "HourCounter_Notify"; $hash->{NotifyFn} = "HourCounter_Notify";
$hash->{AttrList} = "disable:0,1 " . $readingFnAttributes; $hash->{AttrFn} = "HourCounter_Attr";
$hash->{AttrList} = "disable:0,1 interval:5,10,15,20,30,60 " . $readingFnAttributes;
HourCounter_Log "", 3, "Init Done with Version $HourCounter_Version"; HourCounter_Log "", 3, "Init Done with Version $HourCounter_Version";
} }
########################## ##########################
@ -204,7 +213,7 @@ sub HourCounter_Define($$$)
my ( $hash, $def ) = @_; my ( $hash, $def ) = @_;
my @a = split( "[ \t][ \t]*", $def ); my @a = split( "[ \t][ \t]*", $def );
my $name = $a[0]; my $name = $a[0];
HourCounter_Log $hash, 4, "parameters: @a"; HourCounter_Log $hash, ($DEBUG) ? 0 : 4, "parameters: @a";
if ( @a < 3 ) if ( @a < 3 )
{ {
return "wrong syntax: define <name> HourCounter <regexp_for_ON> [<regexp_for_OFF>]"; return "wrong syntax: define <name> HourCounter <regexp_for_ON> [<regexp_for_OFF>]";
@ -235,6 +244,8 @@ sub HourCounter_Define($$$)
@{ $hash->{helper}{cmdQueue} } = (); @{ $hash->{helper}{cmdQueue} } = ();
$modules{HourCounter}{defptr}{$name} = $hash; $modules{HourCounter}{defptr}{$name} = $hash;
RemoveInternalTimer($name); RemoveInternalTimer($name);
# wait until alle readings have been restored
InternalTimer( int( gettimeofday() + 15 ), "HourCounter_Run", $name, 0 ); InternalTimer( int( gettimeofday() + 15 ), "HourCounter_Run", $name, 0 );
return undef; return undef;
} }
@ -284,10 +295,8 @@ sub HourCounter_Set($@)
); );
# standard commands with no parameter # standard commands with no parameter
my @cmdNoPara = ( my @cmdNoPara =
"clear", "forceHourChange", "forceDayChange", "forceWeekChange", ( "clear", "forceHourChange", "forceDayChange", "forceWeekChange", "forceMonthChange", "forceYearChange", "calc" );
"forceMonthChange", "forceYearChange"
);
my @allCommands = ( @cmdPara, @cmdNoPara, @userReadings ); my @allCommands = ( @cmdPara, @cmdNoPara, @userReadings );
my $strAllCommands = my $strAllCommands =
join( " ", ( @cmdPara, @userReadings ) ) . " " . join( ":noArg ", @cmdNoPara ) . ":noArg "; join( " ", ( @cmdPara, @userReadings ) ) . " " . join( ":noArg ", @cmdNoPara ) . ":noArg ";
@ -319,8 +328,8 @@ sub HourCounter_Set($@)
# if parameter needed, it must be an integer # if parameter needed, it must be an integer
return "Value must be an integer" if ( $needPara && !( $value =~ m/$reINT/ ) ); return "Value must be an integer" if ( $needPara && !( $value =~ m/$reINT/ ) );
my $info = "command : ".$cmd; my $info = "command : " . $cmd;
$info .= " ".$value if ($needPara); $info .= " " . $value if ($needPara);
HourCounter_Log $hash, 4, $info; HourCounter_Log $hash, 4, $info;
my $doRun = ''; my $doRun = '';
if ($needPara) if ($needPara)
@ -350,11 +359,16 @@ sub HourCounter_Set($@)
{ {
$hash->{helper}{forceClear} = 1; $hash->{helper}{forceClear} = 1;
$doRun = 1; $doRun = 1;
} elsif ( $cmd eq "calc" )
{
$doRun = 1;
} else } else
{ {
return "unknown command (2): $cmd"; return "unknown command (2): $cmd";
} }
if ($doRun)
# perform run
if ( $doRun && !$hash->{helper}{isFirstRun} )
{ {
$hash->{helper}{value} = -1; $hash->{helper}{value} = -1;
$hash->{helper}{calledByEvent} = 1; $hash->{helper}{calledByEvent} = 1;
@ -376,8 +390,6 @@ sub HourCounter_Notify($$)
} }
my $onRegexp = $hash->{helper}{ON_Regexp}; my $onRegexp = $hash->{helper}{ON_Regexp};
my $offRegexp = $hash->{helper}{OFF_Regexp}; my $offRegexp = $hash->{helper}{OFF_Regexp};
#HourCounter_Log $hash,5,"Notify by DevName: ".$dev->{NAME};
my $max = int( @{ $dev->{CHANGED} } ); my $max = int( @{ $dev->{CHANGED} } );
for ( my $i = 0 ; $i < $max ; $i++ ) for ( my $i = 0 ; $i < $max ; $i++ )
{ {
@ -385,22 +397,41 @@ sub HourCounter_Notify($$)
$s = "" if ( !defined($s) ); $s = "" if ( !defined($s) );
my $isOnReading = ( "$devName:$s" =~ m/^$onRegexp$/ ); my $isOnReading = ( "$devName:$s" =~ m/^$onRegexp$/ );
my $isOffReading = ($offRegexp) ? ( "$devName:$s" =~ m/^$offRegexp$/ ) : ''; my $isOffReading = ($offRegexp) ? ( "$devName:$s" =~ m/^$offRegexp$/ ) : '';
HourCounter_Log $hash, 5,
"devName:$devName; CHANGED:$s; isOnReading:$isOnReading; isOffReading:$isOffReading;"; # HourCounter_Log $hash, 5, "devName:$devName; CHANGED:$s; isOnReading:$isOnReading; isOffReading:$isOffReading;";
next if ( !( $isOnReading || ( $isOffReading && $offRegexp ) ) ); next if ( !( $isOnReading || ( $isOffReading && $offRegexp ) ) );
$hash->{helper}{value} = 1 if ($isOnReading); $hash->{helper}{value} = 1 if ($isOnReading);
$hash->{helper}{value} = 0 if ($isOffReading); $hash->{helper}{value} = 0 if ($isOffReading);
$hash->{helper}{calledByEvent} = 1; $hash->{helper}{calledByEvent} = 1;
if ( !$hash->{helper}{isFirstRun} )
{
HourCounter_Run( $hash->{NAME} ); HourCounter_Run( $hash->{NAME} );
} }
}
}
##########################
sub HourCounter_Attr($$$$)
{
my ( $command, $name, $attribute, $value ) = @_;
my $msg = undef;
my $hash = $defs{$name};
if ( $attribute eq "interval" )
{
#HourCounter_Log $hash, 0, "cmd:$command name:$name attribute:$attribute";
if ( !$hash->{helper}{isFirstRun} )
{
HourCounter_Run($name);
}
}
return $msg;
} }
########################## ##########################
# converts the seconds in the date format # converts the seconds in the date format
sub HourCounter_Seconds2HMS($) sub HourCounter_Seconds2HMS($)
{ {
my ($seconds) = @_; my ($seconds) = @_;
my ( $Sekunde, $Minute, $Stunde, $Monatstag, $Monat, $Jahr, $Wochentag, $Jahrestag, $Sommerzeit ) my ( $Sekunde, $Minute, $Stunde, $Monatstag, $Monat, $Jahr, $Wochentag, $Jahrestag, $Sommerzeit ) =
= localtime($seconds); localtime($seconds);
my $days = int( $seconds / 86400 ); my $days = int( $seconds / 86400 );
return sprintf( "%d Tage %02d:%02d:%02d", $days, $Stunde - 1, $Minute, $Sekunde ); return sprintf( "%d Tage %02d:%02d:%02d", $days, $Stunde - 1, $Minute, $Sekunde );
} }
@ -419,26 +450,46 @@ sub HourCounter_weekBase($)
return $c; return $c;
} }
########################## ##########################
# this either called by timer for cyclic update
# or it is called by an event (on/off)
sub HourCounter_Run($) sub HourCounter_Run($)
{ {
# print "xxx TAG A\n" ; # print "xxx TAG A\n" ;
my ($name) = @_; my ($name) = @_;
my $hash = $defs{$name}; my $hash = $defs{$name};
# must be of type hourcounter
return if ( !defined( $hash->{TYPE} ) || $hash->{TYPE} ne 'HourCounter' ); return if ( !defined( $hash->{TYPE} ) || $hash->{TYPE} ne 'HourCounter' );
delete( $hash->{CHANGETIME} ); # timestamps for event-log-file-entries older, than current time
# timestamps for event-log-file-entries, older than current time
delete( $hash->{CHANGETIME} );
# flag for called by event
my $calledByEvent = $hash->{helper}{calledByEvent}; my $calledByEvent = $hash->{helper}{calledByEvent};
# reset flag
$hash->{helper}{calledByEvent} = ''; $hash->{helper}{calledByEvent} = '';
# if call was made by timer force value to -1 # if call was made by timer, than force value to -1
my $valuePara = ($calledByEvent) ? $hash->{helper}{value} : -1; my $valuePara = ($calledByEvent) ? $hash->{helper}{value} : -1;
# initialize changedTimestamp, if it does not exist
$hash->{helper}{changedTimestamp} = ReadingsTimestamp( $name, "value", TimeNow() ) $hash->{helper}{changedTimestamp} = ReadingsTimestamp( $name, "value", TimeNow() )
if ( !$hash->{helper}{changedTimestamp} ); if ( !$hash->{helper}{changedTimestamp} );
# serial date for changed timestamp
my $sdValue = time_str2num( $hash->{helper}{changedTimestamp} ); my $sdValue = time_str2num( $hash->{helper}{changedTimestamp} );
my $sdCurTime = gettimeofday(); my $sdCurTime = gettimeofday();
my $isOffDefined = ( $hash->{helper}{OFF_Regexp} ) ? 1 : ''; my $isOffDefined = ( $hash->{helper}{OFF_Regexp} ) ? 1 : '';
my $timeIncrement = int( $sdCurTime - $sdValue ); # time diff
$timeIncrement = 0 if ( $timeIncrement < 0 ); # wrong time offset in case of summer/winter time # calc time diff
my $valueOld = ReadingsVal( $name, 'value', 0 ); # get the old value my $timeIncrement = int( $sdCurTime - $sdValue );
# wrong time offset in case of summer/winter time
$timeIncrement = 0 if ( $timeIncrement < 0 );
# get the old value
my $valueOld = ReadingsVal( $name, 'value', 0 );
# variable for reading update # variable for reading update
my $value = undef; my $value = undef;
@ -451,28 +502,42 @@ sub HourCounter_Run($)
my $pauseTimeOverall = undef; my $pauseTimeOverall = undef;
my $pauseTimeIncrement = undef; my $pauseTimeIncrement = undef;
my $state = undef; my $state = undef;
my $clearDate = undef; my $doUpdate = undef;
my $fireEvents = 1;
my $sdTickHour = time_str2num( ReadingsTimestamp( $name, "tickHour", TimeNow() ) );
# serial date for current hour
my $sdRoundHour = HourCounter_RoundHour($sdCurTime); my $sdRoundHour = HourCounter_RoundHour($sdCurTime);
my $sdRoundHourLast = $hash->{helper}{sdRoundHourLast};
#my $sdRoundHourLast = $hash->{helper}{sdRoundHourLast};
my $sdRoundHourLast = HourCounter_RoundHour($sdTickHour);
$sdRoundHourLast = $sdRoundHour if ( !$sdRoundHourLast ); $sdRoundHourLast = $sdRoundHour if ( !$sdRoundHourLast );
my $isHourChanged = ( $sdRoundHour != $sdRoundHourLast ) || $hash->{helper}{forceHourChange}; my $isHourChanged = ( $sdRoundHour != $sdRoundHourLast ) || $hash->{helper}{forceHourChange};
# serial date for current day
my $sdRoundDayCurTime = HourCounter_RoundDay($sdCurTime); my $sdRoundDayCurTime = HourCounter_RoundDay($sdCurTime);
my $sdRoundDayValue = HourCounter_RoundDay($sdRoundHourLast); my $sdRoundDayValue = HourCounter_RoundDay($sdRoundHourLast);
my $isDayChanged = ( $sdRoundDayCurTime != $sdRoundDayValue ) || $hash->{helper}{forceDayChange}; my $isDayChanged = ( $sdRoundDayCurTime != $sdRoundDayValue ) || $hash->{helper}{forceDayChange};
# serial date for current week
my $sdRoundWeekCurTime = HourCounter_RoundWeek($sdCurTime); my $sdRoundWeekCurTime = HourCounter_RoundWeek($sdCurTime);
my $sdRoundWeekValue = HourCounter_RoundWeek($sdRoundHourLast); my $sdRoundWeekValue = HourCounter_RoundWeek($sdRoundHourLast);
my $isWeekChanged = my $isWeekChanged =
( $sdRoundWeekCurTime != $sdRoundWeekValue ) || $hash->{helper}{forceWeekChange}; ( $sdRoundWeekCurTime != $sdRoundWeekValue ) || $hash->{helper}{forceWeekChange};
# serial date for current month
my $sdRoundMonthCurTime = HourCounter_RoundMonth($sdCurTime); my $sdRoundMonthCurTime = HourCounter_RoundMonth($sdCurTime);
my $sdRoundMonthValue = HourCounter_RoundMonth($sdRoundHourLast); my $sdRoundMonthValue = HourCounter_RoundMonth($sdRoundHourLast);
my $isMonthChanged = my $isMonthChanged =
( $sdRoundMonthCurTime != $sdRoundMonthValue ) || $hash->{helper}{forceMonthChange}; ( $sdRoundMonthCurTime != $sdRoundMonthValue ) || $hash->{helper}{forceMonthChange};
# serial date for current year
my $sdRoundYearCurTime = HourCounter_RoundYear($sdCurTime); my $sdRoundYearCurTime = HourCounter_RoundYear($sdCurTime);
my $sdRoundYearValue = HourCounter_RoundYear($sdRoundHourLast); my $sdRoundYearValue = HourCounter_RoundYear($sdRoundHourLast);
my $isYearChanged = my $isYearChanged =
( $sdRoundYearCurTime != $sdRoundYearValue ) || $hash->{helper}{forceYearChange}; ( $sdRoundYearCurTime != $sdRoundYearValue ) || $hash->{helper}{forceYearChange};
#HourCounter_Log $hash, 0,"sdRoundYearCurTime : $sdRoundYearCurTime"; # loop forever
while (1) while (1)
{ {
# stop if disabled # stop if disabled
@ -480,54 +545,73 @@ sub HourCounter_Run($)
# variables for controlling # variables for controlling
my $resetDayCounter = ''; my $resetDayCounter = '';
HourCounter_Log $hash, 5, HourCounter_Log $hash, 5, "value:$valuePara changedTimestamp:" . $hash->{helper}{changedTimestamp};
"value:$valuePara changedTimestamp:" . $hash->{helper}{changedTimestamp};
# --------------- basic init after startup of fhem or reload # ------------ basic init, when first run
if ( $hash->{helper}{isFirstRun} ) if ( $hash->{helper}{isFirstRun} )
{ {
$hash->{helper}{isFirstRun} = undef; $hash->{helper}{isFirstRun} = undef;
$hash->{helper}{sdRoundHourLast} = $sdRoundHourLast; $hash->{helper}{sdRoundHourLast} = $sdRoundHourLast;
HourCounter_Log $hash, 4, "first run done";
}
# ------------ basic init, when first run after initial definition in fhem.cfg # first init after startup
if ( !defined( ReadingsVal( $name, 'value', undef ) ) || $hash->{helper}{forceClear} )
{
HourCounter_Log $hash, 4,
"counters cleared "
. "forceClear:$hash->{helper}{forceClear}"
. " def(valueOld)"
. defined($valueOld);
if ( !defined($valueOld) )
{ # create readings without triggering
readingsBeginUpdate($hash); readingsBeginUpdate($hash);
readingsBulkUpdate( $hash, 'tickHour', 0 ); readingsBulkUpdate( $hash, 'tickHour', 0 );
readingsBulkUpdate( $hash, 'tickDay', 0 ); readingsBulkUpdate( $hash, 'tickDay', 0 );
readingsBulkUpdate( $hash, 'tickWeek', 0 ); readingsBulkUpdate( $hash, 'tickWeek', 0 );
readingsBulkUpdate( $hash, 'tickMonth', 0 ); readingsBulkUpdate( $hash, 'tickMonth', 0 );
readingsEndUpdate( $hash, 1 ); readingsBulkUpdate( $hash, 'tickYear', 0 );
} readingsEndUpdate( $hash, 0 );
if ( !( $hash->{helper}{forceClear} ) ) # set value at basic init
{ # set initial values
$valueOld = 0; $value = $valueOld; # value als reading anlegen falls nicht vorhanden
$value = 0; $countsOverall = ReadingsVal( $name, "countsOverall", 0 );
} $countsPerDay = ReadingsVal( $name, "countsPerDay", 0 );
$pauseTimeIncrement = ReadingsVal( $name, "pauseTimeIncrement", 0 );
$pauseTimeOverall = ReadingsVal( $name, "pauseTimeOverall", 0 );
$pauseTimePerDay = ReadingsVal( $name, "pauseTimePerDay", 0 );
$pulseTimeIncrement = ReadingsVal( $name, "pulseTimeIncrement", 0 );
$pulseTimeOverall = ReadingsVal( $name, "pulseTimeOverall", 0 );
$pulseTimePerDay = ReadingsVal( $name, "pulseTimePerDay", 0 );
$state = ReadingsVal( $name, "state", 0 );
$timeIncrement = 0; $timeIncrement = 0;
$hash->{helper}{forceClear} = '';
$countsPerDay = 0; # do not fire any events, if first initialization
$countsOverall = 0; $fireEvents = 0;
$pulseTimeIncrement = 0; HourCounter_Log $hash, 0, "first run done countsOverall:" . $countsOverall; #4
$pulseTimePerDay = 0;
$pulseTimeOverall = 0;
$pauseTimeIncrement = 0;
$pauseTimePerDay = 0;
$pauseTimeOverall = 0;
$state = 0;
$clearDate = TimeNow();
} }
# ------------------------- handling of transitions # -------- force clear reqeust
if ( $hash->{helper}{forceClear} )
{
# 4
HourCounter_Log $hash, 0, "force cleare request";
# fire only this event
readingsSingleUpdate( $hash, 'clearDate', TimeNow(), 1 );
# reset all counters
$countsOverall = 0;
$countsPerDay = 0;
$pauseTimeIncrement = 0;
$pauseTimeOverall = 0;
$pauseTimePerDay = 0;
$pulseTimeIncrement = 0;
$pulseTimeOverall = 0;
$pulseTimePerDay = 0;
$hash->{helper}{forceClear} = '';
$timeIncrement = 0;
# do not fire any events, if first initialization
$fireEvents = 0;
}
# -------------- handling of transitions
my $hasValueChanged = ( $isOffDefined && $valuePara == $valueOld ) ? '' : 1; my $hasValueChanged = ( $isOffDefined && $valuePara == $valueOld ) ? '' : 1;
# -------------- positive edge # -------------- positive edge
@ -538,9 +622,11 @@ sub HourCounter_Run($)
$valueOld = $valuePara; $valueOld = $valuePara;
# handling of counters # handling of counters
$countsPerDay = ReadingsVal( $name, "countsPerDay", 0 ) + 1; # counter inkrementieren $countsPerDay = ReadingsVal( $name, "countsPerDay", 0 ) + 1;
$countsOverall = ReadingsVal( $name, "countsOverall", 0 ) + 1; # counter inkrementieren $countsOverall = ReadingsVal( $name, "countsOverall", 0 ) + 1;
if ($isOffDefined) # handling of pause
#.. handling of pause
if ($isOffDefined)
{ {
$pauseTimeIncrement = $timeIncrement; $pauseTimeIncrement = $timeIncrement;
$pauseTimePerDay = ReadingsVal( $name, "pauseTimePerDay", 0 ) + $pauseTimeIncrement; $pauseTimePerDay = ReadingsVal( $name, "pauseTimePerDay", 0 ) + $pauseTimeIncrement;
@ -564,61 +650,65 @@ sub HourCounter_Run($)
HourCounter_Log $hash, 4, "falling edge pulseTimeIncrement:$pulseTimeIncrement"; HourCounter_Log $hash, 4, "falling edge pulseTimeIncrement:$pulseTimeIncrement";
} }
# --------------- Day change, update pauseTime and pulseTime # --------------- no change
if ($isDayChanged) elsif ( $valuePara == -1 )
{ {
HourCounter_Log $hash, 4, "day change isDayChanged:$isDayChanged"; $doUpdate = 1;
HourCounter_Log $hash, 4, "force update";
}
# --------------- Day change, update pauseTime and pulseTime
if ( $isDayChanged || $doUpdate )
{
HourCounter_Log $hash, 4, "day change isDayChanged:$isDayChanged" if ($isDayChanged);
### accumulate incurred times until day change ### accumulate incurred times until day change
if ( $valueOld == 0 ) if ( $valueOld == 0 )
{ {
$pauseTimeIncrement = $timeIncrement; # update only,if not already defined (e.g. by clear)
$pauseTimePerDay = ReadingsVal( $name, "pauseTimePerDay", 0 ) + $timeIncrement; $pauseTimeIncrement = $timeIncrement if ( !defined($pauseTimeIncrement) );
$pauseTimeOverall = ReadingsVal( $name, "pauseTimeOverall", 0 ) + $timeIncrement; $pauseTimePerDay = ReadingsVal( $name, "pauseTimePerDay", 0 ) + $timeIncrement
if ( !defined($pauseTimePerDay) );
$pauseTimeOverall = ReadingsVal( $name, "pauseTimeOverall", 0 ) + $timeIncrement
if ( !defined($pauseTimeOverall) );
} elsif ( $valueOld == 1 ) } elsif ( $valueOld == 1 )
{ {
$pulseTimeIncrement = $timeIncrement; # update only,if not already defined
$pulseTimePerDay = ReadingsVal( $name, "pulseTimePerDay", 0 ) + $timeIncrement; $pulseTimeIncrement = $timeIncrement if ( !defined($pulseTimeIncrement) );
$pulseTimeOverall = ReadingsVal( $name, "pulseTimeOverall", 0 ) + $timeIncrement; $pulseTimePerDay = ReadingsVal( $name, "pulseTimePerDay", 0 ) + $timeIncrement
if ( !defined($pulseTimePerDay) );
$pulseTimeOverall = ReadingsVal( $name, "pulseTimeOverall", 0 ) + $timeIncrement
if ( !defined($pulseTimeOverall) );
} }
# update timestamp of reading value with current time # update timestamp of reading value with current time
$hash->{helper}{changedTimestamp} = TimeNow(); $hash->{helper}{changedTimestamp} = TimeNow();
if ($isDayChanged)
# logabriss vermeiden {
$pulseTimeIncrement = ReadingsVal( $name, "pulseTimeIncrement", 0 ) # reset daycounter in case of daychange
if ( !defined($pulseTimeIncrement) );
$pulseTimeOverall = ReadingsVal( $name, "pulseTimeOverall", 0 )
if ( !defined($pulseTimeOverall) );
$pauseTimeIncrement = ReadingsVal( $name, "pauseTimeIncrement", 0 )
if ( !defined($pauseTimeIncrement) );
$pauseTimeOverall = ReadingsVal( $name, "pauseTimeOverall", 0 )
if ( !defined($pauseTimeOverall) );
$countsOverall = ReadingsVal( $name, "countsOverall", 0 ) if ( !defined($countsOverall) );
$value = $valueOld;
HourCounter_Log $hash, 4,
"pulseTimeIncrement:$pulseTimeIncrement pauseTimeIncrement:$pauseTimeIncrement";
$resetDayCounter = 1; $resetDayCounter = 1;
} }
#.. set value
$value = $valueOld;
}
# set state
$state = $countsPerDay $state = $countsPerDay
if ( defined($countsPerDay) && ReadingsVal( $name, "state", 0 ) != $countsPerDay ); if ( defined($countsPerDay) && ReadingsVal( $name, "state", 0 ) != $countsPerDay );
### -------------- update readings
# ---------update readings, if vars defined
readingsBeginUpdate($hash); readingsBeginUpdate($hash);
readingsBulkUpdate( $hash, "countsPerDay", $countsPerDay ) if defined($countsPerDay); readingsBulkUpdate( $hash, "countsPerDay", $countsPerDay ) if defined($countsPerDay);
readingsBulkUpdate( $hash, "countsOverall", $countsOverall ) if defined($countsOverall); readingsBulkUpdate( $hash, "countsOverall", $countsOverall ) if defined($countsOverall);
readingsBulkUpdate( $hash, "pulseTimeIncrement", $pulseTimeIncrement ) readingsBulkUpdate( $hash, "pulseTimeIncrement", $pulseTimeIncrement ) if defined($pulseTimeIncrement);
if defined($pulseTimeIncrement);
readingsBulkUpdate( $hash, "pulseTimePerDay", $pulseTimePerDay ) if defined($pulseTimePerDay); readingsBulkUpdate( $hash, "pulseTimePerDay", $pulseTimePerDay ) if defined($pulseTimePerDay);
readingsBulkUpdate( $hash, "pulseTimeOverall", $pulseTimeOverall ) readingsBulkUpdate( $hash, "pulseTimeOverall", $pulseTimeOverall ) if defined($pulseTimeOverall);
if defined($pulseTimeOverall); readingsBulkUpdate( $hash, "pauseTimeIncrement", $pauseTimeIncrement ) if defined($pauseTimeIncrement);
readingsBulkUpdate( $hash, "pauseTimeIncrement", $pauseTimeIncrement )
if defined($pauseTimeIncrement);
readingsBulkUpdate( $hash, "pauseTimePerDay", $pauseTimePerDay ) if defined($pauseTimePerDay); readingsBulkUpdate( $hash, "pauseTimePerDay", $pauseTimePerDay ) if defined($pauseTimePerDay);
readingsBulkUpdate( $hash, "pauseTimeOverall", $pauseTimeOverall ) readingsBulkUpdate( $hash, "pauseTimeOverall", $pauseTimeOverall ) if defined($pauseTimeOverall);
if defined($pauseTimeOverall);
readingsBulkUpdate( $hash, "value", $value ) if defined($value); readingsBulkUpdate( $hash, "value", $value ) if defined($value);
readingsBulkUpdate( $hash, 'state', $state ) if defined($state); readingsBulkUpdate( $hash, 'state', $state ) if defined($state);
readingsBulkUpdate( $hash, 'clearDate', $clearDate ) if defined($clearDate); readingsEndUpdate( $hash, $fireEvents );
readingsEndUpdate( $hash, 1 );
# --------------- fire time interval ticks for hour,day,month # --------------- fire time interval ticks for hour,day,month
if ($isHourChanged) if ($isHourChanged)
@ -664,17 +754,23 @@ sub HourCounter_Run($)
readingsBulkUpdate( $hash, "pulseTimePerDay", 0 ); readingsBulkUpdate( $hash, "pulseTimePerDay", 0 );
readingsBulkUpdate( $hash, "pauseTimePerDay", 0 ); readingsBulkUpdate( $hash, "pauseTimePerDay", 0 );
readingsEndUpdate( $hash, 1 ); readingsEndUpdate( $hash, 1 );
HourCounter_Log $hash, 4, "reset day counters";
} }
last; last;
} }
# ------------ calculate seconds until next hour starts # ------------ calculate seconds until next hour starts
my $interval = AttrVal( $name, 'interval', '60' );
my $actTime = int( gettimeofday() ); my $actTime = int( gettimeofday() );
my ( $sec, $min, $hour ) = localtime($actTime); my ( $sec, $min, $hour ) = localtime($actTime);
my $nextHourTime = int( ( $actTime + 3600 ) / 3600 ) * 3600; # round to next hour start
# round to next interval
my $seconds = $interval * 60;
my $nextHourTime = int( ( $actTime + $seconds ) / $seconds ) * $seconds;
# calc diff in seconds
my $nextCall = $nextHourTime - $actTime; my $nextCall = $nextHourTime - $actTime;
HourCounter_Log $hash, 5, HourCounter_Log $hash, 5, "nextCall:$nextCall changedTimestamp:" . $hash->{helper}{changedTimestamp};
"nextCall:$nextCall changedTimestamp:" . $hash->{helper}{changedTimestamp};
RemoveInternalTimer($name); RemoveInternalTimer($name);
InternalTimer( gettimeofday() + $nextCall, "HourCounter_Run", $hash->{NAME}, 0 ); InternalTimer( gettimeofday() + $nextCall, "HourCounter_Run", $hash->{NAME}, 0 );
return undef; return undef;
@ -720,6 +816,12 @@ sub HourCounter_Run($)
<a name="HourCounterset"></a> <a name="HourCounterset"></a>
<b>Set-Commands</b> <b>Set-Commands</b>
<ul> <ul>
<br/>
<code>set &lt;name&gt; calc</code>
<br/><br/>
<ul>
starts the calculation of pulse/pause-time.<br/>
</ul><br/>
<br/> <br/>
<code>set &lt;name&gt; clear</code> <code>set &lt;name&gt; clear</code>
@ -825,6 +927,7 @@ sub HourCounter_Run($)
<a name="HourCounterattr"></a> <a name="HourCounterattr"></a>
<b>Attributes</b><br/><br/> <b>Attributes</b><br/><br/>
<ul> <ul>
<li><b>interval</b> <br/> the update interval for pulse/pause-time in minutes [default 60]</li>
<li><a href="#readingFnAttributes">readingFnAttributes</a></li> <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
</ul> </ul>
<br/> <br/>