2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-10 09:16:53 +00:00

overload enhamcements - step1

git-svn-id: https://svn.fhem.de/fhem/trunk@4040 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
martinp876 2013-10-13 18:28:05 +00:00
parent cf3b36b9c3
commit 4015ac8270
4 changed files with 95 additions and 53 deletions

View File

@ -94,8 +94,6 @@ 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;
@ -200,14 +198,11 @@ sub HMLAN_Attr(@) {############################################################
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 ($cmd eq "set"){
return "hmMsgLowLimit:please add integer between 10 and 120"
if ( $aVal !~ m/^(\d+)$/
||$aVal<100
||$aVal >600 );
||$aVal<10
||$aVal >120 );
$attr{$name}{hmMsgLowLimit} =$aVal;
}
}
@ -244,16 +239,16 @@ sub HMLAN_UpdtMsgLoad($$) {####################################################
."000001")
if (ReadingsVal($name,"cond","") eq 'Warning-HighLoad');
}
$hCap->{$hCap->{last}}++ if ($incr);
$hCap->{$hCap->{last}}+=$incr if ($incr);
my @tl;
$hCap->{sum} = 0;
for (($t-5)..$t){# we have 6 slices
push @tl,$hCap->{$_%6};
push @tl,int($hCap->{$_%6}/16.8);
$hCap->{sum} += $hCap->{$_%6}; # need to recalc incase a slice was removed
}
$hash->{msgLoad} = " total 1h:".$hCap->{sum}." recentSteps: ".join("/",reverse @tl);
$hash->{msgLoadEst} = "1hour:".int($hCap->{sum}/16.8)."% 10min steps: ".join("/",reverse @tl);
#testing only ." :".$hCap->{sum}
return;
}
@ -450,7 +445,7 @@ sub HMLAN_Parse($$) {##########################################################
.' '.$p;
# handle status.
#HMcond stat
#HMcnd stat
# 00 00= msg without relation
# 00 01= ack that HMLAN waited for
# 00 02= msg send, no ack requested
@ -470,7 +465,8 @@ sub HMLAN_Parse($$) {##########################################################
# Cond text
# 0 ok
# 2 Warning-HighLoad
#
# 4 Overload condition - no send anymore
#
my $stat = hex($mFld[1]);
my $HMcnd =$stat >>8; #high = HMLAN cond
$stat &= 0xff; # low byte related to message format
@ -485,6 +481,20 @@ sub HMLAN_Parse($$) {##########################################################
if ($stat & 0x03 && $dst eq $attr{$name}{hmId}){HMLAN_qResp($hash,$src,0);}
elsif ($stat & 0x08 && $src eq $attr{$name}{hmId}){HMLAN_qResp($hash,$dst,0);}
# HMLAN_UpdtMsgLoad($name,(($stat & 0x09)?(($stat & 0x08)?2 #2 repetitions
# :1)#one ack
# :0) #no ack
# *((hex($flg)&0x10)?17 #burst=17units
# :1)); #ACK=1 unit
# HMLAN_UpdtMsgLoad($name,(($stat & 0x08)?2 #2 repetitions
# :0) #one ack
# *((hex($flg)&0x10)?17 #burst=17units
# :1)); #ACK=1 unit
HMLAN_UpdtMsgLoad($name,((hex($flg)&0x10)?34 #burst=17units *2
:2)) #ACK=1 unit *2
if (($stat & 0x48) == 8);# reject - but not from repeater
$hash->{helper}{$dst}{flg} = 0;#got response => unblock sending
if ($stat & 0x0A){#08 and 02 dont need to go to CUL, internal ack only
Log $ll5, "HMLAN_Parse: $name no ACK from $dst" if($stat & 0x08);
@ -496,6 +506,12 @@ sub HMLAN_Parse($$) {##########################################################
}elsif (($stat & 0x70) == 0x40){;#$CULinfo = "???";
}
}
else{
HMLAN_UpdtMsgLoad($name,1)
if ( $letter eq "E"
&& (hex($flg)&0x60) == 0x20 # ack but not from repeater
&& $dst eq $attr{$name}{hmId});
}
my $rssi = hex($mFld[4])-65536;
#update some User information ------
@ -597,7 +613,10 @@ sub HMLAN_SimpleWrite(@) {#####################################################
return if ($HMcnd == 4 || $HMcnd == 253);# no send if overload or disconnect
}
my ($src,$dst) = (substr($msg,40,6),substr($msg,46,6));
$msg =~ m/(.{9}).(..).(.{8}).(..).(.{8}).(..)(..)(..)(.{6})(.{6})(.*)/;
my ($s,$stat,$t,$d,$r,$no,$flg,$typ,$src,$dst,$p) =
($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11);
my $hmId = $attr{$name}{hmId};
my $hDst = $hash->{helper}{$dst};# shortcut
my $tn = gettimeofday();
@ -615,7 +634,7 @@ sub HMLAN_SimpleWrite(@) {#####################################################
return;
}
if ($src eq $hmId){
$hDst->{flg} = (hex(substr($msg,36,2))&0x20)?1:0;# answer expected?
$hDst->{flg} = (hex($flg)&0x20)?1:0;# answer expected?
$hDst->{to} = $tn + 2;# flag timeout after 2 sec
$hDst->{msg} = "";
HMLAN_qResp($hash,$dst,1) if ($hDst->{flg} == 1);
@ -630,19 +649,18 @@ sub HMLAN_SimpleWrite(@) {#####################################################
}
$hDst->{chn} = $chn;
}
$msg =~ m/(.{9}).(..).(.{8}).(..).(.{8}).(..)(....)(.{6})(.{6})(.*)/;
Log $ll5, 'HMLAN_Send: '.$name.' S:'.$1
.' stat: ' .$2
.' t:' .$3
.' d:' .$4
.' r:' .$5
.' m:' .$6
.' ' .$7
.' ' .$8
.' ' .$9
.' ' .$10;
Log $ll5, 'HMLAN_Send: '.$name.' S:'.$s
.' stat: ' .$stat
.' t:' .$t
.' d:' .$d
.' r:' .$r
.' m:' .$no
.' ' .$flg.$typ
.' ' .$src
.' ' .$dst
.' ' .$p;
HMLAN_UpdtMsgLoad($name,1);
HMLAN_UpdtMsgLoad($name,(hex($flg)&0x10)?17:1);#burst counts
}
else{
Log $ll5, 'HMLAN_Send: '.$name.' I:'.$msg;
@ -858,13 +876,14 @@ sub HMLAN_condUpdate($$) {#####################################################
<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.
max messages level of HMLAN allowed for low-level message queue
to be executed. Above this level processing will be postponed.<br>
HMLAN will allow a max of messages per hour, it will block sending otherwise.
After about 90% messages the low-priority queue (currently only CUL_HM autoReadReg)
will be delayed until the condition is cleared. <br>
hmMsgLowLimit allowes to reduce this level further.<br>
Note that HMLAN transmitt-level calculation is based on some estimations and
has some tolerance. <br>
</li><br>
<li><a href="#hmId">hmId</a></li><br>
<li><a href="#hmKey">hmKey</a></li><br>

View File

@ -110,7 +110,7 @@ sub CUL_HM_noDupInString($);#return string with no duplicates, comma separated
sub CUL_HM_storeRssi(@);
sub CUL_HM_stateUpdat($);
sub CUL_HM_qStateUpdatIfEnab($@);
sub CUL_HM_getAttrInt($$);
sub CUL_HM_getAttrInt($@);
sub CUL_HM_putHash($);
# ----------------modul globals-----------------------
@ -141,6 +141,7 @@ sub CUL_HM_Initialize($) {
"actCycle actStatus ".
"autoReadReg:0_off,1_restart,2_pon-restart,3_onChange,4_reqStatus ".
"expert:0_off,1_on,2_full ".
"burstAccess:0_off,1_auto ".
"param msgRepeat ".
".stc .devInfo ".
$readingFnAttributes;
@ -179,14 +180,15 @@ sub CUL_HM_autoReadConfig($){
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});
last if ($defs{$dName}{helper}{prt}{sProc}); # predecisor still working
last if ($defs{$dName}{helper}{prt}{sProc} == 1); # predecisor still working
}
my $tName = CUL_HM_getDeviceName(${$modules{CUL_HM}{helper}{autoRdCfgLst}}[0]);
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))){
&& ($defs{$ioName}{helper}{q}{cap}{sum}/16.8)>
AttrVal($ioName,"hmMsgLowLimit",80))){
last;
}
#--- unqueue and process---
@ -495,7 +497,18 @@ sub CUL_HM_Attr(@) {#################################
return "$attrName not usable for channels" if(!$hash->{helper}{role}{dev});#only for device
return "value $attrVal ignored, must be an integer" if ($attrVal !~ m/^(\d+)$/);
}
elsif($attrName eq "model" && $hash->{helper}{role}{dev}){
delete $hash->{helper}{rxType}; # needs new calculation
delete $hash->{helper}{mId};
}
elsif($attrName eq "burstAccess"){
return "use burstAccess only for device" if (!$hash->{helper}{role}{dev});
return "burstAccess only for conditional Burst devices" if ($culHmModel{$hash->{helper}{mId}}{rxt} !~ m /f/);
return "$attrVal not a valid option for burstAccess" if ($attrVal !~ m/^[01]/);
if ($attrVal =~ m/^0/){$hash->{protCondBurst} = "forced_off";}
else {$hash->{protCondBurst} = "unknown";}
delete $hash->{helper}{rxType}; # needs new calculation
}
CUL_HM_queueUpdtCfg($name) if ($updtReq);
return;
}
@ -608,7 +621,7 @@ sub CUL_HM_Parse($$) {##############################
}
}
if ($parse eq "ACK"){# remember - ACKinfo will be passed on
if ($parse eq "ACK"){# remember - ACKinfo will be passed on
push @event, "";
}
elsif($parse eq "NACK"){
@ -3771,7 +3784,8 @@ sub CUL_HM_getRxType($) { #in:hash(chn or dev) out:binary coded Rx type
$rxtEntity |= ($rxtOfModel =~ m/c/)?0x04:0;#config
$rxtEntity |= ($rxtOfModel =~ m/w/)?0x08:0;#wakeup
$rxtEntity |= ($rxtOfModel =~ m/l/)?0x10:0;#lazyConfig
$rxtEntity |= ($rxtOfModel =~ m/f/)?0x80:0;#burstConditional
$rxtEntity |= ($rxtOfModel =~ m/f/)?0x80:0 #burstConditional
if(CUL_HM_getAttrInt($hash->{NAME},"burstAccess",0));
}
$rxtEntity = 1 if (!$rxtEntity);#always
$hash->{helper}{rxType} = $rxtEntity;
@ -4698,12 +4712,14 @@ sub CUL_HM_qStateUpdatIfEnab($@){#in:name or id, queue stat-request after 12 s
InternalTimer(gettimeofday()+120,"CUL_HM_reqStatus","CUL_HM_reqStatus", 0);
}
}
sub CUL_HM_getAttrInt($$){#return attrValue as integer
my ($name,$attrName) = @_;
sub CUL_HM_getAttrInt($@){#return attrValue as integer
my ($name,$attrName,$default) = @_;
my $val = $attr{$name}{$attrName}?$attr{$name}{$attrName}:"";
no warnings 'numeric';
my $devN = $defs{$name}{device}?$defs{$name}{device}:$name;
$val = int($attr{$devN}{$attrName}?$attr{$devN}{$attrName}:0)+0 if($val eq "");
$default = 0 if (!defined $default);
$val = int($attr{$devN}{$attrName}?$attr{$devN}{$attrName}:$default)+0
if($val eq "");
use warnings 'numeric';
return substr($val,0,1);
}
@ -5529,7 +5545,7 @@ sub CUL_HM_putHash($) {# provide data for HMinfo
<li><a href="#readingFnAttributes">readingFnAttributes</a></li>
<li><a href="#actCycle">actCycle</a>
actCycle &lt;[hhh:mm]|off&gt;<br>
Supports 'alive' or better 'not alive' detection for devices. [hhh:mm] is the maxumin silent time for the device. Upon no message received in this period an event will be raised "&lt;device&gt; is dead". If the device sends again another notification is posted "&lt;device&gt; is alive". <br>
Supports 'alive' or better 'not alive' detection for devices. [hhh:mm] is the maximum silent time for the device. Upon no message received in this period an event will be raised "&lt;device&gt; is dead". If the device sends again another notification is posted "&lt;device&gt; is alive". <br>
This actiondetect will be autocreated for each device with build in cyclic status report.<br>
Controlling entity is a pseudo device "ActionDetector" with HMId "000000".<br>
Due to performance considerations the report latency is set to 600sec (10min). It can be controlled by the attribute "actCycle" of "ActionDetector".<br>
@ -5565,6 +5581,13 @@ sub CUL_HM_putHash($) {# provide data for HMinfo
param defines model specific behavior or functions. See models for details</li>
<li><a name="msgRepeat">msgRepeat</a><br>
defines number of repetitions if a device doesn't answer in time</li>
<li><a name="burstAccess">burstAccess</a><br>
can be set for the device entity if the model allowes conditionalBurst.
The attribut will switch off burst operations (0_off) which causes less message load
on HMLAN and therefore reduces the chance of HMLAN overload.<br>
Setting it on (1_auto) allowes shorter reaction time of the device. User does not
need to wait for the device to wake up. <br>
Note that also the register burstRx needs to be set in the device.</li>
<li><a name="rawToReadable">rawToReadable</a><br>
Used to convert raw KFM100 values to readable data, based on measured
values. E.g. fill slowly your container, while monitoring the

View File

@ -315,7 +315,7 @@ sub HMinfo_SetFn($@) {#########################################################
InternalTimer(gettimeofday()+5,"CUL_HM_autoReadConfig","autoRdCfg",0);
push @entities,$dName;
}
return $cmd." done:" ."\n cleared" ."\n ".(join "\n ",sort @entities)
return $cmd." done:" ."\n triggered:" ."\n ".(join "\n ",sort @entities)
;
}
elsif($cmd eq "protoEvents"){##print protocol-events-------------------------
@ -375,7 +375,7 @@ sub HMinfo_SetFn($@) {#########################################################
" pending=".$defs{$_}{helper}{q}{answerPend} :
"")
." condition:".ReadingsVal($_,"cond","-")
."\n msgLoad: ".$defs{$_}{msgLoad};
."\n msgLoadEst: ".$defs{$_}{msgLoadEst};
}
$ret .= "\n IODevs:".(join"\n ",HMinfo_noDup(@IOlist));
}

View File

@ -80,7 +80,7 @@ my %culHmModel=(
"001C" => {name=>"HM-RC-SEC3-B" ,st=>'remote' ,cyc=>'' ,rxt=>'c' ,lst=>'1,4' ,chn=>"Btn:1:3",},
"001D" => {name=>"HM-RC-KEY3" ,st=>'remote' ,cyc=>'' ,rxt=>'c' ,lst=>'1,4' ,chn=>"Btn:1:3",},
"001E" => {name=>"HM-RC-KEY3-B" ,st=>'remote' ,cyc=>'' ,rxt=>'c' ,lst=>'1,4' ,chn=>"Btn:1:3",},
"001F" => {name=>"KS888" ,st=>'THSensor' ,cyc=>'' ,rxt=>'c:w' ,lst=>'p,1' ,chn=>"",},
"001F" => {name=>"KS888" ,st=>'THSensor' ,cyc=>'00:10' ,rxt=>'c:w' ,lst=>'p,1' ,chn=>"",},
"0022" => {name=>"WS888" ,st=>'' ,cyc=>'' ,rxt=>'' ,lst=>'1,3' ,chn=>"",},
"0026" => {name=>"HM-SEC-KEY-S" ,st=>'keyMatic' ,cyc=>'' ,rxt=>'b' ,lst=>'3' ,chn=>"",},
"0027" => {name=>"HM-SEC-KEY-O" ,st=>'keyMatic' ,cyc=>'' ,rxt=>'b' ,lst=>'3' ,chn=>"",},
@ -95,7 +95,7 @@ my %culHmModel=(
"0030" => {name=>"HM-SEC-RHS" ,st=>'threeStateSensor' ,cyc=>'28:00' ,rxt=>'c:w' ,lst=>'1,4' ,chn=>"",},
"0031" => {name=>"HM-WS550LCB" ,st=>'THSensor' ,cyc=>'' ,rxt=>'' ,lst=>'p' ,chn=>"",},
"0032" => {name=>"HM-WS550LCW" ,st=>'THSensor' ,cyc=>'' ,rxt=>'' ,lst=>'p' ,chn=>"",},
"0033" => {name=>"KS550LC" ,st=>'THSensor' ,cyc=>'' ,rxt=>'c:w' ,lst=>'p,1' ,chn=>"",},
"0033" => {name=>"KS550LC" ,st=>'THSensor' ,cyc=>'00:10' ,rxt=>'c:w' ,lst=>'p,1' ,chn=>"",},
"0034" => {name=>"HM-PBI-4-FM" ,st=>'pushButton' ,cyc=>'' ,rxt=>'c' ,lst=>'1,4' ,chn=>"Btn:1:4",}, # HM Push Button Interface
"0035" => {name=>"HM-PB-4-WM" ,st=>'pushButton' ,cyc=>'' ,rxt=>'c' ,lst=>'1,4' ,chn=>"Btn:1:4",},
"0036" => {name=>"HM-PB-2-WM" ,st=>'pushButton' ,cyc=>'' ,rxt=>'c' ,lst=>'1,4' ,chn=>"Btn:1:2",},
@ -112,8 +112,8 @@ my %culHmModel=(
"003E" => {name=>"HM-WDS30-T-O" ,st=>'THSensor' ,cyc=>'00:10' ,rxt=>'c:w' ,lst=>'p' ,chn=>"",},
"003F" => {name=>"HM-WDS40-TH-I" ,st=>'THSensor' ,cyc=>'00:10' ,rxt=>'c:w:f' ,lst=>'p' ,chn=>"",},
"0040" => {name=>"HM-WDS100-C6-O" ,st=>'THSensor' ,cyc=>'00:10' ,rxt=>'c:w' ,lst=>'p,1' ,chn=>"",},
"0041" => {name=>"HM-WDC7000" ,st=>'THSensor' ,cyc=>'' ,rxt=>'' ,lst=>'1,4' ,chn=>"",},
"0042" => {name=>"HM-SEC-SD" ,st=>'smokeDetector' ,cyc=>'99:00' ,rxt=>'b' ,lst=>'p' ,chn=>"",},
"0041" => {name=>"HM-WDC7000" ,st=>'THSensor' ,cyc=>'00:10' ,rxt=>'' ,lst=>'1,4' ,chn=>"",},
"0042" => {name=>"HM-SEC-SD" ,st=>'smokeDetector' ,cyc=>'28:00' ,rxt=>'b' ,lst=>'p' ,chn=>"",},
"0043" => {name=>"HM-SEC-TIS" ,st=>'threeStateSensor' ,cyc=>'28:00' ,rxt=>'c:w' ,lst=>'1,4' ,chn=>"",},
"0044" => {name=>"HM-SEN-EP" ,st=>'sensor' ,cyc=>'' ,rxt=>'c:w' ,lst=>'1,4' ,chn=>"",},
"0045" => {name=>"HM-SEC-WDS" ,st=>'threeStateSensor' ,cyc=>'28:00' ,rxt=>'c:w' ,lst=>'1,4' ,chn=>"",},
@ -121,7 +121,7 @@ my %culHmModel=(
"0047" => {name=>"KFM-Sensor" ,st=>'KFM100' ,cyc=>'' ,rxt=>'' ,lst=>'1,3' ,chn=>"",},
"0048" => {name=>"IS-WDS-TH-OD-S-R3" ,st=>'THSensor' ,cyc=>'00:10' ,rxt=>'c:w:f' ,lst=>'p' ,chn=>"",},
"0049" => {name=>"KFM-Display" ,st=>'KFM100' ,cyc=>'' ,rxt=>'' ,lst=>'1,3' ,chn=>"",},
"004A" => {name=>"HM-SEC-MDIR" ,st=>'motionDetector' ,cyc=>'00:10' ,rxt=>'c:w:l' ,lst=>'1,4' ,chn=>"",},
"004A" => {name=>"HM-SEC-MDIR" ,st=>'motionDetector' ,cyc=>'00:20' ,rxt=>'c:w:l' ,lst=>'1,4' ,chn=>"",},
"004B" => {name=>"HM-Sec-Cen" ,st=>'AlarmControl' ,cyc=>'' ,rxt=>'' ,lst=>'1,3' ,chn=>"",},
"004C" => {name=>"HM-RC-12-SW" ,st=>'remote' ,cyc=>'' ,rxt=>'c' ,lst=>'1,4' ,chn=>"Btn:1:12",},
"004D" => {name=>"HM-RC-19-SW" ,st=>'remote' ,cyc=>'' ,rxt=>'c:b' ,lst=>'1,4:1p.2p.3p.4p.5p.6p.7p.8p.9p.10p.11p.12p.13p.14p.15p.16p'