mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-07 12:58:13 +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:
parent
15cb46808f
commit
fc6db34218
@ -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";
|
||||||
@ -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} : "▾";
|
my $stateal1 = defined($attr{$name}{stateAL1}) ? $attr{$name}{stateAL1} : "↓";
|
||||||
my $stateah1 = defined($attr{$name}{stateAH1}) ? $attr{$name}{stateAH1} : "▴";
|
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,7 +629,10 @@ sub OWAD_Get($@) {
|
|||||||
return "OWAD: Get with wrong IODev type $interface";
|
return "OWAD: Get with wrong IODev type $interface";
|
||||||
}
|
}
|
||||||
|
|
||||||
#-- process results
|
#-- process result
|
||||||
|
if( $master->{ASYNCHRONOUS} ){
|
||||||
|
return "OWAD: $name getting reading, please wait for completion";
|
||||||
|
}else{
|
||||||
if( defined($ret) ){
|
if( defined($ret) ){
|
||||||
$hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1;
|
$hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1;
|
||||||
if( $hash->{ERRCOUNT} > 5 ){
|
if( $hash->{ERRCOUNT} > 5 ){
|
||||||
@ -652,7 +642,7 @@ sub OWAD_Get($@) {
|
|||||||
}
|
}
|
||||||
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,7 +661,10 @@ sub OWAD_Get($@) {
|
|||||||
return "OWAD: Get with wrong IODev type $interface";
|
return "OWAD: Get with wrong IODev type $interface";
|
||||||
}
|
}
|
||||||
|
|
||||||
#-- process results
|
#-- process result
|
||||||
|
if( $master->{ASYNCHRONOUS} ){
|
||||||
|
return "OWAD: $name getting alarm values, please wait for completion";
|
||||||
|
}else{
|
||||||
if( defined($ret) ){
|
if( defined($ret) ){
|
||||||
$hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1;
|
$hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1;
|
||||||
if( $hash->{ERRCOUNT} > 5 ){
|
if( $hash->{ERRCOUNT} > 5 ){
|
||||||
@ -689,6 +682,7 @@ sub OWAD_Get($@) {
|
|||||||
}
|
}
|
||||||
return "OWAD: $name.alarm => $value";
|
return "OWAD: $name.alarm => $value";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#-- get status values according to interface type
|
#-- get status values according to interface type
|
||||||
if($a[1] eq "status") {
|
if($a[1] eq "status") {
|
||||||
@ -708,7 +702,10 @@ sub OWAD_Get($@) {
|
|||||||
return "OWAD: Get with wrong IODev type $interface";
|
return "OWAD: Get with wrong IODev type $interface";
|
||||||
}
|
}
|
||||||
|
|
||||||
#-- process results
|
#-- process result
|
||||||
|
if( $master->{ASYNCHRONOUS} ){
|
||||||
|
return "OWAD: $name getting status, please wait for completion";
|
||||||
|
}else{
|
||||||
if( defined($ret) ){
|
if( defined($ret) ){
|
||||||
$hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1;
|
$hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1;
|
||||||
if( $hash->{ERRCOUNT} > 5 ){
|
if( $hash->{ERRCOUNT} > 5 ){
|
||||||
@ -751,6 +748,7 @@ sub OWAD_Get($@) {
|
|||||||
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) = @_;
|
||||||
|
|
||||||
|
#-- hash of the busmaster
|
||||||
|
my $master = $hash->{IODev};
|
||||||
|
my $name = $hash->{NAME};
|
||||||
|
my @data=[];
|
||||||
|
my $value;
|
||||||
|
my $msg;
|
||||||
|
OWX_WDBG($name,"OWXAD_BinValues called for device $name in context $context with ",$res)
|
||||||
|
if( $main::owx_debug>2 );
|
||||||
|
|
||||||
#-- always check for success, unused are reset
|
|
||||||
return unless ($success and $context);
|
|
||||||
#Log 1,"OWXAD_BinValues context = $context";
|
|
||||||
my $final = ($context =~ /\.final$/ );
|
my $final = ($context =~ /\.final$/ );
|
||||||
|
my ($ow_thn,$ow_tln);
|
||||||
my ($i,$j,$k,@data,$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,6 +1484,8 @@ 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" : "");
|
||||||
|
#-- OLD OWX interface
|
||||||
|
if( !$master->{ASYNCHRONOUS} ){
|
||||||
#-- reset the bus
|
#-- reset the bus
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
#-- reading 9 + 3 + 8 data bytes and 2 CRC bytes = 22 bytes
|
#-- reading 9 + 3 + 8 data bytes and 2 CRC bytes = 22 bytes
|
||||||
@ -1474,7 +1495,14 @@ sub OWXAD_GetPage($$$@) {
|
|||||||
return "$owx_dev has returned invalid data"
|
return "$owx_dev has returned invalid data"
|
||||||
if( length($res)!=22);
|
if( length($res)!=22);
|
||||||
#-- for processing we also need the 3 command bytes
|
#-- for processing we also need the 3 command bytes
|
||||||
return OWXAD_BinValues($hash,$context,1,undef,$owx_dev,$select,10,substr($res,12,10));
|
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";
|
||||||
}
|
}
|
||||||
|
#-- OLD OWX interface
|
||||||
|
if( !$master->{ASYNCHRONOUS} ){
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
$res=OWX_Complex($master,$owx_dev,$select,0);
|
$res=OWX_Complex($master,$owx_dev,$select,0);
|
||||||
if( $res eq 0 ){
|
if( $res eq 0 ){
|
||||||
return "device $owx_dev not accessible for writing";
|
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 <name> stateAH0 <string></code></a>
|
<li><a name="owad_stateAH0"><code>attr <name> stateAH0 <string></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 <name> stateAL1 <string></code></a>
|
<li><a name="owad_stateAL1"><code>attr <name> stateAL1 <string></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 &#x25BE; leading to the sign ▾</li>
|
|
||||||
<li><a name="owad_stateAH1"><code>attr <name> stateAH1 <string></code></a>
|
<li><a name="owad_stateAH1"><code>attr <name> stateAH1 <string></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 &#x25B4; leading to the sign ▴ </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 <name> <channel>Name
|
<li><a name="owad_cname"><code>attr <name> <channel>Name
|
||||||
<string>[|<string>]</code></a>
|
<string>[|<string>]</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 <name> <channel>Unit
|
<li><a name="owad_cunit"><code>attr <name> <channel>Unit
|
||||||
<string>[|<string>]</code></a>
|
<string></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 <name> <channel>Offset
|
|
||||||
<float></code></a>
|
|
||||||
<br />offset added to the reading in this channel. </li>
|
|
||||||
<li><a name="owad_cfactor"><b>deprecated</b>: <code>attr <name> <channel>Factor
|
|
||||||
<float></code></a>
|
|
||||||
<br />factor multiplied to (reading+offset) in this channel. </li>
|
|
||||||
<li><a name="owad_cfunction"> <code>attr <name> <channel>Function
|
<li><a name="owad_cfunction"> <code>attr <name> <channel>Function
|
||||||
<string></code></a>
|
<string></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 <name> <channel>Alarm
|
<li><a name="owad_calarm"><code>attr <name> <channel>Alarm
|
||||||
<string></code></a>
|
<string></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 <name> <channel>Low
|
<li><a name="owad_clow"><code>attr <name> <channel>Low
|
||||||
<float></code></a>
|
<float></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 <name> <channel>High
|
<li><a name="owad_chigh"><code>attr <name> <channel>High
|
||||||
<float></code></a>
|
<float></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
|
||||||
|
@ -44,9 +44,9 @@
|
|||||||
# attr <name> LogM <string> = device name (not file name) of monthly log file
|
# attr <name> LogM <string> = device name (not file name) of monthly log file
|
||||||
# attr <name> LogY <string> = device name (not file name) of yearly log file
|
# attr <name> LogY <string> = device name (not file name) of yearly log file
|
||||||
# attr <name> nomemory = 1|0 (when set to 1, disables use of internal memory)
|
# attr <name> nomemory = 1|0 (when set to 1, disables use of internal memory)
|
||||||
# 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 [|short 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 used in state reading (default cts, none for empty)
|
||||||
# attr <name> <channel>Rate <string>[|<string>] = name for the channel rate [|name used in state reading]
|
# attr <name> <channel>Rate <string>[|<string>] = name for the channel rate [|short name used in state reading]
|
||||||
# attr <name> <channel>Offset <float> = offset added to the reading in this channel
|
# 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>Factor <float> = factor multiplied to (reading+offset) in this channel
|
||||||
# attr <name> <channel>Mode <string> = counting mode = normal(default) or daily
|
# attr <name> <channel>Mode <string> = counting mode = normal(default) or daily
|
||||||
@ -99,11 +99,13 @@ no warnings 'deprecated';
|
|||||||
|
|
||||||
sub Log3($$$);
|
sub Log3($$$);
|
||||||
|
|
||||||
my $owx_version="5.33";
|
my $owx_version="6.0";
|
||||||
#-- fixed raw channel name, flexible channel name
|
#-- fixed raw channel name, flexible channel name
|
||||||
my @owg_fixed = ("A","B");
|
my @owg_fixed = ("A","B");
|
||||||
my @owg_channel = ("A","B");
|
my @owg_channel = ("A","B");
|
||||||
my @owg_rate = ("A_rate","B_rate");
|
my @owg_rate = ("A_rate","B_rate");
|
||||||
|
#-- initially assume that both memory types (low, high) are present
|
||||||
|
my @owg_memory = (1,1,0);
|
||||||
|
|
||||||
my %gets = (
|
my %gets = (
|
||||||
"id" => "",
|
"id" => "",
|
||||||
@ -229,13 +231,16 @@ sub OWCOUNT_Define ($$) {
|
|||||||
if( $model eq "DS2423" ){
|
if( $model eq "DS2423" ){
|
||||||
$fam = "1D";
|
$fam = "1D";
|
||||||
CommandAttr (undef,"$name model DS2423");
|
CommandAttr (undef,"$name model DS2423");
|
||||||
|
@owg_memory = (1,1,0);
|
||||||
}elsif( $model eq "DS2423enew" ){
|
}elsif( $model eq "DS2423enew" ){
|
||||||
$fam = "1D";
|
$fam = "1D";
|
||||||
|
@owg_memory = (1,1,0);
|
||||||
CommandAttr (undef,"$name model DS2423enew");
|
CommandAttr (undef,"$name model DS2423enew");
|
||||||
}elsif( $model eq "DS2423eold" ){
|
}elsif( $model eq "DS2423eold" ){
|
||||||
$fam = "1D";
|
$fam = "1D";
|
||||||
CommandAttr (undef,"$name model DS2423eold");
|
CommandAttr (undef,"$name model DS2423eold");
|
||||||
CommandAttr (undef,"$name nomemory 1");
|
CommandAttr (undef,"$name nomemory 1");
|
||||||
|
@owg_memory = (0,0,0);
|
||||||
}else{
|
}else{
|
||||||
return "OWCOUNT: Wrong 1-Wire device model $model";
|
return "OWCOUNT: Wrong 1-Wire device model $model";
|
||||||
}
|
}
|
||||||
@ -301,12 +306,61 @@ sub OWCOUNT_Notify ($$) {
|
|||||||
|
|
||||||
sub OWCOUNT_Init ($) {
|
sub OWCOUNT_Init ($) {
|
||||||
my ($hash)=@_;
|
my ($hash)=@_;
|
||||||
|
|
||||||
#-- Start timer for updates
|
#-- Start timer for updates
|
||||||
RemoveInternalTimer($hash);
|
RemoveInternalTimer($hash);
|
||||||
InternalTimer(gettimeofday()+10, "OWCOUNT_GetValues", $hash, 0);
|
InternalTimer(gettimeofday()+10, "OWCOUNT_GetValues", $hash, 0);
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
########################################################################################
|
||||||
|
#
|
||||||
|
# OWCOUNT_InitializeDevice - delayed setting of initial readings and channel names
|
||||||
|
#
|
||||||
|
# Parameter hash = hash of device addressed
|
||||||
|
#
|
||||||
|
########################################################################################
|
||||||
|
|
||||||
|
sub OWCOUNT_InitializeDevice($) {
|
||||||
|
my ($hash) = @_;
|
||||||
|
|
||||||
|
my $name = $hash->{NAME};
|
||||||
|
#-- get memory page/counter according to interface type
|
||||||
|
my $master= $hash->{IODev};
|
||||||
|
my $interface= $hash->{IODev}->{TYPE};
|
||||||
|
|
||||||
|
my $olddata = "";
|
||||||
|
my ($olddata1,$olddata2);
|
||||||
|
my $newdata = "OWCOUNT ".$owx_version;
|
||||||
|
my $ret;
|
||||||
|
|
||||||
|
#-- initial values
|
||||||
|
for( my $i=0;$i<int(@owg_fixed);$i++) {
|
||||||
|
#-- initial readings
|
||||||
|
$hash->{owg_val}->[$i] = "";
|
||||||
|
$hash->{owg_midnight}->[$i] = "";
|
||||||
|
$hash->{owg_str}->[$i] = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
#-- Check memory string
|
||||||
|
my $memory;
|
||||||
|
if( ($owg_memory[0]==1) && ($owg_memory[1]==1) ){
|
||||||
|
$memory="page 0..13 and midnight";
|
||||||
|
}elsif( ($owg_memory[0]==0) && ($owg_memory[1]==1) ){
|
||||||
|
$memory="midnight only";
|
||||||
|
}elsif( ($owg_memory[0]==1) && ($owg_memory[1]==0) ){
|
||||||
|
$memory="page 0..13 only";
|
||||||
|
}else{
|
||||||
|
$memory="no pages, no midnight";
|
||||||
|
}
|
||||||
|
readingsSingleUpdate($hash,"memory","$memory",0);
|
||||||
|
|
||||||
|
#-- Set state to initialized
|
||||||
|
readingsSingleUpdate($hash,"state","initialized",1);
|
||||||
|
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
#######################################################################################
|
#######################################################################################
|
||||||
#
|
#
|
||||||
# OWCOUNT_Attr - Set one attribute value for device
|
# OWCOUNT_Attr - Set one attribute value for device
|
||||||
@ -369,56 +423,56 @@ sub OWCOUNT_ChannelNames($) {
|
|||||||
|
|
||||||
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]);
|
||||||
}
|
}
|
||||||
#-- unit
|
#-- unit
|
||||||
$unit = defined($attr{$name}{$owg_fixed[$i]."Unit"}) ? $attr{$name}{$owg_fixed[$i]."Unit"} : "counts|cts";
|
$unit = defined($attr{$name}{$owg_fixed[$i]."Unit"}) ? $attr{$name}{$owg_fixed[$i]."Unit"} : "cts";
|
||||||
@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
|
||||||
$owg_channel[$i]=$cnama[0];
|
$owg_channel[$i]=$cnama[0];
|
||||||
$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];
|
|
||||||
|
|
||||||
$period = defined($attr{$name}{$owg_fixed[$i]."Period"}) ? $attr{$name}{$owg_fixed[$i]."Period"} : "hour";
|
$period = defined($attr{$name}{$owg_fixed[$i]."Period"}) ? $attr{$name}{$owg_fixed[$i]."Period"} : "hour";
|
||||||
#-- put into readings
|
#-- put into readings
|
||||||
$hash->{READINGS}{$owg_channel[$i]}{PERIOD} = $period;
|
$hash->{READINGS}{$owg_channel[$i]}{PERIOD} = $period;
|
||||||
|
|
||||||
#-- rate
|
#-- rate
|
||||||
$cname = defined($attr{$name}{$owg_fixed[$i]."Rate"}) ? $attr{$name}{$owg_fixed[$i]."Rate"} : $cnama[0]."_rate|".$cnama[1]."_rate";
|
$cname = defined($attr{$name}{$owg_fixed[$i]."Rate"}) ? $attr{$name}{$owg_fixed[$i]."Rate"} :
|
||||||
|
(defined($attr{$name}{$owg_fixed[$i]."Name"}) ? "$cnama[0]_rate|$cnama[1]_r" : "$owg_fixed[$i]_rate|$owg_fixed[$i]_r");
|
||||||
@cnama = split(/\|/,$cname);
|
@cnama = split(/\|/,$cname);
|
||||||
if( int(@cnama)!=2){
|
if( int(@cnama)!=2){
|
||||||
push(@cnama,$cnama[0]);
|
push(@cnama,$cnama[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#-- rate unit
|
#-- rate unit
|
||||||
my $runit = "";
|
if( $unit ne " " ){
|
||||||
if( $period eq "hour" ){
|
if( $period eq "hour" ){
|
||||||
$runit = "/h";
|
$unit .= "/h";
|
||||||
}elsif( $period eq "minute" ){
|
}elsif( $period eq "minute" ){
|
||||||
$runit = "/min";
|
$unit .= "/min";
|
||||||
} else {
|
} else {
|
||||||
$runit = "/s";
|
$unit .= "/s";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#-- put into readings
|
|
||||||
$owg_rate[$i]=$cnama[0];
|
|
||||||
$hash->{READINGS}{$owg_rate[$i]}{ABBR} = $cnama[1];
|
|
||||||
$hash->{READINGS}{$owg_rate[$i]}{UNIT} = $unarr[0].$runit;
|
|
||||||
$hash->{READINGS}{$owg_rate[$i]}{UNITABBR} = $unarr[1].$runit;
|
|
||||||
|
|
||||||
#-- some special cases
|
#-- some special cases
|
||||||
# Energy/Power
|
# Energy/Power
|
||||||
$hash->{READINGS}{$owg_rate[$i]}{UNIT} = "kW"
|
$unit = " kW"
|
||||||
if ($unarr[0].$runit eq "kWh/h" );
|
if ($unit eq " kWh/h" );
|
||||||
$hash->{READINGS}{$owg_rate[$i]}{UNITABBR} = "kW"
|
|
||||||
if ($unarr[1].$runit eq "kWh/h" );
|
#-- put into readings
|
||||||
|
$owg_rate[$i]=$cnama[0];
|
||||||
|
$hash->{READINGS}{$owg_rate[$i]}{ABBR} = $cnama[1];
|
||||||
|
$hash->{READINGS}{$owg_rate[$i]}{UNIT} = $unit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -467,9 +521,34 @@ sub OWCOUNT_FormatValues($) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#-- put into READINGS
|
#-- put into READING
|
||||||
readingsBeginUpdate($hash);
|
readingsBeginUpdate($hash);
|
||||||
|
|
||||||
|
#-- Check memory string
|
||||||
|
if( $owg_memory[2]==1 ){
|
||||||
|
my $memory;
|
||||||
|
my $model = $hash->{OW_MODEL};
|
||||||
|
my $nomemory;
|
||||||
|
|
||||||
|
if( ($owg_memory[0]==1) && ($owg_memory[1]==1) ){
|
||||||
|
$memory = "page 0..13 and midnight";
|
||||||
|
$model = "DS2423";
|
||||||
|
$nomemory = 0;
|
||||||
|
}elsif( ($owg_memory[0]==0) && ($owg_memory[1]==1) ){
|
||||||
|
$memory="midnight only";
|
||||||
|
$model = "DS2423enew";
|
||||||
|
$nomemory = 0;
|
||||||
|
}else{
|
||||||
|
$memory="no pages, no midnight";
|
||||||
|
$model = "DS2423eold";
|
||||||
|
$nomemory = 1;
|
||||||
|
}
|
||||||
|
CommandAttr (undef,"$name model ".$model);
|
||||||
|
CommandAttr (undef,"$name nomemory ".$nomemory);
|
||||||
|
readingsBulkUpdate($hash,"memory","$memory");
|
||||||
|
$owg_memory[2]=0;
|
||||||
|
}
|
||||||
|
|
||||||
#-- formats for output
|
#-- formats for output
|
||||||
for (my $i=0;$i<int(@owg_fixed);$i++){
|
for (my $i=0;$i<int(@owg_fixed);$i++){
|
||||||
|
|
||||||
@ -489,13 +568,13 @@ sub OWCOUNT_FormatValues($) {
|
|||||||
$hash->{READINGS}{$owg_channel[$i]}{OFFSET} = $offset;
|
$hash->{READINGS}{$owg_channel[$i]}{OFFSET} = $offset;
|
||||||
$hash->{READINGS}{$owg_channel[$i]}{FACTOR} = $factor;
|
$hash->{READINGS}{$owg_channel[$i]}{FACTOR} = $factor;
|
||||||
|
|
||||||
$unit = $hash->{READINGS}{$owg_channel[$i]}{UNITABBR};
|
$unit = $hash->{READINGS}{$owg_channel[$i]}{UNIT};
|
||||||
$period = $hash->{READINGS}{$owg_channel[$i]}{PERIOD};
|
$period = $hash->{READINGS}{$owg_channel[$i]}{PERIOD};
|
||||||
$runit = $hash->{READINGS}{$owg_rate[$i]}{UNITABBR};
|
$runit = $hash->{READINGS}{$owg_rate[$i]}{UNIT};
|
||||||
|
|
||||||
#-- skip some things if undefined
|
#-- skip some things if undefined
|
||||||
if( $hash->{owg_val}->[$i] eq ""){
|
if( $hash->{owg_val}->[$i] eq ""){
|
||||||
$svalue .= $owg_channel[$i].": ???";
|
$svalue .= $owg_channel[$i]." ???";
|
||||||
}else{
|
}else{
|
||||||
#-- only if attribute value mode=daily, take the midnight value from memory
|
#-- only if attribute value mode=daily, take the midnight value from memory
|
||||||
if( $daily == 1){
|
if( $daily == 1){
|
||||||
@ -555,6 +634,7 @@ sub OWCOUNT_FormatValues($) {
|
|||||||
my $msg = sprintf("%4d-%02d-%02d midnight %7.2f",
|
my $msg = sprintf("%4d-%02d-%02d midnight %7.2f",
|
||||||
$year+1900,$month+1,$day,$dval2);
|
$year+1900,$month+1,$day,$dval2);
|
||||||
OWCOUNT_SetPage($hash,14+$i,$msg);
|
OWCOUNT_SetPage($hash,14+$i,$msg);
|
||||||
|
Log3 $name,5,"OWCOUNT: measured value $vval (midnight ".$hash->{owg_midnight}->[$i].") => new extrapolated midnight $dval2";
|
||||||
|
|
||||||
#-- string buildup for monthly and yearly logging
|
#-- string buildup for monthly and yearly logging
|
||||||
$dvalue .= sprintf( " %s: %5.2f %s %sM: %%5.2f %s", $owg_channel[$i],$dval,$unit,$owg_channel[$i],$unit);
|
$dvalue .= sprintf( " %s: %5.2f %s %sM: %%5.2f %s", $owg_channel[$i],$dval,$unit,$owg_channel[$i],$unit);
|
||||||
@ -585,7 +665,7 @@ sub OWCOUNT_FormatValues($) {
|
|||||||
#-- put in monthly and yearly sums
|
#-- put in monthly and yearly sums
|
||||||
if( int(@monthv) == 2 ){
|
if( int(@monthv) == 2 ){
|
||||||
$total0 = $monthv[0]->[1];
|
$total0 = $monthv[0]->[1];
|
||||||
$total1 = $monthv[1]->[1];
|
$total1 = ($day==1)?$total0:$monthv[1]->[1];
|
||||||
$dvalue = sprintf("D%02d ",$day).$dvalue;
|
$dvalue = sprintf("D%02d ",$day).$dvalue;
|
||||||
$dvalue = sprintf($dvalue,$total0,$total1);
|
$dvalue = sprintf($dvalue,$total0,$total1);
|
||||||
readingsBulkUpdate($hash,"day",$dvalue);
|
readingsBulkUpdate($hash,"day",$dvalue);
|
||||||
@ -597,7 +677,7 @@ sub OWCOUNT_FormatValues($) {
|
|||||||
|
|
||||||
if( int(@yearv) == 2 ){
|
if( int(@yearv) == 2 ){
|
||||||
$total2 = $yearv[0]->[1];
|
$total2 = $yearv[0]->[1];
|
||||||
$total3 = $yearv[1]->[1];
|
$total3 = ($month==0)?$total2: $yearv[1]->[1];
|
||||||
if ( $monthbreak == 1){
|
if ( $monthbreak == 1){
|
||||||
$mvalue = sprintf("M%02d ",$month+1).$mvalue;
|
$mvalue = sprintf("M%02d ",$month+1).$mvalue;
|
||||||
$mvalue = sprintf($mvalue,$total0,$total2,$total1,$total3);
|
$mvalue = sprintf($mvalue,$total0,$total2,$total1,$total3);
|
||||||
@ -631,6 +711,7 @@ sub OWCOUNT_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 $master = $hash->{IODev};
|
||||||
my $value = undef;
|
my $value = undef;
|
||||||
my $ret = "";
|
my $ret = "";
|
||||||
my $page;
|
my $page;
|
||||||
@ -655,18 +736,20 @@ sub OWCOUNT_Get($@) {
|
|||||||
if($a[1] eq "present") {
|
if($a[1] eq "present") {
|
||||||
#-- hash of the busmaster
|
#-- hash of the busmaster
|
||||||
my $master = $hash->{IODev};
|
my $master = $hash->{IODev};
|
||||||
#-- asynchronous mode
|
|
||||||
if( $hash->{ASYNC} ){
|
#-- normal OWX
|
||||||
|
if( !$hash->{ASYNC} ){
|
||||||
|
$value = OWX_Verify($master,$hash->{ROM_ID});
|
||||||
|
$hash->{PRESENT} = $value;
|
||||||
|
return "$name.present => $value";
|
||||||
|
#-- old asynchronous mode
|
||||||
|
}else{
|
||||||
eval {
|
eval {
|
||||||
OWX_ASYNC_RunToCompletion($hash,OWX_ASYNC_PT_Verify($hash));
|
OWX_ASYNC_RunToCompletion($hash,OWX_ASYNC_PT_Verify($hash));
|
||||||
};
|
};
|
||||||
return GP_Catch($@) if $@;
|
return GP_Catch($@) if $@;
|
||||||
return "$name.present => ".ReadingsVal($name,"present","unknown");
|
return "$name.present => ".ReadingsVal($name,"present","unknown");
|
||||||
} else {
|
|
||||||
$value = OWX_Verify($master,$hash->{ROM_ID});
|
|
||||||
}
|
}
|
||||||
$hash->{PRESENT} = $value;
|
|
||||||
return "$name.present => $value";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#-- get interval
|
#-- get interval
|
||||||
@ -733,7 +816,7 @@ sub OWCOUNT_Get($@) {
|
|||||||
$value .= $owg_channel[$i]."Y: ".$year2[$i]->[1]." ".$unit.
|
$value .= $owg_channel[$i]."Y: ".$year2[$i]->[1]." ".$unit.
|
||||||
" (yearly sum until now, average ".$year2[$i]->[2]." ".$unit."/d)\n";
|
" (yearly sum until now, average ".$year2[$i]->[2]." ".$unit."/d)\n";
|
||||||
}else{
|
}else{
|
||||||
$value .= $owg_channel[$i]."Y: ".$year2[$i]->[1]." ".$unit." (last month)\n";
|
$value .= $owg_channel[$i]."Y: ".$year2[$i]->[1]." ".$unit."\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $value;
|
return $value;
|
||||||
@ -754,6 +837,10 @@ sub OWCOUNT_Get($@) {
|
|||||||
return "OWCOUNT: Wrong memory page requested";
|
return "OWCOUNT: Wrong memory page requested";
|
||||||
}
|
}
|
||||||
$ret = OWCOUNT_GetPage($hash,$page,1,1);
|
$ret = OWCOUNT_GetPage($hash,$page,1,1);
|
||||||
|
#-- process result
|
||||||
|
if( $master->{ASYNCHRONOUS} ){
|
||||||
|
return "OWCOUNT: $name getting memory $page, please wait for completion";
|
||||||
|
}else{
|
||||||
#-- when we have a return code, we have an error
|
#-- when we have a return code, we have an error
|
||||||
if( $ret ){
|
if( $ret ){
|
||||||
return "OWCOUNT: Could not get values from device $name, reason: ".$ret;
|
return "OWCOUNT: Could not get values from device $name, reason: ".$ret;
|
||||||
@ -761,6 +848,7 @@ sub OWCOUNT_Get($@) {
|
|||||||
return "OWCOUNT: $name.$reading [$page] =>".$hash->{owg_str}->[$page];
|
return "OWCOUNT: $name.$reading [$page] =>".$hash->{owg_str}->[$page];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if( $reading eq "midnight" ){
|
if( $reading eq "midnight" ){
|
||||||
return "OWCOUNT: get needs parameter when reading midnight: <channel>"
|
return "OWCOUNT: get needs parameter when reading midnight: <channel>"
|
||||||
if( int(@a)<3 );
|
if( int(@a)<3 );
|
||||||
@ -773,6 +861,10 @@ sub OWCOUNT_Get($@) {
|
|||||||
return "OWCOUNT: Invalid midnight counter address, must be A, B or defined channel name"
|
return "OWCOUNT: Invalid midnight counter address, must be A, B or defined channel name"
|
||||||
}
|
}
|
||||||
$ret = OWCOUNT_GetPage($hash,$page,1,1);
|
$ret = OWCOUNT_GetPage($hash,$page,1,1);
|
||||||
|
#-- process result
|
||||||
|
if( $master->{ASYNCHRONOUS} ){
|
||||||
|
return "OWCOUNT: $name getting midnight value $page and counter, please wait for completion";
|
||||||
|
}else{
|
||||||
#-- when we have a return code, we have an error
|
#-- when we have a return code, we have an error
|
||||||
if( $ret ){
|
if( $ret ){
|
||||||
return "OWCOUNT: Could not get values from device $name, reason: ".$ret;
|
return "OWCOUNT: Could not get values from device $name, reason: ".$ret;
|
||||||
@ -780,6 +872,7 @@ sub OWCOUNT_Get($@) {
|
|||||||
return "OWCOUNT: $name.$reading [$page] =>".$hash->{owg_midnight}->[$page-14];
|
return "OWCOUNT: $name.$reading [$page] =>".$hash->{owg_midnight}->[$page-14];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#-- check syntax for getting counter
|
#-- check syntax for getting counter
|
||||||
if( $reading eq "raw" ){
|
if( $reading eq "raw" ){
|
||||||
@ -794,21 +887,27 @@ sub OWCOUNT_Get($@) {
|
|||||||
return "OWCOUNT: Invalid counter address, must be A, B or defined channel name"
|
return "OWCOUNT: Invalid counter address, must be A, B or defined channel name"
|
||||||
}
|
}
|
||||||
$ret = OWCOUNT_GetPage($hash,$page,1,1);
|
$ret = OWCOUNT_GetPage($hash,$page,1,1);
|
||||||
|
#-- process result
|
||||||
|
if( $master->{ASYNCHRONOUS} ){
|
||||||
|
return "OWCOUNT: $name getting page $page and counter, please wait for completion";
|
||||||
|
}else{
|
||||||
#-- when we have a return code, we have an error
|
#-- when we have a return code, we have an error
|
||||||
if( $ret ){
|
if( $ret ){
|
||||||
return "OWCOUNT: Could not get values from device $name, reason: ".$ret;
|
return "OWCOUNT: Could not get values from device $name, reason: ".$ret;
|
||||||
}
|
}
|
||||||
#-- only one counter will be returned
|
#-- only one counter will be returned
|
||||||
return "OWCOUNT: $name.raw $a[2] => ".$hash->{owg_val}->[$page-14];
|
return "OWCOUNT: $name.raw $a[2] => ".$hash->{owg_val}->[$page-14];
|
||||||
|
}
|
||||||
#-- check syntax for getting counters
|
#-- check syntax for getting counters
|
||||||
}elsif( $reading eq "counters" ){
|
}elsif( $reading eq "counters" ){
|
||||||
return "OWCOUNT: Get needs no parameter when reading counters"
|
return "OWCOUNT: Get needs no parameter when reading counters"
|
||||||
if( int(@a)==1 );
|
if( int(@a)==1 );
|
||||||
$ret1 = OWCOUNT_GetPage($hash,14,0,1);
|
$ret1 = OWCOUNT_GetPage($hash,14,0,1);
|
||||||
$ret2 = OWCOUNT_GetPage($hash,15,1,1);
|
$ret2 = OWCOUNT_GetPage($hash,15,1,1);
|
||||||
|
#-- process result
|
||||||
#-- process results
|
if( $master->{ASYNCHRONOUS} ){
|
||||||
|
return "OWCOUNT: $name getting counters, please wait for completion";
|
||||||
|
}else{
|
||||||
$ret .= $ret1
|
$ret .= $ret1
|
||||||
if( defined($ret1) );
|
if( defined($ret1) );
|
||||||
$ret .= $ret2
|
$ret .= $ret2
|
||||||
@ -820,6 +919,7 @@ sub OWCOUNT_Get($@) {
|
|||||||
return "OWCOUNT: $name.counters => ".$hash->{READINGS}{"state"}{VAL};
|
return "OWCOUNT: $name.counters => ".$hash->{READINGS}{"state"}{VAL};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#######################################################################################
|
#######################################################################################
|
||||||
#
|
#
|
||||||
@ -926,7 +1026,7 @@ sub OWCOUNT_GetMonth($) {
|
|||||||
@linarr = split(' ',$line);
|
@linarr = split(' ',$line);
|
||||||
if( int(@linarr)==4+6*int(@owg_fixed) ){
|
if( int(@linarr)==4+6*int(@owg_fixed) ){
|
||||||
$day = $linarr[3];
|
$day = $linarr[3];
|
||||||
$day =~ s/D_0+//;
|
$day =~ s/D_+0+//;
|
||||||
@mchannel = ();
|
@mchannel = ();
|
||||||
for (my $i=0;$i<int(@owg_fixed);$i++){
|
for (my $i=0;$i<int(@owg_fixed);$i++){
|
||||||
$val = $linarr[5+6*$i];
|
$val = $linarr[5+6*$i];
|
||||||
@ -936,9 +1036,8 @@ sub OWCOUNT_GetMonth($) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( int(@month)==0 ){
|
if( int(@month)<($cday-1) ){
|
||||||
return "invalid logfile format in LogM"
|
Log3 $name,3, "OWCOUNT: warning, found only ".int(@month)." lines in logfile $lf of LogM";
|
||||||
if( $cday!=1 );
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return "cannot open logfile of LogM";
|
return "cannot open logfile of LogM";
|
||||||
@ -1023,7 +1122,7 @@ sub OWCOUNT_GetYear($) {
|
|||||||
@linarr = split(' ',$line);
|
@linarr = split(' ',$line);
|
||||||
if( int(@linarr)==4+6*int(@owg_fixed) ){
|
if( int(@linarr)==4+6*int(@owg_fixed) ){
|
||||||
$month = $linarr[3];
|
$month = $linarr[3];
|
||||||
$month =~ s/M_0+//;
|
$month =~ s/M_+0+//;
|
||||||
@mchannel = ();
|
@mchannel = ();
|
||||||
for (my $i=0;$i<int(@owg_fixed);$i++){
|
for (my $i=0;$i<int(@owg_fixed);$i++){
|
||||||
$val = $linarr[5+6*$i];
|
$val = $linarr[5+6*$i];
|
||||||
@ -1033,9 +1132,8 @@ sub OWCOUNT_GetYear($) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( int(@year)==0 ){
|
if( int(@year)<($cmonth-1) ){
|
||||||
return "invalid logfile format in LogY"
|
Log3 $name,3, "OWCOUNT: warning, found only ".int(@year)." lines in logfile $lf of LogY";
|
||||||
if($cmonth != 1);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return "cannot open logfile of LogY";
|
return "cannot open logfile of LogY";
|
||||||
@ -1046,13 +1144,13 @@ sub OWCOUNT_GetYear($) {
|
|||||||
my @month2 = OWCOUNT_GetMonth($hash);
|
my @month2 = OWCOUNT_GetMonth($hash);
|
||||||
for (my $i=0;$i<int(@owg_fixed);$i++){
|
for (my $i=0;$i<int(@owg_fixed);$i++){
|
||||||
$total = 0.0;
|
$total = 0.0;
|
||||||
#-- summing only if mode daily (means daily reset !)
|
|
||||||
$daily = 0;
|
$daily = 0;
|
||||||
if( defined($attr{$name}{$owg_fixed[$i]."Mode"} )){
|
if( defined($attr{$name}{$owg_fixed[$i]."Mode"} )){
|
||||||
if( $attr{$name}{$owg_fixed[$i]."Mode"} eq "daily"){
|
if( $attr{$name}{$owg_fixed[$i]."Mode"} eq "daily"){
|
||||||
$daily = 1;
|
$daily = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#-- sum previous months only in daily mode
|
||||||
if( $daily==1){
|
if( $daily==1){
|
||||||
for (my $j=0;$j<int(@year);$j++){
|
for (my $j=0;$j<int(@year);$j++){
|
||||||
$total += $year[$j][$i];
|
$total += $year[$j][$i];
|
||||||
@ -1061,10 +1159,12 @@ sub OWCOUNT_GetYear($) {
|
|||||||
$total = $year[int(@year)-1][$i]
|
$total = $year[int(@year)-1][$i]
|
||||||
if (int(@year)>0);
|
if (int(@year)>0);
|
||||||
};
|
};
|
||||||
|
|
||||||
#-- add data from current day also for non-summed mode
|
|
||||||
$total = int($total*100)/100;
|
$total = int($total*100)/100;
|
||||||
$total2 = int(100*($total+$month2[$i]->[1]))/100;
|
#-- data from this month is
|
||||||
|
$total2 = int(100*($month2[$i]->[1]))/100;
|
||||||
|
#-- add data from this month and previous months in daily mode
|
||||||
|
$total2+=$total
|
||||||
|
if( $daily==1 );
|
||||||
#-- number of days so far, including the present day
|
#-- number of days so far, including the present day
|
||||||
my $deltim = $cyday+($chour+$cmin/60.0 + $csec/3600.0)/24.0;
|
my $deltim = $cyday+($chour+$cmin/60.0 + $csec/3600.0)/24.0;
|
||||||
my $av = $deltim>0 ? int(100*$total2/$deltim)/100 : -1;
|
my $av = $deltim>0 ? int(100*$total2/$deltim)/100 : -1;
|
||||||
@ -1111,106 +1211,6 @@ sub OWCOUNT_GetValues($) {
|
|||||||
if( $ret ne "" ){
|
if( $ret ne "" ){
|
||||||
return "OWCOUNT: Could not get values from device $name, reason: ".$ret;
|
return "OWCOUNT: Could not get values from device $name, reason: ".$ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return undef;
|
|
||||||
}
|
|
||||||
|
|
||||||
########################################################################################
|
|
||||||
#
|
|
||||||
# OWCOUNT_InitializeDevice - delayed setting of initial readings and channel names
|
|
||||||
#
|
|
||||||
# Parameter hash = hash of device addressed
|
|
||||||
#
|
|
||||||
########################################################################################
|
|
||||||
|
|
||||||
sub OWCOUNT_InitializeDevice($) {
|
|
||||||
my ($hash) = @_;
|
|
||||||
|
|
||||||
my $name = $hash->{NAME};
|
|
||||||
#-- get memory page/counter according to interface type
|
|
||||||
my $master= $hash->{IODev};
|
|
||||||
my $interface= $hash->{IODev}->{TYPE};
|
|
||||||
|
|
||||||
my $olddata = "";
|
|
||||||
my $newdata = "OWCOUNT ".$owx_version;
|
|
||||||
my $ret;
|
|
||||||
|
|
||||||
#-- initial values
|
|
||||||
for( my $i=0;$i<int(@owg_fixed);$i++) {
|
|
||||||
#-- initial readings
|
|
||||||
$hash->{owg_val}->[$i] = "";
|
|
||||||
$hash->{owg_midnight}->[$i] = "";
|
|
||||||
$hash->{owg_str}->[$i] = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
#-- testing if it is the emulator
|
|
||||||
#-- The model may be DS2423, DS2423enew or DS2423eold. Some weird people are violating 1-Wire integrity by using the
|
|
||||||
# the same family ID although the DS2423emu does not fully support the DS2423 commands.
|
|
||||||
# Model attribute will be modified now after checking for memory
|
|
||||||
#-- OWX interface
|
|
||||||
if( $interface eq "OWX" ){
|
|
||||||
$ret = OWXCOUNT_GetPage($hash,14,0);
|
|
||||||
$olddata = $hash->{owg_str}->[14];
|
|
||||||
$ret = OWXCOUNT_SetPage($hash,14,$newdata);
|
|
||||||
$ret = OWXCOUNT_GetPage($hash,14,0);
|
|
||||||
$ret = OWXCOUNT_SetPage($hash,14,$olddata);
|
|
||||||
}elsif( $interface eq "OWX_ASYNC" ){
|
|
||||||
eval {
|
|
||||||
$ret = OWX_ASYNC_RunToCompletion($hash,OWXCOUNT_PT_InitializeDevicePage($hash,14,$newdata));
|
|
||||||
};
|
|
||||||
$ret = GP_Catch($@) if $@;
|
|
||||||
#-- OWFS interface
|
|
||||||
}elsif( $interface eq "OWServer" ){
|
|
||||||
$ret = OWFSCOUNT_GetPage($hash,14,0);
|
|
||||||
$olddata = $hash->{owg_str}->[14];
|
|
||||||
$ret = OWFSCOUNT_SetPage($hash,14,$newdata);
|
|
||||||
$ret = OWFSCOUNT_GetPage($hash,14,0);
|
|
||||||
$ret = OWFSCOUNT_SetPage($hash,14,$olddata);
|
|
||||||
#-- Unknown interface
|
|
||||||
}else{
|
|
||||||
return "OWCOUNT: InitializeDevice with wrong IODev type $interface";
|
|
||||||
}
|
|
||||||
#Log 1,"FIRST CHECK: written $newdata, read ".substr($hash->{owg_str}->[14],0,length($newdata));
|
|
||||||
my $nomid = ( substr($hash->{owg_str}->[14],0,length($newdata)) ne $newdata );
|
|
||||||
#-- OWX interface
|
|
||||||
if( $interface eq "OWX" ){
|
|
||||||
$ret = OWXCOUNT_GetPage($hash,0,0);
|
|
||||||
$olddata = $hash->{owg_str}->[0];
|
|
||||||
$ret = OWXCOUNT_SetPage($hash,0,$newdata);
|
|
||||||
$ret = OWXCOUNT_GetPage($hash,0,0);
|
|
||||||
$ret = OWXCOUNT_SetPage($hash,0,$olddata);
|
|
||||||
}elsif( $interface eq "OWX_ASYNC" ){
|
|
||||||
eval {
|
|
||||||
$ret = OWX_ASYNC_RunToCompletion($hash,OWXCOUNT_PT_InitializeDevicePage($hash,0,$newdata));
|
|
||||||
};
|
|
||||||
$ret = GP_Catch($@) if $@;
|
|
||||||
#-- OWFS interface
|
|
||||||
}elsif( $interface eq "OWServer" ){
|
|
||||||
$ret = OWFSCOUNT_GetPage($hash,0,0);
|
|
||||||
$olddata = $hash->{owg_str}->[0];
|
|
||||||
$ret = OWFSCOUNT_SetPage($hash,0,$newdata);
|
|
||||||
$ret = OWFSCOUNT_GetPage($hash,0,0);
|
|
||||||
$ret = OWFSCOUNT_SetPage($hash,0,$olddata);
|
|
||||||
#-- Unknown interface
|
|
||||||
}else{
|
|
||||||
return "OWCOUNT: InitializeDevice with wrong IODev type $interface";
|
|
||||||
}
|
|
||||||
#Log 1,"SECOND CHECK: written $newdata, read ".substr($hash->{owg_str}->[0],0,length($newdata));
|
|
||||||
my $nomem = ( substr($hash->{owg_str}->[0],0,length($newdata)) ne $newdata );
|
|
||||||
#-- Here we test if writing the memory is ok.
|
|
||||||
if( !$nomid && $nomem ){
|
|
||||||
Log3 $name,1,"OWCOUNT: model attribute of $name set to DS2423enew";
|
|
||||||
CommandAttr (undef,"$name model DS2423enew");
|
|
||||||
CommandAttr (undef,"$name nomemory 0");
|
|
||||||
} elsif( $nomid && $nomem ){
|
|
||||||
Log3 $name,1,"OWCOUNT: model attribute of $name set to DS2423eold because no memory found";
|
|
||||||
CommandAttr (undef,"$name model DS2423eold");
|
|
||||||
CommandAttr (undef,"$name nomemory 1");
|
|
||||||
}
|
|
||||||
|
|
||||||
#-- Set state to initialized
|
|
||||||
readingsSingleUpdate($hash,"state","initialized",1);
|
|
||||||
|
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1315,7 +1315,7 @@ sub OWCOUNT_Set($@) {
|
|||||||
$data.=" ".$a[$i];
|
$data.=" ".$a[$i];
|
||||||
}
|
}
|
||||||
if( length($data) > 32 ){
|
if( length($data) > 32 ){
|
||||||
Log3 $name,1,"OWXCOUNT: Memory data truncated to 32 characters";
|
Log3 $name,3,"OWCOUNT: Memory data truncated to 32 characters";
|
||||||
$data=substr($data,0,32);
|
$data=substr($data,0,32);
|
||||||
}elsif( length($data) < 32 ){
|
}elsif( length($data) < 32 ){
|
||||||
for(my $i=length($data)-1;$i<32;$i++){
|
for(my $i=length($data)-1;$i<32;$i++){
|
||||||
@ -1360,7 +1360,7 @@ sub OWCOUNT_Set($@) {
|
|||||||
$hash->{READINGS}{$owg_channel[$page-14]}{FACTOR} - $a[3];
|
$hash->{READINGS}{$owg_channel[$page-14]}{FACTOR} - $a[3];
|
||||||
$data = sprintf("%4d-%02d-%02d midnight %7.2f",
|
$data = sprintf("%4d-%02d-%02d midnight %7.2f",
|
||||||
$year+1900,$month+1,$day,$midnew);
|
$year+1900,$month+1,$day,$midnew);
|
||||||
#Log 1,"OLD MIDNIGHT ".$hash->{owg_midnight}->[$page-14]." NEW $midnew";
|
Log3 $name,5,"OWCOUNT: old midnight vakue ".$hash->{owg_midnight}->[$page-14].", replaced by $midnew";
|
||||||
$ret = OWCOUNT_SetPage($hash,$page,$data);
|
$ret = OWCOUNT_SetPage($hash,$page,$data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1447,12 +1447,12 @@ sub OWCOUNT_store($$$) {
|
|||||||
} else {
|
} else {
|
||||||
Log3 $name,1,"OWCOUNT_store: Cannot open $filename for writing!";
|
Log3 $name,1,"OWCOUNT_store: Cannot open $filename for writing!";
|
||||||
}
|
}
|
||||||
return undef;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
########################################################################################
|
########################################################################################
|
||||||
#
|
#
|
||||||
# Recall daily start value from a file
|
# OWCOUNT_recall Recall daily start value from a file
|
||||||
#
|
#
|
||||||
# Parameter hash,filename
|
# Parameter hash,filename
|
||||||
#
|
#
|
||||||
@ -1470,8 +1470,18 @@ sub OWCOUNT_recall($$) {
|
|||||||
close(OWXFILE);
|
close(OWXFILE);
|
||||||
return $line;
|
return $line;
|
||||||
}
|
}
|
||||||
Log3 $name,1, "OWCOUNT_recall: Cannot open $filename for reading!";
|
Log3 $name,1, "OWCOUNT_recall: Cannot open $filename for reading, 2nd attempt";
|
||||||
return undef;;
|
$ret = OWCOUNT_store($hash,$filename,0);
|
||||||
|
if (!$ret){
|
||||||
|
$ret = open(OWXFILE, "< $mp/FHEM/$filename" );
|
||||||
|
if( $ret ){
|
||||||
|
my $line = readline OWXFILE;
|
||||||
|
close(OWXFILE);
|
||||||
|
return $line;
|
||||||
|
}
|
||||||
|
Log3 $name,1, "OWCOUNT_recall: Cannot open $filename for reading - tried twice";
|
||||||
|
return "error";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
########################################################################################
|
########################################################################################
|
||||||
@ -1494,6 +1504,8 @@ sub OWCOUNT_Undef ($) {
|
|||||||
# The following subroutines in alphabetical order are only for a 1-Wire bus connected
|
# The following subroutines in alphabetical order are only for a 1-Wire bus connected
|
||||||
# via OWFS
|
# via OWFS
|
||||||
#
|
#
|
||||||
|
# TODO: So far no automatic recognition of DS2423 / Emulator
|
||||||
|
#
|
||||||
# Prefix = OWFSCOUNT
|
# Prefix = OWFSCOUNT
|
||||||
#
|
#
|
||||||
########################################################################################
|
########################################################################################
|
||||||
@ -1603,76 +1615,125 @@ sub OWFSCOUNT_SetPage($$$) {
|
|||||||
# OWXCOUNT_BinValues - Process reading from one device - translate binary into raw
|
# OWXCOUNT_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 OWXCOUNT_BinValues($$$$$) {
|
sub OWXCOUNT_BinValues($$$$$$$) {
|
||||||
my ($hash, $context, $owx_dev, $select, $res) = @_;
|
my ($hash, $context, $proc, $owx_dev, $crcpart, $numread, $res) = @_;
|
||||||
|
|
||||||
#-- unused are success, reset, data
|
#-- hash of the busmaster
|
||||||
|
my $master = $hash->{IODev};
|
||||||
return undef unless (defined $context and $context =~ /^(get|set)page\.([\d]+)(\.final|)$/);
|
my $name = $hash->{NAME};
|
||||||
|
my @data=[];
|
||||||
|
my $value;
|
||||||
|
my $msg;
|
||||||
|
OWX_WDBG($name,"OWCOUNT_BinValues called for device $name in context $context with ",$res)
|
||||||
|
if( $main::owx_debug>2 );
|
||||||
|
|
||||||
|
return undef unless (defined $context and $context =~ /^(get|set|check)page\.([\d]+)(\.final|)$/);
|
||||||
my $cmd = $1;
|
my $cmd = $1;
|
||||||
my $page = $2;
|
my $page = $2;
|
||||||
my $final = $3;
|
my $final = $3;
|
||||||
my $name = $hash->{NAME};
|
#=============== get memory + counter ===============================
|
||||||
|
|
||||||
Log3 ($name,5,"OWXCount_BinValues context: $context, $cmd page: $page, final: ".(defined $final ? $final : "undef"));
|
|
||||||
|
|
||||||
if ($cmd eq "get") {
|
if ($cmd eq "get") {
|
||||||
my ($i,$j,$k,@data,@writedata,$strval,$value);
|
my (@data,$strval,$value);
|
||||||
my $change = 0;
|
my $change = 0;
|
||||||
|
@data=split(//,$res);
|
||||||
|
|
||||||
#-- process results
|
#-- process results
|
||||||
@data=split(//,$res);
|
if(ord($data[17])<=0){
|
||||||
@writedata = split(//,$select);
|
#-- invalid data: do not die, but change memory flags
|
||||||
return "invalid data length, ".int(@data)." instead of 42 bytes in three steps"
|
if( $page > 13 ){
|
||||||
if( int(@data) < 42);
|
$owg_memory[1]=0;
|
||||||
#return "invalid data"
|
}else{
|
||||||
# if (ord($data[17])<=0);
|
$owg_memory[0]=0;
|
||||||
return "invalid CRC, ".ord($data[40])." ".ord($data[41])
|
}
|
||||||
if (OWX_CRC16($select.substr($res,0,40),$data[40],$data[41]) == 0);
|
$owg_memory[2]=1;
|
||||||
|
$msg="memory data could not be read";
|
||||||
|
}else{
|
||||||
|
if( $page > 13 ){
|
||||||
|
$owg_memory[1]=1;
|
||||||
|
}else{
|
||||||
|
$owg_memory[0]=1;
|
||||||
|
}
|
||||||
|
$owg_memory[2]=1;
|
||||||
|
}
|
||||||
|
|
||||||
#-- first 3 command, next 32 are memory
|
if( int(@data) < 42){
|
||||||
#my $res2 = "OWCOUNT FIRST 10 BYTES for device $owx_dev ARE ";
|
$msg="$name returns invalid data length, ".int(@data)." instead of 42 bytes";
|
||||||
#for($i=0;$i<10;$i++){
|
}elsif (OWX_CRC16($crcpart.substr($res,0,40),$data[40],$data[41]) == 0){
|
||||||
# $j=int(ord(substr($res,$i,1))/16);
|
$msg="$name returns invalid CRC, ".ord($data[40])." ".ord($data[41]);
|
||||||
# $k=ord(substr($res,$i,1))%16;
|
}
|
||||||
# $res2.=sprintf "0x%1x%1x ",$j,$k;
|
OWX_WDBG($name,"OWXCOUNT_BinValues: ".$msg,"")
|
||||||
#}
|
if( $main::owx_debug>2 );
|
||||||
#main::Log(1, $res2);
|
|
||||||
|
|
||||||
#--
|
#--
|
||||||
my $nomemory = defined($attr{$name}{"nomemory"}) ? $attr{$name}{"nomemory"} : 0;
|
my $nomemory = defined($attr{$name}{"nomemory"}) ? $attr{$name}{"nomemory"} : 0;
|
||||||
if( $nomemory==0 ){
|
if( $nomemory==0 ){
|
||||||
#-- memory part, treated as string
|
#-- memory part, treated as string
|
||||||
$strval=substr($res,0,32);
|
$strval=substr($res,0,32);
|
||||||
#Log 1," retrieved on device $owx_dev for page $page STRING $strval";
|
#Log3 $name,5,"OWCOUNT: retrieved from memory for page $page ==> $strval";
|
||||||
} else {
|
} else {
|
||||||
$strval = OWCOUNT_recall($hash,"OWCOUNT_".$hash->{NAME}."_".$page.".dat");
|
$strval = OWCOUNT_recall($hash,"OWCOUNT_".$hash->{NAME}."_".$page.".dat");
|
||||||
|
#Log3 $name,5,"OWCOUNT: retrieved from disk for page $page ==> $strval";
|
||||||
}
|
}
|
||||||
$hash->{owg_str}->[$page]= defined $strval ? $strval : "";
|
$hash->{owg_str}->[$page]= defined $strval ? $strval : "";
|
||||||
#-- counter part
|
#-- counter part
|
||||||
if( ($page == 14) || ($page == 15) ){
|
if( ($page == 14) || ($page == 15) ){
|
||||||
@data=split(//,substr($res,32));
|
@data=split(//,substr($res,32));
|
||||||
if ( ($data[4] | $data[5] | $data[6] | $data[7]) ne "\x00" ){
|
if ( ($data[4] | $data[5] | $data[6] | $data[7]) ne "\x00" ){
|
||||||
#Log 1, "device $owx_dev returns invalid data ".ord($data[4])." ".ord($data[5])." ".ord($data[6])." ".ord($data[7]);
|
OWX_WDBG($name, "device $name returns invalid data ".ord($data[4])." ".ord($data[5])." ".ord($data[6])." ".ord($data[7])," ");
|
||||||
return "device $owx_dev returns invalid data";
|
|
||||||
}
|
}
|
||||||
#-- counter value
|
#-- counter value
|
||||||
$value = (ord($data[3])<<24) + (ord($data[2])<<16) +(ord($data[1])<<8) + ord($data[0]);
|
$value = (ord($data[3])<<24) + (ord($data[2])<<16) +(ord($data[1])<<8) + ord($data[0]);
|
||||||
$hash->{owg_val}->[$page-14] = $value;
|
$hash->{owg_val}->[$page-14] = $value;
|
||||||
#-- midnight value
|
#-- midnight value
|
||||||
Log3 $name,5, "OWCOUNT_BinValues ParseMidnight: ".(defined $strval ? $strval : "undef");
|
#Log3 $name,1, "OWCOUNT_BinValues ParseMidnight: ".(defined $strval ? $strval : "undef");
|
||||||
OWCOUNT_ParseMidnight($hash,$strval,$page);
|
OWCOUNT_ParseMidnight($hash,$strval,$page);
|
||||||
}
|
}
|
||||||
#-- and now from raw to formatted values
|
#-- and now from raw to formatted values
|
||||||
$hash->{PRESENT} = 1;
|
$hash->{PRESENT} = 1;
|
||||||
if( $final ) {
|
if( $final ) {
|
||||||
my $value = OWCOUNT_FormatValues($hash);
|
my $value = OWCOUNT_FormatValues($hash);
|
||||||
Log3 $name,5, "OWCOUNT_BinValues->FormatValues returns: ".(defined $value ? $value : "undef");
|
|
||||||
}
|
}
|
||||||
|
#=============== set memory ===============================
|
||||||
|
#-- for setting a page we need a second step where the scratchpad is copied into memory
|
||||||
|
}elsif (($cmd eq "set") && !$final ) {
|
||||||
|
my $select="\x5A".substr($res,0,3);
|
||||||
|
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
||||||
|
# 16 inserts at top of queue
|
||||||
|
OWX_Qomplex($master, $hash, "setpage.$page.final", 16, $owx_dev, $select, 0, 6, 10, \&OWXCOUNT_BinValues, 0);
|
||||||
|
#-- and a third step where this is finalized
|
||||||
|
}elsif (($cmd eq "set") && $final ) {
|
||||||
|
if( substr($res,4,1) ne "\xAA" ){
|
||||||
|
if( $page > 13 ){
|
||||||
|
$owg_memory[1]=0;
|
||||||
|
}else{
|
||||||
|
$owg_memory[0]=0;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if( $page > 13){
|
||||||
|
$owg_memory[1]=1;
|
||||||
|
}else{
|
||||||
|
$owg_memory[0]=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#-- change applied
|
||||||
|
$owg_memory[2]=1;
|
||||||
}
|
}
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
@ -1699,8 +1760,6 @@ sub OWXCOUNT_GetPage($$$) {
|
|||||||
#-- reset presence
|
#-- reset presence
|
||||||
$hash->{PRESENT} = 0;
|
$hash->{PRESENT} = 0;
|
||||||
|
|
||||||
my ($i,$j,$k);
|
|
||||||
|
|
||||||
#=============== wrong value requested ===============================
|
#=============== wrong value requested ===============================
|
||||||
if( ($page<0) || ($page>15) ){
|
if( ($page<0) || ($page>15) ){
|
||||||
return "wrong memory page requested";
|
return "wrong memory page requested";
|
||||||
@ -1713,6 +1772,8 @@ sub OWXCOUNT_GetPage($$$) {
|
|||||||
$select=sprintf("\xA5%c%c",$ta1,$ta2);
|
$select=sprintf("\xA5%c%c",$ta1,$ta2);
|
||||||
|
|
||||||
my $context = "getpage.".$page.($final ? ".final" : "");
|
my $context = "getpage.".$page.($final ? ".final" : "");
|
||||||
|
#-- OLD OWX interface
|
||||||
|
if( !$master->{ASYNCHRONOUS} ){
|
||||||
#-- reset the bus
|
#-- reset the bus
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
#-- reading 9 + 3 + 40 data bytes (32 byte memory, 4 byte counter + 4 byte zeroes) and 2 CRC bytes = 54 bytes
|
#-- reading 9 + 3 + 40 data bytes (32 byte memory, 4 byte counter + 4 byte zeroes) and 2 CRC bytes = 54 bytes
|
||||||
@ -1739,7 +1800,17 @@ sub OWXCOUNT_GetPage($$$) {
|
|||||||
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)!=54);
|
if( length($res)!=54);
|
||||||
return OWXCOUNT_BinValues($hash,$context,$owx_dev,$select,substr($res,12));
|
eval {
|
||||||
|
OWXCOUNT_BinValues($hash,$context,0,$owx_dev,$select,45,substr($res,12));
|
||||||
|
};
|
||||||
|
return $@ ? $@ : undef;
|
||||||
|
#-- 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, 45, 12, \&OWXCOUNT_BinValues, 0);
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
########################################################################################
|
########################################################################################
|
||||||
@ -1747,7 +1818,8 @@ sub OWXCOUNT_GetPage($$$) {
|
|||||||
# OWXCOUNT_SetPage - Set one memory page of device
|
# OWXCOUNT_SetPage - Set one memory page of device
|
||||||
#
|
#
|
||||||
# Parameter hash = hash of device addressed
|
# Parameter hash = hash of device addressed
|
||||||
# page = "alarm" or "status"
|
# page = 0..15
|
||||||
|
# data = string to set into memory
|
||||||
#
|
#
|
||||||
########################################################################################
|
########################################################################################
|
||||||
|
|
||||||
@ -1757,8 +1829,6 @@ sub OWXCOUNT_SetPage($$$) {
|
|||||||
|
|
||||||
my ($select, $res, $res2, $res3);
|
my ($select, $res, $res2, $res3);
|
||||||
|
|
||||||
my ($i,$j,$k);
|
|
||||||
|
|
||||||
#-- ID of the device, hash of the busmaster
|
#-- ID of the device, hash of the busmaster
|
||||||
my $owx_dev = $hash->{ROM_ID};
|
my $owx_dev = $hash->{ROM_ID};
|
||||||
my $master = $hash->{IODev};
|
my $master = $hash->{IODev};
|
||||||
@ -1778,23 +1848,14 @@ sub OWXCOUNT_SetPage($$$) {
|
|||||||
my $ta1 = ($page*32) & 255;
|
my $ta1 = ($page*32) & 255;
|
||||||
#Log 1, "OWXCOUNT: setting page Nr. $ta2 $ta1 $data";
|
#Log 1, "OWXCOUNT: setting page Nr. $ta2 $ta1 $data";
|
||||||
$select=sprintf("\x0F%c%c",$ta1,$ta2).$data;
|
$select=sprintf("\x0F%c%c",$ta1,$ta2).$data;
|
||||||
|
#-- OLD OWX interface
|
||||||
#-- first command, next 2 are address, then data
|
if( !$master->{ASYNCHRONOUS} ){
|
||||||
#$res2 = "OWCOUNT SET PAGE 1 device $owx_dev ";
|
|
||||||
#for($i=0;$i<10;$i++){
|
|
||||||
# $j=int(ord(substr($select,$i,1))/16);
|
|
||||||
# $k=ord(substr($select,$i,1))%16;
|
|
||||||
# $res2.=sprintf "0x%1x%1x ",$j,$k;
|
|
||||||
#}
|
|
||||||
#main::Log(1, $res2);
|
|
||||||
|
|
||||||
#-- reset the bus
|
#-- reset the bus
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
$res=OWX_Complex($master,$owx_dev,$select,0);
|
$res=OWX_Complex($master,$owx_dev,$select,0);
|
||||||
if( $res eq 0 ){
|
if( $res eq 0 ){
|
||||||
return "device $owx_dev not accessible in writing scratchpad";
|
return "OWCOUNT: device $owx_dev not accessible in writing scratchpad";
|
||||||
}
|
}
|
||||||
|
|
||||||
#-- issue the match ROM command \x55 and the read scratchpad command
|
#-- issue the match ROM command \x55 and the read scratchpad command
|
||||||
# \xAA, receiving 2 address bytes, 1 status byte and scratchpad content
|
# \xAA, receiving 2 address bytes, 1 status byte and scratchpad content
|
||||||
$select = "\xAA";
|
$select = "\xAA";
|
||||||
@ -1804,37 +1865,41 @@ sub OWXCOUNT_SetPage($$$) {
|
|||||||
# TODO: sometimes much less than 28
|
# TODO: sometimes much less than 28
|
||||||
$res=OWX_Complex($master,$owx_dev,$select,28);
|
$res=OWX_Complex($master,$owx_dev,$select,28);
|
||||||
if( length($res) < 13 ){
|
if( length($res) < 13 ){
|
||||||
return "device $owx_dev not accessible in reading scratchpad";
|
return "OWCOUNT: device $owx_dev not accessible in reading scratchpad";
|
||||||
}
|
}
|
||||||
|
|
||||||
#-- first 1 command, next 2 are address, then data
|
|
||||||
#$res3 = substr($res,9,10);
|
|
||||||
#$res2 = "OWCOUNT SET PAGE 2 device $owx_dev ";
|
|
||||||
#for($i=0;$i<10;$i++){
|
|
||||||
# $j=int(ord(substr($res3,$i,1))/16);
|
|
||||||
# $k=ord(substr($res3,$i,1))%16;
|
|
||||||
# $res2.=sprintf "0x%1x%1x ",$j,$k;
|
|
||||||
#}
|
|
||||||
#main::Log(1, $res2);
|
|
||||||
#-- issue the match ROM command \x55 and the copy scratchpad command
|
#-- issue the match ROM command \x55 and the copy scratchpad command
|
||||||
# \x5A followed by 3 byte authentication code obtained in previous read
|
# \x5A followed by 3 byte authentication code obtained in previous read
|
||||||
$select="\x5A".substr($res,10,3);
|
$select="\x5A".substr($res,10,3);
|
||||||
#-- first command, next 2 are address, then data
|
|
||||||
#$res2 = "OWCOUNT SET PAGE 3 device $owx_dev ";
|
|
||||||
#for($i=0;$i<10;$i++){
|
|
||||||
# $j=int(ord(substr($select,$i,1))/16);
|
|
||||||
# $k=ord(substr($select,$i,1))%16;
|
|
||||||
# $res2.=sprintf "0x%1x%1x ",$j,$k;
|
|
||||||
#}
|
|
||||||
#main::Log(1, $res2);
|
|
||||||
|
|
||||||
#-- reset the bus
|
#-- reset the bus
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
$res=OWX_Complex($master,$owx_dev,$select,6);
|
$res=OWX_Complex($master,$owx_dev,$select,6);
|
||||||
|
|
||||||
#-- process results
|
#-- process results
|
||||||
if( $res eq 0 ){
|
if( $res eq 0 ){
|
||||||
return "device $owx_dev not accessible for copying scratchpad";
|
return "OWCOUNT: device $owx_dev not accessible for copying scratchpad";
|
||||||
|
}
|
||||||
|
if( substr($res,13,1) ne "\xAA" ){
|
||||||
|
if( $page > 13){
|
||||||
|
$owg_memory[1]=0;
|
||||||
|
}else{
|
||||||
|
$owg_memory[0]=0;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if( $page > 13){
|
||||||
|
$owg_memory[1]=1;
|
||||||
|
}else{
|
||||||
|
$owg_memory[0]=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$owg_memory[2]=1;
|
||||||
|
return undef;
|
||||||
|
#-- NEW OWX interface
|
||||||
|
}else{
|
||||||
|
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
||||||
|
# 8 prevents from filling up with 0xFF
|
||||||
|
OWX_Qomplex($master, $hash, undef, 8, $owx_dev, $select, $select, 35, 10, undef, 0);
|
||||||
|
#-- The third step of copying the scratchpad into memory can be scheduled only when the authorization code has been received
|
||||||
|
# will be done in the callback of the following line
|
||||||
|
OWX_Qomplex($master, $hash, "setpage.".$page, 0, $owx_dev, "\xAA", 0, 37, 10, \&OWXCOUNT_BinValues, 0);
|
||||||
}
|
}
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
@ -1885,7 +1950,7 @@ sub OWXCOUNT_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);
|
||||||
|
|
||||||
if (my $ret = OWXCOUNT_BinValues($hash,"getpage.".$page.($final ? ".final" : ""),$owx_dev,$thread->{'select'},$thread->{response})) {
|
if (my $ret = OWXCOUNT_BinValues($hash,"getpage.".$page.($final ? ".final" : ""),0,$owx_dev,$thread->{'select'},0,$thread->{response})) {
|
||||||
die $ret;
|
die $ret;
|
||||||
}
|
}
|
||||||
PT_END;
|
PT_END;
|
||||||
@ -2026,13 +2091,13 @@ sub OWXCOUNT_PT_InitializeDevicePage($$$) {
|
|||||||
<br /><h4>Example</h4><br />
|
<br /><h4>Example</h4><br />
|
||||||
<code>define OWC OWCOUNT 1D.CE780F000000 60</code>
|
<code>define OWC OWCOUNT 1D.CE780F000000 60</code>
|
||||||
<br />
|
<br />
|
||||||
<code>attr OWC AName Energie|energy</code>
|
<code>attr OWC AName energy|W</code>
|
||||||
<br />
|
<br />
|
||||||
<code>attr OWC AUnit kWh|kWh</code>
|
<code>attr OWC AUnit kWh</code>
|
||||||
<br />
|
<br />
|
||||||
<code>attr OWC APeriod hour</code>
|
<code>attr OWC APeriod hour</code>
|
||||||
<br />
|
<br />
|
||||||
<code>attr OWC ARate Leistung|power</code>
|
<code>attr OWC ARate power|P</code>
|
||||||
<br />
|
<br />
|
||||||
<code>attr OWX_AMode daily</code>
|
<code>attr OWX_AMode daily</code>
|
||||||
<br />
|
<br />
|
||||||
@ -2138,13 +2203,13 @@ sub OWXCOUNT_PT_InitializeDevicePage($$$) {
|
|||||||
<ul>
|
<ul>
|
||||||
<li><a name="owcount_cname"><code>attr <name> <channel>Name
|
<li><a name="owcount_cname"><code>attr <name> <channel>Name
|
||||||
<string>[|<string>]</code></a>
|
<string>[|<string>]</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="owcount_cunit"><code>attr <name> <channel>Unit
|
<li><a name="owcount_cunit"><code>attr <name> <channel>Unit
|
||||||
<string>[|<string>]</code></a>
|
<string&</code></a>
|
||||||
<br />unit of measurement for this channel [|unit used in state reading.] </li>
|
<br />unit of measurement used in state reading (default "cts", set to "none" for empty).</li>
|
||||||
<li><a name="owcount_crate"><code>attr <name> <channel>Rate
|
<li><a name="owcount_crate"><code>attr <name> <channel>Rate
|
||||||
<string>[|<string>]</code></a>
|
<string>[|<string>]</code></a>
|
||||||
<br />name for the channel rate [|name used in state reading]</li>
|
<br />name for the channel rate [|short name used in state reading]</li>
|
||||||
<li><a name="owcount_coffset"><code>attr <name> <channel>Offset
|
<li><a name="owcount_coffset"><code>attr <name> <channel>Offset
|
||||||
<float></code></a>
|
<float></code></a>
|
||||||
<br />offset added to the reading in this channel. </li>
|
<br />offset added to the reading in this channel. </li>
|
||||||
@ -2157,12 +2222,7 @@ sub OWXCOUNT_PT_InitializeDevicePage($$$) {
|
|||||||
<li><a name="owcount_cperiod"><code>attr <name> <channel>Period hour(default) | minute |
|
<li><a name="owcount_cperiod"><code>attr <name> <channel>Period hour(default) | minute |
|
||||||
second</code></a>
|
second</code></a>
|
||||||
<br />period for rate calculation </li>
|
<br />period for rate calculation </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="#verbose">verbose</a>,
|
|
||||||
<a href="#webCmd">webCmd</a></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
=end html
|
=end html
|
||||||
|
@ -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
@ -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
|
|
||||||
#
|
#
|
||||||
# Called By:
|
# OWMULTI_Initialize
|
||||||
# FHEM - Main Loop
|
|
||||||
# Gargelmargel - dunno where
|
|
||||||
#
|
#
|
||||||
#Calling:
|
# Parameter hash = hash of device addressed
|
||||||
# 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");
|
||||||
@ -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,7 +388,9 @@ 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 = "";
|
||||||
|
}elsif( $tunit eq "Celsius" ){
|
||||||
$tabbr = " °C";
|
$tabbr = " °C";
|
||||||
} elsif ($tunit eq "Kelvin" ){
|
} elsif ($tunit eq "Kelvin" ){
|
||||||
$tabbr = " K";
|
$tabbr = " K";
|
||||||
@ -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,7 +580,10 @@ sub OWMULTI_Get($@) {
|
|||||||
return "OWMULTI: Get with wrong IODev type $interface";
|
return "OWMULTI: Get with wrong IODev type $interface";
|
||||||
}
|
}
|
||||||
|
|
||||||
#-- process results
|
#-- process result
|
||||||
|
if( $master->{ASYNCHRONOUS} ){
|
||||||
|
return "OWSMULTI: $name getting readings, please wait for completion";
|
||||||
|
}else{
|
||||||
if( defined($ret) ){
|
if( defined($ret) ){
|
||||||
return "OWMULTI: Could not get values from device $name, reason $ret";
|
return "OWMULTI: Could not get values from device $name, reason $ret";
|
||||||
}
|
}
|
||||||
@ -558,7 +603,8 @@ sub OWMULTI_Get($@) {
|
|||||||
}
|
}
|
||||||
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.;
|
||||||
|
|
||||||
|
#-- 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
|
#-- 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,8 +983,11 @@ 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
|
||||||
|
#-- OLD OWX interface
|
||||||
|
if( !$master->{ASYNCHRONOUS} ){
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
if( OWX_Complex($master,$owx_dev,"\x4E\x00\x08",0) eq 0 ){
|
#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";
|
return "$owx_dev write status failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -930,7 +1011,7 @@ sub OWXMULTI_GetValues($) {
|
|||||||
#-- 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);
|
||||||
@ -939,7 +1020,7 @@ sub OWXMULTI_GetValues($) {
|
|||||||
#-- 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);
|
||||||
@ -953,13 +1034,14 @@ sub OWXMULTI_GetValues($) {
|
|||||||
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 ){
|
||||||
|
if( OWX_Complex($master,$owx_dev,"\x4E\x00\x01",0) eq 0 ){
|
||||||
return "$owx_dev write status failed";
|
return "$owx_dev write status failed";
|
||||||
}
|
}
|
||||||
#-- copy scratchpad to register
|
#-- copy scratchpad to register
|
||||||
@ -972,7 +1054,7 @@ sub OWXMULTI_GetValues($) {
|
|||||||
#-- 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);
|
||||||
@ -981,7 +1063,7 @@ sub OWXMULTI_GetValues($) {
|
|||||||
#-- 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);
|
||||||
@ -997,9 +1079,85 @@ sub OWXMULTI_GetValues($) {
|
|||||||
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 <name> reading</code></a><br />Obtain the measurement values </li>
|
<code>get <name> reading</code></a><br />Obtain the measurement values </li>
|
||||||
<li><a name="owmulti_vad">
|
|
||||||
<code>get <name> VAD</code></a><br />Obtain the measurement value from
|
|
||||||
VFunction. </li>
|
|
||||||
<li><a name="owmulti_temperature">
|
<li><a name="owmulti_temperature">
|
||||||
<code>get <name> temperature</code></a><br />Obtain the temperature value. </li>
|
<code>get <name> temperature</code></a><br />Obtain the temperature value. </li>
|
||||||
<li><a name="owmulti_vdd">
|
<li><a name="owmulti_vdd">
|
||||||
<code>get <name> VDD</code></a><br />Obtain the current supply voltage. </li>
|
<code>get <name> VDD</code></a><br />Obtain the current supply voltage. </li>
|
||||||
<li><a name="owmulti_raw">
|
<li><a name="owmulti_raw">
|
||||||
<code>get <name> V</code> or <code>get <name>
|
<code>get <name> V</code> or <code>get <name>
|
||||||
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 <name> VName
|
<li><a name="owmulti_vname"><code>attr <name> VName
|
||||||
<string>[|<string>]</code></a>
|
<string>[|<string>]</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 <name> VUnit
|
<li><a name="owmulti_vunit"><code>attr <name> VUnit
|
||||||
<string>[|<string>]</code></a>
|
<string></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 <name> VFunction
|
<li><a name="owmulti_vfunction"><code>attr <name> VFunction
|
||||||
<string></code></a>
|
<string></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 <name> WName
|
||||||
|
<string>[|<string>]</code></a>
|
||||||
|
<br />name for the sense channel [|short name used in state reading]. </li>
|
||||||
|
<li><a name="owmulti_wunit"><code>attr <name> WUnit
|
||||||
|
<string></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 <name> WFunction
|
||||||
|
<string></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 <name> tempOffset <float></code>
|
<li><a name="owmulti_tempOffset"><code>attr <name> tempOffset <float></code>
|
||||||
</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>
|
||||||
@ -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 = °C </li>
|
<br />unit of measurement (temperature scale), default is Celsius = °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
|
||||||
|
@ -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"} : "☇";
|
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
|
||||||
|
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};
|
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,12 +570,16 @@ sub OWSWITCH_Get($@) {
|
|||||||
return "OWSWITCH: Get with wrong IODev type $interface";
|
return "OWSWITCH: Get with wrong IODev type $interface";
|
||||||
}
|
}
|
||||||
#-- process results
|
#-- process results
|
||||||
|
if( $master->{ASYNCHRONOUS} ){
|
||||||
|
return "OWSWITCH: $name getting gpio, please wait for completion";
|
||||||
|
}else{
|
||||||
if( defined($ret) ){
|
if( defined($ret) ){
|
||||||
return "OWSWITCH: Could not get values from device $name, reason $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, ";
|
||||||
|
}else{
|
||||||
|
$msg="No error, ";
|
||||||
for(my $i=0;$i<8;$i++){
|
for(my $i=0;$i<8;$i++){
|
||||||
$hash->{owg_val}->[$i] = (ord($data[0])>>$i) & 1;
|
$hash->{owg_val}->[$i] = (ord($data[0])>>$i) & 1;
|
||||||
$hash->{owg_vax}->[$i] = (ord($data[1])>>$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, ";
|
||||||
|
}else{
|
||||||
|
$msg="No error, ";
|
||||||
$hash->{owg_val}->[0] = ord($data[0]) & 1;
|
$hash->{owg_val}->[0] = ord($data[0]) & 1;
|
||||||
$hash->{owg_vax}->[0] = (ord($data[0])>>1) & 1;
|
$hash->{owg_vax}->[0] = (ord($data[0])>>1) & 1;
|
||||||
$hash->{owg_val}->[1] = (ord($data[0])>>2) & 1;
|
$hash->{owg_val}->[1] = (ord($data[0])>>2) & 1;
|
||||||
$hash->{owg_vax}->[1] = (ord($data[0])>>3) & 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,11 +1215,23 @@ 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" ) {
|
||||||
@ -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");
|
||||||
|
#-- OLD OWX interface
|
||||||
|
if( !$master->{ASYNCHRONOUS} ){
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
$res=OWX_Complex($master,$owx_dev,$select,4);
|
$res=OWX_Complex($master,$owx_dev,$select,4);
|
||||||
return "$owx_dev not accessible in reading"
|
return "OWSWITCH: $name not accessible in reading"
|
||||||
if( $res eq 0 );
|
if( $res eq 0 );
|
||||||
return "$owx_dev has returned invalid data"
|
return "OWSWITCH: $name has returned invalid data"
|
||||||
if( length($res)!=16);
|
if( length($res)!=16);
|
||||||
OWX_Reset($master);
|
#OWX_Reset($master);
|
||||||
return OWXSWITCH_BinValues($hash,"ds2406.getstate",1,undef,$owx_dev,substr($res,9,3),undef,substr($res,12));
|
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");
|
||||||
|
#-- OLD OWX interface
|
||||||
|
if( !$master->{ASYNCHRONOUS} ){
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
$res=OWX_Complex($master,$owx_dev,$select,10);
|
$res=OWX_Complex($master,$owx_dev,$select,10);
|
||||||
return "$owx_dev not accessible in reading"
|
return "OWSWITCH: $name not accessible in reading"
|
||||||
if( $res eq 0 );
|
if( $res eq 0 );
|
||||||
return "$owx_dev has returned invalid data"
|
return "OWSWITCH: $name has returned invalid data"
|
||||||
if( length($res)!=22);
|
if( length($res)!=22);
|
||||||
OWX_Reset($master);
|
#OWX_Reset($master);
|
||||||
return OWXSWITCH_BinValues($hash,"ds2408.getstate",1,undef,$owx_dev,substr($res,9,3),undef,substr($res,12));
|
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
|
||||||
|
#-- OLD OWX interface
|
||||||
|
if( !$master->{ASYNCHRONOUS} ){
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
$res=OWX_Complex($master,$owx_dev,"\xF5",2);
|
$res=OWX_Complex($master,$owx_dev,"\xF5",2);
|
||||||
return "$owx_dev not accessible in reading"
|
return "OWSWITCH: $name not accessible in reading"
|
||||||
if( $res eq 0 );
|
if( $res eq 0 );
|
||||||
return "$owx_dev has returned invalid data"
|
return "OWSWITCH: $name has returned invalid data"
|
||||||
if( length($res)!=12);
|
if( length($res)!=12);
|
||||||
#OWX_Reset($master);
|
#OWX_Reset($master);
|
||||||
return OWXSWITCH_BinValues($hash,"ds2413.getstate",1,undef,$owx_dev,substr($res,9,1),undef,substr($res,10));
|
eval {
|
||||||
|
OWXSWITCH_BinValues($hash,"ds2413.$context",0,$owx_dev,substr($res,9,1),2,substr($res,10));
|
||||||
|
};
|
||||||
|
return $@ ? $@ : undef;
|
||||||
|
#-- NEW OWX interface
|
||||||
}else{
|
}else{
|
||||||
return "unknown device family $hash->{OW_FAMILY}\n";
|
#### 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 {
|
||||||
|
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
|
||||||
@ -1216,8 +1338,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" ) {
|
||||||
#=============== set gpio values ===============================
|
#=============== set gpio values ===============================
|
||||||
@ -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);
|
||||||
|
#-- OLD OWX interface
|
||||||
|
if( !$master->{ASYNCHRONOUS} ){
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
$res=OWX_Complex($master,$owx_dev,$select,2);
|
$res=OWX_Complex($master,$owx_dev,$select,2);
|
||||||
if( $res eq 0 ){
|
if( $res eq 0 ){
|
||||||
return "device $owx_dev not accessible in writing";
|
return "device $owx_dev not accessible in writing";
|
||||||
}
|
}
|
||||||
OWX_Reset($master);
|
#OWX_Reset($master);
|
||||||
return OWXSWITCH_BinValues($hash,"ds2406.setstate.$value",1,undef,$owx_dev,substr($res,9,4),undef,substr($res,13));
|
return OWXSWITCH_BinValues($hash,"ds2406.setstate.$value",0,$owx_dev,$select,2,substr($res,13));
|
||||||
return;
|
#-- 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;
|
||||||
|
}
|
||||||
#-- 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);
|
||||||
|
#-- OLD OWX interface
|
||||||
|
if( !$master->{ASYNCHRONOUS} ){
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
$res=OWX_Complex($master,$owx_dev,$select,1);
|
$res=OWX_Complex($master,$owx_dev,$select,1);
|
||||||
if( $res eq 0 ){
|
if( $res eq 0 ){
|
||||||
return "device $owx_dev not accessible in writing";
|
return "device $owx_dev not accessible in writing";
|
||||||
}
|
}
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
return OWXSWITCH_BinValues($hash,"ds2408.setstate",1,undef,$owx_dev,undef,undef,substr($res,12));
|
return OWXSWITCH_BinValues($hash,"ds2408.setstate.$value",0,$owx_dev,0,1,substr($res,12));
|
||||||
return;
|
#-- 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;
|
||||||
|
}
|
||||||
#-- 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);
|
||||||
|
#-- OLD OWX interface
|
||||||
|
if( !$master->{ASYNCHRONOUS} ){
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
$res=OWX_Complex($master,$owx_dev,$select,1);
|
$res=OWX_Complex($master,$owx_dev,$select,1);
|
||||||
if( $res eq 0 ){
|
if( $res eq 0 ){
|
||||||
return "device $owx_dev not accessible in writing";
|
return "device $owx_dev not accessible in writing";
|
||||||
}
|
}
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
return OWXSWITCH_BinValues($hash,"ds2413.setstate",1,undef,$owx_dev,undef,undef,substr($res,12));
|
return OWXSWITCH_BinValues($hash,"ds2413.setstate",0,$owx_dev,0,2,substr($res,12));
|
||||||
return;
|
#-- 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;
|
||||||
|
}
|
||||||
}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 <name> interval</code></a><br />Returns measurement interval in
|
<code>get <name> interval</code></a><br />Measurement interval in
|
||||||
seconds. </li>
|
seconds. </li>
|
||||||
<li><a name="owswitch_input">
|
<li><a name="owswitch_input">
|
||||||
<code>get <name> input <channel-name></code></a><br /> state for
|
<code>get <name> input <channel-name></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 <name> gpio</code></a><br />Obtain state of all channels</li>
|
<code>get <name> 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><name> stateS <string></code></a>
|
<li><a name="owswitch_states"><code><name> stateS <string></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 <name> <channel>Name
|
<li><a name="owswitch_cname"><code>attr <name> <channel>Name
|
||||||
<string>[|<string>]</code></a>
|
<string>[|<string>]</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 <name> <channel>Unit
|
<li><a name="owswitch_cunit"><code>attr <name> <channel>Unit
|
||||||
<string>|<string></code></a>
|
<string>|<string></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
|
||||||
|
@ -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 ".
|
||||||
@ -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,13 +375,15 @@ sub OWTHERM_FormatValues($) {
|
|||||||
my $svalue = "";
|
my $svalue = "";
|
||||||
|
|
||||||
#-- attributes defined ?
|
#-- attributes defined ?
|
||||||
$stateal = AttrVal($name,"stateAL","▾");
|
$stateal = AttrVal($name,"stateAL","↓");
|
||||||
$stateah = AttrVal($name,"stateAH","▴");
|
$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 = "";
|
||||||
|
}elsif( $unit eq "Celsius" ){
|
||||||
$abbr = " °C";
|
$abbr = " °C";
|
||||||
} elsif ($unit eq "Kelvin" ){
|
} elsif ($unit eq "Kelvin" ){
|
||||||
$abbr = " K";
|
$abbr = " K";
|
||||||
@ -375,8 +397,7 @@ sub OWTHERM_FormatValues($) {
|
|||||||
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;
|
||||||
|
|
||||||
@ -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,10 +526,13 @@ sub OWTHERM_Get($@) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#-- process results
|
#-- process results
|
||||||
|
if( $master->{ASYNCHRONOUS} ){
|
||||||
|
return "OWTHERM: $name getting values, please wait for completion";
|
||||||
|
}else{
|
||||||
|
#-- when we have a return code, we have an error
|
||||||
if( defined($ret) ){
|
if( defined($ret) ){
|
||||||
return "OWTHERM: Could not get values from device $name, return was $ret";
|
return "OWTHERM: Could not get values from device $name, return was $ret";
|
||||||
}
|
}
|
||||||
|
|
||||||
#-- return the special reading
|
#-- return the special reading
|
||||||
if ($reading eq "temperature") {
|
if ($reading eq "temperature") {
|
||||||
return "OWTHERM: $name.temperature => ".
|
return "OWTHERM: $name.temperature => ".
|
||||||
@ -514,9 +540,11 @@ sub OWTHERM_Get($@) {
|
|||||||
} elsif ($reading eq "alarm") {
|
} elsif ($reading eq "alarm") {
|
||||||
return "OWTHERM: $name.alarm => L ".$main::attr{$name}{"tempLow"}.
|
return "OWTHERM: $name.alarm => L ".$main::attr{$name}{"tempLow"}.
|
||||||
" H ".$main::attr{$name}{"tempHigh"};
|
" H ".$main::attr{$name}{"tempHigh"};
|
||||||
}
|
} else {
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#######################################################################################
|
#######################################################################################
|
||||||
#
|
#
|
||||||
@ -616,8 +644,7 @@ sub OWTHERM_InitializeDevice($) {
|
|||||||
}
|
}
|
||||||
#-- 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1003,34 +1050,50 @@ sub OWXTHERM_GetValues($) {
|
|||||||
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
|
||||||
if( $con==1 ){
|
|
||||||
#-- issue the match ROM command \x55 and the start conversion command \x44
|
#-- 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 ){
|
||||||
|
#-- OLD OWX interface
|
||||||
|
if( !$master->{ASYNCHRONOUS} ){
|
||||||
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 not accessible";
|
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
|
||||||
|
#-- OLD OWX interface
|
||||||
|
if( !$master->{ASYNCHRONOUS} ){
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
my $res=OWX_Complex($master,$owx_dev,"\xBE",9);
|
my $res=OWX_Complex($master,$owx_dev,"\xBE",9);
|
||||||
return "$owx_dev not accessible in reading"
|
return "OWTHERM: $name not accessible in reading"
|
||||||
if( $res eq 0 );
|
if( $res eq 0 );
|
||||||
return "$owx_dev has returned invalid data"
|
return "OWTHERM: $name has returned invalid data"
|
||||||
if( length($res)!=19);
|
if( length($res)!=19);
|
||||||
eval {
|
eval {
|
||||||
OWXTHERM_BinValues($hash,undef,$owx_dev,undef,undef,substr($res,10,9));
|
OWXTHERM_BinValues($hash,undef,$owx_dev,undef,undef,9,substr($res,10,9));
|
||||||
};
|
};
|
||||||
return $@ ? $@ : undef;
|
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);
|
||||||
|
#-- OLD OWX interface
|
||||||
|
if( !$master->{ASYNCHRONOUS} ){
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
my $res=OWX_Complex($master,$owx_dev,$select,3);
|
my $res=OWX_Complex($master,$owx_dev,$select,3);
|
||||||
if( $res eq 0 ){
|
if( $res eq 0 ){
|
||||||
return "OWXTHERM: Device $owx_dev not accessible";
|
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 <name> stateAL <string></code>
|
<li><a name="owtherm_stateAL"><code>attr <name> stateAL <string></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 &#x25BE; leading to the sign ▾ </li>
|
|
||||||
<li><a name="owtherm_stateAH"><code>attr <name> stateAH <string></code>
|
<li><a name="owtherm_stateAH"><code>attr <name> stateAH <string></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 &#x25B4; leading to the sign ▴ </li>
|
|
||||||
<li><a name="owtherm_tempConv">
|
<li><a name="owtherm_tempConv">
|
||||||
<code>attr <name> tempConv onkick|onread</code>
|
<code>attr <name> 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 <name> tempUnit
|
<li><a name="owtherm_tempUnit"><code>attr <name> 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 <name> resolution 9|10|11|12</code></a><br /> Temperature
|
<code>attr <name> 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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user