2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-06 06:36:36 +00:00
fhem-mirror/fhem/FHEM/09_USF1000.pm
rudolfkoenig db2efd2cd4 UNDEFINED changes
git-svn-id: https://svn.fhem.de/fhem/trunk@519 2b470e98-0d58-463d-a4d8-8e2adae1ed80
2009-12-21 18:03:56 +00:00

172 lines
4.0 KiB
Perl

#
#
# 09_USF1000.pm
# written by Dr. Boris Neubert 2009-06-20
# e-mail: omega at online dot de
#
##############################################
package main;
use strict;
use warnings;
my $PI= 3.141592653589793238;
my %defptr;
my $dev= "a5ce aa";
#############################
sub
USF1000_Initialize($)
{
my ($hash) = @_;
$hash->{Match} = "^81..(04|0c)..0101a001a5ceaa00....";
$hash->{DefFn} = "USF1000_Define";
$hash->{UndefFn} = "USF1000_Undef";
$hash->{ParseFn} = "USF1000_Parse";
$hash->{AttrList} = "IODev do_not_notify:1,0 showtime:0,1 dummy:1,0 model:usf1000s loglevel:0,1,2,3,4,5,6";
}
#############################
sub
USF1000_Define($$)
{
my ($hash, $def) = @_;
my @a = split("[ \t][ \t]*", $def);
my $u= "wrong syntax: define <name> USF1000 geometry";
my $g= "wrong geometry for USF1000";
# geometry (units: meter)
# cub length width height offset cuboid 3+4
# cylv diameter height offset vertical cylinder 3+3
# the offset is measured from the TOP of the box!
return $u if(int(@a)< 6);
my $name = $a[0];
my $geometry = $a[2];
if($geometry eq "cub") {
# cuboid
return $g if(int(@a)< 7);
$hash->{GEOMETRY}= $geometry;
$hash->{LENGTH}= $a[3];
$hash->{WIDTH}= $a[4];
$hash->{HEIGHT}= $a[5];
$hash->{OFFSET}= $a[6];
$hash->{CAPACITY}= int($hash->{LENGTH}*$hash->{WIDTH}*$hash->{HEIGHT}*100.0+0.5)*10.0;
} elsif($geometry eq "cylv") {
# vertical cylinder
return $g if(int(@a)< 6);
$hash->{GEOMETRY}= $geometry;
$hash->{DIAMETER}= $a[3];
$hash->{HEIGHT}= $a[4];
$hash->{OFFSET}= $a[5];
$hash->{CAPACITY}= int($PI*$hash->{DIAMETER}*$hash->{DIAMETER}/4.0*$hash->{HEIGHT}*100.0+0.5)*10.0;
} else {
return $g;
}
$defptr{$dev} = $hash;
AssignIoPort($hash);
}
#############################
sub
USF1000_Undef($$)
{
my ($hash, $name) = @_;
delete($defptr{$dev});
return undef;
}
#############################
sub
USF1000_Parse($$)
{
my ($hash, $msg) = @_; # hash points to the FHZ, not to the USF1000
if(!defined($defptr{$dev})) {
Log 3, "USF1000 Unknown device, please define it";
return "UNDEFINED USF1000 USF1000 cylv 1 1 0.5";
}
my $def= $defptr{$dev};
my $name= $def->{NAME};
my $t= TimeNow();
# Msg format:
# 01 23 45 67 8901 2345 6789 01 23 45 67
# 81 0c 04 .. 0101 a001 a5ce aa 00 cc xx
my $cc= substr($msg, 24, 2);
my $xx= substr($msg, 26, 2);
my $lowbattery= (hex($cc) & 0x40 ? 1 : 0);
my $testmode= (hex($cc) & 0x80 ? 1 : 0);
my $distance= hex($xx)/100.0; # in meters
my $valid= (($distance>0.00) && ($distance<2.55));
if($valid) {
my $wlevel = $def->{HEIGHT}-($distance-$def->{OFFSET}); # water level
my $geometry= $def->{GEOMETRY};
my $capacity= $def->{CAPACITY}; # capacity of tank (for distance= offset) in liters
my $volume; # current volume in tank in liters
my $flevel; # fill level in percent
if($geometry eq "cub") {
# cuboid
$volume = $def->{LENGTH}*$def->{WIDTH}*$wlevel*1000.0;
} elsif($geometry eq "cylv") {
# vertical cylinder
$volume = $PI*$def->{DIAMETER}*$def->{DIAMETER}/4.0*$wlevel*1000.0;
} else {
return 0;
}
$flevel = int($volume/$capacity*100.0+0.5);
$volume= int($volume/10.0+0.5)*10.0;
my $state= sprintf("v: %d V: %d", $flevel, $volume);
$def->{CHANGED}[0] = $state;
$def->{STATE} = $state;
$def->{READINGS}{state}{TIME} = $t;
$def->{READINGS}{state}{VAL} = $state;
Log GetLogLevel($name, 4), "USF1000 $name: $state";
$def->{READINGS}{distance}{TIME} = $t;
$def->{READINGS}{distance}{VAL} = $distance;
$def->{READINGS}{level}{TIME} = $t;
$def->{READINGS}{level}{VAL} = $flevel;
$def->{READINGS}{volume}{TIME} = $t;
$def->{READINGS}{volume}{VAL} = $volume;
}
my $warnings= ($lowbattery ? "Battery low" : "");
if($testmode) {
$warnings.= "; " if($warnings);
$warnings.= "Test mode";
}
$warnings= $warnings ? $warnings : "none";
$def->{READINGS}{"warnings"}{TIME} = $t;
$def->{READINGS}{"warnings"}{VAL} = $warnings;
return $name;
}
#############################
1;