@airframes/acars-decoder 1.6.9 → 1.6.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +644 -451
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +644 -451
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -97,6 +97,192 @@ var DecoderPlugin = class {
|
|
|
97
97
|
}
|
|
98
98
|
};
|
|
99
99
|
|
|
100
|
+
// lib/utils/coordinate_utils.ts
|
|
101
|
+
var CoordinateUtils = class {
|
|
102
|
+
/**
|
|
103
|
+
* Decode a string of coordinates into an object with latitude and longitude in millidegrees
|
|
104
|
+
* @param stringCoords - The string of coordinates to decode
|
|
105
|
+
*
|
|
106
|
+
* @returns An object with latitude and longitude properties
|
|
107
|
+
*/
|
|
108
|
+
static decodeStringCoordinates(stringCoords) {
|
|
109
|
+
var results = {};
|
|
110
|
+
const firstChar = stringCoords.substring(0, 1);
|
|
111
|
+
let middleChar = stringCoords.substring(6, 7);
|
|
112
|
+
let longitudeChars = stringCoords.substring(7, 13);
|
|
113
|
+
if (middleChar == " ") {
|
|
114
|
+
middleChar = stringCoords.substring(7, 8);
|
|
115
|
+
longitudeChars = stringCoords.substring(8, 14);
|
|
116
|
+
}
|
|
117
|
+
if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
|
|
118
|
+
results.latitude = Number(stringCoords.substring(1, 6)) / 1e3 * (firstChar === "S" ? -1 : 1);
|
|
119
|
+
results.longitude = Number(longitudeChars) / 1e3 * (middleChar === "W" ? -1 : 1);
|
|
120
|
+
} else {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
return results;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Decode a string of coordinates into an object with latitude and longitude in degrees and decimal minutes
|
|
127
|
+
* @param stringCoords - The string of coordinates to decode
|
|
128
|
+
*
|
|
129
|
+
* @returns An object with latitude and longitude properties
|
|
130
|
+
*/
|
|
131
|
+
static decodeStringCoordinatesDecimalMinutes(stringCoords) {
|
|
132
|
+
var results = {};
|
|
133
|
+
const firstChar = stringCoords.substring(0, 1);
|
|
134
|
+
let middleChar = stringCoords.substring(6, 7);
|
|
135
|
+
let longitudeChars = stringCoords.substring(7, 13);
|
|
136
|
+
if (middleChar == " ") {
|
|
137
|
+
middleChar = stringCoords.substring(7, 8);
|
|
138
|
+
longitudeChars = stringCoords.substring(8, 14);
|
|
139
|
+
}
|
|
140
|
+
const latDeg = Math.trunc(Number(stringCoords.substring(1, 6)) / 1e3);
|
|
141
|
+
const latMin = Number(stringCoords.substring(1, 6)) % 1e3 / 10;
|
|
142
|
+
const lonDeg = Math.trunc(Number(longitudeChars) / 1e3);
|
|
143
|
+
const lonMin = Number(longitudeChars) % 1e3 / 10;
|
|
144
|
+
if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
|
|
145
|
+
results.latitude = (latDeg + latMin / 60) * (firstChar === "S" ? -1 : 1);
|
|
146
|
+
results.longitude = (lonDeg + lonMin / 60) * (middleChar === "W" ? -1 : 1);
|
|
147
|
+
} else {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
return results;
|
|
151
|
+
}
|
|
152
|
+
static coordinateString(coords) {
|
|
153
|
+
const latDir = coords.latitude > 0 ? "N" : "S";
|
|
154
|
+
const lonDir = coords.longitude > 0 ? "E" : "W";
|
|
155
|
+
return `${Math.abs(coords.latitude).toFixed(3)} ${latDir}, ${Math.abs(coords.longitude).toFixed(3)} ${lonDir}`;
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
// lib/utils/result_formatter.ts
|
|
160
|
+
var ResultFormatter = class {
|
|
161
|
+
static position(decodeResult, value) {
|
|
162
|
+
decodeResult.raw.position = value;
|
|
163
|
+
decodeResult.formatted.items.push({
|
|
164
|
+
type: "aircraft_position",
|
|
165
|
+
code: "POS",
|
|
166
|
+
label: "Aircraft Position",
|
|
167
|
+
value: CoordinateUtils.coordinateString(value)
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
static altitude(decodeResult, value) {
|
|
171
|
+
decodeResult.raw.altitude = value;
|
|
172
|
+
decodeResult.formatted.items.push({
|
|
173
|
+
type: "altitude",
|
|
174
|
+
code: "ALT",
|
|
175
|
+
label: "Altitude",
|
|
176
|
+
value: `${decodeResult.raw.altitude} feet`
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
static flightNumber(decodeResult, value) {
|
|
180
|
+
decodeResult.raw.flight_number = value;
|
|
181
|
+
}
|
|
182
|
+
static departureAirport(decodeResult, value) {
|
|
183
|
+
decodeResult.raw.departure_icao = value;
|
|
184
|
+
decodeResult.formatted.items.push({
|
|
185
|
+
type: "origin",
|
|
186
|
+
code: "ORG",
|
|
187
|
+
label: "Origin",
|
|
188
|
+
value: decodeResult.raw.departure_icao
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
static departureRunway(decodeResult, value) {
|
|
192
|
+
decodeResult.raw.departure_runway = value;
|
|
193
|
+
decodeResult.formatted.items.push({
|
|
194
|
+
type: "runway",
|
|
195
|
+
code: "DEPRWY",
|
|
196
|
+
label: "Departure Runway",
|
|
197
|
+
value: decodeResult.raw.departure_runway
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
static arrivalAirport(decodeResult, value) {
|
|
201
|
+
decodeResult.raw.arrival_icao = value;
|
|
202
|
+
decodeResult.formatted.items.push({
|
|
203
|
+
type: "destination",
|
|
204
|
+
code: "DST",
|
|
205
|
+
label: "Destination",
|
|
206
|
+
value: decodeResult.raw.arrival_icao
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
static eta(decodeResult, value) {
|
|
210
|
+
decodeResult.raw.eta_time = value;
|
|
211
|
+
decodeResult.formatted.items.push({
|
|
212
|
+
type: "eta",
|
|
213
|
+
code: "ETA",
|
|
214
|
+
label: "Estimated Time of Arrival",
|
|
215
|
+
value: value.substring(0, 2) + ":" + value.substring(2, 4) + ":" + value.substring(4, 6)
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
static arrivalRunway(decodeResult, value) {
|
|
219
|
+
decodeResult.raw.arrival_runway = value;
|
|
220
|
+
decodeResult.formatted.items.push({
|
|
221
|
+
type: "runway",
|
|
222
|
+
code: "ARWY",
|
|
223
|
+
label: "Arrival Runway",
|
|
224
|
+
value: decodeResult.raw.arrival_runway
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
static currentFuel(decodeResult, value) {
|
|
228
|
+
decodeResult.raw.fuel_on_board = value;
|
|
229
|
+
decodeResult.formatted.items.push({
|
|
230
|
+
type: "fuel_on_board",
|
|
231
|
+
code: "FOB",
|
|
232
|
+
label: "Fuel On Board",
|
|
233
|
+
value: decodeResult.raw.fuel_on_board.toString()
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
static remainingFuel(decodeResult, value) {
|
|
237
|
+
decodeResult.raw.fuel_remaining = value;
|
|
238
|
+
decodeResult.formatted.items.push({
|
|
239
|
+
type: "fuel_remaining",
|
|
240
|
+
code: "FUEL",
|
|
241
|
+
label: "Fuel Remaining",
|
|
242
|
+
value: decodeResult.raw.fuel_remaining.toString()
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
static checksum(decodeResult, value) {
|
|
246
|
+
decodeResult.raw.checksum = Number("0x" + value);
|
|
247
|
+
decodeResult.formatted.items.push({
|
|
248
|
+
type: "message_checksum",
|
|
249
|
+
code: "CHECKSUM",
|
|
250
|
+
label: "Message Checksum",
|
|
251
|
+
value: "0x" + ("0000" + decodeResult.raw.checksum.toString(16)).slice(-4)
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
static groundspeed(decodeResult, value) {
|
|
255
|
+
decodeResult.raw.groundspeed = value;
|
|
256
|
+
decodeResult.formatted.items.push({
|
|
257
|
+
type: "aircraft_groundspeed",
|
|
258
|
+
code: "GSPD",
|
|
259
|
+
label: "Aircraft Groundspeed",
|
|
260
|
+
value: `${decodeResult.raw.groundspeed}`
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
static temperature(decodeResult, value) {
|
|
264
|
+
decodeResult.raw.outside_air_temperature = Number(value.substring(1)) * (value.charAt(0) === "M" ? -1 : 1);
|
|
265
|
+
decodeResult.formatted.items.push({
|
|
266
|
+
type: "outside_air_temperature",
|
|
267
|
+
code: "OATEMP",
|
|
268
|
+
label: "Outside Air Temperature (C)",
|
|
269
|
+
value: `${decodeResult.raw.outside_air_temperature}`
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
static heading(decodeResult, value) {
|
|
273
|
+
decodeResult.raw.heading = value;
|
|
274
|
+
decodeResult.formatted.items.push({
|
|
275
|
+
type: "heading",
|
|
276
|
+
code: "HDG",
|
|
277
|
+
label: "Heading",
|
|
278
|
+
value: `${decodeResult.raw.heading}`
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
static unknown(decodeResult, value) {
|
|
282
|
+
decodeResult.remaining.text += "," + value;
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
|
|
100
286
|
// lib/plugins/Label_5Z.ts
|
|
101
287
|
var Label_5Z = class extends DecoderPlugin {
|
|
102
288
|
name = "label-5z";
|
|
@@ -127,141 +313,327 @@ var Label_5Z = class extends DecoderPlugin {
|
|
|
127
313
|
};
|
|
128
314
|
qualifiers() {
|
|
129
315
|
return {
|
|
130
|
-
labels: ["5Z"]
|
|
316
|
+
labels: ["5Z"]
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
decode(message, options = {}) {
|
|
320
|
+
const decodeResult = this.defaultResult();
|
|
321
|
+
decodeResult.decoder.name = this.name;
|
|
322
|
+
decodeResult.formatted.description = "Airline Designated Downlink";
|
|
323
|
+
const uaRegex = /^\/(?<type>\w+) (?<remainder>.+)/;
|
|
324
|
+
let results = message.text.match(uaRegex);
|
|
325
|
+
if (results && results.length >= 2) {
|
|
326
|
+
const type = results.groups.type.split("/")[0];
|
|
327
|
+
const { remainder } = results.groups;
|
|
328
|
+
const typeDescription = this.descriptions[type] ? this.descriptions[type] : "Unknown";
|
|
329
|
+
decodeResult.raw.airline = "United Airlines";
|
|
330
|
+
decodeResult.formatted.items.push({
|
|
331
|
+
type: "airline",
|
|
332
|
+
label: "Airline",
|
|
333
|
+
value: "United Airlines"
|
|
334
|
+
});
|
|
335
|
+
decodeResult.raw.message_type = type;
|
|
336
|
+
decodeResult.formatted.items.push({
|
|
337
|
+
type: "message_type",
|
|
338
|
+
label: "Message Type",
|
|
339
|
+
value: `${typeDescription} (${type})`
|
|
340
|
+
});
|
|
341
|
+
if (type === "B3") {
|
|
342
|
+
const rdcRegex = /^(?<from>\w\w\w)(?<to>\w\w\w) (?<unknown1>\d\d) R(?<runway>.+) G(?<unknown2>.+)$/;
|
|
343
|
+
results = remainder.match(rdcRegex);
|
|
344
|
+
if (results) {
|
|
345
|
+
ResultFormatter.departureAirport(decodeResult, results.groups.from);
|
|
346
|
+
ResultFormatter.arrivalAirport(decodeResult, results.groups.to);
|
|
347
|
+
ResultFormatter.arrivalRunway(decodeResult, results.groups.runway);
|
|
348
|
+
} else {
|
|
349
|
+
if (options.debug) {
|
|
350
|
+
console.log(`Decoder: Unkown 5Z RDC format: ${remainder}`);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
} else {
|
|
354
|
+
decodeResult.remaining.text = remainder;
|
|
355
|
+
}
|
|
356
|
+
decodeResult.decoded = true;
|
|
357
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
358
|
+
} else {
|
|
359
|
+
if (options.debug) {
|
|
360
|
+
console.log(`Decoder: Unknown 5Z message: ${message.text}`);
|
|
361
|
+
}
|
|
362
|
+
decodeResult.remaining.text = message.text;
|
|
363
|
+
decodeResult.decoded = false;
|
|
364
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
365
|
+
}
|
|
366
|
+
return decodeResult;
|
|
367
|
+
}
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
// lib/plugins/Label_10_LDR.ts
|
|
371
|
+
var Label_10_LDR = class extends DecoderPlugin {
|
|
372
|
+
// eslint-disable-line camelcase
|
|
373
|
+
name = "label-10-ldr";
|
|
374
|
+
qualifiers() {
|
|
375
|
+
return {
|
|
376
|
+
labels: ["10"],
|
|
377
|
+
preambles: ["LDR"]
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
decode(message, options = {}) {
|
|
381
|
+
const decodeResult = this.defaultResult();
|
|
382
|
+
decodeResult.decoder.name = this.name;
|
|
383
|
+
decodeResult.formatted.description = "Position Report";
|
|
384
|
+
decodeResult.message = message;
|
|
385
|
+
const parts = message.text.split(",");
|
|
386
|
+
if (parts.length < 17) {
|
|
387
|
+
if (options?.debug) {
|
|
388
|
+
console.log(`Decoder: Unknown 10 message: ${message.text}`);
|
|
389
|
+
}
|
|
390
|
+
decodeResult.remaining.text = message.text;
|
|
391
|
+
decodeResult.decoded = false;
|
|
392
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
393
|
+
return decodeResult;
|
|
394
|
+
}
|
|
395
|
+
const lat = parts[5];
|
|
396
|
+
const lon = parts[6];
|
|
397
|
+
const position = {
|
|
398
|
+
latitude: (lat[0] === "N" ? 1 : -1) * Number(lat.substring(1).trim()),
|
|
399
|
+
longitude: (lon[0] === "E" ? 1 : -1) * Number(lon.substring(1).trim())
|
|
400
|
+
};
|
|
401
|
+
ResultFormatter.position(decodeResult, position);
|
|
402
|
+
ResultFormatter.altitude(decodeResult, Number(parts[7]));
|
|
403
|
+
ResultFormatter.departureAirport(decodeResult, parts[9]);
|
|
404
|
+
ResultFormatter.arrivalAirport(decodeResult, parts[10]);
|
|
405
|
+
ResultFormatter.arrivalRunway(decodeResult, parts[12].split("/")[0]);
|
|
406
|
+
decodeResult.remaining.text = [...parts.slice(0, 5), parts[11], ...parts.slice(13)].join(",");
|
|
407
|
+
decodeResult.decoded = true;
|
|
408
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
409
|
+
return decodeResult;
|
|
410
|
+
}
|
|
411
|
+
};
|
|
412
|
+
|
|
413
|
+
// lib/plugins/Label_10_POS.ts
|
|
414
|
+
var Label_10_POS = class extends DecoderPlugin {
|
|
415
|
+
// eslint-disable-line camelcase
|
|
416
|
+
name = "label-10-pos";
|
|
417
|
+
qualifiers() {
|
|
418
|
+
return {
|
|
419
|
+
labels: ["10"],
|
|
420
|
+
preambles: ["POS"]
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
decode(message, options = {}) {
|
|
424
|
+
const decodeResult = this.defaultResult();
|
|
425
|
+
decodeResult.decoder.name = this.name;
|
|
426
|
+
decodeResult.formatted.description = "Position Report";
|
|
427
|
+
decodeResult.message = message;
|
|
428
|
+
const parts = message.text.split(",");
|
|
429
|
+
if (parts.length !== 12) {
|
|
430
|
+
if (options?.debug) {
|
|
431
|
+
console.log(`Decoder: Unknown 10 message: ${message.text}`);
|
|
432
|
+
}
|
|
433
|
+
decodeResult.remaining.text = message.text;
|
|
434
|
+
decodeResult.decoded = false;
|
|
435
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
436
|
+
return decodeResult;
|
|
437
|
+
}
|
|
438
|
+
const lat = parts[1].trim();
|
|
439
|
+
const lon = parts[2].trim();
|
|
440
|
+
const position = {
|
|
441
|
+
latitude: (lat[0] === "N" ? 1 : -1) * Number(lat.substring(1).trim()) / 100,
|
|
442
|
+
longitude: (lon[0] === "E" ? 1 : -1) * Number(lon.substring(1).trim()) / 100
|
|
443
|
+
};
|
|
444
|
+
ResultFormatter.position(decodeResult, position);
|
|
445
|
+
ResultFormatter.altitude(decodeResult, Number(parts[7]));
|
|
446
|
+
decodeResult.remaining.text = [parts[0], ...parts.slice(3, 7), ...parts.slice(8)].join(",");
|
|
447
|
+
decodeResult.decoded = true;
|
|
448
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
449
|
+
return decodeResult;
|
|
450
|
+
}
|
|
451
|
+
};
|
|
452
|
+
|
|
453
|
+
// lib/DateTimeUtils.ts
|
|
454
|
+
var DateTimeUtils = class {
|
|
455
|
+
// Expects a four digit UTC time string (HHMM)
|
|
456
|
+
static UTCToString(UTCString) {
|
|
457
|
+
let utcDate = /* @__PURE__ */ new Date();
|
|
458
|
+
utcDate.setUTCHours(+UTCString.substr(0, 2), +UTCString.substr(2, 2), 0);
|
|
459
|
+
return utcDate.toTimeString();
|
|
460
|
+
}
|
|
461
|
+
// Expects a six digit date string and a four digit UTC time string
|
|
462
|
+
// (DDMMYY) (HHMM)
|
|
463
|
+
static UTCDateTimeToString(dateString, timeString) {
|
|
464
|
+
let utcDate = /* @__PURE__ */ new Date();
|
|
465
|
+
utcDate.setUTCDate(+dateString.substr(0, 2));
|
|
466
|
+
utcDate.setUTCMonth(+dateString.substr(2, 2));
|
|
467
|
+
if (dateString.length === 6) {
|
|
468
|
+
utcDate.setUTCFullYear(2e3 + +dateString.substr(4, 2));
|
|
469
|
+
}
|
|
470
|
+
if (timeString.length === 6) {
|
|
471
|
+
utcDate.setUTCHours(+timeString.substr(0, 2), +timeString.substr(2, 2), +timeString.substr(4, 2));
|
|
472
|
+
} else {
|
|
473
|
+
utcDate.setUTCHours(+timeString.substr(0, 2), +timeString.substr(2, 2), 0);
|
|
474
|
+
}
|
|
475
|
+
return utcDate.toUTCString();
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
*
|
|
479
|
+
* @param time HHMMSS
|
|
480
|
+
* @returns seconds since midnight
|
|
481
|
+
*/
|
|
482
|
+
static convertHHMMSSToTod(time) {
|
|
483
|
+
const h = Number(time.substring(0, 2));
|
|
484
|
+
const m = Number(time.substring(2, 4));
|
|
485
|
+
const s = Number(time.substring(4, 6));
|
|
486
|
+
const tod = h * 3600 + m * 60 + s;
|
|
487
|
+
return tod;
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
*
|
|
491
|
+
* @param time HHMMSS
|
|
492
|
+
* @param date MMDDYY or MMDDYYYY
|
|
493
|
+
* @returns seconds since epoch
|
|
494
|
+
*/
|
|
495
|
+
static convertDateTimeToEpoch(time, date) {
|
|
496
|
+
if (date.length === 6) {
|
|
497
|
+
date = date.substring(0, 4) + `20${date.substring(4, 6)}`;
|
|
498
|
+
}
|
|
499
|
+
const timestamp = `${date.substring(4, 8)}-${date.substring(0, 2)}-${date.substring(2, 4)}T${time.substring(0, 2)}:${time.substring(2, 4)}:${time.substring(4, 6)}.000Z`;
|
|
500
|
+
const millis = Date.parse(timestamp);
|
|
501
|
+
return millis / 1e3;
|
|
502
|
+
}
|
|
503
|
+
};
|
|
504
|
+
|
|
505
|
+
// lib/utils/route_utils.ts
|
|
506
|
+
var RouteUtils = class _RouteUtils {
|
|
507
|
+
static routeToString(route) {
|
|
508
|
+
let str = "";
|
|
509
|
+
if (route.name) {
|
|
510
|
+
str += route.name;
|
|
511
|
+
}
|
|
512
|
+
if (route.runway) {
|
|
513
|
+
str += `(${route.runway})`;
|
|
514
|
+
}
|
|
515
|
+
if (str.length !== 0 && route.waypoints && route.waypoints.length === 1) {
|
|
516
|
+
str += " starting at ";
|
|
517
|
+
} else if (str.length !== 0 && route.waypoints) {
|
|
518
|
+
str += ": ";
|
|
519
|
+
}
|
|
520
|
+
if (route.waypoints) {
|
|
521
|
+
str += _RouteUtils.waypointsToString(route.waypoints);
|
|
522
|
+
}
|
|
523
|
+
return str;
|
|
524
|
+
}
|
|
525
|
+
static waypointToString(waypoint) {
|
|
526
|
+
let s = waypoint.name;
|
|
527
|
+
if (waypoint.latitude && waypoint.longitude) {
|
|
528
|
+
s += `(${CoordinateUtils.coordinateString({ latitude: waypoint.latitude, longitude: waypoint.longitude })})`;
|
|
529
|
+
}
|
|
530
|
+
if (waypoint.offset) {
|
|
531
|
+
s += `[${waypoint.offset.bearing}\xB0 ${waypoint.offset.distance}nm]`;
|
|
532
|
+
}
|
|
533
|
+
if (waypoint.time && waypoint.timeFormat) {
|
|
534
|
+
s += `@${_RouteUtils.timestampToString(waypoint.time, waypoint.timeFormat)}`;
|
|
535
|
+
}
|
|
536
|
+
return s;
|
|
537
|
+
}
|
|
538
|
+
static getWaypoint(leg) {
|
|
539
|
+
const regex = leg.match(/^([A-Z]+)(\d{3})-(\d{4})$/);
|
|
540
|
+
if (regex?.length == 4) {
|
|
541
|
+
return { name: regex[1], offset: { bearing: parseInt(regex[2]), distance: parseInt(regex[3]) / 10 } };
|
|
542
|
+
}
|
|
543
|
+
const waypoint = leg.split(",");
|
|
544
|
+
if (waypoint.length == 2) {
|
|
545
|
+
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(waypoint[1]);
|
|
546
|
+
if (position) {
|
|
547
|
+
return { name: waypoint[0], latitude: position.latitude, longitude: position.longitude };
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
if (leg.length == 13 || leg.length == 14) {
|
|
551
|
+
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(leg);
|
|
552
|
+
const name = waypoint.length == 2 ? waypoint[0] : "";
|
|
553
|
+
if (position) {
|
|
554
|
+
return { name, latitude: position.latitude, longitude: position.longitude };
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
return { name: leg };
|
|
558
|
+
}
|
|
559
|
+
// move out if we want public
|
|
560
|
+
static timestampToString(time, format) {
|
|
561
|
+
const date = new Date(time * 1e3);
|
|
562
|
+
if (format == "tod") {
|
|
563
|
+
return date.toISOString().slice(11, 19);
|
|
564
|
+
}
|
|
565
|
+
return date.toISOString().slice(0, -5) + "Z";
|
|
566
|
+
}
|
|
567
|
+
static waypointsToString(waypoints) {
|
|
568
|
+
let str = waypoints.map((x) => _RouteUtils.waypointToString(x)).join(" > ").replaceAll("> >", ">>");
|
|
569
|
+
if (str.startsWith(" > ")) {
|
|
570
|
+
str = ">>" + str.slice(2);
|
|
571
|
+
}
|
|
572
|
+
return str;
|
|
573
|
+
}
|
|
574
|
+
};
|
|
575
|
+
|
|
576
|
+
// lib/plugins/Label_10_Slash.ts
|
|
577
|
+
var Label_10_Slash = class extends DecoderPlugin {
|
|
578
|
+
// eslint-disable-line camelcase
|
|
579
|
+
name = "label-10-slash";
|
|
580
|
+
qualifiers() {
|
|
581
|
+
return {
|
|
582
|
+
labels: ["10"],
|
|
583
|
+
preambles: ["/"]
|
|
131
584
|
};
|
|
132
585
|
}
|
|
133
586
|
decode(message, options = {}) {
|
|
134
587
|
const decodeResult = this.defaultResult();
|
|
135
588
|
decodeResult.decoder.name = this.name;
|
|
136
|
-
decodeResult.formatted.description = "
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
if (
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const typeDescription = this.descriptions[type] ? this.descriptions[type] : "Unknown";
|
|
143
|
-
decodeResult.raw.airline = "United Airlines";
|
|
144
|
-
decodeResult.formatted.items.push({
|
|
145
|
-
type: "airline",
|
|
146
|
-
label: "Airline",
|
|
147
|
-
value: "United Airlines"
|
|
148
|
-
});
|
|
149
|
-
decodeResult.raw.message_type = type;
|
|
150
|
-
decodeResult.formatted.items.push({
|
|
151
|
-
type: "message_type",
|
|
152
|
-
label: "Message Type",
|
|
153
|
-
value: `${typeDescription} (${type})`
|
|
154
|
-
});
|
|
155
|
-
if (type === "B3") {
|
|
156
|
-
const rdcRegex = /^(?<from>\w\w\w)(?<to>\w\w\w) (?<unknown1>\d\d) R(?<runway>.+) G(?<unknown2>.+)$/;
|
|
157
|
-
results = remainder.match(rdcRegex);
|
|
158
|
-
if (results) {
|
|
159
|
-
decodeResult.raw.origin = results.groups.from;
|
|
160
|
-
decodeResult.formatted.items.push({
|
|
161
|
-
type: "origin",
|
|
162
|
-
label: "Origin",
|
|
163
|
-
value: `${results.groups.from}`
|
|
164
|
-
});
|
|
165
|
-
decodeResult.raw.destination = results.groups.to;
|
|
166
|
-
decodeResult.formatted.items.push({
|
|
167
|
-
type: "destination",
|
|
168
|
-
label: "Destination",
|
|
169
|
-
value: `${results.groups.to}`
|
|
170
|
-
});
|
|
171
|
-
decodeResult.formatted.items.push({
|
|
172
|
-
type: "unknown1",
|
|
173
|
-
label: "Unknown Field 1",
|
|
174
|
-
value: `${results.groups.unknown1}`
|
|
175
|
-
});
|
|
176
|
-
decodeResult.raw.runway = results.groups.runway;
|
|
177
|
-
decodeResult.formatted.items.push({
|
|
178
|
-
type: "runway",
|
|
179
|
-
label: "Runway",
|
|
180
|
-
value: `${results.groups.runway}`
|
|
181
|
-
});
|
|
182
|
-
decodeResult.formatted.items.push({
|
|
183
|
-
type: "unknown2",
|
|
184
|
-
label: "Unknown Field 2",
|
|
185
|
-
value: `${results.groups.unknown2}`
|
|
186
|
-
});
|
|
187
|
-
} else {
|
|
188
|
-
if (options.debug) {
|
|
189
|
-
console.log(`Decoder: Unkown 5Z RDC format: ${remainder}`);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
} else {
|
|
193
|
-
decodeResult.remaining.text = remainder;
|
|
194
|
-
}
|
|
195
|
-
decodeResult.decoded = true;
|
|
196
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
197
|
-
} else {
|
|
198
|
-
if (options.debug) {
|
|
199
|
-
console.log(`Decoder: Unknown 5Z message: ${message.text}`);
|
|
589
|
+
decodeResult.formatted.description = "Position Report";
|
|
590
|
+
decodeResult.message = message;
|
|
591
|
+
const parts = message.text.split("/");
|
|
592
|
+
if (parts.length < 17) {
|
|
593
|
+
if (options?.debug) {
|
|
594
|
+
console.log(`Decoder: Unknown 10 message: ${message.text}`);
|
|
200
595
|
}
|
|
201
596
|
decodeResult.remaining.text = message.text;
|
|
202
597
|
decodeResult.decoded = false;
|
|
203
598
|
decodeResult.decoder.decodeLevel = "none";
|
|
599
|
+
return decodeResult;
|
|
204
600
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
* @param stringCoords - The string of coordinates to decode
|
|
237
|
-
*
|
|
238
|
-
* @returns An object with latitude and longitude properties
|
|
239
|
-
*/
|
|
240
|
-
static decodeStringCoordinatesDecimalMinutes(stringCoords) {
|
|
241
|
-
var results = {};
|
|
242
|
-
const firstChar = stringCoords.substring(0, 1);
|
|
243
|
-
let middleChar = stringCoords.substring(6, 7);
|
|
244
|
-
let longitudeChars = stringCoords.substring(7, 13);
|
|
245
|
-
if (middleChar == " ") {
|
|
246
|
-
middleChar = stringCoords.substring(7, 8);
|
|
247
|
-
longitudeChars = stringCoords.substring(8, 14);
|
|
248
|
-
}
|
|
249
|
-
const latDeg = Math.trunc(Number(stringCoords.substring(1, 6)) / 1e3);
|
|
250
|
-
const latMin = Number(stringCoords.substring(1, 6)) % 1e3 / 10;
|
|
251
|
-
const lonDeg = Math.trunc(Number(longitudeChars) / 1e3);
|
|
252
|
-
const lonMin = Number(longitudeChars) % 1e3 / 10;
|
|
253
|
-
if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
|
|
254
|
-
results.latitude = (latDeg + latMin / 60) * (firstChar === "S" ? -1 : 1);
|
|
255
|
-
results.longitude = (lonDeg + lonMin / 60) * (middleChar === "W" ? -1 : 1);
|
|
256
|
-
} else {
|
|
257
|
-
return;
|
|
601
|
+
const lat = parts[1];
|
|
602
|
+
const lon = parts[2];
|
|
603
|
+
const position = {
|
|
604
|
+
latitude: (lat[0] === "N" ? 1 : -1) * Number(lat.substring(1)),
|
|
605
|
+
longitude: (lon[0] === "E" ? 1 : -1) * Number(lon.substring(1))
|
|
606
|
+
};
|
|
607
|
+
ResultFormatter.position(decodeResult, position);
|
|
608
|
+
ResultFormatter.heading(decodeResult, Number(parts[5]));
|
|
609
|
+
ResultFormatter.altitude(decodeResult, 100 * Number(parts[6]));
|
|
610
|
+
ResultFormatter.arrivalAirport(decodeResult, parts[7]);
|
|
611
|
+
ResultFormatter.eta(decodeResult, parts[8] + "00");
|
|
612
|
+
const waypoints = [{
|
|
613
|
+
name: parts[11]
|
|
614
|
+
}, {
|
|
615
|
+
name: parts[12],
|
|
616
|
+
time: DateTimeUtils.convertHHMMSSToTod(parts[13] + "00"),
|
|
617
|
+
timeFormat: "tod"
|
|
618
|
+
}, {
|
|
619
|
+
name: parts[14],
|
|
620
|
+
time: DateTimeUtils.convertHHMMSSToTod(parts[15] + "00"),
|
|
621
|
+
timeFormat: "tod"
|
|
622
|
+
}];
|
|
623
|
+
decodeResult.raw.route = { waypoints };
|
|
624
|
+
decodeResult.formatted.items.push({
|
|
625
|
+
type: "aircraft_route",
|
|
626
|
+
code: "ROUTE",
|
|
627
|
+
label: "Aircraft Route",
|
|
628
|
+
value: RouteUtils.routeToString(decodeResult.raw.route)
|
|
629
|
+
});
|
|
630
|
+
if (parts[16]) {
|
|
631
|
+
ResultFormatter.departureAirport(decodeResult, parts[16]);
|
|
258
632
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
const lonDir = coords.longitude > 0 ? "E" : "W";
|
|
264
|
-
return `${Math.abs(coords.latitude).toFixed(3)} ${latDir}, ${Math.abs(coords.longitude).toFixed(3)} ${lonDir}`;
|
|
633
|
+
decodeResult.remaining.text = [parts[3], parts[4], ...parts.slice(9, 11), ...parts.slice(17)].join("/");
|
|
634
|
+
decodeResult.decoded = true;
|
|
635
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
636
|
+
return decodeResult;
|
|
265
637
|
}
|
|
266
638
|
};
|
|
267
639
|
|
|
@@ -290,19 +662,14 @@ var Label_12_N_Space = class extends DecoderPlugin {
|
|
|
290
662
|
latitude: Number(results.groups.lat_coord) * (results.groups.lat == "N" ? 1 : -1),
|
|
291
663
|
longitude: Number(results.groups.long_coord) * (results.groups.long == "E" ? 1 : -1)
|
|
292
664
|
};
|
|
293
|
-
|
|
665
|
+
const altitude = results.groups.alt == "GRD" || results.groups.alt == "***" ? 0 : Number(results.groups.alt);
|
|
294
666
|
decodeResult.formatted.items.push({
|
|
295
667
|
type: "aircraft_position",
|
|
296
668
|
code: "POS",
|
|
297
669
|
label: "Aircraft Position",
|
|
298
670
|
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
299
671
|
});
|
|
300
|
-
|
|
301
|
-
type: "flight_level",
|
|
302
|
-
code: "FL",
|
|
303
|
-
label: "Flight Level",
|
|
304
|
-
value: decodeResult.raw.flight_level
|
|
305
|
-
});
|
|
672
|
+
ResultFormatter.altitude(decodeResult, altitude);
|
|
306
673
|
decodeResult.remaining.text = `,${results.groups.unkwn1} ,${results.groups.unkwn2}, ${results.groups.unkwn3}`;
|
|
307
674
|
decodeResult.decoded = true;
|
|
308
675
|
decodeResult.decoder.decodeLevel = "partial";
|
|
@@ -364,39 +731,35 @@ var Label_15_FST = class extends DecoderPlugin {
|
|
|
364
731
|
decodeResult.decoder.name = this.name;
|
|
365
732
|
decodeResult.formatted.description = "Position Report";
|
|
366
733
|
decodeResult.message = message;
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
734
|
+
const parts = message.text.split(" ");
|
|
735
|
+
const header = parts[0];
|
|
736
|
+
decodeResult.raw.departure_icao = header.substring(5, 9);
|
|
737
|
+
decodeResult.raw.arrival_icao = header.substring(9, 13);
|
|
738
|
+
const stringCoords = header.substring(13);
|
|
370
739
|
const firstChar = stringCoords.substring(0, 1);
|
|
371
740
|
const middleChar = stringCoords.substring(7, 8);
|
|
372
741
|
decodeResult.raw.position = {};
|
|
373
742
|
if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
|
|
374
743
|
decodeResult.raw.position.latitude = Number(stringCoords.substring(1, 7)) / 1e4 * (firstChar === "S" ? -1 : 1);
|
|
375
|
-
decodeResult.raw.position.longitude = Number(stringCoords.substring(8,
|
|
744
|
+
decodeResult.raw.position.longitude = Number(stringCoords.substring(8, 15)) / 1e4 * (middleChar === "W" ? -1 : 1);
|
|
745
|
+
decodeResult.raw.altitude = Number(stringCoords.substring(15)) * 100;
|
|
376
746
|
} else {
|
|
377
747
|
decodeResult.decoded = false;
|
|
378
748
|
decodeResult.decoder.decodeLevel = "none";
|
|
379
749
|
return decodeResult;
|
|
380
750
|
}
|
|
381
751
|
decodeResult.formatted.items.push({
|
|
382
|
-
type: "
|
|
383
|
-
|
|
752
|
+
type: "aircraft_position",
|
|
753
|
+
code: "POS",
|
|
754
|
+
label: "Aircraft Position",
|
|
384
755
|
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
385
756
|
});
|
|
386
|
-
decodeResult.
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
value: decodeResult.raw.departure_icao
|
|
391
|
-
});
|
|
392
|
-
decodeResult.formatted.items.push({
|
|
393
|
-
type: "destination",
|
|
394
|
-
code: "DST",
|
|
395
|
-
label: "Destination",
|
|
396
|
-
value: decodeResult.raw.arrival_icao
|
|
397
|
-
});
|
|
757
|
+
ResultFormatter.altitude(decodeResult, decodeResult.raw.altitude);
|
|
758
|
+
ResultFormatter.departureAirport(decodeResult, decodeResult.raw.departure_icao);
|
|
759
|
+
ResultFormatter.arrivalAirport(decodeResult, decodeResult.raw.arrival_icao);
|
|
760
|
+
decodeResult.remaining.text = parts.slice(1).join(" ");
|
|
398
761
|
decodeResult.decoded = true;
|
|
399
|
-
decodeResult.decoder.decodeLevel = "
|
|
762
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
400
763
|
return decodeResult;
|
|
401
764
|
}
|
|
402
765
|
};
|
|
@@ -427,19 +790,14 @@ var Label_16_N_Space = class extends DecoderPlugin {
|
|
|
427
790
|
latitude: Number(results.groups.lat_coord) * (results.groups.lat == "N" ? 1 : -1),
|
|
428
791
|
longitude: Number(results.groups.long_coord) * (results.groups.long == "E" ? 1 : -1)
|
|
429
792
|
};
|
|
430
|
-
|
|
793
|
+
const altitude = results.groups.alt == "GRD" || results.groups.alt == "***" ? 0 : Number(results.groups.alt);
|
|
431
794
|
decodeResult.formatted.items.push({
|
|
432
795
|
type: "aircraft_position",
|
|
433
796
|
code: "POS",
|
|
434
797
|
label: "Aircraft Position",
|
|
435
798
|
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
436
799
|
});
|
|
437
|
-
|
|
438
|
-
type: "flight_level",
|
|
439
|
-
code: "FL",
|
|
440
|
-
label: "Flight Level",
|
|
441
|
-
value: decodeResult.raw.flight_level
|
|
442
|
-
});
|
|
800
|
+
ResultFormatter.altitude(decodeResult, altitude);
|
|
443
801
|
decodeResult.remaining.text = `,${results.groups.unkwn1} ,${results.groups.unkwn2}`;
|
|
444
802
|
decodeResult.decoded = true;
|
|
445
803
|
decodeResult.decoder.decodeLevel = "partial";
|
|
@@ -472,58 +830,6 @@ var Label_16_N_Space = class extends DecoderPlugin {
|
|
|
472
830
|
}
|
|
473
831
|
};
|
|
474
832
|
|
|
475
|
-
// lib/DateTimeUtils.ts
|
|
476
|
-
var DateTimeUtils = class {
|
|
477
|
-
// Expects a four digit UTC time string (HHMM)
|
|
478
|
-
static UTCToString(UTCString) {
|
|
479
|
-
let utcDate = /* @__PURE__ */ new Date();
|
|
480
|
-
utcDate.setUTCHours(+UTCString.substr(0, 2), +UTCString.substr(2, 2), 0);
|
|
481
|
-
return utcDate.toTimeString();
|
|
482
|
-
}
|
|
483
|
-
// Expects a six digit date string and a four digit UTC time string
|
|
484
|
-
// (DDMMYY) (HHMM)
|
|
485
|
-
static UTCDateTimeToString(dateString, timeString) {
|
|
486
|
-
let utcDate = /* @__PURE__ */ new Date();
|
|
487
|
-
utcDate.setUTCDate(+dateString.substr(0, 2));
|
|
488
|
-
utcDate.setUTCMonth(+dateString.substr(2, 2));
|
|
489
|
-
if (dateString.length === 6) {
|
|
490
|
-
utcDate.setUTCFullYear(2e3 + +dateString.substr(4, 2));
|
|
491
|
-
}
|
|
492
|
-
if (timeString.length === 6) {
|
|
493
|
-
utcDate.setUTCHours(+timeString.substr(0, 2), +timeString.substr(2, 2), +timeString.substr(4, 2));
|
|
494
|
-
} else {
|
|
495
|
-
utcDate.setUTCHours(+timeString.substr(0, 2), +timeString.substr(2, 2), 0);
|
|
496
|
-
}
|
|
497
|
-
return utcDate.toUTCString();
|
|
498
|
-
}
|
|
499
|
-
/**
|
|
500
|
-
*
|
|
501
|
-
* @param time HHMMSS
|
|
502
|
-
* @returns seconds since midnight
|
|
503
|
-
*/
|
|
504
|
-
static convertHHMMSSToTod(time) {
|
|
505
|
-
const h = Number(time.substring(0, 2));
|
|
506
|
-
const m = Number(time.substring(2, 4));
|
|
507
|
-
const s = Number(time.substring(4, 6));
|
|
508
|
-
const tod = h * 3600 + m * 60 + s;
|
|
509
|
-
return tod;
|
|
510
|
-
}
|
|
511
|
-
/**
|
|
512
|
-
*
|
|
513
|
-
* @param time HHMMSS
|
|
514
|
-
* @param date MMDDYY or MMDDYYYY
|
|
515
|
-
* @returns seconds since epoch
|
|
516
|
-
*/
|
|
517
|
-
static convertDateTimeToEpoch(time, date) {
|
|
518
|
-
if (date.length === 6) {
|
|
519
|
-
date = date.substring(0, 4) + `20${date.substring(4, 6)}`;
|
|
520
|
-
}
|
|
521
|
-
const timestamp = `${date.substring(4, 8)}-${date.substring(0, 2)}-${date.substring(2, 4)}T${time.substring(0, 2)}:${time.substring(2, 4)}:${time.substring(4, 6)}.000Z`;
|
|
522
|
-
const millis = Date.parse(timestamp);
|
|
523
|
-
return millis / 1e3;
|
|
524
|
-
}
|
|
525
|
-
};
|
|
526
|
-
|
|
527
833
|
// lib/plugins/Label_1M_Slash.ts
|
|
528
834
|
var Label_1M_Slash = class extends DecoderPlugin {
|
|
529
835
|
name = "label-1m-slash";
|
|
@@ -600,6 +906,7 @@ var Label_20_POS = class extends DecoderPlugin {
|
|
|
600
906
|
if (decodeResult.raw.position) {
|
|
601
907
|
decodeResult.formatted.items.push({
|
|
602
908
|
type: "position",
|
|
909
|
+
code: "POS",
|
|
603
910
|
label: "Position",
|
|
604
911
|
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
605
912
|
});
|
|
@@ -613,6 +920,7 @@ var Label_20_POS = class extends DecoderPlugin {
|
|
|
613
920
|
if (decodeResult.raw.position) {
|
|
614
921
|
decodeResult.formatted.items.push({
|
|
615
922
|
type: "position",
|
|
923
|
+
code: "POS",
|
|
616
924
|
label: "Position",
|
|
617
925
|
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
618
926
|
});
|
|
@@ -652,7 +960,7 @@ var Label_21_POS = class extends DecoderPlugin {
|
|
|
652
960
|
processAlt(decodeResult, fields[3]);
|
|
653
961
|
processTemp(decodeResult, fields[6]);
|
|
654
962
|
processArrvApt(decodeResult, fields[8]);
|
|
655
|
-
decodeResult.
|
|
963
|
+
decodeResult.remaining.text = [
|
|
656
964
|
fields[1],
|
|
657
965
|
fields[2],
|
|
658
966
|
fields[4],
|
|
@@ -1016,44 +1324,27 @@ var Label_44_POS = class extends DecoderPlugin {
|
|
|
1016
1324
|
console.log(results.groups);
|
|
1017
1325
|
}
|
|
1018
1326
|
decodeResult.raw.position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(results.groups.unsplit_coords);
|
|
1019
|
-
|
|
1020
|
-
decodeResult.raw.departure_icao = results.groups.departure_icao;
|
|
1021
|
-
decodeResult.raw.arrival_icao = results.groups.arrival_icao;
|
|
1327
|
+
const flight_level = results.groups.flight_level_or_ground == "GRD" || results.groups.flight_level_or_ground == "***" ? 0 : Number(results.groups.flight_level_or_ground);
|
|
1022
1328
|
decodeResult.raw.current_time = Date.parse(
|
|
1023
1329
|
(/* @__PURE__ */ new Date()).getFullYear() + "-" + results.groups.current_date.substr(0, 2) + "-" + results.groups.current_date.substr(2, 2) + "T" + results.groups.current_time.substr(0, 2) + ":" + results.groups.current_time.substr(2, 2) + ":00Z"
|
|
1024
1330
|
);
|
|
1025
1331
|
decodeResult.raw.eta_time = Date.parse(
|
|
1026
|
-
(/* @__PURE__ */ new Date()).getFullYear() + "-" + results.groups.current_date.substr(0, 2) + "-" + results.groups.current_date.substr(2, 2) + "T" + results.groups.eta_time.substr(0, 2) + ":" + results.groups.eta_time.substr(2, 2) + ":00Z"
|
|
1027
|
-
);
|
|
1028
|
-
if (results.groups.fuel_in_tons != "***" && results.groups.fuel_in_tons != "****") {
|
|
1029
|
-
decodeResult.raw.fuel_in_tons = Number(results.groups.fuel_in_tons);
|
|
1030
|
-
}
|
|
1031
|
-
if (decodeResult.raw.position) {
|
|
1032
|
-
decodeResult.formatted.items.push({
|
|
1033
|
-
type: "aircraft_position",
|
|
1034
|
-
code: "POS",
|
|
1035
|
-
label: "Aircraft Position",
|
|
1036
|
-
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
1037
|
-
});
|
|
1038
|
-
}
|
|
1039
|
-
decodeResult.
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
label: "Origin",
|
|
1043
|
-
value: decodeResult.raw.departure_icao
|
|
1044
|
-
});
|
|
1045
|
-
decodeResult.formatted.items.push({
|
|
1046
|
-
type: "destination",
|
|
1047
|
-
code: "DST",
|
|
1048
|
-
label: "Destination",
|
|
1049
|
-
value: decodeResult.raw.arrival_icao
|
|
1050
|
-
});
|
|
1051
|
-
decodeResult.formatted.items.push({
|
|
1052
|
-
type: "flight_level",
|
|
1053
|
-
code: "FL",
|
|
1054
|
-
label: "Flight Level",
|
|
1055
|
-
value: decodeResult.raw.flight_level
|
|
1056
|
-
});
|
|
1332
|
+
(/* @__PURE__ */ new Date()).getFullYear() + "-" + results.groups.current_date.substr(0, 2) + "-" + results.groups.current_date.substr(2, 2) + "T" + results.groups.eta_time.substr(0, 2) + ":" + results.groups.eta_time.substr(2, 2) + ":00Z"
|
|
1333
|
+
);
|
|
1334
|
+
if (results.groups.fuel_in_tons != "***" && results.groups.fuel_in_tons != "****") {
|
|
1335
|
+
decodeResult.raw.fuel_in_tons = Number(results.groups.fuel_in_tons);
|
|
1336
|
+
}
|
|
1337
|
+
if (decodeResult.raw.position) {
|
|
1338
|
+
decodeResult.formatted.items.push({
|
|
1339
|
+
type: "aircraft_position",
|
|
1340
|
+
code: "POS",
|
|
1341
|
+
label: "Aircraft Position",
|
|
1342
|
+
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
1343
|
+
});
|
|
1344
|
+
}
|
|
1345
|
+
ResultFormatter.departureAirport(decodeResult, results.groups.departure_icao);
|
|
1346
|
+
ResultFormatter.arrivalAirport(decodeResult, results.groups.arrival_icao);
|
|
1347
|
+
ResultFormatter.altitude(decodeResult, flight_level * 100);
|
|
1057
1348
|
}
|
|
1058
1349
|
decodeResult.decoded = true;
|
|
1059
1350
|
decodeResult.decoder.decodeLevel = "full";
|
|
@@ -1156,13 +1447,9 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
1156
1447
|
break;
|
|
1157
1448
|
}
|
|
1158
1449
|
case "FL": {
|
|
1159
|
-
|
|
1160
|
-
decodeResult.
|
|
1161
|
-
|
|
1162
|
-
code: "FL",
|
|
1163
|
-
label: this.descriptions[match.groups.field],
|
|
1164
|
-
value: decodeResult.raw.flight_level
|
|
1165
|
-
});
|
|
1450
|
+
const flight_level = match.groups.value;
|
|
1451
|
+
decodeResult.raw.altitude = flight_level * 100;
|
|
1452
|
+
ResultFormatter.altitude(decodeResult, decodeResult.raw.altitude);
|
|
1166
1453
|
break;
|
|
1167
1454
|
}
|
|
1168
1455
|
case "FOB": {
|
|
@@ -1396,183 +1683,6 @@ function processUnknown(decodeResult, value) {
|
|
|
1396
1683
|
decodeResult.remaining.text += value;
|
|
1397
1684
|
}
|
|
1398
1685
|
|
|
1399
|
-
// lib/utils/result_formatter.ts
|
|
1400
|
-
var ResultFormatter = class {
|
|
1401
|
-
static altitude(decodeResult, value) {
|
|
1402
|
-
decodeResult.raw.altitude = value;
|
|
1403
|
-
decodeResult.formatted.items.push({
|
|
1404
|
-
type: "altitude",
|
|
1405
|
-
code: "ALT",
|
|
1406
|
-
label: "Altitude",
|
|
1407
|
-
value: `${decodeResult.raw.altitude} feet`
|
|
1408
|
-
});
|
|
1409
|
-
}
|
|
1410
|
-
static flightNumber(decodeResult, value) {
|
|
1411
|
-
decodeResult.raw.flight_number = value;
|
|
1412
|
-
}
|
|
1413
|
-
static departureAirport(decodeResult, value) {
|
|
1414
|
-
decodeResult.raw.departure_icao = value;
|
|
1415
|
-
decodeResult.formatted.items.push({
|
|
1416
|
-
type: "origin",
|
|
1417
|
-
code: "ORG",
|
|
1418
|
-
label: "Origin",
|
|
1419
|
-
value: decodeResult.raw.departure_icao
|
|
1420
|
-
});
|
|
1421
|
-
}
|
|
1422
|
-
static departureRunway(decodeResult, value) {
|
|
1423
|
-
decodeResult.raw.departure_runway = value;
|
|
1424
|
-
decodeResult.formatted.items.push({
|
|
1425
|
-
type: "runway",
|
|
1426
|
-
code: "DEPRWY",
|
|
1427
|
-
label: "Departure Runway",
|
|
1428
|
-
value: decodeResult.raw.departure_runway
|
|
1429
|
-
});
|
|
1430
|
-
}
|
|
1431
|
-
static arrivalAirport(decodeResult, value) {
|
|
1432
|
-
decodeResult.raw.arrival_icao = value;
|
|
1433
|
-
decodeResult.formatted.items.push({
|
|
1434
|
-
type: "destination",
|
|
1435
|
-
code: "DST",
|
|
1436
|
-
label: "Destination",
|
|
1437
|
-
value: decodeResult.raw.arrival_icao
|
|
1438
|
-
});
|
|
1439
|
-
}
|
|
1440
|
-
static eta(decodeResult, value) {
|
|
1441
|
-
decodeResult.formatted.items.push({
|
|
1442
|
-
type: "eta",
|
|
1443
|
-
code: "ETA",
|
|
1444
|
-
label: "Estimated Time of Arrival",
|
|
1445
|
-
value: value.substring(0, 2) + ":" + value.substring(2, 4) + ":" + value.substring(4, 6)
|
|
1446
|
-
});
|
|
1447
|
-
}
|
|
1448
|
-
static arrivalRunway(decodeResult, value) {
|
|
1449
|
-
decodeResult.raw.arrival_runway = value;
|
|
1450
|
-
decodeResult.formatted.items.push({
|
|
1451
|
-
type: "runway",
|
|
1452
|
-
label: "Arrival Runway",
|
|
1453
|
-
value: decodeResult.raw.arrival_runway
|
|
1454
|
-
});
|
|
1455
|
-
}
|
|
1456
|
-
static currentFuel(decodeResult, value) {
|
|
1457
|
-
decodeResult.raw.fuel_on_board = value;
|
|
1458
|
-
decodeResult.formatted.items.push({
|
|
1459
|
-
type: "fuel_on_board",
|
|
1460
|
-
code: "FOB",
|
|
1461
|
-
label: "Fuel On Board",
|
|
1462
|
-
value: decodeResult.raw.fuel_on_board.toString()
|
|
1463
|
-
});
|
|
1464
|
-
}
|
|
1465
|
-
static remainingFuel(decodeResult, value) {
|
|
1466
|
-
decodeResult.raw.fuel_remaining = value;
|
|
1467
|
-
decodeResult.formatted.items.push({
|
|
1468
|
-
type: "fuel_remaining",
|
|
1469
|
-
label: "Fuel Remaining",
|
|
1470
|
-
value: decodeResult.raw.fuel_remaining.toString()
|
|
1471
|
-
});
|
|
1472
|
-
}
|
|
1473
|
-
static checksum(decodeResult, value) {
|
|
1474
|
-
decodeResult.raw.checksum = Number("0x" + value);
|
|
1475
|
-
decodeResult.formatted.items.push({
|
|
1476
|
-
type: "message_checksum",
|
|
1477
|
-
code: "CHECKSUM",
|
|
1478
|
-
label: "Message Checksum",
|
|
1479
|
-
value: "0x" + ("0000" + decodeResult.raw.checksum.toString(16)).slice(-4)
|
|
1480
|
-
});
|
|
1481
|
-
}
|
|
1482
|
-
static groundspeed(decodeResult, value) {
|
|
1483
|
-
decodeResult.raw.groundspeed = value;
|
|
1484
|
-
decodeResult.formatted.items.push({
|
|
1485
|
-
type: "aircraft_groundspeed",
|
|
1486
|
-
code: "GSPD",
|
|
1487
|
-
label: "Aircraft Groundspeed",
|
|
1488
|
-
value: `${decodeResult.raw.groundspeed}`
|
|
1489
|
-
});
|
|
1490
|
-
}
|
|
1491
|
-
static temperature(decodeResult, value) {
|
|
1492
|
-
decodeResult.raw.outside_air_temperature = Number(value.substring(1)) * (value.charAt(0) === "M" ? -1 : 1);
|
|
1493
|
-
decodeResult.formatted.items.push({
|
|
1494
|
-
type: "outside_air_temperature",
|
|
1495
|
-
code: "OATEMP",
|
|
1496
|
-
label: "Outside Air Temperature (C)",
|
|
1497
|
-
value: `${decodeResult.raw.outside_air_temperature}`
|
|
1498
|
-
});
|
|
1499
|
-
}
|
|
1500
|
-
static unknown(decodeResult, value) {
|
|
1501
|
-
decodeResult.remaining.text += "," + value;
|
|
1502
|
-
}
|
|
1503
|
-
};
|
|
1504
|
-
|
|
1505
|
-
// lib/utils/route_utils.ts
|
|
1506
|
-
var RouteUtils = class _RouteUtils {
|
|
1507
|
-
static routeToString(route) {
|
|
1508
|
-
let str = "";
|
|
1509
|
-
if (route.name) {
|
|
1510
|
-
str += route.name;
|
|
1511
|
-
}
|
|
1512
|
-
if (route.runway) {
|
|
1513
|
-
str += `(${route.runway})`;
|
|
1514
|
-
}
|
|
1515
|
-
if (str.length !== 0 && route.waypoints && route.waypoints.length === 1) {
|
|
1516
|
-
str += " starting at ";
|
|
1517
|
-
} else if (str.length !== 0 && route.waypoints) {
|
|
1518
|
-
str += ": ";
|
|
1519
|
-
}
|
|
1520
|
-
if (route.waypoints) {
|
|
1521
|
-
str += _RouteUtils.waypointsToString(route.waypoints);
|
|
1522
|
-
}
|
|
1523
|
-
return str;
|
|
1524
|
-
}
|
|
1525
|
-
static waypointToString(waypoint) {
|
|
1526
|
-
let s = waypoint.name;
|
|
1527
|
-
if (waypoint.latitude && waypoint.longitude) {
|
|
1528
|
-
s += `(${CoordinateUtils.coordinateString({ latitude: waypoint.latitude, longitude: waypoint.longitude })})`;
|
|
1529
|
-
}
|
|
1530
|
-
if (waypoint.offset) {
|
|
1531
|
-
s += `[${waypoint.offset.bearing}\xB0 ${waypoint.offset.distance}nm]`;
|
|
1532
|
-
}
|
|
1533
|
-
if (waypoint.time && waypoint.timeFormat) {
|
|
1534
|
-
s += `@${_RouteUtils.timestampToString(waypoint.time, waypoint.timeFormat)}`;
|
|
1535
|
-
}
|
|
1536
|
-
return s;
|
|
1537
|
-
}
|
|
1538
|
-
static getWaypoint(leg) {
|
|
1539
|
-
const regex = leg.match(/^([A-Z]+)(\d{3})-(\d{4})$/);
|
|
1540
|
-
if (regex?.length == 4) {
|
|
1541
|
-
return { name: regex[1], offset: { bearing: parseInt(regex[2]), distance: parseInt(regex[3]) / 10 } };
|
|
1542
|
-
}
|
|
1543
|
-
const waypoint = leg.split(",");
|
|
1544
|
-
if (waypoint.length == 2) {
|
|
1545
|
-
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(waypoint[1]);
|
|
1546
|
-
if (position) {
|
|
1547
|
-
return { name: waypoint[0], latitude: position.latitude, longitude: position.longitude };
|
|
1548
|
-
}
|
|
1549
|
-
}
|
|
1550
|
-
if (leg.length == 13 || leg.length == 14) {
|
|
1551
|
-
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(leg);
|
|
1552
|
-
const name = waypoint.length == 2 ? waypoint[0] : "";
|
|
1553
|
-
if (position) {
|
|
1554
|
-
return { name, latitude: position.latitude, longitude: position.longitude };
|
|
1555
|
-
}
|
|
1556
|
-
}
|
|
1557
|
-
return { name: leg };
|
|
1558
|
-
}
|
|
1559
|
-
// move out if we want public
|
|
1560
|
-
static timestampToString(time, format) {
|
|
1561
|
-
const date = new Date(time * 1e3);
|
|
1562
|
-
if (format == "tod") {
|
|
1563
|
-
return date.toISOString().slice(11, 19);
|
|
1564
|
-
}
|
|
1565
|
-
return date.toISOString().slice(0, -5) + "Z";
|
|
1566
|
-
}
|
|
1567
|
-
static waypointsToString(waypoints) {
|
|
1568
|
-
let str = waypoints.map((x) => _RouteUtils.waypointToString(x)).join(" > ").replaceAll("> >", ">>");
|
|
1569
|
-
if (str.startsWith(" > ")) {
|
|
1570
|
-
str = ">>" + str.slice(2);
|
|
1571
|
-
}
|
|
1572
|
-
return str;
|
|
1573
|
-
}
|
|
1574
|
-
};
|
|
1575
|
-
|
|
1576
1686
|
// lib/utils/flight_plan_utils.ts
|
|
1577
1687
|
var FlightPlanUtils = class _FlightPlanUtils {
|
|
1578
1688
|
/**
|
|
@@ -2249,6 +2359,60 @@ function processUnknown2(decodeResult, value) {
|
|
|
2249
2359
|
decodeResult.remaining.text += value;
|
|
2250
2360
|
}
|
|
2251
2361
|
|
|
2362
|
+
// lib/plugins/Label_HX.ts
|
|
2363
|
+
var Label_HX = class extends DecoderPlugin {
|
|
2364
|
+
name = "label-hx";
|
|
2365
|
+
qualifiers() {
|
|
2366
|
+
return {
|
|
2367
|
+
labels: ["HX"],
|
|
2368
|
+
preambles: ["RA FMT LOCATION", "RA FMT 43"]
|
|
2369
|
+
};
|
|
2370
|
+
}
|
|
2371
|
+
decode(message, options = {}) {
|
|
2372
|
+
const decodeResult = this.defaultResult();
|
|
2373
|
+
decodeResult.decoder.name = this.name;
|
|
2374
|
+
decodeResult.message = message;
|
|
2375
|
+
decodeResult.formatted.description = "Undelivered Uplink Report";
|
|
2376
|
+
const parts = message.text.split(" ");
|
|
2377
|
+
decodeResult.decoded = true;
|
|
2378
|
+
if (parts[2] === "LOCATION") {
|
|
2379
|
+
let latdir = parts[3].substring(0, 1);
|
|
2380
|
+
let latdeg = Number(parts[3].substring(1, 3));
|
|
2381
|
+
let latmin = Number(parts[3].substring(3, 7));
|
|
2382
|
+
let londir = parts[4].substring(0, 1);
|
|
2383
|
+
let londeg = Number(parts[4].substring(1, 4));
|
|
2384
|
+
let lonmin = Number(parts[4].substring(4, 8));
|
|
2385
|
+
decodeResult.raw.position = {
|
|
2386
|
+
latitude: (latdeg + latmin / 60) * (latdir === "N" ? 1 : -1),
|
|
2387
|
+
longitude: (londeg + lonmin / 60) * (londir === "E" ? 1 : -1)
|
|
2388
|
+
};
|
|
2389
|
+
decodeResult.remaining.text = parts.slice(5).join(" ");
|
|
2390
|
+
} else if (parts[2] === "43") {
|
|
2391
|
+
ResultFormatter.departureAirport(decodeResult, parts[3]);
|
|
2392
|
+
decodeResult.remaining.text = parts.slice(4).join(" ");
|
|
2393
|
+
} else {
|
|
2394
|
+
decodeResult.decoded = false;
|
|
2395
|
+
}
|
|
2396
|
+
if (decodeResult.raw.position) {
|
|
2397
|
+
decodeResult.formatted.items.push({
|
|
2398
|
+
type: "aircraft_position",
|
|
2399
|
+
code: "POS",
|
|
2400
|
+
label: "Aircraft Position",
|
|
2401
|
+
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
2402
|
+
});
|
|
2403
|
+
}
|
|
2404
|
+
if (decodeResult.decoded) {
|
|
2405
|
+
if (decodeResult.remaining.text === "")
|
|
2406
|
+
decodeResult.decoder.decodeLevel = "full";
|
|
2407
|
+
else
|
|
2408
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
2409
|
+
} else {
|
|
2410
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2411
|
+
}
|
|
2412
|
+
return decodeResult;
|
|
2413
|
+
}
|
|
2414
|
+
};
|
|
2415
|
+
|
|
2252
2416
|
// lib/plugins/Label_SQ.ts
|
|
2253
2417
|
var Label_SQ = class extends DecoderPlugin {
|
|
2254
2418
|
name = "label-sq";
|
|
@@ -2289,11 +2453,13 @@ var Label_SQ = class extends DecoderPlugin {
|
|
|
2289
2453
|
decodeResult.formatted.items = [
|
|
2290
2454
|
{
|
|
2291
2455
|
type: "network",
|
|
2456
|
+
code: "NETT",
|
|
2292
2457
|
label: "Network",
|
|
2293
2458
|
value: formattedNetwork
|
|
2294
2459
|
},
|
|
2295
2460
|
{
|
|
2296
2461
|
type: "version",
|
|
2462
|
+
code: "VER",
|
|
2297
2463
|
label: "Version",
|
|
2298
2464
|
value: decodeResult.raw.version
|
|
2299
2465
|
}
|
|
@@ -2302,6 +2468,7 @@ var Label_SQ = class extends DecoderPlugin {
|
|
|
2302
2468
|
if (decodeResult.raw.groundStation.icaoCode && decodeResult.raw.groundStation.number) {
|
|
2303
2469
|
decodeResult.formatted.items.push({
|
|
2304
2470
|
type: "ground_station",
|
|
2471
|
+
code: "GNDSTN",
|
|
2305
2472
|
label: "Ground Station",
|
|
2306
2473
|
value: `${decodeResult.raw.groundStation.icaoCode}${decodeResult.raw.groundStation.number}`
|
|
2307
2474
|
});
|
|
@@ -2309,6 +2476,7 @@ var Label_SQ = class extends DecoderPlugin {
|
|
|
2309
2476
|
if (decodeResult.raw.groundStation.iataCode) {
|
|
2310
2477
|
decodeResult.formatted.items.push({
|
|
2311
2478
|
type: "iataCode",
|
|
2479
|
+
code: "IATA",
|
|
2312
2480
|
label: "IATA",
|
|
2313
2481
|
value: decodeResult.raw.groundStation.iataCode
|
|
2314
2482
|
});
|
|
@@ -2316,6 +2484,7 @@ var Label_SQ = class extends DecoderPlugin {
|
|
|
2316
2484
|
if (decodeResult.raw.groundStation.icaoCode) {
|
|
2317
2485
|
decodeResult.formatted.items.push({
|
|
2318
2486
|
type: "icaoCode",
|
|
2487
|
+
code: "ICAO",
|
|
2319
2488
|
label: "ICAO",
|
|
2320
2489
|
value: decodeResult.raw.groundStation.icaoCode
|
|
2321
2490
|
});
|
|
@@ -2323,6 +2492,7 @@ var Label_SQ = class extends DecoderPlugin {
|
|
|
2323
2492
|
if (decodeResult.raw.groundStation.coordinates.latitude) {
|
|
2324
2493
|
decodeResult.formatted.items.push({
|
|
2325
2494
|
type: "coordinates",
|
|
2495
|
+
code: "COORD",
|
|
2326
2496
|
label: "Ground Station Location",
|
|
2327
2497
|
value: `${decodeResult.raw.groundStation.coordinates.latitude}, ${decodeResult.raw.groundStation.coordinates.longitude}`
|
|
2328
2498
|
});
|
|
@@ -2330,6 +2500,7 @@ var Label_SQ = class extends DecoderPlugin {
|
|
|
2330
2500
|
if (decodeResult.raw.groundStation.airport) {
|
|
2331
2501
|
decodeResult.formatted.items.push({
|
|
2332
2502
|
type: "airport",
|
|
2503
|
+
code: "APT",
|
|
2333
2504
|
label: "Airport",
|
|
2334
2505
|
value: `${decodeResult.raw.groundStation.airport.name} (${decodeResult.raw.groundStation.airport.icao}) in ${decodeResult.raw.groundStation.airport.location}`
|
|
2335
2506
|
});
|
|
@@ -2338,6 +2509,7 @@ var Label_SQ = class extends DecoderPlugin {
|
|
|
2338
2509
|
if (decodeResult.raw.vdlFrequency) {
|
|
2339
2510
|
decodeResult.formatted.items.push({
|
|
2340
2511
|
type: "vdlFrequency",
|
|
2512
|
+
code: "VDLFRQ",
|
|
2341
2513
|
label: "VDL Frequency",
|
|
2342
2514
|
value: `${decodeResult.raw.vdlFrequency} MHz`
|
|
2343
2515
|
});
|
|
@@ -2494,31 +2666,48 @@ var Label_QQ = class extends DecoderPlugin {
|
|
|
2494
2666
|
decode(message, options = {}) {
|
|
2495
2667
|
const decodeResult = this.defaultResult();
|
|
2496
2668
|
decodeResult.decoder.name = this.name;
|
|
2497
|
-
decodeResult.
|
|
2498
|
-
decodeResult.raw.destination = message.text.substring(4, 8);
|
|
2499
|
-
decodeResult.raw.wheels_off = message.text.substring(8, 12);
|
|
2500
|
-
decodeResult.remaining.text = message.text.substring(12);
|
|
2669
|
+
decodeResult.message = message;
|
|
2501
2670
|
decodeResult.formatted.description = "OFF Report";
|
|
2502
|
-
decodeResult.
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2671
|
+
ResultFormatter.departureAirport(decodeResult, message.text.substring(0, 4));
|
|
2672
|
+
ResultFormatter.arrivalAirport(decodeResult, message.text.substring(4, 8));
|
|
2673
|
+
decodeResult.raw.wheels_off = message.text.substring(8, 12);
|
|
2674
|
+
if (message.text.substring(12, 19) === "\r\n001FE") {
|
|
2675
|
+
decodeResult.raw.day_of_month = message.text.substring(19, 21);
|
|
2676
|
+
decodeResult.raw.wheels_off = message.text.substring(21, 27);
|
|
2677
|
+
let latdir = message.text.substring(27, 28);
|
|
2678
|
+
let latdeg = Number(message.text.substring(28, 30));
|
|
2679
|
+
let latmin = Number(message.text.substring(30, 34));
|
|
2680
|
+
let londir = message.text.substring(34, 35);
|
|
2681
|
+
let londeg = Number(message.text.substring(35, 38));
|
|
2682
|
+
let lonmin = Number(message.text.substring(38, 42));
|
|
2683
|
+
decodeResult.raw.position = {
|
|
2684
|
+
latitude: (latdeg + latmin / 60) * (latdir === "N" ? 1 : -1),
|
|
2685
|
+
longitude: (londeg + lonmin / 60) * (londir === "E" ? 1 : -1)
|
|
2686
|
+
};
|
|
2687
|
+
decodeResult.remaining.text = message.text.substring(42, 45);
|
|
2688
|
+
if (decodeResult.remaining.text !== "---") {
|
|
2689
|
+
ResultFormatter.groundspeed(decodeResult, message.text.substring(45, 48));
|
|
2690
|
+
} else {
|
|
2691
|
+
ResultFormatter.unknown(decodeResult, message.text.substring(45, 48));
|
|
2520
2692
|
}
|
|
2521
|
-
|
|
2693
|
+
ResultFormatter.unknown(decodeResult, message.text.substring(48));
|
|
2694
|
+
} else {
|
|
2695
|
+
decodeResult.remaining.text = message.text.substring(12);
|
|
2696
|
+
}
|
|
2697
|
+
decodeResult.formatted.items.push({
|
|
2698
|
+
type: "wheels_off",
|
|
2699
|
+
code: "WOFF",
|
|
2700
|
+
label: "Wheels OFF",
|
|
2701
|
+
value: decodeResult.raw.wheels_off
|
|
2702
|
+
});
|
|
2703
|
+
if (decodeResult.raw.position) {
|
|
2704
|
+
decodeResult.formatted.items.push({
|
|
2705
|
+
type: "aircraft_position",
|
|
2706
|
+
code: "POS",
|
|
2707
|
+
label: "Aircraft Position",
|
|
2708
|
+
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
2709
|
+
});
|
|
2710
|
+
}
|
|
2522
2711
|
decodeResult.decoded = true;
|
|
2523
2712
|
if (decodeResult.remaining.text === "")
|
|
2524
2713
|
decodeResult.decoder.decodeLevel = "full";
|
|
@@ -3341,6 +3530,9 @@ var MessageDecoder = class {
|
|
|
3341
3530
|
this.debug = false;
|
|
3342
3531
|
this.registerPlugin(new Label_ColonComma(this));
|
|
3343
3532
|
this.registerPlugin(new Label_5Z(this));
|
|
3533
|
+
this.registerPlugin(new Label_10_LDR(this));
|
|
3534
|
+
this.registerPlugin(new Label_10_POS(this));
|
|
3535
|
+
this.registerPlugin(new Label_10_Slash(this));
|
|
3344
3536
|
this.registerPlugin(new Label_12_N_Space(this));
|
|
3345
3537
|
this.registerPlugin(new Label_15(this));
|
|
3346
3538
|
this.registerPlugin(new Label_15_FST(this));
|
|
@@ -3361,6 +3553,7 @@ var MessageDecoder = class {
|
|
|
3361
3553
|
this.registerPlugin(new Label_H1_OHMA(this));
|
|
3362
3554
|
this.registerPlugin(new Label_H1_POS(this));
|
|
3363
3555
|
this.registerPlugin(new Label_H1_WRN(this));
|
|
3556
|
+
this.registerPlugin(new Label_HX(this));
|
|
3364
3557
|
this.registerPlugin(new Label_80(this));
|
|
3365
3558
|
this.registerPlugin(new Label_8E(this));
|
|
3366
3559
|
this.registerPlugin(new Label_1M_Slash(this));
|