mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-02-25 03:44:52 +00:00
CUL_HM:some bug files - thanks to Frank, noansi and beta-user
git-svn-id: https://svn.fhem.de/fhem/trunk@26934 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
78fe11f936
commit
68c76075dd
@ -460,10 +460,18 @@ sub CUL_HM_updateConfig($){##########################
|
||||
$attr{$name}{autoReadReg}= AttrVal($name,"autoReadReg","4_reqStatus");
|
||||
CUL_HM_hmInitMsg($hash);
|
||||
}
|
||||
if (CUL_HM_getRxType($hash)&0x02){#burst dev must restrict retries!
|
||||
# set rxType and mId
|
||||
my $rxt = CUL_HM_getRxType($hash);# set rxType and mId
|
||||
if($rxt & 0x02){#burst dev must restrict retries!
|
||||
$attr{$name}{msgRepeat} = 1 if (!$attr{$name}{msgRepeat});
|
||||
}
|
||||
elsif($rxt & 0x80){# frank: init conditional burst dev
|
||||
if($attr{$name}{burstAccess}){
|
||||
CUL_HM_Attr('set',$name,'burstAccess',$attr{$name}{burstAccess});
|
||||
}
|
||||
else{
|
||||
CUL_HM_Attr('del',$name,'burstAccess');
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($attr{$name}{expert}){
|
||||
CUL_HM_Attr("set",$name,"expert",$attr{$name}{expert});
|
||||
@ -534,7 +542,7 @@ sub CUL_HM_updateConfig($){##########################
|
||||
foreach(sort keys %{$attr{$name}}){
|
||||
delete $attr{$name}{$_} if (CUL_HM_AttrCheck($name,'set',$_,$attr{$name}{$_}));
|
||||
}
|
||||
CUL_HM_qStateUpdatIfEnab($name) if($hash->{helper}{role}{dev});
|
||||
#CUL_HM_qStateUpdatIfEnab($name) if($hash->{helper}{role}{dev});
|
||||
next if (0 == (0x07 & CUL_HM_getAttrInt($name,"autoReadReg")));
|
||||
if(CUL_HM_getPeers($name,"Config") == 2){
|
||||
CUL_HM_qAutoRead($name,1);
|
||||
@ -553,9 +561,10 @@ sub CUL_HM_updateConfig($){##########################
|
||||
CUL_HM_setAssotiat($name);
|
||||
}
|
||||
|
||||
delete $modules{CUL_HM}{helper}{updtCfgLst};
|
||||
#delete $modules{CUL_HM}{helper}{updtCfgLst};
|
||||
if(!$modules{CUL_HM}{helper}{initDone}){
|
||||
Log 5,"CUL_HM finished initial cleanup";
|
||||
InternalTimer(gettimeofday() + 66, 'CUL_HM_startQueues', 'CUL_HM_startQueues', 0); #frank, https://forum.fhem.de/index.php/topic,125378.msg1202273.html#msg1202273 ff
|
||||
if (defined &HMinfo_init){# force reread
|
||||
$modules{HMinfo}{helper}{initDone} = 0;
|
||||
InternalTimer(gettimeofday() + 5,"HMinfo_init", "HMinfo_init", 0);
|
||||
@ -565,6 +574,15 @@ sub CUL_HM_updateConfig($){##########################
|
||||
## configCheck will be issues by HMInfo once
|
||||
}
|
||||
|
||||
sub CUL_HM_startQueues() { #frank, https://forum.fhem.de/index.php/topic,125378.msg1202273.html#msg1202273
|
||||
Log3('global',3,'CUL_HM start Queues'); #Beta-User: changed verbose level
|
||||
for my $name (@{$modules{CUL_HM}{helper}{updtCfgLst}}){
|
||||
CUL_HM_qStateUpdatIfEnab($name) if($defs{$name}->{helper}{role}{dev});
|
||||
}
|
||||
delete $modules{CUL_HM}{helper}{updtCfgLst};
|
||||
return;
|
||||
}
|
||||
|
||||
sub CUL_HM_initializeVirtuals {
|
||||
my $hash = shift // return;
|
||||
my $name = $hash->{NAME} // return;
|
||||
@ -1294,7 +1312,11 @@ sub CUL_HM_Attr(@) {#################################
|
||||
delete $attr{$chNm}{$attrName};
|
||||
}
|
||||
}
|
||||
CUL_HM_assignIO($hash) if $attrName eq 'ignore' && !IsDummy($hash) || $attrName eq 'dummy' && !IsIgnored($hash);
|
||||
if ( $attrName eq 'ignore' && !IsDummy($hash) || $attrName eq 'dummy' && !IsIgnored($hash) ) {
|
||||
RemoveInternalTimer('ActionDetector'); #Beta-User: should solve https://forum.fhem.de/index.php/topic,125490.0.html
|
||||
InternalTimer(gettimeofday()+5,'CUL_HM_ActCheck', 'ActionDetector', 0);
|
||||
CUL_HM_assignIO($hash);
|
||||
}
|
||||
}
|
||||
}
|
||||
elsif($attrName eq "commStInCh"){
|
||||
@ -1780,7 +1802,7 @@ sub CUL_HM_Parse($$) {#########################################################
|
||||
}
|
||||
else {
|
||||
DoTrigger('global', "UNDEFINED $sname CUL_HM $mh{src}"); #Beta-User: procedure similar to ZWave
|
||||
CommandAttr(undef,"$sname room CUL_HM");
|
||||
CommandAttr(undef,"$sname room CUL_HM") if !AttrVal((devspec2array('TYPE=autocreate'))[0],'device_room',0); #Beta-User: see https://forum.fhem.de/index.php/topic,125507.msg1201540.html#msg1201540
|
||||
}
|
||||
$acdone = 1;
|
||||
}
|
||||
@ -2025,7 +2047,7 @@ sub CUL_HM_Parse($$) {#########################################################
|
||||
$mh{devH}->{helper}{aesCommRq}{challenge} = $challenge;
|
||||
$mh{devH}->{helper}{aesCommRq}{kNo} = $kNo;
|
||||
|
||||
my $cmd = $mh{mNo}.($mh{devH}->{helper}{io}{sendWu}?'A1':'A0')."02$mh{dst}$mh{src}04${challenge}".sprintf("%02X", $kNo*2);
|
||||
my $cmd = $mh{mNo}.($mh{devH}->{helper}{io}{sendWu}?'A1':'A0')."02$mh{dst}$mh{src}04$challenge".sprintf("%02X", $kNo*2);
|
||||
$cmd = sprintf("As%02X%s", length($cmd)/2, $cmd);
|
||||
IOWrite($mh{devH}, "", $cmd);
|
||||
$mh{msgStat}="AESpending";
|
||||
@ -2140,7 +2162,6 @@ sub CUL_HM_Parse($$) {#########################################################
|
||||
&& ( $mh{devH}->{IODev}->{helper}{VTS_LZYCFG} # for TSCUL VTS0.34 up, wakeup Ack automatically sent
|
||||
|| $mh{devH}->{IODev}->{TYPE} =~ m/^(?:HMLAN|HMUARTLGW)$/s ) ); # also for HMLAN/HMUARTLGW?
|
||||
$flr = sprintf("%02X", hex($flr)|0x01);
|
||||
$m =~ s/^(..)../$1$flr/s; #noansi: wakeup replacement
|
||||
}
|
||||
CUL_HM_SndCmd($h, $m);
|
||||
}
|
||||
@ -2163,10 +2184,11 @@ sub CUL_HM_Parse($$) {#########################################################
|
||||
CUL_HM_DumpProtocol("RCV",$iohash,$mh{len},$mh{mNo},$mh{mFlg},$mh{mTp},$mh{src},$mh{dst},$mh{p});
|
||||
|
||||
#----------start valid messages parsing ---------
|
||||
my $oldTry = ($mh{devH}->{helper}{prt}{try})? 1: 0;# frank: save old setting
|
||||
my $parse = CUL_HM_parseCommon($iohash,\%mh);
|
||||
if(!defined $mh{md} or $mh{md} eq '' or $mh{md} eq "unknown"){
|
||||
$mh{devN} = '' if (!defined($mh{devN}));
|
||||
Log3 $mh{devH},5, "CUL_HM drop msg for $mh{devN} with unknown model";#actually level 1 - however there might be neighbors around
|
||||
Log3 $mh{devH},5, "CUL_HM drop msg for $mh{devN} with unknown model";
|
||||
$evtDly = 0;#noansi: switch delay trigger off
|
||||
return;
|
||||
}
|
||||
@ -2180,6 +2202,7 @@ sub CUL_HM_Parse($$) {#########################################################
|
||||
|
||||
if ($parse eq "ACK" ||
|
||||
$parse eq "done" ){# remember - ACKinfo will be passed on
|
||||
delete $mh{devH}->{helper}{prt}{try} if($oldTry && $mh{devH}->{helper}{prt}{try});# frank: delete if the try cmd is successful
|
||||
push @evtEt,[$mh{devH},1,""];
|
||||
}
|
||||
elsif($parse eq "NACK"){
|
||||
@ -2995,7 +3018,7 @@ sub CUL_HM_Parse($$) {#########################################################
|
||||
delete $mh{devH}->{cmdStack};
|
||||
delete $mh{devH}->{cmdStacAESPend};
|
||||
delete $mh{devH}->{helper}{prt}{rspWait};
|
||||
delete $mh{devH}->{helper}{prt}{rspWaitSec};
|
||||
#delete $mh{devH}->{helper}{prt}{rspWaitSec};
|
||||
delete $mh{devH}->{helper}{prt}{mmcA};
|
||||
delete $mh{devH}->{helper}{prt}{mmcS};
|
||||
delete $mh{devH}->{lastMsg};
|
||||
@ -3462,7 +3485,16 @@ sub CUL_HM_Parse($$) {#########################################################
|
||||
}
|
||||
|
||||
if($ioId eq $mh{dst} && ($mh{mFlgH}&0x20)){ # Send Ack/Nack
|
||||
push @ack,$mh{shash},$mh{mNo}."8002".$ioId.$mh{src}.($mh{mFlg}.$mh{mTp} eq "A001" ? "80":"00");
|
||||
if ($mh{mFlg}.$mh{mTp} eq 'A001') {
|
||||
push @ack,$mh{shash},$mh{mNo}.'8002'.$ioId.$mh{src}.'80';
|
||||
}
|
||||
else {
|
||||
push @ack,$mh{shash},$mh{mNo}.'8002'.$ioId.$mh{src}.'00' #noansi: additional CUL ACK
|
||||
if ( $ioId eq $mh{dst}
|
||||
&& !$mh{wakupAck} #frank: noansi from https://forum.fhem.de/index.php/topic,121139.msg1158983.html#msg1158983 not if wakeup is sent
|
||||
&& !$mh{devH}->{IODev}->{helper}{VTS_ACK} # for TSCUL VTS0.17 up
|
||||
&& $mh{devH}->{IODev}->{TYPE} !~ m/^(?:HMLAN|HMUARTLGW)$/s ); #noansi: additional CUL ACK
|
||||
}
|
||||
}
|
||||
}
|
||||
elsif($mh{st} eq "threeStateSensor") { ######################################
|
||||
@ -3491,6 +3523,7 @@ sub CUL_HM_Parse($$) {#########################################################
|
||||
push @evtEt,[$mh{devH},1,"battery:". ($err?"low" :"ok" )];
|
||||
push @ack,$mh{shash},$mh{mNo}."8002".$mh{dst}.$mh{src}."00"
|
||||
if ( $ioId eq $mh{dst}
|
||||
&& !$mh{wakupAck} #frank: noansi from https://forum.fhem.de/index.php/topic,121139.msg1158983.html#msg1158983 not if wakeup is sent
|
||||
&& !$mh{devH}->{IODev}->{helper}{VTS_ACK}
|
||||
&& $mh{devH}->{IODev}->{TYPE} !~ m/^(HMLAN|HMUARTLGW)$/); #noansi: additional CUL ACK
|
||||
}
|
||||
@ -3649,7 +3682,9 @@ sub CUL_HM_Parse($$) {#########################################################
|
||||
elsif($ioId eq $mh{dst}){# if fhem is destination check if we need to react
|
||||
if( $mh{mTp} =~ m/^4./ #Push Button event
|
||||
&& !$mh{AckDone} #noansi: allready done device specific
|
||||
&& ($mh{mFlgH} & 0x20)){ #response required Flag
|
||||
&& ($mh{mFlgH} & 0x20) #response required Flag
|
||||
&& !$mh{wakupAck} #frank: noansi from https://forum.fhem.de/index.php/topic,121139.msg1158983.html#msg1158983 not if wakeup is sent
|
||||
){
|
||||
# fhem CUL shall ack a button press
|
||||
if ($mh{md} =~ m/^(HM-SEC-SC.*|ROTO_ZEL-STG-RM-FFK)$/){# SCs - depending on FW version - do not accept ACK only. Especially if peered
|
||||
push @ack,$mh{shash},$mh{mNo}."8002".$mh{dst}.$mh{src}."0101".((hex($mI[0])&1)?"C8":"00")."00";
|
||||
@ -3667,6 +3702,7 @@ sub CUL_HM_Parse($$) {#########################################################
|
||||
push @ack,$mh{shash}, $mh{mNo}."8002".$ioId.$mh{src}."00"
|
||||
if( ($ioId eq $mh{dst}) #are we adressee
|
||||
&& ($mh{mFlgH} & 0x20) #response required Flag
|
||||
&& !$mh{wakupAck} #frank: noansi from https://forum.fhem.de/index.php/topic,121139.msg1158983.html#msg1158983 not if wakeup is sent
|
||||
&& @evtEt #only ack if we identified it
|
||||
&& (!scalar(@ack)) #sender requested ACK
|
||||
);
|
||||
@ -3697,7 +3733,6 @@ sub CUL_HM_Parse($$) {#########################################################
|
||||
&& ( $mh{devH}->{IODev}->{helper}{VTS_LZYCFG} # for TSCUL VTS0.34 up, wakeup Ack automatically sent
|
||||
|| $mh{devH}->{IODev}->{TYPE} =~ m/^(?:HMLAN|HMUARTLGW)$/s ) ); # also for HMLAN/HMUARTLGW?
|
||||
$flr = sprintf("%02X", hex($flr)|0x01);
|
||||
$m =~ s/^(..)../$1$flr/s; #noansi: wakeup replacement
|
||||
}
|
||||
CUL_HM_SndCmd($h, $m);
|
||||
}
|
||||
@ -3706,7 +3741,7 @@ sub CUL_HM_Parse($$) {#########################################################
|
||||
}
|
||||
CUL_HM_ProcessCmdStack($mh{devH}) if ($respRemoved); # cont if complete
|
||||
CUL_HM_sndIfOpen("x:".$mh{ioName});
|
||||
|
||||
|
||||
#------------ process events ------------------
|
||||
push @evtEt,[$mh{devH},1,"noReceiver:src:$mh{src} ".$mh{mFlg}.$mh{mTp}." $mh{p}"]
|
||||
if(!@entities && !@evtEt);
|
||||
@ -3747,6 +3782,7 @@ sub CUL_HM_parseCommon(@){#####################################################
|
||||
}
|
||||
$devHlpr->{prt}{sleeping} = 0;
|
||||
CUL_HM_ProcessCmdStack($mhp->{devH});
|
||||
$mhp->{wakupAck} = 1; #frank: noansi from https://forum.fhem.de/index.php/topic,121139.msg1158983.html#msg1158983
|
||||
}
|
||||
}
|
||||
$devHlpr->{prt}{sleeping} = 1 if (!$devHlpr->{prt}{sProc}); # set back to sleeping with next trigger, if nothing to do
|
||||
@ -3760,6 +3796,7 @@ sub CUL_HM_parseCommon(@){#####################################################
|
||||
CUL_HM_SndCmd($mhp->{devH}, $mhp->{mNo}.'8102'.CUL_HM_IoId($mhp->{devH}).$mhp->{src}.'00'); #noansi: Ack with wakeup bit set for CUL
|
||||
}
|
||||
CUL_HM_ProcessCmdStack($mhp->{devH});
|
||||
$mhp->{wakupAck} = 1; #frank: noansi from https://forum.fhem.de/index.php/topic,121139.msg1158983.html#msg1158983
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3793,13 +3830,9 @@ sub CUL_HM_parseCommon(@){#####################################################
|
||||
if ($devHlpr->{prt}{rspWait}{brstWu}){
|
||||
if ($devHlpr->{prt}{rspWait}{mNo} == $mNoInt &&
|
||||
$mhp->{mStp} eq "00"){
|
||||
CUL_HM_appFromQ($mhp->{devN},"wu");# stack cmd(s) if waiting frank:
|
||||
if ($devHlpr->{prt}{awake} && $devHlpr->{prt}{awake}==4){#re-burstWakeup
|
||||
delete $devHlpr->{prt}{rspWait};#clear burst-wakeup values
|
||||
$devHlpr->{prt}{rspWait}{$_} = $devHlpr->{prt}{rspWaitSec}{$_}
|
||||
foreach (keys%{$devHlpr->{prt}{rspWaitSec}}); #back to original message
|
||||
delete $devHlpr->{prt}{rspWaitSec};
|
||||
IOWrite($mhp->{devH}, "", $devHlpr->{prt}{rspWait}{cmd}); # and send
|
||||
CUL_HM_statCnt($mhp->{devH}{IODev}{NAME},"s",hex(substr($devHlpr->{prt}{rspWait}{cmd},6,2)));
|
||||
CUL_HM_respPendRm($mhp->{devH});
|
||||
return "done";
|
||||
}
|
||||
$mhp->{devH}{protCondBurst} = "on" if ( $mhp->{devH}{protCondBurst}
|
||||
@ -3957,7 +3990,9 @@ sub CUL_HM_parseCommon(@){#####################################################
|
||||
push @evtEt,[$chnhash,0,"CommandAccepted:$success"];
|
||||
CUL_HM_ProcessCmdStack($mhp->{devH}) if(CUL_HM_IoId($mhp->{devH}) eq $mhp->{dst});
|
||||
delete $devHlpr->{prt}{wuReSent}
|
||||
if (!$devHlpr->{prt}{mmcS});
|
||||
if ( !$devHlpr->{prt}{mmcS}
|
||||
&& $devHlpr->{prt}{rspWait}{cmd}
|
||||
&& substr($devHlpr->{prt}{rspWait}{cmd},8,2) ne '12');
|
||||
}
|
||||
$ret = $reply;
|
||||
}
|
||||
@ -4002,7 +4037,6 @@ sub CUL_HM_parseCommon(@){#####################################################
|
||||
CUL_HM_respPendRm($mhp->{devH}); # remove all pending messages
|
||||
delete $mhp->{devH}{cmdStack};
|
||||
delete $devHlpr->{prt}{rspWait};
|
||||
delete $devHlpr->{prt}{rspWaitSec};
|
||||
delete $mhp->{devH}{READINGS}{"RegL_00."};
|
||||
delete $mhp->{devH}{READINGS}{".RegL_00."};
|
||||
push @evtEt,[$defs{$ioOwn},1,"hmPair:name:$mhp->{devN} SN:".$regser." model:$attr{$mhp->{devN}}{model}"];
|
||||
@ -4152,8 +4186,10 @@ sub CUL_HM_parseCommon(@){#####################################################
|
||||
}
|
||||
elsif($mhp->{mStp} eq "02" ||$mhp->{mStp} eq "03"){ #ParamResp==============
|
||||
my $mNoWait = $rspWait->{mNo};
|
||||
if ( $pendType eq "RegisterRead" &&
|
||||
($mNoWait == $mNoInt || $mNoInt == ($mNoWait+1)%256)){ #noWait +1 modulo 256
|
||||
if ( $pendType eq "RegisterRead"
|
||||
&& !(defined($rspWait->{data}) && $rspWait->{data} eq $mhp->{p})# no device retry
|
||||
&& ($mNoWait == $mNoInt || $mNoInt == ($mNoWait+1)%256)){ # noWait +1 modulo 256
|
||||
$rspWait->{data} = $mhp->{p}; # prevent timeout for device resends with mNo+2
|
||||
$rspWait->{mNo} = $mNoInt; # next message will be numbered same or one plus
|
||||
$repeat = 1;#prevent stop for messagenumber match
|
||||
CUL_HM_m_setCh($mhp,$rspWait->{forChn});
|
||||
@ -4206,7 +4242,21 @@ sub CUL_HM_parseCommon(@){#####################################################
|
||||
}
|
||||
}
|
||||
else{
|
||||
Log3 $mhp->{devH},4,"waiting for: $pendType, got:RegisterRead # await msgNo:".(defined $rspWait->{mNo} ? $rspWait->{mNo} :"-no msgNo").", rec:$mNoInt";
|
||||
if( $pendType eq "RegisterRead"# frank: prevent timeout for device resends with mNo+2 or wrong destination
|
||||
&& defined($rspWait->{data}) && $rspWait->{data} eq $mhp->{p}){
|
||||
Log3 $mhp->{devH},3,"device resend for $pendType => mTp:$mhp->{mTp} mStp:$mhp->{mStp} mNo:".hex($mhp->{mNo})." dst:$mhp->{dst} data:$mhp->{p}\n "
|
||||
.join("\n ",map{"$_:$rspWait->{$_}"}keys %{$rspWait});
|
||||
$rspWait->{mNo} = $mNoInt; # next message will be numbered same or one plus
|
||||
$repeat = 1;#prevent stop for messagenumber match
|
||||
CUL_HM_respPendToutProlong($mhp->{devH});#wasn't last - reschedule timer
|
||||
if( $mhp->{dst} ne CUL_HM_IoId($mhp->{devH}) # wrong destination, frank: manage fw bug HM-CC-TC
|
||||
&& $mhp->{devH}->{IODev}->{TYPE} !~ m/^(?:HMLAN|HMUARTLGW)$/s){ # only for cul io
|
||||
CUL_HM_SndCmd($mhp->{devH},"$mhp->{mNo}8002".CUL_HM_IoId($mhp->{devH})."$mhp->{src}00");
|
||||
}
|
||||
}
|
||||
else{
|
||||
Log3 $mhp->{devH},4,"waiting for: $pendType, got:RegisterRead # await msgNo:".(defined $rspWait->{mNo} ? $rspWait->{mNo} :"-no msgNo").", rec:$mNoInt";
|
||||
}
|
||||
}
|
||||
$ret = "done";
|
||||
}
|
||||
@ -4726,8 +4776,9 @@ sub CUL_HM_Get($@) {#+++++++++++++++++ get command+++++++++++++++++++++++++++++
|
||||
}
|
||||
}
|
||||
elsif($cmd eq "regTable") { ################################################
|
||||
return 'not supported w/o HMinfo' if !defined &HMinfo_GetFn;
|
||||
return HMinfo_GetFn($hash,$name,"register","-f","\^".$name."\$");
|
||||
}
|
||||
}
|
||||
elsif($cmd eq "regList") { #################################################
|
||||
return CUL_HM_getRegInfo($name) ;
|
||||
}
|
||||
@ -5339,13 +5390,11 @@ sub CUL_HM_Set($@) {#+++++++++++++++++ set command+++++++++++++++++++++++++++++
|
||||
|
||||
$hash->{helper}{prt}{bErr}=0;
|
||||
delete $hash->{cmdStack};
|
||||
delete($hash->{protCmdPend});
|
||||
delete $hash->{helper}{prt}{rspWait};
|
||||
delete $hash->{helper}{prt}{rspWaitSec};
|
||||
delete $hash->{helper}{prt}{mmcA};
|
||||
delete $hash->{helper}{prt}{mmcS};
|
||||
delete $hash->{lastMsg};
|
||||
delete ($hash->{$_}) foreach (grep(/^prot/,keys %{$hash}));
|
||||
delete ($hash->{$_}) foreach ( grep {$_ =~ m/^prot/ && $_ ne 'protCondBurst'} keys %{$hash} );
|
||||
|
||||
if ($hash->{IODev}{NAME} &&
|
||||
$modules{CUL_HM}{$hash->{IODev}{NAME}} &&
|
||||
@ -5642,7 +5691,6 @@ sub CUL_HM_Set($@) {#+++++++++++++++++ set command+++++++++++++++++++++++++++++
|
||||
my $chnNo = substr($channel,6,2);
|
||||
CUL_HM_PushCmdStack($hash,"++".$flag.'01'.$id.$dst.$chnNo.'0E');
|
||||
}
|
||||
CUL_HM_stateUpdatDly($name,20) if (scalar(@chnIdList));
|
||||
$state = "";
|
||||
}
|
||||
elsif($cmd eq "getSerial") { ################################################
|
||||
@ -7587,10 +7635,17 @@ sub CUL_HM_Set($@) {#+++++++++++++++++ set command+++++++++++++++++++++++++++++
|
||||
CUL_HM_ProcessCmdStack($devHash);
|
||||
}
|
||||
}
|
||||
elsif (CUL_HM_getAttrInt($name,"burstAccess")){ #burstConditional - have a try
|
||||
$hash->{helper}{prt}{brstWu}=1;# start auto-burstWakeup
|
||||
elsif (CUL_HM_getAttrInt($name,"burstAccess") # burstConditional - have a try
|
||||
&& ( !defined($devHash->{helper}{prt}{awake}) # prevent A112/B112 at same time
|
||||
|| defined($devHash->{helper}{prt}{awake}) && $devHash->{helper}{prt}{awake} != 1)# not if wuPrep is scheduled
|
||||
&& !(defined($devHash->{helper}{io}{flgs}) && $devHash->{helper}{io}{flgs} & 0x02)){ # wuPrep is not active (for fhem start)
|
||||
$devHash->{helper}{prt}{brstWu}=1;# start auto-burstWakeup
|
||||
CUL_HM_SndCmd($devHash,"++B112$id$dst");
|
||||
}
|
||||
elsif ( $rxType & 0x18 # wu or lazy device
|
||||
&& !(defined($devHash->{helper}{io}{flgs}) && $devHash->{helper}{io}{flgs} & 0x02)){ # wuPrep is not active
|
||||
CUL_HM_hmInitMsgUpdt($devHash,1);
|
||||
}
|
||||
}
|
||||
return ("",1);# no not generate trigger out of command
|
||||
}
|
||||
@ -8000,10 +8055,11 @@ sub CUL_HM_pushConfig($$$$$$$$@) {#generate messages to config data to register
|
||||
my $addr = substr($content,$l,2);
|
||||
my $data = substr($content,$l+2,2);
|
||||
if(!$regs || !($regs =~ s/$addr:../$addr:$data/)){
|
||||
$regs .= " ".$addr.":".$data;
|
||||
$regs .= " ".$addr.":".$data;
|
||||
}
|
||||
}
|
||||
$sdH->{helper}{shadowReg}{$regLNp} = $regs; # update shadow
|
||||
$sdH->{helper}{shadowReg}{$regLNp} = $regs; # update shadow
|
||||
$sdH->{helper}{shadowRegChn}{$regLNp} = $chn; # save chn for later use, even with prep
|
||||
my @changeList;
|
||||
if ($prep eq "exec"){#update complete registerset
|
||||
@changeList = keys%{$sdH->{helper}{shadowReg}};
|
||||
@ -8033,11 +8089,12 @@ sub CUL_HM_pushConfig($$$$$$$$@) {#generate messages to config data to register
|
||||
if ($pN){($peerAddr,$peerChn) = unpack('A6A2', CUL_HM_name2Id($pN,$hash));}
|
||||
else {($peerAddr,$peerChn) = ('000000','00');}
|
||||
|
||||
if (AttrVal($chnhash->{NAME},"peerIDs",0) =~ m/${peerAddr}00/){$peerChn = "00"}# if device we are not sure about device or channel. Check peers
|
||||
if (AttrVal($chnhash->{NAME},"peerIDs","") =~ m/${peerAddr}00/){$peerChn = "00"}# if device we are not sure about device or channel. Check peers
|
||||
|
||||
CUL_HM_updtRegDisp($hash,$list,$peerAddr.$peerChn);
|
||||
############partition
|
||||
# my @chSplit = unpack('(A28)*',$change);
|
||||
$chn = $sdH->{helper}{shadowRegChn}{$nrn};
|
||||
my @chSplit = unpack('(A1120)*',$change);# makes max 40 lines, 280 byte
|
||||
foreach my $chSpl(@chSplit){
|
||||
my $mch = CUL_HM_lstCh($chnhash,$list,$chn);
|
||||
@ -8046,7 +8103,7 @@ sub CUL_HM_pushConfig($$$$$$$$@) {#generate messages to config data to register
|
||||
$tl = length($chSpl);
|
||||
for(my $l = 0; $l < $tl; $l+=28) {
|
||||
my $ml = $tl-$l < 28 ? $tl-$l : 28;
|
||||
CUL_HM_PushCmdStack($hash, "++A001".$src.$dst.$chn."08".
|
||||
CUL_HM_PushCmdStack($hash, '++A001'.$src.$dst.$mch.'08'.
|
||||
substr($chSpl,$l,$ml));
|
||||
}
|
||||
CUL_HM_PushCmdStack($hash,"++A001".$src.$dst.$mch."06");
|
||||
@ -8452,8 +8509,10 @@ sub CUL_HM_respPendRm($) {#del response related entries in messageing entity
|
||||
|
||||
return if (!defined($hash->{DEF}));
|
||||
$modules{CUL_HM}{prot}{rspPend}-- if($hash->{helper}{prt}{rspWait}{cmd});
|
||||
delete $hash->{helper}{prt}{wuReSent} if ( !$hash->{helper}{prt}{mmcS}
|
||||
&& $hash->{helper}{prt}{rspWait}{cmd}
|
||||
&& substr($hash->{helper}{prt}{rspWait}{cmd},8,2) ne '12');
|
||||
delete $hash->{helper}{prt}{rspWait};
|
||||
delete $hash->{helper}{prt}{wuReSent};
|
||||
delete $hash->{helper}{tmdOn};
|
||||
# delete $hash->{helper}{prt}{mmcA};
|
||||
# delete $hash->{helper}{prt}{mmcS};
|
||||
@ -8468,7 +8527,6 @@ sub CUL_HM_respPendTout($) {
|
||||
my $pHash = $hash->{helper}{prt};#shortcut
|
||||
if ($hash && $hash->{DEF} ne '000000'){# we know the device
|
||||
my $name = $hash->{NAME};
|
||||
$pHash->{awake} = 0 if (defined $pHash->{awake});# set to asleep
|
||||
return if(!$pHash->{rspWait}{reSent}); # Double timer?
|
||||
my $rxt = CUL_HM_getRxType($hash);
|
||||
if ($pHash->{rspWait}{brstWu}){#burst-wakeup try failed (conditionalBurst)
|
||||
@ -8476,8 +8534,9 @@ sub CUL_HM_respPendTout($) {
|
||||
$hash->{protCondBurst} = "off" if (!$hash->{protCondBurst}||
|
||||
$hash->{protCondBurst} !~ m/forced/);;
|
||||
$pHash->{brstWu} = 0;# finished
|
||||
$pHash->{awake} = 0;# set to asleep
|
||||
$pHash->{awake} = 1;# new mode => set to "wait for wu" (wuPrep)
|
||||
CUL_HM_protState($hash,"CMDs_pending");
|
||||
CUL_HM_hmInitMsgUpdt($hash,1);
|
||||
# commandstack will be executed when device wakes up itself
|
||||
}
|
||||
elsif ($pHash->{try}){ #send try failed - revert, wait for wakeup
|
||||
@ -8486,7 +8545,9 @@ sub CUL_HM_respPendTout($) {
|
||||
unshift (@{$hash->{cmdStack}}, "++".substr($pHash->{rspWait}{cmd},6));
|
||||
delete $pHash->{try};
|
||||
CUL_HM_respPendRm($hash);# do not count problems with wakeup try, just wait
|
||||
$pHash->{awake} = 1 if (defined $pHash->{awake}); # frank: new mode => set to "wait for wu" (wuPrep)
|
||||
CUL_HM_protState($hash,"CMDs_pending");
|
||||
CUL_HM_hmInitMsgUpdt($hash,1);
|
||||
}
|
||||
elsif (!CUL_HM_operIObyIOHash($hash->{IODev})){#IO errors
|
||||
CUL_HM_eventP($hash,"IOdly");
|
||||
@ -8509,11 +8570,20 @@ sub CUL_HM_respPendTout($) {
|
||||
Log3 $name,5,"CUL_HM_Resend: $name nr ".$pHash->{rspWait}{reSent};
|
||||
if ($hash->{protCondBurst} && $hash->{protCondBurst} eq "on" ){
|
||||
#timeout while conditional burst was active. try re-wakeup
|
||||
#need to fill back command to queue and wait for next wakeup # frank: change mechanism
|
||||
if ($pHash->{mmcA}){#fillback multi-message command
|
||||
unshift @{$hash->{cmdStack}},$_ foreach (reverse@{$pHash->{mmcA}});
|
||||
delete $pHash->{mmcA};
|
||||
delete $pHash->{mmcS};
|
||||
}
|
||||
else{#fillback simple command
|
||||
unshift (@{$hash->{cmdStack}},"++".substr($pHash->{rspWait}{cmd},6));
|
||||
}
|
||||
$pHash->{wuReSent} = $pHash->{rspWait}{reSent};
|
||||
delete $pHash->{rspWait};
|
||||
$pHash->{awake}=4;#start re-wakeup # frank: change position
|
||||
my $addr = CUL_HM_IoId($hash);
|
||||
$pHash->{rspWaitSec}{$_} = $pHash->{rspWait}{$_}
|
||||
foreach (keys%{$pHash->{rspWait}});
|
||||
CUL_HM_SndCmd($hash,"++B112$addr$HMid");
|
||||
$hash->{helper}{prt}{awake}=4;# start re-wakeup
|
||||
}
|
||||
elsif($rxt & 0x18){# wakeup/lazy devices
|
||||
#need to fill back command to queue and wait for next wakeup
|
||||
@ -8530,6 +8600,7 @@ sub CUL_HM_respPendTout($) {
|
||||
CUL_HM_respPendRm($hash);#clear
|
||||
CUL_HM_protState($hash,"CMDs_pending");
|
||||
$pHash->{wuReSent} = $wuReSent;# restore'invalid' count after general delete
|
||||
CUL_HM_hmInitMsgUpdt($hash,1); # frank:
|
||||
}
|
||||
else{# normal/burst device resend
|
||||
if ($rxt & 0x02){# type = burst - need to set burst-Bit for retry
|
||||
@ -8700,23 +8771,26 @@ sub CUL_HM_eventP($$) {#handle protocol events
|
||||
$hash->{"protLastRcv"} = $t;
|
||||
$t =~ s/[\:\-\ ]//g;
|
||||
CUL_HM_UpdtReadSingle($hash,".protLastRcv",$t,0);
|
||||
# return;
|
||||
}
|
||||
my $evnt = $hash->{"prot".$evntType} ? $hash->{"prot".$evntType} : "0";
|
||||
my ($evntCnt,undef) = split(' last_at:',$evnt);
|
||||
$hash->{"prot".$evntType} = ++$evntCnt." last_at:".TimeNow();
|
||||
|
||||
my $pHash = $hash->{helper}{prt}; # frank: change position
|
||||
if ($evntType =~ m/^(Nack|ResndFail|IOerr|dummy)/){# unrecoverable Error
|
||||
CUL_HM_UpdtReadSingle($hash,"state",$evntType,1);
|
||||
$hash->{helper}{prt}{bErr}++;
|
||||
$pHash->{bErr}++;
|
||||
$hash->{protCmdDel} = 0 if(!$hash->{protCmdDel});
|
||||
$hash->{protCmdDel} += scalar @{$hash->{cmdStack}} + 1
|
||||
if ($hash->{cmdStack});
|
||||
CUL_HM_protState($hash,"CMDs_done");
|
||||
if ($pHash->{mmcA}){ # frank: uncommented in CUL_HM_respPendRm
|
||||
delete $pHash->{mmcA};
|
||||
delete $pHash->{mmcS};
|
||||
}
|
||||
CUL_HM_respPendRm($hash);
|
||||
}
|
||||
elsif($evntType eq "IOdly"){ # IO problem - will see whether it recovers
|
||||
my $pHash = $hash->{helper}{prt};
|
||||
if ($pHash->{mmcA}){
|
||||
unshift @{$hash->{cmdStack}},$_ foreach (reverse@{$pHash->{mmcA}});
|
||||
delete $pHash->{mmcA};
|
||||
@ -8779,9 +8853,10 @@ sub CUL_HM_protState($$){
|
||||
}
|
||||
Log3 $name,5,"CUL_HM $name protEvent:$state".
|
||||
($hash->{cmdStack}?" pending:".scalar @{$hash->{cmdStack}}:"");
|
||||
CUL_HM_hmInitMsgUpdt($hash) if ( $hash->{helper}{prt}{sProc} != $sProcIn
|
||||
&& ( $hash->{helper}{prt}{sProc} < 2
|
||||
||($hash->{helper}{prt}{sProc} == 2 && $sProcIn == 0 )));
|
||||
CUL_HM_hmInitMsgUpdt($hash) if( $hash->{helper}{prt}{sProc} != $sProcIn
|
||||
&& defined $hash->{helper}{io}{flgs} && $hash->{helper}{io}{flgs} & 0x02 # wuPrep is active
|
||||
&& !$hash->{helper}{q}{qReqConf} && !$hash->{helper}{q}{qReqStat} # no wuQueue is scheduled
|
||||
&& $hash->{helper}{prt}{sProc} < 2); # any changing to idle/processing
|
||||
}
|
||||
|
||||
###################-----------helper and shortcuts--------#####################
|
||||
@ -9607,6 +9682,7 @@ sub CUL_HM_updtRegDisp($$$) {
|
||||
}
|
||||
sub CUL_HM_cfgStateDelay($) {#update cfgState: schedule for devices
|
||||
my $name = shift;
|
||||
return if IsIgnored($name);
|
||||
CUL_HM_cfgStateUpdate("cfgStateUpdate:".CUL_HM_getDeviceName($name));
|
||||
}
|
||||
sub CUL_HM_cfgStateUpdate($) {#update cfgState
|
||||
@ -9619,7 +9695,7 @@ sub CUL_HM_cfgStateUpdate($) {#update cfgState
|
||||
){
|
||||
$defs{$name}{helper}{cfgStateUpdt} = 0;
|
||||
my ($hm) = devspec2array("TYPE=HMinfo");
|
||||
HMinfo_GetFn($defs{$hm},$hm,"configCheck","-f","^(".join("|",(CUL_HM_getAssChnNames($name),$name)).")\$") if (defined $hm);
|
||||
HMinfo_GetFn($defs{$hm},$hm,"configCheck","-f","^(".join("|",(CUL_HM_getAssChnNames($name),$name,CUL_HM_getPeers($name,"NamesExt"))).")\$") if (defined $hm);
|
||||
}
|
||||
else {
|
||||
$defs{$name}{helper}{cfgStateUpdt} = 1; # use to remove duplicate timer
|
||||
@ -11066,7 +11142,7 @@ sub CUL_HM_unQEntity($$){# remove entity from q
|
||||
my ($name,$q) = @_;
|
||||
my $devN = CUL_HM_getDeviceName($name);
|
||||
|
||||
return if (AttrVal($devN,"subType","") eq "virtual");
|
||||
return if (AttrVal($devN,'subType','') eq 'virtual') || IsIgnored($devN) || IsDummy($devN);
|
||||
|
||||
my $dq = $defs{$devN}{helper}{q};
|
||||
RemoveInternalTimer("sUpdt:$name") if ($q eq "qReqStat");#remove delayed
|
||||
@ -11098,7 +11174,7 @@ sub CUL_HM_qEntity($$){ # add to queue
|
||||
my ($name,$q) = @_;
|
||||
return if ($modules{CUL_HM}{helper}{hmManualOper});#no autoaction when manual
|
||||
my $devN = CUL_HM_getDeviceName($name);
|
||||
return if (AttrVal($devN,"subType","") eq "virtual");
|
||||
return if (AttrVal($devN,'subType','') eq 'virtual' || IsIgnored($devN) || IsDummy($devN));
|
||||
|
||||
$name = $devN if ($defs{$devN}{helper}{q}{$q} eq "00"); #already requesting all
|
||||
if ($devN eq $name){#config for all device
|
||||
@ -11109,7 +11185,7 @@ sub CUL_HM_qEntity($$){ # add to queue
|
||||
$defs{$devN}{helper}{q}{$q}
|
||||
.",".substr(CUL_HM_name2Id($name),6,2));
|
||||
}
|
||||
my $rxt = CUL_HM_getRxType($defs{$name});
|
||||
my $rxt = CUL_HM_getRxType($defs{$devN});
|
||||
my $wu = ($rxt & 0x1C) ? 'Wu' : ''; #normal or wakeup q?
|
||||
$q .= $wu;
|
||||
my $qa = $modules{CUL_HM}{helper}{$q};
|
||||
@ -11125,7 +11201,12 @@ sub CUL_HM_qEntity($$){ # add to queue
|
||||
InternalTimer(gettimeofday()+ $wT,"CUL_HM_procQs","CUL_HM_procQs", 0);
|
||||
}
|
||||
else {
|
||||
CUL_HM_hmInitMsgUpdt($defs{$devN}, 1) if ($rxt & 0x18); #wakeup prep for wakeup, lazyConfig
|
||||
if( $rxt & 0x18 #wakeup prep for wakeup, lazyConfig
|
||||
&& !(CUL_HM_getAttrInt($devN,'burstAccess') && $defs{$devN}->{cmdStack})
|
||||
&& !(defined($defs{$devN}->{helper}{io}{flgs}) && $defs{$devN}->{helper}{io}{flgs} & 0x02) # wuPrep is not active
|
||||
){
|
||||
CUL_HM_hmInitMsgUpdt($defs{$devN}, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -11176,7 +11257,7 @@ sub CUL_HM_procQs($){#process non-wakeup queues
|
||||
CUL_HM_Set($defs{$eN},$eN,"getConfig");
|
||||
}
|
||||
else{
|
||||
my $ign = CUL_HM_getAttrInt($eN,'ignore');
|
||||
my $ign = CUL_HM_getAttrInt($eN,'ignore') + IsDummy($eN);
|
||||
CUL_HM_Set($defs{$eN},$eN,'statusRequest') if (!$ign);
|
||||
CUL_HM_unQEntity($eN,'qReqStat') if (!$dq->{$q});
|
||||
InternalTimer(gettimeofday()+20,'CUL_HM_readStateTo','sUpdt:'.$eN,0) if (!$ign);
|
||||
@ -11302,8 +11383,6 @@ sub CUL_HM_getAttrInt($@){#return attrValue as integer
|
||||
my ($name,$attrName,$default) = @_;
|
||||
$default = 0 if (!defined $default);
|
||||
|
||||
if($modules{CUL_HM}{AttrListDef} && $modules{CUL_HM}{AttrListDef}{$attrName}){
|
||||
}
|
||||
|
||||
if($name && $defs{$name}){
|
||||
my $devN = $defs{$name}{device}?$defs{$name}{device}:$name;
|
||||
@ -11314,9 +11393,7 @@ sub CUL_HM_getAttrInt($@){#return attrValue as integer
|
||||
$val =~ s/(\d*).*/$1/;
|
||||
return int($val);
|
||||
}
|
||||
else{
|
||||
return $default;
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
|
||||
#+++++++++++++++++ external use +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
@ -11418,8 +11495,8 @@ sub CUL_HM_cleanShadowReg($){
|
||||
# remove shadow-regs if those are identical to readings or
|
||||
# the reading does not exist.
|
||||
# return dirty "1" if some shadowregs still remain active
|
||||
my ($name) = @_;
|
||||
my $hash = $defs{$name};
|
||||
my $name = shift // return 0;
|
||||
my $hash = $defs{$name} // return 0;
|
||||
my $dirty = 0;
|
||||
foreach my $rLn (keys %{$hash->{helper}{shadowReg}}){
|
||||
my $rLnP = ($hash->{helper}{expert}{raw} ? "" : ".").$rLn;
|
||||
|
Loading…
x
Reference in New Issue
Block a user