Skip to content
Browse files

APRS decoding routines for lat/long/time

  • Loading branch information...
1 parent 5346d0a commit f156562cd8215b2b76d73a5942d42bafc5493a9b @robacarp committed Apr 1, 2013
Showing with 147 additions and 40 deletions.
  1. +34 −25 aprs/aprs-listener.rb
  2. +86 −15 aprs/aprs_is_message.rb
  3. +27 −0 aprs/aprs_is_message_test.rb
View
59 aprs/aprs-listener.rb
@@ -1,38 +1,47 @@
require 'socket'
require './aprs_is_message'
-test_messages = [
- "VE3EP>WIDE2-1,qAS,VA3JLF-1:@282328z4354.89N/07711.21W_296/004g006t039r000p000P000h36b10190>East Lake Report (ve3ep@rac.ca) {UIV32N}",
- "KC5EVE-14>APU25N,TCPIP*,qAS,KC5EVE-13:@282328z3735.90N/10748.65W_231/005g006t063r000p000P000h16b10215/ {UIV32N}"
-]
-
-test_messages.each do |m|
- AprsIsMessage.parse m
+def parse_line line
+ puts "PACKET: #{line}"
+ message = AprsIsMessage.parse line
+ return if message.nil?
+
+ puts "SENDER : \033[31m#{message.sender}\033[0m"
+ puts "DEST : \033[33m#{message.dest}\033[0m"
+ puts "PATH : \033[37m#{message.route}\033[0m"
+ puts "DATA : #{message.raw_data}"
+ puts "TIME : #{message.time}"
+ puts "LAT/LON : #{message.lat}/#{message.lon}"
+ puts "\n-----------"
end
+if true
+ File.open('data-log.txt','r') do |historical_data|
+ until historical_data.eof?
+ parse_line historical_data.readline
+ end
+ end
-puts 'Connecting...'
-aprs = TCPSocket.new 'noam.aprs2.net', 14580
-logfile = File.open('data-log.txt', 'w+')
-puts 'connected, requesting filter...'
+ exit
-aprs.puts 'user KD0PNR-A0 pass -1 filter t/w'
-while line = aprs.gets
- logfile.puts line
- logfile.flush
+else
+ puts 'Connecting...'
+ aprs = TCPSocket.new 'noam.aprs2.net', 14580
+ logfile = File.open('data-log.txt', 'w+')
+ puts 'connected, requesting filter...'
- message = AprsIsMessage.parse line
- next if message.nil?
+ aprs.puts 'user KD0PNR-A0 pass -1 filter t/w'
- puts "SENDER: \033[31m#{message.sender}\033[0m"
- puts "DEST : \033[33m#{message.dest}\033[0m"
- puts "PATH : \033[37m#{message.route}\033[0m"
- puts "DATA : #{message.raw_data}"
- puts "PACKET: #{line}"
- puts "\n-----------"
-end
+ while line = aprs.gets
+ logfile.puts line
+ logfile.flush
+ parse_line line
+ end
-aprs.close
+ logfile.close
+ aprs.close
+
+end
View
101 aprs/aprs_is_message.rb
@@ -20,36 +20,107 @@ def self.parse line
# http://www.aprs.net/vm/DOS/PROTOCOL.HTM
def parse_data
return if raw_data.nil?
- type = raw_data[0]
- message = raw_data[1..-1]
-
-
- case type
- when '='
- equal message
- when '!'
- bang message
- when '@'
- at message
- when '_'
- underscore message
- end
+ segments = raw_data.split(/(@|!|_|=)/)
+ .reject{|s| s.empty?}
+ .each_slice(2)
+ .map{|(a,b)| [a,b]}
+
+ segments.each do |(type, message)|
+ puts "\t #{type} >> #{message}"
+ case type
+ when '='
+ equal message
+ when '@'
+ at message
+ when '!'
+ bang message
+ when '_'
+ underscore message
+ when '$'
+ dollar message
+ end
+ end
end
def bang data
+ # 4820.32N/00809.24E
end
def equal data
+ # 3107.77N/12124.52E
+ # Position data
+ ns, ew = data.split('/')
+ puts "\t\t LAT: #{ns}"
+ puts "\t\t LON: #{ew}"
end
def at data
+ # 291651z5209.97N/00709.65W
+ data = data.downcase
+ time_format = data[6]
+ time = data[0..5]
+ coords = data[7..-1]
+
+ debugger if coords.nil?
+ parse_coords coords
end
- def star data
+ def dollar data
+ # comments. may contain weather data?
end
def underscore data
+ # weather data?
+ end
+
+
+ def parse_coords data
+ # DDMM.hh
+ # 5209.97N/00709.65W
+ # 3107.77N/12124.52E
+ # 4820.32N/00809.24E
+ lat, lon = data.split '/'
+
+ lat_sign = lat[-1] == 'N' ? 1 : -1
+ lon_sign = lon[-1] == 'E' ? 1 : -1
+
+ self.lat = lat.to_f * lat_sign
+ self.lon = lon.to_f * lon_sign
end
+ def parse_time data
+ # DDHHMMf
+ # 291651z
+ day = data[0...2].to_i
+ hours = data[2...4].to_i
+ min = data[4...6].to_i
+
+ today_gmt = Time.now.utc
+ today_day = today_gmt.day
+ month = today_gmt.month
+ year = today_gmt.year
+
+ # so, on a month boundary, we need to do some
+ # special handling, incase the packet comes in
+ # a day late or something.
+ if day > today_day
+ month -= 1
+ end
+
+ if month <= 0
+ year -= 1
+ month = 12
+ end
+
+ self.time = Time.new(
+ year,
+ month,
+ day,
+ hours,
+ min,
+ 0,
+ 0
+ )
+ end
end
View
27 aprs/aprs_is_message_test.rb
@@ -0,0 +1,27 @@
+require 'minitest/autorun'
+
+require './aprs_is_message'
+
+class AprsIsMessageTest < MiniTest::Unit::TestCase
+ def setup
+ @aim = AprsIsMessage.new
+ end
+
+ def test_time_parser
+ @aim.parse_time('291651z')
+
+ assert_equal @aim.time.hour, 16
+ assert_equal @aim.time.day, 29
+ assert_equal @aim.time.min, 51
+ end
+
+ def test_coordinate_parser
+ @aim.parse_coords('5209.97N/00709.65W')
+ assert @aim.lat == 5209.97
+ assert @aim.lon == -709.65
+
+ @aim.parse_coords('5209.97S/00709.65E')
+ assert @aim.lat == -5209.97
+ assert @aim.lon == 709.65
+ end
+end

0 comments on commit f156562

Please sign in to comment.
Something went wrong with that request. Please try again.