2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-07 06:48:43 +00:00

OWAD.pm: Neue Version 6.0, eingerichtet für asynchrones OWX

OWCOUNT.pm: Neue Version 6.0, eingerichtet für asynchrones OWX
OWID.pm: Neue Version 6.0, eingerichtet für asynchrones OWX
OWLCD.pm: Neue Version 6.0, eingerichtet für asynchrones OWX
OWMULTI.pm: Neue Version 6.0, eingerichtet für asynchrones OWX
OWSWITCH.pm: Neue Version 6.0, eingerichtet für asynchrones OWX
OWTHERM.pm: Neue Version 6.0, eingerichtet für asynchrones OWX


git-svn-id: https://svn.fhem.de/fhem/trunk@11130 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
pahenning 2016-03-27 09:14:38 +00:00
parent 15cb46808f
commit fc6db34218
7 changed files with 2270 additions and 1630 deletions

View File

@ -36,20 +36,16 @@
# #
# attr <name> stateAL0 "<string>" = character string for denoting low normal condition, default is empty # 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 # attr <name> stateAH0 "<string>" = character string for denoting high normal condition, default is empty
# attr <name> stateAL1 "<string>" = character string for denoting low alarm condition, default is down triangle # attr <name> stateAL1 "<string>" = character string for denoting low alarm condition, default is
# attr <name> stateAH1 "<string>" = character string for denoting high alarm condition, default is up triangle # attr <name> stateAH1 "<string>" = character string for denoting high alarm condition, default is
# attr <name> <channel>Name <string>[|<string>] = name for the channel [|name used in state reading] # attr <name> <channel>Name <string>[|<string>] = name for the channel [|name used in state reading]
# attr <name> <channel>Unit <string>[|<string>] = unit of measurement for this channel [|unit used in state reading] # attr <name> <channel>Unit <string> = unit of measurement for this channel used in state reading (default V, none for empty)
#
# ATTENTION: Usage of Offset/Factor is deprecated, replace by Function attribute
# attr <name> <channel>Offset <float> = offset added to the reading in this channel
# attr <name> <channel>Factor <float> = factor multiplied to (reading+offset) in this channel
# attr <name> <channel>Function <string> = arbitrary functional expression involving the values V<channel>=VA,VB,VC,VD # attr <name> <channel>Function <string> = arbitrary functional expression involving the values V<channel>=VA,VB,VC,VD
# VA is replaced by the measured voltage in channel A, etc. # VA is replaced by the measured voltage in channel A, etc.
# #
# attr <name> <channel>Alarm <string> = alarm setting in this channel, either both, low, high or none (default) # attr <name> <channel>Alarm <string> = alarm setting in this channel, either both, low, high or none (default)
# attr <name> <channel>Low <float> = measurement value (on the scale determined by offset and factor) for low alarm # attr <name> <channel>Low <float> = measurement value (on the scale determined by function) for low alarm
# attr <name> <channel>High <float> = measurement value (on the scale determined by offset and factor) for high alarm # attr <name> <channel>High <float> = measurement value (on the scale determined by function) for high alarm
# #
######################################################################################## ########################################################################################
# #
@ -88,9 +84,9 @@ BEGIN {
use ProtoThreads; use ProtoThreads;
no warnings 'deprecated'; no warnings 'deprecated';
sub Log($$); sub Log3($$$);
my $owx_version="5.20"; my $owx_version="6.0";
#-- fixed raw channel name, flexible channel name #-- fixed raw channel name, flexible channel name
my @owg_fixed = ("A","B","C","D"); my @owg_fixed = ("A","B","C","D");
my @owg_channel = ("A","B","C","D"); my @owg_channel = ("A","B","C","D");
@ -161,15 +157,13 @@ sub OWAD_Initialize ($) {
$hash->{InitFn} = "OWAD_Init"; $hash->{InitFn} = "OWAD_Init";
$hash->{AttrFn} = "OWAD_Attr"; $hash->{AttrFn} = "OWAD_Attr";
my $attlist = "IODev do_not_notify:0,1 showtime:0,1 model:DS2450 verbose:0,1,2,3,4,5 ". my $attlist = "IODev do_not_notify:0,1 showtime:0,1 model:DS2450 ".
"stateAL0 stateAL1 stateAH0 stateAH1 ". "stateAL0 stateAL1 stateAH0 stateAH1 ".
"interval ". "interval ".
$readingFnAttributes; $readingFnAttributes;
for( my $i=0;$i<int(@owg_fixed);$i++ ){ for( my $i=0;$i<int(@owg_fixed);$i++ ){
$attlist .= " ".$owg_fixed[$i]."Name"; $attlist .= " ".$owg_fixed[$i]."Name";
$attlist .= " ".$owg_fixed[$i]."Offset";
$attlist .= " ".$owg_fixed[$i]."Factor";
$attlist .= " ".$owg_fixed[$i]."Function"; $attlist .= " ".$owg_fixed[$i]."Function";
$attlist .= " ".$owg_fixed[$i]."Unit"; $attlist .= " ".$owg_fixed[$i]."Unit";
$attlist .= " ".$owg_fixed[$i]."Alarm:none,low,high,both"; $attlist .= " ".$owg_fixed[$i]."Alarm:none,low,high,both";
@ -276,7 +270,7 @@ sub OWAD_Define ($$) {
$main::modules{OWAD}{defptr}{$id} = $hash; $main::modules{OWAD}{defptr}{$id} = $hash;
#-- #--
readingsSingleUpdate($hash,"state","defined",1); readingsSingleUpdate($hash,"state","defined",1);
Log 3, "OWAD: Device $name defined."; Log 3, "OWAD: Device $name defined.";
$hash->{NOTIFYDEV} = "global"; $hash->{NOTIFYDEV} = "global";
@ -391,11 +385,11 @@ sub OWAD_ChannelNames($) {
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $state = $hash->{READINGS}{"state"}{VAL}; my $state = $hash->{READINGS}{"state"}{VAL};
my ($cname,@cnama,$unit,@unarr); my ($cname,@cnama,$unit);
for (my $i=0;$i<int(@owg_fixed);$i++){ for (my $i=0;$i<int(@owg_fixed);$i++){
#-- name #-- name
$cname = defined($attr{$name}{$owg_fixed[$i]."Name"}) ? $attr{$name}{$owg_fixed[$i]."Name"} : $owg_fixed[$i]; $cname = defined($attr{$name}{$owg_fixed[$i]."Name"}) ? $attr{$name}{$owg_fixed[$i]."Name"} : "$owg_fixed[$i]";
@cnama = split(/\|/,$cname); @cnama = split(/\|/,$cname);
if( int(@cnama)!=2){ if( int(@cnama)!=2){
push(@cnama,$cnama[0]); push(@cnama,$cnama[0]);
@ -403,16 +397,16 @@ sub OWAD_ChannelNames($) {
$owg_channel[$i]=$cnama[0]; $owg_channel[$i]=$cnama[0];
#-- unit #-- unit
$unit = defined($attr{$name}{$owg_fixed[$i]."Unit"}) ? $attr{$name}{$owg_fixed[$i]."Unit"} : "Volt|V"; $unit = defined($attr{$name}{$owg_fixed[$i]."Unit"}) ? $attr{$name}{$owg_fixed[$i]."Unit"} : "V";
@unarr= split(/\|/,$unit); if($unit eq "none"){
if( int(@unarr)!=2 ){ $unit = "";
push(@unarr,$unarr[0]); }else{
$unit = " ".$unit;
} }
#-- put into readings #-- put into readings
$hash->{READINGS}{$owg_channel[$i]}{ABBR} = $cnama[1]; $hash->{READINGS}{$owg_channel[$i]}{ABBR} = $cnama[1];
$hash->{READINGS}{$owg_channel[$i]}{UNIT} = $unarr[0]; $hash->{READINGS}{$owg_channel[$i]}{UNIT} = $unit;
$hash->{READINGS}{$owg_channel[$i]}{UNITABBR} = $unarr[1];
} }
} }
@ -429,7 +423,7 @@ sub OWAD_FormatValues($) {
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $interface = $hash->{IODev}->{TYPE}; my $interface = $hash->{IODev}->{TYPE};
my ($offset,$factor,$vval,$vlow,$vhigh,$vfunc,$ret); my ($vval,$vlow,$vhigh,$vfunc,$ret);
my $vfuncall = ""; my $vfuncall = "";
my $svalue = ""; my $svalue = "";
@ -445,8 +439,8 @@ sub OWAD_FormatValues($) {
$hash->{ALARM} = 0; $hash->{ALARM} = 0;
#-- alarm signatures #-- alarm signatures
my $stateal1 = defined($attr{$name}{stateAL1}) ? $attr{$name}{stateAL1} : "&#x25BE;"; my $stateal1 = defined($attr{$name}{stateAL1}) ? $attr{$name}{stateAL1} : "";
my $stateah1 = defined($attr{$name}{stateAH1}) ? $attr{$name}{stateAH1} : "&#x25B4;"; my $stateah1 = defined($attr{$name}{stateAH1}) ? $attr{$name}{stateAH1} : "";
my $stateal0 = defined($attr{$name}{stateAL0}) ? $attr{$name}{stateAL0} : ""; my $stateal0 = defined($attr{$name}{stateAL0}) ? $attr{$name}{stateAL0} : "";
my $stateah0 = defined($attr{$name}{stateAH0}) ? $attr{$name}{stateAH0} : ""; my $stateah0 = defined($attr{$name}{stateAH0}) ? $attr{$name}{stateAH0} : "";
@ -463,13 +457,7 @@ sub OWAD_FormatValues($) {
#-- formats for output #-- formats for output
for (my $i=0;$i<int(@owg_fixed);$i++){ for (my $i=0;$i<int(@owg_fixed);$i++){
#-- when offset and scale factor are defined, we cannot have a function and vice versa if (defined($attr{$name}{$owg_fixed[$i]."Function"})){
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)";
#-- attribute VFunction defined
} elsif (defined($attr{$name}{$owg_fixed[$i]."Function"})){
$vfunc = $attr{$name}{$owg_fixed[$i]."Function"}; $vfunc = $attr{$name}{$owg_fixed[$i]."Function"};
} else { } else {
$vfunc = "V$owg_fixed[$i]"; $vfunc = "V$owg_fixed[$i]";
@ -504,7 +492,7 @@ sub OWAD_FormatValues($) {
$main::attr{$name}{$owg_fixed[$i]."High"}=$vhigh; $main::attr{$name}{$owg_fixed[$i]."High"}=$vhigh;
#-- string buildup for return value, STATE and alarm #-- string buildup for return value, STATE and alarm
$svalue .= sprintf( "%s: %5.3f %s", $hash->{READINGS}{$owg_channel[$i]}{ABBR}, $vval,$hash->{READINGS}{$owg_channel[$i]}{UNITABBR}); $svalue .= sprintf( "%s: %5.3f%s", $hash->{READINGS}{$owg_channel[$i]}{ABBR}, $vval,$hash->{READINGS}{$owg_channel[$i]}{UNIT});
#-- Test for alarm condition #-- Test for alarm condition
$alarm = "none"; $alarm = "none";
@ -542,6 +530,7 @@ sub OWAD_FormatValues($) {
} }
#-- put into READINGS #-- put into READINGS
$vval = sprintf( "%5.3f", $vval);
readingsBulkUpdate($hash,"$owg_channel[$i]",$vval); readingsBulkUpdate($hash,"$owg_channel[$i]",$vval);
#-- insert space #-- insert space
if( $i<int(@owg_fixed)-1 ){ if( $i<int(@owg_fixed)-1 ){
@ -578,8 +567,6 @@ sub OWAD_Get($@) {
my $interface= $hash->{IODev}->{TYPE}; my $interface= $hash->{IODev}->{TYPE};
my ($value,$value2,$value3) = (undef,undef,undef); my ($value,$value2,$value3) = (undef,undef,undef);
my $ret = ""; my $ret = "";
my $offset;
my $factor;
#-- check syntax #-- check syntax
return "OWAD: Get argument is missing @a" return "OWAD: Get argument is missing @a"
@ -642,17 +629,20 @@ sub OWAD_Get($@) {
return "OWAD: Get with wrong IODev type $interface"; return "OWAD: Get with wrong IODev type $interface";
} }
#-- process results #-- process result
if( defined($ret) ){ if( $master->{ASYNCHRONOUS} ){
$hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1; return "OWAD: $name getting reading, please wait for completion";
if( $hash->{ERRCOUNT} > 5 ){ }else{
$hash->{INTERVAL} = 9999; if( defined($ret) ){
$hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1;
if( $hash->{ERRCOUNT} > 5 ){
$hash->{INTERVAL} = 9999;
}
return "OWAD: Could not get values from device $name for ".$hash->{ERRCOUNT}." times, reason $ret";
} }
return "OWAD: Could not get values from device $name for ".$hash->{ERRCOUNT}." times, reason $ret"; return "OWAD: $name.reading => ".$hash->{READINGS}{"state"}{VAL};
} }
return "OWAD: $name.reading => ".$hash->{READINGS}{"state"}{VAL};
} }
#-- get alarm values according to interface type #-- get alarm values according to interface type
if($a[1] eq "alarm") { if($a[1] eq "alarm") {
#-- OWX interface #-- OWX interface
@ -671,23 +661,27 @@ sub OWAD_Get($@) {
return "OWAD: Get with wrong IODev type $interface"; return "OWAD: Get with wrong IODev type $interface";
} }
#-- process results #-- process result
if( defined($ret) ){ if( $master->{ASYNCHRONOUS} ){
$hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1; return "OWAD: $name getting alarm values, please wait for completion";
if( $hash->{ERRCOUNT} > 5 ){ }else{
$hash->{INTERVAL} = 9999; if( defined($ret) ){
$hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1;
if( $hash->{ERRCOUNT} > 5 ){
$hash->{INTERVAL} = 9999;
}
return "OWAD: Could not get values from device $name for ".$hash->{ERRCOUNT}." times, reason $ret";
} }
return "OWAD: Could not get values from device $name for ".$hash->{ERRCOUNT}." times, reason $ret";
}
#-- assemble ouput string #-- assemble ouput string
$value = ""; $value = "";
for (my $i=0;$i<int(@owg_fixed);$i++){ for (my $i=0;$i<int(@owg_fixed);$i++){
$value .= sprintf "%s:[%4.2f,%4.2f] ",$owg_channel[$i], $value .= sprintf "%s:[%4.2f,%4.2f] ",$owg_channel[$i],
$main::attr{$name}{$owg_channel[$i]."Low"}, $main::attr{$name}{$owg_channel[$i]."Low"},
$main::attr{$name}{$owg_channel[$i]."High"}; $main::attr{$name}{$owg_channel[$i]."High"};
}
return "OWAD: $name.alarm => $value";
} }
return "OWAD: $name.alarm => $value";
} }
#-- get status values according to interface type #-- get status values according to interface type
@ -708,47 +702,51 @@ sub OWAD_Get($@) {
return "OWAD: Get with wrong IODev type $interface"; return "OWAD: Get with wrong IODev type $interface";
} }
#-- process results #-- process result
if( defined($ret) ){ if( $master->{ASYNCHRONOUS} ){
$hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1; return "OWAD: $name getting status, please wait for completion";
if( $hash->{ERRCOUNT} > 5 ){ }else{
$hash->{INTERVAL} = 9999; if( defined($ret) ){
} $hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1;
return "OWAD: Could not get values from device $name for ".$hash->{ERRCOUNT}." times, reason $ret"; if( $hash->{ERRCOUNT} > 5 ){
} $hash->{INTERVAL} = 9999;
}
return "OWAD: Could not get values from device $name for ".$hash->{ERRCOUNT}." times, reason $ret";
}
#-- assemble output string #-- assemble output string
$value = "\n"; $value = "\n";
for (my $i=0;$i<int(@owg_fixed);$i++){ for (my $i=0;$i<int(@owg_fixed);$i++){
$value .= $owg_channel[$i].": ".$owg_mode[$i].", "; $value .= $owg_channel[$i].": ".$owg_mode[$i].", ";
#$value .= "disabled ," #$value .= "disabled ,"
# if ( !($sb2 && 128) ); # if ( !($sb2 && 128) );
$value .= sprintf "raw range %3.2f V, ",$owg_range[$i]/1000; $value .= sprintf "raw range %3.2f V, ",$owg_range[$i]/1000;
$value .= sprintf "resolution %d bit, ",$owg_resoln[$i]; $value .= sprintf "resolution %d bit, ",$owg_resoln[$i];
if (!defined $hash->{owg_slow}->[$i]) { if (!defined $hash->{owg_slow}->[$i]) {
$value .= "low alarm undefined, "; $value .= "low alarm undefined, ";
} elsif( $hash->{owg_slow}->[$i]==0 ) { } elsif( $hash->{owg_slow}->[$i]==0 ) {
$value .= "low alarm disabled, "; $value .= "low alarm disabled, ";
} elsif( $hash->{owg_slow}->[$i]==1 ) { } elsif( $hash->{owg_slow}->[$i]==1 ) {
$value .= "low alarm enabled, "; $value .= "low alarm enabled, ";
} elsif( $hash->{owg_slow}->[$i]==2 ) { } elsif( $hash->{owg_slow}->[$i]==2 ) {
$value .= "alarmed low, "; $value .= "alarmed low, ";
} }
if (!defined $hash->{owg_shigh}) { if (!defined $hash->{owg_shigh}) {
$value .= "high alarm undefined"; $value .= "high alarm undefined";
} elsif( $hash->{owg_shigh}->[$i]==0 ) { } elsif( $hash->{owg_shigh}->[$i]==0 ) {
$value .= "high alarm disabled"; $value .= "high alarm disabled";
} elsif( $hash->{owg_shigh}->[$i]==1 ) { } elsif( $hash->{owg_shigh}->[$i]==1 ) {
$value .= "high alarm enabled"; $value .= "high alarm enabled";
} elsif( $hash->{owg_shigh}->[$i]==2 ) { } elsif( $hash->{owg_shigh}->[$i]==2 ) {
$value .= "alarmed high"; $value .= "alarmed high";
} }
#-- insert space #-- insert space
if( $i<int(@owg_fixed)-1 ){ if( $i<int(@owg_fixed)-1 ){
$value .= "\n"; $value .= "\n";
}
} }
return "OWAD: $name.status => ".$value;
} }
return "OWAD: $name.status => ".$value;
} }
} }
@ -939,8 +937,6 @@ sub OWAD_Set($@) {
my $ret = undef; my $ret = undef;
my $channon = undef; my $channon = undef;
my $channo = undef; my $channo = undef;
my $factor;
my $offset;
my $condx; my $condx;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
@ -1024,7 +1020,7 @@ sub OWAD_Set($@) {
#-- set alarm values (alarm voltages) #-- set alarm values (alarm voltages)
}elsif( $key =~ m/(.*)(Low|High)/ ) { }elsif( $key =~ m/(.*)(Low|High)/ ) {
#-- find upper and lower boundaries for given offset/factor #-- find upper and lower boundaries
my $mmin = 0.0; my $mmin = 0.0;
my $mmax = $owg_range[$channo]/1000; my $mmax = $owg_range[$channo]/1000;
@ -1313,37 +1309,61 @@ sub OWFSAD_SetPage($$) {
# #
######################################################################################## ########################################################################################
# #
# OWXAD_BinValues - Binary readings into clear values # OWXAD_BinValues - Process reading from one device - translate binary into raw
# #
# Parameter hash = hash of device addressed # Parameter hash = hash of device addressed
# context = mode for evaluating the binary data
# proc = processing instruction, also passed to OWX_Read.
# bitwise interpretation !!
# if 0, nothing special
# if 1 = bit 0, a reset will be performed not only before, but also after
# the last operation in OWX_Read
# if 2 = bit 1, the initial reset of the bus will be suppressed
# if 8 = bit 3, the fillup of the data with 0xff will be suppressed
# if 16= bit 4, the insertion will be at the top of the queue
# owx_dev = ROM ID of slave device
# crcpart = part of the data that needs to be part of the CRC check
# numread = number of bytes to receive
# res = result string
#
# #
######################################################################################## ########################################################################################
sub OWXAD_BinValues($$$$$$$$) { sub OWXAD_BinValues($$$$$$$) {
my ($hash, $context, $success, $reset, $owx_dev, $command, $numread, $res) = @_; my ($hash, $context, $proc, $owx_dev, $crcpart, $numread, $res) = @_;
#-- always check for success, unused are reset #-- hash of the busmaster
return unless ($success and $context); my $master = $hash->{IODev};
#Log 1,"OWXAD_BinValues context = $context"; my $name = $hash->{NAME};
my $final = ($context =~ /\.final$/ ); my @data=[];
my $value;
my ($i,$j,$k,@data,$ow_thn,$ow_tln); my $msg;
OWX_WDBG($name,"OWXAD_BinValues called for device $name in context $context with ",$res)
if( $main::owx_debug>2 );
my $final = ($context =~ /\.final$/ );
my ($ow_thn,$ow_tln);
#-- process results #-- process results
@data=split(//,$res); @data=split(//,$res);
return "invalid data length, ".int(@data)." instead of 10 bytes" if (@data != 10){
if (@data != 10); $msg="$name returns invalid data length, ".int(@data)." instead of 10 bytes ";
return "invalid CRC" }elsif (OWX_CRC16($crcpart.substr($res,0,8),$data[8],$data[9])==0){
if (OWX_CRC16($command.substr($res,0,8),$data[8],$data[9])==0); $msg="$name returns invalid CRC "
}else{
$msg="No error ";
}
OWX_WDBG($name,"OWXAD_BinValues: ".$msg,$crcpart)
if( $main::owx_debug>2 );
#=============== get the voltage reading =============================== #=============== get the voltage reading ===============================
if( $context =~ /^ds2450.getreading/ ){ if( $context =~ /^ds2450.getreading/ ){
for( $i=0;$i<int(@owg_fixed);$i++){ for( my $i=0;$i<int(@owg_fixed);$i++){
$hash->{owg_val}->[$i]= (ord($data[2*$i])+256*ord($data[1+2*$i]) )/(1<<$owg_resoln[$i]) * $owg_range[$i]/1000; $hash->{owg_val}->[$i]= (ord($data[2*$i])+256*ord($data[1+2*$i]) )/(1<<$owg_resoln[$i]) * $owg_range[$i]/1000;
} }
#=============== get the alarm reading =============================== #=============== get the alarm reading ===============================
} elsif ( $context =~ /^ds2450.getalarm/ ){ } elsif ( $context =~ /^ds2450.getalarm/ ){
for( $i=0;$i<int(@owg_fixed);$i++){ for( my $i=0;$i<int(@owg_fixed);$i++){
$hash->{owg_vlow}->[$i] = int(ord($data[2*$i])/256 * $owg_range[$i]+0.5)/1000; $hash->{owg_vlow}->[$i] = int(ord($data[2*$i])/256 * $owg_range[$i]+0.5)/1000;
$hash->{owg_vhigh}->[$i] = int(ord($data[1+2*$i])/256 * $owg_range[$i]+0.5)/1000; $hash->{owg_vhigh}->[$i] = int(ord($data[1+2*$i])/256 * $owg_range[$i]+0.5)/1000;
} }
@ -1406,7 +1426,6 @@ sub OWXAD_BinValues($$$$$$$$) {
$hash->{PRESENT} = 1; $hash->{PRESENT} = 1;
if( $final ){ if( $final ){
my $value = OWAD_FormatValues($hash); my $value = OWAD_FormatValues($hash);
Log 5, $value;
} }
return undef return undef
} }
@ -1465,16 +1484,25 @@ sub OWXAD_GetPage($$$@) {
return "wrong memory page requested from $owx_dev"; return "wrong memory page requested from $owx_dev";
} }
my $context = "ds2450.get".$page.($final ? ".final" : ""); my $context = "ds2450.get".$page.($final ? ".final" : "");
#-- reset the bus #-- OLD OWX interface
OWX_Reset($master); if( !$master->{ASYNCHRONOUS} ){
#-- reading 9 + 3 + 8 data bytes and 2 CRC bytes = 22 bytes #-- reset the bus
$res=OWX_Complex($master,$owx_dev,$select,10); OWX_Reset($master);
return "$owx_dev not accessible in reading page $page" #-- reading 9 + 3 + 8 data bytes and 2 CRC bytes = 22 bytes
if( $res eq 0 ); $res=OWX_Complex($master,$owx_dev,$select,10);
return "$owx_dev has returned invalid data" return "$owx_dev not accessible in reading page $page"
if( length($res)!=22); if( $res eq 0 );
#-- for processing we also need the 3 command bytes return "$owx_dev has returned invalid data"
return OWXAD_BinValues($hash,$context,1,undef,$owx_dev,$select,10,substr($res,12,10)); if( length($res)!=22);
#-- for processing we also need the 3 command bytes
return OWXAD_BinValues($hash,$context,1,undef,$owx_dev,$select,substr($res,12,10));
#-- NEW OWX interface
}else{
#### master slave context proc owx_dev data crcpart numread startread callback delay
# 1 additional reset after last action
OWX_Qomplex($master, $hash, $context, 1, $owx_dev, $select, $select, 10, 12, \&OWXAD_BinValues, 0);
return undef;
}
} }
######################################################################################## ########################################################################################
@ -1542,11 +1570,18 @@ sub OWXAD_SetPage($$) {
} else { } else {
return "wrong memory page write attempt"; return "wrong memory page write attempt";
} }
OWX_Reset($master); #-- OLD OWX interface
$res=OWX_Complex($master,$owx_dev,$select,0); if( !$master->{ASYNCHRONOUS} ){
if( $res eq 0 ){ OWX_Reset($master);
return "device $owx_dev not accessible for writing"; $res=OWX_Complex($master,$owx_dev,$select,0);
} if( $res eq 0 ){
return "device $owx_dev not accessible for writing";
}
#-- NEW OWX interface
}else{
#### master slave context proc owx_dev data crcpart numread startread callback delay
OWX_Qomplex($master, $hash, undef, 0, $owx_dev, $select, 0, 0, 0, undef, 0);
}
return undef; return undef;
} }
@ -1613,7 +1648,7 @@ sub OWXAD_PT_GetPage($$$) {
PT_WAIT_THREAD($thread->{pt_execute}); PT_WAIT_THREAD($thread->{pt_execute});
die $thread->{pt_execute}->PT_CAUSE() if ($thread->{pt_execute}->PT_STATE() == PT_ERROR); die $thread->{pt_execute}->PT_CAUSE() if ($thread->{pt_execute}->PT_STATE() == PT_ERROR);
my $response = $thread->{pt_execute}->PT_RETVAL(); my $response = $thread->{pt_execute}->PT_RETVAL();
my $res = OWXAD_BinValues($hash,"ds2450.get".$page.($final ? ".final" : ""),1,1,$owx_dev,$thread->{'select'},10,$response); my $res = OWXAD_BinValues($hash,"ds2450.get".$page.($final ? ".final" : ""),1,$owx_dev,$thread->{'select'},10,$response);
if ($res) { if ($res) {
die $res; die $res;
} }
@ -1716,16 +1751,14 @@ sub OWXAD_PT_SetPage($$) {
<br /> <br />
<code>attr OWX_AD DAlarm high</code> <code>attr OWX_AD DAlarm high</code>
<br /> <br />
<code>attr OWX_AD DFactor 31.907097</code> <code>attr OWX_AD DName humidity</code>
<br />
<code>attr OWX_AD DUnit %</code>
<br />
<code>attr OWX_AD DFunction VD*31.907097-0.8088</code>
<br /> <br />
<code>attr OWX_AD DHigh 50.0</code> <code>attr OWX_AD DHigh 50.0</code>
<br /> <br />
<code>attr OWX_AD DName RelHumidity|humidity</code>
<br />
<code>attr OWX_AD DOffset -0.8088</code>
<br />
<code>attr OWX_AD DUnit percent|%</code>
<br />
</p><br /> </p><br />
<a name="OWADdefine"></a> <a name="OWADdefine"></a>
<h4>Define</h4> <h4>Define</h4>
@ -1792,46 +1825,31 @@ sub OWXAD_PT_SetPage($$) {
<li><a name="owad_stateAH0"><code>attr &lt;name&gt; stateAH0 &lt;string&gt;</code></a> <li><a name="owad_stateAH0"><code>attr &lt;name&gt; stateAH0 &lt;string&gt;</code></a>
<br />character string for denoting high normal condition, default is empty </li> <br />character string for denoting high normal condition, default is empty </li>
<li><a name="owad_stateAL1"><code>attr &lt;name&gt; stateAL1 &lt;string&gt;</code></a> <li><a name="owad_stateAL1"><code>attr &lt;name&gt; stateAL1 &lt;string&gt;</code></a>
<br />character string for denoting low alarm condition, default is down triangle, <br />character string for denoting low alarm condition, default is ↓</li>
e.g. the code &amp;#x25BE; leading to the sign &#x25BE;</li>
<li><a name="owad_stateAH1"><code>attr &lt;name&gt; stateAH1 &lt;string&gt;</code></a> <li><a name="owad_stateAH1"><code>attr &lt;name&gt; stateAH1 &lt;string&gt;</code></a>
<br />character string for denoting high alarm condition, default is upward <br />character string for denoting high alarm condition, default is ↑</li>
triangle, e.g. the code &amp;#x25B4; leading to the sign &#x25B4; </li>
</ul> For each of the following attributes, the channel identification A,B,C,D may be used. <ul> </ul> For each of the following attributes, the channel identification A,B,C,D may be used. <ul>
<li><a name="owad_cname"><code>attr &lt;name&gt; &lt;channel&gt;Name <li><a name="owad_cname"><code>attr &lt;name&gt; &lt;channel&gt;Name
&lt;string&gt;[|&lt;string&gt;]</code></a> &lt;string&gt;[|&lt;string&gt;]</code></a>
<br />name for the channel [|name used in state reading]. </li> <br />name for the channel [|short name used in state reading]. </li>
<li><a name="owad_cunit"><code>attr &lt;name&gt; &lt;channel&gt;Unit <li><a name="owad_cunit"><code>attr &lt;name&gt; &lt;channel&gt;Unit
&lt;string&gt;[|&lt;string&gt;]</code></a> &lt;string&gt;</code></a>
<br />unit of measurement for this channel [|unit used in state reading]. </li> <br />unit of measurement for this channel used in state reading (default "V", set to "none" for empty). </li>
<li><a name="owad_coffset"><b>deprecated</b>: <code>attr &lt;name&gt; &lt;channel&gt;Offset
&lt;float&gt;</code></a>
<br />offset added to the reading in this channel. </li>
<li><a name="owad_cfactor"><b>deprecated</b>: <code>attr &lt;name&gt; &lt;channel&gt;Factor
&lt;float&gt;</code></a>
<br />factor multiplied to (reading+offset) in this channel. </li>
<li><a name="owad_cfunction"> <code>attr &lt;name&gt; &lt;channel&gt;Function <li><a name="owad_cfunction"> <code>attr &lt;name&gt; &lt;channel&gt;Function
&lt;string&gt;</code></a> &lt;string&gt;</code></a>
<br />arbitrary functional expression involving the values VA,VB,VC,VD. VA is replaced by <br />arbitrary functional expression involving the variables VA,VB,VC,VD. VA is replaced by
the measured voltage in channel A, etc. This attribute allows linearization of measurement the (raw) measured voltage in channel A, etc. This attribute allows linearization of measurement
curves as well as the mixing of various channels. <b>Replacement for Offset/Factor !</b></li> curves as well as the mixing of various channels. </li>
<li><a name="owad_calarm"><code>attr &lt;name&gt; &lt;channel&gt;Alarm <li><a name="owad_calarm"><code>attr &lt;name&gt; &lt;channel&gt;Alarm
&lt;string&gt;</code></a> &lt;string&gt;</code></a>
<br />alarm setting in this channel, either both, low, high or none (default). </li> <br />alarm setting in this channel, either both, low, high or none (default). </li>
<li><a name="owad_clow"><code>attr &lt;name&gt; &lt;channel&gt;Low <li><a name="owad_clow"><code>attr &lt;name&gt; &lt;channel&gt;Low
&lt;float&gt;</code></a> &lt;float&gt;</code></a>
<br />measurement value (on the scale determined by offset and factor) for low <br />measurement value for low alarm. </li>
alarm. </li>
<li><a name="owad_chigh"><code>attr &lt;name&gt; &lt;channel&gt;High <li><a name="owad_chigh"><code>attr &lt;name&gt; &lt;channel&gt;High
&lt;float&gt;</code></a> &lt;float&gt;</code></a>
<br />measurement value (on the scale determined by offset and factor) for high <br />measurement value for highalarm. </li>
alarm. </li> <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
<li>Standard attributes <a href="#alias">alias</a>, <a href="#comment">comment</a>, <a
href="#event-on-update-reading">event-on-update-reading</a>, <a
href="#event-on-change-reading">event-on-change-reading</a>, <a
href="#stateFormat">stateFormat</a>, <a href="#room"
>room</a>, <a href="#eventMap">eventMap</a>, <a href="#verbose">verbose</a>,
<a href="#webCmd">webCmd</a></li>
</ul> </ul>
=end html =end html

File diff suppressed because it is too large Load Diff

View File

@ -66,9 +66,9 @@ BEGIN {
use GPUtils qw(:all); use GPUtils qw(:all);
use ProtoThreads; use ProtoThreads;
no warnings 'deprecated'; no warnings 'deprecated';
sub Log($$); sub Log3($$$);
my $owx_version="5.15"; my $owx_version="6.0beta6";
#-- declare variables #-- declare variables
my %gets = ( my %gets = (
"present" => "", "present" => "",
@ -107,8 +107,7 @@ sub OWID_Initialize ($) {
$hash->{AttrFn} = "OWID_Attr"; $hash->{AttrFn} = "OWID_Attr";
$hash->{NotifyFn} = "OWID_Notify"; $hash->{NotifyFn} = "OWID_Notify";
$hash->{InitFn} = "OWID_Init"; $hash->{InitFn} = "OWID_Init";
$hash->{AttrList} = "IODev do_not_notify:0,1 showtime:0,1 model loglevel:0,1,2,3,4,5 ". $hash->{AttrList} = "IODev do_not_notify:0,1 showtime:0,1 model interval".
"interval ".
$readingFnAttributes; $readingFnAttributes;
#--make sure OWX is loaded so OWX_CRC is available if running with OWServer #--make sure OWX is loaded so OWX_CRC is available if running with OWServer
@ -212,7 +211,7 @@ sub OWID_Define ($$) {
$modules{OWID}{defptr}{$id} = $hash; $modules{OWID}{defptr}{$id} = $hash;
#-- #--
readingsSingleUpdate($hash,"state","Defined",1); readingsSingleUpdate($hash,"state","Defined",1);
Log 3, "OWID: Device $name defined."; Log3 $name,1, "OWID: Device $name defined.";
$hash->{NOTIFYDEV} = "global"; $hash->{NOTIFYDEV} = "global";
@ -240,7 +239,7 @@ sub OWID_Notify ($$) {
######################################################################################### #########################################################################################
# #
# OWID_Define - Implements InitFn function # OWID_Init - Implements InitFn function
# #
# Parameter hash = hash of device addressed # Parameter hash = hash of device addressed
# #
@ -531,6 +530,10 @@ sub OWID_Undef ($) {
</a> </a>
<br /> Returns 1 if this 1-Wire device is present, otherwise 0. </li> <br /> Returns 1 if this 1-Wire device is present, otherwise 0. </li>
</ul> </ul>
<h4>Attributes</h4>
<ul>
<li><a href="#readingFnAttributes">readingFnAttributes</a></li>
</ul>
=end html =end html
=cut =cut

File diff suppressed because it is too large Load Diff

View File

@ -28,7 +28,7 @@
# get <name> reading => measurement value obtained from VFunction # get <name> reading => measurement value obtained from VFunction
# get <name> temperature => temperature measurement # get <name> temperature => temperature measurement
# get <name> VDD => supply voltage measurement # get <name> VDD => supply voltage measurement
# get <name> V|raw => raw external voltage measurement # get <name> V|I|raw => external voltage/external current/raw measurement
# get <name> version => OWX version number # get <name> version => OWX version number
# #
# set <name> interval => set period for measurement # set <name> interval => set period for measurement
@ -38,12 +38,17 @@
# #
# 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
# attr <name> tempUnit <string> = unit of measurement, e.g. Celsius/Kelvin/Fahrenheit, default is Celsius # attr <name> tempUnit <string> = unit of measurement, e.g. Celsius/Kelvin/Fahrenheit, default is Celsius
# attr <name> VName <string>[|<string>] = name for the channel [|name used in state reading] # attr <name> VName <string>[|<string>] = name for the voltage channel [|short name used in state reading]
# attr <name> VUnit <string>[|<string>] = unit of measurement for the channel [|unit used in state reading] # attr <name> VUnit <string> = unit of measurement for the voltage channel (default V, none for empty)
# attr <name> Vfunction <string> = arbitrary functional expression involving the values VDD, V, T # attr <name> Vfunction <string> = arbitrary functional expression involving the values VDD, V, W, T
# VDD is replaced by the measured supply voltage in Volt, # VDD is replaced by the measured supply voltage in Volt,
# V by the measured external voltage (the channel) # V by the measured external voltage channel
# W by the measured external sense channel
# T by the measured and corrected temperature in its unit # T by the measured and corrected temperature in its unit
# attr <name> WName <string>[|<string>] = name for the sense channel [|short name used in state reading]
# attr <name> WUnit <string>[|<string>] = unit of measurement for the sense channel (default 1/16384 V, none for empty)
# attr <name> Wfunction <string> = arbitrary functional expression involving the values VDD, V, W, T
#
# #
######################################################################################## ########################################################################################
# #
@ -82,9 +87,9 @@ no warnings 'deprecated';
sub Log($$); sub Log($$);
my $owx_version="5.23"; my $owx_version="6.0";
#-- flexible channel name #-- flexible channel name
my $owg_channel; my ($owg_channel,$owg_schannel);
my %gets = ( my %gets = (
"id" => "", "id" => "",
@ -112,17 +117,14 @@ my %updates = (
# #
# Prefix = OWMULTI # Prefix = OWMULTI
# #
## ########################################################################################
# Parameters: #
# hash - hash of device addressed # OWMULTI_Initialize
# #
# Called By: # Parameter hash = hash of device addressed
# FHEM - Main Loop #
# Gargelmargel - dunno where ########################################################################################
#
#Calling:
# None
##
sub OWMULTI_Initialize ($) { sub OWMULTI_Initialize ($) {
my ($hash) = @_; my ($hash) = @_;
@ -136,16 +138,17 @@ sub OWMULTI_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 model:DS2438 loglevel:0,1,2,3,4,5 ". $hash->{AttrList}= "IODev do_not_notify:0,1 showtime:0,1 model:DS2438 verbose:0,1,2,3,4,5 ".
"tempOffset tempUnit:Celsius,Fahrenheit,Kelvin ". "tempOffset tempUnit:Celsius,Fahrenheit,Kelvin ".
"VName VUnit VFunction ". "VName VUnit VFunction WName WUnit WFunction ".
"interval ". "interval ".
$readingFnAttributes; $readingFnAttributes;
#-- temperature and voltage globals - always the raw values from the device #-- temperature and voltage globals - always the raw values from the device
$hash->{owg_val}->[0] = undef; $hash->{owg_val}->[0] = undef;
$hash->{owg_val}->[2] = undef;
$hash->{owg_val}->[1] = undef; $hash->{owg_val}->[1] = undef;
$hash->{owg_val}->[2] = undef;
$hash->{owg_val}->[3] = undef;
#-- make sure OWX is loaded so OWX_CRC is available if running with OWServer #-- make sure OWX is loaded so OWX_CRC is available if running with OWServer
main::LoadModule("OWX"); main::LoadModule("OWX");
@ -280,7 +283,7 @@ sub OWMULTI_Define ($$) {
$main::modules{OWMULTI}{defptr}{$id} = $hash; $main::modules{OWMULTI}{defptr}{$id} = $hash;
#-- #--
readingsSingleUpdate($hash,"state","defined",1); readingsSingleUpdate($hash,"state","defined",1);
Log 3, "OWMULTI: Device $name defined."; Log 3, "OWMULTI: Device $name defined.";
$hash->{NOTIFYDEV} = "global"; $hash->{NOTIFYDEV} = "global";
@ -336,29 +339,48 @@ sub OWMULTI_ChannelNames($) {
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $state = $hash->{READINGS}{"state"}{VAL}; my $state = $hash->{READINGS}{"state"}{VAL};
my ($cname,@cnama,$unit,@unarr); my ($cname,@cnama,$unit);
my ($tunit,$toffset,$tfactor,$tabbr,$vfunc); my ($tunit,$toffset,$tfactor,$tabbr,$vfunc,$wfunc);
#-- Set channel name, channel unit for voltage channel #-- Set channel name, channel unit for voltage channel
$cname = defined($attr{$name}{"VName"}) ? $attr{$name}{"VName"} : "voltage"; $cname = defined($attr{$name}{"VName"}) ? $attr{$name}{"VName"} : "voltage|vad";
@cnama = split(/\|/,$cname); @cnama = split(/\|/,$cname);
if( int(@cnama)!=2){ if( int(@cnama)!=2){
push(@cnama,$cnama[0]); push(@cnama,$cnama[0]);
} }
#-- unit #-- unit
$unit = defined($attr{$name}{"VUnit"}) ? $attr{$name}{"VUnit"} : "Volt|V"; $unit = defined($attr{$name}{"VUnit"}) ? $attr{$name}{"VUnit"} : "V";
@unarr= split(/\|/,$unit); $unit = ""
if( int(@unarr)!=2 ){ if($unit eq "none");
push(@unarr,$unarr[0]);
}
#-- put into readings #-- put into readings
$owg_channel = $cnama[0]; $owg_channel = $cnama[0];
$hash->{READINGS}{$owg_channel}{VAL} = " "; $hash->{READINGS}{$owg_channel}{VAL} = " ";
$hash->{READINGS}{$owg_channel}{ABBR} = $cnama[1]; $hash->{READINGS}{$owg_channel}{ABBR} = $cnama[1];
$hash->{READINGS}{$owg_channel}{UNIT} = $unarr[0]; $hash->{READINGS}{$owg_channel}{UNIT} = " ".$unit;
$hash->{READINGS}{$owg_channel}{UNITABBR} = $unarr[1];
#-- Set channel name, channel unit for sense channel
$cname = defined($attr{$name}{"WName"}) ? $attr{$name}{"WName"} : "sense|s";
@cnama = split(/\|/,$cname);
if( int(@cnama)!=2){
push(@cnama,$cnama[0]);
}
#-- unit
$unit = defined($attr{$name}{"WUnit"}) ? $attr{$name}{"WUnit"} : "V";
if($unit eq "none"){
$unit = ""
}else{
$unit = " ".$unit
}
#-- put into readings
$owg_schannel = $cnama[0];
$hash->{READINGS}{$owg_schannel}{VAL} = " ";
$hash->{READINGS}{$owg_schannel}{ABBR} = $cnama[1];
$hash->{READINGS}{$owg_schannel}{UNIT} = $unit;
#-- temperature scale #-- temperature scale
$hash->{READINGS}{"temperature"}{UNIT} = defined($attr{$name}{"tempUnit"}) ? $attr{$name}{"tempUnit"} : "Celsius"; $hash->{READINGS}{"temperature"}{UNIT} = defined($attr{$name}{"tempUnit"}) ? $attr{$name}{"tempUnit"} : "Celsius";
@ -366,13 +388,15 @@ sub OWMULTI_ChannelNames($) {
$toffset = defined($attr{$name}{"tempOffset"}) ? $attr{$name}{"tempOffset"} : 0.0 ; $toffset = defined($attr{$name}{"tempOffset"}) ? $attr{$name}{"tempOffset"} : 0.0 ;
$tfactor = 1.0; $tfactor = 1.0;
if( $tunit eq "Celsius" ){ if( $tunit eq "none" ){
$tabbr = "°C"; $tabbr = "";
}elsif( $tunit eq "Celsius" ){
$tabbr = " °C";
} elsif ($tunit eq "Kelvin" ){ } elsif ($tunit eq "Kelvin" ){
$tabbr = "K"; $tabbr = " K";
$toffset += "273.16" $toffset += "273.16"
} elsif ($tunit eq "Fahrenheit" ){ } elsif ($tunit eq "Fahrenheit" ){
$tabbr = "°F"; $tabbr = " °F";
$toffset = ($toffset+32)/1.8; $toffset = ($toffset+32)/1.8;
$tfactor = 1.8; $tfactor = 1.8;
} else { } else {
@ -382,8 +406,7 @@ sub OWMULTI_ChannelNames($) {
#-- these values are rather complex to obtain, therefore save them in the hash #-- these values are rather complex to obtain, therefore save them in the hash
$hash->{READINGS}{"temperature"}{ABBR} = "T"; $hash->{READINGS}{"temperature"}{ABBR} = "T";
$hash->{READINGS}{"temperature"}{UNIT} = $tunit; $hash->{READINGS}{"temperature"}{UNIT} = $tabbr;
$hash->{READINGS}{"temperature"}{UNITABBR} = $tabbr;
$hash->{tempf}{offset} = $toffset; $hash->{tempf}{offset} = $toffset;
$hash->{tempf}{factor} = $tfactor; $hash->{tempf}{factor} = $tfactor;
} }
@ -400,11 +423,11 @@ sub OWMULTI_FormatValues($) {
my ($hash) = @_; my ($hash) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my ($toffset,$tfactor,$tval,$vfunc,$vval); my ($toffset,$tfactor,$tval,$vfunc,$wfunc,$vval,$wval);
my $svalue = ""; my $svalue = "";
#-- no change in any value if invalid reading #-- no change in any value if invalid reading
return if( ($hash->{owg_val}->[0] eq "") || ($hash->{owg_val}->[1] eq "") || ($hash->{owg_val}->[2] eq "") ); return if( ($hash->{owg_val}->[0] eq "") || ($hash->{owg_val}->[1] eq "") || ($hash->{owg_val}->[2] eq "") || ($hash->{owg_val}->[3] eq ""));
#-- obtain channel names #-- obtain channel names
OWMULTI_ChannelNames($hash); OWMULTI_ChannelNames($hash);
@ -414,35 +437,53 @@ sub OWMULTI_FormatValues($) {
$tfactor = $hash->{tempf}{factor}; $tfactor = $hash->{tempf}{factor};
$tval = int(10*($hash->{owg_val}->[0] + $toffset)*$tfactor+0.5)/10; $tval = int(10*($hash->{owg_val}->[0] + $toffset)*$tfactor+0.5)/10;
#-- attribute VFunction defined ? #-- attribute V/WFunction defined ?
$vfunc = defined($attr{$name}{"VFunction"}) ? $attr{$name}{"VFunction"} : "V"; $vfunc = defined($attr{$name}{"VFunction"}) ? $attr{$name}{"VFunction"} : "V";
$wfunc = defined($attr{$name}{"WFunction"}) ? $attr{$name}{"WFunction"} : "W";
#-- replace by proper values #-- replace by proper values
$vfunc =~ s/VDD/\$hash->{owg_val}->[1]/g; $vfunc =~ s/VDD/\$hash->{owg_val}->[1]/g;
$vfunc =~ s/V/\$hash->{owg_val}->[2]/g; $vfunc =~ s/V/\$hash->{owg_val}->[2]/g;
$vfunc =~ s/W/\$hash->{owg_val}->[3]/g;
$vfunc =~ s/T/\$tval/g; $vfunc =~ s/T/\$tval/g;
$wfunc =~ s/VDD/\$hash->{owg_val}->[1]/g;
$wfunc =~ s/V/\$hash->{owg_val}->[2]/g;
$wfunc =~ s/W/\$hash->{owg_val}->[3]/g;
$wfunc =~ s/T/\$tval/g;
#-- determine the measured value from the function #-- determine the measured value from the function
$vfunc = "\$hash->{owg_val}->[1] = $hash->{owg_val}->[1]; \$hash->{owg_val}->[2] = $hash->{owg_val}->[2]; \$tval = $tval; ".$vfunc; $vfunc = "\$hash->{owg_val}->[1] = $hash->{owg_val}->[1]; \$hash->{owg_val}->[2] = $hash->{owg_val}->[2]; \$hash->{owg_val}->[3] = $hash->{owg_val}->[3]; \$tval = $tval; ".$vfunc;
#Log 1, "vfunc= ".$vfunc; #Log 1, "vfunc= ".$vfunc;
$vfunc = eval($vfunc); $vfunc = eval($vfunc);
if( !$vfunc ){ if( !$vfunc ){
$vval = ""; $vval = 0.0;
} elsif( $vfunc ne "" ){ } elsif( $vfunc ne "" ){
$vval = int( $vfunc*10+0.5)/10; $vval = int( $vfunc*100+0.5)/100;
} else { } else {
#-- todo ? $vval = "???";
}
$wfunc = "\$hash->{owg_val}->[1] = $hash->{owg_val}->[1]; \$hash->{owg_val}->[2] = $hash->{owg_val}->[2]; \$hash->{owg_val}->[3] = $hash->{owg_val}->[3]; \$tval = $tval; ".$wfunc;
#Log 1, "wfunc= ".$wfunc;
$wfunc = eval($wfunc);
if( !$wfunc ){
$wval = 0.0;
} elsif( $wfunc ne "" ){
$wval = int( $wfunc*100+0.5)/100;
} else {
$wval = "???";
} }
#-- string buildup for return value, STATE #-- string buildup for return value, STATE
$svalue .= sprintf( "%s: %5.1f %s (T: %5.1f %s)", $svalue .= sprintf( "%s: %5.2f%s (T: %5.1f%s %s: %5.2f%s)",
$hash->{READINGS}{$owg_channel}{ABBR}, $vval,$hash->{READINGS}{$owg_channel}{UNITABBR}, $hash->{READINGS}{$owg_channel}{ABBR}, $vval,$hash->{READINGS}{$owg_channel}{UNIT},
$tval,$hash->{READINGS}{"temperature"}{UNITABBR}); $tval,$hash->{READINGS}{"temperature"}{UNIT}, $hash->{READINGS}{$owg_schannel}{ABBR}, $wval,$hash->{READINGS}{$owg_schannel}{UNIT});
#-- put into READINGS #-- put into READINGS
readingsBeginUpdate($hash); readingsBeginUpdate($hash);
readingsBulkUpdate($hash,$owg_channel,$vval); readingsBulkUpdate($hash,$owg_channel,$vval);
readingsBulkUpdate($hash,"VDD",sprintf("%4.2f %s",$hash->{owg_val}->[1],"V")); readingsBulkUpdate($hash,$owg_schannel,$wval);
readingsBulkUpdate($hash,"VDD",sprintf("%4.2f",$hash->{owg_val}->[1]));
readingsBulkUpdate($hash,"temperature",$tval); readingsBulkUpdate($hash,"temperature",$tval);
#-- STATE #-- STATE
@ -466,6 +507,7 @@ sub OWMULTI_Get($@) {
my $reading = $a[1]; my $reading = $a[1];
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $model = $hash->{OW_MODEL}; my $model = $hash->{OW_MODEL};
my $value = undef; my $value = undef;
my $ret = ""; my $ret = "";
@ -538,27 +580,31 @@ sub OWMULTI_Get($@) {
return "OWMULTI: Get with wrong IODev type $interface"; return "OWMULTI: Get with wrong IODev type $interface";
} }
#-- process results #-- process result
if( defined($ret) ){ if( $master->{ASYNCHRONOUS} ){
return "OWMULTI: Could not get values from device $name, reason $ret"; return "OWSMULTI: $name getting readings, please wait for completion";
} }else{
if( defined($ret) ){
#-- return the special reading return "OWMULTI: Could not get values from device $name, reason $ret";
if ($reading eq "reading") { }
return "OWMULTI: $name.reading => ".$hash->{READINGS}{"state"}{VAL};
} #-- return the special reading
if ($reading eq "reading") {
return "OWMULTI: $name.reading => ".$hash->{READINGS}{"state"}{VAL};
}
if ($reading eq "temperature") { if ($reading eq "temperature") {
return "OWMULTI: $name.temperature => ". return "OWMULTI: $name.temperature => ".
$hash->{READINGS}{"temperature"}{VAL}; $hash->{READINGS}{"temperature"}{VAL};
} }
if ($reading eq "VDD") { if ($reading eq "VDD") {
return "OWMULTI: $name.VDD => ". return "OWMULTI: $name.VDD => ".
$hash->{owg_val}->[1]; $hash->{owg_val}->[1];
} }
if ( $reading eq "raw") { if ( $reading eq "raw") {
return "OWMULTI: $name.raw => ". return "OWMULTI: $name.raw => ".
$hash->{owg_val}->[2]; $hash->{owg_val}->[2]." V ".$hash->{owg_val}->[3]." V";
}
} }
return undef; return undef;
} }
@ -630,8 +676,9 @@ sub OWMULTI_InitializeDevice($) {
#-- Initial readings #-- Initial readings
$hash->{owg_val}->[0] = ""; $hash->{owg_val}->[0] = "";
$hash->{owg_val}->[2] = ""; $hash->{owg_val}->[1] = "";
$hash->{owg_val}->[1] = ""; $hash->{owg_val}->[2] = "";
$hash->{owg_val}->[3] = "";
#-- Set state to initialized #-- Set state to initialized
readingsSingleUpdate($hash,"state","initialized",1); readingsSingleUpdate($hash,"state","initialized",1);
@ -766,16 +813,16 @@ sub OWFSMULTI_GetValues($) {
$hash->{owg_val}->[0] = OWServer_Read($master,"/$owx_add/temperature"); $hash->{owg_val}->[0] = OWServer_Read($master,"/$owx_add/temperature");
$hash->{owg_val}->[1] = OWServer_Read($master,"/$owx_add/VDD"); $hash->{owg_val}->[1] = OWServer_Read($master,"/$owx_add/VDD");
$hash->{owg_val}->[2] = OWServer_Read($master,"/$owx_add/VAD"); $hash->{owg_val}->[2] = OWServer_Read($master,"/$owx_add/VAD");
$hash->{owg_val}->[3] = OWServer_Read($master,"/$owx_add/vis");
return "no return from OWServer" return "no return from OWServer"
if( (!defined($hash->{owg_val}->[0])) || (!defined($hash->{owg_val}->[1])) || (!defined($hash->{owg_val}->[2])) ); if( (!defined($hash->{owg_val}->[0])) || (!defined($hash->{owg_val}->[1])) || (!defined($hash->{owg_val}->[2])) || (!defined($hash->{owg_val}->[3])) );
return "empty return from OWServer" return "empty return from OWServer"
if( ($hash->{owg_val}->[0] eq "") || ($hash->{owg_val}->[1] eq "") || ($hash->{owg_val}->[2] eq "") ); if( ($hash->{owg_val}->[0] eq "") || ($hash->{owg_val}->[1] eq "") || ($hash->{owg_val}->[2] eq "") || ($hash->{owg_val}->[3] eq "") );
#-- and now from raw to formatted values #-- and now from raw to formatted values
$hash->{PRESENT} = 1; $hash->{PRESENT} = 1;
my $value = OWMULTI_FormatValues($hash); my $value = OWMULTI_FormatValues($hash);
Log 5, $value;
return undef; return undef;
} }
@ -802,40 +849,65 @@ sub OWFSMULTI_SetValues($@) {
# #
######################################################################################## ########################################################################################
# #
# OWXMULTI_BinValues - Binary readings into clear values # OWXMULTI_BinValues - Process reading from one device - translate binary into raw
# #
# Parameter hash = hash of device addressed # Parameter hash = hash of device addressed
# context = mode for evaluating the binary data
# proc = processing instruction, also passed to OWX_Read.
# bitwise interpretation !!
# if 0, nothing special
# if 1 = bit 0, a reset will be performed not only before, but also after
# the last operation in OWX_Read
# if 2 = bit 1, the initial reset of the bus will be suppressed
# if 8 = bit 3, the fillup of the data with 0xff will be suppressed
# if 16= bit 4, the insertion will be at the top of the queue
# owx_dev = ROM ID of slave device
# crcpart = part of the data that needs to be part of the CRC check
# numread = number of bytes to receive
# res = result string
#
# #
######################################################################################## ########################################################################################
sub OWXMULTI_BinValues($$$$$$$$) { sub OWXMULTI_BinValues($$$$$$$) {
my ($hash, $context, $success, $reset, $owx_dev, $command, $numread, $res) = @_; my ($hash, $context, $proc, $owx_dev, $crcpart, $numread, $res) = @_;
#-- hash of the busmaster
my $master = $hash->{IODev};
my $name = $hash->{NAME};
my @data=[];
my ($value,$lsb,$msb,$sign);
my $msg;
OWX_WDBG($name,"OWXMULTI_BinValues called for device $name in context $context with ",$res)
if( $main::owx_debug>2 );
#-- always check for success, unused are reset, numread #-- always check for success, unused are reset, numread
return unless ($success and $context =~ /^ds2438.getv[ad]d$/); return unless ($context =~ /^ds2438.getv[ad]d$/);
#Log 1,"OWXMULTI_BinValues context = $context"; #Log 1,"OWXMULTI_BinValues context = $context";
#-- process results #-- process results
my @data=split(//,$res); @data=split(//,$res);
if (@data != 9) { if (@data != 9) {
return "invalid data length, ".int(@data)." instead of 9 bytes"; $msg="$name returns invalid data length, ".int(@data)." instead of 9 bytes";
} }elsif ((ord($data[0]) & 112)!=0) {
if ((ord($data[0]) & 112)!=0) { $msg="$name: conversion not complete or data invalid";
return "conversion not complete or data invalid"; }elsif (OWX_CRC8(substr($res,0,8),$data[8])==0) {
} $msg="$name returns invalid CRC";
if (OWX_CRC8(substr($res,0,8),$data[8])==0) { }else{
return "invalid CRC"; $msg="No error";
} }
OWX_WDBG($name,"OWXMULTI_BinValues: ".$msg,"")
if( $main::owx_debug>2 );
#-- this must be different for the different device types #-- this must be different for the different device types
# family = 26 => DS2438 # family = 26 => DS2438
#-- transform binary rep of VDD #-- transform binary rep of VDD
if( $context eq "ds2438.getvdd") { if( $context eq "ds2438.getvdd") {
#-- temperature #-- temperature
my $lsb = ord($data[1]); $lsb = ord($data[1]);
my $msb = ord($data[2]) & 127; $msb = ord($data[2]) & 127;
my $sign = ord($data[2]) & 128; $sign = ord($data[2]) & 128;
#-- test with -55 degrees #-- test with -55 degrees
#$lsb = 0; #$lsb = 0;
@ -843,7 +915,7 @@ sub OWXMULTI_BinValues($$$$$$$$) {
#$msb = 73; #$msb = 73;
#-- 2's complement form = signed bytes #-- 2's complement form = signed bytes
$hash->{owg_val}->[0] = $msb+ $lsb/256; $hash->{owg_val}->[0] = $msb+ $lsb/256.;
if( $sign !=0 ){ if( $sign !=0 ){
$hash->{owg_val}->[0] = -128+$hash->{owg_val}->[0]; $hash->{owg_val}->[0] = -128+$hash->{owg_val}->[0];
} }
@ -857,25 +929,31 @@ sub OWXMULTI_BinValues($$$$$$$$) {
#$msb = 1; #$msb = 1;
#-- supply voltage #-- supply voltage
$hash->{owg_val}->[1] = ($msb*256+ $lsb)/100; $hash->{owg_val}->[1] = ($msb*256+ $lsb)/100.;
};
#-- transform binary rep of VAD #-- transform binary rep of VAD
if( $context eq "ds2438.getvad") { }elsif( $context eq "ds2438.getvad") {
#-- voltage #-- voltage
my $lsb = ord($data[3]); $lsb = ord($data[3]);
my $msb = ord($data[4]) & 3; $msb = ord($data[4]) & 3;
#-- test with 7.2 V #-- test with 7.2 V
#$lsb = 208; #$lsb = 208;
#$msb = 2; #$msb = 2;
#-- external voltage #-- external voltage
$hash->{owg_val}->[2] = ($msb*256+ $lsb)/100; $hash->{owg_val}->[2] = ($msb*256+ $lsb)/100.;
#-- and now from raw to formatted values #-- current
$lsb = ord($data[5]);
$msb = ord($data[6]) & 3;
#-- external current
$hash->{owg_val}->[3] = ($msb*256.+ $lsb)/4096;
#-- and now from raw to formatted values
$hash->{PRESENT} = 1; $hash->{PRESENT} = 1;
my $value = OWMULTI_FormatValues($hash); my $value = OWMULTI_FormatValues($hash);
Log 5, $value;
}; };
return undef; return undef;
} }
@ -893,7 +971,7 @@ sub OWXMULTI_GetValues($) {
my ($hash) = @_; my ($hash) = @_;
my ($i,$j,$k,$res,$ret); my ($res,$ret);
#-- ID of the device #-- ID of the device
my $owx_dev = $hash->{ROM_ID}; my $owx_dev = $hash->{ROM_ID};
@ -905,101 +983,181 @@ sub OWXMULTI_GetValues($) {
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
#-- switch the device to current measurement off, VDD only #-- switch the device to current measurement off, VDD only
#-- issue the match ROM command \x55 and the write scratchpad command #-- issue the match ROM command \x55 and the write scratchpad command
OWX_Reset($master); #-- OLD OWX interface
if( OWX_Complex($master,$owx_dev,"\x4E\x00\x08",0) eq 0 ){ if( !$master->{ASYNCHRONOUS} ){
return "$owx_dev write status failed"; OWX_Reset($master);
} #if( OWX_Complex($master,$owx_dev,"\x4E\x00\x08",0) eq 0 ){
if( OWX_Complex($master,$owx_dev,"\x4E\x00\x09",0) eq 0 ){
return "$owx_dev write status failed";
}
#-- copy scratchpad to register #-- copy scratchpad to register
#-- issue the match ROM command \x55 and the copy scratchpad command #-- issue the match ROM command \x55 and the copy scratchpad command
OWX_Reset($master); OWX_Reset($master);
if( OWX_Complex($master,$owx_dev,"\x48\x00",0) eq 0){ if( OWX_Complex($master,$owx_dev,"\x48\x00",0) eq 0){
return "$owx_dev copy scratchpad failed"; return "$owx_dev copy scratchpad failed";
} }
#-- initiate temperature conversion #-- initiate temperature conversion
#-- conversion needs some 12 ms ! #-- conversion needs some 12 ms !
#-- issue the match ROM command \x55 and the start conversion command #-- issue the match ROM command \x55 and the start conversion command
OWX_Reset($master); OWX_Reset($master);
if( OWX_Complex($master,$owx_dev,"\x44",0) eq 0 ){ if( OWX_Complex($master,$owx_dev,"\x44",0) eq 0 ){
return "$owx_dev temperature conversion failed"; return "$owx_dev temperature conversion failed";
} }
select(undef,undef,undef,0.012); select(undef,undef,undef,0.012);
#-- initiate voltage conversion #-- initiate voltage conversion
#-- conversion needs some 6 ms ! #-- conversion needs some 6 ms !
#-- issue the match ROM command \x55 and the start conversion command #-- issue the match ROM command \x55 and the start conversion command
OWX_Reset($master); OWX_Reset($master);
if( OWX_Complex($master,$owx_dev,"\xB4",0) eq 0 ){ if( OWX_Complex($master,$owx_dev,"\xB4",0.01) eq 0 ){
return "$owx_dev voltage conversion failed"; return "$owx_dev voltage conversion failed";
} }
select(undef,undef,undef,0.006); select(undef,undef,undef,0.006);
#-- from memory to scratchpad #-- from memory to scratchpad
#-- copy needs some 12 ms ! #-- copy needs some 12 ms !
#-- issue the match ROM command \x55 and the recall memory command #-- issue the match ROM command \x55 and the recall memory command
OWX_Reset($master); OWX_Reset($master);
if( OWX_Complex($master,$owx_dev,"\xB8\x00",0) eq 0 ){ if( OWX_Complex($master,$owx_dev,"\xB8\x00",0.02) eq 0 ){
return "$owx_dev recall memory failed"; return "$owx_dev recall memory failed";
} }
select(undef,undef,undef,0.012); select(undef,undef,undef,0.012);
#-- NOW ask the specific device #-- NOW ask the specific device
#-- issue the match ROM command \x55 and the read scratchpad command \xBE #-- issue the match ROM command \x55 and the read scratchpad command \xBE
#-- reading 9 + 2 + 9 data bytes = 20 bytes #-- reading 9 + 2 + 9 data bytes = 20 bytes
OWX_Reset($master); OWX_Reset($master);
$res=OWX_Complex($master,$owx_dev,"\xBE\x00",9); $res=OWX_Complex($master,$owx_dev,"\xBE\x00",9);
#Log 1,"OWXMULTI: data length from reading device is ".length($res)." bytes"; #Log 1,"OWXMULTI: data length from reading device is ".length($res)." bytes";
return "$owx_dev not accessible in 2nd step" return "$owx_dev not accessible in 2nd step"
if( $res eq 0 ); if( $res eq 0 );
return "$owx_dev has returned invalid data" return "$owx_dev has returned invalid data"
if( length($res)!=20); if( length($res)!=20);
$ret = OWXMULTI_BinValues($hash,"ds2438.getvdd",1,undef,$owx_dev,undef,undef,substr($res,11)); $ret = OWXMULTI_BinValues($hash,"ds2438.getvdd",undef,$owx_dev,undef,undef,substr($res,11));
return $ret if (defined $ret); return $ret if (defined $ret);
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
#-- switch the device to current measurement off, V external only #-- switch the device to current measurement off, V external only
#-- issue the match ROM command \x55 and the write scratchpad command #-- issue the match ROM command \x55 and the write scratchpad command
OWX_Reset($master); OWX_Reset($master);
if( OWX_Complex($master,$owx_dev,"\x4E\x00\x00",0) eq 0 ){ #if( OWX_Complex($master,$owx_dev,"\x4E\x00\x00",0) eq 0 ){
return "$owx_dev write status failed"; if( OWX_Complex($master,$owx_dev,"\x4E\x00\x01",0) eq 0 ){
} return "$owx_dev write status failed";
#-- copy scratchpad to register }
#-- issue the match ROM command \x55 and the copy scratchpad command #-- copy scratchpad to register
OWX_Reset($master); #-- issue the match ROM command \x55 and the copy scratchpad command
if( OWX_Complex($master,$owx_dev,"\x48\x00",0) eq 0){ OWX_Reset($master);
return "$owx_dev copy scratchpad failed"; if( OWX_Complex($master,$owx_dev,"\x48\x00",0) eq 0){
} return "$owx_dev copy scratchpad failed";
#-- initiate voltage conversion }
#-- conversion needs some 6 ms ! #-- initiate voltage conversion
#-- issue the match ROM command \x55 and the start conversion command #-- conversion needs some 6 ms !
OWX_Reset($master); #-- issue the match ROM command \x55 and the start conversion command
if( OWX_Complex($master,$owx_dev,"\xB4",0) eq 0 ){ OWX_Reset($master);
return "$owx_dev voltage conversion failed"; if( OWX_Complex($master,$owx_dev,"\xB4",0.01) eq 0 ){
} return "$owx_dev voltage conversion failed";
select(undef,undef,undef,0.006); }
select(undef,undef,undef,0.006);
#-- from memory to scratchpad #-- from memory to scratchpad
#-- copy needs some 12 ms ! #-- copy needs some 12 ms !
#-- issue the match ROM command \x55 and the recall memory command #-- issue the match ROM command \x55 and the recall memory command
OWX_Reset($master); OWX_Reset($master);
if( OWX_Complex($master,$owx_dev,"\xB8\x00",0) eq 0 ){ if( OWX_Complex($master,$owx_dev,"\xB8\x00",0.02) eq 0 ){
return "$owx_dev recall memory failed"; return "$owx_dev recall memory failed";
} }
select(undef,undef,undef,0.012); select(undef,undef,undef,0.012);
#-- NOW ask the specific device #-- NOW ask the specific device
#-- issue the match ROM command \x55 and the read scratchpad command \xBE #-- issue the match ROM command \x55 and the read scratchpad command \xBE
#-- reading 9 + 2 + 9 data bytes = 20 bytes #-- reading 9 + 2 + 9 data bytes = 20 bytes
my $context = "ds2438.getvad"; my $context = "ds2438.getvad";
OWX_Reset($master); OWX_Reset($master);
$res=OWX_Complex($master,$owx_dev,"\xBE\x00",9); $res=OWX_Complex($master,$owx_dev,"\xBE\x00",9);
#-- process results #-- process results
return "$owx_dev not accessible in 2nd step" return "$owx_dev not accessible in 2nd step"
if( $res eq 0 ); if( $res eq 0 );
return "$owx_dev has returned invalid data" return "$owx_dev has returned invalid data"
if( length($res)!=20); if( length($res)!=20);
return OWXMULTI_BinValues($hash,$context,1,undef,$owx_dev,undef,undef,substr($res,11)); return OWXMULTI_BinValues($hash,$context,undef,$owx_dev,undef,undef,substr($res,11));
#-- NEW OWX interface
}else{
#-- switch the device to current measurement off, VDD only
#-- issue the match ROM command \x55 and the write scratchpad command
#### master slave context proc owx_dev data crcpart numread startread callback delay
#OWX_Qomplex($master, $hash, "write SP", 0, $owx_dev, "\x4E\x00\x08", 0, 0, 0, undef, 0);
#-- switch the device to current measurement on, VDD only
#-- issue the match ROM command \x55 and the write scratchpad command
#### master slave context proc owx_dev data crcpart numread startread callback delay
OWX_Qomplex($master, $hash, "write SP", 0, $owx_dev, "\x4E\x00\x09", 0, 0, 0, undef, 0);
#-- copy scratchpad to register
#-- issue the match ROM command \x55 and the copy scratchpad command
#### master slave context proc owx_dev data crcpart numread startread callback delay
OWX_Qomplex($master, $hash, "copy SP", 0, $owx_dev, "\x48\x00", 0, 0, 0, undef, 0);
#-- initiate temperature conversion
#-- conversion needs some 12 ms !
#-- issue the match ROM command \x55 and the start conversion command
#### master slave context proc owx_dev data crcpart numread startread callback delay
OWX_Qomplex($master, $hash, "T conversion", 0, $owx_dev, "\x44", 0, 0, 0, undef, 0);
#-- initiate voltage conversion
#-- conversion needs some 6 ms !
#-- issue the match ROM command \x55 and the start conversion command
#### master slave context proc owx_dev data crcpart numread startread callback delay
OWX_Qomplex($master, $hash, "V conversion", 0, $owx_dev, "\xB4", 0, 0, 0, undef, 0);
#-- from memory to scratchpad
#-- copy needs some 12 ms !
#-- issue the match ROM command \x55 and the recall memory command
#### master slave context proc owx_dev data crcpart numread startread callback delay
OWX_Qomplex($master, $hash, "recall", 0, $owx_dev, "\xB8\x00", 0, 0, 0, undef, 0);
#-- NOW ask the specific device
#-- issue the match ROM command \x55 and the read scratchpad command \xBE
#-- reading 9 + 2 + 9 data bytes = 20 bytes
#### master slave context proc owx_dev data crcpart numread startread callback delay
# 1 provides additional reset after last operattion
OWX_Qomplex($master, $hash, "ds2438.getvdd", 1, $owx_dev, "\xBE\x00\x08", 0, 9, 11, \&OWXMULTI_BinValues, 0);
#-- switch the device to current measurement off, V external only
#-- issue the match ROM command \x55 and the write scratchpad command
#### master slave context proc owx_dev data crcpart numread startread callback delay
#OWX_Qomplex($master, $hash, "write SP", 0, $owx_dev, "\x4E\x00\x00", 0, 0, 0, undef, 0);
#-- switch the device to current measurement on, V external only
#-- issue the match ROM command \x55 and the write scratchpad command
#### master slave context proc owx_dev data crcpart numread startread callback delay
OWX_Qomplex($master, $hash, "write SP", 0, $owx_dev, "\x4E\x00\x01", 0, 0, 0, undef, 0);
#-- copy scratchpad to register
#-- issue the match ROM command \x55 and the copy scratchpad command
#### master slave context proc owx_dev data crcpart numread startread callback delay
OWX_Qomplex($master, $hash, "copy SP", 0, $owx_dev, "\x48\x00", 0, 0, 0, undef, 0);
#-- initiate voltage conversion
#-- conversion needs some 6 ms !
#-- issue the match ROM command \x55 and the start conversion command
#### master slave context proc owx_dev data crcpart numread startread callback delay
OWX_Qomplex($master, $hash, "V conversion", 0, $owx_dev, "\xB4", 0, 0, 0, undef, 0);
#-- from memory to scratchpad
#-- copy needs some 12 ms !
#-- issue the match ROM command \x55 and the recall memory command
#### master slave context proc owx_dev data crcpart numread startread callback delay
OWX_Qomplex($master, $hash, "recall", 0, $owx_dev, "\xB8\x00", 0, 0, 0, undef, 0);
#-- NOW ask the specific device
#-- issue the match ROM command \x55 and the read scratchpad command \xBE
#-- reading 9 + 2 + 9 data bytes = 20 bytes
#### master slave context proc owx_dev data crcpart numread startread callback delay
# 1 provides additional reset after last operattion
OWX_Qomplex($master, $hash, "ds2438.getvad", 1, $owx_dev, "\xBE\x00", 0, 20, 11, \&OWXMULTI_BinValues, 0);
return undef;
}
} }
####################################################################################### #######################################################################################
# #
# OWXMULTI_SetValues - Set values in device # OWXMULTI_SetValues - Set values in device
@ -1126,7 +1284,7 @@ sub OWXMULTI_PT_GetValues($) {
unless (defined $res and length($res)==9) { unless (defined $res and length($res)==9) {
PT_EXIT("$owx_dev has returned invalid data"); PT_EXIT("$owx_dev has returned invalid data");
} }
$ret = OWXMULTI_BinValues($hash,"ds2438.getvdd",1,undef,$owx_dev,undef,undef,$res); $ret = OWXMULTI_BinValues($hash,"ds2438.getvdd",undef,$owx_dev,undef,undef,$res);
if ($ret) { if ($ret) {
die $ret; die $ret;
} }
@ -1180,7 +1338,7 @@ sub OWXMULTI_PT_GetValues($) {
unless (defined $res and length($res)==9) { unless (defined $res and length($res)==9) {
PT_EXIT("$owx_dev has returned invalid data"); PT_EXIT("$owx_dev has returned invalid data");
} }
$ret = OWXMULTI_BinValues($hash,"ds2438.getvad",1,undef,$owx_dev,undef,undef,$res); $ret = OWXMULTI_BinValues($hash,"ds2438.getvad",undef,$owx_dev,undef,undef,$res);
if ($ret) { if ($ret) {
die $ret; die $ret;
} }
@ -1250,9 +1408,9 @@ sub OWXMULTI_PT_SetValues($@) {
<p> <p>
<code>define OWX_M OWMULTI 7C5034010000 45</code> <code>define OWX_M OWMULTI 7C5034010000 45</code>
<br /> <br />
<code>attr OWX_M VName relHumidity|humidity</code> <code>attr OWX_M VName humidity|rH</code>
<br /> <br />
<code>attr OWX_M VUnit percent|%</code> <code>attr OWX_M VUnit %</code>
<br /> <br />
<code>attr OWX_M VFunction (161.29 * V / VDD - 25.8065)/(1.0546 - 0.00216 * T)</code> <code>attr OWX_M VFunction (161.29 * V / VDD - 25.8065)/(1.0546 - 0.00216 * T)</code>
</p> </p>
@ -1305,34 +1463,43 @@ sub OWXMULTI_PT_SetValues($@) {
seconds. </li> seconds. </li>
<li><a name="owmulti_reading"> <li><a name="owmulti_reading">
<code>get &lt;name&gt; reading</code></a><br />Obtain the measurement values </li> <code>get &lt;name&gt; reading</code></a><br />Obtain the measurement values </li>
<li><a name="owmulti_vad">
<code>get &lt;name&gt; VAD</code></a><br />Obtain the measurement value from
VFunction. </li>
<li><a name="owmulti_temperature"> <li><a name="owmulti_temperature">
<code>get &lt;name&gt; temperature</code></a><br />Obtain the temperature value. </li> <code>get &lt;name&gt; temperature</code></a><br />Obtain the temperature value. </li>
<li><a name="owmulti_vdd"> <li><a name="owmulti_vdd">
<code>get &lt;name&gt; VDD</code></a><br />Obtain the current supply voltage. </li> <code>get &lt;name&gt; VDD</code></a><br />Obtain the current supply voltage. </li>
<li><a name="owmulti_raw"> <li><a name="owmulti_raw">
<code>get &lt;name&gt; V</code> or <code>get &lt;name&gt; <code>get &lt;name&gt; V</code> or <code>get &lt;name&gt;
raw</code></a><br />Obtain the raw external voltage measurement. </li> raw</code></a><br />Obtain the raw external voltage and external sense measurement. </li>
</ul> </ul>
<a name="OWMULTIattr"></a> <a name="OWMULTIattr"></a>
<h4>Attributes</h4> <h4>Attributes</h4>
<ul> <ul>
<li><a name="owmulti_vname"><code>attr &lt;name&gt; VName <li><a name="owmulti_vname"><code>attr &lt;name&gt; VName
&lt;string&gt;[|&lt;string&gt;]</code></a> &lt;string&gt;[|&lt;string&gt;]</code></a>
<br />name for the channel [|name used in state reading]. </li> <br />name for the voltage channel [|short name used in state reading]. </li>
<li><a name="owmulti_vunit"><code>attr &lt;name&gt; VUnit <li><a name="owmulti_vunit"><code>attr &lt;name&gt; VUnit
&lt;string&gt;[|&lt;string&gt;]</code></a> &lt;string&gt;</code></a>
<br />unit of measurement for this channel [|unit used in state reading]. </li> <br />unit of measurement for the voltage channel used in state reading (default "V", set to "none" for empty).</li>
<li><a name="owmulti_vfunction"><code>attr &lt;name&gt; VFunction <li><a name="owmulti_vfunction"><code>attr &lt;name&gt; VFunction
&lt;string&gt;</code></a> &lt;string&gt;</code></a>
<br />arbitrary functional expression involving the values VDD, V, T. Example see <br />arbitrary functional expression involving the values VDD, V, W and T. Example see
above. <ul> above. <ul>
<li>VDD is replaced by the measured supply voltage in Volt,</li> <li>VDD is replaced by the measured supply voltage in Volt,</li>
<li> V by the measured external voltage (the channel),</li> <li>V by the measured external voltage channel,</li>
<li>W by the measured external sense channel,</li>
<li>T by the measured and corrected temperature in its unit</li> <li>T by the measured and corrected temperature in its unit</li>
</ul></li> </ul></li>
<li><a name="owmulti_wname"><code>attr &lt;name&gt; WName
&lt;string&gt;[|&lt;string&gt;]</code></a>
<br />name for the sense channel [|short name used in state reading]. </li>
<li><a name="owmulti_wunit"><code>attr &lt;name&gt; WUnit
&lt;string&gt;</code></a>
<br />unit of measurement for the sense channel used in state reading (default “V", set to "none" for empty).</li>
<li><a name="owmulti_wfunction"><code>attr &lt;name&gt; WFunction
&lt;string&gt;</code></a>
<br />arbitrary functional expression involving the values VDD, V, W and T. Example and usage see
above.</li>
<li><a name="owmulti_tempOffset"><code>attr &lt;name&gt; tempOffset &lt;float&gt;</code> <li><a name="owmulti_tempOffset"><code>attr &lt;name&gt; tempOffset &lt;float&gt;</code>
</a> </a>
<br />temperature offset in &deg;C added to the raw temperature reading. </li> <br />temperature offset in &deg;C added to the raw temperature reading. </li>
@ -1340,12 +1507,7 @@ sub OWXMULTI_PT_SetValues($@) {
Celsius|Kelvin|Fahrenheit</code> Celsius|Kelvin|Fahrenheit</code>
</a> </a>
<br />unit of measurement (temperature scale), default is Celsius = &deg;C </li> <br />unit of measurement (temperature scale), default is Celsius = &deg;C </li>
<li>Standard attributes <a href="#alias">alias</a>, <a href="#comment">comment</a>, <a <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
href="#event-on-update-reading">event-on-update-reading</a>, <a
href="#event-on-change-reading">event-on-change-reading</a>, <a
href="#stateFormat">stateFormat</a>, <a href="#room"
>room</a>, <a href="#eventMap">eventMap</a>, <a href="#loglevel">loglevel</a>,
<a href="#webCmd">webCmd</a></li>
</ul> </ul>
=end html =end html

View File

@ -16,7 +16,7 @@
# where <name> may be replaced by any name string # where <name> may be replaced by any name string
# #
# <model> is a 1-Wire device type. If omitted, we assume this to be an # <model> is a 1-Wire device type. If omitted, we assume this to be an
# DS2413. Allowed values are DS2413, DS2406 # DS2413. Allowed values are DS2413, DS2406, DS2408
# <fam> is a 1-Wire family id, currently allowed values are 12, 29, 3A # <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 # <ROM_ID> is a 12 character (6 byte) 1-Wire ROM ID
# without Family ID, e.g. A2D90D000800 # without Family ID, e.g. A2D90D000800
@ -45,10 +45,8 @@
# Additional attributes are defined in fhem.cfg, in some cases per channel, where <channel>=A,B # Additional attributes are defined in fhem.cfg, in some cases per channel, where <channel>=A,B
# Note: attributes are read only during initialization procedure - later changes are not used. # Note: attributes are read only during initialization procedure - later changes are not used.
# #
# attr <name> stateS <string> = character string denoting external shortening condition, default is (ext) # attr <name> stateS <string> = character string denoting external shortening condition, default is X
# overwritten by an attribute setting "red angled arrow downward" # attr <name> <channel>Name <string>|<string> = name for the channel [|short name used in state reading]
#
# attr <name> <channel>Name <string>|<string> = name for the channel [|name used in state reading]
# attr <name> <channel>Unit <string>|<string> = values to display in state variable for on|off condition # attr <name> <channel>Unit <string>|<string> = values to display in state variable for on|off condition
# #
######################################################################################## ########################################################################################
@ -89,7 +87,7 @@ no warnings 'deprecated';
sub Log($$); sub Log($$);
my $owx_version="5.24"; my $owx_version="6.0";
#-- fixed raw channel name, flexible channel name #-- fixed raw channel name, flexible channel name
my @owg_fixed = ("A","B","C","D","E","F","G","H"); my @owg_fixed = ("A","B","C","D","E","F","G","H");
my @owg_channel = ("A","B","C","D","E","F","G","H"); my @owg_channel = ("A","B","C","D","E","F","G","H");
@ -131,8 +129,6 @@ my %cnumber = (
# #
# OWSWITCH_Initialize # OWSWITCH_Initialize
# #
# CalledBy: FHEM
# Calling: --
# Parameter: hash = hash of device addressed # Parameter: hash = hash of device addressed
# #
######################################################################################## ########################################################################################
@ -148,7 +144,7 @@ sub OWSWITCH_Initialize ($) {
$hash->{InitFn} = "OWSWITCH_Init"; $hash->{InitFn} = "OWSWITCH_Init";
$hash->{AttrFn} = "OWSWITCH_Attr"; $hash->{AttrFn} = "OWSWITCH_Attr";
my $attlist = "IODev do_not_notify:0,1 showtime:0,1 model:DS2413,DS2406,DS2408 loglevel:0,1,2,3,4,5 ". my $attlist = "IODev do_not_notify:0,1 showtime:0,1 model:DS2413,DS2406,DS2408 ".
"stateS interval ". "stateS interval ".
$readingFnAttributes; $readingFnAttributes;
@ -172,8 +168,6 @@ sub OWSWITCH_Initialize ($) {
# #
# OWSWITCH_Define - Implements DefFn function # OWSWITCH_Define - Implements DefFn function
# #
# CalledBy: FHEM
# Calling: --
# Parameter: hash = hash of device addressed, def = definition string # Parameter: hash = hash of device addressed, def = definition string
# #
######################################################################################### #########################################################################################
@ -280,8 +274,6 @@ sub OWSWITCH_Define ($$) {
# #
# OWSWITCH_Notify - Implements Notify function # OWSWITCH_Notify - Implements Notify function
# #
# CalledBy: FHEM
# Calling: --
# Parameter: hash = hash of device addressed, def = definition string # Parameter: hash = hash of device addressed, def = definition string
# #
######################################################################################### #########################################################################################
@ -298,8 +290,6 @@ sub OWSWITCH_Notify ($$) {
# #
# OWSWITCH_Init - Implements Init function # OWSWITCH_Init - Implements Init function
# #
# CalledBy: FHEM
# Calling: --
# Parameter: hash = hash of device addressed, def = definition string # Parameter: hash = hash of device addressed, def = definition string
# #
######################################################################################### #########################################################################################
@ -316,8 +306,6 @@ sub OWSWITCH_Init ($) {
# #
# OWSWITCH_Attr - Set one attribute value for device # OWSWITCH_Attr - Set one attribute value for device
# #
# CalledBy: FHEM
# Calling: --
# Parameter: hash = hash of device addressed # Parameter: hash = hash of device addressed
# a = argument array # a = argument array
# #
@ -362,8 +350,6 @@ sub OWSWITCH_Attr(@) {
# #
# OWSWITCH_ChannelNames - find the real channel names # OWSWITCH_ChannelNames - find the real channel names
# #
# CalledBy: OWSWITCH_FormatValues, OWSWITCH_Get, OWSWITCH_Set
# Calling: --
# Parameter: hash = hash of device addressed # Parameter: hash = hash of device addressed
# #
######################################################################################## ########################################################################################
@ -378,7 +364,7 @@ sub OWSWITCH_ChannelNames($) {
for (my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){ for (my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){
#-- name #-- name
$cname = defined($attr{$name}{$owg_fixed[$i]."Name"}) ? $attr{$name}{$owg_fixed[$i]."Name"} : $owg_fixed[$i]; $cname = defined($attr{$name}{$owg_fixed[$i]."Name"}) ? $attr{$name}{$owg_fixed[$i]."Name"} : "$owg_fixed[$i]";
@cnama = split(/\|/,$cname); @cnama = split(/\|/,$cname);
if( int(@cnama)!=2){ if( int(@cnama)!=2){
push(@cnama,$cnama[0]); push(@cnama,$cnama[0]);
@ -398,7 +384,6 @@ sub OWSWITCH_ChannelNames($) {
#-- put into readings #-- put into readings
$hash->{READINGS}{$owg_channel[$i]}{UNIT} = $unit; $hash->{READINGS}{$owg_channel[$i]}{UNIT} = $unit;
$hash->{READINGS}{$owg_channel[$i]}{UNITABBR} = $unit;
} }
} }
@ -406,8 +391,6 @@ sub OWSWITCH_ChannelNames($) {
# #
# OWSWITCH_FormatValues - put together various format strings # OWSWITCH_FormatValues - put together various format strings
# #
# CalledBy: OWSWITCH_Get, OWSWITCH_Set
# Calling: --
# Parameter; hash = hash of device addressed, fs = format string # Parameter; hash = hash of device addressed, fs = format string
# #
######################################################################################## ########################################################################################
@ -420,7 +403,9 @@ sub OWSWITCH_FormatValues($) {
my $svalue = ""; my $svalue = "";
#-- external shortening signature #-- external shortening signature
my $sname = defined($attr{$name}{"stateS"}) ? $attr{$name}{"stateS"} : "&#x2607;"; my $sname = defined($attr{$name}{"stateS"}) ? $attr{$name}{"stateS"} : "X";
$sname = ""
if($sname eq "none");
#-- obtain channel names #-- obtain channel names
OWSWITCH_ChannelNames($hash); OWSWITCH_ChannelNames($hash);
@ -466,10 +451,6 @@ sub OWSWITCH_FormatValues($) {
# #
# OWSWITCH_Get - Implements GetFn function # OWSWITCH_Get - Implements GetFn function
# #
# CalledBy: FHEM
# Calling: OWSWITCH_ChannelNames,OWSWITCH_FormatValues,
# OWFSSWITCH_GetState,OWXSWITCH_GetState,
# OWX_Verify
# Parameter: hash = hash of device addressed, a = argument array # Parameter: hash = hash of device addressed, a = argument array
# #
######################################################################################## ########################################################################################
@ -480,6 +461,7 @@ sub OWSWITCH_Get($@) {
my $reading = $a[1]; my $reading = $a[1];
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $model = $hash->{OW_MODEL}; my $model = $hash->{OW_MODEL};
my ($value,$value2,$value3) = (undef,undef,undef); my ($value,$value2,$value3) = (undef,undef,undef);
my $ret = ""; my $ret = "";
my ($offset,$factor,$page,$cname,@cnama,@channel); my ($offset,$factor,$page,$cname,@cnama,@channel);
@ -550,7 +532,7 @@ sub OWSWITCH_Get($@) {
#-- OWX interface #-- OWX interface
if( $interface eq "OWX" ){ if( $interface eq "OWX" ){
$ret = OWXSWITCH_GetState($hash); OWXSWITCH_GetModState($hash,undef,undef);
}elsif( $interface eq "OWX_ASYNC") { }elsif( $interface eq "OWX_ASYNC") {
eval { eval {
$ret = OWX_ASYNC_RunToCompletion($hash,OWXSWITCH_PT_GetState($hash)); $ret = OWX_ASYNC_RunToCompletion($hash,OWXSWITCH_PT_GetState($hash));
@ -563,8 +545,12 @@ sub OWSWITCH_Get($@) {
}else{ }else{
return "OWSWITCH: Get with wrong IODev type $interface"; return "OWSWITCH: Get with wrong IODev type $interface";
} }
#-- process results #-- process result
return $name.".".$a[2]." => ".$hash->{READINGS}{$owg_channel[$fnd]}{VAL}; if( ($master->{ASYNCHRONOUS}) && ($interface ne "OWFS") ){
return "OWSWITCH: $name getting input, please wait for completion";
}else{
return $name.".".$a[2]." => ".$hash->{READINGS}{$owg_channel[$fnd]}{VAL};
}
#-- get all states #-- get all states
}elsif( $reading eq "gpio" ){ }elsif( $reading eq "gpio" ){
@ -572,7 +558,7 @@ sub OWSWITCH_Get($@) {
if( int(@a)==1 ); if( int(@a)==1 );
if( $interface eq "OWX" ){ if( $interface eq "OWX" ){
$ret = OWXSWITCH_GetState($hash); $ret = OWXSWITCH_GetModState($hash,undef,undef);
}elsif( $interface eq "OWX_ASYNC" ){ }elsif( $interface eq "OWX_ASYNC" ){
eval { eval {
$ret = OWX_ASYNC_RunToCompletion($hash,OWXSWITCH_PT_GetState($hash)); $ret = OWX_ASYNC_RunToCompletion($hash,OWXSWITCH_PT_GetState($hash));
@ -584,10 +570,14 @@ sub OWSWITCH_Get($@) {
return "OWSWITCH: Get with wrong IODev type $interface"; return "OWSWITCH: Get with wrong IODev type $interface";
} }
#-- process results #-- process results
if( defined($ret) ){ if( $master->{ASYNCHRONOUS} ){
return "OWSWITCH: Could not get values from device $name, reason $ret"; return "OWSWITCH: $name getting gpio, please wait for completion";
}else{
if( defined($ret) ){
return "OWSWITCH: Could not get values from device $name, reason $ret";
}
return "OWSWITCH: $name.$reading => ".$hash->{READINGS}{"state"}{VAL};
} }
return "OWSWITCH: $name.$reading => ".$hash->{READINGS}{"state"}{VAL};
} }
} }
@ -620,7 +610,7 @@ sub OWSWITCH_GetValues($) {
if( $interface eq "OWX" ){ if( $interface eq "OWX" ){
#-- max 3 tries #-- max 3 tries
for(my $try=0; $try<3; $try++){ for(my $try=0; $try<3; $try++){
$ret = OWXSWITCH_GetState($hash); $ret = OWXSWITCH_GetModState($hash,undef,undef);
return if( !defined($ret) ); return if( !defined($ret) );
} }
}elsif( $interface eq "OWX_ASYNC" ){ }elsif( $interface eq "OWX_ASYNC" ){
@ -652,6 +642,7 @@ sub OWSWITCH_GetValues($) {
######################################################################################## ########################################################################################
# #
# OWSWITCH_InitializeDevice - initial readings # OWSWITCH_InitializeDevice - initial readings
#
# Parameter hash = hash of device addressed # Parameter hash = hash of device addressed
# #
######################################################################################## ########################################################################################
@ -738,24 +729,24 @@ sub OWSWITCH_Set($@) {
return "OWSWITCH: Set needs parameter when writing output: <channel>" return "OWSWITCH: Set needs parameter when writing output: <channel>"
if( int(@a)<2 ); if( int(@a)<2 );
#-- find out which channel we have #-- find out which channel we have
my $fnd=undef; my $outfnd=undef;
for (my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){ for (my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){
if( ($a[2] eq $owg_channel[$i]) || ($a[2] eq $owg_fixed[$i]) ){ if( ($a[2] eq $owg_channel[$i]) || ($a[2] eq $owg_fixed[$i]) ){
$fnd=$i; $outfnd=$i;
last; last;
} }
} }
return "OWSWITCH: Invalid output address, must be A,B,... or defined channel name" return "OWSWITCH: Invalid output address, must be A,B,... or defined channel name"
if( !defined($fnd) ); if( !defined($outfnd) );
#-- prepare gpio value #-- prepare gpio value
my $nval; my $outval;
my $ntim; my $ntim;
my $nstr=""; my $nstr="";
if( lc($a[3]) eq "on" ){ if( lc($a[3]) eq "on" ){
$nval = 0; $outval = 0;
}elsif( lc($a[3]) eq "off" ){ }elsif( lc($a[3]) eq "off" ){
$nval = 1; $outval = 1;
}elsif( lc($a[3]) =~ m/for-timer/ ){ }elsif( lc($a[3]) =~ m/for-timer/ ){
if( !($a[4] =~ m/\d\d\:\d\d\:\d\d/) ){ if( !($a[4] =~ m/\d\d\:\d\d\:\d\d/) ){
if( !($a[4] =~ m/\d{1,4}/ )){ if( !($a[4] =~ m/\d{1,4}/ )){
@ -767,10 +758,10 @@ sub OWSWITCH_Set($@) {
$ntim= $a[4]; $ntim= $a[4];
} }
if( lc($a[3]) eq "on-for-timer" ){ if( lc($a[3]) eq "on-for-timer" ){
$nval = 0; $outval = 0;
$nstr = "$a[0] $a[1] $a[2] off"; $nstr = "$a[0] $a[1] $a[2] off";
}elsif( lc($a[3]) eq "off-for-timer" ){ }elsif( lc($a[3]) eq "off-for-timer" ){
$nval = 1; $outval = 1;
$nstr = "$a[0] $a[1] $a[2] on"; $nstr = "$a[0] $a[1] $a[2] on";
} }
}else{ }else{
@ -778,36 +769,31 @@ sub OWSWITCH_Set($@) {
} }
if ($nstr ne ""){ if ($nstr ne ""){
fhem("define ".$a[0].".".$owg_fixed[$fnd]."Timer at +".$ntim." set ".$nstr); fhem("define ".$a[0].".".$owg_fixed[$outfnd]."Timer at +".$ntim." set ".$nstr);
} }
#-- OWX interface #-- OWX interface
if( $interface eq "OWX" ){ if( $interface eq "OWX" ){
$ret1 = OWXSWITCH_GetState($hash); $ret1 = OWXSWITCH_GetModState($hash,$outfnd,$outval);
$value = 0;
#-- vax or val ?
for (my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){
$value += ($hash->{owg_vax}->[$i]<<$i)
if( $i != $fnd );
$value += ($nval<<$i)
if( $i == $fnd );
}
$ret2 = OWXSWITCH_SetState($hash,$value);
}elsif( $interface eq "OWX_ASYNC"){ }elsif( $interface eq "OWX_ASYNC"){
eval { eval {
OWX_ASYNC_Schedule( $hash, OWXSWITCH_PT_SetOutput($hash,$fnd,$nval) ); OWX_ASYNC_Schedule( $hash, OWXSWITCH_PT_SetOutput($hash,$outfnd,$outval) );
}; };
$ret2 = GP_Catch($@) if $@; $ret2 = GP_Catch($@) if $@;
#-- OWFS interface #-- OWFS interface
}elsif( $interface eq "OWServer" ){ }elsif( $interface eq "OWServer" ){
$ret1 = OWFSSWITCH_GetState($hash); $ret1 = OWFSSWITCH_GetState($hash);
$value = 0; my $gpio = 0;
#-- vax or val ? #--
for (my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){ for (my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){
$value += ($hash->{owg_vax}->[$i]<<$i) if( $outval==0 ){
if( $i != $fnd ); $gpio += ($hash->{owg_vax}->[$i]<<$i)
$value += ($nval<<$i) if( $i != $outfnd );
if( $i == $fnd ); }else{
$gpio += ($hash->{owg_vax}->[$i]<<$i);
$gpio += (1<<$i)
if( $i == $outfnd );
}
} }
$ret2 = OWFSSWITCH_SetState($hash,$value); $ret2 = OWFSSWITCH_SetState($hash,$value);
#-- Unknown interface #-- Unknown interface
@ -848,7 +834,7 @@ sub OWSWITCH_Set($@) {
} }
#-- process results - we have to reread the device #-- process results - we have to reread the device
OWSWITCH_GetValues($hash); #OWSWITCH_GetValues($hash);
Log 4, "OWSWITCH: Set $hash->{NAME} $key $value"; Log 4, "OWSWITCH: Set $hash->{NAME} $key $value";
return undef; return undef;
} }
@ -1009,124 +995,216 @@ sub OWFSSWITCH_SetState($$) {
# #
######################################################################################## ########################################################################################
# #
# OWXSWITCH_BinValues - Binary readings into clear values # OWXSWITCH_BinValues - Process reading from one device - translate binary into raw
# #
# Parameter hash = hash of device addressed # Parameter hash = hash of device addressed
# context = mode for evaluating the binary data
# proc = processing instruction, also passed to OWX_Read.
# bitwise interpretation !!
# if 0, nothing special
# if 1 = bit 0, a reset will be performed not only before, but also after
# the last operation in OWX_Read
# if 2 = bit 1, the initial reset of the bus will be suppressed
# if 8 = bit 3, the fillup of the data with 0xff will be suppressed
# if 16= bit 4, the insertion will be at the top of the queue
# owx_dev = ROM ID of slave device
# crcpart = part of the data that needs to be part of the CRC check
# numread = number of bytes to receive
# res = result string
#
# #
######################################################################################## ########################################################################################
sub OWXSWITCH_BinValues($$$$$$$$) { sub OWXSWITCH_BinValues($$$$$$$) {
my ($hash, $context, $success, $reset, $owx_dev, $command, $numread, $res) = @_; my ($hash, $context, $reset, $owx_dev, $crcpart, $numread, $res) = @_;
#-- always check for success, unused are reset, numread
return unless ($success and $context);
#Log 1,"OWXSWITCH_BinValues context = $context";
my @data=[];
my $value;
#-- hash of the busmaster #-- hash of the busmaster
my $master = $hash->{IODev}; my $master = $hash->{IODev};
my $name = $hash->{NAME};
my @data=[];
my $value;
my $msg;
my $cmd;
my $chip;
my $outfnd;
my $outval;
OWX_WDBG($name,"OWXSWITCH_BinValues called for device $name in context $context with data ",$res)
if( $main::owx_debug>2 );
#-- note: value 1 corresponds to OFF, 0 to ON normally #-- note: value 1 corresponds to OFF, 0 to ON normally
# val = input value, vax = output value # val = input value, vax = output value
#-- Outer if - check get or set #-- Outer if - check get or set
if ( $context =~ /.*getstate.*/ ){ if ( $context =~ /^(......)\.(get|mod)state\.?(\d)?\.?(\d)?/){
$cmd = $2;
$chip = $1;
$outfnd = $3;
$outval = $4;
#-- family = 12 => DS2406 ------------------------------------------------------- #-- family = 12 => DS2406 -------------------------------------------------------
if( ($context eq "getstate.ds2406") or ($context eq "ds2406.getstate") ) { if( $chip eq "ds2406" ) {
@data=split(//,$res); @data=split(//,$res);
return "invalid data length, ".int(@data)." instead of 4 bytes" if (@data != 4){
if (@data != 4); $msg="Error - $name returns invalid data length, ".int(@data)." instead of 4 bytes, ";
return "invalid CRC" }elsif(OWX_CRC16($crcpart.substr($res,0,2),$data[2],$data[3]) == 0){
if ( OWX_CRC16($command.substr($res,0,2),$data[2],$data[3]) == 0); $msg="Error - state could not be set for device $name, invalid CRC, ";
$hash->{owg_val}->[0] = (ord($data[0])>>2) & 1; }else{
$hash->{owg_vax}->[0] = ord($data[0]) & 1; $msg="No error, ";
$hash->{owg_val}->[1] = (ord($data[0])>>3) & 1; $value=ord($data[0]);
$hash->{owg_vax}->[1] = (ord($data[0])>>1) & 1; $hash->{owg_val}->[0] = ($value>>2) & 1;
$hash->{owg_vax}->[0] = $value & 1;
$hash->{owg_val}->[1] = ($value>>3) & 1;
$hash->{owg_vax}->[1] = ($value>>1) & 1;
}
OWX_WDBG($name,"OWXSWITCH_BinValues: ".$msg,$res)
if( $main::owx_debug>2 );
#-- family = 29 => DS2408 ------------------------------------------------------- #-- family = 29 => DS2408 -------------------------------------------------------
}elsif( ($context eq "getstate.ds2408") or ($context eq "ds2408.getstate") ) { }elsif( $chip eq "ds2408" ) {
@data=split(//,$res); @data=split(//,$res);
return "invalid data length, ".int(@data)." instead of 10 bytes" if (@data != 10){
if (@data != 10); $msg="Error - $name returns invalid data length, ".int(@data)." instead of 10 bytes, ";
return "invalid data" }elsif(ord($data[6])!=255){
if (ord($data[6])!=255); $msg="Error - $name returns invalid data, ";
return "invalid CRC" }elsif(OWX_CRC16($crcpart.substr($res,0,8),$data[8],$data[9]) == 0){
if( OWX_CRC16($command.substr($res,0,8),$data[8],$data[9]) == 0); $msg="Error - state could not be set for device $name, invalid CRC, ";
for(my $i=0;$i<8;$i++){ }else{
$hash->{owg_val}->[$i] = (ord($data[0])>>$i) & 1; $msg="No error, ";
$hash->{owg_vax}->[$i] = (ord($data[1])>>$i) & 1; for(my $i=0;$i<8;$i++){
}; $hash->{owg_val}->[$i] = (ord($data[0])>>$i) & 1;
$hash->{owg_vax}->[$i] = (ord($data[1])>>$i) & 1;
};
}
OWX_WDBG($name,"OWXSWITCH_BinValues: ".$msg,$res)
if( $main::owx_debug>2 );
#-- family = 3A => DS2413 ------------------------------------------------------- #-- family = 3A => DS2413 -------------------------------------------------------
}elsif( ($context eq "getstate.ds2413") or ($context eq "ds2413.getstate") ){ }elsif( $chip eq "ds2413" ){
@data=split(//,$res); @data=split(//,$res);
return "invalid data length, ".int(@data)." instead of 2 bytes" if (@data != 2){
if (@data != 2); $msg="Error - $name returns invalid data length, ".int(@data)." instead of 2 bytes, ";
return "invalid data" }elsif((15- (ord($data[0])>>4)) != (ord($data[0]) & 15)){
if ( (15- (ord($data[0])>>4)) != (ord($data[0]) & 15) ); $msg="Error - $name returns invalid data, ";
$hash->{owg_val}->[0] = ord($data[0]) & 1; }else{
$hash->{owg_vax}->[0] = (ord($data[0])>>1) & 1; $msg="No error, ";
$hash->{owg_val}->[1] = (ord($data[0])>>2) & 1; $hash->{owg_val}->[0] = ord($data[0]) & 1;
$hash->{owg_vax}->[1] = (ord($data[0])>>3) & 1; $hash->{owg_vax}->[0] = (ord($data[0])>>1) & 1;
$hash->{owg_val}->[1] = (ord($data[0])>>2) & 1;
$hash->{owg_vax}->[1] = (ord($data[0])>>3) & 1;
}
OWX_WDBG($name,"OWXSWITCH_BinValues: ".$msg,$res)
if( $main::owx_debug>2 );
#-- #--
}else{ }else{
return "unknown device family $hash->{OW_FAMILY} in OWXSWITCH_BinValues getstate\n"; die "OWSWITCH: $name has unknown device family $hash->{OW_FAMILY} in OWXSWITCH_BinValues getstate\n";
}; };
#-- now only if data has to be overwritten
if( $cmd eq "mod" ){
my $gpio = 0;
#--
for (my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){
if( $outval==0 ){
$gpio += ($hash->{owg_vax}->[$i]<<$i)
if( $i != $outfnd );
}else{
$gpio += ($hash->{owg_vax}->[$i]<<$i);
$gpio += (1<<$i)
if( $i == $outfnd );
}
}
#-- re-set the state
OWXSWITCH_SetState($hash,$gpio);
}
#-- Now for context setstate #-- Now for context setstate
}elsif ( $context =~ /.*setstate.*/){ }elsif ( $context =~ /^(......)\.setstate\.?(\d+)?\.?(\d+)?/){
$chip = $1;
$value = $2;
#-- family = 12 => DS2406 ------------------------------------------------------- #-- family = 12 => DS2406 -------------------------------------------------------
if( ($context =~ /setstate\.ds2406\..*/) or ($context =~ /ds2406\.setstate\..*/) ) { if( $chip eq "ds2406" ) {
$value = substr($context,-1);
@data=split(//,$res); @data=split(//,$res);
return "state could not be set for device $owx_dev" if (@data != 2){
if( int(@data) != 2); $msg="Error - $name returns invalid data length, ".int(@data)." instead of 2 bytes, ";
return "invalid CRC" }elsif(OWX_CRC16($crcpart,$data[0],$data[1]) == 0){
if (OWX_CRC16($command,$data[0],$data[1]) == 0); $msg="Error - state could not be set for device $name, invalid CRC, ";
#-- put into local buffer]"; }else{
$hash->{owg_val}->[0] = $value % 2; $msg="No error, ";
$hash->{owg_vax}->[0] = $value % 2; $outval = $value % 2;
$hash->{owg_val}->[1] = int($value / 2); $hash->{owg_vax}->[0] = $outval;
$hash->{owg_vax}->[1] = int($value / 2); $hash->{owg_val}->[0] = 0
if( $outval ==0);
$outval = int($value / 2);
$hash->{owg_vax}->[1] = $outval;
$hash->{owg_val}->[1] = 0
if( $outval ==0);
}
OWX_WDBG($name,"OWXSWITCH_BinValues: ".$msg,$res)
if( $main::owx_debug>2 );
#-- family = 29 => DS2408 ------------------------------------------------------- #-- family = 29 => DS2408 -------------------------------------------------------
}elsif( ($context eq "setstate.ds2408") or ($context eq "ds2408.setstate") ) { }elsif( $chip eq "ds2408" ) {
@data=split(//,$res); if (length($res)!=1){
return "invalid data length, ".int(@data)." instead of 1 bytes" $msg="Error - $name returns invalid data length, ".length($res)." instead of 1 bytes, ";
if (@data != 1); }elsif($res ne "\xAA"){
return "state could not be set for device $owx_dev" $msg="Error - state could not be set for device $name, ";
if( $data[0] ne "\xAA"); }else{
$msg="No error, ";
for(my $i=0;$i<8;$i++){
$outval = ($value >>$i) & 1;
$hash->{owg_vax}->[$i] = $outval;
$hash->{owg_val}->[$i] = 0
if( $outval ==0);
};
}
OWX_WDBG($name,"OWXSWITCH_BinValues: ".$msg,$res)
if( $main::owx_debug>2 );
#-- family = 3A => DS2413 ------------------------------------------------------- #-- family = 3A => DS2413 -------------------------------------------------------
}elsif( ($context eq "setstate.ds2413") or ($context eq "ds2413.setstate") ){ }elsif( $chip eq "ds2413" ){
@data=split(//,$res); @data=split(//,$res);
return "invalid data length, ".int(@data)." instead of 1 bytes" if (@data != 2){
if (@data != 1); $msg="Error - $name returns invalid data length, ".int(@data)." instead of 2 bytes, ";
return "state could not be set for device $owx_dev" }elsif( $data[0] ne "\xAA"){
if( $data[0] ne "\xAA"); $msg="Error - state could not be set for device $name, ";
}else{
$msg="No error, ";
$outval = (ord($data[1])>>1) & 1;
$hash->{owg_vax}->[0] = $outval;
$hash->{owg_val}->[0] = 0
if( $outval ==0);
$outval = (ord($data[1])>>3) & 1;
$hash->{owg_vax}->[1] = $outval;
$hash->{owg_val}->[1] = 0
if( $outval ==0);
}
OWX_WDBG($name,"OWXSWITCH_BinValues: ".$msg,$res)
if( $main::owx_debug>2 );
#-- #--
}else{ }else{
return "unknown device family $hash->{OW_FAMILY} in OWXSWITCH_BinValues setstate\n"; die "OWSWITCH: $name has unknown device family $hash->{OW_FAMILY} in OWXSWITCH_BinValues setstate\n";
}; };
OWXSWITCH_GetModState($hash,undef,undef);
}else{ }else{
return "unknown context in OWXSWITCH_BinValues"; die "OWSWITCH: unknown context $context in OWXSWITCH_BinValues";
} }
#-- and now from raw to formatted values #-- and now from raw to formatted values
$hash->{PRESENT} = 1; $hash->{PRESENT} = 1;
$value = OWSWITCH_FormatValues($hash); $value = OWSWITCH_FormatValues($hash);
Log 5, $value;
return undef; return undef;
} }
######################################################################################## ########################################################################################
# #
# OWXSWITCH_GetState - Get gpio ports from device # OWXSWITCH_GetModState - Get gpio ports from device and overwrite
# #
# Parameter hash = hash of device addressed # Parameter hash = hash of device addressed
# mod = if 1, overwrite state with new data
# #
######################################################################################## ########################################################################################
sub OWXSWITCH_GetState($@) { sub OWXSWITCH_GetModState($$$) {
my ($hash,$sync) = @_; my ($hash,$outfnd,$outval) = @_;
my ($select, $res, @data); my ($select, $res, @data);
@ -1137,12 +1215,24 @@ sub OWXSWITCH_GetState($@) {
#-- hash of the busmaster #-- hash of the busmaster
my $master = $hash->{IODev}; my $master = $hash->{IODev};
my $name = $hash->{NAME};
#-- reset presence #-- reset presence
$hash->{PRESENT} = 0; $hash->{PRESENT} = 0;
my ($i,$j,$k); #-- what do we have to do
my $context;
my $proc;
if( !defined($outfnd) ){
$context = "getstate";
#-- take your time
$proc = 0;
}else{
$context = "modstate.$outfnd.$outval";
#-- faster !
$proc = 16;
}
#-- family = 12 => DS2406 #-- family = 12 => DS2406
if( $hash->{OW_FAMILY} eq "12" ) { if( $hash->{OW_FAMILY} eq "12" ) {
#=============== get gpio values =============================== #=============== get gpio values ===============================
@ -1150,45 +1240,78 @@ sub OWXSWITCH_GetState($@) {
# \xF5 plus the two byte channel control and the value # \xF5 plus the two byte channel control and the value
#-- reading 9 + 3 + 2 data bytes + 2 CRC bytes = 16 bytes #-- reading 9 + 3 + 2 data bytes + 2 CRC bytes = 16 bytes
$select=sprintf("\xF5\xDD\xFF"); $select=sprintf("\xF5\xDD\xFF");
OWX_Reset($master); #-- OLD OWX interface
$res=OWX_Complex($master,$owx_dev,$select,4); if( !$master->{ASYNCHRONOUS} ){
return "$owx_dev not accessible in reading" OWX_Reset($master);
if( $res eq 0 ); $res=OWX_Complex($master,$owx_dev,$select,4);
return "$owx_dev has returned invalid data" return "OWSWITCH: $name not accessible in reading"
if( length($res)!=16); if( $res eq 0 );
OWX_Reset($master); return "OWSWITCH: $name has returned invalid data"
return OWXSWITCH_BinValues($hash,"ds2406.getstate",1,undef,$owx_dev,substr($res,9,3),undef,substr($res,12)); if( length($res)!=16);
#OWX_Reset($master);
eval {
OWXSWITCH_BinValues($hash,"ds2406.$context",undef,$owx_dev,$select,4,substr($res,12));
};
return $@ ? $@ : undef;
#-- NEW OWX interface
}else{
#### master slave context proc owx_dev data crcpart numread startread callback delay
OWX_Qomplex($master, $hash, "ds2406.$context", $proc, $owx_dev, $select, $select, 4, 12, \&OWXSWITCH_BinValues, 0);
return undef;
}
#-- family = 29 => DS2408 #-- family = 29 => DS2408
}elsif( $hash->{OW_FAMILY} eq "29" ) { }elsif( $hash->{OW_FAMILY} eq "29" ) {
#=============== get gpio values =============================== #=============== get gpio values ===============================
#-- issue the match ROM command \x55 and the read PIO rtegisters command #-- issue the match ROM command \x55 and the read PIO registers command
# \xF5 plus the two byte channel target address # \xF5 plus the two byte channel target address
#-- reading 9 + 3 + 8 data bytes + 2 CRC bytes = 22 bytes #-- reading 9 + 3 + 8 data bytes + 2 CRC bytes = 22 bytes
$select=sprintf("\xF0\x88\x00"); $select=sprintf("\xF0\x88\x00");
OWX_Reset($master); #-- OLD OWX interface
$res=OWX_Complex($master,$owx_dev,$select,10); if( !$master->{ASYNCHRONOUS} ){
return "$owx_dev not accessible in reading" OWX_Reset($master);
if( $res eq 0 ); $res=OWX_Complex($master,$owx_dev,$select,10);
return "$owx_dev has returned invalid data" return "OWSWITCH: $name not accessible in reading"
if( length($res)!=22); if( $res eq 0 );
OWX_Reset($master); return "OWSWITCH: $name has returned invalid data"
return OWXSWITCH_BinValues($hash,"ds2408.getstate",1,undef,$owx_dev,substr($res,9,3),undef,substr($res,12)); if( length($res)!=22);
#OWX_Reset($master);
eval {
OWXSWITCH_BinValues($hash,"ds2408.$context",0,$owx_dev,$select,4,substr($res,12));
};
return $@ ? $@ : undef;
#-- NEW OWX interface
}else{
#### master slave context proc owx_dev data crcpart numread startread callback delay
OWX_Qomplex($master, $hash, "ds2408.$context", $proc, $owx_dev, $select, $select,10, 12, \&OWXSWITCH_BinValues, 0);
return undef;
}
#-- family = 3A => DS2413 #-- family = 3A => DS2413
}elsif( $hash->{OW_FAMILY} eq "3A" ) { }elsif( $hash->{OW_FAMILY} eq "3A" ) {
#=============== get gpio values =============================== #=============== get gpio values ===============================
#-- issue the match ROM command \x55 and the read gpio command #-- issue the match ROM command \x55 and the read gpio command
# \xF5 plus 2 empty bytes # \xF5 plus 2 empty bytes
#-- reading 9 + 1 + 2 data bytes = 12 bytes #-- reading 9 + 1 + 2 data bytes = 12 bytes
OWX_Reset($master); #-- OLD OWX interface
$res=OWX_Complex($master,$owx_dev,"\xF5",2); if( !$master->{ASYNCHRONOUS} ){
return "$owx_dev not accessible in reading" OWX_Reset($master);
if( $res eq 0 ); $res=OWX_Complex($master,$owx_dev,"\xF5",2);
return "$owx_dev has returned invalid data" return "OWSWITCH: $name not accessible in reading"
if( length($res)!=12); if( $res eq 0 );
#OWX_Reset($master); return "OWSWITCH: $name has returned invalid data"
return OWXSWITCH_BinValues($hash,"ds2413.getstate",1,undef,$owx_dev,substr($res,9,1),undef,substr($res,10)); if( length($res)!=12);
#OWX_Reset($master);
eval {
OWXSWITCH_BinValues($hash,"ds2413.$context",0,$owx_dev,substr($res,9,1),2,substr($res,10));
};
return $@ ? $@ : undef;
#-- NEW OWX interface
}else{
#### master slave context proc owx_dev data crcpart numread startread callback delay
OWX_Qomplex($master, $hash, "ds2413.$context", $proc, $owx_dev, "\xF5", "\xF5", 2, 10, \&OWXSWITCH_BinValues, 0);
return undef;
}
} else { } else {
return "unknown device family $hash->{OW_FAMILY}\n"; return "OWSWITCH: $name has unknown device family $hash->{OW_FAMILY}\n";
} }
} }
@ -1197,7 +1320,7 @@ sub OWXSWITCH_GetState($@) {
# OWXSWITCH_SetState - Set gpio ports of device # OWXSWITCH_SetState - Set gpio ports of device
# #
# Parameter hash = hash of device addressed # Parameter hash = hash of device addressed
# value = integer value for device outputs # value = integer value for device gpio output
# #
######################################################################################## ########################################################################################
@ -1205,7 +1328,6 @@ sub OWXSWITCH_SetState($$) {
my ($hash,$value) = @_; my ($hash,$value) = @_;
my ($select, $res, $res2, @data); my ($select, $res, $res2, @data);
#-- ID of the device #-- ID of the device
@ -1215,8 +1337,6 @@ sub OWXSWITCH_SetState($$) {
#-- hash of the busmaster #-- hash of the busmaster
my $master = $hash->{IODev}; my $master = $hash->{IODev};
my ($i,$j,$k);
#-- family = 12 => DS2406 #-- family = 12 => DS2406
if( $hash->{OW_FAMILY} eq "12" ) { if( $hash->{OW_FAMILY} eq "12" ) {
@ -1240,42 +1360,66 @@ sub OWXSWITCH_SetState($$) {
# \x55 at address TA1 = \x07 TA2 = \x00 # \x55 at address TA1 = \x07 TA2 = \x00
#-- reading 9 + 4 + 2 data bytes = 15 bytes #-- reading 9 + 4 + 2 data bytes = 15 bytes
$select=sprintf("\x55\x07\x00%c",$statneu); $select=sprintf("\x55\x07\x00%c",$statneu);
OWX_Reset($master); #-- OLD OWX interface
$res=OWX_Complex($master,$owx_dev,$select,2); if( !$master->{ASYNCHRONOUS} ){
if( $res eq 0 ){ OWX_Reset($master);
return "device $owx_dev not accessible in writing"; $res=OWX_Complex($master,$owx_dev,$select,2);
if( $res eq 0 ){
return "device $owx_dev not accessible in writing";
}
#OWX_Reset($master);
return OWXSWITCH_BinValues($hash,"ds2406.setstate.$value",0,$owx_dev,$select,2,substr($res,13));
#-- NEW OWX interface
}else{
#### master slave context proc owx_dev data crcpart numread startread callback delay
# 16 pushes this to the top of the queue
OWX_Qomplex($master, $hash, "ds2406.setstate.$value", 16, $owx_dev, $select, $select, 2, 13, \&OWXSWITCH_BinValues, 0);
return undef;
} }
OWX_Reset($master);
return OWXSWITCH_BinValues($hash,"ds2406.setstate.$value",1,undef,$owx_dev,substr($res,9,4),undef,substr($res,13));
return;
#-- family = 29 => DS2408 #-- family = 29 => DS2408
} elsif( $hash->{OW_FAMILY} eq "29" ) { } elsif( $hash->{OW_FAMILY} eq "29" ) {
#=============== set gpio values =============================== #=============== set gpio values ===============================
#-- issue the match ROM command \x55 and the write gpio command #-- issue the match ROM command \x55 and the write gpio command
# \x5A plus the value byte and its complement # \x5A plus the value byte and its complement
$select=sprintf("\x5A%c%c",$value,255-$value); $select=sprintf("\x5A%c%c",$value,255-$value);
OWX_Reset($master); #-- OLD OWX interface
$res=OWX_Complex($master,$owx_dev,$select,1); if( !$master->{ASYNCHRONOUS} ){
if( $res eq 0 ){ OWX_Reset($master);
return "device $owx_dev not accessible in writing"; $res=OWX_Complex($master,$owx_dev,$select,1);
if( $res eq 0 ){
return "device $owx_dev not accessible in writing";
}
OWX_Reset($master);
return OWXSWITCH_BinValues($hash,"ds2408.setstate.$value",0,$owx_dev,0,1,substr($res,12));
#-- NEW OWX interface
}else{
#### master slave context proc owx_dev data crcpart numread startread callback delay
# 16 pushes this to the top of the queue
OWX_Qomplex($master, $hash, "ds2408.setstate.$value", 16, $owx_dev, $select, 0, 1, 12, \&OWXSWITCH_BinValues, 0);
return undef;
} }
OWX_Reset($master);
return OWXSWITCH_BinValues($hash,"ds2408.setstate",1,undef,$owx_dev,undef,undef,substr($res,12));
return;
#-- family = 3A => DS2413 #-- family = 3A => DS2413
} elsif( $hash->{OW_FAMILY} eq "3A" ) { } elsif( $hash->{OW_FAMILY} eq "3A" ) {
#=============== set gpio values =============================== #=============== set gpio values ===============================
#-- issue the match ROM command \x55 and the write gpio command #-- issue the match ROM command \x55 and the write gpio command
# \x5A plus the value byte and its complement # \x5A plus the value byte and its complement
$select=sprintf("\x5A%c%c",252+$value,3-$value); $select=sprintf("\x5A%c%c",252+$value,3-$value);
OWX_Reset($master); #-- OLD OWX interface
$res=OWX_Complex($master,$owx_dev,$select,1); if( !$master->{ASYNCHRONOUS} ){
if( $res eq 0 ){ OWX_Reset($master);
return "device $owx_dev not accessible in writing"; $res=OWX_Complex($master,$owx_dev,$select,1);
if( $res eq 0 ){
return "device $owx_dev not accessible in writing";
}
OWX_Reset($master);
return OWXSWITCH_BinValues($hash,"ds2413.setstate",0,$owx_dev,0,2,substr($res,12));
#-- NEW OWX interface
}else{
#### master slave context proc owx_dev data cmd numread startread callback delay
# 16 pushes this to the top of the queue
OWX_Qomplex($master, $hash, "ds2413.setstate", 16, $owx_dev, $select, 0, 2, 12, \&OWXSWITCH_BinValues, 0);
return undef;
} }
OWX_Reset($master);
return OWXSWITCH_BinValues($hash,"ds2413.setstate",1,undef,$owx_dev,undef,undef,substr($res,12));
return;
}else { }else {
return "unknown device family $hash->{OW_FAMILY}\n"; return "unknown device family $hash->{OW_FAMILY}\n";
} }
@ -1322,7 +1466,7 @@ sub OWXSWITCH_PT_GetState($) {
unless (length($response) == 4) { unless (length($response) == 4) {
PT_EXIT("$owx_dev has returned invalid data"); PT_EXIT("$owx_dev has returned invalid data");
} }
$ret = OWXSWITCH_BinValues($hash,"ds2406.getstate",1,1,$owx_dev,$thread->{'select'},4,$response); $ret = OWXSWITCH_BinValues($hash,"ds2406.getstate",1,$owx_dev,$thread->{'select'},4,$response);
if (defined $ret) { if (defined $ret) {
PT_EXIT($ret); PT_EXIT($ret);
} }
@ -1340,7 +1484,7 @@ sub OWXSWITCH_PT_GetState($) {
unless (length($response) == 10) { unless (length($response) == 10) {
PT_EXIT("$owx_dev has returned invalid data") PT_EXIT("$owx_dev has returned invalid data")
}; };
$ret = OWXSWITCH_BinValues($hash,"ds2408.getstate",1,1,$owx_dev,$thread->{'select'},10,$response); $ret = OWXSWITCH_BinValues($hash,"ds2408.getstate",1,$owx_dev,$thread->{'select'},10,$response);
if (defined $ret) { if (defined $ret) {
PT_EXIT($ret); PT_EXIT($ret);
} }
@ -1358,7 +1502,7 @@ sub OWXSWITCH_PT_GetState($) {
unless (length($response) == 2) { unless (length($response) == 2) {
PT_EXIT("$owx_dev has returned invalid data"); PT_EXIT("$owx_dev has returned invalid data");
} }
$ret = OWXSWITCH_BinValues($hash,"ds2413.getstate",1,1,$owx_dev,$thread->{'select'},2,$response); $ret = OWXSWITCH_BinValues($hash,"ds2413.getstate",1,$owx_dev,$thread->{'select'},2,$response);
if (defined $ret) { if (defined $ret) {
PT_EXIT($ret); PT_EXIT($ret);
} }
@ -1534,7 +1678,7 @@ sub OWXSWITCH_PT_SetOutput($$$) {
<p> <p>
<code>define OWX_S OWSWITCH DS2413 B5D502000000 60</code> <code>define OWX_S OWSWITCH DS2413 B5D502000000 60</code>
<br /> <br />
<code>attr OWX_S AName Lampe|light</code> <code>attr OWX_S AName light-a|la</code>
<br /> <br />
<code>attr OWX_S AUnit AN|AUS</code> <code>attr OWX_S AUnit AN|AUS</code>
</p> </p>
@ -1597,7 +1741,7 @@ sub OWXSWITCH_PT_SetOutput($$$) {
</a> </a>
<br /> Returns 1 if this 1-Wire device is present, otherwise 0. </li> <br /> Returns 1 if this 1-Wire device is present, otherwise 0. </li>
<li><a name="owswitch_interval2"> <li><a name="owswitch_interval2">
<code>get &lt;name&gt; interval</code></a><br />Returns measurement interval in <code>get &lt;name&gt; interval</code></a><br />Measurement interval in
seconds. </li> seconds. </li>
<li><a name="owswitch_input"> <li><a name="owswitch_input">
<code>get &lt;name&gt; input &lt;channel-name&gt;</code></a><br /> state for <code>get &lt;name&gt; input &lt;channel-name&gt;</code></a><br /> state for
@ -1605,7 +1749,7 @@ sub OWXSWITCH_PT_SetOutput($$$) {
not necessarily the one set as output state, because the output transistors are open not necessarily the one set as output state, because the output transistors are open
collector switches. A measured state of 1 = OFF therefore corresponds to an output collector switches. A measured state of 1 = OFF therefore corresponds to an output
state of 1 = OFF, but a measured state of 0 = ON can also be due to an external state of 1 = OFF, but a measured state of 0 = ON can also be due to an external
shortening of the output.</li> shortening of the output, it will be signaled by appending the value of the attribute stateS to the reading.</li>
<li><a name="owswitch_gpio"> <li><a name="owswitch_gpio">
<code>get &lt;name&gt; gpio</code></a><br />Obtain state of all channels</li> <code>get &lt;name&gt; gpio</code></a><br />Obtain state of all channels</li>
</ul> </ul>
@ -1613,19 +1757,14 @@ sub OWXSWITCH_PT_SetOutput($$$) {
<h4>Attributes</h4> For each of the following attributes, the channel identification A,B,... <h4>Attributes</h4> For each of the following attributes, the channel identification A,B,...
may be used. <ul> may be used. <ul>
<li><a name="owswitch_states"><code>&lt;name&gt; stateS &lt;string&gt;</code></a> <li><a name="owswitch_states"><code>&lt;name&gt; stateS &lt;string&gt;</code></a>
<br/> character string denoting external shortening condition, default is "red angled arrow downward"</li> <br/> character string denoting external shortening condition (default is X, set to "none" for empty).</li>
<li><a name="owswitch_cname"><code>attr &lt;name&gt; &lt;channel&gt;Name <li><a name="owswitch_cname"><code>attr &lt;name&gt; &lt;channel&gt;Name
&lt;string&gt;[|&lt;string&gt;]</code></a> &lt;string&gt;[|&lt;string&gt;]</code></a>
<br />name for the channel [|name used in state reading] </li> <br />name for the channel [|short name used in state reading] </li>
<li><a name="owswitch_cunit"><code>attr &lt;name&gt; &lt;channel&gt;Unit <li><a name="owswitch_cunit"><code>attr &lt;name&gt; &lt;channel&gt;Unit
&lt;string&gt;|&lt;string&gt;</code></a> &lt;string&gt;|&lt;string&gt;</code></a>
<br />display for on | off condition </li> <br />display for on | off condition </li>
<li>Standard attributes <a href="#alias">alias</a>, <a href="#comment">comment</a>, <a <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
href="#event-on-update-reading">event-on-update-reading</a>, <a
href="#event-on-change-reading">event-on-change-reading</a>, <a
href="#stateFormat">stateFormat</a>, <a href="#room"
>room</a>, <a href="#eventMap">eventMap</a>, <a href="#loglevel">loglevel</a>,
<a href="#webCmd">webCmd</a></li>
</ul> </ul>
=end html =end html

View File

@ -35,8 +35,8 @@
# #
# Additional attributes are defined in fhem.cfg # Additional attributes are defined in fhem.cfg
# #
# attr <name> stateAL "<string>" = character string for denoting low alarm condition, default is down triangle # attr <name> stateAL "<string>" = character string for denoting low alarm condition, default is
# attr <name> stateAH "<string>" = character string for denoting high alarm condition, default is up triangle # attr <name> stateAH "<string>" = character string for denoting high alarm condition, default is
# 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
# attr <name> tempUnit <string> = unit of measurement, e.g. Celsius/Kelvin/Fahrenheit, default is Celsius # attr <name> tempUnit <string> = unit of measurement, e.g. Celsius/Kelvin/Fahrenheit, default is Celsius
# attr <name> tempConv onkick|onread = determines, whether a temperature measurement will happen when "kicked" # attr <name> tempConv onkick|onread = determines, whether a temperature measurement will happen when "kicked"
@ -86,7 +86,7 @@ no warnings 'deprecated';
sub Log3($$$); sub Log3($$$);
sub AttrVal($$$); sub AttrVal($$$);
my $owx_version="5.28"; my $owx_version="6.0";
my %gets = ( my %gets = (
"id" => "", "id" => "",
@ -141,7 +141,7 @@ sub OWTHERM_Initialize ($) {
$hash->{NotifyFn}= "OWTHERM_Notify"; $hash->{NotifyFn}= "OWTHERM_Notify";
$hash->{InitFn} = "OWTHERM_Init"; $hash->{InitFn} = "OWTHERM_Init";
$hash->{AttrFn} = "OWTHERM_Attr"; $hash->{AttrFn} = "OWTHERM_Attr";
$hash->{AttrList}= "IODev model:DS1820,DS18B20,DS1822 loglevel:0,1,2,3,4,5 ". $hash->{AttrList}= "IODev model:DS1820,DS18B20,DS1822 ".
"stateAL stateAH ". "stateAL stateAH ".
"tempOffset tempUnit:Celsius,Fahrenheit,Kelvin ". "tempOffset tempUnit:Celsius,Fahrenheit,Kelvin ".
"tempConv:onkick,onread tempLow tempHigh ". "tempConv:onkick,onread tempLow tempHigh ".
@ -254,7 +254,7 @@ sub OWTHERM_Define ($$) {
$modules{OWTHERM}{defptr}{$id} = $hash; $modules{OWTHERM}{defptr}{$id} = $hash;
#-- #--
readingsSingleUpdate($hash,"state","defined",1); readingsSingleUpdate($hash,"state","defined",1);
Log3 $name, 3, "OWTHERM: Device $name defined."; Log3 $name, 3, "OWTHERM: Device $name defined.";
$hash->{NOTIFYDEV} = "global"; $hash->{NOTIFYDEV} = "global";
@ -264,6 +264,16 @@ sub OWTHERM_Define ($$) {
return undef; return undef;
} }
#######################################################################################
#
# OWTHERM_Notify - Implements the Notify function
#
# Parameter hash = hash of device addressed
# a = argument array
#
########################################################################################
sub OWTHERM_Notify ($$) { sub OWTHERM_Notify ($$) {
my ($hash,$dev) = @_; my ($hash,$dev) = @_;
if( grep(m/^(INITIALIZED|REREADCFG)$/, @{$dev->{CHANGED}}) ) { if( grep(m/^(INITIALIZED|REREADCFG)$/, @{$dev->{CHANGED}}) ) {
@ -272,6 +282,16 @@ sub OWTHERM_Notify ($$) {
} }
} }
#######################################################################################
#
# OWTHERM_Init - Implements the Init function
#
# Parameter hash = hash of device addressed
# a = argument array
#
########################################################################################
sub OWTHERM_Init ($) { sub OWTHERM_Init ($) {
my ($hash)=@_; my ($hash)=@_;
#-- Start timer for updates #-- Start timer for updates
@ -355,28 +375,29 @@ sub OWTHERM_FormatValues($) {
my $svalue = ""; my $svalue = "";
#-- attributes defined ? #-- attributes defined ?
$stateal = AttrVal($name,"stateAL","&#x25BE;"); $stateal = AttrVal($name,"stateAL","");
$stateah = AttrVal($name,"stateAH","&#x25B4;"); $stateah = AttrVal($name,"stateAH","");
$unit = AttrVal($name,"tempUnit","Celsius"); $unit = AttrVal($name,"tempUnit","Celsius");
$offset = AttrVal($name,"tempOffset",0.0); $offset = AttrVal($name,"tempOffset",0.0);
$factor = 1.0; $factor = 1.0;
if( $unit eq "Celsius" ){ if( $unit eq "none" ){
$abbr = "°C"; $abbr = "";
}elsif( $unit eq "Celsius" ){
$abbr = " °C";
} elsif ($unit eq "Kelvin" ){ } elsif ($unit eq "Kelvin" ){
$abbr = "K"; $abbr = " K";
$offset += "273.16" $offset += "273.16"
} elsif ($unit eq "Fahrenheit" ){ } elsif ($unit eq "Fahrenheit" ){
$abbr = "°F"; $abbr = " °F";
$offset = ($offset+32)/1.8; $offset = ($offset+32)/1.8;
$factor = 1.8; $factor = 1.8;
} else { } else {
$abbr="?"; $abbr=" ?";
Log3 $name, 3, "OWTHERM_FormatValues: Unknown temperature unit $unit"; Log3 $name, 3, "OWTHERM_FormatValues: Unknown temperature unit $unit";
} }
#-- these values are rather complex to obtain, therefore save them in the hash #-- these values are rather complex to obtain, therefore save them in the hash
$hash->{READINGS}{"temperature"}{UNIT} = $unit; $hash->{READINGS}{"temperature"}{UNIT} = $abbr;
$hash->{READINGS}{"temperature"}{UNITABBR} = $abbr;
$hash->{tempf}{offset} = $offset; $hash->{tempf}{offset} = $offset;
$hash->{tempf}{factor} = $factor; $hash->{tempf}{factor} = $factor;
@ -392,7 +413,7 @@ sub OWTHERM_FormatValues($) {
$main::attr{$name}{"tempHigh"} = $vhigh; $main::attr{$name}{"tempHigh"} = $vhigh;
#-- formats for output #-- formats for output
$statef = "T: %5.2f ".$abbr; $statef = "T: %5.2f".$abbr;
$svalue = sprintf($statef,$vval); $svalue = sprintf($statef,$vval);
#-- Test for alarm condition #-- Test for alarm condition
@ -431,6 +452,7 @@ sub OWTHERM_Get($@) {
my $reading = $a[1]; my $reading = $a[1];
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $model = $hash->{OW_MODEL}; my $model = $hash->{OW_MODEL};
my $value = undef; my $value = undef;
my $ret = ""; my $ret = "";
@ -450,6 +472,7 @@ sub OWTHERM_Get($@) {
#-- hash of the busmaster #-- hash of the busmaster
my $master = $hash->{IODev}; my $master = $hash->{IODev};
#-- Get other values according to interface type #-- Get other values according to interface type
my $interface= $hash->{IODev}->{TYPE}; my $interface= $hash->{IODev}->{TYPE};
@ -503,19 +526,24 @@ sub OWTHERM_Get($@) {
} }
#-- process results #-- process results
if( defined($ret) ){ if( $master->{ASYNCHRONOUS} ){
return "OWTHERM: Could not get values from device $name, return was $ret"; return "OWTHERM: $name getting values, please wait for completion";
}else{
#-- when we have a return code, we have an error
if( defined($ret) ){
return "OWTHERM: Could not get values from device $name, return was $ret";
}
#-- return the special reading
if ($reading eq "temperature") {
return "OWTHERM: $name.temperature => ".
$hash->{READINGS}{"temperature"}{VAL};
} elsif ($reading eq "alarm") {
return "OWTHERM: $name.alarm => L ".$main::attr{$name}{"tempLow"}.
" H ".$main::attr{$name}{"tempHigh"};
} else {
return undef;
}
} }
#-- return the special reading
if ($reading eq "temperature") {
return "OWTHERM: $name.temperature => ".
$hash->{READINGS}{"temperature"}{VAL};
} elsif ($reading eq "alarm") {
return "OWTHERM: $name.alarm => L ".$main::attr{$name}{"tempLow"}.
" H ".$main::attr{$name}{"tempHigh"};
}
return undef;
} }
####################################################################################### #######################################################################################
@ -615,9 +643,8 @@ sub OWTHERM_InitializeDevice($) {
Log3 $name, 3, "OWTHERM_InitializeDevice: unknown unit $unit"; Log3 $name, 3, "OWTHERM_InitializeDevice: unknown unit $unit";
} }
#-- these values are rather complex to obtain, therefore save them in the hash #-- these values are rather complex to obtain, therefore save them in the hash
$hash->{READINGS}{"temperature"}{TYPE} = "temperature"; $hash->{READINGS}{"temperature"}{TYPE} = "temperature";
$hash->{READINGS}{"temperature"}{UNIT} = $unit; $hash->{READINGS}{"temperature"}{UNIT} = $abbr;
$hash->{READINGS}{"temperature"}{UNITABBR} = $abbr;
$hash->{ERRCOUNT} = 0; $hash->{ERRCOUNT} = 0;
$hash->{tempf}{offset} = $offset; $hash->{tempf}{offset} = $offset;
$hash->{tempf}{factor} = $factor; $hash->{tempf}{factor} = $factor;
@ -894,32 +921,53 @@ sub OWFSTHERM_SetValues($$) {
# #
######################################################################################## ########################################################################################
# #
# OWXTHERM_BinValues - Binary readings into clear values # OWXTHERM_BinValues - Process reading from one device - translate binary into raw
# #
# Parameter hash = hash of device addressed # Parameter hash = hash of device addressed
# context = mode for evaluating the binary data
# proc = processing instruction, also passed to OWX_Read.
# bitwise interpretation !!
# if 0, nothing special
# if 1 = bit 0, a reset will be performed not only before, but also after
# the last operation in OWX_Read
# if 2 = bit 1, the initial reset of the bus will be suppressed
# if 8 = bit 3, the fillup of the data with 0xff will be suppressed
# if 16= bit 4, the insertion will be at the top of the queue
# owx_dev = ROM ID of slave device
# crcpart = part of the data that needs to be part of the CRC check
# numread = number of bytes to receive
# res = result string
#
# #
######################################################################################## ########################################################################################
sub OWXTHERM_BinValues($$$$$$) { sub OWXTHERM_BinValues($$$$$$$) {
my ($hash, $reset, $owx_dev, $command, $numread, $res) = @_; my ($hash, $context, $reset, $owx_dev, $crcpart, $numread, $res) = @_;
#Log3 $name, 1,"OWXTHERM_BinValues context = $context";
my ($i,$j,$k,@data,$ow_thn,$ow_tln); my ($i,$j,$k,@data,$ow_thn,$ow_tln);
my $change = 0; my $change = 0;
my $name = $hash->{NAME};
#Log3 $name, 1,"OWXTHERM: data length from reading device is ".length($res)." bytes"; my $msg;
#-- process results OWX_WDBG($name,"OWTHERM_BinValues called for device $name with ",$res)
die "$owx_dev not accessible in 2nd step" unless ( defined $res and $res ne 0 ); if( $main::owx_debug>2 );
#-- process results #-- process results
@data=split(//,$res); @data=split(//,$res);
die "invalid data length, ".int(@data)." instead of 9 bytes" if (@data != 9){
if (@data != 9); $msg="Error - $name returns invalid data length, ".int(@data)." instead of 9 bytes, ";
die "invalid data" }elsif(ord($data[7])<=0){
if (ord($data[7])<=0); $msg="Error - $name returns invalid data, ";
die "invalid CRC" }elsif(OWX_CRC8(substr($res,0,8),$data[8])==0){
if (OWX_CRC8(substr($res,0,8),$data[8])==0); $msg="Error - invalid data from device $name, invalid CRC, ";
}else{
$msg="No error, ";
for(my $i=0;$i<8;$i++){
$hash->{owg_val}->[$i] = (ord($data[0])>>$i) & 1;
$hash->{owg_vax}->[$i] = (ord($data[1])>>$i) & 1;
};
}
OWX_WDBG($name,"OWXTHERM_BinValues: ".$msg,$res)
if( $main::owx_debug>2 );
#-- this must be different for the different device types #-- this must be different for the different device types
# family = 10 => DS1820, DS18S20 # family = 10 => DS1820, DS18S20
@ -967,7 +1015,7 @@ sub OWXTHERM_BinValues($$$$$$) {
$ow_tln = ord($data[3]) > 127 ? 128-ord($data[3]) : ord($data[3]); $ow_tln = ord($data[3]) > 127 ? 128-ord($data[3]) : ord($data[3]);
} else { } else {
die "OWXTHERM: Unknown device family $hash->{OW_FAMILY}\n"; die "OWTHERM: $name: Unknown device family $hash->{OW_FAMILY}\n";
} }
#-- process alarm settings #-- process alarm settings
@ -977,7 +1025,6 @@ sub OWXTHERM_BinValues($$$$$$) {
#-- and now from raw to formatted values #-- and now from raw to formatted values
$hash->{PRESENT} = 1; $hash->{PRESENT} = 1;
my $value = OWTHERM_FormatValues($hash); my $value = OWTHERM_FormatValues($hash);
Log3 $hash->{NAME}, 5, $value;
return undef; return undef;
} }
@ -1002,35 +1049,51 @@ sub OWXTHERM_GetValues($) {
#-- hash of the busmaster #-- hash of the busmaster
my $master = $hash->{IODev}; my $master = $hash->{IODev};
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $res;
#-- check, if the conversion has been called before for all sensors #-- check, if the conversion has been called before for all sensors
if( defined($attr{$name}{tempConv}) && ( $attr{$name}{tempConv} eq "onkick") ){ if( defined($attr{$name}{tempConv}) && ( $attr{$name}{tempConv} eq "onkick") ){
$con=0; $con=0;
} }
#-- if the conversion has not been called before #-- if the conversion has not been called before
#-- issue the match ROM command \x55 and the start conversion command \x44
#-- conversion needs some 950 ms - but we may also do it in shorter time !
if( $con==1 ){ if( $con==1 ){
#-- issue the match ROM command \x55 and the start conversion command \x44 #-- OLD OWX interface
OWX_Reset($master); if( !$master->{ASYNCHRONOUS} ){
if( OWX_Complex($master,$owx_dev,"\x44",0) eq 0 ){ OWX_Reset($master);
return "$owx_dev not accessible"; if( OWX_Complex($master,$owx_dev,"\x44",0) eq 0 ){
} return "OWTHERM: $name not accessible";
#-- conversion needs some 950 ms - but we may also do it in shorter time ! }
select(undef,undef,undef,$convtimes{AttrVal($name,"resolution",12)}*0.001); select(undef,undef,undef,$convtimes{AttrVal($name,"resolution",12)}*0.001);
#-- NEW OWX interface
}else{
#### master slave context proc owx_dev data crcpart numread startread callback delay
OWX_Qomplex($master, $hash, undef, 0, $owx_dev, "\x44", 0, 0, undef, undef, $convtimes{AttrVal($name,"resolution",12)}*0.001);
}
} }
#-- NOW ask the specific device #-- NOW ask the specific device
#-- issue the match ROM command \x55 and the read scratchpad command \xBE #-- issue the match ROM command \x55 and the read scratchpad command \xBE
#-- reading 9 + 1 + 8 data bytes and 1 CRC byte = 19 bytes #-- reading 9 + 1 + 8 data bytes and 1 CRC byte = 19 bytes
OWX_Reset($master); #-- OLD OWX interface
my $res=OWX_Complex($master,$owx_dev,"\xBE",9); if( !$master->{ASYNCHRONOUS} ){
return "$owx_dev not accessible in reading" OWX_Reset($master);
if( $res eq 0 ); my $res=OWX_Complex($master,$owx_dev,"\xBE",9);
return "$owx_dev has returned invalid data" return "OWTHERM: $name not accessible in reading"
if( length($res)!=19); if( $res eq 0 );
eval { return "OWTHERM: $name has returned invalid data"
OWXTHERM_BinValues($hash,undef,$owx_dev,undef,undef,substr($res,10,9)); if( length($res)!=19);
}; eval {
return $@ ? $@ : undef; OWXTHERM_BinValues($hash,undef,$owx_dev,undef,undef,9,substr($res,10,9));
};
return $@ ? $@ : undef;
#-- NEW OWX interface
}else{
#### master slave context proc owx_dev data crcpart numread startread callback delay
OWX_Qomplex($master, $hash, undef, 0, $owx_dev, "\xBE", 0, 9, 10, \&OWXTHERM_BinValues, 0);
return undef;
}
} }
####################################################################################### #######################################################################################
@ -1045,8 +1108,6 @@ sub OWXTHERM_GetValues($) {
sub OWXTHERM_SetValues($$) { sub OWXTHERM_SetValues($$) {
my ($hash, $args) = @_; my ($hash, $args) = @_;
my ($i,$j,$k);
my $name = $hash->{NAME}; my $name = $hash->{NAME};
#-- ID of the device #-- ID of the device
@ -1079,12 +1140,18 @@ sub OWXTHERM_SetValues($$) {
# 3. \x48 sent by WriteBytePower after match ROM => command ok, no effect on EEPROM # 3. \x48 sent by WriteBytePower after match ROM => command ok, no effect on EEPROM
my $select=sprintf("\x4E%c%c%c",$thp,$tlp,$cfg); my $select=sprintf("\x4E%c%c%c",$thp,$tlp,$cfg);
OWX_Reset($master); #-- OLD OWX interface
my $res=OWX_Complex($master,$owx_dev,$select,3); if( !$master->{ASYNCHRONOUS} ){
if( $res eq 0 ){ OWX_Reset($master);
return "OWXTHERM: Device $owx_dev not accessible"; my $res=OWX_Complex($master,$owx_dev,$select,3);
if( $res eq 0 ){
return "OWTHERM: $name not accessible for setting";
}
#-- NEW OWX interface
}else{
#### master slave context proc owx_dev data crcpart numread startread callback delay
OWX_Qomplex($master, $hash, undef, 0, $owx_dev, $select, 0, 3, 10, undef, 0);
} }
return undef; return undef;
} }
@ -1137,7 +1204,7 @@ sub OWXTHERM_PT_GetValues($) {
$thread->{pt_execute} = OWX_ASYNC_PT_Execute($master,1,$owx_dev,"\xBE",9); $thread->{pt_execute} = OWX_ASYNC_PT_Execute($master,1,$owx_dev,"\xBE",9);
PT_WAIT_THREAD($thread->{pt_execute}); PT_WAIT_THREAD($thread->{pt_execute});
die $thread->{pt_execute}->PT_CAUSE() if ($thread->{pt_execute}->PT_STATE() == PT_ERROR); die $thread->{pt_execute}->PT_CAUSE() if ($thread->{pt_execute}->PT_STATE() == PT_ERROR);
OWXTHERM_BinValues($hash,1,$owx_dev,undef,9,$thread->{pt_execute}->PT_RETVAL()); OWXTHERM_BinValues($hash,undef,1,$owx_dev,undef,9,$thread->{pt_execute}->PT_RETVAL());
PT_END; PT_END;
}); });
} }
@ -1299,12 +1366,10 @@ sub OWXTHERM_PT_SetValues($$) {
<ul> <ul>
<li><a name="owtherm_stateAL"><code>attr &lt;name&gt; stateAL &lt;string&gt;</code> <li><a name="owtherm_stateAL"><code>attr &lt;name&gt; stateAL &lt;string&gt;</code>
</a> </a>
<br />character string for denoting low alarm condition, default is down triangle, <br />character string for denoting low alarm condition, default is ↓</li>
e.g. the code &amp;#x25BE; leading to the sign &#x25BE; </li>
<li><a name="owtherm_stateAH"><code>attr &lt;name&gt; stateAH &lt;string&gt;</code> <li><a name="owtherm_stateAH"><code>attr &lt;name&gt; stateAH &lt;string&gt;</code>
</a> </a>
<br />character string for denoting high alarm condition, default is upward <br />character string for denoting high alarm condition, default is ↑</li>
triangle, e.g. the code &amp;#x25B4; leading to the sign &#x25B4; </li>
<li><a name="owtherm_tempConv"> <li><a name="owtherm_tempConv">
<code>attr &lt;name&gt; tempConv onkick|onread</code> <code>attr &lt;name&gt; tempConv onkick|onread</code>
</a> </a>
@ -1315,9 +1380,9 @@ sub OWXTHERM_PT_SetValues($$) {
</a> </a>
<br />temperature offset in °C added to the raw temperature reading. </li> <br />temperature offset in °C added to the raw temperature reading. </li>
<li><a name="owtherm_tempUnit"><code>attr &lt;name&gt; tempUnit <li><a name="owtherm_tempUnit"><code>attr &lt;name&gt; tempUnit
Celsius|Kelvin|Fahrenheit</code> none|Celsius|Kelvin|Fahrenheit</code>
</a> </a>
<br />unit of measurement (temperature scale), default is Celsius = °C </li> <br />unit of measurement (temperature scale) for state reading (default is Celsius = °C, use "none" for empty).</li>
<li><a name="owtherm_resolution"> <li><a name="owtherm_resolution">
<code>attr &lt;name&gt; resolution 9|10|11|12</code></a><br /> Temperature <code>attr &lt;name&gt; resolution 9|10|11|12</code></a><br /> Temperature
resolution in bit, only relevant for DS18B20 </li> resolution in bit, only relevant for DS18B20 </li>
@ -1336,13 +1401,7 @@ sub OWXTHERM_PT_SetValues($$) {
</a> </a>
<br /> low alarm temperature (on the temperature scale chosen by the attribute <br /> low alarm temperature (on the temperature scale chosen by the attribute
value). </li> value). </li>
<li><a href="#readingFnAttributes">readingFnAttributes</a></li>
<li>Standard attributes <a href="#alias">alias</a>, <a href="#comment">comment</a>, <a
href="#event-on-update-reading">event-on-update-reading</a>, <a
href="#event-on-change-reading">event-on-change-reading</a>, <a
href="#stateFormat">stateFormat</a>, <a href="#room"
>room</a>, <a href="#eventMap">eventMap</a>, <a href="#loglevel">loglevel</a>,
<a href="#webCmd">webCmd</a></li>
</ul> </ul>
=end html =end html