From 15af99f98e22e0b905a83c15ef1353f2cf622e0c Mon Sep 17 00:00:00 2001 From: pahenning <> Date: Tue, 12 Feb 2013 08:32:06 +0000 Subject: [PATCH] git-svn-id: https://svn.fhem.de/fhem/trunk@2703 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/21_OWAD.pm | 10 +- fhem/FHEM/21_OWCOUNT.pm | 151 ++++++-- fhem/FHEM/21_OWMULTI.pm | 3 +- fhem/FHEM/21_OWSWITCH.pm | 3 +- fhem/FHEM/21_OWTHERM.pm | 38 +- fhem/contrib/15_EMX.pm | 773 ++++++++++++++++++++++++++++++++++++++ fhem/contrib/70_NT5000.pm | 519 ++++++++++++++----------- 7 files changed, 1222 insertions(+), 275 deletions(-) create mode 100755 fhem/contrib/15_EMX.pm diff --git a/fhem/FHEM/21_OWAD.pm b/fhem/FHEM/21_OWAD.pm index c8c988967..15b30cf50 100644 --- a/fhem/FHEM/21_OWAD.pm +++ b/fhem/FHEM/21_OWAD.pm @@ -437,8 +437,13 @@ sub OWAD_FormatValues($) { } else { $vval = "???"; } + + #-- low alarm value $vlow =$owg_vlow[$i]; + $main::attr{$name}{$owg_fixed[$i]."Low"}=$vlow; + #-- high alarm value $vhigh=$owg_vhigh[$i]; + $main::attr{$name}{$owg_fixed[$i]."High"}=$vhigh; #-- string buildup for return value, STATE and alarm $svalue .= sprintf( "%s: %5.3f %s", $owg_channel[$i], $vval,$unarr[1]); @@ -795,7 +800,7 @@ sub OWAD_Set($@) { if($value ne "none" && $value ne "low" && $value ne "high" && $value ne "both"); #-- put into attribute value if( $main::attr{$name}{$owg_fixed[$channo]."Alarm"} ne $value ){ - Log 1,"OWAD: Correcting attribute value ".$owg_fixed[$channo]."Alarm"; + #Log 1,"OWAD: Correcting attribute value ".$owg_fixed[$channo]."Alarm"; $main::attr{$name}{$owg_fixed[$channo]."Alarm"} = $value } #-- put into device @@ -1472,7 +1477,8 @@ sub OWXAD_SetPage($$) { alarm.
  • Standard attributes alias, comment, event-on-update-reading, event-on-change-reading, event-on-change-reading, stateFormat, room, eventMap, loglevel, webCmd
  • diff --git a/fhem/FHEM/21_OWCOUNT.pm b/fhem/FHEM/21_OWCOUNT.pm index 801e20a71..5c70e2498 100644 --- a/fhem/FHEM/21_OWCOUNT.pm +++ b/fhem/FHEM/21_OWCOUNT.pm @@ -36,7 +36,7 @@ # Additional attributes are defined in fhem.cfg, in some cases per channel, where =A,B # Note: attributes are read only during initialization procedure - later changes are not used. # -# attr UnitInReading = whether the physical unit is written into the reading = 1 (default) or 0 +# attr LogM = device name (not file name) of monthly log file # attr Name | = name for the channel | a type description for the measured value # attr Unit | = unit of measurement for this channel | its abbreviation # attr Offset = offset added to the reading in this channel @@ -132,8 +132,8 @@ sub OWCOUNT_Initialize ($) { $hash->{SetFn} = "OWCOUNT_Set"; #-- see header for attributes - my $attlist = "IODev do_not_notify:0,1 showtime:0,1 model:DS2423 loglevel:0,1,2,3,4,5 ". - "event-on-update-reading event-on-change-reading "; + my $attlist = "IODev do_not_notify:0,1 showtime:0,1 model:DS2423 loglevel:0,1,2,3,4,5 LogM ". + $readingFnAttributes; for( my $i=0;$i{READINGS}{"$owg_channel[$i]"}{PERIOD}; $runit = $hash->{READINGS}{"$owg_rate[$i]"}{UNITABBR}; - #-- skip some thing if undefined + #-- skip some things if undefined if( $owg_val[$i] eq ""){ $svalue .= $owg_channel[$i].": ???"; }else{ - #-- only if attribute value Mode=daily, take the midnight value from memory + #-- only if attribute value mode=daily, take the midnight value from memory if( defined($attr{$name}{$owg_fixed[$i]."Mode"} )){ if( $attr{$name}{$owg_fixed[$i]."Mode"} eq "daily"){ $midnight = $owg_midnight[$i]; @@ -407,43 +408,44 @@ sub OWCOUNT_FormatValues($) { #-- safeguard against the case where no previous measurement if( length($oldtim) > 0 ){ - #-- time difference in seconds + #-- previous measurement time ($yearo,$montho,$dayrest) = split(/-/,$oldtim); $dayo = substr($dayrest,0,2); ($houro,$mino,$seco) = split(/:/,substr($dayrest,3)); - my $delt = ($hour-$houro)*3600 + ($min-$mino)*60 + ($sec-$seco); - #-- debugging: changing the day every 10 minutes - #$delt = - #-- correct time for wraparound at midnight - if( ($delt<0) && ($present==1)){ + + #-- time dfifference to previous measurement and to midnight + $delt = ($hour-$houro)*3600 + ($min-$mino)*60 + ($sec-$seco); + $delf = $hour *3600 + $min *60 + $sec - 86400; + if( ($delf+$hash->{INTERVAL}) >= 0 ){ $daybreak = 1; - $delt += 86400; + #-- Timer data from tomorrow + my ($secn,$minn,$hourn,$dayn,$monthn,$yearn,$wdayn,$ydayn,$isdstn) = localtime(time() + 24*60*60); + #-- Check, whether we have a new month + if( (($delf+$hash->{INTERVAL}) > 0) && ($dayn == 1) ){ + $monthbreak =1; + } } + #-- correct $vval for wraparound of 32 bit counter if( ($vval < $oldval) && ($daybreak==0) && ($present==1) ){ Log 1,"OWCOUNT TODO: Counter wraparound"; } if( $daybreak==1 ){ - #-- linear interpolation - my $dt = ((24-$houro)*3600 -$mino*60 - $seco)/( ($hour+24-$houro)*3600 + ($min-$mino)*60 + ($sec-$seco) ); - my $dv = $oldval*(1-$dt)+$vval*$dt; - #-- correct reading in daily mode - if( $midnight > 0.0 ){ - $vval -= $dv; - $delt *= (1-$dt); - $oldval = 0.0; - } + #-- linear extrapolation + $dt = -$delf/$delt; + $dv = ($vval-$oldval)*$dt; + $dval = $vval+$dv; + #-- in any mode store the interpolated value in the midnight store - $midnight += $dv; - OWXCOUNT_SetPage($hash,14+$i,sprintf("%f",$midnight)); + OWXCOUNT_SetPage($hash,14+$i,sprintf("%f",$dval)); #-- string buildup for monthly logging - $dvalue .= sprintf( "%s: %5.1f %s", $owg_channel[$i], $dv,$unit); + $dvalue .= sprintf( "%s: %5.1f %s", $owg_channel[$i], $dval,$unit); if( $day<$dayo ){ $monthbreak = 1; Log 1, "OWCOUNT: Change of month"; #-- string buildup for yearly logging - $mvalue .= sprintf( "%s: %5.1f %s", $owg_channel[$i], $dv,$unit); + $mvalue .= sprintf( "%s: %5.1f %s", $owg_channel[$i], $dval,$unit); } } #-- rate @@ -480,24 +482,25 @@ sub OWCOUNT_FormatValues($) { #-- insert space if( $i{NAME}; + my $regexp = ".*$name.*"; + my $val; + my @month = (); + my @month2 = (); + my @channel; + my ($total,$total2,$deltim,$av); + + #-- Check current logfile + my $ln = $attr{$name}{"LogM"}; + if( !(defined($ln))){ + Log 1,"OWCOUNT_GetMonth: Attribute LogM is missing"; + return undef; + } else { + my $lf = $defs{$ln}{currentlogfile}; + my $ret = open(OWXFILE, "< $lf" ); + if( $ret) { + while( ){ + #-- line looks as + # 2013-02-09_23:59:31 day D_09 : 180.0 cts : 180.0 cts etc. + my $line = $_; + chomp($line); + if ( $line =~ m/$regexp/i){ + my @linarr = split(' ',$line); + my $day = $linarr[3]; + $day =~ s/D_0+//; + @channel = (); + for (my $i=0;$i{READINGS}{"$owg_channel[$i]"}{VAL}))/100; + my $av = int(100*$total2/(int(@month)+$deltim))/100; + + push(@month2,[($total,$total2,$av)]); + } + return @month2; + } +} + ####################################################################################### # # OWCOUNT_GetValues - Updates the reading from one device @@ -1168,6 +1239,11 @@ sub OWXCOUNT_SetPage($$$) {

    Attributes

    +

    For each of the following attributes, the channel identification A,B may be used.

    diff --git a/fhem/FHEM/21_OWMULTI.pm b/fhem/FHEM/21_OWMULTI.pm index 10d9eeb29..bd3c0a5bc 100644 --- a/fhem/FHEM/21_OWMULTI.pm +++ b/fhem/FHEM/21_OWMULTI.pm @@ -985,7 +985,8 @@ sub OWXMULTI_SetValues($@) {
    unit of measurement (temperature scale), default is Celsius = °C
  • Standard attributes alias, comment, event-on-update-reading, event-on-change-reading, event-on-change-reading, stateFormat, room, eventMap, loglevel, webCmd
  • diff --git a/fhem/FHEM/21_OWSWITCH.pm b/fhem/FHEM/21_OWSWITCH.pm index 126794624..2d7222277 100644 --- a/fhem/FHEM/21_OWSWITCH.pm +++ b/fhem/FHEM/21_OWSWITCH.pm @@ -1198,7 +1198,8 @@ sub OWXSWITCH_SetState($$) {
    display for on | off condition
  • Standard attributes alias, comment, event-on-update-reading, event-on-change-reading, event-on-change-reading, stateFormat, room, eventMap, loglevel, webCmd
  • diff --git a/fhem/FHEM/21_OWTHERM.pm b/fhem/FHEM/21_OWTHERM.pm index f0ad2f222..3b83d419d 100755 --- a/fhem/FHEM/21_OWTHERM.pm +++ b/fhem/FHEM/21_OWTHERM.pm @@ -142,7 +142,6 @@ sub OWTHERM_Define ($$) { my @a = split("[ \t][ \t]*", $def); my ($name,$model,$fam,$id,$crc,$interval,$ret); - my $tn = TimeNow(); #-- default $name = $a[0]; @@ -334,8 +333,8 @@ sub OWTHERM_FormatValues($) { #-- correct values for proper offset, factor $vval = ($owg_temp + $offset)*$factor; - $vlow = ($owg_tl + $offset)*$factor; - $vhigh = ($owg_th + $offset)*$factor; + $vlow = floor(($owg_tl + $offset)*$factor+0.5); + $vhigh = floor(($owg_th + $offset)*$factor+0.5); $main::attr{$name}{"tempLow"} = $vlow; $main::attr{$name}{"tempHigh"} = $vhigh; @@ -553,30 +552,35 @@ sub OWTHERM_Set($@) { #-- set tempLow or tempHigh if( (lc($key) eq "templow") || (lc($key) eq "temphigh")) { - #-- First we have to read the current data, because alarms may not be set independently - OWTHERM_GetValues($hash); - + my $interface = $hash->{IODev}->{TYPE}; my $offset = defined($hash->{tempf}{offset}) ? $hash->{tempf}{offset} : 0.0; my $factor = defined($hash->{tempf}{factor}) ? $hash->{tempf}{factor} : 1.0; + #-- Only integer values are allowed + $value = floor($value+0.5); + + #-- First we have to read the current data, because alarms may not be set independently + $owg_tl = floor($main::attr{$name}{"tempLow"}/$factor-$offset+0.5); + $owg_th = floor($main::attr{$name}{"tempHigh"}/$factor-$offset+0.5); + #-- find upper and lower boundaries for given offset/factor - my $mmin = (-55+$offset)*$factor; - my $mmax = (125+$offset)*$factor; + my $mmin = floor((-55+$offset)*$factor+0.5); + my $mmax = floor((125+$offset)*$factor+0.5); return sprintf("OWTHERM: Set with wrong value $value for $key, range is [%3.1f,%3.1f]",$mmin,$mmax) if($value < $mmin || $value > $mmax); #-- seems to be ok, correcting for offset and factor - $a[2] = int($value/$factor-$offset); + $a[2] = floor($value/$factor-$offset+0.5); #-- put into attribute value if( lc($key) eq "templow" ){ - if( $main::attr{$name}{"tempLow"} != $a[2] ){ - $main::attr{$name}{"tempLow"} = $a[2]; + if( $main::attr{$name}{"tempLow"} != $value ){ + $main::attr{$name}{"tempLow"} = $value; } } if( lc($key) eq "temphigh" ){ - if( $main::attr{$name}{"tempHigh"} != $a[2] ){ - $main::attr{$name}{"tempHigh"} = $a[2]; + if( $main::attr{$name}{"tempHigh"} != $value ){ + $main::attr{$name}{"tempHigh"} = $value; } } #-- put into device @@ -593,10 +597,9 @@ sub OWTHERM_Set($@) { if(defined($ret)); } - #-- process results - we have to reread the device + #-- process results $hash->{PRESENT} = 1; - # - #OWTHERM_FormatValues($hash); + OWTHERM_FormatValues($hash); Log 4, "OWTHERM: Set $hash->{NAME} $key $value"; return undef; @@ -1019,7 +1022,8 @@ sub OWXTHERM_SetValues($@) { value).
  • Standard attributes alias, comment, event-on-update-reading, event-on-change-reading, event-on-change-reading, stateFormat, room, eventMap, loglevel, webCmd
  • diff --git a/fhem/contrib/15_EMX.pm b/fhem/contrib/15_EMX.pm new file mode 100755 index 000000000..731f0eab2 --- /dev/null +++ b/fhem/contrib/15_EMX.pm @@ -0,0 +1,773 @@ +######################################################################################## +# +# 15_EMX.pm MUST be saved as 15_CUL_EM.pm !!! +# +# FHEM module to read the data from an EM1000 S/IR power sensor +# +# Version 1.0 - January 21, 2013 +# +# Prof. Dr. Peter A. Henning, 2011 +# +#---------------------------------------------------------------------------------------------------- +# +# Setup as: +# define EMX +# +# where +# may be replaced by any name string +# is a number 1 - 12 or the keyword "emulator". +# is the scale factor = rotations per kWh or m^3 (not needed for emulator) +# +# get midnight => todays starting value for counter +# get month => summary of current month +# +# Attributes are set as +# +# Monthly and yearly log file +# attr emx LogM EnergyM +# attr emx LogY EnergyY +# +# NOT YET OPERATIVE: +# +# Basic fee per Month (€ per Month) +# attr emx FixedM +# +# Rate during daytime (€ per kWh) +# attr emx RateD +# +# Start and end of daytime rate - optional +# attr emx RateDStart