From c961a6af6d9aec8eba4d58803f890fc514a109cc Mon Sep 17 00:00:00 2001 From: djk Date: Thu, 21 Oct 1999 18:44:22 +0000 Subject: [PATCH] Fixed console to wrap. added sh/muf command --- Changes | 1 + cmd/Commands_en.hlp | 45 ++++++++++++ cmd/show/muf.pl | 165 ++++++++++++++++++++++++++++++++++++++++++ perl/DXCommandmode.pm | 5 +- perl/DXProt.pm | 3 +- perl/Geomag.pm | 6 +- perl/Minimuf.pm | 86 ++++++++++++++++++++-- perl/console.pl | 4 +- 8 files changed, 302 insertions(+), 13 deletions(-) diff --git a/Changes b/Changes index e04ef39d..4d355001 100644 --- a/Changes +++ b/Changes @@ -1,6 +1,7 @@ 21Oct99======================================================================= 1. fixed reply so that reply b or reply nop generate a bulletin with the correct address. +2. implemented sh/muf command. 20Oct99======================================================================= 1. Translated all the subroutines of minimuf into perl as Minimuf.pm 2. Limited the length of an ANN that is saved for de-duping to $pc12_dup_lth diff --git a/cmd/Commands_en.hlp b/cmd/Commands_en.hlp index d789a51e..f11b6b2a 100644 --- a/cmd/Commands_en.hlp +++ b/cmd/Commands_en.hlp @@ -468,6 +468,51 @@ string to see a selection of files in a filearea eg:- See also TYPE - to see the contents of a file. +=== 0^SHOW/MUF []^Show the likely propagation to a prefix +This command allow you to estimate the likelyhood of you contacting +a station with the prefix you have specified. The output assumes a modest +power of 20dBW and receiver sensitivity of -123dBm (about 0.15muV/10dB SINAD) + +The command will display some header information detailing its +assumptions, together with the locations, latitude and longitudes and +bearings. It will then show UTC (UT), local time at the other end +(LT), calculate the MUFs, Sun zenith angle at the midpoint of the path +(Zen) and the likely signal strengths. Then for each frequency for which +the system thinks there is a likelihood of a circuit it prints a value. + +The value is currently a likely S meter reading based on the conventional +6dB / S point scale. If the value has a '+' appended it means that it is +1/2 an S point stronger. If the value is preceeded by an 'm' it means that +there is likely to be much fading and by an 's' that the signal is likely +to be noisy. + +By default SHOW/MUF will show the next two hours worth of data. You +can specify anything up to 24 hours worth of data by appending the no of +hours required after the prefix. For example:- + + SH/MUF W + +produces: + + RxSens: -123 dBM SFI: 159 R: 193 Month: 10 Day: 21 + Power : 20 dBW Distance: 6283 km Delay: 22.4 ms + Location Lat / Long Azim + East Dereham, Norfolk 52 41 N 0 57 E 47 + United-States-W 43 0 N 87 54 W 299 + UT LT MUF Zen 1.8 3.5 7.0 10.1 14.0 18.1 21.0 24.9 28.0 50.0 + 18 23 11.5 -35 mS0+ mS2 S3 + 19 0 11.2 -41 mS0+ mS2 S3 + +indicating that you will have weak, fading circuits on top band and +80m but usable signals on 40m (about S3). + +inputing:- + + SH/MUF W 24 + +will get you the above display, but with the next 24 hours worth of +propagation data. + === 0^SHOW/PREFIX ^Interrogate the prefix database This command takes the (which can be a full or partial callsign or a prefix), looks up which internal country number diff --git a/cmd/show/muf.pl b/cmd/show/muf.pl index e69de29b..e880eabd 100644 --- a/cmd/show/muf.pl +++ b/cmd/show/muf.pl @@ -0,0 +1,165 @@ +#!/usr/bin/perl +# +# show/muf command +# +# Copyright (c) 1999 Dirk Koopman G1TLH +# +# $Id$ +# + +my ($self, $line) = @_; +my ($prefix, $hr2) = split /\s+/, $line; +return (1, $self->msg('e4')) unless $prefix; + +$hr2 = 2 if !$hr2 || $hr2 < 2; +$hr2 = 24 if $hr2 > 24; + +my @out; + +# get prefix data +my ($pre, $a) = Prefix::extract($prefix); + +# calc bearings and distance +my ($d, $b1, $b2); # distance, bearing from TX and from RX +my ($lat2, $lon2); # lats and longs in radians +my $lat1 = $self->user->lat; +my $lon1 = $self->user->long; +if (!$lon1 && !$lat1) { + push @out, $self->msg('heade1'); + $lat1 = $main::mylatitude; + $lon1 = $main::mylongitude; +} +$lat2 = $a->{lat}; +$lon2 = $a->{long}; +($b2, $d) = DXBearing::bdist($lat1, $lon1, $lat2, $lon2); +($b1, undef) = DXBearing::bdist($lat2, $lon2, $lat1, $lon1); + +# convert stuff into radians +$lat1 *= $d2r; +$lat2 *= $d2r; +$lon1 *= $d2r; +$lon2 *= $d2r; +$b1 *= $d2r; +$b2 *= $d2r; +$d = ($d / $R); + +my ($hr1, $day, $month) = (gmtime($main::systime))[2,3,4]; +$month++; +my $flux = Geomag::sfi; +my $ssn = Geomag::r || Minimuf::spots($flux); + +my $theta; # path angle (rad) +my ($lats, $lons); # subsolar coordinates (rad) +my $dB1 = 20; # transmitter output power (dBW) + +my $delay; # path delay (ms) +my $psi; # sun zenith angle (rad) +my ($ftemp, $gtemp); # my $temps +my ($i, $j, $h, $n); # int temps +my $offset; # offset for local time (hours) +my $fcF; # F-layer critical frequency (MHz) +my $phiF; # F-layer angle of incidence (rad) +my $hop; # number of ray hops +my $beta1; # elevation angle (rad) +my $dhop; # hop great-circle distance (rad) +my $height; # height of F layer (km) +my $time; # time of day (hour) +my $rsens = -123; # RX sensitivity + + +my @freq = qw(1.8 3.5 7.0 10.1 14.0 18.1 21.0 24.9 28.0 50.0); # working frequencies (MHz) +my $nfreq = @freq; # number of frequencies +my @mufE; # maximum E-layer MUF (MHz) +my @mufF; # minimum F-layer MUF (MHz) +my @absorp; # ionospheric absorption coefficient +my @dB2; # receive power (dBm) +my @path; # path length (km) +my @beta; # elevation angle (rad) +my @daynight; # path flags + +# calculate hops, elevation angle, F-layer incidence, delay. +$hop = int ($d / (2 * acos($R / ($R + $hF)))); +$beta1 = 0; +while ($beta1 < $MINBETA) { + $hop++; + $dhop = $d / ($hop * 2); + $beta1 = atan((cos($dhop) - $R / ($R + $hF)) / sin($dhop)); +} +$ftemp = $R * cos($beta1) / ($R + $hF); +$phiF = atan($ftemp / sqrt(1 - $ftemp * $ftemp)); +$delay = ((2 * $hop * sin($dhop) * ($R + $hF)) / cos($beta1) / $VOFL) * 1e6; + +# print summary of data so far +push @out, sprintf("RxSens: $rsens dBM SFI:%4.0lf R:%4.0lf Month: $month Day: $day", $flux, $ssn); +push @out, sprintf("Power : %3.0f dBW Distance:%6.0f km Delay:%5.1f ms", $dB1, $d * $R, $delay); +push @out, sprintf("Location Lat / Long Azim"); +push @out, sprintf("%-30.30s %-18s %3.0f", $main::myqth, DXBearing::lltos($lat1*$r2d, $lon1*$r2d), $b1 * $r2d); +push @out, sprintf("%-30.30s %-18s %3.0f", $a->name, DXBearing::lltos($lat2*$r2d, $lon2*$r2d), $b2 * $r2d); +my $head = "UT LT MUF Zen"; +for ($i = 0; $i < $nfreq; $i++) { + $head .= sprintf "%5.1f", $freq[$i]; +} +push @out, $head; + +my $hour; + +# Hour loop: This loop determines the min-hop path and next two +# higher-hop paths. It selects the most likely path for each +# frequency and calculates the receive power. The F-layer +# critical frequency is computed directly from MINIMUF 3.5 and +# the secant law. + +$offset = int ($lon2 * 24. / $pi2); +for ($hour = $hr1; $hour < $hr2+$hr1; $hour++) { + my $dh = $hour; + while ($dh >= 24) { + $dh -= 24; + }; + $time = $dh - $offset; + $time += 24 if ($time < 0); + $time -= 24 if ($time >= 24); + my $out = sprintf("%2.0f %2.0f", $dh, $time); + $ftemp = Minimuf::minimuf($flux, $month, $day, $dh, $lat1, $lon1, $lat2, $lon2); + $fcF = $ftemp * cos($phiF); + + # Calculate subsolar coordinates. + $ftemp = ($month - 1) * 365.25 / 12. + $day - 80.; + $lats = 23.5 * $d2r * sin($ftemp / 365.25 * $pi2); + $lons = ($dh * 15. - 180.) * $d2r; + + # Path loop: This loop determines the geometry of the + # min-hop path and the next two higher-hop paths. It + # calculates the minimum F-layer MUF, maximum E-layer + # MUF and ionospheric absorption factor for each + # geometry. + for ($h = $hop; $h < $hop + 3; $h++) { + + # We assume the F layer height increases during + # the day and decreases at night, as determined + # at the midpoint of the path. + $height = $hF; + $psi = Minimuf::zenith($d / 2, $lat1, $lon1, $b2, $b1, $lats, $lons); + if ($psi < 0) { + $height -= 70.; + } else { + $height += 30; + } + $dhop = $d / ($h * 2.); + $beta[$h] = atan((cos($dhop) - $R / ($R + $height)) / sin($dhop)); + $path[$h] = 2 * $h * sin($dhop) * ($R + $height) / cos($beta[$h]); + Minimuf::ion($h, $d, $fcF, $ssn, $lat1, $lon1, $b2, $b1, $lats, $lons, \@daynight, \@mufE, \@mufF, \@absorp); + } + + # Display one line for this hour. + $out .= sprintf("%5.1f%4.0f ", $mufF[$hop], 90 - $psi * $r2d); + $ftemp = $noise; + for ($i = 0; $i < $nfreq; $i++) { + $n = Minimuf::pathloss($hop, $freq[$i], 20, $rsens, 0, \@daynight, \@beta, \@path, \@mufF, \@mufE, \@absorp, \@dB2); + my $s = Minimuf::ds($n, $rsens, \@dB2, \@daynight); + $out .= " $s"; + } + $out =~ s/\s+$//; + push @out, $out; +} + +return (1, @out); diff --git a/perl/DXCommandmode.pm b/perl/DXCommandmode.pm index 35fd35cc..44c2728c 100644 --- a/perl/DXCommandmode.pm +++ b/perl/DXCommandmode.pm @@ -9,6 +9,9 @@ package DXCommandmode; +use POSIX; +use IO::File; + @ISA = qw(DXChannel); use DXUtil; @@ -21,9 +24,9 @@ use DXLog; use DXLogPrint; use DXBearing; use CmdAlias; -use IO::File; use Filter; use Carp; +use Minimuf; use strict; use vars qw(%Cache %cmd_cache $errstr %aliases); diff --git a/perl/DXProt.pm b/perl/DXProt.pm index a28d36f5..6ecf0e79 100644 --- a/perl/DXProt.pm +++ b/perl/DXProt.pm @@ -516,7 +516,8 @@ sub normal my $sfi = unpad($field[3]); my $k = unpad($field[4]); my $i = unpad($field[5]); - my $r = $field[6] =~ /R=(\d+)/ || 0; + my ($r) = $field[6] =~ /R=(\d+)/; + $r = 0 unless $r; my $dupkey = "$d.$sfi$k$i"; if ($wwvdup{$dupkey}) { dbg('chan', "Dup WWV Spot ignored\n"); diff --git a/perl/Geomag.pm b/perl/Geomag.pm index d78ff2cd..1a1a8a40 100644 --- a/perl/Geomag.pm +++ b/perl/Geomag.pm @@ -73,8 +73,12 @@ sub update # my $trydate = cltounix($mydate, sprintf("%02d18Z", $mytime)); if ($mydate >= $date) { + if ($myr) { + $r = 0 + $myr; + } else { + $r = 0 unless abs ($mysfi - $sfi) > 3; + } $sfi = 0 + $mysfi; - $r = 0 + $myr unless !$r && $myk == $k; $k = 0 + $myk; $a = 0 + $mya; $forecast = $myforecast; diff --git a/perl/Minimuf.pm b/perl/Minimuf.pm index e493e5b9..e911663c 100644 --- a/perl/Minimuf.pm +++ b/perl/Minimuf.pm @@ -34,12 +34,19 @@ package Minimuf; -use strict; use POSIX; -use vars qw($pi $d2r $r2d $halfpi $pi2 $VOFL $R $hE $hF $GAMMA $LN10 + +require Exporter; +@ISA = qw(Exporter); +@EXPORT = qw($pi $d2r $r2d $halfpi $pi2 $VOFL $R $hE $hF $GAMMA $LN10 $MINBETA $BOLTZ $NTEMP $DELTAF $MPATH $GLOSS $SLOSS $noise); +use strict; +use vars qw($pi $d2r $r2d $halfpi $pi2 $VOFL $R $hE $hF $GAMMA $LN10 + $MINBETA $BOLTZ $NTEMP $DELTAF $MPATH $GLOSS $SLOSS + $noise); + $pi = 3.141592653589; $d2r = ($pi/180); $r2d = (180/$pi); @@ -201,9 +208,15 @@ sub ion my $d = shift; # path angle (rad) my $fcF = shift; # F-layer critical frequency my $ssn = shift; # current sunspot number - my $daynight = shift; # ref to daynight array one per hop + my $lat1 = shift; + my $lon1 = shift; + my $b1 = shift; + my $b2 = shift; + my $lats = shift; + my $lons = shift; # various refs to arrays + my $daynight = shift; # ref to daynight array one per hop my $mufE = shift; my $mufF = shift; my $absorp = shift; @@ -233,13 +246,14 @@ sub ion $phiE = atan($ftemp / sqrt(1 - $ftemp * $ftemp)); $ftemp = $R * cos($beta) / ($R + $hF); $phiF = atan($ftemp / sqrt(1 - $ftemp * $ftemp)); - $$mufF->[$h] = $fcF / cos($phiF);; + $absorp->[$h] = $mufE->[$h] = $daynight->[$h] = 0; + $mufF->[$h] = $fcF / cos($phiF);; for ($dist = $dhop; $dist < $d; $dist += $dhop * 2) { # Calculate the E-layer critical frequency and MUF. $fcE = 0; - $psi = zenith($dist); + $psi = zenith($dist, $lat1, $lon1, $b2, $b1, $lats, $lons); $ftemp = cos($psi); $fcE = .9 * pow((180. + 1.44 * $ssn) * $ftemp, .25) if ($ftemp > 0); $fcE = .005 * $ssn if ($fcE < .005 * $ssn); @@ -306,7 +320,7 @@ sub pathloss $level = $noise; $j = 0; for ($h = $hop; $h < $hop + 3; $h++) { -# $daynight->[$h] &= ~(P_E | P_S | P_M); + $daynight->[$h] &= ~(4 | 8 | 16); if ($freq < 0.85 * $mufF->[$h]) { # Transmit power (dBm) @@ -401,7 +415,63 @@ sub zenith $psi += $pi if ($psi < 0); return($psi); } - - + +# official minimuf version of display +sub dsx +{ + my $h = shift; + my $rsens = shift; + my $dB2 = shift; + my $daynight = shift; + + my $c1; + my $c2; + + return " " unless $h; + + if (($daynight->[$h] & 3) == 3) { + $c1 = 'x'; + } elsif ($daynight->[$h] & 1) { + $c1 = 'j'; + } elsif ($daynight->[$h] & 2) { + $c1 = 'n'; + } + if ($daynight->[$h] & 4) { + $c2 = 's'; + } elsif ($daynight->[$h] & 16) { + $c2 = 'm'; + } else { + $c2 = ' '; + } + return sprintf("%4.0f%s%1d%s", $dB2->[$h] - $rsens, $c1, $h, $c2) +} + +# my version +sub ds +{ + my $h = shift; + my $rsens = shift; + my $dB2 = shift; + my $daynight = shift; + + my $c2; + + return " " unless $h; + + if ($daynight->[$h] & 4) { + $c2 = 's'; + } elsif ($daynight->[$h] & 16) { + $c2 = 'm'; + } else { + $c2 = ' '; + } + my $l = $dB2->[$h] - $rsens; + my $s = int $l / 6; + $s = 9 if $s > 9; + $s = 0 if $s < 0; + my $plus = (($l / 6) >= $s + 0.5) ? '+' : ' '; + + return "$c2\S$s$plus"; +} 1; diff --git a/perl/console.pl b/perl/console.pl index bf747b86..75632aa8 100755 --- a/perl/console.pl +++ b/perl/console.pl @@ -195,9 +195,9 @@ sub rec_socket if (defined $msg) { my ($sort, $call, $line) = $msg =~ /^(\w)(\S+)\|(.*)$/; - if ($sort eq 'D') { + if ($sort && $sort eq 'D') { addtotop($line); - } elsif ($sort eq 'Z') { # end, disconnect, go, away ..... + } elsif ($sort && $sort eq 'Z') { # end, disconnect, go, away ..... cease(0); } } -- 2.34.1