@airframes/acars-decoder 1.6.10 → 1.6.11
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 +349 -75
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +349 -75
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -154,6 +154,17 @@ var CoordinateUtils = class {
|
|
|
154
154
|
const lonDir = coords.longitude > 0 ? "E" : "W";
|
|
155
155
|
return `${Math.abs(coords.latitude).toFixed(3)} ${latDir}, ${Math.abs(coords.longitude).toFixed(3)} ${lonDir}`;
|
|
156
156
|
}
|
|
157
|
+
static getDirection(coord) {
|
|
158
|
+
if (coord.startsWith("N") || coord.startsWith("E")) {
|
|
159
|
+
return 1;
|
|
160
|
+
} else if (coord.startsWith("S") || coord.startsWith("W")) {
|
|
161
|
+
return -1;
|
|
162
|
+
}
|
|
163
|
+
return NaN;
|
|
164
|
+
}
|
|
165
|
+
static dmsToDecimalDegrees(degrees, minutes, seconds) {
|
|
166
|
+
return degrees + minutes / 60 + seconds / 3600;
|
|
167
|
+
}
|
|
157
168
|
};
|
|
158
169
|
|
|
159
170
|
// lib/utils/result_formatter.ts
|
|
@@ -206,6 +217,16 @@ var ResultFormatter = class {
|
|
|
206
217
|
value: decodeResult.raw.arrival_icao
|
|
207
218
|
});
|
|
208
219
|
}
|
|
220
|
+
static alternateAirport(decodeResult, value) {
|
|
221
|
+
decodeResult.raw.alternate_icao = value;
|
|
222
|
+
decodeResult.formatted.items.push({
|
|
223
|
+
type: "destination",
|
|
224
|
+
code: "ALT_DST",
|
|
225
|
+
label: "Alternate Destination",
|
|
226
|
+
value: decodeResult.raw.alternate_icao
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
// FIXME - make seconds since midnight for time of day
|
|
209
230
|
static eta(decodeResult, value) {
|
|
210
231
|
decodeResult.raw.eta_time = value;
|
|
211
232
|
decodeResult.formatted.items.push({
|
|
@@ -224,6 +245,15 @@ var ResultFormatter = class {
|
|
|
224
245
|
value: decodeResult.raw.arrival_runway
|
|
225
246
|
});
|
|
226
247
|
}
|
|
248
|
+
static alternateRunway(decodeResult, value) {
|
|
249
|
+
decodeResult.raw.alternate_runway = value;
|
|
250
|
+
decodeResult.formatted.items.push({
|
|
251
|
+
type: "runway",
|
|
252
|
+
code: "ALT_ARWY",
|
|
253
|
+
label: "Alternate Runway",
|
|
254
|
+
value: decodeResult.raw.alternate_runway
|
|
255
|
+
});
|
|
256
|
+
}
|
|
227
257
|
static currentFuel(decodeResult, value) {
|
|
228
258
|
decodeResult.raw.fuel_on_board = value;
|
|
229
259
|
decodeResult.formatted.items.push({
|
|
@@ -257,7 +287,7 @@ var ResultFormatter = class {
|
|
|
257
287
|
type: "aircraft_groundspeed",
|
|
258
288
|
code: "GSPD",
|
|
259
289
|
label: "Aircraft Groundspeed",
|
|
260
|
-
value: `${decodeResult.raw.groundspeed}`
|
|
290
|
+
value: `${decodeResult.raw.groundspeed} knots`
|
|
261
291
|
});
|
|
262
292
|
}
|
|
263
293
|
static temperature(decodeResult, value) {
|
|
@@ -278,6 +308,55 @@ var ResultFormatter = class {
|
|
|
278
308
|
value: `${decodeResult.raw.heading}`
|
|
279
309
|
});
|
|
280
310
|
}
|
|
311
|
+
static tail(decodeResult, value) {
|
|
312
|
+
decodeResult.raw.tail = value;
|
|
313
|
+
decodeResult.formatted.items.push({
|
|
314
|
+
type: "tail",
|
|
315
|
+
code: "TAIL",
|
|
316
|
+
label: "Tail",
|
|
317
|
+
value: decodeResult.raw.tail
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
static out(decodeResult, time) {
|
|
321
|
+
decodeResult.raw.out_time = time;
|
|
322
|
+
const date = new Date(time * 1e3);
|
|
323
|
+
decodeResult.formatted.items.push({
|
|
324
|
+
type: "time_of_day",
|
|
325
|
+
code: "OUT",
|
|
326
|
+
label: "Out of Gate Time",
|
|
327
|
+
value: date.toISOString().slice(11, 19)
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
static off(decodeResult, time) {
|
|
331
|
+
decodeResult.raw.off_time = time;
|
|
332
|
+
const date = new Date(time * 1e3);
|
|
333
|
+
decodeResult.formatted.items.push({
|
|
334
|
+
type: "time_of_day",
|
|
335
|
+
code: "OFF",
|
|
336
|
+
label: "Takeoff Time",
|
|
337
|
+
value: date.toISOString().slice(11, 19)
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
static on(decodeResult, time) {
|
|
341
|
+
decodeResult.raw.on_time = time;
|
|
342
|
+
const date = new Date(time * 1e3);
|
|
343
|
+
decodeResult.formatted.items.push({
|
|
344
|
+
type: "time_of_day",
|
|
345
|
+
code: "ON",
|
|
346
|
+
label: "Landing Time",
|
|
347
|
+
value: date.toISOString().slice(11, 19)
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
static in(decodeResult, time) {
|
|
351
|
+
decodeResult.raw.in_time = time;
|
|
352
|
+
const date = new Date(time * 1e3);
|
|
353
|
+
decodeResult.formatted.items.push({
|
|
354
|
+
type: "time_of_day",
|
|
355
|
+
code: "IN",
|
|
356
|
+
label: "In Gate Time",
|
|
357
|
+
value: date.toISOString().slice(11, 19)
|
|
358
|
+
});
|
|
359
|
+
}
|
|
281
360
|
static unknown(decodeResult, value) {
|
|
282
361
|
decodeResult.remaining.text += "," + value;
|
|
283
362
|
}
|
|
@@ -384,7 +463,7 @@ var Label_10_LDR = class extends DecoderPlugin {
|
|
|
384
463
|
decodeResult.message = message;
|
|
385
464
|
const parts = message.text.split(",");
|
|
386
465
|
if (parts.length < 17) {
|
|
387
|
-
if (options
|
|
466
|
+
if (options.debug) {
|
|
388
467
|
console.log(`Decoder: Unknown 10 message: ${message.text}`);
|
|
389
468
|
}
|
|
390
469
|
decodeResult.remaining.text = message.text;
|
|
@@ -402,8 +481,13 @@ var Label_10_LDR = class extends DecoderPlugin {
|
|
|
402
481
|
ResultFormatter.altitude(decodeResult, Number(parts[7]));
|
|
403
482
|
ResultFormatter.departureAirport(decodeResult, parts[9]);
|
|
404
483
|
ResultFormatter.arrivalAirport(decodeResult, parts[10]);
|
|
484
|
+
ResultFormatter.alternateAirport(decodeResult, parts[11]);
|
|
405
485
|
ResultFormatter.arrivalRunway(decodeResult, parts[12].split("/")[0]);
|
|
406
|
-
|
|
486
|
+
const altRwy = [parts[13].split("/")[0], parts[14].split("/")[0]].filter((r) => r != "").join(",");
|
|
487
|
+
if (altRwy != "") {
|
|
488
|
+
ResultFormatter.alternateRunway(decodeResult, altRwy);
|
|
489
|
+
}
|
|
490
|
+
decodeResult.remaining.text = [...parts.slice(0, 5), ...parts.slice(15)].join(",");
|
|
407
491
|
decodeResult.decoded = true;
|
|
408
492
|
decodeResult.decoder.decodeLevel = "partial";
|
|
409
493
|
return decodeResult;
|
|
@@ -427,7 +511,7 @@ var Label_10_POS = class extends DecoderPlugin {
|
|
|
427
511
|
decodeResult.message = message;
|
|
428
512
|
const parts = message.text.split(",");
|
|
429
513
|
if (parts.length !== 12) {
|
|
430
|
-
if (options
|
|
514
|
+
if (options.debug) {
|
|
431
515
|
console.log(`Decoder: Unknown 10 message: ${message.text}`);
|
|
432
516
|
}
|
|
433
517
|
decodeResult.remaining.text = message.text;
|
|
@@ -590,7 +674,7 @@ var Label_10_Slash = class extends DecoderPlugin {
|
|
|
590
674
|
decodeResult.message = message;
|
|
591
675
|
const parts = message.text.split("/");
|
|
592
676
|
if (parts.length < 17) {
|
|
593
|
-
if (options
|
|
677
|
+
if (options.debug) {
|
|
594
678
|
console.log(`Decoder: Unknown 10 message: ${message.text}`);
|
|
595
679
|
}
|
|
596
680
|
decodeResult.remaining.text = message.text;
|
|
@@ -685,6 +769,97 @@ var Label_12_N_Space = class extends DecoderPlugin {
|
|
|
685
769
|
}
|
|
686
770
|
};
|
|
687
771
|
|
|
772
|
+
// lib/plugins/Label_13Through18_Slash.ts
|
|
773
|
+
var Label_13Through18_Slash = class extends DecoderPlugin {
|
|
774
|
+
// eslint-disable-line camelcase
|
|
775
|
+
name = "label-13-18-slash";
|
|
776
|
+
qualifiers() {
|
|
777
|
+
return {
|
|
778
|
+
labels: ["13", "14", "15", "16", "17", "18"],
|
|
779
|
+
preambles: ["/"]
|
|
780
|
+
};
|
|
781
|
+
}
|
|
782
|
+
decode(message, options = {}) {
|
|
783
|
+
const decodeResult = this.defaultResult();
|
|
784
|
+
decodeResult.decoder.name = this.name;
|
|
785
|
+
decodeResult.message = message;
|
|
786
|
+
const lines = message.text.split("\r\n");
|
|
787
|
+
const parts = lines[0].split("/");
|
|
788
|
+
const labelNumber = Number(parts[1].substring(0, 2));
|
|
789
|
+
decodeResult.formatted.description = getMsgType(labelNumber);
|
|
790
|
+
if (labelNumber !== 18 && parts.length !== 4 || labelNumber === 18 && parts.length !== 7) {
|
|
791
|
+
if (options?.debug) {
|
|
792
|
+
console.log(`Decoder: Unknown OOOI message: ${message.text}`);
|
|
793
|
+
}
|
|
794
|
+
decodeResult.remaining.text = message.text;
|
|
795
|
+
decodeResult.decoded = false;
|
|
796
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
797
|
+
return decodeResult;
|
|
798
|
+
}
|
|
799
|
+
decodeResult.remaining.text = "";
|
|
800
|
+
const data = parts[2].split(" ");
|
|
801
|
+
ResultFormatter.departureAirport(decodeResult, data[1]);
|
|
802
|
+
ResultFormatter.arrivalAirport(decodeResult, data[2]);
|
|
803
|
+
decodeResult.raw.day_of_month = Number(data[3]);
|
|
804
|
+
const time = DateTimeUtils.convertHHMMSSToTod(data[4]);
|
|
805
|
+
if (labelNumber === 13) {
|
|
806
|
+
ResultFormatter.out(decodeResult, time);
|
|
807
|
+
} else if (labelNumber === 14) {
|
|
808
|
+
ResultFormatter.off(decodeResult, time);
|
|
809
|
+
} else if (labelNumber === 15) {
|
|
810
|
+
ResultFormatter.on(decodeResult, time);
|
|
811
|
+
} else if (labelNumber === 16) {
|
|
812
|
+
ResultFormatter.in(decodeResult, time);
|
|
813
|
+
}
|
|
814
|
+
if (parts.length === 7) {
|
|
815
|
+
decodeResult.remaining.text += parts.slice(4).join("/");
|
|
816
|
+
}
|
|
817
|
+
for (let i = 1; i < lines.length; i++) {
|
|
818
|
+
if (lines[i].startsWith("/LOC")) {
|
|
819
|
+
const location = lines[i].substring(5).split(",");
|
|
820
|
+
let position;
|
|
821
|
+
if (location[0].startsWith("+") || location[0].startsWith("-")) {
|
|
822
|
+
position = { latitude: Number(location[0]), longitude: Number(location[1]) };
|
|
823
|
+
} else {
|
|
824
|
+
position = {
|
|
825
|
+
latitude: CoordinateUtils.getDirection(location[0][0]) * CoordinateUtils.dmsToDecimalDegrees(Number(location[0].substring(1, 3)), Number(location[0].substring(3, 5)), Number(location[0].substring(5, 7))),
|
|
826
|
+
longitude: CoordinateUtils.getDirection(location[1][0]) * CoordinateUtils.dmsToDecimalDegrees(Number(location[1].substring(1, 4)), Number(location[1].substring(4, 6)), Number(location[1].substring(6, 8)))
|
|
827
|
+
};
|
|
828
|
+
}
|
|
829
|
+
if (!isNaN(position.latitude) && !isNaN(position.longitude)) {
|
|
830
|
+
ResultFormatter.position(decodeResult, position);
|
|
831
|
+
}
|
|
832
|
+
} else {
|
|
833
|
+
decodeResult.remaining.text += "\r\n" + lines[i];
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
decodeResult.decoded = true;
|
|
837
|
+
decodeResult.decoder.decodeLevel = decodeResult.remaining.text ? "partial" : "full";
|
|
838
|
+
return decodeResult;
|
|
839
|
+
}
|
|
840
|
+
};
|
|
841
|
+
function getMsgType(labelNumber) {
|
|
842
|
+
if (labelNumber === 13) {
|
|
843
|
+
return "Out of Gate Report";
|
|
844
|
+
}
|
|
845
|
+
if (labelNumber === 14) {
|
|
846
|
+
return "Takeoff Report";
|
|
847
|
+
}
|
|
848
|
+
if (labelNumber === 15) {
|
|
849
|
+
return "On Ground Report";
|
|
850
|
+
}
|
|
851
|
+
if (labelNumber === 16) {
|
|
852
|
+
return "In Gate Report";
|
|
853
|
+
}
|
|
854
|
+
if (labelNumber === 17) {
|
|
855
|
+
return "Post Report";
|
|
856
|
+
}
|
|
857
|
+
if (labelNumber === 18) {
|
|
858
|
+
return "Post Times Report";
|
|
859
|
+
}
|
|
860
|
+
return "Unknown";
|
|
861
|
+
}
|
|
862
|
+
|
|
688
863
|
// lib/plugins/Label_15.ts
|
|
689
864
|
var Label_15 = class extends DecoderPlugin {
|
|
690
865
|
name = "label-5z";
|
|
@@ -896,11 +1071,11 @@ var Label_20_POS = class extends DecoderPlugin {
|
|
|
896
1071
|
decodeResult.message = message;
|
|
897
1072
|
decodeResult.raw.preamble = message.text.substring(0, 3);
|
|
898
1073
|
const content = message.text.substring(3);
|
|
899
|
-
console.log("Content: " + content);
|
|
900
1074
|
const fields = content.split(",");
|
|
901
|
-
console.log("Field Count: " + fields.length);
|
|
902
1075
|
if (fields.length == 11) {
|
|
903
|
-
|
|
1076
|
+
if (options.debug) {
|
|
1077
|
+
console.log(`DEBUG: ${this.name}: Variation 1 detected`);
|
|
1078
|
+
}
|
|
904
1079
|
const rawCoords = fields[0];
|
|
905
1080
|
decodeResult.raw.position = CoordinateUtils.decodeStringCoordinates(rawCoords);
|
|
906
1081
|
if (decodeResult.raw.position) {
|
|
@@ -914,7 +1089,9 @@ var Label_20_POS = class extends DecoderPlugin {
|
|
|
914
1089
|
decodeResult.decoded = true;
|
|
915
1090
|
decodeResult.decoder.decodeLevel = "full";
|
|
916
1091
|
} else if (fields.length == 5) {
|
|
917
|
-
|
|
1092
|
+
if (options.debug) {
|
|
1093
|
+
console.log(`DEBUG: ${this.name}: Variation 2 detected`);
|
|
1094
|
+
}
|
|
918
1095
|
const rawCoords = fields[0];
|
|
919
1096
|
decodeResult.raw.position = CoordinateUtils.decodeStringCoordinates(rawCoords);
|
|
920
1097
|
if (decodeResult.raw.position) {
|
|
@@ -928,7 +1105,9 @@ var Label_20_POS = class extends DecoderPlugin {
|
|
|
928
1105
|
decodeResult.decoded = true;
|
|
929
1106
|
decodeResult.decoder.decodeLevel = "full";
|
|
930
1107
|
} else {
|
|
931
|
-
|
|
1108
|
+
if (options.debug) {
|
|
1109
|
+
console.log(`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${content}`);
|
|
1110
|
+
}
|
|
932
1111
|
decodeResult.decoded = false;
|
|
933
1112
|
decodeResult.decoder.decodeLevel = "none";
|
|
934
1113
|
}
|
|
@@ -952,9 +1131,7 @@ var Label_21_POS = class extends DecoderPlugin {
|
|
|
952
1131
|
decodeResult.message = message;
|
|
953
1132
|
decodeResult.raw.preamble = message.text.substring(0, 3);
|
|
954
1133
|
const content = message.text.substring(3);
|
|
955
|
-
console.log("Content: " + content);
|
|
956
1134
|
const fields = content.split(",");
|
|
957
|
-
console.log("Field Count: " + fields.length);
|
|
958
1135
|
if (fields.length == 9) {
|
|
959
1136
|
processPosition(decodeResult, fields[0].trim());
|
|
960
1137
|
processAlt(decodeResult, fields[3]);
|
|
@@ -970,7 +1147,9 @@ var Label_21_POS = class extends DecoderPlugin {
|
|
|
970
1147
|
decodeResult.decoded = true;
|
|
971
1148
|
decodeResult.decoder.decodeLevel = "partial";
|
|
972
1149
|
} else {
|
|
973
|
-
|
|
1150
|
+
if (options.debug) {
|
|
1151
|
+
console.log(`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${content}`);
|
|
1152
|
+
}
|
|
974
1153
|
decodeResult.decoded = false;
|
|
975
1154
|
decodeResult.decoder.decodeLevel = "none";
|
|
976
1155
|
}
|
|
@@ -1352,6 +1531,64 @@ var Label_44_POS = class extends DecoderPlugin {
|
|
|
1352
1531
|
}
|
|
1353
1532
|
};
|
|
1354
1533
|
|
|
1534
|
+
// lib/plugins/Label_4N.ts
|
|
1535
|
+
var Label_4N = class extends DecoderPlugin {
|
|
1536
|
+
name = "label-4n";
|
|
1537
|
+
qualifiers() {
|
|
1538
|
+
return {
|
|
1539
|
+
labels: ["4N"]
|
|
1540
|
+
};
|
|
1541
|
+
}
|
|
1542
|
+
decode(message, options = {}) {
|
|
1543
|
+
const decodeResult = this.defaultResult();
|
|
1544
|
+
decodeResult.decoder.name = this.name;
|
|
1545
|
+
decodeResult.message = message;
|
|
1546
|
+
decodeResult.formatted.description = "Airline Defined";
|
|
1547
|
+
let text = message.text;
|
|
1548
|
+
if (text.match(/^M\d{2}A\w{6}/)) {
|
|
1549
|
+
ResultFormatter.flightNumber(decodeResult, message.text.substring(4, 10).replace(/^([A-Z]+)0*/g, "$1"));
|
|
1550
|
+
text = text.substring(10);
|
|
1551
|
+
}
|
|
1552
|
+
decodeResult.decoded = true;
|
|
1553
|
+
const fields = text.split(",");
|
|
1554
|
+
if (text.length === 51) {
|
|
1555
|
+
decodeResult.raw.day_of_month = text.substring(0, 2);
|
|
1556
|
+
ResultFormatter.departureAirport(decodeResult, text.substring(8, 11));
|
|
1557
|
+
ResultFormatter.arrivalAirport(decodeResult, text.substring(13, 16));
|
|
1558
|
+
ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(text.substring(30, 45).replace(/^(.)0/, "$1")));
|
|
1559
|
+
ResultFormatter.altitude(decodeResult, text.substring(48, 51) * 100);
|
|
1560
|
+
decodeResult.remaining.text = [text.substring(2, 4), text.substring(19, 29)].join(" ");
|
|
1561
|
+
} else if (fields.length === 33) {
|
|
1562
|
+
decodeResult.raw.date = fields[3];
|
|
1563
|
+
if (fields[1] === "B") {
|
|
1564
|
+
ResultFormatter.position(decodeResult, { latitude: Number(fields[4]), longitude: Number(fields[5]) });
|
|
1565
|
+
ResultFormatter.altitude(decodeResult, fields[6]);
|
|
1566
|
+
}
|
|
1567
|
+
ResultFormatter.departureAirport(decodeResult, fields[8]);
|
|
1568
|
+
ResultFormatter.arrivalAirport(decodeResult, fields[9]);
|
|
1569
|
+
ResultFormatter.alternateAirport(decodeResult, fields[10]);
|
|
1570
|
+
ResultFormatter.arrivalRunway(decodeResult, fields[11].split("/")[0]);
|
|
1571
|
+
if (fields[12].length > 1) {
|
|
1572
|
+
ResultFormatter.alternateRunway(decodeResult, fields[12].split("/")[0]);
|
|
1573
|
+
}
|
|
1574
|
+
ResultFormatter.checksum(decodeResult, fields[32]);
|
|
1575
|
+
decodeResult.remaining.text = [...fields.slice(1, 3), fields[7], ...fields.slice(13, 32)].filter((f) => f != "").join(",");
|
|
1576
|
+
} else {
|
|
1577
|
+
decodeResult.decoded = false;
|
|
1578
|
+
decodeResult.remaining.text = text;
|
|
1579
|
+
}
|
|
1580
|
+
if (decodeResult.decoded) {
|
|
1581
|
+
if (decodeResult.remaining.text === "")
|
|
1582
|
+
decodeResult.decoder.decodeLevel = "full";
|
|
1583
|
+
else
|
|
1584
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
1585
|
+
} else {
|
|
1586
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1587
|
+
}
|
|
1588
|
+
return decodeResult;
|
|
1589
|
+
}
|
|
1590
|
+
};
|
|
1591
|
+
|
|
1355
1592
|
// lib/plugins/Label_80.ts
|
|
1356
1593
|
var Label_80 = class extends DecoderPlugin {
|
|
1357
1594
|
name = "label-80";
|
|
@@ -1383,27 +1620,15 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
1383
1620
|
const parts = message.text.split("\n");
|
|
1384
1621
|
let posRptRegex = /^3N01 POSRPT \d\d\d\d\/\d\d (?<orig>\w+)\/(?<dest>\w+) \.(?<tail>[\w-]+)(\/(?<agate>.+) (?<sta>\w+:\w+))*/;
|
|
1385
1622
|
let results = parts[0].match(posRptRegex);
|
|
1623
|
+
if (!results?.groups) {
|
|
1624
|
+
decodeResult.decoded = false;
|
|
1625
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1626
|
+
return decodeResult;
|
|
1627
|
+
}
|
|
1386
1628
|
if (results && results.length > 0) {
|
|
1387
|
-
decodeResult
|
|
1388
|
-
decodeResult.
|
|
1389
|
-
|
|
1390
|
-
code: "ORG",
|
|
1391
|
-
label: "Origin",
|
|
1392
|
-
value: `${results.groups.orig}`
|
|
1393
|
-
});
|
|
1394
|
-
decodeResult.raw.destination = results.groups.dest;
|
|
1395
|
-
decodeResult.formatted.items.push({
|
|
1396
|
-
type: "destination",
|
|
1397
|
-
code: "DST",
|
|
1398
|
-
label: "Destination",
|
|
1399
|
-
value: `${results.groups.dest}`
|
|
1400
|
-
});
|
|
1401
|
-
decodeResult.raw.tail = results.groups.tail;
|
|
1402
|
-
decodeResult.formatted.items.push({
|
|
1403
|
-
type: "tail",
|
|
1404
|
-
label: "Tail",
|
|
1405
|
-
value: `${results.groups.tail}`
|
|
1406
|
-
});
|
|
1629
|
+
ResultFormatter.departureAirport(decodeResult, results.groups.orig);
|
|
1630
|
+
ResultFormatter.arrivalAirport(decodeResult, results.groups.dest);
|
|
1631
|
+
ResultFormatter.tail(decodeResult, results.groups.tail);
|
|
1407
1632
|
if (results.groups.agate) {
|
|
1408
1633
|
decodeResult.raw.arrival_gate = results.groups.agate;
|
|
1409
1634
|
decodeResult.formatted.items.push({
|
|
@@ -1425,15 +1650,9 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
1425
1650
|
for (const part of remainingParts) {
|
|
1426
1651
|
const matches = part.matchAll(posRptRegex);
|
|
1427
1652
|
for (const match of matches) {
|
|
1428
|
-
switch (match.groups
|
|
1653
|
+
switch (match.groups?.field) {
|
|
1429
1654
|
case "ALT": {
|
|
1430
|
-
|
|
1431
|
-
decodeResult.formatted.items.push({
|
|
1432
|
-
type: "altitude",
|
|
1433
|
-
code: "ALT",
|
|
1434
|
-
label: this.descriptions[match.groups.field],
|
|
1435
|
-
value: `${decodeResult.raw.altitude} feet`
|
|
1436
|
-
});
|
|
1655
|
+
ResultFormatter.altitude(decodeResult, Number(match.groups.value));
|
|
1437
1656
|
break;
|
|
1438
1657
|
}
|
|
1439
1658
|
case "DWND": {
|
|
@@ -1447,9 +1666,8 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
1447
1666
|
break;
|
|
1448
1667
|
}
|
|
1449
1668
|
case "FL": {
|
|
1450
|
-
const flight_level = match.groups.value;
|
|
1451
|
-
|
|
1452
|
-
ResultFormatter.altitude(decodeResult, decodeResult.raw.altitude);
|
|
1669
|
+
const flight_level = Number(match.groups.value);
|
|
1670
|
+
ResultFormatter.altitude(decodeResult, flight_level * 100);
|
|
1453
1671
|
break;
|
|
1454
1672
|
}
|
|
1455
1673
|
case "FOB": {
|
|
@@ -1473,7 +1691,7 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
1473
1691
|
break;
|
|
1474
1692
|
}
|
|
1475
1693
|
case "MCH": {
|
|
1476
|
-
decodeResult.raw.mach = match.groups.value / 1e3;
|
|
1694
|
+
decodeResult.raw.mach = Number(match.groups.value) / 1e3;
|
|
1477
1695
|
decodeResult.formatted.items.push({
|
|
1478
1696
|
type: "mach",
|
|
1479
1697
|
code: "MCH",
|
|
@@ -1495,20 +1713,13 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
1495
1713
|
case "POS": {
|
|
1496
1714
|
const posRegex = /^(?<latd>[NS])(?<lat>.+)(?<lngd>[EW])(?<lng>.+)/;
|
|
1497
1715
|
const posResult = match.groups.value.match(posRegex);
|
|
1498
|
-
const lat = Number(posResult
|
|
1499
|
-
const lon = Number(posResult
|
|
1500
|
-
const
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
latitude,
|
|
1504
|
-
longitude
|
|
1716
|
+
const lat = Number(posResult?.groups?.lat) * (posResult?.groups?.lngd === "S" ? -1 : 1);
|
|
1717
|
+
const lon = Number(posResult?.groups?.lng) * (posResult?.groups?.lngd === "W" ? -1 : 1);
|
|
1718
|
+
const position = {
|
|
1719
|
+
latitude: Number.isInteger(lat) ? lat / 1e3 : lat / 100,
|
|
1720
|
+
longitude: Number.isInteger(lon) ? lon / 1e3 : lon / 100
|
|
1505
1721
|
};
|
|
1506
|
-
|
|
1507
|
-
type: "position",
|
|
1508
|
-
code: "POS",
|
|
1509
|
-
label: "Position",
|
|
1510
|
-
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
1511
|
-
});
|
|
1722
|
+
ResultFormatter.position(decodeResult, position);
|
|
1512
1723
|
break;
|
|
1513
1724
|
}
|
|
1514
1725
|
case "SWND": {
|
|
@@ -1522,7 +1733,7 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
1522
1733
|
break;
|
|
1523
1734
|
}
|
|
1524
1735
|
default: {
|
|
1525
|
-
if (match.groups
|
|
1736
|
+
if (match.groups?.field != void 0) {
|
|
1526
1737
|
const description = this.descriptions[match.groups.field] ? this.descriptions[match.groups.field] : "Unknown";
|
|
1527
1738
|
decodeResult.formatted.items.push({
|
|
1528
1739
|
type: match.groups.field,
|
|
@@ -1536,7 +1747,77 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
1536
1747
|
}
|
|
1537
1748
|
}
|
|
1538
1749
|
decodeResult.decoded = true;
|
|
1539
|
-
decodeResult.decodeLevel = "partial";
|
|
1750
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
1751
|
+
}
|
|
1752
|
+
return decodeResult;
|
|
1753
|
+
}
|
|
1754
|
+
};
|
|
1755
|
+
|
|
1756
|
+
// lib/plugins/Label_83.ts
|
|
1757
|
+
var Label_83 = class extends DecoderPlugin {
|
|
1758
|
+
name = "label-83";
|
|
1759
|
+
qualifiers() {
|
|
1760
|
+
return {
|
|
1761
|
+
labels: ["83"]
|
|
1762
|
+
};
|
|
1763
|
+
}
|
|
1764
|
+
decode(message, options = {}) {
|
|
1765
|
+
const decodeResult = this.defaultResult();
|
|
1766
|
+
decodeResult.decoder.name = this.name;
|
|
1767
|
+
decodeResult.message = message;
|
|
1768
|
+
decodeResult.formatted.description = "Airline Defined";
|
|
1769
|
+
let text = message.text;
|
|
1770
|
+
if (text.match(/^M\d{2}A\w{6}/)) {
|
|
1771
|
+
ResultFormatter.flightNumber(decodeResult, message.text.substring(4, 10).replace(/^([A-Z]+)0*/g, "$1"));
|
|
1772
|
+
text = text.substring(10);
|
|
1773
|
+
}
|
|
1774
|
+
decodeResult.decoded = true;
|
|
1775
|
+
if (text.substring(0, 10) === "4DH3 ETAT2") {
|
|
1776
|
+
const fields = text.split(/\s+/);
|
|
1777
|
+
if (fields[2].length > 5) {
|
|
1778
|
+
decodeResult.raw.day_of_month = fields[2].substring(5);
|
|
1779
|
+
}
|
|
1780
|
+
decodeResult.remaining.text = fields[2].substring(0, 4);
|
|
1781
|
+
const subfields = fields[3].split("/");
|
|
1782
|
+
ResultFormatter.departureAirport(decodeResult, subfields[0]);
|
|
1783
|
+
ResultFormatter.arrivalAirport(decodeResult, subfields[1]);
|
|
1784
|
+
ResultFormatter.tail(decodeResult, fields[4].replace(/\./g, ""));
|
|
1785
|
+
ResultFormatter.eta(decodeResult, fields[6] + "00");
|
|
1786
|
+
} else if (text.substring(0, 5) === "001PR") {
|
|
1787
|
+
decodeResult.raw.day_of_month = text.substring(5, 7);
|
|
1788
|
+
ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(text.substring(13, 28).replace(/\./g, "")));
|
|
1789
|
+
ResultFormatter.altitude(decodeResult, Number(text.substring(28, 33)));
|
|
1790
|
+
decodeResult.remaining.text = text.substring(33);
|
|
1791
|
+
} else {
|
|
1792
|
+
const fields = text.replace(/\s/g, "").split(",");
|
|
1793
|
+
if (fields.length === 9) {
|
|
1794
|
+
ResultFormatter.departureAirport(decodeResult, fields[0]);
|
|
1795
|
+
ResultFormatter.arrivalAirport(decodeResult, fields[1]);
|
|
1796
|
+
decodeResult.raw.day_of_month = fields[2].substring(0, 2);
|
|
1797
|
+
decodeResult.raw.time = fields[2].substring(2);
|
|
1798
|
+
ResultFormatter.position(
|
|
1799
|
+
decodeResult,
|
|
1800
|
+
{
|
|
1801
|
+
latitude: Number(fields[3].replace(/\s/g, "")),
|
|
1802
|
+
longitude: Number(fields[4].replace(/\s/g, ""))
|
|
1803
|
+
}
|
|
1804
|
+
);
|
|
1805
|
+
ResultFormatter.altitude(decodeResult, fields[5]);
|
|
1806
|
+
ResultFormatter.groundspeed(decodeResult, fields[6]);
|
|
1807
|
+
ResultFormatter.heading(decodeResult, fields[7]);
|
|
1808
|
+
decodeResult.remaining.text = fields[8];
|
|
1809
|
+
} else {
|
|
1810
|
+
decodeResult.decoded = false;
|
|
1811
|
+
decodeResult.remaining.text = message.text;
|
|
1812
|
+
}
|
|
1813
|
+
}
|
|
1814
|
+
if (decodeResult.decoded) {
|
|
1815
|
+
if (decodeResult.remaining.text === "")
|
|
1816
|
+
decodeResult.decoder.decodeLevel = "full";
|
|
1817
|
+
else
|
|
1818
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
1819
|
+
} else {
|
|
1820
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1540
1821
|
}
|
|
1541
1822
|
return decodeResult;
|
|
1542
1823
|
}
|
|
@@ -1944,13 +2225,7 @@ function processTimeOfDeparture(decodeResult, data) {
|
|
|
1944
2225
|
return false;
|
|
1945
2226
|
}
|
|
1946
2227
|
function processIdentification(decodeResult, data) {
|
|
1947
|
-
|
|
1948
|
-
decodeResult.formatted.items.push({
|
|
1949
|
-
type: "tail",
|
|
1950
|
-
code: "TAIL",
|
|
1951
|
-
label: "Tail",
|
|
1952
|
-
value: decodeResult.raw.tail
|
|
1953
|
-
});
|
|
2228
|
+
ResultFormatter.tail(decodeResult, data[0]);
|
|
1954
2229
|
if (data.length > 1) {
|
|
1955
2230
|
decodeResult.raw.flight_number = data[1];
|
|
1956
2231
|
}
|
|
@@ -2047,8 +2322,6 @@ function processPS(decodeResult, data) {
|
|
|
2047
2322
|
} else {
|
|
2048
2323
|
allKnownFields = false;
|
|
2049
2324
|
}
|
|
2050
|
-
console.log("PS data.length: ", data.length);
|
|
2051
|
-
console.log("PS data: ", data);
|
|
2052
2325
|
if (data.length === 9) {
|
|
2053
2326
|
processRoute(decodeResult, data[3], data[1], data[5], data[4], void 0);
|
|
2054
2327
|
ResultFormatter.altitude(decodeResult, Number(data[2]) * 100);
|
|
@@ -2083,8 +2356,6 @@ function processPosition2(decodeResult, data) {
|
|
|
2083
2356
|
} else {
|
|
2084
2357
|
allKnownFields = false;
|
|
2085
2358
|
}
|
|
2086
|
-
console.log("data.length: ", data.length);
|
|
2087
|
-
console.log("data: ", data);
|
|
2088
2359
|
if (data.length >= 10) {
|
|
2089
2360
|
ResultFormatter.altitude(decodeResult, Number(data[3]) * 100);
|
|
2090
2361
|
processRoute(decodeResult, data[1], data[2], data[4], data[5], data[6]);
|
|
@@ -2142,7 +2413,7 @@ var Label_H1_FPN = class extends DecoderPlugin {
|
|
|
2142
2413
|
decodeResult.decoded = true;
|
|
2143
2414
|
decodeResult.decoder.decodeLevel = fulllyDecoded ? "full" : "partial";
|
|
2144
2415
|
if (decodeResult.formatted.items.length === 0) {
|
|
2145
|
-
if (options
|
|
2416
|
+
if (options.debug) {
|
|
2146
2417
|
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
2147
2418
|
}
|
|
2148
2419
|
decodeResult.remaining.text = message.text;
|
|
@@ -2172,7 +2443,7 @@ var Label_H1_FTX = class extends DecoderPlugin {
|
|
|
2172
2443
|
decodeResult.decoded = true;
|
|
2173
2444
|
decodeResult.decoder.decodeLevel = fulllyDecoded ? "full" : "partial";
|
|
2174
2445
|
if (decodeResult.formatted.items.length === 0) {
|
|
2175
|
-
if (options
|
|
2446
|
+
if (options.debug) {
|
|
2176
2447
|
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
2177
2448
|
}
|
|
2178
2449
|
decodeResult.remaining.text = message.text;
|
|
@@ -2203,7 +2474,7 @@ var Label_H1_INI = class extends DecoderPlugin {
|
|
|
2203
2474
|
decodeResult.decoded = true;
|
|
2204
2475
|
decodeResult.decoder.decodeLevel = fulllyDecoded ? "full" : "partial";
|
|
2205
2476
|
if (decodeResult.formatted.items.length === 0) {
|
|
2206
|
-
if (options
|
|
2477
|
+
if (options.debug) {
|
|
2207
2478
|
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
2208
2479
|
}
|
|
2209
2480
|
decodeResult.remaining.text = message.text;
|
|
@@ -2292,7 +2563,7 @@ var Label_H1_POS = class extends DecoderPlugin {
|
|
|
2292
2563
|
decodeResult.decoded = true;
|
|
2293
2564
|
decodeResult.decoder.decodeLevel = fulllyDecoded ? "full" : "partial";
|
|
2294
2565
|
if (decodeResult.formatted.items.length === 0) {
|
|
2295
|
-
if (options
|
|
2566
|
+
if (options.debug) {
|
|
2296
2567
|
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
2297
2568
|
}
|
|
2298
2569
|
decodeResult.remaining.text = message.text;
|
|
@@ -3534,6 +3805,7 @@ var MessageDecoder = class {
|
|
|
3534
3805
|
this.registerPlugin(new Label_10_POS(this));
|
|
3535
3806
|
this.registerPlugin(new Label_10_Slash(this));
|
|
3536
3807
|
this.registerPlugin(new Label_12_N_Space(this));
|
|
3808
|
+
this.registerPlugin(new Label_13Through18_Slash(this));
|
|
3537
3809
|
this.registerPlugin(new Label_15(this));
|
|
3538
3810
|
this.registerPlugin(new Label_15_FST(this));
|
|
3539
3811
|
this.registerPlugin(new Label_16_N_Space(this));
|
|
@@ -3545,6 +3817,7 @@ var MessageDecoder = class {
|
|
|
3545
3817
|
this.registerPlugin(new Label_44_OFF(this));
|
|
3546
3818
|
this.registerPlugin(new Label_44_ON(this));
|
|
3547
3819
|
this.registerPlugin(new Label_44_POS(this));
|
|
3820
|
+
this.registerPlugin(new Label_4N(this));
|
|
3548
3821
|
this.registerPlugin(new Label_B6_Forwardslash(this));
|
|
3549
3822
|
this.registerPlugin(new Label_H1_FPN(this));
|
|
3550
3823
|
this.registerPlugin(new Label_H1_FLR(this));
|
|
@@ -3555,6 +3828,7 @@ var MessageDecoder = class {
|
|
|
3555
3828
|
this.registerPlugin(new Label_H1_WRN(this));
|
|
3556
3829
|
this.registerPlugin(new Label_HX(this));
|
|
3557
3830
|
this.registerPlugin(new Label_80(this));
|
|
3831
|
+
this.registerPlugin(new Label_83(this));
|
|
3558
3832
|
this.registerPlugin(new Label_8E(this));
|
|
3559
3833
|
this.registerPlugin(new Label_1M_Slash(this));
|
|
3560
3834
|
this.registerPlugin(new Label_SQ(this));
|