2
0
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:
pahenning 2012-08-25 14:23:15 +00:00
parent aa3445fe82
commit c0aa71ae70
3 changed files with 303 additions and 235 deletions

View File

@ -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);
}

View File

@ -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;

View File

@ -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";
}