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 enum DataType { // 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 = "," } 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; /** * 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 distanceTo?(other: IPosition): number; // Optional method to calculate distance to another position } export interface IPowerHeightGain { power?: number; // Transmit power in watts height?: number; // Antenna height in meters gain?: number; // Antenna gain in dBi directivity?: number | "omni" | "unknown"; // Optional directivity pattern (numeric code or "omni") } export interface IDirectionFinding { bearing?: number; // Direction finding bearing in degrees strength?: number; // Relative signal strength (0-9) height?: number; // Antenna height in meters gain?: number; // Antenna gain in dBi quality?: number; // Signal quality or other metric (0-9) directivity?: number | "omni" | "unknown"; // Optional directivity pattern (numeric code or "omni") } 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: | DataType.PositionNoTimestampNoMessaging | DataType.PositionNoTimestampWithMessaging | DataType.PositionWithTimestampNoMessaging | DataType.PositionWithTimestampWithMessaging; 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: DataType.MicECurrent | DataType.MicEOld; position: IPosition; messageType?: string; // Standard Mic-E message isStandard?: boolean; // Whether messageType is a standard Mic-E message telemetry?: number[]; // Optional telemetry channels status?: string; } export type MessageVariant = "message" | "bulletin"; // Message Payload export interface MessagePayload { type: DataType.Message; variant: "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: DataType.Message; variant: "bulletin"; bulletinId: string; // Bulletin identifier (BLN#) text: string; group?: string; // Optional group bulletin } // Object Payload export interface ObjectPayload { type: DataType.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: DataType.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: DataType.Status; timestamp?: ITimestamp; text: string; maidenhead?: string; // Optional Maidenhead grid locator symbol?: { table: string; code: string; }; } // Query Payload export interface QueryPayload { type: DataType.Query; queryType: string; // e.g., 'APRSD', 'APRST', 'PING' target?: string; // Target callsign or area } export type TelemetryVariant = "data" | "parameters" | "unit" | "coefficients" | "bitsense"; // Telemetry Data Payload export interface TelemetryDataPayload { type: DataType.TelemetryData; variant: "data"; sequence: number; analog: number[]; // Up to 5 analog channels digital: number; // 8-bit digital value } // Telemetry Parameter Names export interface TelemetryParameterPayload { type: DataType.TelemetryData; variant: "parameters"; names: string[]; // Parameter names } // Telemetry Unit/Label export interface TelemetryUnitPayload { type: DataType.TelemetryData; variant: "unit"; units: string[]; // Units for each parameter } // Telemetry Coefficients export interface TelemetryCoefficientsPayload { type: DataType.TelemetryData; variant: "coefficients"; coefficients: { a: number[]; // a coefficients b: number[]; // b coefficients c: number[]; // c coefficients }; } // Telemetry Bit Sense/Project Name export interface TelemetryBitSensePayload { type: DataType.TelemetryData; variant: "bitsense"; sense: number; // 8-bit sense value projectName?: string; } // Weather Report Payload export interface WeatherPayload { type: DataType.WeatherReportNoPosition; 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: DataType.RawGPS; sentence: string; // Raw NMEA sentence position?: IPosition; // Optional parsed position if available } // Station Capabilities Payload export interface StationCapabilitiesPayload { type: DataType.StationCapabilities; capabilities: string[]; } // User-Defined Payload export interface UserDefinedPayload { type: DataType.UserDefined; userPacketType: string; data: string; } // Third-Party Traffic Payload export interface ThirdPartyPayload { type: DataType.ThirdParty; frame?: IFrame; // Optional nested frame if payload contains another APRS frame comment?: string; // Optional comment } // DF Report Payload export interface DFReportPayload { 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: DataType; } // 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 ); // Extended Frame with decoded payload export interface DecodedFrame extends IFrame { decoded?: Payload; structure?: Dissected; // Routing and other frame-level sections }