From fc6db342182bf692b95af8fbf10d5e8f3bd0f6ba Mon Sep 17 00:00:00 2001
From: pahenning <>
Date: Sun, 27 Mar 2016 09:14:38 +0000
Subject: [PATCH] =?UTF-8?q?OWAD.pm:=20Neue=20Version=206.0,=20eingerichtet?=
=?UTF-8?q?=20f=C3=BCr=20asynchrones=20OWX=20OWCOUNT.pm:=20Neue=20Version?=
=?UTF-8?q?=206.0,=20eingerichtet=20f=C3=BCr=20asynchrones=20OWX=20OWID.pm?=
=?UTF-8?q?:=20Neue=20Version=206.0,=20eingerichtet=20f=C3=BCr=20asynchron?=
=?UTF-8?q?es=20OWX=20OWLCD.pm:=20Neue=20Version=206.0,=20eingerichtet=20f?=
=?UTF-8?q?=C3=BCr=20asynchrones=20OWX=20OWMULTI.pm:=20Neue=20Version=206.?=
=?UTF-8?q?0,=20eingerichtet=20f=C3=BCr=20asynchrones=20OWX=20OWSWITCH.pm:?=
=?UTF-8?q?=20Neue=20Version=206.0,=20eingerichtet=20f=C3=BCr=20asynchrone?=
=?UTF-8?q?s=20OWX=20OWTHERM.pm:=20Neue=20Version=206.0,=20eingerichtet=20?=
=?UTF-8?q?f=C3=BCr=20asynchrones=20OWX?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
git-svn-id: https://svn.fhem.de/fhem/trunk@11130 2b470e98-0d58-463d-a4d8-8e2adae1ed80
---
fhem/FHEM/21_OWAD.pm | 348 ++++-----
fhem/FHEM/21_OWCOUNT.pm | 706 +++++++++---------
fhem/FHEM/21_OWID.pm | 15 +-
fhem/FHEM/21_OWLCD.pm | 1479 +++++++++++++++++++++-----------------
fhem/FHEM/21_OWMULTI.pm | 578 +++++++++------
fhem/FHEM/21_OWSWITCH.pm | 543 ++++++++------
fhem/FHEM/21_OWTHERM.pm | 231 +++---
7 files changed, 2270 insertions(+), 1630 deletions(-)
diff --git a/fhem/FHEM/21_OWAD.pm b/fhem/FHEM/21_OWAD.pm
index 28b62e413..2c221a264 100644
--- a/fhem/FHEM/21_OWAD.pm
+++ b/fhem/FHEM/21_OWAD.pm
@@ -36,20 +36,16 @@
#
# attr stateAL0 "" = character string for denoting low normal condition, default is empty
# attr stateAH0 "" = character string for denoting high normal condition, default is empty
-# attr stateAL1 "" = character string for denoting low alarm condition, default is down triangle
-# attr stateAH1 "" = character string for denoting high alarm condition, default is up triangle
+# attr stateAL1 "" = character string for denoting low alarm condition, default is ↓
+# attr stateAH1 "" = character string for denoting high alarm condition, default is ↑
# attr Name [|] = name for the channel [|name used in state reading]
-# attr Unit [|] = unit of measurement for this channel [|unit used in state reading]
-#
-# ATTENTION: Usage of Offset/Factor is deprecated, replace by Function attribute
-# attr Offset = offset added to the reading in this channel
-# attr Factor = factor multiplied to (reading+offset) in this channel
+# attr Unit = unit of measurement for this channel used in state reading (default V, none for empty)
# attr Function = arbitrary functional expression involving the values V=VA,VB,VC,VD
# VA is replaced by the measured voltage in channel A, etc.
#
# attr Alarm = alarm setting in this channel, either both, low, high or none (default)
-# attr Low = measurement value (on the scale determined by offset and factor) for low alarm
-# attr High = measurement value (on the scale determined by offset and factor) for high alarm
+# attr Low = measurement value (on the scale determined by function) for low alarm
+# attr High = measurement value (on the scale determined by function) for high alarm
#
########################################################################################
#
@@ -88,9 +84,9 @@ BEGIN {
use ProtoThreads;
no warnings 'deprecated';
-sub Log($$);
+sub Log3($$$);
-my $owx_version="5.20";
+my $owx_version="6.0";
#-- fixed raw channel name, flexible channel name
my @owg_fixed = ("A","B","C","D");
my @owg_channel = ("A","B","C","D");
@@ -161,15 +157,13 @@ sub OWAD_Initialize ($) {
$hash->{InitFn} = "OWAD_Init";
$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 ".
"interval ".
$readingFnAttributes;
for( my $i=0;$i{NOTIFYDEV} = "global";
@@ -391,11 +385,11 @@ sub OWAD_ChannelNames($) {
my $name = $hash->{NAME};
my $state = $hash->{READINGS}{"state"}{VAL};
- my ($cname,@cnama,$unit,@unarr);
+ my ($cname,@cnama,$unit);
for (my $i=0;$i{READINGS}{$owg_channel[$i]}{ABBR} = $cnama[1];
- $hash->{READINGS}{$owg_channel[$i]}{UNIT} = $unarr[0];
- $hash->{READINGS}{$owg_channel[$i]}{UNITABBR} = $unarr[1];
+ $hash->{READINGS}{$owg_channel[$i]}{UNIT} = $unit;
}
}
@@ -429,7 +423,7 @@ sub OWAD_FormatValues($) {
my $name = $hash->{NAME};
my $interface = $hash->{IODev}->{TYPE};
- my ($offset,$factor,$vval,$vlow,$vhigh,$vfunc,$ret);
+ my ($vval,$vlow,$vhigh,$vfunc,$ret);
my $vfuncall = "";
my $svalue = "";
@@ -445,8 +439,8 @@ sub OWAD_FormatValues($) {
$hash->{ALARM} = 0;
#-- alarm signatures
- my $stateal1 = defined($attr{$name}{stateAL1}) ? $attr{$name}{stateAL1} : "▾";
- my $stateah1 = defined($attr{$name}{stateAH1}) ? $attr{$name}{stateAH1} : "▴";
+ my $stateal1 = defined($attr{$name}{stateAL1}) ? $attr{$name}{stateAL1} : "↓";
+ my $stateah1 = defined($attr{$name}{stateAH1}) ? $attr{$name}{stateAH1} : "↑";
my $stateal0 = defined($attr{$name}{stateAL0}) ? $attr{$name}{stateAL0} : "";
my $stateah0 = defined($attr{$name}{stateAH0}) ? $attr{$name}{stateAH0} : "";
@@ -463,13 +457,7 @@ sub OWAD_FormatValues($) {
#-- formats for output
for (my $i=0;$i{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
$alarm = "none";
@@ -542,6 +530,7 @@ sub OWAD_FormatValues($) {
}
#-- put into READINGS
+ $vval = sprintf( "%5.3f", $vval);
readingsBulkUpdate($hash,"$owg_channel[$i]",$vval);
#-- insert space
if( $i{IODev}->{TYPE};
my ($value,$value2,$value3) = (undef,undef,undef);
my $ret = "";
- my $offset;
- my $factor;
#-- check syntax
return "OWAD: Get argument is missing @a"
@@ -642,17 +629,20 @@ sub OWAD_Get($@) {
return "OWAD: Get with wrong IODev type $interface";
}
- #-- process results
- if( defined($ret) ){
- $hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1;
- if( $hash->{ERRCOUNT} > 5 ){
- $hash->{INTERVAL} = 9999;
+ #-- process result
+ if( $master->{ASYNCHRONOUS} ){
+ return "OWAD: $name getting reading, please wait for completion";
+ }else{
+ if( defined($ret) ){
+ $hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1;
+ if( $hash->{ERRCOUNT} > 5 ){
+ $hash->{INTERVAL} = 9999;
+ }
+ return "OWAD: Could not get values from device $name for ".$hash->{ERRCOUNT}." times, reason $ret";
}
- return "OWAD: Could not get values from device $name for ".$hash->{ERRCOUNT}." times, reason $ret";
+ return "OWAD: $name.reading => ".$hash->{READINGS}{"state"}{VAL};
}
- return "OWAD: $name.reading => ".$hash->{READINGS}{"state"}{VAL};
}
-
#-- get alarm values according to interface type
if($a[1] eq "alarm") {
#-- OWX interface
@@ -671,23 +661,27 @@ sub OWAD_Get($@) {
return "OWAD: Get with wrong IODev type $interface";
}
- #-- process results
- if( defined($ret) ){
- $hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1;
- if( $hash->{ERRCOUNT} > 5 ){
- $hash->{INTERVAL} = 9999;
+ #-- process result
+ if( $master->{ASYNCHRONOUS} ){
+ return "OWAD: $name getting alarm values, please wait for completion";
+ }else{
+ if( defined($ret) ){
+ $hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1;
+ if( $hash->{ERRCOUNT} > 5 ){
+ $hash->{INTERVAL} = 9999;
+ }
+ return "OWAD: Could not get values from device $name for ".$hash->{ERRCOUNT}." times, reason $ret";
}
- return "OWAD: Could not get values from device $name for ".$hash->{ERRCOUNT}." times, reason $ret";
- }
- #-- assemble ouput string
- $value = "";
- for (my $i=0;$i $value";
}
- return "OWAD: $name.alarm => $value";
}
#-- get status values according to interface type
@@ -708,47 +702,51 @@ sub OWAD_Get($@) {
return "OWAD: Get with wrong IODev type $interface";
}
- #-- process results
- if( defined($ret) ){
- $hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1;
- if( $hash->{ERRCOUNT} > 5 ){
- $hash->{INTERVAL} = 9999;
- }
- return "OWAD: Could not get values from device $name for ".$hash->{ERRCOUNT}." times, reason $ret";
- }
+ #-- process result
+ if( $master->{ASYNCHRONOUS} ){
+ return "OWAD: $name getting status, please wait for completion";
+ }else{
+ if( defined($ret) ){
+ $hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1;
+ if( $hash->{ERRCOUNT} > 5 ){
+ $hash->{INTERVAL} = 9999;
+ }
+ return "OWAD: Could not get values from device $name for ".$hash->{ERRCOUNT}." times, reason $ret";
+ }
- #-- assemble output string
- $value = "\n";
- for (my $i=0;$i{owg_slow}->[$i]) {
- $value .= "low alarm undefined, ";
- } elsif( $hash->{owg_slow}->[$i]==0 ) {
- $value .= "low alarm disabled, ";
- } elsif( $hash->{owg_slow}->[$i]==1 ) {
- $value .= "low alarm enabled, ";
- } elsif( $hash->{owg_slow}->[$i]==2 ) {
- $value .= "alarmed low, ";
- }
- if (!defined $hash->{owg_shigh}) {
- $value .= "high alarm undefined";
- } elsif( $hash->{owg_shigh}->[$i]==0 ) {
- $value .= "high alarm disabled";
- } elsif( $hash->{owg_shigh}->[$i]==1 ) {
- $value .= "high alarm enabled";
- } elsif( $hash->{owg_shigh}->[$i]==2 ) {
- $value .= "alarmed high";
- }
- #-- insert space
- if( $i{owg_slow}->[$i]) {
+ $value .= "low alarm undefined, ";
+ } elsif( $hash->{owg_slow}->[$i]==0 ) {
+ $value .= "low alarm disabled, ";
+ } elsif( $hash->{owg_slow}->[$i]==1 ) {
+ $value .= "low alarm enabled, ";
+ } elsif( $hash->{owg_slow}->[$i]==2 ) {
+ $value .= "alarmed low, ";
+ }
+ if (!defined $hash->{owg_shigh}) {
+ $value .= "high alarm undefined";
+ } elsif( $hash->{owg_shigh}->[$i]==0 ) {
+ $value .= "high alarm disabled";
+ } elsif( $hash->{owg_shigh}->[$i]==1 ) {
+ $value .= "high alarm enabled";
+ } elsif( $hash->{owg_shigh}->[$i]==2 ) {
+ $value .= "alarmed high";
+ }
+ #-- insert space
+ if( $i ".$value;
}
- return "OWAD: $name.status => ".$value;
}
}
@@ -939,8 +937,6 @@ sub OWAD_Set($@) {
my $ret = undef;
my $channon = undef;
my $channo = undef;
- my $factor;
- my $offset;
my $condx;
my $name = $hash->{NAME};
@@ -1024,7 +1020,7 @@ sub OWAD_Set($@) {
#-- set alarm values (alarm voltages)
}elsif( $key =~ m/(.*)(Low|High)/ ) {
- #-- find upper and lower boundaries for given offset/factor
+ #-- find upper and lower boundaries
my $mmin = 0.0;
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
+# 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($$$$$$$$) {
- my ($hash, $context, $success, $reset, $owx_dev, $command, $numread, $res) = @_;
+sub OWXAD_BinValues($$$$$$$) {
+ my ($hash, $context, $proc, $owx_dev, $crcpart, $numread, $res) = @_;
- #-- always check for success, unused are reset
- return unless ($success and $context);
- #Log 1,"OWXAD_BinValues context = $context";
- my $final = ($context =~ /\.final$/ );
-
- my ($i,$j,$k,@data,$ow_thn,$ow_tln);
+ #-- 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 );
+
+ my $final = ($context =~ /\.final$/ );
+ my ($ow_thn,$ow_tln);
#-- process results
@data=split(//,$res);
- return "invalid data length, ".int(@data)." instead of 10 bytes"
- if (@data != 10);
- return "invalid CRC"
- if (OWX_CRC16($command.substr($res,0,8),$data[8],$data[9])==0);
-
+ if (@data != 10){
+ $msg="$name returns invalid data length, ".int(@data)." instead of 10 bytes ";
+ }elsif (OWX_CRC16($crcpart.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 ===============================
if( $context =~ /^ds2450.getreading/ ){
- for( $i=0;$i{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 ===============================
} elsif ( $context =~ /^ds2450.getalarm/ ){
- for( $i=0;$i{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;
}
@@ -1406,7 +1426,6 @@ sub OWXAD_BinValues($$$$$$$$) {
$hash->{PRESENT} = 1;
if( $final ){
my $value = OWAD_FormatValues($hash);
- Log 5, $value;
}
return undef
}
@@ -1465,16 +1484,25 @@ sub OWXAD_GetPage($$$@) {
return "wrong memory page requested from $owx_dev";
}
my $context = "ds2450.get".$page.($final ? ".final" : "");
- #-- reset the bus
- OWX_Reset($master);
- #-- reading 9 + 3 + 8 data bytes and 2 CRC bytes = 22 bytes
- $res=OWX_Complex($master,$owx_dev,$select,10);
- return "$owx_dev not accessible in reading page $page"
- if( $res eq 0 );
- return "$owx_dev has returned invalid data"
- if( length($res)!=22);
- #-- for processing we also need the 3 command bytes
- return OWXAD_BinValues($hash,$context,1,undef,$owx_dev,$select,10,substr($res,12,10));
+ #-- OLD OWX interface
+ if( !$master->{ASYNCHRONOUS} ){
+ #-- reset the bus
+ OWX_Reset($master);
+ #-- reading 9 + 3 + 8 data bytes and 2 CRC bytes = 22 bytes
+ $res=OWX_Complex($master,$owx_dev,$select,10);
+ return "$owx_dev not accessible in reading page $page"
+ if( $res eq 0 );
+ return "$owx_dev has returned invalid data"
+ if( length($res)!=22);
+ #-- for processing we also need the 3 command bytes
+ return OWXAD_BinValues($hash,$context,1,undef,$owx_dev,$select,substr($res,12,10));
+ #-- NEW OWX interface
+ }else{
+ #### master slave context proc owx_dev data crcpart numread startread callback delay
+ # 1 additional reset after last action
+ OWX_Qomplex($master, $hash, $context, 1, $owx_dev, $select, $select, 10, 12, \&OWXAD_BinValues, 0);
+ return undef;
+ }
}
########################################################################################
@@ -1542,11 +1570,18 @@ sub OWXAD_SetPage($$) {
} else {
return "wrong memory page write attempt";
}
- OWX_Reset($master);
- $res=OWX_Complex($master,$owx_dev,$select,0);
- if( $res eq 0 ){
- return "device $owx_dev not accessible for writing";
- }
+ #-- OLD OWX interface
+ if( !$master->{ASYNCHRONOUS} ){
+ OWX_Reset($master);
+ $res=OWX_Complex($master,$owx_dev,$select,0);
+ if( $res eq 0 ){
+ return "device $owx_dev not accessible for writing";
+ }
+ #-- NEW OWX interface
+ }else{
+ #### master slave context proc owx_dev data crcpart numread startread callback delay
+ OWX_Qomplex($master, $hash, undef, 0, $owx_dev, $select, 0, 0, 0, undef, 0);
+ }
return undef;
}
@@ -1613,7 +1648,7 @@ sub OWXAD_PT_GetPage($$$) {
PT_WAIT_THREAD($thread->{pt_execute});
die $thread->{pt_execute}->PT_CAUSE() if ($thread->{pt_execute}->PT_STATE() == PT_ERROR);
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) {
die $res;
}
@@ -1716,16 +1751,14 @@ sub OWXAD_PT_SetPage($$) {
attr OWX_AD DAlarm high
- attr OWX_AD DFactor 31.907097
+ attr OWX_AD DName humidity
+
+ attr OWX_AD DUnit %
+
+ attr OWX_AD DFunction VD*31.907097-0.8088
attr OWX_AD DHigh 50.0
- attr OWX_AD DName RelHumidity|humidity
-
- attr OWX_AD DOffset -0.8088
-
- attr OWX_AD DUnit percent|%
-
Define
@@ -1792,46 +1825,31 @@ sub OWXAD_PT_SetPage($$) {
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,
- e.g. the code ▾ leading to the sign ▾
+
character string for denoting low alarm condition, default is ↓
attr <name> stateAH1 <string>
-
character string for denoting high alarm condition, default is upward
- triangle, e.g. the code ▴ leading to the sign ▴
+
character string for denoting high alarm condition, default is ↑
For each of the following attributes, the channel identification A,B,C,D may be used.
attr <name> <channel>Name
<string>[|<string>]
-
name for the channel [|name used in state reading].
+
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].
- - deprecated:
attr <name> <channel>Offset
- <float>
-
offset added to the reading in this channel.
- - deprecated:
attr <name> <channel>Factor
- <float>
-
factor multiplied to (reading+offset) in this channel.
+ <string>
+
unit of measurement for this channel used in state reading (default "V", set to "none" for empty).
-
attr <name> <channel>Function
<string>
-
arbitrary functional expression involving the values VA,VB,VC,VD. VA is replaced by
- the measured voltage in channel A, etc. This attribute allows linearization of measurement
- curves as well as the mixing of various channels. Replacement for Offset/Factor !
+
arbitrary functional expression involving the variables VA,VB,VC,VD. VA is replaced by
+ the (raw) measured voltage in channel A, etc. This attribute allows linearization of measurement
+ curves as well as the mixing of various channels.
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.
+
measurement value for low alarm.
attr <name> <channel>High
<float>
-
measurement value (on the scale determined by offset and factor) for high
- alarm.
- - Standard attributes alias, comment, event-on-update-reading, event-on-change-reading, stateFormat, room, eventMap, verbose,
- webCmd
+
measurement value for highalarm.
+ - readingFnAttributes
=end html
diff --git a/fhem/FHEM/21_OWCOUNT.pm b/fhem/FHEM/21_OWCOUNT.pm
index f6905d65f..34154d1a6 100644
--- a/fhem/FHEM/21_OWCOUNT.pm
+++ b/fhem/FHEM/21_OWCOUNT.pm
@@ -44,9 +44,9 @@
# attr LogM = device name (not file name) of monthly log file
# attr LogY = device name (not file name) of yearly log file
# attr nomemory = 1|0 (when set to 1, disables use of internal memory)
-# attr Name [|] = name for the channel [|name used in state reading]
-# attr Unit [|] = unit of measurement for this channel [|unit used in state reading]
-# attr Rate [|] = name for the channel rate [|name used in state reading]
+# attr Name [|] = name for the channel [|short name used in state reading]
+# attr Unit = unit of measurement used in state reading (default cts, none for empty)
+# attr Rate [|] = name for the channel rate [|short name used in state reading]
# attr Offset = offset added to the reading in this channel
# attr Factor = factor multiplied to (reading+offset) in this channel
# attr Mode = counting mode = normal(default) or daily
@@ -99,11 +99,13 @@ no warnings 'deprecated';
sub Log3($$$);
-my $owx_version="5.33";
+my $owx_version="6.0";
#-- fixed raw channel name, flexible channel name
my @owg_fixed = ("A","B");
my @owg_channel = ("A","B");
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 = (
"id" => "",
@@ -229,13 +231,16 @@ sub OWCOUNT_Define ($$) {
if( $model eq "DS2423" ){
$fam = "1D";
CommandAttr (undef,"$name model DS2423");
+ @owg_memory = (1,1,0);
}elsif( $model eq "DS2423enew" ){
$fam = "1D";
+ @owg_memory = (1,1,0);
CommandAttr (undef,"$name model DS2423enew");
}elsif( $model eq "DS2423eold" ){
$fam = "1D";
CommandAttr (undef,"$name model DS2423eold");
CommandAttr (undef,"$name nomemory 1");
+ @owg_memory = (0,0,0);
}else{
return "OWCOUNT: Wrong 1-Wire device model $model";
}
@@ -264,7 +269,7 @@ sub OWCOUNT_Define ($$) {
$modules{OWCOUNT}{defptr}{$id} = $hash;
#--
readingsSingleUpdate($hash,"state","defined",1);
- Log3 $name, 3, "OWCOUNT: Device $name defined.";
+ Log3 $name, 3, "OWCOUNT: Device $name defined.";
$hash->{NOTIFYDEV} = "global";
@@ -301,12 +306,61 @@ sub OWCOUNT_Notify ($$) {
sub OWCOUNT_Init ($) {
my ($hash)=@_;
+
#-- Start timer for updates
RemoveInternalTimer($hash);
InternalTimer(gettimeofday()+10, "OWCOUNT_GetValues", $hash, 0);
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{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
@@ -369,56 +423,56 @@ sub OWCOUNT_ChannelNames($) {
for (my $i=0;$i{READINGS}{$owg_channel[$i]}{ABBR} = $cnama[1];
- $hash->{READINGS}{$owg_channel[$i]}{UNIT} = $unarr[0];
- $hash->{READINGS}{$owg_channel[$i]}{UNITABBR} = $unarr[1];
+ $hash->{READINGS}{$owg_channel[$i]}{UNIT} = $unit;
$period = defined($attr{$name}{$owg_fixed[$i]."Period"}) ? $attr{$name}{$owg_fixed[$i]."Period"} : "hour";
#-- put into readings
$hash->{READINGS}{$owg_channel[$i]}{PERIOD} = $period;
#-- 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);
if( int(@cnama)!=2){
push(@cnama,$cnama[0]);
}
#-- rate unit
- my $runit = "";
- if( $period eq "hour" ){
- $runit = "/h";
- }elsif( $period eq "minute" ){
- $runit = "/min";
- } else {
- $runit = "/s";
+ if( $unit ne " " ){
+ if( $period eq "hour" ){
+ $unit .= "/h";
+ }elsif( $period eq "minute" ){
+ $unit .= "/min";
+ } else {
+ $unit .= "/s";
+ }
}
+
+ #-- some special cases
+ # Energy/Power
+ $unit = " kW"
+ if ($unit 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} = $unarr[0].$runit;
- $hash->{READINGS}{$owg_rate[$i]}{UNITABBR} = $unarr[1].$runit;
-
- #-- some special cases
- # Energy/Power
- $hash->{READINGS}{$owg_rate[$i]}{UNIT} = "kW"
- if ($unarr[0].$runit eq "kWh/h" );
- $hash->{READINGS}{$owg_rate[$i]}{UNITABBR} = "kW"
- if ($unarr[1].$runit eq "kWh/h" );
+ $hash->{READINGS}{$owg_rate[$i]}{UNIT} = $unit;
}
}
@@ -467,9 +521,34 @@ sub OWCOUNT_FormatValues($) {
}
}
- #-- put into READINGS
+ #-- put into READING
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
for (my $i=0;$i{READINGS}{$owg_channel[$i]}{OFFSET} = $offset;
$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};
- $runit = $hash->{READINGS}{$owg_rate[$i]}{UNITABBR};
+ $runit = $hash->{READINGS}{$owg_rate[$i]}{UNIT};
#-- skip some things if undefined
if( $hash->{owg_val}->[$i] eq ""){
- $svalue .= $owg_channel[$i].": ???";
+ $svalue .= $owg_channel[$i]." ???";
}else{
#-- only if attribute value mode=daily, take the midnight value from memory
if( $daily == 1){
@@ -555,6 +634,7 @@ sub OWCOUNT_FormatValues($) {
my $msg = sprintf("%4d-%02d-%02d midnight %7.2f",
$year+1900,$month+1,$day,$dval2);
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
$dvalue .= sprintf( " %s: %5.2f %s %sM: %%5.2f %s", $owg_channel[$i],$dval,$unit,$owg_channel[$i],$unit);
@@ -563,7 +643,7 @@ sub OWCOUNT_FormatValues($) {
#-- string buildup for return value and STATE
#-- 1 or 3 decimals
- my $fs = ( $factor == 1.0 )? "%s: %5.2f %s %s: %5.2f %s":"%s: %5.3f %s %s: %5.3f %s";
+ my $fs = ( $factor == 1.0 )? "%s: %5.2f %s %s: %5.2f %s" : "%s: %5.3f %s %s: %5.3f %s";
$svalue .= sprintf( $fs, $hash->{READINGS}{$owg_channel[$i]}{ABBR}, $vval,$unit,$hash->{READINGS}{$owg_rate[$i]}{ABBR},$vrate,$runit);
#-- 3 decimals
}
@@ -585,7 +665,7 @@ sub OWCOUNT_FormatValues($) {
#-- put in monthly and yearly sums
if( int(@monthv) == 2 ){
$total0 = $monthv[0]->[1];
- $total1 = $monthv[1]->[1];
+ $total1 = ($day==1)?$total0:$monthv[1]->[1];
$dvalue = sprintf("D%02d ",$day).$dvalue;
$dvalue = sprintf($dvalue,$total0,$total1);
readingsBulkUpdate($hash,"day",$dvalue);
@@ -597,7 +677,7 @@ sub OWCOUNT_FormatValues($) {
if( int(@yearv) == 2 ){
$total2 = $yearv[0]->[1];
- $total3 = $yearv[1]->[1];
+ $total3 = ($month==0)?$total2: $yearv[1]->[1];
if ( $monthbreak == 1){
$mvalue = sprintf("M%02d ",$month+1).$mvalue;
$mvalue = sprintf($mvalue,$total0,$total2,$total1,$total3);
@@ -631,6 +711,7 @@ sub OWCOUNT_Get($@) {
my $reading = $a[1];
my $name = $hash->{NAME};
my $model = $hash->{OW_MODEL};
+ my $master = $hash->{IODev};
my $value = undef;
my $ret = "";
my $page;
@@ -655,18 +736,20 @@ sub OWCOUNT_Get($@) {
if($a[1] eq "present") {
#-- hash of the busmaster
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 {
OWX_ASYNC_RunToCompletion($hash,OWX_ASYNC_PT_Verify($hash));
};
return GP_Catch($@) if $@;
return "$name.present => ".ReadingsVal($name,"present","unknown");
- } else {
- $value = OWX_Verify($master,$hash->{ROM_ID});
}
- $hash->{PRESENT} = $value;
- return "$name.present => $value";
}
#-- get interval
@@ -733,7 +816,7 @@ sub OWCOUNT_Get($@) {
$value .= $owg_channel[$i]."Y: ".$year2[$i]->[1]." ".$unit.
" (yearly sum until now, average ".$year2[$i]->[2]." ".$unit."/d)\n";
}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;
@@ -754,11 +837,16 @@ sub OWCOUNT_Get($@) {
return "OWCOUNT: Wrong memory page requested";
}
$ret = OWCOUNT_GetPage($hash,$page,1,1);
- #-- when we have a return code, we have an error
- if( $ret ){
- return "OWCOUNT: Could not get values from device $name, reason: ".$ret;
+ #-- process result
+ if( $master->{ASYNCHRONOUS} ){
+ return "OWCOUNT: $name getting memory $page, please wait for completion";
}else{
- return "OWCOUNT: $name.$reading [$page] =>".$hash->{owg_str}->[$page];
+ #-- when we have a return code, we have an error
+ if( $ret ){
+ return "OWCOUNT: Could not get values from device $name, reason: ".$ret;
+ }else{
+ return "OWCOUNT: $name.$reading [$page] =>".$hash->{owg_str}->[$page];
+ }
}
}
if( $reading eq "midnight" ){
@@ -773,11 +861,16 @@ sub OWCOUNT_Get($@) {
return "OWCOUNT: Invalid midnight counter address, must be A, B or defined channel name"
}
$ret = OWCOUNT_GetPage($hash,$page,1,1);
- #-- when we have a return code, we have an error
- if( $ret ){
- return "OWCOUNT: Could not get values from device $name, reason: ".$ret;
+ #-- process result
+ if( $master->{ASYNCHRONOUS} ){
+ return "OWCOUNT: $name getting midnight value $page and counter, please wait for completion";
}else{
- return "OWCOUNT: $name.$reading [$page] =>".$hash->{owg_midnight}->[$page-14];
+ #-- when we have a return code, we have an error
+ if( $ret ){
+ return "OWCOUNT: Could not get values from device $name, reason: ".$ret;
+ }else{
+ return "OWCOUNT: $name.$reading [$page] =>".$hash->{owg_midnight}->[$page-14];
+ }
}
}
@@ -794,30 +887,37 @@ sub OWCOUNT_Get($@) {
return "OWCOUNT: Invalid counter address, must be A, B or defined channel name"
}
$ret = OWCOUNT_GetPage($hash,$page,1,1);
- #-- when we have a return code, we have an error
- if( $ret ){
- return "OWCOUNT: Could not get values from device $name, reason: ".$ret;
- }
- #-- only one counter will be returned
- return "OWCOUNT: $name.raw $a[2] => ".$hash->{owg_val}->[$page-14];
-
+ #-- 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
+ if( $ret ){
+ return "OWCOUNT: Could not get values from device $name, reason: ".$ret;
+ }
+ #-- only one counter will be returned
+ return "OWCOUNT: $name.raw $a[2] => ".$hash->{owg_val}->[$page-14];
+ }
#-- check syntax for getting counters
}elsif( $reading eq "counters" ){
return "OWCOUNT: Get needs no parameter when reading counters"
if( int(@a)==1 );
$ret1 = OWCOUNT_GetPage($hash,14,0,1);
$ret2 = OWCOUNT_GetPage($hash,15,1,1);
-
- #-- process results
- $ret .= $ret1
- if( defined($ret1) );
- $ret .= $ret2
- if( defined($ret2) );
- if( defined($ret1) || defined($ret2) ){
- return "OWCOUNT: Could not get values from device $name, reason: ".$ret;
+ #-- process result
+ if( $master->{ASYNCHRONOUS} ){
+ return "OWCOUNT: $name getting counters, please wait for completion";
+ }else{
+ $ret .= $ret1
+ if( defined($ret1) );
+ $ret .= $ret2
+ if( defined($ret2) );
+ if( defined($ret1) || defined($ret2) ){
+ return "OWCOUNT: Could not get values from device $name, reason: ".$ret;
+ }
+ #-- both counters will be returned
+ return "OWCOUNT: $name.counters => ".$hash->{READINGS}{"state"}{VAL};
}
- #-- both counters will be returned
- return "OWCOUNT: $name.counters => ".$hash->{READINGS}{"state"}{VAL};
}
}
@@ -926,7 +1026,7 @@ sub OWCOUNT_GetMonth($) {
@linarr = split(' ',$line);
if( int(@linarr)==4+6*int(@owg_fixed) ){
$day = $linarr[3];
- $day =~ s/D_0+//;
+ $day =~ s/D_+0+//;
@mchannel = ();
for (my $i=0;$i0);
};
-
- #-- add data from current day also for non-summed mode
- $total = int($total*100)/100;
- $total2 = int(100*($total+$month2[$i]->[1]))/100;
+ $total = int($total*100)/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
my $deltim = $cyday+($chour+$cmin/60.0 + $csec/3600.0)/24.0;
my $av = $deltim>0 ? int(100*$total2/$deltim)/100 : -1;
@@ -1094,7 +1194,7 @@ sub OWCOUNT_GetValues($) {
#-- check if device needs to be initialized
OWCOUNT_InitializeDevice($hash)
if( $hash->{READINGS}{"state"}{VAL} eq "defined");
-
+
#-- restart timer for updates
RemoveInternalTimer($hash);
InternalTimer(time()+$hash->{INTERVAL}, "OWCOUNT_GetValues", $hash, 0);
@@ -1111,106 +1211,6 @@ sub OWCOUNT_GetValues($) {
if( $ret ne "" ){
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{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;
}
@@ -1315,7 +1315,7 @@ sub OWCOUNT_Set($@) {
$data.=" ".$a[$i];
}
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);
}elsif( length($data) < 32 ){
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];
$data = sprintf("%4d-%02d-%02d midnight %7.2f",
$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);
}
}
@@ -1447,12 +1447,12 @@ sub OWCOUNT_store($$$) {
} else {
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
#
@@ -1470,8 +1470,18 @@ sub OWCOUNT_recall($$) {
close(OWXFILE);
return $line;
}
- Log3 $name,1, "OWCOUNT_recall: Cannot open $filename for reading!";
- return undef;;
+ Log3 $name,1, "OWCOUNT_recall: Cannot open $filename for reading, 2nd attempt";
+ $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
# via OWFS
#
+# TODO: So far no automatic recognition of DS2423 / Emulator
+#
# Prefix = OWFSCOUNT
#
########################################################################################
@@ -1603,76 +1615,125 @@ sub OWFSCOUNT_SetPage($$$) {
# OWXCOUNT_BinValues - Process reading from one device - translate binary into raw
#
# 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($$$$$) {
- my ($hash, $context, $owx_dev, $select, $res) = @_;
+sub OWXCOUNT_BinValues($$$$$$$) {
+ my ($hash, $context, $proc, $owx_dev, $crcpart, $numread, $res) = @_;
- #-- unused are success, reset, data
-
- return undef unless (defined $context and $context =~ /^(get|set)page\.([\d]+)(\.final|)$/);
+ #-- hash of the busmaster
+ my $master = $hash->{IODev};
+ 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 $page = $2;
my $final = $3;
- my $name = $hash->{NAME};
-
- Log3 ($name,5,"OWXCount_BinValues context: $context, $cmd page: $page, final: ".(defined $final ? $final : "undef"));
-
+ #=============== get memory + counter ===============================
if ($cmd eq "get") {
- my ($i,$j,$k,@data,@writedata,$strval,$value);
+ my (@data,$strval,$value);
my $change = 0;
+ @data=split(//,$res);
#-- process results
- @data=split(//,$res);
- @writedata = split(//,$select);
- return "invalid data length, ".int(@data)." instead of 42 bytes in three steps"
- if( int(@data) < 42);
- #return "invalid data"
- # if (ord($data[17])<=0);
- return "invalid CRC, ".ord($data[40])." ".ord($data[41])
- if (OWX_CRC16($select.substr($res,0,40),$data[40],$data[41]) == 0);
-
- #-- first 3 command, next 32 are memory
- #my $res2 = "OWCOUNT FIRST 10 BYTES for device $owx_dev ARE ";
- #for($i=0;$i<10;$i++){
- # $j=int(ord(substr($res,$i,1))/16);
- # $k=ord(substr($res,$i,1))%16;
- # $res2.=sprintf "0x%1x%1x ",$j,$k;
- #}
- #main::Log(1, $res2);
+ if(ord($data[17])<=0){
+ #-- invalid data: do not die, but change memory flags
+ if( $page > 13 ){
+ $owg_memory[1]=0;
+ }else{
+ $owg_memory[0]=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;
+ }
+
+ if( int(@data) < 42){
+ $msg="$name returns invalid data length, ".int(@data)." instead of 42 bytes";
+ }elsif (OWX_CRC16($crcpart.substr($res,0,40),$data[40],$data[41]) == 0){
+ $msg="$name returns invalid CRC, ".ord($data[40])." ".ord($data[41]);
+ }
+ OWX_WDBG($name,"OWXCOUNT_BinValues: ".$msg,"")
+ if( $main::owx_debug>2 );
#--
my $nomemory = defined($attr{$name}{"nomemory"}) ? $attr{$name}{"nomemory"} : 0;
if( $nomemory==0 ){
#-- memory part, treated as string
$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 {
$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 : "";
#-- counter part
if( ($page == 14) || ($page == 15) ){
@data=split(//,substr($res,32));
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]);
- return "device $owx_dev returns invalid data";
+ OWX_WDBG($name, "device $name returns invalid data ".ord($data[4])." ".ord($data[5])." ".ord($data[6])." ".ord($data[7])," ");
}
#-- counter value
$value = (ord($data[3])<<24) + (ord($data[2])<<16) +(ord($data[1])<<8) + ord($data[0]);
$hash->{owg_val}->[$page-14] = $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);
}
#-- and now from raw to formatted values
$hash->{PRESENT} = 1;
if( $final ) {
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;
}
@@ -1699,8 +1760,6 @@ sub OWXCOUNT_GetPage($$$) {
#-- reset presence
$hash->{PRESENT} = 0;
- my ($i,$j,$k);
-
#=============== wrong value requested ===============================
if( ($page<0) || ($page>15) ){
return "wrong memory page requested";
@@ -1713,33 +1772,45 @@ sub OWXCOUNT_GetPage($$$) {
$select=sprintf("\xA5%c%c",$ta1,$ta2);
my $context = "getpage.".$page.($final ? ".final" : "");
- #-- reset the bus
- OWX_Reset($master);
- #-- reading 9 + 3 + 40 data bytes (32 byte memory, 4 byte counter + 4 byte zeroes) and 2 CRC bytes = 54 bytes
- $res=OWX_Complex($master,$owx_dev,$select,42);
- if( $res eq 0 ){
- return "device $owx_dev not accessible in reading page $page";
- }
- #-- process results
- if( length($res) < 54 ) {
- #Log 1, "OWXCOUNT: warning, have received ".length($res)." bytes in first step";
- #-- read the data in a second step
- $res.=OWX_Complex($master,"","",0);
+ #-- OLD OWX interface
+ if( !$master->{ASYNCHRONOUS} ){
+ #-- reset the bus
+ OWX_Reset($master);
+ #-- reading 9 + 3 + 40 data bytes (32 byte memory, 4 byte counter + 4 byte zeroes) and 2 CRC bytes = 54 bytes
+ $res=OWX_Complex($master,$owx_dev,$select,42);
+ if( $res eq 0 ){
+ return "device $owx_dev not accessible in reading page $page";
+ }
#-- process results
if( length($res) < 54 ) {
- #Log 1, "OWXCOUNT: warning, have received ".length($res)." bytes in second step";
- #-- read the data in a third step
+ #Log 1, "OWXCOUNT: warning, have received ".length($res)." bytes in first step";
+ #-- read the data in a second step
$res.=OWX_Complex($master,"","",0);
- }
- }
- #-- reset the bus (needed to stop receiving data ?)
- OWX_Reset($master);
- #-- for processing we need 45 bytes
- return "$owx_dev not accessible in reading"
- if( $res eq 0 );
- return "$owx_dev has returned invalid data"
- if( length($res)!=54);
- return OWXCOUNT_BinValues($hash,$context,$owx_dev,$select,substr($res,12));
+ #-- process results
+ if( length($res) < 54 ) {
+ #Log 1, "OWXCOUNT: warning, have received ".length($res)." bytes in second step";
+ #-- read the data in a third step
+ $res.=OWX_Complex($master,"","",0);
+ }
+ }
+ #-- reset the bus (needed to stop receiving data ?)
+ OWX_Reset($master);
+ #-- for processing we need 45 bytes
+ return "$owx_dev not accessible in reading"
+ if( $res eq 0 );
+ return "$owx_dev has returned invalid data"
+ if( length($res)!=54);
+ 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
#
# 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 ($i,$j,$k);
-
#-- ID of the device, hash of the busmaster
my $owx_dev = $hash->{ROM_ID};
my $master = $hash->{IODev};
@@ -1778,64 +1848,59 @@ sub OWXCOUNT_SetPage($$$) {
my $ta1 = ($page*32) & 255;
#Log 1, "OWXCOUNT: setting page Nr. $ta2 $ta1 $data";
$select=sprintf("\x0F%c%c",$ta1,$ta2).$data;
-
- #-- first command, next 2 are address, then data
- #$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
- OWX_Reset($master);
- $res=OWX_Complex($master,$owx_dev,$select,0);
- if( $res eq 0 ){
- return "device $owx_dev not accessible in writing scratchpad";
- }
-
- #-- issue the match ROM command \x55 and the read scratchpad command
- # \xAA, receiving 2 address bytes, 1 status byte and scratchpad content
- $select = "\xAA";
- #-- reset the bus
- OWX_Reset($master);
- #-- reading 9 + 3 + up to 32 bytes
- # TODO: sometimes much less than 28
- $res=OWX_Complex($master,$owx_dev,$select,28);
- if( length($res) < 13 ){
- return "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
- # \x5A followed by 3 byte authentication code obtained in previous read
- $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
- OWX_Reset($master);
- $res=OWX_Complex($master,$owx_dev,$select,6);
-
- #-- process results
- if( $res eq 0 ){
- return "device $owx_dev not accessible for copying scratchpad";
- }
+ #-- OLD OWX interface
+ if( !$master->{ASYNCHRONOUS} ){
+ #-- reset the bus
+ OWX_Reset($master);
+ $res=OWX_Complex($master,$owx_dev,$select,0);
+ if( $res eq 0 ){
+ return "OWCOUNT: device $owx_dev not accessible in writing scratchpad";
+ }
+ #-- issue the match ROM command \x55 and the read scratchpad command
+ # \xAA, receiving 2 address bytes, 1 status byte and scratchpad content
+ $select = "\xAA";
+ #-- reset the bus
+ OWX_Reset($master);
+ #-- reading 9 + 3 + up to 32 bytes
+ # TODO: sometimes much less than 28
+ $res=OWX_Complex($master,$owx_dev,$select,28);
+ if( length($res) < 13 ){
+ return "OWCOUNT: device $owx_dev not accessible in reading scratchpad";
+ }
+ #-- issue the match ROM command \x55 and the copy scratchpad command
+ # \x5A followed by 3 byte authentication code obtained in previous read
+ $select="\x5A".substr($res,10,3);
+ #-- reset the bus
+ OWX_Reset($master);
+ $res=OWX_Complex($master,$owx_dev,$select,6);
+ #-- process results
+ if( $res eq 0 ){
+ 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;
}
@@ -1885,7 +1950,7 @@ sub OWXCOUNT_PT_GetPage($$$) {
PT_WAIT_THREAD($thread->{pt_execute});
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;
}
PT_END;
@@ -2026,13 +2091,13 @@ sub OWXCOUNT_PT_InitializeDevicePage($$$) {
Example
define OWC OWCOUNT 1D.CE780F000000 60
- attr OWC AName Energie|energy
+ attr OWC AName energy|W
- attr OWC AUnit kWh|kWh
+ attr OWC AUnit kWh
attr OWC APeriod hour
- attr OWC ARate Leistung|power
+ attr OWC ARate power|P
attr OWX_AMode daily
@@ -2138,13 +2203,13 @@ sub OWXCOUNT_PT_InitializeDevicePage($$$) {
attr <name> <channel>Name
<string>[|<string>]
-
name for the channel [|name used in state reading].
+
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.]
+ <string&
+
unit of measurement used in state reading (default "cts", set to "none" for empty).
attr <name> <channel>Rate
<string>[|<string>]
-
name for the channel rate [|name used in state reading]
+
name for the channel rate [|short name used in state reading]
attr <name> <channel>Offset
<float>
offset added to the reading in this channel.
@@ -2157,12 +2222,7 @@ sub OWXCOUNT_PT_InitializeDevicePage($$$) {
attr <name> <channel>Period hour(default) | minute |
second
period for rate calculation
- - Standard attributes alias, comment, event-on-update-reading, event-on-change-reading, stateFormat, room, eventMap, verbose,
- webCmd
+ - readingFnAttributes
=end html
diff --git a/fhem/FHEM/21_OWID.pm b/fhem/FHEM/21_OWID.pm
index 3795c2c82..d3728513b 100644
--- a/fhem/FHEM/21_OWID.pm
+++ b/fhem/FHEM/21_OWID.pm
@@ -66,9 +66,9 @@ BEGIN {
use GPUtils qw(:all);
use ProtoThreads;
no warnings 'deprecated';
-sub Log($$);
+sub Log3($$$);
-my $owx_version="5.15";
+my $owx_version="6.0beta6";
#-- declare variables
my %gets = (
"present" => "",
@@ -107,8 +107,7 @@ sub OWID_Initialize ($) {
$hash->{AttrFn} = "OWID_Attr";
$hash->{NotifyFn} = "OWID_Notify";
$hash->{InitFn} = "OWID_Init";
- $hash->{AttrList} = "IODev do_not_notify:0,1 showtime:0,1 model loglevel:0,1,2,3,4,5 ".
- "interval ".
+ $hash->{AttrList} = "IODev do_not_notify:0,1 showtime:0,1 model interval".
$readingFnAttributes;
#--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;
#--
readingsSingleUpdate($hash,"state","Defined",1);
- Log 3, "OWID: Device $name defined.";
+ Log3 $name,1, "OWID: Device $name defined.";
$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
#
@@ -531,6 +530,10 @@ sub OWID_Undef ($) {
Returns 1 if this 1-Wire device is present, otherwise 0.
+ Attributes
+
=end html
=cut
diff --git a/fhem/FHEM/21_OWLCD.pm b/fhem/FHEM/21_OWLCD.pm
index 1392e6242..82f6a904e 100644
--- a/fhem/FHEM/21_OWLCD.pm
+++ b/fhem/FHEM/21_OWLCD.pm
@@ -36,6 +36,8 @@
# set reset => reset the display
# set test => display a test content
#
+# attr lcdgeometry => LCD geometry values are 0-32-64-96 or 0-64-20-84
+#
# Careful: Not ASCII ! strange Codepage
########################################################################################
#
@@ -77,15 +79,15 @@ no warnings 'deprecated';
sub Log3($$$);
-my $owx_version="5.3";
+my $owx_version="6.0beta6";
#-- controller may be HD44780 or KS0073
# these values have to be changed for different display
# geometries or memory maps
my $lcdcontroller = "KS0073";
my $lcdlines = 4;
my $lcdchars = 20;
-my @lcdpage = (0,32,64,96);
-#my @lcdpage = (0,64,20,84);
+
+my @lcdpage = (0,32,64,96);
#-- declare variables
my %gets = (
@@ -137,7 +139,8 @@ sub OWLCD_Initialize ($) {
$hash->{InitFn} = "OWLCD_Init";
$hash->{AttrFn} = "OWLCD_Attr";
my $attlist = "IODev do_not_notify:0,1 showtime:0,1 ".
- "";
+ "lcdgeometry:0-32-64-96,0-64-20-84 ".
+ $readingFnAttributes;
$hash->{AttrList} = $attlist;
#-- make sure OWX is loaded so OWX_CRC is available if running with OWServer
@@ -208,6 +211,14 @@ sub OWLCD_Define ($$) {
return undef;
}
+########################################################################################
+#
+# OWLCD_Notify - Implements Notify function
+#
+# Parameter hash = hash of device addressed
+#
+########################################################################################
+
sub OWLCD_Notify ($$) {
my ($hash,$dev) = @_;
if( grep(m/^(INITIALIZED|REREADCFG)$/, @{$dev->{CHANGED}}) ) {
@@ -216,6 +227,14 @@ sub OWLCD_Notify ($$) {
}
}
+########################################################################################
+#
+# OWLCD_Init - Implements Init function
+#
+# Parameter hash = hash of device addressed
+#
+########################################################################################
+
sub OWLCD_Init($) {
my ($hash) = @_;
#-- Initialization reading according to interface type
@@ -275,6 +294,14 @@ sub OWLCD_Attr(@) {
}
last;
};
+ $key eq "lcdgeometry" and do {
+ if( $value eq "0-32-64-96" ){
+ @lcdpage = (0,32,64,96);
+ }elsif( $value eq "0-64-20-84" ){
+ @lcdpage = (0,64,20,84);
+ }
+ last;
+ };
};
#} elsif ( $do eq "del" ) {
# ARGUMENT_HANDLER: {
@@ -298,6 +325,7 @@ sub OWLCD_Get($@) {
my $reading = $a[1];
my $name = $hash->{NAME};
my $model = $hash->{OW_MODEL};
+ my $master = $hash->{IODev};
my $value = undef;
my $ret = "";
my $offset;
@@ -347,7 +375,12 @@ sub OWLCD_Get($@) {
return "$name.gpio => ".main::ReadingsVal($hash->{NAME},"gpio","");
} else {
$value = OWXLCD_Get($hash,"gpio");
- return "$name.gpio => $value";
+ #-- process result
+ if( $master->{ASYNCHRONOUS} ){
+ return "OWLCD: $name getting gpio, please wait for completion";
+ }else{
+ return "$name.gpio => $value";
+ }
}
}
@@ -362,7 +395,12 @@ sub OWLCD_Get($@) {
return "$name.counter => ".main::ReadingsVal($hash->{NAME},"counter","");
} else {
$value = OWXLCD_Get($hash,"counter");
- return "$name.counter => $value";
+ #-- process result
+ if( $master->{ASYNCHRONOUS} ){
+ return "OWLCD: $name getting counter, please wait for completion";
+ }else{
+ return "$name.counter => $value";
+ }
}
}
@@ -377,14 +415,18 @@ sub OWLCD_Get($@) {
return "$name.gpio => ".main::ReadingsVal($hash->{NAME},"version","");
} else {
$value = OWXLCD_Get($hash,"version");
- return "$name.version => $owx_version (LCD firmware $value)";
+ #-- process result
+ if( $master->{ASYNCHRONOUS} ){
+ return "OWLCD: $name getting version, please wait for completion";
+ }else{
+ return "$name.version => $owx_version (LCD firmware $value)";
+ }
}
}
#-- get EEPROM content
if($a[1] eq "memory") {
my $page = (defined $a[2] and $a[2] =~ m/\d/) ? int($a[2]) : 0;
- Log3 $name,1,"Calling GetMemory with page $page";
if ($hash->{ASYNC}) {
eval {
$ret = OWX_ASYNC_RunToCompletion($hash,OWXLCD_PT_GetMemory($hash,$page));
@@ -394,7 +436,12 @@ sub OWLCD_Get($@) {
return "$name $reading $page => ".main::ReadingsVal($hash->{NAME},"memory$page","");
} else {
$value = OWXLCD_GetMemory($hash,$page);
- return "$name $reading $page => $value";
+ #-- process result
+ if( $master->{ASYNCHRONOUS} ){
+ return "OWLCD: $name memory page $page, please wait for completion";
+ }else{
+ return "$name $reading $page => $value";
+ }
}
}
}
@@ -660,8 +707,7 @@ sub OWLCD_Set($@) {
if( (0 > $line) || ($line > 6) );
return "OWLCD: Wrong line length, must be <=16 "
if( length($value) > 16 );
- #-- check value and write to device
- Log3 $name,1,"Calling SetMemory with page $line";
+ #-- write to device
if ($hash->{ASYNC}) {
eval {
OWX_ASYNC_Schedule( $hash, OWXLCD_PT_SetMemory($hash, $line, $value) );
@@ -755,334 +801,6 @@ sub OWLCD_Undef ($) {
return undef;
}
-########################################################################################
-#
-# OWXLCD_Byte - write a single byte to the LCD device
-#
-# Parameter hash = hash of device addressed
-# cmd = register or data
-# byte = byte
-#
-########################################################################################
-
-sub OWXLCD_Byte($$$) {
-
- my ($hash,$cmd,$byte) = @_;
-
- my ($select, $select2, $res, $res2, $res3, @data);
-
- #-- ID of the device
- my $owx_dev = $hash->{ROM_ID};
- my $owx_rnf = substr($owx_dev,3,12);
- my $owx_f = substr($owx_dev,0,2);
-
- #-- hash of the busmaster
- my $master = $hash->{IODev};
-
- my ($i,$j,$k);
-
- #=============== write to LCD register ===============================
- if ( $cmd eq "register" ) {
- #-- issue the read LCD register command \x10
- $select = sprintf("\x10%c",$byte);
- #=============== write to LCD data ===============================
- }elsif ( $cmd eq "data" ) {
- #-- issue the read LCD data command \x12
- $select = sprintf("\x12%c",$byte);
- #=============== wrong value requested ===============================
- } else {
- return "OWXLCD: Wrong byte write attempt";
- }
-
- #-- write to device
- OWX_Reset($master);
- $res=OWX_Complex($master,$owx_dev,$select,0);
- #-- process results
- if( $res eq 0 ){
- return "OWLCD: Device $owx_dev not accessible for writing a byte";
- }
-
- return undef;
-}
-
-########################################################################################
-#
-# OWXLCD_PT_Byte - write a single byte to the LCD device async
-#
-# Parameter hash = hash of device addressed
-# cmd = register or data
-# byte = byte
-#
-########################################################################################
-
-sub OWXLCD_PT_Byte($$$) {
-
- my ($hash,$cmd,$byte) = @_;
-
- return PT_THREAD(sub {
- my ($thread) = @_;
- my ($select);
- #-- ID of the device
- my $owx_dev = $hash->{ROM_ID};
- #-- hash of the busmaster
- my $master = $hash->{IODev};
- my ($i,$j,$k);
-
- PT_BEGIN($thread);
-
- #=============== write to LCD register ===============================
- if ( $cmd eq "register" ) {
- #-- issue the read LCD register command \x10
- $select = sprintf("\x10%c",$byte);
- #=============== write to LCD data ===============================
- }elsif ( $cmd eq "data" ) {
- #-- issue the read LCD data command \x12
- $select = sprintf("\x12%c",$byte);
- #=============== wrong value requested ===============================
- } else {
- die "OWXLCD: Wrong byte write attempt";
- }
-
- #"byte"
- $thread->{pt_execute} = OWX_ASYNC_PT_Execute($master,1,$owx_dev,$select,0);
- PT_WAIT_THREAD($thread->{pt_execute});
- die $thread->{pt_execute}->PT_CAUSE() if ($thread->{pt_execute}->PT_STATE() == PT_ERROR);
- PT_END;
- });
-}
-
-########################################################################################
-#
-# OWXLCD_Get - get values from the LCD device
-#
-# Parameter hash = hash of device addressed
-# cmd = command string
-#
-########################################################################################
-
-sub OWXLCD_Get($$) {
-
- my ($hash,$cmd) = @_;
-
- my ($select, $select2, $len, $addr, $res, $res2);
-
- #-- ID of the device
- my $owx_dev = $hash->{ROM_ID};
-
- #-- hash of the busmaster
- my $master = $hash->{IODev};
-
- my ($i,$j,$k);
-
- #=============== fill scratch with gpio ports ===============================
- if ( $cmd eq "gpio" ) {
- #-- issue the read GPIO command \x22 (1 byte)
- $select = "\x22";
- $len = 1;
- #=============== fill scratch with gpio counters ===============================
- }elsif ( $cmd eq "counter" ) {
- #-- issue the read counter command \x23 (8 bytes)
- $select = "\x23";
- $len = 8;
- #=============== fill scratch with version ===============================
- }elsif ( $cmd eq "version" ) {
- #-- issue the read version command \x41
- $select = "\x41";
- $len = 16;
- } else {
- return "OWXLCD: Wrong get attempt";
- }
- #-- write to device
- OWX_Reset($master);
- $res=OWX_Complex($master,$owx_dev,$select,0);
- #-- process results
- if( $res eq 0 ){
- return "OWLCD: Device $owx_dev not accessible for reading";
- }
-
- #-- issue the read scratchpad command \xBE
- $select2 = "\xBE";
- #-- write to device
- OWX_Reset($master);
- $res=OWX_Complex($master,$owx_dev,$select2,$len);
- #-- process results
- if( $res eq 0 ){
- return "OWLCD: Device $owx_dev not accessible for reading in 2nd step";
- }
- OWXLCD_BinValues($hash, "get.".$cmd, 1, 1, $owx_dev, $select2, $len, substr($res,10));
-
- return main::ReadingsVal($hash->{NAME},$cmd,"");
-}
-
-########################################################################################
-#
-# OWXLCD_PT_Get - get values from the LCD device async
-#
-# Parameter hash = hash of device addressed
-# cmd = command string
-#
-########################################################################################
-
-sub OWXLCD_PT_Get($$) {
-
- my ($hash,$cmd) = @_;
-
- return PT_THREAD(sub {
-
- my ($thread) = @_;
- my ($select);
-
- #-- ID of the device
- my $owx_dev = $hash->{ROM_ID};
-
- #-- hash of the busmaster
- my $master = $hash->{IODev};
-
- my ($i,$j,$k);
-
- PT_BEGIN($thread);
- #=============== fill scratch with gpio ports ===============================
- if ( $cmd eq "gpio" ) {
- #-- issue the read GPIO command \x22 (1 byte)
- $select = "\x22";
- $thread->{len} = 1;
- #=============== fill scratch with gpio counters ===============================
- }elsif ( $cmd eq "counter" ) {
- #-- issue the read counter command \x23 (8 bytes)
- $select = "\x23";
- $thread->{len} = 8;
- #=============== fill scratch with version ===============================
- }elsif ( $cmd eq "version" ) {
- #-- issue the read version command \x41
- $select = "\x41";
- $thread->{len} = 16;
- } else {
- die("OWXLCD: Wrong get attempt");
- }
- #"get.prepare"
- $thread->{pt_execute} = OWX_ASYNC_PT_Execute($master,1,$owx_dev,$select,0);
- PT_WAIT_THREAD($thread->{pt_execute});
- die $thread->{pt_execute}->PT_CAUSE() if ($thread->{pt_execute}->PT_STATE() == PT_ERROR);
-
- #-- issue the read scratchpad command \xBE
- $thread->{pt_execute} = OWX_ASYNC_PT_Execute($master,1,$owx_dev,"\xBE", $thread->{len});
- PT_WAIT_THREAD($thread->{pt_execute});
- die $thread->{pt_execute}->PT_CAUSE() if ($thread->{pt_execute}->PT_STATE() == PT_ERROR);
-
- OWXLCD_BinValues($hash, "get.".$cmd, 1, 1, $owx_dev, "\xBE", $thread->{len}, $thread->{pt_execute}->PT_RETVAL());
-
- PT_END;
- });
-}
-
-########################################################################################
-#
-# OWXLCD_GetMemory - get memory page from LCD device (EXPERIMENTAL)
-#
-# Parameter hash = hash of device addressed
-# page = memory page address
-#
-########################################################################################
-
-sub OWXLCD_GetMemory($$) {
-
- my ($hash,$page) = @_;
-
- my ($select, $res, $res2, $res3);
-
- #-- ID of the device
- my $owx_dev = $hash->{ROM_ID};
- my $owx_rnf = substr($owx_dev,3,12);
- my $owx_f = substr($owx_dev,0,2);
-
- #-- hash of the busmaster
- my $master = $hash->{IODev};
-
- my ($i,$j,$k);
-
- #-- issue the match ROM command \x55 and the copy eeprom to scratchpad command \x4E
- #Log 1," page read is ".$page;
- $select = sprintf("\4E%c\x10\x37",$page);
- #-- write to device
- OWX_Reset($master);
- $res=OWX_Complex($master,$owx_dev,$select,0);
- #-- process results
- if( $res eq 0 ){
- return "OWLCD: Device $owx_dev not accessible for reading";
- }
-
- #-- sleeping for some time
- #select(undef,undef,undef,0.5);
-
- #-- issue the match ROM command \x55 and the read scratchpad command \xBE
- $select = "\xBE";
- #-- write to device
- OWX_Reset($master);
- $res=OWX_Complex($master,$owx_dev,$select,16);
- #-- process results
- if( $res eq 0 ){
- return "OWLCD: Device $owx_dev not accessible for reading in 2nd step";
- }
- OWXLCD_BinValues($hash, "get.memory.$page", 1, 1, $owx_dev, $select, 16, substr($res,11,16));
- #-- process results (10 bytes or more have been sent)
- #$res2 = substr($res,11,16);
- #return $res2;
- return main::ReadingsVal($hash->{NAME},"memory$page","");
-}
-
-########################################################################################
-#
-# OWXLCD_PT_GetMemory - get memory page from LCD device async (EXPERIMENTAL)
-#
-# Parameter hash = hash of device addressed
-# page = memory page address
-#
-########################################################################################
-
-sub OWXLCD_PT_GetMemory($$) {
-
- my ($hash,$page) = @_;
-
- return PT_THREAD(sub {
-
- my ($thread) = @_;
- my ($select);
-
- #-- ID of the device
- my $owx_dev = $hash->{ROM_ID};
-
- #-- hash of the busmaster
- my $master = $hash->{IODev};
-
- PT_BEGIN($thread);
- #-- issue the match ROM command \x55 and the copy eeprom to scratchpad command \x4E
- #Log 1," page read is ".$page;
- $select = sprintf("\4E%c\x10\x37",$page);
- #"prepare"
- $thread->{pt_execute} = OWX_ASYNC_PT_Execute($master,1,$owx_dev,$select,0);
- PT_WAIT_THREAD($thread->{pt_execute});
- die $thread->{pt_execute}->PT_CAUSE() if ($thread->{pt_execute}->PT_STATE() == PT_ERROR);
-
- #-- sleeping for some time
- $thread->{ExecuteTime} = gettimeofday()+0.5;
- PT_YIELD_UNTIL(gettimeofday() >= $thread->{ExecuteTime});
- delete $thread->{ExecuteTime};
-
- #-- issue the match ROM command \x55 and the read scratchpad command \xBE
- $thread->{'select'} = "\xBE";
- #"get.memory.$page"
- $thread->{pt_execute} = OWX_ASYNC_PT_Execute($master,1,$owx_dev,$thread->{'select'},16);
- PT_WAIT_THREAD($thread->{pt_execute});
- die $thread->{pt_execute}->PT_CAUSE() if ($thread->{pt_execute}->PT_STATE() == PT_ERROR);
-
- OWXLCD_BinValues($hash, "get.memory.$page", 1, 1, $owx_dev, $thread->{'select'}, 16, $thread->{pt_execute}->PT_RETVAL());
- #-- process results (10 bytes or more have been sent)
- #$res2 = substr($res,11,16);
- #return $res2;
- PT_END;
- });
-}
-
########################################################################################
#
# OWXLCD_InitializeDevice - initialize the display
@@ -1144,9 +862,312 @@ sub OWXLCD_InitializeDevice($) {
} else {
return "OWXLCD: Wrong LCD controller type";
}
-
}
+########################################################################################
+#
+# OWXLCD_Byte - write a single byte to the LCD device
+#
+# Parameter hash = hash of device addressed
+# cmd = register or data
+# byte = byte
+#
+########################################################################################
+
+sub OWXLCD_Byte($$$) {
+
+ my ($hash,$cmd,$byte) = @_;
+
+ my ($select, $select2, $res, $res2, $res3, @data);
+
+ #-- ID of the device
+ my $owx_dev = $hash->{ROM_ID};
+ my $owx_rnf = substr($owx_dev,3,12);
+ my $owx_f = substr($owx_dev,0,2);
+
+ #-- hash of the busmaster
+ my $master = $hash->{IODev};
+
+ my ($i,$j,$k);
+
+ #=============== write to LCD register ===============================
+ if ( $cmd eq "register" ) {
+ #-- issue the read LCD register command \x10
+ $select = sprintf("\x10%c",$byte);
+ #=============== write to LCD data ===============================
+ }elsif ( $cmd eq "data" ) {
+ #-- issue the read LCD data command \x12
+ $select = sprintf("\x12%c",$byte);
+ #=============== wrong value requested ===============================
+ } else {
+ return "OWXLCD: Wrong byte write attempt";
+ }
+
+ #-- write to device
+ #-- OLD OWX interface
+ if( !$master->{ASYNCHRONOUS} ){
+ OWX_Reset($master);
+ $res=OWX_Complex($master,$owx_dev,$select,0);
+ #-- process results
+ if( $res eq 0 ){
+ return "OWLCD: Device $owx_dev not accessible for writing a byte";
+ }
+ #-- NEW OWX interface
+ }else{
+ #### master slave context proc owx_dev data crcpart numread startread callback delay
+ OWX_Qomplex($master, $hash, "writebyte", 0, $owx_dev,$select, 0, 0, 0, undef, 0);
+ }
+ return undef;
+}
+
+########################################################################################
+#
+# OWXLCD_Get - get values from the LCD device
+#
+# Parameter hash = hash of device addressed
+# cmd = command string
+#
+########################################################################################
+
+sub OWXLCD_Get($$) {
+
+ my ($hash,$cmd) = @_;
+
+ my ($select, $select2, $len, $addr, $res, $res2);
+
+ #-- ID of the device
+ my $owx_dev = $hash->{ROM_ID};
+
+ #-- hash of the busmaster
+ my $master = $hash->{IODev};
+
+ my ($i,$j,$k);
+
+ #=============== fill scratch with gpio ports ===============================
+ if ( $cmd eq "gpio" ) {
+ #-- issue the read GPIO command \x22 (1 byte)
+ $select = "\x22";
+ $len = 1;
+ #=============== fill scratch with gpio counters ===============================
+ }elsif ( $cmd eq "counter" ) {
+ #-- issue the read counter command \x23 (8 bytes)
+ $select = "\x23";
+ $len = 8;
+ #=============== fill scratch with version ===============================
+ }elsif ( $cmd eq "version" ) {
+ #-- issue the read version command \x41
+ $select = "\x41";
+ $len = 16;
+ } else {
+ return "OWXLCD: Wrong get attempt";
+ }
+ #-- write to device
+ #-- OLD OWX interface
+ if( !$master->{ASYNCHRONOUS} ){
+ OWX_Reset($master);
+ $res=OWX_Complex($master,$owx_dev,$select,0);
+
+ #-- process results
+ if( $res eq 0 ){
+ return "OWLCD: Device $owx_dev not accessible for reading";
+ }
+
+ #-- issue the read scratchpad command \xBE
+ $select2 = "\xBE";
+ #-- write to device
+
+ OWX_Reset($master);
+ $res=OWX_Complex($master,$owx_dev,$select2,$len);
+ #-- process results
+ if( $res eq 0 ){
+ return "OWLCD: Device $owx_dev not accessible for reading in 2nd step";
+ }
+ OWXLCD_BinValues($hash, "get.".$cmd, 1, $owx_dev, "\xBE", $len, substr($res,10));
+
+ return main::ReadingsVal($hash->{NAME},$cmd,"");
+ #-- NEW OWX interface
+ }else{
+ #### master slave context proc owx_dev data crcpart numread startread callback delay
+ OWX_Qomplex($master, $hash, "get.prep.".$len, 0, $owx_dev, $select, $cmd, 1, 10, \&OWXLCD_BinValues, 0);
+ return undef;
+ }
+}
+
+########################################################################################
+#
+# OWXLCD_GetMemory - get memory page from LCD device (EXPERIMENTAL)
+#
+# Parameter hash = hash of device addressed
+# page = memory page address
+#
+########################################################################################
+
+sub OWXLCD_GetMemory($$) {
+
+ my ($hash,$page) = @_;
+
+ my ($select, $res, $res2, $res3);
+
+ #-- ID of the device
+ my $owx_dev = $hash->{ROM_ID};
+ my $owx_rnf = substr($owx_dev,3,12);
+ my $owx_f = substr($owx_dev,0,2);
+
+ #-- hash of the busmaster
+ my $master = $hash->{IODev};
+
+ my ($i,$j,$k);
+
+ #-- issue the match ROM command \x55 and the copy eeprom to scratchpad command \x4E
+ #Log 1," page read is ".$page;
+ $select = sprintf("\4E%c\x10\x37",$page);
+ #-- write to device
+ #-- OLD OWX interface
+ if( !$master->{ASYNCHRONOUS} ){
+ OWX_Reset($master);
+ $res=OWX_Complex($master,$owx_dev,$select,0);
+
+ #-- process results
+ if( $res eq 0 ){
+ return "OWLCD: Device $owx_dev not accessible for reading";
+ }
+ #-- issue the match ROM command \x55 and the read scratchpad command \xBE
+ $select = "\xBE";
+ #-- write to device
+ OWX_Reset($master);
+ $res=OWX_Complex($master,$owx_dev,$select,16);
+ #-- process results
+ if( $res eq 0 ){
+ return "OWLCD: Device $owx_dev not accessible for reading in 2nd step";
+ }
+ OWXLCD_BinValues($hash, "get.memory.$page", 1, $owx_dev, $select, 16, substr($res,11,16));
+ #-- process results (10 bytes or more have been sent)
+ #$res2 = substr($res,11,16);
+ #return $res2;
+ return main::ReadingsVal($hash->{NAME},"memory$page","");
+ #-- NEW OWX interface
+ }else{
+ #### master slave context proc owx_dev data crcpart numread startread callback delay
+ OWX_Qomplex($master, $hash, "get.prep.16", 0, $owx_dev, $select, "memory.$page", 1, 11, \&OWXLCD_BinValues, 0);
+ return undef;
+ }
+}
+
+########################################################################################
+#
+# OWXLCD_BinValues - Process reading from one device - translate binary into raw
+#
+# 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 OWXLCD_BinValues($$$$$$$) {
+ my ($hash, $context, $reset, $owx_dev, $crcpart, $numread, $res) = @_;
+
+
+ my ($ret,@data,$select);
+ my $change = 0;
+
+ my $master = $hash->{IODev};
+ my $name = $hash->{NAME};
+
+ my $msg;
+ OWX_WDBG($name,"OWLCD: $name: BinValues called with ",$res)
+ if( $main::owx_debug>2 );
+
+ #-- process results
+ #die "OWVAR: $name not accessible in 2nd step" unless ( defined $res and $res ne 0 );
+
+ #=============== setline 2nd step ===============================
+ if( $context eq "setline" ) {
+ #-- issue the copy scratchpad to LCD command \x48
+ #### master slave context proc owx_dev data crcpart numread startread callback delay
+ # 16 ensures entry at top of queue
+ OWX_Qomplex($master, $hash, "", 16, $owx_dev,"\x48", 0, 0, 0, undef, 0);
+ #=============== seteeprom 2nd step ===============================
+ }elsif( $context eq "seteeprom" ) {
+ #-- issue the copy scratchpad to EEPROM command \x39
+ #### master slave context proc owx_dev data crcpart numread startread callback delay
+ # 16 ensures entry at top of queue
+ OWX_Qomplex($master, $hash, "", 16, $owx_dev,"\x39", 0, 0, 0, undef, 0);
+ #=============== eraseicon 2nd step ===============================
+ }elsif( $context eq "eraseicon.1" ) {
+ #-- SEGRAM addres to 0 = \x40,
+ $select = "\x10\x40";
+ #-- write 16 zeros to scratchpad
+ $select .= "\x4E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
+ #### master slave context proc owx_dev data crcpart numread startread callback delay
+ # 16 ensures entry at top of queue
+ OWX_Qomplex($master, $hash, "eraseicon.2", 16, $owx_dev, $select, 0, 0, 0, \&OWXLCD_BinValues, 0);
+ #=============== eraseicon 3rd step ===============================
+ }elsif( $context eq "eraseicon.2" ) {
+ #-- issue the copy scratchpad to LCD command \x48
+ #### master slave context proc owx_dev data crcpart numread startread callback delay
+ # 16 ensures entry at top of queue
+ OWX_Qomplex($master, $hash, "endicon", 16, $owx_dev,"\x48", 0, 1, 0, \&OWXLCD_BinValues, 0);
+ #=============== seticon 2nd step ===============================
+ }elsif( $context eq "seticon.1" ) {
+ #-- SEGRAM addres to 0 = \x40 + icon address
+ $select = substr($crcpart,0,2);
+ #### master slave context proc owx_dev data crcpart numread startread callback delay
+ # 16 ensures entry at top of queue
+ OWX_Qomplex($master, $hash, "seticon.2", 16, $owx_dev, $select,$crcpart, 0, 0, \&OWXLCD_BinValues, 0);
+ #=============== seticon 2nd step ===============================
+ }elsif( $context eq "seticon.2" ) {
+ #-- data
+ $select = substr($crcpart,2);
+ #### master slave context proc owx_dev data crcpart numread startread callback delay
+ # 16 ensures entry at top of queue
+ OWX_Qomplex($master, $hash, "endicon", 16, $owx_dev, $select, 0, 1, 0, \&OWXLCD_BinValues, 0);
+ #=============== endicon ===============================
+ }elsif( $context eq "endicon" ) {
+ #-- issue the return to normal state command
+ #### master slave context proc owx_dev data crcpart numread startread callback delay
+ # 16 ensures entry at top of queue
+ OWX_Qomplex($master, $hash, "", 16, $owx_dev, "\x10\x20", 0, 0, 0, undef, 0);
+ #=============== prepare some get values ===============================
+ }elsif ( $context =~ /^get\.prep\.(\d+)/ ) {
+ my $len = $1;
+ #Log 1,"OWXLCD_BinValues: context get.$crcpart with length $len";
+ #-- command hidden in crcpart, issueing read scratchpad command
+ #### master slave context proc owx_dev data crcpart numread startread callback delay
+ OWX_Qomplex($master, $hash, "get.".$crcpart, 0, $owx_dev, "\xBE", 0, $len, 10, \&OWXLCD_BinValues, 0);
+ #=============== gpio ports ===============================
+ }elsif ( $context eq "get.gpio" ) {
+ $ret = ord($res);
+ readingsSingleUpdate($hash,"gpio",$ret,1);
+ #=============== gpio counters ===============================
+ }elsif ( $context eq "get.counter" ) {
+ for( my $i=0; $i<4; $i++){
+ $data[$i] = ord(substr($res,2*$i+1,1))*256+ord(substr($res,2*$i,1));
+ }
+ $ret = join(" ",@data);
+ readingsSingleUpdate($hash,"counter",$ret,1);
+ #=============== version ===============================
+ }elsif ( $context eq "get.version" ) {
+ #TODO format version, raw value is unreadable
+ readingsSingleUpdate($hash,"version",$res,1);
+ #=============== memory ===============================
+ }elsif ( $context =~ /^get\.memory\.([\d]+)$/ ) {
+ readingsSingleUpdate($hash,"memory$1",unpack("H*",$res),1);
+ }
+ return undef;
+}
+
########################################################################################
#
# OWXLCD_SetFunction - write state and values of the LCD device
@@ -1199,15 +1220,482 @@ sub OWXLCD_SetFunction($$$) {
return "OWXLCD: Wrong function selected";
}
- #-- write to device
- OWX_Reset($master);
- $res=OWX_Complex($master,$owx_dev,$select,0);
- #-- process results
- if( $res eq 0 ){
- return "OWLCD: Device $owx_dev not accessible for writing";
+ #-- OLD OWX interface
+ if( !$master->{ASYNCHRONOUS} ){
+ #-- write to device
+ OWX_Reset($master);
+ $res=OWX_Complex($master,$owx_dev,$select,0);
+ #-- process results
+ if( $res eq 0 ){
+ return "OWLCD: 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, "setfunction", 0, $owx_dev, $select, 0, 0, 0, undef, 0);
+ }
+ return undef;
+}
+
+########################################################################################
+#
+# OWXLCD_SetIcon - set one of the icons
+#
+# Parameter hash = hash of device addressed
+# icon = address of the icon used = 0,1 .. 16 (0 = all off)
+# value = data value: 0 = off, 1 = on, 2 = blink
+# for battery icon 16: 0 = off, 1 = empty ... 5 = full, 6 = empty blink
+#
+########################################################################################
+
+sub OWXLCD_SetIcon($$$) {
+ my ($hash,$icon,$value) = @_;
+
+ my ($i,$data,$select, $res);
+
+ #-- ID of the device, hash of the busmaster
+ my $owx_dev = $hash->{ROM_ID};
+ my $master = $hash->{IODev};
+
+ #-- only for KS0073
+ if ( $lcdcontroller eq "KS0073"){
+
+ #-- write 16 zeros to erase all icons
+ if( $icon == 0){
+ #-- 4 bit data size, RE => 1, blink Enable = \x26
+ $select = "\x10\x26";
+ #-- OLD OWX interface
+ if( !$master->{ASYNCHRONOUS} ){
+ OWX_Reset($master);
+ $res=OWX_Complex($master,$owx_dev,$select,0);
+
+ #-- SEGRAM addres to 0 = \x40,
+ $select = "\x10\x40";
+ #-- write 16 zeros to scratchpad
+ $select .= "\x4E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
+ OWX_Reset($master);
+ $res=OWX_Complex($master,$owx_dev,$select,0);
+
+ #-- issue the copy scratchpad to LCD command \x48
+ $select="\x48";
+ OWX_Reset($master);
+ $res=OWX_Complex($master,$owx_dev,$select,0);
+
+ #-- return to normal state
+ $select = "\x10\x20";
+ OWX_Reset($master);
+ $res=OWX_Complex($master,$owx_dev,$select,0);
+ #-- NEW OWX interface
+ }else{
+ #### master slave context proc owx_dev data crcpart numread startread callback delay
+ OWX_Qomplex($master, $hash, "eraseicon.1", 0, $owx_dev, $select, 0, 0, 0, \&OWXLCD_BinValues, 0);
+ }
+ } else {
+ #-- determine data value
+ if( int($icon) != 16 ){
+ if( $value == 0 ){
+ $data = 0;
+ } elsif ( $value == 1) {
+ $data = 16;
+ } elsif ( $value == 2) {
+ $data = 80;
+ } else {
+ return "OWXLCD: Wrong data value $value for icon $icon";
+ }
+ } else {
+ if( $value == 0 ){
+ $data = 0;
+ } elsif ( $value == 1) {
+ $data = 16;
+ } elsif ( $value == 2) {
+ $data = 24;
+ } elsif ( $value == 3) {
+ $data = 28;
+ } elsif ( $value == 4) {
+ $data = 30;
+ } elsif ( $value == 5) {
+ $data = 31;
+ } elsif ( $value == 6) {
+ $data = 80;
+ } else {
+ return "OWXLCD: Wrong data value $value for icon $icon";
+ }
+ }
+ #-- 4 bit data size, RE => 1, blink Enable = \x26
+ $select = "\x10\x26";
+ #-- OLD OWX interface
+ if( !$master->{ASYNCHRONOUS} ){
+ OWX_Reset($master);
+ $res=OWX_Complex($master,$owx_dev,$select,0);
+
+ #-- SEGRAM addres to 0 = \x40 + icon address
+ $select = sprintf("\x10%c",63+$icon);
+ OWX_Reset($master);
+ $res=OWX_Complex($master,$owx_dev,$select,0);
+
+ #-- data
+ $select = sprintf("\x12%c",$data);
+ OWX_Reset($master);
+ $res=OWX_Complex($master,$owx_dev,$select,0);
+
+ #-- return to normal state
+ $select = "\x10\x20";
+ OWX_Reset($master);
+ $res=OWX_Complex($master,$owx_dev,$select,0);
+ #-- NEW OWX interface
+ }else{
+ #### master slave context proc owx_dev data crcpart numread startread callback delay
+ OWX_Qomplex($master, $hash, "seticon.1", 0, $owx_dev, $select, sprintf("\x10%c",63+$icon).sprintf("\x12%c",$data), 0, 0, \&OWXLCD_BinValues, 0);
+ }
+ }
+
+ #-- or else
+ } else {
+ return "OWXLCD: Wrong LCD controller type";
+ }
+}
+
+########################################################################################
+#
+# OWXLCD_SetLine - set one of the display lines
+#
+# Parameter hash = hash of device addressed
+# line = line number (0..3)
+# msg = data string to be written
+#
+########################################################################################
+
+sub OWXLCD_SetLine($$$) {
+
+ my ($hash,$line,$msg) = @_;
+
+ my ($select, $res, $res2, $res3, $i, $msgA, $msgB);
+ $res2 = "";
+ $line = int($line);
+ $msg = defined($msg) ? $msg : "";
+
+ $msg = OWXLCD_Trans($msg);
+
+ #-- ID of the device, hash of the busmaster
+ my $owx_dev = $hash->{ROM_ID};
+ my $master = $hash->{IODev};
+
+ #-- split if longer than 16 bytes, fill each with blanks
+ # has already been checked to be <= $lcdchars
+ if( $lcdchars > 16 ){
+ if( length($msg) > 16 ) {
+ $msgA = substr($msg,0,16);
+ $msgB = substr($msg,16,length($msg)-16);
+ for($i = 0;$i<$lcdchars-length($msg);$i++){
+ $msgB .= "\x20";
+ }
+ } else {
+ $msgA = $msg;
+ for($i = 0;$i<16-length($msg);$i++){
+ $msgA .= "\x20";
+ }
+ for($i = 0;$i<$lcdchars-16;$i++){
+ $msgB .= "\x20";
+ }
+ }
+ }else{
+ $msgA = $msg;
+ for($i = 0;$i<$lcdchars-length($msg);$i++){
+ $msgA .= "\x20";
+ }
+ $msgB = undef;
+ }
+
+ #-- issue the match ROM command \x55 and the write scratchpad command \x4E
+ # followed by LCD page address and the text
+ $select=sprintf("\x4E%c",$lcdpage[$line]).$msgA;
+ #-- OLD OWX interface
+ if( !$master->{ASYNCHRONOUS} ){
+ OWX_Reset($master);
+ $res=OWX_Complex($master,$owx_dev,$select,0);
+
+ #-- issue the copy scratchpad to LCD command \x48
+ $select="\x48";
+ OWX_Reset($master);
+ $res3=OWX_Complex($master,$owx_dev,$select,0);
+ #-- NEW OWX interface
+ }else{
+ #### master slave context proc owx_dev data crcpart numread startread callback delay
+ OWX_Qomplex($master, $hash, "setline", 0, $owx_dev, $select, 0, 0, 0, \&OWXLCD_BinValues, 0);
+ }
+ #-- if second string available:
+ if( defined($msgB) ) {
+ #select(undef,undef,undef,0.005);
+ #-- issue the match ROM command \x55 and the write scratchpad command \x4E
+ # followed by LCD page address and the text
+ $select=sprintf("\x4E%c",$lcdpage[$line]+16).$msgB;
+ #-- OLD OWX interface
+ if( !$master->{ASYNCHRONOUS} ){
+ OWX_Reset($master);
+ $res2=OWX_Complex($master,$owx_dev,$select,0);
+
+ #-- issue the copy scratchpad to LCD command \x48
+ $select="\x48";
+ OWX_Reset($master);
+ $res3=OWX_Complex($master,$owx_dev,$select,0);
+ #-- NEW OWX interface
+ }else{
+ #### master slave context proc owx_dev data crcpart numread startread callback delay
+ OWX_Qomplex($master, $hash, "setline", 0, $owx_dev, $select, 0, 0, 0, \&OWXLCD_BinValues, 0);
+ }
}
+ #-- process results
+ if( !$master->{ASYNCHRONOUS} ){
+ if( ($res eq 0) || ($res2 eq 0) || ($res3 eq 0) ){
+ return "OWLCD: Device $owx_dev not accessible for writing";
+ }
+ }
return undef;
+
+}
+
+########################################################################################
+#
+# OWXLCD_Trans - String translation helper
+#
+# Parameter msg = data string to be written
+#
+########################################################################################
+
+sub OWXLCD_Trans($) {
+
+ my ($msg) = @_;
+
+ #-- replace umlaut chars for special codepage
+ $msg =~ s/ä/\x7B/g;
+ $msg =~ s/ö/\x7C/g;
+ $msg =~ s/ü/\x7E/g;
+ $msg =~ s/Ä/\x5B/g;
+ $msg =~ s/Ö/\x5C/g;
+ $msg =~ s/Ü/\x5E/g;
+ $msg =~ s/ß/\xBE/g;
+ #-- replace other special chars
+ $msg =~s/_/\xC4/g;
+ #--take out HTML degree sign
+ if( $msg =~ m/.*\°\;.*/ ) {
+ my @ma = split(/\°\;/,$msg);
+ $msg = $ma[0]."\x80".$ma[1];
+ }
+ return $msg;
+}
+
+########################################################################################
+#
+# OWXLCD_SetMemory - set internal nonvolatile memory
+#
+# Parameter hash = hash of device addressed
+# page = page number (0..14)
+# msg = data string to be written
+#
+########################################################################################
+
+sub OWXLCD_SetMemory($$$) {
+
+ my ($hash,$page,$msg) = @_;
+
+ my ($select, $res, $res2, $res3, $i, $msgA);
+ $page = int($page);
+ $msg = defined($msg) ? $msg : "";
+
+ #-- ID of the device, hash of the busmaster
+ my $owx_dev = $hash->{ROM_ID};
+ my $master = $hash->{IODev};
+
+ #-- fillup with blanks
+ $msgA = $msg;
+ for($i = 0;$i<16-length($msg);$i++){
+ $msgA .= "\x20";
+ }
+
+ #-- issue the match ROM command \x55 and the write scratchpad command \x4E
+ # followed by LCD page address and the text
+ #Log 1," page written is ".$page;
+ $select=sprintf("\x4E\%c",$page).$msgA;
+ #-- OLD OWX interface
+ if( !$master->{ASYNCHRONOUS} ){
+ OWX_Reset($master);
+ $res=OWX_Complex($master,$owx_dev,$select,0);
+ #-- issue the copy scratchpad to EEPROM command \x39
+ $select = "\x39";
+ OWX_Reset($master);
+ $res2=OWX_Complex($master,$owx_dev,$select,0);
+
+ #-- process results
+ if( ($res eq 0) || ($res2 eq 0) ){
+ return "OWLCD: 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, "seteeprom", 0, $owx_dev, $select, 0, 0, 0, \&OWXLCD_BinValues, 0);
+ }
+ return undef;
+}
+
+########################################################################################
+#
+# OWXLCD_PT_Byte - write a single byte to the LCD device async
+#
+# Parameter hash = hash of device addressed
+# cmd = register or data
+# byte = byte
+#
+########################################################################################
+
+sub OWXLCD_PT_Byte($$$) {
+
+ my ($hash,$cmd,$byte) = @_;
+
+ return PT_THREAD(sub {
+ my ($thread) = @_;
+ my ($select);
+ #-- ID of the device
+ my $owx_dev = $hash->{ROM_ID};
+ #-- hash of the busmaster
+ my $master = $hash->{IODev};
+ my ($i,$j,$k);
+
+ PT_BEGIN($thread);
+
+ #=============== write to LCD register ===============================
+ if ( $cmd eq "register" ) {
+ #-- issue the read LCD register command \x10
+ $select = sprintf("\x10%c",$byte);
+ #=============== write to LCD data ===============================
+ }elsif ( $cmd eq "data" ) {
+ #-- issue the read LCD data command \x12
+ $select = sprintf("\x12%c",$byte);
+ #=============== wrong value requested ===============================
+ } else {
+ die "OWXLCD: Wrong byte write attempt";
+ }
+
+ #"byte"
+ $thread->{pt_execute} = OWX_ASYNC_PT_Execute($master,1,$owx_dev,$select,0);
+ PT_WAIT_THREAD($thread->{pt_execute});
+ die $thread->{pt_execute}->PT_CAUSE() if ($thread->{pt_execute}->PT_STATE() == PT_ERROR);
+ PT_END;
+ });
+}
+
+########################################################################################
+#
+# OWXLCD_PT_Get - get values from the LCD device async
+#
+# Parameter hash = hash of device addressed
+# cmd = command string
+#
+########################################################################################
+
+sub OWXLCD_PT_Get($$) {
+
+ my ($hash,$cmd) = @_;
+
+ return PT_THREAD(sub {
+
+ my ($thread) = @_;
+ my ($select);
+
+ #-- ID of the device
+ my $owx_dev = $hash->{ROM_ID};
+
+ #-- hash of the busmaster
+ my $master = $hash->{IODev};
+
+ my ($i,$j,$k);
+
+ PT_BEGIN($thread);
+ #=============== fill scratch with gpio ports ===============================
+ if ( $cmd eq "gpio" ) {
+ #-- issue the read GPIO command \x22 (1 byte)
+ $select = "\x22";
+ $thread->{len} = 1;
+ #=============== fill scratch with gpio counters ===============================
+ }elsif ( $cmd eq "counter" ) {
+ #-- issue the read counter command \x23 (8 bytes)
+ $select = "\x23";
+ $thread->{len} = 8;
+ #=============== fill scratch with version ===============================
+ }elsif ( $cmd eq "version" ) {
+ #-- issue the read version command \x41
+ $select = "\x41";
+ $thread->{len} = 16;
+ } else {
+ die("OWXLCD: Wrong get attempt");
+ }
+ #"get.prepare"
+ $thread->{pt_execute} = OWX_ASYNC_PT_Execute($master,1,$owx_dev,$select,0);
+ PT_WAIT_THREAD($thread->{pt_execute});
+ die $thread->{pt_execute}->PT_CAUSE() if ($thread->{pt_execute}->PT_STATE() == PT_ERROR);
+
+ #-- issue the read scratchpad command \xBE
+ $thread->{pt_execute} = OWX_ASYNC_PT_Execute($master,1,$owx_dev,"\xBE", $thread->{len});
+ PT_WAIT_THREAD($thread->{pt_execute});
+ die $thread->{pt_execute}->PT_CAUSE() if ($thread->{pt_execute}->PT_STATE() == PT_ERROR);
+
+ OWXLCD_BinValues($hash, "get.".$cmd, 1, $owx_dev, "\xBE", $thread->{len}, $thread->{pt_execute}->PT_RETVAL());
+
+ PT_END;
+ });
+}
+
+########################################################################################
+#
+# OWXLCD_PT_GetMemory - get memory page from LCD device async (EXPERIMENTAL)
+#
+# Parameter hash = hash of device addressed
+# page = memory page address
+#
+########################################################################################
+
+sub OWXLCD_PT_GetMemory($$) {
+
+ my ($hash,$page) = @_;
+
+ return PT_THREAD(sub {
+
+ my ($thread) = @_;
+ my ($select);
+
+ #-- ID of the device
+ my $owx_dev = $hash->{ROM_ID};
+
+ #-- hash of the busmaster
+ my $master = $hash->{IODev};
+
+ PT_BEGIN($thread);
+ #-- issue the match ROM command \x55 and the copy eeprom to scratchpad command \x4E
+ #Log 1," page read is ".$page;
+ $select = sprintf("\4E%c\x10\x37",$page);
+ #"prepare"
+ $thread->{pt_execute} = OWX_ASYNC_PT_Execute($master,1,$owx_dev,$select,0);
+ PT_WAIT_THREAD($thread->{pt_execute});
+ die $thread->{pt_execute}->PT_CAUSE() if ($thread->{pt_execute}->PT_STATE() == PT_ERROR);
+
+ #-- sleeping for some time
+ $thread->{ExecuteTime} = gettimeofday()+0.5;
+ PT_YIELD_UNTIL(gettimeofday() >= $thread->{ExecuteTime});
+ delete $thread->{ExecuteTime};
+
+ #-- issue the match ROM command \x55 and the read scratchpad command \xBE
+ $thread->{'select'} = "\xBE";
+ #"get.memory.$page"
+ $thread->{pt_execute} = OWX_ASYNC_PT_Execute($master,1,$owx_dev,$thread->{'select'},16);
+ PT_WAIT_THREAD($thread->{pt_execute});
+ die $thread->{pt_execute}->PT_CAUSE() if ($thread->{pt_execute}->PT_STATE() == PT_ERROR);
+
+ OWXLCD_BinValues($hash, "get.memory.$page", 1, $owx_dev, $thread->{'select'}, 16, $thread->{pt_execute}->PT_RETVAL());
+ #-- process results (10 bytes or more have been sent)
+ #$res2 = substr($res,11,16);
+ #return $res2;
+ PT_END;
+ });
}
########################################################################################
@@ -1275,104 +1763,6 @@ sub OWXLCD_PT_SetFunction($$$) {
});
}
-########################################################################################
-#
-# OWXLCD_SetIcon - set one of the icons
-#
-# Parameter hash = hash of device addressed
-# icon = address of the icon used = 0,1 .. 16 (0 = all off)
-# value = data value: 0 = off, 1 = on, 2 = blink
-# for battery icon 16: 0 = off, 1 = empty ... 5 = full, 6 = empty blink
-#
-########################################################################################
-
-sub OWXLCD_SetIcon($$$) {
- my ($hash,$icon,$value) = @_;
-
- my ($i,$data,$select, $res);
-
- #-- ID of the device, hash of the busmaster
- my $owx_dev = $hash->{ROM_ID};
- my $master = $hash->{IODev};
-
- #-- only for KS0073
- if ( $lcdcontroller eq "KS0073"){
-
- #-- write 16 zeros to erase all icons
- if( $icon == 0){
- #-- 4 bit data size, RE => 1, blink Enable = \x26
- $select = "\x10\x26";
- OWX_Reset($master);
- $res=OWX_Complex($master,$owx_dev,$select,0);
-
- #-- SEGRAM addres to 0 = \x40,
- $select = "\x10\x40";
- #-- write 16 zeros to scratchpad
- $select .= "\x4E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
- OWX_Reset($master);
- $res=OWX_Complex($master,$owx_dev,$select,0);
-
- #-- issue the copy scratchpad to LCD command \x48
- $select="\x48";
- OWX_Reset($master);
- $res=OWX_Complex($master,$owx_dev,$select,0);
- } else {
- #-- determine data value
- if( int($icon) != 16 ){
- if( $value == 0 ){
- $data = 0;
- } elsif ( $value == 1) {
- $data = 16;
- } elsif ( $value == 2) {
- $data = 80;
- } else {
- return "OWXLCD: Wrong data value $value for icon $icon";
- }
- } else {
- if( $value == 0 ){
- $data = 0;
- } elsif ( $value == 1) {
- $data = 16;
- } elsif ( $value == 2) {
- $data = 24;
- } elsif ( $value == 3) {
- $data = 28;
- } elsif ( $value == 4) {
- $data = 30;
- } elsif ( $value == 5) {
- $data = 31;
- } elsif ( $value == 6) {
- $data = 80;
- } else {
- return "OWXLCD: Wrong data value $value for icon $icon";
- }
- }
- #-- 4 bit data size, RE => 1, blink Enable = \x26
- $select = "\x10\x26";
- OWX_Reset($master);
- $res=OWX_Complex($master,$owx_dev,$select,0);
-
- #-- SEGRAM addres to 0 = \x40 + icon address
- $select = sprintf("\x10%c",63+$icon);
- OWX_Reset($master);
- $res=OWX_Complex($master,$owx_dev,$select,0);
-
- #-- data
- $select = sprintf("\x12%c",$data);
- OWX_Reset($master);
- $res=OWX_Complex($master,$owx_dev,$select,0);
- }
-
- #-- return to normal state
- $select = "\x10\x20";
- OWX_Reset($master);
- $res=OWX_Complex($master,$owx_dev,$select,0);
- #-- or else
- } else {
- return "OWXLCD: Wrong LCD controller type";
- }
-}
-
########################################################################################
#
# OWXLCD_PT_SetIcon - set one of the icons async
@@ -1492,92 +1882,6 @@ sub OWXLCD_PT_SetIcon($$$) {
});
}
-########################################################################################
-#
-# OWXLCD_SetLine - set one of the display lines
-#
-# Parameter hash = hash of device addressed
-# line = line number (0..3)
-# msg = data string to be written
-#
-########################################################################################
-
-sub OWXLCD_SetLine($$$) {
-
- my ($hash,$line,$msg) = @_;
-
- my ($select, $res, $res2, $res3, $i, $msgA, $msgB);
- $res2 = "";
- $line = int($line);
- $msg = defined($msg) ? $msg : "";
-
- $msg = OWXLCD_Trans($msg);
-
- #-- ID of the device, hash of the busmaster
- my $owx_dev = $hash->{ROM_ID};
- my $master = $hash->{IODev};
-
- #-- split if longer than 16 bytes, fill each with blanks
- # has already been checked to be <= $lcdchars
- if( $lcdchars > 16 ){
- if( length($msg) > 16 ) {
- $msgA = substr($msg,0,16);
- $msgB = substr($msg,16,length($msg)-16);
- for($i = 0;$i<$lcdchars-length($msg);$i++){
- $msgB .= "\x20";
- }
- } else {
- $msgA = $msg;
- for($i = 0;$i<16-length($msg);$i++){
- $msgA .= "\x20";
- }
- for($i = 0;$i<$lcdchars-16;$i++){
- $msgB .= "\x20";
- }
- }
- }else{
- $msgA = $msg;
- for($i = 0;$i<$lcdchars-length($msg);$i++){
- $msgA .= "\x20";
- }
- $msgB = undef;
- }
-
- #-- issue the match ROM command \x55 and the write scratchpad command \x4E
- # followed by LCD page address and the text
- $select=sprintf("\x4E%c",$lcdpage[$line]).$msgA;
- OWX_Reset($master);
- $res=OWX_Complex($master,$owx_dev,$select,0);
-
- #-- issue the copy scratchpad to LCD command \x48
- $select="\x48";
- OWX_Reset($master);
- $res3=OWX_Complex($master,$owx_dev,$select,0);
-
- #-- if second string available:
- if( defined($msgB) ) {
- #select(undef,undef,undef,0.005);
- #-- issue the match ROM command \x55 and the write scratchpad command \x4E
- # followed by LCD page address and the text
- $select=sprintf("\x4E%c",$lcdpage[$line]+16).$msgB;
- OWX_Reset($master);
- $res2=OWX_Complex($master,$owx_dev,$select,0);
-
- #-- issue the copy scratchpad to LCD command \x48
- $select="\x48";
- OWX_Reset($master);
- $res3=OWX_Complex($master,$owx_dev,$select,0);
- }
-
- #-- process results
- if( ($res eq 0) || ($res2 eq 0) || ($res3 eq 0) ){
- return "OWLCD: Device $owx_dev not accessible for writing";
- }
-
- return undef;
-
-}
-
########################################################################################
#
# OWXLCD_PT_SetLine - set one of the display lines async
@@ -1672,84 +1976,6 @@ sub OWXLCD_PT_SetLine($$$) {
});
}
-########################################################################################
-#
-# OWXLCD_Trans - String translation helper
-#
-# Parameter msg = data string to be written
-#
-########################################################################################
-
-sub OWXLCD_Trans($) {
-
- my ($msg) = @_;
-
- #-- replace umlaut chars for special codepage
- $msg =~ s/ä/\x7B/g;
- $msg =~ s/ö/\x7C/g;
- $msg =~ s/ü/\x7E/g;
- $msg =~ s/Ä/\x5B/g;
- $msg =~ s/Ö/\x5C/g;
- $msg =~ s/Ü/\x5E/g;
- $msg =~ s/ß/\xBE/g;
- #-- replace other special chars
- $msg =~s/_/\xC4/g;
- #--take out HTML degree sign
- if( $msg =~ m/.*\°\;.*/ ) {
- my @ma = split(/\°\;/,$msg);
- $msg = $ma[0]."\x80".$ma[1];
- }
- return $msg;
-}
-
-########################################################################################
-#
-# OWXLCD_SetMemory - set internal nonvolatile memory
-#
-# Parameter hash = hash of device addressed
-# page = page number (0..14)
-# msg = data string to be written
-#
-########################################################################################
-
-sub OWXLCD_SetMemory($$$) {
-
- my ($hash,$page,$msg) = @_;
-
- my ($select, $res, $res2, $res3, $i, $msgA);
- $page = int($page);
- $msg = defined($msg) ? $msg : "";
-
- #-- ID of the device, hash of the busmaster
- my $owx_dev = $hash->{ROM_ID};
- my $master = $hash->{IODev};
-
- #-- fillup with blanks
- $msgA = $msg;
- for($i = 0;$i<16-length($msg);$i++){
- $msgA .= "\x20";
- }
-
- #-- issue the match ROM command \x55 and the write scratchpad command \x4E
- # followed by LCD page address and the text
- #Log 1," page written is ".$page;
- $select=sprintf("\x4E\%c",$page).$msgA;
- OWX_Reset($master);
- $res=OWX_Complex($master,$owx_dev,$select,0);
-
- #-- issue the copy scratchpad to EEPROM command \x39
- $select = "\x39";
- OWX_Reset($master);
- $res2=OWX_Complex($master,$owx_dev,$select,0);
-
- #-- process results
- if( ($res eq 0) || ($res2 eq 0) ){
- return "OWLCD: Device $owx_dev not accessible for writing";
- }
-
- return undef;
-
-}
########################################################################################
#
@@ -1804,34 +2030,6 @@ sub OWXLCD_PT_SetMemory($$$) {
});
}
-sub OWXLCD_BinValues($$$$$$$$) {
- my ($hash, $cmd, $success, $reset, $owx_dev, $command, $numread, $res) = @_;
-
- my ($i,@data,$ret);
-
- #=============== gpio ports ===============================
- if ( $cmd eq "get.gpio" ) {
- $ret = ord($res);
- readingsSingleUpdate($hash,"gpio",$ret,1);
- return $ret;
- #=============== gpio counters ===============================
- }elsif ( $cmd eq "get.counter" ) {
- for( $i=0; $i<4; $i++){
- $data[$i] = ord(substr($res,2*$i+1,1))*256+ord(substr($res,2*$i,1));
- }
- $ret = join(" ",@data);
- readingsSingleUpdate($hash,"counter",$ret,1);
- #=============== version ===============================
- }elsif ( $cmd eq "get.version" ) {
- #TODO format version, raw value is unreadable
- readingsSingleUpdate($hash,"version",$res,1);
- return $res;
- }elsif ( $cmd =~ /^get\.memory\.([\d]+)$/ ) {
- readingsSingleUpdate($hash,"memory$1",unpack("H*",$res),1);
- return $ret;
- }
-}
-
1;
=pod
@@ -1912,7 +2110,7 @@ sub OWXLCD_BinValues($$$$$$$$) {
get <name> gpio
Obtain state of all four input
channels (15 = all off, 0 = all on)
- get <name> gpio
Obtain state of all four input
+ get <name> counter
Obtain state of all four input
counters (4 x 16 Bit)
get <name> version
Obtain firmware version of the
@@ -1922,9 +2120,10 @@ sub OWXLCD_BinValues($$$$$$$$) {
Attributes
=end html
diff --git a/fhem/FHEM/21_OWMULTI.pm b/fhem/FHEM/21_OWMULTI.pm
index b581373ae..ff4cb86f0 100644
--- a/fhem/FHEM/21_OWMULTI.pm
+++ b/fhem/FHEM/21_OWMULTI.pm
@@ -28,7 +28,7 @@
# get reading => measurement value obtained from VFunction
# get temperature => temperature measurement
# get VDD => supply voltage measurement
-# get V|raw => raw external voltage measurement
+# get V|I|raw => external voltage/external current/raw measurement
# get version => OWX version number
#
# set interval => set period for measurement
@@ -38,12 +38,17 @@
#
# attr tempOffset = temperature offset in degree Celsius added to the raw temperature reading
# attr tempUnit = unit of measurement, e.g. Celsius/Kelvin/Fahrenheit, default is Celsius
-# attr VName [|] = name for the channel [|name used in state reading]
-# attr VUnit [|] = unit of measurement for the channel [|unit used in state reading]
-# attr Vfunction = arbitrary functional expression involving the values VDD, V, T
+# attr VName [|] = name for the voltage channel [|short name used in state reading]
+# attr VUnit = unit of measurement for the voltage channel (default V, none for empty)
+# attr Vfunction = arbitrary functional expression involving the values VDD, V, W, T
# 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
+# attr WName [|] = name for the sense channel [|short name used in state reading]
+# attr WUnit [|] = unit of measurement for the sense channel (default 1/16384 V, none for empty)
+# attr Wfunction = arbitrary functional expression involving the values VDD, V, W, T
+#
#
########################################################################################
#
@@ -82,9 +87,9 @@ no warnings 'deprecated';
sub Log($$);
-my $owx_version="5.23";
+my $owx_version="6.0";
#-- flexible channel name
-my $owg_channel;
+my ($owg_channel,$owg_schannel);
my %gets = (
"id" => "",
@@ -112,17 +117,14 @@ my %updates = (
#
# Prefix = OWMULTI
#
-##
-# Parameters:
-# hash - hash of device addressed
-#
-# Called By:
-# FHEM - Main Loop
-# Gargelmargel - dunno where
-#
-#Calling:
-# None
-##
+########################################################################################
+#
+# OWMULTI_Initialize
+#
+# Parameter hash = hash of device addressed
+#
+########################################################################################
+
sub OWMULTI_Initialize ($) {
my ($hash) = @_;
@@ -136,16 +138,17 @@ sub OWMULTI_Initialize ($) {
#tempOffset = a temperature offset added to the temperature reading for correction
#tempUnit = a unit of measure: C/F/K
- $hash->{AttrList}= "IODev do_not_notify:0,1 showtime:0,1 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 ".
- "VName VUnit VFunction ".
+ "VName VUnit VFunction WName WUnit WFunction ".
"interval ".
$readingFnAttributes;
#-- temperature and voltage globals - always the raw values from the device
$hash->{owg_val}->[0] = undef;
- $hash->{owg_val}->[2] = 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
main::LoadModule("OWX");
@@ -280,7 +283,7 @@ sub OWMULTI_Define ($$) {
$main::modules{OWMULTI}{defptr}{$id} = $hash;
#--
readingsSingleUpdate($hash,"state","defined",1);
- Log 3, "OWMULTI: Device $name defined.";
+ Log 3, "OWMULTI: Device $name defined.";
$hash->{NOTIFYDEV} = "global";
@@ -336,29 +339,48 @@ sub OWMULTI_ChannelNames($) {
my $name = $hash->{NAME};
my $state = $hash->{READINGS}{"state"}{VAL};
- my ($cname,@cnama,$unit,@unarr);
- my ($tunit,$toffset,$tfactor,$tabbr,$vfunc);
+ my ($cname,@cnama,$unit);
+ my ($tunit,$toffset,$tfactor,$tabbr,$vfunc,$wfunc);
#-- 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);
if( int(@cnama)!=2){
push(@cnama,$cnama[0]);
}
#-- unit
- $unit = defined($attr{$name}{"VUnit"}) ? $attr{$name}{"VUnit"} : "Volt|V";
- @unarr= split(/\|/,$unit);
- if( int(@unarr)!=2 ){
- push(@unarr,$unarr[0]);
- }
+ $unit = defined($attr{$name}{"VUnit"}) ? $attr{$name}{"VUnit"} : "V";
+ $unit = ""
+ if($unit eq "none");
#-- put into readings
$owg_channel = $cnama[0];
$hash->{READINGS}{$owg_channel}{VAL} = " ";
$hash->{READINGS}{$owg_channel}{ABBR} = $cnama[1];
- $hash->{READINGS}{$owg_channel}{UNIT} = $unarr[0];
- $hash->{READINGS}{$owg_channel}{UNITABBR} = $unarr[1];
+ $hash->{READINGS}{$owg_channel}{UNIT} = " ".$unit;
+
+
+ #-- 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
$hash->{READINGS}{"temperature"}{UNIT} = defined($attr{$name}{"tempUnit"}) ? $attr{$name}{"tempUnit"} : "Celsius";
@@ -366,13 +388,15 @@ sub OWMULTI_ChannelNames($) {
$toffset = defined($attr{$name}{"tempOffset"}) ? $attr{$name}{"tempOffset"} : 0.0 ;
$tfactor = 1.0;
- if( $tunit eq "Celsius" ){
- $tabbr = "°C";
+ if( $tunit eq "none" ){
+ $tabbr = "";
+ }elsif( $tunit eq "Celsius" ){
+ $tabbr = " °C";
} elsif ($tunit eq "Kelvin" ){
- $tabbr = "K";
+ $tabbr = " K";
$toffset += "273.16"
} elsif ($tunit eq "Fahrenheit" ){
- $tabbr = "°F";
+ $tabbr = " °F";
$toffset = ($toffset+32)/1.8;
$tfactor = 1.8;
} else {
@@ -382,8 +406,7 @@ sub OWMULTI_ChannelNames($) {
#-- these values are rather complex to obtain, therefore save them in the hash
$hash->{READINGS}{"temperature"}{ABBR} = "T";
- $hash->{READINGS}{"temperature"}{UNIT} = $tunit;
- $hash->{READINGS}{"temperature"}{UNITABBR} = $tabbr;
+ $hash->{READINGS}{"temperature"}{UNIT} = $tabbr;
$hash->{tempf}{offset} = $toffset;
$hash->{tempf}{factor} = $tfactor;
}
@@ -400,11 +423,11 @@ sub OWMULTI_FormatValues($) {
my ($hash) = @_;
my $name = $hash->{NAME};
- my ($toffset,$tfactor,$tval,$vfunc,$vval);
+ my ($toffset,$tfactor,$tval,$vfunc,$wfunc,$vval,$wval);
my $svalue = "";
#-- 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
OWMULTI_ChannelNames($hash);
@@ -414,35 +437,53 @@ sub OWMULTI_FormatValues($) {
$tfactor = $hash->{tempf}{factor};
$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";
+ $wfunc = defined($attr{$name}{"WFunction"}) ? $attr{$name}{"WFunction"} : "W";
#-- replace by proper values
$vfunc =~ s/VDD/\$hash->{owg_val}->[1]/g;
$vfunc =~ s/V/\$hash->{owg_val}->[2]/g;
+ $vfunc =~ s/W/\$hash->{owg_val}->[3]/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
- $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;
$vfunc = eval($vfunc);
if( !$vfunc ){
- $vval = "";
+ $vval = 0.0;
} elsif( $vfunc ne "" ){
- $vval = int( $vfunc*10+0.5)/10;
+ $vval = int( $vfunc*100+0.5)/100;
} 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
- $svalue .= sprintf( "%s: %5.1f %s (T: %5.1f %s)",
- $hash->{READINGS}{$owg_channel}{ABBR}, $vval,$hash->{READINGS}{$owg_channel}{UNITABBR},
- $tval,$hash->{READINGS}{"temperature"}{UNITABBR});
+ $svalue .= sprintf( "%s: %5.2f%s (T: %5.1f%s %s: %5.2f%s)",
+ $hash->{READINGS}{$owg_channel}{ABBR}, $vval,$hash->{READINGS}{$owg_channel}{UNIT},
+ $tval,$hash->{READINGS}{"temperature"}{UNIT}, $hash->{READINGS}{$owg_schannel}{ABBR}, $wval,$hash->{READINGS}{$owg_schannel}{UNIT});
#-- put into READINGS
readingsBeginUpdate($hash);
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);
#-- STATE
@@ -466,6 +507,7 @@ sub OWMULTI_Get($@) {
my $reading = $a[1];
my $name = $hash->{NAME};
my $model = $hash->{OW_MODEL};
+
my $value = undef;
my $ret = "";
@@ -538,27 +580,31 @@ sub OWMULTI_Get($@) {
return "OWMULTI: Get with wrong IODev type $interface";
}
- #-- process results
- if( defined($ret) ){
- return "OWMULTI: Could not get values from device $name, reason $ret";
- }
-
- #-- return the special reading
- if ($reading eq "reading") {
- return "OWMULTI: $name.reading => ".$hash->{READINGS}{"state"}{VAL};
- }
+ #-- process result
+ if( $master->{ASYNCHRONOUS} ){
+ return "OWSMULTI: $name getting readings, please wait for completion";
+ }else{
+ if( defined($ret) ){
+ return "OWMULTI: Could not get values from device $name, reason $ret";
+ }
+
+ #-- return the special reading
+ if ($reading eq "reading") {
+ return "OWMULTI: $name.reading => ".$hash->{READINGS}{"state"}{VAL};
+ }
- if ($reading eq "temperature") {
- return "OWMULTI: $name.temperature => ".
- $hash->{READINGS}{"temperature"}{VAL};
- }
- if ($reading eq "VDD") {
- return "OWMULTI: $name.VDD => ".
- $hash->{owg_val}->[1];
- }
- if ( $reading eq "raw") {
- return "OWMULTI: $name.raw => ".
- $hash->{owg_val}->[2];
+ if ($reading eq "temperature") {
+ return "OWMULTI: $name.temperature => ".
+ $hash->{READINGS}{"temperature"}{VAL};
+ }
+ if ($reading eq "VDD") {
+ return "OWMULTI: $name.VDD => ".
+ $hash->{owg_val}->[1];
+ }
+ if ( $reading eq "raw") {
+ return "OWMULTI: $name.raw => ".
+ $hash->{owg_val}->[2]." V ".$hash->{owg_val}->[3]." V";
+ }
}
return undef;
}
@@ -630,8 +676,9 @@ sub OWMULTI_InitializeDevice($) {
#-- Initial readings
$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
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}->[1] = OWServer_Read($master,"/$owx_add/VDD");
$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"
- 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"
- 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
$hash->{PRESENT} = 1;
my $value = OWMULTI_FormatValues($hash);
- Log 5, $value;
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
+# 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($$$$$$$$) {
- my ($hash, $context, $success, $reset, $owx_dev, $command, $numread, $res) = @_;
+sub OWXMULTI_BinValues($$$$$$$) {
+ 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
- return unless ($success and $context =~ /^ds2438.getv[ad]d$/);
+ return unless ($context =~ /^ds2438.getv[ad]d$/);
#Log 1,"OWXMULTI_BinValues context = $context";
#-- process results
- my @data=split(//,$res);
+ @data=split(//,$res);
if (@data != 9) {
- return "invalid data length, ".int(@data)." instead of 9 bytes";
- }
- if ((ord($data[0]) & 112)!=0) {
- return "conversion not complete or data invalid";
- }
- if (OWX_CRC8(substr($res,0,8),$data[8])==0) {
- return "invalid CRC";
+ $msg="$name returns invalid data length, ".int(@data)." instead of 9 bytes";
+ }elsif ((ord($data[0]) & 112)!=0) {
+ $msg="$name: conversion not complete or data invalid";
+ }elsif (OWX_CRC8(substr($res,0,8),$data[8])==0) {
+ $msg="$name returns invalid CRC";
+ }else{
+ $msg="No error";
}
+ OWX_WDBG($name,"OWXMULTI_BinValues: ".$msg,"")
+ if( $main::owx_debug>2 );
#-- this must be different for the different device types
# family = 26 => DS2438
#-- transform binary rep of VDD
- if( $context eq "ds2438.getvdd") {
+ if( $context eq "ds2438.getvdd") {
#-- temperature
- my $lsb = ord($data[1]);
- my $msb = ord($data[2]) & 127;
- my $sign = ord($data[2]) & 128;
+ $lsb = ord($data[1]);
+ $msb = ord($data[2]) & 127;
+ $sign = ord($data[2]) & 128;
#-- test with -55 degrees
#$lsb = 0;
@@ -843,7 +915,7 @@ sub OWXMULTI_BinValues($$$$$$$$) {
#$msb = 73;
#-- 2's complement form = signed bytes
- $hash->{owg_val}->[0] = $msb+ $lsb/256;
+ $hash->{owg_val}->[0] = $msb+ $lsb/256.;
if( $sign !=0 ){
$hash->{owg_val}->[0] = -128+$hash->{owg_val}->[0];
}
@@ -857,25 +929,31 @@ sub OWXMULTI_BinValues($$$$$$$$) {
#$msb = 1;
#-- supply voltage
- $hash->{owg_val}->[1] = ($msb*256+ $lsb)/100;
- };
+ $hash->{owg_val}->[1] = ($msb*256+ $lsb)/100.;
+
#-- transform binary rep of VAD
- if( $context eq "ds2438.getvad") {
+ }elsif( $context eq "ds2438.getvad") {
#-- voltage
- my $lsb = ord($data[3]);
- my $msb = ord($data[4]) & 3;
+ $lsb = ord($data[3]);
+ $msb = ord($data[4]) & 3;
#-- test with 7.2 V
#$lsb = 208;
#$msb = 2;
#-- external voltage
- $hash->{owg_val}->[2] = ($msb*256+ $lsb)/100;
-
- #-- and now from raw to formatted values
+ $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
$hash->{PRESENT} = 1;
my $value = OWMULTI_FormatValues($hash);
- Log 5, $value;
};
return undef;
}
@@ -893,7 +971,7 @@ sub OWXMULTI_GetValues($) {
my ($hash) = @_;
- my ($i,$j,$k,$res,$ret);
+ my ($res,$ret);
#-- ID of the device
my $owx_dev = $hash->{ROM_ID};
@@ -905,101 +983,181 @@ sub OWXMULTI_GetValues($) {
#------------------------------------------------------------------------------------
#-- switch the device to current measurement off, VDD only
#-- issue the match ROM command \x55 and the write scratchpad command
- OWX_Reset($master);
- if( OWX_Complex($master,$owx_dev,"\x4E\x00\x08",0) eq 0 ){
- return "$owx_dev write status failed";
- }
+ #-- OLD OWX interface
+ if( !$master->{ASYNCHRONOUS} ){
+ OWX_Reset($master);
+ #if( OWX_Complex($master,$owx_dev,"\x4E\x00\x08",0) eq 0 ){
+ if( OWX_Complex($master,$owx_dev,"\x4E\x00\x09",0) eq 0 ){
+ return "$owx_dev write status failed";
+ }
- #-- copy scratchpad to register
- #-- issue the match ROM command \x55 and the copy scratchpad command
- OWX_Reset($master);
- if( OWX_Complex($master,$owx_dev,"\x48\x00",0) eq 0){
- return "$owx_dev copy scratchpad failed";
- }
+ #-- copy scratchpad to register
+ #-- issue the match ROM command \x55 and the copy scratchpad command
+ OWX_Reset($master);
+ if( OWX_Complex($master,$owx_dev,"\x48\x00",0) eq 0){
+ return "$owx_dev copy scratchpad failed";
+ }
- #-- initiate temperature conversion
- #-- conversion needs some 12 ms !
- #-- issue the match ROM command \x55 and the start conversion command
- OWX_Reset($master);
- if( OWX_Complex($master,$owx_dev,"\x44",0) eq 0 ){
- return "$owx_dev temperature conversion failed";
- }
- select(undef,undef,undef,0.012);
+ #-- initiate temperature conversion
+ #-- conversion needs some 12 ms !
+ #-- issue the match ROM command \x55 and the start conversion command
+ OWX_Reset($master);
+ if( OWX_Complex($master,$owx_dev,"\x44",0) eq 0 ){
+ return "$owx_dev temperature conversion failed";
+ }
+ select(undef,undef,undef,0.012);
- #-- initiate voltage conversion
- #-- conversion needs some 6 ms !
- #-- issue the match ROM command \x55 and the start conversion command
- OWX_Reset($master);
- if( OWX_Complex($master,$owx_dev,"\xB4",0) eq 0 ){
- return "$owx_dev voltage conversion failed";
- }
- select(undef,undef,undef,0.006);
+ #-- initiate voltage conversion
+ #-- conversion needs some 6 ms !
+ #-- issue the match ROM command \x55 and the start conversion command
+ OWX_Reset($master);
+ if( OWX_Complex($master,$owx_dev,"\xB4",0.01) eq 0 ){
+ return "$owx_dev voltage conversion failed";
+ }
+ select(undef,undef,undef,0.006);
- #-- from memory to scratchpad
- #-- copy needs some 12 ms !
- #-- issue the match ROM command \x55 and the recall memory command
- OWX_Reset($master);
- if( OWX_Complex($master,$owx_dev,"\xB8\x00",0) eq 0 ){
- return "$owx_dev recall memory failed";
- }
- select(undef,undef,undef,0.012);
- #-- 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
- OWX_Reset($master);
- $res=OWX_Complex($master,$owx_dev,"\xBE\x00",9);
- #Log 1,"OWXMULTI: data length from reading device is ".length($res)." bytes";
- return "$owx_dev not accessible in 2nd step"
- if( $res eq 0 );
- return "$owx_dev has returned invalid data"
- if( length($res)!=20);
- $ret = OWXMULTI_BinValues($hash,"ds2438.getvdd",1,undef,$owx_dev,undef,undef,substr($res,11));
- return $ret if (defined $ret);
- #------------------------------------------------------------------------------------
- #-- switch the device to current measurement off, V external only
- #-- issue the match ROM command \x55 and the write scratchpad command
- OWX_Reset($master);
- if( OWX_Complex($master,$owx_dev,"\x4E\x00\x00",0) eq 0 ){
- return "$owx_dev write status failed";
- }
- #-- copy scratchpad to register
- #-- issue the match ROM command \x55 and the copy scratchpad command
- OWX_Reset($master);
- if( OWX_Complex($master,$owx_dev,"\x48\x00",0) eq 0){
- return "$owx_dev copy scratchpad failed";
- }
- #-- initiate voltage conversion
- #-- conversion needs some 6 ms !
- #-- issue the match ROM command \x55 and the start conversion command
- OWX_Reset($master);
- if( OWX_Complex($master,$owx_dev,"\xB4",0) eq 0 ){
- return "$owx_dev voltage conversion failed";
- }
- select(undef,undef,undef,0.006);
+ #-- from memory to scratchpad
+ #-- copy needs some 12 ms !
+ #-- issue the match ROM command \x55 and the recall memory command
+ OWX_Reset($master);
+ if( OWX_Complex($master,$owx_dev,"\xB8\x00",0.02) eq 0 ){
+ return "$owx_dev recall memory failed";
+ }
+ select(undef,undef,undef,0.012);
+ #-- 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
+ OWX_Reset($master);
+ $res=OWX_Complex($master,$owx_dev,"\xBE\x00",9);
+ #Log 1,"OWXMULTI: data length from reading device is ".length($res)." bytes";
+ return "$owx_dev not accessible in 2nd step"
+ if( $res eq 0 );
+ return "$owx_dev has returned invalid data"
+ if( length($res)!=20);
+ $ret = OWXMULTI_BinValues($hash,"ds2438.getvdd",undef,$owx_dev,undef,undef,substr($res,11));
+ return $ret if (defined $ret);
+ #------------------------------------------------------------------------------------
+ #-- switch the device to current measurement off, V external only
+ #-- issue the match ROM command \x55 and the write scratchpad command
+ OWX_Reset($master);
+ #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";
+ }
+ #-- copy scratchpad to register
+ #-- issue the match ROM command \x55 and the copy scratchpad command
+ OWX_Reset($master);
+ if( OWX_Complex($master,$owx_dev,"\x48\x00",0) eq 0){
+ return "$owx_dev copy scratchpad failed";
+ }
+ #-- initiate voltage conversion
+ #-- conversion needs some 6 ms !
+ #-- issue the match ROM command \x55 and the start conversion command
+ OWX_Reset($master);
+ if( OWX_Complex($master,$owx_dev,"\xB4",0.01) eq 0 ){
+ return "$owx_dev voltage conversion failed";
+ }
+ select(undef,undef,undef,0.006);
- #-- from memory to scratchpad
- #-- copy needs some 12 ms !
- #-- issue the match ROM command \x55 and the recall memory command
- OWX_Reset($master);
- if( OWX_Complex($master,$owx_dev,"\xB8\x00",0) eq 0 ){
- return "$owx_dev recall memory failed";
- }
- select(undef,undef,undef,0.012);
+ #-- from memory to scratchpad
+ #-- copy needs some 12 ms !
+ #-- issue the match ROM command \x55 and the recall memory command
+ OWX_Reset($master);
+ if( OWX_Complex($master,$owx_dev,"\xB8\x00",0.02) eq 0 ){
+ return "$owx_dev recall memory failed";
+ }
+ select(undef,undef,undef,0.012);
- #-- 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
- my $context = "ds2438.getvad";
- OWX_Reset($master);
- $res=OWX_Complex($master,$owx_dev,"\xBE\x00",9);
- #-- process results
- return "$owx_dev not accessible in 2nd step"
- if( $res eq 0 );
- return "$owx_dev has returned invalid data"
- if( length($res)!=20);
- return OWXMULTI_BinValues($hash,$context,1,undef,$owx_dev,undef,undef,substr($res,11));
+ #-- 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
+ my $context = "ds2438.getvad";
+ OWX_Reset($master);
+ $res=OWX_Complex($master,$owx_dev,"\xBE\x00",9);
+ #-- process results
+ return "$owx_dev not accessible in 2nd step"
+ if( $res eq 0 );
+ return "$owx_dev has returned invalid data"
+ if( length($res)!=20);
+ 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
@@ -1126,7 +1284,7 @@ sub OWXMULTI_PT_GetValues($) {
unless (defined $res and length($res)==9) {
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) {
die $ret;
}
@@ -1180,7 +1338,7 @@ sub OWXMULTI_PT_GetValues($) {
unless (defined $res and length($res)==9) {
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) {
die $ret;
}
@@ -1250,9 +1408,9 @@ sub OWXMULTI_PT_SetValues($@) {
define OWX_M OWMULTI 7C5034010000 45
- attr OWX_M VName relHumidity|humidity
+ attr OWX_M VName humidity|rH
- attr OWX_M VUnit percent|%
+ attr OWX_M VUnit %
attr OWX_M VFunction (161.29 * V / VDD - 25.8065)/(1.0546 - 0.00216 * T)
@@ -1305,34 +1463,43 @@ sub OWXMULTI_PT_SetValues($@) {
seconds.
get <name> reading
Obtain the measurement values
-
- get <name> VAD
Obtain the measurement value from
- VFunction.
get <name> temperature
Obtain the temperature value.
get <name> VDD
Obtain the current supply voltage.
get <name> V
or get <name>
- raw
Obtain the raw external voltage measurement.
+ raw
Obtain the raw external voltage and external sense measurement.
Attributes
attr <name> VName
<string>[|<string>]
-
name for the channel [|name used in state reading].
+
name for the voltage channel [|short name used in state reading].
+
attr <name> VUnit
- <string>[|<string>]
-
unit of measurement for this channel [|unit used in state reading].
+ <string>
+
unit of measurement for the voltage channel used in state reading (default "V", set to "none" for empty).
attr <name> VFunction
<string>
-
arbitrary functional expression involving the values VDD, V, T. Example see
+
arbitrary functional expression involving the values VDD, V, W and T. Example see
above.
- 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
+ attr <name> WName
+ <string>[|<string>]
+
name for the sense channel [|short name used in state reading].
+ attr <name> WUnit
+ <string>
+
unit of measurement for the sense channel used in state reading (default “V", set to "none" for empty).
+ attr <name> WFunction
+ <string>
+
arbitrary functional expression involving the values VDD, V, W and T. Example and usage see
+ above.
attr <name> tempOffset <float>
temperature offset in °C added to the raw temperature reading.
@@ -1340,12 +1507,7 @@ sub OWXMULTI_PT_SetValues($@) {
Celsius|Kelvin|Fahrenheit
unit of measurement (temperature scale), default is Celsius = °C
- - Standard attributes alias, comment, event-on-update-reading, event-on-change-reading, stateFormat, room, eventMap, loglevel,
- webCmd
+ - readingFnAttributes
=end html
diff --git a/fhem/FHEM/21_OWSWITCH.pm b/fhem/FHEM/21_OWSWITCH.pm
index 5fbd9da81..53e60fdfd 100644
--- a/fhem/FHEM/21_OWSWITCH.pm
+++ b/fhem/FHEM/21_OWSWITCH.pm
@@ -16,7 +16,7 @@
# where may be replaced by any name string
#
# 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
# is a 1-Wire family id, currently allowed values are 12, 29, 3A
# is a 12 character (6 byte) 1-Wire ROM ID
# without Family ID, e.g. A2D90D000800
@@ -45,10 +45,8 @@
# Additional attributes are defined in fhem.cfg, in some cases per channel, where =A,B
# Note: attributes are read only during initialization procedure - later changes are not used.
#
-# attr stateS = character string denoting external shortening condition, default is (ext)
-# overwritten by an attribute setting "red angled arrow downward"
-#
-# attr Name | = name for the channel [|name used in state reading]
+# attr stateS = character string denoting external shortening condition, default is X
+# attr Name | = name for the channel [|short name used in state reading]
# attr Unit | = values to display in state variable for on|off condition
#
########################################################################################
@@ -89,7 +87,7 @@ no warnings 'deprecated';
sub Log($$);
-my $owx_version="5.24";
+my $owx_version="6.0";
#-- fixed raw channel name, flexible channel name
my @owg_fixed = ("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
#
-# CalledBy: FHEM
-# Calling: --
# Parameter: hash = hash of device addressed
#
########################################################################################
@@ -148,7 +144,7 @@ sub OWSWITCH_Initialize ($) {
$hash->{InitFn} = "OWSWITCH_Init";
$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 ".
$readingFnAttributes;
@@ -172,8 +168,6 @@ sub OWSWITCH_Initialize ($) {
#
# OWSWITCH_Define - Implements DefFn function
#
-# CalledBy: FHEM
-# Calling: --
# Parameter: hash = hash of device addressed, def = definition string
#
#########################################################################################
@@ -280,8 +274,6 @@ sub OWSWITCH_Define ($$) {
#
# OWSWITCH_Notify - Implements Notify function
#
-# CalledBy: FHEM
-# Calling: --
# Parameter: hash = hash of device addressed, def = definition string
#
#########################################################################################
@@ -298,8 +290,6 @@ sub OWSWITCH_Notify ($$) {
#
# OWSWITCH_Init - Implements Init function
#
-# CalledBy: FHEM
-# Calling: --
# Parameter: hash = hash of device addressed, def = definition string
#
#########################################################################################
@@ -316,8 +306,6 @@ sub OWSWITCH_Init ($) {
#
# OWSWITCH_Attr - Set one attribute value for device
#
-# CalledBy: FHEM
-# Calling: --
# Parameter: hash = hash of device addressed
# a = argument array
#
@@ -362,8 +350,6 @@ sub OWSWITCH_Attr(@) {
#
# OWSWITCH_ChannelNames - find the real channel names
#
-# CalledBy: OWSWITCH_FormatValues, OWSWITCH_Get, OWSWITCH_Set
-# Calling: --
# Parameter: hash = hash of device addressed
#
########################################################################################
@@ -378,7 +364,7 @@ sub OWSWITCH_ChannelNames($) {
for (my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){
#-- 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);
if( int(@cnama)!=2){
push(@cnama,$cnama[0]);
@@ -398,7 +384,6 @@ sub OWSWITCH_ChannelNames($) {
#-- put into readings
$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
#
-# CalledBy: OWSWITCH_Get, OWSWITCH_Set
-# Calling: --
# Parameter; hash = hash of device addressed, fs = format string
#
########################################################################################
@@ -420,7 +403,9 @@ sub OWSWITCH_FormatValues($) {
my $svalue = "";
#-- 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
OWSWITCH_ChannelNames($hash);
@@ -466,10 +451,6 @@ sub OWSWITCH_FormatValues($) {
#
# 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
#
########################################################################################
@@ -480,6 +461,7 @@ sub OWSWITCH_Get($@) {
my $reading = $a[1];
my $name = $hash->{NAME};
my $model = $hash->{OW_MODEL};
+
my ($value,$value2,$value3) = (undef,undef,undef);
my $ret = "";
my ($offset,$factor,$page,$cname,@cnama,@channel);
@@ -550,7 +532,7 @@ sub OWSWITCH_Get($@) {
#-- OWX interface
if( $interface eq "OWX" ){
- $ret = OWXSWITCH_GetState($hash);
+ OWXSWITCH_GetModState($hash,undef,undef);
}elsif( $interface eq "OWX_ASYNC") {
eval {
$ret = OWX_ASYNC_RunToCompletion($hash,OWXSWITCH_PT_GetState($hash));
@@ -563,8 +545,12 @@ sub OWSWITCH_Get($@) {
}else{
return "OWSWITCH: Get with wrong IODev type $interface";
}
- #-- process results
- return $name.".".$a[2]." => ".$hash->{READINGS}{$owg_channel[$fnd]}{VAL};
+ #-- 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};
+ }
#-- get all states
}elsif( $reading eq "gpio" ){
@@ -572,7 +558,7 @@ sub OWSWITCH_Get($@) {
if( int(@a)==1 );
if( $interface eq "OWX" ){
- $ret = OWXSWITCH_GetState($hash);
+ $ret = OWXSWITCH_GetModState($hash,undef,undef);
}elsif( $interface eq "OWX_ASYNC" ){
eval {
$ret = OWX_ASYNC_RunToCompletion($hash,OWXSWITCH_PT_GetState($hash));
@@ -584,10 +570,14 @@ sub OWSWITCH_Get($@) {
return "OWSWITCH: Get with wrong IODev type $interface";
}
#-- process results
- if( defined($ret) ){
- return "OWSWITCH: Could not get values from device $name, reason $ret";
+ if( $master->{ASYNCHRONOUS} ){
+ return "OWSWITCH: $name getting gpio, please wait for completion";
+ }else{
+ if( defined($ret) ){
+ return "OWSWITCH: Could not get values from device $name, reason $ret";
+ }
+ return "OWSWITCH: $name.$reading => ".$hash->{READINGS}{"state"}{VAL};
}
- return "OWSWITCH: $name.$reading => ".$hash->{READINGS}{"state"}{VAL};
}
}
@@ -620,7 +610,7 @@ sub OWSWITCH_GetValues($) {
if( $interface eq "OWX" ){
#-- max 3 tries
for(my $try=0; $try<3; $try++){
- $ret = OWXSWITCH_GetState($hash);
+ $ret = OWXSWITCH_GetModState($hash,undef,undef);
return if( !defined($ret) );
}
}elsif( $interface eq "OWX_ASYNC" ){
@@ -652,6 +642,7 @@ sub OWSWITCH_GetValues($) {
########################################################################################
#
# OWSWITCH_InitializeDevice - initial readings
+#
# Parameter hash = hash of device addressed
#
########################################################################################
@@ -738,24 +729,24 @@ sub OWSWITCH_Set($@) {
return "OWSWITCH: Set needs parameter when writing output: "
if( int(@a)<2 );
#-- find out which channel we have
- my $fnd=undef;
+ my $outfnd=undef;
for (my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){
if( ($a[2] eq $owg_channel[$i]) || ($a[2] eq $owg_fixed[$i]) ){
- $fnd=$i;
+ $outfnd=$i;
last;
}
}
return "OWSWITCH: Invalid output address, must be A,B,... or defined channel name"
- if( !defined($fnd) );
+ if( !defined($outfnd) );
#-- prepare gpio value
- my $nval;
+ my $outval;
my $ntim;
my $nstr="";
if( lc($a[3]) eq "on" ){
- $nval = 0;
+ $outval = 0;
}elsif( lc($a[3]) eq "off" ){
- $nval = 1;
+ $outval = 1;
}elsif( lc($a[3]) =~ m/for-timer/ ){
if( !($a[4] =~ m/\d\d\:\d\d\:\d\d/) ){
if( !($a[4] =~ m/\d{1,4}/ )){
@@ -767,10 +758,10 @@ sub OWSWITCH_Set($@) {
$ntim= $a[4];
}
if( lc($a[3]) eq "on-for-timer" ){
- $nval = 0;
+ $outval = 0;
$nstr = "$a[0] $a[1] $a[2] off";
}elsif( lc($a[3]) eq "off-for-timer" ){
- $nval = 1;
+ $outval = 1;
$nstr = "$a[0] $a[1] $a[2] on";
}
}else{
@@ -778,36 +769,31 @@ sub OWSWITCH_Set($@) {
}
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
if( $interface eq "OWX" ){
- $ret1 = OWXSWITCH_GetState($hash);
- $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);
+ $ret1 = OWXSWITCH_GetModState($hash,$outfnd,$outval);
}elsif( $interface eq "OWX_ASYNC"){
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 $@;
#-- OWFS interface
}elsif( $interface eq "OWServer" ){
$ret1 = OWFSSWITCH_GetState($hash);
- $value = 0;
- #-- vax or val ?
+ my $gpio = 0;
+ #--
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 );
+ 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 );
+ }
}
$ret2 = OWFSSWITCH_SetState($hash,$value);
#-- Unknown interface
@@ -848,7 +834,7 @@ sub OWSWITCH_Set($@) {
}
#-- process results - we have to reread the device
- OWSWITCH_GetValues($hash);
+ #OWSWITCH_GetValues($hash);
Log 4, "OWSWITCH: Set $hash->{NAME} $key $value";
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
+# 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($$$$$$$$) {
- my ($hash, $context, $success, $reset, $owx_dev, $command, $numread, $res) = @_;
-
- #-- always check for success, unused are reset, numread
- return unless ($success and $context);
- #Log 1,"OWXSWITCH_BinValues context = $context";
+sub OWXSWITCH_BinValues($$$$$$$) {
+ my ($hash, $context, $reset, $owx_dev, $crcpart, $numread, $res) = @_;
- my @data=[];
- my $value;
#-- hash of the busmaster
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
# val = input value, vax = output value
#-- 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 -------------------------------------------------------
- if( ($context eq "getstate.ds2406") or ($context eq "ds2406.getstate") ) {
+ if( $chip eq "ds2406" ) {
@data=split(//,$res);
- return "invalid data length, ".int(@data)." instead of 4 bytes"
- if (@data != 4);
- return "invalid CRC"
- if ( OWX_CRC16($command.substr($res,0,2),$data[2],$data[3]) == 0);
- $hash->{owg_val}->[0] = (ord($data[0])>>2) & 1;
- $hash->{owg_vax}->[0] = ord($data[0]) & 1;
- $hash->{owg_val}->[1] = (ord($data[0])>>3) & 1;
- $hash->{owg_vax}->[1] = (ord($data[0])>>1) & 1;
-
+ if (@data != 4){
+ $msg="Error - $name returns invalid data length, ".int(@data)." instead of 4 bytes, ";
+ }elsif(OWX_CRC16($crcpart.substr($res,0,2),$data[2],$data[3]) == 0){
+ $msg="Error - state could not be set for device $name, invalid CRC, ";
+ }else{
+ $msg="No error, ";
+ $value=ord($data[0]);
+ $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 -------------------------------------------------------
- }elsif( ($context eq "getstate.ds2408") or ($context eq "ds2408.getstate") ) {
+ }elsif( $chip eq "ds2408" ) {
@data=split(//,$res);
- return "invalid data length, ".int(@data)." instead of 10 bytes"
- if (@data != 10);
- return "invalid data"
- if (ord($data[6])!=255);
- return "invalid CRC"
- if( OWX_CRC16($command.substr($res,0,8),$data[8],$data[9]) == 0);
- 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;
- };
+ if (@data != 10){
+ $msg="Error - $name returns invalid data length, ".int(@data)." instead of 10 bytes, ";
+ }elsif(ord($data[6])!=255){
+ $msg="Error - $name returns invalid data, ";
+ }elsif(OWX_CRC16($crcpart.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++){
+ $hash->{owg_val}->[$i] = (ord($data[0])>>$i) & 1;
+ $hash->{owg_vax}->[$i] = (ord($data[1])>>$i) & 1;
+ };
+ }
+ OWX_WDBG($name,"OWXSWITCH_BinValues: ".$msg,$res)
+ if( $main::owx_debug>2 );
#-- family = 3A => DS2413 -------------------------------------------------------
- }elsif( ($context eq "getstate.ds2413") or ($context eq "ds2413.getstate") ){
+ }elsif( $chip eq "ds2413" ){
@data=split(//,$res);
- return "invalid data length, ".int(@data)." instead of 2 bytes"
- if (@data != 2);
- return "invalid data"
- if ( (15- (ord($data[0])>>4)) != (ord($data[0]) & 15) );
- $hash->{owg_val}->[0] = ord($data[0]) & 1;
- $hash->{owg_vax}->[0] = (ord($data[0])>>1) & 1;
- $hash->{owg_val}->[1] = (ord($data[0])>>2) & 1;
- $hash->{owg_vax}->[1] = (ord($data[0])>>3) & 1;
+ if (@data != 2){
+ $msg="Error - $name returns invalid data length, ".int(@data)." instead of 2 bytes, ";
+ }elsif((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_vax}->[0] = (ord($data[0])>>1) & 1;
+ $hash->{owg_val}->[1] = (ord($data[0])>>2) & 1;
+ $hash->{owg_vax}->[1] = (ord($data[0])>>3) & 1;
+ }
+ OWX_WDBG($name,"OWXSWITCH_BinValues: ".$msg,$res)
+ if( $main::owx_debug>2 );
+
#--
}else{
- 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
- }elsif ( $context =~ /.*setstate.*/){
+ }elsif ( $context =~ /^(......)\.setstate\.?(\d+)?\.?(\d+)?/){
+ $chip = $1;
+ $value = $2;
#-- family = 12 => DS2406 -------------------------------------------------------
- if( ($context =~ /setstate\.ds2406\..*/) or ($context =~ /ds2406\.setstate\..*/) ) {
- $value = substr($context,-1);
+ if( $chip eq "ds2406" ) {
@data=split(//,$res);
- return "state could not be set for device $owx_dev"
- if( int(@data) != 2);
- return "invalid CRC"
- if (OWX_CRC16($command,$data[0],$data[1]) == 0);
- #-- put into local buffer]";
- $hash->{owg_val}->[0] = $value % 2;
- $hash->{owg_vax}->[0] = $value % 2;
- $hash->{owg_val}->[1] = int($value / 2);
- $hash->{owg_vax}->[1] = int($value / 2);
-
+ if (@data != 2){
+ $msg="Error - $name returns invalid data length, ".int(@data)." instead of 2 bytes, ";
+ }elsif(OWX_CRC16($crcpart,$data[0],$data[1]) == 0){
+ $msg="Error - state could not be set for device $name, invalid CRC, ";
+ }else{
+ $msg="No error, ";
+ $outval = $value % 2;
+ $hash->{owg_vax}->[0] = $outval;
+ $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 -------------------------------------------------------
- }elsif( ($context eq "setstate.ds2408") or ($context eq "ds2408.setstate") ) {
- @data=split(//,$res);
- return "invalid data length, ".int(@data)." instead of 1 bytes"
- if (@data != 1);
- return "state could not be set for device $owx_dev"
- if( $data[0] ne "\xAA");
+ }elsif( $chip eq "ds2408" ) {
+ if (length($res)!=1){
+ $msg="Error - $name returns invalid data length, ".length($res)." instead of 1 bytes, ";
+ }elsif($res ne "\xAA"){
+ $msg="Error - state could not be set for device $name, ";
+ }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 -------------------------------------------------------
- }elsif( ($context eq "setstate.ds2413") or ($context eq "ds2413.setstate") ){
+ }elsif( $chip eq "ds2413" ){
@data=split(//,$res);
- return "invalid data length, ".int(@data)." instead of 1 bytes"
- if (@data != 1);
- return "state could not be set for device $owx_dev"
- if( $data[0] ne "\xAA");
+ if (@data != 2){
+ $msg="Error - $name returns invalid data length, ".int(@data)." instead of 2 bytes, ";
+ }elsif( $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{
- 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{
- return "unknown context in OWXSWITCH_BinValues";
+ die "OWSWITCH: unknown context $context in OWXSWITCH_BinValues";
}
#-- and now from raw to formatted values
$hash->{PRESENT} = 1;
$value = OWSWITCH_FormatValues($hash);
- Log 5, $value;
return undef;
}
########################################################################################
#
-# OWXSWITCH_GetState - Get gpio ports from device
+# OWXSWITCH_GetModState - Get gpio ports from device and overwrite
#
# Parameter hash = hash of device addressed
+# mod = if 1, overwrite state with new data
#
########################################################################################
-sub OWXSWITCH_GetState($@) {
- my ($hash,$sync) = @_;
+sub OWXSWITCH_GetModState($$$) {
+ my ($hash,$outfnd,$outval) = @_;
my ($select, $res, @data);
@@ -1137,12 +1215,24 @@ sub OWXSWITCH_GetState($@) {
#-- hash of the busmaster
my $master = $hash->{IODev};
+ my $name = $hash->{NAME};
#-- reset presence
$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
if( $hash->{OW_FAMILY} eq "12" ) {
#=============== get gpio values ===============================
@@ -1150,45 +1240,78 @@ sub OWXSWITCH_GetState($@) {
# \xF5 plus the two byte channel control and the value
#-- reading 9 + 3 + 2 data bytes + 2 CRC bytes = 16 bytes
$select=sprintf("\xF5\xDD\xFF");
- OWX_Reset($master);
- $res=OWX_Complex($master,$owx_dev,$select,4);
- return "$owx_dev not accessible in reading"
- if( $res eq 0 );
- return "$owx_dev has returned invalid data"
- if( length($res)!=16);
- OWX_Reset($master);
- return OWXSWITCH_BinValues($hash,"ds2406.getstate",1,undef,$owx_dev,substr($res,9,3),undef,substr($res,12));
+ #-- OLD OWX interface
+ if( !$master->{ASYNCHRONOUS} ){
+ OWX_Reset($master);
+ $res=OWX_Complex($master,$owx_dev,$select,4);
+ return "OWSWITCH: $name not accessible in reading"
+ if( $res eq 0 );
+ return "OWSWITCH: $name has returned invalid data"
+ if( length($res)!=16);
+ #OWX_Reset($master);
+ eval {
+ OWXSWITCH_BinValues($hash,"ds2406.$context",undef,$owx_dev,$select,4,substr($res,12));
+ };
+ return $@ ? $@ : undef;
+ #-- NEW OWX interface
+ }else{
+ #### master slave context proc owx_dev data crcpart numread startread callback delay
+ OWX_Qomplex($master, $hash, "ds2406.$context", $proc, $owx_dev, $select, $select, 4, 12, \&OWXSWITCH_BinValues, 0);
+ return undef;
+ }
#-- family = 29 => DS2408
}elsif( $hash->{OW_FAMILY} eq "29" ) {
#=============== 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
#-- reading 9 + 3 + 8 data bytes + 2 CRC bytes = 22 bytes
- $select=sprintf("\xF0\x88\x00");
- OWX_Reset($master);
- $res=OWX_Complex($master,$owx_dev,$select,10);
- return "$owx_dev not accessible in reading"
- if( $res eq 0 );
- return "$owx_dev has returned invalid data"
- if( length($res)!=22);
- OWX_Reset($master);
- return OWXSWITCH_BinValues($hash,"ds2408.getstate",1,undef,$owx_dev,substr($res,9,3),undef,substr($res,12));
+ $select=sprintf("\xF0\x88\x00");
+ #-- OLD OWX interface
+ if( !$master->{ASYNCHRONOUS} ){
+ OWX_Reset($master);
+ $res=OWX_Complex($master,$owx_dev,$select,10);
+ return "OWSWITCH: $name not accessible in reading"
+ if( $res eq 0 );
+ return "OWSWITCH: $name has returned invalid data"
+ if( length($res)!=22);
+ #OWX_Reset($master);
+ eval {
+ OWXSWITCH_BinValues($hash,"ds2408.$context",0,$owx_dev,$select,4,substr($res,12));
+ };
+ return $@ ? $@ : undef;
+ #-- NEW OWX interface
+ }else{
+ #### master slave context proc owx_dev data crcpart numread startread callback delay
+ OWX_Qomplex($master, $hash, "ds2408.$context", $proc, $owx_dev, $select, $select,10, 12, \&OWXSWITCH_BinValues, 0);
+ return undef;
+ }
#-- family = 3A => DS2413
}elsif( $hash->{OW_FAMILY} eq "3A" ) {
#=============== get gpio values ===============================
#-- issue the match ROM command \x55 and the read gpio command
# \xF5 plus 2 empty bytes
#-- reading 9 + 1 + 2 data bytes = 12 bytes
- OWX_Reset($master);
- $res=OWX_Complex($master,$owx_dev,"\xF5",2);
- return "$owx_dev not accessible in reading"
- if( $res eq 0 );
- return "$owx_dev has returned invalid data"
- if( length($res)!=12);
- #OWX_Reset($master);
- return OWXSWITCH_BinValues($hash,"ds2413.getstate",1,undef,$owx_dev,substr($res,9,1),undef,substr($res,10));
+ #-- OLD OWX interface
+ if( !$master->{ASYNCHRONOUS} ){
+ OWX_Reset($master);
+ $res=OWX_Complex($master,$owx_dev,"\xF5",2);
+ return "OWSWITCH: $name not accessible in reading"
+ if( $res eq 0 );
+ return "OWSWITCH: $name has returned invalid data"
+ if( length($res)!=12);
+ #OWX_Reset($master);
+ eval {
+ OWXSWITCH_BinValues($hash,"ds2413.$context",0,$owx_dev,substr($res,9,1),2,substr($res,10));
+ };
+ return $@ ? $@ : undef;
+ #-- NEW OWX interface
+ }else{
+ #### master slave context proc owx_dev data crcpart numread startread callback delay
+ OWX_Qomplex($master, $hash, "ds2413.$context", $proc, $owx_dev, "\xF5", "\xF5", 2, 10, \&OWXSWITCH_BinValues, 0);
+ return undef;
+ }
} else {
- return "unknown device family $hash->{OW_FAMILY}\n";
+ return "OWSWITCH: $name has unknown device family $hash->{OW_FAMILY}\n";
}
}
@@ -1197,7 +1320,7 @@ sub OWXSWITCH_GetState($@) {
# OWXSWITCH_SetState - Set gpio ports of device
#
# 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 ($select, $res, $res2, @data);
#-- ID of the device
@@ -1215,8 +1337,6 @@ sub OWXSWITCH_SetState($$) {
#-- hash of the busmaster
my $master = $hash->{IODev};
-
- my ($i,$j,$k);
#-- family = 12 => DS2406
if( $hash->{OW_FAMILY} eq "12" ) {
@@ -1240,42 +1360,66 @@ sub OWXSWITCH_SetState($$) {
# \x55 at address TA1 = \x07 TA2 = \x00
#-- reading 9 + 4 + 2 data bytes = 15 bytes
$select=sprintf("\x55\x07\x00%c",$statneu);
- OWX_Reset($master);
- $res=OWX_Complex($master,$owx_dev,$select,2);
- if( $res eq 0 ){
- return "device $owx_dev not accessible in writing";
+ #-- OLD OWX interface
+ if( !$master->{ASYNCHRONOUS} ){
+ OWX_Reset($master);
+ $res=OWX_Complex($master,$owx_dev,$select,2);
+ if( $res eq 0 ){
+ return "device $owx_dev not accessible in writing";
+ }
+ #OWX_Reset($master);
+ return OWXSWITCH_BinValues($hash,"ds2406.setstate.$value",0,$owx_dev,$select,2,substr($res,13));
+ #-- NEW OWX interface
+ }else{
+ #### master slave context proc owx_dev data crcpart numread startread callback delay
+ # 16 pushes this to the top of the queue
+ OWX_Qomplex($master, $hash, "ds2406.setstate.$value", 16, $owx_dev, $select, $select, 2, 13, \&OWXSWITCH_BinValues, 0);
+ return undef;
}
- OWX_Reset($master);
- return OWXSWITCH_BinValues($hash,"ds2406.setstate.$value",1,undef,$owx_dev,substr($res,9,4),undef,substr($res,13));
- return;
#-- family = 29 => DS2408
} elsif( $hash->{OW_FAMILY} eq "29" ) {
#=============== set gpio values ===============================
#-- issue the match ROM command \x55 and the write gpio command
# \x5A plus the value byte and its complement
$select=sprintf("\x5A%c%c",$value,255-$value);
- OWX_Reset($master);
- $res=OWX_Complex($master,$owx_dev,$select,1);
- if( $res eq 0 ){
- return "device $owx_dev not accessible in writing";
+ #-- OLD OWX interface
+ if( !$master->{ASYNCHRONOUS} ){
+ OWX_Reset($master);
+ $res=OWX_Complex($master,$owx_dev,$select,1);
+ if( $res eq 0 ){
+ return "device $owx_dev not accessible in writing";
+ }
+ OWX_Reset($master);
+ return OWXSWITCH_BinValues($hash,"ds2408.setstate.$value",0,$owx_dev,0,1,substr($res,12));
+ #-- NEW OWX interface
+ }else{
+ #### master slave context proc owx_dev data crcpart numread startread callback delay
+# 16 pushes this to the top of the queue
+ OWX_Qomplex($master, $hash, "ds2408.setstate.$value", 16, $owx_dev, $select, 0, 1, 12, \&OWXSWITCH_BinValues, 0);
+ return undef;
}
- OWX_Reset($master);
- return OWXSWITCH_BinValues($hash,"ds2408.setstate",1,undef,$owx_dev,undef,undef,substr($res,12));
- return;
#-- family = 3A => DS2413
} elsif( $hash->{OW_FAMILY} eq "3A" ) {
#=============== set gpio values ===============================
#-- issue the match ROM command \x55 and the write gpio command
# \x5A plus the value byte and its complement
$select=sprintf("\x5A%c%c",252+$value,3-$value);
- OWX_Reset($master);
- $res=OWX_Complex($master,$owx_dev,$select,1);
- if( $res eq 0 ){
- return "device $owx_dev not accessible in writing";
+ #-- OLD OWX interface
+ if( !$master->{ASYNCHRONOUS} ){
+ OWX_Reset($master);
+ $res=OWX_Complex($master,$owx_dev,$select,1);
+ if( $res eq 0 ){
+ return "device $owx_dev not accessible in writing";
+ }
+ OWX_Reset($master);
+ return OWXSWITCH_BinValues($hash,"ds2413.setstate",0,$owx_dev,0,2,substr($res,12));
+ #-- NEW OWX interface
+ }else{
+ #### master slave context proc owx_dev data cmd numread startread callback delay
+ # 16 pushes this to the top of the queue
+ OWX_Qomplex($master, $hash, "ds2413.setstate", 16, $owx_dev, $select, 0, 2, 12, \&OWXSWITCH_BinValues, 0);
+ return undef;
}
- OWX_Reset($master);
- return OWXSWITCH_BinValues($hash,"ds2413.setstate",1,undef,$owx_dev,undef,undef,substr($res,12));
- return;
}else {
return "unknown device family $hash->{OW_FAMILY}\n";
}
@@ -1322,7 +1466,7 @@ sub OWXSWITCH_PT_GetState($) {
unless (length($response) == 4) {
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) {
PT_EXIT($ret);
}
@@ -1340,7 +1484,7 @@ sub OWXSWITCH_PT_GetState($) {
unless (length($response) == 10) {
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) {
PT_EXIT($ret);
}
@@ -1358,7 +1502,7 @@ sub OWXSWITCH_PT_GetState($) {
unless (length($response) == 2) {
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) {
PT_EXIT($ret);
}
@@ -1534,7 +1678,7 @@ sub OWXSWITCH_PT_SetOutput($$$) {
define OWX_S OWSWITCH DS2413 B5D502000000 60
- attr OWX_S AName Lampe|light
+ attr OWX_S AName light-a|la
attr OWX_S AUnit AN|AUS
@@ -1597,7 +1741,7 @@ sub OWXSWITCH_PT_SetOutput($$$) {
Returns 1 if this 1-Wire device is present, otherwise 0.
- get <name> interval
Returns measurement interval in
+ get <name> interval
Measurement interval in
seconds.
get <name> input <channel-name>
state for
@@ -1605,7 +1749,7 @@ sub OWXSWITCH_PT_SetOutput($$$) {
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
state of 1 = OFF, but a measured state of 0 = ON can also be due to an external
- shortening of the output.
+ shortening of the output, it will be signaled by appending the value of the attribute stateS to the reading.
get <name> gpio
Obtain state of all channels
@@ -1613,19 +1757,14 @@ sub OWXSWITCH_PT_SetOutput($$$) {
Attributes
For each of the following attributes, the channel identification A,B,...
may be used.
<name> stateS <string>
-
character string denoting external shortening condition, default is "red angled arrow downward"
+
character string denoting external shortening condition (default is X, set to "none" for empty).
attr <name> <channel>Name
<string>[|<string>]
-
name for the channel [|name used in state reading]
+
name for the channel [|short name used in state reading]
attr <name> <channel>Unit
<string>|<string>
display for on | off condition
- - Standard attributes alias, comment, event-on-update-reading, event-on-change-reading, stateFormat, room, eventMap, loglevel,
- webCmd
+ - readingFnAttributes
=end html
diff --git a/fhem/FHEM/21_OWTHERM.pm b/fhem/FHEM/21_OWTHERM.pm
index c049db51e..34bd565d9 100644
--- a/fhem/FHEM/21_OWTHERM.pm
+++ b/fhem/FHEM/21_OWTHERM.pm
@@ -35,8 +35,8 @@
#
# Additional attributes are defined in fhem.cfg
#
-# attr stateAL "" = character string for denoting low alarm condition, default is down triangle
-# attr stateAH "" = character string for denoting high alarm condition, default is up triangle
+# attr stateAL "" = character string for denoting low alarm condition, default is ↓
+# attr stateAH "" = character string for denoting high alarm condition, default is ↑
# attr tempOffset = temperature offset in degree Celsius added to the raw temperature reading
# attr tempUnit = unit of measurement, e.g. Celsius/Kelvin/Fahrenheit, default is Celsius
# attr tempConv onkick|onread = determines, whether a temperature measurement will happen when "kicked"
@@ -86,7 +86,7 @@ no warnings 'deprecated';
sub Log3($$$);
sub AttrVal($$$);
-my $owx_version="5.28";
+my $owx_version="6.0";
my %gets = (
"id" => "",
@@ -141,7 +141,7 @@ sub OWTHERM_Initialize ($) {
$hash->{NotifyFn}= "OWTHERM_Notify";
$hash->{InitFn} = "OWTHERM_Init";
$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 ".
"tempOffset tempUnit:Celsius,Fahrenheit,Kelvin ".
"tempConv:onkick,onread tempLow tempHigh ".
@@ -254,7 +254,7 @@ sub OWTHERM_Define ($$) {
$modules{OWTHERM}{defptr}{$id} = $hash;
#--
readingsSingleUpdate($hash,"state","defined",1);
- Log3 $name, 3, "OWTHERM: Device $name defined.";
+ Log3 $name, 3, "OWTHERM: Device $name defined.";
$hash->{NOTIFYDEV} = "global";
@@ -264,6 +264,16 @@ sub OWTHERM_Define ($$) {
return undef;
}
+#######################################################################################
+#
+# OWTHERM_Notify - Implements the Notify function
+#
+# Parameter hash = hash of device addressed
+# a = argument array
+#
+########################################################################################
+
+
sub OWTHERM_Notify ($$) {
my ($hash,$dev) = @_;
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 ($) {
my ($hash)=@_;
#-- Start timer for updates
@@ -355,28 +375,29 @@ sub OWTHERM_FormatValues($) {
my $svalue = "";
#-- attributes defined ?
- $stateal = AttrVal($name,"stateAL","▾");
- $stateah = AttrVal($name,"stateAH","▴");
+ $stateal = AttrVal($name,"stateAL","↓");
+ $stateah = AttrVal($name,"stateAH","↑");
$unit = AttrVal($name,"tempUnit","Celsius");
$offset = AttrVal($name,"tempOffset",0.0);
$factor = 1.0;
- if( $unit eq "Celsius" ){
- $abbr = "°C";
+ if( $unit eq "none" ){
+ $abbr = "";
+ }elsif( $unit eq "Celsius" ){
+ $abbr = " °C";
} elsif ($unit eq "Kelvin" ){
- $abbr = "K";
+ $abbr = " K";
$offset += "273.16"
} elsif ($unit eq "Fahrenheit" ){
- $abbr = "°F";
+ $abbr = " °F";
$offset = ($offset+32)/1.8;
$factor = 1.8;
} else {
- $abbr="?";
+ $abbr=" ?";
Log3 $name, 3, "OWTHERM_FormatValues: Unknown temperature unit $unit";
}
#-- these values are rather complex to obtain, therefore save them in the hash
- $hash->{READINGS}{"temperature"}{UNIT} = $unit;
- $hash->{READINGS}{"temperature"}{UNITABBR} = $abbr;
+ $hash->{READINGS}{"temperature"}{UNIT} = $abbr;
$hash->{tempf}{offset} = $offset;
$hash->{tempf}{factor} = $factor;
@@ -392,7 +413,7 @@ sub OWTHERM_FormatValues($) {
$main::attr{$name}{"tempHigh"} = $vhigh;
#-- formats for output
- $statef = "T: %5.2f ".$abbr;
+ $statef = "T: %5.2f".$abbr;
$svalue = sprintf($statef,$vval);
#-- Test for alarm condition
@@ -431,6 +452,7 @@ sub OWTHERM_Get($@) {
my $reading = $a[1];
my $name = $hash->{NAME};
my $model = $hash->{OW_MODEL};
+
my $value = undef;
my $ret = "";
@@ -450,6 +472,7 @@ sub OWTHERM_Get($@) {
#-- hash of the busmaster
my $master = $hash->{IODev};
+
#-- Get other values according to interface type
my $interface= $hash->{IODev}->{TYPE};
@@ -503,19 +526,24 @@ sub OWTHERM_Get($@) {
}
#-- process results
- if( defined($ret) ){
- return "OWTHERM: Could not get values from device $name, return was $ret";
+ 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) ){
+ return "OWTHERM: Could not get values from device $name, return was $ret";
+ }
+ #-- return the special reading
+ if ($reading eq "temperature") {
+ return "OWTHERM: $name.temperature => ".
+ $hash->{READINGS}{"temperature"}{VAL};
+ } elsif ($reading eq "alarm") {
+ return "OWTHERM: $name.alarm => L ".$main::attr{$name}{"tempLow"}.
+ " H ".$main::attr{$name}{"tempHigh"};
+ } else {
+ return undef;
+ }
}
-
- #-- return the special reading
- if ($reading eq "temperature") {
- return "OWTHERM: $name.temperature => ".
- $hash->{READINGS}{"temperature"}{VAL};
- } elsif ($reading eq "alarm") {
- return "OWTHERM: $name.alarm => L ".$main::attr{$name}{"tempLow"}.
- " H ".$main::attr{$name}{"tempHigh"};
- }
- return undef;
}
#######################################################################################
@@ -615,9 +643,8 @@ sub OWTHERM_InitializeDevice($) {
Log3 $name, 3, "OWTHERM_InitializeDevice: unknown unit $unit";
}
#-- these values are rather complex to obtain, therefore save them in the hash
- $hash->{READINGS}{"temperature"}{TYPE} = "temperature";
- $hash->{READINGS}{"temperature"}{UNIT} = $unit;
- $hash->{READINGS}{"temperature"}{UNITABBR} = $abbr;
+ $hash->{READINGS}{"temperature"}{TYPE} = "temperature";
+ $hash->{READINGS}{"temperature"}{UNIT} = $abbr;
$hash->{ERRCOUNT} = 0;
$hash->{tempf}{offset} = $offset;
$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
+# 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($$$$$$) {
- my ($hash, $reset, $owx_dev, $command, $numread, $res) = @_;
-
- #Log3 $name, 1,"OWXTHERM_BinValues context = $context";
+sub OWXTHERM_BinValues($$$$$$$) {
+ my ($hash, $context, $reset, $owx_dev, $crcpart, $numread, $res) = @_;
my ($i,$j,$k,@data,$ow_thn,$ow_tln);
my $change = 0;
-
- #Log3 $name, 1,"OWXTHERM: data length from reading device is ".length($res)." bytes";
- #-- process results
- die "$owx_dev not accessible in 2nd step" unless ( defined $res and $res ne 0 );
+ my $name = $hash->{NAME};
+ my $msg;
+ OWX_WDBG($name,"OWTHERM_BinValues called for device $name with ",$res)
+ if( $main::owx_debug>2 );
#-- process results
@data=split(//,$res);
- die "invalid data length, ".int(@data)." instead of 9 bytes"
- if (@data != 9);
- die "invalid data"
- if (ord($data[7])<=0);
- die "invalid CRC"
- if (OWX_CRC8(substr($res,0,8),$data[8])==0);
+ if (@data != 9){
+ $msg="Error - $name returns invalid data length, ".int(@data)." instead of 9 bytes, ";
+ }elsif(ord($data[7])<=0){
+ $msg="Error - $name returns invalid data, ";
+ }elsif(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
# family = 10 => DS1820, DS18S20
@@ -967,7 +1015,7 @@ sub OWXTHERM_BinValues($$$$$$) {
$ow_tln = ord($data[3]) > 127 ? 128-ord($data[3]) : ord($data[3]);
} else {
- die "OWXTHERM: Unknown device family $hash->{OW_FAMILY}\n";
+ die "OWTHERM: $name: Unknown device family $hash->{OW_FAMILY}\n";
}
#-- process alarm settings
@@ -977,7 +1025,6 @@ sub OWXTHERM_BinValues($$$$$$) {
#-- and now from raw to formatted values
$hash->{PRESENT} = 1;
my $value = OWTHERM_FormatValues($hash);
- Log3 $hash->{NAME}, 5, $value;
return undef;
}
@@ -1002,35 +1049,51 @@ sub OWXTHERM_GetValues($) {
#-- hash of the busmaster
my $master = $hash->{IODev};
my $name = $hash->{NAME};
+
+ my $res;
#-- check, if the conversion has been called before for all sensors
if( defined($attr{$name}{tempConv}) && ( $attr{$name}{tempConv} eq "onkick") ){
$con=0;
}
-
#-- if the conversion has not been called before
+ #-- issue the match ROM command \x55 and the start conversion command \x44
+ #-- conversion needs some 950 ms - but we may also do it in shorter time !
if( $con==1 ){
- #-- issue the match ROM command \x55 and the start conversion command \x44
- OWX_Reset($master);
- if( OWX_Complex($master,$owx_dev,"\x44",0) eq 0 ){
- return "$owx_dev 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);
+ #-- OLD OWX interface
+ if( !$master->{ASYNCHRONOUS} ){
+ OWX_Reset($master);
+ if( OWX_Complex($master,$owx_dev,"\x44",0) eq 0 ){
+ return "OWTHERM: $name not accessible";
+ }
+ 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
#-- issue the match ROM command \x55 and the read scratchpad command \xBE
#-- reading 9 + 1 + 8 data bytes and 1 CRC byte = 19 bytes
- OWX_Reset($master);
- my $res=OWX_Complex($master,$owx_dev,"\xBE",9);
- return "$owx_dev not accessible in reading"
- if( $res eq 0 );
- return "$owx_dev has returned invalid data"
- if( length($res)!=19);
- eval {
- OWXTHERM_BinValues($hash,undef,$owx_dev,undef,undef,substr($res,10,9));
- };
- return $@ ? $@ : undef;
+ #-- OLD OWX interface
+ if( !$master->{ASYNCHRONOUS} ){
+ OWX_Reset($master);
+ my $res=OWX_Complex($master,$owx_dev,"\xBE",9);
+ return "OWTHERM: $name not accessible in reading"
+ if( $res eq 0 );
+ return "OWTHERM: $name has returned invalid data"
+ if( length($res)!=19);
+ eval {
+ OWXTHERM_BinValues($hash,undef,$owx_dev,undef,undef,9,substr($res,10,9));
+ };
+ return $@ ? $@ : undef;
+ #-- 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($$) {
my ($hash, $args) = @_;
- my ($i,$j,$k);
-
my $name = $hash->{NAME};
#-- 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
my $select=sprintf("\x4E%c%c%c",$thp,$tlp,$cfg);
- OWX_Reset($master);
- my $res=OWX_Complex($master,$owx_dev,$select,3);
- if( $res eq 0 ){
- return "OWXTHERM: Device $owx_dev not accessible";
+ #-- OLD OWX interface
+ if( !$master->{ASYNCHRONOUS} ){
+ OWX_Reset($master);
+ my $res=OWX_Complex($master,$owx_dev,$select,3);
+ if( $res eq 0 ){
+ return "OWTHERM: $name not accessible for setting";
+ }
+ #-- NEW OWX interface
+ }else{
+ #### master slave context proc owx_dev data crcpart numread startread callback delay
+ OWX_Qomplex($master, $hash, undef, 0, $owx_dev, $select, 0, 3, 10, undef, 0);
}
-
return undef;
}
@@ -1137,7 +1204,7 @@ sub OWXTHERM_PT_GetValues($) {
$thread->{pt_execute} = OWX_ASYNC_PT_Execute($master,1,$owx_dev,"\xBE",9);
PT_WAIT_THREAD($thread->{pt_execute});
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;
});
}
@@ -1299,12 +1366,10 @@ sub OWXTHERM_PT_SetValues($$) {
attr <name> stateAL <string>
-
character string for denoting low alarm condition, default is down triangle,
- e.g. the code ▾ leading to the sign ▾
+
character string for denoting low alarm condition, default is ↓
attr <name> stateAH <string>
-
character string for denoting high alarm condition, default is upward
- triangle, e.g. the code ▴ leading to the sign ▴
+
character string for denoting high alarm condition, default is ↑
-
attr <name> tempConv onkick|onread
@@ -1315,9 +1380,9 @@ sub OWXTHERM_PT_SetValues($$) {
temperature offset in °C added to the raw temperature reading.
attr <name> tempUnit
- Celsius|Kelvin|Fahrenheit
+ none|Celsius|Kelvin|Fahrenheit
-
unit of measurement (temperature scale), default is Celsius = °C
+
unit of measurement (temperature scale) for state reading (default is Celsius = °C, use "none" for empty).
-
attr <name> resolution 9|10|11|12
Temperature
resolution in bit, only relevant for DS18B20
@@ -1336,13 +1401,7 @@ sub OWXTHERM_PT_SetValues($$) {
low alarm temperature (on the temperature scale chosen by the attribute
value).
-
- - Standard attributes alias, comment, event-on-update-reading, event-on-change-reading, stateFormat, room, eventMap, loglevel,
- webCmd
+ - readingFnAttributes
=end html