diff --git a/fhem/FHEM/00_OWX.pm b/fhem/FHEM/00_OWX.pm index 773f14355..08399a595 100644 --- a/fhem/FHEM/00_OWX.pm +++ b/fhem/FHEM/00_OWX.pm @@ -33,10 +33,6 @@ # attr buspower real/parasitic - whether the 1-Wire bus is really powered or # the 1-Wire devices take their power from the data wire (parasitic is default !) # -# Ordering of subroutines in this module -# 1. Subroutines independent of bus interface type -# 2. Subroutines for a specific type of the interface -# ######################################################################################## # # This programm is free software; you can redistribute it and/or modify @@ -62,13 +58,13 @@ use warnings; #-- unfortunately some things OS-dependent my $owgdevregexp; -if ($^O=~m/linux/i) { - require Device::SerialPort; - $owgdevregexp= "/dev/"; -} else { +if( $^O =~ /Win/ ) { require Win32::SerialPort; $owgdevregexp= "com"; -} +} else { + require Device::SerialPort; + $owgdevregexp= "/dev/"; +} use vars qw{%attr %defs}; @@ -191,43 +187,30 @@ sub OWX_Define ($$) { #-- store with OWX device $hash->{INTERFACE} = "serial"; $hash->{HWDEVICE} = $owx_hwdevice; - - #-- sleeping for some time - select(undef,undef,undef,0.1); - #-- In 10 seconds discover all devices on the 1-Wire bus - InternalTimer(gettimeofday()+10, "OWX_Discover", $hash,0); - - } else { $hash->{DeviceName} = $dev; #-- Second step in case of CUNO: See if we can open it - my $msg = "OWX: CUNO/COC device $dev"; + my $msg = "OWX: COC/CUNO device $dev"; #-- hash des COC/CUNO $owx_hwdevice = $main::defs{$dev}; if($owx_hwdevice){ Log 1,$msg." defined"; #-- store with OWX device - $hash->{INTERFACE} = "CUNO"; + $hash->{INTERFACE} = "COC/CUNO"; $hash->{HWDEVICE} = $owx_hwdevice; #-- loop for some time until the state is "Initialized" - for(my $i=0;$i<6;$i++){ last if( $owx_hwdevice->{STATE} eq "Initialized"); Log 1,"OWX: Waiting, at t=$i ".$dev." is still ".$owx_hwdevice->{STATE}; - select(undef,undef,undef,10); + select(undef,undef,undef,3); } - return "OWX: Can't open ".$dev if( $owx_hwdevice->{STATE} ne "Initialized"); - #-- reset the 1-Wire system in CUNO + Log 1, "OWX: Can't open ".$dev if( $owx_hwdevice->{STATE} ne "Initialized"); + #-- reset the 1-Wire system in COC/CUNO CUL_SimpleWrite($owx_hwdevice, "Oi"); }else{ Log 1, $msg." not defined"; return $msg." not defined"; - } - #-- sleeping for some time - select(undef,undef,undef,0.5); - #-- In 10 seconds discover all devices on the 1-Wire bus - InternalTimer(gettimeofday()+10, "OWX_Discover", $hash,0); - + } } #-- Third step: see, if a bus interface is detected if (!OWX_Detect($hash)){ @@ -236,7 +219,10 @@ sub OWX_Define ($$) { $init_done = 1; return undef; } - + #-- Fourth step: discovering devices on the bus + # in 10 seconds discover all devices on the 1-Wire bus + InternalTimer(gettimeofday()+10, "OWX_Discover", $hash,0); + #-- Default settings $hash->{interval} = 300; # kick every 5 minutes $hash->{followAlarms} = "off"; @@ -337,8 +323,8 @@ sub OWX_Complex ($$$$) { return OWX_Complex_SER($hash,$owx_dev,$data,$numread); #-- here we treat the CUNO/COC devices - }elsif( $owx_interface eq "CUNO" ){ - return OWX_Complex_CUNO($hash,$owx_dev,$data,$numread); + }elsif( ($owx_interface eq "COC") || ($owx_interface eq "CUNO") ){ + return OWX_Complex_CCC($hash,$owx_dev,$data,$numread); #-- interface error }else{ @@ -576,44 +562,36 @@ sub OWX_Detect ($) { $ress.=sprintf "0x%1x%1x ",$j,$k; } } - #-- here we treat the CUNO/COC + #-- here we treat the COC/CUNO } else { select(undef,undef,undef,2); - #-- Max 6 tries to detect an interface - #Log 1, "Sending $owx_hwdevice->{NAME}: ORm"; - #my $ob = CallFn($owx_hwdevice->{NAME}, "GetFn", $owx_hwdevice, (" ", "raw", "ORm")); - #Log 1, "Answer from $owx_hwdevice->{NAME}:$ob: "; - #select(undef,undef,undef,3); - for($l=0;$l<6;$l++) { - #-- write 1-Wire bus - # Log 1, "Sending $owx_hwdevice->{NAME}: ORm"; - my $ob = CallFn($owx_hwdevice->{NAME}, "GetFn", $owx_hwdevice, (" ", "raw", "ORm")); - # Log 1, "Answer from $owx_hwdevice->{NAME}:$ob: "; -# if( $owx_hwdevice->{NAME} eq "CUNO"); - - #-- process result for detection -# Log 1,"ERGEBNIS Oi =>".$ob."<="; - if( !defined($ob)){ - $ob=""; - $ret=0; - }elsif( $ob =~ m/OK.*/){ - $owx_interface="CUNO"; - $ress .= "DS2482 detected in $owx_hwdevice->{NAME}"; - $ret=1; - } else { - $ret=0; - } - last - if( $ret==1 ); - $ress .= "not found, answer was ".$ob; - Log 1, $ress; - $ress = $ress0; - #-- sleeping for some time - select(undef,undef,undef,10); + #-- type of interface + CUL_SimpleWrite($owx_hwdevice, "V"); + select(undef,undef,undef,0.01); + my ($err,$ob) = OWX_ReadAnswer_CCC($owx_hwdevice); + #my $ob = CallFn($owx_hwdevice->{NAME}, "GetFn", $owx_hwdevice, (" ", "raw", "V")); + #-- process result for detection + if( !defined($ob)){ + $ob=""; + $ret=0; + #-- COC + }elsif( $ob =~ m/.*CSM.*/){ + $owx_interface="COC"; + $ress .= "DS2482 / COC detected in $owx_hwdevice->{NAME} with response $ob"; + $ret=1; + #-- CUNO + }elsif( $ob =~ m/.*CUNO.*/){ + $owx_interface="CUNO"; + $ress .= "DS2482 / CUNO detected in $owx_hwdevice->{NAME} with response $ob"; + $ret=1; + #-- something else + } else { + $ret=0; } + #-- treat the failure cases if( $ret == 0 ){ $owx_interface=undef; - $ress .= "in $owx_hwdevice->{NAME} could not be addressed"; + $ress .= "in $owx_hwdevice->{NAME} could not be addressed, return was $ob"; } } #-- store with OWX device @@ -629,8 +607,7 @@ sub OWX_Detect ($) { # # Parameter hash = hash of bus master # -# Return 1 : OK -# 0 : no device present +# Return: List of devices in table format or undef # ######################################################################################## @@ -647,18 +624,22 @@ sub OWX_Discover ($) { my $owx_hwdevice = $hash->{HWDEVICE}; my @owx_names=(); - #-- Discover all devices on the 1-Wire bus + #-- Discover all devices on the 1-Wire bus, they will be found in $hash->{DEVS} return undef if( !defined($owx_interface) ); - #-- directly connected interface - if( $owx_interface =~ m/DS.*/ ){ + #-- Directly connected serial interface + if( ($owx_interface eq "DS2480") || ($owx_interface eq "DS9097") ){ $res = OWX_First_SER($hash,"discover"); while( $owx_LastDeviceFlag==0 && $res!=0 ){ $res = $res & OWX_Next_SER($hash,"discover"); } - #-- Ask the cuno - }else { - $res = OWX_Discover_CUNO($hash); + #-- Ask the COC/CUNO + }elsif( ($owx_interface eq "COC" ) || ($owx_interface eq "CUNO") ){ + $res = OWX_Discover_CCC($hash); + #-- Something else + } else { + Log 1,"OWX: Discover called with unknown interface"; + return undef; } #-- Go through all devices found on this bus @@ -694,8 +675,8 @@ sub OWX_Discover ($) { #-- warn if improper family id if( substr($id_fhem,0,2) ne substr($id_owx,0,2) ){ Log 1, "OWX: Warning, $fhem_dev is defined with improper family id ".substr($id_fhem,0,2). - ", correcting to ".substr($id_owx,0,2); - $main::defs{$fhem_dev}{OW_FAMILY} = substr($id_owx,0,2); + ", must enter correct model in configuration"; + #$main::defs{$fhem_dev}{OW_FAMILY} = substr($id_owx,0,2); } $exname=$main::defs{$fhem_dev}{NAME}; push(@owx_names,$exname); @@ -708,7 +689,8 @@ sub OWX_Discover ($) { # } - #-- Determine the device type + #-- Determine the device type. This is done manually here + # could be automatic as in OWServer my $acstring; my $chip; #-- Family 10 = Temperature sensor DS1820 @@ -749,7 +731,7 @@ sub OWX_Discover ($) { $acstring = "OWSWITCH DS2413"; #-- Family FF = LCD display }elsif( $owx_f eq "FF" ){ - $chip = "LCD Cont"; + $chip = "LCD"; $acstring = "OWLCD"; #-- All unknown families are ID only (ID-Chips have family id 09) } else { @@ -758,29 +740,38 @@ sub OWX_Discover ($) { } #Log 1,"###\nfor the following device match=$match, chip=$chip name=$name acstring=$acstring"; - #-- autocreate the device if necessary + #-- device exists if( $match==1 ){ - $ret .= sprintf("%s %-10s %s\n", $owx_f.$owx_rnf, $chip, $exname); - # + $ret .= sprintf("%s.%s %-10s %s\n", $owx_f,$owx_rnf, $chip, $exname); + #-- device unknoen, autocreate }else{ + #-- example code for checking global autocreate - do we want this ? + #foreach my $d (keys %defs) { + #next if($defs{$d}{TYPE} ne "autocreate"); + #return undef if(AttrVal($defs{$d}{NAME},"disable",undef)); my $acname = sprintf "OWX_%s_%s",$owx_f,$owx_rnf; #Log 1, "to define $acname $acstring $owx_rnf"; - CommandDefine(undef,"$acname $acstring $owx_rnf"); - select(undef,undef,undef,0.1); - push(@owx_names,$acname); - $main::defs{$acname}{PRESENT}=1; - #-- THIS IODev, default room - #CommandAttr (undef,"$name IODev $hash->{NAME}"); - CommandAttr (undef,"$acname room OWX"); - #-- replace the ROM ID by the proper value - $main::defs{$acname}{ROM_ID}=$owx_dev; - $ret .= sprintf("%s %-10s %s\n", $owx_f.$owx_rnf, $chip, $acname); + $res = CommandDefine(undef,"$acname $acstring $owx_rnf"); + if($res) { + $ret.= "OWX: Error autocreating with $acname $acstring $owx_rnf: $res\n"; + } else{ + select(undef,undef,undef,0.1); + push(@owx_names,$acname); + $main::defs{$acname}{PRESENT}=1; + #-- THIS IODev, default room (model is set in the device module) + CommandAttr (undef,"$acname IODev $hash->{NAME}"); + CommandAttr (undef,"$acname room OWX"); + #-- replace the ROM ID by the proper value + $main::defs{$acname}{ROM_ID}=$owx_dev; + $ret .= sprintf("%s.%s %-10s %s\n", $owx_f,$owx_rnf, $chip, $acname); + } } - - } - #-- final step: Undefine all 1-Wire devices which are not on this bus but have this IODev + #-- final step: Undefine all 1-Wire devices which + # are autocreated and + # not discovered on this bus + # but have this IODev foreach my $fhem_dev (sort keys %main::defs) { #-- skip if malformed device #next if( !defined($main::defs{$fhem_dev}{NAME}) ); @@ -791,6 +782,8 @@ sub OWX_Discover ($) { next if( uc($main::defs{$fhem_dev}{TYPE}) eq "OWFS"); next if( uc($main::defs{$fhem_dev}{TYPE}) eq "OWSERVER"); next if( uc($main::defs{$fhem_dev}{TYPE}) eq "OWDEVICE"); + #-- restrict to autocreated devices + next if( $main::defs{$fhem_dev}{NAME} !~ m/OWX_[0-9a-fA-F]{2}_/); #-- skip if the device is present. next if( $main::defs{$fhem_dev}{PRESENT} == 1); #-- skip if different IODev, but only if other IODev exists @@ -899,8 +892,10 @@ sub OWX_Reset ($) { return OWX_Reset_2480($hash); }elsif( $owx_interface eq "DS9097" ){ return OWX_Reset_9097($hash); + }elsif( $owx_interface eq "COC" ){ + return OWX_Reset_CCC($hash); }elsif( $owx_interface eq "CUNO" ){ - return OWX_Reset_CUNO($hash); + return OWX_Reset_CCC($hash); }else{ Log 3,"OWX: Reset called with unknown interface $owx_interface"; return 0; @@ -981,7 +976,7 @@ sub OWX_Undef ($$) { # Parameter hash = hash of bus master, dev = 8 Byte ROM ID of device to be tested # # Return 1 : device found -# 0 : device not +# 0 : device not found # ######################################################################################## @@ -992,12 +987,15 @@ sub OWX_Verify ($$) { #-- get the interface my $owx_interface = $hash->{INTERFACE}; - #-- directly connected interface + #-- Verify this device on the 1-Wire bus + return 0 + if( !defined($owx_interface) ); + #-- Directly connected interface if( ($owx_interface eq "DS2480") || ($owx_interface eq "DS9097") ){ return OWX_Verify_SER($hash,$dev) - #-- Ask the cuno - }elsif( $owx_interface eq "CUNO" ) { - return OWX_Verify_CUNO($hash,$dev) + #-- Ask the COC/CUNO + }elsif( ($owx_interface eq "COC" ) || ($owx_interface eq "CUNO") ){ + return OWX_Verify_CCC($hash,$dev) } else { Log 1,"OWX: Verify called with unknown interface"; return 0; @@ -1985,11 +1983,11 @@ sub OWX_WriteBit_9097 ($$) { ######################################################################################## # -# The following subroutines in alphabetical order are only for a CUNO interface +# The following subroutines in alphabetical order are only for a COC/CUNO interface # ######################################################################################## # -# OWX_Complex_CUNO - Send match ROM, data block and receive bytes as response +# OWX_Complex_CCC - Send match ROM, data block and receive bytes as response # # Parameter hash = hash of bus master, # owx_dev = ROM ID of device @@ -2001,7 +1999,7 @@ sub OWX_WriteBit_9097 ($$) { # ######################################################################################## -sub OWX_Complex_CUNO ($$$$) { +sub OWX_Complex_CCC ($$$$) { my ($hash,$owx_dev,$data,$numread) =@_; my $select; @@ -2024,35 +2022,35 @@ sub OWX_Complex_CUNO ($$$$) { $owx_ROM_ID[7-$i]=substr($owx_dev,2*$i,2); } $select=sprintf("Om%s%s%s%s%s%s%s%s",@owx_ROM_ID); - Log 3,"OWX: Sending match ROM to CUNO ".$select + Log 3,"OWX: Sending match ROM to COC/CUNO ".$select if( $owx_debug > 1); #-- CUL_SimpleWrite($owx_hwdevice, $select); - my ($err,$ob) = CUL_ReadAnswer($owx_hwdevice,"",0,undef); + my ($err,$ob) = OWX_ReadAnswer_CCC($owx_hwdevice); #-- padding first 9 bytes into result string, since we have this # in the serial interfaces as well $res .= "000000000"; } #-- has data part if ( $data ){ - OWX_Send_CUNO($hash,$data); + OWX_Send_CCC($hash,$data); $res .= $data; } #-- has receive part if( $numread > 0 ){ #$numread += length($data); - Log 3,"CUNO is expected to deliver $numread bytes" + Log 3,"COC/CUNO is expected to deliver $numread bytes" if( $owx_debug > 1); - $res.=OWX_Receive_CUNO($hash,$numread); + $res.=OWX_Receive_CCC($hash,$numread); } - Log 3,"OWX: returned from CUNO $res" + Log 3,"OWX: returned from COC/CUNO $res" if( $owx_debug > 1); return $res; } ######################################################################################## # -# OWX_Discover_CUNO - Discover devices on the 1-Wire bus via CUNO internal firmware +# OWX_Discover_CCC - Discover devices on the 1-Wire bus via internal firmware # # Parameter hash = hash of bus master # @@ -2061,7 +2059,7 @@ sub OWX_Complex_CUNO ($$$$) { # ######################################################################################## -sub OWX_Discover_CUNO ($) { +sub OWX_Discover_CCC ($) { my ($hash) = @_; my $res; @@ -2071,10 +2069,12 @@ sub OWX_Discover_CUNO ($) { #-- zero the array @{$hash->{DEVS}}=(); - OWX_ReInit_CUNO($hash,0); + #-- reset the busmaster + OWX_ReInit_CCC($hash,0); + #-- get the devices CUL_SimpleWrite($owx_hwdevice, "Oc"); select(undef,undef,undef,0.5); - my ($err,$ob) = CUL_ReadAnswer($owx_hwdevice,"",0,undef); + my ($err,$ob) = OWX_ReadAnswer_CCC($owx_hwdevice); if( $ob ){ Log 3,"OWX: Answer to ".$owx_hwdevice->{NAME}." device search is ".$ob; foreach my $dx (split(/\n/,$ob)){ @@ -2097,15 +2097,76 @@ sub OWX_Discover_CUNO ($) { ######################################################################################## # -# OWX_Receive_CUNO - Read from the CUNO +# OWX_ReadAnswer_CCC - Replacement for CUL_ReadAnswer for better control # -# Parameter: hash = hash of bus master, numread = number of bytes to read +# Parameter: hash = hash of bus master # -# Return: string received from the CUNO +# Return: string received # ######################################################################################## -sub OWX_Receive_CUNO ($$) { +sub +OWX_ReadAnswer_CCC($) +{ + my ($hash) = @_; + + my $type = $hash->{TYPE}; + + my $arg =""; + my $anydata=0; + my $regexp =undef; + + my ($mculdata, $rin) = ("", ''); + my $buf; + my $to = 3; # 3 seconds timeout + $to = $hash->{RA_Timeout} if($hash->{RA_Timeout}); # ...or less + for(;;) { + return ("Device lost when reading answer for get $arg", undef) + if(!$hash->{FD}); + + vec($rin, $hash->{FD}, 1) = 1; + my $nfound = select($rin, undef, undef, $to); + if($nfound < 0) { + next if ($! == EAGAIN() || $! == EINTR() || $! == 0); + my $err = $!; + DevIo_Disconnected($hash); + return("OWX_ReadAnswer_CCC $arg: $err", undef); + } + return ("Timeout reading answer for get $arg", undef) + if($nfound == 0); + $buf = DevIo_SimpleRead($hash); + return ("No data", undef) if(!defined($buf)); + + + + if($buf) { + Log 5, "CUL/RAW (ReadAnswer): $buf"; + $mculdata .= $buf; + } + + # \n\n is socat special + if($mculdata =~ m/\r\n/ || $anydata || $mculdata =~ m/\n\n/ ) { + if($regexp && $mculdata !~ m/$regexp/) { + CUL_Parse($hash, $hash, $hash->{NAME}, $mculdata, $hash->{initString}); + } else { + return (undef, $mculdata) + } + } + } + +} + +######################################################################################## +# +# OWX_Receive_CCC - Read data from the 1-Wire bus +# +# Parameter: hash = hash of bus master, numread = number of bytes to read +# +# Return: string received +# +######################################################################################## + +sub OWX_Receive_CCC ($$) { my ($hash,$numread) = @_; my $res=""; @@ -2117,7 +2178,10 @@ sub OWX_Receive_CUNO ($$) { for( my $i=0;$i<$numread;$i++){ #Log 1, "Sending $owx_hwdevice->{NAME}: OrB"; - my $ob = CallFn($owx_hwdevice->{NAME}, "GetFn", $owx_hwdevice, (" ", "raw", "OrB")); + #my $ob = CallFn($owx_hwdevice->{NAME}, "GetFn", $owx_hwdevice, (" ", "raw", "OrB")); + CUL_SimpleWrite($owx_hwdevice, "OrB"); + select(undef,undef,undef,0.01); + my ($err,$ob) = OWX_ReadAnswer_CCC($owx_hwdevice); #Log 1, "Answer from $owx_hwdevice->{NAME}:$ob: "; #-- process results @@ -2158,7 +2222,7 @@ sub OWX_Receive_CUNO ($$) { ######################################################################################## # -# OWX_Reset_CUNO - Reset the 1-Wire bus +# OWX_Reset_CCC - Reset the 1-Wire bus # # Parameter hash = hash of bus master # @@ -2167,7 +2231,7 @@ sub OWX_Receive_CUNO ($$) { # ######################################################################################## -sub OWX_Reset_CUNO ($) { +sub OWX_Reset_CCC ($) { my ($hash) = @_; #-- get the interface @@ -2184,7 +2248,7 @@ sub OWX_Reset_CUNO ($) { ######################################################################################## # -# OWX_ReInit_CUNO - Reset the 1-Wire bus master chip or subsystem +# OWX_ReInit_CCC - Reset the 1-Wire bus master chip or subsystem # # Parameter hash = hash of bus master # typ = 0 for bus master, 1 for subsystem @@ -2194,7 +2258,7 @@ sub OWX_Reset_CUNO ($) { # ######################################################################################## -sub OWX_ReInit_CUNO ($$) { +sub OWX_ReInit_CCC ($$) { my ($hash,$type) = @_; #-- get the interface @@ -2218,7 +2282,7 @@ sub OWX_ReInit_CUNO ($$) { ######################################################################################### # -# OWX_Send_CUNO - Send data block +# OWX_Send_CCC - Send data block # # Parameter hash = hash of bus master, data = string to send # @@ -2227,7 +2291,7 @@ sub OWX_ReInit_CUNO ($$) { # ######################################################################################## -sub OWX_Send_CUNO ($$) { +sub OWX_Send_CCC ($$) { my ($hash,$data) =@_; my ($i,$j,$k); @@ -2244,13 +2308,13 @@ sub OWX_Send_CUNO ($$) { $res2.=sprintf "0x%1x%1x ",$j,$k; CUL_SimpleWrite($owx_hwdevice, $res); } - Log 3,"OWX: Send to CUNO/COC $res2" + Log 3,"OWX: Send to COC/CUNO $res2" if( $owx_debug > 1); } ######################################################################################## # -# OWX_Verify_CUNO - Verify a particular device on the 1-Wire bus +# OWX_Verify_CCC - Verify a particular device on the 1-Wire bus # # Parameter hash = hash of bus master, dev = 8 Byte ROM ID of device to be tested # @@ -2259,7 +2323,7 @@ sub OWX_Send_CUNO ($$) { # ######################################################################################## -sub OWX_Verify_CUNO ($$) { +sub OWX_Verify_CCC ($$) { my ($hash,$dev) = @_; my $i; @@ -2267,13 +2331,13 @@ sub OWX_Verify_CUNO ($$) { #-- get the interface my $owx_hwdevice = $hash->{HWDEVICE}; - #-- Ask the CUNO/COC + #-- Ask the COC/CUNO CUL_SimpleWrite($owx_hwdevice, "OCf"); #-- sleeping for some time select(undef,undef,undef,3); CUL_SimpleWrite($owx_hwdevice, "Oc"); select(undef,undef,undef,0.5); - my ($err,$ob) = CUL_ReadAnswer($owx_hwdevice,"",0,undef); + my ($err,$ob) = OWX_ReadAnswer_CCC($owx_hwdevice); if( $ob ){ foreach my $dx (split(/\n/,$ob)){ next if ($dx !~ /^\d\d?\:[0-9a-fA-F]{16}/); @@ -2290,6 +2354,7 @@ sub OWX_Verify_CUNO ($$) { return 0; } + 1; =pod @@ -2382,5 +2447,6 @@ sub OWX_Verify_CUNO ($$) { >room, eventMap, loglevel, webCmd + =end html =cut diff --git a/fhem/FHEM/21_OWAD.pm b/fhem/FHEM/21_OWAD.pm index d3812f188..5a49cd8f2 100644 --- a/fhem/FHEM/21_OWAD.pm +++ b/fhem/FHEM/21_OWAD.pm @@ -10,12 +10,13 @@ # ######################################################################################## # -# define OWAD [] [interval] +# 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 @@ -30,7 +31,6 @@ # set interval => set period for measurement # # Additional attributes are defined in fhem.cfg, in some cases per channel, where =A,B,C,D -# Note: attributes are read only during initialization procedure - later changes are not used. # # attr stateAL0 "" = character string for denoting low normal condition, default is empty # attr stateAH0 "" = character string for denoting high normal condition, default is empty @@ -137,15 +137,12 @@ sub OWAD_Initialize ($) { $hash->{UndefFn} = "OWAD_Undef"; $hash->{GetFn} = "OWAD_Get"; $hash->{SetFn} = "OWAD_Set"; - #Name = channel name - #Offset = a v(oltage) offset added to the reading - #Factor = a v(oltage) factor multiplied with (reading+offset) - #Unit = a unit of measure + $hash->{AttrFn} = "OWAD_Attr"; my $attlist = "IODev do_not_notify:0,1 showtime:0,1 model:DS2450 loglevel:0,1,2,3,4,5 ". "event-on-update-reading event-on-change-reading ". "stateAL0 stateAL1 stateAH0 stateAH1"; - for( my $i=0;$i<4;$i++ ){ + for( my $i=0;$i OWAD [] [interval] - # e.g.: define flow OWAD 525715020000 300 + my @a = split("[ \t][ \t]*", $def); my ($name,$model,$fam,$id,$crc,$interval,$scale,$ret); @@ -182,34 +177,42 @@ sub OWAD_Define ($$) { $ret = ""; #-- check syntax - return "OWAD: Wrong syntax, must be define OWAD [] [interval]" + return "OWAD: Wrong syntax, must be define OWAD [] [interval] or OWAD . [interval]" if(int(@a) < 2 || int(@a) > 5); - - #-- check if this is an old style definition, e.g. is missing + + #-- different types of definition allowed my $a2 = $a[2]; my $a3 = defined($a[3]) ? $a[3] : ""; + #-- no model, 12 characters if( $a2 =~ m/^[0-9|a-f|A-F]{12}$/ ) { $model = "DS2450"; + $fam = "20"; $id = $a[2]; if(int(@a)>=4) { $interval = $a[3]; } + #-- no model, 2+12 characters + } elsif( $a2 =~ m/^[0-9|a-f|A-F]{2}\.[0-9|a-f|A-F]{12}$/ ) { + $fam = substr($a[2],0,2); + $id = substr($a[2],3); + if(int(@a)>=4) { $interval = $a[3]; } + if( $fam eq "20" ){ + $model = "DS2450"; + CommandAttr (undef,"$name model DS2450"); + }else{ + return "OWAD: Wrong 1-Wire device family $fam"; + } + #-- model, 12 characters } elsif( $a3 =~ m/^[0-9|a-f|A-F]{12}$/ ) { $model = $a[2]; - return "OWAD: Wrong 1-Wire device model $model" - if( $model ne "DS2450"); $id = $a[3]; if(int(@a)>=5) { $interval = $a[4]; } + if( $model eq "DS2450" ){ + $fam = "20"; + CommandAttr (undef,"$name model DS2450"); + }else{ + return "OWAD: Wrong 1-Wire device model $model"; + } } else { - return "OWAD: $a[0] ID $a[2] invalid, specify a 12 digit value"; - } - - #-- 1-Wire ROM identifier in the form "FF.XXXXXXXXXXXX.YY" - # FF = family id follows from the model - # YY must be determined from id - if( $model eq "DS2450" ){ - $fam = "20"; - CommandAttr (undef,"$name model DS2450"); - }else{ - return "OWMULTI: Wrong 1-Wire device model $model"; + return "OWAD: $a[0] ID $a[2] invalid, specify a 12 or 2.12 digit value"; } #-- determine CRC Code - only if this is a direct interface @@ -224,12 +227,13 @@ sub OWAD_Define ($$) { #-- Couple to I/O device AssignIoPort($hash); - if( !defined($hash->{IODev}->{NAME}) | !defined($hash->{IODev}) | !defined($hash->{IODev}->{PRESENT}) ){ - return "OWSWITCH: Warning, no 1-Wire I/O device found for $name."; - } - if( $hash->{IODev}->{PRESENT} != 1 ){ - return "OWSWITCH: Warning, 1-Wire I/O device ".$hash->{IODev}->{NAME}." not present for $name."; + ## | !defined($hash->{IODev}->{PRESENT}) + if( !defined($hash->{IODev}->{NAME}) | !defined($hash->{IODev}) ){ + return "OWAD: Warning, no 1-Wire I/O device found for $name."; } + #if( $hash->{IODev}->{PRESENT} != 1 ){ + # return "OWAD: Warning, 1-Wire I/O device ".$hash->{IODev}->{NAME}." not present for $name."; + #} $modules{OWAD}{defptr}{$id} = $hash; #-- readingsSingleUpdate($hash,"state","defined",1); @@ -242,7 +246,7 @@ sub OWAD_Define ($$) { InternalTimer(time()+10, "OWAD_InitializeDevice", $hash, 0); #-- Start timer for updates - InternalTimer(time()+$hash->{INTERVAL}, "OWAD_GetValues", $hash, 0); + InternalTimer(time()+10+$hash->{INTERVAL}, "OWAD_GetValues", $hash, 0); return undef; } @@ -261,9 +265,7 @@ sub OWAD_InitializeDevice($) { my $name = $hash->{NAME}; #-- Initial readings - @owg_val = ("".""."".""); - @owg_slow = ("".""."".""); - @owg_shigh = ("".""."".""); + @owg_val = ("","","",""); #-- Set channel names, channel units and alarm values for( my $i=0;$i{IODev}->{TYPE}; - - #-- OWX interface - if( !defined($interface) ){ - return "OWAD: Interface missing"; - } elsif( $interface eq "OWX" ){ - OWXAD_SetPage($hash,"alarm"); - OWXAD_SetPage($hash,"status"); - #-- OWFS interface - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSAD_GetPage($hash,"reading"); - #-- Unknown interface - }else{ - return "OWAD: InitializeDevice with wrong IODev type $interface"; - } } @@ -344,7 +335,8 @@ sub OWAD_FormatValues($) { for( my $k=0;$k{ALARM} = 0; #-- alarm signatures my $stateal1 = defined($attr{$name}{stateAL1}) ? $attr{$name}{stateAL1} : "▾"; @@ -352,6 +344,11 @@ sub OWAD_FormatValues($) { my $stateal0 = defined($attr{$name}{stateAL0}) ? $attr{$name}{stateAL0} : ""; my $stateah0 = defined($attr{$name}{stateAH0}) ? $attr{$name}{stateAH0} : ""; + #-- no change in any value if invalid reading + for (my $i=0;$i{READINGS}{"$owg_channel[$i]"}{UNITABBR}); - - #-- alarm - my $alarm = defined($attr{$name}{$owg_fixed[$i]."Alarm"}) ? $attr{$name}{$owg_fixed[$i]."Alarm"} : "none"; - my $vlow = defined($attr{$name}{$owg_fixed[$i]."Low"}) ? $attr{$name}{$owg_fixed[$i]."Low"} : 0.0; - my $vhigh = defined($attr{$name}{$owg_fixed[$i]."High"}) ? $attr{$name}{$owg_fixed[$i]."High"} : 5.0; - if( $alarm eq "low" || $alarm eq "both" ){ - $owg_slow[$i]=1; - } - if( $alarm eq "high" || $alarm eq "both" ){ - $owg_shigh[$i]=1; - }; - #-- this needs to be fixed => HOW ??? - $owg_vlow[$i] = $vlow; - $owg_vhigh[$i] = $vhigh; - + $svalue .= sprintf( "%s: %5.3f %s", $owg_channel[$i], $vval,$unarr[1]); + #-- Test for alarm condition + my $alarm = "none"; #-- alarm signature low if( $owg_slow[$i] == 0 ) { } else { + $alarm="low"; if( $vval > $vlow ){ $owg_slow[$i] = 1; $svalue .= $stateal0; @@ -436,6 +422,11 @@ sub OWAD_FormatValues($) { #-- 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; @@ -448,8 +439,20 @@ sub OWAD_FormatValues($) { #-- put into READINGS readingsBulkUpdate($hash,"$owg_channel[$i]",$vval); - readingsBulkUpdate($hash,"$owg_channel[$i]Low",$vlow); - readingsBulkUpdate($hash,"$owg_channel[$i]High",$vhigh); + #-- well - we may also put these into attributes instead of readings + if( $alarm eq "low" || $alarm eq "none" ){ + delete($main::attr{$name}{"$owg_channel[$i]High"}); + } + if( $alarm eq "high" || $alarm eq "none" ){ + delete($main::attr{$name}{"$owg_channel[$i]Low"}); + }; + if( $alarm eq "low" || $alarm eq "both" ){ + $main::attr{$name}{"$owg_channel[$i]Low"}=$vlow; + } + if( $alarm eq "high" || $alarm eq "both" ){ + $main::attr{$name}{"$owg_channel[$i]High"}=$vhigh; + }; + $main::attr{$name}{"$owg_channel[$i]Alarm"}=$alarm; } } #-- insert space @@ -460,6 +463,8 @@ sub OWAD_FormatValues($) { #-- STATE readingsBulkUpdate($hash,"state",$svalue); readingsEndUpdate($hash,1); + $hash->{ALARM} = 1 + if( $galarm == 1); return $svalue; } @@ -522,8 +527,8 @@ sub OWAD_Get($@) { if( $interface eq "OWX" ){ $ret = OWXAD_GetPage($hash,"reading"); #-- OWFS interface - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSAD_GetPage($hash,"reading"); + }elsif( $interface eq "OWServer" ){ + $ret = OWFSAD_GetPage($hash,"reading"); #-- Unknown interface }else{ return "OWAD: Get with wrong IODev type $interface"; @@ -531,7 +536,7 @@ sub OWAD_Get($@) { #-- process results if( defined($ret) ){ - return "OWAD: Could not get values from device $name"; + return "OWAD: Could not get values from device $name, reason $ret"; } $hash->{PRESENT} = 1; return "OWAD: $name.reading => ".OWAD_FormatValues($hash); @@ -543,8 +548,8 @@ sub OWAD_Get($@) { if( $interface eq "OWX" ){ $ret = OWXAD_GetPage($hash,"alarm"); #-- OWFS interface - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSAD_GetPage($hash,"alarm"); + }elsif( $interface eq "OWServer" ){ + $ret = OWFSAD_GetPage($hash,"alarm"); #-- Unknown interface }else{ return "OWAD: Get with wrong IODev type $interface"; @@ -552,7 +557,7 @@ sub OWAD_Get($@) { #-- process results if( defined($ret) ){ - return "OWAD: Could not get values from device $name"; + return "OWAD: Could not get values from device $name, reason $ret"; } $hash->{PRESENT} = 1; OWAD_FormatValues($hash); @@ -561,8 +566,8 @@ sub OWAD_Get($@) { $value = ""; for (my $i=0;$i{READINGS}{$owg_channel[$i]."Low"}{VAL}, - $hash->{READINGS}{$owg_channel[$i]."High"}{VAL}; + $main::attr{$name}{$owg_channel[$i]."Low"}, + $main::attr{$name}{$owg_channel[$i]."High"}; } return "OWAD: $name.alarm => $value"; } @@ -573,8 +578,8 @@ sub OWAD_Get($@) { if( $interface eq "OWX" ){ $ret = OWXAD_GetPage($hash,"status"); #-- OWFS interface - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSAD_GetPage($hash,"status"); + }elsif( $interface eq "OWServer" ){ + $ret = OWFSAD_GetPage($hash,"status"); #-- Unknown interface }else{ return "OWAD: Get with wrong IODev type $interface"; @@ -582,7 +587,7 @@ sub OWAD_Get($@) { #-- process results if( defined($ret) ){ - return "OWAD: Could not get values from device $name"; + return "OWAD: Could not get values from device $name, reason $ret"; } $hash->{PRESENT} = 1; OWAD_FormatValues($hash); @@ -633,8 +638,7 @@ sub OWAD_GetValues($) { my $interface= $hash->{IODev}->{TYPE}; my $value = ""; my $ret = ""; - my $offset; - my $factor; + my ($ret1,$ret2,$ret3); #-- define warnings my $warn = "none"; @@ -649,17 +653,30 @@ sub OWAD_GetValues($) { #-- Get readings, alarms and stati according to interface type if( $interface eq "OWX" ){ - $ret = OWXAD_GetPage($hash,"reading"); - $ret = OWXAD_GetPage($hash,"alarm"); - $ret = OWXAD_GetPage($hash,"status"); - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSAD_GetValues($hash); + #-- max 3 tries + for(my $try=0; $try<3; $try++){ + $ret1 = OWXAD_GetPage($hash,"reading"); + $ret2 = OWXAD_GetPage($hash,"alarm"); + $ret3 = OWXAD_GetPage($hash,"status"); + last + if( (!defined($ret)) && (!defined($ret2)) && (!defined($ret3)) ); + } + }elsif( $interface eq "OWServer" ){ + $ret1 = OWFSAD_GetPage($hash,"reading"); + $ret2 = OWFSAD_GetPage($hash,"alarm"); + $ret3 = OWFSAD_GetPage($hash,"status"); }else{ return "OWAD: GetValues with wrong IODev type $interface"; } #-- process results - if( defined($ret) ){ + $ret .= $ret1 + if( defined($ret1) ); + $ret .= $ret2 + if( defined($ret2) ); + $ret .= $ret3 + if( defined($ret3) ); + if( $ret ne "" ){ return "OWAD: Could not get values from device $name, reason $ret"; } $hash->{PRESENT} = 1; @@ -688,10 +705,12 @@ sub OWAD_Set($@) { #-- for the selector: which values are possible if (@a == 2){ my $newkeys = join(" ", sort keys %sets); - for( my $i=0;$i $mmax); - #$value /= $factor if ( $factor ); - #$value -= $offset if ( $offset ); #-- round to those numbers understood by the device my $value2 = int($value*255000/$owg_range[$channo])*$owg_range[$channo]/255000; @@ -807,10 +816,10 @@ sub OWAD_Set($@) { return $ret if(defined($ret)); #-- OWFS interface - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSAD_SetValues($hash,@a); - # return $ret - # if(defined($ret)); + }elsif( $interface eq "OWServer" ){ + $ret = OWFSAD_SetPage($hash,"alarm"); + return $ret + if(defined($ret)); } else { return "OWAD: Set with wrong IODev type $interface"; } @@ -825,6 +834,36 @@ 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)/ ); + + 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 @@ -848,9 +887,201 @@ sub OWAD_Undef ($) { # Prefix = OWFSAD # ######################################################################################## +# +# OWFSAD_GetPage - Get one memory page from device +# +# Parameter hash = hash of device addressed +# page = "reading", "alarm" or "status" +# +######################################################################################## +sub OWFSAD_GetPage($$) { + my ($hash,$page) = @_; + + #-- ID of the device + my $owx_add = substr($hash->{ROM_ID},0,15); + + #-- hash of the busmaster + my $master = $hash->{IODev}; + my $name = $hash->{NAME}; + + my ($rel,$rel2,@ral,@ral2,$i); + + #=============== get the voltage reading =============================== + if( $page eq "reading"){ + #-- get values - or should we rather use the uncached ones ? + $rel = OWServer_Read($master,"/$owx_add/volt.ALL"); + return "no return from OWServer" + if( !defined($rel) ); + return "empty return from OWServer" + if( $rel eq "" ); + + @ral = split(/,/,$rel); + + return "wrong data length from OWServer" + if( int(@ral) != 4); + for( $i=0;$i{ROM_ID},0,15); + + #-- hash of the busmaster + my $master = $hash->{IODev}; + my $name = $hash->{NAME}; + + my $i; + my @ral=(0,0,0,0); + my @ral2=(0,0,0,0); + + #=============== set the alarm values =============================== + if ( $page eq "alarm" ) { + OWServer_Write($master, "/$owx_add/set_alarm/voltlow.ALL",join(',',@owg_vlow)); + OWServer_Write($master, "/$owx_add/set_alarm/volthigh.ALL",join(',',@owg_vhigh)); + #=============== set the status =============================== + } elsif ( $page eq "status" ) { + for( $i=0;$i0); + } + if( defined($owg_shigh[$i]) ){ + $ral2[$i]=1 + if($owg_shigh[$i]>0); + } + } + } + OWServer_Write($master, "/$owx_add/set_alarm/low.ALL",join(',',@ral)); + OWServer_Write($master, "/$owx_add/set_alarm/high.ALL",join(',',@ral2)); + #=============== wrong page write attempt =============================== + } else { + return "OWXAD: Wrong memory page write attempt"; + } + return undef; +} ######################################################################################## @@ -1026,7 +1257,7 @@ sub OWXAD_SetPage($$) { #-- issue the match ROM command \x55 and the set status memory page command # \x55\x08\x00 reading 8 data bytes and 2 CRC bytes $select="\x55\x08\x00"; - for( $i=0;$i<4;$i++){ + for( $i=0;$i -

