Files
aprs.ts/src/frame.types.ts

330 lines
8.0 KiB
TypeScript

import { Dissected, Segment } from "@hamradio/packet";
export interface IAddress {
call: string;
ssid: string;
isRepeated: boolean;
}
export interface IFrame {
source: IAddress;
destination: IAddress;
path: IAddress[];
payload: string;
}
// APRS Data Type Identifiers (first character of payload)
export const DataTypeIdentifier = {
// Position Reports
PositionNoTimestampNoMessaging: "!",
PositionNoTimestampWithMessaging: "=",
PositionWithTimestampNoMessaging: "/",
PositionWithTimestampWithMessaging: "@",
// Mic-E
MicECurrent: "`",
MicEOld: "'",
// Messages and Bulletins
Message: ":",
// Objects and Items
Object: ";",
Item: ")",
// Status
Status: ">",
// Query
Query: "?",
// Telemetry
TelemetryData: "T",
// Weather
WeatherReportNoPosition: "_",
// Raw GPS Data
RawGPS: "$",
// Station Capabilities
StationCapabilities: "<",
// User-Defined
UserDefined: "{",
// Third-Party Traffic
ThirdParty: "}",
// Invalid/Test Data
InvalidOrTest: ",",
} as const;
export type DataTypeIdentifier =
(typeof DataTypeIdentifier)[keyof typeof DataTypeIdentifier];
export interface ISymbol {
table: string; // Symbol table identifier
code: string; // Symbol code
toString(): string; // Return combined symbol representation (e.g., "tablecode")
}
// Position data common to multiple formats
export interface IPosition {
latitude: number; // Decimal degrees
longitude: number; // Decimal degrees
ambiguity?: number; // Position ambiguity (0-4)
altitude?: number; // Meters
speed?: number; // Speed in knots/kmh depending on source
course?: number; // Course in degrees
symbol?: ISymbol;
comment?: string;
toString(): string; // Return combined position representation (e.g., "lat,lon,alt")
toCompressed?(): CompressedPosition; // Optional method to convert to compressed format
distanceTo?(other: IPosition): number; // Optional method to calculate distance to another position
}
export interface ITimestamp {
day?: number; // Day of month (DHM format)
month?: number; // Month (MDHM format)
hours: number;
minutes: number;
seconds?: number;
format: "DHM" | "HMS" | "MDHM"; // Day-Hour-Minute, Hour-Minute-Second, Month-Day-Hour-Minute
zulu?: boolean; // Is UTC/Zulu time
toDate(): Date; // Convert to Date object respecting timezone
}
// Position Report Payload
export interface PositionPayload {
type: "position";
timestamp?: ITimestamp;
position: IPosition;
messaging: boolean; // Whether APRS messaging is enabled
micE?: {
messageType?: string;
isStandard?: boolean;
};
sections?: Segment[];
}
// Compressed Position Format
export interface CompressedPosition {
latitude: number;
longitude: number;
symbol: {
table: string;
code: string;
};
course?: number; // Degrees
speed?: number; // Knots
range?: number; // Miles
altitude?: number; // Feet
radioRange?: number; // Miles
compression: "old" | "current";
}
// Mic-E Payload (compressed in destination address)
export interface MicEPayload {
type: "mic-e";
position: IPosition;
course?: number;
speed?: number;
altitude?: number;
messageType?: string; // Standard Mic-E message
telemetry?: number[]; // Optional telemetry channels
status?: string;
}
// Message Payload
export interface MessagePayload {
type: "message";
addressee: string; // 9 character padded callsign
text: string; // Message text
messageNumber?: string; // Message ID for acknowledgment
ack?: string; // Acknowledgment of message ID
reject?: string; // Rejection of message ID
}
// Bulletin/Announcement (variant of message)
export interface BulletinPayload {
type: "bulletin";
bulletinId: string; // Bulletin identifier (BLN#)
text: string;
group?: string; // Optional group bulletin
}
// Object Payload
export interface ObjectPayload {
type: "object";
name: string; // 9 character object name
timestamp: ITimestamp;
alive: boolean; // True if object is active, false if killed
position: IPosition;
course?: number;
speed?: number;
}
// Item Payload
export interface ItemPayload {
type: "item";
name: string; // 3-9 character item name
alive: boolean; // True if item is active, false if killed
position: IPosition;
}
// Status Payload
export interface StatusPayload {
type: "status";
timestamp?: ITimestamp;
text: string;
maidenhead?: string; // Optional Maidenhead grid locator
symbol?: {
table: string;
code: string;
};
}
// Query Payload
export interface QueryPayload {
type: "query";
queryType: string; // e.g., 'APRSD', 'APRST', 'PING'
target?: string; // Target callsign or area
}
// Telemetry Data Payload
export interface TelemetryDataPayload {
type: "telemetry-data";
sequence: number;
analog: number[]; // Up to 5 analog channels
digital: number; // 8-bit digital value
}
// Telemetry Parameter Names
export interface TelemetryParameterPayload {
type: "telemetry-parameters";
names: string[]; // Parameter names
}
// Telemetry Unit/Label
export interface TelemetryUnitPayload {
type: "telemetry-units";
units: string[]; // Units for each parameter
}
// Telemetry Coefficients
export interface TelemetryCoefficientsPayload {
type: "telemetry-coefficients";
coefficients: {
a: number[]; // a coefficients
b: number[]; // b coefficients
c: number[]; // c coefficients
};
}
// Telemetry Bit Sense/Project Name
export interface TelemetryBitSensePayload {
type: "telemetry-bitsense";
sense: number; // 8-bit sense value
projectName?: string;
}
// Weather Report Payload
export interface WeatherPayload {
type: "weather";
timestamp?: ITimestamp;
position?: IPosition;
windDirection?: number; // Degrees
windSpeed?: number; // MPH
windGust?: number; // MPH
temperature?: number; // Fahrenheit
rainLastHour?: number; // Hundredths of inch
rainLast24Hours?: number; // Hundredths of inch
rainSinceMidnight?: number; // Hundredths of inch
humidity?: number; // Percent
pressure?: number; // Tenths of millibar
luminosity?: number; // Watts per square meter
snowfall?: number; // Inches
rawRain?: number; // Raw rain counter
software?: string; // Weather software type
weatherUnit?: string; // Weather station type
comment?: string; // Additional comment
}
// Raw GPS Payload (NMEA sentences)
export interface RawGPSPayload {
type: "raw-gps";
sentence: string; // Raw NMEA sentence
position?: IPosition; // Optional parsed position if available
}
// Station Capabilities Payload
export interface StationCapabilitiesPayload {
type: "capabilities";
capabilities: string[];
}
// User-Defined Payload
export interface UserDefinedPayload {
type: "user-defined";
userPacketType: string;
data: string;
}
// Third-Party Traffic Payload
export interface ThirdPartyPayload {
type: "third-party";
frame?: IFrame; // Optional nested frame if payload contains another APRS frame
comment?: string; // Optional comment
}
// DF Report Payload
export interface DFReportPayload {
type: "df-report";
timestamp?: ITimestamp;
position: IPosition;
course?: number;
bearing?: number; // Direction finding bearing
quality?: number; // Signal quality
strength?: number; // Signal strength
height?: number; // Antenna height
gain?: number; // Antenna gain
directivity?: string; // Antenna directivity pattern
}
export interface BasePayload {
type: string;
}
// Union type for all decoded payload types
export type Payload = BasePayload &
(
| PositionPayload
| MicEPayload
| MessagePayload
| BulletinPayload
| ObjectPayload
| ItemPayload
| StatusPayload
| QueryPayload
| TelemetryDataPayload
| TelemetryParameterPayload
| TelemetryUnitPayload
| TelemetryCoefficientsPayload
| TelemetryBitSensePayload
| WeatherPayload
| RawGPSPayload
| StationCapabilitiesPayload
| UserDefinedPayload
| ThirdPartyPayload
| DFReportPayload
);
// Extended Frame with decoded payload
export interface DecodedFrame extends IFrame {
decoded?: Payload;
structure?: Dissected; // Routing and other frame-level sections
}