2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-01-31 18:59:33 +00:00

CUL_HM: HMLANIO and CUL_HM minors

git-svn-id: https://svn.fhem.de/fhem/trunk@12133 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
martinp876 2016-09-10 05:17:31 +00:00
parent 2d5b83b9e1
commit 4d2d88ee60
2 changed files with 77 additions and 76 deletions

View File

@ -117,12 +117,12 @@ sub HMLAN_Define($$) {#########################################################
my @arr = ();
@{$hash->{helper}{q}{apIDs}} = \@arr;
$hash->{helper}{q}{scnt} = 0;
$hash->{helper}{q}{loadNo} = 0;
$hash->{helper}{q}{loadLast} = 0;
$hash->{msgLoadHistory} = (60/$HMmlSlice)."min steps: "
.join("/",("-") x $HMmlSlice);
$hash->{msgLoadCurrent} = 0;
$hash->{helper}{q}{scnt} = 0;
$hash->{helper}{q}{loadNo} = 0;
$hash->{helper}{q}{loadLastMax} = 0; # max load in last slice
my @ald = ("0") x $HMmlSlice;
$hash->{helper}{q}{ald} = \@ald; # array of load events
$hash->{msgLoadCurrent} = 0;
$defs{$name}{helper}{log}{all} = 0;# selective log support
$defs{$name}{helper}{log}{sys} = 0;
@ -352,18 +352,24 @@ sub HMLAN_Attr(@) {############################################################
sub HMLAN_UpdtMsgLoad($$) {####################################################
my($name,$val) = @_;
my $hash = $defs{$name};
my $hashQ = $defs{$name}{helper}{q};
my $t = int(gettimeofday()/(3600/$HMmlSlice))%$HMmlSlice;
$hash->{msgLoadCurrent} = $val;
my ($r) = grep { $_ <= $val } @{$hash->{helper}{loadLvl}{a}};
readingsSingleUpdate($hash,"loadLvl",$hash->{helper}{loadLvl}{h}{$r},1);
if ($hash->{helper}{q}{loadNo} != $t){
$hash->{helper}{q}{loadNo} = $t;
my (undef,@a) = split(": ",$hash->{msgLoadHistory});
@a = ( ($hash->{msgLoadCurrent} - $hash->{helper}{q}{loadLast})
,split("/",$a[0]));
$hash->{helper}{q}{loadLast} = $hash->{msgLoadCurrent};
$hashQ->{loadLastMax} = $val if ($hashQ->{loadLastMax} < $val);
my $t = int(gettimeofday()/(3600/$HMmlSlice))%$HMmlSlice;
if ($hashQ->{loadNo} != $t){
$hashQ->{loadNo} = $t;
unshift @{$hashQ->{ald}},$hashQ->{loadLastMax};
#relative history my @a = map{$hashQ->{ald}[$_] -
#relative history $hashQ->{ald}[$_ + 1]} (0..($HMmlSlice-1));
#relative history $hash->{msgLoadHistory} = (60/$HMmlSlice)."min steps: ".join("/",@a);
pop @{$hashQ->{ald}};
$hash->{msgLoadHistory} = (60/$HMmlSlice)."min steps: "
.join("/",@a[0...($HMmlSlice-1)]);
$hash->{msgLoadHistoryAbs} = (60/$HMmlSlice)."min steps: ".join("/",@{$hashQ->{ald}});
# try to release high-load condition with a dummy message
# one a while
if (ReadingsVal($name,"cond","") =~ m /(Warning-HighLoad|ERROR-Overload)/){
@ -372,11 +378,8 @@ sub HMLAN_UpdtMsgLoad($$) {####################################################
.AttrVal($name,"hmId","999999")
."000000");
}
$hashQ->{loadLastMax} = 0;
}
$hash->{msgLoadCurrent} = $val;
my ($r) = grep { $_ <= $val } @{$hash->{helper}{loadLvl}{a}};
readingsSingleUpdate($hash,"loadLvl",$hash->{helper}{loadLvl}{h}{$r},1);
return;
}
@ -1262,8 +1265,8 @@ sub HMLAN_getVerbLvl ($$$$){#get verboseLevel for message
Current transmit load of HMLAN. When capacity reaches 100% HMLAN stops sending and waits for
reduction. See also:
<a href="#HMLANloadLevel">loadLevel</a><br></li>
<li><B>msgLoadHistory</B><br>
Historical transmition load of HMLAN.</li>
<li><B>msgLoadHistoryAbs</B><br>
Historical transmition load of IO.</li>
<li><B>msgParseDly</B><br>
calculates the delay of messages in ms from send in HMLAN until processing in FHEM.
It therefore gives an indication about FHEM system performance.
@ -1412,8 +1415,8 @@ sub HMLAN_getVerbLvl ($$$$){#get verboseLevel for message
Aktuelle Funklast des HMLAN. Da HMLAN nur eine begrenzte Kapzit&auml;t je Stunde hat
Telegramme abzusetzen stellt es bei 100% das Senden ein. Siehe auch
<a href="#loadLevel">loadLevel</a><br></li>
<li><B>msgLoadHistory</B><br>
Funklast vergangener Zeitabschnitte.</li>
<li><B>msgLoadHistoryAbs</B><br>
IO Funkbelastung vergangener Zeitabschnitte.</li>
<li><B>msgParseDly</B><br>
Kalkuliert die Verz&ouml;gerungen einer Meldung vom Zeitpunkt des Abschickens im HMLAN
bis zu Verarbeitung in FHEM. Deshalb ist dies ein Indikator f&uuml;r die Leistungsf&auml;higkeit

View File

@ -2553,7 +2553,7 @@ sub CUL_HM_Parse($$) {#########################################################
#Info Level: mTp=0x10 p(..)(..)(..) subtype=06, channel, state (1 byte)
#Event: mTp=0x41 p(..)(..)(..) channel , unknown, state (1 byte)
if ($mh{mTp} eq "10" && $mh{p} =~ m/^06..(..)(..)/) {
if ($mh{mTp} eq "10" && $mh{p} =~ m/^06..(..)(..)/) {
# m:A0 A010 233FCE 1743BF 0601 01 00 31
my ($state,$err) = (hex($1),hex($2));
@ -3444,26 +3444,25 @@ sub CUL_HM_parseSDteam(@){#handle SD team events
sub CUL_HM_parseSDteam_2(@){#handle SD team events
my ($mTp,$sId,$dId,$p) = @_;
my @entities;
my $dHash = CUL_HM_id2Hash($dId);
my $dName = CUL_HM_id2Name($dId);
my $sHash = CUL_HM_id2Hash($sId);
my $sName = CUL_HM_hash2Name($sHash);
if (AttrVal($sName,"subType","") eq "virtual"){
if (AttrVal($sName,"subType","") eq "virtual"){#search for the team lead channel
foreach my $cId (CUL_HM_getAssChnIds($sName)){
my $cHash = CUL_HM_id2Hash($cId);
next if (!$cHash->{sdTeam} || $cHash->{sdTeam} ne "sdLead");
my $cName = CUL_HM_id2Name($cId);
$sHash = $cHash;
$sName = CUL_HM_id2Name($cId);
$sName = CUL_HM_hash2Name($sHash);
last;
}
}
return () if (!$sHash->{sdTeam} || $sHash->{sdTeam} ne "sdLead");
return () if (!$sHash->{sdTeam} || $sHash->{sdTeam} ne "sdLead"
||!$dHash);
my ($chn,$No,$state,$null,$aesKNo,$aesStr) = unpack 'A2A2A2A4A2A8',$p;
if(($dHash) && # update source(ID reported in $dst)
(!$dHash->{helper}{alarmNo} || $dHash->{helper}{alarmNo} ne $No)){
if(!$dHash->{helper}{alarmNo} || $dHash->{helper}{alarmNo} ne $No){
$dHash->{helper}{alarmNo} = $No;
}
else{
@ -3499,8 +3498,9 @@ sub CUL_HM_parseSDteam_2(@){#handle SD team events
}
push @evtEt,[$dHash,1,"battery:" .((hex($chn)&0x80) ? "low":"ok")];
push @evtEt,[$sHash,1,"eventNo:".$No];
Log3 $sHash,5,"CUL_HM $sName sdTeam: no:$No state:$state aesNo:$aesKNo aesStr:$aesStr";
return @entities;
return;
}
sub CUL_HM_updtSDTeam(@){#in: TeamName, optional caller name and its new state
# update team status if virtual team lead
@ -5348,21 +5348,17 @@ sub CUL_HM_Set($@) {#+++++++++++++++++ set command+++++++++++++++++++++++++++++
my $sId = $roleV ? $dst : $id; # ID of cmd-source must not be a physical
# device. It can cause trouble with
# subsequent alarming
if ($fkt ne "sdLead2"){# $md eq "HM-CC-SCD")
my $testnr = $hash->{TESTNR} ? ($hash->{TESTNR} +1) : 1;
$hash->{TESTNR} = $testnr;
my $tstNo = sprintf("%02X",$testnr);
$hash->{TESTNR} = ($a[2] ? $a[2] : ($hash->{TESTNR} + 1))%255;
if ($fkt eq "sdLead1"){# ($md eq "HM-CC-SCD")
my $tstNo = sprintf("%02X",$hash->{TESTNR});
CUL_HM_PushCmdStack($hash, "++9440".$dst.$sId."00".$tstNo);
CUL_HM_parseSDteam("40",$dst,$sId,"00".$tstNo);
}
else {#if ($md eq "HM-SEC-SD-2"){
#1441 44E347 44E347 0102 960000 039190BDC8
my $testnr = $hash->{TESTNR} ? ($hash->{TESTNR} +1) : 1;
$testnr = $a[2]if ($a[2]);
$hash->{TESTNR} = $testnr;
# 96 switch on- others unknown
else {#($md eq "HM-SEC-SD-2"){
# 96 switch on- others unknown
my $msg = CUL_HM_generateCBCsignature($hash,
sprintf("++1441$dst${sId}01%02X9600",$testnr));
sprintf("++1441$dst${sId}01%02X9600",$hash->{TESTNR}));
CUL_HM_PushCmdStack($hash, $msg) foreach (1..6);
CUL_HM_parseSDteam_2("41",$dst,$sId,substr($msg, 18));
}
@ -5373,19 +5369,18 @@ sub CUL_HM_Set($@) {#+++++++++++++++++ set command+++++++++++++++++++++++++++++
my $sId = $roleV ? $dst : $id; # ID of cmd-source must not be a physical
# device. It can cause trouble with
# subsequent alarming
if ($fkt ne "sdLead2"){
if ($fkt eq "sdLead1"){# ($md eq "HM-CC-SCD")
my $p = (($1 eq "On")?"0BC8":"0C01");
my $msg = "++9441".$dst.$sId."01".$p;
CUL_HM_PushCmdStack($hash, $msg) foreach (1..3);# 3 reps fpr non-ack msg
CUL_HM_parseSDteam("41",$dst,$sId,"01".$p);
}
else{
else{#($md eq "HM-SEC-SD-2"){
my $p = (($1 eq "On")?"C6":"00");
my $testnr = $hash->{TESTNR} ? ($hash->{TESTNR} +1) : 1;
$hash->{TESTNR} = $testnr;
$hash->{TESTNR} = ($hash->{TESTNR} + 1)%255;
my $msg = CUL_HM_generateCBCsignature($hash,
sprintf("++1441$dst${sId}01%02X${p}00",$testnr));
sprintf("++1441$dst${sId}01%02X${p}00",$hash->{TESTNR}));
CUL_HM_PushCmdStack($hash, $msg) foreach (1..6);
CUL_HM_parseSDteam_2("41",$dst,$sId,substr($msg, 18));
@ -7002,8 +6997,6 @@ sub CUL_HM_ID2PeerList ($$$) {
#if any of the peers is an SD we are team master
my ($tMstr,$tcSim,$thSim) = (0,0,0);
foreach (split(",",$peerNames)){
# $tMstr = 1 if(AttrVal($_,"subType","") eq "smokeDetector");
if(AttrVal($_,"subType","") eq "smokeDetector"){#have smoke detector
$tMstr = AttrVal($_,"model","") eq "HM-SEC-SD-2"? 2:1;#differentiate SD and SD2
}
@ -7013,8 +7006,9 @@ sub CUL_HM_ID2PeerList ($$$) {
$thSim = 1 if(AttrVal($_,"model","") =~ m /HM-CC-RT-DN/ && $pch eq "01");
}
if ($tMstr){
$hash->{helper}{fkt}="sdLead".$tMstr;
$hash->{sdTeam}="sdLead";
$hash->{helper}{fkt} = "sdLead".$tMstr;
$hash->{sdTeam} = "sdLead";
$hash->{TESTNR} = 1 if(!exists $hash->{TESTNR});#must be defined for all sdLead
CUL_HM_updtSDTeam($name);
}
elsif($tcSim){
@ -7030,8 +7024,9 @@ sub CUL_HM_ID2PeerList ($$$) {
foreach (split(",",$peerNames)){
my $tn = ($_ =~ m/self/)?$name:$_;
next if (!$defs{$tn});
$defs{$tn}{sdTeam} = "sdLead" ;
$defs{$tn}{helper}{fkt} = "sdLead".(AttrVal($name,"model","") eq "HM-SEC-SD-2"? 2:1);
$defs{$tn}{sdTeam} = "sdLead" ;
$defs{$tn}{TESTNR} = 1 if(!exists $defs{$tn}{TESTNR});#must be defined for all sdLead
}
if($peerNames !~ m/self/){
delete $hash->{sdTeam};
@ -7184,7 +7179,7 @@ sub CUL_HM_generateCBCsignature($$) { #in: device-hash,msg out: signed message
my ($hash,$msg) = @_;
my $oldcounter = ReadingsVal($hash->{NAME},"aesCBCCounter","000000");
my $counter = substr($oldcounter, 0, 4);
my $msgNo = substr($msg, 0, 2);
my ($mNo,$mFlg,$mTg,$mSnd,$mPay) = unpack 'A2A2A2A12A*',$msg;
my $devH = CUL_HM_getDeviceHash($hash);
if ($cryptFunc != 1) {
@ -7199,44 +7194,45 @@ sub CUL_HM_generateCBCsignature($$) { #in: device-hash,msg out: signed message
}
#generate message number
if($msgNo eq "++") {
$msgNo = ($devH->{helper}{HM_CMDNR} + 1) & 0xff;
if($mNo eq "++") {
$mNo = ($devH->{helper}{HM_CMDNR} + 1) & 0xff;
my $oldNo = hex(substr($oldcounter, 4, 2));
if ($msgNo <= $oldNo && (($oldNo + 1) & 0xff) > $oldNo) {
$msgNo = ($oldNo + 1) & 0xff;
if ($mNo <= $oldNo && (($oldNo + 1) & 0xff) > $oldNo) {
$mNo = ($oldNo + 1) & 0xff;
}
$devH->{helper}{HM_CMDNR} = $msgNo;
$msgNo = sprintf("%02X", $msgNo);
$devH->{helper}{HM_CMDNR} = $mNo;
$mNo = sprintf("%02X", $mNo);
}
if (hex($counter.$msgNo) <= hex($oldcounter)) {
if (hex($counter.$mNo) <= hex($oldcounter)) {
$counter = sprintf("%04X", (hex($counter) + 1) & 0xffff);
}
push @evtEt,[$hash,1,"aesCBCCounter:".$counter.$msgNo];
push @evtEt,[$hash,1,"aesCBCCounter:".$counter.$mNo];
CUL_HM_pushEvnts();
my $cipher = Crypt::Rijndael->new($keys{$kNo}, Crypt::Rijndael::MODE_ECB());
my $iv = "49"
.substr($msg, 6, 12) #sender receiver
.$counter #generation counter
.$msgNo
.$mSnd #sender receiver
.$counter #generation counter
.$mNo
."000000000005";
Log3 $hash,5,"CUL_HM $hash->{NAME} CBC IV: " . $iv;
$iv = $cipher->encrypt(pack("H32", $iv));
my $d = $msgNo
.substr($msg, 2, 2)#Flags
.substr($msg, 18); #payload
my $ivC = $cipher->encrypt(pack("H32", $iv));
my $d = $mNo
.$mFlg #Flags
.$mPay; #payload
$d .= "00" x ((32 - length($d)) / 2) if (length($d) < 32);
Log3 $hash,5,"CUL_HM $hash->{NAME} CBC D: " . $d;
my $cbc = $cipher->encrypt(pack("H32", $d) ^ $iv);
Log3 $hash,5,"CUL_HM $hash->{NAME} CBC E: " . unpack("H*", $cbc);
return uc( $msgNo
. substr($msg, 2)
my $cbc = $cipher->encrypt(pack("H32", $d) ^ $ivC);
#2016.09.04 06:52:54.227 3: CUL_HM
Log3 $hash,5, "CUL_HM $hash->{NAME} CBC IV: " . $iv
."\n".(" "x30)."$hash->{NAME} CBC D: " . $d
."\n".(" "x30)."$hash->{NAME} CBC E: " . unpack("H*", $cbc);
return uc( $mNo
. $mFlg.$mTg.$mSnd.$mPay
. $counter
. unpack("H8", substr($cbc, 12, 4)));
}
@ -7951,6 +7947,8 @@ sub CUL_HM_TCITRTtempReadings($$@) {# parse RT - TC-IT temperature readings
my %idxN = (7=>"P1_",8=>"P2_",9=>"P3_");
$idxN{7} = "" if($md =~ m/CC-RT/);# not prefix for RT
my @days = ("Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri");
delete $hash->{READINGS}{hyst2pointWrite};
foreach my $lst (@list){
my @r1;
$lst +=0;
@ -8694,7 +8692,7 @@ sub CUL_HM_procQs($){#process non-wakeup queues
else{
CUL_HM_Set($defs{$eN},$eN,"statusRequest");
CUL_HM_unQEntity($eN,"qReqStat") if (!$dq->{$q});
InternalTimer(gettimeofday()+5,"CUL_HM_readStateTo","sUpdt:$eN",0);
InternalTimer(gettimeofday()+20,"CUL_HM_readStateTo","sUpdt:$eN",0);
}
}
last; # execute only one!