2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-01-31 06:39:11 +00:00

USF1000S support for FHEM added (Boris 2009-06-20)

git-svn-id: https://svn.fhem.de/fhem/trunk@394 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
borisneubert 2009-06-20 17:18:59 +00:00
parent 37d116eba0
commit ed7893570e
6 changed files with 288 additions and 6 deletions

View File

@ -502,6 +502,7 @@
- feature: CUL FHT sending added
- bugfix: workaround to make M232 counter wraparound
- feature: sequence module added
- feature: Google Weather API support form FHEM (Boris 2009-06-01)
- feature: Google Weather API support for FHEM (Boris 2009-06-01)
- feature: lazy attribute for FHT devices (Boris 2009-06-09)
- feature: tmpcorr attribute for FHT devices
- feature: USF1000S support for FHEM added (Boris 2009-06-20)

View File

@ -57,12 +57,13 @@ FHZ_Initialize($)
# Provider
$hash->{ReadFn} = "FHZ_Read";
$hash->{WriteFn} = "FHZ_Write";
$hash->{Clients} = ":FHZ:FS20:FHT:HMS:KS300:";
$hash->{Clients} = ":FHZ:FS20:FHT:HMS:KS300:USF1000:";
my %mc = (
"1:FS20" => "^81..(04|0c)..0101a001",
"2:FHT" => "^81..(04|09|0d)..(0909a001|83098301|c409c401)..",
"3:HMS" => "^810e04....(1|5|9).a001",
"4:KS300" => "^810d04..4027a001"
"4:KS300" => "^810d04..4027a001",
"5:USF1000" => "^810c04..0101a001a5ceaa00...."
);
$hash->{MatchList} = \%mc;
$hash->{ReadyFn} = "FHZ_Ready";

170
fhem/FHEM/09_USF1000.pm Normal file
View File

@ -0,0 +1,170 @@
#
#
# 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} = "^810c04..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";
}
my $def= $defptr{$dev};
my $name= $def->{NAME};
return "" if($def->{IODev} && $def->{IODev}{NAME} ne $hash->{NAME});
# 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 $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 $t= TimeNow();
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;

View File

@ -412,5 +412,8 @@
- Tue Jun 09 2009 (Boris)
- 11_FHT.pm: lazy attribute for FHT devices
- Sun Jun 14 2009 (Rudi
- Sun Jun 14 2009 (Rudi)
- 11_FHT.pm: tmpcorr attribute for FHT devices
- Sat Jun 20 2009 (Boris)
- 09_USF1000.pm: new module to support USF1000S devices.

41
fhem/docs/USF1000.txt Executable file
View File

@ -0,0 +1,41 @@
2009-06-20bn
This document describes the protocol for the ultrasound fill-meter USF 1000 S.
Datagram is of FS20 sensor message type:
81 0C 04 ?? 01 01 A0 01 A5 CE AA 00 cc xx
81: begin of FS20/FHT communication
0C: remaining length of datagram (12 bytes)
04: type of datagram
??: checksum
01 01 A0 01: FS20 fix sequence, always 01 01 A0 01
A5 CE: FS20 housecode, always A5CE
AA: FS20 command, always AA
00: always 00
cc: code, see below
xx: measured distance in cm
code:
hex bin
37 00110111 30s message interval, normal operation
B7 10110111 3s message interval, normal operation
F7 11110111 3s message interval, battery low
|||+++++-- 0x17 always 0x17
||+------- 0x20 always 1 (= value byte follows)
|+-------- 0x40 battery warning
+--------- 0x80 test mode (3s message interval)
measured distance from ultrasound sender/transmitter:
distance hex dec
0.50 m 0x30 48
1.00 m 0x60 96
1.50 m 0x92 146
2.00 m 0xC4 196
It is assumed that xx is the distance in centimeters from the top of the box
(4 cm box height + 1 cm height of ultrasound sender/transmitter).

View File

@ -74,6 +74,7 @@
<a href="#WS2000">WS2000</a> &nbsp;
<a href="#WS300">WS300</a> &nbsp;
<a href="#Weather">Weather</a> &nbsp;
<a href="#USF1000">USF1000</a> &nbsp;
<a href="#X10">X10</a> &nbsp;
<a href="#FHEMRENDERER">FHEMRENDERER</a> &nbsp;
@ -2149,7 +2150,7 @@ A line ending with \ will be concatenated with the next one, so long lines
<ul>
<br>
<a name="WS300"></a>
<a name="WS300define"></a>
<b>Define</b>
<ul>
<code>define WS300Device WS300 &lt;serial device&gt;</code><br>
@ -2205,7 +2206,7 @@ A line ending with \ will be concatenated with the next one, so long lines
<ul>
<br>
<a name="Weather"></a>
<a name="Weatherdefine"></a>
<b>Define</b>
<ul>
<code>define &lt;name&gt; Weather &lt;location&gt; [&lt;interval&gt;]</code><br>
@ -2277,6 +2278,71 @@ A line ending with \ will be concatenated with the next one, so long lines
</ul>
<a name="USF1000"></a>
<h3>USF1000</h3>
<ul>
Fhem can receive your tank's fill level from the USF1000S device
through a <a href="#FHZ">FHZ</a> device, so one must be defined first.
The state contains the fill level in % (lower case v in the device state)
and the current volume in liters (upper case V in the device state).
Measured distance to the liquid's surface, fill level, volume and warnings
(Test mode, Battery low) are available.<br>
<br>
<a name="USF1000Define"></a>
<b>Define</b>
<ul>
<code>define &lt;name&gt; USF1000 &lt;geometry&gt;</code>
<br><br>
<code>&lt;geometry&gt;</code> determines the form of the tank and the
position of the sensor. The following geometries are currently
supported:<br><br>
<ul>
<li><code>cub &lt;length&gt; &lt;width&gt; &lt;height&gt; &lt;offset&gt;</code></li>
<li><code>cylv &lt;diameter&gt; &lt;height&gt; &lt;offset&gt;</code></li>
</ul>
<br>
<code>cub</code> stands for a cuboid whose base is &lt;length&gt; &times; &lt;width&gt;.
<code>cylv</code> stands for a vertical cylinder whose diameter is &lt;diameter&gt;.
&lt;height&gt; is the distance of the surface of the liquid from the ground
if the tank is full. &lt;offset&gt; is the distance of the sensor relative to
the surface of the liquid. All quantities are expressed in meters.<br>
<br>
Example:<br>
<ul>
<code>define MyTank USF1000 cylv 2 1 0.3</code>: a cylindrical water tank with
2 meters diameter. The water stands 1 meter high if the tank is full. The
sensor is fixed 1,3 meters above ground.<br>
</ul>
</ul>
<br>
<b>Set </b>
<ul>
N/A
</ul>
<br>
<b>Get</b>
<ul>
N/A
</ul>
<br>
<b>Attributes</b>
<ul>
<li><a href="#do_not_notify">do_not_notify</a></li>
<li><a href="#showtime">showtime</a></li>
<li><a href="#loglevel">loglevel</a></li>
<li><a href="#model">model</a> (usf1000s)</li>
</ul>
<br>
</ul>
<a name="SCIVT"></a>
<h3>SCIVT</h3>