2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-06 06:08:44 +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
#
# 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
# * 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
@ -9,16 +12,16 @@
# Internally these interfaces are vastly different, read the corresponding Wiki pages
# 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
#
# 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
# <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> 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
# (mod suggested by T.Faust)
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
my $msg = "OWX: Serial device $dev";
my $ret = DevIo_OpenDev($hash,0,undef);
@ -186,8 +191,9 @@ sub OWX_Define ($$) {
select(undef,undef,undef,0.1);
} else {
$hash->{DeviceName} = $dev;
#-- 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};
if($owx_hwdevice){
Log 1,$msg." defined";
@ -198,7 +204,7 @@ sub OWX_Define ($$) {
CUL_SimpleWrite($owx_hwdevice, "Oi");
}else{
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
@ -529,16 +535,37 @@ sub OWX_Detect ($) {
}
#-- here we treat the network-connected CUNO
} else {
CUL_SimpleWrite($owx_hwdevice, "ORm");
my $ob = DevIo_SimpleRead($owx_hwdevice);
if( $ob =~ m/OK.*/){
$owx_interface="CUNO";
$ress .= "DS2482 detected in $owx_hwdevice->{NAME}";
$ret=1;
} else {
#-- sleeping for some time
select(undef,undef,undef,0.5);
#-- Max 4 tries to detect an interface
for($l=0;$l<4;$l++) {
#-- write 1-Wire bus
CUL_SimpleWrite($owx_hwdevice, "ORm");
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;
$ress .= "in $owx_hwdevice->{NAME} could not be addressed";
$ret=0;
}
}
#-- store with OWX device
@ -583,7 +610,7 @@ sub OWX_Discover ($) {
#-- sleeping for some time
select(undef,undef,undef,3);
CUL_SimpleWrite($owx_hwdevice, "Oc");
my $ob = DevIo_SimpleRead($owx_hwdevice);
my $ob = OWX_SimpleRead($owx_hwdevice);
if( $ob ){
foreach my $dx (split(/\n/,$ob)){
$dx =~ s/\d+\://;
@ -1879,7 +1906,7 @@ sub OWX_Complex_CUNO ($$$$) {
Log 3,"OWX: Sending match ROM to CUNO ".$select
if( $owx_debug > 1);
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
# in the serial interfaces as well
$res .= "000000000";
@ -1894,12 +1921,14 @@ sub OWX_Complex_CUNO ($$$$) {
#$numread += length($data);
$res.=OWX_Receive_CUNO($hash,$numread);
}
Log 3,"OWX: returned from CUNO $res"
if( $owx_debug > 1);
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
#
@ -1915,7 +1944,7 @@ sub OWX_Receive_CUNO ($$) {
for(
my $i=0;$i<$numread;$i++){
CUL_SimpleWrite($owx_hwdevice, "OrB");
my $ob = DevIo_SimpleRead($owx_hwdevice);
my $ob = OWX_SimpleRead($owx_hwdevice);
#-- process results
if( !(defined($ob)) ){
return "";
@ -1949,7 +1978,7 @@ sub OWX_Receive_CUNO ($$) {
sub OWX_Reset_CUNO ($) {
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" ){
return 1;
}else{
@ -1985,6 +2014,36 @@ sub OWX_Send_CUNO ($$) {
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
@ -2005,7 +2064,7 @@ sub OWX_Verify_CUNO ($$) {
#-- sleeping for some time
select(undef,undef,undef,3);
CUL_SimpleWrite($owx_hwdevice, "Oc");
my $ob = DevIo_SimpleRead($owx_hwdevice);
my $ob = OWX_SimpleRead($owx_hwdevice);
if( $ob ){
foreach my $dx (split(/\n/,$ob)){
$dx =~ s/\d+\://;

View File

@ -15,7 +15,7 @@
# Prof. Dr. Peter A. Henning, 2012
# Martin Fischer, 2011
#
# Version 2.17 - August, 2012
# Version 2.20 - October, 2012
#
# Setup bus device in fhem.cfg as
#
@ -43,6 +43,8 @@
# Additional attributes are defined in fhem.cfg
# 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> 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
@ -129,6 +131,7 @@ sub OWTHERM_Initialize ($) {
#tempOffset = a temperature offset added to the temperature reading for correction
#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 ".
"event:on-update,on-change ".
"stateAL stateAH ".
"tempOffset tempUnit:C,Celsius,F,Fahrenheit,K,Kelvin ".
"tempLow tempHigh";
@ -278,7 +281,7 @@ sub OWTHERM_FormatValues($) {
$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>";
$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;
if( $unit eq "Celsius" ){
@ -474,12 +477,18 @@ sub OWTHERM_GetValues($@) {
return "OWTHERM: Could not get values from device $name, reason $ret";
}
$hash->{PRESENT} = 1;
#-- old state, new state
my $oldval = $hash->{STATE};
$value=OWTHERM_FormatValues($hash);
#--logging
my $newval = $hash->{STATE};
#--logging depends on setting of the event-attribute
Log 5, $value;
$hash->{CHANGED}[0] = $value;
DoTrigger($name, undef);
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;
}
@ -685,21 +694,25 @@ sub OWXTHERM_GetValues($) {
return "OWXTHERM: Device $owx_dev not accessible in 2nd step";
}
#my $res2 = "====> OWXTHERM Received ";
#for(my $i=0;$i<19;$i++){
# my $j=int(ord(substr($res,$i,1))/16);
# my $k=ord(substr($res,$i,1))%16;
# $res2.=sprintf "0x%1x%1x ",$j,$k;
#if (length($res) == 10){
# my $res2 = "====> OWXTHERM Received ";
# for(my $i=0;$i<19;$i++){
# my $j=int(ord(substr($res,$i,1))/16);
# my $k=ord(substr($res,$i,1))%16;
# $res2.=sprintf "0x%1x%1x ",$j,$k;
# }
# Log 1, $res2;
#}
#Log 1, $res2;
#-- process results
#$res="000000000".$res
# if(length($res)==10);
my @data=split(//,$res);
return "invalid data length"
return "OWTHERM: invalid data length, ".int(@data)." bytes"
if (@data != 19);
return "invalid data"
return "OWXTHERM: invalid data"
if (ord($data[17])<=0);
return "invalid CRC"
return "OWXTHERM: invalid CRC"
if (OWX_CRC8(substr($res,10,8),$data[18])==0);
#-- this must be different for the different device types