From 4015ac827078f51f720168a567bb715c673deaf9 Mon Sep 17 00:00:00 2001 From: martinp876 <> Date: Sun, 13 Oct 2013 18:28:05 +0000 Subject: [PATCH] overload enhamcements - step1 git-svn-id: https://svn.fhem.de/fhem/trunk@4040 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/00_HMLAN.pm | 91 +++++++++++++++++++++++++----------------- fhem/FHEM/10_CUL_HM.pm | 43 +++++++++++++++----- fhem/FHEM/98_HMinfo.pm | 4 +- fhem/FHEM/HMConfig.pm | 10 ++--- 4 files changed, 95 insertions(+), 53 deletions(-) diff --git a/fhem/FHEM/00_HMLAN.pm b/fhem/FHEM/00_HMLAN.pm index dc7d09890..078d7a4ec 100755 --- a/fhem/FHEM/00_HMLAN.pm +++ b/fhem/FHEM/00_HMLAN.pm @@ -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($$) {#####################################################
  • loglevel

  • addvaltrigger

  • hmMsgLowLimit
    - max number of messages allowed per hour before low-level message queue - will be postponed.
    - 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.
    - 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.
    + 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.
    + hmMsgLowLimit allowes to reduce this level further.
    + Note that HMLAN transmitt-level calculation is based on some estimations and + has some tolerance.

  • hmId

  • hmKey

  • diff --git a/fhem/FHEM/10_CUL_HM.pm b/fhem/FHEM/10_CUL_HM.pm index 312f8d73f..cbf7eeda7 100755 --- a/fhem/FHEM/10_CUL_HM.pm +++ b/fhem/FHEM/10_CUL_HM.pm @@ -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
  • readingFnAttributes
  • actCycle actCycle <[hhh:mm]|off>
    - 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 "<device> is dead". If the device sends again another notification is posted "<device> is alive".
    + 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 "<device> is dead". If the device sends again another notification is posted "<device> is alive".
    This actiondetect will be autocreated for each device with build in cyclic status report.
    Controlling entity is a pseudo device "ActionDetector" with HMId "000000".
    Due to performance considerations the report latency is set to 600sec (10min). It can be controlled by the attribute "actCycle" of "ActionDetector".
    @@ -5565,6 +5581,13 @@ sub CUL_HM_putHash($) {# provide data for HMinfo param defines model specific behavior or functions. See models for details
  • msgRepeat
    defines number of repetitions if a device doesn't answer in time
  • +
  • burstAccess
    + 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.
    + Setting it on (1_auto) allowes shorter reaction time of the device. User does not + need to wait for the device to wake up.
    + Note that also the register burstRx needs to be set in the device.
  • rawToReadable
    Used to convert raw KFM100 values to readable data, based on measured values. E.g. fill slowly your container, while monitoring the diff --git a/fhem/FHEM/98_HMinfo.pm b/fhem/FHEM/98_HMinfo.pm index 671844792..55f85bf89 100644 --- a/fhem/FHEM/98_HMinfo.pm +++ b/fhem/FHEM/98_HMinfo.pm @@ -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)); } diff --git a/fhem/FHEM/HMConfig.pm b/fhem/FHEM/HMConfig.pm index 15f9e4a7d..9f8e711ab 100644 --- a/fhem/FHEM/HMConfig.pm +++ b/fhem/FHEM/HMConfig.pm @@ -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'