From 52cd8fcf23878245521d6bae31dd5a3618c04bc3 Mon Sep 17 00:00:00 2001 From: borisneubert Date: Sat, 14 Feb 2009 20:54:45 +0000 Subject: [PATCH] added counter differential per time in 81_M232Counter.pm git-svn-id: https://svn.fhem.de/fhem/trunk@352 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/CHANGED | 1 + fhem/FHEM/81_M232Counter.pm | 119 ++++++++++++++++++++++++++++-------- fhem/HISTORY | 5 ++ fhem/docs/commandref.html | 40 ++++++++---- 4 files changed, 126 insertions(+), 39 deletions(-) diff --git a/fhem/CHANGED b/fhem/CHANGED index ab25f6d37..b0cab7457 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -491,3 +491,4 @@ - feature: avoid the "unknown/help me" message for unloaded devices - feature: structure module for big installations - feature: Cost Control in 15_CUL_EM (CostPerUnit, BasisFeePerMonth) + - feature: add counter differential per time in 81_M232Counter.pm diff --git a/fhem/FHEM/81_M232Counter.pm b/fhem/FHEM/81_M232Counter.pm index 92d10dda0..5e8652e50 100644 --- a/fhem/FHEM/81_M232Counter.pm +++ b/fhem/FHEM/81_M232Counter.pm @@ -1,7 +1,7 @@ # # # 81_M232Counter.pm -# written by Dr. Boris Neubert 2007-11-26 +# written by Dr. Boris Neubert 2007-11-26 # e-mail: omega at online dot de # ############################################## @@ -37,10 +37,11 @@ M232Counter_GetStatus($) my ($hash) = @_; if(!$hash->{LOCAL}) { - InternalTimer(gettimeofday()+60, "M232Counter_GetStatus", $hash, 1); + InternalTimer(gettimeofday()+$hash->{INTERVAL}, "M232Counter_GetStatus", $hash, 1); } my $name = $hash->{NAME}; + my $r= $hash->{READINGS}; my $d = IOWrite($hash, "z"); if(!defined($d)) { @@ -49,29 +50,81 @@ M232Counter_GetStatus($) return $msg; } + # time my $tn = TimeNow(); - if(!defined($hash->{READINGS}{basis})) { - $hash->{READINGS}{basis}{VAL}= 0; - $hash->{READINGS}{basis}{TIME}= $tn; - } - if(!defined($hash->{READINGS}{count})) { - $hash->{READINGS}{count}{VAL}= 0; - $hash->{READINGS}{count}{TIME}= $tn; - } - my $count= hex $d; - if($count< $hash->{READINGS}{count}{VAL}) { - $hash->{READINGS}{basis}{VAL}+= 65536; - $hash->{READINGS}{basis}{TIME}= $tn; - } - my $value= ($hash->{READINGS}{basis}{VAL}+$count) * $hash->{FACTOR}; - $hash->{READINGS}{count}{TIME} = $tn; - $hash->{READINGS}{count}{VAL} = $count; - $hash->{READINGS}{value}{TIME} = $tn; - $hash->{READINGS}{value}{VAL} = $value; + #tsecs + my $tsecs= time(); # number of non-leap seconds since January 1, 1970, UTC + + # previous tsecs + my $tsecs_prev; + if(defined($r->{tsecs})) { + $tsecs_prev= $r->{tsecs}{VAL}; + } else{ + $tsecs_prev= $tsecs; # 1970-01-01 + } + + # basis + my $basis; + if(defined($r->{basis})) { + $basis= $r->{basis}{VAL}; + } else { + $basis= 0; + } + my $basis_prev= $basis; + + # previous count + my $count_prev; + if(defined($r->{count})) { + $count_prev= $r->{count}{VAL}; + } else { + $count_prev= 0; + } + + # current count + my $count= hex $d; + if($count< $count_prev) { + $basis+= 65536; + $r->{basis}{VAL} = $basis; + $r->{basis}{TIME}= $tn; + } + + # previous value + my $value_prev; + if(defined($r->{value})) { + $value_prev= $r->{value}{VAL}; + } else { + $value_prev= 0; + } + + # current value + my $value= ($basis+$count) * $hash->{FACTOR}; + # round to 3 digits + $value= int($value*1000.0+0.5)/1000.0; + + # set new values + $r->{count}{TIME} = $tn; + $r->{count}{VAL} = $count; + $r->{value}{TIME} = $tn; + $r->{value}{VAL} = $value; + $r->{tsecs}{TIME} = $tn; + $r->{tsecs}{VAL} = $tsecs; $hash->{CHANGED}[0]= "value: $value"; + # delta + my $tsecs_delta= $tsecs-$tsecs_prev; + my $count_delta= ($count+$basis)-($count_prev+$basis_prev); + if($tsecs_delta>0) { + my $delta= ($count_delta/$tsecs_delta)*$hash->{DELTAFACTOR}; + # round to 3 digits + $delta= int($delta*1000.0+0.5)/1000.0; + $r->{delta}{TIME} = $tn; + $r->{delta}{VAL} = $delta; + $hash->{CHANGED}[1]= "delta: $delta"; + } + + if(!$hash->{LOCAL}) { DoTrigger($name, undef) if($init_done); } @@ -121,7 +174,7 @@ M232Counter_Calibrate($@) # recalculate value $hash->{READINGS}{value}{VAL} = $value; $hash->{READINGS}{value}{TIME} = $tn; - + # reset counter my $ret = IOWrite($hash, "Z1"); if(!defined($ret)) { @@ -137,14 +190,21 @@ sub M232Counter_Set($@) { my ($hash, @a) = @_; - my $u = "Usage: set value "; + my $u = "Usage: set value \n" . + "set interval \n" ; return $u if(int(@a) != 3); my $reading= $a[1]; - my $value = $a[2]; - return $u unless($reading eq "value"); - my $rm= M232Counter_Calibrate($hash, $value); + if($a[1] eq "value") { + my $value= $a[2]; + my $rm= M232Counter_Calibrate($hash, $value); + } elsif($a[1] eq "interval") { + my $interval= $a[2]; + $hash->{INTERVAL}= $interval; + } else { + return $u; + } return undef; } @@ -157,13 +217,18 @@ M232Counter_Define($$) my ($hash, $def) = @_; my @a = split("[ \t][ \t]*", $def); - return "syntax: define M232Counter [unit] [multiplicator]" - if(int(@a) < 2 && int(@a) > 4); + return "syntax: define M232Counter [unit] [factor] [deltaunit] [deltafactor]" + if(int(@a) < 2 && int(@a) > 6); my $unit= ((int(@a) > 2) ? $a[2] : "ticks"); my $factor= ((int(@a) > 3) ? $a[3] : 1.0); + my $deltaunit= ((int(@a) > 4) ? $a[4] : "ticks per second"); + my $deltafactor= ((int(@a) > 5) ? $a[5] : 1.0); $hash->{UNIT}= $unit; $hash->{FACTOR}= $factor; + $hash->{DELTAUNIT}= $deltaunit; + $hash->{DELTAFACTOR}= $deltafactor; + $hash->{INTERVAL}= 60; # poll every minute per default AssignIoPort($hash); diff --git a/fhem/HISTORY b/fhem/HISTORY index 9fa1cfb7f..bfa63f1ad 100644 --- a/fhem/HISTORY +++ b/fhem/HISTORY @@ -388,3 +388,8 @@ e.g.: attr global logdir /var/tmp define emGaslog FileLog %ld/emGas.log emGas:.*CNT.* +- Sat Feb 15 2009 (Boris) + - added counter differential per time in 81_M232Counter.pm, commandref.html + updated + + diff --git a/fhem/docs/commandref.html b/fhem/docs/commandref.html index e69d0e555..1e25cfede 100644 --- a/fhem/docs/commandref.html +++ b/fhem/docs/commandref.html @@ -2302,25 +2302,36 @@ A line ending with \ will be concatenated with the next one, so long lines Define
    - define <name> M232Counter [unit [factor]] + define <name> M232Counter [unit [factor [deltaunit [deltafactor]]]]

    Define at most one M232Counter for a M232 device. Defining a M232Counter - will schedule an internal task, which reads the status of the counter every - minute, and triggers notify/filelog commands. unit is the unit + will schedule an internal task, which periodically reads the status of the + counter, and triggers notify/filelog commands. unit is the unit name, factor is used to calculate the reading of the counter - from number of ticks.


    Note: the unit defaults to the string - "ticks", but it must be specified if you wish to set the factor, which - defaults to 1.0. In the second example below one tick equals 1/1250th kWh. + from the number of ticks. deltaunit is the unit name of the counter + differential per second, deltafactor is used to calculate the + counter differential per second from the number of ticks per second.

    + Default values: +
      +
    • unit: ticks
    • +
    • factor: 1.0
    • +
    • deltaunit: ticks per second
    • +
    • deltafactor: 1.0
    • +
    +
    Note: the parameters in square brackets are optional. If you wish to + specify an optional parameter, all preceding parameters must be specified + as well. +

    Examples: +
      + define counter M232Counter turns
      + define counter M232Counter kWh 0.0008 kW 2.88 + (one tick equals 1/1250th kWh)
      +
    +
    Do not forget to start the counter (with set .. start for M232) or to start the counter and set the reading to a specified value (with set ... value for M232Counter).

    - Example: -
      - define counter M232Counter turns
      - define counter M232Counter kWh 0.0008
      -
    -
@@ -2331,6 +2342,11 @@ A line ending with \ will be concatenated with the next one, so long lines Sets the reading of the counter to the given value. The counter is reset and started and the offset is adjusted to value/unit.

+ set <name> interval <interval> +

+ Sets the status polling interval in seconds to the given value. The default + is 60 seconds. +