diff --git a/fhem/CHANGED b/fhem/CHANGED index 4aac64e44..53bf13571 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -20,6 +20,7 @@ - feature: IPV6 support, FHEMWEB basicAuth and HTTPS support - feature: createlog added to the autocreate module - feature: contrib/tcptee.pl added + - feature: HMLAN support - 2010-08-15 (5.0) - **NOTE*: The default installation path is changed to satisfy lintian diff --git a/fhem/FHEM/00_HMLAN.pm b/fhem/FHEM/00_HMLAN.pm index abce73cf3..058c448d4 100755 --- a/fhem/FHEM/00_HMLAN.pm +++ b/fhem/FHEM/00_HMLAN.pm @@ -131,10 +131,10 @@ HMLAN_Set($@) return "Usage: set $name hmPairSerial <10-character-serialnumber>" if(!$arg || $arg !~ m/^.{10}$/); - my $id = AttrVal($hash->{NAME}, "hmId", undef); + my $id = AttrVal($hash->{NAME}, "hmId", "123456"); $hash->{HM_CMDNR} = $hash->{HM_CMDNR} ? ($hash->{HM_CMDNR}+1)%256 : 1; -FixMe(); - HMLAN_SimpleWrite($hash, sprintf("As15%02x8401%s000000010A%s", + + HMLAN_Write($hash, undef, sprintf("As15%02X8401%s000000010A%s", $hash->{HM_CMDNR}, $id, unpack('H*', $arg))); $hash->{hmPairSerial} = $arg; @@ -189,17 +189,24 @@ HMLAN_ReadAnswer($$$) } } +my %lhash; + ##################################### sub HMLAN_Write($$$) { my ($hash,$fn,$msg) = @_; - Log 1, "IN: $msg"; + my $dst = substr($msg, 16, 6); + if(!$lhash{$dst} && $dst ne "000000") { + HMLAN_SimpleWrite($hash, "+$dst,00,00,\r\n+$dst,00,00,\r\n+112A29"); + HMLAN_SimpleWrite($hash, "-$dst"); + HMLAN_SimpleWrite($hash, "+$dst,00,00,\r\n+$dst,00,00,\r\n+112A29"); + $lhash{$dst} = 1; + } my $tm = int(gettimeofday()*1000) & 0xffffffff; $msg = sprintf("S%08X,00,00000000,01,%08X,%s", $tm, $tm, substr($msg, 4)); - Log 1, "$hash->{NAME} sending $msg"; HMLAN_SimpleWrite($hash, $msg); } @@ -249,22 +256,27 @@ HMLAN_Parse($$) my ($hash, $rmsg) = @_; my $name = $hash->{NAME}; my $rssi; + my $ll5 = GetLogLevel($name,5); my $dmsg = $rmsg; - if($rmsg =~ m/E(......),(....),(........),(..),(....),(.*)/) { + Log $ll5, "HMLAN $rmsg"; + if($rmsg =~ m/^E(......),(....),(........),(..),(....),(.*)/) { my ($src, $d1, $msec, $d2, $rssi, $msg) = ($1, $2, $3, $4, $5, $6); $dmsg = sprintf("A%02X%s", length($msg)/2, uc($msg)); $hash->{uptime} = HMLAN_uptime($msec); - } elsif($rmsg =~ m/R(........),(....),(........),(..),(....),(.*)/) { - my ($src, $d1, $msec, $d2, $rssi, $msg) = - ($1, $2, $3, $4, $5, $6); + } elsif($rmsg =~ m/^R(........),(....),(........),(..),(....),(.*)/) { + my ($src, $status, $msec, $d2, $rssi, $msg) = + ($1, $2, $3, $4, $5, $6); + $dmsg = sprintf("A%02X%s", length($msg)/2, uc($msg)); + $dmsg .= "NACK" if($status !~ m/...1/); $hash->{uptime} = HMLAN_uptime($msec); - } elsif($rmsg =~ m/HHM-LAN-IF,(....),(..........),(......),(......),(........),(....)/) { + } elsif($rmsg =~ + m/^HHM-LAN-IF,(....),(..........),(......),(......),(........),(....)/) { my ($vers, $serno, $d1, $owner, $msec, $d2) = (hex($1), $2, $3, $4, $5, $6); $hash->{serialNr} = $serno; @@ -279,7 +291,7 @@ HMLAN_Parse($$) return; } else { - Log 1, "$name Unknown msg $rmsg"; + Log $ll5, "$name Unknown msg $rmsg"; return; } @@ -310,12 +322,13 @@ sub HMLAN_SimpleWrite(@) { my ($hash, $msg, $nonl) = @_; + my $name = $hash->{NAME}; return if(!$hash || AttrVal($hash->{NAME}, "dummy", undef)); - Log 1, "SW: $msg"; - $msg .= "\n" unless($nonl); + Log GetLogLevel($name,5), "SW: $msg"; + + $msg .= "\r\n" unless($nonl); syswrite($hash->{TCPDev}, $msg) if($hash->{TCPDev}); - select(undef, undef, undef, 0.001); } ######################## diff --git a/fhem/FHEM/10_CUL_HM.pm b/fhem/FHEM/10_CUL_HM.pm index 366035e5d..5cceb34f0 100755 --- a/fhem/FHEM/10_CUL_HM.pm +++ b/fhem/FHEM/10_CUL_HM.pm @@ -181,9 +181,9 @@ CUL_HM_Parse($$) $msg =~ m/A(..)(..)(....)(......)(......)(.*)/; my @msgarr = ($1,$2,$3,$4,$5,$6,$7); my ($len,$msgcnt,$cmd,$src,$dst,$p) = @msgarr; - CUL_HM_DumpProtocol("CUL_HM RCV", $iohash, @msgarr); - my $shash = $modules{CUL_HM}{defptr}{$src}; # Will be replaced fo multichannel commands + # $shash will be replaced for multichannel commands + my $shash = $modules{CUL_HM}{defptr}{$src}; my $lcm = "$len$cmd"; my $dhash = $modules{CUL_HM}{defptr}{$dst}; @@ -191,6 +191,16 @@ CUL_HM_Parse($$) $dname = "broadcast" if($dst eq "000000"); $dname = $iohash->{NAME} if($dst eq $id); + if($p =~ m/NACK$/) { + if($dhash) { + $dhash->{STATE} = "MISSING ACK"; + DoTrigger($dname, "MISSING ACK"); + } + return ""; + } + + CUL_HM_DumpProtocol("CUL_HM RCV", $iohash, @msgarr); + # Generate an UNKNOWN event with a better name if(!$shash) { my $sname = "CUL_HM_$src"; @@ -239,7 +249,6 @@ CUL_HM_Parse($$) push @event, ""; } - if($lcm eq "1A8400" || $lcm eq "1A8000") { #### Pairing-Request push @event, CUL_HM_Pair($name, $shash, @msgarr); @@ -251,7 +260,9 @@ CUL_HM_Parse($$) $st eq "dimmer" || $st eq "blindActuator") { - if($p =~ m/^(0.)(..)(..).0/ && $cmd ne "A010") { + if($p =~ m/^(0.)(..)(..).0/ + && $cmd ne "A010" + && $cmd ne "A002") { my $msgType = $1; my $chn = $2; if($chn ne "01" && $chn ne "00") { # Switch to the shadow device @@ -343,8 +354,7 @@ CUL_HM_Parse($$) } - } elsif($model eq "KS550" || $model eq "HM-WDS100-C6-O") { # Identical to KS550? - + } elsif($model eq "KS550" || $model eq "HM-WDS100-C6-O") { if($cmd eq "8670" && $p =~ m/^(....)(..)(....)(....)(..)(..)(..)/) { @@ -429,9 +439,11 @@ CUL_HM_Parse($$) } my %culHmGlobalSets = ( - raw => "data ...", - reset => "", - pair => "", + raw => "data ...", + reset => "", + pair => "", + unpair => "", + sign => "[on|off]", statusRequest => "", ); my %culHmSubTypeSets = ( @@ -508,6 +520,23 @@ CUL_HM_Set($@) } elsif($cmd eq "reset") { ############################################ $sndcmd = sprintf("++A011%s%s0400", $id,$dst); + } elsif($cmd eq "unpair") { ########################################### + $sndcmd = + sprintf("++A001%s%s00050000000000", $id,$dst); + CUL_HM_PushCmdStack($shash, + sprintf("++A001%s%s000802000A000B000C00",$id,$dst)); + CUL_HM_PushCmdStack($shash, + sprintf("++A001%s%s0006",$id,$dst)); + + } elsif($cmd eq "sign") { ############################################ + $sndcmd = + sprintf("++A001%s%s%s050000000000", $id,$dst, $chn); + CUL_HM_PushCmdStack($shash, + sprintf("++A001%s%s%s0808%s",$id,$dst, $chn, + ($a[2] eq "on" ? "01" : "02")); + CUL_HM_PushCmdStack($shash, + sprintf("++A001%s%s%s06",$id,$dst, $chn)); + } elsif($cmd eq "pair") { ############################################# my $serialNr = AttrVal($name, "serialNr", undef); return "serialNr is not set" if(!$serialNr); @@ -530,7 +559,7 @@ CUL_HM_Set($@) } elsif($cmd eq "toggle") { ########################################### $shash->{toggleIndex} = 1 if(!$shash->{toggleIndex}); $shash->{toggleIndex} = (($shash->{toggleIndex}+1) % 128); - $sndcmd = sprintf("++A03E%s%s%s40%s%02x", $id, $dst, + $sndcmd = sprintf("++A03E%s%s%s40%s%02X", $id, $dst, $dst, $chn, $shash->{toggleIndex}); } elsif($st eq "pct") { ############################################## @@ -671,7 +700,7 @@ CUL_HM_Pair(@) $attr{$name}{devInfo} =~ m,(..)(..)(..), ) { my ($b1, $b2, $b3) = (hex($1), hex($2), $3); for(my $i = $b2+1; $i<=$b1; $i++) { - my $nSrc = sprintf("%s%02x", $src, $i); + my $nSrc = sprintf("%s%02X", $src, $i); if(!defined($modules{CUL_HM}{defptr}{$nSrc})) { delete($defs{"global"}{INTRIGGER}); # Hack DoTrigger("global", "UNDEFINED ${name}_CHN_$i CUL_HM $nSrc"); @@ -704,7 +733,7 @@ CUL_HM_SendCmd($$$$) } $io->{HM_CMDNR} = $mn; - $cmd = sprintf("As%02X%02x%s", length($cmd2)/2+1, $mn, $cmd2); + $cmd = sprintf("As%02X%02X%s", length($cmd2)/2+1, $mn, $cmd2); IOWrite($hash, "", $cmd); if($waitforack) { if($hash->{IODev} && $hash->{IODev}{TYPE} ne "HMLAN") { diff --git a/fhem/docs/commandref.html b/fhem/docs/commandref.html index 4841ca54c..8f3ecfbf3 100644 --- a/fhem/docs/commandref.html +++ b/fhem/docs/commandref.html @@ -93,6 +93,7 @@ FHZ FS20 HMS + IPWE KM271 KS300 @@ -1885,6 +1886,67 @@ A line ending with \ will be concatenated with the next one, so long lines + +
define <name> HMLAN <ip-address>[:port]
set hm1 raw ++A001F100001234560105000000001\ ++A001F10000123456010802010AF10B000C00\