From cb831673b8c574b8afbe3520ec6f12d506a02d56 Mon Sep 17 00:00:00 2001 From: phenning <> Date: Sat, 15 Jul 2017 03:27:23 +0000 Subject: [PATCH] 21_OWAD.pm: Neue Version, angepasst an OWX Next Generation 21_OWCOUNT.pm: Neue Version, angepasst an OWX Next Generation git-svn-id: https://svn.fhem.de/fhem/trunk@14719 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/21_OWAD.pm | 215 ++++++++------------ fhem/FHEM/21_OWCOUNT.pm | 436 ++++++++++++++++------------------------ 2 files changed, 256 insertions(+), 395 deletions(-) diff --git a/fhem/FHEM/21_OWAD.pm b/fhem/FHEM/21_OWAD.pm index c043e4a9b..63f9f4060 100644 --- a/fhem/FHEM/21_OWAD.pm +++ b/fhem/FHEM/21_OWAD.pm @@ -10,44 +10,6 @@ # $Id$ # ######################################################################################## -# -# define OWAD [] [interval] or or OWAD . [interval] -# -# where may be replaced by any name string -# -# is a 1-Wire device type. If omitted, we assume this to be an -# DS2450 A/D converter -# is a 1-Wire family id, currently allowed value is 20 -# is a 12 character (6 byte) 1-Wire ROM ID -# without Family ID, e.g. A2D90D000800 -# [interval] is an optional query interval in seconds -# -# get id => FAM_ID.ROM_ID.CRC -# get present => 1 if device present, 0 if not -# get interval => query interval -# get reading => measurement for all channels -# get alarm => alarm measurement settings for all channels -# get status => alarm and i/o status for all channels -# get version => OWX version number -# -# set interval => set period for measurement -# -# Additional attributes are defined in fhem.cfg, in some cases per channel, where =A,B,C,D -# -# attr stateAL0 "" = character string for denoting low normal condition, default is empty -# attr stateAH0 "" = character string for denoting high normal condition, default is empty -# attr stateAL1 "" = character string for denoting low alarm condition, default is ↓ -# attr stateAH1 "" = character string for denoting high alarm condition, default is ↑ -# attr Name [|] = name for the channel [|name used in state reading] -# attr Unit = unit of measurement for this channel used in state reading (default V, none for empty) -# attr Function = arbitrary functional expression involving the values V=VA,VB,VC,VD -# VA is replaced by the measured voltage in channel A, etc. -# -# attr Alarm = alarm setting in this channel, either both, low, high or none (default) -# attr Low = measurement value (on the scale determined by function) for low alarm -# attr High = measurement value (on the scale determined by function) for high alarm -# -######################################################################################## # # This programm is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -86,7 +48,7 @@ use ProtoThreads; no warnings 'deprecated'; sub Log3($$$); -my $owx_version="6.1"; +my $owx_version="7.0"; #-- fixed raw channel name, flexible channel name my @owg_fixed = ("A","B","C","D"); my @owg_channel = ("A","B","C","D"); @@ -99,8 +61,6 @@ my @owg_range; my %gets = ( "id" => "", - "present" => "", - "interval" => "", "reading" => "", "alarm" => "", "status" => "", @@ -332,9 +292,9 @@ sub OWAD_Attr(@) { #-- interval modified at runtime $key eq "interval" and do { #-- check value - return "OWAD: Set with short interval, must be > 1" if(int($value) < 1); + return "OWAD: set $name interval, must be >= 0" if(int($value) < 0); #-- update timer - $hash->{INTERVAL} = $value; + $hash->{INTERVAL} = int($value); if ($init_done) { RemoveInternalTimer($hash); InternalTimer(gettimeofday()+$hash->{INTERVAL}, "OWAD_GetValues", $hash, 0); @@ -436,7 +396,6 @@ sub OWAD_FormatValues($) { my $galarm = 0; my $achange = 0; my $schange = 0; - $hash->{ALARM} = 0; #-- alarm signatures my $stateal1 = defined($attr{$name}{stateAL1}) ? $attr{$name}{stateAL1} : "↓"; @@ -541,8 +500,10 @@ sub OWAD_FormatValues($) { #-- STATE readingsBulkUpdate($hash,"state",$svalue); readingsEndUpdate($hash,1); - $hash->{ALARM} = 1 - if( $galarm == 1); + if( $galarm != $hash->{ALARM} ){ + $hash->{ALARM} = $galarm; + main::OWX_Alarms($hash->{IODev}); + } return $svalue; } @@ -582,35 +543,11 @@ sub OWAD_Get($@) { return "$name.id => $value"; } - #-- get present - if($a[1] eq "present") { - #-- asynchronous mode - if( $hash->{ASYNC} ){ - my ($task,$task_state); - eval { - OWX_ASYNC_RunToCompletion($hash,OWX_ASYNC_PT_Verify($hash)); - }; - return GP_Catch($@) if $@; - return "$name.present => ".ReadingsVal($name,"present","unknown"); - } else { - $value = OWX_Verify($master,$hash->{ROM_ID}); - } - $hash->{PRESENT} = $value; - return "$name.present => $value"; - } - - #-- get interval - if($a[1] eq "interval") { - $value = $hash->{INTERVAL}; - return "$name.interval => $value"; - } - #-- get version if( $a[1] eq "version") { return "$name.version => $owx_version"; } - #-- get reading according to interface type if($a[1] eq "reading") { #-- OWX interface @@ -631,18 +568,16 @@ sub OWAD_Get($@) { #-- process result if( $master->{ASYNCHRONOUS} ){ - return "OWAD: $name getting reading, please wait for completion"; + return undef; }else{ if( defined($ret) ){ $hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1; - if( $hash->{ERRCOUNT} > 5 ){ - $hash->{INTERVAL} = 9999; - } - return "OWAD: Could not get values from device $name for ".$hash->{ERRCOUNT}." times, reason $ret"; + return "OWAD: Could not get reading from device $name for ".$hash->{ERRCOUNT}." times, reason $ret"; } return "OWAD: $name.reading => ".$hash->{READINGS}{"state"}{VAL}; } } + #-- get alarm values according to interface type if($a[1] eq "alarm") { #-- OWX interface @@ -663,14 +598,11 @@ sub OWAD_Get($@) { #-- process result if( $master->{ASYNCHRONOUS} ){ - return "OWAD: $name getting alarm values, please wait for completion"; + return undef; }else{ if( defined($ret) ){ $hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1; - if( $hash->{ERRCOUNT} > 5 ){ - $hash->{INTERVAL} = 9999; - } - return "OWAD: Could not get values from device $name for ".$hash->{ERRCOUNT}." times, reason $ret"; + return "OWAD: Could not get alarm values from device $name for ".$hash->{ERRCOUNT}." times, reason $ret"; } #-- assemble ouput string @@ -704,13 +636,11 @@ sub OWAD_Get($@) { #-- process result if( $master->{ASYNCHRONOUS} ){ - return "OWAD: $name getting status, please wait for completion"; + #return "OWAD: $name getting status, please wait for completion"; + return undef; }else{ if( defined($ret) ){ $hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1; - if( $hash->{ERRCOUNT} > 5 ){ - $hash->{INTERVAL} = 9999; - } return "OWAD: Could not get values from device $name for ".$hash->{ERRCOUNT}." times, reason $ret"; } @@ -772,18 +702,18 @@ sub OWAD_GetValues($) { my $warn = "none"; $hash->{ALARM} = "0"; - #-- restart timer for updates - RemoveInternalTimer($hash); + RemoveInternalTimer($hash); + #-- auto-update for device disabled; + return undef + if( $hash->{INTERVAL} == 0 ); + #-- restart timer for updates InternalTimer(time()+$hash->{INTERVAL}, "OWAD_GetValues", $hash, 0); - #-- Get readings, alarms and stati according to interface type + #-- Get readings, alarms and status according to interface type if( $interface eq "OWX" ){ - #-- max 3 tries - #for(my $try=0; $try<3; $try++){ - $ret1 = OWXAD_GetPage($hash,"reading",0); - $ret2 = OWXAD_GetPage($hash,"alarm",0); - $ret3 = OWXAD_GetPage($hash,"status",1); - #} + $ret1 = OWXAD_GetPage($hash,"reading",0); + $ret2 = OWXAD_GetPage($hash,"alarm",0); + $ret3 = OWXAD_GetPage($hash,"status",1); }elsif( $interface eq "OWX_ASYNC" ){ eval { OWX_ASYNC_Schedule( $hash, OWXAD_PT_GetPage($hash,"reading",0)); @@ -807,7 +737,7 @@ sub OWAD_GetValues($) { $ret .= $ret3 if( defined($ret3) ); if( $ret ne "" ){ - return "OWAD: Could not get values from device $name, reason $ret"; + return "OWAD: Could not get reading, alarm and status values from device $name, reason $ret"; } return undef; @@ -944,17 +874,17 @@ sub OWAD_Set($@) { #-- re-intialize if($key eq "initialize") { - OWAD_Initialize($hash); + OWAD_InitializeDevice($hash); return undef; } #-- set new timer interval if($key eq "interval") { # check value - return "OWAD: Set with short interval, must be > 1" - if(int($value) < 1); + return "OWAD: set $name interval must be >= 0" + if(int($value) < 0); # update timer - $hash->{INTERVAL} = $value; + $hash->{INTERVAL} = int($value); RemoveInternalTimer($hash); InternalTimer(gettimeofday()+$hash->{INTERVAL}, "OWAD_GetValues", $hash, 0); return undef; @@ -1239,7 +1169,7 @@ sub OWFSAD_GetPage($$$) { } #-- and now from raw to formatted values $hash->{PRESENT} = 1; - if( $final==1){ + if( $final==1 ){ my $value = OWAD_FormatValues($hash); Log 5, $value; } @@ -1335,26 +1265,36 @@ sub OWXAD_BinValues($$$$$$$) { #-- hash of the busmaster my $master = $hash->{IODev}; my $name = $hash->{NAME}; - my @data=[]; + my $error = 0; + my @data = []; my $value; my $msg; - OWX_WDBG($name,"OWXAD_BinValues called for device $name in context $context with ",$res) - if( $main::owx_debug>2 ); + + OWX_WDBGL($name,4,"OWXAD_BinValues: called for device $name in context $context with data ",$res); my $final = ($context =~ /\.final$/ ); my ($ow_thn,$ow_tln); - #-- process results - @data=split(//,$res); - if (@data != 10){ - $msg="$name returns invalid data length, ".int(@data)." instead of 10 bytes "; - }elsif (OWX_CRC16($crcpart.substr($res,0,8),$data[8],$data[9])==0){ - $msg="$name returns invalid CRC " - }else{ - $msg="No error "; + #-- we have to get rid of the first 12 bytes + if( length($res) == 22 ){ + $res=substr($res,12); } - OWX_WDBG($name,"OWXAD_BinValues: ".$msg,$crcpart) - if( $main::owx_debug>2 ); + @data=split(//,$res); + $crcpart = $crcpart.substr($res,0,8); + + #-- process results + if (int(@data) != 10){ + $msg = "$name: invalid data length, ".int(@data)." instead of 10 bytes "; + $error = 1; + }elsif (OWX_CRC16($crcpart,$data[8],$data[9])==0){ + $msg ="$name: invalid CRC "; + $error = 1; + }else{ + $msg = "$name: no error "; + } + OWX_WDBGL($name,5-4*$error,"OWXAD_BinValues: context $context ".$msg,$res); + $hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1 + if( $error ); #=============== get the voltage reading =============================== if( $context =~ /^ds2450.getreading/ ){ @@ -1424,7 +1364,7 @@ sub OWXAD_BinValues($$$$$$$) { } #-- and now from raw to formatted values $hash->{PRESENT} = 1; - if( $final ){ + if( ($final) && (!$error) ){ my $value = OWAD_FormatValues($hash); } return undef @@ -1458,14 +1398,21 @@ sub OWXAD_GetPage($$$@) { #=============== get the voltage reading =============================== if( $page eq "reading") { #-- issue the match ROM command \x55 and the start conversion command - OWX_Reset($master); - $res= OWX_Complex($master,$owx_dev,"\x3C\x0F\x00\xFF\xFF",0); - if( $res eq 0 ){ - return "not accessible for conversion"; - } - #-- conversion needs some 5 ms per channel - select(undef,undef,undef,0.02); - + #-- OLD OWX interface + if( !$master->{ASYNCHRONOUS} ){ + OWX_Reset($master); + $res= OWX_Complex($master,$owx_dev,"\x3C\x0F\x00\xFF\xFF",0); + if( $res eq 0 ){ + return "not accessible for conversion"; + } + #-- conversion needs some 5 ms per channel + select(undef,undef,undef,0.02); + #-- NEW OWX interface + }else{ + #### master slave context proc owx_dev data crcpart numread startread callback delay + # 1 additional reset after last action + OWX_Qomplex($master, $hash, "convert", 4, $owx_dev, "\x3C\x0F\x00\xFF\xFF", 0, 0, undef, undef, 0.02); + } #-- issue the match ROM command \x55 and the read conversion page command # \xAA\x00\x00 $select="\xAA\x00\x00"; @@ -1484,6 +1431,7 @@ sub OWXAD_GetPage($$$@) { return "wrong memory page requested from $owx_dev"; } my $context = "ds2450.get".$page.($final ? ".final" : ""); + my $proc = ($final ? 1 : 0); #-- OLD OWX interface if( !$master->{ASYNCHRONOUS} ){ #-- reset the bus @@ -1495,12 +1443,13 @@ sub OWXAD_GetPage($$$@) { return "$owx_dev has returned invalid data" if( length($res)!=22); #-- for processing we also need the 3 command bytes - return OWXAD_BinValues($hash,$context,1,undef,$owx_dev,$select,substr($res,12,10)); + return OWXAD_BinValues($hash,$context,$proc,$owx_dev,$select,10,substr($res,12,10)); + #-- NEW OWX interface }else{ #### master slave context proc owx_dev data crcpart numread startread callback delay # 1 additional reset after last action - OWX_Qomplex($master, $hash, $context, 1, $owx_dev, $select, $select, 10, 12, \&OWXAD_BinValues, 0); + OWX_Qomplex($master, $hash, $context, 0, $owx_dev, $select, $select, 22, 0, \&OWXAD_BinValues, 0.01); return undef; } } @@ -1536,8 +1485,6 @@ sub OWXAD_SetPage($$) { $select .= sprintf "%c\xFF\xFF\xFF",int($hash->{owg_vhigh}->[$i]*256000/$owg_range[$i]); } -#++Use of uninitialized value within @owg_vlow in multiplication at -#++/usr/share/fhem/FHEM/21_OWAD.pm line 1362. #=============== set the status =============================== } elsif ( $page eq "status" ) { my ($sb1,$sb2)=(0,0); @@ -1579,8 +1526,8 @@ sub OWXAD_SetPage($$) { } #-- NEW OWX interface }else{ - #### master slave context proc owx_dev data crcpart numread startread callback delay - OWX_Qomplex($master, $hash, undef, 0, $owx_dev, $select, 0, 0, 0, undef, 0); + #### master slave context proc owx_dev data crcpart numread startread callback delay + OWX_Qomplex($master, $hash, "ds2450.set", 0, $owx_dev, $select, 0, 0, 0, undef, undef); } return undef; } @@ -1786,7 +1733,7 @@ sub OWXAD_PT_SetPage($$) { code
  • <interval> -
    Measurement interval in seconds. The default is 300 seconds.
  • +
    Measurement interval in seconds. The default is 300 seconds, a value of 0 disables the automatic update.
    @@ -1794,7 +1741,7 @@ sub OWXAD_PT_SetPage($$) {
    • set <name> interval <int>
      Measurement - interval in seconds. The default is 300 seconds.
    • + interval in seconds. The default is 300 seconds, a value of 0 disables the automatic update.

    @@ -1803,13 +1750,6 @@ sub OWXAD_PT_SetPage($$) {
  • get <name> id
    Returns the full 1-Wire device id OW_FAMILY.ROM_ID.CRC
  • -
  • - get <name> present - -
    Returns 1 if this 1-Wire device is present, otherwise 0.
  • -
  • - get <name> interval
    Returns measurement interval in - seconds.
  • get <name> reading
    Obtain the measuement values.
  • @@ -1830,6 +1770,9 @@ sub OWXAD_PT_SetPage($$) {
    character string for denoting low alarm condition, default is ↓
  • attr <name> stateAH1 <string>
    character string for denoting high alarm condition, default is ↑
  • +
  • + attr <name> interval <int>
    Measurement + interval in seconds. The default is 300 seconds, a value of 0 disables the automatic update.
  • For each of the following attributes, the channel identification A,B,C,D may be used.
    • attr <name> <channel>Name <string>[|<string>] diff --git a/fhem/FHEM/21_OWCOUNT.pm b/fhem/FHEM/21_OWCOUNT.pm index 537bcbf48..aa6dc374a 100644 --- a/fhem/FHEM/21_OWCOUNT.pm +++ b/fhem/FHEM/21_OWCOUNT.pm @@ -11,58 +11,6 @@ # ######################################################################################## # -# define OWCOUNT [] [interval] or OWCOUNT . [interval] -# -# where may be replaced by any name string -# -# is a 1-Wire device type DS2423,DS2423ene,wDS2423eold. If omitted, we assume this to be an -# DS2423 Counter/RAM -# is a 1-Wire family id, currently allowed value is 1D -# is a 12 character (6 byte) 1-Wire ROM ID -# without Family ID, e.g. A2D90D000800 -# [interval] is an optional query interval in seconds -# -# get id => FAM_ID.ROM_ID.CRC -# get present => 1 if device present, 0 if not -# get interval => query interval -# get memory => 32 byte string from page 0..13 -# get midnight => todays starting value (formatted) for counter -# get month => summary and average for month -# get year => summary and average for year -# get raw => raw value for counter -# get counters => formatted values for both counters -# get version => OWX version number -# -# set interval => set query interval for measurement -# set memory => 32 byte string into page 0..13 -# set midnight => todays starting value for counter -# set counter => correct midnight value such that -# counter shows this value -# -# Additional attributes are defined in fhem.cfg, in some cases per channel, where =A,B -# -# attr LogM = device name (not file name) of monthly log file -# attr LogY = device name (not file name) of yearly log file -# attr nomemory = 1|0 (when set to 1, disables use of internal memory) -# attr Name [|] = name for the channel [|short name used in state reading] -# attr Unit = unit of measurement used in state reading (default cts, none for empty) -# attr Rate [|] = name for the channel rate [|short name used in state reading] -# attr Offset = offset added to the reading in this channel -# attr Factor = factor multiplied to (reading+offset) in this channel -# attr Mode = counting mode = normal(default) or daily -# attr Period = period for rate calculation = hour (default), minute or second -# -# In normal counting mode each returned counting value will be factor*(reading+offset) -# In daily counting mode each returned counting value will be factor*(reading+offset)-midnight -# where midnight is stored as string in the 32 byte memory associated with the counter -# -# Log Lines -# after each interval : / / : / / -# example: 2012-07-30_00:07:55 OWX_C Taste: 17.03 p 28.1 p/h B: 7.0 cts 0.0 cts/min -# after midnight : : -# example: 2012-07-30_00:00:57 OWX_C D29: 2012-7-29_23:59:59 Taste: 110.0 p, B: 7.0 cts -######################################################################################## -# # This programm 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 @@ -99,7 +47,7 @@ no warnings 'deprecated'; sub Log3($$$); -my $owx_version="6.11"; +my $owx_version="7.0"; #-- fixed raw channel name, flexible channel name my @owg_fixed = ("A","B"); my @owg_channel = ("A","B"); @@ -111,9 +59,7 @@ my $owgauto = 0; my %gets = ( "id" => "", - "present" => "", - "interval" => "", - "mcache" => "", + "mcache" => "", "memory" => "", "midnight" => "", "raw" => "", @@ -197,7 +143,7 @@ sub OWCOUNT_Define ($$) { $interval = 300; $scale = ""; $ret = ""; - + #-- check syntax return "OWCOUNT: Wrong syntax, must be define OWCOUNT [] [interval] or OWCOUNT . [interval]" if(int(@a) < 2 || int(@a) > 5); @@ -266,6 +212,7 @@ sub OWCOUNT_Define ($$) { $hash->{ROM_ID} = "$fam.$id.$crc"; $hash->{OW_ID} = $id; $hash->{OW_FAMILY} = $fam; + $hash->{ERRCOUNT} = 0; $hash->{PRESENT} = 0; $hash->{INTERVAL} = $interval; @@ -358,7 +305,7 @@ sub OWCOUNT_InitializeDevice($) { $hash->{owg_midnight}->[$i] = ""; $hash->{owg_str}->[$i] = ""; } - $hash->{memory} = ""; + $hash->{DATA}{memory} = ""; #-- Set state to initialized readingsSingleUpdate($hash,"state","initialized",1); @@ -373,7 +320,7 @@ sub OWCOUNT_InitializeDevice($) { # Parameter hash = hash of device addressed # a = argument array # -######################################################################################## +####################################################################################### sub OWCOUNT_Attr(@) { my ($do,$name,$key,$value) = @_; @@ -386,9 +333,9 @@ sub OWCOUNT_Attr(@) { #-- interval modified at runtime $key eq "interval" and do { #-- check value - return "OWCOUNT: Set with short interval, must be > 1" if(int($value) < 1); + return "OWCOUNT: set $name interval must be >= 0" if(int($value) < 0); #-- update timer - $hash->{INTERVAL} = $value; + $hash->{INTERVAL} = int($value); if ($init_done) { RemoveInternalTimer($hash); InternalTimer(gettimeofday()+$hash->{INTERVAL}, "OWCOUNT_GetValues", $hash, 0); @@ -513,7 +460,7 @@ sub OWCOUNT_FormatValues($) { OWCOUNT_ChannelNames($hash); #-- Check, whether we have a new day at the next reading - $deltim = $hour*60.0+$min+$sec/60.0 - (1440 - $hash->{INTERVAL}/60.0); + $deltim = $hour*60.0+$min+$sec/60.0 + $hash->{INTERVAL}/60.0 - 1440; #$deltim = $min+$sec/60.0 - 55; if( $deltim>=0 ){ $daybreak = 1; @@ -530,6 +477,7 @@ sub OWCOUNT_FormatValues($) { readingsBeginUpdate($hash); #-- Check memory string only if model is defined automatically + # TODO: REMOVE THIS TAKES TOO MUCH TIME IN FORMAT if( $owgauto ){ my $msg = "OWCOUNT: In device $name, "; if( $owg_memory[2]==1 ){ @@ -620,9 +568,13 @@ sub OWCOUNT_FormatValues($) { #--midnight extrapolation only possible if previous measurement if( $daybreak==1 ){ #-- linear extrapolation - $dt = -$delf/$delt; - $dval = int(($vval+($vval-$oldval)*$dt)*10000+0.5)/10000; - + if( $delt > 0.0 ){ + $dt = -$delf/$delt; + $dval = int(($vval+($vval-$oldval)*$dt)*10000+0.5)/10000; + Log3 $name,5,"OWCOUNT: midnight exploration $name channel ".$owg_channel[$i]." with time delta $delt, dt $dt and dval=$dval"; + }else{ + Log3 $name,5,"OWCOUNT: midnight exploration $name channel ".$owg_channel[$i]." fails because of zero time delta. dval=$dval"; + } if( $daily == 1 ){ $dval2 = $dval+$hash->{owg_midnight}->[$i]; } else { @@ -630,10 +582,10 @@ sub OWCOUNT_FormatValues($) { } #-- in any mode store the interpolated value in the midnight store - my $msg = sprintf("%4d-%02d-%02d midnight %7.2f", + my $msg = sprintf("%4d-%02d-%02d midnight %7.2f ", $year+1900,$month+1,$day,$dval2); + Log3 $name,5,"OWCOUNT: measured $name value $vval (midnight ".$hash->{owg_midnight}->[$i].") => extrapolated midnight $dval2"; OWCOUNT_SetPage($hash,14+$i,$msg); - Log3 $name,5,"OWCOUNT: measured value $vval (midnight ".$hash->{owg_midnight}->[$i].") => new extrapolated midnight $dval2"; #-- string buildup for monthly and yearly logging $dvalue .= sprintf( " %s: %5.2f %s %sM: %%5.2f %s", $owg_channel[$i],$dval,$unit,$owg_channel[$i],$unit); @@ -669,11 +621,11 @@ sub OWCOUNT_FormatValues($) { $dvalue = sprintf($dvalue,$total0,$total1); readingsBulkUpdate($hash,"day",$dvalue); }else{ - Log3 $name,3,"OWCOUNT: No monthly summary possible, ".$monthv[0]." for device $name"; + Log3 $name,5,"OWCOUNT: No monthly summary possible, ".$monthv[0]." for device $name"; $total0 = 0; $total1 = 0; - }; - + } + if( int(@yearv) == 2 ){ $total2 = $yearv[0]->[1]; $total3 = ($month==0)?$total2: $yearv[1]->[1]; @@ -683,13 +635,13 @@ sub OWCOUNT_FormatValues($) { readingsBulkUpdate($hash,"month",$mvalue); } }else{ - Log3 $name,3,"OWCOUNT: No yearly summary possible, ".$yearv[0]." for device $name"; + Log3 $name,5,"OWCOUNT: No yearly summary possible, ".$yearv[0]." for device $name"; $total2 = 0; $total3 = 0; - }; + } } #--- memory most recently read - readingsBulkUpdate($hash,"memory",$hash->{memory}); + readingsBulkUpdate($hash,"memory",$hash->{DATA}{memory}); #-- STATE readingsBulkUpdate($hash,"state",$svalue); @@ -720,11 +672,11 @@ sub OWCOUNT_Get($@) { my ($ret1,$ret2); #-- check syntax - return "OWCOUNT: Get argument is missing @a" + return "OWCOUNT: get $name argument is missing @a" if(int(@a) < 2); #-- check argument - return "OWCOUNT: Get with unknown argument $a[1], choose one of ".join(" ", sort keys %gets) + return "OWCOUNT: get $name with unknown argument $a[1], choose one of ".join(" ", sort keys %gets) if(!defined($gets{$a[1]})); #-- get id @@ -733,32 +685,6 @@ sub OWCOUNT_Get($@) { return "$name.id => $value"; } - #-- get present - if($a[1] eq "present") { - #-- hash of the busmaster - my $master = $hash->{IODev}; - - #-- normal OWX - if( !$hash->{ASYNC} ){ - $value = OWX_Verify($master,$hash->{ROM_ID}); - $hash->{PRESENT} = $value; - return "$name.present => $value"; - #-- old asynchronous mode - }else{ - eval { - OWX_ASYNC_RunToCompletion($hash,OWX_ASYNC_PT_Verify($hash)); - }; - return GP_Catch($@) if $@; - return "$name.present => ".ReadingsVal($name,"present","unknown"); - } - } - - #-- get interval - if($a[1] eq "interval") { - $value = $hash->{INTERVAL}; - return "$name.interval => $value"; - } - #-- get version if( $a[1] eq "version") { return "$name.version => $owx_version"; @@ -829,23 +755,24 @@ sub OWCOUNT_Get($@) { #-- check syntax for getting memory page 0..13 or midnight A/B my $nomemory = defined($attr{$name}{"nomemory"}) ? $attr{$name}{"nomemory"} : 0; if( ($reading eq "memory") || ($reading eq "mcache") ){ - return "OWCOUNT: Memory usage disabled" + return "OWCOUNT: Memory usage disabled in $name" if( $nomemory==1 ); - return "OWCOUNT: Get needs parameter when reading memory/mcache: " + return "OWCOUNT: get $name memory/mcache: needs parameter " if( int(@a)<2 ); $page=int($a[2]); if( ($page<0) || ($page>13) ){ - return "OWCOUNT: Wrong memory/mcache page requested"; + return "OWCOUNT: get $name memory/mcache requested wrong page $page"; } if( $reading eq "memory" ){ $ret = OWCOUNT_GetPage($hash,$page,1,1); #-- process result if( $master->{ASYNCHRONOUS} ){ - return "OWCOUNT: $name getting memory $page, please wait for completion"; + #return "OWCOUNT: $name getting memory $page, please wait for completion"; + return undef; }else{ #-- when we have a return code, we have an error if( $ret ){ - return "OWCOUNT: Could not get values from device $name, reason: ".$ret; + return "OWCOUNT: get $name failed, reason: ".$ret; }else{ return "OWCOUNT: $name.$reading [$page] =>".$hash->{owg_str}->[$page]; } @@ -856,7 +783,7 @@ sub OWCOUNT_Get($@) { } #-- get midnight value if( $reading eq "midnight" ){ - return "OWCOUNT: get needs parameter when reading midnight: " + return "OWCOUNT: get $name midnight needs parameter " if( int(@a)<3 ); #-- find out which channel we have if( ($a[2] eq $owg_channel[0]) || ($a[2] eq "A") ){ @@ -864,16 +791,16 @@ sub OWCOUNT_Get($@) { }elsif( ($a[2] eq $owg_channel[1]) || ($a[2] eq "B") ){ $page=15; } else { - return "OWCOUNT: Invalid midnight counter address, must be A, B or defined channel name" + return "OWCOUNT: get $name midnight has invalid counter address, must be A, B or defined channel name" } $ret = OWCOUNT_GetPage($hash,$page,1,1); #-- process result if( $master->{ASYNCHRONOUS} ){ - return "OWCOUNT: $name getting midnight value $page and counter, please wait for completion"; + return undef; }else{ #-- when we have a return code, we have an error if( $ret ){ - return "OWCOUNT: Could not get values from device $name, reason: ".$ret; + return "OWCOUNT: get $name midnight failed, reason: ".$ret; }else{ return "OWCOUNT: $name.$reading [$page] =>".$hash->{owg_midnight}->[$page-14]; } @@ -882,7 +809,7 @@ sub OWCOUNT_Get($@) { #-- check syntax for getting counter if( $reading eq "raw" ){ - return "OWCOUNT: Get needs parameter when reading raw counter: " + return "OWCOUNT: get $name raw needs parameter " if( int(@a)<2 ); #-- find out which channel we have if( ($a[2] eq $owg_channel[0]) || ($a[2] eq "A") ){ @@ -890,36 +817,36 @@ sub OWCOUNT_Get($@) { }elsif( ($a[2] eq $owg_channel[1]) || ($a[2] eq "B") ){ $page=15; } else { - return "OWCOUNT: Invalid counter address, must be A, B or defined channel name" + return "OWCOUNT: get $name raw has invalid counter address, must be A, B or defined channel name" } $ret = OWCOUNT_GetPage($hash,$page,1,1); #-- process result if( $master->{ASYNCHRONOUS} ){ - return "OWCOUNT: $name getting page $page and counter, please wait for completion"; + return undef; }else{ #-- when we have a return code, we have an error if( $ret ){ - return "OWCOUNT: Could not get values from device $name, reason: ".$ret; + return "OWCOUNT: get $name raw failed, reason: ".$ret; } #-- only one counter will be returned return "OWCOUNT: $name.raw $a[2] => ".$hash->{owg_val}->[$page-14]; } #-- check syntax for getting counters }elsif( $reading eq "counters" ){ - return "OWCOUNT: Get needs no parameter when reading counters" + return "OWCOUNT: get $name counters needs no parameter" if( int(@a)==1 ); $ret1 = OWCOUNT_GetPage($hash,14,0,1); $ret2 = OWCOUNT_GetPage($hash,15,1,1); #-- process result if( $master->{ASYNCHRONOUS} ){ - return "OWCOUNT: $name getting counters, please wait for completion"; + return undef; }else{ $ret .= $ret1 if( defined($ret1) ); $ret .= $ret2 if( defined($ret2) ); if( defined($ret1) || defined($ret2) ){ - return "OWCOUNT: Could not get values from device $name, reason: ".$ret; + return "OWCOUNT: get $name counters failed, reason: ".$ret; } #-- both counters will be returned return "OWCOUNT: $name.counters => ".$hash->{READINGS}{"state"}{VAL}; @@ -1201,8 +1128,11 @@ sub OWCOUNT_GetValues($) { OWCOUNT_InitializeDevice($hash) if( $hash->{READINGS}{"state"}{VAL} eq "defined"); - #-- restart timer for updates - RemoveInternalTimer($hash); + RemoveInternalTimer($hash); + #-- auto-update for device disabled; + return undef + if( $hash->{INTERVAL} == 0 ); + #-- restart timer for updates InternalTimer(time()+$hash->{INTERVAL}, "OWCOUNT_GetValues", $hash, 0); #-- Get readings @@ -1232,6 +1162,8 @@ sub OWCOUNT_GetValues($) { sub OWCOUNT_ParseMidnight($$$) { my ($hash,$strval,$page) = @_; + + my $name = $hash->{NAME}; #-- midnight value #-- new format @@ -1247,6 +1179,7 @@ sub OWCOUNT_ParseMidnight($$$) { } else { $strval = 0.0; } + #Log 1,"============> Parsed $name midnight value $strval"; $hash->{owg_midnight}->[$page-14] = $strval; } @@ -1262,8 +1195,14 @@ sub OWCOUNT_ParseMidnight($$$) { sub OWCOUNT_Set($@) { my ($hash, @a) = @_; + my $name = $hash->{NAME}; + my $model = $hash->{OW_MODEL}; + my $ret = undef; + my $page; + my $data; my $key = $a[1]; my $value = $a[2]; + my ($cname,@cnama,@channel); #-- for the selector: which values are possible if (@a == 2){ @@ -1272,28 +1211,20 @@ sub OWCOUNT_Set($@) { } #-- check syntax - return "OWCOUNT: Set needs at least one parameter" + return "OWCOUNT: set $name needs at least one parameter" if( int(@a)<3 ); #-- check argument if( !defined($sets{$a[1]}) ){ - return "OWCOUNT: Set with unknown argument $a[1]"; + return "OWCOUNT: set $name with unknown argument $a[1]"; } - #-- define vars - my $ret = undef; - my $page; - my $data; - my $name = $hash->{NAME}; - my $model = $hash->{OW_MODEL}; - my ($cname,@cnama,@channel); - #-- set new timer interval if($key eq "interval") { # check value - return "OWCOUNT: Set with short interval, must be > 1" - if(int($value) < 1); + return "OWCOUNT: set $name interval must be >= 0" + if(int($value) < 0); # update timer - $hash->{INTERVAL} = $value; + $hash->{INTERVAL} = int($value); RemoveInternalTimer($hash); InternalTimer(gettimeofday()+$hash->{INTERVAL}, "OWCOUNT_GetValues", $hash, 0); return undef; @@ -1308,32 +1239,24 @@ sub OWCOUNT_Set($@) { #-- check syntax for setting memory page 0..13 my $nomemory = defined($attr{$name}{"nomemory"}) ? $attr{$name}{"nomemory"} : 0; if( $key eq "memory" ){ - return "OWCOUNT: Memory usage disabled" + return "OWCOUNT: set $name memory usage disabled" if( $nomemory==1 ); - return "OWCOUNT: Set needs parameter when writing memory: " + return "OWCOUNT: set $name memory needs parameter " if( int(@a)<2 ); $page=int($a[2]); if( ($page<0) || ($page>13) ){ - return "OWXCOUNT: Wrong memory page write attempted"; + return "OWXCOUNT: set $name memory with wrong page $page attempted"; } $data=$a[3]; for( my $i=4;$i 32 ){ - Log3 $name,3,"OWCOUNT: Memory data truncated to 32 characters"; - $data=substr($data,0,32); - }elsif( length($data) < 32 ){ - for(my $i=length($data)-1;$i<32;$i++){ - $data.=" "; - } - } $ret = OWCOUNT_SetPage($hash,$page,$data); } #-- other commands are per channel if( ($key eq "midnight") || ($key eq "counter" )){ - return "OWCOUNT: Set $key needs parameter: " + return "OWCOUNT: set $name $key needs parameter: " if( int(@a)<2 ); #-- find out which channel we have if( ($a[2] eq $owg_channel[0]) || ($a[2] eq "A") ){ @@ -1341,7 +1264,7 @@ sub OWCOUNT_Set($@) { }elsif( ($a[2] eq $owg_channel[1]) || ($a[2] eq "B") ){ $page=15; } else { - return "OWCOUNT: Invalid counter address, must be A, B or defined channel name" + return "OWCOUNT: set $name $key has invalid counter address, must be A, B or defined channel name" } #-- mode normal or daily my $daily = 0; @@ -1350,13 +1273,13 @@ sub OWCOUNT_Set($@) { $daily = 1; } } - return "OWCOUNT: Set $key for channel $a[2] not possible, is not in daily mode" + return "OWCOUNT: set $name $key for channel $a[2] not possible, is not in daily mode" if( $daily==0 ); my ($sec, $min, $hour, $day, $month, $year, $wday,$yday,$isdst) = localtime(time); if( $key eq "midnight" ){ - $data = sprintf("%4d-%02d-%02d midnight %7.2f", + $data = sprintf("%4d-%02d-%02d midnight %7.2f ", $year+1900,$month+1,$day,$a[3]); $ret = OWCOUNT_SetPage($hash,$page,$data); } @@ -1364,19 +1287,19 @@ sub OWCOUNT_Set($@) { if( $key eq "counter" ){ my $midnew=($hash->{owg_val}->[$page-14] + $hash->{READINGS}{$owg_channel[$page-14]}{OFFSET})* $hash->{READINGS}{$owg_channel[$page-14]}{FACTOR} - $a[3]; - $data = sprintf("%4d-%02d-%02d midnight %7.2f", + $data = sprintf("%4d-%02d-%02d midnight %7.2f ", $year+1900,$month+1,$day,$midnew); - Log3 $name,5,"OWCOUNT: old midnight vakue ".$hash->{owg_midnight}->[$page-14].", replaced by $midnew"; + Log3 $name,1,"OWCOUNT: old midnight value for device $name ".$hash->{owg_midnight}->[$page-14].", replaced by $midnew"; $ret = OWCOUNT_SetPage($hash,$page,$data); } } #-- process results - we have to reread the device if( defined($ret) && ($ret ne "") ){ - return "OWCOUNT: Could not set device $name, reason: ".$ret; + return "OWCOUNT: set $name $key failed, reason: ".$ret; } - - OWCOUNT_GetValues($hash); - Log3 $name,5, "OWCOUNT: Set $hash->{NAME} $key $value"; + #-- Took this out, not possible in asynchronoues mode + #OWCOUNT_GetValues($hash); + Log3 $name,5, "OWCOUNT: set $name $key $value"; } ####################################################################################### @@ -1399,7 +1322,11 @@ sub OWCOUNT_SetPage ($$$) { #-- check if memory usage has been disabled my $nomemory = defined($attr{$name}{"nomemory"}) ? $attr{$name}{"nomemory"} : 0; - + + #Log 1,"=========> device $name set page $page with nomemory=$nomemory and data of length ".length($data)." has data >$data< "; + + $data=sprintf("%-32s",$data); + if( $nomemory==0 ){ #-- OWX interface if( $interface eq "OWX" ){ @@ -1414,12 +1341,12 @@ sub OWCOUNT_SetPage ($$$) { $ret = OWFSCOUNT_SetPage($hash,$page,$data); #-- Unknown interface }else{ - return "OWCOUNT: SetPage with wrong IODev type $interface"; + return "OWCOUNT: SetPage $name with wrong IODev type $interface"; } #-- process results if( defined($ret) && ($ret ne "") ){ - return "OWCOUNT: Could not set device $name, reason: ".$ret; + return "OWCOUNT: SetPage $name failed, reason: ".$ret; } }else{ if( $page==14 ){ @@ -1449,11 +1376,12 @@ sub OWCOUNT_store($$$) { if( $ret) { print OWXFILE $data; Log3 $name,1, "OWCOUNT_store: $name $data"; - close(OWXFILE); + close(OWXFILE); + return undef; } else { Log3 $name,1,"OWCOUNT_store: Cannot open $filename for writing!"; - } - return $ret; + return $ret; + } } ######################################################################################## @@ -1644,105 +1572,114 @@ sub OWXCOUNT_BinValues($$$$$$$) { #-- hash of the busmaster my $master = $hash->{IODev}; my $name = $hash->{NAME}; - my @data=[]; + my $error = 0; + my @data = []; my $value; my $msg; - OWX_WDBG($name,"OWCOUNT_BinValues called for device $name in context $context with ",$res) - if( $main::owx_debug>2 ); + + OWX_WDBGL($name,4,"OWXCOUNT_BinValues called for device $name in context $context with data ",$res); return undef unless (defined $context and $context =~ /^(get|set|check)page\.([\d]+)(\.final|)$/); my $cmd = $1; my $page = $2; my $final = $3; + #=============== get memory + counter =============================== if ($cmd eq "get") { my (@data,$strval,$value); my $change = 0; + + #-- we have to get rid of the first 12 bytes + if( length($res) == 54 ){ + $res=substr($res,12); + } @data=split(//,$res); + $crcpart = $crcpart.substr($res,0,40); #-- process results - if(ord($data[17])<=0){ - #-- invalid data: do not die, but change memory flags - if( $page > 13 ){ - $owg_memory[1]=0; - }else{ - $owg_memory[0]=0; - } - $owg_memory[2]=1; - $msg="memory data could not be read"; + if( int(@data) != 42){ + $error = 1; + $msg = "$name: invalid data length, ".int(@data)." instead of 42 bytes "; + + }elsif (OWX_CRC16($crcpart,$data[40],$data[41]) == 0){ + $error = 1; + $msg = "$name: invalid CRC, ".ord($data[40])." ".ord($data[41])." "; }else{ - if( $page > 13 ){ - $owg_memory[1]=1; - }else{ - $owg_memory[0]=1; - } - $owg_memory[2]=1; + $msg = "$name: no error "; } - - if( int(@data) < 42){ - $msg="$name returns invalid data length, ".int(@data)." instead of 42 bytes"; - }elsif (OWX_CRC16($crcpart.substr($res,0,40),$data[40],$data[41]) == 0){ - $msg="$name returns invalid CRC, ".ord($data[40])." ".ord($data[41]); - } - OWX_WDBG($name,"OWXCOUNT_BinValues: ".$msg,"") - if( $main::owx_debug>2 ); - + OWX_WDBGL($name,5-$error*4,"=====================> OWXCOUNT_BinValues getpage: ".$msg,$res); + #-- - my $nomemory = defined($attr{$name}{"nomemory"}) ? $attr{$name}{"nomemory"} : 0; + my $nomemory = defined($attr{$name}{"nomemory"}) ? $attr{$name}{"nomemory"} : 0; if( $nomemory==0 ){ #-- memory part, treated as string $strval=substr($res,0,32); - #Log3 $name,5,"OWCOUNT: retrieved from memory for page $page ==> $strval"; } else { $strval = OWCOUNT_recall($hash,"OWCOUNT_".$hash->{NAME}."_".$page.".dat"); - #Log3 $name,5,"OWCOUNT: retrieved from disk for page $page ==> $strval"; } $hash->{owg_str}->[$page] = defined $strval ? $strval : ""; - $hash->{memory} = defined $strval ? $strval : ""; + $hash->{DATA}{memory} = defined $strval ? $strval : ""; + #-- counter part if( ($page == 14) || ($page == 15) ){ @data=split(//,substr($res,32)); - if ( ($data[4] | $data[5] | $data[6] | $data[7]) ne "\x00" ){ - my $msg = "device $name returns invalid data ".ord($data[4])." ".ord($data[5])." ".ord($data[6])." ".ord($data[7]); - OWX_WDBG($name,"OWXCOUNT_BinValues: ".$msg,"") + #-- does not work with old emulator devices + #if ( ($data[4] | $data[5] | $data[6] | $data[7]) ne "\x00" ){ + # $error = 1; + # my $msg = "$name: invalid data in counter page ".ord($data[4])." ".ord($data[5])." ".ord($data[6])." ".ord($data[7]); + # OWX_WDBGL($name,1,"=====================> OWXCOUNT_BinValues getpage counter: ".$msg,"") + #} + if( !$error ){ + #-- counter value + $value = (ord($data[3])<<24) + (ord($data[2])<<16) +(ord($data[1])<<8) + ord($data[0]); + $hash->{owg_val}->[$page-14] = $value; + #-- midnight value + OWCOUNT_ParseMidnight($hash,$strval,$page); } - #-- counter value - $value = (ord($data[3])<<24) + (ord($data[2])<<16) +(ord($data[1])<<8) + ord($data[0]); - $hash->{owg_val}->[$page-14] = $value; - - #-- midnight value - #Log3 $name,1, "OWCOUNT_BinValues ParseMidnight: ".(defined $strval ? $strval : "undef"); - OWCOUNT_ParseMidnight($hash,$strval,$page); } - #-- and now from raw to formatted values - $hash->{PRESENT} = 1; - if( $final ) { - my $value = OWCOUNT_FormatValues($hash); + if( $error ){ + $hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1; + }else{ + $hash->{PRESENT} = 1; + #-- and now from raw to formatted values + OWCOUNT_FormatValues($hash) + if( $final ); } + #=============== set memory =============================== #-- for setting a page we need a second step where the scratchpad is copied into memory }elsif (($cmd eq "set") && !$final ) { - my $select="\x5A".substr($res,0,3); + + if( length($res) != 45){ + $error = 1; + $msg = "$name: invalid data length, ".length($res)." instead of 45 bytes "; + }else{ + $msg = "$name: no error "; + } + OWX_WDBGL($name,5-$error*4,"=====================> OWXCOUNT_BinValues: setpage ".$msg,$res); + + #-- process results + my $select="\x5A".substr($res,10,3); #### master slave context proc owx_dev data crcpart numread startread callback delay # 16 inserts at top of queue - OWX_Qomplex($master, $hash, "setpage.$page.final", 16, $owx_dev, $select, 0, 6, 10, \&OWXCOUNT_BinValues, 0); + OWX_Qomplex($master, $hash, "setpage.$page.final", 16, $owx_dev, $select, 0, 16, 0, \&OWXCOUNT_BinValues, undef); + #-- and a third step where this is finalized }elsif (($cmd eq "set") && $final ) { - if( substr($res,4,1) ne "\xAA" ){ - if( $page > 13 ){ - $owg_memory[1]=0; - }else{ - $owg_memory[0]=0; - } - }else{ - if( $page > 13){ - $owg_memory[1]=1; - }else{ - $owg_memory[0]=1; - } + #-- we have to get rid of the first 10 bytes + if( length($res) == 16 ){ + $res=substr($res,10); } - #-- change applied - $owg_memory[2]=1; + + #-- process results + if( substr($res,4,1) ne "\xAA"){ + $error = 1; + $msg = "$name: copy scratchpad to memory not successful "; + }else{ + $msg = "$name: no error "; + } + OWX_WDBGL($name,5-$error*4,"=====================> OWXCOUNT_BinValues: setpage.$page.final ".$msg,$res); + } return undef; } @@ -1771,7 +1708,7 @@ sub OWXCOUNT_GetPage($$$) { #=============== wrong value requested =============================== if( ($page<0) || ($page>15) ){ - return "wrong memory page requested"; + return "wrong memory page requested from $owx_dev"; } #=============== get memory + counter =============================== #-- issue the match ROM command \x55 and the read memory + counter command @@ -1788,16 +1725,14 @@ sub OWXCOUNT_GetPage($$$) { #-- reading 9 + 3 + 40 data bytes (32 byte memory, 4 byte counter + 4 byte zeroes) and 2 CRC bytes = 54 bytes $res=OWX_Complex($master,$owx_dev,$select,42); if( $res eq 0 ){ - return "device $owx_dev not accessible in reading page $page"; + return "$owx_dev not accessible in reading page $page"; } #-- process results if( length($res) < 54 ) { - #Log 1, "OWXCOUNT: warning, have received ".length($res)." bytes in first step"; #-- read the data in a second step $res.=OWX_Complex($master,"","",0); #-- process results if( length($res) < 54 ) { - #Log 1, "OWXCOUNT: warning, have received ".length($res)." bytes in second step"; #-- read the data in a third step $res.=OWX_Complex($master,"","",0); } @@ -1807,17 +1742,15 @@ sub OWXCOUNT_GetPage($$$) { #-- for processing we need 45 bytes return "$owx_dev not accessible in reading" if( $res eq 0 ); - return "$owx_dev has returned invalid data" + return "$owx_dev has returned invalid data of length ".length($res) if( length($res)!=54); - eval { - OWXCOUNT_BinValues($hash,$context,0,$owx_dev,$select,44,substr($res,12)); - }; - return $@ ? $@ : undef; + return OWXCOUNT_BinValues($hash,$context,0,$owx_dev,$select,44,substr($res,12)); + #-- NEW OWX interface }else{ #### master slave context proc owx_dev data crcpart numread startread callback delay # 1 additional reset after last action - OWX_Qomplex($master, $hash, $context, 1, $owx_dev, $select, $select, 44, 12, \&OWXCOUNT_BinValues, 0.01); + OWX_Qomplex($master, $hash, $context, 0, $owx_dev, $select, $select, 54, 0, \&OWXCOUNT_BinValues, undef); return undef; } } @@ -1833,7 +1766,6 @@ sub OWXCOUNT_GetPage($$$) { ######################################################################################## sub OWXCOUNT_SetPage($$$) { - my ($hash,$page,$data) = @_; my ($select, $res, $res2, $res3); @@ -1844,7 +1776,7 @@ sub OWXCOUNT_SetPage($$$) { #=============== wrong page requested =============================== if( ($page<0) || ($page>15) ){ - return "wrong memory page write attempt"; + return "OWCOUNT: device $owx_dev wrong memory page write attempt"; } #=============== midnight value ===================================== if( ($page==14) || ($page==15) ){ @@ -1885,29 +1817,15 @@ sub OWXCOUNT_SetPage($$$) { if( $res eq 0 ){ return "OWCOUNT: device $owx_dev not accessible for copying scratchpad"; } - if( substr($res,13,1) ne "\xAA" ){ - if( $page > 13){ - $owg_memory[1]=0; - }else{ - $owg_memory[0]=0; - } - }else{ - if( $page > 13){ - $owg_memory[1]=1; - }else{ - $owg_memory[0]=1; - } - } - $owg_memory[2]=1; return undef; #-- NEW OWX interface }else{ #### master slave context proc owx_dev data crcpart numread startread callback delay # 8 prevents from filling up with 0xFF - OWX_Qomplex($master, $hash, "setscratch", 8, $owx_dev, $select, $select, 35, 10, undef, 0); + OWX_Qomplex($master, $hash, "setscratch", 8, $owx_dev, $select, 0, 40, 0, undef, 0.05); #-- The third step of copying the scratchpad into memory can be scheduled only when the authorization code has been received # will be done in the callback of the following line - OWX_Qomplex($master, $hash, "setpage.".$page, 0, $owx_dev, "\xAA", 0, 35, 10, \&OWXCOUNT_BinValues, 0.01); + OWX_Qomplex($master, $hash, "setpage.".$page, 0, $owx_dev, "\xAA", 0, 45, 0, \&OWXCOUNT_BinValues, undef); } return undef; } @@ -2138,7 +2056,7 @@ sub OWXCOUNT_PT_InitializeDevicePage($$$) { code
    • <interval> -
      Measurement interval in seconds. The default is 300 seconds.
    • +
      Measurement interval in seconds. The default is 300 seconds, a value of 0 disables the automatic update.

    @@ -2146,7 +2064,11 @@ sub OWXCOUNT_PT_InitializeDevicePage($$$) {
    • set <name> interval <int>
      Measurement - interval in seconds. The default is 300 seconds.
    • + interval in seconds. The default is 300 seconds, a value of 0 disables the automatic update. + Log line after each interval <date> <name> <channel>: <value> <unit> <value> / + <unit>/<period> <channel>: <value> <unit> / <value> <unit>/<period>
      + example: 2012-07-30_00:07:55 OWX_C Taste: 17.03 p 28.1 p/h B: 7.0 cts 0.0 cts/min +
    • set <name> memory <page> <string>
      Write 32 bytes to memory page 0..13
    • @@ -2166,13 +2088,6 @@ sub OWXCOUNT_PT_InitializeDevicePage($$$) {
    • get <name> id
      Returns the full 1-Wire device id OW_FAMILY.ROM_ID.CRC
    • -
    • - get <name> present - -
      Returns 1 if this 1-Wire device is present, otherwise 0.
    • -
    • - get <name> interval
      Returns measurement interval in - seconds.
    • get <name> memory <page>
      Obtain 32 bytes from memory page 0..13 and store in cache $hash->{owg_str}->[page] as well as in reading "memory"
    • @@ -2200,14 +2115,17 @@ sub OWXCOUNT_PT_InitializeDevicePage($$$) {
      • attr <name> LogM <string> -
        device name (not file name) of monthly log file.
      • +
        device name (not file name) of monthly log file. + Log line after midnight <new date> <name> <old day> <old date> <channel>: <value> <unit> <channel>: <value> <unit> +
        example: 2012-07-30_00:00:57 OWX_C D29: 2012-7-29_23:59:59 Taste: 110.0 p, B: 7.0 cts +
      • attr <name> LogY <string>
        device name (not file name) of yearly log file.
      • attr <name> interval <int>
        Measurement - interval in seconds. The default is 300 seconds.
      • + interval in seconds. The default is 300 seconds, a value of 0 disables the automatic update.
      • attr <name> nomemory 0|1
        when set to 1, midnight values will be stored in files instead of the internal memory.