89 lines
2.1 KiB
Elixir
89 lines
2.1 KiB
Elixir
defmodule Parser.Telemetry do
|
|
@moduledoc """
|
|
APRS telemetry parsing.
|
|
"""
|
|
|
|
@doc """
|
|
Parse an APRS telemetry string. Returns a struct or error.
|
|
"""
|
|
@spec parse(String.t()) :: map() | nil
|
|
def parse("T#" <> rest) do
|
|
case String.split(rest, ",") do
|
|
[seq | [_ | _] = values] ->
|
|
analog_values = Enum.take(values, 5)
|
|
digital_values = values |> Enum.drop(5) |> Enum.take(8)
|
|
|
|
%{
|
|
sequence_number: Parser.Helpers.parse_telemetry_sequence(seq),
|
|
analog_values: Parser.Helpers.parse_analog_values(analog_values),
|
|
digital_values: Parser.Helpers.parse_digital_values(digital_values),
|
|
data_type: :telemetry,
|
|
raw_data: rest
|
|
}
|
|
|
|
_ ->
|
|
%{
|
|
raw_data: rest,
|
|
data_type: :telemetry
|
|
}
|
|
end
|
|
end
|
|
|
|
def parse(<<":PARM.", rest::binary>>) do
|
|
%{
|
|
data_type: :telemetry_parameters,
|
|
parameter_names: String.split(rest, ",", trim: true),
|
|
raw_data: rest
|
|
}
|
|
end
|
|
|
|
def parse(<<":EQNS.", rest::binary>>) do
|
|
equations =
|
|
rest
|
|
|> String.split(",", trim: true)
|
|
|> Enum.chunk_every(3)
|
|
|> Enum.map(fn [a, b, c] ->
|
|
%{
|
|
a: Parser.Helpers.parse_coefficient(a),
|
|
b: Parser.Helpers.parse_coefficient(b),
|
|
c: Parser.Helpers.parse_coefficient(c)
|
|
}
|
|
end)
|
|
|
|
%{
|
|
data_type: :telemetry_equations,
|
|
equations: equations,
|
|
raw_data: rest
|
|
}
|
|
end
|
|
|
|
def parse(<<":UNIT.", rest::binary>>) do
|
|
%{
|
|
data_type: :telemetry_units,
|
|
units: String.split(rest, ",", trim: true),
|
|
raw_data: rest
|
|
}
|
|
end
|
|
|
|
def parse(<<":BITS.", rest::binary>>) do
|
|
case String.split(rest, ",", trim: true) do
|
|
[bits_sense | project_names] ->
|
|
%{
|
|
data_type: :telemetry_bits,
|
|
bits_sense: String.to_charlist(bits_sense),
|
|
project_names: project_names,
|
|
raw_data: rest
|
|
}
|
|
|
|
[] ->
|
|
%{
|
|
data_type: :telemetry_bits,
|
|
bits_sense: [],
|
|
project_names: [],
|
|
raw_data: rest
|
|
}
|
|
end
|
|
end
|
|
|
|
def parse(data), do: %{raw_data: data, data_type: :telemetry}
|
|
end
|