mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-03 16:56:54 +00:00
98_HourCounter : new module
git-svn-id: https://svn.fhem.de/fhem/trunk@6802 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
12d480e8e5
commit
900c655224
@ -1,5 +1,6 @@
|
||||
# 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.
|
||||
- feature: new module 98_HourCounter added, 99_UtilsHourCounter.pm added to contrib (john)
|
||||
- added: MYSENSORS: connect to serial or Ethernet MySensors Gateway
|
||||
- added: MYSENSORS_DEVICE: represent a MySensors sensor- or actor node
|
||||
- feature: global ATTR/DELETEATTR/MODIFIED events
|
||||
|
930
fhem/FHEM/98_HourCounter.pm
Normal file
930
fhem/FHEM/98_HourCounter.pm
Normal file
@ -0,0 +1,930 @@
|
||||
# $Id: 98_HourCounter.pm 6802 2014-10-23 18:00:00Z john $
|
||||
####################################################################################################
|
||||
#
|
||||
# 98_HourCounter.pm
|
||||
# The HourCounter accumulates single events to a counter object.
|
||||
# In the case of binary weighted events pulse- and pause-time are determined
|
||||
#
|
||||
# This module is written by john.
|
||||
#
|
||||
# This file is part of fhem.
|
||||
#
|
||||
# Fhem is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Fhem is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with fhem. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
#
|
||||
# 16.11.13 - 0.99.b
|
||||
# Loglevel adjusted
|
||||
# 02.12.13 - 0.99.c
|
||||
# $readingFnAttributes added
|
||||
# 03.12.13 - 0.99.d
|
||||
# missed attribute event-on-change-reading
|
||||
# 02.02.14 - 1.00
|
||||
# command queues
|
||||
# 04.02.14 - 1.01
|
||||
# queue removed
|
||||
# 17.03.14 - 1.02
|
||||
# adjusting log-levels, forceYearChange,HourCounter_RoundYear
|
||||
# 07.06.14 - 1.03
|
||||
# $ID changed
|
||||
# setter for pulseTimeIncrement, pauseTimeIncrement
|
||||
# 25.10.14 - 1.0.0.4
|
||||
# official part of fhem
|
||||
# adjusting log-output
|
||||
# update documentation
|
||||
|
||||
|
||||
####################################################################################################
|
||||
package main;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use vars qw(%defs);
|
||||
use vars qw($readingFnAttributes);
|
||||
use vars qw(%attr);
|
||||
use vars qw(%modules);
|
||||
|
||||
my $HourCounter_Version="1.0.0.4 - 23.10.2014";
|
||||
|
||||
my @HourCounter_cmdQeue =();
|
||||
|
||||
##########################
|
||||
sub HourCounter_Log($$$)
|
||||
{
|
||||
my ( $hash, $loglevel, $text ) = @_;
|
||||
my $xline = (caller(0))[2];
|
||||
|
||||
my $xsubroutine = (caller(1))[3];
|
||||
my $sub = (split( ':', $xsubroutine ))[2];
|
||||
$sub =~ s/HourCounter_//;
|
||||
|
||||
my $instName = ( ref($hash) eq "HASH" ) ? $hash->{NAME} : "HourCounter";
|
||||
Log3 $hash, $loglevel, "HourCounter $instName $sub.$xline " . $text;
|
||||
}
|
||||
|
||||
##########################
|
||||
sub HourCounter_AddLog($$$)
|
||||
{
|
||||
my ($logdevice, $readingName,$value) = @_;
|
||||
|
||||
my $cmd='';
|
||||
if ($readingName =~ m,state,i)
|
||||
{
|
||||
$cmd="trigger $logdevice $value << addLog";
|
||||
}
|
||||
else
|
||||
{
|
||||
$cmd="trigger $logdevice $readingName: $value << addLog";
|
||||
}
|
||||
|
||||
HourCounter_Log '',3,$cmd;
|
||||
fhem ($cmd);
|
||||
}
|
||||
|
||||
##########################
|
||||
# execute the content of the given parameter
|
||||
sub HourCounter_Exec($)
|
||||
{
|
||||
my $doit = shift;
|
||||
my $ret='';
|
||||
eval $doit;
|
||||
$ret = $@ if ($@);
|
||||
return $ret;
|
||||
}
|
||||
##########################
|
||||
# add command to queue
|
||||
sub HourCounter_cmdQueueAdd($$)
|
||||
{
|
||||
my ($hash,$cmd)= @_;
|
||||
push(@{$hash->{helper}{cmdQueue}},$cmd);
|
||||
}
|
||||
|
||||
##########################
|
||||
# execute command queue
|
||||
sub HourCounter_ExecQueue($)
|
||||
{
|
||||
my ($hash)=@_;
|
||||
my $result;
|
||||
|
||||
my $cnt=$#{$hash->{helper}{cmdQueue}};
|
||||
my $loops =0;
|
||||
my $cntAll=0;
|
||||
|
||||
HourCounter_Log $hash,4,"cnt: $cnt";
|
||||
|
||||
while ($cnt>=0)
|
||||
{
|
||||
for my $i (0 .. $cnt)
|
||||
{
|
||||
my $cmd = ${$hash->{helper}{cmdQueue}}[$i];
|
||||
${$hash->{helper}{cmdQueue}}[$i]='';
|
||||
$result=HourCounter_Exec($cmd);
|
||||
if ($result)
|
||||
{
|
||||
HourCounter_Log $hash,2,"$result";
|
||||
}
|
||||
else {
|
||||
HourCounter_Log $hash,4,"exec ok:$cmd";
|
||||
}
|
||||
$cntAll++;
|
||||
}
|
||||
|
||||
# bearbeitete eintraege loeschen
|
||||
for (my $i = $cnt; $i > -1; $i--)
|
||||
{
|
||||
splice (@{$hash->{helper}{cmdQueue}}, $i, 1)
|
||||
}
|
||||
|
||||
$cnt=$#HourCounter_cmdQeue;
|
||||
$loops++;
|
||||
if ($loops >= 5 || $cntAll>100)
|
||||
{
|
||||
HourCounter_Log $hash,2, "!!! too deep recursion";
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
##########################
|
||||
# round off the date passed to the hour
|
||||
sub HourCounter_RoundHour($)
|
||||
{
|
||||
my ($sec,$min,$hour,$mday,$mon,$year) = localtime(shift);
|
||||
return mktime(0, 0, $hour, $mday, $mon, $year);
|
||||
}
|
||||
|
||||
##########################
|
||||
# round off the date passed to the day
|
||||
sub HourCounter_RoundDay($)
|
||||
{
|
||||
my ($sec,$min,$hour,$mday,$mon,$year) = localtime(shift);
|
||||
return mktime(0, 0, 0, $mday, $mon, $year);
|
||||
}
|
||||
|
||||
##########################
|
||||
# round off the date passed to the week
|
||||
sub HourCounter_RoundWeek($)
|
||||
{
|
||||
my ($time) = @_;
|
||||
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time);
|
||||
# wday 0 Sonntag 1 Montag ...
|
||||
$time-=$wday * 86400;
|
||||
return HourCounter_RoundDay($time);
|
||||
}
|
||||
|
||||
##########################
|
||||
# returns the seconds since the start of the day
|
||||
sub HourCounter_SecondsOfDay()
|
||||
{
|
||||
my $timeToday = gettimeofday();
|
||||
return int($timeToday - HourCounter_RoundDay($timeToday));
|
||||
}
|
||||
|
||||
##########################
|
||||
# round off the date passed to the month
|
||||
sub HourCounter_RoundMonth($)
|
||||
{
|
||||
my ($sec,$min,$hour,$mday,$mon,$year) = localtime(shift);
|
||||
return mktime(0, 0, 0, 1, $mon, $year);
|
||||
}
|
||||
##########################
|
||||
# round off the date passed to the year
|
||||
sub HourCounter_RoundYear($)
|
||||
{
|
||||
my ($sec,$min,$hour,$mday,$mon,$year) = localtime(shift);
|
||||
return mktime(0, 0, 0, 1, 1, $year);
|
||||
}
|
||||
|
||||
##########################
|
||||
sub HourCounter_Initialize($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
$hash->{DefFn} = "HourCounter_Define";
|
||||
$hash->{UndefFn} = "HourCounter_Undef";
|
||||
|
||||
$hash->{SetFn} = "HourCounter_Set";
|
||||
$hash->{GetFn} = "HourCounter_Get";
|
||||
$hash->{NotifyFn} = "HourCounter_Notify";
|
||||
$hash->{AttrList} = "disable:0,1 ". $readingFnAttributes;
|
||||
|
||||
HourCounter_Log "", 3, "Init Done with Version $HourCounter_Version";
|
||||
}
|
||||
|
||||
##########################
|
||||
sub HourCounter_Define($$$)
|
||||
{
|
||||
my ( $hash, $def ) = @_;
|
||||
my @a = split( "[ \t][ \t]*", $def );
|
||||
my $name = $a[0];
|
||||
HourCounter_Log $hash, 4, "parameters: @a";
|
||||
if ( @a < 3 )
|
||||
{
|
||||
return "wrong syntax: define <name> HourCounter <regexp_for_ON> [<regexp_for_OFF>]";
|
||||
}
|
||||
my $onRegexp = $a[2];
|
||||
|
||||
my $offRegexp = (@a==4)?$a[3]:undef;
|
||||
|
||||
# Checking for misleading regexps
|
||||
eval { "Hallo" =~ m/^$onRegexp/ };
|
||||
return "Bad regexp_for_ON : $@" if ($@);
|
||||
if ($offRegexp)
|
||||
{
|
||||
eval { "Hallo" =~ m/^$offRegexp/ };
|
||||
return "Bad regexp_for_ON : $@" if ($@);
|
||||
}
|
||||
|
||||
$hash->{helper}{ON_Regexp} = $onRegexp;
|
||||
$hash->{helper}{OFF_Regexp} = $offRegexp;
|
||||
$hash->{helper}{isFirstRun} = 1;
|
||||
$hash->{helper}{value} = -1;
|
||||
$hash->{helper}{forceHourChange} = '';
|
||||
$hash->{helper}{forceDayChange} = '';
|
||||
$hash->{helper}{forceWeekChange} = '';
|
||||
$hash->{helper}{forceMonthChange} = '';
|
||||
$hash->{helper}{forceYearChange} = '';
|
||||
|
||||
$hash->{helper}{forceClear} = '';
|
||||
$hash->{helper}{calledByEvent} = '';
|
||||
$hash->{helper}{changedTimestamp} = '';
|
||||
@{$hash->{helper}{cmdQueue}} = ();
|
||||
|
||||
$modules{HourCounter}{defptr}{$name}=$hash;
|
||||
RemoveInternalTimer($name);
|
||||
InternalTimer( int(gettimeofday() + 15), "HourCounter_Run", $name, 0 );
|
||||
return undef;
|
||||
|
||||
}
|
||||
##########################
|
||||
sub HourCounter_Undef($$)
|
||||
{
|
||||
my ( $hash, $arg ) = @_;
|
||||
|
||||
HourCounter_Log $hash, 3, "Done";
|
||||
return undef;
|
||||
}
|
||||
###########################
|
||||
sub HourCounter_Get($@)
|
||||
{
|
||||
my ( $hash, @a ) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
my $ret = "Unknown argument $a[1], choose one of version:noArg";
|
||||
my $cmd = lc( $a[1] );
|
||||
|
||||
if ($cmd eq 'version')
|
||||
{
|
||||
$ret = "Version : $HourCounter_Version\n";
|
||||
}
|
||||
|
||||
return $ret;
|
||||
|
||||
}
|
||||
###########################
|
||||
sub HourCounter_Set($@)
|
||||
{
|
||||
my ( $hash, @a ) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $reINT = '^([\\+,\\-]?\\d+$)'; # int
|
||||
|
||||
# determine userReadings beginning with app
|
||||
my @readingNames = keys (%{$hash->{READINGS}});
|
||||
my @userReadings = ();
|
||||
foreach (@readingNames)
|
||||
{
|
||||
if ($_ =~ m/app.*/)
|
||||
{
|
||||
push (@userReadings,$_);
|
||||
}
|
||||
}
|
||||
my $strUserReadings = join(" ",@userReadings)." ";
|
||||
|
||||
# standard commands with parameter
|
||||
my @cmdPara =(
|
||||
"countsOverall","countsPerDay",
|
||||
"pauseTimeIncrement","pauseTimePerDay","pauseTimeOverall",
|
||||
"pulseTimeIncrement","pulseTimePerDay","pulseTimeOverall");
|
||||
|
||||
# standard commands with no parameter
|
||||
my @cmdNoPara =("clear","forceHourChange","forceDayChange","forceWeekChange","forceMonthChange","forceYearChange");
|
||||
|
||||
my @allCommands = (@cmdPara,@cmdNoPara,@userReadings);
|
||||
my $strAllCommands = join(" ",(@cmdPara,@userReadings))." ".join(":noArg ",@cmdNoPara).":noArg ";
|
||||
#HourCounter_Log $hash, 2, "strAllCommands : $strAllCommands";
|
||||
|
||||
# stop:noArg
|
||||
my $usage =
|
||||
"Unknown argument $a[1], choose one of "
|
||||
.$strAllCommands;
|
||||
|
||||
# we need at least 2 parameters
|
||||
return "Need a parameter for set" if ( @a < 2 );
|
||||
|
||||
my $cmd = $a[1];
|
||||
if ($cmd eq "?")
|
||||
{
|
||||
return $usage;
|
||||
}
|
||||
my $value = $a[2];
|
||||
|
||||
# is command defined ?
|
||||
if ( (grep { /$cmd/ } @allCommands) <= 0)
|
||||
{
|
||||
HourCounter_Log $hash, 2, "cmd:$cmd no match for : @allCommands";
|
||||
return return "unknown command : $cmd";
|
||||
}
|
||||
|
||||
# need we a parameter ?
|
||||
my $hits = scalar grep { /$cmd/ } @cmdNoPara;
|
||||
my $needPara = ($hits > 0) ? '' : 1;
|
||||
HourCounter_Log $hash, 4, "hits: $hits needPara:$needPara";
|
||||
|
||||
# if parameter needed, it must be an integer
|
||||
return "Value must be an integer" if ($needPara && !($value =~ m/$reINT/));
|
||||
|
||||
HourCounter_Log $hash, 4, "$cmd $value";
|
||||
my $doRun='';
|
||||
|
||||
if($needPara)
|
||||
{
|
||||
readingsSingleUpdate( $hash, $cmd, $value, 1 );
|
||||
}
|
||||
elsif ($cmd eq "forceHourChange")
|
||||
{
|
||||
$hash->{helper}{forceHourChange}=1;
|
||||
$doRun=1;
|
||||
}
|
||||
elsif ($cmd eq "forceDayChange")
|
||||
{
|
||||
$hash->{helper}{forceDayChange}=1;
|
||||
$doRun=1;
|
||||
}
|
||||
elsif ($cmd eq "forceWeekChange")
|
||||
{
|
||||
$hash->{helper}{forceWeekChange}=1;
|
||||
$doRun=1;
|
||||
}
|
||||
elsif ($cmd eq "forceMonthChange")
|
||||
{
|
||||
$hash->{helper}{forceMonthChange}=1;
|
||||
$doRun=1;
|
||||
}
|
||||
elsif ($cmd eq "forceYearChange")
|
||||
{
|
||||
$hash->{helper}{forceYearChange}=1;
|
||||
$doRun=1;
|
||||
}
|
||||
elsif ($cmd eq "clear")
|
||||
{
|
||||
$hash->{helper}{forceClear}=1;
|
||||
$doRun=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return "unknown command (2): $cmd";
|
||||
}
|
||||
|
||||
if ($doRun)
|
||||
{
|
||||
$hash->{helper}{value}=-1;
|
||||
$hash->{helper}{calledByEvent}=1;
|
||||
HourCounter_Run($hash->{NAME});
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
##########################
|
||||
sub HourCounter_Notify($$)
|
||||
{
|
||||
my ( $hash, $dev ) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $devName = $dev->{NAME};
|
||||
|
||||
# return if disabled
|
||||
if ( AttrVal( $name, 'disable', '0' ) eq '1' )
|
||||
{
|
||||
return "";
|
||||
}
|
||||
my $onRegexp = $hash->{helper}{ON_Regexp};
|
||||
my $offRegexp = $hash->{helper}{OFF_Regexp};
|
||||
|
||||
#HourCounter_Log $hash,5,"Notify by DevName: ".$dev->{NAME};
|
||||
my $max = int( @{ $dev->{CHANGED} } );
|
||||
for ( my $i = 0 ; $i < $max ; $i++ )
|
||||
{
|
||||
my $s = $dev->{CHANGED}[$i]; # read changed reading
|
||||
$s = "" if ( !defined($s) );
|
||||
my $isOnReading = ( "$devName:$s" =~ m/^$onRegexp$/ );
|
||||
my $isOffReading = ($offRegexp) ? ( "$devName:$s" =~ m/^$offRegexp$/ ):'';
|
||||
|
||||
HourCounter_Log $hash, 5,
|
||||
"devName:$devName; CHANGED:$s; isOnReading:$isOnReading; isOffReading:$isOffReading;";
|
||||
next if ( !( $isOnReading || ($isOffReading && $offRegexp) ) );
|
||||
|
||||
$hash->{helper}{value} = 1 if ($isOnReading);
|
||||
$hash->{helper}{value} = 0 if ($isOffReading);
|
||||
$hash->{helper}{calledByEvent}=1;
|
||||
HourCounter_Run($hash->{NAME});
|
||||
}
|
||||
}
|
||||
|
||||
##########################
|
||||
# converts the seconds in the date format
|
||||
sub HourCounter_Seconds2HMS($)
|
||||
{
|
||||
my ( $seconds) = @_;
|
||||
my ($Sekunde, $Minute, $Stunde, $Monatstag, $Monat, $Jahr, $Wochentag, $Jahrestag, $Sommerzeit) = localtime($seconds);
|
||||
my $days = int($seconds/86400);
|
||||
return sprintf( "%d Tage %02d:%02d:%02d", $days,$Stunde - 1, $Minute, $Sekunde );
|
||||
}
|
||||
|
||||
##########################
|
||||
# rounds the timestamp do the beginning of the week
|
||||
sub HourCounter_weekBase($)
|
||||
{
|
||||
my ($time) = @_;
|
||||
my $dayDiff = 60*60*24;
|
||||
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time);
|
||||
# wday 0 Sonntag 1 Montag ...
|
||||
my $a=$time-$wday*$dayDiff;
|
||||
my $b=int($a/$dayDiff); # auf tage gehen
|
||||
my $c=$b*$dayDiff;
|
||||
return $c;
|
||||
}
|
||||
|
||||
##########################
|
||||
sub HourCounter_Run($)
|
||||
{
|
||||
# print "xxx TAG A\n" ;
|
||||
my ($name) = @_;
|
||||
my $hash = $defs{$name};
|
||||
|
||||
return if (!defined($hash->{TYPE}) || $hash->{TYPE} ne 'HourCounter');
|
||||
|
||||
delete($hash->{CHANGETIME}); # timestamps for event-log-file-entries older, than current time
|
||||
|
||||
my $calledByEvent = $hash->{helper}{calledByEvent};
|
||||
$hash->{helper}{calledByEvent} = '';
|
||||
|
||||
# if call was made by timer force value to -1
|
||||
my $valuePara = ($calledByEvent)? $hash->{helper}{value}:-1;
|
||||
|
||||
$hash->{helper}{changedTimestamp} = ReadingsTimestamp( $name, "value", TimeNow() )
|
||||
if (!$hash->{helper}{changedTimestamp});
|
||||
my $sdValue = time_str2num($hash->{helper}{changedTimestamp});
|
||||
my $sdCurTime = gettimeofday();
|
||||
|
||||
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
|
||||
|
||||
my $valueOld = ReadingsVal( $name, 'value', 0 ); # get the old value
|
||||
|
||||
# variable for reading update
|
||||
my $value = undef;
|
||||
my $countsPerDay=undef;
|
||||
my $countsOverall=undef;
|
||||
|
||||
my $pulseTimeIncrement=undef;
|
||||
my $pulseTimePerDay=undef;
|
||||
my $pulseTimeOverall=undef;
|
||||
|
||||
my $pauseTimePerDay=undef;
|
||||
my $pauseTimeOverall=undef;
|
||||
my $pauseTimeIncrement=undef;
|
||||
|
||||
my $state=undef;
|
||||
my $clearDate = undef;
|
||||
|
||||
my $sdRoundHour = HourCounter_RoundHour($sdCurTime);
|
||||
my $sdRoundHourLast = $hash->{helper}{sdRoundHourLast};
|
||||
$sdRoundHourLast = $sdRoundHour if (!$sdRoundHourLast);
|
||||
my $isHourChanged = ($sdRoundHour != $sdRoundHourLast) || $hash->{helper}{forceHourChange};
|
||||
|
||||
my $sdRoundDayCurTime = HourCounter_RoundDay($sdCurTime);
|
||||
my $sdRoundDayValue = HourCounter_RoundDay($sdRoundHourLast);
|
||||
my $isDayChanged = ($sdRoundDayCurTime != $sdRoundDayValue) || $hash->{helper}{forceDayChange};
|
||||
|
||||
my $sdRoundWeekCurTime = HourCounter_RoundWeek($sdCurTime);
|
||||
my $sdRoundWeekValue = HourCounter_RoundWeek($sdRoundHourLast);
|
||||
my $isWeekChanged = ($sdRoundWeekCurTime != $sdRoundWeekValue) || $hash->{helper}{forceWeekChange};
|
||||
|
||||
my $sdRoundMonthCurTime = HourCounter_RoundMonth($sdCurTime);
|
||||
my $sdRoundMonthValue = HourCounter_RoundMonth($sdRoundHourLast);
|
||||
my $isMonthChanged = ($sdRoundMonthCurTime != $sdRoundMonthValue) || $hash->{helper}{forceMonthChange};
|
||||
|
||||
my $sdRoundYearCurTime = HourCounter_RoundYear($sdCurTime);
|
||||
my $sdRoundYearValue = HourCounter_RoundYear($sdRoundHourLast);
|
||||
my $isYearChanged = ($sdRoundYearCurTime != $sdRoundYearValue) || $hash->{helper}{forceYearChange};
|
||||
#HourCounter_Log $hash, 0,"sdRoundYearCurTime : $sdRoundYearCurTime";
|
||||
|
||||
while (1)
|
||||
{
|
||||
# stop if disabled
|
||||
last if ( AttrVal( $name, 'disable', '0' ) eq '1' );
|
||||
|
||||
# variables for controlling
|
||||
my $resetDayCounter='';
|
||||
|
||||
HourCounter_Log $hash, 5, "value:$valuePara changedTimestamp:".$hash->{helper}{changedTimestamp} ;
|
||||
|
||||
# --------------- basic init after startup of fhem or reload
|
||||
if ( $hash->{helper}{isFirstRun} )
|
||||
{
|
||||
$hash->{helper}{isFirstRun}=undef;
|
||||
$hash->{helper}{sdRoundHourLast} = $sdRoundHourLast;
|
||||
HourCounter_Log $hash, 4, "first run done";
|
||||
}
|
||||
|
||||
# ------------ basic init, when first run after initial definition in fhem.cfg
|
||||
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);
|
||||
readingsBulkUpdate( $hash, 'tickHour', 0);
|
||||
readingsBulkUpdate( $hash, 'tickDay', 0);
|
||||
readingsBulkUpdate( $hash, 'tickWeek', 0);
|
||||
readingsBulkUpdate( $hash, 'tickMonth',0);
|
||||
readingsEndUpdate( $hash, 1 );
|
||||
}
|
||||
|
||||
if (! ($hash->{helper}{forceClear})) # set value at basic init
|
||||
{
|
||||
$valueOld = 0;
|
||||
$value = 0;
|
||||
}
|
||||
|
||||
$timeIncrement = 0;
|
||||
$hash->{helper}{forceClear} = '';
|
||||
$countsPerDay = 0;
|
||||
$countsOverall = 0;
|
||||
|
||||
$pulseTimeIncrement = 0;
|
||||
$pulseTimePerDay = 0;
|
||||
$pulseTimeOverall = 0;
|
||||
|
||||
$pauseTimeIncrement = 0;
|
||||
$pauseTimePerDay = 0;
|
||||
$pauseTimeOverall = 0;
|
||||
|
||||
$state = 0;
|
||||
$clearDate = TimeNow();
|
||||
}
|
||||
|
||||
# ------------------------- handling of transitions
|
||||
|
||||
my $hasValueChanged = ( $isOffDefined && $valuePara == $valueOld ) ? '' :1;
|
||||
|
||||
# -------------- positive edge
|
||||
if ( $hasValueChanged && $valuePara == 1 )
|
||||
{
|
||||
$hash->{helper}{changedTimestamp} = TimeNow();
|
||||
|
||||
$value = $valuePara;
|
||||
$valueOld = $valuePara;
|
||||
|
||||
# handling of counters
|
||||
$countsPerDay = ReadingsVal( $name, "countsPerDay", 0 ) + 1; # counter inkrementieren
|
||||
$countsOverall = ReadingsVal( $name, "countsOverall", 0 ) + 1; # counter inkrementieren
|
||||
|
||||
if ($isOffDefined) # handling of pause
|
||||
{
|
||||
$pauseTimeIncrement = $timeIncrement;
|
||||
|
||||
$pauseTimePerDay = ReadingsVal( $name, "pauseTimePerDay", 0 ) + $pauseTimeIncrement;
|
||||
$pauseTimeOverall = ReadingsVal( $name, "pauseTimeOverall", 0 )+ $pauseTimeIncrement;
|
||||
my $pulsInc = ReadingsVal( $name, "pulseTimeIncrement", 0 );
|
||||
}
|
||||
HourCounter_Log $hash, 4, "rising edge; countPerDay:$countsPerDay";
|
||||
}
|
||||
|
||||
# ------------ negative edge
|
||||
elsif ($isOffDefined && $hasValueChanged && $valuePara == 0 )
|
||||
{
|
||||
$hash->{helper}{changedTimestamp} = TimeNow();
|
||||
$value = $valuePara;
|
||||
$valueOld = $valuePara;
|
||||
|
||||
# handling of pulse time
|
||||
$pulseTimeIncrement = $timeIncrement;
|
||||
$pulseTimePerDay = ReadingsVal( $name, "pulseTimePerDay", 0 ) + $pulseTimeIncrement;
|
||||
$pulseTimeOverall = ReadingsVal( $name, "pulseTimeOverall", 0 ) + $pulseTimeIncrement;
|
||||
|
||||
HourCounter_Log $hash, 4, "falling edge pulseTimeIncrement:$pulseTimeIncrement";
|
||||
}
|
||||
|
||||
|
||||
# --------------- Day change, update pauseTime and pulseTime
|
||||
if ($isDayChanged)
|
||||
{
|
||||
HourCounter_Log $hash, 4, "day change isDayChanged:$isDayChanged";
|
||||
|
||||
### accumulate incurred times until day change
|
||||
if ($valueOld==0)
|
||||
{
|
||||
$pauseTimeIncrement = $timeIncrement;
|
||||
$pauseTimePerDay = ReadingsVal( $name, "pauseTimePerDay", 0 ) + $timeIncrement;
|
||||
$pauseTimeOverall = ReadingsVal( $name, "pauseTimeOverall", 0 ) + $timeIncrement;
|
||||
}
|
||||
elsif ($valueOld==1)
|
||||
{
|
||||
$pulseTimeIncrement = $timeIncrement;
|
||||
$pulseTimePerDay = ReadingsVal( $name, "pulseTimePerDay", 0 ) + $timeIncrement;
|
||||
$pulseTimeOverall = ReadingsVal( $name, "pulseTimeOverall", 0 ) + $timeIncrement;
|
||||
}
|
||||
|
||||
# update timestamp of reading value with current time
|
||||
$hash->{helper}{changedTimestamp}=TimeNow();
|
||||
|
||||
# logabriss vermeiden
|
||||
$pulseTimeIncrement = ReadingsVal( $name, "pulseTimeIncrement", 0 ) 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;
|
||||
}
|
||||
|
||||
$state =$countsPerDay if (defined($countsPerDay) && ReadingsVal( $name, "state", 0 ) !=$countsPerDay);
|
||||
|
||||
|
||||
### -------------- update readings
|
||||
readingsBeginUpdate($hash);
|
||||
readingsBulkUpdate( $hash, "countsPerDay", $countsPerDay ) if defined($countsPerDay);
|
||||
readingsBulkUpdate( $hash, "countsOverall", $countsOverall ) if defined($countsOverall);
|
||||
|
||||
readingsBulkUpdate( $hash, "pulseTimeIncrement",$pulseTimeIncrement ) if defined($pulseTimeIncrement);
|
||||
readingsBulkUpdate( $hash, "pulseTimePerDay", $pulseTimePerDay ) if defined($pulseTimePerDay);
|
||||
readingsBulkUpdate( $hash, "pulseTimeOverall", $pulseTimeOverall) if defined($pulseTimeOverall);
|
||||
|
||||
readingsBulkUpdate( $hash, "pauseTimeIncrement",$pauseTimeIncrement) if defined($pauseTimeIncrement);
|
||||
readingsBulkUpdate( $hash, "pauseTimePerDay", $pauseTimePerDay) if defined($pauseTimePerDay);
|
||||
readingsBulkUpdate( $hash, "pauseTimeOverall", $pauseTimeOverall) if defined($pauseTimeOverall);
|
||||
|
||||
readingsBulkUpdate( $hash, "value", $value) if defined($value);
|
||||
readingsBulkUpdate( $hash, 'state', $state) if defined($state);
|
||||
readingsBulkUpdate( $hash, 'clearDate', $clearDate) if defined($clearDate);
|
||||
readingsEndUpdate( $hash, 1 );
|
||||
|
||||
# --------------- fire time interval ticks for hour,day,month
|
||||
if ($isHourChanged)
|
||||
{
|
||||
$hash->{helper}{forceHourChange} = '';
|
||||
$hash->{helper}{sdRoundHourLast} = $sdRoundHour;
|
||||
readingsSingleUpdate( $hash, 'tickHour', 1,1);
|
||||
HourCounter_Log $hash, 4, "tickHour fired";
|
||||
}
|
||||
|
||||
if ($isDayChanged)
|
||||
{
|
||||
$hash->{helper}{forceDayChange}= '';
|
||||
readingsSingleUpdate( $hash, 'tickDay', 1,1);
|
||||
HourCounter_Log $hash, 4, "tickDay fired";
|
||||
}
|
||||
|
||||
if ($isWeekChanged)
|
||||
{
|
||||
$hash->{helper}{forceWeekChange}= '';
|
||||
readingsSingleUpdate( $hash, 'tickWeek', 1,1);
|
||||
HourCounter_Log $hash, 4, "tickWeek fired";
|
||||
}
|
||||
|
||||
if ($isMonthChanged)
|
||||
{
|
||||
$hash->{helper}{forceMonthChange}= '';
|
||||
readingsSingleUpdate( $hash, 'tickMonth', 1,1);
|
||||
HourCounter_Log $hash, 4, "tickMonth fired";
|
||||
}
|
||||
|
||||
if ($isYearChanged)
|
||||
{
|
||||
$hash->{helper}{forceYearChange}= '';
|
||||
readingsSingleUpdate( $hash, 'tickYear', 1,1);
|
||||
HourCounter_Log $hash, 4, "tickYear fired";
|
||||
}
|
||||
|
||||
HourCounter_ExecQueue($hash); # execute command queue
|
||||
|
||||
# ----------- pending request for resetting all day counters
|
||||
if ($resetDayCounter)
|
||||
{
|
||||
$resetDayCounter=undef;
|
||||
|
||||
### reset all day counters
|
||||
readingsBeginUpdate($hash);
|
||||
readingsBulkUpdate( $hash, "countsPerDay", 0 );
|
||||
readingsBulkUpdate( $hash, "pulseTimePerDay", 0 );
|
||||
readingsBulkUpdate( $hash, "pauseTimePerDay", 0 );
|
||||
readingsEndUpdate( $hash, 1 );
|
||||
}
|
||||
|
||||
|
||||
last;
|
||||
}
|
||||
|
||||
# ------------ calculate seconds until next hour starts
|
||||
my $actTime = int(gettimeofday());
|
||||
my ($sec,$min,$hour) = localtime($actTime);
|
||||
my $nextHourTime = int(($actTime + 3600)/3600)*3600; # round to next hour start
|
||||
my $nextCall = $nextHourTime - $actTime;
|
||||
|
||||
HourCounter_Log $hash, 5, "nextCall:$nextCall changedTimestamp:"
|
||||
.$hash->{helper}{changedTimestamp};
|
||||
|
||||
RemoveInternalTimer($name);
|
||||
InternalTimer( gettimeofday() + $nextCall, "HourCounter_Run", $hash->{NAME}, 0 );
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
||||
=pod
|
||||
=begin html
|
||||
|
||||
<a name="HourCounter"></a>
|
||||
<h3>HourCounter</h3>
|
||||
<ul>
|
||||
<a name="HourCounterdefine"></a>
|
||||
<b>Define</b>
|
||||
<ul>
|
||||
<br/>
|
||||
<code>define <name> HourCounter <pattern_for_ON> [<pattern_for_OFF>] </code>
|
||||
<br/>
|
||||
<br/>
|
||||
Hourcounter can detect both the activiy-time and the inactivity-time of a property.<br/>
|
||||
The "pattern_for_ON" identifies the events, that signal the activity of the desired property.<br/>
|
||||
The "pattern_for_OFF" identifies the events, that signal the inactivity of the desired property.<br/>
|
||||
<br/>
|
||||
If "pattern_for_OFF" is not defined, any matching event of "patter_for_ON" will be counted.<br/>
|
||||
Otherwise only the rising edges of "pattern_for_ON" will be counted.<br/>
|
||||
This means a "pattern_for_OFF"-event must be detected before a "pattern_for_ON"-event is accepted. <br/>
|
||||
<br/>
|
||||
"pattern_for_ON" and "pattern_for_OFF" must be formed using the following structure:<br/>
|
||||
<br/>
|
||||
<code>device:[regexp]</code>
|
||||
<br/>
|
||||
<br/>
|
||||
The forming-rules are the same as for the notify-command.<br/>
|
||||
<br/>
|
||||
<b>Example:</b><br/>
|
||||
<br/>
|
||||
<ul>
|
||||
<code>define BurnerCounter HourCounter SHUTTER_TEST:on SHUTTER_TEST:off</code>
|
||||
</ul>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<a name="HourCounterset"></a>
|
||||
<b>Set-Commands</b>
|
||||
<ul>
|
||||
|
||||
<br/>
|
||||
<code>set <name> clear</code>
|
||||
<br/><br/>
|
||||
<ul>
|
||||
clears the readings countsPerDay, countsOverall,pauseTimeIncrement, pauseTimePerDay, pauseTimeOverall,
|
||||
pulseTimeIncrement, pulseTimePerDay, pulseTimeOverall by setting to 0.<br/>
|
||||
The reading clearDate is set to the current Date/Time.
|
||||
</ul><br/>
|
||||
|
||||
<br/>
|
||||
<code>set <name> countsOverall <value> </code>
|
||||
<br/><br/>
|
||||
<ul>Sets the reading countsOverall to the given value.This is the total-counter.</ul><br/>
|
||||
|
||||
<br/>
|
||||
<code>set <name> countsPerDay <value> </code>
|
||||
<br/><br/>
|
||||
<ul>Sets the reading countsPerDay to the given value. This reading will automatically be set to 0, after change of day.</ul><br/>
|
||||
|
||||
<br/>
|
||||
<code>set <name> pauseTimeIncrement <value> </code>
|
||||
<br/><br/>
|
||||
<ul>Sets the reading pauseTimeIncrement to the given value.<br/>
|
||||
This reading in seconds is automatically set after a rising edge of the property.</ul><br/>
|
||||
|
||||
<br/>
|
||||
<code>set <name> pauseTimeOverall <value> </code>
|
||||
<br/><br/>
|
||||
<ul>Sets the reading pauseTimeOverall to the given value.<br/>
|
||||
This reading in seconds is automatically adjusted after a change of pauseTimeIncrement.</ul><br/>
|
||||
|
||||
<br/>
|
||||
<code>set <name> pauseTimePerDay <value> </code>
|
||||
<br/><br/>
|
||||
<ul>Sets the reading pauseTimePerDay to the given value.<br/>
|
||||
This reading in seconds is automatically adjusted after a change of pauseTimeIncrement and set to 0 after change of day.</ul><br/>
|
||||
|
||||
<br/>
|
||||
<code>set <name> pulseTimeIncrement <value> </code>
|
||||
<br/><br/>
|
||||
<ul>Sets the reading pulseTimeIncrement to the given value.<br/>
|
||||
This reading in seconds is automatically set after a falling edge of the property.</ul><br/>
|
||||
|
||||
<br/>
|
||||
<code>set <name> pulseTimeOverall <value> </code>
|
||||
<br/><br/>
|
||||
<ul>Sets the reading pulseTimeOverall to the given value.<br/>
|
||||
This reading in seconds is automatically adjusted after a change of pulseTimeIncrement.</ul><br/>
|
||||
|
||||
<br/>
|
||||
<code>set <name> pulseTimePerDay <value> </code>
|
||||
<br/><br/>
|
||||
<ul>Sets the reading pulseTimePerDay to the given value.<br/>
|
||||
This reading in seconds is automatically adjusted after a change of pulseTimeIncrement and set to 0 after change of day.</ul><br/>
|
||||
|
||||
<br/>
|
||||
<code>set <name> forceHourChange </code>
|
||||
<br/><br/>
|
||||
<ul>This modifies the reading tickHour, which is automatically modified after change of hour.</ul><br/>
|
||||
|
||||
<br/>
|
||||
<code>set <name> forceDayChange </code>
|
||||
<br/><br/>
|
||||
<ul>This modifies the reading tickDay, which is automatically modified after change of day.</ul><br/>
|
||||
|
||||
<br/>
|
||||
<code>set <name> forceWeekChange </code>
|
||||
<br/><br/>
|
||||
<ul>This modifies the reading tickWeek, which is automatically modified after change of week.</ul><br/>
|
||||
|
||||
<br/>
|
||||
<code>set <name> forceMonthChange </code>
|
||||
<br/><br/>
|
||||
<ul>This modifies the reading tickMonth, which is automatically modified after change of month.</ul><br/>
|
||||
|
||||
<br/>
|
||||
<code>set <name> forceYearChange </code>
|
||||
<br/><br/>
|
||||
<ul>This modifies the reading tickYear, which is automatically modified after change of year.</ul><br/>
|
||||
|
||||
<br/>
|
||||
<code>set <name> app.* <value> </code>
|
||||
<br/><br/>
|
||||
<ul>Any reading with the leading term "app", can be modified.<br/
|
||||
This can be useful for user-readings.
|
||||
</ul><br/>
|
||||
|
||||
</ul>
|
||||
<br/>
|
||||
|
||||
<a name="HourCounterget"></a>
|
||||
<b>Get-Commands</b><br/>
|
||||
<ul>
|
||||
<br/>
|
||||
<code>get <name> version</code>
|
||||
<br/><br/>
|
||||
<ul>Get the current version of the module.</ul>
|
||||
<br/>
|
||||
</ul>
|
||||
<br/>
|
||||
|
||||
<a name="HourCounterattr"></a>
|
||||
<b>Attributes</b><br/><br/>
|
||||
<ul>
|
||||
<li><a href="#readingFnAttributes">readingFnAttributes</a></li>
|
||||
</ul>
|
||||
<br/>
|
||||
|
||||
<b>Additional information</b><br/><br/>
|
||||
<ul>
|
||||
<li><a href="http://forum.fhem.de/index.php/topic,12216.0.html">Discussion in FHEM forum</a></li><br/>
|
||||
<li><a href="http://www.fhemwiki.de/wiki/HourCounter">WIKI information in FHEM Wiki</a></li><br/>
|
||||
<li>
|
||||
The file 99_UtilsHourCounter.pm is a reference implementation for user defined extensions.<br/>
|
||||
It shows how to create sum values for hours,days, weeks, months and years.<br/>
|
||||
This file is located in the sub-folder contrib. For further information take a look to FHEM Wiki.<br/>
|
||||
</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
|
||||
=end html
|
||||
=cut
|
||||
|
@ -250,6 +250,7 @@ FHEM/98_CustomReadings.pm HCS http://forum.fhem.de Unterstue
|
||||
FHEM/98_dewpoint.pm Joachim http://forum.fhem.de Automatisierung
|
||||
FHEM/98_dummy.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/98_fheminfo.pm mfr69bs http://forum.fhem.de Sonstiges
|
||||
FHEM/98_HourCounter.pm john http://forum.fhem.de MAX
|
||||
FHEM/98_notice.pm mfr69bs http://forum.fhem.de Sonstiges
|
||||
FHEM/98_pilight.pm andreas-fey http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/98_rain.pm baumrasen http://forum.fhem.de Sonstiges
|
||||
|
283
fhem/contrib/99_UtilsHourCounter.pm
Normal file
283
fhem/contrib/99_UtilsHourCounter.pm
Normal file
@ -0,0 +1,283 @@
|
||||
##############################################
|
||||
# $Id: 99_UtilsHourCounter.pm 6802 2014-10-25 18:00:00Z john $
|
||||
#
|
||||
# This ist a reference implementation for enhanced features for modul hourCounter
|
||||
#
|
||||
# This module is written by john.
|
||||
#
|
||||
# This file is part of fhem.
|
||||
#
|
||||
# Fhem is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Fhem is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with fhem. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Changelog
|
||||
#
|
||||
# 04.02.14 - 1.00 modul created
|
||||
# 06.02.14 - 1.01 fixed: wrong timing in assignment appUtilization
|
||||
# 17.03.14 - 1.01 added: appHC_OnYear
|
||||
|
||||
|
||||
package main;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use POSIX;
|
||||
use vars qw(%defs);
|
||||
use vars qw(%modules);
|
||||
|
||||
#require "98_HourCounter.pm";
|
||||
|
||||
my $UtilsHourCounter_Version="1.02 - 17.03.2014 (john)";
|
||||
sub Log3($$$);
|
||||
|
||||
# --------------------------------------------------
|
||||
sub UtilsHourCounter_Initialize($$)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
|
||||
Log3 '', 3, "[UtilsHourCounter] Init Done with Version $UtilsHourCounter_Version";
|
||||
}
|
||||
|
||||
# --------------------------------------------------
|
||||
# yearly tasks
|
||||
#
|
||||
sub appHC_OnYear($$$)
|
||||
{
|
||||
my ($name,$part0,$part1) = @_; # name objects, name des parameters, wert des parameters
|
||||
$part0='' if (!defined($part0));
|
||||
my $hash = $defs{$name};
|
||||
return undef if (!defined ($hash));
|
||||
|
||||
my $appCountsPerYear = ReadingsVal ($name, 'appCountsPerYearTemp' ,0);
|
||||
my $appOpHoursPerYear = ReadingsVal ($name, 'appOpHoursPerYearTemp' ,0);
|
||||
|
||||
#---------------
|
||||
readingsBeginUpdate($hash);
|
||||
|
||||
readingsBulkUpdate ($hash, 'appCountsPerYearTemp' , 0 );
|
||||
readingsBulkUpdate ($hash, 'appCountsPerYear' , $appCountsPerYear );
|
||||
|
||||
readingsBulkUpdate ($hash, 'appOpHoursPerYearTemp' , 0 );
|
||||
readingsBulkUpdate ($hash, 'appOpHoursPerYear' , $appOpHoursPerYear );
|
||||
|
||||
readingsEndUpdate($hash, 1)
|
||||
}
|
||||
|
||||
# --------------------------------------------------
|
||||
# monthly tasks
|
||||
#
|
||||
sub appHC_OnMonth($$$)
|
||||
{
|
||||
my ($name,$part0,$part1) = @_; # name objects, name des parameters, wert des parameters
|
||||
$part0='' if (!defined($part0));
|
||||
my $hash = $defs{$name};
|
||||
return undef if (!defined ($hash));
|
||||
|
||||
my $appCountsPerMonth = ReadingsVal ($name, 'appCountsPerMonthTemp' ,0);
|
||||
my $appOpHoursPerMonth = ReadingsVal ($name, 'appOpHoursPerMonthTemp' ,0);
|
||||
|
||||
#---------------
|
||||
readingsBeginUpdate($hash);
|
||||
|
||||
readingsBulkUpdate ($hash, 'appCountsPerMonthTemp' , 0 );
|
||||
readingsBulkUpdate ($hash, 'appCountsPerMonth' , $appCountsPerMonth );
|
||||
|
||||
readingsBulkUpdate ($hash, 'appOpHoursPerMonthTemp' , 0 );
|
||||
readingsBulkUpdate ($hash, 'appOpHoursPerMonth' , $appOpHoursPerMonth );
|
||||
|
||||
readingsEndUpdate($hash, 1)
|
||||
}
|
||||
|
||||
# --------------------------------------------------
|
||||
# weekly tasks
|
||||
sub appHC_OnWeek($$$)
|
||||
{
|
||||
my ($name,$part0,$part1) = @_; # name objects, name des parameters, wert des parameters
|
||||
$part0='' if (!defined($part0));
|
||||
my $hash = $defs{$name};
|
||||
return undef if (!defined ($hash));
|
||||
|
||||
my $appCountsPerWeek = ReadingsVal ($name, 'appCountsPerWeekTemp' ,0);
|
||||
my $appOpHoursPerWeek = ReadingsVal ($name, 'appOpHoursPerWeekTemp' ,0);
|
||||
|
||||
readingsBeginUpdate($hash);
|
||||
|
||||
readingsBulkUpdate ($hash, 'appCountsPerWeekTemp' , 0);
|
||||
readingsBulkUpdate ($hash, 'appCountsPerWeek' , $appCountsPerWeek);
|
||||
|
||||
readingsBulkUpdate ($hash, 'appOpHoursPerWeekTemp' , 0);
|
||||
readingsBulkUpdate ($hash, 'appOpHoursPerWeek' , $appOpHoursPerWeek);
|
||||
|
||||
readingsEndUpdate( $hash, 1 );
|
||||
|
||||
}
|
||||
|
||||
# --------------------------------------------------
|
||||
# dayly tasks
|
||||
sub appHC_OnDay($$$)
|
||||
{
|
||||
my ($name,$part0,$part1) = @_; # name objects, name des parameters, wert des parameters
|
||||
$part0='' if (!defined($part0));
|
||||
my $hash = $defs{$name};
|
||||
return undef if (!defined ($hash));
|
||||
|
||||
my $appCountsPerDay = ReadingsVal($name, 'countsPerDay',0);
|
||||
my $pulseTimePerDay = ReadingsVal($name, 'pulseTimePerDay',0);
|
||||
|
||||
#HourCounter_Log $hash, 2, "pulseTimePerDay:$pulseTimePerDay";
|
||||
|
||||
my $appOpHoursPerDay = $pulseTimePerDay/3600;
|
||||
my $appOpHoursPerWeekTemp = ReadingsVal ($name,'appOpHoursPerWeekTemp',0 )+$appOpHoursPerDay;
|
||||
my $appOpHoursPerMonthTemp =ReadingsVal ($name,'appOpHoursPerMonthTemp',0 )+$appOpHoursPerDay;
|
||||
my $appOpHoursPerYearTemp =ReadingsVal ($name,'appOpHoursPerYearTemp',0 )+$appOpHoursPerDay;
|
||||
|
||||
my $appUtilizationTempOld = ReadingsVal ($name,'appUtilizationTempOld',0 );
|
||||
|
||||
readingsBeginUpdate($hash);
|
||||
|
||||
readingsBulkUpdate ($hash, 'appCountsPerDay' , $appCountsPerDay);
|
||||
readingsBulkUpdate ($hash, 'appOpHoursPerDay' , $appOpHoursPerDay);
|
||||
readingsBulkUpdate ($hash, 'appOpHoursPerDayTemp' , 0);
|
||||
|
||||
readingsBulkUpdate ($hash, 'appOpHoursPerWeekTemp' , $appOpHoursPerWeekTemp);
|
||||
readingsBulkUpdate ($hash, 'appOpHoursPerMonthTemp', $appOpHoursPerMonthTemp);
|
||||
readingsBulkUpdate ($hash, 'appOpHoursPerYearTemp' , $appOpHoursPerYearTemp);
|
||||
|
||||
readingsBulkUpdate ($hash, 'appUtilization', $appUtilizationTempOld);
|
||||
|
||||
readingsEndUpdate( $hash, 1 );
|
||||
}
|
||||
|
||||
# --------------------------------------------------
|
||||
# hourly tasks
|
||||
sub appHC_OnHour($$$)
|
||||
{
|
||||
my ($name,$part0,$part1) = @_; # name objects, name des parameters, wert des parameters
|
||||
$part0='' if (!defined($part0));
|
||||
my $hash = $defs{$name};
|
||||
return undef if (!defined ($hash));
|
||||
|
||||
my $appCountsPerHourTemp = ReadingsVal($name, 'appCountsPerHourTemp',0);
|
||||
|
||||
readingsBeginUpdate($hash);
|
||||
readingsBulkUpdate ($hash, 'appCountsPerHourTemp', 0 );
|
||||
readingsBulkUpdate ($hash, 'appCountsPerHour', $appCountsPerHourTemp);
|
||||
readingsEndUpdate( $hash, 1 );
|
||||
|
||||
}
|
||||
# --------------------------------------------------
|
||||
# task on count change
|
||||
sub appHC_OnCount($$$)
|
||||
{
|
||||
my ($name,$part0,$part1) = @_; # name objects, name des parameters, wert des parameters
|
||||
$part0='' if (!defined($part0));
|
||||
my $hash = $defs{$name};
|
||||
return undef if (!defined ($hash));
|
||||
|
||||
|
||||
my $appCountsPerHourTemp = ReadingsVal($name,'appCountsPerHourTemp',0) + 1;
|
||||
my $appCountsPerWeekTemp = ReadingsVal($name,'appCountsPerWeekTemp',0) + 1;
|
||||
my $appCountsPerMonthTemp = ReadingsVal($name,'appCountsPerMonthTemp',0)+ 1;
|
||||
my $appCountsPerYearTemp = ReadingsVal($name,'appCountsPerYearTemp',0) + 1;
|
||||
|
||||
readingsBeginUpdate($hash);
|
||||
readingsBulkUpdate ($hash, 'appCountsPerHourTemp', $appCountsPerHourTemp );
|
||||
readingsBulkUpdate ($hash, 'appCountsPerWeekTemp', $appCountsPerWeekTemp );
|
||||
readingsBulkUpdate ($hash, 'appCountsPerMonthTemp',$appCountsPerMonthTemp );
|
||||
readingsBulkUpdate ($hash, 'appCountsPerYearTemp',$appCountsPerYearTemp );
|
||||
readingsEndUpdate( $hash, 1 );
|
||||
|
||||
}
|
||||
|
||||
# --------------------------------------------------
|
||||
# task on value change
|
||||
sub appHC_OnValueChanged($$$)
|
||||
{
|
||||
my ($name,$part0,$part1) = @_; # object name, parameter name, parameter value
|
||||
$part0='' if (!defined($part0));
|
||||
my $hash = $defs{$name};
|
||||
return undef if (!defined ($hash));
|
||||
|
||||
# acquire needed values
|
||||
my $secs= HourCounter_SecondsOfDay();
|
||||
my $pulseTimePerDay = ReadingsVal($name,'pulseTimePerDay',0);
|
||||
|
||||
# calc utilization
|
||||
$secs= 1 if ($secs==0); # no zero division
|
||||
my $appUtilizationTempOld = ReadingsVal($name,'appUtilizationTemp',0);
|
||||
my $appUtilizationTemp = $pulseTimePerDay/$secs*100;
|
||||
|
||||
# calc operating hours
|
||||
my $appOpHoursPerDayTemp =$pulseTimePerDay/3600; # operating time per Day temporary
|
||||
|
||||
readingsBeginUpdate($hash);
|
||||
readingsBulkUpdate ($hash, 'appOpHoursPerDayTemp' , $appOpHoursPerDayTemp);
|
||||
readingsBulkUpdate ($hash, 'appUtilizationTemp' , $appUtilizationTemp );
|
||||
readingsBulkUpdate ($hash, 'appUtilizationTempOld' , $appUtilizationTempOld );
|
||||
readingsEndUpdate( $hash, 1 );
|
||||
|
||||
}
|
||||
|
||||
|
||||
# --------------------------------------------------
|
||||
# central event dispatcher
|
||||
sub appHCNotify($$$)
|
||||
{
|
||||
my ($name,$part0,$part1) = @_; # object name, parameter name, parameter value
|
||||
$name = "?" if (!defined($name));
|
||||
$part0='' if (!defined($part0));
|
||||
my $hash = $defs{$name};
|
||||
|
||||
return undef if (!defined ($hash));
|
||||
|
||||
# HourCounter_Log $hash, 2, "Name:$name part0:$part0 part1:$part1";
|
||||
|
||||
# event dispatcher for delayed execution
|
||||
if ($part0 eq "value:") # trigger CN.Test value: 1
|
||||
{
|
||||
HourCounter_cmdQueueAdd($hash,"appHC_OnValueChanged q($name),q($part0),q($part1)");
|
||||
}
|
||||
elsif ($part0 eq "countsOverall:")
|
||||
{
|
||||
HourCounter_cmdQueueAdd($hash,"appHC_OnCount q($name),q($part0),q($part1)");
|
||||
}
|
||||
elsif ($part0 eq "tickHour:") # trigger CN.Test tickHour: 1
|
||||
{
|
||||
HourCounter_cmdQueueAdd($hash,"appHC_OnHour q($name),q($part0),q($part1)");
|
||||
}
|
||||
elsif ($part0 eq "tickDay:") # trigger CN.Test tickDay: 1
|
||||
{
|
||||
HourCounter_cmdQueueAdd($hash,"appHC_OnDay q($name),q($part0),q($part1)");
|
||||
}
|
||||
elsif ($part0 eq "tickWeek:")
|
||||
{
|
||||
HourCounter_cmdQueueAdd($hash,"appHC_OnWeek q($name),q($part0),q($part1)");
|
||||
}
|
||||
elsif ($part0 eq "tickMonth:")
|
||||
{
|
||||
HourCounter_cmdQueueAdd($hash,"appHC_OnMonth q($name),q($part0),q($part1)");
|
||||
}
|
||||
elsif ($part0 eq "tickYear:")
|
||||
{
|
||||
HourCounter_cmdQueueAdd($hash,"appHC_OnYear q($name),q($part0),q($part1)");
|
||||
}
|
||||
|
||||
return '';
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
1;
|
||||
|
@ -110,10 +110,10 @@
|
||||
<a href="#HTTPSRV">HTTPSRV</a>
|
||||
<a href="#Heating_Control">Heating_Control</a>
|
||||
<a href="#holiday">holiday</a>
|
||||
<a href="#HourCounter">HourCounter</a>
|
||||
<a href="#LightScene">LightScene</a>
|
||||
<a href="#mailcheck">mailcheck</a>
|
||||
<a href="#notify">notify</a>
|
||||
<a href="#PID">PID</a>
|
||||
<a href="#PRESENCE">PRESENCE</a>
|
||||
<a href="#PachLog">PachLog</a>
|
||||
<a href="#RSS">RSS</a>
|
||||
|
Loading…
x
Reference in New Issue
Block a user