mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-03 16:56:54 +00:00
CUL_FHTTK from Kai
git-svn-id: https://svn.fhem.de/fhem/trunk@465 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
d9d47d181c
commit
6ee3308885
@ -538,5 +538,6 @@
|
||||
- feature: softfhtbuffer added to CUL
|
||||
- bugfix: pgm3: Pulldown-Menu without selected FHTDEV not possible any more
|
||||
- feature: duplicate buffer added for multi-cul/-fhz setups
|
||||
- feature: 20_OWFS.pm for communication to 1-Wire via OWFS added (Martin Fischer)
|
||||
- feature: 20_OWFS.pm for 1-Wire via OWFS added (Martin Fischer)
|
||||
- feature: 21_OWTEMP.pm for 1-Wire Digital Thermometer added (Martin Fischer)
|
||||
- feature: CUL_FHTTK from Kai
|
||||
|
@ -54,15 +54,16 @@ CUL_Initialize($)
|
||||
# Provider
|
||||
$hash->{ReadFn} = "CUL_Read";
|
||||
$hash->{WriteFn} = "CUL_Write";
|
||||
$hash->{Clients} = ":FS20:FHT:KS300:CUL_EM:CUL_WS:USF1000:HMS:";
|
||||
$hash->{Clients} = ":FS20:FHT:KS300:CUL_EM:CUL_WS:USF1000:HMS:CUL_FHTTK:";
|
||||
my %mc = (
|
||||
"1:USF1000" => "^81..(04|0c)..0101a001a5ceaa00....",
|
||||
"2:FS20" => "^81..(04|0c)..0101a001",
|
||||
"3:FHT" => "^81..(04|09|0d)..(0909a001|83098301|c409c401)..",
|
||||
"4:KS300" => "^810d04..4027a001",
|
||||
"5:CUL_WS" => "^K.....",
|
||||
"6:CUL_EM" => "^E0.................\$",
|
||||
"7:HMS" => "^810e04....(1|5|9).a001",
|
||||
"1:USF1000" => "^81..(04|0c)..0101a001a5ceaa00....",
|
||||
"2:FS20" => "^81..(04|0c)..0101a001",
|
||||
"3:FHT" => "^81..(04|09|0d)..(0909a001|83098301|c409c401)..",
|
||||
"4:KS300" => "^810d04..4027a001",
|
||||
"5:CUL_WS" => "^K.....",
|
||||
"6:CUL_EM" => "^E0.................\$",
|
||||
"7:HMS" => "^810e04....(1|5|9).a001",
|
||||
"8:CUL_FHTTK" => "^T........",
|
||||
);
|
||||
$hash->{MatchList} = \%mc;
|
||||
$hash->{ReadyFn} = "CUL_Ready";
|
||||
@ -714,11 +715,16 @@ CUL_Read($)
|
||||
$len/2+7, substr($dmsg,1,6), substr($dmsg,7));
|
||||
$dmsg = lc($dmsg);
|
||||
|
||||
} elsif($fn eq "T" && $len >= 11) { # Reformat for 11_FHT.pm
|
||||
} elsif($fn eq "T") {
|
||||
if ($len >= 11) { # Reformat for 11_FHT.pm
|
||||
$dmsg = sprintf("81%02x04xx0909a001%s00%s",
|
||||
$len/2+7, substr($dmsg,1,6), substr($dmsg,7));
|
||||
$dmsg = lc($dmsg);
|
||||
|
||||
$dmsg = sprintf("81%02x04xx0909a001%s00%s",
|
||||
$len/2+7, substr($dmsg,1,6), substr($dmsg,7));
|
||||
$dmsg = lc($dmsg);
|
||||
} else {
|
||||
; # => 09_CUL_FHTTK.pm
|
||||
|
||||
}
|
||||
|
||||
} elsif($fn eq "H" && $len >= 13) { # Reformat for 12_HMS.pm
|
||||
|
||||
|
250
fhem/FHEM/09_CUL_FHTTK.pm
Normal file
250
fhem/FHEM/09_CUL_FHTTK.pm
Normal file
@ -0,0 +1,250 @@
|
||||
#
|
||||
# 09_CUL_FHTTK.pm
|
||||
#
|
||||
# A module for FHEM to handle ELV's FHT80 TF-type sensors
|
||||
# written by Kai 'wusel' Siering, 2009-11-06 with help
|
||||
# from previously written FHEM code as well as members
|
||||
# of fhem-users at googlegroups.com! Thanks, guys!
|
||||
#
|
||||
# e-mail: wusel+source at uu punkt org
|
||||
#
|
||||
# This module reads, despite setting an IODev explicitely,
|
||||
# from any (CUL-) source and drops any identical message
|
||||
# arriving within 5 seconds. It does handle the automatic
|
||||
# retransmission of FHT80 TF as well as concurrent recep-
|
||||
# tion from multiple sources; in my system, it could happen
|
||||
# that the CUL in the same room "overhears" a telegram from
|
||||
# FHT80 TF (most likely due to other messages sent/received
|
||||
# at the same time) but the one downstairs still picks it up.
|
||||
# My implementation should be safe for the device in question,
|
||||
# if you see problems, the "only on this IODev"-code is still
|
||||
# in place but commented out.
|
||||
#
|
||||
#
|
||||
# Note: The sensor in question is named "FHT80 TF",
|
||||
# in it's (formerly current, now old) design it looks
|
||||
# similar to "FS20 TFK" but operates differently.
|
||||
#
|
||||
# FHT80 TF is designed to serve as a sensor to FHT80 B,
|
||||
# only the B receives TF's transmissions (after made
|
||||
# known to each FHT80 B) normally. The B then, if in-
|
||||
# structed that way, turns down the heating while any
|
||||
# of the TFs known to it signal "Window open". The TF
|
||||
# transmits about every 255 seconds a telegram stating
|
||||
# whether or nor the (reed-) contact is open (which
|
||||
# means Window or Door, relevant for heating, open)
|
||||
# and whether the battery is still full enough.
|
||||
#
|
||||
# The FS20 TFK on the other hand just directly addresses
|
||||
# another FS20 device on opening/closing of it's (reed-)
|
||||
# contact.
|
||||
#
|
||||
# Finally, the HMS100 TFK is designed to notify a HMS-
|
||||
# central about opened/closed contacts immediately,
|
||||
# but you can't directly address FS20 devices ...
|
||||
#
|
||||
# So, to notify e. g. FHEM instantly about opening
|
||||
# or closure of doors/windows, your best buy might be
|
||||
# an HMS100 TFK (as of this writing EUR 29,95 @ ELV).
|
||||
# You could use an FS20 TFK as well (EUR 34,95 @ ELV),
|
||||
# that way you could directly have FS20 switches act
|
||||
# on opened/closed doors or windows in parallel or
|
||||
# even without FHEM. The FHT80 TF (as eQ-3 FHT 80 TF
|
||||
# currently for EUR 14,95 available @ ELV) only sends
|
||||
# out a status telegram every ca. 2,5 minutes, so it's
|
||||
# ok for seeing where one might have left a window
|
||||
# open before leaving the house but by no means suit-
|
||||
# able for any alerting uses (unless a delay of said
|
||||
# amount of time doesn't matter, of course ;)).
|
||||
#
|
||||
##############################################
|
||||
package main;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my %fhttfk_codes = (
|
||||
"02" => "Window:Closed",
|
||||
"82" => "Window:Closed",
|
||||
"01" => "Window:Open",
|
||||
"81" => "Window:Open",
|
||||
"0c" => "Sync:Syncing",
|
||||
"91" => "Window:Open, Low Batt",
|
||||
"11" => "Window:Open, Low Batt",
|
||||
"92" => "Window:Closed, Low Batt",
|
||||
"12" => "Window:Closed, Low Batt",
|
||||
"0f" => "Test:Success");
|
||||
my %defptr;
|
||||
|
||||
# -wusel, 2009-11-09: Map retransmission codes to major (8x) ones (0x)
|
||||
# As I'm somewhat lazy, I just list all codes from
|
||||
# %fhttfk_codes and map them to their major one.
|
||||
# (FIXME: it would be sufficient to have %fhttfk_codes
|
||||
# only list these major, "translated" ones.)
|
||||
my %fhttfk_translatedcodes = (
|
||||
"01" => "01",
|
||||
"11" => "11",
|
||||
"12" => "12",
|
||||
"02" => "02",
|
||||
"0c" => "0c",
|
||||
"0f" => "0f",
|
||||
"81" => "01",
|
||||
"82" => "02",
|
||||
"91" => "11",
|
||||
"92" => "12");
|
||||
|
||||
# -wusel, 2009-11-06
|
||||
#
|
||||
# Parse messages from FHT80TK, normally interpreted only by FHT80
|
||||
#
|
||||
# Format as follows: "TCCCCCCXX" with CCCCCC being the id of the
|
||||
# sensor in hex, XX being the current status: 02/82 is Window
|
||||
# closes, 01/81 is Window open, 0C is synchronization, ?? is the
|
||||
# battery low warning. FIXME!
|
||||
|
||||
|
||||
#############################
|
||||
sub
|
||||
CUL_FHTTK_Initialize($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
|
||||
$hash->{Match} = "^T........";
|
||||
$hash->{DefFn} = "CUL_FHTTK_Define";
|
||||
$hash->{UndefFn} = "CUL_FHTTK_Undef";
|
||||
$hash->{ParseFn} = "CUL_FHTTK_Parse";
|
||||
$hash->{AttrList} = "IODev do_not_notify:1,0 showtime:0,1 dummy:1,0 model:FHT80TF loglevel:0,1,2,3,4,5,6";
|
||||
}
|
||||
|
||||
|
||||
#############################
|
||||
sub
|
||||
CUL_FHTTK_Define($$)
|
||||
{
|
||||
my ($hash, $def) = @_;
|
||||
my @a = split("[ \t][ \t]*", $def);
|
||||
|
||||
my $u= "wrong syntax: define <name> CUL_FHTTK <sensor>";
|
||||
return $u if((int(@a)< 3) || (int(@a)>3));
|
||||
|
||||
my $name = $a[0];
|
||||
my $sensor = lc($a[2]);
|
||||
if($sensor !~ /[0123456789abcdef]/) {
|
||||
return "erroneous sensor specification $sensor, use one of 0..9..f";
|
||||
}
|
||||
|
||||
# $hash->{SENSOR}= "$sensor";
|
||||
$hash->{CODE} = $sensor;
|
||||
$defptr{$sensor} = $hash;
|
||||
# $defs{$hash}{READINGS}{PREV}{STATE}="00";
|
||||
# $defs{$hash}{READINGS}{PREV}{TIMESTAMP} = localtime();
|
||||
AssignIoPort($hash);
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
||||
#############################
|
||||
sub
|
||||
CUL_FHTTK_Undef($$)
|
||||
{
|
||||
my ($hash, $name) = @_;
|
||||
delete($defptr{$hash->{CODE}}) if($hash && $hash->{CODE});
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
||||
#############################
|
||||
sub
|
||||
CUL_FHTTK_Parse($$)
|
||||
{
|
||||
my ($hash, $msg) = @_;
|
||||
|
||||
my $sensor= lc(substr($msg, 1, 6));
|
||||
my $state = lc(substr($msg, 7, 2));
|
||||
my $def = $defptr{$sensor};
|
||||
my $self = $def->{NAME};
|
||||
if(!defined($def)) {
|
||||
Log 3, sprintf("FHTTK Unknown device %s, please define it", $sensor);
|
||||
return "UNDEFINED FHTTK";
|
||||
}
|
||||
|
||||
# if it's not our device
|
||||
# if($def->{IODev} && $def->{IODev}{NAME} ne $hash->{NAME}) {
|
||||
# Log 3, sprintf("skipping device %s on this receiver", $sensor);
|
||||
# return "";
|
||||
# }
|
||||
|
||||
if(!defined($fhttfk_translatedcodes{$state})) {
|
||||
Log 3, sprintf("FHTTK $def Unknown state $state");
|
||||
$defs{$self}{READINGS}{"Unknown"}{VAL} = $state;
|
||||
$defs{$self}{READINGS}{"Unknown"}{TIME} = TimeNow();
|
||||
return "";
|
||||
}
|
||||
|
||||
# Log 3, sprintf("FHTTK Translating $state into %s", $fhttfk_translatedcodes{$state});
|
||||
$state=$fhttfk_translatedcodes{$state};
|
||||
# PREVIOUS
|
||||
# FIXME: Message regarded as similar if last char is identical; sure that's always
|
||||
# the differentiator? -wusel, 2009-11-09
|
||||
if(defined($defs{$self}{READINGS}{PREV}{TIMESTAMP})) {
|
||||
if($defs{$self}{READINGS}{PREV}{TIMESTAMP} > time()-5) {
|
||||
if(defined($defs{$self}{READINGS}{PREV}{STATE})) {
|
||||
if($defs{$self}{READINGS}{PREV}{STATE} eq $state) {
|
||||
Log 3, sprintf("FHTTK skipping state $state as last similar telegram was received less than 5 secs ago", $defs{$self}{READINGS}{PREV}{STATE});
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$def->{PREVTIMESTAMP} = defined($defs{$self}{READINGS}{PREV}{TIMESTAMP})?$defs{$self}{READINGS}{PREV}{TIMESTAMP}:time();
|
||||
$def->{PREVSTATE} = defined($def->{STATE})?$def->{STATE}:"Unknown";
|
||||
$defs{$self}{READINGS}{PREV}{STATE}=$state;
|
||||
#READINGS
|
||||
my ($reading,$val) = split(/:/, $fhttfk_codes{$state});
|
||||
$defs{$self}{READINGS}{$reading}{VAL} = $val;
|
||||
$defs{$self}{READINGS}{$reading}{TIME} = TimeNow();
|
||||
$defs{$self}{READINGS}{PREV}{TIMESTAMP} = time();
|
||||
# -wusel, 2009-11-09: According to http://fhz4linux.info/tiki-index.php?page=FHT+protocol,
|
||||
# FHT80TF usually transmitts between 60 and 240 seconds. (255-256 sec in
|
||||
# my experience ...) If we got no fresh data for over 5 minutes (300 sec),
|
||||
# flag this.
|
||||
if($defs{$self}{READINGS}{PREV}{TIMESTAMP}+720 < time()) {
|
||||
$defs{$self}{READINGS}{"Reliability"}{VAL} = "dead";
|
||||
$defs{$self}{READINGS}{"Reliability"}{TIME} = TimeNow();
|
||||
} elsif($defs{$self}{READINGS}{PREV}{TIMESTAMP}+600 < time()) {
|
||||
$defs{$self}{READINGS}{"Reliability"}{VAL} = "low";
|
||||
$defs{$self}{READINGS}{"Reliability"}{TIME} = TimeNow();
|
||||
} elsif($defs{$self}{READINGS}{PREV}{TIMESTAMP}+300 < time()) {
|
||||
$defs{$self}{READINGS}{"Reliability"}{VAL} = "medium";
|
||||
$defs{$self}{READINGS}{"Reliability"}{TIME} = TimeNow();
|
||||
} else {
|
||||
undef($defs{$self}{READINGS}{"Reliability"}{VAL});
|
||||
undef($defs{$self}{READINGS}{"Reliability"}{TIME});
|
||||
undef($defs{$self}{READINGS}{"Reliability"});
|
||||
}
|
||||
# Flag the battery warning separately
|
||||
if($state eq "11" || $state eq "12") {
|
||||
$defs{$self}{READINGS}{"Battery"}{VAL} = "Low";
|
||||
$defs{$self}{READINGS}{"Battery"}{TIME} = TimeNow();
|
||||
$defs{$self}{READINGS}{"Warning"}{VAL} = "Battery Low";
|
||||
$defs{$self}{READINGS}{"Warning"}{TIME} = TimeNow();
|
||||
} else {
|
||||
undef($defs{$self}{READINGS}{"Battery"}{VAL});
|
||||
undef($defs{$self}{READINGS}{"Battery"}{TIME});
|
||||
undef($defs{$self}{READINGS}{"Battery"});
|
||||
undef($defs{$self}{READINGS}{"Warning"}{VAL});
|
||||
undef($defs{$self}{READINGS}{"Warning"}{TIME});
|
||||
undef($defs{$self}{READINGS}{"Warning"});
|
||||
}
|
||||
#CHANGED
|
||||
$defs{$self}{CHANGED}[0] = $reading . ": " . $val;
|
||||
$def->{STATE} = $val;
|
||||
$def->{OPEN} = lc($val) eq "open" ? 1 : 0;
|
||||
Log GetLogLevel($def->{NAME},4), "FHTTK Device $self ($reading: $val)";
|
||||
|
||||
return $def->{NAME};
|
||||
}
|
||||
|
||||
#############################
|
||||
|
||||
1;
|
@ -53,6 +53,7 @@
|
||||
<a href="#CM11">CM11</a>
|
||||
<a href="#CUL">CUL</a>
|
||||
<a href="#CUL_EM">CUL_EM</a>
|
||||
<a href="#CUL_FHTTK">CUL_FHTTK</a>
|
||||
<a href="#CUL_WS">CUL_WS</a>
|
||||
<a href="#DbLog">DbLog</a>
|
||||
<a href="#EM">EM</a>
|
||||
@ -1203,7 +1204,7 @@ A line ending with \ will be concatenated with the next one, so long lines
|
||||
devices:<br><br>
|
||||
<b>Sender/Sensor</b>: fs20hgs fs20ls fs20pira fs20piri fs20s20 fs20s8
|
||||
fs20s4 fs20s4a fs20s4m fs20s4u fs20s4ub fs20sd fs20sn fs20sr fs20ss
|
||||
fs20str fs20tfk fs20tfk fs20tk fs20uts fs20ze<br><br>
|
||||
fs20str fs20tfk fs20tk fs20uts fs20ze<br><br>
|
||||
|
||||
<b>Receiver/Actor</b>: fs20as1 fs20as4 fs20di fs20du fs20ms2
|
||||
fs20rst fs20sa fs20sig fs20st fs20sv fs20sv fs20usr
|
||||
@ -1462,6 +1463,60 @@ A line ending with \ will be concatenated with the next one, so long lines
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
<a name="CUL_FHTTK"></a>
|
||||
<h3>CUL_FHTTK</h3>
|
||||
<ul>
|
||||
This module handles messages from the FHT80 TF "Fenster-Tür-Kontakt" (Window-Door-Contact)
|
||||
which are normally only acted upon by the <a href="#FHT">FHT80B</a>. With this module,
|
||||
FHT80 TFs are in a limited way (see <a href="http://fhz4linux.info/tiki-index.php?page=FHT+protocol">Wiki</a>
|
||||
for detailed explanation of TF's mode of operation) usable similar to HMS100 TFK. The name
|
||||
of the module was chosen as a) only CUL will spill out the datagrams and b) "TF" designates
|
||||
usually temperature+humidity sensors (no clue, why ELV didn't label this one "TFK" like with
|
||||
FS20 and HMS).<br><br>
|
||||
As said before, FHEM can receive FHT80 TF radio (868.35 MHz) messages only through an
|
||||
<a href="#CUL">CUL</a> device, so this must be defined first.<br><br>
|
||||
|
||||
<a name="CUL_FHTTKdefine"></a>
|
||||
<b>Define</b>
|
||||
<ul>
|
||||
<code>define <name> CUL_FHTTK <devicecode></code>
|
||||
<br><br>
|
||||
|
||||
<code><devicecode></code> is a six digit hex number, given to the FHT80 TF during
|
||||
production, i. e. it is not changeable. (Yes, it keeps this code after changing batteries
|
||||
as well.)<br>
|
||||
|
||||
Examples:
|
||||
<ul>
|
||||
<code>define TK_TEST CUL_FHTTK 965AB0</code>
|
||||
</ul>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<a name="CUL_FHTTKset"></a>
|
||||
<b>Set </b>
|
||||
<ul> Nothing to set here yet ... </ul>
|
||||
<br>
|
||||
|
||||
<b>Get</b>
|
||||
<ul> No get implemented yet ...
|
||||
</ul><br>
|
||||
|
||||
<b>Attributes</b>
|
||||
<ul>
|
||||
<li><a href="#do_not_notify">do_not_notify</a></li><br>
|
||||
<li><a href="#attrdummy">dummy</a></li><br>
|
||||
<li><a href="#loglevel">loglevel</a></li><br>
|
||||
<li><a href="#model">model</a> (FHT80TF)</li><br>
|
||||
<li><a href="#showtime">showtime</a></li><br>
|
||||
<li><a href="#IODev">IODev</a></li><br>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
<a name="HMS"></a>
|
||||
<h3>HMS</h3>
|
||||
<ul>
|
||||
|
Loading…
x
Reference in New Issue
Block a user