mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-03 16:56:54 +00:00
git-svn-id: https://svn.fhem.de/fhem/trunk@1814 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
aa3445fe82
commit
c0aa71ae70
@ -9,7 +9,7 @@
|
||||
# Internally these interfaces are vastly different, read the corresponding Wiki pages
|
||||
# http://fhemwiki.de/wiki/Interfaces_f%C3%BCr_1-Wire
|
||||
#
|
||||
# Version 2.15 - July, 2012
|
||||
# Version 2.17 - August, 2012
|
||||
#
|
||||
# Prof. Dr. Peter A. Henning, 2012
|
||||
#
|
||||
@ -57,9 +57,10 @@ package main;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Device::SerialPort;
|
||||
|
||||
# Prototypes to make komodo happy
|
||||
use vars qw{%attr %defs};
|
||||
|
||||
require "$attr{global}{modpath}/FHEM/DevIo.pm";
|
||||
|
||||
sub Log($$);
|
||||
|
||||
# Line counter
|
||||
@ -129,6 +130,105 @@ sub OWX_Initialize ($) {
|
||||
$hash->{AttrList}= "loglevel:0,1,2,3,4,5,6 buspower:real,parasitic";
|
||||
}
|
||||
|
||||
########################################################################################
|
||||
#
|
||||
# OWX_Define - Implements DefFn function
|
||||
#
|
||||
# Parameter hash = hash of device addressed, def = definition string
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub OWX_Define ($$) {
|
||||
my ($hash, $def) = @_;
|
||||
my @a = split("[ \t][ \t]*", $def);
|
||||
|
||||
#-- check syntax
|
||||
if(int(@a) < 3){
|
||||
return "OWX: Syntax error - must be define <name> OWX"
|
||||
}
|
||||
|
||||
#-- check syntax
|
||||
Log 1,"OWX: Warning - Some parameter(s) ignored, must be define <name> OWX <serial-device>|<cuno-device>"
|
||||
if(int(@a) > 3);
|
||||
#-- If this line contains 3 parameters, it is the bus master definition
|
||||
my $dev = $a[2];
|
||||
|
||||
#-- TODO: what should we do when the specified device name contains @ already ?
|
||||
$hash->{DeviceName} = $dev."\@9600";
|
||||
#-- Dummy 1-Wire ROM identifier
|
||||
$hash->{ROM_ID} = "FF";
|
||||
|
||||
#-- First step: check if we have a directly connected serial interface or a CUNO attached
|
||||
# (mod suggested by T.Faust)
|
||||
if ( $dev =~ m/\/dev\/.*/ ){
|
||||
#-- Second step in case of serial device: open the serial device to test it
|
||||
my $msg = "OWX: Serial device $dev";
|
||||
my $ret = DevIo_OpenDev($hash,0,undef);
|
||||
$owx_hwdevice = $hash->{USBDev};
|
||||
if($ret){
|
||||
Log 1, $msg." not defined";
|
||||
return "OWX: Can't open serial device $dev: $!"
|
||||
} else {
|
||||
Log 1,$msg." defined";
|
||||
}
|
||||
$owx_hwdevice->reset_error();
|
||||
$owx_hwdevice->baudrate(9600);
|
||||
$owx_hwdevice->databits(8);
|
||||
$owx_hwdevice->parity('none');
|
||||
$owx_hwdevice->stopbits(1);
|
||||
$owx_hwdevice->handshake('none');
|
||||
$owx_hwdevice->write_settings;
|
||||
#-- store with OWX device
|
||||
$hash->{INTERFACE} = "serial";
|
||||
$hash->{HWDEVICE} = $owx_hwdevice;
|
||||
|
||||
#-- sleeping for some time
|
||||
select(undef,undef,undef,0.1);
|
||||
|
||||
} else {
|
||||
#-- Second step in case of CUNO: See if we can open it
|
||||
my $msg = "OWX: CUNO device $dev";
|
||||
$owx_hwdevice = $main::defs{$dev};
|
||||
if($owx_hwdevice){
|
||||
Log 1,$msg." defined";
|
||||
#-- store with OWX device
|
||||
$hash->{INTERFACE} = "CUNO";
|
||||
$hash->{HWDEVICE} = $owx_hwdevice;
|
||||
#-- reset the 1-Wire system in CUNO
|
||||
CUL_SimpleWrite($owx_hwdevice, "Oi");
|
||||
}else{
|
||||
Log 1, $msg." not defined";
|
||||
return "OWX: Can't open cuno device $dev: $!"
|
||||
}
|
||||
}
|
||||
#-- Third step: see, if a bus interface is detected
|
||||
if (!OWX_Detect($hash)){
|
||||
$hash->{STATE} = "Failed";
|
||||
$hash->{PRESENT} = 0;
|
||||
$init_done = 1;
|
||||
return undef;
|
||||
}
|
||||
|
||||
#-- In 10 seconds discover all devices on the 1-Wire bus
|
||||
InternalTimer(gettimeofday()+10, "OWX_Discover", $hash,0);
|
||||
|
||||
#-- Default settings
|
||||
$hash->{interval} = 300; # kick every minute
|
||||
$hash->{followAlarms} = "off";
|
||||
$hash->{ALARMED} = "no";
|
||||
|
||||
#-- InternalTimer blocks if init_done is not true
|
||||
my $oid = $init_done;
|
||||
$hash->{PRESENT} = 1;
|
||||
$hash->{STATE} = "Initialized";
|
||||
$init_done = 1;
|
||||
#-- Intiate first alarm detection and eventually conversion in a minute or so
|
||||
InternalTimer(gettimeofday() + $hash->{interval}, "OWX_Kick", $hash,1);
|
||||
$init_done = $oid;
|
||||
$hash->{STATE} = "Active";
|
||||
return undef;
|
||||
}
|
||||
|
||||
########################################################################################
|
||||
#
|
||||
# OWX_Alarms - Find devices on the 1-Wire bus,
|
||||
@ -143,6 +243,7 @@ sub OWX_Initialize ($) {
|
||||
|
||||
sub OWX_Alarms ($) {
|
||||
my ($hash) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my @owx_alarm_names=();
|
||||
|
||||
#-- Discover all alarmed devices on the 1-Wire bus
|
||||
@ -152,13 +253,13 @@ sub OWX_Alarms ($) {
|
||||
$res = $res & OWX_Next_SER($hash,"alarm");
|
||||
}
|
||||
if( @owx_alarm_devs == 0){
|
||||
return "OWX: No alarmed 1-Wire devices found ";
|
||||
return "OWX: No alarmed 1-Wire devices found on bus $name";
|
||||
}
|
||||
|
||||
#-- walk through all the devices to get their proper fhem names
|
||||
foreach my $fhem_dev (sort keys %main::defs) {
|
||||
#-- skip if busmaster
|
||||
next if( $hash->{NAME} eq $main::defs{$fhem_dev}{NAME} );
|
||||
next if( $name eq $main::defs{$fhem_dev}{NAME} );
|
||||
#-- all OW types start with OW
|
||||
next if( substr($main::defs{$fhem_dev}{TYPE},0,2) ne "OW");
|
||||
foreach my $owx_dev (@owx_alarm_devs) {
|
||||
@ -175,7 +276,7 @@ sub OWX_Alarms ($) {
|
||||
}
|
||||
}
|
||||
#-- so far, so good - what do we want to do with this ?
|
||||
return "OWX: Alarmed 1-Wire devices found (".join(",",@owx_alarm_names).")";
|
||||
return "OWX: Alarmed 1-Wire devices found on bus $name (".join(",",@owx_alarm_names).")";
|
||||
}
|
||||
|
||||
########################################################################################
|
||||
@ -194,6 +295,7 @@ sub OWX_Alarms ($) {
|
||||
|
||||
sub OWX_Complex ($$$$) {
|
||||
my ($hash,$owx_dev,$data,$numread) =@_;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
#-- get the interface
|
||||
$owx_interface = $hash->{INTERFACE};
|
||||
@ -201,7 +303,7 @@ sub OWX_Complex ($$$$) {
|
||||
|
||||
#-- interface error
|
||||
if( !(defined($owx_interface))){
|
||||
Log 3,"OWX: Complex called with unknown interface";
|
||||
Log 3,"OWX: Complex called with unknown interface on bus $name";
|
||||
return 0;
|
||||
#-- here we treat the directly connected serial interfaces
|
||||
}elsif( ($owx_interface eq "DS2480") || ($owx_interface eq "DS9097") ){
|
||||
@ -213,7 +315,7 @@ sub OWX_Complex ($$$$) {
|
||||
|
||||
#-- interface error
|
||||
}else{
|
||||
Log 3,"OWX: Complex called with unknown interface";
|
||||
Log 3,"OWX: Complex called with unknown interface $owx_interface on bus $name";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -226,10 +328,7 @@ sub OWX_Complex ($$$$) {
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub OWX_CRC ($) {
|
||||
my ($romid) = @_;
|
||||
|
||||
my @crc8_table = (
|
||||
my @crc8_table = (
|
||||
0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
|
||||
157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
|
||||
35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
|
||||
@ -247,6 +346,9 @@ sub OWX_CRC ($) {
|
||||
233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
|
||||
116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53);
|
||||
|
||||
|
||||
sub OWX_CRC ($) {
|
||||
my ($romid) = @_;
|
||||
my $crc8=0;
|
||||
|
||||
if( $romid eq "0" ){
|
||||
@ -267,6 +369,36 @@ sub OWX_CRC ($) {
|
||||
}
|
||||
}
|
||||
|
||||
########################################################################################
|
||||
#
|
||||
# OWX_CRC - Check the CRC8 code of an a byte string
|
||||
#
|
||||
# Parameter string, crc.
|
||||
# If crc is defined, make a comparison, otherwise output crc8
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub OWX_CRC8 ($$) {
|
||||
my ($string,$crc) = @_;
|
||||
my $crc8=0;
|
||||
my @strhex;
|
||||
|
||||
for(my $i=0; $i<8; $i++){
|
||||
$strhex[$i]=ord(substr($string,$i,1));
|
||||
$crc8 = $crc8_table[ $crc8 ^ $strhex[$i] ];
|
||||
}
|
||||
|
||||
if( defined($crc) ){
|
||||
if ( $crc = $crc8 ){
|
||||
return 1;
|
||||
}else{
|
||||
return 0;
|
||||
}
|
||||
}else{
|
||||
return $crc8;
|
||||
}
|
||||
}
|
||||
|
||||
########################################################################################
|
||||
#
|
||||
# OWX_CRC16 - Calculate the CRC16 code of a string
|
||||
@ -318,103 +450,6 @@ sub OWX_DOCRC16($$) {
|
||||
#//...
|
||||
#}
|
||||
|
||||
|
||||
|
||||
########################################################################################
|
||||
#
|
||||
# OWX_Define - Implements DefFn function
|
||||
#
|
||||
# Parameter hash = hash of device addressed, def = definition string
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub OWX_Define ($$) {
|
||||
my ($hash, $def) = @_;
|
||||
my @a = split("[ \t][ \t]*", $def);
|
||||
|
||||
if(int(@a) >= 3){
|
||||
#-- check syntax
|
||||
Log 1,"OWX: Warning - Some parameter(s) ignored, must be define <name> OWX <serial-device>|<cuno-device>"
|
||||
if(int(@a) > 3);
|
||||
#-- If this line contains 3 parameters, it is the bus master definition
|
||||
my $dev = $a[2];
|
||||
$hash->{DeviceName} = $dev;
|
||||
#-- Dummy 1-Wire ROM identifier
|
||||
$hash->{ROM_ID} = "FF";
|
||||
|
||||
#-- First step: check if we have a directly connected serial interface or a CUNO attached
|
||||
if ( $dev =~ m/.*USB.*/){
|
||||
#-- Second step in case of serial device: open the serial device to test it
|
||||
my $msg = "OWX: Serial device $dev";
|
||||
$owx_hwdevice = new Device::SerialPort ($dev);
|
||||
if($owx_hwdevice){
|
||||
Log 1,$msg." defined";
|
||||
}else{
|
||||
Log 1, $msg." not defined";
|
||||
return "OWX: Can't open serial device $dev: $!"
|
||||
}
|
||||
$owx_hwdevice->reset_error();
|
||||
$owx_hwdevice->baudrate(9600);
|
||||
$owx_hwdevice->databits(8);
|
||||
$owx_hwdevice->parity('none');
|
||||
$owx_hwdevice->stopbits(1);
|
||||
$owx_hwdevice->handshake('none');
|
||||
$owx_hwdevice->write_settings;
|
||||
#-- store with OWX device
|
||||
$hash->{INTERFACE} = "serial";
|
||||
$hash->{HWDEVICE} = $owx_hwdevice;
|
||||
#-- sleeping for some time
|
||||
select(undef,undef,undef,0.1);
|
||||
} else {
|
||||
#-- Second step in case of CUNO: See if we can open it
|
||||
my $msg = "OWX: CUNO device $dev";
|
||||
$owx_hwdevice = $main::defs{$dev};
|
||||
if($owx_hwdevice){
|
||||
Log 1,$msg." defined";
|
||||
#-- store with OWX device
|
||||
$hash->{INTERFACE} = "CUNO";
|
||||
$hash->{HWDEVICE} = $owx_hwdevice;
|
||||
#-- reset the 1-Wire system in CUNO
|
||||
CUL_SimpleWrite($owx_hwdevice, "Oi");
|
||||
}else{
|
||||
Log 1, $msg." not defined";
|
||||
return "OWX: Can't open cuno device $dev: $!"
|
||||
}
|
||||
}
|
||||
|
||||
#-- Third step: see, if a bus interface is detected
|
||||
if (!OWX_Detect($hash)){
|
||||
$hash->{STATE} = "Failed";
|
||||
$hash->{PRESENT} = 0;
|
||||
$init_done = 1;
|
||||
return undef;
|
||||
}
|
||||
|
||||
#-- In 10 seconds discover all devices on the 1-Wire bus
|
||||
InternalTimer(gettimeofday()+10, "OWX_Discover", $hash,0);
|
||||
|
||||
#-- Default settings
|
||||
$hash->{interval} = 300; # kick every minute
|
||||
$hash->{followAlarms} = "off";
|
||||
$hash->{ALARMED} = "no";
|
||||
|
||||
#-- InternalTimer blocks if init_done is not true
|
||||
my $oid = $init_done;
|
||||
$hash->{PRESENT} = 1;
|
||||
$hash->{STATE} = "Initialized";
|
||||
$init_done = 1;
|
||||
|
||||
#-- Intiate first alarm detection and eventually conversion in a minute or so
|
||||
InternalTimer(gettimeofday() + $hash->{interval}, "OWX_Kick", $hash,1);
|
||||
$init_done = $oid;
|
||||
$hash->{STATE} = "Active";
|
||||
return undef;
|
||||
} else {
|
||||
#-- check syntax
|
||||
return "OWX: Syntax error - must be define <name> OWX"
|
||||
}
|
||||
}
|
||||
|
||||
########################################################################################
|
||||
#
|
||||
# OWX_Detect - Detect 1-Wire interface
|
||||
@ -433,6 +468,9 @@ sub OWX_Detect ($) {
|
||||
my ($hash) = @_;
|
||||
|
||||
my ($i,$j,$k,$l,$res,$ret,$ress);
|
||||
my $name = $hash->{NAME};
|
||||
my $ress0 = "OWX: 1-Wire bus $name: interface ";
|
||||
$ress = $ress0;
|
||||
|
||||
#-- get the interface
|
||||
$owx_interface = $hash->{INTERFACE};
|
||||
@ -449,16 +487,19 @@ sub OWX_Detect ($) {
|
||||
$res = OWX_Query_2480($hash,"\x17\x45\x5B\x0F\x91");
|
||||
|
||||
#-- process 4/5-byte string for detection
|
||||
if( ($res eq "\x16\x44\x5A\x00\x90") || ($res eq "\x16\x44\x5A\x00\x93")){
|
||||
Log 1, "OWX: 1-Wire bus master DS2480 detected for the first time";
|
||||
if( !defined($res)){
|
||||
$res="";
|
||||
$ret=0;
|
||||
}elsif( ($res eq "\x16\x44\x5A\x00\x90") || ($res eq "\x16\x44\x5A\x00\x93")){
|
||||
$ress .= "master DS2480 detected for the first time";
|
||||
$owx_interface="DS2480";
|
||||
$ret=1;
|
||||
} elsif( $res eq "\x17\x45\x5B\x0F\x91"){
|
||||
Log 1, "OWX: 1-Wire bus master DS2480 re-detected";
|
||||
$ress .= "master DS2480 re-detected";
|
||||
$owx_interface="DS2480";
|
||||
$ret=1;
|
||||
} elsif( ($res eq "\x17\x0A\x5B\x0F\x02") || ($res eq "\x00\x17\x0A\x5B\x0F\x02") ){
|
||||
Log 1, "OWX: Passive 1-Wire bus interface DS9097 detected";
|
||||
} elsif( ($res eq "\x17\x0A\x5B\x0F\x02") || ($res eq "\x00\x17\x0A\x5B\x0F\x02") || ($res eq "\x30\xf8\x00") ){
|
||||
$ress .= "passive DS9097 detected";
|
||||
$owx_interface="DS9097";
|
||||
$ret=1;
|
||||
} else {
|
||||
@ -466,19 +507,20 @@ sub OWX_Detect ($) {
|
||||
}
|
||||
last
|
||||
if( $ret==1 );
|
||||
$ress = "OWX: Trying again to detect an interface, answer was ";
|
||||
$ress .= "not found, answer was ";
|
||||
for($i=0;$i<length($res);$i++){
|
||||
$j=int(ord(substr($res,$i,1))/16);
|
||||
$k=ord(substr($res,$i,1))%16;
|
||||
$ress.=sprintf "0x%1x%1x ",$j,$k;
|
||||
}
|
||||
Log 1, $ress;
|
||||
$ress = $ress0;
|
||||
#-- sleeping for some time
|
||||
select(undef,undef,undef,0.5);
|
||||
}
|
||||
if( $ret == 0 ){
|
||||
$owx_interface=undef;
|
||||
$ress = "OWX: No 1-Wire bus interface detected, answer was ";
|
||||
$ress .= "not detected, answer was ";
|
||||
for($i=0;$i<length($res);$i++){
|
||||
$j=int(ord(substr($res,$i,1))/16);
|
||||
$k=ord(substr($res,$i,1))%16;
|
||||
@ -491,11 +533,11 @@ sub OWX_Detect ($) {
|
||||
my $ob = DevIo_SimpleRead($owx_hwdevice);
|
||||
if( $ob =~ m/OK.*/){
|
||||
$owx_interface="CUNO";
|
||||
$ress="OWX: 1-Wire bus interface DS2482 detected in $owx_hwdevice->{NAME}";
|
||||
$ress .= "DS2482 detected in $owx_hwdevice->{NAME}";
|
||||
$ret=1;
|
||||
} else {
|
||||
$owx_interface=undef;
|
||||
$ress="OWX: 1-Wire bus interface in $owx_hwdevice->{NAME} could not be addressed";
|
||||
$ress .= "in $owx_hwdevice->{NAME} could not be addressed";
|
||||
$ret=0;
|
||||
}
|
||||
}
|
||||
@ -520,6 +562,7 @@ sub OWX_Detect ($) {
|
||||
sub OWX_Discover ($) {
|
||||
my ($hash) = @_;
|
||||
my $res;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
#-- get the interface
|
||||
$owx_interface = $hash->{INTERFACE};
|
||||
@ -649,8 +692,8 @@ sub OWX_Discover ($) {
|
||||
Log 1, "OWX: Deleting unused 1-Wire device $main::defs{$fhem_dev}{NAME} of type $main::defs{$fhem_dev}{TYPE}";
|
||||
CommandDelete(undef,$main::defs{$fhem_dev}{NAME});
|
||||
}
|
||||
Log 1, "OWX: 1-Wire devices found (".join(",",@owx_names).")";
|
||||
return "OWX: 1-Wire devices found (".join(",",@owx_names).")";
|
||||
Log 1, "OWX: 1-Wire devices found on bus $name: (".join(",",@owx_names).")";
|
||||
return "OWX: 1-Wire devices found on bus $name: (".join(",",@owx_names).")";
|
||||
}
|
||||
|
||||
########################################################################################
|
||||
@ -738,7 +781,7 @@ sub OWX_Reset ($) {
|
||||
|
||||
#-- interface error
|
||||
if( !(defined($owx_interface))){
|
||||
Log 3,"OWX: Reset called with unknown interface";
|
||||
Log 3,"OWX: Reset called with undefined interface";
|
||||
return 0;
|
||||
}elsif( $owx_interface eq "DS2480" ){
|
||||
return OWX_Reset_2480($hash);
|
||||
@ -747,7 +790,7 @@ sub OWX_Reset ($) {
|
||||
}elsif( $owx_interface eq "CUNO" ){
|
||||
return OWX_Reset_CUNO($hash);
|
||||
}else{
|
||||
Log 3,"OWX: Reset called with unknown interface";
|
||||
Log 3,"OWX: Reset called with unknown interface $owx_interface";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -815,6 +858,7 @@ sub OWX_Set($@) {
|
||||
sub OWX_Undef ($$) {
|
||||
my ($hash, $name) = @_;
|
||||
RemoveInternalTimer($hash);
|
||||
DevIo_CloseDev($hash);
|
||||
return undef;
|
||||
}
|
||||
|
||||
@ -1221,8 +1265,8 @@ sub OWX_Query_2480 ($$) {
|
||||
|
||||
my ($hash,$cmd) = @_;
|
||||
my ($i,$j,$k);
|
||||
my $dev = $hash->{DeviceName};
|
||||
|
||||
$owx_hwdevice = $hash->{HWDEVICE};
|
||||
$owx_hwdevice->baudrate($owx_baud);
|
||||
$owx_hwdevice->write_settings;
|
||||
|
||||
@ -1257,8 +1301,6 @@ sub OWX_Query_2480 ($$) {
|
||||
|
||||
#-- sleeping for some time
|
||||
select(undef,undef,undef,0.04);
|
||||
|
||||
#$owx_hwdevice->close();
|
||||
return($string_in);
|
||||
}
|
||||
|
||||
@ -1280,7 +1322,7 @@ sub OWX_Reset_2480 ($) {
|
||||
|
||||
my ($res,$r1,$r2);
|
||||
#-- if necessary, prepend \xE3 character for command mode
|
||||
if( $owx_mode ne "command" ) {
|
||||
if( $owx_mode ne "command" ){
|
||||
$cmd = "\xE3";
|
||||
}
|
||||
#-- Reset command \xC5
|
||||
@ -1504,8 +1546,7 @@ sub OWX_Query_9097 ($$) {
|
||||
|
||||
my ($hash,$cmd) = @_;
|
||||
my ($i,$j,$k);
|
||||
my $dev = $hash->{DeviceName};
|
||||
|
||||
$owx_hwdevice = $hash->{HWDEVICE};
|
||||
$owx_hwdevice->baudrate($owx_baud);
|
||||
$owx_hwdevice->write_settings;
|
||||
|
||||
@ -1541,7 +1582,6 @@ sub OWX_Query_9097 ($$) {
|
||||
#-- sleeping for some time
|
||||
select(undef,undef,undef,0.01);
|
||||
|
||||
#$owx_hwdevice->close();
|
||||
return($string_in);
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
#
|
||||
# Prof. Dr. Peter A. Henning, 2012
|
||||
#
|
||||
# Version 2.15 - July, 2012
|
||||
# Version 2.17 - August, 2012
|
||||
#
|
||||
# Setup bus device in fhem.cfg as
|
||||
#
|
||||
@ -290,13 +290,6 @@ sub OWCOUNT_InitializeDevice($) {
|
||||
$hash->{READINGS}{"$owg_rate[$i]"}{UNITABBR} = $unarr[1].$runit;
|
||||
#Log 1,"OWCOUNT InitializeDevice with period $period and UNITABBR = ".$hash->{READINGS}{"$owg_rate[$i]"}{UNITABBR};
|
||||
|
||||
#-- remove units if they are unwanted
|
||||
if( defined($attr{$name}{"UnitInReading"})){
|
||||
if( $attr{$name}{"UnitInReading"} == 0){
|
||||
$hash->{READINGS}{"$owg_channel[$i]"}{UNITABBR} = "";
|
||||
$hash->{READINGS}{"$owg_rate[$i]"}{UNITABBR} = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#-- set status according to interface type
|
||||
@ -319,9 +312,9 @@ sub OWCOUNT_InitializeDevice($) {
|
||||
|
||||
########################################################################################
|
||||
#
|
||||
# OWCOUNT_FormatValues - put together various format strings
|
||||
# OWCOUNT_FormatValues - put together various format strings and assemble STATE variable
|
||||
#
|
||||
# Parameter hash = hash of device addressed, fs = format string
|
||||
# Parameter hash = hash of device addressed
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
@ -329,7 +322,7 @@ sub OWCOUNT_FormatValues($) {
|
||||
my ($hash) = @_;
|
||||
|
||||
my $name = $hash->{NAME};
|
||||
my ($offset,$factor,$present,$period,$unit,$runit,$midnight,$vval,$vrate);
|
||||
my ($offset,$factor,$period,$unit,$runit,$midnight,$vval,$vrate);
|
||||
my ($value1,$value2,$value3,$value4,$value5) = ("","","","","");
|
||||
my $galarm = 0;
|
||||
|
||||
@ -339,6 +332,10 @@ sub OWCOUNT_FormatValues($) {
|
||||
my $daybreak = 0;
|
||||
my $monthbreak = 0;
|
||||
|
||||
my $present = $hash->{PRESENT};
|
||||
#-- remove units if they are unwanted
|
||||
my $unir = defined($attr{$name}{"UnitInReading"}) ? $attr{$name}{"UnitInReading"} : 1;
|
||||
|
||||
#-- formats for output
|
||||
for (my $i=0;$i<int(@owg_fixed);$i++){
|
||||
my $cname = defined($attr{$name}{$owg_fixed[$i]."Name"}) ? $attr{$name}{$owg_fixed[$i]."Name"} : $owg_fixed[$i];
|
||||
@ -347,7 +344,8 @@ sub OWCOUNT_FormatValues($) {
|
||||
$offset = $hash->{READINGS}{"$owg_channel[$i]"}{OFFSET};
|
||||
$factor = $hash->{READINGS}{"$owg_channel[$i]"}{FACTOR};
|
||||
$unit = $hash->{READINGS}{"$owg_channel[$i]"}{UNITABBR};
|
||||
$present = $hash->{PRESENT};
|
||||
$period = $hash->{READINGS}{"$owg_channel[$i]"}{PERIOD};
|
||||
$runit = $hash->{READINGS}{"$owg_rate[$i]"}{UNITABBR};
|
||||
|
||||
#-- only if attribute value Mode=daily, take the midnight value from memory
|
||||
if( defined($attr{$name}{$owg_fixed[$i]."Mode"} )){
|
||||
@ -362,21 +360,16 @@ sub OWCOUNT_FormatValues($) {
|
||||
} else {
|
||||
$midnight = 0.0;
|
||||
}
|
||||
|
||||
#-- correct values for proper offset, factor
|
||||
# careful: midnight value has not been corrected so far !
|
||||
#-- 1 decimal
|
||||
if( $factor == 1.0 ){
|
||||
$vval = int(($owg_val[$i] + $offset - $midnight)*10)/10;
|
||||
#-- string buildup for return value and STATE
|
||||
$value1 .= sprintf( "%s: %5.1f %s", $owg_channel[$i], $vval,$unit);
|
||||
$value2 .= sprintf( "%s: %5.1f %s ", $owg_channel[$i], $vval,$unit);
|
||||
#-- 3 decimals
|
||||
} else {
|
||||
$vval = int((($owg_val[$i] + $offset)*$factor - $midnight)*1000)/1000;
|
||||
#-- string buildup for return value and STATE
|
||||
$value1 .= sprintf( "%s: %5.3f %s", $owg_channel[$i], $vval,$unit);
|
||||
$value2 .= sprintf( "%s: %5.2f %s ", $owg_channel[$i], $vval,$unit);
|
||||
}
|
||||
$value3 .= sprintf( "%s: " , $owg_channel[$i]);
|
||||
|
||||
#-- get the old values
|
||||
my $oldval = $hash->{READINGS}{"$owg_channel[$i]"}{VAL};
|
||||
@ -398,40 +391,20 @@ sub OWCOUNT_FormatValues($) {
|
||||
if( ($vval < $oldval) && ($daybreak==0) && ($present==1) ){
|
||||
Log 1,"OWCOUNT TODO: Counter wraparound";
|
||||
}
|
||||
#-- rate
|
||||
if( $delt > 0 ){
|
||||
$vrate = ($vval-$oldval)/$delt;
|
||||
} else {
|
||||
Log 1, "OWCOUNT: Invalid time interval $delt for rate calculation";
|
||||
$vrate = 0.0;
|
||||
}
|
||||
#-- correct rate for wraparound at midnight
|
||||
if( ($vrate < 0) && ($hash->{PRESENT}==1) ){
|
||||
Log 1,"OWCOUNT: correcting raw rate directly after midnight from $vrate to ".($vrate+$midnight/$delt)." vval=$vval, oldval=$oldval, delt=$delt";
|
||||
$vrate += $midnight/$delt;
|
||||
}
|
||||
#-- correct rate for peroid setting
|
||||
$period = $hash->{READINGS}{"$owg_channel[$i]"}{PERIOD};
|
||||
if( $period eq "hour" ){
|
||||
$vrate*=3600;
|
||||
}elsif( $period eq "minute" ){
|
||||
$vrate*=60;
|
||||
}
|
||||
$runit = $hash->{READINGS}{"$owg_rate[$i]"}{UNITABBR};
|
||||
#-- string buildup for return value and STATE
|
||||
$value1 .= sprintf( " %5.3f %s", $vrate,$runit);
|
||||
$value2 .= sprintf( " %5.2f %s ",$vrate,$runit);
|
||||
|
||||
if( $daybreak==1 ){
|
||||
#-- we need to check this !
|
||||
Log 1,"OWCOUNT: Daybreak routine called with oldtim=$oldtim and day=$day and present=".$present;
|
||||
#-- linear interpolation
|
||||
my $dt = ((24-$houro)*3600 -$mino*60 - $seco)/( ($hour+24-$houro)*3600 + ($min-$mino)*60 + ($sec-$seco) );
|
||||
my $dv = $oldval*(1-$dt)+$vval*$dt;
|
||||
#-- correct reading in daily mode
|
||||
if( $midnight > 0.0 ){
|
||||
$vval -= $dv;
|
||||
$delt *= (1-$dt);
|
||||
$oldval = 0.0;
|
||||
}
|
||||
#-- in any mode store the interpolated value in the midnight store
|
||||
$midnight += $dv;
|
||||
#-- in any mode, when midnight has passed, store the interpolated value in the midnight store
|
||||
OWXCOUNT_SetPage($hash,14+$i,sprintf("%f",$midnight));
|
||||
Log 1, "OWCOUNT: Interpolated additional value for channel ".$owg_channel[$i]." is ".$dv." at time ".$tn;
|
||||
#-- string buildup for monthly logging
|
||||
$value4 .= sprintf( "%s: %5.1f %s", $owg_channel[$i], $dv,$unit);
|
||||
if( $day<$dayo ){
|
||||
@ -441,11 +414,52 @@ sub OWCOUNT_FormatValues($) {
|
||||
$value5 .= sprintf( "%s: %5.1f %s", $owg_channel[$i], $dv,$unit);
|
||||
}
|
||||
}
|
||||
#-- rate
|
||||
if( ($delt > 0.0) && $present ){
|
||||
$vrate = ($vval-$oldval)/$delt;
|
||||
} else {
|
||||
$vrate = 0.0;
|
||||
}
|
||||
#-- correct rate for period setting
|
||||
if( $period eq "hour" ){
|
||||
$vrate*=3600;
|
||||
}elsif( $period eq "minute" ){
|
||||
$vrate*=60;
|
||||
}
|
||||
|
||||
if( !defined($runit) ){
|
||||
Log 1,"OWCOUNT: Error in rate unit definition. i=$i, owg_rate[i]=".$owg_rate[$i];
|
||||
$runit = "ERR";
|
||||
}
|
||||
|
||||
#-- string buildup for return value and STATE
|
||||
if( $unir ){
|
||||
#-- 1 decimal
|
||||
if( $factor == 1.0 ){
|
||||
$value1 .= sprintf( "%s: %5.1f %s %5.2f %s", $owg_channel[$i], $vval,$unit,$vrate,$runit);
|
||||
$value2 .= sprintf( "%s: %5.1f %s %5.2f %s", $owg_channel[$i], $vval,$unit,$vrate,$runit);
|
||||
#-- 3 decimals
|
||||
} else {
|
||||
$value1 .= sprintf( "%s: %5.3f %s %5.2f %s", $owg_channel[$i], $vval,$unit,$vrate,$runit);
|
||||
$value2 .= sprintf( "%s: %5.2f %s %5.2f %s", $owg_channel[$i], $vval,$unit,$vrate,$runit);
|
||||
}
|
||||
}else {
|
||||
#-- 1 decimal
|
||||
if( $factor == 1.0 ){
|
||||
$value1 .= sprintf( "%s: %5.1f %5.2f", $owg_channel[$i], $vval,$vrate);
|
||||
$value2 .= sprintf( "%s: %5.1f %5.2f", $owg_channel[$i], $vval,$vrate);
|
||||
#-- 3 decimals
|
||||
} else {
|
||||
$value1 .= sprintf( "%s: %5.3f %5.2f", $owg_channel[$i], $vval,$vrate);
|
||||
$value2 .= sprintf( "%s: %5.2f %5.2f", $owg_channel[$i], $vval,$vrate);
|
||||
}
|
||||
}
|
||||
$value3 .= sprintf( "%s: " , $owg_channel[$i]);
|
||||
}
|
||||
#-- put into READINGS
|
||||
$hash->{READINGS}{"$owg_channel[$i]"}{VAL} = $vval;
|
||||
#-- but times and rate only when valid
|
||||
if( $hash->{PRESENT}==1 ){
|
||||
if( $present ){
|
||||
$hash->{READINGS}{"$owg_channel[$i]"}{TIME} = $tn;
|
||||
$hash->{READINGS}{"$owg_rate[$i]"}{VAL} = $vrate;
|
||||
$hash->{READINGS}{"$owg_rate[$i]"}{TIME} = $tn;
|
||||
@ -465,6 +479,12 @@ sub OWCOUNT_FormatValues($) {
|
||||
}
|
||||
#-- STATE
|
||||
$hash->{STATE} = $value2;
|
||||
|
||||
#-- write units as header if they are unwanted in lines
|
||||
if( $unir == 0 ){
|
||||
#TODO: the entry into CHANGED must be into the lowest array position
|
||||
}
|
||||
|
||||
if( $daybreak == 1 ){
|
||||
$value4 = sprintf("D_%d: %d-%d-%d_23:59:59 %s",$dayo,$yearo,$montho,$dayo,$value4);
|
||||
#-- needs to be higher array elements,
|
||||
@ -896,8 +916,8 @@ sub OWXCOUNT_GetPage($$) {
|
||||
return "OWXCOUNT: Device $owx_dev returns invalid data";
|
||||
}
|
||||
|
||||
#-- first ignore memory and only use counter
|
||||
my $value = ord($data[3])*4096 + ord($data[2])*256 +ord($data[1])*16 + ord($data[0]);
|
||||
#-- first ignore memory and only use counter (Fehler gefunden von jamesgo)
|
||||
my $value = (ord($data[3])<<32) + (ord($data[2])<<16) +(ord($data[1])<<8) + ord($data[0]);
|
||||
|
||||
if( $page == 14) {
|
||||
$owg_val[0] = $value;
|
||||
|
@ -15,7 +15,7 @@
|
||||
# Prof. Dr. Peter A. Henning, 2012
|
||||
# Martin Fischer, 2011
|
||||
#
|
||||
# Version 2.13 - July, 2012
|
||||
# Version 2.17 - August, 2012
|
||||
#
|
||||
# Setup bus device in fhem.cfg as
|
||||
#
|
||||
@ -457,7 +457,12 @@ sub OWTHERM_GetValues($@) {
|
||||
#-- Get values according to interface type
|
||||
my $interface= $hash->{IODev}->{TYPE};
|
||||
if( $interface eq "OWX" ){
|
||||
#-- max 3 tries
|
||||
for(my $try=0; $try<3; $try++){
|
||||
$ret = OWXTHERM_GetValues($hash);
|
||||
last
|
||||
if( !defined($ret) );
|
||||
}
|
||||
}elsif( $interface eq "OWFS" ){
|
||||
$ret = OWFSTHERM_GetValues($hash);
|
||||
}else{
|
||||
@ -466,7 +471,7 @@ sub OWTHERM_GetValues($@) {
|
||||
|
||||
#-- process results
|
||||
if( defined($ret) ){
|
||||
return "OWTHERM: Could not get values from device $name";
|
||||
return "OWTHERM: Could not get values from device $name, reason $ret";
|
||||
}
|
||||
$hash->{PRESENT} = 1;
|
||||
$value=OWTHERM_FormatValues($hash);
|
||||
@ -653,7 +658,6 @@ sub OWXTHERM_GetValues($) {
|
||||
#-- hash of the busmaster
|
||||
my $master = $hash->{IODev};
|
||||
|
||||
|
||||
#-- check, if the conversion has been called before - only on devices with real power
|
||||
if( defined($attr{$hash->{IODev}->{NAME}}{buspower}) && ( $attr{$hash->{IODev}->{NAME}}{buspower} eq "real") ){
|
||||
$con=0;
|
||||
@ -691,10 +695,17 @@ sub OWXTHERM_GetValues($) {
|
||||
|
||||
#-- process results
|
||||
my @data=split(//,$res);
|
||||
return "invalid data length"
|
||||
if (@data != 19);
|
||||
return "invalid data"
|
||||
if (ord($data[17])<=0);
|
||||
return "invalid CRC"
|
||||
if (OWX_CRC8(substr($res,10,8),$data[18])==0);
|
||||
|
||||
#-- this must be different for the different device types
|
||||
# family = 10 => DS1820, DS18S20
|
||||
if( $hash->{OW_FAMILY} eq "10" ) {
|
||||
if ( (@data == 19) && (ord($data[17])>0) ){
|
||||
|
||||
my $count_remain = ord($data[16]);
|
||||
my $count_perc = ord($data[17]);
|
||||
my $delta = -0.25 + ($count_perc - $count_remain)/$count_perc;
|
||||
@ -716,12 +727,10 @@ sub OWXTHERM_GetValues($) {
|
||||
|
||||
$owg_th = ord($data[12]) > 127 ? 128-ord($data[12]) : ord($data[12]);
|
||||
$owg_tl = ord($data[13]) > 127 ? 128-ord($data[13]) : ord($data[13]);
|
||||
|
||||
return undef;
|
||||
} else {
|
||||
return "OWXTHERM: Device $owx_dev returns invalid data";
|
||||
}
|
||||
|
||||
} elsif ( ($hash->{OW_FAMILY} eq "22") || ($hash->{OW_FAMILY} eq "28") ) {
|
||||
if ( (@data == 19) && (ord($data[17])>0) ){
|
||||
|
||||
my $lsb = ord($data[10]);
|
||||
my $msb = ord($data[11]) & 7;
|
||||
@ -739,10 +748,9 @@ sub OWXTHERM_GetValues($) {
|
||||
}
|
||||
$owg_th = ord($data[12]) > 127 ? 128-ord($data[12]) : ord($data[12]);
|
||||
$owg_tl = ord($data[13]) > 127 ? 128-ord($data[13]) : ord($data[13]);
|
||||
|
||||
return undef;
|
||||
} else {
|
||||
return "OWXTHERM: Device $owx_dev returns invalid data";
|
||||
}
|
||||
|
||||
} else {
|
||||
return "OWXTHERM: Unknown device family $hash->{OW_FAMILY}\n";
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user