2
0
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:
martinp876 2013-10-09 12:02:22 +00:00
parent 56d5e2736d
commit 62c7057e71
4 changed files with 207 additions and 60 deletions

View File

@ -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>

View File

@ -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--------#####################

View File

@ -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>

View File

@ -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 ..."