Better parsing for extras; Added deviceID resolution

This commit is contained in:
2026-03-18 17:01:46 +01:00
parent be8cd00c00
commit 17caa22331
8 changed files with 1517 additions and 240 deletions

View File

@@ -1,5 +1,12 @@
import { Dissected, Segment } from "@hamradio/packet";
// Any comment that contains this marker will set the doNotArchive flag on the
// decoded payload, which can be used by applications to skip archiving or
// logging frames that are meant to be transient or test data. This allows users
// to include the marker in their APRS comments when they want to indicate that
// a particular frame should not be stored long-term.
export const DO_NOT_ARCHIVE_MARKER = "!x!";
export interface IAddress {
call: string;
ssid: string;
@@ -22,7 +29,7 @@ export enum DataType {
PositionWithTimestampWithMessaging = "@",
// Mic-E
MicECurrent = "`",
MicE = "`",
MicEOld = "'",
// Messages and Bulletins
@@ -60,6 +67,27 @@ export enum DataType {
InvalidOrTest = ","
}
export const DataTypeNames: { [key in DataType]: string } = {
[DataType.PositionNoTimestampNoMessaging]: "position",
[DataType.PositionNoTimestampWithMessaging]: "position with messaging",
[DataType.PositionWithTimestampNoMessaging]: "position with timestamp",
[DataType.PositionWithTimestampWithMessaging]: "position with timestamp and messaging",
[DataType.MicE]: "Mic-E",
[DataType.MicEOld]: "Mic-E (old)",
[DataType.Message]: "message/bulletin",
[DataType.Object]: "object",
[DataType.Item]: "item",
[DataType.Status]: "status",
[DataType.Query]: "query",
[DataType.TelemetryData]: "telemetry data",
[DataType.WeatherReportNoPosition]: "weather report",
[DataType.RawGPS]: "raw GPS data",
[DataType.StationCapabilities]: "station capabilities",
[DataType.UserDefined]: "user defined",
[DataType.ThirdParty]: "third-party traffic",
[DataType.InvalidOrTest]: "invalid/test"
};
export interface ISymbol {
table: string; // Symbol table identifier
code: string; // Symbol code
@@ -73,21 +101,13 @@ export interface IPosition {
longitude: number; // Decimal degrees
ambiguity?: number; // Position ambiguity (0-4)
altitude?: number; // Meters
speed?: number; // Speed in knots/kmh depending on source
speed?: number; // Speed in km/h
course?: number; // Course in degrees
range?: number; // Kilometers
phg?: IPowerHeightGain;
dfs?: IDirectionFinding;
symbol?: ISymbol;
comment?: string;
/**
* Optional reported radio range in miles (from RNG token in comment)
*/
range?: number;
/**
* Optional power/height/gain information from PHG token
* PHG format: PHGpphhgg (pp=power, hh=height, gg=gain) as numeric values
*/
phg?: IPowerHeightGain;
/** Direction-finding / DF information parsed from comment tokens */
dfs?: IDirectionFinding;
toString(): string; // Return combined position representation (e.g., "lat,lon,alt")
toCompressed?(): CompressedPosition; // Optional method to convert to compressed format
@@ -128,6 +148,7 @@ export interface PositionPayload {
| DataType.PositionNoTimestampWithMessaging
| DataType.PositionWithTimestampNoMessaging
| DataType.PositionWithTimestampWithMessaging;
doNotArchive?: boolean; // Optional flag to indicate frame should not be archived
timestamp?: ITimestamp;
position: IPosition;
messaging: boolean; // Whether APRS messaging is enabled
@@ -156,7 +177,8 @@ export interface CompressedPosition {
// Mic-E Payload (compressed in destination address)
export interface MicEPayload {
type: DataType.MicECurrent | DataType.MicEOld;
type: DataType.MicE | DataType.MicEOld;
doNotArchive?: boolean; // Optional flag to indicate frame should not be archived
position: IPosition;
messageType?: string; // Standard Mic-E message
isStandard?: boolean; // Whether messageType is a standard Mic-E message
@@ -170,6 +192,7 @@ export type MessageVariant = "message" | "bulletin";
export interface MessagePayload {
type: DataType.Message;
variant: "message";
doNotArchive?: boolean; // Optional flag to indicate frame should not be archived
addressee: string; // 9 character padded callsign
text: string; // Message text
messageNumber?: string; // Message ID for acknowledgment
@@ -181,6 +204,7 @@ export interface MessagePayload {
export interface BulletinPayload {
type: DataType.Message;
variant: "bulletin";
doNotArchive?: boolean; // Optional flag to indicate frame should not be archived
bulletinId: string; // Bulletin identifier (BLN#)
text: string;
group?: string; // Optional group bulletin
@@ -189,6 +213,7 @@ export interface BulletinPayload {
// Object Payload
export interface ObjectPayload {
type: DataType.Object;
doNotArchive?: boolean; // Optional flag to indicate frame should not be archived
name: string; // 9 character object name
timestamp: ITimestamp;
alive: boolean; // True if object is active, false if killed
@@ -200,6 +225,7 @@ export interface ObjectPayload {
// Item Payload
export interface ItemPayload {
type: DataType.Item;
doNotArchive?: boolean; // Optional flag to indicate frame should not be archived
name: string; // 3-9 character item name
alive: boolean; // True if item is active, false if killed
position: IPosition;
@@ -208,6 +234,7 @@ export interface ItemPayload {
// Status Payload
export interface StatusPayload {
type: DataType.Status;
doNotArchive?: boolean; // Optional flag to indicate frame should not be archived
timestamp?: ITimestamp;
text: string;
maidenhead?: string; // Optional Maidenhead grid locator
@@ -332,6 +359,7 @@ export interface DFReportPayload {
export interface BasePayload {
type: DataType;
doNotArchive?: boolean; // Optional flag to indicate frame should not be archived
}
// Union type for all decoded payload types