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

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

This commit is contained in:
pahenning 2013-01-23 07:54:06 +00:00
parent b5dd6ccaac
commit ea199fa95a
6 changed files with 965 additions and 434 deletions

View File

@ -33,10 +33,6 @@
# attr <name> 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</a>, <a href="#eventMap">eventMap</a>, <a href="#loglevel">loglevel</a>,
<a href="#webCmd">webCmd</a></li>
</ul>
=end html
=cut

View File

@ -10,12 +10,13 @@
#
########################################################################################
#
# define <name> OWAD [<model>] <ROM_ID> [interval]
# define <name> OWAD [<model>] <ROM_ID> [interval] or or OWAD <FAM_ID>.<ROM_ID> [interval]
#
# where <name> may be replaced by any name string
#
# <model> is a 1-Wire device type. If omitted, we assume this to be an
# DS2450 A/D converter
# <FAM_ID> is a 1-Wire family id, currently allowed value is 20
# <ROM_ID> 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 <name> interval => set period for measurement
#
# Additional attributes are defined in fhem.cfg, in some cases per channel, where <channel>=A,B,C,D
# Note: attributes are read only during initialization procedure - later changes are not used.
#
# attr <name> stateAL0 "<string>" = character string for denoting low normal condition, default is empty
# attr <name> stateAH0 "<string>" = 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<int(@owg_fixed);$i++ ){
$attlist .= " ".$owg_fixed[$i]."Name";
$attlist .= " ".$owg_fixed[$i]."Offset";
$attlist .= " ".$owg_fixed[$i]."Factor";
@ -168,9 +165,7 @@ sub OWAD_Initialize ($) {
sub OWAD_Define ($$) {
my ($hash, $def) = @_;
# define <name> OWAD [<model>] <id> [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 <name> OWAD [<model>] <id> [interval]"
return "OWAD: Wrong syntax, must be define <name> OWAD [<model>] <id> [interval] or OWAD <fam>.<id> [interval]"
if(int(@a) < 2 || int(@a) > 5);
#-- check if this is an old style definition, e.g. <model> 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<int(@owg_fixed);$i++) {
@ -291,37 +293,26 @@ sub OWAD_InitializeDevice($) {
#-- Initial readings
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;
$owg_vlow[$i] = defined($attr{$name}{$owg_fixed[$i]."Low"}) ? $attr{$name}{$owg_fixed[$i]."Low"} : "";
$owg_vhigh[$i] = defined($attr{$name}{$owg_fixed[$i]."High"}) ? $attr{$name}{$owg_fixed[$i]."High"} : "";
if( $alarm eq "low" || $alarm eq "both" ){
$owg_slow[$i]=1;
}
if( $alarm eq "high" || $alarm eq "both" ){
$owg_shigh[$i]=1;
};
$owg_vlow[$i] = $vlow;
$owg_vhigh[$i] = $vhigh;
my @args = ($name,$owg_fixed[$i]."Alarm",$alarm);
OWAD_Set($hash,@args);
@args = ($name,$owg_fixed[$i]."Low",$owg_vlow[$i]);
OWAD_Set($hash,@args)
if( $owg_vlow[$i] ne "");
@args = ($name,$owg_fixed[$i]."High",$owg_vhigh[$i]);
OWAD_Set($hash,@args)
if( $owg_vhigh[$i] ne "");
}
#-- Initialize all the display stuff
#-- Output formatting because of reading attributes
OWAD_FormatValues($hash);
#-- set status according to interface type
my $interface= $hash->{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<int(@owg_fixed);$k++ ){
$vfuncall .= "\$owg_val[$k]=$owg_val[$k];";
}
my $galarm = 0;
my $galarm = 0;
$hash->{ALARM} = 0;
#-- alarm signatures
my $stateal1 = defined($attr{$name}{stateAL1}) ? $attr{$name}{stateAL1} : "&#x25BE;";
@ -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<int(@owg_fixed);$i++){
return if( $owg_val[$i] eq "");
}
#-- put into READINGS
readingsBeginUpdate($hash);
@ -360,7 +357,10 @@ sub OWAD_FormatValues($) {
my $cname = defined($attr{$name}{$owg_fixed[$i]."Name"}) ? $attr{$name}{$owg_fixed[$i]."Name"} : $owg_fixed[$i]."|voltage";
my @cnama = split(/\|/,$cname);
$owg_channel[$i]=$cnama[0];
my $unit = defined($attr{$name}{$owg_fixed[$i]."Unit"}) ? $attr{$name}{$owg_fixed[$i]."Unit"} : "Volt|V";
my @unarr= split(/\|/,$unit);
#-- skip a few things when the values are undefined or zero
if( !defined($owg_val[$i]) ){
$svalue .= "$owg_channel[$i]: ???"
@ -370,7 +370,7 @@ sub OWAD_FormatValues($) {
}else{
#-- when offset and scale factor are defined, we cannot have a function and vice versa
if( defined($attr{$name}{$owg_fixed[$i]."Offset"}) & defined($attr{$name}{$owg_fixed[$i]."Factor"}) ){
if( defined($attr{$name}{$owg_fixed[$i]."Offset"}) && defined($attr{$name}{$owg_fixed[$i]."Factor"}) ){
my $offset = $attr{$name}{$owg_fixed[$i]."Offset"};
my $factor = $attr{$name}{$owg_fixed[$i]."Factor"};
$vfunc = "$factor*(V$owg_fixed[$i] + $offset)";
@ -387,43 +387,29 @@ sub OWAD_FormatValues($) {
my $sstr = "V$owg_fixed[$k]";
$vfunc =~ s/$sstr/\$owg_val[$k]/g;
}
#-- correct alarm values for proper offset, factor
#$vlow = int(($owg_vlow[$i] + $offset)*$factor*1000)/1000;
#$vhigh = int(($owg_vhigh[$i] + $offset)*$factor*1000)/1000;
#-- determine the measured value from the function
$vfunc = $vfuncall.$vfunc;
#Log 1, "After completion vfunc= ".$vfunc;
$vfunc = eval($vfunc);
if( !$vfunc ){
$vval = 0.0;
} elsif( $vfunc ne "" ){
$vval = int( $vfunc*1000 )/1000;
} else {
$vval = "???";
}
#Log 1," And finally after evaluation $vfunc";
$vlow =$owg_vlow[$i];
$vhigh=$owg_vhigh[$i];
#-- string buildup for return value, STATE and alarm
$svalue .= sprintf( "%s: %5.3f %s", $owg_channel[$i], $vval,$hash->{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<int(@owg_fixed);$i++){
$value .= sprintf "%s:[%4.2f,%4.2f] ",$owg_channel[$i],
$hash->{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<int(@owg_fixed);$i++ ){
$newkeys .= " ".$owg_channel[$i]."Alarm";
$newkeys .= " ".$owg_channel[$i]."Low";
$newkeys .= " ".$owg_channel[$i]."High";
if( defined($owg_channel[0]) ){
for( my $i=0;$i<int(@owg_fixed);$i++ ){
$newkeys .= " ".$owg_channel[$i]."Alarm";
$newkeys .= " ".$owg_channel[$i]."Low";
$newkeys .= " ".$owg_channel[$i]."High";
}
}
return $newkeys ;
}
@ -765,32 +784,22 @@ 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,"status");
return $ret
if(defined($ret));
} else {
return "OWAD: Set with wrong IODev type $interface";
}
}elsif( $key =~ m/(.*)(Low|High)/ ) {
#$offset = $attr{$name}{$owg_fixed[$channo]."Offset"};
#$factor = $attr{$name}{$owg_fixed[$channo]."Factor"};
#-- find upper and lower boundaries for given offset/factor
my $mmin = 0.0;
#$mmin += $offset if ( $offset );
#$mmin *= $factor if ( $factor );
my $mmax = $owg_range[$channo]/1000;
#$mmax += $offset if ( $offset );
#$mmax *= $factor if ( $factor );
return sprintf("OWAD: Set with wrong value $value for $key, range is [%3.1f,%3.1f]",$mmin,$mmax)
if($value < $mmin || $value > $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<int(@owg_fixed);$i++){
$owg_val[$i]= int($ral[$i]*1000)/1000;
}
#=============== get the alarm reading ===============================
} elsif ( $page eq "alarm" ) {
#-- get values - or should we rather use the uncached ones ?
$rel = OWServer_Read($master,"/$owx_add/set_alarm/voltlow.ALL");
$rel2 = OWServer_Read($master,"/$owx_add/set_alarm/volthigh.ALL");
return "no return from OWServer"
if( (!defined($rel)) || (!defined($rel2)) );
return "empty return from OWServer"
if( ($rel eq "") || ($rel2 eq "") );
@ral = split(/,/,$rel);
@ral2= split(/,/,$rel2);
return "wrong data length from OWServer"
if( (int(@ral) != 4) || (int(@ral2) != 4) );
for( $i=0;$i<int(@owg_fixed);$i++){
$owg_vlow[$i]= int($ral[$i]*1000)/1000;
$owg_vhigh[$i]= int($ral2[$i]*1000)/1000;
}
#=============== get the status reading ===============================
} elsif ( $page eq "status" ) {
#-- so far not clear, how to find out which type of operation we have.
# We therefore ASSUME normal operation
#-- normal operation
#-- put into globals
for( $i=0;$i<int(@owg_fixed);$i++){
$owg_mode[$i] = "input";
$owg_resoln[$i] = 16;
$owg_range[$i] = 5100;
}
#-- get values - or should we rather use the uncached ones ?
$rel = OWServer_Read($master,"/$owx_add/alarm/low.ALL");
$rel2 = OWServer_Read($master,"/$owx_add/set_alarm/low.ALL");
return "no return from OWServer"
if( (!defined($rel)) || (!defined($rel2)) );
return "empty return from OWServer"
if( ($rel eq "") || ($rel2 eq "") );
@ral = split(/,/,$rel);
@ral2= split(/,/,$rel2);
return "wrong data length from OWServer"
if( (int(@ral) != 4) || (int(@ral2) != 4) );
for( $i=0;$i<int(@owg_fixed);$i++){
#-- low alarm disabled
if( $ral2[$i]==0 ){
$owg_slow[$i] = 0;
}else {
#-- low alarm enabled and not set
if ( $ral[$i]==0 ){
$owg_slow[$i] = 1;
#-- low alarm enabled and set
}else{
$owg_slow[$i] = 2;
}
}
}
#-- get values - or should we rather use the uncached ones ?
$rel = OWServer_Read($master,"/$owx_add/alarm/high.ALL");
$rel2 = OWServer_Read($master,"/$owx_add/set_alarm/high.ALL");
return "no return from OWServer"
if( (!defined($rel)) || (!defined($rel2)) );
return "empty return from OWServer"
if( ($rel eq "") || ($rel2 eq "") );
@ral = split(/,/,$rel);
@ral2= split(/,/,$rel2);
return "wrong data length from OWServer"
if( (int(@ral) != 4) || (int(@ral2) != 4) );
for( $i=0;$i<int(@owg_fixed);$i++){
#-- low alarm disabled
if( $ral2[$i]==0 ){
$owg_shigh[$i] = 0;
}else {
#-- low alarm enabled and not set
if ( $ral[$i]==0 ){
$owg_shigh[$i] = 1;
#-- low alarm enabled and set
}else{
$owg_shigh[$i] = 2;
}
}
}
##-- output operation
#} else {
# $owg_mode[$i] = "output";
# #-- assemble status string
# $owg_status[$i] = $owg_mode[$i].", ";
# $owg_status[$i] .= ($sb1 & 64 ) ? "ON" : "OFF";
#}
}
return undef
}
########################################################################################
#
# OWXAD_SetPage - Set one page of device
#
# Parameter hash = hash of device addressed
# page = "alarm" or "status"
#
########################################################################################
sub OWFSAD_SetPage($$) {
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 $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;$i<int(@owg_fixed);$i++){
if( $owg_mode[$i] eq "input" ){
#-- resolution (TODO: check !)
#
#-- alarm enabled
if( defined($owg_slow[$i]) ){
$ral[$i]=1
if($owg_slow[$i]>0);
}
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<int(@owg_fixed);$i++){
if( $owg_mode[$i] eq "input" ){
#-- resolution (TODO: check !)
$sb1 = $owg_resoln[$i]-1;
@ -1069,10 +1300,11 @@ sub OWXAD_SetPage($$) {
=begin html
<a name="OWAD"></a>
<h3>OWAD</h3>
<p>FHEM module to commmunicate with 1-Wire A/D converters<br /><br /> Note:<br /> This
1-Wire module so far works only with the OWX interface module. Please define an <a
href="#OWX">OWX</a> device first. <br /></p>
<h3>OWAD</h3>
<p>FHEM module to commmunicate with 1-Wire A/D converters<br /><br />
<br />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 <a href="#OWX">OWX</a> device or <a href="#OWServer">OWServer</a> device first. <br/></p>
<br /><h4>Example</h4>
<p>
<code>define OWX_AD OWAD 724610000000 45</code>
@ -1093,7 +1325,8 @@ sub OWXAD_SetPage($$) {
<a name="OWADdefine"></a>
<h4>Define</h4>
<p>
<code>define &lt;name&gt; OWAD [&lt;model&gt;] &lt;id&gt; [&lt;interval&gt;]</code>
<code>define &lt;name&gt; OWAD [&lt;model&gt;] &lt;id&gt; [&lt;interval&gt;]</code> or <br/>
<code>define &lt;name&gt; OWAD &lt;fam&gt;.&lt;id&gt; [&lt;interval&gt;]</code>
<br /><br /> Define a 1-Wire A/D converter.<br /><br /></p>
<ul>
<li>
@ -1102,6 +1335,10 @@ sub OWXAD_SetPage($$) {
<li>model DS2450 with family id 20 (default if the model parameter is
omitted)</li>
</ul>
</li>
<li>
<code>&lt;fam&gt;</code>
<br />2-character unique family id, see above
</li>
<li>
<code>&lt;id&gt;</code>

View File

@ -10,12 +10,13 @@
#
########################################################################################
#
# define <name> OWCOUNT [<model>] <ROM_ID> [interval]
# define <name> OWCOUNT [<model>] <ROM_ID> [interval] or OWCOUNT <FAM_ID>.<ROM_ID> [interval]
#
# where <name> may be replaced by any name string
#
# <model> is a 1-Wire device type. If omitted, we assume this to be an
# DS2423 Counter/RAM
# <FAM_ID> is a 1-Wire family id, currently allowed value is 1D
# <ROM_ID> 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 <name> OWCOUNT [<model>] <id> [interval]"
return "OWCOUNT: Wrong syntax, must be define <name> OWCOUNT [<model>] <id> [interval] or OWCOUNT <fam>.<id> [interval]"
if(int(@a) < 2 || int(@a) > 5);
#-- check if this is an old style definition, e.g. <model> 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($$$) {
<a name="OWCOUNT"></a>
<h3>OWCOUNT</h3>
<p>FHEM module to commmunicate with 1-Wire Counter/RAM DS2423 #<br /><br /> Note:<br /> This
1-Wire module so far works only with the OWX interface module. Please define an <a
href="#OWX">OWX</a> device first. </p>
<p>FHEM module to commmunicate with 1-Wire Counter/RAM DS2423 <br />
<br />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 <a href="#OWX">OWX</a> device or <a href="#OWServer">OWServer</a> device first. <br/><p/>
<br /><h4>Example</h4><br />
<code>define OWX_C OWCOUNT DS2423 CE780F000000 300</code>
<br />
@ -999,7 +1099,8 @@ sub OWXCOUNT_SetPage($$$) {
<a name="OWCOUNTdefine"></a>
<h4>Define</h4>
<p>
<code>define &lt;name&gt; OWCOUNT [&lt;model&gt;] &lt;id&gt; [&lt;interval&gt;]</code>
<code>define &lt;name&gt; OWCOUNT [&lt;model&gt;] &lt;id&gt; [&lt;interval&gt;]</code> or <br/>
<code>define &lt;name&gt; OWCOUNT &lt;fam&gt;.&lt;id&gt; [&lt;interval&gt;]</code>
<br /><br /> Define a 1-Wire counter.<br /><br /></p>
<ul>
<li>
@ -1009,6 +1110,10 @@ sub OWXCOUNT_SetPage($$$) {
omitted)</li>
</ul>
</li>
<li>
<code>&lt;fam&gt;</code>
<br />2-character unique family id, see above
</li>
<li>
<code>&lt;id&gt;</code>
<br />12-character unique ROM id of the converter device without family id and CRC
@ -1088,4 +1193,4 @@ sub OWXCOUNT_SetPage($$$) {
</ul>
=end html
=cut
=cut

View File

@ -10,13 +10,13 @@
#
########################################################################################
#
# define <name> OWMULTI [<model>] <ROM_ID> [interval]
# define <name> OWMULTI [<model>] <ROM_ID> [interval] or OWMULTI <FAM_ID>.<ROM_ID> [interval]
#
# where <name> may be replaced by any name string
#
# <model> is a 1-Wire device type. If omitted, we assume this to be an
# DS2438
#
# <FAM_ID> is a 1-Wire family id, currently allowed value is 26
# <ROM_ID> 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 <name> OWMULTI [<model>] <id> [interval]"
if(int(@a) < 2 || int(@a) > 6);
#-- check if this is an old style definition, e.g. <model> 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($@) {
<a name="OWMULTI"></a>
<h3>OWMULTI</h3>
<p>FHEM module to commmunicate with 1-Wire multi-sensors, currently the DS2438 smart battery
monitor<br /><br /> Note:<br /> This 1-Wire module so far works only with the OWX
interface module. Please define an <a href="#OWX">OWX</a> device first. <br /></p>
monitor<br /> <br />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 <a href="#OWX">OWX</a> device or <a href="#OWServer">OWServer</a> device first. <br/></p>
<br /><h4>Example</h4>
<p>
<code>define OWX_M OWMULTI 7C5034010000 45</code>
@ -842,7 +901,8 @@ sub OWXMULTI_SetValues($@) {
<a name="OWMULTIdefine"></a>
<h4>Define</h4>
<p>
<code>define &lt;name&gt; OWMULTI [&lt;model&gt;] &lt;id&gt; [&lt;interval&gt;]</code>
<code>define &lt;name&gt; OWMULTI [&lt;model&gt;] &lt;id&gt; [&lt;interval&gt;]</code> or <br/>
<code>define &lt;name&gt; OWMULTI &lt;fam&gt;.&lt;id&gt; [&lt;interval&gt;]</code>
<br /><br /> Define a 1-Wire multi-sensor<br /><br /></p>
<ul>
<li>
@ -852,6 +912,10 @@ sub OWXMULTI_SetValues($@) {
Measured is a temperature value, an external voltage and the current supply
voltage</li>
</ul>
</li>
<li>
<code>&lt;fam&gt;</code>
<br />2-character unique family id, see above
</li>
<li>
<code>&lt;id&gt;</code>
@ -927,4 +991,4 @@ sub OWXMULTI_SetValues($@) {
</ul>
=end html
=cut
=cut

View File

@ -10,12 +10,13 @@
#
########################################################################################
#
# define <name> OWSWITCH [<model>] <ROM_ID> [interval]
# define <name> OWSWITCH [<model>] <ROM_ID> [interval] or OWSWITCH <fam>.<ROM_ID> [interval]
#
# where <name> may be replaced by any name string
#
# <model> is a 1-Wire device type. If omitted, we assume this to be an
# DS2413. Allowed values are DS2413, DS2406
# <fam> is a 1-Wire family id, currently allowed values are 12, 29, 3A
# <ROM_ID> 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($$) {
<a name="OWSWITCH"></a>
<h3>OWSWITCH</h3>
<p>FHEM module to commmunicate with 1-Wire Programmable Switches <br /><br /> Note:<br />
This 1-Wire module so far works only with the OWX interface module. Please define an <a
href="#OWX">OWX</a> device first. <br /></p>
<p>FHEM module to commmunicate with 1-Wire Programmable Switches <br />
<br />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 <a href="#OWX">OWX</a> device or <a href="#OWServer">OWServer</a> device first. <br /></p>
<br /><h4>Example</h4>
<p>
<code>define OWX_S OWSWITCH DS2413 B5D502000000 60</code>
@ -1113,7 +1117,8 @@ sub OWXSWITCH_SetState($$) {
<a name="OWSWITCHdefine"></a>
<h4>Define</h4>
<p>
<code>define &lt;name&gt; OWSWITCH [&lt;model&gt;] &lt;id&gt; [&lt;interval&gt;]</code>
<code>define &lt;name&gt; OWSWITCH [&lt;model&gt;] &lt;id&gt; [&lt;interval&gt;]</code> or <br/>
<code>define &lt;name&gt; OWSWITCH &lt;fam&gt;.&lt;id&gt; [&lt;interval&gt;]</code>
<br /><br /> Define a 1-Wire switch.<br /><br /></p>
<ul>
<li>
@ -1125,9 +1130,13 @@ sub OWXSWITCH_SetState($$) {
<li>model DS2408 with family id 29. 8 Channel switch</li>
</ul>
</li>
<li>
<code>&lt;fam&gt;</code>
<br />2-character unique family id, see above
</li>
<li>
<code>&lt;id&gt;</code>
<br />12-character unique ROM id of the converter device without family id and CRC
<br />12-character unique ROM id of the device without family id and CRC
code </li>
<li>
<code>&lt;interval&gt;</code>

View File

@ -12,18 +12,19 @@
#
########################################################################################
#
# define <name> OWTHERM [<model>] <ROM_ID> [interval]
# define <name> OWTHERM [<model>] <ROM_ID> [interval] or <FAM_ID>.<ROM_ID> [interval]
#
# where <name> may be replaced by any name string
#
# <model> is a 1-Wire device type. If omitted, we assume this to be an
# DS1820 temperature sensor
# Currently allowed values are DS1820, DS18B20, DS1822
# <FAM_ID> is a 1-Wire family id, currently allowed values are 10, 22, 28
# <ROM_ID> 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 <name> id => OW_FAMILY.ROM_ID.CRC
# get <name> id => FAM_ID.ROM_ID.CRC
# get <name> present => 1 if device present, 0 if not
# get <name> interval => query interval
# get <name> temperature => temperature measurement
@ -34,7 +35,6 @@
# set <name> tempHigh => higher alarm temperature setting
#
# Additional attributes are defined in fhem.cfg
# Note: attributes "tempXXXX" are read during every update operation.
#
# attr <name> stateAL "<string>" = character string for denoting low alarm condition, default is down triangle
# attr <name> stateAH "<string>" = 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 <name> OWTHERM [<model>] <id> [interval]"
return "OWTHERM: Wrong syntax, must be define <name> OWTHERM [<model>] <id> [interval] or OWTHERM <fam>.<id> [interval]"
if(int(@a) < 2 || int(@a) > 6);
#-- check if this is an old style definition, e.g. <model> 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
<a name="OWTHERM"></a>
<a name="OWTHERM"></a>
<h3>OWTHERM</h3>
<p>FHEM module to commmunicate with 1-Wire bus digital thermometer devices<br /><br />
Note:<br /> This is the only 1-Wire module which so far works with both the OWFS and the
OWX interface module. Please define an <a href="#OWFS">OWFS</a> device or an <a
href="#OWX">OWX</a> device first. <br />
<p>FHEM module to commmunicate with 1-Wire bus digital thermometer devices<br />
<br />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 <a href="#OWX">OWX</a> device or <a href="#OWServer">OWServer</a> device first. <br />
</p>
<h4>Example</h4>
<p>
@ -813,7 +859,8 @@ sub OWXTHERM_SetValues($@) {
<a name="OWTHERMdefine"></a>
<h4>Define</h4>
<p>
<code>define &lt;name&gt; OWTHERM [&lt;model&gt;] &lt;id&gt; [&lt;interval&gt;]</code>
<code>define &lt;name&gt; OWTHERM [&lt;model&gt;] &lt;id&gt; [&lt;interval&gt;]</code> or <br/>
<code>define &lt;name&gt; OWTHERM &lt;fam&gt;.lt;id&gt; [&lt;interval&gt;]</code>
<br /><br /> Define a 1-Wire digital thermometer device.</p>
<ul>
<li>
@ -825,6 +872,9 @@ sub OWXTHERM_SetValues($@) {
<li>model DS18B20 with family id 28</li>
</ul>
</li>
<li>
<code>&lt;fam&gt;</code>
<br />2-character unique family id, see above </li>
<li>
<code>&lt;id&gt;</code>
<br />12-character unique ROM id of the thermometer device without family id and CRC