Log3 support, parse HMId in CUL and HMLAN

git-svn-id: https://svn.fhem.de/fhem/trunk@4232 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
martinp876 2013-11-16 14:00:26 +00:00
parent 4a1ce5c399
commit d5fe84ba8c
4 changed files with 147 additions and 82 deletions

View File

@ -104,8 +104,9 @@ CUL_Initialize($)
$hash->{AttrFn} = "CUL_Attr"; $hash->{AttrFn} = "CUL_Attr";
$hash->{AttrList}= "do_not_notify:1,0 dummy:1,0 " . $hash->{AttrList}= "do_not_notify:1,0 dummy:1,0 " .
"showtime:1,0 model:CUL,CUN,CUR " . "showtime:1,0 model:CUL,CUN,CUR " .
"sendpool addvaltrigger rfmode:SlowRF,HomeMatic,MAX hmId ". "sendpool addvaltrigger rfmode:SlowRF,HomeMatic,MAX ".
"hmProtocolEvents:0_off,1_dump,2_dumpFull,3_dumpTrigger"; "hmId ".
"hmProtocolEvents:0_off,1_dump,2_dumpFull,3_dumpTrigger";
$hash->{ShutdownFn} = "CUL_Shutdown"; $hash->{ShutdownFn} = "CUL_Shutdown";
@ -1005,17 +1006,15 @@ CUL_SimpleWrite(@)
sub sub
CUL_Attr(@) CUL_Attr(@)
{ {
my @a = @_; my ($cmd,$name,$aName,$aVal) = @_;
if($aName eq "rfmode") {
if($a[2] eq "rfmode") {
my $name = $a[1];
my $hash = $defs{$name}; my $hash = $defs{$name};
$a[3] = "SlowRF" if(!$a[3] || ($a[3] ne "HomeMatic" && $a[3] ne "MAX")); $aVal = "SlowRF" if(!$aVal || ($aVal ne "HomeMatic" && $aVal ne "MAX"));
my $msg = $hash->{NAME} . ": Mode $a[3] not supported"; my $msg = $hash->{NAME} . ": Mode $aVal not supported";
if($a[3] eq "HomeMatic") { if($aVal eq "HomeMatic") {
return if($hash->{initString} =~ m/Ar/); return if($hash->{initString} =~ m/Ar/);
if(($hash->{CMDS} =~ m/A/) || IsDummy($hash->{NAME})) { if(($hash->{CMDS} =~ m/A/) || IsDummy($hash->{NAME})) {
$hash->{Clients} = $clientsHomeMatic; $hash->{Clients} = $clientsHomeMatic;
@ -1024,11 +1023,11 @@ CUL_Attr(@)
$hash->{initString} = "X21\nAr"; # X21 is needed for RSSI reporting $hash->{initString} = "X21\nAr"; # X21 is needed for RSSI reporting
CUL_SimpleWrite($hash, $hash->{initString}); CUL_SimpleWrite($hash, $hash->{initString});
} else { } else {
Log3 $name, 2, $msg; Log3 $name, 2, $msg;
return $msg; return $msg;
} }
} elsif($a[3] eq "MAX") { } elsif($aVal eq "MAX") {
return if($hash->{initString} =~ m/Zr/); return if($hash->{initString} =~ m/Zr/);
if(($hash->{CMDS} =~ m/Z/) || IsDummy($hash->{NAME})) { if(($hash->{CMDS} =~ m/Z/) || IsDummy($hash->{NAME})) {
$hash->{Clients} = $clientsMAX; $hash->{Clients} = $clientsMAX;
@ -1049,12 +1048,15 @@ CUL_Attr(@)
CUL_SimpleWrite($hash, "Ax") if ($hash->{CMDS} =~ m/A/); # reset AskSin CUL_SimpleWrite($hash, "Ax") if ($hash->{CMDS} =~ m/A/); # reset AskSin
CUL_SimpleWrite($hash, "Zx") if ($hash->{CMDS} =~ m/Z/); # reset Moritz CUL_SimpleWrite($hash, "Zx") if ($hash->{CMDS} =~ m/Z/); # reset Moritz
CUL_SimpleWrite($hash, $hash->{initString}); CUL_SimpleWrite($hash, $hash->{initString});
} }
Log3 $name, 2, "Switched $name rfmode to $a[3]"; Log3 $name, 2, "Switched $name rfmode to $aVal";
delete $hash->{".clientArray"}; delete $hash->{".clientArray"};
} elsif($aName eq "hmId"){
if ($cmd eq "set"){
return "wrong syntax: hmId must be 6-digit-hex-code (3 byte)"
if ($aVal !~ m/^[A-F0-9]{6}$/i);
}
} }
return undef; return undef;

View File

@ -68,13 +68,14 @@ sub HMLAN_Initialize($) {
$hash->{DefFn} = "HMLAN_Define"; $hash->{DefFn} = "HMLAN_Define";
$hash->{UndefFn} = "HMLAN_Undef"; $hash->{UndefFn} = "HMLAN_Undef";
$hash->{AttrList}= "do_not_notify:1,0 dummy:1,0 " . $hash->{AttrList}= "do_not_notify:1,0 dummy:1,0 " .
"loglevel:0,1,2,3,4,5,6 addvaltrigger " . "addvaltrigger " .
"hmId hmKey hmKey2 hmKey3 " . "hmId hmKey hmKey2 hmKey3 " .
"respTime " . "respTime " .
"hmProtocolEvents:0_off,1_dump,2_dumpFull,3_dumpTrigger ". "hmProtocolEvents:0_off,1_dump,2_dumpFull,3_dumpTrigger ".
"hmMsgLowLimit ". "hmMsgLowLimit ".
"hmLanQlen:1_min,2_low,3_normal,4_high,5_critical ". "hmLanQlen:1_min,2_low,3_normal,4_high,5_critical ".
"wdTimer:5,10,15,20,25 ". "wdTimer:5,10,15,20,25 ".
"logIDs ".
$readingFnAttributes; $readingFnAttributes;
} }
sub HMLAN_Define($$) {######################################################### sub HMLAN_Define($$) {#########################################################
@ -83,7 +84,7 @@ sub HMLAN_Define($$) {#########################################################
if(@a != 3) { if(@a != 3) {
my $msg = "wrong syntax: define <name> HMLAN ip[:port]"; my $msg = "wrong syntax: define <name> HMLAN ip[:port]";
Log 2, $msg; Log3 $hash, 2, $msg;
return $msg; return $msg;
} }
DevIo_CloseDev($hash); DevIo_CloseDev($hash);
@ -93,7 +94,7 @@ sub HMLAN_Define($$) {#########################################################
$dev .= ":1000" if($dev !~ m/:/ && $dev ne "none" && $dev !~ m/\@/); $dev .= ":1000" if($dev !~ m/:/ && $dev ne "none" && $dev !~ m/\@/);
if($dev eq "none") { if($dev eq "none") {
Log 1, "$name device is none, commands will be echoed only"; Log3 $hash, 1, "$name device is none, commands will be echoed only";
$attr{$name}{dummy} = 1; $attr{$name}{dummy} = 1;
return undef; return undef;
} }
@ -115,7 +116,11 @@ sub HMLAN_Define($$) {#########################################################
$hash->{helper}{q}{cap}{last} = 0; $hash->{helper}{q}{cap}{last} = 0;
$hash->{helper}{q}{cap}{sum} = 0; $hash->{helper}{q}{cap}{sum} = 0;
HMLAN_UpdtMsgCnt("UpdtMsg:".$name); HMLAN_UpdtMsgCnt("UpdtMsg:".$name);
$defs{$name}{helper}{log}{all} = 0;# selective log support
$defs{$name}{helper}{log}{sys} = 0;
my @al = ();
@{$defs{$name}{helper}{log}{ids}} = \@al;
HMLAN_condUpdate($hash,253);#set disconnected HMLAN_condUpdate($hash,253);#set disconnected
$hash->{STATE} = "disconnected"; $hash->{STATE} = "disconnected";
@ -131,8 +136,7 @@ sub HMLAN_Undef($$) {##########################################################
defined($defs{$d}{IODev}) && defined($defs{$d}{IODev}) &&
$defs{$d}{IODev} == $hash) $defs{$d}{IODev} == $hash)
{ {
my $lev = ($reread_active ? 4 : 2); Log3 $hash, 2, "deleting port for $d";
Log GetLogLevel($name,$lev), "deleting port for $d";
delete $defs{$d}{IODev}; delete $defs{$d}{IODev};
} }
} }
@ -156,13 +160,13 @@ sub HMLAN_Notify(@) {##########################################################
return; return;
} }
sub HMLAN_Attr(@) {############################################################ sub HMLAN_Attr(@) {############################################################
my ($cmd,$name, $attrName,$aVal) = @_; my ($cmd,$name, $aName,$aVal) = @_;
if ($attrName eq "wdTimer" && $cmd eq "set"){#allow between 5 and 25 second if ($aName eq "wdTimer" && $cmd eq "set"){#allow between 5 and 25 second
return "select wdTimer between 5 and 25 seconds" if ($aVal>30 || $aVal<5); return "select wdTimer between 5 and 25 seconds" if ($aVal>30 || $aVal<5);
$attr{$name}{wdTimer} = $aVal; $attr{$name}{wdTimer} = $aVal;
$defs{$name}{helper}{k}{Start} = 0; $defs{$name}{helper}{k}{Start} = 0;
} }
elsif($attrName eq "hmLanQlen"){ elsif($aName eq "hmLanQlen"){
if ($cmd eq "set"){ if ($cmd eq "set"){
no warnings 'numeric'; no warnings 'numeric';
$defs{$name}{helper}{q}{hmLanQlen} = int($aVal)+0; $defs{$name}{helper}{q}{hmLanQlen} = int($aVal)+0;
@ -172,23 +176,23 @@ sub HMLAN_Attr(@) {############################################################
$defs{$name}{helper}{q}{hmLanQlen} = 1; $defs{$name}{helper}{q}{hmLanQlen} = 1;
} }
} }
elsif($attrName =~ m /^hmKey/){ elsif($aName =~ m /^hmKey/){
my $retVal= ""; my $retVal= "";
if ($cmd eq "set"){ if ($cmd eq "set"){
my $kno = ($attrName eq "hmKey")?1:substr($attrName,5,1); my $kno = ($aName eq "hmKey")?1:substr($aName,5,1);
my ($no,$val) = (sprintf("%02X",$kno),$aVal); my ($no,$val) = (sprintf("%02X",$kno),$aVal);
if ($aVal =~ m/:/){#number given if ($aVal =~ m/:/){#number given
($no,$val) = split ":",$aVal; ($no,$val) = split ":",$aVal;
return "illegal number:$no" if (hex($no) < 1 || hex($no) > 255 || length($no) != 2); return "illegal number:$no" if (hex($no) < 1 || hex($no) > 255 || length($no) != 2);
} }
$attr{$name}{$attrName} = "$no:". $attr{$name}{$aName} = "$no:".
(($val =~ m /^[0-9A-Fa-f]{32}$/ )? (($val =~ m /^[0-9A-Fa-f]{32}$/ )?
$val: $val:
unpack('H*', md5($val))); unpack('H*', md5($val)));
$retVal = "$attrName set to $attr{$name}{$attrName}"; $retVal = "$aName set to $attr{$name}{$aName}";
} }
else{ else{
delete $attr{$name}{$attrName}; delete $attr{$name}{$aName};
} }
my ($k1no,$k1,$k2no,$k2,$k3no,$k3) my ($k1no,$k1,$k2no,$k2,$k3no,$k3)
=( "01",AttrVal($name,"hmKey","") =( "01",AttrVal($name,"hmKey","")
@ -205,15 +209,54 @@ sub HMLAN_Attr(@) {############################################################
HMLAN_SimpleWrite($defs{$name}, "Y03,".($k3?"$k3no,$k3":"00,")); HMLAN_SimpleWrite($defs{$name}, "Y03,".($k3?"$k3no,$k3":"00,"));
return $retVal; return $retVal;
} }
elsif($attrName eq "hmMsgLowLimit"){ elsif($aName eq "hmMsgLowLimit"){
if ($cmd eq "set"){ if ($cmd eq "set"){
return "hmMsgLowLimit:please add integer between 10 and 120" return "hmMsgLowLimit:please add integer between 10 and 120"
if ( $aVal !~ m/^(\d+)$/ if ( $aVal !~ m/^(\d+)$/
||$aVal<10 ||$aVal<10
||$aVal >120 ); ||$aVal >120 );
$attr{$name}{hmMsgLowLimit} =$aVal;
} }
} }
elsif($aName eq "hmId"){
if ($cmd eq "set"){
return "wrong syntax: hmId must be 6-digit-hex-code (3 byte)"
if ($aVal !~ m/^[A-F0-9]{6}$/i);
}
}
elsif($aName eq "logIDs"){
if ($cmd eq "set"){
my @ids = split",",$aVal;
my @idName;
if (grep /sys/,@ids){
push @idName,"sys";
$defs{$name}{helper}{log}{sys}=1;
}
else{
$defs{$name}{helper}{log}{sys}=0;
}
if (grep /all/,@ids){
push @idName,"all";
$defs{$name}{helper}{log}{all}=1;
}
else{
$defs{$name}{helper}{log}{all}=0;
$_=substr(CUL_HM_name2Id($_),0,6) foreach(grep !/^$/,@ids);
$_="" foreach(grep !/^[A-F0-9]{6}$/,@ids);
@ids = HMLAN_noDup(@ids);
push @idName,CUL_HM_id2Name($_) foreach(@ids);
}
$attr{$name}{$aName} = join(",",@idName);
@{$defs{$name}{helper}{log}{ids}}=@ids;
}
else{
my @ids = ();
$defs{$name}{helper}{log}{sys}=0;
$defs{$name}{helper}{log}{all}=0;
@{$defs{$name}{helper}{log}{ids}}=@ids;
}
return "logging set to $attr{$name}{$aName}"
if ($attr{$name}{$aName} ne $aVal);
}
return; return;
} }
@ -272,7 +315,6 @@ sub HMLAN_Set($@) {############################################################
my $name = shift @a; my $name = shift @a;
my $type = shift @a; my $type = shift @a;
my $arg = join("", @a); my $arg = join("", @a);
my $ll = GetLogLevel($name,3);
if($type eq "hmPairForSec") { #################################### if($type eq "hmPairForSec") { ####################################
return "Usage: set $name hmPairForSec <seconds_active>" return "Usage: set $name hmPairForSec <seconds_active>"
if(!$arg || $arg !~ m/^\d+$/); if(!$arg || $arg !~ m/^\d+$/);
@ -321,7 +363,7 @@ sub HMLAN_ReadAnswer($$$) {# This is a direct read for commands like get
return ("No data", undef) if(!defined($buf)); return ("No data", undef) if(!defined($buf));
if($buf) { if($buf) {
Log 5, "HMLAN/RAW (ReadAnswer): $buf"; Log3 $hash, 5, "HMLAN/RAW (ReadAnswer): $buf";
$mdata .= $buf; $mdata .= $buf;
} }
if($mdata =~ m/\r\n/) { if($mdata =~ m/\r\n/) {
@ -343,13 +385,12 @@ sub HMLAN_Write($$$) {#########################################################
my ($mtype,$src,$dst) = (substr($msg, 8, 2), my ($mtype,$src,$dst) = (substr($msg, 8, 2),
substr($msg, 10, 6), substr($msg, 10, 6),
substr($msg, 16, 6)); substr($msg, 16, 6));
my $ll5 = GetLogLevel($hash->{NAME},5);
if ( $mtype eq "02" && $src eq $hash->{owner} && length($msg) == 24 if ( $mtype eq "02" && $src eq $hash->{owner} && length($msg) == 24
&& $hash->{assignIDs} =~ m/$dst/){ && $hash->{assignIDs} =~ m/$dst/){
# Acks are generally send by HMLAN autonomously # Acks are generally send by HMLAN autonomously
# Special # Special
Log $ll5, "HMLAN: Skip ACK" if (!$debug); Log3 $hash, 5, "HMLAN: Skip ACK" if (!$debug);
return; return;
} }
# my $IDHM = '+'.$dst.',01,00,F1EF'; #used by HMconfig - meanning?? # my $IDHM = '+'.$dst.',01,00,F1EF'; #used by HMconfig - meanning??
@ -387,10 +428,9 @@ sub HMLAN_Read($) {############################################################
my $buf = DevIo_SimpleRead($hash); my $buf = DevIo_SimpleRead($hash);
return "" if(!defined($buf)); return "" if(!defined($buf));
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $ll5 = GetLogLevel($name,5);
my $hmdata = $hash->{PARTIAL}; my $hmdata = $hash->{PARTIAL};
Log $ll5, "HMLAN/RAW: $hmdata/$buf" if (!$debug); Log3 $hash, 5, "HMLAN/RAW: $hmdata/$buf" if (!$debug);
$hmdata .= $buf; $hmdata .= $buf;
while($hmdata =~ m/\n/) { while($hmdata =~ m/\n/) {
@ -434,7 +474,6 @@ sub HMLAN_uptime($@) {#########################################################
sub HMLAN_Parse($$) {########################################################## sub HMLAN_Parse($$) {##########################################################
my ($hash, $rmsg) = @_; my ($hash, $rmsg) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $ll5 = GetLogLevel($name,5);
my @mFld = split(',', $rmsg); my @mFld = split(',', $rmsg);
my $letter = substr($mFld[0],0,1); # get leading char my $letter = substr($mFld[0],0,1); # get leading char
@ -443,7 +482,10 @@ sub HMLAN_Parse($$) {##########################################################
my ($mNo,$flg,$type,$src,$dst,$p) = unpack('A2A2A2A6A6A*',$mFld[5]); my ($mNo,$flg,$type,$src,$dst,$p) = unpack('A2A2A2A6A6A*',$mFld[5]);
my $CULinfo = ""; my $CULinfo = "";
Log $ll5, "HMLAN_Parse: $name R:".$mFld[0]
my @logIds = ("150B94","172A85");
Log3 $hash, HMLAN_getVerbLvl ($hash,$src,$dst,"5")
, "HMLAN_Parse: $name R:".$mFld[0]
.(($mFld[0] =~ m/^E/)?' ':'') .(($mFld[0] =~ m/^E/)?' ':'')
.' stat:' .$mFld[1] .' stat:' .$mFld[1]
.' t:' .$mFld[2] .' t:' .$mFld[2]
@ -499,9 +541,11 @@ sub HMLAN_Parse($$) {##########################################################
$hash->{helper}{$dst}{flg} = 0;#got response => unblock sending $hash->{helper}{$dst}{flg} = 0;#got response => unblock sending
if ($stat & 0x0A){#08 and 02 dont need to go to CUL, internal ack only if ($stat & 0x0A){#08 and 02 dont need to go to CUL, internal ack only
Log $ll5, "HMLAN_Parse: $name no ACK from $dst" if($stat & 0x08); Log3 $hash, HMLAN_getVerbLvl ($hash,$src,$dst,"5")
, "HMLAN_Parse: $name no ACK from $dst" if($stat & 0x08);
return; return;
}elsif (($stat & 0x70) == 0x30){Log $ll5, "HMLAN_Parse: $name AES code rejected for $dst $stat"; }elsif (($stat & 0x70) == 0x30){Log3 $hash, HMLAN_getVerbLvl ($hash,$src,$dst,"5")
, "HMLAN_Parse: $name AES code rejected for $dst $stat";
$CULinfo = "AESerrReject"; $CULinfo = "AESerrReject";
HMLAN_qResp($hash,$src,0); HMLAN_qResp($hash,$src,0);
}elsif (($stat & 0x70) == 0x20){$CULinfo = "AESok"; }elsif (($stat & 0x70) == 0x20){$CULinfo = "AESok";
@ -549,14 +593,16 @@ sub HMLAN_Parse($$) {##########################################################
$hash->{helper}{$src}{nextSend} = gettimeofday() + $wait if ($wait > 0); $hash->{helper}{$src}{nextSend} = gettimeofday() + $wait if ($wait > 0);
} }
if (hex($flg)&0xA4 == 0xA4 && $hash->{owner} eq $dst){ if (hex($flg)&0xA4 == 0xA4 && $hash->{owner} eq $dst){
Log $ll5, "HMLAN_Parse: $name ACK config"; Log3 $hash, HMLAN_getVerbLvl ($hash,$src,$dst,"5")
, "HMLAN_Parse: $name ACK config";
HMLAN_Write($hash,undef, "As15".$mNo."8002".$dst.$src."00"); HMLAN_Write($hash,undef, "As15".$mNo."8002".$dst.$src."00");
} }
if ($letter eq 'R' && $hash->{helper}{$src}{flg}){ if ($letter eq 'R' && $hash->{helper}{$src}{flg}){
$hash->{helper}{$src}{flg} = 0; #release send-holdoff $hash->{helper}{$src}{flg} = 0; #release send-holdoff
if ($hash->{helper}{$src}{msg}){ #send delayed msg if any if ($hash->{helper}{$src}{msg}){ #send delayed msg if any
Log $ll5,"HMLAN_SdDly: $name $src"; Log3 $hash, HMLAN_getVerbLvl ($hash,$src,$dst,"5")
,"HMLAN_SdDly: $name $src";
HMLAN_SimpleWrite($hash, $hash->{helper}{$src}{msg}); HMLAN_SimpleWrite($hash, $hash->{helper}{$src}{msg});
} }
$hash->{helper}{$src}{msg} = ""; #clear message $hash->{helper}{$src}{msg} = ""; #clear message
@ -576,14 +622,15 @@ sub HMLAN_Parse($$) {##########################################################
$hash->{assignIDsReport}=hex($mFld[6]); $hash->{assignIDsReport}=hex($mFld[6]);
$hash->{helper}{q}{keepAliveRec} = 1; $hash->{helper}{q}{keepAliveRec} = 1;
$hash->{helper}{q}{keepAliveRpt} = 0; $hash->{helper}{q}{keepAliveRpt} = 0;
Log $ll5, 'HMLAN_Parse: '.$name. ' V:'.$mFld[1] Log3 $hash, ($hash->{helper}{log}{sys}?0:5)
, 'HMLAN_Parse: '.$name. ' V:'.$mFld[1]
.' sNo:'.$mFld[2].' d:'.$mFld[3] .' sNo:'.$mFld[2].' d:'.$mFld[3]
.' O:' .$mFld[4].' t:'.$mFld[5].' IDcnt:'.$mFld[6]; .' O:' .$mFld[4].' t:'.$mFld[5].' IDcnt:'.$mFld[6];
my $myId = AttrVal($name, "hmId", ""); my $myId = AttrVal($name, "hmId", "");
$myId = $attr{$name}{hmId} = $mFld[4] if (!$myId); $myId = $attr{$name}{hmId} = $mFld[4] if (!$myId);
if($mFld[4] ne $myId && !AttrVal($name, "dummy", 0)) { if($mFld[4] ne $myId && !AttrVal($name, "dummy", 0)) {
Log 1, 'HMLAN setting owner to '.$myId.' from '.$mFld[4]; Log3 $hash, 1, 'HMLAN setting owner to '.$myId.' from '.$mFld[4];
HMLAN_SimpleWrite($hash, "A$myId"); HMLAN_SimpleWrite($hash, "A$myId");
} }
} }
@ -591,7 +638,7 @@ sub HMLAN_Parse($$) {##########################################################
# Ack from the HMLAN # Ack from the HMLAN
} }
else { else {
Log $ll5, "$name Unknown msg >$rmsg<"; Log3 $hash, 5, "$name Unknown msg >$rmsg<";
} }
} }
sub HMLAN_Ready($) {########################################################### sub HMLAN_Ready($) {###########################################################
@ -604,7 +651,6 @@ sub HMLAN_SimpleWrite(@) {#####################################################
return if(!$hash || AttrVal($hash->{NAME}, "dummy", undef)); return if(!$hash || AttrVal($hash->{NAME}, "dummy", undef));
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $ll5 = GetLogLevel($name,5);
my $len = length($msg); my $len = length($msg);
# It is not possible to answer befor 100ms # It is not possible to answer befor 100ms
@ -632,7 +678,7 @@ sub HMLAN_SimpleWrite(@) {#####################################################
if ( $hDst->{flg} && #HMLAN's ack pending if ( $hDst->{flg} && #HMLAN's ack pending
($hDst->{to} > $tn)){#won't wait forever! check timeout ($hDst->{to} > $tn)){#won't wait forever! check timeout
$hDst->{msg} = $msg; #postpone message $hDst->{msg} = $msg; #postpone message
Log $ll5,"HMLAN_Delay: $name $dst"; Log3 $hash, HMLAN_getVerbLvl($hash,$src,$dst,"5"),"HMLAN_Delay: $name $dst";
return; return;
} }
if ($src eq $hmId){ if ($src eq $hmId){
@ -647,12 +693,14 @@ sub HMLAN_SimpleWrite(@) {#####################################################
my $chn = substr($msg,52,2); my $chn = substr($msg,52,2);
if ($hDst->{chn} && $hDst->{chn} ne $chn){ if ($hDst->{chn} && $hDst->{chn} ne $chn){
my $updt = $hDst->{newChn}; my $updt = $hDst->{newChn};
Log $ll5, 'HMLAN_Send: '.$name.' S:'.$updt; Log3 $hash, HMLAN_getVerbLvl($hash,$src,$dst,"5")
, 'HMLAN_Send: '.$name.' S:'.$updt;
syswrite($hash->{TCPDev}, $updt."\r\n") if($hash->{TCPDev}); syswrite($hash->{TCPDev}, $updt."\r\n") if($hash->{TCPDev});
} }
$hDst->{chn} = $chn; $hDst->{chn} = $chn;
} }
Log $ll5, 'HMLAN_Send: '.$name.' S:'.$s Log3 $hash, HMLAN_getVerbLvl($hash,$src,$dst,"5")
, 'HMLAN_Send: '.$name.' S:'.$s
.' stat: ' .$stat .' stat: ' .$stat
.' t:' .$t .' t:' .$t
.' d:' .$d .' d:' .$d
@ -665,8 +713,8 @@ sub HMLAN_SimpleWrite(@) {#####################################################
HMLAN_UpdtMsgLoad($name,(hex($flg)&0x10)?17:1);#burst counts HMLAN_UpdtMsgLoad($name,(hex($flg)&0x10)?17:1);#burst counts
} }
else{ else{
Log $ll5, 'HMLAN_Send: '.$name.' I:'.$msg; Log3 $hash, ($hash->{helper}{log}{sys}?0:5), 'HMLAN_Send: '.$name.' I:'.$msg;
} }
$msg .= "\r\n" unless($nonl); $msg .= "\r\n" unless($nonl);
@ -812,7 +860,7 @@ sub HMLAN_condUpdate($$) {#####################################################
} }
my $HMcndTxt = $HMcond{$HMcnd}?$HMcond{$HMcnd}:"Unknown:$HMcnd"; my $HMcndTxt = $HMcond{$HMcnd}?$HMcond{$HMcnd}:"Unknown:$HMcnd";
Log GetLogLevel($name,2), "HMLAN_Parse: $name new condition $HMcndTxt"; Log3 $hash, 1, "HMLAN_Parse: $name new condition $HMcndTxt";
my $txt; my $txt;
$txt .= $HMcond{$_}.":".$hashCnd->{$_}." " $txt .= $HMcond{$_}.":".$hashCnd->{$_}." "
foreach (keys%{$hashCnd}); foreach (keys%{$hashCnd});
@ -845,6 +893,19 @@ sub HMLAN_condUpdate($$) {#####################################################
readingsEndUpdate($hash,1); readingsEndUpdate($hash,1);
} }
sub HMLAN_noDup(@) {#return list with no duplicates
my %all;
return "" if (scalar(@_) == 0);
$all{$_}=0 foreach (grep !/^$/,@_);
delete $all{""}; #remove empties if present
return (sort keys %all);
}
sub HMLAN_getVerbLvl ($$$$){#get verboseLevel for message
my ($hash,$src,$dst,$def) = @_;
return ($hash->{helper}{log}{all}||
(grep /($src|$dst)/,@{$hash->{helper}{log}{ids}}))?0:$def;
}
1; 1;
=pod =pod
@ -870,8 +931,7 @@ sub HMLAN_condUpdate($$) {#####################################################
</ul> </ul>
<br/><br/> <br/><br/>
<a name="HMLANdefine"></a> <a name="HMLANdefine"><b>Define</b></a>
<b>Define</b>
<ul> <ul>
<code>define &lt;name&gt; HMLAN &lt;ip-address&gt;[:port]</code><br> <code>define &lt;name&gt; HMLAN &lt;ip-address&gt;[:port]</code><br>
<br> <br>
@ -880,28 +940,33 @@ sub HMLAN_condUpdate($$) {#####################################################
</ul> </ul>
<br><br> <br><br>
<a name="HMLANset"></a> <a name="HMLANset"><b>Set</b></a>
<b>Set</b>
<ul> <ul>
<li><a href="#hmPairForSec">hmPairForSec</a></li> <li><a href="#hmPairForSec">hmPairForSec</a></li>
<li><a href="#hmPairSerial">hmPairSerial</a></li> <li><a href="#hmPairSerial">hmPairSerial</a></li>
</ul> </ul>
<br><br> <br><br>
<a name="HMLANget"></a> <a name="HMLANget"><b>Get</b></a>
<b>Get</b>
<ul> <ul>
N/A N/A
</ul> </ul>
<br><br> <br><br>
<a name="HMLANattr"></a> <a name="HMLANattr"><b>Attributes</b></a>
<b>Attributes</b>
<ul> <ul>
<li><a href="#do_not_notify">do_not_notify</a></li><br> <li><a href="#do_not_notify">do_not_notify</a></li><br>
<li><a href="#attrdummy">dummy</a></li><br> <li><a href="#attrdummy">dummy</a></li><br>
<li><a href="#loglevel">loglevel</a></li><br>
<li><a href="#addvaltrigger">addvaltrigger</a></li><br> <li><a href="#addvaltrigger">addvaltrigger</a></li><br>
<li><a href="#HMLANlogIDs">logIDs</a><br>
enables selective logging of HMLAN messages. A list of HMIds or names can be
entered, comma separated, which shall be logged.<br>
The attribute only allows device-IDs, not channel IDs.
Channel-IDs will be modified to device-IDs automatically.
<b>all</b> will log raw messages for all HMIds<br>
<b>sys</b> will log system related messages like keep-alive<br>
in order to enable all messages set "<b>all,sys</b>"<br>
</li>
<li><a name="HMLANhmMsgLowLimit">hmMsgLowLimit</a><br> <li><a name="HMLANhmMsgLowLimit">hmMsgLowLimit</a><br>
max messages level of HMLAN allowed for low-level message queue max messages level of HMLAN allowed for low-level message queue
to be executed. Above this level processing will be postponed.<br> to be executed. Above this level processing will be postponed.<br>

View File

@ -133,7 +133,7 @@ sub CUL_HM_Initialize($) {
$hash->{RenameFn} = "CUL_HM_Rename"; $hash->{RenameFn} = "CUL_HM_Rename";
$hash->{AttrFn} = "CUL_HM_Attr"; $hash->{AttrFn} = "CUL_HM_Attr";
$hash->{AttrList} = "IODev do_not_notify:1,0 ignore:1,0 dummy:1,0 ". $hash->{AttrList} = "IODev do_not_notify:1,0 ignore:1,0 dummy:1,0 ".
"showtime:1,0 loglevel:0,1,2,3,4,5,6 ". "showtime:1,0 ".
"serialNr firmware ". "serialNr firmware ".
"rawToReadable unit ".#"KFM-Sensor" only "rawToReadable unit ".#"KFM-Sensor" only
"peerIDs repPeers ". "peerIDs repPeers ".
@ -545,7 +545,7 @@ sub CUL_HM_Parse($$) {##############################
"ID_".$md; "ID_".$md;
my $sname = "CUL_HM_".$md."_$src"; my $sname = "CUL_HM_".$md."_$src";
$sname =~ s/-/_/g; $sname =~ s/-/_/g;
Log 3, "CUL_HM Unknown device $sname, please define it"; Log3 undef, 3, "CUL_HM Unknown device $sname, please define it";
return "UNDEFINED $sname CUL_HM $src $msg"; return "UNDEFINED $sname CUL_HM $src $msg";
} }
return ""; return "";
@ -586,10 +586,10 @@ sub CUL_HM_Parse($$) {##############################
my $i=0; my $i=0;
$shash->{helper}{rpt}{ts} = gettimeofday(); $shash->{helper}{rpt}{ts} = gettimeofday();
CUL_HM_SndCmd(${$ack}[$i++],${$ack}[$i++]) while ($i<@{$ack}); CUL_HM_SndCmd(${$ack}[$i++],${$ack}[$i++]) while ($i<@{$ack});
Log GetLogLevel($name,4), "CUL_HM $name dup: repeat ack, dont process"; Log3 $name,4,"CUL_HM $name dup: repeat ack, dont process";
} }
else{ else{
Log GetLogLevel($name,4), "CUL_HM $name dup: dont process"; Log3 $name,4,"CUL_HM $name dup: dont process";
} }
return $name; #return something to please dispatcher return $name; #return something to please dispatcher
} }
@ -1529,7 +1529,7 @@ sub CUL_HM_Parse($$) {##############################
$sRptHash->{ts} = gettimeofday(); $sRptHash->{ts} = gettimeofday();
my $i=0; my $i=0;
CUL_HM_SndCmd($ack[$i++],$ack[$i++])while ($i<@ack); CUL_HM_SndCmd($ack[$i++],$ack[$i++])while ($i<@ack);
Log GetLogLevel($name,6), "CUL_HM $name sent ACK:".(int(@ack)); Log3 $name,6,"CUL_HM $name sent ACK:".(int(@ack));
} }
CUL_HM_ProcessCmdStack($shash) if ($respRemoved); # cont if complete CUL_HM_ProcessCmdStack($shash) if ($respRemoved); # cont if complete
@ -1668,10 +1668,10 @@ sub CUL_HM_parseCommon(@){#####################################################
&& $iohash->{hmPairSerial} eq $attr{$shash->{NAME}}{serialNr})) && $iohash->{hmPairSerial} eq $attr{$shash->{NAME}}{serialNr}))
&&( $mFlg.$mTp ne "0400") ) { &&( $mFlg.$mTp ne "0400") ) {
#-- try to pair #-- try to pair
Log GetLogLevel($shash->{NAME},3), "CUL_HM pair: $shash->{NAME} " Log3 $shash,3, "CUL_HM pair: $shash->{NAME} "
."$attr{$shash->{NAME}}{subType}, " ."$attr{$shash->{NAME}}{subType}, "
."model $attr{$shash->{NAME}}{model} " ."model $attr{$shash->{NAME}}{model} "
."serialNr $attr{$shash->{NAME}}{serialNr}"; ."serialNr $attr{$shash->{NAME}}{serialNr}";
delete $iohash->{hmPairSerial}; delete $iohash->{hmPairSerial};
CUL_HM_respPendRm($shash); # remove all pending messages CUL_HM_respPendRm($shash); # remove all pending messages
delete $shash->{cmdStack}; delete $shash->{cmdStack};
@ -2113,7 +2113,7 @@ sub CUL_HM_Get($@) {
close(aSave); close(aSave);
} }
Log GetLogLevel($name,4), "CUL_HM get $name " . join(" ", @a[1..$#a]); Log3 $name,4,"CUL_HM get $name " . join(" ", @a[1..$#a]);
CUL_HM_ProcessCmdStack($devHash) if ($rxType & 0x03);#burst/all CUL_HM_ProcessCmdStack($devHash) if ($rxType & 0x03);#burst/all
return ""; return "";
@ -3200,7 +3200,7 @@ sub CUL_HM_Set($@) {
readingsSingleUpdate($hash,"state",$state,1) if($state); readingsSingleUpdate($hash,"state",$state,1) if($state);
my $rxType = CUL_HM_getRxType($devHash); my $rxType = CUL_HM_getRxType($devHash);
Log GetLogLevel($name,2), "CUL_HM set $name $act"; Log3 $name,2,"CUL_HM set $name $act";
if($rxType & 0x03){#all/burst if($rxType & 0x03){#all/burst
CUL_HM_ProcessCmdStack($devHash); CUL_HM_ProcessCmdStack($devHash);
} }
@ -3816,7 +3816,7 @@ sub CUL_HM_respPendTout($) {
IOWrite($hash, "", $pHash->{rspWait}{cmd}); IOWrite($hash, "", $pHash->{rspWait}{cmd});
CUL_HM_statCnt($hash->{IODev}{NAME},"s"); CUL_HM_statCnt($hash->{IODev}{NAME},"s");
$pHash->{rspWait}{reSent}++; $pHash->{rspWait}{reSent}++;
Log GetLogLevel($name,4),"CUL_HM_Resend: ".$name. " nr ".$pHash->{rspWait}{reSent}; Log3 $name,4,"CUL_HM_Resend: ".$name. " nr ".$pHash->{rspWait}{reSent};
InternalTimer(gettimeofday()+rand(20)/10+4,"CUL_HM_respPendTout","respPend:$hash->{DEF}", 0); InternalTimer(gettimeofday()+rand(20)/10+4,"CUL_HM_respPendTout","respPend:$hash->{DEF}", 0);
} }
} }
@ -3870,7 +3870,7 @@ sub CUL_HM_protState($$){
$hash->{protState} = $state; $hash->{protState} = $state;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
readingsSingleUpdate($hash,"state",$state,0) if (!$hash->{helper}{role}{chn}); readingsSingleUpdate($hash,"state",$state,0) if (!$hash->{helper}{role}{chn});
Log GetLogLevel($name,6),"CUL_HM $name protEvent:$state". Log3 $name,6,"CUL_HM $name protEvent:$state".
($hash->{cmdStack}?" pending:".scalar @{$hash->{cmdStack}}:""); ($hash->{cmdStack}?" pending:".scalar @{$hash->{cmdStack}}:"");
if ($state =~ m/processing/) {$hash->{helper}{prt}{sProc} = 1; if ($state =~ m/processing/) {$hash->{helper}{prt}{sProc} = 1;
} }
@ -4122,7 +4122,7 @@ sub CUL_HM_DumpProtocol($$@) {
$src=CUL_HM_id2Name($src); $src=CUL_HM_id2Name($src);
$dst=CUL_HM_id2Name($dst); $dst=CUL_HM_id2Name($dst);
my $msg ="$prefix L:$len N:$cnt F:$msgFlags CMD:$mTp SRC:$src DST:$dst $p$txt ($msgFlLong)"; my $msg ="$prefix L:$len N:$cnt F:$msgFlags CMD:$mTp SRC:$src DST:$dst $p$txt ($msgFlLong)";
Log GetLogLevel($iname, 4), $msg; Log3 $iname,4,$msg;
DoTrigger($iname, $msg) if($hmProtocolEvents > 2); DoTrigger($iname, $msg) if($hmProtocolEvents > 2);
} }
@ -4736,7 +4736,7 @@ sub CUL_HM_ActAdd($$) {# add an HMid to list for activity supervision
$actHash->{helper}{peers} = CUL_HM_noDupInString( $actHash->{helper}{peers} = CUL_HM_noDupInString(
($actHash->{helper}{peers}?$actHash->{helper}{peers}:"") ($actHash->{helper}{peers}?$actHash->{helper}{peers}:"")
.",$devId"); .",$devId");
Log 3,"Device ".$devName." added to ActionDetector with " Log3 $actHash, 3,"Device ".$devName." added to ActionDetector with "
.$cycleString." time"; .$cycleString." time";
#run ActionDetector #run ActionDetector
RemoveInternalTimer("ActionDetector"); RemoveInternalTimer("ActionDetector");
@ -4756,8 +4756,7 @@ sub CUL_HM_ActDel($) {# delete HMid for activity supervision
my $peerIDs = $actHash->{helper}{peers}; my $peerIDs = $actHash->{helper}{peers};
$peerIDs =~ s/$devId//g if($peerIDs); $peerIDs =~ s/$devId//g if($peerIDs);
$actHash->{helper}{peers} = CUL_HM_noDupInString($peerIDs); $actHash->{helper}{peers} = CUL_HM_noDupInString($peerIDs);
Log 3,"Device ".$devName Log3 $actHash,3,"Device ".$devName." removed from ActionDetector";
." removed from ActionDetector";
RemoveInternalTimer("ActionDetector"); RemoveInternalTimer("ActionDetector");
CUL_HM_ActCheck(); CUL_HM_ActCheck();
return; return;
@ -4816,7 +4815,7 @@ sub CUL_HM_ActCheck() {# perform supervision
if ($oldState ne $state){ if ($oldState ne $state){
readingsSingleUpdate($devHash,"Activity",$state,1); readingsSingleUpdate($devHash,"Activity",$state,1);
$attr{$devName}{actStatus} = $state; $attr{$devName}{actStatus} = $state;
Log 4,"Device ".$devName." is ".$state; Log3 $actHash,4,"Device ".$devName." is ".$state;
} }
push @event, "status_".$devName.":".$state; push @event, "status_".$devName.":".$state;
} }
@ -5988,7 +5987,6 @@ sub CUL_HM_reglUsed($) {# provide data for HMinfo
<li><a href="#ignore">ignore</a></li> <li><a href="#ignore">ignore</a></li>
<li><a href="#dummy">dummy</a></li> <li><a href="#dummy">dummy</a></li>
<li><a href="#showtime">showtime</a></li> <li><a href="#showtime">showtime</a></li>
<li><a href="#loglevel">loglevel</a></li>
<li><a href="#readingFnAttributes">readingFnAttributes</a></li> <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
<li><a href="#actCycle">actCycle</a> <li><a href="#actCycle">actCycle</a>
actCycle &lt;[hhh:mm]|off&gt;<br> actCycle &lt;[hhh:mm]|off&gt;<br>

View File

@ -689,10 +689,10 @@ sub HMinfo_SetFnDly($) {#######################################################
sub HMinfo_post($) {########################################################### sub HMinfo_post($) {###########################################################
my ($name,$childName) = (split":",$_); my ($name,$childName) = (split":",$_);
foreach (keys %{$defs{$name}{helper}{child}}){ foreach (keys %{$defs{$name}{helper}{child}}){
Log 1,"General still running: $_ ".$defs{$name}{helper}{child}{$_}; Log3 $name, 1,"General still running: $_ ".$defs{$name}{helper}{child}{$_};
} }
delete $defs{$name}{helper}{child}{$childName}; delete $defs{$name}{helper}{child}{$childName};
Log 1,"General deleted $childName now++++++++++++++"; Log3 $name, 1,"General deleted $childName now++++++++++++++";
return "finished"; return "finished";
} }
sub HMinfo_status($){########################################################## sub HMinfo_status($){##########################################################