diff --git a/fhem/FHEM/00_HMLAN.pm b/fhem/FHEM/00_HMLAN.pm index b9f971fa1..4eeee9544 100755 --- a/fhem/FHEM/00_HMLAN.pm +++ b/fhem/FHEM/00_HMLAN.pm @@ -46,6 +46,9 @@ HMLAN_Initialize($) "loglevel:0,1,2,3,4,5,6 addvaltrigger " . "hmId hmKey " . "hmProtocolEvents:0_off,1_dump,2_dumpFull,3_dumpTrigger"; + $hash->{helper}{dPend} = 0;# data pending in HMLAN + $hash->{helper}{lastSend} = 0; + } ##################################### @@ -311,10 +314,10 @@ HMLAN_Parse($$) # 81=open HMLAN_SimpleWrite($hash, '+'.$src) if (($letter eq 'R')); - if (!($flg & 0x25)){#rule out other messages - HMLAN_SimpleWrite($hash, '-'.$src); - HMLAN_SimpleWrite($hash, '+'.$src); - } +# if (!($flg & 0x25)){#rule out other messages +# HMLAN_SimpleWrite($hash, '-'.$src); +# HMLAN_SimpleWrite($hash, '+'.$src); +# } $dmsg .= "NACK" if($mFld[1] !~ m/00(01|02|21)/ && $letter eq 'R'); $hash->{uptime} = HMLAN_uptime($mFld[2]); @@ -366,16 +369,32 @@ HMLAN_SimpleWrite(@) return if(!$hash || AttrVal($hash->{NAME}, "dummy", undef)); my $name = $hash->{NAME}; my $ll5 = GetLogLevel($name,5); - - # Currently it does not seem to be necessary to wait Thus this code is inhibit for now + + my $tn = gettimeofday(); + # calculate maximum data speed for HMLAN. + # Theorie 2,5kByte/s + # tested allowes no more then 2 byte/ms incl overhead + # It is even slower if HMLAN waits for acks, acks are missing,... + my $bytPend = $hash->{helper}{dPend} - + int(($tn - $hash->{helper}{lastSend})*2000); + $bytPend = 0 if ($bytPend < 0); + $hash->{helper}{dPend} = $bytPend + length($msg); + $hash->{helper}{lastSend} = $tn; + my $wait = $bytPend/2000; # HMLAN + # => wait time to protect HMLAN overload +# my $wait = $bytPend>>11; # fast divide by 2048 + + # It is not possible to answer befor 100ms my $id = (length($msg)>51)?substr($msg,46,6):""; - if ($id){ - my $DevDelay = $hash->{helper}{nextSend}{$id} - gettimeofday(); - if ($DevDelay > 0.01){# wait less then 10 ms will not work - $DevDelay = ((int($DevDelay*100))%100)/100;# security - wait no more then 1 sec - select(undef, undef, undef, $DevDelay); - } + my $DevDelay=0; + if ($id && $hash->{helper}{nextSend}{$id}){ + $DevDelay = $hash->{helper}{nextSend}{$id} - $tn; # calculate time passed + $DevDelay = ($DevDelay > 0.01)?( $DevDelay -= int($DevDelay)):0; } + $wait = ($DevDelay >$wait)?$DevDelay:$wait; # select the longer waittime + select(undef, undef, undef, $wait)if ($wait>0.01); + + if ($debug){ Log $ll5, 'HMLAN_Send: S:' .substr($msg,0,9). ' stat: ' .substr($msg,10,2). @@ -417,7 +436,8 @@ HMLAN_DoInit($) HMLAN_SimpleWrite($hash, "Y03,00,"); HMLAN_SimpleWrite($hash, "Y03,00,"); HMLAN_SimpleWrite($hash, "T$s2000,04,00,00000000"); - + + RemoveInternalTimer( $hash);# avoid duplicate timer InternalTimer(gettimeofday()+25, "HMLAN_KeepAlive", $hash, 0); return undef; } @@ -429,6 +449,7 @@ HMLAN_KeepAlive($) my $hash = shift; return if(!$hash->{FD}); HMLAN_SimpleWrite($hash, "K"); + RemoveInternalTimer( $hash);# avoid duplicate timer InternalTimer(gettimeofday()+25, "HMLAN_KeepAlive", $hash, 1); } sub diff --git a/fhem/FHEM/10_CUL_HM.pm b/fhem/FHEM/10_CUL_HM.pm index 68acc61ce..1ec7ca9ab 100755 --- a/fhem/FHEM/10_CUL_HM.pm +++ b/fhem/FHEM/10_CUL_HM.pm @@ -456,7 +456,7 @@ CUL_HM_Parse($$) $vp = int($vp/2.56+0.5); # valve position in % my $chnHash = $modules{CUL_HM}{defptr}{$src.$chn}; readingsSingleUpdate($chnHash,"state","$vp %",1) if($chnHash); - push @event, "actuator:$vp%"; + push @event, "actuator:$vp %"; # Set the valve state too, without an extra trigger readingsSingleUpdate($dhash,"state","set_$vp %",1) if($dhash); @@ -554,10 +554,10 @@ CUL_HM_Parse($$) elsif($msgType eq "01"){ # status reports if($p =~ m/^010809(..)0A(..)/) { # TC set valve for VD => post events to VD my ( $of, $vep) = (hex($1), hex($2)); - push @event, "ValveErrorPosition_for_$dname: $vep%"; - push @event, "ValveOffset_for_$dname: $of%"; - CUL_HM_UpdtReadBulk($dhash,1,'ValveErrorPosition:set_'.$vep.'%', - 'ValveOffset:set_'.$of.'%'); + push @event, "ValveErrorPosition_for_$dname: $vep %"; + push @event, "ValveOffset_for_$dname: $of %"; + CUL_HM_UpdtReadBulk($dhash,1,'ValveErrorPosition:set_'.$vep.' %', + 'ValveOffset:set_'.$of.' %'); } elsif($p =~ m/^010[56]/){ # 'prepare to set' or 'end set' push @event,""; # @@ -576,8 +576,8 @@ CUL_HM_Parse($$) if($msgType eq "02" && $p =~ m/^(..)(..)(..)(..)/) {#subtype+chn+value+err my ($chn,$vp, $err) = ($2,hex($3), hex($4)); $vp = int($vp)/2; # valve position in % - push @event, "ValvePosition:$vp%"; - push @event, "state:$vp%"; + push @event, "ValvePosition:$vp %"; + push @event, "state:$vp %"; $shash = $modules{CUL_HM}{defptr}{"$src$chn"} if($modules{CUL_HM}{defptr}{"$src$chn"}); @@ -612,8 +612,8 @@ CUL_HM_Parse($$) # => Link discriminator (00000000) is fixed elsif($msgType eq "10" && $p =~ m/^04..........0509(..)0A(..)/) { my ( $of, $vep) = (hex($1), hex($2)); - push @event, "ValveErrorPosition:$vep%"; - push @event, "ValveOffset:$of%"; + push @event, "ValveErrorPosition:$vep %"; + push @event, "ValveOffset:$of %"; } } @@ -768,7 +768,7 @@ CUL_HM_Parse($$) my $mask = 3<<$bitLoc; my $value = sprintf("%08X",(hex($devState) &~$mask)|($msgState<<$bitLoc)); CUL_HM_UpdtReadBulk($shash,1,"color:".$value, - "state".$value); + "state:".$value); if ($chnHash){ $shash = $chnHash; my %colorTable=("00"=>"off","01"=>"red","02"=>"green","03"=>"orange"); @@ -923,10 +923,10 @@ CUL_HM_Parse($$) push @event, "state:$txt"; push @event, "contact:$txt$target"; - if($id eq $dst && hex($msgFlag)&0x20){ - CUL_HM_SndCmd($shash, $msgcnt."8002$id$src${chn}00"); #Send Ack - $sendAck = ""; - } +# if($id eq $dst && hex($msgFlag)&0x20){ General remove if Peter agrees +# CUL_HM_SndCmd($shash, $msgcnt."8002$id$src${chn}00"); #Send Ack +# $sendAck = ""; +# } } else{push @event, "3SSunknownMsg:$p" if(!@event);} } @@ -1048,7 +1048,7 @@ CUL_HM_Parse($$) my ($d1,$vp) =($1,hex($2)); # adjust_command[0..4] adj_data[0..250] $vp = int($vp/2.56+0.5); # valve position in % my $chnHash = $modules{CUL_HM}{defptr}{$dst."01"}; - CUL_HM_UpdtReadBulk($chnHash,1,"ValvePosition:$vp%", + CUL_HM_UpdtReadBulk($chnHash,1,"ValvePosition:$vp %", "ValveAdjCmd:".$d1); CUL_HM_SndCmd($chnHash,$msgcnt."8002".$dst.$src.'0101'. sprintf("%02X",$vp*2)."0000");#$vp, $err,$?? @@ -2098,8 +2098,9 @@ CUL_HM_Set($@) else{ return "$a[2] unknown. use hex or: ".join(" ",sort keys(%color)); } - CUL_HM_PushCmdStack($hash,sprintf("++%s11%s%s8100%s", - $flag,$id,$dst,$col4all)); + CUL_HM_UpdtReadBulk($hash,1,"color:".$col4all, + "state:set_".$col4all); + CUL_HM_PushCmdStack($hash,"++".$flag."11".$id.$dst."8100".$col4all); }else{# operating on a channel return "$a[2] unknown. use: ".join(" ",sort keys(%color)) if (!defined($color{$a[2]}) ); @@ -2223,10 +2224,10 @@ CUL_HM_Set($@) } else { my $vp = $a[2]; - readingsSingleUpdate($hash,"valvePosTC","$vp%",0); + readingsSingleUpdate($hash,"valvePosTC","$vp %",0); CUL_HM_valvePosUpdt("valvePos:$dst$chn") if (!$hash->{helper}{virtTC}); $hash->{helper}{virtTC} = "03"; - $state = "ValveAdjust:$vp%"; + $state = "ValveAdjust:$vp %"; } } elsif($cmd eq "matic") { ##################################### @@ -2424,7 +2425,7 @@ CUL_HM_valvePosUpdt(@) # else{ my $name = $hash->{NAME}; my $vp = ReadingsVal($name,"valvePosTC","15 %"); - $vp =~ s/%//; + $vp =~ s/ %//; $vp *=2.56; foreach my $peer (sort(split(',',AttrVal($name,"peerIDs","")))) { next if (length($peer) != 8); @@ -3363,7 +3364,7 @@ CUL_HM_getRegFromStore($$$$) } } else { return " conversion undefined - please contact admin"; } - return $convFlg.$data.$unit; + return $convFlg.$data.' '.$unit; } #----------------------