2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-07 19:04:20 +00:00

git-svn-id: https://svn.fhem.de/fhem/trunk@1936 2b470e98-0d58-463d-a4d8-8e2adae1ed80

This commit is contained in:
pahenning 2012-10-07 16:40:19 +00:00
parent ae906f9c5f
commit 9a21e5ee40
2 changed files with 106 additions and 34 deletions

View File

@ -2,6 +2,9 @@
# #
# OWX.pm # OWX.pm
# #
# TODO: Abfangen, wenn das Serial Device nach Öffnung nicht existiert ???
# set init als rediscover ausführen.
#
# FHEM module to commmunicate with 1-Wire bus devices # FHEM module to commmunicate with 1-Wire bus devices
# * via an active DS2480/DS2482/DS2490/DS9097U bus master interface attached to an USB port # * via an active DS2480/DS2482/DS2490/DS9097U bus master interface attached to an USB port
# * via a passive DS9097 interface attached to an USB port # * via a passive DS9097 interface attached to an USB port
@ -9,16 +12,16 @@
# Internally these interfaces are vastly different, read the corresponding Wiki pages # Internally these interfaces are vastly different, read the corresponding Wiki pages
# http://fhemwiki.de/wiki/Interfaces_f%C3%BCr_1-Wire # http://fhemwiki.de/wiki/Interfaces_f%C3%BCr_1-Wire
# #
# Version 2.17 - August, 2012 # Version 2.20 - October, 2012
# #
# Prof. Dr. Peter A. Henning, 2012 # Prof. Dr. Peter A. Henning, 2012
# #
# define <name> OWX <serial-device> for USB interfaces or # define <name> OWX <serial-device> for USB interfaces or
# define <name> OWX <cuno-device> for a CUNO interface # define <name> OWX <cuno/coc-device> for a CUNO or COC interface
# #
# where <name> may be replaced by any name string # where <name> may be replaced by any name string
# <serial-device> is a serial (USB) device # <serial-device> is a serial (USB) device
# <cuno-device> is a CUNO device # <cuno/coc-device> is a CUNO or COC device
# #
# get <name> alarms => find alarmed 1-Wire devices (not with CUNO) # get <name> alarms => find alarmed 1-Wire devices (not with CUNO)
# get <name> devices => find all 1-Wire devices # get <name> devices => find all 1-Wire devices
@ -161,6 +164,8 @@ sub OWX_Define ($$) {
#-- First step: check if we have a directly connected serial interface or a CUNO attached #-- First step: check if we have a directly connected serial interface or a CUNO attached
# (mod suggested by T.Faust) # (mod suggested by T.Faust)
if ( $dev =~ m/\/dev\/.*/ ){ if ( $dev =~ m/\/dev\/.*/ ){
#-- TODO: what should we do when the specified device name contains @ already ?
$hash->{DeviceName} = $dev."\@9600";
#-- Second step in case of serial device: open the serial device to test it #-- Second step in case of serial device: open the serial device to test it
my $msg = "OWX: Serial device $dev"; my $msg = "OWX: Serial device $dev";
my $ret = DevIo_OpenDev($hash,0,undef); my $ret = DevIo_OpenDev($hash,0,undef);
@ -186,8 +191,9 @@ sub OWX_Define ($$) {
select(undef,undef,undef,0.1); select(undef,undef,undef,0.1);
} else { } else {
$hash->{DeviceName} = $dev;
#-- Second step in case of CUNO: See if we can open it #-- Second step in case of CUNO: See if we can open it
my $msg = "OWX: CUNO device $dev"; my $msg = "OWX: CUNO/COC device $dev";
$owx_hwdevice = $main::defs{$dev}; $owx_hwdevice = $main::defs{$dev};
if($owx_hwdevice){ if($owx_hwdevice){
Log 1,$msg." defined"; Log 1,$msg." defined";
@ -198,7 +204,7 @@ sub OWX_Define ($$) {
CUL_SimpleWrite($owx_hwdevice, "Oi"); CUL_SimpleWrite($owx_hwdevice, "Oi");
}else{ }else{
Log 1, $msg." not defined"; Log 1, $msg." not defined";
return "OWX: Can't open cuno device $dev: $!" return "OWX: Can't open CUNO/COC device $dev: $!"
} }
} }
#-- Third step: see, if a bus interface is detected #-- Third step: see, if a bus interface is detected
@ -529,16 +535,37 @@ sub OWX_Detect ($) {
} }
#-- here we treat the network-connected CUNO #-- here we treat the network-connected CUNO
} else { } else {
CUL_SimpleWrite($owx_hwdevice, "ORm"); #-- sleeping for some time
my $ob = DevIo_SimpleRead($owx_hwdevice); select(undef,undef,undef,0.5);
if( $ob =~ m/OK.*/){ #-- Max 4 tries to detect an interface
$owx_interface="CUNO"; for($l=0;$l<4;$l++) {
$ress .= "DS2482 detected in $owx_hwdevice->{NAME}"; #-- write 1-Wire bus
$ret=1; CUL_SimpleWrite($owx_hwdevice, "ORm");
} else { my $ob = OWX_SimpleRead($owx_hwdevice);
#-- process result for detection
#Log 1,"ERGEBNIS ORm =>".$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,0.5);
}
if( $ret == 0 ){
$owx_interface=undef; $owx_interface=undef;
$ress .= "in $owx_hwdevice->{NAME} could not be addressed"; $ress .= "in $owx_hwdevice->{NAME} could not be addressed";
$ret=0;
} }
} }
#-- store with OWX device #-- store with OWX device
@ -583,7 +610,7 @@ sub OWX_Discover ($) {
#-- sleeping for some time #-- sleeping for some time
select(undef,undef,undef,3); select(undef,undef,undef,3);
CUL_SimpleWrite($owx_hwdevice, "Oc"); CUL_SimpleWrite($owx_hwdevice, "Oc");
my $ob = DevIo_SimpleRead($owx_hwdevice); my $ob = OWX_SimpleRead($owx_hwdevice);
if( $ob ){ if( $ob ){
foreach my $dx (split(/\n/,$ob)){ foreach my $dx (split(/\n/,$ob)){
$dx =~ s/\d+\://; $dx =~ s/\d+\://;
@ -1879,7 +1906,7 @@ sub OWX_Complex_CUNO ($$$$) {
Log 3,"OWX: Sending match ROM to CUNO ".$select Log 3,"OWX: Sending match ROM to CUNO ".$select
if( $owx_debug > 1); if( $owx_debug > 1);
CUL_SimpleWrite($owx_hwdevice, $select); CUL_SimpleWrite($owx_hwdevice, $select);
my $ob = DevIo_SimpleRead($owx_hwdevice); my $ob = OWX_SimpleRead($owx_hwdevice);
#-- padding first 9 bytes into result string, since we have this #-- padding first 9 bytes into result string, since we have this
# in the serial interfaces as well # in the serial interfaces as well
$res .= "000000000"; $res .= "000000000";
@ -1894,12 +1921,14 @@ sub OWX_Complex_CUNO ($$$$) {
#$numread += length($data); #$numread += length($data);
$res.=OWX_Receive_CUNO($hash,$numread); $res.=OWX_Receive_CUNO($hash,$numread);
} }
Log 3,"OWX: returned from CUNO $res"
if( $owx_debug > 1);
return $res; return $res;
} }
######################################################################################## ########################################################################################
# #
# OWX_receive_CUNO - Read from the CUNO # OWX_Receive_CUNO - Read from the CUNO
# #
# Parameter: hash = hash of bus master, numread = number of bytes to read # Parameter: hash = hash of bus master, numread = number of bytes to read
# #
@ -1915,7 +1944,7 @@ sub OWX_Receive_CUNO ($$) {
for( for(
my $i=0;$i<$numread;$i++){ my $i=0;$i<$numread;$i++){
CUL_SimpleWrite($owx_hwdevice, "OrB"); CUL_SimpleWrite($owx_hwdevice, "OrB");
my $ob = DevIo_SimpleRead($owx_hwdevice); my $ob = OWX_SimpleRead($owx_hwdevice);
#-- process results #-- process results
if( !(defined($ob)) ){ if( !(defined($ob)) ){
return ""; return "";
@ -1949,7 +1978,7 @@ sub OWX_Receive_CUNO ($$) {
sub OWX_Reset_CUNO ($) { sub OWX_Reset_CUNO ($) {
CUL_SimpleWrite($owx_hwdevice, "ORb"); CUL_SimpleWrite($owx_hwdevice, "ORb");
my $ob = DevIo_SimpleRead($owx_hwdevice); my $ob = OWX_SimpleRead($owx_hwdevice);
if( substr($ob,0,4) eq "OK:1" ){ if( substr($ob,0,4) eq "OK:1" ){
return 1; return 1;
}else{ }else{
@ -1985,6 +2014,36 @@ sub OWX_Send_CUNO ($$) {
if( $owx_debug > 1); if( $owx_debug > 1);
} }
#########################################################################################
#
# OWX_SimpleRead - Reading with retry.
# Suggested in this way by Dirk Tostmann
#
# Parameter hash = hash of device
#
# Return response, if OK
# 0 if not OK
#
########################################################################################
sub OWX_SimpleRead($)
{
my ($hash) = @_;
my $buf = DevIo_DoSimpleRead($owx_hwdevice);
# Lets' try again: Some drivers return len(0) on the first read...
if(defined($buf) && length($buf) == 0) {
#-- allow some time
select(undef,undef,undef,0.5);
$buf = DevIo_DoSimpleRead($owx_hwdevice);
}
if(!defined($buf) || length($buf) == 0) {
DevIo_Disconnected($hash);
return undef;
}
return $buf;
}
######################################################################################## ########################################################################################
# #
# OWX_Verify_CUNO - Verify a particular device on the 1-Wire bus # OWX_Verify_CUNO - Verify a particular device on the 1-Wire bus
@ -2005,7 +2064,7 @@ sub OWX_Verify_CUNO ($$) {
#-- sleeping for some time #-- sleeping for some time
select(undef,undef,undef,3); select(undef,undef,undef,3);
CUL_SimpleWrite($owx_hwdevice, "Oc"); CUL_SimpleWrite($owx_hwdevice, "Oc");
my $ob = DevIo_SimpleRead($owx_hwdevice); my $ob = OWX_SimpleRead($owx_hwdevice);
if( $ob ){ if( $ob ){
foreach my $dx (split(/\n/,$ob)){ foreach my $dx (split(/\n/,$ob)){
$dx =~ s/\d+\://; $dx =~ s/\d+\://;

View File

@ -15,7 +15,7 @@
# Prof. Dr. Peter A. Henning, 2012 # Prof. Dr. Peter A. Henning, 2012
# Martin Fischer, 2011 # Martin Fischer, 2011
# #
# Version 2.17 - August, 2012 # Version 2.20 - October, 2012
# #
# Setup bus device in fhem.cfg as # Setup bus device in fhem.cfg as
# #
@ -43,6 +43,8 @@
# Additional attributes are defined in fhem.cfg # Additional attributes are defined in fhem.cfg
# Note: attributes "tempXXXX" are read during every update operation. # Note: attributes "tempXXXX" are read during every update operation.
# #
# attr <name> event on-change/on-update = when to write an event (default= on-update)
#
# attr <name> stateAL "<string>" = character string for denoting low alarm condition, default is red down triangle # attr <name> stateAL "<string>" = character string for denoting low alarm condition, default is red down triangle
# attr <name> stateAH "<string>" = character string for denoting high alarm condition, default is red up triangle # attr <name> stateAH "<string>" = character string for denoting high alarm condition, default is red up triangle
# attr <name> tempOffset <float> = temperature offset in degree Celsius added to the raw temperature reading # attr <name> tempOffset <float> = temperature offset in degree Celsius added to the raw temperature reading
@ -129,6 +131,7 @@ sub OWTHERM_Initialize ($) {
#tempOffset = a temperature offset added to the temperature reading for correction #tempOffset = a temperature offset added to the temperature reading for correction
#tempUnit = a unit of measure: C/F/K #tempUnit = a unit of measure: C/F/K
$hash->{AttrList}= "IODev do_not_notify:0,1 showtime:0,1 loglevel:0,1,2,3,4,5 ". $hash->{AttrList}= "IODev do_not_notify:0,1 showtime:0,1 loglevel:0,1,2,3,4,5 ".
"event:on-update,on-change ".
"stateAL stateAH ". "stateAL stateAH ".
"tempOffset tempUnit:C,Celsius,F,Fahrenheit,K,Kelvin ". "tempOffset tempUnit:C,Celsius,F,Fahrenheit,K,Kelvin ".
"tempLow tempHigh"; "tempLow tempHigh";
@ -278,7 +281,7 @@ sub OWTHERM_FormatValues($) {
$stateal = defined($attr{$name}{stateAL}) ? $attr{$name}{stateAL} : "<span style=\"color:red\">&#x25BE;</span>"; $stateal = defined($attr{$name}{stateAL}) ? $attr{$name}{stateAL} : "<span style=\"color:red\">&#x25BE;</span>";
$stateah = defined($attr{$name}{stateAH}) ? $attr{$name}{stateAH} : "<span style=\"color:red\">&#x25B4;</span>"; $stateah = defined($attr{$name}{stateAH}) ? $attr{$name}{stateAH} : "<span style=\"color:red\">&#x25B4;</span>";
$unit = defined($attr{$name}{"tempUnit"}) ? $attr{$name}{"tempUnit"} : $hash->{READINGS}{"temperature"}{UNIT}; $unit = defined($attr{$name}{"tempUnit"}) ? $attr{$name}{"tempUnit"} : $hash->{READINGS}{"temperature"}{UNIT};
$offset = defined($attr{$name}{"tempoffset"}) ? $attr{$name}{"tempOffset"} : 0.0 ; $offset = defined($attr{$name}{"tempOffset"}) ? $attr{$name}{"tempOffset"} : 0.0 ;
$factor = 1.0; $factor = 1.0;
if( $unit eq "Celsius" ){ if( $unit eq "Celsius" ){
@ -474,12 +477,18 @@ sub OWTHERM_GetValues($@) {
return "OWTHERM: Could not get values from device $name, reason $ret"; return "OWTHERM: Could not get values from device $name, reason $ret";
} }
$hash->{PRESENT} = 1; $hash->{PRESENT} = 1;
$value=OWTHERM_FormatValues($hash);
#--logging
Log 5, $value;
$hash->{CHANGED}[0] = $value;
DoTrigger($name, undef); #-- old state, new state
my $oldval = $hash->{STATE};
$value=OWTHERM_FormatValues($hash);
my $newval = $hash->{STATE};
#--logging depends on setting of the event-attribute
Log 5, $value;
my $ev = defined($attr{$name}{"event"}) ? $attr{$name}{"event"} : "on-update";
if( ($ev eq "on-update") || (($ev eq "on-change") && ($newval ne $oldval)) ){
$hash->{CHANGED}[0] = $value;
DoTrigger($name, undef);
}
return undef; return undef;
} }
@ -685,21 +694,25 @@ sub OWXTHERM_GetValues($) {
return "OWXTHERM: Device $owx_dev not accessible in 2nd step"; return "OWXTHERM: Device $owx_dev not accessible in 2nd step";
} }
#my $res2 = "====> OWXTHERM Received "; #if (length($res) == 10){
#for(my $i=0;$i<19;$i++){ # my $res2 = "====> OWXTHERM Received ";
# my $j=int(ord(substr($res,$i,1))/16); # for(my $i=0;$i<19;$i++){
# my $k=ord(substr($res,$i,1))%16; # my $j=int(ord(substr($res,$i,1))/16);
# $res2.=sprintf "0x%1x%1x ",$j,$k; # my $k=ord(substr($res,$i,1))%16;
# $res2.=sprintf "0x%1x%1x ",$j,$k;
# }
# Log 1, $res2;
#} #}
#Log 1, $res2;
#-- process results #-- process results
#$res="000000000".$res
# if(length($res)==10);
my @data=split(//,$res); my @data=split(//,$res);
return "invalid data length" return "OWTHERM: invalid data length, ".int(@data)." bytes"
if (@data != 19); if (@data != 19);
return "invalid data" return "OWXTHERM: invalid data"
if (ord($data[17])<=0); if (ord($data[17])<=0);
return "invalid CRC" return "OWXTHERM: invalid CRC"
if (OWX_CRC8(substr($res,10,8),$data[18])==0); if (OWX_CRC8(substr($res,10,8),$data[18])==0);
#-- this must be different for the different device types #-- this must be different for the different device types