Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Re: AM Radio Station Finder

by Anonymous Monk
on Dec 22, 2005 at 01:56 UTC ( [id://518461]=note: print w/replies, xml ) Need Help??


in reply to AM Radio Station Finder

I don't know why, but the code is gone. Maybe the administrators took it offline due to size? Here's the script without the data part:
#!/usr/local/bin/perl # joeys_dx_stations.pl # version 1.2, Dec. 21, 2005 # by David Rhett Baker, davebaker@benefitslink.com # This small script (with a large appended DATA section) was written i +n 2005 for # my 11-year-old son, who enjoys listening to AM radio late at night i +n bed. # He tries to find "DX" stations, meaning long-distance stations that +are capable # of being received at night due to the "skip" off of the ionosphere. # This program shows which stations in the U.S. and Canada are broadca +sting on a # given frequency, and conversely shows which frequency and how much p +ower a given # station uses. It's about 5 megs in size due to the large database fr +om the FCC. # This program does not use every field of the data; it could be impro +ved to show # the direction in degrees to a particular broadcasting station from t +he reception # point, for example, or to show the distance between the broadcasting + station and # the reception point, if one were to take advantage of all the fields + of data. # History # 1.0 - initial release # 1.2 - added ability to enter c or f even when at prompt asking for u +pward or # downward adjustment of frequency to the next channel (10 kHz u +p or down), # so Joey will be able to get used to entering c to input a call +sign no matter # where in the program he is (and same for f to input a frequenc +y). use strict; use warnings; my @data_array; print "Christmas 2005: loading program for Joseph Rhett Baker... pleas +e stand by."; # We'll use an __END__ token at the end, which works like __DATA__, bu +t in a program # rather than a module... while (my $line = <main::DATA> ) { # Spinning bar in column 1, over the C in 'Christmas' <g> print "\r/"; print "\r-"; print "\r\\"; print "\r|"; print "\r/"; print "\r-"; print "\r\\"; print "\r|"; print "\rC"; #TS print "\nLine is $line\n"; my @values = split /\|/, $line; foreach my $value (@values) { $value =~ s/^\s+//; $value =~ s/\s+$//; #TS print "\$value is $value\n"; } # Chop spaces and kHz following the numeric frequency... $values[2] =~ s/ //gi; $values[2] =~ s/khz//gi; # Chop extra spaces in the power column... $values[14] =~ tr/ //s; my $data_hashref = { callsign => $values[1], freq => $values[2], time => $values[6], town => $values[10], state => $values[11], country => $values[12], kw => $values[14], }; #TS print "Callsign is $values[1], freq is $values[2], time is $values +[6], town is $values[10], state is $values[11], kw is $values[14].\n" +; push @data_array, $data_hashref; } PROMPT: while (1) { print "\nJoey, <c>allsign, <f>requency or <q>uit? (c, f or q): "; my $choice = <>; chomp $choice; unless ($choice eq 'c' || $choice eq 'C' || $choice eq 'f' || $choice eq 'F' || $choice eq 'q' || $choice eq 'Q' ) { next PROMPT; } if ($choice eq 'c' || $choice eq 'C') { CALLSIGN_PROMPT: print "\nWhat callsign? "; my $callsign = <>; chomp $callsign; $callsign = uc( $callsign ); foreach my $hashref (@data_array) { if ($hashref->{callsign} eq $callsign) { print $hashref->{callsign}, " broadcasts on ", $hashre +f->{freq}, " kHz (", $hashref->{time}, ") from ", $hashref->{town}, ", +", $hashref->{state}, ", running ", $hashref->{kw}, ".\n\n"; } } } elsif ($choice eq 'f' || $choice eq 'F') { FREQ_PROMPT: print "\nWhich frequency? "; my $frequency = <>; chomp $frequency; my %printed_already; FREQ_OUT: print "\nHere are the U.S. and Canada stations on $f +requency kHz:\n"; # Initialize or re-initialize, in the case of a freq adjustmen +t ordered later in the script... %printed_already = (); foreach my $hashref (@data_array) { if ( $hashref->{freq} == $frequency && ( $hashref->{country} eq 'US' || $hashref->{country} eq 'CA' ) ) { my $station = $hashref->{callsign}; unless ($printed_already{$station} ) { print "\n ", $hashref->{callsign}, ' in ', $hash +ref->{town}, ', ', $hashref->{state}; } # Instantiate and increment to non-zero value... $printed_already{$station}++; } } CHOICE: print "\n\n<u>p or <d>own to next frequency, or <q>uit +? "; my $choice = <>; chomp $choice; goto CHOICE unless ( $choice eq 'u' || $choice eq 'U' || $ch +oice eq 'd' || $choice eq 'D' || $choice eq 'q' || $choice eq 'Q' || $ch +oice eq 'c' || $choice eq 'C' || $choice eq 'f' || $choice eq 'F' ); if ($choice eq 'u' || $choice eq 'U') { $frequency += 10; goto FREQ_OUT; } elsif ($choice eq 'd' || $choice eq 'D') { $frequency -= 10; goto FREQ_OUT; } elsif ($choice eq 'c' || $choice eq 'C') { goto CALLSIGN_PROMPT; } elsif ($choice eq 'f' || $choice eq 'F') { goto FREQ_PROMPT; } else { next PROMPT; } } else { print "\n\nI love you, son! --Dad\n\n"; sleep 5; last; } } __END__
To get the data, go to the FCC web site and use their online database to get all the AM stations. The format will be something like this:
|NEW |1190 kHz |AM |- |DA3 |Daytime |B |B |AP +P |NELLIS AFB |NV |US |BNP -20040130BOW |50.0 k +W |- |- |- |161247 |N |35 |53 |53.00 |W |115 +|17 |4.00 |RAMS III + | 0.00 km | 0.00 mi | 0.00 deg | |WYNI |1190 kHz |AM |- |DA2 |Critical Hours |D |B |AP +P |HARAHAN |LA |US |BMJP -20040130AZP |11.0 k +W |- |- |- |40900 |N |29 |52 |46.00 |W |89 +|59 |51.00 |MCKISSICK ENTERPRISES + | 0.00 km | 0.00 mi | 0.00 deg | |WYNI |1190 kHz |AM |- |DA2 |Daytime |D |B |AP +P |HARAHAN |LA |US |BMJP -20040130AZP |11.0 k +W |- |- |- |40900 |N |29 |52 |46.00 |W |89 +|59 |51.00 |MCKISSICK ENTERPRISES + | 0.00 km | 0.00 mi | 0.00 deg | |NEW |1190 kHz |AM |- |DAN |Nighttime |B |B |AP +P |PINE BLUFF |AR |US |BNP -20040130ARB |0.25 k +W |- |- |- |161393 |N |34 |15 |18.00 |W |92 +|1 |44.00 |JOEL J. KINLOW + | 0.00 km | 0.00 mi | 0.00 deg | |NEW |1190 kHz |AM |- |DAN |Daytime |B |B |AP +P |PINE BLUFF |AR |US |BNP -20040130ARB |10.0 k +W |- |- |- |161393 |N |34 |15 |18.00 |W |92 +|1 |44.00 |JOEL J. KINLOW + | 0.00 km | 0.00 mi | 0.00 deg | |KRFT |1190 kHz |AM |- |DA2 |Nighttime |B |B |AP +P |UNIVERSITY CITY |MO |US |BMJP -20040130AQS |4.0 k +W |- |- |- |5281 |N |38 |26 |13.00 |W |90 +|16 |45.00 |ALL SPORTS RADIO, LLC + | 0.00 km | 0.00 mi | 0.00 deg | |KRFT |1190 kHz |AM |- |DA2 |Daytime |B |B |AP +P |UNIVERSITY CITY |MO |US |BMJP -20040130AQS |10.0 k +W |- |- |- |5281 |N |38 |42 |25.00 |W |90 +|3 |10.00 |ALL SPORTS RADIO, LLC + | 0.00 km | 0.00 mi | 0.00 deg | |WWNB |1190 kHz |AM |- |ND2 |Critical Hours |D |B |AP +P |NEW BERN |NC |US |BMJP -20040130AKH |2.5 k +W |- |- |- |14672 |N |35 |6 |3.00 |W |77 +|4 |33.00 |CTC MEDIA GROUP, INC. + | 0.00 km | 0.00 mi | 0.00 deg |
Just paste those lines immediately after the __END__ line (the last line of the script).

Replies are listed 'Best First'.
Re^2: AM Radio Station Finder
by davebaker (Pilgrim) on Dec 22, 2005 at 02:00 UTC
    Here's the URL for the data on the FCC site:

    http://www.fcc.gov/mb/audio/amq.html

    Choose the "text file, pipe-delimited, no links" option for the FCC search engine's output. Then copy and paste that output immediately after the __END__ line of the script above.

Version 1.3: download fresh data!
by davebaker (Pilgrim) on Dec 23, 2005 at 00:08 UTC
    Version 1.3, with ability to suck down fresh data from the FCC site if you have an Internet connection. Uses a separate data file rather than the __END__ technique, for maximum PAR compatibility. To create your first data file, just request the data from the FCC; the program saves it automatically as the separate data file now required (stations.dat).
    #!/usr/bin/perl use strict; use warnings; use Fcntl qw( :flock ); use LWP::Simple; # stations.pl # version 1.3, Dec. 22, 2005 # by David Rhett Baker, davebaker@benefitslink.com # This script (with a large appended DATA section) was written in 2005 + for my # 11-year-old son, who enjoys listening to AM radio late at night in b +ed. He # finds "DX" stations, meaning long-distance stations that are capable + of being # received at night due to the "skip" off of the ionosphere. # # This program shows which stations in the U.S. and Canada are broadca +sting on a # given frequency, and conversely shows which frequency and how much p +ower a given # station uses. It's about 5 megs in size due to the large database fr +om the FCC. # # This program does not use every field of the data; it could be impro +ved to show # the direction in degrees to a particular broadcasting station from t +he reception # point, for example, or to show the distance between the broadcasting + station and # the reception point, if one were to take advantage of all the fields + of data. # History # 1.0 - initial release # 1.2 - added ability to enter c or f even when at prompt asking for u +pward or # downward adjustment of frequency to the next channel (10 kHz u +p or down), # so Joey will be able to get used to entering c to input a call +sign no matter # where in the program he is (and same for f to input a frequenc +y). # # 1.2d - Optional version using external stations.dat file rather than + inline data; # PAR packager seems to need data in separate file. # # 1.3 - Ability to request refresh of data from the FCC site; data now + stored in an # external file (stations.dat) in same directory as executable. +If no stations.dat # file came with your distribution of version 1.3, this version +allows you to # automatically create one by requesting data data from the FCC +site. Thanks to # jdporter on perlmonks.org for the idea! my @data_array; my @data_lines; print "Christmas 2005: loading program for Joseph Rhett Baker... \n"; my $data_choice; DATA_PROMPT: print "\nUse <l>ocally-stored data, or <d>ownload fresh d +ata from the FCC server?\n(press l or d, then the ENTER key): "; $data_choice = <>; chomp $data_choice; unless ($data_choice eq 'l' || $data_choice eq 'L' || $data_choice eq 'd' || $data_choice eq 'D' ) { goto DATA_PROMPT; } if ($data_choice eq 'l' || $data_choice eq 'L') { open my $fh, '<', 'stations.dat' or die "Trouble opening stations.dat; is it in same directory +as stations.exe? Stopped: $!"; flock $fh, LOCK_SH or die "Trouble getting file lock for stations.dat; is it in u +se by another program? Stopped: $!"; @data_lines = <$fh>; } else { print "\nNow requesting data from the FCC server; this will take a + minute or two, even with a high-speed internet connection...\n"; my $stations_data = get( 'http://www.fcc.gov/fcc-bin/amq?state=&ca +ll=&arn=&city=&freq=530&fre2=1700&type=0&facid=&class=&list=4&dist=&d +lat2=&mlat2=&slat2=&NS=N&dlon2=&mlon2=&slon2=&EW=W&size=9' ); open my $fh, '>', 'stations.dat' or warn "Trouble opening stations.dat to save new FCC data; is + hard drive full? Stopped: $!"; flock $fh, LOCK_EX or die "Trouble getting file lock for stations.dat; is it in u +se by another program? Stopped: $!"; print {$fh} $stations_data; close $fh or warn "Trouble closing file lock for stations.dat"; @data_lines = split /\n/, $stations_data; } print "\nParsing data for AM station callsigns, frequencies, locations +, output power and broadcast times... \n"; LINE: foreach my $line (@data_lines) { next LINE unless ($line =~ /\|/); # Spinning bar in column 1, over the C in 'Christmas' <g> print "\r/"; print "\r-"; print "\r\\"; print "\r|"; print "\r/"; print "\r-"; print "\r\\"; print "\r|"; #TS print "\nLine is $line\n"; my @values = split /\|/, $line; foreach my $value (@values) { $value =~ s/^\s+//; $value =~ s/\s+$//; #TS print "\$value is $value\n"; } # Chop spaces and kHz following the numeric frequency... $values[2] =~ s/ //gi; $values[2] =~ s/khz//gi; # Chop extra spaces in the power column... $values[14] =~ tr/ //s; my $data_hashref = { callsign => $values[1], freq => $values[2], time => $values[6], town => $values[10], state => $values[11], country => $values[12], kw => $values[14], }; #TS print "Callsign is $values[1], freq is $values[2], time is $va +lues[6], town is $values[10], state is $values[11], kw is $values[14] +.\n"; push @data_array, $data_hashref; } PROMPT: while (1) { print "\nJoey, <c>allsign, <f>requency or <q>uit? (c, f or q): "; my $choice = <>; chomp $choice; unless ($choice eq 'c' || $choice eq 'C' || $choice eq 'f' || $choice eq 'F' || $choice eq 'q' || $choice eq 'Q' ) { next PROMPT; } if ($choice eq 'c' || $choice eq 'C') { CALLSIGN_PROMPT: print "\nWhat callsign? "; my $callsign = <>; chomp $callsign; $callsign = uc( $callsign ); foreach my $hashref (@data_array) { if ($hashref->{callsign} eq $callsign) { print $hashref->{callsign}, " broadcasts on ", $hashre +f->{freq}, " kHz (", $hashref->{time}, ") from ", $hashref->{town}, ", +", $hashref->{state}, ", running ", $hashref->{kw}, ".\n\n"; } } } elsif ($choice eq 'f' || $choice eq 'F') { FREQ_PROMPT: print "\nWhich frequency? "; my $frequency = <>; chomp $frequency; my %printed_already; FREQ_OUT: print "\nHere are the U.S. and Canada stations on $f +requency kHz:\n"; # Initialize or re-initialize, in the case of a freq adjustmen +t ordered later in the script... %printed_already = (); foreach my $hashref (@data_array) { if ( $hashref->{freq} == $frequency && ( $hashref->{country} eq 'US' || $hashref->{country} eq 'CA' ) ) { my $station = $hashref->{callsign}; unless ($printed_already{$station} ) { print "\n ", $hashref->{callsign}, ' in ', $hash +ref->{town}, ', ', $hashref->{state}; } # Instantiate and increment to non-zero value... $printed_already{$station}++; } } CHOICE: print "\n\n<u>p or <d>own to next frequency, or <q>uit +? "; my $choice = <>; chomp $choice; goto CHOICE unless ( $choice eq 'u' || $choice eq 'U' || $ch +oice eq 'd' || $choice eq 'D' || $choice eq 'q' || $choice eq 'Q' || $ch +oice eq 'c' || $choice eq 'C' || $choice eq 'f' || $choice eq 'F' ); if ($choice eq 'u' || $choice eq 'U') { $frequency += 10; goto FREQ_OUT; } elsif ($choice eq 'd' || $choice eq 'D') { $frequency -= 10; goto FREQ_OUT; } elsif ($choice eq 'c' || $choice eq 'C') { goto CALLSIGN_PROMPT; } elsif ($choice eq 'f' || $choice eq 'F') { goto FREQ_PROMPT; } else { next PROMPT; } } else { print "\n\nI love you, son! --Dad\n\n"; sleep 5; last; } }
      if ($data_choice eq 'l' || $data_choice eq 'L') { open my $fh, '<', 'stations.dat' or die "Trouble opening stations.dat; is it in same directory +as stations.exe? Stopped: $!"; flock $fh, LOCK_SH or die "Trouble getting file lock for stations.dat; is it in u +se by another program? Stopped: $!"; @data_lines = <$fh>; } else { print "\nNow requesting data from the FCC server; this will take a + minute or two, even with a high-speed internet connection...\n"; my $stations_data = get( 'http://www.fcc.gov/fcc-bin/amq?state=&ca +ll=&arn=&city=&freq=530&fre2=1700&type=0&facid=&class=&list=4&dist=&d +lat2=&mlat2=&slat2=&NS=N&dlon2=&mlon2=&slon2=&EW=W&size=9' ); open my $fh, '>', 'stations.dat' or warn "Trouble opening stations.dat to save new FCC data; is + hard drive full? Stopped: $!"; flock $fh, LOCK_EX or die "Trouble getting file lock for stations.dat; is it in u +se by another program? Stopped: $!"; print {$fh} $stations_data; close $fh or warn "Trouble closing file lock for stations.dat"; @data_lines = split /\n/, $stations_data; }

      Good grief. That's way too much work. And error prone. Just use the mirror function from LWP::Simple:

      # update file if necessary: mirror( $url, 'stations.dat' ); # and then: open my $fh, '<', 'stations.dat' or die "Trouble opening stations.dat - $!"; # LOCK_SH not necessary when using mirror() @data_lines = <$fh>;
      We're building the house of the future together.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://518461]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (6)
As of 2024-04-19 13:47 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found