# this is to allow the feed to "warm up" with duplicates
# so that the "big rush" doesn't happen.
-our $minspottime = 15*60; # the time between respots of a callsign - if a call is
+our $minspottime = 30*60; # the time between respots of a callsign - if a call is
# still being spotted (on the same freq) and it has been
# spotted before, it's spotted again after this time
# until the next minspottime has passed.
my $quality = shift;
my $cand = shift;
my $call = $dxchan->{call};
-
-
my $strength = 100; # because it could if we talk about FTx
my $saver;
-
my %zone;
- my %qrg;
my $respot;
my $qra;
# Spot::prepare($qrg, $call, $utz, $comment, $origin);
next unless ref $r;
- $respot = 1 if $r->[Respot];
$qra = $r->[RQra] if !$qra && $r->[RQra] && is_qra($r->[RQra]);
$comment = sprintf "%-3s %2ddB $quality", $r->[RMode], $r->[RStrength];
my $s = $r->[RSpotData]; # the prepared spot
$s->[SComment] = $comment; # apply new generated comment
-
++$zone{$s->[SZone]}; # save the spotter's zone
- ++$qrg{$s->[SQrg]}; # and the qrg
-
# save the lowest strength one
if ($r->[RStrength] < $strength) {
delete $zone{$saver->[SZone]}; # remove this spotter's zone (leaving all the other zones)
my $z = join ',', sort {$a <=> $b} keys %zone;
- # determine the most likely qrg and then set it
- my $mv = 0;
- my $fk;
- my $c = 0;
- while (my ($k, $v) = each %qrg) {
- $fk = $k, $mv = $v if $v > $mv;
- ++$c;
- }
- $saver->[SQrg] = $fk;
- $saver->[SComment] .= '*' if $c > 1;
- $saver->[SComment] .= '+' if $respot;
+ # alter spot data accordingly
$saver->[SComment] .= " Z:$z" if $z;
- if ($c > 1 && (isdbg('rbnqrg') || isdbg('rbn'))) {
-
- }
dbg("RBN: SENDING to $call spot: $saver->[SCall] qrg: $saver->[SQrg] origin: $saver->[SOrigin] $saver->[SComment]") if isdbg 'rbnll';
if ($dxchan->{ve7cc}) {
next;
}
dbg "RBN: QUEUE PROCESSING key: '$sp' $now >= $cand->[CTime]" if isdbg 'rbnqueue';
- my $r = $cand->[CData];
my $quality = @$cand - CData;
$quality = 9 if $quality > 9;
$cand->[CQual] = $quality if $quality > $cand->[CQual];
+
+ my $r;
+ my %qrg;
+ foreach $r (@$cand) {
+ next unless ref $r;
+ ++$qrg{$r->[RQrg]};
+ }
+ # determine the most likely qrg and then set it
+ my @deviant;
+ my $c = 0;
+ my $mv = 0;
+ my $qrg;
+ while (my ($k, $votes) = each %qrg) {
+ $qrg = $k, $mv = $votes if $votes > $mv;
+ ++$c;
+ }
+ # spit out the deviants
+ if ($c > 1) {
+ foreach $r (@$cand) {
+ next unless ref $r;
+ my $diff = nearest(.1, $qrg - $r->[RQrg]);
+ push @deviant, sprintf("$r->[ROrigin]:%+.1f", $diff) if $diff != 0;
+ $r->[RSpotData]->[SQrg] = $qrg; # set all the QRGs to the agreed value
+ }
+ }
+
+ $qrg = sprintf "%.1f", $qrg;
+ $r = $cand->[CData];
+ $r->[RQrg] = $qrg;
my $squality = "Q:$cand->[CQual]";
+ $squality .= '*' if $c > 1;
+ $squality .= '+' if $r->[Respot];
if ($cand->[CQual] >= $minqual) {
if (isdbg('progress')) {
my $s = "RBN: SPOT key: '$sp' = $r->[RCall] on $r->[RQrg] by $r->[ROrigin] \@ $r->[RTime] $squality route: $dxchan->{call}";
+ $s .= " Deviants: " . join(', ', sort @deviant) if @deviant;
dbg($s);
}
send_dx_spot($dxchan, $squality, $cand);
$spots->{$sp} = [$now, $cand->[CQual]];
delete $dxchan->{queue}->{$sp};
- } else {
+ }
+ else {
dbg sprintf("RBN: QUEUE key: '$sp' SEND time not yet reached %.1f secs left", $cand->[CTime] + $dwelltime - $now) if isdbg 'rbnqueue';
}
}
{
foreach my $dxchan (DXChannel::get_all()) {
next unless $dxchan->is_rbn;
- dbg "RBN:STATS minute $dxchan->{call} raw: $dxchan->{noraw} sent: $dxchan->{norbn} delivered: $dxchan->{nospot} users: " . scalar keys %{$dxchan->{nousers}} if isdbg('rbnstats');
+ dbg "RBN:STATS minute $dxchan->{call} raw: $dxchan->{noraw} retrieved spots: $dxchan->{norbn} delivered: $dxchan->{nospot} after filtering to users: " . scalar keys %{$dxchan->{nousers}} if isdbg('rbnstats');
if ($dxchan->{noraw} == 0 && $dxchan->{lasttime} > 60) {
LogDbg('RBN', "RBN: no input from $dxchan->{call}, disconnecting");
$dxchan->disconnect;
my $count = 0;
my $removed = 0;
while (my ($k,$cand) = each %{$spots}) {
+ next if $k eq 'VERSION';
+ next if $k =~ /^O\|/;
+
if ($main::systime - $cand->[CTime] > $minspottime*2) {
delete $spots->{$k};
++$removed;
foreach my $dxchan (DXChannel::get_all()) {
next unless $dxchan->is_rbn;
my $nq = keys %{$dxchan->{queue}};
- dbg "RBN:STATS 10-minute $dxchan->{call} queue: $nq raw: $dxchan->{noraw10} sent: $dxchan->{norbn10} delivered: $dxchan->{nospot10} users: " . scalar keys %{$dxchan->{nousers10}};
+ dbg "RBN:STATS 10-minute $dxchan->{call} queue: $nq raw: $dxchan->{noraw10} retrieved spots: $dxchan->{norbn10} delivered: $dxchan->{nospot10} after filtering to users: " . scalar keys %{$dxchan->{nousers10}};
$dxchan->{noraw10} = $dxchan->{norbn10} = $dxchan->{nospot10} = 0; $dxchan->{nousers10} = {};
}
}
foreach my $dxchan (DXChannel::get_all()) {
next unless $dxchan->is_rbn;
my $nq = keys %{$dxchan->{queue}};
- dbg "RBN:STATS hour $dxchan->{call} queue: $nq raw: $dxchan->{norawhour} sent: $dxchan->{norbnhour} delivered: $dxchan->{nospothour} users: " . scalar keys %{$dxchan->{nousershour}};
+ dbg "RBN:STATS hour $dxchan->{call} queue: $nq raw: $dxchan->{norawhour} retrieved spots: $dxchan->{norbnhour} delivered: $dxchan->{nospothour} after filtering to users: " . scalar keys %{$dxchan->{nousershour}};
$dxchan->{norawhour} = $dxchan->{norbnhour} = $dxchan->{nospothour} = 0; $dxchan->{nousershour} = {};
}
}
if (-e $cachefn) {
my $mt = (stat($cachefn))[9];
my $t = $main::systime - $mt || 1;
- my $p = difft($mt);
+ my $p = difft($mt, 2);
if ($t < $cache_valid) {
dbg("RBN:check_cache '$cachefn' spot cache exists, created $p ago and not too old");
my $fh = IO::File->new($cachefn);
if (exists $spots->{VERSION} && $spots->{VERSION} == $DATA_VERSION) {
# now clean out anything that is current
while (my ($k, $cand) = each %$spots) {
- next unless ref $cand;
+ next if $k eq 'VERSION';
+ next if $k =~ /^O\|/;
if (@$cand > CData) {
$spots->{$k} = [$cand->[CTime], $cand->[CQual]];
}