OWAD

-

FHEM module to commmunicate with 1-Wire A/D converters

Note:
This - 1-Wire module so far works only with the OWX interface module. Please define an OWX device first.

+

OWAD

+

FHEM module to commmunicate with 1-Wire A/D converters

+
This 1-Wire module works with the OWX interface module or with the OWServer interface module + (prerequisite: Add this module's name to the list of clients in OWServer). + Please define an OWX device or OWServer device first.


Example

define OWX_AD OWAD 724610000000 45 @@ -1093,7 +1325,8 @@ sub OWXAD_SetPage($$) {

Define

- define <name> OWAD [<model>] <id> [<interval>] + define <name> OWAD [<model>] <id> [<interval>] or
+ define <name> OWAD <fam>.<id> [<interval>]

Define a 1-Wire A/D converter.

  • @@ -1102,6 +1335,10 @@ sub OWXAD_SetPage($$) {
  • model DS2450 with family id 20 (default if the model parameter is omitted)
+ +
  • + <fam> +
    2-character unique family id, see above
  • <id> diff --git a/fhem/FHEM/21_OWCOUNT.pm b/fhem/FHEM/21_OWCOUNT.pm index 9896b6d2d..801e20a71 100644 --- a/fhem/FHEM/21_OWCOUNT.pm +++ b/fhem/FHEM/21_OWCOUNT.pm @@ -10,12 +10,13 @@ # ######################################################################################## # -# define OWCOUNT [] [interval] +# define OWCOUNT [] [interval] or OWCOUNT . [interval] # # where may be replaced by any name string # # is a 1-Wire device type. 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 @@ -165,36 +166,44 @@ sub OWCOUNT_Define ($$) { $ret = ""; #-- check syntax - return "OWCOUNT: Wrong syntax, must be define OWCOUNT [] [interval]" + return "OWCOUNT: Wrong syntax, must be define OWCOUNT [] [interval] or OWCOUNT . [interval]" if(int(@a) < 2 || int(@a) > 5); - #-- check if this is an old style definition, e.g. is missing + #-- different types of definition allowed my $a2 = $a[2]; my $a3 = defined($a[3]) ? $a[3] : ""; + #-- no model, 12 characters if( $a2 =~ m/^[0-9|a-f|A-F]{12}$/ ) { $model = "DS2423"; + $fam = "1D"; $id = $a[2]; if(int(@a)>=4) { $interval = $a[3]; } + #-- no model, 2+12 characters + } elsif( $a2 =~ m/^[0-9|a-f|A-F]{2}\.[0-9|a-f|A-F]{12}$/ ) { + $fam = substr($a[2],0,2); + $id = substr($a[2],3); + if(int(@a)>=4) { $interval = $a[3]; } + if( $fam eq "1D" ){ + $model = "DS2423"; + CommandAttr (undef,"$name model DS2423"); + }else{ + return "OWCOUNT: Wrong 1-Wire device family $fam"; + } + #-- model, 12 characters } elsif( $a3 =~ m/^[0-9|a-f|A-F]{12}$/ ) { $model = $a[2]; - return "OWCOUNT: Wrong 1-Wire device model $model" - if( $model ne "DS2423"); $id = $a[3]; if(int(@a)>=5) { $interval = $a[4]; } + if( $model eq "DS2423" ){ + $fam = "1D"; + CommandAttr (undef,"$name model DS2423"); + }else{ + return "OWCOUNT: Wrong 1-Wire device model $model"; + } } else { - return "OWCOUNT: $a[0] ID $a[2] invalid, specify a 12 digit value"; + return "OWCOUNT: $a[0] ID $a[2] invalid, specify a 12 or 2.12 digit value"; } - - #-- 1-Wire ROM identifier in the form "FF.XXXXXXXXXXXX.YY" - # FF = family id follows from the model - # YY must be determined from id - if( $model eq "DS2423" ){ - $fam = "1D"; - CommandAttr (undef,"$name model DS2423"); - }else{ - return "OWMULTI: Wrong 1-Wire device model $model"; - } - + # determine CRC Code - only if this is a direct interface $crc = defined($hash->{IODev}->{INTERFACE}) ? sprintf("%02x",OWX_CRC($fam.".".$id."00")) : "00"; @@ -206,13 +215,18 @@ sub OWCOUNT_Define ($$) { $hash->{INTERVAL} = $interval; #-- Couple to I/O device + $hash->{IODev}=$attr{$name}{"IODev"} + if( defined($attr{$name}{"IODev"}) ); AssignIoPort($hash); - if( !defined($hash->{IODev}->{NAME}) | !defined($hash->{IODev}) | !defined($hash->{IODev}->{PRESENT}) ){ + if( (!defined($hash->{IODev}->{NAME})) || (!defined($hash->{IODev})) ){ return "OWSWITCH: Warning, no 1-Wire I/O device found for $name."; } - if( $hash->{IODev}->{PRESENT} != 1 ){ - return "OWSWITCH: Warning, 1-Wire I/O device ".$hash->{IODev}->{NAME}." not present for $name."; - } + + + + #if( $hash->{IODev}->{PRESENT} != 1 ){ + # return "OWSWITCH: Warning, 1-Wire I/O device ".$hash->{IODev}->{NAME}." not present for $name."; + #} $modules{OWCOUNT}{defptr}{$id} = $hash; #-- readingsSingleUpdate($hash,"state","defined",1); @@ -225,7 +239,7 @@ sub OWCOUNT_Define ($$) { InternalTimer(time()+5, "OWCOUNT_InitializeDevice", $hash, 0); #-- Start timer for updates - InternalTimer(time()+$hash->{INTERVAL}, "OWCOUNT_GetValues", $hash, 0); + InternalTimer(time()+5+$hash->{INTERVAL}, "OWCOUNT_GetValues", $hash, 0); return undef; } @@ -570,8 +584,8 @@ sub OWCOUNT_Get($@) { if( $interface eq "OWX" ){ $ret = OWXCOUNT_GetPage($hash,$page); #-- OWFS interface - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSAD_GetPage($hash,"reading"); + }elsif( $interface eq "OWServer" ){ + $ret = OWFSCOUNT_GetPage($hash,$page); #-- Unknown interface }else{ return "OWCOUNT: Get with wrong IODev type $interface"; @@ -601,8 +615,8 @@ sub OWCOUNT_Get($@) { if( $interface eq "OWX" ){ $ret = OWXCOUNT_GetPage($hash,$page); #-- OWFS interface - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSAD_GetPage($hash,"reading"); + }elsif( $interface eq "OWServer" ){ + $ret = OWFSCOUNT_GetPage($hash,$page); #-- Unknown interface }else{ return "OWCOUNT: Get with wrong IODev type $interface"; @@ -615,8 +629,9 @@ sub OWCOUNT_Get($@) { if( $interface eq "OWX" ){ $ret = OWXCOUNT_GetPage($hash,14); $ret = OWXCOUNT_GetPage($hash,15); - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSAD_GetValues($hash); + }elsif( $interface eq "OWServer" ){ + $ret = OWFSCOUNT_GetPage($hash,14); + $ret = OWFSCOUNT_GetPage($hash,15); }else{ return "OWCOUNT: GetValues with wrong IODev type $interface"; } @@ -664,8 +679,9 @@ sub OWCOUNT_GetValues($) { if( $interface eq "OWX" ){ $ret = OWXCOUNT_GetPage($hash,14); $ret = OWXCOUNT_GetPage($hash,15); - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSAD_GetValues($hash); + }elsif( $interface eq "OWServer" ){ + $ret = OWFSCOUNT_GetPage($hash,14); + $ret = OWFSCOUNT_GetPage($hash,15); }else{ return "OWCOUNT: GetValues with wrong IODev type $interface"; } @@ -774,8 +790,8 @@ sub OWCOUNT_Set($@) { if( $interface eq "OWX" ){ $ret = OWXCOUNT_SetPage($hash,$page,$data); #-- OWFS interface - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSAD_setPage($hash,$page,$data); + }elsif( $interface eq "OWServer" ){ + $ret = OWFSCOUNT_SetPage($hash,$page,$data); #-- Unknown interface }else{ return "OWCOUNT: Set with wrong IODev type $interface"; @@ -812,10 +828,92 @@ sub OWCOUNT_Undef ($) { # Prefix = OWFSCOUNT # ######################################################################################## +# +# OWFSCOUNT_GetPage - Get page from device +# +# Parameter hash = hash of device addressed +# +######################################################################################## +sub OWFSCOUNT_GetPage($$) { + my ($hash,$page) = @_; + + #-- ID of the device + my $owx_add = substr($hash->{ROM_ID},0,15); + + #-- hash of the busmaster + my $master = $hash->{IODev}; + my $name = $hash->{NAME}; + + my $vval; + + #=============== wrong value requested =============================== + if( ($page<0) || ($page>15) ){ + return "OWXCOUNT: Wrong memory page requested"; + } + #-- get values - or shoud we rather get the uncached ones ? + if( $page == 14) { + $vval = OWServer_Read($master,"/$owx_add/counters.A"); + $owg_str = OWServer_Read($master,"/$owx_add/pages/page.14"); + + return "no return from OWServer" + if( (!defined($vval)) || (!defined($owg_str)) ); + + return "empty return from OWServer" + if( ($vval eq "") || ($owg_str eq "") ); + + $owg_val[0] = $vval; + $owg_midnight[0] = $owg_str; + + }elsif( $page == 15) { + $vval = OWServer_Read($master,"/$owx_add/counters.B"); + $owg_str = OWServer_Read($master,"/$owx_add/pages/page.15"); + + return "no return from OWServer" + if( (!defined($vval)) || (!defined($owg_str)) ); + + return "empty return from OWServer" + if( ($vval eq "") || ($owg_str eq "") ); + + $owg_val[1] = $vval; + $owg_midnight[1] = $owg_str; + }else { + $owg_str = OWServer_Read($master,"/$owx_add/pages/page.".$page); + + return "no return from OWServer" + if( !defined($owg_str) ); + + return "empty return from OWServer" + if( $owg_str eq "" ); + } + return undef +} +######################################################################################## +# +# OWFSCOUNT_SetPage - Set page in device +# +# Parameter hash = hash of device addressed +# +######################################################################################## - +sub OWFSCOUNT_SetPage($$$) { + my ($hash,$page,$data) = @_; + + #-- ID of the device + my $owx_add = substr($hash->{ROM_ID},0,15); + + #-- hash of the busmaster + my $master = $hash->{IODev}; + my $name = $hash->{NAME}; + + #=============== wrong page requested =============================== + if( ($page<0) || ($page>15) ){ + return "OWXCOUNT: Wrong memory page write attempt"; + } + OWServer_Write($master, "/$owx_add/pages/page.".$page,$data ); + return undef +} ######################################################################################## # @@ -907,6 +1005,7 @@ sub OWXCOUNT_GetPage($$) { $owg_val[1] = $value; $owg_midnight[1] = $owg_str; } + } return undef; @@ -931,9 +1030,9 @@ sub OWXCOUNT_SetPage($$$) { my $owx_dev = $hash->{ROM_ID}; my $master = $hash->{IODev}; - #=============== wrong value requested =============================== + #=============== wrong page requested =============================== if( ($page<0) || ($page>15) ){ - return "OWXCOUNT: Wrong memory page requested"; + return "OWXCOUNT: Wrong memory page write attempt"; } #=============== set memory ========================================= #-- issue the match ROM command \x55 and the write scratchpad command @@ -983,9 +1082,10 @@ sub OWXCOUNT_SetPage($$$) {

    OWCOUNT

    -

    FHEM module to commmunicate with 1-Wire Counter/RAM DS2423 #

    Note:
    This - 1-Wire module so far works only with the OWX interface module. Please define an OWX device first.

    +

    FHEM module to commmunicate with 1-Wire Counter/RAM DS2423
    +
    This 1-Wire module works with the OWX interface module or with the OWServer interface module + (prerequisite: Add this module's name to the list of clients in OWServer). + Please define an OWX device or OWServer device first.


    Example


    define OWX_C OWCOUNT DS2423 CE780F000000 300
    @@ -999,7 +1099,8 @@ sub OWXCOUNT_SetPage($$$) {

    Define

    - define <name> OWCOUNT [<model>] <id> [<interval>] + define <name> OWCOUNT [<model>] <id> [<interval>] or
    + define <name> OWCOUNT <fam>.<id> [<interval>]

    Define a 1-Wire counter.

    • @@ -1009,6 +1110,10 @@ sub OWXCOUNT_SetPage($$$) { omitted)
  • +
  • + <fam> +
    2-character unique family id, see above +
  • <id>
    12-character unique ROM id of the converter device without family id and CRC @@ -1088,4 +1193,4 @@ sub OWXCOUNT_SetPage($$$) { =end html -=cut +=cut \ No newline at end of file diff --git a/fhem/FHEM/21_OWMULTI.pm b/fhem/FHEM/21_OWMULTI.pm index 54d24d3db..6396cf861 100644 --- a/fhem/FHEM/21_OWMULTI.pm +++ b/fhem/FHEM/21_OWMULTI.pm @@ -10,13 +10,13 @@ # ######################################################################################## # -# define OWMULTI [] [interval] +# define OWMULTI [] [interval] or OWMULTI . [interval] # # where may be replaced by any name string # # is a 1-Wire device type. If omitted, we assume this to be an # DS2438 -# +# is a 1-Wire family id, currently allowed value is 26 # is a 12 character (6 byte) 1-Wire ROM ID # without Family ID, e.g. A2D90D000800 # [interval] is an optional query interval in seconds @@ -150,36 +150,42 @@ sub OWMULTI_Define ($$) { return "OWMULTI: Wrong syntax, must be define OWMULTI [] [interval]" if(int(@a) < 2 || int(@a) > 6); - #-- check if this is an old style definition, e.g. is missing + #-- different types of definition allowed my $a2 = $a[2]; my $a3 = defined($a[3]) ? $a[3] : ""; - if( ($a2 eq "none") || ($a3 eq "none") ) { - return "OWMULTI: ID = none is obsolete now, please redefine"; - } elsif( $a2 =~ m/^[0-9|a-f|A-F]{12}$/ ) { + #-- no model, 12 characters + if( $a2 =~ m/^[0-9|a-f|A-F]{12}$/ ) { $model = "DS2438"; + $fam = "26"; $id = $a[2]; if(int(@a)>=4) { $interval = $a[3]; } - Log 1, "OWMULTI: Parameter [alarminterval] is obsolete now - must be set with I/O-Device" - if(int(@a) == 5); - } elsif( $a3 =~ m/^[0-9|a-f|A-F]{12}$/ ) { + CommandAttr (undef,"$name model DS2438"); + #-- no model, 2+12 characters + } elsif( $a2 =~ m/^[0-9|a-f|A-F]{2}\.[0-9|a-f|A-F]{12}$/ ) { + $fam = substr($a[2],0,2); + $id = substr($a[2],3); + if(int(@a)>=4) { $interval = $a[3]; } + if( $fam eq "26" ){ + $model = "DS2438"; + CommandAttr (undef,"$name model DS2438"); + }else{ + return "OWMULTI: Wrong 1-Wire device family $fam"; + } + #-- model, 12 characters + } elsif( $a3 =~ m/^[0-9|a-f|A-F]{12}$/ ) { $model = $a[2]; $id = $a[3]; if(int(@a)>=5) { $interval = $a[4]; } - Log 1, "OWMULTI: Parameter [alarminterval] is obsolete now - must be set with I/O-Device" - if(int(@a) == 6); + if( $model eq "DS2438" ){ + $fam = "26"; + CommandAttr (undef,"$name model DS2438"); + }else{ + return "OWMULTI: Wrong 1-Wire device model $model"; + } } else { - return "OWMULTI: $a[0] ID $a[2] invalid, specify a 12 digit value"; - } - - #-- 1-Wire ROM identifier in the form "FF.XXXXXXXXXXXX.YY" - # FF = family id follows from the model - # YY must be determined from id - if( $model eq "DS2438" ){ - $fam = "26"; - CommandAttr (undef,"$name model DS2438"); - }else{ - return "OWMULTI: Wrong 1-Wire device model $model"; + return "OWMULTI: $a[0] ID $a[2] invalid, specify a 12 or 2.12 digit value"; } + #-- determine CRC Code - only if this is a direct interface $crc = defined($hash->{IODev}->{INTERFACE}) ? sprintf("%02x",OWX_CRC($fam.".".$id."00")) : "00"; @@ -193,12 +199,12 @@ sub OWMULTI_Define ($$) { #-- Couple to I/O device AssignIoPort($hash); - if( !defined($hash->{IODev}->{NAME}) | !defined($hash->{IODev}) | !defined($hash->{IODev}->{PRESENT}) ){ - return "OWSWITCH: Warning, no 1-Wire I/O device found for $name."; - } - if( $hash->{IODev}->{PRESENT} != 1 ){ - return "OWSWITCH: Warning, 1-Wire I/O device ".$hash->{IODev}->{NAME}." not present for $name."; + if( !defined($hash->{IODev}->{NAME}) || !defined($hash->{IODev}) ){ + return "OWMULTI: Warning, no 1-Wire I/O device found for $name."; } + #if( $hash->{IODev}->{PRESENT} != 1 ){ + # return "OWMULTI: Warning, 1-Wire I/O device ".$hash->{IODev}->{NAME}." not present for $name."; + #} $modules{OWMULTI}{defptr}{$id} = $hash; #-- readingsSingleUpdate($hash,"state","defined",1); @@ -208,7 +214,7 @@ sub OWMULTI_Define ($$) { InternalTimer(time()+10, "OWMULTI_InitializeDevice", $hash, 0); #-- Start timer for updates - InternalTimer(time()+$hash->{INTERVAL}, "OWMULTI_GetValues", $hash, 0); + InternalTimer(time()+10+$hash->{INTERVAL}, "OWMULTI_GetValues", $hash, 0); return undef; } @@ -409,8 +415,8 @@ sub OWMULTI_Get($@) { #-- not different from getting all values .. $ret = OWXMULTI_GetValues($hash); #-- OWFS interface not yet implemented - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSMULTI_GetValues($hash); + }elsif( $interface eq "OWServer" ){ + $ret = OWFSMULTI_GetValues($hash); #-- Unknown interface }else{ return "OWMULTI: Get with wrong IODev type $interface"; @@ -474,8 +480,8 @@ sub OWMULTI_GetValues($@) { last if( !defined($ret) ); } - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSMULTI_GetValues($hash); + }elsif( $interface eq "OWServer" ){ + $ret = OWFSMULTI_GetValues($hash); }else{ Log 3, "OWMULTI: GetValues with wrong IODev type $interface"; return 1; @@ -551,11 +557,11 @@ sub OWMULTI_Set($@) { #-- OWX interface if( $interface eq "OWX" ){ $ret = OWXMULTI_SetValues($hash,@a); - #-- OWFS interface not yet implemented - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSMULTI_SetValues($hash,@a); - # return $ret - # if(defined($ret)); + #-- OWFS interface + }elsif( $interface eq "OWServer" ){ + $ret = OWFSMULTI_SetValues($hash,@a); + return $ret + if(defined($ret)); } else { return "OWMULTI: Set with wrong IODev type $interface"; } @@ -585,6 +591,58 @@ sub OWMULTI_Undef ($) { return undef; } +######################################################################################## +# +# The following subroutines in alphabetical order are only for a 1-Wire bus connected +# via OWFS +# +# Prefix = OWFSMULTI +# +######################################################################################## +# +# OWFSMULTI_GetValues - Get reading from one device +# +# Parameter hash = hash of device addressed +# +######################################################################################## + +sub OWFSMULTI_GetValues($) { + my ($hash) = @_; + + #-- ID of the device + my $owx_add = substr($hash->{ROM_ID},0,15); + + #-- hash of the busmaster + my $master = $hash->{IODev}; + my $name = $hash->{NAME}; + + #-- get values - or should we rather get the uncached ones ? + $owg_temp = OWServer_Read($master,"/$owx_add/temperature"); + $owg_vdd = OWServer_Read($master,"/$owx_add/VDD"); + $owg_volt = OWServer_Read($master,"/$owx_add/VAD"); + + return "no return from OWServer" + if( (!defined($owg_temp)) || (!defined($owg_vdd)) || (!defined($owg_volt)) ); + return "empty return from OWServer" + if( ($owg_temp eq "") || ($owg_vdd eq "") || ($owg_volt eq "") ); + + return undef; +} + +####################################################################################### +# +# OWFSMULTI_SetValues - Set values in device +# +# Parameter hash = hash of device addressed +# a = argument array +# +######################################################################################## + +sub OWFSMULTI_SetValues($@) { + my ($hash, @a) = @_; + +} + ######################################################################################## # # The following subroutines in alphabetical order are only for a 1-Wire bus connected @@ -775,7 +833,7 @@ sub OWXMULTI_GetValues($) { ####################################################################################### # -# OWXMULTI_SetValues - Implements SetFn function +# OWXMULTI_SetValues - Set values in device # # Parameter hash = hash of device addressed # a = argument array @@ -814,7 +872,7 @@ sub OWXMULTI_SetValues($@) { return "OWXMULTI: Device $owx_dev not accessible"; } - DoTrigger($name, undef) if($init_done); + #DoTrigger($name, undef) if($init_done); return undef; } @@ -826,8 +884,9 @@ sub OWXMULTI_SetValues($@) {

    OWMULTI

    FHEM module to commmunicate with 1-Wire multi-sensors, currently the DS2438 smart battery - monitor

    Note:
    This 1-Wire module so far works only with the OWX - interface module. Please define an OWX device first.

    + monitor

    This 1-Wire module works with the OWX interface module or with the OWServer interface module + (prerequisite: Add this module's name to the list of clients in OWServer). + Please define an OWX device or OWServer device first.


    Example

    define OWX_M OWMULTI 7C5034010000 45 @@ -842,7 +901,8 @@ sub OWXMULTI_SetValues($@) {

    Define

    - define <name> OWMULTI [<model>] <id> [<interval>] + define <name> OWMULTI [<model>] <id> [<interval>] or
    + define <name> OWMULTI <fam>.<id> [<interval>]

    Define a 1-Wire multi-sensor

    • @@ -852,6 +912,10 @@ sub OWXMULTI_SetValues($@) { Measured is a temperature value, an external voltage and the current supply voltage
    +
  • +
  • + <fam> +
    2-character unique family id, see above
  • <id> @@ -927,4 +991,4 @@ sub OWXMULTI_SetValues($@) { =end html -=cut +=cut \ No newline at end of file diff --git a/fhem/FHEM/21_OWSWITCH.pm b/fhem/FHEM/21_OWSWITCH.pm index f8169e5d7..17ef0daa9 100644 --- a/fhem/FHEM/21_OWSWITCH.pm +++ b/fhem/FHEM/21_OWSWITCH.pm @@ -10,12 +10,13 @@ # ######################################################################################## # -# define OWSWITCH [] [interval] +# define OWSWITCH [] [interval] or OWSWITCH . [interval] # # where may be replaced by any name string # # is a 1-Wire device type. If omitted, we assume this to be an # DS2413. Allowed values are DS2413, DS2406 +# is a 1-Wire family id, currently allowed values are 12, 29, 3A # is a 12 character (6 byte) 1-Wire ROM ID # without Family ID, e.g. A2D90D000800 # [interval] is an optional query interval in seconds @@ -178,7 +179,7 @@ sub OWSWITCH_Define ($$) { $id = $a[2]; if(int(@a)>=4) { $interval = $a[3]; } #-- no model, 2+12 characters - } elsif( $a2 =~ m/^^[0-9|a-f|A-F]{2}\.[0-9|a-f|A-F]{12}$/ ) { + } elsif( $a2 =~ m/^[0-9|a-f|A-F]{2}\.[0-9|a-f|A-F]{12}$/ ) { $fam = substr($a[2],0,2); $id = substr($a[2],3); if(int(@a)>=4) { $interval = $a[3]; } @@ -233,12 +234,12 @@ sub OWSWITCH_Define ($$) { #-- Couple to I/O device AssignIoPort($hash); - if( !defined($hash->{IODev}->{NAME}) | !defined($hash->{IODev}) | !defined($hash->{IODev}->{PRESENT}) ){ + if( !defined($hash->{IODev}->{NAME}) || !defined($hash->{IODev}) ){ return "OWSWITCH: Warning, no 1-Wire I/O device found for $name."; } - if( $hash->{IODev}->{PRESENT} != 1 ){ - return "OWSWITCH: Warning, 1-Wire I/O device ".$hash->{IODev}->{NAME}." not present for $name."; - } + #if( $hash->{IODev}->{PRESENT} != 1 ){ + # return "OWSWITCH: Warning, 1-Wire I/O device ".$hash->{IODev}->{NAME}." not present for $name."; + #} $modules{OWSWITCH}{defptr}{$id} = $hash; #-- readingsSingleUpdate($hash,"state","defined",1); @@ -251,7 +252,7 @@ sub OWSWITCH_Define ($$) { InternalTimer(time()+10, "OWSWITCH_InitializeDevice", $hash, 0); #-- Start timer for updates - InternalTimer(time()+$hash->{INTERVAL}, "OWSWITCH_GetValues", $hash, 0); + InternalTimer(time()+10+$hash->{INTERVAL}, "OWSWITCH_GetValues", $hash, 0); return undef; } @@ -743,11 +744,13 @@ sub OWFSSWITCH_GetState($) { my $master = $hash->{IODev}; my $name = $hash->{NAME}; - #-- get values + #-- get values - or should we rather use the uncached ones ? my $rel = OWServer_Read($master,"/$owx_add/sensed.ALL"); my $rex = OWServer_Read($master,"/$owx_add/PIO.ALL"); return "no return from OWServer" + if( !defined($rel) || !defined($rex) ); + return "empty return from OWServer" if( ($rel eq "") || ($rex eq "") ); my @ral = split(/,/,$rel); @@ -1097,9 +1100,10 @@ sub OWXSWITCH_SetState($$) {

    OWSWITCH

    -

    FHEM module to commmunicate with 1-Wire Programmable Switches

    Note:
    - This 1-Wire module so far works only with the OWX interface module. Please define an OWX device first.

    +

    FHEM module to commmunicate with 1-Wire Programmable Switches
    +
    This 1-Wire module works with the OWX interface module or with the OWServer interface module + (prerequisite: Add this module's name to the list of clients in OWServer). + Please define an OWX device or OWServer device first.


    Example

    define OWX_S OWSWITCH DS2413 B5D502000000 60 @@ -1113,7 +1117,8 @@ sub OWXSWITCH_SetState($$) {

    Define

    - define <name> OWSWITCH [<model>] <id> [<interval>] + define <name> OWSWITCH [<model>] <id> [<interval>] or
    + define <name> OWSWITCH <fam>.<id> [<interval>]

    Define a 1-Wire switch.

    • @@ -1125,9 +1130,13 @@ sub OWXSWITCH_SetState($$) {
    • model DS2408 with family id 29. 8 Channel switch
  • +
  • + <fam> +
    2-character unique family id, see above +
  • <id> -
    12-character unique ROM id of the converter device without family id and CRC +
    12-character unique ROM id of the device without family id and CRC code
  • <interval> diff --git a/fhem/FHEM/21_OWTHERM.pm b/fhem/FHEM/21_OWTHERM.pm index dad8a7113..8ffa924d7 100755 --- a/fhem/FHEM/21_OWTHERM.pm +++ b/fhem/FHEM/21_OWTHERM.pm @@ -12,18 +12,19 @@ # ######################################################################################## # -# define OWTHERM [] [interval] +# define OWTHERM [] [interval] or . [interval] # # where may be replaced by any name string # # is a 1-Wire device type. If omitted, we assume this to be an # DS1820 temperature sensor # Currently allowed values are DS1820, DS18B20, DS1822 +# is a 1-Wire family id, currently allowed values are 10, 22, 28 # 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 => OW_FAMILY.ROM_ID.CRC +# get id => FAM_ID.ROM_ID.CRC # get present => 1 if device present, 0 if not # get interval => query interval # get temperature => temperature measurement @@ -34,7 +35,6 @@ # set tempHigh => higher alarm temperature setting # # Additional attributes are defined in fhem.cfg -# Note: attributes "tempXXXX" are read during every update operation. # # attr stateAL "" = character string for denoting low alarm condition, default is down triangle # attr stateAH "" = character string for denoting high alarm condition, default is up triangle @@ -118,8 +118,7 @@ sub OWTHERM_Initialize ($) { $hash->{UndefFn} = "OWTHERM_Undef"; $hash->{GetFn} = "OWTHERM_Get"; $hash->{SetFn} = "OWTHERM_Set"; - #tempOffset = a temperature offset added to the temperature reading for correction - #tempUnit = a unit of measure: C/F/K + $hash->{AttrFn} = "OWTHERM_Attr"; $hash->{AttrList}= "IODev do_not_notify:0,1 showtime:0,1 model:DS1820,DS18B20,DS1822 loglevel:0,1,2,3,4,5 ". "event-on-update-reading event-on-change-reading ". "stateAL stateAH ". @@ -151,45 +150,56 @@ sub OWTHERM_Define ($$) { $ret = ""; #-- check syntax - return "OWTHERM: Wrong syntax, must be define OWTHERM [] [interval]" + return "OWTHERM: Wrong syntax, must be define OWTHERM [] [interval] or OWTHERM . [interval]" if(int(@a) < 2 || int(@a) > 6); - #-- check if this is an old style definition, e.g. is missing + #-- different types of definition allowed my $a2 = $a[2]; my $a3 = defined($a[3]) ? $a[3] : ""; - if( ($a2 eq "none") || ($a3 eq "none") ) { - return "OWTHERM: ID = none is obsolete now, please redefine"; - } elsif( $a2 =~ m/^[0-9|a-f|A-F]{12}$/ ) { + #-- no model, 12 characters + if( $a2 =~ m/^[0-9|a-f|A-F]{12}$/ ) { $model = "DS1820"; + $fam = "10"; $id = $a[2]; if(int(@a)>=4) { $interval = $a[3]; } - Log 1, "OWTHERM: Parameter [alarminterval] is obsolete now - must be set with I/O-Device" - if(int(@a) == 5); - } elsif( $a3 =~ m/^[0-9|a-f|A-F]{12}$/ ) { + #-- no model, 2+12 characters + } elsif( $a2 =~ m/^[0-9|a-f|A-F]{2}\.[0-9|a-f|A-F]{12}$/ ) { + $fam = substr($a[2],0,2); + $id = substr($a[2],3); + if(int(@a)>=4) { $interval = $a[3]; } + if( $fam eq "10" ){ + $model = "DS1820"; + CommandAttr (undef,"$name model DS1820"); + }elsif( $fam eq "22" ){ + $model = "DS1822"; + CommandAttr (undef,"$name model DS1822"); + }elsif( $fam eq "28" ){ + $model = "DS18B20"; + CommandAttr (undef,"$name model DS18B20"); + }else{ + return "OWTHERM: Wrong 1-Wire device family $fam"; + } + #-- model, 12 characters + } elsif( $a3 =~ m/^[0-9|a-f|A-F]{12}$/ ) { $model = $a[2]; $id = $a[3]; if(int(@a)>=5) { $interval = $a[4]; } - Log 1, "OWTHERM: Parameter [alarminterval] is obsolete now - must be set with I/O-Device" - if(int(@a) == 6); + if( $model eq "DS1820" ){ + $fam = "10"; + CommandAttr (undef,"$name model DS1820"); + }elsif( $model eq "DS1822" ){ + $fam = "22"; + CommandAttr (undef,"$name model DS1822"); + }elsif( $model eq "DS18B20" ){ + $fam = "28"; + CommandAttr (undef,"$name model DS1822"); + }else{ + return "OWTHERM: Wrong 1-Wire device model $model"; + } } else { - return "OWTHERM: $a[0] ID $a[2] invalid, specify a 12 digit value"; - } - - #-- 1-Wire ROM identifier in the form "FF.XXXXXXXXXXXX.YY" - # FF = family id follows from the model - # YY must be determined from id - if( $model eq "DS1820" ){ - $fam = "10"; - CommandAttr (undef,"$name model DS1820"); - }elsif( $model eq "DS1822" ){ - $fam = "22"; - CommandAttr (undef,"$name model DS1822"); - }elsif( $model eq "DS18B20" ){ - $fam = "28"; - CommandAttr (undef,"$name model DS18B20"); - }else{ - return "OWTHERM: Wrong 1-Wire device model $model"; + return "OWTHERM: $a[0] ID $a[2] invalid, specify a 12 or 2.12 digit value"; } + #-- determine CRC Code - only if this is a direct interface $crc = defined($hash->{IODev}->{INTERFACE}) ? sprintf("%02x",OWX_CRC($fam.".".$id."00")) : "00"; @@ -203,12 +213,12 @@ sub OWTHERM_Define ($$) { #-- Couple to I/O device, exit if not possible AssignIoPort($hash); - if( !defined($hash->{IODev}->{NAME}) | !defined($hash->{IODev}) | !defined($hash->{IODev}->{PRESENT}) ){ - return "OWSWITCH: Warning, no 1-Wire I/O device found for $name."; - } - if( $hash->{IODev}->{PRESENT} != 1 ){ - return "OWSWITCH: Warning, 1-Wire I/O device ".$hash->{IODev}->{NAME}." not present for $name."; + if( !defined($hash->{IODev}->{NAME}) || !defined($hash->{IODev}) ){ + return "OWTHERM: Warning, no 1-Wire I/O device found for $name."; } + #if( $hash->{IODev}->{PRESENT} != 1 ){ + # return "OWTHERM: Warning, 1-Wire I/O device ".$hash->{IODev}->{NAME}." not present for $name."; + #} $modules{OWTHERM}{defptr}{$id} = $hash; #-- readingsSingleUpdate($hash,"state","defined",1); @@ -218,14 +228,14 @@ sub OWTHERM_Define ($$) { InternalTimer(time()+10, "OWTHERM_InitializeDevice", $hash, 0); #-- Start timer for updates - InternalTimer(time()+$hash->{INTERVAL}, "OWTHERM_GetValues", $hash, 0); + InternalTimer(time()+10+$hash->{INTERVAL}, "OWTHERM_GetValues", $hash, 0); return undef; } ######################################################################################## # -# OWTHERM_InitializeDevice - delayed setting of initial readings and channel names +# OWTHERM_InitializeDevice - delayed setting of initial readings # # Parameter hash = hash of device addressed # @@ -326,11 +336,10 @@ sub OWTHERM_FormatValues($) { } #-- put into READINGS + $main::attr{$name}{"tempLow"} = $vlow; + $main::attr{$name}{"tempHigh"} = $vhigh; readingsBeginUpdate($hash); readingsBulkUpdate($hash,"temperature",$vval); - readingsBulkUpdate($hash,"tempLow",$vlow); - readingsBulkUpdate($hash,"tempHigh",$vhigh); - #-- STATE readingsBulkUpdate($hash,"state",$svalue); readingsEndUpdate($hash,1); @@ -400,7 +409,7 @@ sub OWTHERM_Get($@) { #-- not different from getting all values .. $ret = OWXTHERM_GetValues($hash); #-- OWFS interface - }elsif( $interface eq "OWFS" ){ + }elsif( $interface eq "OWServer" ){ $ret = OWFSTHERM_GetValues($hash); #-- Unknown interface }else{ @@ -419,8 +428,8 @@ sub OWTHERM_Get($@) { return "OWTHERM: $name.temperature => ". $hash->{READINGS}{"temperature"}{VAL}; } elsif ($reading eq "alarm") { - return "OWTHERM: $name.alarm => L ".$hash->{READINGS}{"tempLow"}{VAL}. - " H ".$hash->{READINGS}{"tempHigh"}{VAL}; + return "OWTHERM: $name.alarm => L ".$main::attr{$name}{"tempLow"}. + " H ".$main::attr{$name}{"tempHigh"}; } return undef; } @@ -456,7 +465,7 @@ sub OWTHERM_GetValues($@) { last if( !defined($ret) ); } - }elsif( $interface eq "OWFS" ){ + }elsif( $interface eq "OWServer" ){ $ret = OWFSTHERM_GetValues($hash); }else{ Log 3, "OWTHERM: GetValues with wrong IODev type $interface"; @@ -534,7 +543,7 @@ sub OWTHERM_Set($@) { if( $interface eq "OWX" ){ $ret = OWXTHERM_SetValues($hash,@a); #-- OWFS interface - }elsif( $interface eq "OWFS" ){ + }elsif( $interface eq "OWServer" ){ $ret = OWFSTHERM_SetValues($hash,@a); return $ret if(defined($ret)); @@ -551,6 +560,34 @@ 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)/ ); + + if( $do eq "set") + { + $ret = OWTHERM_Set($main::defs{$name},@a); + } elsif( $do eq "del"){ + } + return $ret; +} + ######################################################################################## # # OWTHERM_Undef - Implements UndefFn function @@ -576,49 +613,58 @@ sub OWTHERM_Undef ($) { # ######################################################################################## # -# OWFSTHERM_GetValues - Get reading from one device +# OWFSTHERM_GetValues - Get values from device # # Parameter hash = hash of device addressed # ######################################################################################## -sub OWFSTHERM_GetValues($) -{ +sub OWFSTHERM_GetValues($) { my ($hash) = @_; - - my $ret = OW::get("/uncached/".$hash->{OW_FAMILY}.".".$hash->{OW_ID}."/temperature"); - if( defined($ret) ) { - $hash->{PRESENT} = 1; - $owg_temp = $ret; - $owg_th = OW::get("/uncached/".$hash->{OW_FAMILY}.".".$hash->{OW_ID}."/temphigh"); - $owg_tl = OW::get("/uncached/".$hash->{OW_FAMILY}.".".$hash->{OW_ID}."/templow"); - } else { - $hash->{PRESENT} = 0; - $owg_temp = 0.0; - $owg_th = 0.0; - $owg_tl = 0.0; - } - - return undef; + + #-- ID of the device + my $owx_add = substr($hash->{ROM_ID},0,15); + + #-- hash of the busmaster + my $master = $hash->{IODev}; + my $name = $hash->{NAME}; + + #-- get values - or should we rather get the uncached ones ? + $owg_temp = OWServer_Read($master,"/$owx_add/temperature"); + $owg_th = OWServer_Read($master,"/$owx_add/temphigh"); + $owg_tl = OWServer_Read($master,"/$owx_add/templow"); + + return "no return from OWServer" + if( (!defined($owg_temp)) || (!defined($owg_th)) || (!defined($owg_tl)) ); + return "empty return from OWServer" + if( ($owg_temp eq "") || ($owg_th eq "") || ($owg_tl eq "") ); + + #return "wrong data length from OWServer" + # if( (int(@ral) != $cnumber{$attr{$name}{"model"}}) || (int(@rax) != $cnumber{$attr{$name}{"model"}}) ); + + return undef } -####################################################################################### +######################################################################################## +# +# OWFSTHERM_SetValues - Set values in device # -# OWFSTHERM_SetValues - Implements SetFn function -# # Parameter hash = hash of device addressed -# a = argument array # ######################################################################################## sub OWFSTHERM_SetValues($@) { - my ($hash, @a) = @_; + my ($hash,@a) = @_; - #-- define vars - my $key = lc($a[1]); - my $value = $a[2]; + #-- ID of the device + my $owx_add = substr($hash->{ROM_ID},0,15); - return OW::put($hash->{OW_FAMILY}.".".$hash->{OW_ID}."/$key",$value); + #-- hash of the busmaster + my $master = $hash->{IODev}; + my $name = $hash->{NAME}; + + OWServer_Write($master, "/$owx_add/".lc($a[0]),$a[1] ); + return undef } ######################################################################################## @@ -796,12 +842,12 @@ sub OWXTHERM_SetValues($@) { =pod =begin html - +

    OWTHERM

    -

    FHEM module to commmunicate with 1-Wire bus digital thermometer devices

    - Note:
    This is the only 1-Wire module which so far works with both the OWFS and the - OWX interface module. Please define an OWFS device or an OWX device first.
    +

    FHEM module to commmunicate with 1-Wire bus digital thermometer devices
    +
    This 1-Wire module works with the OWX interface module or with the OWServer interface module + (prerequisite: Add this module's name to the list of clients in OWServer). + Please define an OWX device or OWServer device first.

    Example

    @@ -813,7 +859,8 @@ sub OWXTHERM_SetValues($@) {

    Define

    - define <name> OWTHERM [<model>] <id> [<interval>] + define <name> OWTHERM [<model>] <id> [<interval>] or
    + define <name> OWTHERM <fam>.lt;id> [<interval>]

    Define a 1-Wire digital thermometer device.

    • @@ -825,6 +872,9 @@ sub OWXTHERM_SetValues($@) {
    • model DS18B20 with family id 28
  • +
  • + <fam> +
    2-character unique family id, see above
  • <id>
    12-character unique ROM id of the thermometer device without family id and CRC