From d527f908cabf3eec38155bd47c00acab8f7ed5ff Mon Sep 17 00:00:00 2001 From: rudolfkoenig Date: Mon, 22 Mar 2010 14:31:37 +0000 Subject: [PATCH] sendpool attribute git-svn-id: https://fhem.svn.sourceforge.net/svnroot/fhem/trunk/fhem@602 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- CHANGED | 2 +- FHEM/00_CUL.pm | 66 +++++++++++++++++++++++++++++--------------- docs/commandref.html | 14 +++++++++- fhem.pl | 28 ++++++++----------- 4 files changed, 69 insertions(+), 41 deletions(-) diff --git a/CHANGED b/CHANGED index ec2c1e437..ee17e566c 100644 --- a/CHANGED +++ b/CHANGED @@ -581,4 +581,4 @@ - feature: KM271: Read only - bugfix: 99_SUNRISE_EL endless loop bug - feature: CUL: optional baudrate spec in definition - + - feature: CUL: sendpool attribute diff --git a/FHEM/00_CUL.pm b/FHEM/00_CUL.pm index 711bb7c95..aec10a712 100755 --- a/FHEM/00_CUL.pm +++ b/FHEM/00_CUL.pm @@ -78,7 +78,7 @@ CUL_Initialize($) $hash->{StateFn} = "CUL_SetState"; $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 " . - "fhtsoftbuffer:1,0"; + "fhtsoftbuffer:1,0 sendpool"; $hash->{ShutdownFn} = "CUL_Shutdown"; } @@ -101,7 +101,7 @@ CUL_Define($$) $hash->{FHTID} = uc($a[3]); 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; return undef; } @@ -613,17 +613,12 @@ CUL_Write($$$) if($fn eq "F") { - if(!CUL_AddFS20Queue($hash, $bstring)) { - CUL_XmitLimitCheck($hash,$bstring); - CUL_SimpleWrite($hash, $bstring); - } + CUL_AddFS20Queue($hash, $bstring); } elsif($bstring =~ m/u....F/) { # put FS20 messages sent over an RFR in the common queue - if(!CUL_AddFS20Queue($hash, $bstring)) { - CUL_SimpleWrite($hash, $bstring); - } + CUL_AddFS20Queue($hash, $bstring); } 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 CUL_AddFS20Queue($$) { my ($hash, $bstring) = @_; 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 ]; - InternalTimer(gettimeofday()+0.3, "CUL_HandleWriteQueue", $hash, 1); - return 0; + CUL_SendFromQueue($hash, $bstring); + + } else { + push(@{$hash->{QUEUE}}, $bstring); } - push(@{$hash->{QUEUE}}, $bstring); - return 1; } @@ -667,12 +691,10 @@ CUL_HandleWriteQueue($) return; } my $bstring = $arr->[0]; - if($bstring eq "-") { + if($bstring eq "") { CUL_HandleWriteQueue($hash); } else { - CUL_XmitLimitCheck($hash,$bstring); - CUL_SimpleWrite($hash, $bstring); - InternalTimer(gettimeofday()+0.3, "CUL_HandleWriteQueue", $hash, 1); + CUL_SendFromQueue($hash, $bstring); } } } @@ -743,7 +765,7 @@ CUL_Parse($$$$$) 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", $len/2+7, substr($dmsg,1,6), substr($dmsg,7)); $dmsg = lc($dmsg); diff --git a/docs/commandref.html b/docs/commandref.html index a68c95184..cb6bea623 100644 --- a/docs/commandref.html +++ b/docs/commandref.html @@ -1712,7 +1712,8 @@ A line ending with \ will be concatenated with the next one, so long lines character, e.g.: /dev/ttyACM0@38400

Network-connected devices (CUN):

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
  • showtime

  • loglevel

  • model (CUL,CUR)

  • +
  • sendpool
    + 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:
    + attr CUL1 sendpool CUL1,CUL2,CUL3
    + attr CUL2 sendpool CUL1,CUL2,CUL3
    + attr CUL3 sendpool CUL1,CUL2,CUL3
    +


  • diff --git a/fhem.pl b/fhem.pl index b6fb9a062..eacd7df8d 100755 --- a/fhem.pl +++ b/fhem.pl @@ -159,7 +159,7 @@ my $nextat; # Time when next timer will be triggered. my $intAtCnt=0; my %duplicate; # Pool of received msg for multi-fhz/cul setups 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 = "where is either:\n" . "- a single device name\n" . @@ -862,21 +862,15 @@ WriteStatefile() my $r = $defs{$d}{READINGS}; if($r) { foreach my $c (sort keys %{$r}) { - my $errors=0; - if(!defined($r->{$c}{TIME})) { - Log 4, "ERROR WITH DEF $d: Missing TIME in READINGS of key $c!"; - $errors++; - } - if(!defined($r->{$c}{VAL})) { - Log 4, "ERROR WITH DEF $d: Missing VAL in READINGS of key $c!"; - $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."; - } + if(!defined($r->{$c}{TIME})) { + Log 3, "WriteStatefile $d $c: Missing TIME"; + } elsif(!defined($r->{$c}{VAL})) { + Log 3, "WriteStatefile $d $c: Missing VAL"; + } else { + print SFH "setstate $d $r->{$c}{TIME} $c $r->{$c}{VAL}\n"; + } + } } } @@ -1691,7 +1685,8 @@ HandleTimeout() $nextat = 0; ############# # 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 $fn = $intAt{$i}{FN}; if(!defined($tim) || !defined($fn)) { @@ -1725,7 +1720,6 @@ InternalTimer($$$$) use strict "refs"; return; } - $intAt{$intAtCnt}{TRIGGERTIME} = $tim; $intAt{$intAtCnt}{FN} = $fn; $intAt{$intAtCnt}{ARG} = $arg;