View Source AprsUtils.AprsParser (AprsUtils v0.1.0)
Module for parsing APRS packets into components.
Philosopy
By its own admission, the APRS protocol is complex and shows definate signs of having
a design which evolved and grew during it's development. This module is designed to abstract
as much of this away as possible. It reveals only the actual information contained in the packet,
and as little about the protocol as it can. For example, the module will not return any
information about the type of packet, or if the positional information was compressed.
Basically the structure that is returns contains the information the
packet contains, and nil
in the information fields that the packet does not contain.
See this set of documents for the APRS protocol:
Units
For historical reasons, APRS uses a variety of units. This module will convert all units to this set of SI units.
- latitude, longitude: degrees (float)
- distance: meters (float)
- speed: meters per second (float)
- temperature: degrees Celsius (float)
- pressure: pascals (float)
- humidity: relative percent (float)
Time handling
Some, but not all, APRS packet formats contain timestamps. However all of the formats give only partial time information. One of the most common formats, for example, provides the day, hour, and minutes of transmission. It is the receiver's responsibility to provide the year and month. This can introduce incorrect interpretation of the time, especially if the time between transmission and parsing of the data is long. This module does not attempt to interpret the time, but simply returns the time information that is in the packet. Note that most, but not all, timestamp formats are Zulu Time.
Caution on binary data
Many of the fields described below are returned as binaries taken directly from the APRS packet. These binaries are not
necessarily valid UTF-8 strings. In fact, it is common for APRS packets to contain non-printable characters, and non-UTF-8.
If you attempt to use these for in an iolist
for example, make sure you are prepared to handle non-UTF-8 binaries that
fail String.valid?/1
.
Unsupported APRS Features
This is the set of Data Type Identifiers which are supported (others will return {:error, ...}
tuples).
["!", "=", "@", "/", "'", "`", <<\x1c>>, <<\x1d>>, ">", ":", "T", ";", ")", "$", "_" ]
This module does not support the "!DAO!" construct in the Mic-E format.
This module does not recognize the software/device identifiers (APxxxx) in the TO field.
Summary
Functions
Parses an APRS string into components.
Functions
Parses an APRS string into components.
Args
aprs_packet
- The APRS packet to parse. Note that this is a binary, but is not necessarily a valid String. APRS packets can, and regularly do, contain non-printable characters, and non-UTF-8 sequences.
Successful Returns
{:ok, %AprsUtils.AprsParser{}}
If an :ok is returned, the APRS packet has been successfully parsed into a struct. The struct contains the decoded components of the APRS packet. If the field of the struct is nil, then the packet did not contain that information.
Here is how to interpret each field of the struct:
Field | Description |
---|---|
:raw | The same binary passed in to the parse function. |
:to | A binary containing callsign of the station from which the packet is sent. |
:from | A binary often containing callsign of the station to which the packet is sent. Or, this can be used to encode other information found in the packet. |
:path | A list of binaries containing the callsigns of the digipeaters or other gateways that the packet has passed through. |
:timestamp | A map containting a set of the following fields: :month , :day , :hour , :minute , :second , and timezone . The fields are all integers, except for :timezone , which is either :zulu or :local_to_sender . |
:symbol | A two byte binary containing the symbol table and symbol represented in the packet. If you want to extract the bytes you can match <<symbol_table::binary-size(1), symbol::binary-size(1)>> |
:position | A map, see the table below for the fields. |
:course | A map, see the table below for the fields. |
:antenna | A map, see the table below for the fields. |
:weather | A map, see the table below for the fields. |
:telemetry | A map containing :sequence_counter , :values , and :bits . :sequence_counter is an integer used to order telemetry reports. :values and :bits are lists. The former contains numeric values, and the later is a sequence of either 1 or 0 . |
:message | Certain APRS packets are meant to be messages to a specific destination. In this case a message map is returned with the following fields: :addressee , :message , :message_no (which may be missing). :message is a textual message. :message_no is an integer message sequencer. |
:status | A binary which is the text from a packet containing a status report. Note, this is distinct from a message or a comment. |
:device | A binary containing the name of the sending device. This implementation is a bit weak in this area. |
:object | A map which define's an object which has the fields :name and :state . :name is a binary identifier, and :state is either :killed or :alive . |
:item | An item is just like an object (above) except that semantically it represents an inanimate thing that are occasionally posted on a map (e.g. marathon checkpoints or first-aid posts). |
:raw_gps | A binary. A packet can contain the raw GPS information in one of the popular GPS device formats, like an NMEA sentence. |
:comment | A binary comment on the packet. |
Position | |
---|---|
:latitude | A tuple in the form {degrees, precision} where degrees is a float, and precision is one of :hundredth_minute , :tenth_minute , :minute , :tenth_degree , or :degree giving the approximate precision. |
:longitude | A tuple in the form {degrees, precision} where degrees is a float, and precision is one of :hundredth_minute , :tenth_minute , :minute , :tenth_degree , or :degree giving the approximate precision. |
:maidenhead | A string like IO91SX . This is given instead of latitude and longitude, but is considered obsolete. |
:altitude | A floating point number in meters. |
Course | |
---|---|
:direction | A float in degrees. |
:speed | A float in meters per second. |
:bearing | A float in degrees. |
:range | A float in meters. |
:report_quality | An integer from 0 to 8 with 8 being the best, or :manual . |
:bearing_accuracy | An integer from 1 to 9 with 9 being the best, or :useless . See Chapter 7 of the APRS Spec. if you want to understand report quality and bearing accuracy better. |
Antenna | |
---|---|
:power | A float in watts. |
:strength | An integer in S-points from 0 to 9. |
:height | A float in meters. |
:directivity | A float in degrees, or :omnidirectional . |
Weather | |
---|---|
:temperature | A float in degrees celsius. |
:wind_speed | A float in meters per second. |
:wind_direction | A float in degrees. |
:gust_speed | A float in meters per second. |
:barometric_pressure | A float in pascals. |
:humidity | A float in percent. |
:rainfall_last_hour | A float in meters. |
:rainfall_last_24_hours | A float in meters. |
:rainfall_since_midnight | A float in meters. |
:rain_counts | A float in counts. |
:luminosity | A float in watts per square meter. |
:snow_fall | A float in meters. |
:water_height | A float in meters. |
:peak_wind_gust | A float in meters per second. |
:hurricane_winds_radius | A float in meters. |
:tropical_storm_winds_radius | A float in meters. |
:gale_force_winds_radius | A float in meters. |
:software_type | A binary. Together with :wx_unit are meant to describe the weather device reporting. This isn't robustly handled. |
:wx_unit | A binary. |
Error Returns
{:error, Map.t()}
Field | |
---|---|
:raw | The same binary passed in to the parse function. |
:error | A binary describing the error. |
:near_character_position | An integer indicating the position in the binary where the error was detected. |
Note that for many type of errors :near_character_position
will be nil.