326 lines
8.2 KiB
TypeScript
326 lines
8.2 KiB
TypeScript
import { PacketSegment, PacketStructure } from "./parser.types";
|
|
|
|
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?: PacketSegment[];
|
|
}
|
|
|
|
// 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
|
|
}
|
|
|
|
// Raw GPS Payload (NMEA sentences)
|
|
export interface RawGPSPayload {
|
|
type: 'raw-gps';
|
|
sentence: string; // Raw NMEA sentence
|
|
}
|
|
|
|
// 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';
|
|
header: string; // Source path of third-party packet
|
|
payload: string; // Nested APRS packet
|
|
}
|
|
|
|
// 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?: PacketStructure; // Routing and other frame-level sections
|
|
}
|