mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-05-04 22:19:38 +00:00
git-svn-id: https://svn.fhem.de/fhem/trunk@4799 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
4b1af51cc9
commit
95a14bfdee
@ -1,10 +1,11 @@
|
|||||||
########################################################################################
|
########################################################################################
|
||||||
#
|
#
|
||||||
# OWAD.pm WIESO EVENT DREIFACH
|
# OWAD.pm
|
||||||
#
|
#
|
||||||
# FHEM module to commmunicate with 1-Wire A/D converters DS2450
|
# FHEM module to commmunicate with 1-Wire A/D converters DS2450
|
||||||
#
|
#
|
||||||
# Prof. Dr. Peter A. Henning, 2012
|
# Prof. Dr. Peter A. Henning
|
||||||
|
# Norbert Truchsess
|
||||||
#
|
#
|
||||||
# $Id$
|
# $Id$
|
||||||
#
|
#
|
||||||
@ -75,7 +76,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
sub Log($$);
|
sub Log($$);
|
||||||
|
|
||||||
my $owx_version="5.01";
|
my $owx_version="5.03";
|
||||||
#-- fixed raw channel name, flexible channel name
|
#-- fixed raw channel name, flexible channel name
|
||||||
my @owg_fixed = ("A","B","C","D");
|
my @owg_fixed = ("A","B","C","D");
|
||||||
my @owg_channel = ("A","B","C","D");
|
my @owg_channel = ("A","B","C","D");
|
||||||
@ -162,7 +163,7 @@ sub OWAD_Initialize ($) {
|
|||||||
|
|
||||||
#-- value globals
|
#-- value globals
|
||||||
$hash->{owg_status} = [];
|
$hash->{owg_status} = [];
|
||||||
$hash->{owg_state} = undef;
|
#$hash->{owg_state} = undef;
|
||||||
#-- channel values - always the raw values from the device
|
#-- channel values - always the raw values from the device
|
||||||
$hash->{owg_val} = ["","","",""];
|
$hash->{owg_val} = ["","","",""];
|
||||||
#-- alarm status 0 = disabled, 1 = enabled, but not alarmed, 2 = alarmed
|
#-- alarm status 0 = disabled, 1 = enabled, but not alarmed, 2 = alarmed
|
||||||
@ -172,9 +173,9 @@ sub OWAD_Initialize ($) {
|
|||||||
$hash->{owg_vlow} = [];
|
$hash->{owg_vlow} = [];
|
||||||
$hash->{owg_vhigh} = [];
|
$hash->{owg_vhigh} = [];
|
||||||
|
|
||||||
#-- ASYNC this function is needed for asynchronous execution of the device reads
|
#-- this function is needed for asynchronous execution of the device reads
|
||||||
$hash->{AfterExecuteFn} = "OWXAD_ProcValues";
|
$hash->{AfterExecuteFn} = "OWXAD_BinValues";
|
||||||
#--make sure OWX is loaded so OWX_CRC is available if running with OWServer
|
#-- make sure OWX is loaded so OWX_CRC is available if running with OWServer
|
||||||
main::LoadModule("OWX");
|
main::LoadModule("OWX");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1221,103 +1222,20 @@ sub OWFSAD_SetPage($$) {
|
|||||||
#
|
#
|
||||||
########################################################################################
|
########################################################################################
|
||||||
#
|
#
|
||||||
# OWXAD_GetPage - Get one memory page from device
|
# OWXAD_BinValues - Binary readings into clear values
|
||||||
#
|
|
||||||
# Parameter hash = hash of device addressed
|
|
||||||
# page = "reading", "alarm" or "status"
|
|
||||||
#
|
|
||||||
########################################################################################
|
|
||||||
|
|
||||||
sub OWXAD_GetPage($$) {
|
|
||||||
|
|
||||||
my ($hash,$page) = @_;
|
|
||||||
|
|
||||||
my ($select, $res, $res2, $res3, @data, $an, $vn);
|
|
||||||
|
|
||||||
#-- ID of the device, hash of the busmaster
|
|
||||||
my $owx_dev = $hash->{ROM_ID};
|
|
||||||
my $master = $hash->{IODev};
|
|
||||||
|
|
||||||
my ($i,$j,$k);
|
|
||||||
|
|
||||||
#=============== get the voltage reading ===============================
|
|
||||||
if( $page eq "reading") {
|
|
||||||
#-- issue the match ROM command \x55 and the start conversion command
|
|
||||||
#-- asynchronous mode
|
|
||||||
if( $hash->{ASYNC} ){
|
|
||||||
if (!OWX_Execute( $master, "getpageconvert", 1, $owx_dev, "\x3C\x0F\x00\xFF\xFF", 0, 20 )) {
|
|
||||||
return "not accessible for conversion";
|
|
||||||
}
|
|
||||||
#-- synchronous mode
|
|
||||||
} else {
|
|
||||||
OWX_Reset($master);
|
|
||||||
$res= OWX_Complex($master,$owx_dev,"\x3C\x0F\x00\xFF\xFF",0);
|
|
||||||
if( $res eq 0 ){
|
|
||||||
return "not accessible for conversion";
|
|
||||||
}
|
|
||||||
#-- conversion needs some 5 ms per channel
|
|
||||||
select(undef,undef,undef,0.02);
|
|
||||||
}
|
|
||||||
|
|
||||||
#-- issue the match ROM command \x55 and the read conversion page command
|
|
||||||
# \xAA\x00\x00
|
|
||||||
$select="\xAA\x00\x00";
|
|
||||||
#=============== get the alarm reading ===============================
|
|
||||||
} elsif ( $page eq "alarm" ) {
|
|
||||||
#-- issue the match ROM command \x55 and the read alarm page command
|
|
||||||
# \xAA\x10\x00
|
|
||||||
$select="\xAA\x10\x00";
|
|
||||||
#=============== get the status reading ===============================
|
|
||||||
} elsif ( $page eq "status" ) {
|
|
||||||
#-- issue the match ROM command \x55 and the read status memory page command
|
|
||||||
# \xAA\x08\x00 r
|
|
||||||
$select="\xAA\x08\x00";
|
|
||||||
#=============== wrong value requested ===============================
|
|
||||||
} else {
|
|
||||||
return "wrong memory page requested from $owx_dev";
|
|
||||||
}
|
|
||||||
|
|
||||||
#-- asynchronous mode
|
|
||||||
if( $hash->{ASYNC} ){
|
|
||||||
#-- reading 9 + 3 + 8 data bytes and 2 CRC bytes = 22 bytes
|
|
||||||
if (OWX_Execute( $master, "getpage$page", 1, $owx_dev, $select, 10, undef)) {
|
|
||||||
} else {
|
|
||||||
return "$owx_dev not accessible in reading $page page";
|
|
||||||
}
|
|
||||||
return OWX_AwaitExecuteResponse( $master, "getpage$page", $owx_dev );
|
|
||||||
#-- asynchronous mode
|
|
||||||
} else {
|
|
||||||
#-- 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);
|
|
||||||
if( $res eq 0 ){
|
|
||||||
return "$owx_dev not accessible in reading $page page";
|
|
||||||
}
|
|
||||||
#-- for processing we also need the 3 command bytes
|
|
||||||
OWXAD_ProcValues($hash,$page,undef,undef,$owx_dev,undef,undef,substr($res,9,13));
|
|
||||||
}
|
|
||||||
|
|
||||||
return undef;
|
|
||||||
}
|
|
||||||
|
|
||||||
########################################################################################
|
|
||||||
#
|
|
||||||
# OWXAD_ProcValues - Process reading from one device - translate binary into raw
|
|
||||||
#
|
#
|
||||||
# Parameter hash = hash of device addressed
|
# Parameter hash = hash of device addressed
|
||||||
#
|
#
|
||||||
########################################################################################
|
########################################################################################
|
||||||
|
|
||||||
sub OWXAD_ProcValues($$$$$$$$) {
|
sub OWXAD_BinValues($$$$$$$$) {
|
||||||
my ($hash, $page, $success, $reset, $owx_dev, $data, $numread, $res) = @_;
|
my ($hash, $context, $success, $reset, $owx_dev, $command, $numread, $res) = @_;
|
||||||
|
|
||||||
#-- unused are success, reset, data numread
|
#-- always check for success, unused are reset, numread
|
||||||
|
return unless ($success and $context);
|
||||||
return undef unless (defined $page and $page ne "convert");
|
#Log 1,"OWXAD_BinValues context = $context";
|
||||||
|
|
||||||
my ($i,$j,$k,@data,$ow_thn,$ow_tln);
|
my ($i,$j,$k,@data,$ow_thn,$ow_tln);
|
||||||
my $change = 0;
|
|
||||||
|
|
||||||
#-- process results
|
#-- process results
|
||||||
@data=split(//,substr($res,3,10));
|
@data=split(//,substr($res,3,10));
|
||||||
@ -1327,18 +1245,18 @@ sub OWXAD_ProcValues($$$$$$$$) {
|
|||||||
if (OWX_CRC16(substr($res,9,11),$data[11],$data[12])==0);
|
if (OWX_CRC16(substr($res,9,11),$data[11],$data[12])==0);
|
||||||
|
|
||||||
#=============== get the voltage reading ===============================
|
#=============== get the voltage reading ===============================
|
||||||
if( $page eq "reading"){
|
if( $context eq "ds2450.getreading"){
|
||||||
for( $i=0;$i<int(@owg_fixed);$i++){
|
for( $i=0;$i<int(@owg_fixed);$i++){
|
||||||
$hash->{owg_val}->[$i]= (ord($data[2*$i])+256*ord($data[1+2*$i]) )/(1<<$owg_resoln[$i]) * $owg_range[$i]/1000;
|
$hash->{owg_val}->[$i]= (ord($data[2*$i])+256*ord($data[1+2*$i]) )/(1<<$owg_resoln[$i]) * $owg_range[$i]/1000;
|
||||||
}
|
}
|
||||||
#=============== get the alarm reading ===============================
|
#=============== get the alarm reading ===============================
|
||||||
} elsif ( $page eq "alarm" ) {
|
} elsif ( $context eq "ds2450.getalarm" ) {
|
||||||
for( $i=0;$i<int(@owg_fixed);$i++){
|
for( $i=0;$i<int(@owg_fixed);$i++){
|
||||||
$hash->{owg_vlow}->[$i] = int(ord($data[2*$i])/256 * $owg_range[$i]+0.5)/1000;
|
$hash->{owg_vlow}->[$i] = int(ord($data[2*$i])/256 * $owg_range[$i]+0.5)/1000;
|
||||||
$hash->{owg_vhigh}->[$i] = int(ord($data[1+2*$i])/256 * $owg_range[$i]+0.5)/1000;
|
$hash->{owg_vhigh}->[$i] = int(ord($data[1+2*$i])/256 * $owg_range[$i]+0.5)/1000;
|
||||||
}
|
}
|
||||||
#=============== get the status reading ===============================
|
#=============== get the status reading ===============================
|
||||||
} elsif ( $page eq "status" ) {
|
} elsif ( $context eq "ds2450.getstatus" ) {
|
||||||
my ($sb1,$sb2);
|
my ($sb1,$sb2);
|
||||||
for( my $i=0;$i<int(@owg_fixed);$i++){
|
for( my $i=0;$i<int(@owg_fixed);$i++){
|
||||||
$sb1 = ord($data[2*$i]);
|
$sb1 = ord($data[2*$i]);
|
||||||
@ -1392,13 +1310,93 @@ sub OWXAD_ProcValues($$$$$$$$) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
my $value = OWAD_FormatValues($hash);
|
||||||
#my $value=OWAD_FormatValues($hash);
|
Log 5, $value;
|
||||||
#Log 5, $value;
|
|
||||||
|
|
||||||
return undef
|
return undef
|
||||||
}
|
}
|
||||||
|
|
||||||
|
########################################################################################
|
||||||
|
#
|
||||||
|
# OWXAD_GetPage - Get one memory page from device
|
||||||
|
#
|
||||||
|
# Parameter hash = hash of device addressed
|
||||||
|
# page = "reading", "alarm" or "status"
|
||||||
|
#
|
||||||
|
########################################################################################
|
||||||
|
|
||||||
|
sub OWXAD_GetPage($$) {
|
||||||
|
|
||||||
|
my ($hash,$page) = @_;
|
||||||
|
|
||||||
|
my ($select, $res, $res2, $res3, @data, $an, $vn);
|
||||||
|
|
||||||
|
#-- ID of the device, hash of the busmaster
|
||||||
|
my $owx_dev = $hash->{ROM_ID};
|
||||||
|
my $master = $hash->{IODev};
|
||||||
|
|
||||||
|
my ($i,$j,$k);
|
||||||
|
|
||||||
|
#=============== get the voltage reading ===============================
|
||||||
|
if( $page eq "reading") {
|
||||||
|
#-- issue the match ROM command \x55 and the start conversion command
|
||||||
|
#-- asynchronous mode
|
||||||
|
# difficult here, shoul dbe put into Binvalues as in OWSWITCH
|
||||||
|
if( $hash->{ASYNC} ){
|
||||||
|
if (!OWX_Execute( $master, "getpageconvert", 1, $owx_dev, "\x3C\x0F\x00\xFF\xFF", 0, 20 )) {
|
||||||
|
return "not accessible for conversion";
|
||||||
|
}
|
||||||
|
#-- synchronous mode
|
||||||
|
} else {
|
||||||
|
OWX_Reset($master);
|
||||||
|
$res= OWX_Complex($master,$owx_dev,"\x3C\x0F\x00\xFF\xFF",0);
|
||||||
|
if( $res eq 0 ){
|
||||||
|
return "not accessible for conversion";
|
||||||
|
}
|
||||||
|
#-- conversion needs some 5 ms per channel
|
||||||
|
select(undef,undef,undef,0.02);
|
||||||
|
}
|
||||||
|
|
||||||
|
#-- issue the match ROM command \x55 and the read conversion page command
|
||||||
|
# \xAA\x00\x00
|
||||||
|
$select="\xAA\x00\x00";
|
||||||
|
#=============== get the alarm reading ===============================
|
||||||
|
} elsif ( $page eq "alarm" ) {
|
||||||
|
#-- issue the match ROM command \x55 and the read alarm page command
|
||||||
|
# \xAA\x10\x00
|
||||||
|
$select="\xAA\x10\x00";
|
||||||
|
#=============== get the status reading ===============================
|
||||||
|
} elsif ( $page eq "status" ) {
|
||||||
|
#-- issue the match ROM command \x55 and the read status memory page command
|
||||||
|
# \xAA\x08\x00 r
|
||||||
|
$select="\xAA\x08\x00";
|
||||||
|
#=============== wrong value requested ===============================
|
||||||
|
} else {
|
||||||
|
return "wrong memory page requested from $owx_dev";
|
||||||
|
}
|
||||||
|
#-- asynchronous mode
|
||||||
|
if( $hash->{ASYNC} ){
|
||||||
|
#-- reading 9 + 3 + 8 data bytes and 2 CRC bytes = 22 bytes
|
||||||
|
if (OWX_Execute( $master, "ds2450.get".$page, 1, $owx_dev, $select, 10, undef)) {
|
||||||
|
return OWX_AwaitExecuteResponse( $master, "getpage$page", $owx_dev );
|
||||||
|
} else {
|
||||||
|
return "$owx_dev not accessible in reading $page page";
|
||||||
|
}
|
||||||
|
#-- synchronous mode
|
||||||
|
} else {
|
||||||
|
#-- 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);
|
||||||
|
if( $res eq 0 ){
|
||||||
|
return "$owx_dev not accessible in reading $page page";
|
||||||
|
}
|
||||||
|
#-- for processing we also need the 3 command bytes
|
||||||
|
OWXAD_BinValues($hash,"ds2450.get".$page,1,undef,$owx_dev,undef,undef,substr($res,9,13));
|
||||||
|
}
|
||||||
|
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
########################################################################################
|
########################################################################################
|
||||||
#
|
#
|
||||||
# OWXAD_SetPage - Set one page of device
|
# OWXAD_SetPage - Set one page of device
|
||||||
@ -1475,8 +1473,6 @@ sub OWXAD_SetPage($$) {
|
|||||||
} else {
|
} else {
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
$res=OWX_Complex($master,$owx_dev,$select,0);
|
$res=OWX_Complex($master,$owx_dev,$select,0);
|
||||||
|
|
||||||
#-- process results
|
|
||||||
if( $res eq 0 ){
|
if( $res eq 0 ){
|
||||||
return "device $owx_dev not accessible for writing";
|
return "device $owx_dev not accessible for writing";
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
# FHEM module to commmunicate with 1-Wire Counter/RAM DS2423
|
# FHEM module to commmunicate with 1-Wire Counter/RAM DS2423
|
||||||
#
|
#
|
||||||
# Prof. Dr. Peter A. Henning
|
# Prof. Dr. Peter A. Henning
|
||||||
|
# Norbert Truchsess
|
||||||
#
|
#
|
||||||
# $Id$
|
# $Id$
|
||||||
#
|
#
|
||||||
@ -14,7 +15,7 @@
|
|||||||
#
|
#
|
||||||
# where <name> may be replaced by any name string
|
# where <name> may be replaced by any name string
|
||||||
#
|
#
|
||||||
# <model> is a 1-Wire device type. If omitted, we assume this to be an
|
# <model> is a 1-Wire device type DS2423 or DS2423emu. If omitted, we assume this to be an
|
||||||
# DS2423 Counter/RAM
|
# DS2423 Counter/RAM
|
||||||
# <FAM_ID> is a 1-Wire family id, currently allowed value is 1D
|
# <FAM_ID> is a 1-Wire family id, currently allowed value is 1D
|
||||||
# <ROM_ID> is a 12 character (6 byte) 1-Wire ROM ID
|
# <ROM_ID> is a 12 character (6 byte) 1-Wire ROM ID
|
||||||
@ -40,6 +41,7 @@
|
|||||||
#
|
#
|
||||||
# attr <name> LogM <string> = device name (not file name) of monthly log file
|
# attr <name> LogM <string> = device name (not file name) of monthly log file
|
||||||
# attr <name> LogY <string> = device name (not file name) of yearly log file
|
# attr <name> LogY <string> = device name (not file name) of yearly log file
|
||||||
|
# attr <name> nomemory = 1|0 (when set to 1, disabels use of internal memory)
|
||||||
# attr <name> <channel>Name <string>|<string> = name for the channel | a type description for the measured value
|
# attr <name> <channel>Name <string>|<string> = name for the channel | a type description for the measured value
|
||||||
# attr <name> <channel>Unit <string>|<string> = unit of measurement for this channel | its abbreviation
|
# attr <name> <channel>Unit <string>|<string> = unit of measurement for this channel | its abbreviation
|
||||||
# attr <name> <channel>Rate <string>|<string> = name for the channel ratw | a type description for the measured value
|
# attr <name> <channel>Rate <string>|<string> = name for the channel ratw | a type description for the measured value
|
||||||
@ -82,17 +84,12 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
sub Log($$);
|
sub Log($$);
|
||||||
|
|
||||||
my $owx_version="3.33";
|
my $owx_version="5.02";
|
||||||
#-- fixed raw channel name, flexible channel name
|
#-- fixed raw channel name, flexible channel name
|
||||||
my @owg_fixed = ("A","B");
|
my @owg_fixed = ("A","B");
|
||||||
my @owg_channel = ("A","B");
|
my @owg_channel = ("A","B");
|
||||||
my @owg_rate = ("A_rate","B_rate");
|
my @owg_rate = ("A_rate","B_rate");
|
||||||
|
|
||||||
#-- channel values - always the raw values from the device
|
|
||||||
my @owg_val;
|
|
||||||
my @owg_midnight;
|
|
||||||
my $owg_str;
|
|
||||||
|
|
||||||
my %gets = (
|
my %gets = (
|
||||||
"id" => "",
|
"id" => "",
|
||||||
"present" => "",
|
"present" => "",
|
||||||
@ -140,8 +137,8 @@ sub OWCOUNT_Initialize ($) {
|
|||||||
$hash->{SetFn} = "OWCOUNT_Set";
|
$hash->{SetFn} = "OWCOUNT_Set";
|
||||||
$hash->{AttrFn} = "OWCOUNT_Attr";
|
$hash->{AttrFn} = "OWCOUNT_Attr";
|
||||||
#-- see header for attributes
|
#-- see header for attributes
|
||||||
my $attlist = "IODev do_not_notify:0,1 showtime:0,1 model:DS2423 loglevel:0,1,2,3,4,5 LogM LogY ".
|
my $attlist = "IODev do_not_notify:0,1 showtime:0,1 model:DS2423,DS2423emu loglevel:0,1,2,3,4,5 LogM LogY ".
|
||||||
"interval ".
|
"nomemory:1,0 interval ".
|
||||||
$readingFnAttributes;
|
$readingFnAttributes;
|
||||||
for( my $i=0;$i<int(@owg_fixed);$i++ ){
|
for( my $i=0;$i<int(@owg_fixed);$i++ ){
|
||||||
$attlist .= " ".$owg_fixed[$i]."Name";
|
$attlist .= " ".$owg_fixed[$i]."Name";
|
||||||
@ -154,7 +151,9 @@ sub OWCOUNT_Initialize ($) {
|
|||||||
}
|
}
|
||||||
$hash->{AttrList} = $attlist;
|
$hash->{AttrList} = $attlist;
|
||||||
|
|
||||||
#make sure OWX is loaded so OWX_CRC is available if running with OWServer
|
#-- ASYNC this function is needed for asynchronous execution of the device reads
|
||||||
|
$hash->{AfterExecuteFn} = "OWXCOUNT_BinValues";
|
||||||
|
#-- make sure OWX is loaded so OWX_CRC is available if running with OWServer
|
||||||
main::LoadModule("OWX");
|
main::LoadModule("OWX");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,6 +184,9 @@ sub OWCOUNT_Define ($$) {
|
|||||||
#-- different types of definition allowed
|
#-- different types of definition allowed
|
||||||
my $a2 = $a[2];
|
my $a2 = $a[2];
|
||||||
my $a3 = defined($a[3]) ? $a[3] : "";
|
my $a3 = defined($a[3]) ? $a[3] : "";
|
||||||
|
#-- The model may be DS2423 or DS2423emu. 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 later when memory is checked
|
||||||
#-- no model, 12 characters
|
#-- no model, 12 characters
|
||||||
if( $a2 =~ m/^[0-9|a-f|A-F]{12}$/ ) {
|
if( $a2 =~ m/^[0-9|a-f|A-F]{12}$/ ) {
|
||||||
$model = "DS2423";
|
$model = "DS2423";
|
||||||
@ -211,6 +213,10 @@ sub OWCOUNT_Define ($$) {
|
|||||||
if( $model eq "DS2423" ){
|
if( $model eq "DS2423" ){
|
||||||
$fam = "1D";
|
$fam = "1D";
|
||||||
CommandAttr (undef,"$name model DS2423");
|
CommandAttr (undef,"$name model DS2423");
|
||||||
|
}elsif( $model eq "DS2423emu" ){
|
||||||
|
$fam = "1D";
|
||||||
|
CommandAttr (undef,"$name model DS2423emu");
|
||||||
|
CommandAttr (undef,"$name nomemory 1");
|
||||||
}else{
|
}else{
|
||||||
return "OWCOUNT: Wrong 1-Wire device model $model";
|
return "OWCOUNT: Wrong 1-Wire device model $model";
|
||||||
}
|
}
|
||||||
@ -227,6 +233,7 @@ sub OWCOUNT_Define ($$) {
|
|||||||
$hash->{OW_FAMILY} = $fam;
|
$hash->{OW_FAMILY} = $fam;
|
||||||
$hash->{PRESENT} = 0;
|
$hash->{PRESENT} = 0;
|
||||||
$hash->{INTERVAL} = $interval;
|
$hash->{INTERVAL} = $interval;
|
||||||
|
$hash->{ASYNC} = 0; #-- false for now
|
||||||
|
|
||||||
#-- Couple to I/O device
|
#-- Couple to I/O device
|
||||||
$hash->{IODev}=$attr{$name}{"IODev"}
|
$hash->{IODev}=$attr{$name}{"IODev"}
|
||||||
@ -264,10 +271,11 @@ sub OWCOUNT_Attr(@) {
|
|||||||
|
|
||||||
if ( $do eq "set") {
|
if ( $do eq "set") {
|
||||||
ARGUMENT_HANDLER: {
|
ARGUMENT_HANDLER: {
|
||||||
|
#-- interval modified at runtime
|
||||||
$key eq "interval" and do {
|
$key eq "interval" and do {
|
||||||
# check value
|
#-- check value
|
||||||
return "OWCOUNT: Set with short interval, must be > 1" if(int($value) < 1);
|
return "OWCOUNT: Set with short interval, must be > 1" if(int($value) < 1);
|
||||||
# update timer
|
#-- update timer
|
||||||
$hash->{INTERVAL} = $value;
|
$hash->{INTERVAL} = $value;
|
||||||
if ($init_done) {
|
if ($init_done) {
|
||||||
RemoveInternalTimer($hash);
|
RemoveInternalTimer($hash);
|
||||||
@ -384,7 +392,7 @@ sub OWCOUNT_FormatValues($) {
|
|||||||
|
|
||||||
#-- no change in any value if invalid reading
|
#-- no change in any value if invalid reading
|
||||||
for (my $i=0;$i<int(@owg_fixed);$i++){
|
for (my $i=0;$i<int(@owg_fixed);$i++){
|
||||||
return if( $owg_val[$i] eq "");
|
return if( $hash->{owg_val}->[$i] eq "");
|
||||||
}
|
}
|
||||||
|
|
||||||
#-- obtain channel names
|
#-- obtain channel names
|
||||||
@ -431,14 +439,14 @@ sub OWCOUNT_FormatValues($) {
|
|||||||
$runit = $hash->{READINGS}{$owg_rate[$i]}{UNITABBR};
|
$runit = $hash->{READINGS}{$owg_rate[$i]}{UNITABBR};
|
||||||
|
|
||||||
#-- skip some things if undefined
|
#-- skip some things if undefined
|
||||||
if( $owg_val[$i] eq ""){
|
if( $hash->{owg_val}->[$i] eq ""){
|
||||||
$svalue .= $owg_channel[$i].": ???";
|
$svalue .= $owg_channel[$i].": ???";
|
||||||
}else{
|
}else{
|
||||||
#-- only if attribute value mode=daily, take the midnight value from memory
|
#-- only if attribute value mode=daily, take the midnight value from memory
|
||||||
if( $daily == 1){
|
if( $daily == 1){
|
||||||
$vval = int( (($owg_val[$i] + $offset)*$factor - $owg_midnight[$i])*10000+0.5)/10000;
|
$vval = int( (($hash->{owg_val}->[$i] + $offset)*$factor - $hash->{owg_midnight}->[$i])*10000+0.5)/10000;
|
||||||
} else {
|
} else {
|
||||||
$vval = int( ($owg_val[$i] + $offset)*$factor*10000+0.5)/10000;
|
$vval = int( ($hash->{owg_val}->[$i] + $offset)*$factor*10000+0.5)/10000;
|
||||||
}
|
}
|
||||||
|
|
||||||
#-- rate calculation: get the old values
|
#-- rate calculation: get the old values
|
||||||
@ -483,7 +491,7 @@ sub OWCOUNT_FormatValues($) {
|
|||||||
$dval = int(($vval+($vval-$oldval)*$dt)*10000+0.5)/10000;
|
$dval = int(($vval+($vval-$oldval)*$dt)*10000+0.5)/10000;
|
||||||
|
|
||||||
if( $daily == 1 ){
|
if( $daily == 1 ){
|
||||||
$dval2 = $dval+$owg_midnight[$i];
|
$dval2 = $dval+$hash->{owg_midnight}->[$i];
|
||||||
} else {
|
} else {
|
||||||
$dval2 = $dval;
|
$dval2 = $dval;
|
||||||
}
|
}
|
||||||
@ -492,8 +500,8 @@ sub OWCOUNT_FormatValues($) {
|
|||||||
OWCOUNT_SetPage($hash,14+$i,sprintf("%f",$dval2));
|
OWCOUNT_SetPage($hash,14+$i,sprintf("%f",$dval2));
|
||||||
|
|
||||||
#-- string buildup for monthly and yearly logging
|
#-- string buildup for monthly and yearly logging
|
||||||
$dvalue .= sprintf( " %s: %5.1f %s %sm: %%5.1f %s", $owg_channel[$i],$dval,$unit,$owg_channel[$i],$unit);
|
$dvalue .= sprintf( " %s: %5.1f %s %sM: %%5.1f %s", $owg_channel[$i],$dval,$unit,$owg_channel[$i],$unit);
|
||||||
$mvalue .= sprintf( " %s: %%5.1f %s %sy: %%5.1f %s", $owg_channel[$i],$unit,$owg_channel[$i],$unit);
|
$mvalue .= sprintf( " %s: %%5.1fM %s %sY: %%5.1f %s", $owg_channel[$i],$unit,$owg_channel[$i],$unit);
|
||||||
} #-- end daybreak
|
} #-- end daybreak
|
||||||
|
|
||||||
#-- string buildup for return value and STATE
|
#-- string buildup for return value and STATE
|
||||||
@ -634,10 +642,10 @@ sub OWCOUNT_Get($@) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( $daily==1){
|
if( $daily==1){
|
||||||
$value .= $owg_channel[$i]."m: ".$month2[$i]->[1]." ".$unit.
|
$value .= $owg_channel[$i]."M: ".$month2[$i]->[1]." ".$unit.
|
||||||
" (monthly sum until now, average ".$month2[$i]->[2]." ".$unit."/d)\n";
|
" (monthly sum until now, average ".$month2[$i]->[2]." ".$unit."/d)\n";
|
||||||
}else{
|
}else{
|
||||||
$value .= $owg_channel[$i]."m: ".$month2[$i]->[1]." ".$unit." (last midnight)\n";
|
$value .= $owg_channel[$i]."M: ".$month2[$i]->[1]." ".$unit." (last midnight)\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $value;
|
return $value;
|
||||||
@ -662,10 +670,10 @@ sub OWCOUNT_Get($@) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( $daily==1){
|
if( $daily==1){
|
||||||
$value .= $owg_channel[$i]."y: ".$year2[$i]->[1]." ".$unit.
|
$value .= $owg_channel[$i]."Y: ".$year2[$i]->[1]." ".$unit.
|
||||||
" (yearly sum until now, average ".$year2[$i]->[2]." ".$unit."/d)\n";
|
" (yearly sum until now, average ".$year2[$i]->[2]." ".$unit."/d)\n";
|
||||||
}else{
|
}else{
|
||||||
$value .= $owg_channel[$i]."y: ".$year2[$i]->[1]." ".$unit." (last month)\n";
|
$value .= $owg_channel[$i]."Y: ".$year2[$i]->[1]." ".$unit." (last month)\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $value;
|
return $value;
|
||||||
@ -675,8 +683,11 @@ sub OWCOUNT_Get($@) {
|
|||||||
my $interface= $hash->{IODev}->{TYPE};
|
my $interface= $hash->{IODev}->{TYPE};
|
||||||
|
|
||||||
#-- check syntax for getting memory page 0..13 or midnight A/B
|
#-- check syntax for getting memory page 0..13 or midnight A/B
|
||||||
|
my $nomemory = defined($attr{$name}{"nomemory"}) ? $attr{$name}{"nomemory"} : 0;
|
||||||
if( ($reading eq "memory") || ($reading eq "midnight") ){
|
if( ($reading eq "memory") || ($reading eq "midnight") ){
|
||||||
if( $reading eq "memory" ){
|
if( $reading eq "memory" ){
|
||||||
|
return "OWCOUNT: Memory usage disabled"
|
||||||
|
if( $nomemory==1 );
|
||||||
return "OWCOUNT: Get needs parameter when reading memory: <page>"
|
return "OWCOUNT: Get needs parameter when reading memory: <page>"
|
||||||
if( int(@a)<2 );
|
if( int(@a)<2 );
|
||||||
$page=int($a[2]);
|
$page=int($a[2]);
|
||||||
@ -695,21 +706,13 @@ sub OWCOUNT_Get($@) {
|
|||||||
return "OWCOUNT: Invalid midnight counter address, must be A, B or defined channel name"
|
return "OWCOUNT: Invalid midnight counter address, must be A, B or defined channel name"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#-- OWX interface
|
$ret = OWCOUNT_GetPage($hash,$page);
|
||||||
if( $interface eq "OWX" ){
|
|
||||||
$ret = OWXCOUNT_GetPage($hash,$page);
|
|
||||||
#-- OWFS interface
|
|
||||||
}elsif( $interface eq "OWServer" ){
|
|
||||||
$ret = OWFSCOUNT_GetPage($hash,$page);
|
|
||||||
#-- Unknown interface
|
|
||||||
}else{
|
|
||||||
return "OWCOUNT: Get with wrong IODev type $interface";
|
|
||||||
}
|
|
||||||
#-- when we have a return code, we have an error
|
#-- when we have a return code, we have an error
|
||||||
if( $ret ){
|
if( $ret ){
|
||||||
return "OWCOUNT: Could not get values from device $name, reason: ".$ret;
|
return "OWCOUNT: Could not get values from device $name, reason: ".$ret;
|
||||||
}else{
|
}else{
|
||||||
return "OWCOUNT: $name.$reading [$page] =>".$owg_str;
|
return "OWCOUNT: $name.$reading [$page] =>".$hash->{owg_str}->[$page];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -726,37 +729,22 @@ sub OWCOUNT_Get($@) {
|
|||||||
return "OWCOUNT: Invalid counter address, must be A, B or defined channel name"
|
return "OWCOUNT: Invalid counter address, must be A, B or defined channel name"
|
||||||
}
|
}
|
||||||
|
|
||||||
#-- OWX interface
|
$ret = OWCOUNT_GetPage($hash,$page);
|
||||||
if( $interface eq "OWX" ){
|
|
||||||
$ret = OWXCOUNT_GetPage($hash,$page);
|
|
||||||
#-- OWFS interface
|
|
||||||
}elsif( $interface eq "OWServer" ){
|
|
||||||
$ret = OWFSCOUNT_GetPage($hash,$page);
|
|
||||||
#-- Unknown interface
|
|
||||||
}else{
|
|
||||||
return "OWCOUNT: Get with wrong IODev type $interface";
|
|
||||||
}
|
|
||||||
if( defined($ret) ){
|
if( defined($ret) ){
|
||||||
return "OWCOUNT: Could not get values from device $name, reason: ".$ret;
|
return "OWCOUNT: Could not get values from device $name, reason: ".$ret;
|
||||||
}
|
}
|
||||||
$hash->{PRESENT} = 1;
|
$hash->{PRESENT} = 1;
|
||||||
#-- only one counter will be returned
|
#-- only one counter will be returned
|
||||||
OWCOUNT_FormatValues($hash);
|
OWCOUNT_FormatValues($hash);
|
||||||
return "OWCOUNT: $name.raw $a[2] => ".$owg_val[$page-14];
|
return "OWCOUNT: $name.raw $a[2] => ".$hash->{owg_val}->[$page-14];
|
||||||
|
|
||||||
#-- check syntax for getting counters
|
#-- check syntax for getting counters
|
||||||
}elsif( $reading eq "counters" ){
|
}elsif( $reading eq "counters" ){
|
||||||
return "OWCOUNT: Get needs no parameter when reading counters"
|
return "OWCOUNT: Get needs no parameter when reading counters"
|
||||||
if( int(@a)==1 );
|
if( int(@a)==1 );
|
||||||
#-- OWX interface
|
$ret1 = OWCOUNT_GetPage($hash,14);
|
||||||
if( $interface eq "OWX" ){
|
$ret2 = OWCOUNT_GetPage($hash,15);
|
||||||
$ret1 = OWXCOUNT_GetPage($hash,14);
|
|
||||||
$ret2 = OWXCOUNT_GetPage($hash,15);
|
|
||||||
}elsif( $interface eq "OWServer" ){
|
|
||||||
$ret1 = OWFSCOUNT_GetPage($hash,14);
|
|
||||||
$ret2 = OWFSCOUNT_GetPage($hash,15);
|
|
||||||
}else{
|
|
||||||
return "OWCOUNT: GetValues with wrong IODev type $interface";
|
|
||||||
}
|
|
||||||
#-- process results
|
#-- process results
|
||||||
$ret .= $ret1
|
$ret .= $ret1
|
||||||
if( defined($ret1) );
|
if( defined($ret1) );
|
||||||
@ -771,6 +759,60 @@ sub OWCOUNT_Get($@) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#######################################################################################
|
||||||
|
#
|
||||||
|
# OWCOUNT_GetPage - Get a memory page
|
||||||
|
#
|
||||||
|
# Parameter hash = hash of device addressed
|
||||||
|
# page = page addressed
|
||||||
|
#
|
||||||
|
########################################################################################
|
||||||
|
|
||||||
|
sub OWCOUNT_GetPage ($$) {
|
||||||
|
my ($hash, $page) = @_;
|
||||||
|
|
||||||
|
#-- get memory page/counter according to interface type
|
||||||
|
my $interface= $hash->{IODev}->{TYPE};
|
||||||
|
my $name = $hash->{NAME};
|
||||||
|
my $ret;
|
||||||
|
|
||||||
|
#-- check if memory usage has been disabled
|
||||||
|
my $nomemory = defined($attr{$name}{"nomemory"}) ? $attr{$name}{"nomemory"} : 0;
|
||||||
|
|
||||||
|
#-- even if memory usage has been disabled, we need to read the page because it contains the counter values
|
||||||
|
if( ($nomemory==0) || (($nomemory==1) && ( ($page==14)||($page==15) )) ){
|
||||||
|
#-- OWX interface
|
||||||
|
if( $interface eq "OWX" ){
|
||||||
|
$ret = OWXCOUNT_GetPage($hash,$page);
|
||||||
|
#-- OWFS interface
|
||||||
|
}elsif( $interface eq "OWServer" ){
|
||||||
|
$ret = OWFSCOUNT_GetPage($hash,$page);
|
||||||
|
#-- Unknown interface
|
||||||
|
}else{
|
||||||
|
return "OWCOUNT: GetPage with wrong IODev type $interface";
|
||||||
|
}
|
||||||
|
|
||||||
|
#-- process results
|
||||||
|
if( defined($ret) ){
|
||||||
|
return "OWCOUNT: Could not get values from device $name, reason: ".$ret;
|
||||||
|
} else {
|
||||||
|
return undef
|
||||||
|
if( $nomemory==0 );
|
||||||
|
}
|
||||||
|
#-- when nomemory==1, we need to read the files
|
||||||
|
if( $page==14 ){
|
||||||
|
$hash->{owg_str}->[14] = OWCOUNT_recall($hash,"OWCOUNT_".$name."_14.dat");
|
||||||
|
return undef;
|
||||||
|
}elsif( $page==15 ){
|
||||||
|
$hash->{owg_str}->[15] = OWCOUNT_recall($hash,"OWCOUNT_".$name."_15.dat");
|
||||||
|
return undef;
|
||||||
|
} else {
|
||||||
|
return "OWCOUNT: file recall with wrong page number";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
########################################################################################
|
########################################################################################
|
||||||
#
|
#
|
||||||
# OWCOUNT_GetMonth Read monthly data from a file
|
# OWCOUNT_GetMonth Read monthly data from a file
|
||||||
@ -809,6 +851,9 @@ sub OWCOUNT_GetMonth($) {
|
|||||||
return "logfile of LogM is missing";
|
return "logfile of LogM is missing";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#-- current date
|
||||||
|
my ($csec,$cmin,$chour,$cday,$cmonth,$cyear,$cwday,$cyday,$cisdst) = localtime(time);
|
||||||
|
|
||||||
my $ret = open(OWXFILE, "< $lf" );
|
my $ret = open(OWXFILE, "< $lf" );
|
||||||
if( $ret) {
|
if( $ret) {
|
||||||
while( <OWXFILE> ){
|
while( <OWXFILE> ){
|
||||||
@ -831,7 +876,8 @@ sub OWCOUNT_GetMonth($) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( int(@month)==0 ){
|
if( int(@month)==0 ){
|
||||||
return "invalid logfile format in LogM";
|
return "invalid logfile format in LogM"
|
||||||
|
if( $cday!=1 );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return "cannot open logfile of LogM";
|
return "cannot open logfile of LogM";
|
||||||
@ -857,8 +903,7 @@ sub OWCOUNT_GetMonth($) {
|
|||||||
$total = int($total*100)/100;
|
$total = int($total*100)/100;
|
||||||
$total2 = int(100*($total+$hash->{READINGS}{$owg_channel[$i]}{VAL}))/100;
|
$total2 = int(100*($total+$hash->{READINGS}{$owg_channel[$i]}{VAL}))/100;
|
||||||
#-- number of days so far, including the present day
|
#-- number of days so far, including the present day
|
||||||
my ($sec,$min,$hour,$day,$month,$year,$wday,$yday,$isdst) = localtime(time);
|
my $deltim = int(@month)+($chour+$cmin/60.0 + $csec/3600.0)/24.0;
|
||||||
my $deltim = int(@month)+($hour+$min/60.0 + $sec/3600.0)/24.0;
|
|
||||||
my $av = int(100*$total2/$deltim)/100;
|
my $av = int(100*$total2/$deltim)/100;
|
||||||
#-- output format
|
#-- output format
|
||||||
push(@month2,[($total,$total2,$av)]);
|
push(@month2,[($total,$total2,$av)]);
|
||||||
@ -899,6 +944,9 @@ sub OWCOUNT_GetYear($) {
|
|||||||
#-- get channel names
|
#-- get channel names
|
||||||
OWCOUNT_ChannelNames($hash);
|
OWCOUNT_ChannelNames($hash);
|
||||||
|
|
||||||
|
#-- current date
|
||||||
|
my ($csec,$cmin,$chour,$cday,$cmonth,$cyear,$cwday,$cyday,$cisdst) = localtime(time);
|
||||||
|
|
||||||
my $lf = $defs{$ln}{currentlogfile};
|
my $lf = $defs{$ln}{currentlogfile};
|
||||||
if( !(defined($lf))){
|
if( !(defined($lf))){
|
||||||
return "logfile of LogY is missing";
|
return "logfile of LogY is missing";
|
||||||
@ -926,7 +974,8 @@ sub OWCOUNT_GetYear($) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( int(@year)==0 ){
|
if( int(@year)==0 ){
|
||||||
return "invalid logfile format in LogY";
|
return "invalid logfile format in LogY"
|
||||||
|
if($cmonth != 1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return "cannot open logfile of LogY";
|
return "cannot open logfile of LogY";
|
||||||
@ -956,7 +1005,6 @@ sub OWCOUNT_GetYear($) {
|
|||||||
Log 1," GetYear total = $total";
|
Log 1," GetYear total = $total";
|
||||||
$total2 = int(100*($total))/100;
|
$total2 = int(100*($total))/100;
|
||||||
#-- number of months so far, including the present day
|
#-- number of months so far, including the present day
|
||||||
my ($sec,$min,$hour,$day,$month,$year,$wday,$yday,$isdst) = localtime(time);
|
|
||||||
my $deltim = int(@year);
|
my $deltim = int(@year);
|
||||||
my $av = int(100*$total2/$deltim)/100;
|
my $av = int(100*$total2/$deltim)/100;
|
||||||
#-- output format
|
#-- output format
|
||||||
@ -1033,13 +1081,56 @@ sub OWCOUNT_InitializeDevice($) {
|
|||||||
my ($hash) = @_;
|
my ($hash) = @_;
|
||||||
|
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
|
#-- get memory page/counter according to interface type
|
||||||
|
my $interface= $hash->{IODev}->{TYPE};
|
||||||
|
|
||||||
|
my $olddata = "";
|
||||||
|
my $newdata = "OWCOUNT ".$owx_version;
|
||||||
|
my $ret = "";
|
||||||
$hash->{PRESENT} = 0;
|
$hash->{PRESENT} = 0;
|
||||||
|
|
||||||
#-- initial values
|
#-- initial values
|
||||||
for( my $i=0;$i<int(@owg_fixed);$i++) {
|
for( my $i=0;$i<int(@owg_fixed);$i++) {
|
||||||
#-- initial readings
|
#-- initial readings
|
||||||
$owg_val[$i] = "";
|
$hash->{owg_val}->[$i] = "";
|
||||||
$owg_midnight[$i] = "";
|
$hash->{owg_midnight}->[$i] = "";
|
||||||
|
$hash->{owg_str}->[$i] = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#-- testing if it is the emulator
|
||||||
|
#-- The model may be DS2423 or DS2423emu. 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,0);
|
||||||
|
$olddata = $hash->{owg_str}->[0];
|
||||||
|
$ret = OWXCOUNT_SetPage($hash,0,$newdata);
|
||||||
|
$ret .= OWXCOUNT_GetPage($hash,0);
|
||||||
|
$ret .= OWXCOUNT_SetPage($hash,0,$olddata);
|
||||||
|
##Use of uninitialized value in concatenation (.) or string at
|
||||||
|
##ERRORR /usr/share/fhem/FHEM/21_OWCOUNT.pm line 1100.
|
||||||
|
##Use of uninitialized value in concatenation (.) or string at
|
||||||
|
##/usr/share/fhem/FHEM/21_OWCOUNT.pm line 1103.
|
||||||
|
##Use of uninitialized value in concatenation (.) or string at
|
||||||
|
##/usr/share/fhem/FHEM/21_OWCOUNT.pm line 1104.
|
||||||
|
#-- OWFS interface
|
||||||
|
}elsif( $interface eq "OWServer" ){
|
||||||
|
$ret .= OWXCOUNT_GetPage($hash,0);
|
||||||
|
$olddata = $hash->{owg_str}->[0];
|
||||||
|
$ret = OWFSCOUNT_SetPage($hash,0,$newdata);
|
||||||
|
$ret .= OWFSCOUNT_GetPage($hash,0);
|
||||||
|
$ret .= OWFSCOUNT_SetPage($hash,0,$olddata);
|
||||||
|
#-- Unknown interface
|
||||||
|
}else{
|
||||||
|
return "OWCOUNT: InitializeDevice with wrong IODev type $interface";
|
||||||
|
}
|
||||||
|
#-- Here we test if writing the memory is ok.
|
||||||
|
if( substr($hash->{owg_str}->[0],0,length($newdata)) ne $newdata ){
|
||||||
|
Log 1,"OWCOUNT: model attribute of $name set to DS2423emu because no memory found";
|
||||||
|
CommandAttr (undef,"$name model DS2423emu");
|
||||||
|
CommandAttr (undef,"$name nomemory 1");
|
||||||
}
|
}
|
||||||
|
|
||||||
#-- Set state to initialized
|
#-- Set state to initialized
|
||||||
@ -1104,8 +1195,11 @@ sub OWCOUNT_Set($@) {
|
|||||||
my $interface= $hash->{IODev}->{TYPE};
|
my $interface= $hash->{IODev}->{TYPE};
|
||||||
|
|
||||||
#-- check syntax for setting memory page 0..13 or midnight A/B
|
#-- check syntax for setting memory page 0..13 or midnight A/B
|
||||||
|
my $nomemory = defined($attr{$name}{"nomemory"}) ? $attr{$name}{"nomemory"} : 0;
|
||||||
if( ($key eq "memory") || ($key eq "midnight") ){
|
if( ($key eq "memory") || ($key eq "midnight") ){
|
||||||
if( $key eq "memory" ){
|
if( $key eq "memory" ){
|
||||||
|
return "OWCOUNT: Memory usage disabled"
|
||||||
|
if( $nomemory==1 );
|
||||||
return "OWCOUNT: Set needs parameter when writing memory: <page>"
|
return "OWCOUNT: Set needs parameter when writing memory: <page>"
|
||||||
if( int(@a)<2 );
|
if( int(@a)<2 );
|
||||||
$page=int($a[2]);
|
$page=int($a[2]);
|
||||||
@ -1137,17 +1231,7 @@ sub OWCOUNT_Set($@) {
|
|||||||
$data.=" ";
|
$data.=" ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$ret = OWCOUNT_SetPage($hash,$page,$data);
|
||||||
#-- OWX interface
|
|
||||||
if( $interface eq "OWX" ){
|
|
||||||
$ret = OWXCOUNT_SetPage($hash,$page,$data);
|
|
||||||
#-- OWFS interface
|
|
||||||
}elsif( $interface eq "OWServer" ){
|
|
||||||
$ret = OWFSCOUNT_SetPage($hash,$page,$data);
|
|
||||||
#-- Unknown interface
|
|
||||||
}else{
|
|
||||||
return "OWCOUNT: Set with wrong IODev type $interface";
|
|
||||||
}
|
|
||||||
|
|
||||||
#-- process results
|
#-- process results
|
||||||
if( defined($ret) ){
|
if( defined($ret) ){
|
||||||
@ -1180,6 +1264,10 @@ sub OWCOUNT_SetPage ($$$) {
|
|||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
my $ret;
|
my $ret;
|
||||||
|
|
||||||
|
#-- check if memory usage has been disabled
|
||||||
|
my $nomemory = defined($attr{$name}{"nomemory"}) ? $attr{$name}{"nomemory"} : 0;
|
||||||
|
|
||||||
|
if( $nomemory==0 ){
|
||||||
#-- OWX interface
|
#-- OWX interface
|
||||||
if( $interface eq "OWX" ){
|
if( $interface eq "OWX" ){
|
||||||
$ret = OWXCOUNT_SetPage($hash,$page,$data);
|
$ret = OWXCOUNT_SetPage($hash,$page,$data);
|
||||||
@ -1195,6 +1283,62 @@ sub OWCOUNT_SetPage ($$$) {
|
|||||||
if( defined($ret) ){
|
if( defined($ret) ){
|
||||||
return "OWCOUNT: Could not set device $name, reason: ".$ret;
|
return "OWCOUNT: Could not set device $name, reason: ".$ret;
|
||||||
}
|
}
|
||||||
|
}else{
|
||||||
|
if( $page==14 ){
|
||||||
|
return OWCOUNT_store($hash,"OWCOUNT_".$name."_14.dat",$data);
|
||||||
|
}elsif( $page==15 ){
|
||||||
|
return OWCOUNT_store($hash,"OWCOUNT_".$name."_15.dat",$data);
|
||||||
|
} else {
|
||||||
|
return "OWCOUNT: file store with wrong page number";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
########################################################################################
|
||||||
|
#
|
||||||
|
# Store daily start value in a file
|
||||||
|
#
|
||||||
|
# Parameter hash, filename
|
||||||
|
#
|
||||||
|
########################################################################################
|
||||||
|
|
||||||
|
sub OWCOUNT_store($$$) {
|
||||||
|
my ($hash,$filename,$data) = @_;
|
||||||
|
|
||||||
|
my $name = $hash->{NAME};
|
||||||
|
my $mp = AttrVal("global", "modpath", ".");
|
||||||
|
my $ret = open(OWXFILE, "> $mp/FHEM/$filename" );
|
||||||
|
if( $ret) {
|
||||||
|
print OWXFILE $data;
|
||||||
|
Log 1, "OWCOUNT_store: $name $data";
|
||||||
|
close(OWXFILE);
|
||||||
|
} else {
|
||||||
|
Log 1,"OWCOUNT_store: Cannot open $filename for writing!";
|
||||||
|
}
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
########################################################################################
|
||||||
|
#
|
||||||
|
# Recall daily start value from a file
|
||||||
|
#
|
||||||
|
# Parameter hash,filename
|
||||||
|
#
|
||||||
|
########################################################################################
|
||||||
|
|
||||||
|
sub OWCOUNT_recall($$) {
|
||||||
|
my ($hash,$filename) = @_;
|
||||||
|
|
||||||
|
my $name= $hash->{NAME};
|
||||||
|
my $mp = AttrVal("global", "modpath", ".");
|
||||||
|
my $ret = open(OWXFILE, "< $mp/FHEM/$filename" );
|
||||||
|
if( $ret ){
|
||||||
|
my $line = readline OWXFILE;
|
||||||
|
close(OWXFILE);
|
||||||
|
return $line;
|
||||||
|
}
|
||||||
|
Log 1, "OWCOUNT_recall: Cannot open $filename for reading!";
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
########################################################################################
|
########################################################################################
|
||||||
@ -1238,6 +1382,7 @@ sub OWFSCOUNT_GetPage($$) {
|
|||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
my $vval;
|
my $vval;
|
||||||
|
my $strval;
|
||||||
|
|
||||||
#=============== wrong value requested ===============================
|
#=============== wrong value requested ===============================
|
||||||
if( ($page<0) || ($page>15) ){
|
if( ($page<0) || ($page>15) ){
|
||||||
@ -1246,49 +1391,48 @@ sub OWFSCOUNT_GetPage($$) {
|
|||||||
#-- get values - or shoud we rather get the uncached ones ?
|
#-- get values - or shoud we rather get the uncached ones ?
|
||||||
if( $page == 14) {
|
if( $page == 14) {
|
||||||
$vval = OWServer_Read($master,"/$owx_add/counters.A");
|
$vval = OWServer_Read($master,"/$owx_add/counters.A");
|
||||||
$owg_str = OWServer_Read($master,"/$owx_add/pages/page.14");
|
$strval = OWServer_Read($master,"/$owx_add/pages/page.14");
|
||||||
|
|
||||||
return "no return from OWServer"
|
return "no return from OWServer"
|
||||||
if( (!defined($vval)) || (!defined($owg_str)) );
|
if( (!defined($vval)) || (!defined($strval)) );
|
||||||
|
|
||||||
return "empty return from OWServer"
|
return "empty return from OWServer"
|
||||||
if( ($vval eq "") || ($owg_str eq "") );
|
if( ($vval eq "") || ($strval eq "") );
|
||||||
|
|
||||||
$owg_val[0] = $vval;
|
$hash->{owg_val}->[0] = $vval;
|
||||||
|
$hash->{owg_str}->[14] = $strval;
|
||||||
#-- parse float from midnight
|
#-- parse float from midnight
|
||||||
# $owg_str =~ /([\d\.]+)/;
|
$strval =~ s/[^\d\.]+//g;
|
||||||
# a la truchsess
|
$strval = 0.0 if(!defined($strval) or $strval !~ /^\d+\.?\d*$/);
|
||||||
$owg_str =~ s/[^\d\.]+//g;
|
$strval = int($strval*100)/100;
|
||||||
$owg_str = 0.0 if(!defined($owg_str) or $owg_str !~ /^\d+\.?\d*$/);
|
$hash->{owg_midnight}->[0] = $strval;
|
||||||
$owg_str = int($owg_str*100)/100;
|
|
||||||
$owg_midnight[0] = $owg_str;
|
|
||||||
|
|
||||||
}elsif( $page == 15) {
|
}elsif( $page == 15) {
|
||||||
$vval = OWServer_Read($master,"/$owx_add/counters.B");
|
$vval = OWServer_Read($master,"/$owx_add/counters.B");
|
||||||
$owg_str = OWServer_Read($master,"/$owx_add/pages/page.15");
|
$strval = OWServer_Read($master,"/$owx_add/pages/page.15");
|
||||||
|
|
||||||
return "no return from OWServer"
|
return "no return from OWServer"
|
||||||
if( (!defined($vval)) || (!defined($owg_str)) );
|
if( (!defined($vval)) || (!defined($strval)) );
|
||||||
|
|
||||||
return "empty return from OWServer"
|
return "empty return from OWServer"
|
||||||
if( ($vval eq "") || ($owg_str eq "") );
|
if( ($vval eq "") || ($strval eq "") );
|
||||||
|
|
||||||
$owg_val[1] = $vval;
|
$hash->{owg_val}->[1] = $vval;
|
||||||
|
$hash->{owg_str}->[15] = $strval;
|
||||||
#-- parse float from midnight
|
#-- parse float from midnight
|
||||||
# $owg_str =~ /([\d\.]+)/;
|
$strval =~ s/[^\d\.]+//g;
|
||||||
# a la truchsess
|
$strval = 0.0 if(!defined($strval) or $strval !~ /^\d+\.\d*$/);
|
||||||
$owg_str =~ s/[^\d\.]+//g;
|
$strval = int($strval*100)/100;
|
||||||
$owg_str = 0.0 if(!defined($owg_str) or $owg_str !~ /^\d+\.\d*$/);
|
$hash->{owg_midnight}->[1] = $strval;
|
||||||
$owg_str = int($owg_str*100)/100;
|
|
||||||
$owg_midnight[1] = $owg_str;
|
|
||||||
}else {
|
}else {
|
||||||
$owg_str = OWServer_Read($master,"/$owx_add/pages/page.".$page);
|
$strval = OWServer_Read($master,"/$owx_add/pages/page.".$page);
|
||||||
|
|
||||||
return "no return from OWServer"
|
return "no return from OWServer"
|
||||||
if( !defined($owg_str) );
|
if( !defined($strval) );
|
||||||
|
|
||||||
return "empty return from OWServer"
|
return "empty return from OWServer"
|
||||||
if( $owg_str eq "" );
|
if( $strval eq "" );
|
||||||
|
$hash->{owg_str}->[$page] = $strval;
|
||||||
}
|
}
|
||||||
return undef
|
return undef
|
||||||
}
|
}
|
||||||
@ -1328,7 +1472,7 @@ sub OWFSCOUNT_SetPage($$$) {
|
|||||||
#
|
#
|
||||||
########################################################################################
|
########################################################################################
|
||||||
#
|
#
|
||||||
# OWXAD_GetPage - Get one memory page + counter from device
|
# OWXCOUNT_GetPage - Get one memory page + counter from device
|
||||||
#
|
#
|
||||||
# Parameter hash = hash of device addressed
|
# Parameter hash = hash of device addressed
|
||||||
# page = 0..15
|
# page = 0..15
|
||||||
@ -1356,14 +1500,23 @@ sub OWXCOUNT_GetPage($$) {
|
|||||||
my $ta2 = ($page*32) >> 8;
|
my $ta2 = ($page*32) >> 8;
|
||||||
my $ta1 = ($page*32) & 255;
|
my $ta1 = ($page*32) & 255;
|
||||||
$select=sprintf("\xA5%c%c",$ta1,$ta2);
|
$select=sprintf("\xA5%c%c",$ta1,$ta2);
|
||||||
|
|
||||||
|
#-- asynchronous mode
|
||||||
|
if( $hash->{ASYNC} ){
|
||||||
|
#TODO: Parameters possibly wrong
|
||||||
|
if (!OWX_Execute( $master, "getpage", 1, $owx_dev, "\x3C\x0F\x00\xFF\xFF", 0, 20 )) {
|
||||||
|
return "not accessible for reading";
|
||||||
|
}
|
||||||
|
return OWX_AwaitExecuteResponse( $master, "getpage", $owx_dev );
|
||||||
|
#-- synchronous mode
|
||||||
|
} else {
|
||||||
#-- reset the bus
|
#-- reset the bus
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
#-- reading 9 + 3 + 40 data bytes and 2 CRC bytes = 54 bytes
|
#-- reading 9 + 3 + 40 data bytes (32 byte memory, 4 byte counter + 4 byte zeroes) and 2 CRC bytes = 54 bytes
|
||||||
$res=OWX_Complex($master,$owx_dev,$select,42);
|
$res=OWX_Complex($master,$owx_dev,$select,42);
|
||||||
if( $res eq 0 ){
|
if( $res eq 0 ){
|
||||||
return "device $owx_dev not accessible in reading page $page";
|
return "device $owx_dev not accessible in reading page $page";
|
||||||
}
|
}
|
||||||
|
|
||||||
#-- process results
|
#-- process results
|
||||||
if( length($res) < 54 ) {
|
if( length($res) < 54 ) {
|
||||||
#Log 1, "OWXCOUNT: warning, have received ".length($res)." bytes in first step";
|
#Log 1, "OWXCOUNT: warning, have received ".length($res)." bytes in first step";
|
||||||
@ -1376,24 +1529,48 @@ sub OWXCOUNT_GetPage($$) {
|
|||||||
$res.=OWX_Complex($master,"","",0);
|
$res.=OWX_Complex($master,"","",0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#-- reset the bus
|
#-- reset the bus (needed to stop receiving data ?)
|
||||||
OWX_Reset($master);
|
#OWX_Reset($master);
|
||||||
|
#-- for processing we need 45 bytes
|
||||||
|
OWXCOUNT_BinValues($hash,$page,undef,undef,$owx_dev,undef,undef,substr($res,9));
|
||||||
|
}
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
########################################################################################
|
||||||
|
#
|
||||||
|
# OWXCOUNT_BinValues - Process reading from one device - translate binary into raw
|
||||||
|
#
|
||||||
|
# Parameter hash = hash of device addressed
|
||||||
|
#
|
||||||
|
########################################################################################
|
||||||
|
|
||||||
|
sub OWXCOUNT_BinValues($$$$$$$$) {
|
||||||
|
my ($hash, $page, $success, $reset, $owx_dev, $data, $numread, $res) = @_;
|
||||||
|
|
||||||
|
#-- unused are success, reset, data numread
|
||||||
|
|
||||||
|
return undef unless (defined $page and $page ne "convert");
|
||||||
|
|
||||||
|
my ($i,$j,$k,@data,$strval);
|
||||||
|
my $change = 0;
|
||||||
|
|
||||||
#-- process results
|
#-- process results
|
||||||
@data=split(//,substr($res,9));
|
@data=split(//,$res);
|
||||||
return "invalid data length, ".int(@data)." instead of 45 bytes in three steps"
|
return "invalid data length, ".int(@data)." instead of 45 bytes in three steps"
|
||||||
if( int(@data) < 45);
|
if( int(@data) < 45);
|
||||||
#return "invalid data"
|
#return "invalid data"
|
||||||
# if (ord($data[17])<=0);
|
# if (ord($data[17])<=0);
|
||||||
return "invalid CRC"
|
Log 1,"invalid CRC"
|
||||||
if (OWX_CRC16(substr($res,9,43),$data[43],$data[44]) == 0);
|
if (OWX_CRC16(substr($res,0,43),$data[43],$data[44]) == 0);
|
||||||
|
|
||||||
#-- first 3 command, next 32 are memory
|
#-- first 3 command, next 32 are memory
|
||||||
#-- memory part, treated as string
|
#-- memory part, treated as string
|
||||||
$owg_str=substr($res,12,32);
|
$strval=substr($res,3,32);
|
||||||
|
$hash->{owg_str}->[$page]=$strval;
|
||||||
#-- counter part
|
#-- counter part
|
||||||
if( ($page == 14) || ($page == 15) ){
|
if( ($page == 14) || ($page == 15) ){
|
||||||
@data=split(//,substr($res,44));
|
@data=split(//,substr($res,35));
|
||||||
if ( ($data[4] | $data[5] | $data[6] | $data[7]) ne "\x00" ){
|
if ( ($data[4] | $data[5] | $data[6] | $data[7]) ne "\x00" ){
|
||||||
#Log 1, "device $owx_dev returns invalid data ".ord($data[4])." ".ord($data[5])." ".ord($data[6])." ".ord($data[7]);
|
#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";
|
return "device $owx_dev returns invalid data";
|
||||||
@ -1402,25 +1579,20 @@ sub OWXCOUNT_GetPage($$) {
|
|||||||
my $value = (ord($data[3])<<24) + (ord($data[2])<<16) +(ord($data[1])<<8) + ord($data[0]);
|
my $value = (ord($data[3])<<24) + (ord($data[2])<<16) +(ord($data[1])<<8) + ord($data[0]);
|
||||||
|
|
||||||
if( $page == 14) {
|
if( $page == 14) {
|
||||||
$owg_val[0] = $value;
|
$hash->{owg_val}->[0] = $value;
|
||||||
#-- parse float from midnight
|
#-- parse float from midnight
|
||||||
# $owg_str =~ /([\d\.]+)/;
|
$strval =~ s/[^\d\.]+//g;
|
||||||
# a la truchsess
|
$strval = 0.0 if(!defined($strval) or $strval !~ /^\d+\.\d*$/);
|
||||||
$owg_str =~ s/[^\d\.]+//g;
|
$strval = int($strval*100)/100;
|
||||||
$owg_str = 0.0 if(!defined($owg_str) or $owg_str !~ /^\d+\.\d*$/);
|
$hash->{owg_midnight}->[0] = $strval;
|
||||||
$owg_str = int($owg_str*100)/100;
|
|
||||||
$owg_midnight[0] = $owg_str;
|
|
||||||
}elsif( $page == 15) {
|
}elsif( $page == 15) {
|
||||||
$owg_val[1] = $value;
|
$hash->{owg_val}->[1] = $value;
|
||||||
#-- parse float from midnight
|
#-- parse float from midnight
|
||||||
# $owg_str =~ /([\d\.]+)/;
|
$strval =~ s/[^\d\.]+//g;
|
||||||
# a la truchsess
|
$strval = 0.0 if(!defined($strval) or $strval !~ /^\d+\.\d*$/);
|
||||||
$owg_str =~ s/[^\d\.]+//g;
|
$strval = int($strval*100)/100;
|
||||||
$owg_str = 0.0 if(!defined($owg_str) or $owg_str !~ /^\d+\.\d*$/);
|
$hash->{owg_midnight}->[1] = $strval;
|
||||||
$owg_str = int($owg_str*100)/100;
|
|
||||||
$owg_midnight[1] = $owg_str;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return undef;
|
return undef;
|
||||||
@ -1456,16 +1628,33 @@ sub OWXCOUNT_SetPage($$$) {
|
|||||||
my $ta1 = ($page*32) & 255;
|
my $ta1 = ($page*32) & 255;
|
||||||
#Log 1, "OWXCOUNT: setting page Nr. $ta2 $ta1";
|
#Log 1, "OWXCOUNT: setting page Nr. $ta2 $ta1";
|
||||||
$select=sprintf("\x0F%c%c",$ta1,$ta2).$data;
|
$select=sprintf("\x0F%c%c",$ta1,$ta2).$data;
|
||||||
|
#-- asynchronous mode
|
||||||
|
if( $hash->{ASYNC} ){
|
||||||
|
if (OWX_Execute( $master, "setpage", 1, $owx_dev, $select, 0, undef )) {
|
||||||
|
return undef;
|
||||||
|
} else {
|
||||||
|
return "device $owx_dev not accessible for writing";
|
||||||
|
}
|
||||||
|
#-- synchronous mode
|
||||||
|
} else {
|
||||||
#-- reset the bus
|
#-- reset the bus
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
#-- reading 9 + 3 + 16 bytes = 29 bytes
|
|
||||||
$res=OWX_Complex($master,$owx_dev,$select,0);
|
$res=OWX_Complex($master,$owx_dev,$select,0);
|
||||||
if( $res eq 0 ){
|
if( $res eq 0 ){
|
||||||
return "device $owx_dev not accessible in writing scratchpad";
|
return "device $owx_dev not accessible in writing scratchpad";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#-- issue the match ROM command \x55 and the read scratchpad command
|
#-- issue the match ROM command \x55 and the read scratchpad command
|
||||||
# \xAA
|
# \xAA
|
||||||
|
#-- asynchronous mode
|
||||||
|
if( $hash->{ASYNC} ){
|
||||||
|
if (OWX_Execute( $master, "setpage", 1, $owx_dev, "\xAA", 0, undef )) {
|
||||||
|
return undef;
|
||||||
|
} else {
|
||||||
|
return "device $owx_dev not accessible for writing";
|
||||||
|
}
|
||||||
|
#-- synchronous mode
|
||||||
|
} else {
|
||||||
#-- reset the bus
|
#-- reset the bus
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
#-- reading 9 + 4 + 16 bytes = 28 bytes
|
#-- reading 9 + 4 + 16 bytes = 28 bytes
|
||||||
@ -1474,10 +1663,19 @@ sub OWXCOUNT_SetPage($$$) {
|
|||||||
if( length($res) < 13 ){
|
if( length($res) < 13 ){
|
||||||
return "device $owx_dev not accessible in reading scratchpad";
|
return "device $owx_dev not accessible in reading scratchpad";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#-- issue the match ROM command \x55 and the copy scratchpad command
|
#-- issue the match ROM command \x55 and the copy scratchpad command
|
||||||
# \x5A followed by 3 byte authentication code
|
# \x5A followed by 3 byte authentication code
|
||||||
$select="\x5A".substr($res,10,3);
|
$select="\x5A".substr($res,10,3);
|
||||||
|
#-- asynchronous mode
|
||||||
|
if( $hash->{ASYNC} ){
|
||||||
|
if (OWX_Execute( $master, "setpage", 1, $owx_dev, "\xAA", 0, undef )) {
|
||||||
|
return undef;
|
||||||
|
} else {
|
||||||
|
return "device $owx_dev not accessible for writing";
|
||||||
|
}
|
||||||
|
#-- synchronous mode
|
||||||
|
} else {
|
||||||
#-- reset the bus
|
#-- reset the bus
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
$res=OWX_Complex($master,$owx_dev,$select,6);
|
$res=OWX_Complex($master,$owx_dev,$select,6);
|
||||||
@ -1486,7 +1684,7 @@ sub OWXCOUNT_SetPage($$$) {
|
|||||||
if( $res eq 0 ){
|
if( $res eq 0 ){
|
||||||
return "device $owx_dev not accessible for writing";
|
return "device $owx_dev not accessible for writing";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1497,7 +1695,7 @@ sub OWXCOUNT_SetPage($$$) {
|
|||||||
|
|
||||||
<a name="OWCOUNT"></a>
|
<a name="OWCOUNT"></a>
|
||||||
<h3>OWCOUNT</h3>
|
<h3>OWCOUNT</h3>
|
||||||
<p>FHEM module to commmunicate with 1-Wire Counter/RAM DS2423 <br />
|
<p>FHEM module to commmunicate with 1-Wire Counter/RAM DS2423 or its emulation DS2423emu <br />
|
||||||
<br />This 1-Wire module works with the OWX interface module or with the OWServer interface module
|
<br />This 1-Wire module works with the OWX interface module or with the OWServer interface module
|
||||||
(prerequisite: Add this module's name to the list of clients in OWServer).
|
(prerequisite: Add this module's name to the list of clients in OWServer).
|
||||||
Please define an <a href="#OWX">OWX</a> device or <a href="#OWServer">OWServer</a> device first. <br/><p/>
|
Please define an <a href="#OWX">OWX</a> device or <a href="#OWServer">OWServer</a> device first. <br/><p/>
|
||||||
@ -1527,6 +1725,7 @@ sub OWXCOUNT_SetPage($$$) {
|
|||||||
id), currently the following values are permitted: <ul>
|
id), currently the following values are permitted: <ul>
|
||||||
<li>model DS2423 with family id 1D (default if the model parameter is
|
<li>model DS2423 with family id 1D (default if the model parameter is
|
||||||
omitted)</li>
|
omitted)</li>
|
||||||
|
<li>model DS2423emu with family id 1D - works like DS2423 except that the internal memory is not used</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
@ -1581,9 +1780,9 @@ sub OWXCOUNT_SetPage($$$) {
|
|||||||
<code>get <name> month</code></a><br />Returns cumulated and averaged monthly value if mode=daily, otherwise last day's and averaged value </li>
|
<code>get <name> month</code></a><br />Returns cumulated and averaged monthly value if mode=daily, otherwise last day's and averaged value </li>
|
||||||
<li><a name="owcount_year">
|
<li><a name="owcount_year">
|
||||||
<code>get <name> year</code></a><br />Returns cumulated and averaged yearly value if mode=daily, otherwise last months's and averaged value </li>
|
<code>get <name> year</code></a><br />Returns cumulated and averaged yearly value if mode=daily, otherwise last months's and averaged value </li>
|
||||||
<li><a name="owcount_counter">
|
<li><a name="owcount_raw">
|
||||||
<code>get <name> counter <channel-name></code></a><br />Obtain the
|
<code>get <name> raw <channel-name></code></a><br />Obtain the
|
||||||
current value for counter <channel> (A, B or named channel, see below)</li>
|
current raw value for counter <channel> (A, B or named channel, see below)</li>
|
||||||
<li><a name="owcount_counters">
|
<li><a name="owcount_counters">
|
||||||
<code>get <name> counters</code></a><br />Obtain the current value both
|
<code>get <name> counters</code></a><br />Obtain the current value both
|
||||||
counters</li>
|
counters</li>
|
||||||
@ -1598,6 +1797,13 @@ sub OWXCOUNT_SetPage($$$) {
|
|||||||
<li><a name="owcount_logy"><code>attr <name> LogY
|
<li><a name="owcount_logy"><code>attr <name> LogY
|
||||||
<string></code></a>
|
<string></code></a>
|
||||||
<br />device name (not file name) of yearly log file.</li>
|
<br />device name (not file name) of yearly log file.</li>
|
||||||
|
<li><a name="owcount_interval2">
|
||||||
|
<code>attr <name> interval <int></code></a>
|
||||||
|
<br /> Measurement
|
||||||
|
interval in seconds. The default is 300 seconds. </li>
|
||||||
|
<li><a name="owcount_nomemory"><code>attr <name> nomemory
|
||||||
|
0|1</code></a>
|
||||||
|
<br />when set to 1, midnight values will be stored in files instead of the internal memory.</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p>For each of the following attributes, the channel identification A,B may be used.</p>
|
<p>For each of the following attributes, the channel identification A,B may be used.</p>
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
# FHEM module to commmunicate with general 1-Wire ID-ROMS
|
# FHEM module to commmunicate with general 1-Wire ID-ROMS
|
||||||
#
|
#
|
||||||
# Prof. Dr. Peter A. Henning
|
# Prof. Dr. Peter A. Henning
|
||||||
|
# Norbert Truchsess
|
||||||
#
|
#
|
||||||
# $Id$
|
# $Id$
|
||||||
#
|
#
|
||||||
@ -52,7 +53,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
sub Log($$);
|
sub Log($$);
|
||||||
|
|
||||||
my $owx_version="3.24";
|
my $owx_version="5.03";
|
||||||
#-- declare variables
|
#-- declare variables
|
||||||
my %gets = (
|
my %gets = (
|
||||||
"present" => "",
|
"present" => "",
|
||||||
@ -93,7 +94,7 @@ sub OWID_Initialize ($) {
|
|||||||
"interval ".
|
"interval ".
|
||||||
$readingFnAttributes;
|
$readingFnAttributes;
|
||||||
|
|
||||||
#make sure OWX is loaded so OWX_CRC is available if running with OWServer
|
#--make sure OWX is loaded so OWX_CRC is available if running with OWServer
|
||||||
main::LoadModule("OWX");
|
main::LoadModule("OWX");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,6 +193,11 @@ sub OWID_Define ($$) {
|
|||||||
|
|
||||||
#--
|
#--
|
||||||
readingsSingleUpdate($hash,"state","Initialized",1);
|
readingsSingleUpdate($hash,"state","Initialized",1);
|
||||||
|
|
||||||
|
if (! (defined AttrVal($hash->{NAME},"stateFormat",undef))) {
|
||||||
|
$main::attr{$hash->{NAME}}{"stateFormat"} = "{ReadingsVal(\$name,\"present\",0) ? \"present\" : \"not present\"}";
|
||||||
|
}
|
||||||
|
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,10 +218,11 @@ sub OWID_Attr(@) {
|
|||||||
|
|
||||||
if ( $do eq "set") {
|
if ( $do eq "set") {
|
||||||
ARGUMENT_HANDLER: {
|
ARGUMENT_HANDLER: {
|
||||||
|
#-- interval modified at runtime
|
||||||
$key eq "interval" and do {
|
$key eq "interval" and do {
|
||||||
# check value
|
#-- check value
|
||||||
return "OWID: Set with short interval, must be > 1" if(int($value) < 1);
|
return "OWID: Set with short interval, must be > 1" if(int($value) < 1);
|
||||||
# update timer
|
#-- update timer
|
||||||
$hash->{INTERVAL} = $value;
|
$hash->{INTERVAL} = $value;
|
||||||
if ($init_done) {
|
if ($init_done) {
|
||||||
RemoveInternalTimer($hash);
|
RemoveInternalTimer($hash);
|
||||||
@ -272,12 +279,12 @@ sub OWID_Get($@) {
|
|||||||
#-- hash of the busmaster
|
#-- hash of the busmaster
|
||||||
my $master = $hash->{IODev};
|
my $master = $hash->{IODev};
|
||||||
$value = OWX_Verify($master,$hash->{ROM_ID});
|
$value = OWX_Verify($master,$hash->{ROM_ID});
|
||||||
$hash->{PRESENT} = $value;
|
|
||||||
if( $value == 0 ){
|
if( $value == 0 ){
|
||||||
readingsSingleUpdate($hash,"state","not present",1);
|
readingsSingleUpdate($hash,"present",0,$hash->{PRESENT});
|
||||||
} else {
|
} else {
|
||||||
readingsSingleUpdate($hash,"state","present",1);
|
readingsSingleUpdate($hash,"present",1,!$hash->{PRESENT});
|
||||||
}
|
}
|
||||||
|
$hash->{PRESENT} = $value;
|
||||||
return "$name.present => $value";
|
return "$name.present => $value";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,10 +292,8 @@ sub OWID_Get($@) {
|
|||||||
if( $a[1] eq "version") {
|
if( $a[1] eq "version") {
|
||||||
return "$name.version => $owx_version";
|
return "$name.version => $owx_version";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
########################################################################################
|
########################################################################################
|
||||||
#
|
#
|
||||||
# OWID_GetValues - Updates the reading from one device
|
# OWID_GetValues - Updates the reading from one device
|
||||||
@ -313,12 +318,14 @@ sub OWID_GetValues($) {
|
|||||||
#-- hash of the busmaster
|
#-- hash of the busmaster
|
||||||
my $master = $hash->{IODev};
|
my $master = $hash->{IODev};
|
||||||
$value = OWX_Verify($master,$hash->{ROM_ID});
|
$value = OWX_Verify($master,$hash->{ROM_ID});
|
||||||
$hash->{PRESENT} = $value;
|
|
||||||
|
#-- generate an event only if presence has changed
|
||||||
if( $value == 0 ){
|
if( $value == 0 ){
|
||||||
readingsSingleUpdate($hash,"state","not present",1);
|
readingsSingleUpdate($hash,"present",0,$hash->{PRESENT});
|
||||||
} else {
|
} else {
|
||||||
readingsSingleUpdate($hash,"state","present",1);
|
readingsSingleUpdate($hash,"present",1,!$hash->{PRESENT});
|
||||||
}
|
}
|
||||||
|
$hash->{PRESENT} = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
#######################################################################################
|
#######################################################################################
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
# FHEM module to commmunicate with 1-Wire chip DS2438Z - Smart Battery Monitor
|
# FHEM module to commmunicate with 1-Wire chip DS2438Z - Smart Battery Monitor
|
||||||
#
|
#
|
||||||
# Prof. Dr. Peter A. Henning
|
# Prof. Dr. Peter A. Henning
|
||||||
|
# Norbert Truchsess
|
||||||
#
|
#
|
||||||
# $Id$
|
# $Id$
|
||||||
#
|
#
|
||||||
@ -36,7 +37,7 @@
|
|||||||
# Note: attributes "tempXXXX" are read during every update operation.
|
# Note: attributes "tempXXXX" are read during every update operation.
|
||||||
#
|
#
|
||||||
# attr <name> tempOffset <float> = temperature offset in degree Celsius added to the raw temperature reading
|
# attr <name> tempOffset <float> = temperature offset in degree Celsius added to the raw temperature reading
|
||||||
# attr <name> tempUnit <string> = unit of measurement, e.g. Celsius/Kelvin/Fahrenheit or C/K/F, default is Celsius
|
# attr <name> tempUnit <string> = unit of measurement, e.g. Celsius/Kelvin/Fahrenheit, default is Celsius
|
||||||
# attr <name> VName <string>|<string> = name for the channel | a type description for the measured value
|
# attr <name> VName <string>|<string> = name for the channel | a type description for the measured value
|
||||||
# attr <name> VUnit <string>|<string> = unit of measurement for the voltage channel | its abbreviation
|
# attr <name> VUnit <string>|<string> = unit of measurement for the voltage channel | its abbreviation
|
||||||
# attr <name> Vfunction <string> = arbitrary functional expression involving the values VDD, V, T
|
# attr <name> Vfunction <string> = arbitrary functional expression involving the values VDD, V, T
|
||||||
@ -69,11 +70,8 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
sub Log($$);
|
sub Log($$);
|
||||||
|
|
||||||
my $owx_version="3.24";
|
my $owx_version="5.03";
|
||||||
#-- temperature and voltage globals - always the raw values from the device
|
#-- flexible channel name
|
||||||
my $owg_temp;
|
|
||||||
my $owg_volt;
|
|
||||||
my $owg_vdd;
|
|
||||||
my $owg_channel;
|
my $owg_channel;
|
||||||
|
|
||||||
my %gets = (
|
my %gets = (
|
||||||
@ -83,7 +81,6 @@ my %gets = (
|
|||||||
"reading" => "",
|
"reading" => "",
|
||||||
"temperature" => "",
|
"temperature" => "",
|
||||||
"VDD" => "",
|
"VDD" => "",
|
||||||
"VAD" => "",
|
|
||||||
"raw" => "",
|
"raw" => "",
|
||||||
"version" => ""
|
"version" => ""
|
||||||
);
|
);
|
||||||
@ -118,16 +115,25 @@ sub OWMULTI_Initialize ($) {
|
|||||||
$hash->{UndefFn} = "OWMULTI_Undef";
|
$hash->{UndefFn} = "OWMULTI_Undef";
|
||||||
$hash->{GetFn} = "OWMULTI_Get";
|
$hash->{GetFn} = "OWMULTI_Get";
|
||||||
$hash->{SetFn} = "OWMULTI_Set";
|
$hash->{SetFn} = "OWMULTI_Set";
|
||||||
|
$hash->{AfterExecuteFn} = "OWXMULTI_BinValues";
|
||||||
$hash->{AttrFn} = "OWMULTI_Attr";
|
$hash->{AttrFn} = "OWMULTI_Attr";
|
||||||
|
|
||||||
#tempOffset = a temperature offset added to the temperature reading for correction
|
#tempOffset = a temperature offset added to the temperature reading for correction
|
||||||
#tempUnit = a unit of measure: C/F/K
|
#tempUnit = a unit of measure: C/F/K
|
||||||
$hash->{AttrList}= "IODev do_not_notify:0,1 showtime:0,1 model:DS2438 loglevel:0,1,2,3,4,5 ".
|
$hash->{AttrList}= "IODev do_not_notify:0,1 showtime:0,1 model:DS2438 loglevel:0,1,2,3,4,5 ".
|
||||||
"tempOffset tempUnit:C,Celsius,F,Fahrenheit,K,Kelvin ".
|
"tempOffset tempUnit:Celsius,Fahrenheit,Kelvin ".
|
||||||
"VName VUnit VFunction ".
|
"VName VUnit VFunction ".
|
||||||
"interval ".
|
"interval ".
|
||||||
$readingFnAttributes;
|
$readingFnAttributes;
|
||||||
|
|
||||||
#make sure OWX is loaded so OWX_CRC is available if running with OWServer
|
#-- 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;
|
||||||
|
|
||||||
|
#-- this function is needed for asynchronous execution of the device reads
|
||||||
|
$hash->{AfterExecuteFn} = "OWXMULTI_BinValues";
|
||||||
|
#-- make sure OWX is loaded so OWX_CRC is available if running with OWServer
|
||||||
main::LoadModule("OWX");
|
main::LoadModule("OWX");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,10 +154,11 @@ sub OWMULTI_Attr(@) {
|
|||||||
|
|
||||||
if ( $do eq "set") {
|
if ( $do eq "set") {
|
||||||
ARGUMENT_HANDLER: {
|
ARGUMENT_HANDLER: {
|
||||||
|
#-- interval modified at runtime
|
||||||
$key eq "interval" and do {
|
$key eq "interval" and do {
|
||||||
# check value
|
#-- check value
|
||||||
return "OWMULTI: Set with short interval, must be > 1" if(int($value) < 1);
|
return "OWMULTI: Set with short interval, must be > 1" if(int($value) < 1);
|
||||||
# update timer
|
#-- update timer
|
||||||
$hash->{INTERVAL} = $value;
|
$hash->{INTERVAL} = $value;
|
||||||
if ($init_done) {
|
if ($init_done) {
|
||||||
RemoveInternalTimer($hash);
|
RemoveInternalTimer($hash);
|
||||||
@ -237,6 +244,7 @@ sub OWMULTI_Define ($$) {
|
|||||||
$hash->{PRESENT} = 0;
|
$hash->{PRESENT} = 0;
|
||||||
$hash->{ROM_ID} = "$fam.$id.$crc";
|
$hash->{ROM_ID} = "$fam.$id.$crc";
|
||||||
$hash->{INTERVAL} = $interval;
|
$hash->{INTERVAL} = $interval;
|
||||||
|
$hash->{ASYNC} = 0; #-- false for now
|
||||||
|
|
||||||
#-- Couple to I/O device
|
#-- Couple to I/O device
|
||||||
AssignIoPort($hash);
|
AssignIoPort($hash);
|
||||||
@ -246,7 +254,7 @@ sub OWMULTI_Define ($$) {
|
|||||||
#if( $hash->{IODev}->{PRESENT} != 1 ){
|
#if( $hash->{IODev}->{PRESENT} != 1 ){
|
||||||
# return "OWMULTI: Warning, 1-Wire I/O device ".$hash->{IODev}->{NAME}." not present for $name.";
|
# return "OWMULTI: Warning, 1-Wire I/O device ".$hash->{IODev}->{NAME}." not present for $name.";
|
||||||
#}
|
#}
|
||||||
$modules{OWMULTI}{defptr}{$id} = $hash;
|
$main::modules{OWMULTI}{defptr}{$id} = $hash;
|
||||||
#--
|
#--
|
||||||
readingsSingleUpdate($hash,"state","defined",1);
|
readingsSingleUpdate($hash,"state","defined",1);
|
||||||
Log 3, "OWMULTI: Device $name defined.";
|
Log 3, "OWMULTI: Device $name defined.";
|
||||||
@ -342,7 +350,7 @@ sub OWMULTI_FormatValues($) {
|
|||||||
my $svalue = "";
|
my $svalue = "";
|
||||||
|
|
||||||
#-- no change in any value if invalid reading
|
#-- no change in any value if invalid reading
|
||||||
return if( ($owg_temp eq "") || ($owg_vdd eq "") || ($owg_volt eq "") );
|
return if( ($hash->{owg_val}->[0] eq "") || ($hash->{owg_val}->[1] eq "") || ($hash->{owg_val}->[2] eq "") );
|
||||||
|
|
||||||
#-- obtain channel names
|
#-- obtain channel names
|
||||||
OWMULTI_ChannelNames($hash);
|
OWMULTI_ChannelNames($hash);
|
||||||
@ -350,18 +358,18 @@ sub OWMULTI_FormatValues($) {
|
|||||||
#-- correct values for proper offset, factor
|
#-- correct values for proper offset, factor
|
||||||
$toffset = $hash->{tempf}{offset};
|
$toffset = $hash->{tempf}{offset};
|
||||||
$tfactor = $hash->{tempf}{factor};
|
$tfactor = $hash->{tempf}{factor};
|
||||||
$tval = ($owg_temp + $toffset)*$tfactor;
|
$tval = ($hash->{owg_val}->[0] + $toffset)*$tfactor;
|
||||||
|
|
||||||
#-- attribute VFunction defined ?
|
#-- attribute VFunction defined ?
|
||||||
$vfunc = defined($attr{$name}{"VFunction"}) ? $attr{$name}{"VFunction"} : "V";
|
$vfunc = defined($attr{$name}{"VFunction"}) ? $attr{$name}{"VFunction"} : "V";
|
||||||
|
|
||||||
#-- replace by proper values
|
#-- replace by proper values
|
||||||
$vfunc =~ s/VDD/\$owg_vdd/g;
|
$vfunc =~ s/VDD/\$hash->{owg_val}->[1]/g;
|
||||||
$vfunc =~ s/V/\$owg_volt/g;
|
$vfunc =~ s/V/\$hash->{owg_val}->[2]/g;
|
||||||
$vfunc =~ s/T/\$tval/g;
|
$vfunc =~ s/T/\$tval/g;
|
||||||
|
|
||||||
#-- determine the measured value from the function
|
#-- determine the measured value from the function
|
||||||
$vfunc = "\$owg_vdd = $owg_vdd; \$owg_volt = $owg_volt; \$tval = $tval; ".$vfunc;
|
$vfunc = "\$hash->{owg_val}->[1] = $hash->{owg_val}->[1]; \$hash->{owg_val}->[2] = $hash->{owg_val}->[2]; \$tval = $tval; ".$vfunc;
|
||||||
#Log 1, "vfunc= ".$vfunc;
|
#Log 1, "vfunc= ".$vfunc;
|
||||||
$vfunc = eval($vfunc);
|
$vfunc = eval($vfunc);
|
||||||
if( !$vfunc ){
|
if( !$vfunc ){
|
||||||
@ -378,7 +386,7 @@ sub OWMULTI_FormatValues($) {
|
|||||||
#-- put into READINGS
|
#-- put into READINGS
|
||||||
readingsBeginUpdate($hash);
|
readingsBeginUpdate($hash);
|
||||||
readingsBulkUpdate($hash,$owg_channel,$vval);
|
readingsBulkUpdate($hash,$owg_channel,$vval);
|
||||||
readingsBulkUpdate($hash,"VDD",$owg_vdd);
|
readingsBulkUpdate($hash,"VDD",$hash->{owg_val}->[1]);
|
||||||
readingsBulkUpdate($hash,"temperature",$tval);
|
readingsBulkUpdate($hash,"temperature",$tval);
|
||||||
|
|
||||||
#-- STATE
|
#-- STATE
|
||||||
@ -450,6 +458,7 @@ sub OWMULTI_Get($@) {
|
|||||||
#-- reset presence
|
#-- reset presence
|
||||||
$hash->{PRESENT} = 0;
|
$hash->{PRESENT} = 0;
|
||||||
|
|
||||||
|
#-- for the other readings we need a new reading
|
||||||
#-- OWX interface
|
#-- OWX interface
|
||||||
if( $interface eq "OWX" ){
|
if( $interface eq "OWX" ){
|
||||||
#-- not different from getting all values ..
|
#-- not different from getting all values ..
|
||||||
@ -473,22 +482,17 @@ sub OWMULTI_Get($@) {
|
|||||||
return "OWMULTI: $name.reading => ".OWMULTI_FormatValues($hash);
|
return "OWMULTI: $name.reading => ".OWMULTI_FormatValues($hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
#-- return the special reading
|
|
||||||
if ($reading eq "VAD") {
|
|
||||||
return "OWMULTI: $name.VAD => ".
|
|
||||||
$hash->{READINGS}{$owg_channel}{VAL};
|
|
||||||
}
|
|
||||||
if ($reading eq "temperature") {
|
if ($reading eq "temperature") {
|
||||||
return "OWMULTI: $name.temperature => ".
|
return "OWMULTI: $name.temperature => ".
|
||||||
$hash->{READINGS}{"temperature"}{VAL};
|
$hash->{READINGS}{"temperature"}{VAL};
|
||||||
}
|
}
|
||||||
if ($reading eq "VDD") {
|
if ($reading eq "VDD") {
|
||||||
return "OWMULTI: $name.VDD => ".
|
return "OWMULTI: $name.VDD => ".
|
||||||
$hash->{READINGS}{"VDD"}{VAL};
|
$hash->{owg_val}->[1];
|
||||||
}
|
}
|
||||||
if ( $reading eq "raw") {
|
if ( $reading eq "raw") {
|
||||||
return "OWMULTI: $name.V => ".
|
return "OWMULTI: $name.raw => ".
|
||||||
$owg_volt;
|
$hash->{owg_val}->[2];
|
||||||
}
|
}
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
@ -525,8 +529,7 @@ sub OWMULTI_GetValues($@) {
|
|||||||
#-- max 3 tries
|
#-- max 3 tries
|
||||||
for(my $try=0; $try<3; $try++){
|
for(my $try=0; $try<3; $try++){
|
||||||
$ret = OWXMULTI_GetValues($hash);
|
$ret = OWXMULTI_GetValues($hash);
|
||||||
last
|
return if( !defined($ret) );
|
||||||
if( !defined($ret) );
|
|
||||||
}
|
}
|
||||||
}elsif( $interface eq "OWServer" ){
|
}elsif( $interface eq "OWServer" ){
|
||||||
$ret = OWFSMULTI_GetValues($hash);
|
$ret = OWFSMULTI_GetValues($hash);
|
||||||
@ -560,9 +563,9 @@ sub OWMULTI_InitializeDevice($) {
|
|||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
#-- Initial readings
|
#-- Initial readings
|
||||||
$owg_temp = "";
|
$hash->{owg_val}->[0] = "";
|
||||||
$owg_volt = "";
|
$hash->{owg_val}->[2] = "";
|
||||||
$owg_vdd = "";
|
$hash->{owg_val}->[1] = "";
|
||||||
|
|
||||||
#-- Set state to initialized
|
#-- Set state to initialized
|
||||||
readingsSingleUpdate($hash,"state","initialized",1);
|
readingsSingleUpdate($hash,"state","initialized",1);
|
||||||
@ -656,7 +659,7 @@ sub OWMULTI_Set($@) {
|
|||||||
sub OWMULTI_Undef ($) {
|
sub OWMULTI_Undef ($) {
|
||||||
my ($hash) = @_;
|
my ($hash) = @_;
|
||||||
|
|
||||||
delete($modules{OWMULTI}{defptr}{$hash->{OW_ID}});
|
delete($main::modules{OWMULTI}{defptr}{$hash->{OW_ID}});
|
||||||
RemoveInternalTimer($hash);
|
RemoveInternalTimer($hash);
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
@ -687,14 +690,14 @@ sub OWFSMULTI_GetValues($) {
|
|||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
#-- get values - or should we rather get the uncached ones ?
|
#-- get values - or should we rather get the uncached ones ?
|
||||||
$owg_temp = OWServer_Read($master,"/$owx_add/temperature");
|
$hash->{owg_val}->[0] = OWServer_Read($master,"/$owx_add/temperature");
|
||||||
$owg_vdd = OWServer_Read($master,"/$owx_add/VDD");
|
$hash->{owg_val}->[1] = OWServer_Read($master,"/$owx_add/VDD");
|
||||||
$owg_volt = OWServer_Read($master,"/$owx_add/VAD");
|
$hash->{owg_val}->[2] = OWServer_Read($master,"/$owx_add/VAD");
|
||||||
|
|
||||||
return "no return from OWServer"
|
return "no return from OWServer"
|
||||||
if( (!defined($owg_temp)) || (!defined($owg_vdd)) || (!defined($owg_volt)) );
|
if( (!defined($hash->{owg_val}->[0])) || (!defined($hash->{owg_val}->[1])) || (!defined($hash->{owg_val}->[2])) );
|
||||||
return "empty return from OWServer"
|
return "empty return from OWServer"
|
||||||
if( ($owg_temp eq "") || ($owg_vdd eq "") || ($owg_volt eq "") );
|
if( ($hash->{owg_val}->[0] eq "") || ($hash->{owg_val}->[1] eq "") || ($hash->{owg_val}->[2] eq "") );
|
||||||
|
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
@ -720,6 +723,79 @@ sub OWFSMULTI_SetValues($@) {
|
|||||||
#
|
#
|
||||||
# Prefix = OWXMULTI
|
# Prefix = OWXMULTI
|
||||||
#
|
#
|
||||||
|
########################################################################################
|
||||||
|
#
|
||||||
|
# OWXMULTI_BinValues - Binary readings into clear values
|
||||||
|
#
|
||||||
|
# Parameter hash = hash of device addressed
|
||||||
|
#
|
||||||
|
########################################################################################
|
||||||
|
|
||||||
|
sub OWXMULTI_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,"OWXMULTI_BinValues context = $context";
|
||||||
|
|
||||||
|
#-- process results
|
||||||
|
my @data=split(//,$res);
|
||||||
|
Log 1, "invalid data length, ".int(@data)." instead of 9 bytes"
|
||||||
|
if (@data != 9);
|
||||||
|
Log 1, "conversion not complete or data invalid"
|
||||||
|
if ((ord($data[0]) & 112)!=0);
|
||||||
|
Log 1, "invalid CRC"
|
||||||
|
if (OWX_CRC8(substr($res,0,8),$data[8])==0);
|
||||||
|
|
||||||
|
#-- this must be different for the different device types
|
||||||
|
# family = 26 => DS2438
|
||||||
|
#-- transform binary rep of VDD
|
||||||
|
if( $context eq "ds2438.getvdd") {
|
||||||
|
#-- temperature
|
||||||
|
my $lsb = ord($data[1]);
|
||||||
|
my $msb = ord($data[2]) & 127;
|
||||||
|
my $sign = ord($data[2]) & 128;
|
||||||
|
|
||||||
|
#-- test with -55 degrees
|
||||||
|
#$lsb = 0;
|
||||||
|
#$sign = 1;
|
||||||
|
#$msb = 73;
|
||||||
|
|
||||||
|
#-- 2's complement form = signed bytes
|
||||||
|
$hash->{owg_val}->[0] = $msb+ $lsb/256;
|
||||||
|
if( $sign !=0 ){
|
||||||
|
$hash->{owg_val}->[0] = -128+$hash->{owg_val}->[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
#-- voltage
|
||||||
|
$lsb = ord($data[3]);
|
||||||
|
$msb = ord($data[4]) & 3;
|
||||||
|
|
||||||
|
#-- test with 5V
|
||||||
|
#$lsb = 244;
|
||||||
|
#$msb = 1;
|
||||||
|
|
||||||
|
#-- supply voltage
|
||||||
|
$hash->{owg_val}->[1] = ($msb*256+ $lsb)/100;
|
||||||
|
};
|
||||||
|
#-- transform binary rep of VAD
|
||||||
|
if( $context eq "ds2438.getvad") {
|
||||||
|
#-- voltage
|
||||||
|
my $lsb = ord($data[3]);
|
||||||
|
my $msb = ord($data[4]) & 3;
|
||||||
|
|
||||||
|
#-- test with 7.2 V
|
||||||
|
#$lsb = 208;
|
||||||
|
#$msb = 2;
|
||||||
|
|
||||||
|
#-- external voltage
|
||||||
|
$hash->{owg_val}->[2] = ($msb*256+ $lsb)/100;
|
||||||
|
my $value = OWMULTI_FormatValues($hash);
|
||||||
|
Log 5, $value;
|
||||||
|
};
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
########################################################################################
|
########################################################################################
|
||||||
#
|
#
|
||||||
# OWXMULTI_GetValues - Get reading from one device
|
# OWXMULTI_GetValues - Get reading from one device
|
||||||
@ -739,161 +815,186 @@ sub OWXMULTI_GetValues($) {
|
|||||||
#-- hash of the busmaster
|
#-- hash of the busmaster
|
||||||
my $master = $hash->{IODev};
|
my $master = $hash->{IODev};
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------------
|
||||||
#-- switch the device to current measurement off, VDD only
|
#-- switch the device to current measurement off, VDD only
|
||||||
OWX_Reset($master);
|
|
||||||
#-- issue the match ROM command \x55 and the write scratchpad command
|
#-- issue the match ROM command \x55 and the write scratchpad command
|
||||||
|
#-- asynchronous mode
|
||||||
|
if( $hash->{ASYNC} ){
|
||||||
|
if (!OWX_Execute( $master, "ds2438.writestatusvdd", 1, $owx_dev, "\x4E\x00\x08", 0, undef )) {
|
||||||
|
return "$owx_dev write status failed";
|
||||||
|
}
|
||||||
|
#-- synchronous mode
|
||||||
|
} else {
|
||||||
|
OWX_Reset($master);
|
||||||
if( OWX_Complex($master,$owx_dev,"\x4E\x00\x08",0) eq 0 ){
|
if( OWX_Complex($master,$owx_dev,"\x4E\x00\x08",0) eq 0 ){
|
||||||
return "$owx_dev write status failed";
|
return "$owx_dev write status failed";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#-- copy scratchpad to register
|
#-- copy scratchpad to register
|
||||||
OWX_Reset($master);
|
|
||||||
#-- issue the match ROM command \x55 and the copy scratchpad command
|
#-- issue the match ROM command \x55 and the copy scratchpad command
|
||||||
|
#-- asynchronous mode
|
||||||
|
if( $hash->{ASYNC} ){
|
||||||
|
if (!OWX_Execute( $master, "ds2438.copyscratchpadvdd", 1, $owx_dev, "\x48\x00", 0, undef )) {
|
||||||
|
return "$owx_dev copy scratchpad failed";
|
||||||
|
}
|
||||||
|
#-- synchronous mode
|
||||||
|
} else {
|
||||||
|
OWX_Reset($master);
|
||||||
if( OWX_Complex($master,$owx_dev,"\x48\x00",0) eq 0){
|
if( OWX_Complex($master,$owx_dev,"\x48\x00",0) eq 0){
|
||||||
return "$owx_dev copy scratchpad failed";
|
return "$owx_dev copy scratchpad failed";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#-- initiate temperature conversion
|
#-- initiate temperature conversion
|
||||||
OWX_Reset($master);
|
#-- conversion needs some 12 ms !
|
||||||
#-- issue the match ROM command \x55 and the start conversion command
|
#-- issue the match ROM command \x55 and the start conversion command
|
||||||
|
#-- asynchronous mode
|
||||||
|
if( $hash->{ASYNC} ){
|
||||||
|
if (!OWX_Execute( $master, "ds2438.temperaturconversionvdd", 1, $owx_dev, "\x44", 0, 12 )) {
|
||||||
|
return "$owx_dev temperature conversion failed";
|
||||||
|
}
|
||||||
|
#-- synchronous mode
|
||||||
|
} else {
|
||||||
|
OWX_Reset($master);
|
||||||
if( OWX_Complex($master,$owx_dev,"\x44",0) eq 0 ){
|
if( OWX_Complex($master,$owx_dev,"\x44",0) eq 0 ){
|
||||||
return "$owx_dev temperature conversion failed";
|
return "$owx_dev temperature conversion failed";
|
||||||
}
|
}
|
||||||
#-- conversion needs some 10 ms !
|
|
||||||
select(undef,undef,undef,0.012);
|
select(undef,undef,undef,0.012);
|
||||||
|
}
|
||||||
|
|
||||||
#-- initiate voltage conversion
|
#-- initiate voltage conversion
|
||||||
OWX_Reset($master);
|
#-- conversion needs some 6 ms !
|
||||||
#-- issue the match ROM command \x55 and the start conversion command
|
#-- issue the match ROM command \x55 and the start conversion command
|
||||||
|
#-- asynchronous mode
|
||||||
|
if( $hash->{ASYNC} ){
|
||||||
|
if (!OWX_Execute( $master, "ds2438.voltageconversionvdd", 1, $owx_dev, "\xB4", 0, 6 )) {
|
||||||
|
return "$owx_dev voltage conversion failed";
|
||||||
|
}
|
||||||
|
#-- synchronous mode
|
||||||
|
} else {
|
||||||
|
OWX_Reset($master);
|
||||||
if( OWX_Complex($master,$owx_dev,"\xB4",0) eq 0 ){
|
if( OWX_Complex($master,$owx_dev,"\xB4",0) eq 0 ){
|
||||||
return "$owx_dev voltage conversion failed";
|
return "$owx_dev voltage conversion failed";
|
||||||
}
|
}
|
||||||
#-- conversion needs some 4 ms !
|
|
||||||
select(undef,undef,undef,0.006);
|
select(undef,undef,undef,0.006);
|
||||||
|
}
|
||||||
|
|
||||||
#-- from memory to scratchpad
|
#-- from memory to scratchpad
|
||||||
OWX_Reset($master);
|
#-- copy needs some 12 ms !
|
||||||
#-- issue the match ROM command \x55 and the recall memory command
|
#-- issue the match ROM command \x55 and the recall memory command
|
||||||
|
#-- asynchronous mode
|
||||||
|
if( $hash->{ASYNC} ){
|
||||||
|
if (!OWX_Execute( $master, "ds2438.recallmemoryvdd", 1, $owx_dev, "\xB8\x00", 0, 12 )) {
|
||||||
|
return "$owx_dev recall memory failed";
|
||||||
|
}
|
||||||
|
#-- synchronous mode
|
||||||
|
} else {
|
||||||
|
OWX_Reset($master);
|
||||||
if( OWX_Complex($master,$owx_dev,"\xB8\x00",0) eq 0 ){
|
if( OWX_Complex($master,$owx_dev,"\xB8\x00",0) eq 0 ){
|
||||||
return "$owx_dev recall memory failed";
|
return "$owx_dev recall memory failed";
|
||||||
}
|
}
|
||||||
#-- copy needs some 10 ms !
|
|
||||||
select(undef,undef,undef,0.012);
|
select(undef,undef,undef,0.012);
|
||||||
|
}
|
||||||
#-- NOW ask the specific device
|
#-- NOW ask the specific device
|
||||||
OWX_Reset($master);
|
|
||||||
#-- issue the match ROM command \x55 and the read scratchpad command \xBE
|
#-- issue the match ROM command \x55 and the read scratchpad command \xBE
|
||||||
#-- reading 9 + 2 + 9 data bytes = 20 bytes
|
#-- reading 9 + 2 + 9 data bytes = 20 bytes
|
||||||
|
#-- asynchronous mode
|
||||||
|
if( $hash->{ASYNC} ){
|
||||||
|
if (!OWX_Execute( $master, "ds2438.getvdd", 1, $owx_dev, "\xBE\x00", 9, undef )) {
|
||||||
|
return "$owx_dev not accessible in 2nd step";
|
||||||
|
}
|
||||||
|
#-- synchronous mode
|
||||||
|
} else {
|
||||||
|
OWX_Reset($master);
|
||||||
$res=OWX_Complex($master,$owx_dev,"\xBE\x00",9);
|
$res=OWX_Complex($master,$owx_dev,"\xBE\x00",9);
|
||||||
#Log 1,"OWXMULTI: data length from reading device is ".length($res)." bytes";
|
#Log 1,"OWXMULTI: data length from reading device is ".length($res)." bytes";
|
||||||
#-- process results
|
|
||||||
if( $res eq 0 ){
|
if( $res eq 0 ){
|
||||||
return "$owx_dev not accessible in 2nd step";
|
return "$owx_dev not accessible in 2nd step";
|
||||||
}
|
}
|
||||||
|
OWXMULTI_BinValues($hash,"ds2438.getvdd",1,undef,$owx_dev,undef,undef,substr($res,11));
|
||||||
#-- process results
|
|
||||||
my @data=split(//,substr($res,9));
|
|
||||||
return "invalid data length, ".int(@data)." instead of 11 bytes"
|
|
||||||
if (@data != 11);
|
|
||||||
return "conversion not complete or data invalid"
|
|
||||||
if ((ord($data[2]) & 112)!=0);
|
|
||||||
return "invalid CRC"
|
|
||||||
if (OWX_CRC8(substr($res,11,8),$data[10])==0);
|
|
||||||
|
|
||||||
#-- this must be different for the different device types
|
|
||||||
# family = 26 => DS2438
|
|
||||||
|
|
||||||
#-- temperature
|
|
||||||
my $lsb = ord($data[3]);
|
|
||||||
my $msb = ord($data[4]) & 127;
|
|
||||||
my $sign = ord($data[4]) & 128;
|
|
||||||
|
|
||||||
#-- test with -55 degrees
|
|
||||||
#$lsb = 0;
|
|
||||||
#$sign = 1;
|
|
||||||
#$msb = 73;
|
|
||||||
|
|
||||||
#-- 2's complement form = signed bytes
|
|
||||||
$owg_temp = $msb+ $lsb/256;
|
|
||||||
if( $sign !=0 ){
|
|
||||||
$owg_temp = -128+$owg_temp;
|
|
||||||
}
|
}
|
||||||
|
#------------------------------------------------------------------------------------
|
||||||
#-- voltage
|
|
||||||
$lsb = ord($data[5]);
|
|
||||||
$msb = ord($data[6]) & 3;
|
|
||||||
|
|
||||||
#-- test with 5V
|
|
||||||
#$lsb = 244;
|
|
||||||
#$msb = 1;
|
|
||||||
|
|
||||||
#-- supply voltage
|
|
||||||
$owg_vdd = ($msb*256+ $lsb)/100;
|
|
||||||
|
|
||||||
#-- switch the device to current measurement off, V external only
|
#-- switch the device to current measurement off, V external only
|
||||||
OWX_Reset($master);
|
|
||||||
#-- issue the match ROM command \x55 and the write scratchpad command
|
#-- issue the match ROM command \x55 and the write scratchpad command
|
||||||
|
#-- asynchronous mode
|
||||||
|
if( $hash->{ASYNC} ){
|
||||||
|
if (!OWX_Execute( $master, "ds2438.writestatusvad", 1, $owx_dev, "\x4E\x00\x00", 0, undef )) {
|
||||||
|
return "$owx_dev write status failed";
|
||||||
|
}
|
||||||
|
#-- synchronous mode
|
||||||
|
} else {
|
||||||
|
OWX_Reset($master);
|
||||||
if( OWX_Complex($master,$owx_dev,"\x4E\x00\x00",0) eq 0 ){
|
if( OWX_Complex($master,$owx_dev,"\x4E\x00\x00",0) eq 0 ){
|
||||||
return "$owx_dev write status failed";
|
return "$owx_dev write status failed";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#-- copy scratchpad to register
|
#-- copy scratchpad to register
|
||||||
OWX_Reset($master);
|
|
||||||
#-- issue the match ROM command \x55 and the copy scratchpad command
|
#-- issue the match ROM command \x55 and the copy scratchpad command
|
||||||
|
#-- asynchronous mode
|
||||||
|
if( $hash->{ASYNC} ){
|
||||||
|
if (!OWX_Execute( $master, "ds2438.copyscratchpadvad", 1, $owx_dev, "\x48\x00", 0, undef )) {
|
||||||
|
return "$owx_dev copy scratchpad failed";
|
||||||
|
}
|
||||||
|
#-- synchronous mode
|
||||||
|
} else {
|
||||||
|
OWX_Reset($master);
|
||||||
if( OWX_Complex($master,$owx_dev,"\x48\x00",0) eq 0){
|
if( OWX_Complex($master,$owx_dev,"\x48\x00",0) eq 0){
|
||||||
return "$owx_dev copy scratchpad failed";
|
return "$owx_dev copy scratchpad failed";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#-- initiate voltage conversion
|
#-- initiate voltage conversion
|
||||||
OWX_Reset($master);
|
#-- conversion needs some 6 ms !
|
||||||
#-- issue the match ROM command \x55 and the start conversion command
|
#-- issue the match ROM command \x55 and the start conversion command
|
||||||
|
#-- asynchronous mode
|
||||||
|
if( $hash->{ASYNC} ){
|
||||||
|
if (!OWX_Execute( $master, "ds2438.voltageconversionvad", 1, $owx_dev, "\xB4", 0, 6 )) {
|
||||||
|
return "$owx_dev voltage conversion failed";
|
||||||
|
}
|
||||||
|
#-- synchronous mode
|
||||||
|
} else {
|
||||||
|
OWX_Reset($master);
|
||||||
if( OWX_Complex($master,$owx_dev,"\xB4",0) eq 0 ){
|
if( OWX_Complex($master,$owx_dev,"\xB4",0) eq 0 ){
|
||||||
return "$owx_dev voltage conversion failed";
|
return "$owx_dev voltage conversion failed";
|
||||||
}
|
}
|
||||||
#-- conversion needs some 4 ms !
|
|
||||||
select(undef,undef,undef,0.006);
|
select(undef,undef,undef,0.006);
|
||||||
|
}
|
||||||
|
|
||||||
#-- from memory to scratchpad
|
#-- from memory to scratchpad
|
||||||
OWX_Reset($master);
|
#-- copy needs some 12 ms !
|
||||||
#-- issue the match ROM command \x55 and the recall memory command
|
#-- issue the match ROM command \x55 and the recall memory command
|
||||||
|
#-- asynchronous mode
|
||||||
|
if( $hash->{ASYNC} ){
|
||||||
|
if (!OWX_Execute( $master, "ds2438.recallmemoryvad", 1, $owx_dev, "\xB8\x00", 0, 12 )) {
|
||||||
|
return "$owx_dev recall memory failed";
|
||||||
|
}
|
||||||
|
#-- synchronous mode
|
||||||
|
} else {
|
||||||
|
OWX_Reset($master);
|
||||||
if( OWX_Complex($master,$owx_dev,"\xB8\x00",0) eq 0 ){
|
if( OWX_Complex($master,$owx_dev,"\xB8\x00",0) eq 0 ){
|
||||||
return "$owx_dev recall memory failed";
|
return "$owx_dev recall memory failed";
|
||||||
}
|
}
|
||||||
#-- copy needs some 10 ms !
|
|
||||||
select(undef,undef,undef,0.012);
|
select(undef,undef,undef,0.012);
|
||||||
|
}
|
||||||
|
|
||||||
#-- NOW ask the specific device
|
#-- NOW ask the specific device
|
||||||
OWX_Reset($master);
|
|
||||||
#-- issue the match ROM command \x55 and the read scratchpad command \xBE
|
#-- issue the match ROM command \x55 and the read scratchpad command \xBE
|
||||||
#-- reading 9 + 2 + 9 data bytes = 20 bytes
|
#-- reading 9 + 2 + 9 data bytes = 20 bytes
|
||||||
|
#-- asynchronous mode
|
||||||
|
if( $hash->{ASYNC} ){
|
||||||
|
if (!OWX_Execute( $master, "ds2438.getvad", 1, $owx_dev, "\xBE\x00", 9, undef )) {
|
||||||
|
return "$owx_dev not accessible in 2nd step";
|
||||||
|
}
|
||||||
|
#-- synchronous mode
|
||||||
|
} else {
|
||||||
|
OWX_Reset($master);
|
||||||
$res=OWX_Complex($master,$owx_dev,"\xBE\x00",9);
|
$res=OWX_Complex($master,$owx_dev,"\xBE\x00",9);
|
||||||
#-- process results
|
#-- process results
|
||||||
if( $res eq 0 ){
|
if( $res eq 0 ){
|
||||||
return "$owx_dev not accessible in 2nd step";
|
return "$owx_dev not accessible in 2nd step";
|
||||||
}
|
}
|
||||||
|
OWXMULTI_BinValues($hash,"ds2438.getvad",1,undef,$owx_dev,undef,undef,substr($res,11));
|
||||||
#-- process results
|
}
|
||||||
@data=split(//,substr($res,9));
|
|
||||||
return "invalid data length, ".int(@data)." instead of 11 bytes"
|
|
||||||
if (@data != 11);
|
|
||||||
return "conversion not complete or data invalid"
|
|
||||||
if ((ord($data[2]) & 112)!=0);
|
|
||||||
return "invalid CRC"
|
|
||||||
if (OWX_CRC8(substr($res,11,8),$data[10])==0);
|
|
||||||
|
|
||||||
#-- this must be different for the different device types
|
|
||||||
# family = 26 => DS2438
|
|
||||||
#-- voltage
|
|
||||||
$lsb = ord($data[5]);
|
|
||||||
$msb = ord($data[6]) & 3;
|
|
||||||
|
|
||||||
#-- test with 7.2 V
|
|
||||||
#$lsb = 208;
|
|
||||||
#$msb = 2;
|
|
||||||
|
|
||||||
#-- external voltage
|
|
||||||
$owg_volt = ($msb*256+ $lsb)/100;
|
|
||||||
|
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -932,11 +1033,18 @@ sub OWXMULTI_SetValues($@) {
|
|||||||
# 3. \x48 sent by WriteBytePower after match ROM => command ok, no effect on EEPROM
|
# 3. \x48 sent by WriteBytePower after match ROM => command ok, no effect on EEPROM
|
||||||
|
|
||||||
my $select=sprintf("\x4E%c%c\x48",0,0);
|
my $select=sprintf("\x4E%c%c\x48",0,0);
|
||||||
|
#-- asynchronous mode
|
||||||
|
if( $hash->{ASYNC} ){
|
||||||
|
if (!OWX_Execute( $master, "setvalues", 1, $owx_dev, $select, 0, undef )) {
|
||||||
|
return "OWXMULTI: Device $owx_dev not accessible";
|
||||||
|
}
|
||||||
|
#-- synchronous mode
|
||||||
|
} else {
|
||||||
my $res=OWX_Complex($master,$owx_dev,$select,0);
|
my $res=OWX_Complex($master,$owx_dev,$select,0);
|
||||||
|
|
||||||
if( $res eq 0 ){
|
if( $res eq 0 ){
|
||||||
return "OWXMULTI: Device $owx_dev not accessible";
|
return "OWXMULTI: Device $owx_dev not accessible";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
@ -1043,7 +1151,7 @@ sub OWXMULTI_SetValues($@) {
|
|||||||
</a>
|
</a>
|
||||||
<br />temperature offset in °C added to the raw temperature reading. </li>
|
<br />temperature offset in °C added to the raw temperature reading. </li>
|
||||||
<li><a name="owmulti_tempUnit"><code>attr <name> tempUnit
|
<li><a name="owmulti_tempUnit"><code>attr <name> tempUnit
|
||||||
Celsius|Kelvin|Fahrenheit|C|K|F</code>
|
Celsius|Kelvin|Fahrenheit</code>
|
||||||
</a>
|
</a>
|
||||||
<br />unit of measurement (temperature scale), default is Celsius = °C </li>
|
<br />unit of measurement (temperature scale), default is Celsius = °C </li>
|
||||||
<li>Standard attributes <a href="#alias">alias</a>, <a href="#comment">comment</a>, <a
|
<li>Standard attributes <a href="#alias">alias</a>, <a href="#comment">comment</a>, <a
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
# FHEM module to commmunicate with 1-Wire adressable switches DS2413, DS206, DS2408
|
# FHEM module to commmunicate with 1-Wire adressable switches DS2413, DS206, DS2408
|
||||||
#
|
#
|
||||||
# Prof. Dr. Peter A. Henning
|
# Prof. Dr. Peter A. Henning
|
||||||
|
# Norbert Truchsess
|
||||||
#
|
#
|
||||||
# $Id$
|
# $Id$
|
||||||
#
|
#
|
||||||
@ -75,15 +76,11 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
sub Log($$);
|
sub Log($$);
|
||||||
|
|
||||||
my $owx_version="3.24";
|
my $owx_version="5.03";
|
||||||
#-- fixed raw channel name, flexible channel name
|
#-- fixed raw channel name, flexible channel name
|
||||||
my @owg_fixed = ("A","B","C","D","E","F","G","H");
|
my @owg_fixed = ("A","B","C","D","E","F","G","H");
|
||||||
my @owg_channel = ("A","B","C","D","E","F","G","H");
|
my @owg_channel = ("A","B","C","D","E","F","G","H");
|
||||||
|
|
||||||
#-- channel values - always the raw input resp. output values from the device
|
|
||||||
my @owg_val;
|
|
||||||
my @owg_vax;
|
|
||||||
|
|
||||||
my %gets = (
|
my %gets = (
|
||||||
"id" => "",
|
"id" => "",
|
||||||
"present" => "",
|
"present" => "",
|
||||||
@ -121,7 +118,9 @@ my %cnumber = (
|
|||||||
#
|
#
|
||||||
# OWSWITCH_Initialize
|
# OWSWITCH_Initialize
|
||||||
#
|
#
|
||||||
# Parameter hash = hash of device addressed
|
# CalledBy: FHEM
|
||||||
|
# Calling: --
|
||||||
|
# Parameter: hash = hash of device addressed
|
||||||
#
|
#
|
||||||
########################################################################################
|
########################################################################################
|
||||||
|
|
||||||
@ -133,6 +132,7 @@ sub OWSWITCH_Initialize ($) {
|
|||||||
$hash->{GetFn} = "OWSWITCH_Get";
|
$hash->{GetFn} = "OWSWITCH_Get";
|
||||||
$hash->{SetFn} = "OWSWITCH_Set";
|
$hash->{SetFn} = "OWSWITCH_Set";
|
||||||
$hash->{AttrFn} = "OWSWITCH_Attr";
|
$hash->{AttrFn} = "OWSWITCH_Attr";
|
||||||
|
|
||||||
my $attlist = "IODev do_not_notify:0,1 showtime:0,1 model:DS2413,DS2406,DS2408 loglevel:0,1,2,3,4,5 ".
|
my $attlist = "IODev do_not_notify:0,1 showtime:0,1 model:DS2413,DS2406,DS2408 loglevel:0,1,2,3,4,5 ".
|
||||||
"stateS interval ".
|
"stateS interval ".
|
||||||
$readingFnAttributes;
|
$readingFnAttributes;
|
||||||
@ -145,7 +145,13 @@ sub OWSWITCH_Initialize ($) {
|
|||||||
|
|
||||||
$hash->{AttrList} = $attlist;
|
$hash->{AttrList} = $attlist;
|
||||||
|
|
||||||
#make sure OWX is loaded so OWX_CRC is available if running with OWServer
|
#-- channel values - always the raw input resp. output values from the device
|
||||||
|
$hash->{owg_val} = [];
|
||||||
|
$hash->{owg_vax} = [];
|
||||||
|
|
||||||
|
#-- ASYNC this function is needed for asynchronous execution of the device reads
|
||||||
|
$hash->{AfterExecuteFn} = "OWXSWITCH_BinValues";
|
||||||
|
#-- make sure OWX is loaded so OWX_CRC is available if running with OWServer
|
||||||
main::LoadModule("OWX");
|
main::LoadModule("OWX");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,7 +159,9 @@ sub OWSWITCH_Initialize ($) {
|
|||||||
#
|
#
|
||||||
# OWSWITCH_Define - Implements DefFn function
|
# OWSWITCH_Define - Implements DefFn function
|
||||||
#
|
#
|
||||||
# Parameter hash = hash of device addressed, def = definition string
|
# CalledBy: FHEM
|
||||||
|
# Calling: --
|
||||||
|
# Parameter: hash = hash of device addressed, def = definition string
|
||||||
#
|
#
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
|
|
||||||
@ -182,6 +190,7 @@ sub OWSWITCH_Define ($$) {
|
|||||||
#-- no model, 12 characters
|
#-- no model, 12 characters
|
||||||
if( $a2 =~ m/^[0-9|a-f|A-F]{12}$/ ) {
|
if( $a2 =~ m/^[0-9|a-f|A-F]{12}$/ ) {
|
||||||
$model = "DS2413";
|
$model = "DS2413";
|
||||||
|
CommandAttr (undef,"$name model DS2413");
|
||||||
$fam = "3A";
|
$fam = "3A";
|
||||||
$id = $a[2];
|
$id = $a[2];
|
||||||
if(int(@a)>=4) { $interval = $a[3]; }
|
if(int(@a)>=4) { $interval = $a[3]; }
|
||||||
@ -232,6 +241,7 @@ sub OWSWITCH_Define ($$) {
|
|||||||
$hash->{OW_FAMILY} = $fam;
|
$hash->{OW_FAMILY} = $fam;
|
||||||
$hash->{PRESENT} = 0;
|
$hash->{PRESENT} = 0;
|
||||||
$hash->{INTERVAL} = $interval;
|
$hash->{INTERVAL} = $interval;
|
||||||
|
$hash->{ASYNC} = 0; #-- false for now
|
||||||
|
|
||||||
#-- Couple to I/O device
|
#-- Couple to I/O device
|
||||||
AssignIoPort($hash);
|
AssignIoPort($hash);
|
||||||
@ -241,7 +251,7 @@ sub OWSWITCH_Define ($$) {
|
|||||||
#if( $hash->{IODev}->{PRESENT} != 1 ){
|
#if( $hash->{IODev}->{PRESENT} != 1 ){
|
||||||
# return "OWSWITCH: Warning, 1-Wire I/O device ".$hash->{IODev}->{NAME}." not present for $name.";
|
# return "OWSWITCH: Warning, 1-Wire I/O device ".$hash->{IODev}->{NAME}." not present for $name.";
|
||||||
#}
|
#}
|
||||||
$modules{OWSWITCH}{defptr}{$id} = $hash;
|
$main::modules{OWSWITCH}{defptr}{$id} = $hash;
|
||||||
#--
|
#--
|
||||||
readingsSingleUpdate($hash,"state","defined",1);
|
readingsSingleUpdate($hash,"state","defined",1);
|
||||||
Log 3, "OWSWITCH: Device $name defined.";
|
Log 3, "OWSWITCH: Device $name defined.";
|
||||||
@ -256,7 +266,9 @@ sub OWSWITCH_Define ($$) {
|
|||||||
#
|
#
|
||||||
# OWSWITCH_Attr - Set one attribute value for device
|
# OWSWITCH_Attr - Set one attribute value for device
|
||||||
#
|
#
|
||||||
# Parameter hash = hash of device addressed
|
# CalledBy: FHEM
|
||||||
|
# Calling: --
|
||||||
|
# Parameter: hash = hash of device addressed
|
||||||
# a = argument array
|
# a = argument array
|
||||||
#
|
#
|
||||||
########################################################################################
|
########################################################################################
|
||||||
@ -269,10 +281,11 @@ sub OWSWITCH_Attr(@) {
|
|||||||
|
|
||||||
if ( $do eq "set") {
|
if ( $do eq "set") {
|
||||||
ARGUMENT_HANDLER: {
|
ARGUMENT_HANDLER: {
|
||||||
|
#-- interval modified at runtime
|
||||||
$key eq "interval" and do {
|
$key eq "interval" and do {
|
||||||
# check value
|
#-- check value
|
||||||
return "OWSWITCH: Set with short interval, must be > 1" if(int($value) < 1);
|
return "OWSWITCH: Set with short interval, must be > 1" if(int($value) < 1);
|
||||||
# update timer
|
#-- update timer
|
||||||
$hash->{INTERVAL} = $value;
|
$hash->{INTERVAL} = $value;
|
||||||
if ($init_done) {
|
if ($init_done) {
|
||||||
RemoveInternalTimer($hash);
|
RemoveInternalTimer($hash);
|
||||||
@ -289,7 +302,9 @@ sub OWSWITCH_Attr(@) {
|
|||||||
#
|
#
|
||||||
# OWSWITCH_ChannelNames - find the real channel names
|
# OWSWITCH_ChannelNames - find the real channel names
|
||||||
#
|
#
|
||||||
# Parameter hash = hash of device addressed
|
# CalledBy: OWSWITCH_FormatValues, OWSWITCH_Get, OWSWITCH_Set
|
||||||
|
# Calling: --
|
||||||
|
# Parameter: hash = hash of device addressed
|
||||||
#
|
#
|
||||||
########################################################################################
|
########################################################################################
|
||||||
|
|
||||||
@ -333,7 +348,9 @@ sub OWSWITCH_ChannelNames($) {
|
|||||||
#
|
#
|
||||||
# OWSWITCH_FormatValues - put together various format strings
|
# OWSWITCH_FormatValues - put together various format strings
|
||||||
#
|
#
|
||||||
# Parameter hash = hash of device addressed, fs = format string
|
# CalledBy: OWSWITCH_FormatValues, OWSWITCH_Get, OWSWITCH_Set
|
||||||
|
# Calling: --
|
||||||
|
# Parameter; hash = hash of device addressed, fs = format string
|
||||||
#
|
#
|
||||||
########################################################################################
|
########################################################################################
|
||||||
|
|
||||||
@ -357,9 +374,9 @@ sub OWSWITCH_FormatValues($) {
|
|||||||
for (my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){
|
for (my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){
|
||||||
|
|
||||||
#-- input state is 0 = ON or 1 = OFF
|
#-- input state is 0 = ON or 1 = OFF
|
||||||
$vval = $owg_val[$i];
|
$vval = $hash->{owg_val}->[$i];
|
||||||
#-- output state is 0 = ON or 1 = OFF
|
#-- output state is 0 = ON or 1 = OFF
|
||||||
$vvax = $owg_vax[$i];
|
$vvax = $hash->{owg_vax}->[$i];
|
||||||
|
|
||||||
#-- string buildup for return value and STATE
|
#-- string buildup for return value and STATE
|
||||||
@unarr= split(/\|/,$hash->{READINGS}{$owg_channel[$i]}{UNIT});
|
@unarr= split(/\|/,$hash->{READINGS}{$owg_channel[$i]}{UNIT});
|
||||||
@ -391,7 +408,11 @@ sub OWSWITCH_FormatValues($) {
|
|||||||
#
|
#
|
||||||
# OWSWITCH_Get - Implements GetFn function
|
# OWSWITCH_Get - Implements GetFn function
|
||||||
#
|
#
|
||||||
# Parameter hash = hash of device addressed, a = argument array
|
# CalledBy: FHEM
|
||||||
|
# Calling: OWSWITCH_ChannelNames,OWSWITCH_FormatValues,
|
||||||
|
# OWFSSWITCH_GetState,OWXSWITCH_GetState,
|
||||||
|
# OWX_Verify
|
||||||
|
# Parameter: hash = hash of device addressed, a = argument array
|
||||||
#
|
#
|
||||||
########################################################################################
|
########################################################################################
|
||||||
|
|
||||||
@ -465,6 +486,7 @@ sub OWSWITCH_Get($@) {
|
|||||||
#-- OWX interface
|
#-- OWX interface
|
||||||
if( $interface eq "OWX" ){
|
if( $interface eq "OWX" ){
|
||||||
$ret = OWXSWITCH_GetState($hash);
|
$ret = OWXSWITCH_GetState($hash);
|
||||||
|
#OWXSWITCH_AwaitGetState($hash);
|
||||||
#-- OWFS interface
|
#-- OWFS interface
|
||||||
}elsif( $interface eq "OWFS" ){
|
}elsif( $interface eq "OWFS" ){
|
||||||
$ret = OWFSSWITCH_GetState($hash);
|
$ret = OWFSSWITCH_GetState($hash);
|
||||||
@ -484,6 +506,7 @@ sub OWSWITCH_Get($@) {
|
|||||||
|
|
||||||
if( $interface eq "OWX" ){
|
if( $interface eq "OWX" ){
|
||||||
$ret = OWXSWITCH_GetState($hash);
|
$ret = OWXSWITCH_GetState($hash);
|
||||||
|
#OWXSWITCH_AwaitGetState($hash);
|
||||||
}elsif( $interface eq "OWServer" ){
|
}elsif( $interface eq "OWServer" ){
|
||||||
$ret = OWFSSWITCH_GetState($hash);
|
$ret = OWFSSWITCH_GetState($hash);
|
||||||
}else{
|
}else{
|
||||||
@ -531,8 +554,7 @@ sub OWSWITCH_GetValues($) {
|
|||||||
#-- max 3 tries
|
#-- max 3 tries
|
||||||
for(my $try=0; $try<3; $try++){
|
for(my $try=0; $try<3; $try++){
|
||||||
$ret = OWXSWITCH_GetState($hash);
|
$ret = OWXSWITCH_GetState($hash);
|
||||||
last
|
return if( !defined($ret) );
|
||||||
if( !defined($ret) );
|
|
||||||
}
|
}
|
||||||
}elsif( $interface eq "OWServer" ){
|
}elsif( $interface eq "OWServer" ){
|
||||||
$ret = OWFSSWITCH_GetState($hash);
|
$ret = OWFSSWITCH_GetState($hash);
|
||||||
@ -544,8 +566,8 @@ sub OWSWITCH_GetValues($) {
|
|||||||
#-- process results
|
#-- process results
|
||||||
if( defined($ret) ){
|
if( defined($ret) ){
|
||||||
for (my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){
|
for (my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){
|
||||||
$owg_val[$i] = 1;
|
$hash->{owg_val}->[$i] = 1;
|
||||||
$owg_vax[$i] = 0;
|
$hash->{owg_vax}->[$i] = 0;
|
||||||
}
|
}
|
||||||
Log 3, "OWSWITCH: Could not get values from device $name, reason $ret";
|
Log 3, "OWSWITCH: Could not get values from device $name, reason $ret";
|
||||||
return 1;
|
return 1;
|
||||||
@ -573,8 +595,8 @@ sub OWSWITCH_InitializeDevice($) {
|
|||||||
#-- Initial readings
|
#-- Initial readings
|
||||||
for( my $i=0;$i<$cnumber{$attr{$name}{"model"}} ;$i++) {
|
for( my $i=0;$i<$cnumber{$attr{$name}{"model"}} ;$i++) {
|
||||||
#-- Initial readings ERR
|
#-- Initial readings ERR
|
||||||
$owg_val[$i] = 1;
|
$hash->{owg_val}->[$i] = 1;
|
||||||
$owg_vax[$i] = 0;
|
$hash->{owg_vax}->[$i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#-- Set state to initialized
|
#-- Set state to initialized
|
||||||
@ -696,7 +718,7 @@ sub OWSWITCH_Set($@) {
|
|||||||
$value = 0;
|
$value = 0;
|
||||||
#-- vax or val ?
|
#-- vax or val ?
|
||||||
for (my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){
|
for (my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){
|
||||||
$value += ($owg_vax[$i]<<$i)
|
$value += ($hash->{owg_vax}->[$i]<<$i)
|
||||||
if( $i != $fnd );
|
if( $i != $fnd );
|
||||||
$value += ($nval<<$i)
|
$value += ($nval<<$i)
|
||||||
if( $i == $fnd );
|
if( $i == $fnd );
|
||||||
@ -708,7 +730,7 @@ sub OWSWITCH_Set($@) {
|
|||||||
$value = 0;
|
$value = 0;
|
||||||
#-- vax or val ?
|
#-- vax or val ?
|
||||||
for (my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){
|
for (my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){
|
||||||
$value += ($owg_vax[$i]<<$i)
|
$value += ($hash->{owg_vax}->[$i]<<$i)
|
||||||
if( $i != $fnd );
|
if( $i != $fnd );
|
||||||
$value += ($nval<<$i)
|
$value += ($nval<<$i)
|
||||||
if( $i == $fnd );
|
if( $i == $fnd );
|
||||||
@ -765,7 +787,7 @@ sub OWSWITCH_Set($@) {
|
|||||||
|
|
||||||
sub OWSWITCH_Undef ($) {
|
sub OWSWITCH_Undef ($) {
|
||||||
my ($hash) = @_;
|
my ($hash) = @_;
|
||||||
delete($modules{OWSWITCH}{defptr}{$hash->{OW_ID}});
|
delete($main::modules{OWSWITCH}{defptr}{$hash->{OW_ID}});
|
||||||
RemoveInternalTimer($hash);
|
RemoveInternalTimer($hash);
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
@ -815,25 +837,25 @@ sub OWFSSWITCH_GetState($) {
|
|||||||
if( $hash->{OW_FAMILY} eq "12" ) {
|
if( $hash->{OW_FAMILY} eq "12" ) {
|
||||||
#=============== get gpio values ===============================
|
#=============== get gpio values ===============================
|
||||||
for(my $i=0;$i<2;$i++){
|
for(my $i=0;$i<2;$i++){
|
||||||
$owg_val[$i] = $ral[$i];
|
$hash->{owg_val}->[$i] = $ral[$i];
|
||||||
#-- reading a zero means it is off
|
#-- reading a zero means it is off
|
||||||
$owg_vax[$i] = 1 - $rax[$i];
|
$hash->{owg_vax}->[$i] = 1 - $rax[$i];
|
||||||
}
|
}
|
||||||
#-- family = 29 => DS2408
|
#-- family = 29 => DS2408
|
||||||
}elsif( $hash->{OW_FAMILY} eq "29" ) {
|
}elsif( $hash->{OW_FAMILY} eq "29" ) {
|
||||||
#=============== get gpio values ===============================
|
#=============== get gpio values ===============================
|
||||||
for(my $i=0;$i<8;$i++){
|
for(my $i=0;$i<8;$i++){
|
||||||
$owg_val[$i] = $ral[$i];
|
$hash->{owg_val}->[$i] = $ral[$i];
|
||||||
#-- reading a zero means it is off
|
#-- reading a zero means it is off
|
||||||
$owg_vax[$i] = 1 - $rax[$i];
|
$hash->{owg_vax}->[$i] = 1 - $rax[$i];
|
||||||
}
|
}
|
||||||
#-- family = 3A => DS2413
|
#-- family = 3A => DS2413
|
||||||
}elsif( $hash->{OW_FAMILY} eq "3A" ) {
|
}elsif( $hash->{OW_FAMILY} eq "3A" ) {
|
||||||
#=============== get gpio values ===============================
|
#=============== get gpio values ===============================
|
||||||
for(my $i=0;$i<2;$i++){
|
for(my $i=0;$i<2;$i++){
|
||||||
$owg_val[$i] = $ral[$i];
|
$hash->{owg_val}->[$i] = $ral[$i];
|
||||||
#-- reading a zero means it is off
|
#-- reading a zero means it is off
|
||||||
$owg_vax[$i] = 1 - $rax[$i];
|
$hash->{owg_vax}->[$i] = 1 - $rax[$i];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return "unknown device family $hash->{OW_FAMILY}\n";
|
return "unknown device family $hash->{OW_FAMILY}\n";
|
||||||
@ -863,32 +885,32 @@ sub OWFSSWITCH_SetState($$) {
|
|||||||
if( $hash->{OW_FAMILY} eq "12" ) {
|
if( $hash->{OW_FAMILY} eq "12" ) {
|
||||||
#=============== set gpio values ===============================
|
#=============== set gpio values ===============================
|
||||||
#-- put into local buffer
|
#-- put into local buffer
|
||||||
$owg_val[0] = $value % 2;
|
$hash->{owg_val}->[0] = $value % 2;
|
||||||
$owg_vax[0] = $owg_val[0];
|
$hash->{owg_vax}->[0] = $hash->{owg_val}->[0];
|
||||||
$owg_val[1] = int($value / 2);
|
$hash->{owg_val}->[1] = int($value / 2);
|
||||||
$owg_vax[1] = $owg_val[1];
|
$hash->{owg_vax}->[1] = $hash->{owg_val}->[1];
|
||||||
|
|
||||||
#-- family = 29 => DS2408
|
#-- family = 29 => DS2408
|
||||||
}elsif( $hash->{OW_FAMILY} eq "29" ) {
|
}elsif( $hash->{OW_FAMILY} eq "29" ) {
|
||||||
#=============== set gpio values ===============================
|
#=============== set gpio values ===============================
|
||||||
for(my $i=0;$i<8;$i++){
|
for(my $i=0;$i<8;$i++){
|
||||||
$owg_val[$i] = ($value>>$i) & 1;
|
$hash->{owg_val}->[$i] = ($value>>$i) & 1;
|
||||||
$owg_vax[$i] = $owg_val[$i]
|
$hash->{owg_vax}->[$i] = $hash->{owg_val}->[$i]
|
||||||
}
|
}
|
||||||
#-- family = 3A => DS2413
|
#-- family = 3A => DS2413
|
||||||
}elsif( $hash->{OW_FAMILY} eq "3A" ) {
|
}elsif( $hash->{OW_FAMILY} eq "3A" ) {
|
||||||
#=============== set gpio values ===============================
|
#=============== set gpio values ===============================
|
||||||
$owg_val[0] = $value % 2;
|
$hash->{owg_val}->[0] = $value % 2;
|
||||||
$owg_vax[0] = $owg_val[0];
|
$hash->{owg_vax}->[0] = $hash->{owg_val}->[0];
|
||||||
$owg_val[1] = int($value / 2);
|
$hash->{owg_val}->[1] = int($value / 2);
|
||||||
$owg_vax[1] = $owg_val[1];
|
$hash->{owg_vax}->[1] = $hash->{owg_val}->[1];
|
||||||
} else {
|
} else {
|
||||||
return "unknown device family $hash->{OW_FAMILY}\n";
|
return "unknown device family $hash->{OW_FAMILY}\n";
|
||||||
}
|
}
|
||||||
#-- writing a zero will switch output transistor off
|
#-- writing a zero will switch output transistor off
|
||||||
my @res;
|
my @res;
|
||||||
for(my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){
|
for(my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){
|
||||||
$res[$i]=1-$owg_val[$i];
|
$res[$i]=1-$hash->{owg_val}->[$i];
|
||||||
}
|
}
|
||||||
OWServer_Write($master, "/$owx_add/PIO.ALL", join(',',@res));
|
OWServer_Write($master, "/$owx_add/PIO.ALL", join(',',@res));
|
||||||
return undef
|
return undef
|
||||||
@ -901,6 +923,170 @@ sub OWFSSWITCH_SetState($$) {
|
|||||||
#
|
#
|
||||||
# Prefix = OWXSWITCH
|
# Prefix = OWXSWITCH
|
||||||
#
|
#
|
||||||
|
########################################################################################
|
||||||
|
#
|
||||||
|
# OWXSWITCH_BinValues - Binary readings into clear values
|
||||||
|
#
|
||||||
|
# Parameter hash = hash of device addressed
|
||||||
|
#
|
||||||
|
########################################################################################
|
||||||
|
|
||||||
|
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";
|
||||||
|
|
||||||
|
my @data=[];
|
||||||
|
my $value;
|
||||||
|
#-- hash of the busmaster
|
||||||
|
my $master = $hash->{IODev};
|
||||||
|
|
||||||
|
#-- 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.*/ ){
|
||||||
|
#-- family = 12 => DS2406 -------------------------------------------------------
|
||||||
|
if( ($context eq "getstate.ds2406") or ($context eq "ds2406.getstate") ) {
|
||||||
|
@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;
|
||||||
|
|
||||||
|
#-- family = 29 => DS2408 -------------------------------------------------------
|
||||||
|
}elsif( ($context eq "getstate.ds2408") or ($context eq "ds2408.getstate") ) {
|
||||||
|
@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;
|
||||||
|
};
|
||||||
|
|
||||||
|
#-- family = 3A => DS2413 -------------------------------------------------------
|
||||||
|
}elsif( ($context eq "getstate.ds2413") or ($context eq "ds2413.getstate") ){
|
||||||
|
@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;
|
||||||
|
#--
|
||||||
|
}else{
|
||||||
|
return "unknown device family $hash->{OW_FAMILY} in OWXSWITCH_BinValues getstate\n";
|
||||||
|
};
|
||||||
|
#-- Now for context setstate
|
||||||
|
}elsif ( $context =~ /.*setstate.*/){
|
||||||
|
#-- family = 12 => DS2406 -------------------------------------------------------
|
||||||
|
#-- first step
|
||||||
|
if( ($context =~ /setstate\.ds2406\.1\..*/) or ($context =~ /ds2406\.setstate\.1\..*/) ) {
|
||||||
|
$value = substr($context,-1);
|
||||||
|
my $stat = ord(substr($res,0,1));
|
||||||
|
my $statneu = ( $stat & 159 ) | (($value<<5) & 96) ;
|
||||||
|
#-- call the second step
|
||||||
|
#-- issue the match ROM command \x55 and the write status command
|
||||||
|
# \x55 at address TA1 = \x07 TA2 = \x00
|
||||||
|
#-- reading 9 + 4 + 2 data bytes = 15 bytes
|
||||||
|
my $select=sprintf("\x55\x07\x00%c",$statneu);
|
||||||
|
#-- asynchronous mode
|
||||||
|
if( $hash->{ASYNC} ){
|
||||||
|
if (OWX_Execute( $master, "setstateds2406.2.".$value, 1, $owx_dev, $select, 2, undef )) {
|
||||||
|
OWX_Reset($master);
|
||||||
|
return undef;
|
||||||
|
} else {
|
||||||
|
return "device $owx_dev not accessible in writing";
|
||||||
|
}
|
||||||
|
#-- synchronous mode
|
||||||
|
}else{
|
||||||
|
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.2.".$value,1,undef,$owx_dev,$select,undef,substr($res,13));
|
||||||
|
}
|
||||||
|
#-- family = 12 => DS2406 -------------------------------------------------------
|
||||||
|
#-- second step from above
|
||||||
|
}elsif( ($context =~ /setstate\.ds2406\.2\..*/) or ($context =~ /ds2406\.setstate\.2\..*/) ) {
|
||||||
|
$value = substr($context,-1);
|
||||||
|
@data=split(//,$res);
|
||||||
|
if( int(@data) != 2){
|
||||||
|
return "state could not be set for device $owx_dev";
|
||||||
|
}
|
||||||
|
Log 1,"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);
|
||||||
|
|
||||||
|
#-- 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");
|
||||||
|
#-- family = 3A => DS2413 -------------------------------------------------------
|
||||||
|
}elsif( ($context eq "setstate.ds2413") or ($context eq "ds2413.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");
|
||||||
|
#--
|
||||||
|
}else{
|
||||||
|
return "unknown device family $hash->{OW_FAMILY} in OWXSWITCH_BinValues setstate\n";
|
||||||
|
};
|
||||||
|
}else{
|
||||||
|
return "unknown context in OWXSWITCH_BinValues";
|
||||||
|
}
|
||||||
|
|
||||||
|
#-- put into real readings
|
||||||
|
my $value = OWSWITCH_FormatValues($hash);
|
||||||
|
Log 5, $value;
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub OWXSWITCH_AwaitGetState($) {
|
||||||
|
my ($hash) = @_;
|
||||||
|
|
||||||
|
#-- ID of the device, hash of the busmaster
|
||||||
|
my $owx_dev = $hash->{ROM_ID};
|
||||||
|
my $master = $hash->{IODev};
|
||||||
|
my $family = $hash->{OW_FAMILY};
|
||||||
|
|
||||||
|
if ($master and $owx_dev) {
|
||||||
|
#-- family = 12 => DS2406
|
||||||
|
if( $family eq "12" ) {
|
||||||
|
return OWX_AwaitExecuteResponse( $master, "getstateds2406", $owx_dev );
|
||||||
|
#-- family = 29 => DS2408
|
||||||
|
} elsif( $family eq "29" ) {
|
||||||
|
return OWX_AwaitExecuteResponse( $master, "getstateds2408", $owx_dev );
|
||||||
|
#-- family = 3A => DS2413
|
||||||
|
} elsif( $family eq "3A" ) {
|
||||||
|
return OWX_AwaitExecuteResponse( $master, "getstateds2413", $owx_dev );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
########################################################################################
|
########################################################################################
|
||||||
#
|
#
|
||||||
# OWXSWITCH_GetState - Get gpio ports from device
|
# OWXSWITCH_GetState - Get gpio ports from device
|
||||||
@ -929,31 +1115,26 @@ sub OWXSWITCH_GetState($) {
|
|||||||
#=============== get gpio values ===============================
|
#=============== get gpio values ===============================
|
||||||
#-- issue the match ROM command \x55 and the access channel command
|
#-- issue the match ROM command \x55 and the access channel command
|
||||||
# \xF5 plus the two byte channel control and the value
|
# \xF5 plus the two byte channel control and the value
|
||||||
#-- reading 9 + 3 + 1 data bytes + 2 CRC bytes = 15 bytes
|
#-- reading 9 + 3 + 2 data bytes + 2 CRC bytes = 16 bytes
|
||||||
$select=sprintf("\xF5\xDD\xFF");
|
$select=sprintf("\xF5\xDD\xFF");
|
||||||
#-- reset the bus
|
#-- asynchronous mode
|
||||||
|
if( $hash->{ASYNC} ){
|
||||||
|
if (OWX_Execute( $master, "getstateds2406", 1, $owx_dev, $select, 4, undef )) {
|
||||||
|
OWX_Reset($master);
|
||||||
|
return undef;
|
||||||
|
} else {
|
||||||
|
return "not accessible in reading";
|
||||||
|
}
|
||||||
|
#-- synchronous mode
|
||||||
|
}else{
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
#-- read the data
|
|
||||||
$res=OWX_Complex($master,$owx_dev,$select,4);
|
$res=OWX_Complex($master,$owx_dev,$select,4);
|
||||||
if( $res eq 0 ){
|
if( $res eq 0 ){
|
||||||
return "not accessible in reading";
|
return "not accessible in reading";
|
||||||
}
|
}
|
||||||
|
|
||||||
#-- reset the bus
|
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
|
OWXSWITCH_BinValues($hash,"ds2406.getstate",1,undef,$owx_dev,substr($res,9,3),undef,substr($res,12));
|
||||||
#-- process results
|
}
|
||||||
@data=split(//,substr($res,9));
|
|
||||||
return "invalid data length, ".int(@data)." instead of 7 bytes"
|
|
||||||
if (@data != 7);
|
|
||||||
return "invalid CRC"
|
|
||||||
if ( OWX_CRC16(substr($res,9,5),$data[5],$data[6]) == 0);
|
|
||||||
|
|
||||||
$owg_val[0] = (ord($data[3])>>2) & 1;
|
|
||||||
$owg_vax[0] = ord($data[3]) & 1;
|
|
||||||
$owg_val[1] = (ord($data[3])>>3) & 1;
|
|
||||||
$owg_vax[1] = (ord($data[3])>>1) & 1;
|
|
||||||
|
|
||||||
#-- family = 29 => DS2408
|
#-- family = 29 => DS2408
|
||||||
}elsif( $hash->{OW_FAMILY} eq "29" ) {
|
}elsif( $hash->{OW_FAMILY} eq "29" ) {
|
||||||
#=============== get gpio values ===============================
|
#=============== get gpio values ===============================
|
||||||
@ -961,64 +1142,51 @@ sub OWXSWITCH_GetState($) {
|
|||||||
# \xF5 plus the two byte channel target address
|
# \xF5 plus the two byte channel target address
|
||||||
#-- reading 9 + 3 + 8 data bytes + 2 CRC bytes = 22 bytes
|
#-- reading 9 + 3 + 8 data bytes + 2 CRC bytes = 22 bytes
|
||||||
$select=sprintf("\xF0\x88\x00");
|
$select=sprintf("\xF0\x88\x00");
|
||||||
#-- reset the bus
|
#-- asynchronous mode
|
||||||
|
if( $hash->{ASYNC} ){
|
||||||
|
if (OWX_Execute( $master, "getstateds2408", 1, $owx_dev, $select, 10, undef )) {
|
||||||
|
OWX_Reset($master);
|
||||||
|
return undef;
|
||||||
|
} else {
|
||||||
|
return "not accessible in reading";
|
||||||
|
}
|
||||||
|
#-- synchronous mode
|
||||||
|
}else{
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
#-- read the data
|
|
||||||
$res=OWX_Complex($master,$owx_dev,$select,10);
|
$res=OWX_Complex($master,$owx_dev,$select,10);
|
||||||
if( $res eq 0 ){
|
if( $res eq 0 ){
|
||||||
return "not accessible in reading";
|
return "not accessible in reading";
|
||||||
}
|
}
|
||||||
|
|
||||||
#-- reset the bus
|
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
|
return OWXSWITCH_BinValues($hash,"ds2408.getstate",1,undef,$owx_dev,substr($res,9,3),undef,substr($res,12));
|
||||||
#-- process results
|
|
||||||
@data=split(//,substr($res,9));
|
|
||||||
return "invalid data length, ".int(@data)." instead of 13 bytes"
|
|
||||||
if (@data != 13);
|
|
||||||
return "invalid data"
|
|
||||||
if (ord($data[9])!=255);
|
|
||||||
return "invalid CRC"
|
|
||||||
if( OWX_CRC16(substr($res,9,11),$data[11],$data[12]) == 0);
|
|
||||||
for(my $i=0;$i<8;$i++){
|
|
||||||
$owg_val[$i] = (ord($data[3])>>$i) & 1;
|
|
||||||
$owg_vax[$i] = (ord($data[4])>>$i) & 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#-- family = 3A => DS2413
|
#-- family = 3A => DS2413
|
||||||
}elsif( $hash->{OW_FAMILY} eq "3A" ) {
|
}elsif( $hash->{OW_FAMILY} eq "3A" ) {
|
||||||
#=============== get gpio values ===============================
|
#=============== get gpio values ===============================
|
||||||
#-- issue the match ROM command \x55 and the read gpio command
|
#-- issue the match ROM command \x55 and the read gpio command
|
||||||
# \xF5 plus 2 empty bytes
|
# \xF5 plus 2 empty bytes
|
||||||
#-- reset the bus
|
#-- reading 9 + 1 + 2 data bytes = 12 bytes
|
||||||
|
#-- asynchronous mode
|
||||||
|
if( $hash->{ASYNC} ){
|
||||||
|
if (OWX_Execute( $master, "getstateds2413", 1, $owx_dev, "\xF5", 2, undef )) {
|
||||||
|
OWX_Reset($master);
|
||||||
|
return undef;
|
||||||
|
} else {
|
||||||
|
return "not accessible in reading";
|
||||||
|
}
|
||||||
|
#-- synchronous mode
|
||||||
|
}else{
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
#-- read the data
|
|
||||||
$res=OWX_Complex($master,$owx_dev,"\xF5",2);
|
$res=OWX_Complex($master,$owx_dev,"\xF5",2);
|
||||||
if( $res eq 0 ){
|
if( $res eq 0 ){
|
||||||
return "not accessible in reading";
|
return "not accessible in reading";
|
||||||
}
|
}
|
||||||
|
|
||||||
#-- reset the bus
|
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
|
return OWXSWITCH_BinValues($hash,"ds2413.getstate",1,undef,$owx_dev,substr($res,9,1),undef,substr($res,10));
|
||||||
#-- process results
|
}
|
||||||
@data=split(//,substr($res,9));
|
|
||||||
return "invalid data length, ".int(@data)." instead of 3 bytes"
|
|
||||||
if (@data != 3);
|
|
||||||
return "invalid data"
|
|
||||||
if ( (15- (ord($data[1])>>4)) != (ord($data[1]) & 15) );
|
|
||||||
|
|
||||||
# note: value 1 corresponds to OFF, 0 to ON normally
|
|
||||||
# note: val = input value, vax = output value
|
|
||||||
$owg_val[0] = ord($data[1]) & 1;
|
|
||||||
$owg_vax[0] = (ord($data[1])>>1) & 1;
|
|
||||||
$owg_val[1] = (ord($data[1])>>2) & 1;
|
|
||||||
$owg_vax[1] = (ord($data[1])>>3) & 1;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return "unknown device family $hash->{OW_FAMILY}\n";
|
return "unknown device family $hash->{OW_FAMILY}\n";
|
||||||
}
|
}
|
||||||
return undef
|
|
||||||
}
|
}
|
||||||
|
|
||||||
########################################################################################
|
########################################################################################
|
||||||
@ -1047,7 +1215,6 @@ sub OWXSWITCH_SetState($$) {
|
|||||||
|
|
||||||
my ($i,$j,$k);
|
my ($i,$j,$k);
|
||||||
|
|
||||||
|
|
||||||
#-- family = 12 => DS2406
|
#-- family = 12 => DS2406
|
||||||
if( $hash->{OW_FAMILY} eq "12" ) {
|
if( $hash->{OW_FAMILY} eq "12" ) {
|
||||||
#=============== set gpio values ===============================
|
#=============== set gpio values ===============================
|
||||||
@ -1056,92 +1223,75 @@ sub OWXSWITCH_SetState($$) {
|
|||||||
#-- issue the match ROM command \x55 and the read status command
|
#-- issue the match ROM command \x55 and the read status command
|
||||||
# \xAA at address TA1 = \x07 TA2 = \x00
|
# \xAA at address TA1 = \x07 TA2 = \x00
|
||||||
#-- reading 9 + 3 + 1 data bytes + 2 CRC bytes = 15 bytes
|
#-- reading 9 + 3 + 1 data bytes + 2 CRC bytes = 15 bytes
|
||||||
#-- reset the bus
|
#-- asynchronous mode
|
||||||
|
if( $hash->{ASYNC} ){
|
||||||
|
if (OWX_Execute( $master, "setstateds2406.1.".$value, 1, $owx_dev, "\xAA\x07\x00", 3, undef )) {
|
||||||
|
return undef;
|
||||||
|
} else {
|
||||||
|
return "not accessible in writing";
|
||||||
|
}
|
||||||
|
#-- synchronous mode
|
||||||
|
}else{
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
#-- read the data
|
|
||||||
$res = OWX_Complex($master,$owx_dev,"\xAA\x07\x00",3);
|
$res = OWX_Complex($master,$owx_dev,"\xAA\x07\x00",3);
|
||||||
my $stat = ord(substr($res,10,1));
|
|
||||||
my $statneu = ( $stat & 159 ) | (($value<<5) & 96) ;
|
|
||||||
#-- issue the match ROM command \x55 and the write status command
|
|
||||||
# \x55 at address TA1 = \x07 TA2 = \x00
|
|
||||||
#
|
|
||||||
$select=sprintf("\x55\x07\x00%c",$statneu);
|
|
||||||
#-- reset the bus
|
|
||||||
OWX_Reset($master);
|
|
||||||
#-- read the data
|
|
||||||
$res=OWX_Complex($master,$owx_dev,$select,2);
|
|
||||||
if( $res eq 0 ){
|
if( $res eq 0 ){
|
||||||
return "device $owx_dev not accessible in writing";
|
return "device $owx_dev not accessible in writing";
|
||||||
}
|
}
|
||||||
#-- reset the bus
|
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
|
return OWXSWITCH_BinValues($hash,"ds2406.setstate.1.".$value,1,undef,$owx_dev,undef,undef,substr($res,12));
|
||||||
#-- process results
|
|
||||||
@data=split(//,substr($res,9));
|
|
||||||
|
|
||||||
#-- very crude check - should be CRC
|
|
||||||
if( int(@data) != 6){
|
|
||||||
return "state could not be set for device $owx_dev";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#-- put into local buffer
|
|
||||||
$owg_val[0] = $value % 2;
|
|
||||||
$owg_vax[0] = $owg_val[0];
|
|
||||||
$owg_val[1] = int($value / 2);
|
|
||||||
$owg_vax[1] = $owg_val[1];
|
|
||||||
|
|
||||||
#-- family = 29 => DS2408
|
#-- family = 29 => DS2408
|
||||||
}elsif( $hash->{OW_FAMILY} eq "29" ) {
|
} elsif( $hash->{OW_FAMILY} eq "29" ) {
|
||||||
#=============== set gpio values ===============================
|
#=============== set gpio values ===============================
|
||||||
#-- issue the match ROM command \x55 and the write gpio command
|
#-- issue the match ROM command \x55 and the write gpio command
|
||||||
# \x5A plus the value byte and its complement
|
# \x5A plus the value byte and its complement
|
||||||
$select=sprintf("\x5A%c%c",$value,255-$value);
|
$select=sprintf("\x5A%c%c",$value,255-$value);
|
||||||
#-- reset the bus
|
#-- asynchronous mode
|
||||||
|
if( $hash->{ASYNC} ){
|
||||||
|
if (OWX_Execute( $master, "setstateds2408", 1, $owx_dev, $select, 1, undef )) {
|
||||||
|
OWX_Reset($master);
|
||||||
|
return undef;
|
||||||
|
} else {
|
||||||
|
return "device $owx_dev not accessible in writing";
|
||||||
|
}
|
||||||
|
#-- synchronous mode
|
||||||
|
}else{
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
#-- read the data
|
|
||||||
$res=OWX_Complex($master,$owx_dev,$select,1);
|
$res=OWX_Complex($master,$owx_dev,$select,1);
|
||||||
if( $res eq 0 ){
|
if( $res eq 0 ){
|
||||||
return "device $owx_dev not accessible in writing";
|
return "device $owx_dev not accessible in writing";
|
||||||
}
|
}
|
||||||
|
|
||||||
#-- process results
|
|
||||||
@data=split(//,substr($res,10));
|
|
||||||
|
|
||||||
if( $data[2] ne "\xAA"){
|
|
||||||
return "state could not be set for device $owx_dev";
|
|
||||||
}
|
|
||||||
#-- reset the bus
|
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
|
return OWXSWITCH_BinValues($hash,"ds2408.setstate",1,undef,$owx_dev,undef,undef,substr($res,12));
|
||||||
|
}
|
||||||
#-- family = 3A => DS2413
|
#-- family = 3A => DS2413
|
||||||
}elsif( $hash->{OW_FAMILY} eq "3A" ) {
|
} elsif( $hash->{OW_FAMILY} eq "3A" ) {
|
||||||
#=============== set gpio values ===============================
|
#=============== set gpio values ===============================
|
||||||
#-- issue the match ROM command \x55 and the write gpio command
|
#-- issue the match ROM command \x55 and the write gpio command
|
||||||
# \x5A plus the value byte and its complement
|
# \x5A plus the value byte and its complement
|
||||||
$select=sprintf("\x5A%c%c",252+$value,3-$value);
|
$select=sprintf("\x5A%c%c",252+$value,3-$value);
|
||||||
#-- reset the bus
|
#-- asynchronous mode
|
||||||
|
if( $hash->{ASYNC} ){
|
||||||
|
if (OWX_Execute( $master, "setstateds2413", 1, $owx_dev, $select, 1, undef )) {
|
||||||
|
OWX_Reset($master);
|
||||||
|
return undef;
|
||||||
|
} else {
|
||||||
|
return "device $owx_dev not accessible in writing";
|
||||||
|
}
|
||||||
|
#-- synchronous mode
|
||||||
|
}else{
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
#-- read the data
|
|
||||||
$res=OWX_Complex($master,$owx_dev,$select,1);
|
$res=OWX_Complex($master,$owx_dev,$select,1);
|
||||||
if( $res eq 0 ){
|
if( $res eq 0 ){
|
||||||
return "device $owx_dev not accessible in writing";
|
return "device $owx_dev not accessible in writing";
|
||||||
}
|
}
|
||||||
#-- reset the bus
|
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
|
return OWXSWITCH_BinValues($hash,"ds2413.setstate",1,undef,$owx_dev,undef,undef,substr($res,12));
|
||||||
#-- process results
|
|
||||||
@data=split(//,substr($res,10));
|
|
||||||
|
|
||||||
if( $data[2] ne "\xAA"){
|
|
||||||
return "state could not be set for device $owx_dev";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}else {
|
}else {
|
||||||
return "unknown device family $hash->{OW_FAMILY}\n";
|
return "unknown device family $hash->{OW_FAMILY}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return undef;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
@ -4,7 +4,8 @@
|
|||||||
#
|
#
|
||||||
# FHEM module to commmunicate with 1-Wire temperature sensors DS1820, DS18S20, DS18B20, DS1822
|
# FHEM module to commmunicate with 1-Wire temperature sensors DS1820, DS18S20, DS18B20, DS1822
|
||||||
#
|
#
|
||||||
# Prof. Dr. Peter A. Henning und Norbert Truchsess
|
# Prof. Dr. Peter A. Henning
|
||||||
|
# Norbert Truchsess
|
||||||
#
|
#
|
||||||
# $Id$
|
# $Id$
|
||||||
#
|
#
|
||||||
@ -16,9 +17,8 @@
|
|||||||
#
|
#
|
||||||
# where <name> may be replaced by any name string
|
# where <name> may be replaced by any name string
|
||||||
#
|
#
|
||||||
# <model> is a 1-Wire device type. If omitted, we assume this to be an
|
# <model> is a 1-Wire device type. If omitted AND no FAM_ID given we assume this to be an
|
||||||
# DS1820 temperature sensor
|
# DS1820 temperature sensor. Currently allowed values are DS1820, DS18B20, DS1822
|
||||||
# Currently allowed values are DS1820, DS18B20, DS1822
|
|
||||||
# <FAM_ID> is a 1-Wire family id, currently allowed values are 10, 22, 28
|
# <FAM_ID> is a 1-Wire family id, currently allowed values are 10, 22, 28
|
||||||
# <ROM_ID> is a 12 character (6 byte) 1-Wire ROM ID
|
# <ROM_ID> is a 12 character (6 byte) 1-Wire ROM ID
|
||||||
# without Family ID, e.g. A2D90D000800
|
# without Family ID, e.g. A2D90D000800
|
||||||
@ -75,7 +75,7 @@ use warnings;
|
|||||||
sub Log($$);
|
sub Log($$);
|
||||||
sub AttrVal($$$);
|
sub AttrVal($$$);
|
||||||
|
|
||||||
my $owx_version="5.02";
|
my $owx_version="5.03";
|
||||||
|
|
||||||
my %gets = (
|
my %gets = (
|
||||||
"id" => "",
|
"id" => "",
|
||||||
@ -98,6 +98,7 @@ my %updates = (
|
|||||||
"alarm" => ""
|
"alarm" => ""
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#-- conversion times in milliseconds depend on resolution
|
||||||
my %convtimes = (
|
my %convtimes = (
|
||||||
9 => 100,
|
9 => 100,
|
||||||
10 => 200,
|
10 => 200,
|
||||||
@ -134,7 +135,7 @@ sub OWTHERM_Initialize ($) {
|
|||||||
"resolution:9,10,11,12 interval ".
|
"resolution:9,10,11,12 interval ".
|
||||||
$readingFnAttributes;
|
$readingFnAttributes;
|
||||||
#-- ASYNC this function is needed for asynchronous execution of the device reads
|
#-- ASYNC this function is needed for asynchronous execution of the device reads
|
||||||
$hash->{AfterExecuteFn} = "OWXTHERM_ProcValues";
|
$hash->{AfterExecuteFn} = "OWXTHERM_BinValues";
|
||||||
#-- make sure OWX is loaded so OWX_CRC is available if running with OWServer
|
#-- make sure OWX is loaded so OWX_CRC is available if running with OWServer
|
||||||
main::LoadModule("OWX");
|
main::LoadModule("OWX");
|
||||||
}
|
}
|
||||||
@ -818,75 +819,20 @@ sub OWFSTHERM_SetValues($$) {
|
|||||||
#
|
#
|
||||||
########################################################################################
|
########################################################################################
|
||||||
#
|
#
|
||||||
# OWXTHERM_GetValues - Trigger reading from one device
|
# OWXTHERM_BinValues - Binary readings into clear values
|
||||||
#
|
#
|
||||||
# Parameter hash = hash of device addressed
|
# Parameter hash = hash of device addressed
|
||||||
#
|
#
|
||||||
########################################################################################
|
########################################################################################
|
||||||
|
|
||||||
sub OWXTHERM_GetValues($) {
|
sub OWXTHERM_BinValues($$$$$$$$) {
|
||||||
|
my ($hash, $context, $success, $reset, $owx_dev, $command, $numread, $res) = @_;
|
||||||
|
|
||||||
my ($hash) = @_;
|
#-- always check for success, unused are reset, numread
|
||||||
|
return unless ($success and ($context =~ /.*reading.*/));
|
||||||
|
|
||||||
my ($i,$j,$k,@data,$ow_thn,$ow_tln);
|
#Log 1,"OWXTHERM_BinValues context = $context";
|
||||||
my $change = 0;
|
|
||||||
|
|
||||||
#-- For default, perform the conversion now
|
|
||||||
my $con=1;
|
|
||||||
|
|
||||||
#-- ID of the device
|
|
||||||
my $owx_dev = $hash->{ROM_ID};
|
|
||||||
#-- hash of the busmaster
|
|
||||||
my $master = $hash->{IODev};
|
|
||||||
my $name = $hash->{NAME};
|
|
||||||
|
|
||||||
#-- 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
|
|
||||||
if( $con==1 ){
|
|
||||||
#-- issue the match ROM command \x55 and the start conversion command \x44
|
|
||||||
#-- asynchronous mode
|
|
||||||
if( $hash->{ASYNC} ){
|
|
||||||
OWX_Execute($master,"convert",1,$owx_dev,"\x44",0,$convtimes{AttrVal($name,"resolution",12)});
|
|
||||||
#-- synchronous mode
|
|
||||||
}else{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#-- 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
|
|
||||||
#-- asynchronous mode
|
|
||||||
if( $hash->{ASYNC} ){
|
|
||||||
OWX_Execute($master,"read",1,$owx_dev,"\xBE",9,undef);
|
|
||||||
#-- synchronous mode
|
|
||||||
} else {
|
|
||||||
OWX_Reset($master);
|
|
||||||
my $res=OWX_Complex($master,$owx_dev,"\xBE",9);
|
|
||||||
OWXTHERM_ProcValues($hash,"read",undef,undef,$owx_dev,undef,undef,substr($res,10,9));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
########################################################################################
|
|
||||||
#
|
|
||||||
# OWXTHERM_ProcValues - Process reading from one device - translate binary into raw
|
|
||||||
#
|
|
||||||
# Parameter hash = hash of device addressed
|
|
||||||
#
|
|
||||||
########################################################################################
|
|
||||||
|
|
||||||
sub OWXTHERM_ProcValues($$$$$$$$) {
|
|
||||||
my ($hash, $context, $success, $reset, $owx_dev, $data, $numread, $res) = @_;
|
|
||||||
|
|
||||||
return undef unless (defined $context and $context eq "read");
|
|
||||||
my ($i,$j,$k,@data,$ow_thn,$ow_tln);
|
my ($i,$j,$k,@data,$ow_thn,$ow_tln);
|
||||||
my $change = 0;
|
my $change = 0;
|
||||||
|
|
||||||
@ -963,6 +909,65 @@ sub OWXTHERM_ProcValues($$$$$$$$) {
|
|||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
########################################################################################
|
||||||
|
#
|
||||||
|
# OWXTHERM_GetValues - Trigger reading from one device
|
||||||
|
#
|
||||||
|
# Parameter hash = hash of device addressed
|
||||||
|
#
|
||||||
|
########################################################################################
|
||||||
|
|
||||||
|
sub OWXTHERM_GetValues($) {
|
||||||
|
|
||||||
|
my ($hash) = @_;
|
||||||
|
|
||||||
|
#-- For default, perform the conversion now
|
||||||
|
my $con=1;
|
||||||
|
|
||||||
|
#-- ID of the device
|
||||||
|
my $owx_dev = $hash->{ROM_ID};
|
||||||
|
#-- hash of the busmaster
|
||||||
|
my $master = $hash->{IODev};
|
||||||
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
|
#-- 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
|
||||||
|
if( $con==1 ){
|
||||||
|
#-- issue the match ROM command \x55 and the start conversion command \x44
|
||||||
|
#-- asynchronous mode
|
||||||
|
if( $hash->{ASYNC} ){
|
||||||
|
OWX_Execute($master,"ds182x.convert",1,$owx_dev,"\x44",0,$convtimes{AttrVal($name,"resolution",12)});
|
||||||
|
#-- synchronous mode
|
||||||
|
}else{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#-- 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
|
||||||
|
#-- asynchronous mode
|
||||||
|
if( $hash->{ASYNC} ){
|
||||||
|
OWX_Execute($master,"read",1,$owx_dev,"\xBE",9,undef);
|
||||||
|
#-- synchronous mode
|
||||||
|
} else {
|
||||||
|
OWX_Reset($master);
|
||||||
|
my $res=OWX_Complex($master,$owx_dev,"\xBE",9);
|
||||||
|
if( $res eq 0 ){
|
||||||
|
return "$owx_dev not accessible in reading";
|
||||||
|
}
|
||||||
|
OWXTHERM_BinValues($hash,"ds182x.reading",1,undef,$owx_dev,undef,undef,substr($res,10,9));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#######################################################################################
|
#######################################################################################
|
||||||
#
|
#
|
||||||
# OWXTHERM_SetValues - Implements SetFn function
|
# OWXTHERM_SetValues - Implements SetFn function
|
||||||
|
Loading…
x
Reference in New Issue
Block a user