diff --git a/fhem/FHEM/21_OWAD.pm b/fhem/FHEM/21_OWAD.pm index cd0d5bdf5..d2cd7efe7 100644 --- a/fhem/FHEM/21_OWAD.pm +++ b/fhem/FHEM/21_OWAD.pm @@ -75,7 +75,7 @@ use strict; use warnings; sub Log($$); -my $owx_version="3.21"; +my $owx_version="3.23"; #-- fixed raw channel name, flexible channel name my @owg_fixed = ("A","B","C","D"); my @owg_channel = ("A","B","C","D"); @@ -259,11 +259,44 @@ sub OWAD_Define ($$) { my $interface= $hash->{IODev}->{TYPE}; #-- Start timer for updates - InternalTimer(time()+10, "OWAD_GetValues", $hash, 0); + InternalTimer(time()+60, "OWAD_GetValues", $hash, 0); return undef; } +####################################################################################### +# +# OWAD_Attr - Set one attribute value for device +# +# Parameter hash = hash of device addressed +# a = argument array +# +######################################################################################## + +sub OWAD_Attr(@) { + my ($do,@a) = @_; + + my $name = $a[0]; + my $key = $a[1]; + my $ret; + + #-- only alarm settings may be modified at runtime for now + return undef + if( $key !~ m/(.*)(Alarm|Low|High)/ ); + #-- safeguard against uninitialized devices + return undef + if( $main::defs{$name}->{READINGS}{"state"}{VAL} eq "defined" ); + + if( $do eq "set") + { + $ret = OWAD_Set($main::defs{$name},@a); + } elsif( $do eq "del"){ + if( $key =~ m/(.*)(Alarm)/ ){ + } + } + return $ret; +} + ######################################################################################## # # OWAD_ChannelNames - find the real channel names @@ -307,71 +340,6 @@ sub OWAD_ChannelNames($) { } } -######################################################################################## -# -# OWAD_InitializeDevice - delayed setting of initial readings and channel names -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWAD_InitializeDevice($) { - my ($hash) = @_; - - my $name = $hash->{NAME}; - my $interface = $hash->{IODev}->{TYPE}; - - #-- Initial readings - @owg_val = ("","","",""); - - #-- Initial alarm values - for( my $i=0;$i{ERRCOUNT} = 0; - - #-- alarm enabling - if( AttrVal($name,$owg_fixed[$i]."Alarm",undef) ){ - my $alarm = AttrVal($name,$owg_fixed[$i]."Alarm",undef); - if( $alarm eq "none" ){ - $owg_slow[$i]=0; - $owg_shigh[$i]=0; - }elsif( $alarm eq "low" ){ - $owg_slow[$i]=1; - $owg_shigh[$i]=0; - }elsif( $alarm eq "high" ){ - $owg_slow[$i]=0; - $owg_shigh[$i]=1; - }elsif( $alarm eq "both" ){ - $owg_slow[$i]=1; - $owg_shigh[$i]=1; - } - } - #-- low alarm value - no checking for correct parameters - if( AttrVal($name,$owg_fixed[$i]."Low",undef) ){ - $owg_vlow[$i] = $main::attr{$name}{$owg_fixed[$i]."Low"}; - } - #-- high alarm value - if( AttrVal($name,$owg_fixed[$i]."High",undef) ){ - $owg_vhigh[$i] = $main::attr{$name}{$owg_fixed[$i]."High"}; - } - } - #-- resolution in bit - fixed for now - @owg_resoln = (16,16,16,16); - #-- raw range in mV - fixed for now - @owg_range = (5100,5100,5100,5100); - #-- OWX interface - if( $interface eq "OWX" ){ - OWXAD_SetPage($hash,"status"); - OWXAD_SetPage($hash,"alarm"); - #-- OWFS interface - }elsif( $interface eq "OWServer" ){ - OWFSAD_SetPage($hash,"status"); - OWFSAD_SetPage($hash,"alarm"); - } - - #-- Set state to initialized - readingsSingleUpdate($hash,"state","initialized",1); -} - ######################################################################################## # # OWAD_FormatValues - put together various format strings @@ -407,110 +375,95 @@ sub OWAD_FormatValues($) { #-- no change in any value if invalid reading for (my $i=0;$i{READINGS}{"state"}{VAL} eq "defined"); - + #-- put into READINGS readingsBeginUpdate($hash); #-- formats for output for (my $i=0;$i{tempf}{$owg_fixed[$i]}{function} = $vfunc; + + #-- replace by proper values (VA -> $owg_val[0] etc.) + # careful: how to prevent {VAL} from being replaced ? + for( my $k=0;$k{tempf}{$owg_fixed[$i]}{function} = $vfunc; + #-- determine the measured value from the function + $vfunc = $vfuncall.$vfunc; + $vfunc = eval($vfunc); + if( !$vfunc ){ + $vval = 0.0; + } elsif( $vfunc ne "" ){ + $vval = int( $vfunc*1000 )/1000; + } else { + $vval = "???"; + } - #-- replace by proper values (VA -> $owg_val[0] etc.) - # careful: how to prevent {VAL} from being replaced ? - for( my $k=0;$k{READINGS}{$owg_channel[$i]}{UNITABBR}); - - #-- Test for alarm condition - $alarm = "none"; - #-- alarm signature low - if( $owg_slow[$i] == 0 ) { - } else { - $alarm="low"; - if( $vval > $vlow ){ - $owg_slow[$i] = 1; - $svalue .= $stateal0; - } else { - $galarm = 1; - $owg_slow[$i] = 2; - $svalue .= $stateal1; - } - } - #-- alarm signature high - if( $owg_shigh[$i] == 0 ) { - } else { - if( $alarm eq "low") { - $alarm="both"; - }else{ - $alarm="high"; - } - if( $vval < $vhigh ){ - $owg_shigh[$i] = 1; - $svalue .= $stateah0; - } else { - $galarm = 1; - $owg_shigh[$i] = 2; - $svalue .= $stateah1; - } - } - - #-- put into READINGS - readingsBulkUpdate($hash,"$owg_channel[$i]",$vval); + #-- string buildup for return value, STATE and alarm + $svalue .= sprintf( "%s: %5.3f %s", $owg_channel[$i], $vval,$hash->{READINGS}{$owg_channel[$i]}{UNITABBR}); + + #-- Test for alarm condition + $alarm = "none"; + #-- alarm signature low + if( $owg_slow[$i] == 0 ) { + } else { + $alarm="low"; + if( $vval > $vlow ){ + $owg_slow[$i] = 1; + $svalue .= $stateal0; + } else { + $galarm = 1; + $owg_slow[$i] = 2; + $svalue .= $stateal1; } } + #-- alarm signature high + if( $owg_shigh[$i] == 0 ) { + } else { + if( $alarm eq "low") { + $alarm="both"; + }else{ + $alarm="high"; + } + if( $vval < $vhigh ){ + $owg_shigh[$i] = 1; + $svalue .= $stateah0; + } else { + $galarm = 1; + $owg_shigh[$i] = 2; + $svalue .= $stateah1; + } + } + + #-- put into READINGS + readingsBulkUpdate($hash,"$owg_channel[$i]",$vval); #-- insert space if( $i{READINGS}{"state"}{VAL} eq "defined"); + #-- define warnings my $warn = "none"; $hash->{ALARM} = "0"; @@ -759,6 +716,86 @@ sub OWAD_GetValues($) { return undef; } +######################################################################################## +# +# OWAD_InitializeDevice - delayed setting of initial readings and channel names +# +# Parameter hash = hash of device addressed +# +######################################################################################## + +sub OWAD_InitializeDevice($) { + my ($hash) = @_; + + my $name = $hash->{NAME}; + my $interface = $hash->{IODev}->{TYPE}; + + my $ret=""; + my ($ret1,$ret2); + + #-- Initial readings + @owg_val = ("","","",""); + + #-- Initial alarm values + for( my $i=0;$i{ERRCOUNT} = 0; + + #-- alarm enabling + if( AttrVal($name,$owg_fixed[$i]."Alarm",undef) ){ + my $alarm = AttrVal($name,$owg_fixed[$i]."Alarm",undef); + if( $alarm eq "none" ){ + $owg_slow[$i]=0; + $owg_shigh[$i]=0; + }elsif( $alarm eq "low" ){ + $owg_slow[$i]=1; + $owg_shigh[$i]=0; + }elsif( $alarm eq "high" ){ + $owg_slow[$i]=0; + $owg_shigh[$i]=1; + }elsif( $alarm eq "both" ){ + $owg_slow[$i]=1; + $owg_shigh[$i]=1; + } + } + #-- low alarm value - no checking for correct parameters + if( AttrVal($name,$owg_fixed[$i]."Low",undef) ){ + $owg_vlow[$i] = $main::attr{$name}{$owg_fixed[$i]."Low"}; + } + #-- high alarm value + if( AttrVal($name,$owg_fixed[$i]."High",undef) ){ + $owg_vhigh[$i] = $main::attr{$name}{$owg_fixed[$i]."High"}; + } + Log 1,"+++++++++> Alarm enabling for $name channel $i is $owg_slow[$i] $owg_shigh[$i] $owg_vlow[$i] $owg_vhigh[$i]"; + } + #-- resolution in bit - fixed for now + @owg_resoln = (16,16,16,16); + #-- raw range in mV - fixed for now + @owg_range = (5100,5100,5100,5100); + #-- OWX interface + if( $interface eq "OWX" ){ + $ret1 = OWXAD_SetPage($hash,"status"); + $ret2 = OWXAD_SetPage($hash,"alarm"); + #-- OWFS interface + }elsif( $interface eq "OWServer" ){ + $ret1 = OWFSAD_SetPage($hash,"status"); + $ret2 = OWFSAD_SetPage($hash,"alarm"); + } + Log 1,"Status return $ret1 $ret2"; + #-- process results + $ret .= $ret1 + if( defined($ret1) ); + $ret .= $ret2 + if( defined($ret2) ); + if( $ret ne "" ){ + return "OWAD: Could not initialize device $name, reason: ".$ret; + } + + #-- Set state to initialized + readingsSingleUpdate($hash,"state","initialized",1); + + return undef; +} + ####################################################################################### # # OWAD_Set - Set one value for device @@ -850,16 +887,17 @@ sub OWAD_Set($@) { #-- OWX interface if( $interface eq "OWX" ){ $ret = OWXAD_SetPage($hash,"status"); - return $ret - if(defined($ret)); #-- OWFS interface }elsif( $interface eq "OWServer" ){ $ret = OWFSAD_SetPage($hash,"status"); - return $ret - if(defined($ret)); } else { return "OWAD: Set with wrong IODev type $interface"; } + #-- process results + if( defined($ret) ){ + return "OWAD: Could not set device $name, reason: ".$ret; + } + #-- set alarm values (alarm voltages) }elsif( $key =~ m/(.*)(Low|High)/ ) { @@ -895,16 +933,16 @@ sub OWAD_Set($@) { #-- OWX interface if( $interface eq "OWX" ){ $ret = OWXAD_SetPage($hash,"alarm"); - return $ret - if(defined($ret)); #-- OWFS interface }elsif( $interface eq "OWServer" ){ $ret = OWFSAD_SetPage($hash,"alarm"); - return $ret - if(defined($ret)); } else { return "OWAD: Set with wrong IODev type $interface"; } + #-- process results + if( defined($ret) ){ + return "OWAD: Could not set device $name, reason: ".$ret; + } } #-- process results - we have to reread the device @@ -916,39 +954,6 @@ sub OWAD_Set($@) { return undef; } -####################################################################################### -# -# OWAD_Attr - Set one attribute value for device -# -# Parameter hash = hash of device addressed -# a = argument array -# -######################################################################################## - -sub OWAD_Attr(@) { - my ($do,@a) = @_; - - my $name = $a[0]; - my $key = $a[1]; - my $ret; - - #-- only alarm settings may be modified at runtime for now - return undef - if( $key !~ m/(.*)(Alarm|Low|High)/ ); - #-- safeguard against uninitialized devices - return undef - if( $main::defs{$name}->{READINGS}{"state"}{VAL} eq "defined" ); - - if( $do eq "set") - { - $ret = OWAD_Set($main::defs{$name},@a); - } elsif( $do eq "del"){ - if( $key =~ m/(.*)(Alarm)/ ){ - } - } - return $ret; -} - ######################################################################################## # # OWAD_Undef - Implements UndefFn function @@ -1157,7 +1162,7 @@ sub OWFSAD_SetPage($$) { OWServer_Write($master, "/$owx_add/set_alarm/high.ALL",join(',',@ral2)); #=============== wrong page write attempt =============================== } else { - return "OWXAD: Wrong memory page write attempt"; + return "wrong memory page write attempt"; } return undef; } @@ -1366,7 +1371,7 @@ sub OWXAD_SetPage($$) { } #=============== wrong page write attempt =============================== } else { - return "OWXAD: Wrong memory page write attempt"; + return "wrong memory page write attempt"; } OWX_Reset($master); @@ -1374,7 +1379,7 @@ sub OWXAD_SetPage($$) { #-- process results if( $res eq 0 ){ - return "OWXAD: Device $owx_dev not accessible for writing"; + return "device $owx_dev not accessible for writing"; } return undef; diff --git a/fhem/FHEM/21_OWCOUNT.pm b/fhem/FHEM/21_OWCOUNT.pm index e8e6f76c7..4fb452e6d 100644 --- a/fhem/FHEM/21_OWCOUNT.pm +++ b/fhem/FHEM/21_OWCOUNT.pm @@ -351,6 +351,7 @@ sub OWCOUNT_FormatValues($) { #-- 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 = $min+$sec/60.0 - 55; if( $deltim>=0 ){ $daybreak = 1; $monthbreak = 0; @@ -478,10 +479,10 @@ sub OWCOUNT_FormatValues($) { @monthv = OWCOUNT_GetMonth($hash); #-- error check if( int(@monthv) == 2 ){ - $total0 = @monthv[0]->[1]; - $total1 = @monthv[1]->[1]; + $total0 = $monthv[0]->[1]; + $total1 = $monthv[1]->[1]; }else{ - Log 3,"OWCOUNT: No monthly summary possible, ".@monthv[0]; + Log 3,"OWCOUNT: No monthly summary possible, ".$monthv[0]; $total0 = ""; $total1 = ""; }; @@ -521,6 +522,7 @@ sub OWCOUNT_Get($@) { my $ret = ""; my $page; my ($unit,$daily); + my ($ret1,$ret2); #-- check syntax return "OWCOUNT: Get argument is missing @a" @@ -596,7 +598,7 @@ sub OWCOUNT_Get($@) { #-- check syntax for getting memory page 0..13 or midnight A/B if( ($reading eq "memory") || ($reading eq "midnight") ){ if( $reading eq "memory" ){ - return "OWCOUNT: get needs parameter when reading memory: " + return "OWCOUNT: Get needs parameter when reading memory: " if( int(@a)<2 ); $page=int($a[2]); if( ($page<0) || ($page>13) ){ @@ -611,7 +613,7 @@ 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: Invalid midnight counter address, must be A, B or defined channel name" } } #-- OWX interface @@ -634,7 +636,7 @@ sub OWCOUNT_Get($@) { #-- check syntax for getting counter if( $reading eq "counter" ){ - return "OWCOUNT: get needs parameter when reading counter: " + return "OWCOUNT: Get needs parameter when reading counter: " if( int(@a)<2 ); #-- find out which channel we have if( ($a[2] eq $owg_channel[0]) || ($a[2] eq "A") ){ @@ -642,7 +644,7 @@ 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: Invalid counter address, must be A, B or defined channel name" } #-- OWX interface @@ -657,21 +659,25 @@ sub OWCOUNT_Get($@) { } #-- check syntax for getting counters }elsif( $reading eq "counters" ){ - return "OWCOUNT: get needs no parameter when reading counters" + return "OWCOUNT: Get needs no parameter when reading counters" if( int(@a)==1 ); #-- OWX interface if( $interface eq "OWX" ){ - $ret = OWXCOUNT_GetPage($hash,14); - $ret .= OWXCOUNT_GetPage($hash,15); + $ret1 = OWXCOUNT_GetPage($hash,14); + $ret2 = OWXCOUNT_GetPage($hash,15); }elsif( $interface eq "OWServer" ){ - $ret = OWFSCOUNT_GetPage($hash,14); - $ret .= OWFSCOUNT_GetPage($hash,15); + $ret1 = OWFSCOUNT_GetPage($hash,14); + $ret2 = OWFSCOUNT_GetPage($hash,15); }else{ return "OWCOUNT: GetValues with wrong IODev type $interface"; } } #-- process results - if( $ret ){ + $ret .= $ret1 + if( defined($ret1) ); + $ret .= $ret2 + if( defined($ret2) ); + if( $ret ne "" ){ return "OWCOUNT: Could not get values from device $name, reason: ".$ret; } $hash->{PRESENT} = 1; @@ -780,14 +786,11 @@ sub OWCOUNT_GetValues($) { my $model = $hash->{OW_MODEL}; my $value = ""; my $ret = ""; + my ($ret1,$ret2); #-- check if device needs to be initialized OWCOUNT_InitializeDevice($hash) if( $hash->{READINGS}{"state"}{VAL} eq "defined"); - - #-- define warnings - my $warn = "none"; - $hash->{ALARM} = "0"; #-- restart timer for updates RemoveInternalTimer($hash); @@ -799,17 +802,21 @@ sub OWCOUNT_GetValues($) { #-- Get readings according to interface type my $interface= $hash->{IODev}->{TYPE}; if( $interface eq "OWX" ){ - $ret = OWXCOUNT_GetPage($hash,14); - $ret .= OWXCOUNT_GetPage($hash,15); + $ret1 = OWXCOUNT_GetPage($hash,14); + $ret2 = OWXCOUNT_GetPage($hash,15); }elsif( $interface eq "OWServer" ){ - $ret = OWFSCOUNT_GetPage($hash,14); - $ret .= OWFSCOUNT_GetPage($hash,15); + $ret1 = OWFSCOUNT_GetPage($hash,14); + $ret2 = OWFSCOUNT_GetPage($hash,15); }else{ return "OWCOUNT: GetValues with wrong IODev type $interface"; } #-- process results - if( defined($ret) ){ + $ret .= $ret1 + if( defined($ret1) ); + $ret .= $ret2 + if( defined($ret2) ); + if( $ret ne "" ){ return "OWCOUNT: Could not get values from device $name, reason: ".$ret; } $hash->{PRESENT} = 1; diff --git a/fhem/FHEM/21_OWID.pm b/fhem/FHEM/21_OWID.pm index 09f3aca07..2b2bf74a4 100644 --- a/fhem/FHEM/21_OWID.pm +++ b/fhem/FHEM/21_OWID.pm @@ -52,7 +52,7 @@ use strict; use warnings; sub Log($$); -my $owx_version="3.21"; +my $owx_version="3.23"; #-- declare variables my %gets = ( "present" => "", diff --git a/fhem/FHEM/21_OWLCD.pm b/fhem/FHEM/21_OWLCD.pm index 61b75c3be..c363017a4 100644 --- a/fhem/FHEM/21_OWLCD.pm +++ b/fhem/FHEM/21_OWLCD.pm @@ -62,7 +62,7 @@ use strict; use warnings; sub Log($$); -my $owx_version="3.21"; +my $owx_version="3.23"; #-- controller may be HD44780 or KS0073 # these values have to be changed for different display # geometries or memory maps diff --git a/fhem/FHEM/21_OWSWITCH.pm b/fhem/FHEM/21_OWSWITCH.pm index d099f351f..838e7438b 100644 --- a/fhem/FHEM/21_OWSWITCH.pm +++ b/fhem/FHEM/21_OWSWITCH.pm @@ -293,27 +293,6 @@ sub OWSWITCH_ChannelNames($) { } } -######################################################################################## -# -# OWSWITCH_InitializeDevice - delayed setting of initial readings and channel names -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWSWITCH_InitializeDevice($) { - - my ($hash) = @_; - my $name = $hash->{NAME}; - - #-- Initial readings - for( my $i=0;$i<$cnumber{$attr{$name}{"model"}} ;$i++) { - #-- Initial readings ERR - $owg_val[$i] = 1; - $owg_vax[$i] = 0; - } -} - ######################################################################################## # # OWSWITCH_FormatValues - put together various format strings @@ -335,10 +314,6 @@ sub OWSWITCH_FormatValues($) { #-- obtain channel names OWSWITCH_ChannelNames($hash); - #-- check if device needs to be initialized - OWSWITCH_InitializeDevice($hash) - if( $hash->{READINGS}{"state"}{VAL} eq "defined"); - #-- put into READINGS readingsBeginUpdate($hash); @@ -439,7 +414,7 @@ sub OWSWITCH_Get($@) { #-- get single state if( $reading eq "input" ){ - return "OWSWITCH: get needs parameter when reading input: " + return "OWSWITCH: Get needs parameter when reading input: " if( int(@a)<2 ); my $fnd=undef; for (my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){ @@ -448,7 +423,7 @@ sub OWSWITCH_Get($@) { last; } } - return "OWSWITCH: invalid input address, must be A,B,... or defined channel name" + return "OWSWITCH: Invalid input address, must be A,B,... or defined channel name" if( !defined($fnd) ); #-- OWX interface @@ -468,7 +443,7 @@ sub OWSWITCH_Get($@) { #-- get all states }elsif( $reading eq "gpio" ){ - return "OWSWITCH: get needs no parameter when reading gpio" + return "OWSWITCH: Get needs no parameter when reading gpio" if( int(@a)==1 ); if( $interface eq "OWX" ){ @@ -502,8 +477,10 @@ sub OWSWITCH_GetValues($) { my $model = $hash->{OW_MODEL}; my $value = ""; my $ret = ""; - my $offset; - my $factor; + + #-- check if device needs to be initialized + OWSWITCH_InitializeDevice($hash) + if( $hash->{READINGS}{"state"}{VAL} eq "defined"); #-- restart timer for updates RemoveInternalTimer($hash); @@ -545,6 +522,31 @@ sub OWSWITCH_GetValues($) { return undef; } +######################################################################################## +# +# OWSWITCH_InitializeDevice - initial readings +# Parameter hash = hash of device addressed +# +######################################################################################## + +sub OWSWITCH_InitializeDevice($) { + + my ($hash) = @_; + my $name = $hash->{NAME}; + + #-- Initial readings + for( my $i=0;$i<$cnumber{$attr{$name}{"model"}} ;$i++) { + #-- Initial readings ERR + $owg_val[$i] = 1; + $owg_vax[$i] = 0; + } + + #-- Set state to initialized + readingsSingleUpdate($hash,"state","initialized",1); + + return undef; +} + ####################################################################################### # # OWSWITCH_Set - Set one value for device @@ -563,7 +565,9 @@ sub OWSWITCH_Set($@) { my $name = $hash->{NAME}; my $model = $hash->{OW_MODEL}; - my ($ret,$cname,@cnama,@channel); + my ($cname,@cnama,@channel); + my $ret=""; + my ($ret1,$ret2); #-- for the selector: which values are possible if (@a == 2){ @@ -578,7 +582,7 @@ sub OWSWITCH_Set($@) { #-- reset the device if($key eq "init") { - return "OWSWITCH: init needs parameter 'yes'" + return "OWSWITCH: Set init needs parameter 'yes'" if($value ne "yes"); OWSWITCH_InitializeDevice($hash); return "OWSWITCH: Re-initialized device $name"; @@ -604,7 +608,7 @@ sub OWSWITCH_Set($@) { #-- set single state if( $key eq "output" ){ - return "OWSWITCH: get needs parameter when writing output: " + return "OWSWITCH: Set needs parameter when writing output: " if( int(@a)<2 ); #-- find out which channel we have my $fnd=undef; @@ -614,7 +618,7 @@ sub OWSWITCH_Set($@) { last; } } - return "OWSWITCH: invalid output address, must be A,B,... or defined channel name" + return "OWSWITCH: Invalid output address, must be A,B,... or defined channel name" if( !defined($fnd) ); #-- prepare gpio value @@ -652,7 +656,7 @@ sub OWSWITCH_Set($@) { #-- OWX interface if( $interface eq "OWX" ){ - $ret = OWXSWITCH_GetState($hash); + $ret1 = OWXSWITCH_GetState($hash); $value = 0; #-- vax or val ? for (my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){ @@ -661,10 +665,10 @@ sub OWSWITCH_Set($@) { $value += ($nval<<$i) if( $i == $fnd ); } - $ret = OWXSWITCH_SetState($hash,$value); + $ret2 = OWXSWITCH_SetState($hash,$value); #-- OWFS interface }elsif( $interface eq "OWServer" ){ - $ret = OWFSSWITCH_GetState($hash); + $ret1 = OWFSSWITCH_GetState($hash); $value = 0; #-- vax or val ? for (my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){ @@ -673,11 +677,19 @@ sub OWSWITCH_Set($@) { $value += ($nval<<$i) if( $i == $fnd ); } - $ret = OWFSSWITCH_SetState($hash,$value); + $ret2 = OWFSSWITCH_SetState($hash,$value); #-- Unknown interface }else{ return "OWSWITCH: Get with wrong IODev type $interface"; } + #-- process results + $ret .= $ret1 + if( defined($ret1) ); + $ret .= $ret2 + if( defined($ret2) ); + if( $ret ne "" ){ + return "OWSWITCH: Could not set device $name, reason: ".$ret; + } #-- set state }elsif( $key eq "gpio" ){ @@ -692,6 +704,10 @@ sub OWSWITCH_Set($@) { }else{ return "OWSWITCH: GetValues with wrong IODev type $interface"; } + #-- process results + if( defined($ret) ){ + return "OWSWITCH: Could not set device $name, reason: ".$ret; + } } #-- process results - we have to reread the device @@ -1019,7 +1035,7 @@ sub OWXSWITCH_SetState($$) { #-- read the data $res=OWX_Complex($master,$owx_dev,$select,2); if( $res eq 0 ){ - return "OWXSWITCH: Device $owx_dev not accessible in writing"; + return "device $owx_dev not accessible in writing"; } #-- reset the bus OWX_Reset($master); @@ -1029,7 +1045,7 @@ sub OWXSWITCH_SetState($$) { #-- very crude check - should be CRC if( int(@data) != 6){ - return "OWXSWITCH: State could not be set for device $owx_dev"; + return "state could not be set for device $owx_dev"; } #-- put into local buffer @@ -1049,14 +1065,14 @@ sub OWXSWITCH_SetState($$) { #-- read the data $res=OWX_Complex($master,$owx_dev,$select,1); if( $res eq 0 ){ - return "OWXSWITCH: Device $owx_dev not accessible in writing"; + return "device $owx_dev not accessible in writing"; } #-- process results @data=split(//,substr($res,10)); if( $data[2] ne "\xAA"){ - return "OWXSWITCH: State could not be set for device $owx_dev"; + return "state could not be set for device $owx_dev"; } #-- reset the bus OWX_Reset($master); @@ -1072,7 +1088,7 @@ sub OWXSWITCH_SetState($$) { #-- read the data $res=OWX_Complex($master,$owx_dev,$select,1); if( $res eq 0 ){ - return "OWXSWITCH: Device $owx_dev not accessible in writing"; + return "device $owx_dev not accessible in writing"; } #-- reset the bus OWX_Reset($master); @@ -1081,11 +1097,11 @@ sub OWXSWITCH_SetState($$) { @data=split(//,substr($res,10)); if( $data[2] ne "\xAA"){ - return "OWXSWITCH: State could not be set for device $owx_dev"; + return "state could not be set for device $owx_dev"; } }else { - return "OWXSWITCH: Unknown device family $hash->{OW_FAMILY}\n"; + return "unknown device family $hash->{OW_FAMILY}\n"; } return undef; diff --git a/fhem/FHEM/21_OWTHERM.pm b/fhem/FHEM/21_OWTHERM.pm index 3c176a12f..12bc27c8d 100755 --- a/fhem/FHEM/21_OWTHERM.pm +++ b/fhem/FHEM/21_OWTHERM.pm @@ -72,7 +72,7 @@ use strict; use warnings; sub Log($$); -my $owx_version="3.21"; +my $owx_version="3.23"; #-- temperature globals - always the raw values from/for the device my $owg_temp = ""; my $owg_th = ""; @@ -235,97 +235,36 @@ sub OWTHERM_Define ($$) { return undef; } - -######################################################################################## + +####################################################################################### # -# OWTHERM_InitializeDevice - delayed setting of initial readings +# OWTHERM_Attr - Set one attribute value for device # # Parameter hash = hash of device addressed +# a = argument array # ######################################################################################## -sub OWTHERM_InitializeDevice($) { - my ($hash) = @_; +sub OWTHERM_Attr(@) { + my ($do,@a) = @_; - my $name = $hash->{NAME}; - my $interface = $hash->{IODev}->{TYPE}; - my @a = ($name,"",0); - my ($unit,$offset,$factor,$abbr,$value); + my $name = $a[0]; + my $key = $a[1]; + my $ret; - #-- attributes defined ? - $stateal = defined($attr{$name}{stateAL}) ? $attr{$name}{stateAL} : "▾"; - $stateah = defined($attr{$name}{stateAH}) ? $attr{$name}{stateAH} : "▴"; - $unit = defined($attr{$name}{"tempUnit"}) ? $attr{$name}{"tempUnit"} : "Celsius"; - $offset = defined($attr{$name}{"tempOffset"}) ? $attr{$name}{"tempOffset"} : 0.0 ; - $factor = 1.0; + #-- only alarm settings may be modified at runtime for now + return undef + if( $key !~ m/(.*)(Low|High)/ ); + #-- safeguard against uninitialized devices + return undef + if( $main::defs{$name}->{READINGS}{"state"}{VAL} eq "defined" ); - if( $unit eq "Celsius" ){ - $abbr = "°C"; - } elsif ($unit eq "Kelvin" ){ - $abbr = "K"; - $offset += "273.16" - } elsif ($unit eq "Fahrenheit" ){ - $abbr = "°F"; - $offset = ($offset+32)/1.8; - $factor = 1.8; - } else { - $abbr="?"; - Log 3, "OWTHERM_FormatValues: unknown unit $unit"; + if( $do eq "set") + { + $ret = OWTHERM_Set($main::defs{$name},@a); + } elsif( $do eq "del"){ } - #-- these values are rather complex to obtain, therefore save them in the hash - $hash->{READINGS}{"temperature"}{TYPE} = "temperature"; - $hash->{READINGS}{"temperature"}{UNIT} = $unit; - $hash->{READINGS}{"temperature"}{UNITABBR} = $abbr; - $hash->{ERRCOUNT} = 0; - $hash->{tempf}{offset} = $offset; - $hash->{tempf}{factor} = $factor; - - #-- Check if temperature conversion is consistent - if( $interface eq "OWX" ){ - if( defined($attr{$name}{tempConv}) && ( $attr{$name}{tempConv} eq "onkick") ){ - if( !(defined($attr{$hash->{IODev}->{NAME}}{dokick})) || - ( defined($attr{$hash->{IODev}->{NAME}}{dokick}) && ($attr{$hash->{IODev}->{NAME}}{dokick} eq "0") )){ - Log 1,"OWTHERM: Attribute tempConv=onkick changed to onread for $name because interface is not kicking"; - $attr{$name}{tempConv}="onread"; - } - } - }elsif( $interface eq "OWServer" ){ - if( !(defined($attr{$name}{tempConv})) || - (defined($attr{$name}{tempConv}) && ($attr{$name}{tempConv} eq "onread") ) ){ - Log 1,"OWTHERM: Attribute tempConv=onread changed to onkick for $name because interface is OWFS"; - $attr{$name}{tempConv}="onread"; - } - } - - #-- Set the attribute values if defined - if( defined($attr{$name}{"tempLow"}) ){ - $value = $attr{$name}{"tempLow"}; - $a[1] = "tempLow"; - $a[2] = floor($value/$factor-$offset+0.5); - #-- put into device - #-- OWX interface - if( $interface eq "OWX" ){ - OWXTHERM_SetValues($hash,@a); - #-- OWFS interface - }elsif( $interface eq "OWServer" ){ - OWFSTHERM_SetValues($hash,@a); - } - } - if( defined($attr{$name}{"tempHigh"}) ){ - $value = $attr{$name}{"tempHigh"}; - $a[1] = "tempHigh"; - $a[2] = floor($value/$factor-$offset+0.5); - #-- put into device - #-- OWX interface - if( $interface eq "OWX" ){ - OWXTHERM_SetValues($hash,@a); - #-- OWFS interface - }elsif( $interface eq "OWServer" ){ - OWFSTHERM_SetValues($hash,@a); - } - } - #-- Set state to initialized - readingsSingleUpdate($hash,"state","initialized",1); + return $ret; } ######################################################################################## @@ -362,7 +301,7 @@ sub OWTHERM_FormatValues($) { $factor = 1.8; } else { $abbr="?"; - Log 3, "OWTHERM_FormatValues: unknown unit $unit"; + Log 3, "OWTHERM_FormatValues: Unknown temperature unit $unit"; } #-- these values are rather complex to obtain, therefore save them in the hash $hash->{READINGS}{"temperature"}{UNIT} = $unit; @@ -373,10 +312,6 @@ sub OWTHERM_FormatValues($) { #-- no change in any value if invalid reading return if( $owg_temp eq ""); - #-- check if device needs to be initialized - OWTHERM_InitializeDevice($hash) - if( $hash->{READINGS}{"state"}{VAL} eq "defined"); - #-- correct values for proper offset, factor $vval = ($owg_temp + $offset)*$factor; $vlow = floor(($owg_tl + $offset)*$factor+0.5); @@ -518,6 +453,10 @@ sub OWTHERM_GetValues($@) { my $value = ""; my $ret = ""; + #-- check if device needs to be initialized + OWTHERM_InitializeDevice($hash) + if( $hash->{READINGS}{"state"}{VAL} eq "defined"); + #-- restart timer for updates RemoveInternalTimer($hash); InternalTimer(time()+$hash->{INTERVAL}, "OWTHERM_GetValues", $hash, 1); @@ -557,6 +496,108 @@ sub OWTHERM_GetValues($@) { return undef; } +######################################################################################## +# +# OWTHERM_InitializeDevice - delayed setting of initial readings +# +# Parameter hash = hash of device addressed +# +######################################################################################## + +sub OWTHERM_InitializeDevice($) { + my ($hash) = @_; + + my $name = $hash->{NAME}; + my $interface = $hash->{IODev}->{TYPE}; + my @a = ($name,"",0); + my ($unit,$offset,$factor,$abbr,$value,$ret); + + #-- attributes defined ? + $stateal = defined($attr{$name}{stateAL}) ? $attr{$name}{stateAL} : "▾"; + $stateah = defined($attr{$name}{stateAH}) ? $attr{$name}{stateAH} : "▴"; + $unit = defined($attr{$name}{"tempUnit"}) ? $attr{$name}{"tempUnit"} : "Celsius"; + $offset = defined($attr{$name}{"tempOffset"}) ? $attr{$name}{"tempOffset"} : 0.0 ; + $factor = 1.0; + + if( $unit eq "Celsius" ){ + $abbr = "°C"; + } elsif ($unit eq "Kelvin" ){ + $abbr = "K"; + $offset += "273.16" + } elsif ($unit eq "Fahrenheit" ){ + $abbr = "°F"; + $offset = ($offset+32)/1.8; + $factor = 1.8; + } else { + $abbr="?"; + Log 3, "OWTHERM_FormatValues: unknown unit $unit"; + } + #-- these values are rather complex to obtain, therefore save them in the hash + $hash->{READINGS}{"temperature"}{TYPE} = "temperature"; + $hash->{READINGS}{"temperature"}{UNIT} = $unit; + $hash->{READINGS}{"temperature"}{UNITABBR} = $abbr; + $hash->{ERRCOUNT} = 0; + $hash->{tempf}{offset} = $offset; + $hash->{tempf}{factor} = $factor; + + #-- Check if temperature conversion is consistent + if( $interface eq "OWX" ){ + if( defined($attr{$name}{tempConv}) && ( $attr{$name}{tempConv} eq "onkick") ){ + if( !(defined($attr{$hash->{IODev}->{NAME}}{dokick})) || + ( defined($attr{$hash->{IODev}->{NAME}}{dokick}) && ($attr{$hash->{IODev}->{NAME}}{dokick} eq "0") )){ + Log 1,"OWTHERM: Attribute tempConv=onkick changed to onread for $name because interface is not kicking"; + $attr{$name}{tempConv}="onread"; + } + } + }elsif( $interface eq "OWServer" ){ + if( !(defined($attr{$name}{tempConv})) || + (defined($attr{$name}{tempConv}) && ($attr{$name}{tempConv} eq "onread") ) ){ + Log 1,"OWTHERM: Attribute tempConv=onread changed to onkick for $name because interface is OWFS"; + $attr{$name}{tempConv}="onread"; + } + } + + #-- Set the attribute values if defined + if( defined($attr{$name}{"tempLow"}) ){ + $value = $attr{$name}{"tempLow"}; + $a[1] = "tempLow"; + $a[2] = floor($value/$factor-$offset+0.5); + #-- put into device + #-- OWX interface + if( $interface eq "OWX" ){ + $ret = OWXTHERM_SetValues($hash,@a); + #-- OWFS interface + }elsif( $interface eq "OWServer" ){ + $ret = OWFSTHERM_SetValues($hash,@a); + } + #-- process results + if( defined($ret) ){ + return "OWTHERM: Could not initialize device $name, reason: ".$ret; + } + } + if( defined($attr{$name}{"tempHigh"}) ){ + $value = $attr{$name}{"tempHigh"}; + $a[1] = "tempHigh"; + $a[2] = floor($value/$factor-$offset+0.5); + #-- put into device + #-- OWX interface + if( $interface eq "OWX" ){ + $ret = OWXTHERM_SetValues($hash,@a); + #-- OWFS interface + }elsif( $interface eq "OWServer" ){ + $ret = OWFSTHERM_SetValues($hash,@a); + } + #-- process results + if( defined($ret) ){ + return "OWTHERM: Could not initialize device $name, reason: ".$ret; + } + } + #-- Set state to initialized + readingsSingleUpdate($hash,"state","initialized",1); + + return undef; +} + ####################################################################################### # # OWTHERM_Set - Set one value for device @@ -640,8 +681,10 @@ sub OWTHERM_Set($@) { } else { return "OWTHERM: Set with wrong IODev type $interface"; } - return $ret - if(defined($ret)); + #-- process results + if( defined($ret) ){ + return "OWTHERM: Could not set device $name, reason: ".$ret; + } } #-- process results @@ -652,37 +695,6 @@ sub OWTHERM_Set($@) { return undef; } -####################################################################################### -# -# OWTHERM_Attr - Set one attribute value for device -# -# Parameter hash = hash of device addressed -# a = argument array -# -######################################################################################## - -sub OWTHERM_Attr(@) { - my ($do,@a) = @_; - - my $name = $a[0]; - my $key = $a[1]; - my $ret; - - #-- only alarm settings may be modified at runtime for now - return undef - if( $key !~ m/(.*)(Low|High)/ ); - #-- safeguard against uninitialized devices - return undef - if( $main::defs{$name}->{READINGS}{"state"}{VAL} eq "defined" ); - - if( $do eq "set") - { - $ret = OWTHERM_Set($main::defs{$name},@a); - } elsif( $do eq "del"){ - } - return $ret; -} - ######################################################################################## # # OWTHERM_Undef - Implements UndefFn function