From 4280910524bf8b77e4c144fa34bbbc11c64bcd7e Mon Sep 17 00:00:00 2001 From: rudolfkoenig <> Date: Sun, 28 Mar 2010 15:11:26 +0000 Subject: [PATCH] Internal parsing rewrite, Sending data should work now git-svn-id: https://svn.fhem.de/fhem/trunk@606 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/00_KM271.pm | 479 ++++++++++++++++++++++-------------------- 1 file changed, 253 insertions(+), 226 deletions(-) diff --git a/fhem/FHEM/00_KM271.pm b/fhem/FHEM/00_KM271.pm index d77704435..181e8475b 100755 --- a/fhem/FHEM/00_KM271.pm +++ b/fhem/FHEM/00_KM271.pm @@ -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;