365 lines
9.5 KiB
TypeScript
365 lines
9.5 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 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
|
|
}
|