HM Multi-channel device tuning

git-svn-id: https://svn.fhem.de/fhem/trunk/fhem@986 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
rudolfkoenig 2011-08-21 11:07:27 +00:00
parent 7e6dc55f2f
commit 1e70d39b2f
3 changed files with 55 additions and 58 deletions

View File

@ -688,16 +688,12 @@ CUL_Write($$$)
Log 5, "$hash->{NAME} sending $fn$msg"; Log 5, "$hash->{NAME} sending $fn$msg";
my $bstring = "$fn$msg"; my $bstring = "$fn$msg";
if($fn eq "F") { if($fn eq "F" || # FS20 message
$bstring =~ m/^u....F/ || # FS20 messages sent over an RFR
($fn eq "" && $bstring =~ m/^A/)) { # AskSin/BidCos/HomeMatic
CUL_AddFS20Queue($hash, $bstring); CUL_AddFS20Queue($hash, $bstring);
} elsif($bstring =~ m/u....F/) {
# put FS20 messages sent over an RFR in the common queue
CUL_AddFS20Queue($hash, $bstring);
} else { } else {
CUL_SimpleWrite($hash, $bstring); CUL_SimpleWrite($hash, $bstring);
@ -712,10 +708,13 @@ CUL_SendFromQueue($$)
my ($hash, $bstring) = @_; my ($hash, $bstring) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $hm = ($bstring =~ m/^A/);
my $to = ($hm ? 0.15 : 0.3);
if($bstring ne "") { if($bstring ne "") {
# Is one of the CUL-fellows sending data? my $sp = AttrVal($name, "sendpool", undef);
if($attr{$name} && $attr{$name}{sendpool}) { if($sp) { # Is one of the CUL-fellows sending data?
my @fellows = split(",", $attr{$name}{sendpool}); my @fellows = split(",", $sp);
foreach my $f (@fellows) { foreach my $f (@fellows) {
if($f ne $name && if($f ne $name &&
$defs{$f} && $defs{$f} &&
@ -723,12 +722,12 @@ CUL_SendFromQueue($$)
$defs{$f}{QUEUE}->[0] ne "") $defs{$f}{QUEUE}->[0] ne "")
{ {
unshift(@{$hash->{QUEUE}}, ""); unshift(@{$hash->{QUEUE}}, "");
InternalTimer(gettimeofday()+0.3, "CUL_HandleWriteQueue", $hash, 1); InternalTimer(gettimeofday()+$to, "CUL_HandleWriteQueue", $hash, 1);
return; return;
} }
} }
} }
CUL_XmitLimitCheck($hash,$bstring); CUL_XmitLimitCheck($hash,$bstring) if(!$hm);
CUL_SimpleWrite($hash, $bstring); CUL_SimpleWrite($hash, $bstring);
} }
@ -736,7 +735,7 @@ CUL_SendFromQueue($$)
# Write the next buffer not earlier than 0.23 seconds # Write the next buffer not earlier than 0.23 seconds
# = 3* (12*0.8+1.2+1.0*5*9+0.8+10) = 226.8ms # = 3* (12*0.8+1.2+1.0*5*9+0.8+10) = 226.8ms
# else it will be sent too early by the CUL, resulting in a collision # else it will be sent too early by the CUL, resulting in a collision
InternalTimer(gettimeofday()+0.3, "CUL_HandleWriteQueue", $hash, 1); InternalTimer(gettimeofday()+$to, "CUL_HandleWriteQueue", $hash, 1);
} }
sub sub
@ -941,7 +940,11 @@ CUL_SimpleWrite(@)
# Prefix $msg with RRBBU and return the corresponding CUL hash. # Prefix $msg with RRBBU and return the corresponding CUL hash.
($hash, $msg) = CUL_RFR_AddPrefix($hash, $msg); ($hash, $msg) = CUL_RFR_AddPrefix($hash, $msg);
} }
#Log 1, "SW: $msg";
my $name = $hash->{NAME};
my $ll5 = GetLogLevel($name,5);
Log $ll5, "SW: $msg";
$msg .= "\n" unless($nonl); $msg .= "\n" unless($nonl);
$hash->{USBDev}->write($msg) if($hash->{USBDev}); $hash->{USBDev}->write($msg) if($hash->{USBDev});

View File

