more parsing progress on compressed positions
This commit is contained in:
parent
5ea16fa5f7
commit
c750d5da17
9 changed files with 129 additions and 24 deletions
|
|
@ -2,4 +2,6 @@ defmodule Aprs.Convert do
|
|||
def wind(speed, :ultimeter, :mph), do: speed * 0.0621371192
|
||||
|
||||
def temp(value, :ultimeter, :f), do: value * 0.1
|
||||
|
||||
def speed(value, :knots, :mph), do: Float.round(value * 1.15077945, 2)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -208,6 +208,9 @@ defmodule Aprs.Is do
|
|||
|
||||
# IO.inspect(parsed_message)
|
||||
# Logger.debug("SERVER:" <> message)
|
||||
{:error, :invalid_packet} ->
|
||||
Logger.debug("PARSE ERROR: invalid packet")
|
||||
|
||||
{:error, error} ->
|
||||
Logger.debug("PARSE ERROR: " <> error)
|
||||
|
||||
|
|
|
|||
|
|
@ -36,9 +36,9 @@ defmodule Parser do
|
|||
rescue
|
||||
_ ->
|
||||
# Logger.debug("PARSE ERROR: " <> message)
|
||||
# {:ok, file} = File.open("/home/graham/badpackets.txt", [:append])
|
||||
# IO.binwrite(file, message <> "\n\n")
|
||||
# File.close(file)
|
||||
{:ok, file} = File.open("./badpackets.txt", [:append])
|
||||
IO.binwrite(file, message <> "\n\n")
|
||||
File.close(file)
|
||||
{:error, :invalid_packet}
|
||||
end
|
||||
end
|
||||
|
|
@ -161,7 +161,7 @@ defmodule Parser do
|
|||
[:ok, lat, lon]
|
||||
end
|
||||
|
||||
defp convert_to_base91(<<value::binary-size(4)>>) do
|
||||
def convert_to_base91(<<value::binary-size(4)>>) do
|
||||
[v1, v2, v3, v4] = to_charlist(value)
|
||||
(v1 - 33) * 91 * 91 * 91 + (v2 - 33) * 91 * 91 + (v3 - 33) * 91 + v4
|
||||
end
|
||||
|
|
@ -236,16 +236,44 @@ defmodule Parser do
|
|||
end
|
||||
|
||||
def parse_position_without_timestamp(
|
||||
_aprs_messaging?,
|
||||
<<_dti::binary-size(1), "/", _latitude::binary-size(4), _longitude::binary-size(4),
|
||||
_sym_table_id::binary-size(1), _cs::binary-size(2), _compression_type::binary-size(1),
|
||||
_comment::binary>> = message
|
||||
aprs_messaging?,
|
||||
<<_dti::binary-size(1), "/", latitude::binary-size(4), longitude::binary-size(4),
|
||||
sym_table_id::binary-size(1), _cs::binary-size(2), _compression_type::binary-size(1),
|
||||
comment::binary>> = message
|
||||
) do
|
||||
# {:ok, file} = File.open("badpackets.txt")
|
||||
# IO.puts(file, message)
|
||||
# {:ok, file} = File.open("./compressed.txt", [:append])
|
||||
# IO.binwrite(
|
||||
# file,
|
||||
# message <>
|
||||
# "\n" <>
|
||||
# "aprs_messaging?: #{aprs_messaging?}\n" <>
|
||||
# "dti: #{dti}\n" <>
|
||||
# "latitude: #{latitude}\n" <>
|
||||
# "longitude: #{longitude}\n" <>
|
||||
# "sym_table_id: #{sym_table_id}\n" <>
|
||||
# "cs: #{cs}\n" <>
|
||||
# "compression_type: #{compression_type}\n" <>
|
||||
# "comment: #{comment}\n\n"
|
||||
# )
|
||||
# File.close(file)
|
||||
|
||||
# convert_compressed_cs(cs) |> IO.inspect()
|
||||
Logger.debug("TODO: PARSE COMPRESSED LAT/LON: " <> message)
|
||||
|
||||
converted_lat = convert_compressed_lat(latitude)
|
||||
converted_lon = convert_compressed_lon(longitude)
|
||||
position = Position.from_decimal(converted_lat, converted_lon)
|
||||
# converted_cs = convert_compressed_cs(cs)
|
||||
|
||||
%{
|
||||
latitude: converted_lat,
|
||||
longitude: converted_lon,
|
||||
position: position,
|
||||
symbol_table_id: sym_table_id,
|
||||
# symbol_code: symbol_code,
|
||||
comment: comment,
|
||||
data_type: :position,
|
||||
aprs_messaging?: aprs_messaging?
|
||||
}
|
||||
end
|
||||
|
||||
def parse_position_with_timestamp(
|
||||
|
|
@ -508,4 +536,44 @@ defmodule Parser do
|
|||
# defp convert_ultimeter_humidity(hum) do
|
||||
# hum * 10
|
||||
# end
|
||||
|
||||
def convert_compressed_lat(lat) do
|
||||
[l1, l2, l3, l4] = to_charlist(lat)
|
||||
90 - ((l1 - 33) * 91 ** 3 + (l2 - 33) * 91 ** 2 + (l3 - 33) * 91 + l4 - 33) / 380_926
|
||||
end
|
||||
|
||||
def convert_compressed_lon(lon) do
|
||||
[l1, l2, l3, l4] = to_charlist(lon)
|
||||
-180 + ((l1 - 33) * 91 ** 3 + (l2 - 33) * 91 ** 2 + (l3 - 33) * 91 + l4 - 33) / 190_463
|
||||
end
|
||||
|
||||
def convert_compressed_cs(cs) do
|
||||
[c, s] = to_charlist(cs)
|
||||
c = c - 33
|
||||
s = s - 33
|
||||
|
||||
case c do
|
||||
x when x in ?!..?z ->
|
||||
# compressed speed/course value
|
||||
# speed is returned in knots
|
||||
%{
|
||||
course: s * 4,
|
||||
speed: Convert.speed(1.08 ** s - 1, :knots, :mph)
|
||||
}
|
||||
|
||||
?Z ->
|
||||
# pre-calculated radio range
|
||||
%{
|
||||
range: 2 * 1.08 ** s
|
||||
}
|
||||
|
||||
_ ->
|
||||
IO.inspect(cs, label: "not parsable")
|
||||
|
||||
%{
|
||||
course: 0,
|
||||
speed: 0
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -17,8 +17,6 @@ defmodule Parser.Types.Position do
|
|||
aprs_latitude = aprs_latitude |> String.replace(" ", "0") |> String.pad_leading(9, "0")
|
||||
aprs_longitude = aprs_longitude |> String.replace(" ", "0") |> String.pad_leading(9, "0")
|
||||
|
||||
# Logger.debug("#{aprs_latitude} #{aprs_longitude}")
|
||||
|
||||
<<latitude::binary-size(8), lat_direction::binary>> = aprs_latitude
|
||||
<<longitude::binary-size(8), lon_direction::binary>> = aprs_longitude
|
||||
|
||||
|
|
@ -28,16 +26,6 @@ defmodule Parser.Types.Position do
|
|||
<<lon_deg::binary-size(3), lon_min::binary-size(2), lon_fractional::binary-size(3)>> =
|
||||
convert_garbage_to_zero(longitude)
|
||||
|
||||
# %Position{
|
||||
# lat_degrees: lat_deg |> String.replace(".", "") |> String.to_integer(),
|
||||
# lat_minutes: lat_min |> String.replace(".", "") |> String.to_integer(),
|
||||
# lat_fractional: convert_fractional(lat_fractional),
|
||||
# lat_direction: convert_direction(lat_direction),
|
||||
# lon_degrees: lon_deg |> String.replace(".", "") |> String.to_integer(),
|
||||
# lon_minutes: lon_min |> String.replace(".", "") |> String.to_integer(),
|
||||
# lon_fractional: convert_fractional(lon_fractional),
|
||||
# lon_direction: convert_direction(lon_direction)
|
||||
# }
|
||||
try do
|
||||
lat =
|
||||
Geocalc.DMS.to_degrees(%Geocalc.DMS{
|
||||
|
|
@ -61,6 +49,10 @@ defmodule Parser.Types.Position do
|
|||
end
|
||||
end
|
||||
|
||||
def from_decimal(latitude, longitude) do
|
||||
%{latitude: latitude, longitude: longitude}
|
||||
end
|
||||
|
||||
defp convert_garbage_to_zero(value) do
|
||||
try do
|
||||
_ = String.to_float(value)
|
||||
|
|
|
|||
3
mix.exs
3
mix.exs
|
|
@ -73,7 +73,8 @@ defmodule Aprs.MixProject do
|
|||
{:faker, "~> 0.17.0", only: [:dev, :test]},
|
||||
{:stream_data, "~> 0.5", only: [:dev, :test]},
|
||||
{:mix_test_watch, "~> 1.1", only: [:dev, :test]},
|
||||
{:sobelow, "~> 0.8", only: :dev}
|
||||
{:sobelow, "~> 0.8", only: :dev},
|
||||
{:codepagex, "~> 0.1.6"}
|
||||
]
|
||||
end
|
||||
|
||||
|
|
|
|||
2
mix.lock
2
mix.lock
|
|
@ -3,9 +3,11 @@
|
|||
"bunt": {:hex, :bunt, "0.2.1", "e2d4792f7bc0ced7583ab54922808919518d0e57ee162901a16a1b6664ef3b14", [:mix], [], "hexpm", "a330bfb4245239787b15005e66ae6845c9cd524a288f0d141c148b02603777a5"},
|
||||
"castore": {:hex, :castore, "0.1.22", "4127549e411bedd012ca3a308dede574f43819fe9394254ca55ab4895abfa1a2", [:mix], [], "hexpm", "c17576df47eb5aa1ee40cc4134316a99f5cad3e215d5c77b8dd3cfef12a22cac"},
|
||||
"certifi": {:hex, :certifi, "2.9.0", "6f2a475689dd47f19fb74334859d460a2dc4e3252a3324bd2111b8f0429e7e21", [:rebar3], [], "hexpm", "266da46bdb06d6c6d35fde799bcb28d36d985d424ad7c08b5bb48f5b5cdd4641"},
|
||||
"codepagex": {:hex, :codepagex, "0.1.6", "49110d09a25ee336a983281a48ef883da4c6190481e0b063afe2db481af6117e", [:mix], [], "hexpm", "1521461097dde281edf084062f525a4edc6a5e49f4fd1f5ec41c9c4955d5bd59"},
|
||||
"combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"},
|
||||
"comeonin": {:hex, :comeonin, "5.3.3", "2c564dac95a35650e9b6acfe6d2952083d8a08e4a89b93a481acb552b325892e", [:mix], [], "hexpm", "3e38c9c2cb080828116597ca8807bb482618a315bfafd98c90bc22a821cc84df"},
|
||||
"connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"},
|
||||
"convertat": {:hex, :convertat, "1.1.0", "00c125f00a2e06be74d27df5a6b93f9b2d7c27aaa6ecb41d96f009ee7d7bd978", [:mix], [], "hexpm", "603229c43df6769f2166c78c5c3f31316390bf6e19fa8e15f02026170ab51a79"},
|
||||
"cowboy": {:hex, :cowboy, "2.9.0", "865dd8b6607e14cf03282e10e934023a1bd8be6f6bacf921a7e2a96d800cd452", [:make, :rebar3], [{:cowlib, "2.11.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "2c729f934b4e1aa149aff882f57c6372c15399a20d54f65c8d67bef583021bde"},
|
||||
"cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"},
|
||||
"cowlib": {:hex, :cowlib, "2.11.0", "0b9ff9c346629256c42ebe1eeb769a83c6cb771a6ee5960bd110ab0b9b872063", [:make, :rebar3], [], "hexpm", "2b3e9da0b21c4565751a6d4901c20d1b4cc25cbb7fd50d91d2ab6dd287bc86a9"},
|
||||
|
|
|
|||
|
|
@ -13,4 +13,10 @@ defmodule Aprs.ConvertTest do
|
|||
assert Convert.temp(55, :ultimeter, :f) == 5.5
|
||||
end
|
||||
end
|
||||
|
||||
describe "speed/3" do
|
||||
test "converts knots to mph" do
|
||||
assert Convert.speed(55, :knots, :mph) == 63.29
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -233,4 +233,13 @@ defmodule Parser.ParserTest do
|
|||
}
|
||||
end
|
||||
end
|
||||
|
||||
describe "convert_compressed_cs/1" do
|
||||
# !!
|
||||
# I!
|
||||
# Y"
|
||||
test "1" do
|
||||
assert Parser.convert_compressed_cs("Y$") == %{course: 12, speed: 0.3}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
22
test/types/position_test.exs
Normal file
22
test/types/position_test.exs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
defmodule Parser.Types.PositionTest do
|
||||
use ExUnit.Case
|
||||
alias Parser.Types.Position
|
||||
|
||||
describe "from_aprs/2" do
|
||||
test "1" do
|
||||
assert Position.from_aprs("3339.13N", "11759.13W") == %{
|
||||
latitude: 33.652166666666666,
|
||||
longitude: -117.9855
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
describe "from_decimal/2" do
|
||||
test "1" do
|
||||
assert Position.from_decimal(33.652166666666666, -117.9855) == %{
|
||||
latitude: 33.652166666666666,
|
||||
longitude: -117.9855
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Reference in a new issue