2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-03 10:46:53 +00:00

21_OWID.pm: Neue Version 7.0, angepasst an OWX Next Generation.

21_OWVAR.pm: Neue Version 7.0, angepasst an OWX Next Generation.
21_OWTHERM.pm: Neue Version 7.0, angepasst an OWX Next Generation.

git-svn-id: https://svn.fhem.de/fhem/trunk@14699 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
phenning 2017-07-13 08:07:17 +00:00
parent 01ab9f74f0
commit 2dffd5cf20
3 changed files with 217 additions and 321 deletions

View File

@ -11,25 +11,6 @@
#
########################################################################################
#
# define <name> OWID <FAM_ID> <ROM_ID> [interval] or OWID <FAM_ID>.<ROM_ID> [interval]
#
# where <name> may be replaced by any name string
#
# <FAM_ID> is a 2 character (1 byte) 1-Wire Family ID
#
# <ROM_ID> is a 12 character (6 byte) 1-Wire ROM ID
# without Family ID, e.g. A2D90D000800
# [interval] is an optional query interval in seconds
#
# set <name> interval => set query interval for checking presence
#
# get <name> id => FAM_ID.ROM_ID.CRC
# get <name> present => 1 if device present, 0 if not
# get <name> version => OWX version number
#
#
########################################################################################
#
# This programm is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
@ -68,11 +49,10 @@ use ProtoThreads;
no warnings 'deprecated';
sub Log3($$$);
my $owx_version="6.1";
my $owx_version="7.0";
#-- declare variables
my %gets = (
"present" => "",
"interval" => "",
"id" => "",
"version" => ""
);
@ -80,7 +60,7 @@ my %sets = (
"interval" => ""
);
my %updates = (
"present" => ""
"present" => ""
);
########################################################################################
@ -215,10 +195,8 @@ sub OWID_Define ($$) {
$hash->{NOTIFYDEV} = "global";
if ($init_done) {
return OWID_Init($hash);
}
return undef;
return OWID_Init($hash);
}
#########################################################################################
@ -249,7 +227,7 @@ sub OWID_Init ($) {
my ($hash)=@_;
#-- Start timer for updates
RemoveInternalTimer($hash);
InternalTimer(gettimeofday()+10, "OWID_GetValues", $hash, 0);
InternalTimer(gettimeofday()+30, "OWID_GetValues", $hash, 0);
#--
readingsSingleUpdate($hash,"state","Initialized",1);
@ -280,9 +258,9 @@ sub OWID_Attr(@) {
#-- interval modified at runtime
$key eq "interval" and do {
#-- check value
return "OWID: Set with short interval, must be > 1" if(int($value) < 1);
return "OWID: set $name interval must be >= 0" if(int($value) < 0);
#-- update timer
$hash->{INTERVAL} = $value;
$hash->{INTERVAL} = int($value);
if ($init_done) {
RemoveInternalTimer($hash);
InternalTimer(gettimeofday()+$hash->{INTERVAL}, "OWID_GetValues", $hash, 0);
@ -337,33 +315,39 @@ sub OWID_Get($@) {
return "$name.id => $value";
}
#-- get interval
if($a[1] eq "interval") {
$value = $hash->{INTERVAL};
return "$name.interval => $value";
}
#-- get present
if($a[1] eq "present") {
#-- hash of the busmaster
my $master = $hash->{IODev};
#-- asynchronous mode
if( $hash->{ASYNC} ){
my $master = $hash->{IODev};
my $interface = $master->{TYPE};
#-- OWX interface
if( $interface eq "OWX" ){
$value = OWX_Verify($master,$name,$hash->{ROM_ID},0);
#-- OWX_ASYNC interface
}elsif( $interface eq "OWX_ASYNC" ){
eval {
OWX_ASYNC_RunToCompletion($hash,OWX_ASYNC_PT_Verify($hash));
};
return GP_Catch($@) if $@;
return "$name.present => ".ReadingsVal($name,"present","unknown");
#-- Unknown interface
} else {
$value = OWX_Verify($master,$hash->{ROM_ID});
return "OWID: Verification not yet implemented for interface $interface";
}
if( $value == 0 ){
readingsSingleUpdate($hash,"present",0,$hash->{PRESENT});
} else {
readingsSingleUpdate($hash,"present",1,!$hash->{PRESENT});
#-- process results
if( $master->{ASYNCHRONOUS} ){
return undef;
}else{
#-- generate an event only if presence has changed
if( $value == 0 ){
readingsSingleUpdate($hash,"present",0,$hash->{PRESENT});
} else {
readingsSingleUpdate($hash,"present",1,!$hash->{PRESENT});
}
$hash->{PRESENT} = $value;
return "$name.present => $value";
}
$hash->{PRESENT} = $value;
return "$name.present => $value";
}
#-- get version
@ -389,30 +373,42 @@ sub OWID_GetValues($) {
my $offset;
my $factor;
#-- restart timer for updates
RemoveInternalTimer($hash);
RemoveInternalTimer($hash);
#-- auto-update for device disabled;
return undef
if( $hash->{INTERVAL} == 0 );
#-- restart timer for updates
InternalTimer(time()+$hash->{INTERVAL}, "OWID_GetValues", $hash, 0);
#-- hash of the busmaster
my $master = $hash->{IODev};
my $master = $hash->{IODev};
my $interface = $master->{TYPE};
if( $hash->{ASYNC} ){
#-- OWX interface
if( $interface eq "OWX" ){
$value = OWX_Verify($master,$name,$hash->{ROM_ID},0);
#-- OWX_ASYNC interface
}elsif( $interface eq "OWX_ASYNC" ){
eval {
OWX_ASYNC_Schedule($hash,OWX_ASYNC_PT_Verify($hash));
OWX_ASYNC_RunToCompletion($hash,OWX_ASYNC_PT_Verify($hash));
};
return GP_Catch($@) if $@;
return undef;
} else {
$value = OWX_Verify($master,$hash->{ROM_ID});
}
#-- generate an event only if presence has changed
if( $value == 0 ){
readingsSingleUpdate($hash,"present",0,$hash->{PRESENT});
} else {
readingsSingleUpdate($hash,"present",1,!$hash->{PRESENT});
#-- process results
if( $master->{ASYNCHRONOUS} ){
return undef;
}else{
#-- generate an event only if presence has changed
if( $value == 0 ){
readingsSingleUpdate($hash,"present",0,$hash->{PRESENT});
} else {
readingsSingleUpdate($hash,"present",1,!$hash->{PRESENT});
}
$hash->{PRESENT} = $value;
return "$name.present => $value";
}
$hash->{PRESENT} = $value;
}
#######################################################################################
@ -449,10 +445,10 @@ sub OWID_Set($@) {
#-- set new timer interval
if($key eq "interval") {
# check value
return "OWID: Set with short interval, must be > 1"
if(int($value) < 1);
return "OWID: Set $name interval must be >= 0"
if(int($value) < 0);
# update timer
$hash->{INTERVAL} = $value;
$hash->{INTERVAL} = int($value);
RemoveInternalTimer($hash);
InternalTimer(gettimeofday()+$hash->{INTERVAL}, "OWID_GetValues", $hash, 0);
return undef;
@ -533,7 +529,9 @@ sub OWID_Undef ($) {
<br /> Returns 1 if this 1-Wire device is present, otherwise 0. </li>
</ul>
<h4>Attributes</h4>
<ul>
<ul><li><a name="owtherm_interval2">
<code>attr &lt;name&gt; interval &lt;int&gt;</code></a><br /> Measurement
interval in seconds. The default is 300 seconds, a value of 0 disables the automatic update.</li>
<li><a href="#readingFnAttributes">readingFnAttributes</a></li>
</ul>

View File

@ -11,44 +11,6 @@
#
########################################################################################
#
# define <name> OWTHERM [<model>] <ROM_ID> [interval] or <FAM_ID>.<ROM_ID> [interval]
#
# where <name> may be replaced by any name string
#
# <model> is a 1-Wire device type. If omitted AND no FAM_ID given we assume this to be an
# DS1820 temperature sensor. Currently allowed values are DS1820, DS18B20, DS1822
# <FAM_ID> is a 1-Wire family id, currently allowed values are 10, 22, 28
# <ROM_ID> is a 12 character (6 byte) 1-Wire ROM ID
# without Family ID, e.g. A2D90D000800
# [interval] is an optional query interval in seconds
#
# get <name> id => FAM_ID.ROM_ID.CRC
# get <name> present => 1 if device present, 0 if not
# get <name> interval => query interval
# get <name> temperature => temperature measurement
# get <name> alarm => alarm temperature settings
# get <name> version => OWX version number
#
# set <name> interval => period for measurement
# set <name> tempLow => lower alarm temperature setting
# set <name> tempHigh => higher alarm temperature setting
#
# Additional attributes are defined in fhem.cfg
#
# 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 ↑
# 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> tempConv onkick|onread = determines, whether a temperature measurement will happen when "kicked"
# through the OWX backend module (all temperature sensors at the same time), or on
# reading the sensor (1 second waiting time).
# attr <name> resolution 9|10|11|12 = resolution in bit for measurement
# attr <name> interval <floar> = period for measurement
# attr <name> tempLow <float> = lower alarm temperature setting
# attr <name> tempHigh <float> = higher alarm temperature setting
#
########################################################################################
#
# This programm is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
@ -86,12 +48,10 @@ no warnings 'deprecated';
sub Log3($$$);
sub AttrVal($$$);
my $owx_version="6.1";
my $owx_version="7.0";
my %gets = (
"id" => "",
"present" => "",
"interval" => "",
"temperature" => "",
"alarm" => "",
"version" => ""
@ -114,7 +74,7 @@ my %convtimes = (
9 => 100,
10 => 200,
11 => 400,
12 => 800,
12 => 1000,
);
########################################################################################
@ -273,7 +233,6 @@ sub OWTHERM_Define ($$) {
#
########################################################################################
sub OWTHERM_Notify ($$) {
my ($hash,$dev) = @_;
if( grep(m/^(INITIALIZED|REREADCFG)$/, @{$dev->{CHANGED}}) ) {
@ -291,7 +250,6 @@ sub OWTHERM_Notify ($$) {
#
########################################################################################
sub OWTHERM_Init ($) {
my ($hash)=@_;
#-- Start timer for updates
@ -317,12 +275,12 @@ sub OWTHERM_Attr(@) {
if ( $do eq "set") {
ARGUMENT_HANDLER: {
#-- interval modified at runtime
#-- interval modified at runtime
$key eq "interval" and do {
#-- check value
return "OWTHERM: Set with short interval, must be > 1" if(int($value) < 1);
return "OWTHERM: set $name interval must be >=0" if(int($value) < 0);
#-- update timer
$hash->{INTERVAL} = $value;
$hash->{INTERVAL} = int($value);
if ($init_done) {
RemoveInternalTimer($hash);
@ -427,6 +385,8 @@ sub OWTHERM_FormatValues($) {
} else {
$hash->{ALARM} = 0;
}
main::OWX_Alarms($hash->{IODev})
if( $hash->{ALARM} );
#-- put into READINGS
readingsBeginUpdate($hash);
@ -470,39 +430,12 @@ sub OWTHERM_Get($@) {
return "$name.id => $value";
}
#-- hash of the busmaster
#-- hash of the busmaster
my $master = $hash->{IODev};
#-- Get other values according to interface type
my $interface= $hash->{IODev}->{TYPE};
#-- get present
if($a[1] eq "present" ) {
#-- OWX interface
if( $interface =~ /^OWX/ ){
#-- asynchronous mode
if( $hash->{ASYNC} ){
eval {
OWX_ASYNC_RunToCompletion($hash,OWX_ASYNC_PT_Verify($hash));
};
return GP_Catch($@) if $@;
return "$name.present => ".ReadingsVal($name,"present","unknown");
} else {
$value = OWX_Verify($master,$hash->{ROM_ID});
}
$hash->{PRESENT} = $value;
return "$name.present => $value";
} else {
return "OWTHERM: Verification not yet implemented for interface $interface";
}
}
#-- get interval
if($a[1] eq "interval") {
$value = $hash->{INTERVAL};
return "$name.interval => $value";
}
#-- get version
if( $a[1] eq "version") {
return "$name.version => $owx_version";
@ -510,13 +443,15 @@ sub OWTHERM_Get($@) {
#-- OWX interface
if( $interface eq "OWX" ){
#-- not different from getting all values ..
$ret = OWXTHERM_GetValues($hash);
#-- OWX_ASYNC interface
}elsif( $interface eq "OWX_ASYNC" ){
eval {
$ret = OWX_ASYNC_RunToCompletion($hash,OWXTHERM_PT_GetValues($hash));
};
$ret = GP_Catch($@) if $@;
#-- OWFS interface
}elsif( $interface eq "OWServer" ){
$ret = OWFSTHERM_GetValues($hash);
@ -527,7 +462,8 @@ sub OWTHERM_Get($@) {
#-- process results
if( $master->{ASYNCHRONOUS} ){
return "OWTHERM: $name getting values, please wait for completion";
#return "OWTHERM: $name getting values, please wait for completion";
return undef;
}else{
#-- when we have a return code, we have an error
if( defined($ret) ){
@ -567,19 +503,17 @@ sub OWTHERM_GetValues($@) {
OWTHERM_FormatValues($hash);
}
#-- restart timer for updates
RemoveInternalTimer($hash);
RemoveInternalTimer($hash);
#-- auto-update for device disabled;
return undef
if( $hash->{INTERVAL} == 0 );
#-- restart timer for updates
InternalTimer(time()+$hash->{INTERVAL}, "OWTHERM_GetValues", $hash, 0);
#-- Get values according to interface type
my $interface= $hash->{IODev}->{TYPE};
if( $interface eq "OWX" ){
#-- max 3 tries
for(my $try=0; $try<3; $try++){
$ret = OWXTHERM_GetValues($hash);
last
if( !defined($ret) );
}
$ret = OWXTHERM_GetValues($hash);
}elsif( $interface eq "OWX_ASYNC" ){
#-- skip, if the conversion is driven by master
unless ( defined($attr{$name}{tempConv}) && ( $attr{$name}{tempConv} eq "onkick") ){
@ -597,10 +531,6 @@ sub OWTHERM_GetValues($@) {
#-- process results
if( defined($ret) ){
$hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1;
if( $hash->{ERRCOUNT} > 5 ){
$hash->{INTERVAL} = 9999;
}
return "OWTHERM: Could not get values from device $name for ".$hash->{ERRCOUNT}." times, reason $ret";
}
@ -735,10 +665,11 @@ sub OWTHERM_Set($@) {
#-- set new timer interval
if($key eq "interval") {
# check value
return "OWTHERM: Set with short interval, must be >= 1"
if(int($value) < 1);
# update timer
return OWTHERM_Attr("set",@a);
return "OWTHERM: set $name interval must be >= 0"
if(int($value) < 0);
$hash->{INTERVAL} = int($value);
RemoveInternalTimer($hash);
InternalTimer(gettimeofday()+$hash->{INTERVAL}, "OWTHERM_GetValues", $hash, 0);
}
#-- set tempLow or tempHigh
@ -800,7 +731,7 @@ sub OWTHERM_Set($@) {
#-- process results
$hash->{PRESENT} = 1;
OWTHERM_FormatValues($hash);
#OWTHERM_FormatValues($hash);
Log3 $name, 4, "OWTHERM: Set $hash->{NAME} $key $value";
return undef;
@ -944,30 +875,35 @@ sub OWFSTHERM_SetValues($$) {
sub OWXTHERM_BinValues($$$$$$$) {
my ($hash, $context, $reset, $owx_dev, $crcpart, $numread, $res) = @_;
my ($i,$j,$k,@data,$ow_thn,$ow_tln);
my $change = 0;
#-- hash of the busmaster
my $master = $hash->{IODev};
my $name = $hash->{NAME};
my ($i,$j,$k,@data,$ow_thn,$ow_tln);
my $error = 0;
my $change = 0;
my $msg;
OWX_WDBG($name,"OWTHERM_BinValues called for device $name with ",$res)
if( $main::owx_debug>2 );
OWX_WDBGL($name,5,"OWXTHERM_BinValues called for device $name in context $context with data ",$res);
#-- we have to get rid of the first 10 bytes
if( length($res) == 19 ){
$res=substr($res,10);
}
@data=split(//,$res);
#-- process results
@data=split(//,$res);
if (@data != 9){
$msg="Error - $name returns invalid data length, ".int(@data)." instead of 9 bytes, ";
$error = 1;
$msg = "$name: invalid data length, ".int(@data)." instead of 9 bytes, ";
}elsif(ord($data[7])<=0){
$msg="Error - $name returns invalid data, ";
$error = 1;
$msg = "$name: invalid data, ";
}elsif(OWX_CRC8(substr($res,0,8),$data[8])==0){
$msg="Error - invalid data from device $name, invalid CRC, ";
$error = 1;
$msg = "$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;
};
$msg = "$name: no error, ";
}
OWX_WDBG($name,"OWXTHERM_BinValues: ".$msg,$res)
if( $main::owx_debug>2 );
#-- this must be different for the different device types
# family = 10 => DS1820, DS18S20
@ -975,7 +911,7 @@ sub OWXTHERM_BinValues($$$$$$$) {
my $count_remain = ord($data[6]);
my $count_perc = ord($data[7]);
my $delta = -0.25 + ($count_perc - $count_remain)/$count_perc;
my $delta = ($count_perc != 0)?(-0.25 + ($count_perc - $count_remain)/$count_perc):0;
my $lsb = ord($data[0]);
my $msb = 0;
@ -1014,17 +950,22 @@ sub OWXTHERM_BinValues($$$$$$$) {
$ow_thn = ord($data[2]) > 127 ? 128-ord($data[2]) : ord($data[2]);
$ow_tln = ord($data[3]) > 127 ? 128-ord($data[3]) : ord($data[3]);
} else {
die "OWTHERM: $name: Unknown device family $hash->{OW_FAMILY}\n";
}
}
#-- process alarm settings
$hash->{owg_tl} = $ow_tln;
$hash->{owg_th} = $ow_thn;
OWX_WDBGL($name,5-4*$error,"OWXTHERM_BinValues: ".$msg." ".$hash->{owg_temp}." ",$res);
#-- and now from raw to formatted values
$hash->{PRESENT} = 1;
my $value = OWTHERM_FormatValues($hash);
if( $error ){
$hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1;
}else{
$hash->{PRESENT} = 1;
OWTHERM_FormatValues($hash);
}
return undef;
}
@ -1069,10 +1010,11 @@ sub OWXTHERM_GetValues($) {
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);
#### master slave context proc owx_dev data crcpart numread startread callback delay
OWX_Qomplex($master, $hash, "convert", 5, $owx_dev, "\x44", 0, 1, undef, undef, $convtimes{AttrVal($name,"resolution",12)}*0.001 );
}
}
#-- NOW ask the specific device
#-- issue the match ROM command \x55 and the read scratchpad command \xBE
#-- reading 9 + 1 + 8 data bytes and 1 CRC byte = 19 bytes
@ -1082,16 +1024,14 @@ sub OWXTHERM_GetValues($) {
my $res=OWX_Complex($master,$owx_dev,"\xBE",9);
return "OWTHERM: $name not accessible in reading"
if( $res eq 0 );
return "OWTHERM: $name has returned invalid data"
if( length($res)!=19);
eval {
OWXTHERM_BinValues($hash,undef,$owx_dev,undef,undef,9,substr($res,10,9));
};
return $@ ? $@ : undef;
Log 1,"OWTHERM: $name has returned invalid data of length ".length($res)
if( length($res)!=19);
return OWXTHERM_BinValues($hash,"getsp",$owx_dev,undef,undef,9,substr($res,10,9));
#-- NEW OWX interface
}else{
#### master slave context proc owx_dev data crcpart numread startread callback delay
OWX_Qomplex($master, $hash, undef, 1, $owx_dev, "\xBE", 0, 9, 10, \&OWXTHERM_BinValues, 0.01);
#### master slave context proc owx_dev data crcpart numread startread callback delay
OWX_Qomplex($master, $hash, "readsp", 1, $owx_dev, "\xBE", 0, 19, 0, \&OWXTHERM_BinValues, undef);
return undef;
}
}
@ -1149,8 +1089,8 @@ sub OWXTHERM_SetValues($$) {
}
#-- 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.05);
#### master slave context proc owx_dev data crcpart numread startread callback delay
OWX_Qomplex($master, $hash, "writesp", 0, $owx_dev, $select, 0, 3, 10, undef, undef);
}
return undef;
}
@ -1331,7 +1271,7 @@ sub OWXTHERM_PT_SetValues($$) {
<ul>
<li><a name="owtherm_interval">
<code>set &lt;name&gt; interval &lt;int&gt;</code></a><br /> Temperature
readout interval in seconds. The default is 300 seconds. <b>Attention:</b>This is the
readout interval in seconds. The default is 300 seconds, a value of 0 disables the automatic update. <b>Attention:</b>This is the
readout interval. Whether an actual temperature measurement is performed, is determined by the
tempConv attribute </li>
<li><a name="owtherm_tempHigh">
@ -1350,12 +1290,6 @@ sub OWXTHERM_PT_SetValues($$) {
<li><a name="owtherm_id">
<code>get &lt;name&gt; id</code></a>
<br /> Returns the full 1-Wire device id OW_FAMILY.ROM_ID.CRC </li>
<li><a name="owtherm_present">
<code>get &lt;name&gt; present</code></a>
<br /> Returns 1 if this 1-Wire device is present, otherwise 0. </li>
<li><a name="owtherm_interval2">
<code>get &lt;name&gt; interval</code></a><br />Returns temperature measurement
interval in seconds.</li>
<li><a name="owtherm_temperature">
<code>get &lt;name&gt; temperature</code></a><br />Obtain the temperature. </li>
<li><a name="owtherm_alarm">

View File

@ -10,34 +10,6 @@
#
########################################################################################
#
# define <name> OWVAR [<model>] <ROM_ID> or <FAM_ID>.<ROM_ID>
#
# where <name> may be replaced by any name string
#
# <model> is a 1-Wire device type. If omitted AND no FAM_ID given we assume this to be an
# DS2890 variable resistor
# <FAM_ID> is a 1-Wire family id, currently allowed values are 2C
# <ROM_ID> is a 12 character (6 byte) 1-Wire ROM ID
# without Family ID, e.g. A2D90D000800
#
# get <name> id => FAM_ID.ROM_ID.CRC
# get <name> present => 1 if device present, 0 if not
# get <name> value => query value
# get <name> version => OWX version number
# set <name> value => wiper setting
#
# Additional attributes are defined in fhem.cfg
# attr <name> Name <string>[|<string>] = name for the channel [|name used in state reading]
# attr <name> Unit <string>[|<string>] = unit of measurement for this channel [|unit used in state reading]
# attr <name> Function <string>|<string> = The first string is an arbitrary functional expression f(V) involving the variable V.
# V is replaced by the raw potentiometer reading (in the range of [0,100]). The second string must be the inverse
# function g(U) involving the variable U, such that U can be replaced by the value given in the
# set argument. Care has to taken that g(U) is in the range [0,100].
# No check on the validity of these functions is performed,
# singularities my crash FHEM.
#
########################################################################################
#
# This programm is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
@ -75,12 +47,11 @@ no warnings 'deprecated';
sub Log3($$$);
sub AttrVal($$$);
my $owx_version="6.1";
my $owx_version="7.0";
my $owg_channel = "";
my %gets = (
"id" => "",
"present" => "",
"value" => "",
"version" => ""
);
@ -266,7 +237,7 @@ sub OWVAR_Attr(@) {
if ( $do eq "set") {
ARGUMENT_HANDLER: {
#-- interval modified at runtime
#-- IODev
$key eq "IODev" and do {
AssignIoPort($hash,$value);
if( defined($hash->{IODev}) ) {
@ -407,28 +378,6 @@ sub OWVAR_Get($@) {
#-- Get other values according to interface type
my $interface= $hash->{IODev}->{TYPE};
#-- get present
if($a[1] eq "present" ) {
#-- OWX interface
if( $interface =~ /^OWX/ ){
#-- asynchronous mode
if( $hash->{ASYNC} ){
Log3 $name, 1,"OWVAR: Get ASYNC interface not implemented";
#eval {
# OWX_ASYNC_RunToCompletion($hash,OWX_ASYNC_PT_Verify($hash));
#};
#return GP_Catch($@) if $@;
return "$name.present => ".ReadingsVal($name,"present","unknown");
} else {
$value = OWX_Verify($master,$hash->{ROM_ID});
}
$hash->{PRESENT} = $value;
return "$name.present => $value";
} else {
return "OWVAR: Verification not yet implemented for interface $interface";
}
}
#-- get version
if( $a[1] eq "version") {
return "$name.version => $owx_version";
@ -455,7 +404,8 @@ sub OWVAR_Get($@) {
}
#-- process results
if( $master->{ASYNCHRONOUS} ){
return "OWVAR: $name getting value, please wait for completion";
#return "OWVAR: $name getting value, please wait for completion";
return undef;
}else{
#-- when we have a return code, we have an error
if( defined($ret) ){
@ -493,19 +443,10 @@ sub OWVAR_GetValues($@) {
OWVAR_FormatValues($hash);
}
#-- restart timer for updates
RemoveInternalTimer($hash);
#InternalTimer(time()+$hash->{INTERVAL}, "OWVAR_GetValues", $hash, 0);
#-- Get values according to interface type
my $interface= $hash->{IODev}->{TYPE};
if( $interface eq "OWX" ){
#-- max 3 tries
for(my $try=0; $try<3; $try++){
$ret = OWXVAR_GetValues($hash);
last
if( !defined($ret) );
}
$ret = OWXVAR_GetValues($hash);
}elsif( $interface eq "OWX_ASYNC" ){
Log3 $name, 1,"OWVAR: Get ASYNC interface not implemented";
}elsif( $interface eq "OWServer" ){
@ -518,9 +459,6 @@ sub OWVAR_GetValues($@) {
#-- process results
if( defined($ret) ){
$hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1;
if( $hash->{ERRCOUNT} > 5 ){
$hash->{INTERVAL} = 9999;
}
return "OWVAR: Could not get values from device $name for ".$hash->{ERRCOUNT}." times, reason $ret";
}
@ -747,59 +685,93 @@ sub OWFSVAR_SetValues($$$) {
sub OWXVAR_BinValues($$$$$$$) {
my ($hash, $context, $reset, $owx_dev, $crcpart, $numread, $res) = @_;
my ($i,$j,$k,@data);
my $change = 0;
my $master = $hash->{IODev};
my $name = $hash->{NAME};
my $error = 0;
my ($i,$j,$k,@data);
my $change = 0;
my $msg;
OWX_WDBG($name,"OWVAR: $name: BinValues called with ",$res)
if( $main::owx_debug>2 );
OWX_WDBGL($name,4,"OWXVAR_BinValues called for device $name in context $context with data ",$res);
#-- process results
#die "OWVAR: $name not accessible in 2nd step" unless ( defined $res and $res ne 0 );
if( $context eq "getstate" ) {
#-- process results
@data=split(//,$res);
if (@data != 2) {
$msg="Error- $name returns invalid data length, ".int(@data)." instead of 2 bytes ";
}else{
$msg="No error";
my $stat = ord($data[0]);
my $val = ord($data[1]);
$hash->{owg_val}=sprintf("%5.2f",(1.0-$val/255.0)*100);
#-- and now from raw to formatted values
$hash->{PRESENT} = 1;
my $value = OWVAR_FormatValues($hash);
#Log3 $hash->{NAME}, 5, $value;
#-- process results
if( $context eq "setstate" ) {
#-- we have to get rid of the first 10 bytes
if( length($res) == 11 ){
$res=substr($res,10);
}
OWX_WDBG($name,"OWXVAR_BinValues: ".$msg,$res)
if( $main::owx_debug>2 );
return undef;
#--- obsolete code - we have put all operations into the SetValues part. Leave in for now
}elsif( $context eq "setstate" ) {
my $val = ord($res);
#$hash->{owg_val}=sprintf("%5.2f",(1-$val/255.0)*100);
#-- process results
if (length($res) != 1){
$msg="$name returns invalid data length, ".length($res)." instead of 1 bytes, ";
}elsif($val ne $crcpart){
$msg="$name returns invalid data $val instead of $crcpart, "
if( length($res) != 1 ) {
$error = 1;
$msg = "$name: invalid data length, ".length($res)." instead of 1 bytes ";
}elsif( $res ne $crcpart ){
$error = 1;
$msg = "$name: invalid data ";
}else{
$msg="No error, val = $val";
$msg = "$name: no error, ";
}
OWX_WDBGL($name,5-4*$error,"OWXVAR_BinValues setstate: ".$msg,$res);
#-- increase error count
if( $error ){
$hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1;
}else{
#### master slave context proc owx_dev data crcpart numread startread callback delay
OWX_Qomplex($master, $hash, "release", 18, $owx_dev, "\x96", 0, 11, 0, \&OWXVAR_BinValues, 0.01);
}
#------------------------------------------------------------------
}elsif( $context eq "release" ) {
#-- we have to get rid of the first 10 bytes
if( length($res) == 11 ){
$res=substr($res,10);
}
if( length($res) != 1 ) {
$error = 1;
$msg = "$name: invalid data length, ".length($res)." instead of 1 bytes ";
}elsif( $res ne "\x96" ){
$error = 1;
$msg = "$name: invalid data ";
}else{
$msg = "$name: no error, ";
}
OWX_WDBGL($name,5-4*$error,"OWXVAR_BinValues release : ".$msg,$res);
#-- increase error count
if( $error ){
$hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1;
}
#------------------------------------------------------------------
}elsif( $context eq "getstate" ) {
#-- we have to get rid of the first 10 bytes
if( length($res) == 12 ){
$res=substr($res,10);
}
@data=split(//,$res);
#-- process results
if (@data != 2) {
$error = 1;
$msg = "$name: invalid data length, ".int(@data)." instead of 2 bytes ";
}else{
$msg = "$name: no error, ";
}
OWX_WDBGL($name,5-4*$error,"OWXVAR_BinValues getstate: ".$msg,$res);
my $stat = ord($data[0]);
my $val = ord($data[1]);
$hash->{owg_val}=sprintf("%5.2f",(1.0-$val/255.0)*100);
#-- and now from raw to formatted values
$hash->{PRESENT} = 1;
if ( !$error ){
my $value = OWVAR_FormatValues($hash)
}else{
$hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1;
}
OWX_WDBG($name,"OWXVAR_BinValues: ".$msg,$res)
if( $main::owx_debug>2 );
#### master slave context proc owx_dev data crcpart numread startread callback delay
# 2 suppresses the initial bus reset, 16 inserts at top of queue
#OWX_Qomplex($master, $hash, "confirm", 18, $owx_dev, "\x96", 0, 2, 11, undef, 0.01);
return undef;
}
return undef;
}
########################################################################################
@ -832,14 +804,12 @@ sub OWXVAR_GetValues($) {
return "OWVAR: $name has returned invalid data"
if( length($res)!=12);
OWX_Reset($master);
eval {
OWXVAR_BinValues($hash,"getstate",0,$owx_dev,0,2,substr($res,10,2));
};
return $@ ? $@ : undef;
return OWXVAR_BinValues($hash,"getstate",0,$owx_dev,0,2,substr($res,10,2));
#-- NEW OWX interface
}else{
#### master slave context proc owx_dev data crcpart numread startread callback delay
OWX_Qomplex($master, $hash, "getstate", 0, $owx_dev, "\xF0", 0, 2, 10, \&OWXVAR_BinValues, 0.01);
OWX_Qomplex($master, $hash, "getstate", 0, $owx_dev, "\xF0", 0, 12, 0, \&OWXVAR_BinValues, undef);
return undef;
}
}
@ -889,9 +859,8 @@ sub OWXVAR_SetValues($$$) {
$hash->{owg_val}=sprintf("%5.2f",(1-$pos/255.0)*100);
#-- NEW OWX interface
}else{
#### master slave context proc owx_dev data crcpart numread startread callback delay
OWX_Qomplex($master, $hash, "setstate", 0, $owx_dev, $select, 0, 1, 0, undef, 0);
OWX_Qomplex($master, $hash, "confirm", 3, $owx_dev, "\x96", 0, 1, 0, undef, 0);
#### master slave context proc owx_dev data crcpart numread startread callback delay
OWX_Qomplex($master, $hash, "setstate", 0, $owx_dev, $select, substr($select,1), 11, 0, \&OWXVAR_BinValues, 0.1);
$hash->{owg_val}=sprintf("%5.2f",(1-$pos/255.0)*100);
}
return undef;
@ -951,11 +920,6 @@ sub OWXVAR_SetValues($$$) {
<li><a name="owvar_id">
<code>get &lt;name&gt; id</code></a>
<br /> Returns the full 1-Wire device id OW_FAMILY.ROM_ID.CRC </li>
<li><a name="owvar_present">
<code>get &lt;name&gt; present</code></a>
<br /> Returns 1 if this 1-Wire device is present, otherwise 0. </li>
<li><a name="owvar_value2">
<code>get &lt;name&gt; value</code></a><br />Obtain the value. </li>
</ul>
<br />
<a name="OWVARattr"></a>