@ -266,7 +266,7 @@ HMLAN_Parse($$)
my $dmsg = $rmsg; my $dmsg = $rmsg;
Log $ll5, "HMLAN $rmsg"; Log $ll5, "HMLAN_Parse: $name $rmsg";
if($rmsg =~ m/^E(......),(....),(........),(..),(....),(.*)/) { if($rmsg =~ m/^E(......),(....),(........),(..),(....),(.*)/) {
($src, $status, $msec, $d2, $rssi, $msg) = ($src, $status, $msec, $d2, $rssi, $msg) =
($1, $2, $3, $4, $5, $6); ($1, $2, $3, $4, $5, $6);
@ -289,6 +289,11 @@ HMLAN_Parse($$)
$hash->{firmware} = sprintf("%d.%d", ($vers>>12)&0xf, $vers & 0xffff); $hash->{firmware} = sprintf("%d.%d", ($vers>>12)&0xf, $vers & 0xffff);
$hash->{owner} = $owner; $hash->{owner} = $owner;
$hash->{uptime} = HMLAN_uptime($msec); $hash->{uptime} = HMLAN_uptime($msec);
my $myId = AttrVal($name, "hmId", $owner);
if($owner ne $myId && !AttrVal($name, "dummy", 0)) {
Log 1, "HMLAN setting owner to $myId from $owner";
HMLAN_SimpleWrite($hash, "A$myId");
}
return; return;
} elsif($rmsg =~ m/^I00.*/) { } elsif($rmsg =~ m/^I00.*/) {

View File

@ -131,7 +131,7 @@ CUL_HM_Initialize($)
"swi,pushButton,threeStateSensor,motionDetector,". "swi,pushButton,threeStateSensor,motionDetector,".
"keyMatic,winMatic,smokeDetector " . "keyMatic,winMatic,smokeDetector " .
"hmClass:receiver,sender serialNr firmware devInfo ". "hmClass:receiver,sender serialNr firmware devInfo ".
"rawToReadable unit follow-on-for-timer"; "rawToReadable unit";
} }
@ -238,14 +238,6 @@ CUL_HM_Parse($$)
my $name = $shash->{NAME}; my $name = $shash->{NAME};
my @event; my @event;
my $isack;
if($shash->{ackWaiting}) {
delete($shash->{ackWaiting});
delete($shash->{ackCmdSent});
RemoveInternalTimer($shash);
$isack = 1;
}
my $st = AttrVal($name, "subType", ""); my $st = AttrVal($name, "subType", "");
my $model = AttrVal($name, "model", ""); my $model = AttrVal($name, "model", "");
my $tn = TimeNow(); my $tn = TimeNow();
@ -565,6 +557,13 @@ CUL_HM_Parse($$)
$shash->{CHANGED} = \@changed; $shash->{CHANGED} = \@changed;
$shash->{lastMsg} = $msgX; $shash->{lastMsg} = $msgX;
if($shash->{ackWaiting}) {
delete($shash->{ackWaiting});
delete($shash->{ackCmdSent});
RemoveInternalTimer($shash);
}
return $name; return $name;
} }
@ -619,12 +618,10 @@ CUL_HM_Set($@)
my $cmd = $a[1]; my $cmd = $a[1];
my $dst = $hash->{DEF}; my $dst = $hash->{DEF};
my $chn = "01"; my $chn = "01";
my $shash = $hash;
if(length($dst) == 8) { # shadow switch device for multi-channel switch if(length($dst) == 8) { # shadow switch device for multi-channel switch
$chn = substr($dst, 6, 2); $chn = substr($dst, 6, 2);
$dst = substr($dst, 0, 6); $dst = substr($dst, 0, 6);
$shash = $modules{CUL_HM}{defptr}{$dst};
} }
my $h = $culHmGlobalSets{$cmd}; my $h = $culHmGlobalSets{$cmd};
@ -655,17 +652,15 @@ CUL_HM_Set($@)
} }
my $id = CUL_HM_Id($shash->{IODev}); my $id = CUL_HM_Id($hash->{IODev});
my $sndcmd; my $sndcmd;
my $state = join(" ", @a[1..(int(@a)-1)]); my $state = join(" ", @a[1..(int(@a)-1)]);
CommandDelete(undef, $name."_fortimer") if($defs{"${name}_fortimer"});
if($cmd eq "raw") { ################################################## if($cmd eq "raw") { ##################################################
return "Usage: set $a[0] $cmd data [data ...]" if(@a < 3); return "Usage: set $a[0] $cmd data [data ...]" if(@a < 3);
$sndcmd = $a[2]; $sndcmd = $a[2];
for (my $i = 3; $i < @a; $i++) { for (my $i = 3; $i < @a; $i++) {
CUL_HM_PushCmdStack($shash, $a[$i]); CUL_HM_PushCmdStack($hash, $a[$i]);
} }
$state = ""; $state = "";
@ -676,16 +671,16 @@ CUL_HM_Set($@)
my $serialNr = AttrVal($name, "serialNr", undef); my $serialNr = AttrVal($name, "serialNr", undef);
return "serialNr is not set" if(!$serialNr); return "serialNr is not set" if(!$serialNr);
$sndcmd = sprintf("++A401%s000000010A%s", $id, unpack("H*",$serialNr)); $sndcmd = sprintf("++A401%s000000010A%s", $id, unpack("H*",$serialNr));
$shash->{hmPairSerial} = $serialNr; $hash->{hmPairSerial} = $serialNr;
} elsif($cmd eq "unpair") { ########################################### } elsif($cmd eq "unpair") { ###########################################
CUL_HM_pushConfig($shash, $id, $dst, 0, 0, "02010A000B000C00"); CUL_HM_pushConfig($hash, $id, $dst, 0, 0, "02010A000B000C00");
$sndcmd = shift @{$shash->{cmdStack}}; $sndcmd = shift @{$hash->{cmdStack}};
} elsif($cmd eq "sign") { ############################################ } elsif($cmd eq "sign") { ############################################
CUL_HM_pushConfig($shash, $id, $dst, $chn, $chn, CUL_HM_pushConfig($hash, $id, $dst, $chn, $chn,
"08" . ($a[2] eq "on" ? "01":"02")); "08" . ($a[2] eq "on" ? "01":"02"));
$sndcmd = shift @{$shash->{cmdStack}}; $sndcmd = shift @{$hash->{cmdStack}};
} elsif($cmd eq "statusRequest") { #################################### } elsif($cmd eq "statusRequest") { ####################################
$sndcmd = sprintf("++A001%s%s%s0E", $id,$dst, $chn); $sndcmd = sprintf("++A001%s%s%s0E", $id,$dst, $chn);
@ -700,19 +695,11 @@ CUL_HM_Set($@)
($tval,$ret) = CUL_HM_encodeTime16($a[2]); ($tval,$ret) = CUL_HM_encodeTime16($a[2]);
$sndcmd = sprintf("++A011%s%s02%sC80000%s", $id,$dst, $chn, $tval); $sndcmd = sprintf("++A011%s%s02%sC80000%s", $id,$dst, $chn, $tval);
if(AttrVal($name, "follow-on-for-timer", undef)) {
my $val = $a[2];
my $to = sprintf("%02d:%02d:%02d", $val/3600, ($val%3600)/60, $val%60);
Log 4, "Follow: +$to setstate $name off";
Log 1, "FOFT: $to";
CommandDefine(undef, $name . "_fortimer at +$to setstate $name off");
}
} elsif($cmd eq "toggle") { ########################################### } elsif($cmd eq "toggle") { ###########################################
$shash->{toggleIndex} = 1 if(!$shash->{toggleIndex}); $hash->{toggleIndex} = 1 if(!$hash->{toggleIndex});
$shash->{toggleIndex} = (($shash->{toggleIndex}+1) % 128); $hash->{toggleIndex} = (($hash->{toggleIndex}+1) % 128);
$sndcmd = sprintf("++A03E%s%s%s40%s%02X", $id, $dst, $sndcmd = sprintf("++A03E%s%s%s40%s%02X", $id, $dst,
$dst, $chn, $shash->{toggleIndex}); $dst, $chn, $hash->{toggleIndex});
} elsif($cmd eq "pct") { ############################################## } elsif($cmd eq "pct") { ##############################################
$a[1] = 100 if ($a[1] > 100); $a[1] = 100 if ($a[1] > 100);
@ -838,19 +825,19 @@ Log 1, "FOFT: $to";
# First the remote # First the remote
for(my $i = 1; $i <= 2; $i++) { for(my $i = 1; $i <= 2; $i++) {
my $b = ($i==1 ? $b1 : $b2); my $b = ($i==1 ? $b1 : $b2);
CUL_HM_PushCmdStack($shash, "++A001${id}${dst}${b}03"); CUL_HM_PushCmdStack($hash, "++A001${id}${dst}${b}03");
CUL_HM_PushCmdStack($shash, "++A001${id}${dst}${b}01${dst2}${chn2}00"); CUL_HM_PushCmdStack($hash, "++A001${id}${dst}${b}01${dst2}${chn2}00");
CUL_HM_PushCmdStack($shash, "++A001${id}${dst}${b}05${dst2}${chn2}04"); CUL_HM_PushCmdStack($hash, "++A001${id}${dst}${b}05${dst2}${chn2}04");
CUL_HM_PushCmdStack($shash, "++A001${id}${dst}${b}080100"); CUL_HM_PushCmdStack($hash, "++A001${id}${dst}${b}080100");
CUL_HM_PushCmdStack($shash, "++A001${id}${dst}${b}06"); CUL_HM_PushCmdStack($hash, "++A001${id}${dst}${b}06");
CUL_HM_PushCmdStack($shash, "++A001${id}${dst}${b}04${dst2}${chn2}04"); CUL_HM_PushCmdStack($hash, "++A001${id}${dst}${b}04${dst2}${chn2}04");
} }
# Now the switch. # Now the switch.
$sndcmd = "++A001${id}${dst2}${chn2}01${dst}${b2}${b1}"; $sndcmd = "++A001${id}${dst2}${chn2}01${dst}${b2}${b1}";
CUL_HM_PushCmdStack($dhash, "++A001${id}${dst2}${chn2}04${dst}${b1}03"); CUL_HM_PushCmdStack($dhash, "++A001${id}${dst2}${chn2}04${dst}${b1}03");
CUL_HM_PushCmdStack($dhash, "++A001${id}${dst2}${chn2}04${dst}${b2}03"); CUL_HM_PushCmdStack($dhash, "++A001${id}${dst2}${chn2}04${dst}${b2}03");
$shash = $dhash; # Exchange the shash, as the switch is always alive. $hash = $dhash; # Exchange the hash, as the switch is always alive.
} }
@ -858,7 +845,7 @@ Log 1, "FOFT: $to";
$hash->{STATE} = $state; $hash->{STATE} = $state;
$hash->{cmdSent} = $state; $hash->{cmdSent} = $state;
} }
CUL_HM_SendCmd($shash, $sndcmd, 0, 1) if($sndcmd); CUL_HM_SendCmd($hash, $sndcmd, 0, 1) if($sndcmd);
return $ret; return $ret;
} }
@ -984,10 +971,13 @@ CUL_HM_SendCmd($$$$)
$cmd = sprintf("As%02X%02X%s", length($cmd2)/2+1, $mn, $cmd2); $cmd = sprintf("As%02X%02X%s", length($cmd2)/2+1, $mn, $cmd2);
IOWrite($hash, "", $cmd); IOWrite($hash, "", $cmd);
if($waitforack) { if($waitforack) {
if($hash->{IODev} && $hash->{IODev}{TYPE} ne "HMLAN") { my $iohash = $hash->{IODev};
if($iohash && $iohash->{TYPE} ne "HMLAN") {
$hash->{ackWaiting} = $cmd; $hash->{ackWaiting} = $cmd;
$hash->{ackCmdSent} = 1; $hash->{ackCmdSent} = 1;
InternalTimer(gettimeofday()+0.4, "CUL_HM_Resend", $hash, 0) my $off = 0.5;
$off += 0.15*int(@{$iohash->{QUEUE}}) if($iohash->{QUEUE});
InternalTimer(gettimeofday()+$off, "CUL_HM_Resend", $hash, 0);
} }
} }
$cmd =~ m/As(..)(..)(....)(......)(......)(.*)/; $cmd =~ m/As(..)(..)(....)(......)(......)(.*)/;
@ -1002,7 +992,6 @@ CUL_HM_PushCmdStack($$)
my @arr = (); my @arr = ();
$hash->{cmdStack} = \@arr if(!$hash->{cmdStack}); $hash->{cmdStack} = \@arr if(!$hash->{cmdStack});
push(@{$hash->{cmdStack}}, $cmd); push(@{$hash->{cmdStack}}, $cmd);
Log 1, "PushStack: $hash->{NAME} ". @{$hash->{cmdStack}};
} }
################################### ###################################
@ -1042,7 +1031,7 @@ CUL_HM_Resend($)
IOWrite($hash, "", $hash->{ackWaiting}); IOWrite($hash, "", $hash->{ackWaiting});
$hash->{ackCmdSent}++; $hash->{ackCmdSent}++;
DoTrigger($name, "resend nr ".$hash->{ackCmdSent}); DoTrigger($name, "resend nr ".$hash->{ackCmdSent});
InternalTimer(gettimeofday()+0.4, "CUL_HM_Resend", $hash, 0); InternalTimer(gettimeofday()+0.5, "CUL_HM_Resend", $hash, 0);
} }
################################### ###################################