HMLAN assigned IDs improvement

git-svn-id: https://svn.fhem.de/fhem/trunk@6344 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
martinp876 2014-08-02 11:06:35 +00:00
parent 84c222b574
commit dd40a6f97e
2 changed files with 103 additions and 56 deletions

View File

@ -29,6 +29,9 @@ sub HMLAN_condUpdate($$);
my %sets = ( "hmPairForSec" => "HomeMatic" my %sets = ( "hmPairForSec" => "HomeMatic"
,"hmPairSerial" => "HomeMatic" ,"hmPairSerial" => "HomeMatic"
,"reassignIDs" => ""
);
my %gets = ( "assignIDs" => ""
); );
my %HMcond = ( 0 =>'ok' my %HMcond = ( 0 =>'ok'
,2 =>'Warning-HighLoad' ,2 =>'Warning-HighLoad'
@ -56,6 +59,7 @@ sub HMLAN_Initialize($) {
$hash->{WriteFn} = "HMLAN_Write"; $hash->{WriteFn} = "HMLAN_Write";
$hash->{ReadyFn} = "HMLAN_Ready"; $hash->{ReadyFn} = "HMLAN_Ready";
$hash->{SetFn} = "HMLAN_Set"; $hash->{SetFn} = "HMLAN_Set";
$hash->{GetFn} = "HMLAN_Get";
$hash->{NotifyFn}= "HMLAN_Notify"; $hash->{NotifyFn}= "HMLAN_Notify";
$hash->{AttrFn} = "HMLAN_Attr"; $hash->{AttrFn} = "HMLAN_Attr";
$hash->{Clients} = ":CUL_HM:"; $hash->{Clients} = ":CUL_HM:";
@ -122,7 +126,8 @@ sub HMLAN_Define($$) {#########################################################
@{$hash->{helper}{log}{ids}} = \@al; @{$hash->{helper}{log}{ids}} = \@al;
$hash->{assignedIDsCnt} = 0;#define hash $hash->{assignedIDsCnt} = 0;#define hash
$hash->{assignedIDs} = ""; $hash->{helper}{assIdRep} = 0;
$hash->{helper}{assIdCnt} = 0;
HMLAN_condUpdate($hash,253);#set disconnected HMLAN_condUpdate($hash,253);#set disconnected
$hash->{STATE} = "disconnected"; $hash->{STATE} = "disconnected";
$hash->{owner} = ""; $hash->{owner} = "";
@ -307,7 +312,7 @@ sub HMLAN_UpdtMsgLoad($$) {####################################################
$hash->{helper}{recoverTest} = 1; $hash->{helper}{recoverTest} = 1;
HMLAN_Write($hash,"","As09998112" HMLAN_Write($hash,"","As09998112"
.AttrVal($name,"hmId","999999") .AttrVal($name,"hmId","999999")
."000001"); ."000000");
} }
} }
$hCap->{$hCap->{last}}+=$incr if ($incr); $hCap->{$hCap->{last}}+=$incr if ($incr);
@ -323,24 +328,42 @@ sub HMLAN_UpdtMsgLoad($$) {####################################################
return; return;
} }
sub HMLAN_Get($@) {############################################################
my ($hash, @a) = @_;
my $ret = "";
return "\"get $hash->{NAME}\" no command given" if(@a < 2);
return "Unknown argument $a[1], choose one of " . join(" ", sort keys %gets)
if(!defined($gets{$a[1]}));
my $name = shift @a;
my $cmd = shift @a;
my $arg = join("", @a);
if($cmd eq "assignIDs") { #--------------------------------------
return "set $name $cmd doesn't support parameter" if(scalar(@a));
my @aIds = map{CUL_HM_id2Name($_)} keys %{$hash->{helper}{ids}};
@aIds = map{CUL_HM_name2Id($_)." : $_"} sort @aIds;
$ret = "assignedIDs: ".scalar(@aIds)."\n".join("\n", @aIds);
}
return ($ret);# no not generate trigger outof command
}
sub HMLAN_Set($@) {############################################################ sub HMLAN_Set($@) {############################################################
my ($hash, @a) = @_; my ($hash, @a) = @_;
return "\"set HMLAN\" needs at least one parameter" if(@a < 2); return "\"set $hash->{NAME}\" no command given" if(@a < 2);
return "Unknown argument $a[1], choose one of " . join(" ", sort keys %sets) return "Unknown argument $a[1], choose one of " . join(" ", sort keys %sets)
if(!defined($sets{$a[1]})); if(!defined($sets{$a[1]}));
my $name = shift @a; my $name = shift @a;
my $type = shift @a; my $cmd = shift @a;
my $arg = join("", @a); my $arg = join("", @a);
if($type eq "hmPairForSec") { #################################### if($cmd 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+$/);
HMLAN_RemoveHMPair("hmPairForSec:$name"); HMLAN_RemoveHMPair("hmPairForSec:$name");
$hash->{hmPair} = 1; $hash->{hmPair} = 1;
InternalTimer(gettimeofday()+$arg, "HMLAN_RemoveHMPair", "hmPairForSec:$name", 1); InternalTimer(gettimeofday()+$arg, "HMLAN_RemoveHMPair", "hmPairForSec:$name", 1);
} }
elsif($type eq "hmPairSerial") { ################################ elsif($cmd eq "hmPairSerial") { #################################
return "Usage: set $name hmPairSerial <10-character-serialnumber>" return "Usage: set $name hmPairSerial <10-character-serialnumber>"
if(!$arg || $arg !~ m/^.{10}$/); if(!$arg || $arg !~ m/^.{10}$/);
@ -354,8 +377,13 @@ sub HMLAN_Set($@) {############################################################
$hash->{hmPairSerial} = $arg; $hash->{hmPairSerial} = $arg;
InternalTimer(gettimeofday()+20, "HMLAN_RemoveHMPair", "hmPairForSec:".$name, 1); InternalTimer(gettimeofday()+20, "HMLAN_RemoveHMPair", "hmPairForSec:".$name, 1);
} }
elsif($cmd eq "reassignIDs") { ##################################
return "set $name $cmd doesn't support parameter" if(scalar(@a));
HMLAN_assignIDs($hash);
}
return ("",1);# no not generate trigger outof command return ("",1);# no not generate trigger outof command
} }
sub HMLAN_ReadAnswer($$$) {# This is a direct read for commands like get sub HMLAN_ReadAnswer($$$) {# This is a direct read for commands like get
my ($hash, $arg, $regexp) = @_; my ($hash, $arg, $regexp) = @_;
my $type = $hash->{TYPE}; my $type = $hash->{TYPE};
@ -411,7 +439,7 @@ sub HMLAN_Write($$$) {#########################################################
substr($msg, 16, 6)); substr($msg, 16, 6));
if ( $mtype eq "02" && $src eq $hash->{owner} && length($msg) == 24 if ( $mtype eq "02" && $src eq $hash->{owner} && length($msg) == 24
&& defined $hash->{assIDs}{$dst}){ && defined $hash->{helper}{ids}{$dst}){
# Acks are generally send by HMLAN autonomously # Acks are generally send by HMLAN autonomously
# Special # Special
Log3 $hash, 5, "HMLAN: Skip ACK"; Log3 $hash, 5, "HMLAN: Skip ACK";
@ -425,13 +453,15 @@ sub HMLAN_Write($$$) {#########################################################
# my $IDnew = '+'.$dst.',00,01,'; # newChannel- trailing 01 to be sent if talk to neu channel # my $IDnew = '+'.$dst.',00,01,'; # newChannel- trailing 01 to be sent if talk to neu channel
my $IDadd = '+'.$dst.',00,00,'; # guess: add ID? my $IDadd = '+'.$dst.',00,00,'; # guess: add ID?
if (!$hash->{assIDs}{$dst} && $dst ne "000000"){ if (!$hash->{helper}{ids}{$dst} && $dst ne "000000"){
HMLAN_SimpleWrite($hash, $IDadd); HMLAN_SimpleWrite($hash, $IDadd);
$hash->{helper}{$dst}{name} = CUL_HM_id2Name($dst); $hash->{helper}{ids}{$dst}{name} = CUL_HM_id2Name($dst);
$hash->{assIDs}{$dst} = 1; $hash->{helper}{assIdCnt} = scalar(keys %{$hash->{helper}{ids}});
my @asId = HMLAN_noDup(keys %{$hash->{assIDs}}); $hash->{assignedIDsCnt} = $hash->{helper}{assIdCnt}
$hash->{assignedIDs}=join(',',@asId); .(($hash->{helper}{assIdCnt} eq $hash->{helper}{assIdRep})
$hash->{assignedIDsCnt}=scalar(@asId); ?""
:" report:$hash->{helper}{assIdRep}")
;
} }
} }
elsif($msg =~ m /init:(......)/){ elsif($msg =~ m /init:(......)/){
@ -439,11 +469,13 @@ sub HMLAN_Write($$$) {#########################################################
if ($modules{CUL_HM}{defptr}{$dst} && if ($modules{CUL_HM}{defptr}{$dst} &&
$modules{CUL_HM}{defptr}{$dst}{helper}{io}{newChn} ){ $modules{CUL_HM}{defptr}{$dst}{helper}{io}{newChn} ){
HMLAN_SimpleWrite($hash,$modules{CUL_HM}{defptr}{$dst}{helper}{io}{newChn}); HMLAN_SimpleWrite($hash,$modules{CUL_HM}{defptr}{$dst}{helper}{io}{newChn});
$hash->{helper}{$dst}{name} = CUL_HM_id2Name($dst); $hash->{helper}{ids}{$dst}{name} = CUL_HM_id2Name($dst);
$hash->{assIDs}{$dst} = 1; $hash->{helper}{assIdCnt} = scalar(keys %{$hash->{helper}{ids}});
my @asId = HMLAN_noDup(keys %{$hash->{assIDs}}); $hash->{assignedIDsCnt} = $hash->{helper}{assIdCnt}
$hash->{assignedIDs}=join(',',@asId); .(($hash->{helper}{assIdCnt} eq $hash->{helper}{assIdRep})
$hash->{assignedIDsCnt}=scalar(@asId); ?""
:" report:$hash->{helper}{assIdRep}")
;
} }
return; return;
} }
@ -452,11 +484,13 @@ sub HMLAN_Write($$$) {#########################################################
if ($modules{CUL_HM}{defptr}{$dst} && if ($modules{CUL_HM}{defptr}{$dst} &&
$modules{CUL_HM}{defptr}{$dst}{helper}{io}{newChn} ){ $modules{CUL_HM}{defptr}{$dst}{helper}{io}{newChn} ){
HMLAN_SimpleWrite($hash,"-$dst"); HMLAN_SimpleWrite($hash,"-$dst");
delete $hash->{helper}{$dst}; delete $hash->{helper}{ids}{$dst};
delete $hash->{assIDs}{$dst}; $hash->{helper}{assIdCnt} = scalar(keys %{$hash->{helper}{ids}});
my @asId = HMLAN_noDup(keys %{$hash->{assIDs}}); $hash->{assignedIDsCnt} = $hash->{helper}{assIdCnt}
$hash->{assignedIDs}=join(',',@asId); .(($hash->{helper}{assIdCnt} eq $hash->{helper}{assIdRep})
$hash->{assignedIDsCnt}=scalar(@asId); ?""
:" report:$hash->{helper}{assIdRep}")
;
} }
return; return;
} }
@ -570,15 +604,16 @@ sub HMLAN_Parse($$) {##########################################################
if ($stat){# message with status information if ($stat){# message with status information
HMLAN_condUpdate($hash,$HMcnd)if ($hash->{helper}{q}{HMcndN} != $HMcnd); HMLAN_condUpdate($hash,$HMcnd)if ($hash->{helper}{q}{HMcndN} != $HMcnd);
my $myId = $attr{$name}{hmId};
if ($stat & 0x03 && $dst eq $attr{$name}{hmId}){HMLAN_qResp($hash,$src,0);} if ($stat & 0x03 && $dst eq $myId){HMLAN_qResp($hash,$src,0);}
elsif ($stat & 0x08 && $src eq $attr{$name}{hmId}){HMLAN_qResp($hash,$dst,0);} elsif ($stat & 0x08 && $src eq $myId){HMLAN_qResp($hash,$dst,0);}
HMLAN_UpdtMsgLoad($name,((hex($flg)&0x10)?($mLen*2+880) #burst=17units *2 HMLAN_UpdtMsgLoad($name,((hex($flg)&0x10)?($mLen*2+880) #burst=17units *2
:($mLen*2+22))) #ACK=1 unit *2 :($mLen*2+22))) #ACK=1 unit *2
if (($stat & 0x48) == 8);# reject - but not from repeater if (($stat & 0x48) == 8);# reject - but not from repeater
$hash->{helper}{$dst}{flg} = 0;#got response => unblock sending $hash->{helper}{ids}{$dst}{flg} = 0 if(defined $hash->{helper}{ids}{$dst});
#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
Log3 $hash, HMLAN_getVerbLvl ($hash,$src,$dst,"5") Log3 $hash, HMLAN_getVerbLvl ($hash,$src,$dst,"5")
, "HMLAN_Parse: $name no ACK from $dst" if($stat & 0x08); , "HMLAN_Parse: $name no ACK from $dst" if($stat & 0x08);
@ -599,7 +634,7 @@ sub HMLAN_Parse($$) {##########################################################
if ( $letter eq "E" if ( $letter eq "E"
&& (hex($flg)&0x60) == 0x20 # ack but not from repeater && (hex($flg)&0x60) == 0x20 # ack but not from repeater
&& $dst eq $attr{$name}{hmId} && $dst eq $attr{$name}{hmId}
&& $hash->{assignedIDs} =~ m/$src/); && $hash->{helper}{ids}{$src});
} }
my $rssi = hex($mFld[4])-65536; my $rssi = hex($mFld[4])-65536;
@ -648,14 +683,15 @@ sub HMLAN_Parse($$) {##########################################################
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}{ids}{$src}{flg}){
$hash->{helper}{$src}{flg} = 0; #release send-holdoff $hash->{helper}{ids}{$src}{flg} = 0 if($dst ne "000000"); #release send-holdoff
if ($hash->{helper}{$src}{msg}){ #send delayed msg if any
if ($hash->{helper}{ids}{$src}{msg}){ #send delayed msg if any
Log3 $hash, HMLAN_getVerbLvl ($hash,$src,$dst,"5") Log3 $hash, HMLAN_getVerbLvl ($hash,$src,$dst,"5")
,"HMLAN_SdDly: $name $src"; ,"HMLAN_SdDly: $name $src";
HMLAN_SimpleWrite($hash, $hash->{helper}{$src}{msg}); HMLAN_SimpleWrite($hash, $hash->{helper}{ids}{$src}{msg});
} }
$hash->{helper}{$src}{msg} = ""; #clear message $hash->{helper}{ids}{$src}{msg} = ""; #clear message
} }
# prepare dispatch----------- # prepare dispatch-----------
# HM format A<len><msg>:<info>:<RSSI>:<IOname> Info is not used anymore # HM format A<len><msg>:<info>:<RSSI>:<IOname> Info is not used anymore
@ -667,7 +703,14 @@ sub HMLAN_Parse($$) {##########################################################
elsif($mFld[0] eq 'HHM-LAN-IF'){#HMLAN version info elsif($mFld[0] eq 'HHM-LAN-IF'){#HMLAN version info
$hash->{uptime} = HMLAN_uptime($mFld[5],$hash); $hash->{uptime} = HMLAN_uptime($mFld[5],$hash);
$hash->{assignedIDsReport}=hex($mFld[6]);
$hash->{helper}{assIdRep} = hex($mFld[6]);
$hash->{assignedIDsCnt} = $hash->{helper}{assIdCnt}
.(($hash->{helper}{assIdCnt} eq $hash->{helper}{assIdRep})
?""
:" report:$hash->{helper}{assIdRep}")
;
$hash->{helper}{q}{keepAliveRec} = 1; $hash->{helper}{q}{keepAliveRec} = 1;
$hash->{helper}{q}{keepAliveRpt} = 0; $hash->{helper}{q}{keepAliveRpt} = 0;
Log3 $hash, ($hash->{helper}{log}{sys}?0:5) Log3 $hash, ($hash->{helper}{log}{sys}?0:5)
@ -727,7 +770,7 @@ sub HMLAN_SimpleWrite(@) {#####################################################
unpack('A9A1A2A1A8A1A2A1A8A1A2A2A2A6A6A*',$msg); unpack('A9A1A2A1A8A1A2A1A8A1A2A2A2A6A6A*',$msg);
my $hmId = AttrVal($name,"hmId",""); my $hmId = AttrVal($name,"hmId","");
my $hDst = $hash->{helper}{$dst};# shortcut my $hDst = $hash->{helper}{ids}{$dst};# shortcut
my $tn = gettimeofday(); my $tn = gettimeofday();
if($modules{CUL_HM}{defptr}{$dst} && if($modules{CUL_HM}{defptr}{$dst} &&
@ -823,7 +866,7 @@ sub HMLAN_DoInit($) {##########################################################
RemoveInternalTimer( "keepAlive:".$name);# avoid duplicate timer RemoveInternalTimer( "keepAlive:".$name);# avoid duplicate timer
InternalTimer($tn+$wdTimer, "HMLAN_KeepAlive", "keepAlive:".$name, 0); InternalTimer($tn+$wdTimer, "HMLAN_KeepAlive", "keepAlive:".$name, 0);
# send first message to retrieve HMLAN condition # send first message to retrieve HMLAN condition
HMLAN_Write($hash,"","As09998112".$id."000001"); HMLAN_Write($hash,"","As09998112".$id."000000");
return undef; return undef;
} }
@ -832,8 +875,7 @@ sub HMLAN_assignIDs($){
my ($hash) = @_; my ($hash) = @_;
HMLAN_SimpleWrite($hash, "C"); #clear all assigned IDs HMLAN_SimpleWrite($hash, "C"); #clear all assigned IDs
my @ids = split",",InternalVal($hash->{NAME},"assignedIDs",""); HMLAN_Write($hash,"","init:$_") foreach(keys %{$hash->{helper}{ids}});
HMLAN_Write($hash,"","init:$_") foreach(@ids);
} }
sub HMLAN_writeAesKey($) {##################################################### sub HMLAN_writeAesKey($) {#####################################################
@ -1045,12 +1087,17 @@ sub HMLAN_getVerbLvl ($$$$){#get verboseLevel for message
<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> <li><a href="#HMLANset_reassignIDs">reassignIDs</a>
Syncs the IDs between HMLAN and teh FHEM list.
Usually this is done automatically and only is recomended if there is a difference in counts.
</li>
<br><br> <br><br>
</ul>
<a name="HMLANget"><b>Get</b></a> <a name="HMLANget"><b>Get</b></a>
<ul> <ul>
N/A <li><a href="#HMLANgetassignIDs">assignIDs</a>
Gibt eine Liste aller diesem IO zugewiesenen IOs aus.
</li>
</ul> </ul>
<br><br> <br><br>
@ -1106,13 +1153,11 @@ sub HMLAN_getVerbLvl ($$$$){#get verboseLevel for message
</ul><br> </ul><br>
<a name="HMLANparameter"><b>parameter</b></a> <a name="HMLANparameter"><b>parameter</b></a>
<ul> <ul>
<li><B>assignedIDs</B><br>
HMIds that are assigned to HMLAN and will be handled. e.g. ACK will be generated internally</li>
<li><B>assignedIDsCnt</B><br> <li><B>assignedIDsCnt</B><br>
number of IDs that are assigned to HMLAN by FHEM</li> number of IDs that are assigned to HMLAN by FHEM.
<li><B>assignedIDsReport</B><br> If the number reported by HMLAN differ it will be reported as 'reported'.<br>
number of HMIds that HMLAN reports are assigned. This should be identical It is recommended to resync HMLAN using the command 'assignIDs'.
to assignedIDsCnt</li> </li>
<li><B>msgKeepAlive</B><br> <li><B>msgKeepAlive</B><br>
performance of keep-alive messages. <br> performance of keep-alive messages. <br>
<B>dlyMax</B>: maximum delay of sheduled message-time to actual message send.<br> <B>dlyMax</B>: maximum delay of sheduled message-time to actual message send.<br>
@ -1181,12 +1226,17 @@ sub HMLAN_getVerbLvl ($$$$){#get verboseLevel for message
<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>
<li><a href="#HMLANset_reassignIDs">reassignIDs</a>
Synchronisiert die im HMLAN eingetragenen IDs mit der von FHEM verwalteten Liste.
I.a. findet dies automatisch statt, koennte aber in reset Fällen abweichen.
</li>
</ul> </ul>
<br><br> <br><br>
<a name="HMLANget"><b>Get</b></a> <a name="HMLANget"><b>Get</b></a>
<ul> <ul>
N/A <li><a href="#HMLANgetassignIDs">assignIDs</a>
Gibt eine Liste aller diesem IO zugewiesenen IOs aus.
</li>
</ul> </ul>
<br><br> <br><br>
@ -1250,13 +1300,11 @@ sub HMLAN_getVerbLvl ($$$$){#get verboseLevel for message
</ul> </ul>
<a name="HMLANparameter"><b>parameter</b></a> <a name="HMLANparameter"><b>parameter</b></a>
<ul> <ul>
<li><B>assignedIDs</B><br>
HMIds, die einem HMLAM zugeordnet sind und verarbeitet werden. Z.B. ACK werden intern generiert.</li>
<li><B>assignedIDsCnt</B><br> <li><B>assignedIDsCnt</B><br>
Anzahl der IDs, die von FHEM einem HMLAN zugeordnet sind</li> Anzahl der IDs, die von FHEM einem HMLAN zugeordnet sind.
<li><B>assignedIDsReport</B><br> Sollte die Anzahl von der im HMLAN abweichen wird dies als 'reported' gemeldet.<br>
Anzahl der HMIDs, die vom HMLAN als zugeordnet gemeldet werden. Wird eine Abweichung festgestellt kann man mit dem Kommando assignIDs das HMLAN synchronisieren.
Diese Anzahl sollte mit assignedIDsCnt identisch sein.</li> </li>
<li><B>msgKeepAlive</B><br> <li><B>msgKeepAlive</B><br>
G&uuml;te der keep-alive Meldungen. <br> G&uuml;te der keep-alive Meldungen. <br>
<B>dlyMax</B>: maximale Verz&ouml;gerungsdauer zwischen dem geplanten Meldungszeitpunkt <B>dlyMax</B>: maximale Verz&ouml;gerungsdauer zwischen dem geplanten Meldungszeitpunkt

View File

@ -5907,7 +5907,6 @@ sub CUL_HM_updtRegDisp($$$) {
if (($md eq "HM-MOD-Re-8") && $listNo == 0){#handle Fw bug if (($md eq "HM-MOD-Re-8") && $listNo == 0){#handle Fw bug
CUL_HM_ModRe8($hash,$regLN); CUL_HM_ModRe8($hash,$regLN);
} }
foreach my $rgN (@regArr){ foreach my $rgN (@regArr){
next if ($culHmRegDefine->{$rgN}->{l} ne $listNo); next if ($culHmRegDefine->{$rgN}->{l} ne $listNo);
my $rgVal = CUL_HM_getRegFromStore($name,$rgN,$list,$peerId,$regLN); my $rgVal = CUL_HM_getRegFromStore($name,$rgN,$list,$peerId,$regLN);