sendpool attribute

git-svn-id: https://fhem.svn.sourceforge.net/svnroot/fhem/trunk/fhem@602 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
rudolfkoenig
2010-03-22 14:31:37 +00:00
parent e64e622782
commit d527f908ca
4 changed files with 69 additions and 41 deletions

View File

@@ -581,4 +581,4 @@
- feature: KM271: Read only - feature: KM271: Read only
- bugfix: 99_SUNRISE_EL endless loop bug - bugfix: 99_SUNRISE_EL endless loop bug
- feature: CUL: optional baudrate spec in definition - feature: CUL: optional baudrate spec in definition
- feature: CUL: sendpool attribute

View File

@@ -78,7 +78,7 @@ CUL_Initialize($)
$hash->{StateFn} = "CUL_SetState"; $hash->{StateFn} = "CUL_SetState";
$hash->{AttrList}= "do_not_notify:1,0 dummy:1,0 " . $hash->{AttrList}= "do_not_notify:1,0 dummy:1,0 " .
"showtime:1,0 model:CUL,CUN,CUR loglevel:0,1,2,3,4,5,6 " . "showtime:1,0 model:CUL,CUN,CUR loglevel:0,1,2,3,4,5,6 " .
"fhtsoftbuffer:1,0"; "fhtsoftbuffer:1,0 sendpool";
$hash->{ShutdownFn} = "CUL_Shutdown"; $hash->{ShutdownFn} = "CUL_Shutdown";
} }
@@ -101,7 +101,7 @@ CUL_Define($$)
$hash->{FHTID} = uc($a[3]); $hash->{FHTID} = uc($a[3]);
if($dev eq "none") { if($dev eq "none") {
Log 1, "CUL device is none, commands will be echoed only"; Log 1, "$name device is none, commands will be echoed only";
$attr{$name}{dummy} = 1; $attr{$name}{dummy} = 1;
return undef; return undef;
} }
@@ -613,17 +613,12 @@ CUL_Write($$$)
if($fn eq "F") { if($fn eq "F") {
if(!CUL_AddFS20Queue($hash, $bstring)) { CUL_AddFS20Queue($hash, $bstring);
CUL_XmitLimitCheck($hash,$bstring);
CUL_SimpleWrite($hash, $bstring);
}
} elsif($bstring =~ m/u....F/) { } elsif($bstring =~ m/u....F/) {
# put FS20 messages sent over an RFR in the common queue # put FS20 messages sent over an RFR in the common queue
if(!CUL_AddFS20Queue($hash, $bstring)) { CUL_AddFS20Queue($hash, $bstring);
CUL_SimpleWrite($hash, $bstring);
}
} else { } else {
@@ -634,22 +629,51 @@ CUL_Write($$$)
} }
sub
CUL_SendFromQueue($$)
{
my ($hash, $bstring) = @_;
my $name = $hash->{NAME};
if($bstring ne "") {
# Is one of the CUL-fellows sending data?
if($attr{$name} && $attr{$name}{sendpool}) {
my @fellows = split(",", $attr{$name}{sendpool});
foreach my $f (@fellows) {
if($f ne $name &&
$defs{$f} &&
$defs{$f}{QUEUE} &&
$defs{$f}{QUEUE}->[0] ne "")
{
unshift(@{$hash->{QUEUE}}, "");
InternalTimer(gettimeofday()+0.3, "CUL_HandleWriteQueue", $hash, 1);
return;
}
}
}
CUL_XmitLimitCheck($hash,$bstring);
CUL_SimpleWrite($hash, $bstring);
}
##############
# 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
# else it will be sent too early by the CUL, resulting in a collision
InternalTimer(gettimeofday()+0.3, "CUL_HandleWriteQueue", $hash, 1);
}
sub sub
CUL_AddFS20Queue($$) CUL_AddFS20Queue($$)
{ {
my ($hash, $bstring) = @_; my ($hash, $bstring) = @_;
if(!$hash->{QUEUE}) { if(!$hash->{QUEUE}) {
##############
# 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
# else it will be sent too early by the CUL, resulting in a collision
$hash->{QUEUE} = [ $bstring ]; $hash->{QUEUE} = [ $bstring ];
InternalTimer(gettimeofday()+0.3, "CUL_HandleWriteQueue", $hash, 1); CUL_SendFromQueue($hash, $bstring);
return 0;
} else {
push(@{$hash->{QUEUE}}, $bstring);
} }
push(@{$hash->{QUEUE}}, $bstring);
return 1;
} }
@@ -667,12 +691,10 @@ CUL_HandleWriteQueue($)
return; return;
} }
my $bstring = $arr->[0]; my $bstring = $arr->[0];
if($bstring eq "-") { if($bstring eq "") {
CUL_HandleWriteQueue($hash); CUL_HandleWriteQueue($hash);
} else { } else {
CUL_XmitLimitCheck($hash,$bstring); CUL_SendFromQueue($hash, $bstring);
CUL_SimpleWrite($hash, $bstring);
InternalTimer(gettimeofday()+0.3, "CUL_HandleWriteQueue", $hash, 1);
} }
} }
} }
@@ -743,7 +765,7 @@ CUL_Parse($$$$$)
if($fn eq "F" && $len >= 9) { # Reformat for 10_FS20.pm if($fn eq "F" && $len >= 9) { # Reformat for 10_FS20.pm
CUL_AddFS20Queue($iohash, "-"); # Block immediate replies CUL_AddFS20Queue($iohash, ""); # Block immediate replies
$dmsg = sprintf("81%02x04xx0101a001%s00%s", $dmsg = sprintf("81%02x04xx0101a001%s00%s",
$len/2+7, substr($dmsg,1,6), substr($dmsg,7)); $len/2+7, substr($dmsg,1,6), substr($dmsg,7));
$dmsg = lc($dmsg); $dmsg = lc($dmsg);

View File

@@ -1712,7 +1712,8 @@ A line ending with \ will be concatenated with the next one, so long lines
character, e.g.: /dev/ttyACM0@38400<br><br> character, e.g.: /dev/ttyACM0@38400<br><br>
</ul> </ul>
Network-connected devices (CUN):<br><ul> Network-connected devices (CUN):<br><ul>
&lt;device&gt; specifies the host:port of the device. E.g. 192.168.0.244:2323 &lt;device&gt; specifies the host:port of the device. E.g.
192.168.0.244:2323
</ul> </ul>
<br> <br>
If the device is called none, then no device will be opened, so you If the device is called none, then no device will be opened, so you
@@ -1770,6 +1771,17 @@ A line ending with \ will be concatenated with the next one, so long lines
<li><a href="#showtime">showtime</a></li><br> <li><a href="#showtime">showtime</a></li><br>
<li><a href="#loglevel">loglevel</a></li><br> <li><a href="#loglevel">loglevel</a></li><br>
<li><a href="#model">model</a> (CUL,CUR)</li><br> <li><a href="#model">model</a> (CUL,CUR)</li><br>
<li><a href="#sendpool">sendpool</a><br>
If using more than one CUL/CUN for covering a large area, sending
different events by the different CUL's might disturb each other. This
phenomenon is also known as the Palm-Beach-Resort effect.
Putting them in a common sendpool will serialize sending the events.
E.g. if you have three CUN's, you have to specify following
attributes:<br>
attr CUL1 sendpool CUL1,CUL2,CUL3<br>
attr CUL2 sendpool CUL1,CUL2,CUL3<br>
attr CUL3 sendpool CUL1,CUL2,CUL3<br>
</li><br>
</ul> </ul>
<br> <br>
</ul> </ul>

28
fhem.pl
View File

@@ -159,7 +159,7 @@ my $nextat; # Time when next timer will be triggered.
my $intAtCnt=0; my $intAtCnt=0;
my %duplicate; # Pool of received msg for multi-fhz/cul setups my %duplicate; # Pool of received msg for multi-fhz/cul setups
my $duplidx=0; # helper for the above pool my $duplidx=0; # helper for the above pool
my $cvsid = '$Id: fhem.pl,v 1.102 2010-02-24 08:20:37 rudolfkoenig Exp $'; my $cvsid = '$Id: fhem.pl,v 1.103 2010-03-22 14:31:37 rudolfkoenig Exp $';
my $namedef = my $namedef =
"where <name> is either:\n" . "where <name> is either:\n" .
"- a single device name\n" . "- a single device name\n" .
@@ -862,21 +862,15 @@ WriteStatefile()
my $r = $defs{$d}{READINGS}; my $r = $defs{$d}{READINGS};
if($r) { if($r) {
foreach my $c (sort keys %{$r}) { foreach my $c (sort keys %{$r}) {
my $errors=0;
if(!defined($r->{$c}{TIME})) { if(!defined($r->{$c}{TIME})) {
Log 4, "ERROR WITH DEF $d: Missing TIME in READINGS of key $c!"; Log 3, "WriteStatefile $d $c: Missing TIME";
$errors++; } elsif(!defined($r->{$c}{VAL})) {
} Log 3, "WriteStatefile $d $c: Missing VAL";
if(!defined($r->{$c}{VAL})) { } else {
Log 4, "ERROR WITH DEF $d: Missing VAL in READINGS of key $c!"; print SFH "setstate $d $r->{$c}{TIME} $c $r->{$c}{VAL}\n";
$errors++; }
}
if($errors==0) {
print SFH "setstate $d $r->{$c}{TIME} $c $r->{$c}{VAL}\n";
} else {
Log 3, "Sanitizer: not saving READING $c of $d due to missing VAL and/or TIME.";
}
} }
} }
} }
@@ -1691,7 +1685,8 @@ HandleTimeout()
$nextat = 0; $nextat = 0;
############# #############
# Check the internal list. # Check the internal list.
foreach my $i (keys %intAt) { foreach my $i (sort { $intAt{$a}{TRIGGERTIME} <=>
$intAt{$b}{TRIGGERTIME} } keys %intAt) {
my $tim = $intAt{$i}{TRIGGERTIME}; my $tim = $intAt{$i}{TRIGGERTIME};
my $fn = $intAt{$i}{FN}; my $fn = $intAt{$i}{FN};
if(!defined($tim) || !defined($fn)) { if(!defined($tim) || !defined($fn)) {
@@ -1725,7 +1720,6 @@ InternalTimer($$$$)
use strict "refs"; use strict "refs";
return; return;
} }
$intAt{$intAtCnt}{TRIGGERTIME} = $tim; $intAt{$intAtCnt}{TRIGGERTIME} = $tim;
$intAt{$intAtCnt}{FN} = $fn; $intAt{$intAtCnt}{FN} = $fn;
$intAt{$intAtCnt}{ARG} = $arg; $intAt{$intAtCnt}{ARG} = $arg;