Initial release

This commit is contained in:
2026-03-11 17:24:57 +01:00
commit 5d537975e9
17 changed files with 6635 additions and 0 deletions

325
src/frame.types.ts Normal file
View File

@@ -0,0 +1,325 @@
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
}