2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-03 04:36:36 +00:00

Internal parsing rewrite, Sending data should work now

git-svn-id: https://svn.fhem.de/fhem/trunk@606 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
rudolfkoenig 2010-03-28 15:11:26 +00:00
parent 7eb5d9deb1
commit 4280910524

View File

@ -1,4 +1,10 @@
##############################################
# Thx to Himtronics
# http://www.mikrocontroller.net/topic/141831
# http://www.mikrocontroller.net/attachment/63563/km271-protokoll.txt
# Buderus documents: 63011376, 63011377, 63011378
# e.g. http://www.buderus.de/pdf/unterlagen/0063061377.pdf
package main;
use strict;
@ -12,148 +18,161 @@ sub KM271_CloseDev($);
sub KM271_SimpleWrite(@);
sub KM271_SimpleRead($);
sub KM271_crc($);
sub KM271_setbits($$$);
sub KM271_Reading($$);
my $stx = pack('H*', "02");
my $dle = pack('H*', "10");
my $etx = pack('H*', "03");
my $nak = pack('H*', "15");
my $logmode = pack('H*', "EE00001003FD");
# Thx to Himtronics
# http://www.mikrocontroller.net/topic/141831
# http://www.mikrocontroller.net/attachment/63563/km271-protokoll.txt
# Buderus documents: 63011376, 63011377, 63011378
# http://www.buderus.de/pdf/unterlagen/0063061377.pdf
my %km271_trhash =
(
"007e" => "Manuell_WW",
"0085" => "Manuell_ZirkulationsPumpe",
"0093" => "Manuell_Uhrzeit",
"0300" => "Tagwechsel_1",
"0307" => "Tagwechsel_2",
"030e" => "Tagwechsel_3",
"0315" => "Tagwechsel_4",
"0400" => "NoData",
"8000" => 'HK1_Betriebswerte1', # 76, 4 [repeat]
"8001" => 'HK1_Betriebswerte2', # 0 (22:33), 2 (7:33)
"8002" => 'HK1_Vorlaufsolltemperatur', # 50-65
"8003" => 'HK1_Vorlaufisttemperatur', # Schwingt um soll herum
"8004" => 'HK1_Raumsolltemperatur', # 34 (22:33) 42 (7:33)
"8005" => 'HK1_Raumisttemperatur',
"8006" => 'HK1_Einschaltoptimierungszeit',
"8007" => 'HK1_Ausschaltoptimierungszeit',
"8008" => 'HK1_Pumpenleistung', # 0/100 == Ladepumpe
"8009" => 'HK1_Mischerstellung',
"800c" => 'HK1_Heizkennlinie_bei_+_10_Grad', # bei Umschaltung tag/nacht
"800d" => 'HK1_Heizkennlinie_bei_0_Grad', # bei Umschaltung tag/nacht
"800e" => 'HK1_Heizkennlinie_bei_-_10_Grad', # bei Umschaltung tag/nacht
"8112" => 'HK2_Betriebswerte1',
"8113" => 'HK2_Betriebswerte2',
"8114" => 'HK2_Vorlaufsolltemperatur',
"8115" => 'HK2_Vorlaufisttemperatur',
"8116" => 'HK2_Raumsolltemperatur',
"8117" => 'HK2_Raumisttemperatur',
"8118" => 'HK2_Einschaltoptimierungszeit',
"8119" => 'HK2_Ausschaltoptimierungszeit',
"811a" => 'HK2_Pumpenleistung',
"811b" => 'HK2_Mischerstellung',
"811e" => 'HK2_Heizkennlinie_bei_+_10_Grad', # == HK1 - (1 bis 3 Grad)
"811f" => 'HK2_Heizkennlinie_bei_0_Grad', # == HK1 - (1 bis 3 Grad)
"8120" => 'HK2_Heizkennlinie_bei_-_10_Grad', # == HK1 - (1 bis 3 Grad)
# 1377, page 11
"8424" => 'WW_Betriebswerte1',
"8425" => 'WW_Betriebswerte2', # 0 64 96 104 225 228
"8426" => 'WW_Solltemperatur', # 10/55
"8427" => 'WW_Isttemperatur', # 32-55
"8428" => 'WW_Einschaltoptimierungszeit',
"8429" => 'WW_Ladepumpe', # 0 1 (an/aus?)
# 1377, page 13
"882a" => 'Kessel_Vorlaufsolltemperatur',
"882b" => 'Kessel_Vorlaufisttemperatur', # == Vorlaufisttemperatur_HK1
"882c" => 'Brenner_Einschalttemperatur', # 5-81
"882d" => 'Brenner_Ausschalttemperatur', # 19-85
"882e" => 'Kessel_IntegralHB', # 0-23
"882f" => 'Kessel_IntegralLB', # 0-255
"8830" => 'Kessel_Fehler',
"8831" => 'Kessel_Betrieb', # 0 2 32 34
"8832" => 'Brenner_Ansteuerung', # 0 1 (an/aus?)
"8833" => 'Abgastemperatur',
"8834" => 'Brenner_Stellwert',
"8836" => 'Brenner_Laufzeit1_Minuten2',
"8837" => 'Brenner_Laufzeit1_Minuten1', # 176
"8838" => 'Brenner_Laufzeit1_Minuten0', # 0-255 (Minuten)
"8839" => 'Brenner_Laufzeit2_Minuten2',
"883a" => 'Brenner_Laufzeit2_Minuten1',
"883b" => 'Brenner_Laufzeit2_Minuten0',
# 1377, page 16
"893c" => 'Aussentemperatur', # 0 1 254 255
"893d" => 'Aussentemperatur_gedaempft', # 0 1 2
"893e" => 'Versionsnummer_VK',
"893f" => 'Versionsnummer_NK',
"8940" => 'Modulkennung',
);
# Do not generate fhem events for the following high volume telegrams
# the % represents the relative nr of messages in an unfiltered stream.
# You can switch them on with attr all_km271_events
my %km271_noevent = (
"HK1_Vorlaufisttemperatur" => 1, # 23% of all messages
"HK2_Vorlaufisttemperatur" => 1,
"Kesselvorlaufisttemperatur" => 1, # 23%, same as Vorlaufisttemperatur_HK1
"Kessel_IntegralHB" => 1, # 8%, ??
"Kessel_IntegralLB" => 1, # 38%, ??
);
my @km271_HK_Betriebswerte1 = (
"Ausschaltoptimierung", "Einschaltoptimierung", "Automatik",
"Warmwasservorrang", "Estrichtrocknung", "Ferien", "Frostschutz", "Manuell",
);
my @km271_HK_Betriebswerte2 = (
"Sommer", "Tag", "keine Kommunikation mit FB", "FB fehlerhhaft",
"Fehler Vorlauffühler", "maximaler Vorlauf", "externer Störeingang", "frei",
);
my @km271_WW_Betriebswerte1 = (
"Automatik", "Desinfektion", "Nachladung", "Ferien", "Fehler Desinfektion",
"Fehler Fuehler", "Fehler WW bleibt kalt", "Fehler Anode",
);
my @km271_WW_Betriebswerte2 = (
"Laden", "Manuell", "Nachladen", "Ausschaltoptimierung",
"Einschaltoptimierung", "Tag", "Warm", "Vorrang",
);
my @km271_Kessel_Betrieb = (
"Tag", "Automatik", "Sommer", "Bit3", "Bit4", "Bit5", "Bit6", "Bit7",
);
my @km271_WW_Ladepumpe = (
"Ladepumpe", "Zirkulationspumpe", "Absenkung Solar",
"Bit3", "Bit4", "Bit5", "Bit6", "Bit7",
);
my %km271_set_betriebsart = (
"manuell_nacht"=>0,
"manuell_tag" =>1,
"automatik" =>2,
);
sub KM271_setbits($$);
sub KM271_GetReading($$);
sub KM271_SetReading($$$$$);
my %km271_sets = (
"hk1_nachtsoll" => "07006565%02x656565", # 0.5 celsius
"hk1_tagsoll" => "0700656565%02x6565", # 0.5 celsius
"hk1_betriebsart" => "070065656565%02x65",
"ww_soll" => "0C07656565%02x6565", # 1.0 celsius
"ww_betriebsart" => "0C0E%02x6565656565",
"logmode" => "EE0000",
);
# Message address:byte_offset in the message
# Attributes:
# d:x (divide), p:x (add), bf:x (bitfield), a:x (array) ne (generate no event)
# mb:x (multi-byte-message, x-bytes, low byte), s (signed value)
my %km271_tr = (
"CFG_SommerAb" => "0000:1", # 6510242a021e
"CFG_Raum_Temp_Nacht" => "0000:2,d:2",
"CFG_Raum_Temp_Tag" => "0000:3,d:2",
"CFG_Betriebsart" => "0000:4,a:4",
"CFG_Auslegung" => "000e:4", # 01045a054d65
"CFG_FrostAb" => "0015:2", # 030104650005
"CFG_Raum_Temp_Aufschalt" => "0015:0,s",
"CFG_Absenkungsart" => "001c:1,a:6", # 0c0101656565
"CFG_Fernbedienung" => "0031:4,a:0", # 656565fc0104
"CFG_Raum_Temp_Offset" => "0031:3,s", #
"CFG_GebaeudeArt" => "0070:2,p:1", # f66502066565
"CFG_WW_Temperatur" => "007e:3", # 65fb28373c65
"CFG_ZirkPumpe" => "0085:5", # 026565016502
"CFG_Warmwasser" => "0085:3,a:0",
"CFG_Display_Lang" => "0093:0,a:3", # 000302656565
"CFG_Display" => "0093:1,a:1",
"CFG_MaxAus" => "009a:3", # 65016554050c
"CFG_PumpLogik" => "00a1:0", # 2a0565656509
"CFG_Abgastemp" => "00a1:5,p:-9,a:5",
"CFG_Programm" => "0100:0,a:2", # 01ffff00ffff
"CFG_UrlaubsTage" => "0169:3", # 01ffff03ffff
"CFG_UhrDiff" => "01e0:1,s", # 010065656565
"HK1_Betriebswerte1" => "8000:0,bf:0",
"HK1_Betriebswerte2" => "8001:0,bf:1",
"HK1_Vorlaufsolltemperatur" => "8002:0",
"HK1_Vorlaufisttemperatur" => "8003:0,ne", # 23% of all messages
"HK1_Raumsolltemperatur" => "8004:0,d:2",
"HK1_Raumisttemperatur" => "8005:0,d:2",
"HK1_Einschaltoptimierungszeit" => "8006:0",
"HK1_Ausschaltoptimierungszeit" => "8007:0",
"HK1_Pumpenleistung" => "8008:0",
"HK1_Mischerstellung" => "8009:0",
"HK1_Heizkennlinie_bei_+_10_Grad" => "800c:0",
"HK1_Heizkennlinie_bei_0_Grad" => "800d:0",
"HK1_Heizkennlinie_bei_-_10_Grad" => "800e:0",
"HK2_Betriebswerte1" => "8112:0,bf:0",
"HK2_Betriebswerte2" => "8113:0,bf:1",
"HK2_Vorlaufsolltemperatur" => "8114:0",
"HK2_Vorlaufisttemperatur" => "8115:0,ne",
"HK2_Raumsolltemperatur" => "8116:0,d:2",
"HK2_Raumisttemperatur" => "8117:0,d:2",
"HK2_Einschaltoptimierungszeit" => "8118:0",
"HK2_Ausschaltoptimierungszeit" => "8119:0",
"HK2_Pumpenleistung" => "811a:0",
"HK2_Mischerstellung" => "811b:0",
"HK2_Heizkennlinie_bei_+_10_Grad" => "811e:0",
"HK2_Heizkennlinie_bei_0_Grad" => "811f:0",
"HK2_Heizkennlinie_bei_-_10_Grad" => "8120:0",
"WW_Betriebswerte1" => "8424:0,bf:2",
"WW_Betriebswerte2" => "8425:0,bf:3",
"WW_Solltemperatur" => "8426:0",
"WW_Isttemperatur" => "8427:0",
"WW_Einschaltoptimierungszeit" => "8428:0",
"WW_Ladepumpe" => "8429:0,bf:5",
"Kessel_Vorlaufsolltemperatur" => "882a:0",
"Kessel_Vorlaufisttemperatur" => "882b:0,ne", # 23% of all messages
"Brenner_Einschalttemperatur" => "882c:0",
"Brenner_Ausschalttemperatur" => "882d:0",
"Kessel_Integral1" => "882e:0,ne",
"Kessel_Integral" => "882f:0,ne,mb:2", # 46% of all messages
"Kessel_Fehler" => "8830:0,bf:6",
"Kessel_Betrieb" => "8831:0,bf:4",
"Brenner_Ansteuerung" => "8832:0,a:0",
"Abgastemperatur" => "8833:0",
"Brenner_Stellwert" => "8834:0",
"Brenner_Laufzeit1_Minuten2" => "8836:0,ne",
"Brenner_Laufzeit1_Minuten1" => "8837:0,ne",
"Brenner_Laufzeit1_Minuten" => "8838:0,ne,mb:3",
"Brenner_Laufzeit2_Minuten2" => "8839:0,ne",
"Brenner_Laufzeit2_Minuten1" => "883a:0,ne",
"Brenner_Laufzeit2_Minuten" => "883b:0,ne:mb:3",
"Aussentemperatur" => "893c:0,s",
"Aussentemperatur_gedaempft" => "893d:0,s",
"Versionsnummer_VK" => "893e:0",
"Versionsnummer_NK" => "893f:0",
"Modulkennung" => "8940:0",
);
my %km271_rev;
my @km271_bitarrays = (
# 0 - HK_Betriebswerte1
[ "leer", "Ausschaltoptimierung", "Einschaltoptimierung", "Automatik",
"Warmwasservorrang", "Estrichtrocknung", "Ferien", "Frostschutz",
"Manuell" ],
# 1 - HK_Betriebswerte2
[ "leer", "Sommer", "Tag", "keine Kommunikation mit FB", "FB fehlerhaft",
"Fehler Vorlauffuehler", "maximaler Vorlauf",
"externer Stoehreingang", "frei" ],
# 2 - WW_Betriebswerte1
[ "aus", "Automatik", "Desinfektion", "Nachladung", "Ferien",
"Fehler Desinfektion", "Fehler Fuehler", "Fehler WW bleibt kalt",
"Fehler Anode" ],
# 3 - WW_Betriebswerte2
[ "aus", "Laden", "Manuell", "Nachladen", "Ausschaltoptimierung",
"Einschaltoptimierung", "Tag", "Warm", "Vorrang" ],
# 4 - Kessel_Betrieb
[ "aus", "Tag", "Automatik", "Sommer",
"Bit3", "Bit4", "Bit5", "Bit6", "Bit7" ],
# 5 - WW_Ladepumpe
[ "aus", "Ladepumpe", "Zirkulationspumpe", "Absenkung Solar",
"Bit3", "Bit4", "Bit5", "Bit6", "Bit7" ],
# 6 - Kessel_Fehler
[ "keine", "Bit1", "Bit2", "Bit3", "Bit4",
"Abgastemperatur ueberschritten", "Bit6", "Bit7" ],
);
my @km271_arrays = (
# 0 - Brenner_Ansteuerung , CFG_Fernbedienung, CFG_Warmwasser
[ "aus", "an" ],
# 1 - CFG_Display
[ "Automatik", "Kessel", "Warmwasser", "Aussen" ],
# 2 - CFG_Programm
[ "Eigen1", "Familie", "Frueh", "Spaet", "Vormit", "Nachmit",
"Mittag", "Single", "Senior" ],
# 3 - CFG_Display_Lang
[ "DE", "FR", "IT", "NL", "EN", "PL" ],
# 4 - CFG_Betriebsart
[ "Nacht", "Tag", "Automatik" ],
# 5 - CFG_Abgastemp
[ "Aus","50","55","60","65","70","75","80","85","90","95","100","105",
"110","115","120","125","130","135","140","145","150","155","160","165",
"170","175","180","185","190","195","200","205","210","215","220","225",
"230","235","240","245","250" ],
# 6 - CFG_Absenkungsart
[ "Abschalt","Reduziert","Raumhal","Aussenhal"]
);
my %km271_set_betriebsart = (
"nacht" => 0,
"tag" => 1,
"automatik" => 2,
);
sub
@ -170,6 +189,13 @@ KM271_Initialize($)
$hash->{AttrList}= "do_not_notify:1,0 all_km271_events loglevel:0,1,2,3,4,5,6";
my @a = ();
$hash->{SENDBUFFER} = \@a;
%km271_rev = ();
foreach my $k (sort keys %km271_tr) { # Reverse map
my $v = $km271_tr{$k};
my ($addr, $b) = split("[:,]", $v);
$km271_rev{$addr}{$b} = $k;
}
}
#####################################
@ -212,30 +238,38 @@ KM271_Set($@)
{
my ($hash, @a) = @_;
return "\"set KM271\" needs at least one parameter" if(@a < 2);
return "\"set KM271\" needs at least an argument" if(@a < 2);
my $fmt = $km271_sets{$a[1]};
return "Unknown argument $a[1], choose one of " .
join(" ", sort keys %km271_sets) if(!defined($fmt));
my $val = $a[2];
my $numeric_arg = ($val =~ m/^[.0-9]+$/);
my ($val, $numeric_val);
if($fmt =~ m/%/) {
return "\"set KM271 $a[1]\" needs at least one parameter" if(@a < 3);
$val = $a[2];
$numeric_val = ($val =~ m/^[.0-9]+$/);
}
if($a[1] =~ m/^hk.*soll$/) {
return "Argument must be numeric (between 10 and 30)" if(!$numeric_arg);
return "Argument must be numeric (between 10 and 30)" if(!$numeric_val);
$val *= 2;
}
if($a[1] =~ m/^ww.*soll$/) {
return "Argument must be numeric (between 30 and 60)" if(!$numeric_arg);
return "Argument must be numeric (between 30 and 60)" if(!$numeric_val);
}
if($a[1] =~ m/_betriebsart/) {
$val = $km271_set_betriebsart{$val};
return "Unknown arg, use one of " .
join(" ", sort keys %km271_set_betriebsart) if(!defined($val));
}
my $data = sprintf($fmt, $val);
my $data = ($val ? sprintf($fmt, $val) : $fmt);
push @{$hash->{SENDBUFFER}}, $data;
KM271_SimpleWrite($hash, $stx) if(!$hash->{WAITING});
KM271_SimpleWrite($hash, "02") if(!$hash->{WAITING});
return undef;
}
@ -251,7 +285,7 @@ KM271_Read($)
my ($data, $crc);
my $buf = KM271_SimpleRead($hash);
Log GetLogLevel($name,5), "KM271 RAW: " . unpack('H*', $buf);
Log 5, "KM271RAW: " . unpack('H*', $buf);
if(!defined($buf)) {
Log 1, "$name: EOF";
@ -259,32 +293,40 @@ KM271_Read($)
return;
}
if($buf eq "02") { # KM271: Want to send
$hash->{PARTIAL} = "";
KM271_SimpleWrite($hash, $dle); # We are ready
$hash->{WAITING} = 1;
return;
}
$buf = unpack('H*', $buf);
if(!$hash->{WAITING}) { # Send data
if(@{$hash->{SENDBUFFER}} || $hash->{DATASENT}) { # Send data
if($buf eq "02") { # KM271 Wants to send, override
KM271_SimpleWrite($hash, "02");
return;
}
if($buf eq "10") {
if($hash->{DATASENT}) { # ACK Data
if($hash->{DATASENT}) {
delete($hash->{DATASENT});
KM271_SimpleWrite($hash, "02") if(@{$hash->{SENDBUFFER}});
return;
}
$data = pop @{ $hash->{SENDBUFFER} };
$data =~ s/10/1010/g;
$crc = KM271_crc($data);
KM271_SimpleWrite($hash, $data."1003$crc"); # Send the data
$hash->{DATASENT} = 1;
}
if($buf eq "15" && $hash->{DATASENT}) { # NACK from the KM271
if($buf eq "15") { # NACK from the KM271
Log 1, "$name: NACK!";
delete($hash->{DATASENT});
KM271_SimpleWrite($hash, "02") if(@{$hash->{SENDBUFFER}});
return;
}
} elsif($buf eq "02") { # KM271 Wants to send
KM271_SimpleWrite($hash, "10"); # We are ready
$hash->{PARTIAL} = "";
$hash->{WAITING} = 1;
return;
}
@ -292,93 +334,70 @@ KM271_Read($)
my $len = length($hash->{PARTIAL});
return if($hash->{PARTIAL} !~ m/^(.*)1003(..)$/);
($data, $crc) = ($1, $2);
$hash->{PARTIAL} = "";
delete($hash->{WAITING});
if(KM271_crc($data) ne $crc) {
Log 1, "Wrong CRC in $hash->{PARTIAL}: $crc vs. ". KM271_crc($data);
$hash->{PARTIAL} = "";
KM271_SimpleWrite($hash, $nak);
KM271_SimpleWrite($hash, "15"); # NAK
KM271_SimpleWrite($hash, "02") if(@{$hash->{SENDBUFFER}}); # want to send
return;
}
KM271_SimpleWrite($hash, $dle); # Data received ok
delete($hash->{WAITING});
if($hash->{SENDBUFFER}) {
KM271_SimpleWrite($hash, $stx)
}
KM271_SimpleWrite($hash, "10"); # ACK, Data received ok
$data =~ s/1010/10/g;
if($data !~ m/^(....)(.*)/) {
Log 1, "$name: Bogus message: $data";
return;
}
######################################
# Analyze the data
my ($fn, $arg) = ($1, $2);
my $msg = $km271_trhash{$fn};
$msg = "UNKNOWN_$fn" if(!$msg);
my $msghash = $km271_rev{$fn};
my $all_events = KM271_attr($name, "all_km271_events") ;
my $tn = TimeNow();
my $val = unpack('H*', $arg);
my $gen_notify = $km271_noevent{$msg} ? 0 : 1;
$gen_notify = KM271_attr($name, "all_km271_events")
if(!$gen_notify);
#Log 1, "$data" if($fn ne "0400");
if($msg eq "NoData") {
$gen_notify = 0;
if($msghash) {
foreach my $off (keys %{$msghash}) {
} elsif($msg =~ m/^UNKNOWN/) {
$val = $data;
$gen_notify = 0;
} elsif($msg =~ m/Aussentemperatur/) {
$val = $val-256 if($val > 128);
my $key = $msghash->{$off};
my $val = hex(substr($arg, $off*2, 2));
my $ntfy = 1;
my @postprocessing = split(",", $km271_tr{$key});
shift @postprocessing;
while(@postprocessing) {
my ($f,$farg) = split(":", shift @postprocessing);
} elsif($msg =~ m/Brenner_Laufzeit(.)_Minuten(.)/) {
my ($idx, $no) = ($1, $2);
if($no == 2 || $no == 1) {
$gen_notify = 0;
} else {
$msg = "Brenner_Laufzeit${idx}_Minuten";
$val = KM271_Reading($hash, $msg . "2") * 65536 +
KM271_Reading($hash, $msg . "1") * 256 +
$val;
if($f eq "d") { $val /= $farg; }
elsif($f eq "p") { $val += $farg; }
elsif($f eq "ne") { $ntfy = $all_events; }
elsif($f eq "s") { $val = $val-256 if($val > 128); }
elsif($f eq "bf") { $val = KM271_setbits($val, $farg); }
elsif($f eq "a") { $val = $km271_arrays[$farg][$val]; }
elsif($f eq "mb") {
$val += KM271_GetReading($hash, $key."1") * 256;
$val += KM271_GetReading($hash, $key."2") * 65536 if($farg == 3);
}
}
KM271_SetReading($hash, $tn, $key, $val, $ntfy);
}
} elsif($msg =~ m/HK._Betriebswerte/) {
$val = KM271_setbits($val, \@km271_HK_Betriebswerte1, "leer");
} elsif($fn eq "0400") {
KM271_SetReading($hash, $tn, "NoData", $arg, 0);
} elsif($msg =~ m/HK._Betriebswerte2/) {
$val = KM271_setbits($val, \@km271_HK_Betriebswerte2, "leer");
} elsif($all_events) {
KM271_SetReading($hash, $tn, "UNKNOWN_$fn", $data, 1);
} elsif($msg =~ m/WW_Betriebswerte1/) {
$val = KM271_setbits($val, \@km271_WW_Betriebswerte1, "aus");
} elsif($msg =~ m/WW_Betriebswerte2/) {
$val = KM271_setbits($val, \@km271_WW_Betriebswerte2, "aus");
} elsif($msg =~ m/Brenner_Ansteuerung/) {
$val = ($val ? "an" : "aus");
} elsif($msg =~ m/Kessel_Betrieb/) {
$val = KM271_setbits($val, \@km271_Kessel_Betrieb, "aus");
} elsif($msg =~ m/WW_Ladepumpe/) {
$val = KM271_setbits($val, \@km271_WW_Ladepumpe, "aus");
} elsif($msg =~ m/HK?_Raum.*temperatur/) {
$val = $val/2;
} else { # Just ignore
return;
}
$val = $arg if(length($arg) > 2);
Log GetLogLevel($name,4), "KM271 $name: $msg $val";
$hash->{READINGS}{$msg}{TIME} = $tn;
$hash->{READINGS}{$msg}{VAL} = $val;
DoTrigger($name, "$msg: $val") if($gen_notify);
$hash->{PARTIAL} = "";
}
#####################################
@ -398,7 +417,8 @@ sub
KM271_SimpleWrite(@)
{
my ($hash, $msg) = @_;
$hash->{Dev}->write($msg) if($hash->{DeviceName});
Log 3, "KM271 SimpleWrite $msg" if(length($msg) != 2);
$hash->{Dev}->write(pack('H*',$msg)) if($hash->{DeviceName});
}
########################
@ -406,7 +426,6 @@ sub
KM271_SimpleRead($)
{
my ($hash) = @_;
return $hash->{Dev}->input() if($hash->{Dev});
return undef;
}
@ -429,6 +448,7 @@ KM271_CloseDev($)
delete($selectlist{"$name.$dev"});
delete($readyfnlist{"$name.$dev"});
delete($hash->{FD});
delete($hash->{DeviceName});
}
########################
@ -473,26 +493,22 @@ KM271_OpenDev($)
$hash->{STATE} = "Initialized";
#$po->write($logmode);
push @{$hash->{SENDBUFFER}}, "EE0000";
KM271_SimpleWrite($hash, $stx);
KM271_SimpleWrite($hash, "02"); # STX
Log 3, "$dev opened";
return undef;
}
sub
KM271_setbits($$$)
KM271_setbits($$)
{
my ($val, $arr, $nulltxt) = @_;
my $bit = 1;
my ($val, $arridx) = @_;
my @ret;
for(my $idx = 0; $idx < 8; $idx++) {
push(@ret, $arr->[$idx]) if($val & $bit);
$bit *= 2;
for(my $idx = 1; $idx <= 8; $idx++) {
push(@ret, $km271_bitarrays[$arridx][$idx]) if($val & (1<<($idx-1)));
}
return $nulltxt if(!@ret);
return $km271_bitarrays[$arridx][0] if(!int(@ret));
return join(",", @ret);
}
@ -518,7 +534,7 @@ KM271_attr($$)
}
sub
KM271_Reading($$)
KM271_GetReading($$)
{
my ($hash, $msg) = @_;
return $hash->{READINGS}{$msg}{VAL}
@ -526,5 +542,16 @@ KM271_Reading($$)
return 0;
}
sub
KM271_SetReading($$$$$)
{
my ($hash,$tn,$key,$val,$ntfy) = @_;
my $name = $hash->{NAME};
Log GetLogLevel($name,4), "$name: $key $val" if($key ne "NoData");
$hash->{READINGS}{$key}{TIME} = $tn;
$hash->{READINGS}{$key}{VAL} = $val;
DoTrigger($name, "$key: $val") if($ntfy);
}
1;