mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-02-08 05:15:10 +00:00
HMLAN capacity supervision
git-svn-id: https://svn.fhem.de/fhem/trunk@4024 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
56d5e2736d
commit
62c7057e71
@ -65,6 +65,7 @@ sub HMLAN_Initialize($) {
|
||||
"hmId hmKey hmKey2 hmKey3 " .
|
||||
"respTime wdStrokeTime:5,10,15,20,25 " .
|
||||
"hmProtocolEvents:0_off,1_dump,2_dumpFull,3_dumpTrigger ".
|
||||
"hmMsgLowLimit ".
|
||||
"hmLanQlen:1_min,2_low,3_normal,4_high,5_critical ".
|
||||
"wdTimer ".
|
||||
$readingFnAttributes;
|
||||
@ -91,6 +92,9 @@ sub HMLAN_Define($$) {#########################################################
|
||||
}
|
||||
$attr{$name}{wdTimer} = 25;
|
||||
$attr{$name}{hmLanQlen} = "1_min"; #max message queue length in HMLan
|
||||
$attr{$name}{hmMsgLowLimit} = 550; #max msgs to be send per h -
|
||||
#then block low prio messages
|
||||
|
||||
no warnings 'numeric';
|
||||
$hash->{helper}{q}{hmLanQlen} = int($attr{$name}{hmLanQlen})+0;
|
||||
use warnings 'numeric';
|
||||
@ -100,6 +104,11 @@ sub HMLAN_Define($$) {#########################################################
|
||||
my @arr = ();
|
||||
@{$hash->{helper}{q}{apIDs}} = \@arr;
|
||||
|
||||
$hash->{helper}{q}{cap}{$_} = 0 for (0..9);
|
||||
$hash->{helper}{q}{cap}{last} = 0;
|
||||
$hash->{helper}{q}{cap}{sum} = 0;
|
||||
HMLAN_UpdtMsgCnt("UpdtMsg:".$name);
|
||||
|
||||
HMLAN_condUpdate($hash,253);#set disconnected
|
||||
$hash->{STATE} = "disconnected";
|
||||
|
||||
@ -178,6 +187,61 @@ sub HMLAN_Attr(@) {#################################
|
||||
HMLAN_SimpleWrite($defs{$name}, "Y03,".($k3?"$k3no,$k3":"00,"));
|
||||
return $retVal;
|
||||
}
|
||||
elsif($attrName eq "hmMsgLowLimit"){
|
||||
if ($cmd eq "del"){
|
||||
$attr{$name}{hmMsgLowLimit} = 500;# return to default
|
||||
}
|
||||
else{
|
||||
return "please add plain integer between 100 and 600"
|
||||
if ( $aVal !~ m/^(\d+)$/
|
||||
||$aVal<100
|
||||
||$aVal >300 );
|
||||
$attr{$name}{hmMsgLowLimit} =$aVal;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
sub HMLAN_UpdtMsgCnt($) {#################################
|
||||
# update HMLAN capacity counter
|
||||
# HMLAN will raise high-load after ~610 msgs per hour
|
||||
# overload with send-stop after 670 msgs
|
||||
# this count is an approximation and best guess - nevertheless it cannot
|
||||
# read the real values of HMLAN that might persist e.g. after FHEM reboot
|
||||
my($in ) = shift;
|
||||
my(undef,$name) = split(':',$in);
|
||||
|
||||
HMLAN_UpdtMsgLoad($name,0);
|
||||
InternalTimer(gettimeofday()+100, "HMLAN_UpdtMsgCnt", "UpdtMsg:".$name, 0);
|
||||
return;
|
||||
}
|
||||
sub HMLAN_UpdtMsgLoad($$) {#################################
|
||||
my($name,$incr) = @_;
|
||||
my $hash = $defs{$name};
|
||||
my $hCap = $hash->{helper}{q}{cap};
|
||||
|
||||
my $t = int(gettimeofday()/600)%6;# 10 min slices
|
||||
|
||||
if ($hCap->{last} != $t){
|
||||
$hCap->{last} = $t;
|
||||
$hCap->{$t} = 0;
|
||||
# try to release high-load condition with a dummy message
|
||||
# one a while
|
||||
HMLAN_Write($hash,"","As09998112"
|
||||
.AttrVal($name,"hmId","999999")
|
||||
."000001")
|
||||
if (ReadingsVal($name,"cond","") eq 'Warning-HighLoad');
|
||||
}
|
||||
$hCap->{$hCap->{last}}++ if ($incr);
|
||||
|
||||
my @tl;
|
||||
$hCap->{sum} = 0;
|
||||
for (($t-5)..$t){# we have 6 slices
|
||||
push @tl,$hCap->{$_%6};
|
||||
$hCap->{sum} += $hCap->{$_%6}; # need to recalc incase a slice was removed
|
||||
}
|
||||
|
||||
$hash->{msgLoad} = " total 1h:".$hCap->{sum}." recentSteps: ".join("/",reverse @tl);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -525,22 +589,23 @@ sub HMLAN_SimpleWrite(@) {#####################################################
|
||||
my ($src,$dst) = (substr($msg,40,6),substr($msg,46,6));
|
||||
my $hmId = $attr{$name}{hmId};
|
||||
my $hDst = $hash->{helper}{$dst};# shortcut
|
||||
my $tn = gettimeofday();
|
||||
if ($hDst->{nextSend}){
|
||||
my $DevDelay = $hDst->{nextSend} - gettimeofday();
|
||||
my $DevDelay = $hDst->{nextSend} - $tn;
|
||||
select(undef, undef, undef, (($DevDelay > 0.1)?0.1:$DevDelay))
|
||||
if ($DevDelay > 0.01);
|
||||
delete $hDst->{nextSend};
|
||||
}
|
||||
if ($dst ne $hmId){ #delay send if answer is pending
|
||||
if ( $hDst->{flg} && #HMLAN's ack pending
|
||||
($hDst->{to} > gettimeofday())){#won't wait forever! check timeout
|
||||
($hDst->{to} > $tn)){#won't wait forever! check timeout
|
||||
$hDst->{msg} = $msg; #postpone message
|
||||
Log $ll5,"HMLAN_Delay: $name $dst";
|
||||
return;
|
||||
}
|
||||
if ($src eq $hmId){
|
||||
$hDst->{flg} = (hex(substr($msg,36,2))&0x20)?1:0;# answer expected?
|
||||
$hDst->{to} = gettimeofday() + 2;# flag timeout after 2 sec
|
||||
$hDst->{to} = $tn + 2;# flag timeout after 2 sec
|
||||
$hDst->{msg} = "";
|
||||
HMLAN_qResp($hash,$dst,1) if ($hDst->{flg} == 1);
|
||||
}
|
||||
@ -565,6 +630,8 @@ sub HMLAN_SimpleWrite(@) {#####################################################
|
||||
.' ' .$8
|
||||
.' ' .$9
|
||||
.' ' .$10;
|
||||
|
||||
HMLAN_UpdtMsgLoad($name,1);
|
||||
}
|
||||
else{
|
||||
Log $ll5, 'HMLAN_Send: '.$name.' I:'.$msg;
|
||||
@ -598,9 +665,10 @@ sub HMLAN_DoInit($) {##########################################################
|
||||
HMLAN_SimpleWrite($defs{$name}, "Y03,".($k3?"$k3no,$k3":"00,"));
|
||||
HMLAN_SimpleWrite($hash, "T$s2000,04,00,00000000");
|
||||
delete $hash->{helper}{ref};
|
||||
|
||||
|
||||
HMLAN_condUpdate($hash,0xff);
|
||||
RemoveInternalTimer( "Overload:".$name);
|
||||
$hash->{helper}{q}{cap}{$_}=0 foreach (keys %{$hash->{helper}{q}{cap}});
|
||||
|
||||
foreach (keys %lhash){delete ($lhash{$_})};# clear IDs - HMLAN might have a reset
|
||||
$hash->{helper}{q}{keepAliveRec} = 1; # ok for first time
|
||||
@ -778,6 +846,15 @@ sub HMLAN_condUpdate($$) {#####################################################
|
||||
<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="#hmMsgLowLimit">hmMsgLowLimit</a><br>
|
||||
max number of messages allowed per hour before low-level message queue
|
||||
will be postponed. <br>
|
||||
HMLAN will allow a max of about 670 msgs per hour, then it will block sending.
|
||||
After 610 messages the low-priority queue (currently only CUL_HM autoReadReg)
|
||||
will be postponed anyway until the condition is cleared. <br>
|
||||
The counting of messages can be observed in msgLoad of HMLAN. It is updated every 10 min.
|
||||
Besides the hourly sum the six 10min counter are displayed.
|
||||
</li><br>
|
||||
<li><a href="#hmId">hmId</a></li><br>
|
||||
<li><a href="#hmKey">hmKey</a></li><br>
|
||||
<li><a href="#hmKey2">hmKey2</a></li><br>
|
||||
|
@ -120,7 +120,6 @@ my $IOpoll = 0.2;# poll speed to scan IO device out of order
|
||||
my $IOpolltout = 60; # poll timeout - stop poll and discard if to late
|
||||
|
||||
my $maxPendCmds = 10; #number of parallel requests
|
||||
my $autoConfDly = 12; # delay autoConf readings
|
||||
|
||||
# need to take care that ACK is first
|
||||
#+++++++++++++++++ startup, init, definition+++++++++++++++++++++++++++++++++++
|
||||
@ -146,6 +145,8 @@ sub CUL_HM_Initialize($) {
|
||||
"param msgRepeat ".
|
||||
".stc .devInfo ".
|
||||
$readingFnAttributes;
|
||||
$hash->{hmAutoReadScan} = 4; # delay autoConf readings
|
||||
|
||||
my @modellist;
|
||||
foreach my $model (keys %culHmModel){
|
||||
push @modellist,$culHmModel{$model}{name};
|
||||
@ -171,18 +172,45 @@ sub CUL_HM_reqStatus($){
|
||||
sub CUL_HM_autoReadConfig($){
|
||||
# will trigger a getConfig and statusrequest for each device assigned.
|
||||
#
|
||||
return if (!$modules{CUL_HM}{helper}{autoRdCfgLst});
|
||||
if (!$modules{CUL_HM}{helper}{autoRdCfgLst}){
|
||||
delete $modules{CUL_HM}{helper}{autoRdActive};
|
||||
return;
|
||||
}
|
||||
while(@{$modules{CUL_HM}{helper}{autoRdCfgLst}}){
|
||||
|
||||
if ( $modules{CUL_HM}{helper}{autoRdActive} # predecisor is stored
|
||||
&& $defs{$modules{CUL_HM}{helper}{autoRdActive}}){
|
||||
my $dName = CUL_HM_getDeviceName($modules{CUL_HM}{helper}{autoRdActive});
|
||||
if ($defs{$dName}{helper}{prt}{sProc}){ # predecisor still working
|
||||
InternalTimer(gettimeofday()+$modules{CUL_HM}{hmAutoReadScan}
|
||||
,"CUL_HM_autoReadConfig"
|
||||
,"autoRdCfg",0);
|
||||
last;
|
||||
}
|
||||
}
|
||||
my $tName = ${$modules{CUL_HM}{helper}{autoRdCfgLst}}[0]; # test before remove
|
||||
my $ioName = $defs{$tName}{IODev}{NAME};
|
||||
if (ReadingsVal($ioName,"cond","") !~ m /^(ok|Overload-released|init)$/
|
||||
|| ( $defs{$ioName}{helper}{q}
|
||||
&& $defs{$ioName}{helper}{q}{cap}{sum}>AttrVal($ioName,"hmMsgLowLimit",500))){
|
||||
InternalTimer(gettimeofday()+$modules{CUL_HM}{hmAutoReadScan}
|
||||
,"CUL_HM_autoReadConfig"
|
||||
,"autoRdCfg",0);
|
||||
last;
|
||||
}
|
||||
#--- unqueue and process---
|
||||
my $name = shift(@{$modules{CUL_HM}{helper}{autoRdCfgLst}});
|
||||
my $hash = $defs{$name};
|
||||
delete $hash->{autoRead};
|
||||
|
||||
if (0 != CUL_HM_getAttrInt($name,"autoReadReg")){
|
||||
CUL_HM_Set($hash,$name,"getSerial");
|
||||
#CUL_HM_Set($hash,$name,"getSerial");
|
||||
CUL_HM_Set($hash,$name,"getConfig");
|
||||
CUL_HM_Set($hash,$name,"statusRequest");
|
||||
InternalTimer(gettimeofday()+$autoConfDly
|
||||
InternalTimer(gettimeofday()+$modules{CUL_HM}{hmAutoReadScan}
|
||||
,"CUL_HM_autoReadConfig"
|
||||
,"autoRdCfg",0);
|
||||
$modules{CUL_HM}{helper}{autoRdActive} = $name;#remember name
|
||||
last;
|
||||
}
|
||||
}
|
||||
@ -273,7 +301,7 @@ sub CUL_HM_updateConfig($){
|
||||
if ($st eq "virtual" ){$webCmd="press short:press long";
|
||||
}elsif($hash->{helper}{role}{dev} &&
|
||||
!$hash->{helper}{role}{chn} &&
|
||||
$st ne "thermostat" ){$webCmd="getConfig";
|
||||
$md ne "HM-CC-TC" ){$webCmd="getConfig";
|
||||
}elsif($st eq "blindActuator"){$webCmd="toggle:on:off:up:down:stop:statusRequest";
|
||||
}elsif($st eq "dimmer" ){$webCmd="toggle:on:off:up:down:statusRequest";
|
||||
}elsif($st eq "switch" ){$webCmd="toggle:on:off:statusRequest";
|
||||
@ -342,7 +370,7 @@ sub CUL_HM_Define($$) {##############################
|
||||
CUL_HM_ActGetCreateHash() if($HMid eq '000000');#startTimer
|
||||
$hash->{DEF} = $HMid;
|
||||
CUL_HM_Parse($hash, $a[3]) if(int(@a) == 4);
|
||||
|
||||
|
||||
CUL_HM_queueUpdtCfg($name);
|
||||
return undef;
|
||||
}
|
||||
@ -2205,9 +2233,10 @@ sub CUL_HM_Set($@) {
|
||||
}
|
||||
}
|
||||
elsif($sect eq "msgEvents"){
|
||||
return if (!$hash->{IODev}{NAME});
|
||||
CUL_HM_respPendRm($hash);
|
||||
|
||||
delete $hash->{helper}{burstEvtCnt};
|
||||
$hash->{helper}{prt}{bErr}=0;
|
||||
delete $hash->{cmdStack};
|
||||
delete $hash->{EVENTS};
|
||||
delete $hash->{helper}{prt}{rspWait};
|
||||
@ -2221,6 +2250,9 @@ sub CUL_HM_Set($@) {
|
||||
@{$modules{CUL_HM}{$hash->{IODev}{NAME}}{pendDev}} =
|
||||
grep !/$name/,@{$modules{CUL_HM}{$hash->{IODev}{NAME}}{pendDev}};
|
||||
}
|
||||
@{$modules{CUL_HM}{helper}{autoRdCfgLst}} =
|
||||
grep !/$name/,@{$modules{CUL_HM}{helper}{autoRdCfgLst}}
|
||||
if ($modules{CUL_HM}{helper}{autoRdCfgLst});
|
||||
CUL_HM_protState($hash,"Info_Cleared");
|
||||
}
|
||||
elsif($sect eq "rssi"){
|
||||
@ -3060,7 +3092,7 @@ sub CUL_HM_Set($@) {
|
||||
if (!$target || $target =~ m/^(actor|both)$/ ){
|
||||
if ($pSt eq "virtual"){
|
||||
CUL_HM_ID2PeerList ($peerN,$dst.sprintf("%02X",$b2),$set); #update peerlist
|
||||
CUL_HM_ID2PeerList ($peerN,$dst.sprintf("%02X",$b1),$set) if ($b1 & !$single); #update peerlist
|
||||
CUL_HM_ID2PeerList ($peerN,$dst.sprintf("%02X",$b1),$set) if ($b1 & !$single);
|
||||
}
|
||||
else{
|
||||
my $peerFlag = CUL_HM_getFlag($peerHash);
|
||||
@ -3086,7 +3118,7 @@ sub CUL_HM_Set($@) {
|
||||
}
|
||||
elsif(($rxType & 0x80) && #burstConditional - have a try
|
||||
$devHash->{cmdStack} &&
|
||||
!$devHash->{helper}{prt}{sProc}
|
||||
$devHash->{helper}{prt}{sProc} != 1 # not pocessing
|
||||
){
|
||||
$hash->{helper}{prt}{awake}=1;# start wakeup
|
||||
CUL_HM_SndCmd($devHash,"++B112$id$dst");
|
||||
@ -3115,7 +3147,8 @@ sub CUL_HM_valvePosUpdt(@) {#update valve position periodically to please valve
|
||||
foreach my $peer (sort(split(',',AttrVal($name,"peerIDs","")))) {
|
||||
next if (length($peer) != 8);
|
||||
$peer = substr($peer,0,6);
|
||||
CUL_HM_PushCmdStack($hash,sprintf("++A258%s%s%s%02X",$vDevId,$peer,$hash->{helper}{virtTC},$vp));
|
||||
CUL_HM_PushCmdStack($hash,sprintf("++A258%s%s%s%02X",$vDevId
|
||||
,$peer,$hash->{helper}{virtTC},$vp));
|
||||
}
|
||||
# }
|
||||
$hash->{helper}{virtTC} = "00";
|
||||
@ -3176,8 +3209,8 @@ sub CUL_HM_Pair(@) {
|
||||
my $id = CUL_HM_Id($iohash);
|
||||
my $serNo = $attr{$name}{serialNr};
|
||||
|
||||
Log GetLogLevel($name,3),
|
||||
"CUL_HM pair: $name $attr{$name}{subType}, model $attr{$name}{model} serialNr $serNo";
|
||||
Log GetLogLevel($name,3), "CUL_HM pair: $name $attr{$name}{subType}, "
|
||||
."model $attr{$name}{model} serialNr $serNo";
|
||||
|
||||
# Abort if we are not authorized
|
||||
if($dst eq "000000") {
|
||||
@ -3207,10 +3240,10 @@ sub CUL_HM_Pair(@) {
|
||||
sub CUL_HM_getConfig($$$$$){
|
||||
my ($hash,$chnhash,$id,$dst,$chn) = @_;
|
||||
my $flag = CUL_HM_getFlag($hash);
|
||||
# foreach my $readEntry (grep /^[\.]?(RegL_|R-)/,keys %{$chnhash->{READINGS}}){
|
||||
foreach my $readEntry (grep /^[\.]?(RegL_)/,keys %{$chnhash->{READINGS}}){
|
||||
delete $chnhash->{READINGS}{$readEntry};
|
||||
}
|
||||
|
||||
delete $chnhash->{READINGS}{$_}
|
||||
foreach (grep /^[\.]?(RegL_)/,keys %{$chnhash->{READINGS}});
|
||||
|
||||
my $lstAr = $culHmModel{CUL_HM_getMId($hash)}{lst};
|
||||
if($lstAr){
|
||||
my @list = split(",",$lstAr); #get valid lists e.g."1, 5:2.3p ,6:2"
|
||||
@ -3226,7 +3259,7 @@ sub CUL_HM_getConfig($$$$$){
|
||||
my @chnLst = split('\.',$chnLst1);
|
||||
foreach my $lchn (@chnLst){
|
||||
$peerReq = 1 if ($lchn =~ m/p/);
|
||||
no warnings;#know that lchan may be followed by a 'p' causing a warning
|
||||
no warnings;#know that lchan may be followed by 'p' causing a warning
|
||||
$chnValid = 1 if (int($lchn) == hex($chn));
|
||||
use warnings;
|
||||
last if ($chnValid);
|
||||
@ -3239,12 +3272,14 @@ sub CUL_HM_getConfig($$$$$){
|
||||
$chnhash->{helper}{getCfgListNo} = $listNo;
|
||||
}
|
||||
if (!$pReq){#get peers first, but only once per channel
|
||||
CUL_HM_PushCmdStack($hash,sprintf("++%s01%s%s%s03",$flag,$id,$dst,$chn));
|
||||
CUL_HM_PushCmdStack($hash,sprintf("++%s01%s%s%s03"
|
||||
,$flag,$id,$dst,$chn));
|
||||
$pReq = 1;
|
||||
}
|
||||
}
|
||||
else{
|
||||
CUL_HM_PushCmdStack($hash,sprintf("++%s01%s%s%s0400000000%02X",$flag,$id,$dst,$chn,$listNo));
|
||||
CUL_HM_PushCmdStack($hash,sprintf("++%s01%s%s%s0400000000%02X"
|
||||
,$flag,$id,$dst,$chn,$listNo));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3260,7 +3295,8 @@ sub CUL_HM_pushConfig($$$$$$$$@) {#generate messages to config data to register
|
||||
$chn = sprintf("%02X",$chn);
|
||||
$peerChn = sprintf("%02X",$peerChn);
|
||||
$list = sprintf("%02X",$list);
|
||||
|
||||
$prep = "" if (!defined $prep);
|
||||
|
||||
# --store pending changes in shadow to handle bit manipulations cululativ--
|
||||
$peerAddr = "000000" if(!$peerAddr);
|
||||
my $peerN = ($peerAddr ne "000000")?CUL_HM_peerChName($peerAddr.$peerChn,$dst,""):"";
|
||||
@ -3271,7 +3307,7 @@ sub CUL_HM_pushConfig($$$$$$$$@) {#generate messages to config data to register
|
||||
#--- copy data from readings to shadow
|
||||
my $chnhash = $modules{CUL_HM}{defptr}{$dst.$chn};
|
||||
$chnhash = $hash if (!$chnhash);
|
||||
my $rRd = ReadingsVal($chnhash->{NAME},$regLN,"");#General
|
||||
my $rRd = ReadingsVal($chnhash->{NAME},$regLN,"");
|
||||
if (!$chnhash->{helper}{shadowReg} ||
|
||||
!$chnhash->{helper}{shadowReg}{$regLN}){
|
||||
$chnhash->{helper}{shadowReg}{$regLN} = $rRd;
|
||||
@ -3289,7 +3325,7 @@ sub CUL_HM_pushConfig($$$$$$$$@) {#generate messages to config data to register
|
||||
my $change;
|
||||
if ($prep eq "exec"){#update complete registerset
|
||||
foreach (sort split " ",$chnhash->{helper}{shadowReg}{$regLN}){
|
||||
$change .= $_." " if ($rRd !~ m /$_/);
|
||||
$change .= $_." " if ($rRd !~ m /$_/);# filter only changes
|
||||
}
|
||||
$change =~ s/(\ |:)//g;
|
||||
}
|
||||
@ -3315,14 +3351,14 @@ sub CUL_HM_PushCmdStack($$) {
|
||||
my @arr = ();
|
||||
my $hash = CUL_HM_getDeviceHash($chnhash);
|
||||
my $name = $hash->{NAME};
|
||||
if(!$hash->{cmdStack}){
|
||||
if(!$hash->{cmdStack}){# this is a new 'burst' of messages
|
||||
$hash->{cmdStack} = \@arr;
|
||||
delete ($hash->{helper}{burstEvtCnt}) if (!$hash->{helper}{prt}{rspWait});
|
||||
$hash->{helper}{prt}{bErr}=0 if ($hash->{helper}{prt}{sProc} != 1);# not processing
|
||||
}
|
||||
push(@{$hash->{cmdStack}}, $cmd);
|
||||
my $entries = scalar @{$hash->{cmdStack}};
|
||||
$hash->{protCmdPend} = $entries." CMDs_pending";
|
||||
CUL_HM_protState($hash,"CMDs_pending") if(!$hash->{helper}{prt}{sProc});
|
||||
CUL_HM_protState($hash,"CMDs_pending") if($hash->{helper}{prt}{sProc} != 1);# not processing
|
||||
}
|
||||
sub CUL_HM_ProcessCmdStack($) {
|
||||
my ($chnhash) = @_;
|
||||
@ -3335,8 +3371,8 @@ sub CUL_HM_ProcessCmdStack($) {
|
||||
delete($hash->{cmdStack});
|
||||
delete($hash->{protCmdPend});
|
||||
#-- update info ---
|
||||
CUL_HM_protState($hash,"CMDs_done".($hash->{helper}{burstEvtCnt}?
|
||||
("_events:".$hash->{helper}{burstEvtCnt}):""));
|
||||
CUL_HM_protState($hash,"CMDs_done".($hash->{helper}{prt}{bErr}?
|
||||
("_Errors:".$hash->{helper}{prt}{bErr}):""));
|
||||
}
|
||||
}
|
||||
return;
|
||||
@ -3345,6 +3381,7 @@ sub CUL_HM_ProcessCmdStack($) {
|
||||
sub CUL_HM_prtInit ($){ #setup protocol variables after define
|
||||
my ($hash)=@_;
|
||||
$hash->{helper}{prt}{sProc} = 0; # stack not being processed by now
|
||||
$hash->{helper}{prt}{bErr}=0;
|
||||
}
|
||||
sub CUL_HM_respWaitSu ($@){ #setup response for multi-message response
|
||||
# single commands
|
||||
@ -3443,8 +3480,8 @@ sub CUL_HM_responseSetup($$) {#store all we need to handle the response
|
||||
InternalTimer(gettimeofday()+.5, "CUL_HM_ProcessCmdStack", $hash, 0);
|
||||
}
|
||||
else{
|
||||
CUL_HM_protState($hash,"CMDs_done".($hash->{helper}{burstEvtCnt}?
|
||||
("_events:".$hash->{helper}{burstEvtCnt}):""));
|
||||
CUL_HM_protState($hash,"CMDs_done".($hash->{helper}{prt}{bErr}?
|
||||
("_Errors:".$hash->{helper}{prt}{bErr}):""));
|
||||
}
|
||||
}
|
||||
|
||||
@ -3630,20 +3667,18 @@ sub CUL_HM_eventP($$) {#handle protocol events
|
||||
my ($evntCnt,undef) = split(' last_at:',$evnt);
|
||||
$nAttr->{"prot".$evntType} = ++$evntCnt." last_at:".TimeNow();
|
||||
|
||||
if ($evntType !~ m/(Snd|Evt_AESok)/){#count abnormal events
|
||||
$hash->{helper}{burstEvtCnt}=0 if(!defined $hash->{helper}{burstEvtCnt});
|
||||
$hash->{helper}{burstEvtCnt}++;
|
||||
}
|
||||
if ($evntType =~ m/(Nack|ResndFail|IOerr)/){
|
||||
if ($evntType =~ m/(Nack|ResndFail|IOerr)/){# unrecoverable Error
|
||||
$hash->{helper}{prt}{bErr}++;
|
||||
$nAttr->{protCmdDel}++;
|
||||
if ( (CUL_HM_getRxType($hash) & 0x03) == 0 #to slow for wakeup and config
|
||||
|| $evntType eq "IOerr"){ #IO problem
|
||||
$nAttr->{protCmdDel} = 0 if(!$nAttr->{protCmdDel});
|
||||
$nAttr->{protCmdDel} += scalar @{$hash->{cmdStack}} + 1
|
||||
$nAttr->{protCmdDel} += scalar @{$hash->{cmdStack}}
|
||||
if ($hash->{cmdStack});
|
||||
delete($hash->{cmdStack});
|
||||
delete($nAttr->{protCmdPend});
|
||||
CUL_HM_protState($hash,"CMDs_done".($hash->{helper}{burstEvtCnt}?
|
||||
("_events:".$hash->{helper}{burstEvtCnt}):""));
|
||||
CUL_HM_protState($hash,"CMDs_done".($hash->{helper}{prt}{bErr}?
|
||||
("_Errors:".$hash->{helper}{prt}{bErr}):""));
|
||||
}
|
||||
CUL_HM_respPendRm($hash);
|
||||
}
|
||||
@ -3656,15 +3691,17 @@ sub CUL_HM_protState($$){
|
||||
Log GetLogLevel($name,6),"CUL_HM $name protEvent:$state".
|
||||
($hash->{cmdStack}?" pending:".scalar @{$hash->{cmdStack}}:"");
|
||||
|
||||
if ($state =~ m/^CMDs_done/){ DoTrigger($name, undef);
|
||||
if ($state =~ m/^CMDs_done/) {DoTrigger($name, undef);
|
||||
$hash->{helper}{prt}{sProc} = 0;
|
||||
$hash->{helper}{prt}{awake} = 0 if (defined$hash->{helper}{prt}{awake}); # asleep
|
||||
}
|
||||
elsif($state =~ m/processing/){ $hash->{helper}{prt}{sProc} = 1;
|
||||
elsif($state =~ m/processing/) {$hash->{helper}{prt}{sProc} = 1;
|
||||
}
|
||||
elsif($state eq "Info_Cleared"){$hash->{helper}{prt}{sProc} = 0;
|
||||
$hash->{helper}{prt}{awake} = 0 if (defined$hash->{helper}{prt}{awake}); # asleep
|
||||
}
|
||||
elsif($state eq "CMDs_pending"){$hash->{helper}{prt}{sProc} = 2;
|
||||
}
|
||||
}
|
||||
|
||||
###################-----------helper and shortcuts--------#####################
|
||||
|
@ -26,6 +26,7 @@ sub HMinfo_Initialize($$) {####################################################
|
||||
$hash->{AttrList} = "loglevel:0,1,2,3,4,5,6 ".
|
||||
"sumStatus sumERROR ".
|
||||
"autoUpdate ".
|
||||
"hmAutoReadScan ".
|
||||
$readingFnAttributes;
|
||||
|
||||
}
|
||||
@ -68,6 +69,23 @@ sub HMinfo_Attr(@) {#################################
|
||||
$hash->{helper}{autoUpdate} = $sec;
|
||||
InternalTimer(gettimeofday()+$sec,"HMinfo_autoUpdate","sUpdt:".$name,0);
|
||||
}
|
||||
elsif ($attrName eq "hmAutoReadScan"){# 00:00 hh:mm
|
||||
if ($cmd eq "del"){
|
||||
$modules{CUL_HM}{hmAutoReadScan} = 4;# return to default
|
||||
}
|
||||
else{
|
||||
return "please add plain integer between 1 and 300"
|
||||
if ( $attrVal !~ m/^(\d+)$/
|
||||
||$attrVal<0
|
||||
||$attrVal >300 );
|
||||
## implement new timer to CUL_HM
|
||||
$modules{CUL_HM}{hmAutoReadScan}=$attrVal;
|
||||
RemoveInternalTimer("autoRdCfg");
|
||||
InternalTimer(gettimeofday()+$modules{CUL_HM}{hmAutoReadScan}
|
||||
,"CUL_HM_autoReadConfig"
|
||||
,"autoRdCfg",0);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
sub HMinfo_autoUpdate($){#in:name, send status-request
|
||||
@ -328,7 +346,6 @@ sub HMinfo_SetFn($@) {#########################################################
|
||||
}
|
||||
push @IOlist,$defs{$pl[0]}{IODev}->{NAME};
|
||||
}
|
||||
|
||||
|
||||
my $hdr = sprintf("%-20s:%-16s|%-18s|%-18s|%-14s|%-18s#%-18s|%-18s|%-18s|%-18s",
|
||||
,"name"
|
||||
@ -343,18 +360,21 @@ sub HMinfo_SetFn($@) {#########################################################
|
||||
$ret = $cmd." done:" ."\n ".$hdr ."\n ".(join "\n ",sort @paramList)
|
||||
;
|
||||
$ret .= "\n\n CUL_HM queue:$modules{CUL_HM}{prot}{rspPend}";
|
||||
$ret .= "\n autoRegRead pending:".
|
||||
join(",",@{$modules{CUL_HM}{helper}{autoRdCfgLst}})
|
||||
$ret .= "\n autoRegRead pending:"
|
||||
.join(",",@{$modules{CUL_HM}{helper}{autoRdCfgLst}})
|
||||
.($modules{CUL_HM}{helper}{autoRdActive}?" recent:".$modules{CUL_HM}{helper}{autoRdActive}:"")
|
||||
if ($modules{CUL_HM}{helper}{autoRdCfgLst});
|
||||
$ret .= "\n status request pending:".
|
||||
join(",",@{$modules{CUL_HM}{helper}{reqStatus}})
|
||||
if ($modules{CUL_HM}{helper}{reqStatus});
|
||||
@IOlist = HMinfo_noDup(@IOlist);
|
||||
foreach(@IOlist){
|
||||
$_ .= ":".$defs{$_}{STATE}.
|
||||
(defined $defs{$_}{helper}{q}{answerPend}?
|
||||
$_ .= ":".$defs{$_}{STATE}
|
||||
.(defined $defs{$_}{helper}{q}{answerPend}?
|
||||
" pending=".$defs{$_}{helper}{q}{answerPend} :
|
||||
"");
|
||||
"")
|
||||
." condition:".ReadingsVal($_,"cond","-")
|
||||
."\n msgLoad: ".$defs{$_}{msgLoad};
|
||||
}
|
||||
$ret .= "\n IODevs:".(join"\n ",HMinfo_noDup(@IOlist));
|
||||
}
|
||||
@ -1383,6 +1403,15 @@ sub HMinfo_noDup(@) {#return list with no duplicates
|
||||
</code></ul>
|
||||
will trigger the update every 10 min<br>
|
||||
</li>
|
||||
<li><a name="#HMhmAutoReadScan">hmAutoReadScan</a>
|
||||
defines the time in seconds CUL_HM tries to schedule the next autoRead
|
||||
from the queue. Despide this timer FHEM will take care that only one device from the queue will be
|
||||
handled at one point in time. With this timer user can stretch timing even further - to up to 300sec
|
||||
min delay between execution. <br>
|
||||
Setting to 1 still obeys the "only one at a time" prinzip.<br>
|
||||
Note that compressing will increase message load while stretch will extent waiting time.
|
||||
data. <br>
|
||||
</li>
|
||||
</ul>
|
||||
<br>
|
||||
<a name="HMinfovariables"><b>Variables</b></a>
|
||||
|
@ -563,7 +563,7 @@ my %culHmRegDefine = (
|
||||
decalcWeekday =>{a=> 7 ,s=>0.3,l=>7,min=>0 ,max=>7 ,c=>'lit' ,f=>'' ,u=>'' ,d=>1,t=>"decalc at day" ,lit=>{Sat=>0,Sun=>1,Mon=>2,Tue=>3,Wed=>4,Thu=>5,Fri=>6}},
|
||||
decalcTime =>{a=> 8 ,s=>0.6,l=>7,min=>0 ,max=>1410 ,c=>'min2time' ,f=>'' ,u=>'' ,d=>1,t=>"decalc at hour"},
|
||||
tempOffset =>{a=> 9 ,s=>0.4,l=>7,min=>0 ,max=>15 ,c=>'lit' ,f=>'' ,u=>'' ,d=>1,t=>"temperature offset",lit=>{"-3.5K"=>0,"-3.0K"=>1,"-2.5K"=>2,"-2.0K"=>3,"-1.5K"=>4,"-1.0K"=>5,"-0.5K"=>6,
|
||||
"0.0K"=>7, "0.5K"=>8, "1.0K"=>10, "1.5K"=>11, "2.0K"=>12, "2.5K"=>13, "3.0K"=>14, "3.5K"=>15}},
|
||||
"0.0K"=>7, "0.5K"=>8, "1.0K"=>9, "1.5K"=>10, "2.0K"=>11, "2.5K"=>12, "3.0K"=>13, "3.5K"=>14}},
|
||||
btnNoBckLight =>{a=> 9.4,s=>0.1,l=>7,min=>0 ,max=>1 ,c=>'lit' ,f=>'' ,u=>'' ,d=>1,t=>"button response without backlight",lit=>{off=>0,on=>1}},
|
||||
boostPos =>{a=> 10.0,s=>0.5,l=>7,min=>0 ,max=>100 ,c=>'' ,f=>'0.2' ,u=>'%' ,d=>1,t=>"valve boost position"},
|
||||
boostPeriod =>{a=> 10.5,s=>0.3,l=>7,min=>0 ,max=>6 ,c=>'lit' ,f=>'' ,u=>'min' ,d=>1,t=>"boost period [min]" ,lit=>{0=>0,5=>1,10=>2,15=>3,20=>4,25=>5,30=>6}},
|
||||
@ -909,22 +909,25 @@ my %culHmGlobalSetsDevice = (# all devices but virtuals
|
||||
reset => "",
|
||||
pair => "",
|
||||
unpair => "",
|
||||
getSerial => "",
|
||||
);
|
||||
|
||||
my %culHmSubTypeDevSets = (# device of this subtype
|
||||
switch =>{ statusRequest =>""},
|
||||
dimmer =>{ statusRequest =>""},
|
||||
blindActuator =>{ statusRequest =>""},
|
||||
switch =>{ statusRequest => "",
|
||||
getSerial => ""},
|
||||
dimmer =>{ statusRequest => "",
|
||||
getSerial => ""},
|
||||
blindActuator =>{ statusRequest => "",
|
||||
getSerial => ""},
|
||||
# remote =>{ },
|
||||
threeStateSensor =>{ statusRequest =>""},
|
||||
# THSensor =>{ statusRequest =>""}, at least OT/OT2 do not support this
|
||||
# virtual =>{ },
|
||||
smokeDetector =>{ statusRequest =>""},
|
||||
winMatic =>{ statusRequest =>""},
|
||||
keyMatic =>{ statusRequest =>""},
|
||||
repeater =>{ statusRequest =>""},
|
||||
outputUnit =>{ statusRequest =>""},
|
||||
smokeDetector =>{ statusRequest => ""},
|
||||
winMatic =>{ statusRequest => ""},
|
||||
keyMatic =>{ statusRequest => ""},
|
||||
repeater =>{ statusRequest => "",
|
||||
getSerial => ""},
|
||||
outputUnit =>{ statusRequest => ""},
|
||||
);
|
||||
|
||||
my %culHmGlobalSetsChn = (# all channels but virtuals
|
||||
@ -1030,7 +1033,8 @@ $culHmModelSets{"HM-OU-CM-PCB"} = $culHmModelSets{"HM-OU-CFM-PL"};
|
||||
|
||||
my %culHmChanSets = (
|
||||
"HM-CC-TC00" =>{ "desired-temp" =>"[on|off|6.0..30.0]"
|
||||
,sysTime =>"" },
|
||||
,sysTime =>""
|
||||
,getSerial => ""},
|
||||
"HM-CC-TC02" =>{ peerChan =>" 0 <actChn> ... single [set|unset] [actor|remote|both]"
|
||||
,"desired-temp" =>"[on|off|6.0..30.0]"
|
||||
,tempListSat =>"HH:MM temp ..."
|
||||
|
Loading…
x
Reference in New Issue
Block a user