@airframes/acars-decoder 1.6.13 → 1.6.15
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 +785 -676
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +785 -676
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -38,10 +38,13 @@ var DateTimeUtils = class {
|
|
|
38
38
|
}
|
|
39
39
|
/**
|
|
40
40
|
*
|
|
41
|
-
* @param time HHMMSS
|
|
41
|
+
* @param time HHMMSS or HHMM
|
|
42
42
|
* @returns seconds since midnight
|
|
43
43
|
*/
|
|
44
44
|
static convertHHMMSSToTod(time) {
|
|
45
|
+
if (time.length === 4) {
|
|
46
|
+
time += "00";
|
|
47
|
+
}
|
|
45
48
|
const h = Number(time.substring(0, 2));
|
|
46
49
|
const m = Number(time.substring(2, 4));
|
|
47
50
|
const s = Number(time.substring(4, 6));
|
|
@@ -566,27 +569,36 @@ var ResultFormatter = class {
|
|
|
566
569
|
});
|
|
567
570
|
}
|
|
568
571
|
static day(decodeResult, day) {
|
|
569
|
-
decodeResult.raw.
|
|
572
|
+
decodeResult.raw.day = day;
|
|
570
573
|
decodeResult.formatted.items.push({
|
|
571
|
-
type: "
|
|
574
|
+
type: "day",
|
|
572
575
|
code: "MSG_DAY",
|
|
573
576
|
label: "Day of Month",
|
|
574
577
|
value: `${day}`
|
|
575
578
|
});
|
|
576
579
|
}
|
|
580
|
+
static month(decodeResult, month) {
|
|
581
|
+
decodeResult.raw.month = month;
|
|
582
|
+
decodeResult.formatted.items.push({
|
|
583
|
+
type: "month",
|
|
584
|
+
code: "MSG_MON",
|
|
585
|
+
label: "Month of Year",
|
|
586
|
+
value: `${month}`
|
|
587
|
+
});
|
|
588
|
+
}
|
|
577
589
|
static departureDay(decodeResult, day) {
|
|
578
|
-
decodeResult.raw.
|
|
590
|
+
decodeResult.raw.departure_day = day;
|
|
579
591
|
decodeResult.formatted.items.push({
|
|
580
|
-
type: "
|
|
592
|
+
type: "day",
|
|
581
593
|
code: "DEP_DAY",
|
|
582
594
|
label: "Departure Day",
|
|
583
595
|
value: `${day}`
|
|
584
596
|
});
|
|
585
597
|
}
|
|
586
598
|
static arrivalDay(decodeResult, day) {
|
|
587
|
-
decodeResult.raw.
|
|
599
|
+
decodeResult.raw.arrival_day = day;
|
|
588
600
|
decodeResult.formatted.items.push({
|
|
589
|
-
type: "
|
|
601
|
+
type: "day",
|
|
590
602
|
code: "ARR_DAY",
|
|
591
603
|
label: "Arrival Day",
|
|
592
604
|
value: `${day}`
|
|
@@ -681,14 +693,14 @@ var Label_5Z_Slash = class extends DecoderPlugin {
|
|
|
681
693
|
const info = data[2].split(" ");
|
|
682
694
|
ResultFormatter.departureAirport(decodeResult, info[1]);
|
|
683
695
|
ResultFormatter.arrivalAirport(decodeResult, info[2]);
|
|
684
|
-
decodeResult.raw.
|
|
696
|
+
decodeResult.raw.day = Number(info[3]);
|
|
685
697
|
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(info[4]));
|
|
686
698
|
ResultFormatter.arrivalRunway(decodeResult, info[5].slice(1));
|
|
687
699
|
ResultFormatter.unknownArr(decodeResult, data.slice(3), "/");
|
|
688
700
|
} else if (type === "B3") {
|
|
689
701
|
ResultFormatter.departureAirport(decodeResult, header[1].substring(0, 3), "IATA");
|
|
690
702
|
ResultFormatter.arrivalAirport(decodeResult, header[1].substring(3), "IATA");
|
|
691
|
-
decodeResult.raw.
|
|
703
|
+
decodeResult.raw.day = Number(header[2]);
|
|
692
704
|
ResultFormatter.arrivalRunway(decodeResult, header[3].slice(1));
|
|
693
705
|
if (header.length > 4) {
|
|
694
706
|
ResultFormatter.unknownArr(decodeResult, header.slice(4), "/");
|
|
@@ -697,7 +709,7 @@ var Label_5Z_Slash = class extends DecoderPlugin {
|
|
|
697
709
|
const info = data[2].split(" ");
|
|
698
710
|
ResultFormatter.departureAirport(decodeResult, info[1]);
|
|
699
711
|
ResultFormatter.arrivalAirport(decodeResult, info[2]);
|
|
700
|
-
decodeResult.raw.
|
|
712
|
+
decodeResult.raw.day = Number(info[3]);
|
|
701
713
|
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(info[4]));
|
|
702
714
|
ResultFormatter.unknownArr(decodeResult, info.slice(5), " ");
|
|
703
715
|
} else if (type === "C3") {
|
|
@@ -707,10 +719,10 @@ var Label_5Z_Slash = class extends DecoderPlugin {
|
|
|
707
719
|
const airports = data[2].split(" ");
|
|
708
720
|
ResultFormatter.departureAirport(decodeResult, airports[1]);
|
|
709
721
|
ResultFormatter.arrivalAirport(decodeResult, airports[2]);
|
|
710
|
-
decodeResult.raw.
|
|
722
|
+
decodeResult.raw.day = Number(airports[3]);
|
|
711
723
|
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(airports[4]));
|
|
712
724
|
const estimates = data[3].split(" ");
|
|
713
|
-
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(estimates[1]
|
|
725
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(estimates[1]));
|
|
714
726
|
ResultFormatter.unknown(decodeResult, estimates[2]);
|
|
715
727
|
} else {
|
|
716
728
|
if (options.debug) {
|
|
@@ -854,16 +866,16 @@ var Label_10_Slash = class extends DecoderPlugin {
|
|
|
854
866
|
ResultFormatter.heading(decodeResult, Number(parts[5]));
|
|
855
867
|
ResultFormatter.altitude(decodeResult, 100 * Number(parts[6]));
|
|
856
868
|
ResultFormatter.arrivalAirport(decodeResult, parts[7]);
|
|
857
|
-
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[8]
|
|
869
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[8]));
|
|
858
870
|
const waypoints = [{
|
|
859
871
|
name: parts[11]
|
|
860
872
|
}, {
|
|
861
873
|
name: parts[12],
|
|
862
|
-
time: DateTimeUtils.convertHHMMSSToTod(parts[13]
|
|
874
|
+
time: DateTimeUtils.convertHHMMSSToTod(parts[13]),
|
|
863
875
|
timeFormat: "tod"
|
|
864
876
|
}, {
|
|
865
877
|
name: parts[14],
|
|
866
|
-
time: DateTimeUtils.convertHHMMSSToTod(parts[15]
|
|
878
|
+
time: DateTimeUtils.convertHHMMSSToTod(parts[15]),
|
|
867
879
|
timeFormat: "tod"
|
|
868
880
|
}];
|
|
869
881
|
ResultFormatter.route(decodeResult, { waypoints });
|
|
@@ -883,7 +895,7 @@ var Label_12_N_Space = class extends DecoderPlugin {
|
|
|
883
895
|
qualifiers() {
|
|
884
896
|
return {
|
|
885
897
|
labels: ["12"],
|
|
886
|
-
preambles: ["N "]
|
|
898
|
+
preambles: ["N ", "S "]
|
|
887
899
|
};
|
|
888
900
|
}
|
|
889
901
|
decode(message, options = {}) {
|
|
@@ -949,7 +961,7 @@ var Label_13Through18_Slash = class extends DecoderPlugin {
|
|
|
949
961
|
const data = parts[2].split(" ");
|
|
950
962
|
ResultFormatter.departureAirport(decodeResult, data[1]);
|
|
951
963
|
ResultFormatter.arrivalAirport(decodeResult, data[2]);
|
|
952
|
-
decodeResult.raw.
|
|
964
|
+
decodeResult.raw.day = Number(data[3]);
|
|
953
965
|
const time = DateTimeUtils.convertHHMMSSToTod(data[4]);
|
|
954
966
|
if (labelNumber === 13) {
|
|
955
967
|
ResultFormatter.out(decodeResult, time);
|
|
@@ -1009,7 +1021,7 @@ function getMsgType(labelNumber) {
|
|
|
1009
1021
|
|
|
1010
1022
|
// lib/plugins/Label_15.ts
|
|
1011
1023
|
var Label_15 = class extends DecoderPlugin {
|
|
1012
|
-
name = "label-
|
|
1024
|
+
name = "label-15";
|
|
1013
1025
|
qualifiers() {
|
|
1014
1026
|
return {
|
|
1015
1027
|
labels: ["15"],
|
|
@@ -1020,10 +1032,28 @@ var Label_15 = class extends DecoderPlugin {
|
|
|
1020
1032
|
const decodeResult = this.defaultResult();
|
|
1021
1033
|
decodeResult.decoder.name = this.name;
|
|
1022
1034
|
decodeResult.formatted.description = "Position Report";
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
ResultFormatter.position(decodeResult, CoordinateUtils.
|
|
1035
|
+
decodeResult.message = message;
|
|
1036
|
+
if (message.text.startsWith("(2") && message.text.endsWith("(Z")) {
|
|
1037
|
+
const between = message.text.substring(2, message.text.length - 2);
|
|
1038
|
+
ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(between.substring(0, 13)));
|
|
1039
|
+
if (between.length === 25) {
|
|
1040
|
+
ResultFormatter.unknown(decodeResult, between.substring(13, 19));
|
|
1041
|
+
const alt = between.substring(19, 22);
|
|
1042
|
+
if (alt != "---") {
|
|
1043
|
+
ResultFormatter.altitude(decodeResult, 100 * Number(alt));
|
|
1044
|
+
}
|
|
1045
|
+
ResultFormatter.temperature(decodeResult, between.substring(22).replace(" ", "0"));
|
|
1046
|
+
} else {
|
|
1047
|
+
ResultFormatter.unknown(decodeResult, between.substring(13));
|
|
1048
|
+
}
|
|
1049
|
+
} else {
|
|
1050
|
+
if (options.debug) {
|
|
1051
|
+
console.log(`Decoder: Unknown 15 message: ${message.text}`);
|
|
1052
|
+
}
|
|
1053
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
1054
|
+
decodeResult.decoded = false;
|
|
1055
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1056
|
+
return decodeResult;
|
|
1027
1057
|
}
|
|
1028
1058
|
decodeResult.decoded = true;
|
|
1029
1059
|
decodeResult.decoder.decodeLevel = "partial";
|
|
@@ -1076,7 +1106,7 @@ var Label_16_N_Space = class extends DecoderPlugin {
|
|
|
1076
1106
|
qualifiers() {
|
|
1077
1107
|
return {
|
|
1078
1108
|
labels: ["16"],
|
|
1079
|
-
preambles: ["N "]
|
|
1109
|
+
preambles: ["N ", "S "]
|
|
1080
1110
|
};
|
|
1081
1111
|
}
|
|
1082
1112
|
decode(message, options = {}) {
|
|
@@ -1206,7 +1236,7 @@ var Label_1L_3Line = class extends DecoderPlugin {
|
|
|
1206
1236
|
}
|
|
1207
1237
|
const eta = data.get("ETA");
|
|
1208
1238
|
if (eta) {
|
|
1209
|
-
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(eta
|
|
1239
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(eta));
|
|
1210
1240
|
data.delete("ETA");
|
|
1211
1241
|
}
|
|
1212
1242
|
const alt = data.get("ALT");
|
|
@@ -1287,8 +1317,8 @@ var Label_1L_070 = class extends DecoderPlugin {
|
|
|
1287
1317
|
}
|
|
1288
1318
|
ResultFormatter.departureAirport(decodeResult, parts[0]);
|
|
1289
1319
|
ResultFormatter.arrivalAirport(decodeResult, parts[1]);
|
|
1290
|
-
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[2]
|
|
1291
|
-
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[3]
|
|
1320
|
+
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[2]));
|
|
1321
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[3]));
|
|
1292
1322
|
ResultFormatter.position(decodeResult, {
|
|
1293
1323
|
latitude: CoordinateUtils.getDirection(parts[4][0]) * Number(parts[4].substring(1)),
|
|
1294
1324
|
longitude: CoordinateUtils.getDirection(parts[5][0]) * Number(parts[5].substring(1))
|
|
@@ -1408,7 +1438,7 @@ var Label_1L_Slash = class extends DecoderPlugin {
|
|
|
1408
1438
|
}
|
|
1409
1439
|
const eta = data.get("ETA");
|
|
1410
1440
|
if (eta) {
|
|
1411
|
-
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(eta
|
|
1441
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(eta));
|
|
1412
1442
|
data.delete("ETA");
|
|
1413
1443
|
}
|
|
1414
1444
|
let remaining = "";
|
|
@@ -1542,7 +1572,7 @@ var Label_22_OFF = class extends DecoderPlugin {
|
|
|
1542
1572
|
ResultFormatter.flightNumber(decodeResult, fields[0]);
|
|
1543
1573
|
ResultFormatter.departureDay(decodeResult, Number(fields[1].substring(0, 2)));
|
|
1544
1574
|
ResultFormatter.arrivalDay(decodeResult, Number(fields[1].substring(2, 4)));
|
|
1545
|
-
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(4, 8)
|
|
1575
|
+
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(4, 8)));
|
|
1546
1576
|
ResultFormatter.departureAirport(decodeResult, fields[1].substring(8, 12));
|
|
1547
1577
|
ResultFormatter.arrivalAirport(decodeResult, fields[1].substring(12, 16));
|
|
1548
1578
|
ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(16, 22)));
|
|
@@ -1558,7 +1588,7 @@ var Label_22_OFF = class extends DecoderPlugin {
|
|
|
1558
1588
|
}
|
|
1559
1589
|
ResultFormatter.departureAirport(decodeResult, fields[0]);
|
|
1560
1590
|
ResultFormatter.arrivalAirport(decodeResult, fields[1]);
|
|
1561
|
-
ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[2]
|
|
1591
|
+
ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[2]));
|
|
1562
1592
|
ResultFormatter.unknown(decodeResult, fields[3]);
|
|
1563
1593
|
decodeResult.decoded = true;
|
|
1564
1594
|
decodeResult.decoder.decodeLevel = "partial";
|
|
@@ -1575,12 +1605,12 @@ var Label_22_OFF = class extends DecoderPlugin {
|
|
|
1575
1605
|
ResultFormatter.position(decodeResult, position);
|
|
1576
1606
|
}
|
|
1577
1607
|
ResultFormatter.day(decodeResult, Number(fields[1].substring(14, 16)));
|
|
1578
|
-
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(16, 20)
|
|
1608
|
+
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(16, 20)));
|
|
1579
1609
|
ResultFormatter.departureAirport(decodeResult, fields[1].substring(20, 24));
|
|
1580
1610
|
ResultFormatter.arrivalAirport(decodeResult, fields[1].substring(24, 28));
|
|
1581
|
-
ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(28, 32)
|
|
1611
|
+
ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(28, 32)));
|
|
1582
1612
|
ResultFormatter.unknown(decodeResult, fields[1].substring(32, 36));
|
|
1583
|
-
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(36, 40)
|
|
1613
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(36, 40)));
|
|
1584
1614
|
decodeResult.decoded = true;
|
|
1585
1615
|
decodeResult.decoder.decodeLevel = "partial";
|
|
1586
1616
|
} else {
|
|
@@ -1662,7 +1692,7 @@ var Label_24_Slash = class extends DecoderPlugin {
|
|
|
1662
1692
|
longitude: (lon[0] === "E" ? 1 : -1) * Number(lon.substring(1))
|
|
1663
1693
|
};
|
|
1664
1694
|
ResultFormatter.position(decodeResult, position);
|
|
1665
|
-
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[8]
|
|
1695
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[8]));
|
|
1666
1696
|
ResultFormatter.unknown(decodeResult, fields[7]);
|
|
1667
1697
|
decodeResult.decoded = true;
|
|
1668
1698
|
decodeResult.decoder.decodeLevel = "partial";
|
|
@@ -1698,7 +1728,7 @@ var Label_30_Slash_EA = class extends DecoderPlugin {
|
|
|
1698
1728
|
console.log(results);
|
|
1699
1729
|
}
|
|
1700
1730
|
}
|
|
1701
|
-
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(results[0].substr(2, 4)
|
|
1731
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(results[0].substr(2, 4)));
|
|
1702
1732
|
if (results[1].substring(0, 2) === "DS") {
|
|
1703
1733
|
ResultFormatter.arrivalAirport(decodeResult, results[1].substring(2, 6));
|
|
1704
1734
|
ResultFormatter.unknown(decodeResult, "/".concat(results[2]));
|
|
@@ -1725,22 +1755,35 @@ var Label_44_ETA = class extends DecoderPlugin {
|
|
|
1725
1755
|
decodeResult.decoder.name = this.name;
|
|
1726
1756
|
decodeResult.formatted.description = "ETA Report";
|
|
1727
1757
|
decodeResult.message = message;
|
|
1728
|
-
const
|
|
1729
|
-
|
|
1730
|
-
if (results?.groups) {
|
|
1758
|
+
const data = message.text.split(",");
|
|
1759
|
+
if (data.length >= 9) {
|
|
1731
1760
|
if (options.debug) {
|
|
1732
1761
|
console.log(`Label 44 ETA Report: groups`);
|
|
1733
|
-
console.log(
|
|
1762
|
+
console.log(data);
|
|
1734
1763
|
}
|
|
1735
|
-
ResultFormatter.position(decodeResult, CoordinateUtils.
|
|
1736
|
-
ResultFormatter.
|
|
1737
|
-
ResultFormatter.
|
|
1738
|
-
decodeResult
|
|
1739
|
-
|
|
1740
|
-
);
|
|
1741
|
-
|
|
1742
|
-
|
|
1764
|
+
ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1]));
|
|
1765
|
+
ResultFormatter.altitude(decodeResult, 100 * Number(data[2]));
|
|
1766
|
+
ResultFormatter.departureAirport(decodeResult, data[3]);
|
|
1767
|
+
ResultFormatter.arrivalAirport(decodeResult, data[4]);
|
|
1768
|
+
ResultFormatter.month(decodeResult, Number(data[5].substring(0, 2)));
|
|
1769
|
+
ResultFormatter.day(decodeResult, Number(data[5].substring(2, 4)));
|
|
1770
|
+
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[6]));
|
|
1771
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[7]));
|
|
1772
|
+
const fuel = Number(data[8]);
|
|
1773
|
+
if (!isNaN(fuel)) {
|
|
1774
|
+
ResultFormatter.remainingFuel(decodeResult, Number(fuel));
|
|
1775
|
+
}
|
|
1776
|
+
if (data.length > 9) {
|
|
1777
|
+
ResultFormatter.unknownArr(decodeResult, data.slice(9));
|
|
1778
|
+
}
|
|
1779
|
+
} else {
|
|
1780
|
+
if (options.debug) {
|
|
1781
|
+
console.log(`Decoder: Unknown 44 message: ${message.text}`);
|
|
1743
1782
|
}
|
|
1783
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
1784
|
+
decodeResult.decoded = false;
|
|
1785
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1786
|
+
return decodeResult;
|
|
1744
1787
|
}
|
|
1745
1788
|
decodeResult.decoded = true;
|
|
1746
1789
|
decodeResult.decoder.decodeLevel = "full";
|
|
@@ -1762,22 +1805,33 @@ var Label_44_IN = class extends DecoderPlugin {
|
|
|
1762
1805
|
decodeResult.decoder.name = this.name;
|
|
1763
1806
|
decodeResult.formatted.description = "In Air Report";
|
|
1764
1807
|
decodeResult.message = message;
|
|
1765
|
-
const
|
|
1766
|
-
|
|
1767
|
-
if (results?.groups) {
|
|
1808
|
+
const data = message.text.split(",");
|
|
1809
|
+
if (data.length >= 7) {
|
|
1768
1810
|
if (options.debug) {
|
|
1769
1811
|
console.log(`Label 44 In Air Report: groups`);
|
|
1770
|
-
console.log(
|
|
1812
|
+
console.log(data);
|
|
1771
1813
|
}
|
|
1772
|
-
ResultFormatter.position(decodeResult, CoordinateUtils.
|
|
1773
|
-
ResultFormatter.departureAirport(decodeResult,
|
|
1774
|
-
ResultFormatter.arrivalAirport(decodeResult,
|
|
1775
|
-
decodeResult
|
|
1776
|
-
|
|
1777
|
-
);
|
|
1778
|
-
|
|
1779
|
-
|
|
1814
|
+
ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1]));
|
|
1815
|
+
ResultFormatter.departureAirport(decodeResult, data[2]);
|
|
1816
|
+
ResultFormatter.arrivalAirport(decodeResult, data[3]);
|
|
1817
|
+
ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
|
|
1818
|
+
ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
|
|
1819
|
+
ResultFormatter.in(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[5]));
|
|
1820
|
+
const fuel = Number(data[6]);
|
|
1821
|
+
if (!isNaN(fuel)) {
|
|
1822
|
+
ResultFormatter.remainingFuel(decodeResult, Number(fuel));
|
|
1823
|
+
}
|
|
1824
|
+
if (data.length > 7) {
|
|
1825
|
+
ResultFormatter.unknownArr(decodeResult, data.slice(7));
|
|
1826
|
+
}
|
|
1827
|
+
} else {
|
|
1828
|
+
if (options.debug) {
|
|
1829
|
+
console.log(`Decoder: Unknown 44 message: ${message.text}`);
|
|
1780
1830
|
}
|
|
1831
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
1832
|
+
decodeResult.decoded = false;
|
|
1833
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1834
|
+
return decodeResult;
|
|
1781
1835
|
}
|
|
1782
1836
|
decodeResult.decoded = true;
|
|
1783
1837
|
decodeResult.decoder.decodeLevel = "full";
|
|
@@ -1799,25 +1853,34 @@ var Label_44_OFF = class extends DecoderPlugin {
|
|
|
1799
1853
|
decodeResult.decoder.name = this.name;
|
|
1800
1854
|
decodeResult.formatted.description = "Off Runway Report";
|
|
1801
1855
|
decodeResult.message = message;
|
|
1802
|
-
const
|
|
1803
|
-
|
|
1804
|
-
if (results?.groups) {
|
|
1856
|
+
const data = message.text.split(",");
|
|
1857
|
+
if (data.length >= 8) {
|
|
1805
1858
|
if (options.debug) {
|
|
1806
1859
|
console.log(`Label 44 Off Runway Report: groups`);
|
|
1807
|
-
console.log(
|
|
1860
|
+
console.log(data);
|
|
1808
1861
|
}
|
|
1809
|
-
ResultFormatter.position(decodeResult, CoordinateUtils.
|
|
1810
|
-
ResultFormatter.departureAirport(decodeResult,
|
|
1811
|
-
ResultFormatter.arrivalAirport(decodeResult,
|
|
1812
|
-
decodeResult
|
|
1813
|
-
|
|
1814
|
-
);
|
|
1815
|
-
decodeResult
|
|
1816
|
-
|
|
1817
|
-
)
|
|
1818
|
-
|
|
1819
|
-
|
|
1862
|
+
ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1]));
|
|
1863
|
+
ResultFormatter.departureAirport(decodeResult, data[2]);
|
|
1864
|
+
ResultFormatter.arrivalAirport(decodeResult, data[3]);
|
|
1865
|
+
ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
|
|
1866
|
+
ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
|
|
1867
|
+
ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[5]));
|
|
1868
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[6]));
|
|
1869
|
+
const fuel = Number(data[7]);
|
|
1870
|
+
if (!isNaN(fuel)) {
|
|
1871
|
+
ResultFormatter.remainingFuel(decodeResult, Number(fuel));
|
|
1872
|
+
}
|
|
1873
|
+
if (data.length > 8) {
|
|
1874
|
+
ResultFormatter.unknownArr(decodeResult, data.slice(8));
|
|
1875
|
+
}
|
|
1876
|
+
} else {
|
|
1877
|
+
if (options.debug) {
|
|
1878
|
+
console.log(`Decoder: Unknown 44 message: ${message.text}`);
|
|
1820
1879
|
}
|
|
1880
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
1881
|
+
decodeResult.decoded = false;
|
|
1882
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1883
|
+
return decodeResult;
|
|
1821
1884
|
}
|
|
1822
1885
|
decodeResult.decoded = true;
|
|
1823
1886
|
decodeResult.decoder.decodeLevel = "full";
|
|
@@ -1839,22 +1902,33 @@ var Label_44_ON = class extends DecoderPlugin {
|
|
|
1839
1902
|
decodeResult.decoder.name = this.name;
|
|
1840
1903
|
decodeResult.formatted.description = "On Runway Report";
|
|
1841
1904
|
decodeResult.message = message;
|
|
1842
|
-
const
|
|
1843
|
-
|
|
1844
|
-
if (results?.groups) {
|
|
1905
|
+
const data = message.text.split(",");
|
|
1906
|
+
if (data.length >= 7) {
|
|
1845
1907
|
if (options.debug) {
|
|
1846
1908
|
console.log(`Label 44 On Runway Report: groups`);
|
|
1847
|
-
console.log(
|
|
1909
|
+
console.log(data);
|
|
1848
1910
|
}
|
|
1849
|
-
ResultFormatter.position(decodeResult, CoordinateUtils.
|
|
1850
|
-
ResultFormatter.departureAirport(decodeResult,
|
|
1851
|
-
ResultFormatter.arrivalAirport(decodeResult,
|
|
1852
|
-
decodeResult
|
|
1853
|
-
|
|
1854
|
-
);
|
|
1855
|
-
|
|
1856
|
-
|
|
1911
|
+
ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1]));
|
|
1912
|
+
ResultFormatter.departureAirport(decodeResult, data[2]);
|
|
1913
|
+
ResultFormatter.arrivalAirport(decodeResult, data[3]);
|
|
1914
|
+
ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
|
|
1915
|
+
ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
|
|
1916
|
+
ResultFormatter.on(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[5]));
|
|
1917
|
+
const fuel = Number(data[6]);
|
|
1918
|
+
if (!isNaN(fuel)) {
|
|
1919
|
+
ResultFormatter.remainingFuel(decodeResult, Number(fuel));
|
|
1920
|
+
}
|
|
1921
|
+
if (data.length > 7) {
|
|
1922
|
+
ResultFormatter.unknownArr(decodeResult, data.slice(7));
|
|
1923
|
+
}
|
|
1924
|
+
} else {
|
|
1925
|
+
if (options.debug) {
|
|
1926
|
+
console.log(`Decoder: Unknown 44 message: ${message.text}`);
|
|
1857
1927
|
}
|
|
1928
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
1929
|
+
decodeResult.decoded = false;
|
|
1930
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1931
|
+
return decodeResult;
|
|
1858
1932
|
}
|
|
1859
1933
|
decodeResult.decoded = true;
|
|
1860
1934
|
decodeResult.decoder.decodeLevel = "full";
|
|
@@ -2113,456 +2187,95 @@ var Label_4A_Slash_01 = class extends DecoderPlugin {
|
|
|
2113
2187
|
}
|
|
2114
2188
|
};
|
|
2115
2189
|
|
|
2116
|
-
// lib/
|
|
2117
|
-
var
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
let
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2190
|
+
// lib/utils/flight_plan_utils.ts
|
|
2191
|
+
var FlightPlanUtils = class _FlightPlanUtils {
|
|
2192
|
+
/**
|
|
2193
|
+
* Processes flight plan data
|
|
2194
|
+
*
|
|
2195
|
+
* Expected format is [header, key1, val1, ... keyN, valN]
|
|
2196
|
+
*
|
|
2197
|
+
* @param decodeResult - results
|
|
2198
|
+
* @param data - original message split by ':'
|
|
2199
|
+
* @returns whether all fields were processed or not
|
|
2200
|
+
*/
|
|
2201
|
+
static processFlightPlan(decodeResult, data) {
|
|
2202
|
+
let allKnownFields = _FlightPlanUtils.parseHeader(decodeResult, data[0]);
|
|
2203
|
+
for (let i = 1; i < data.length; i += 2) {
|
|
2204
|
+
const key = data[i];
|
|
2205
|
+
const value = data[i + 1];
|
|
2206
|
+
switch (key) {
|
|
2207
|
+
case "A":
|
|
2208
|
+
addProcedure(decodeResult, value, "arrival");
|
|
2209
|
+
break;
|
|
2210
|
+
case "AA":
|
|
2211
|
+
addArrivalAirport(decodeResult, value);
|
|
2212
|
+
break;
|
|
2213
|
+
case "AP":
|
|
2214
|
+
addProcedure(decodeResult, value, "approach");
|
|
2215
|
+
break;
|
|
2216
|
+
case "CR":
|
|
2217
|
+
addCompanyRoute(decodeResult, value);
|
|
2218
|
+
break;
|
|
2219
|
+
case "D":
|
|
2220
|
+
addProcedure(decodeResult, value, "departure");
|
|
2221
|
+
break;
|
|
2222
|
+
case "DA":
|
|
2223
|
+
addDepartureAirport(decodeResult, value);
|
|
2224
|
+
break;
|
|
2225
|
+
case "F":
|
|
2226
|
+
addRoute(decodeResult, value);
|
|
2227
|
+
break;
|
|
2228
|
+
case "R":
|
|
2229
|
+
addRunway(decodeResult, value);
|
|
2230
|
+
break;
|
|
2231
|
+
// case 'WS': // something about routes, has altitude, so current parsing won't work
|
|
2232
|
+
// break;
|
|
2233
|
+
default:
|
|
2234
|
+
if (allKnownFields) {
|
|
2235
|
+
decodeResult.remaining.text = "";
|
|
2236
|
+
allKnownFields = false;
|
|
2237
|
+
}
|
|
2238
|
+
decodeResult.remaining.text += `:${key}:${value}`;
|
|
2239
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
2155
2240
|
}
|
|
2156
|
-
ResultFormatter.checksum(decodeResult, fields[32]);
|
|
2157
|
-
ResultFormatter.unknownArr(decodeResult, [...fields.slice(1, 3), fields[7], ...fields.slice(13, 32)].filter((f) => f != ""));
|
|
2158
|
-
} else {
|
|
2159
|
-
decodeResult.decoded = false;
|
|
2160
|
-
ResultFormatter.unknown(decodeResult, text);
|
|
2161
2241
|
}
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2242
|
+
return allKnownFields;
|
|
2243
|
+
}
|
|
2244
|
+
static parseHeader(decodeResult, header) {
|
|
2245
|
+
let allKnownFields = true;
|
|
2246
|
+
if (header.startsWith("RF")) {
|
|
2247
|
+
decodeResult.formatted.items.push({
|
|
2248
|
+
type: "status",
|
|
2249
|
+
code: "ROUTE_STATUS",
|
|
2250
|
+
label: "Route Status",
|
|
2251
|
+
value: "Route Filed"
|
|
2252
|
+
});
|
|
2253
|
+
decodeResult.raw.route_status = "RF";
|
|
2254
|
+
if (header.length > 2) {
|
|
2255
|
+
addRoute(decodeResult, header.substring(2));
|
|
2256
|
+
}
|
|
2257
|
+
} else if (header.startsWith("RP")) {
|
|
2258
|
+
decodeResult.raw.route_status = "RP";
|
|
2259
|
+
decodeResult.formatted.items.push({
|
|
2260
|
+
type: "status",
|
|
2261
|
+
code: "ROUTE_STATUS",
|
|
2262
|
+
label: "Route Status",
|
|
2263
|
+
value: "Route Planned"
|
|
2264
|
+
});
|
|
2265
|
+
decodeResult.raw.route_status = header;
|
|
2266
|
+
} else if (header.startsWith("RI")) {
|
|
2267
|
+
decodeResult.raw.route_status = "RI";
|
|
2268
|
+
decodeResult.formatted.items.push({
|
|
2269
|
+
type: "status",
|
|
2270
|
+
code: "ROUTE_STATUS",
|
|
2271
|
+
label: "Route Status",
|
|
2272
|
+
value: "Route Inactive"
|
|
2273
|
+
});
|
|
2167
2274
|
} else {
|
|
2168
|
-
decodeResult.
|
|
2275
|
+
decodeResult.remaining.text += header;
|
|
2276
|
+
allKnownFields = false;
|
|
2169
2277
|
}
|
|
2170
|
-
return
|
|
2171
|
-
}
|
|
2172
|
-
};
|
|
2173
|
-
|
|
2174
|
-
// lib/plugins/Label_80.ts
|
|
2175
|
-
var Label_80 = class extends DecoderPlugin {
|
|
2176
|
-
name = "label-80";
|
|
2177
|
-
descriptions = {
|
|
2178
|
-
ALT: "Altitude",
|
|
2179
|
-
DWND: "Wind Direction",
|
|
2180
|
-
ETA: "Estimated Time of Arrival",
|
|
2181
|
-
FOB: "Fuel on Board",
|
|
2182
|
-
FL: "Flight Level",
|
|
2183
|
-
HDG: "Heading",
|
|
2184
|
-
MCH: "Aircraft Speed",
|
|
2185
|
-
NWYP: "Next Waypoint",
|
|
2186
|
-
POS: "Aircraft Position",
|
|
2187
|
-
SAT: "Static Air Temperature",
|
|
2188
|
-
SWND: "Wind Speed",
|
|
2189
|
-
TAS: "True Airspeed",
|
|
2190
|
-
WYP: "Waypoint"
|
|
2191
|
-
};
|
|
2192
|
-
qualifiers() {
|
|
2193
|
-
return {
|
|
2194
|
-
labels: ["80"],
|
|
2195
|
-
preambles: ["3N01 POSRPT"]
|
|
2196
|
-
};
|
|
2197
|
-
}
|
|
2198
|
-
decode(message, options = {}) {
|
|
2199
|
-
const decodeResult = this.defaultResult();
|
|
2200
|
-
decodeResult.decoder.name = this.name;
|
|
2201
|
-
decodeResult.formatted.description = "Airline Defined Position Report";
|
|
2202
|
-
const parts = message.text.split("\n");
|
|
2203
|
-
let posRptRegex = /^3N01 POSRPT \d\d\d\d\/\d\d (?<orig>\w+)\/(?<dest>\w+) \.(?<tail>[\w-]+)(\/(?<agate>.+) (?<sta>\w+:\w+))*/;
|
|
2204
|
-
let results = parts[0].match(posRptRegex);
|
|
2205
|
-
if (!results?.groups) {
|
|
2206
|
-
decodeResult.decoded = false;
|
|
2207
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
2208
|
-
return decodeResult;
|
|
2209
|
-
}
|
|
2210
|
-
if (results && results.length > 0) {
|
|
2211
|
-
ResultFormatter.departureAirport(decodeResult, results.groups.orig);
|
|
2212
|
-
ResultFormatter.arrivalAirport(decodeResult, results.groups.dest);
|
|
2213
|
-
ResultFormatter.tail(decodeResult, results.groups.tail);
|
|
2214
|
-
if (results.groups.agate) {
|
|
2215
|
-
decodeResult.raw.arrival_gate = results.groups.agate;
|
|
2216
|
-
decodeResult.formatted.items.push({
|
|
2217
|
-
type: "arrival_gate",
|
|
2218
|
-
code: "ARG",
|
|
2219
|
-
label: "Arrival Gate",
|
|
2220
|
-
value: `${results.groups.agate}`
|
|
2221
|
-
});
|
|
2222
|
-
decodeResult.raw.scheduled_time_of_arrival = results.groups.sta;
|
|
2223
|
-
decodeResult.formatted.items.push({
|
|
2224
|
-
type: "scheduled_time_of_arrival",
|
|
2225
|
-
code: "STA",
|
|
2226
|
-
label: "Scheduled Time of Arrival",
|
|
2227
|
-
value: `${results.groups.sta}`
|
|
2228
|
-
});
|
|
2229
|
-
}
|
|
2230
|
-
posRptRegex = /\/(?<field>\w+)\s(?<value>[\w\+\-:\.]+)\s*/gi;
|
|
2231
|
-
const remainingParts = parts.slice(1);
|
|
2232
|
-
for (const part of remainingParts) {
|
|
2233
|
-
const matches = part.matchAll(posRptRegex);
|
|
2234
|
-
for (const match of matches) {
|
|
2235
|
-
switch (match.groups?.field) {
|
|
2236
|
-
case "ALT": {
|
|
2237
|
-
ResultFormatter.altitude(decodeResult, Number(match.groups.value));
|
|
2238
|
-
break;
|
|
2239
|
-
}
|
|
2240
|
-
case "DWND": {
|
|
2241
|
-
decodeResult.raw.wind_direction = Number(match.groups.value);
|
|
2242
|
-
decodeResult.formatted.items.push({
|
|
2243
|
-
type: "wind_direction",
|
|
2244
|
-
code: "DWND",
|
|
2245
|
-
label: this.descriptions[match.groups.field],
|
|
2246
|
-
value: decodeResult.raw.wind_direction
|
|
2247
|
-
});
|
|
2248
|
-
break;
|
|
2249
|
-
}
|
|
2250
|
-
case "FL": {
|
|
2251
|
-
const flight_level = Number(match.groups.value);
|
|
2252
|
-
ResultFormatter.altitude(decodeResult, flight_level * 100);
|
|
2253
|
-
break;
|
|
2254
|
-
}
|
|
2255
|
-
case "FOB": {
|
|
2256
|
-
const fob = Number(match.groups.value);
|
|
2257
|
-
if (!isNaN(fob)) {
|
|
2258
|
-
ResultFormatter.currentFuel(decodeResult, fob);
|
|
2259
|
-
}
|
|
2260
|
-
break;
|
|
2261
|
-
}
|
|
2262
|
-
case "HDG": {
|
|
2263
|
-
ResultFormatter.heading(decodeResult, Number(match.groups.value));
|
|
2264
|
-
break;
|
|
2265
|
-
}
|
|
2266
|
-
case "MCH": {
|
|
2267
|
-
decodeResult.raw.mach = Number(match.groups.value) / 1e3;
|
|
2268
|
-
decodeResult.formatted.items.push({
|
|
2269
|
-
type: "mach",
|
|
2270
|
-
code: "MCH",
|
|
2271
|
-
label: this.descriptions[match.groups.field],
|
|
2272
|
-
value: `${decodeResult.raw.mach} Mach`
|
|
2273
|
-
});
|
|
2274
|
-
break;
|
|
2275
|
-
}
|
|
2276
|
-
case "NWYP": {
|
|
2277
|
-
decodeResult.raw.next_waypoint = match.groups.value;
|
|
2278
|
-
decodeResult.formatted.items.push({
|
|
2279
|
-
type: "next_waypoint",
|
|
2280
|
-
code: "NWYP",
|
|
2281
|
-
label: this.descriptions[match.groups.field],
|
|
2282
|
-
value: decodeResult.raw.next_waypoint
|
|
2283
|
-
});
|
|
2284
|
-
break;
|
|
2285
|
-
}
|
|
2286
|
-
case "POS": {
|
|
2287
|
-
const posRegex = /^(?<latd>[NS])(?<lat>.+)(?<lngd>[EW])(?<lng>.+)/;
|
|
2288
|
-
const posResult = match.groups.value.match(posRegex);
|
|
2289
|
-
const lat = Number(posResult?.groups?.lat) * (posResult?.groups?.lngd === "S" ? -1 : 1);
|
|
2290
|
-
const lon = Number(posResult?.groups?.lng) * (posResult?.groups?.lngd === "W" ? -1 : 1);
|
|
2291
|
-
const position = {
|
|
2292
|
-
latitude: Number.isInteger(lat) ? lat / 1e3 : lat / 100,
|
|
2293
|
-
longitude: Number.isInteger(lon) ? lon / 1e3 : lon / 100
|
|
2294
|
-
};
|
|
2295
|
-
ResultFormatter.position(decodeResult, position);
|
|
2296
|
-
break;
|
|
2297
|
-
}
|
|
2298
|
-
case "SWND": {
|
|
2299
|
-
decodeResult.raw.wind_speed = Number(match.groups.value);
|
|
2300
|
-
decodeResult.formatted.items.push({
|
|
2301
|
-
type: "wind_speed",
|
|
2302
|
-
code: "SWND",
|
|
2303
|
-
label: this.descriptions[match.groups.field],
|
|
2304
|
-
value: decodeResult.raw.wind_speed
|
|
2305
|
-
});
|
|
2306
|
-
break;
|
|
2307
|
-
}
|
|
2308
|
-
default: {
|
|
2309
|
-
if (match.groups?.field != void 0) {
|
|
2310
|
-
const description = this.descriptions[match.groups.field] ? this.descriptions[match.groups.field] : "Unknown";
|
|
2311
|
-
decodeResult.formatted.items.push({
|
|
2312
|
-
type: match.groups.field,
|
|
2313
|
-
code: match.groups.field,
|
|
2314
|
-
label: description || `Unknown (${match.groups.field})`,
|
|
2315
|
-
value: `${match.groups.value}`
|
|
2316
|
-
});
|
|
2317
|
-
}
|
|
2318
|
-
}
|
|
2319
|
-
}
|
|
2320
|
-
}
|
|
2321
|
-
}
|
|
2322
|
-
decodeResult.decoded = true;
|
|
2323
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
2324
|
-
}
|
|
2325
|
-
return decodeResult;
|
|
2326
|
-
}
|
|
2327
|
-
};
|
|
2328
|
-
|
|
2329
|
-
// lib/plugins/Label_83.ts
|
|
2330
|
-
var Label_83 = class extends DecoderPlugin {
|
|
2331
|
-
name = "label-83";
|
|
2332
|
-
qualifiers() {
|
|
2333
|
-
return {
|
|
2334
|
-
labels: ["83"]
|
|
2335
|
-
};
|
|
2336
|
-
}
|
|
2337
|
-
decode(message, options = {}) {
|
|
2338
|
-
const decodeResult = this.defaultResult();
|
|
2339
|
-
decodeResult.decoder.name = this.name;
|
|
2340
|
-
decodeResult.message = message;
|
|
2341
|
-
decodeResult.formatted.description = "Airline Defined";
|
|
2342
|
-
let text = message.text;
|
|
2343
|
-
if (text.match(/^M\d{2}A\w{6}/)) {
|
|
2344
|
-
ResultFormatter.flightNumber(decodeResult, message.text.substring(4, 10).replace(/^([A-Z]+)0*/g, "$1"));
|
|
2345
|
-
text = text.substring(10);
|
|
2346
|
-
}
|
|
2347
|
-
decodeResult.decoded = true;
|
|
2348
|
-
if (text.substring(0, 10) === "4DH3 ETAT2") {
|
|
2349
|
-
const fields = text.split(/\s+/);
|
|
2350
|
-
if (fields[2].length > 5) {
|
|
2351
|
-
decodeResult.raw.day_of_month = fields[2].substring(5);
|
|
2352
|
-
}
|
|
2353
|
-
ResultFormatter.unknown(decodeResult, fields[2].substring(0, 4));
|
|
2354
|
-
const subfields = fields[3].split("/");
|
|
2355
|
-
ResultFormatter.departureAirport(decodeResult, subfields[0]);
|
|
2356
|
-
ResultFormatter.arrivalAirport(decodeResult, subfields[1]);
|
|
2357
|
-
ResultFormatter.tail(decodeResult, fields[4].replace(/\./g, ""));
|
|
2358
|
-
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[6] + "00"));
|
|
2359
|
-
} else if (text.substring(0, 5) === "001PR") {
|
|
2360
|
-
decodeResult.raw.day_of_month = text.substring(5, 7);
|
|
2361
|
-
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(text.substring(13, 28).replace(/\./g, ""));
|
|
2362
|
-
if (position) {
|
|
2363
|
-
ResultFormatter.position(decodeResult, position);
|
|
2364
|
-
}
|
|
2365
|
-
ResultFormatter.altitude(decodeResult, Number(text.substring(28, 33)));
|
|
2366
|
-
ResultFormatter.unknown(decodeResult, text.substring(33));
|
|
2367
|
-
} else {
|
|
2368
|
-
const fields = text.replace(/\s/g, "").split(",");
|
|
2369
|
-
if (fields.length === 9) {
|
|
2370
|
-
ResultFormatter.departureAirport(decodeResult, fields[0]);
|
|
2371
|
-
ResultFormatter.arrivalAirport(decodeResult, fields[1]);
|
|
2372
|
-
decodeResult.raw.day_of_month = fields[2].substring(0, 2);
|
|
2373
|
-
decodeResult.raw.time = fields[2].substring(2);
|
|
2374
|
-
ResultFormatter.position(
|
|
2375
|
-
decodeResult,
|
|
2376
|
-
{
|
|
2377
|
-
latitude: Number(fields[3].replace(/\s/g, "")),
|
|
2378
|
-
longitude: Number(fields[4].replace(/\s/g, ""))
|
|
2379
|
-
}
|
|
2380
|
-
);
|
|
2381
|
-
ResultFormatter.altitude(decodeResult, Number(fields[5]));
|
|
2382
|
-
ResultFormatter.groundspeed(decodeResult, Number(fields[6]));
|
|
2383
|
-
ResultFormatter.heading(decodeResult, Number(fields[7]));
|
|
2384
|
-
ResultFormatter.unknown(decodeResult, fields[8]);
|
|
2385
|
-
} else {
|
|
2386
|
-
decodeResult.decoded = false;
|
|
2387
|
-
ResultFormatter.unknown(decodeResult, message.text);
|
|
2388
|
-
}
|
|
2389
|
-
}
|
|
2390
|
-
if (decodeResult.decoded) {
|
|
2391
|
-
if (!decodeResult.remaining.text)
|
|
2392
|
-
decodeResult.decoder.decodeLevel = "full";
|
|
2393
|
-
else
|
|
2394
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
2395
|
-
} else {
|
|
2396
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
2397
|
-
}
|
|
2398
|
-
return decodeResult;
|
|
2399
|
-
}
|
|
2400
|
-
};
|
|
2401
|
-
|
|
2402
|
-
// lib/plugins/Label_8E.ts
|
|
2403
|
-
var Label_8E = class extends DecoderPlugin {
|
|
2404
|
-
name = "label-8e";
|
|
2405
|
-
qualifiers() {
|
|
2406
|
-
return {
|
|
2407
|
-
labels: ["8E"]
|
|
2408
|
-
};
|
|
2409
|
-
}
|
|
2410
|
-
decode(message, options = {}) {
|
|
2411
|
-
const decodeResult = this.defaultResult();
|
|
2412
|
-
decodeResult.decoder.name = this.name;
|
|
2413
|
-
decodeResult.formatted.description = "ETA Report";
|
|
2414
|
-
decodeResult.message = message;
|
|
2415
|
-
const regex = /^(?<arrival_icao>\w{4}),(?<arrival_eta>\d{4})$/;
|
|
2416
|
-
const results = message.text.match(regex);
|
|
2417
|
-
if (results?.groups) {
|
|
2418
|
-
if (options.debug) {
|
|
2419
|
-
console.log(`Label 8E ETA: groups`);
|
|
2420
|
-
console.log(results.groups);
|
|
2421
|
-
}
|
|
2422
|
-
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(results.groups.arrival_eta + "00"));
|
|
2423
|
-
ResultFormatter.arrivalAirport(decodeResult, results.groups.arrival_icao);
|
|
2424
|
-
}
|
|
2425
|
-
decodeResult.decoded = true;
|
|
2426
|
-
decodeResult.decoder.decodeLevel = "full";
|
|
2427
|
-
return decodeResult;
|
|
2428
|
-
}
|
|
2429
|
-
};
|
|
2430
|
-
|
|
2431
|
-
// lib/plugins/Label_B6.ts
|
|
2432
|
-
var Label_B6_Forwardslash = class extends DecoderPlugin {
|
|
2433
|
-
name = "label-b6-forwardslash";
|
|
2434
|
-
qualifiers() {
|
|
2435
|
-
return {
|
|
2436
|
-
labels: ["B6"],
|
|
2437
|
-
preambles: ["/"]
|
|
2438
|
-
};
|
|
2439
|
-
}
|
|
2440
|
-
decode(message, options = {}) {
|
|
2441
|
-
const decodeResult = this.defaultResult();
|
|
2442
|
-
decodeResult.decoder.name = this.name;
|
|
2443
|
-
decodeResult.formatted.description = "CPDLC Message";
|
|
2444
|
-
decodeResult.message = message;
|
|
2445
|
-
if (options.debug) {
|
|
2446
|
-
console.log("CPDLC: " + message);
|
|
2447
|
-
}
|
|
2448
|
-
return decodeResult;
|
|
2449
|
-
}
|
|
2450
|
-
};
|
|
2451
|
-
|
|
2452
|
-
// lib/plugins/Label_ColonComma.ts
|
|
2453
|
-
var Label_ColonComma = class extends DecoderPlugin {
|
|
2454
|
-
name = "label-colon-comma";
|
|
2455
|
-
qualifiers() {
|
|
2456
|
-
return {
|
|
2457
|
-
labels: [":;"]
|
|
2458
|
-
};
|
|
2459
|
-
}
|
|
2460
|
-
decode(message, options = {}) {
|
|
2461
|
-
const decodeResult = this.defaultResult();
|
|
2462
|
-
decodeResult.decoder.name = this.name;
|
|
2463
|
-
decodeResult.raw.frequency = Number(message.text) / 1e3;
|
|
2464
|
-
decodeResult.formatted.description = "Aircraft Transceiver Frequency Change";
|
|
2465
|
-
decodeResult.formatted.items.push({
|
|
2466
|
-
type: "frequency",
|
|
2467
|
-
label: "Frequency",
|
|
2468
|
-
value: `${decodeResult.raw.frequency} MHz`,
|
|
2469
|
-
code: "FREQ"
|
|
2470
|
-
});
|
|
2471
|
-
decodeResult.decoded = true;
|
|
2472
|
-
decodeResult.decoder.decodeLevel = "full";
|
|
2473
|
-
return decodeResult;
|
|
2474
|
-
}
|
|
2475
|
-
};
|
|
2476
|
-
|
|
2477
|
-
// lib/utils/flight_plan_utils.ts
|
|
2478
|
-
var FlightPlanUtils = class _FlightPlanUtils {
|
|
2479
|
-
/**
|
|
2480
|
-
* Processes flight plan data
|
|
2481
|
-
*
|
|
2482
|
-
* Expected format is [header, key1, val1, ... keyN, valN]
|
|
2483
|
-
*
|
|
2484
|
-
* @param decodeResult - results
|
|
2485
|
-
* @param data - original message split by ':'
|
|
2486
|
-
* @returns whether all fields were processed or not
|
|
2487
|
-
*/
|
|
2488
|
-
static processFlightPlan(decodeResult, data) {
|
|
2489
|
-
let allKnownFields = _FlightPlanUtils.parseHeader(decodeResult, data[0]);
|
|
2490
|
-
for (let i = 1; i < data.length; i += 2) {
|
|
2491
|
-
const key = data[i];
|
|
2492
|
-
const value = data[i + 1];
|
|
2493
|
-
switch (key) {
|
|
2494
|
-
case "A":
|
|
2495
|
-
addProcedure(decodeResult, value, "arrival");
|
|
2496
|
-
break;
|
|
2497
|
-
case "AA":
|
|
2498
|
-
addArrivalAirport(decodeResult, value);
|
|
2499
|
-
break;
|
|
2500
|
-
case "AP":
|
|
2501
|
-
addProcedure(decodeResult, value, "approach");
|
|
2502
|
-
break;
|
|
2503
|
-
case "CR":
|
|
2504
|
-
addCompanyRoute(decodeResult, value);
|
|
2505
|
-
break;
|
|
2506
|
-
case "D":
|
|
2507
|
-
addProcedure(decodeResult, value, "departure");
|
|
2508
|
-
break;
|
|
2509
|
-
case "DA":
|
|
2510
|
-
addDepartureAirport(decodeResult, value);
|
|
2511
|
-
break;
|
|
2512
|
-
case "F":
|
|
2513
|
-
addRoute(decodeResult, value);
|
|
2514
|
-
break;
|
|
2515
|
-
case "R":
|
|
2516
|
-
addRunway(decodeResult, value);
|
|
2517
|
-
break;
|
|
2518
|
-
// case 'WS': // something about routes, has altitude, so current parsing won't work
|
|
2519
|
-
// break;
|
|
2520
|
-
default:
|
|
2521
|
-
if (allKnownFields) {
|
|
2522
|
-
decodeResult.remaining.text = "";
|
|
2523
|
-
allKnownFields = false;
|
|
2524
|
-
}
|
|
2525
|
-
decodeResult.remaining.text += `:${key}:${value}`;
|
|
2526
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
2527
|
-
}
|
|
2528
|
-
}
|
|
2529
|
-
return allKnownFields;
|
|
2530
|
-
}
|
|
2531
|
-
static parseHeader(decodeResult, header) {
|
|
2532
|
-
let allKnownFields = true;
|
|
2533
|
-
if (header.startsWith("RF")) {
|
|
2534
|
-
decodeResult.formatted.items.push({
|
|
2535
|
-
type: "status",
|
|
2536
|
-
code: "ROUTE_STATUS",
|
|
2537
|
-
label: "Route Status",
|
|
2538
|
-
value: "Route Filed"
|
|
2539
|
-
});
|
|
2540
|
-
decodeResult.raw.route_status = "RF";
|
|
2541
|
-
if (header.length > 2) {
|
|
2542
|
-
addRoute(decodeResult, header.substring(2));
|
|
2543
|
-
}
|
|
2544
|
-
} else if (header.startsWith("RP")) {
|
|
2545
|
-
decodeResult.raw.route_status = "RP";
|
|
2546
|
-
decodeResult.formatted.items.push({
|
|
2547
|
-
type: "status",
|
|
2548
|
-
code: "ROUTE_STATUS",
|
|
2549
|
-
label: "Route Status",
|
|
2550
|
-
value: "Route Planned"
|
|
2551
|
-
});
|
|
2552
|
-
decodeResult.raw.route_status = header;
|
|
2553
|
-
} else if (header.startsWith("RI")) {
|
|
2554
|
-
decodeResult.raw.route_status = "RI";
|
|
2555
|
-
decodeResult.formatted.items.push({
|
|
2556
|
-
type: "status",
|
|
2557
|
-
code: "ROUTE_STATUS",
|
|
2558
|
-
label: "Route Status",
|
|
2559
|
-
value: "Route Inactive"
|
|
2560
|
-
});
|
|
2561
|
-
} else {
|
|
2562
|
-
decodeResult.remaining.text += header;
|
|
2563
|
-
allKnownFields = false;
|
|
2564
|
-
}
|
|
2565
|
-
return allKnownFields;
|
|
2278
|
+
return allKnownFields;
|
|
2566
2279
|
}
|
|
2567
2280
|
};
|
|
2568
2281
|
function addArrivalAirport(decodeResult, value) {
|
|
@@ -2674,9 +2387,11 @@ var H1Helper = class {
|
|
|
2674
2387
|
ResultFormatter.freetext(decodeResult, fields[i].substring(2));
|
|
2675
2388
|
} else if (fields[i].startsWith("ET")) {
|
|
2676
2389
|
if (fields[i].length === 7) {
|
|
2677
|
-
ResultFormatter.
|
|
2390
|
+
ResultFormatter.day(decodeResult, Number(fields[i].substring(2, 3)));
|
|
2391
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[i].substring(3)));
|
|
2678
2392
|
} else if (fields[i].length === 8) {
|
|
2679
|
-
ResultFormatter.
|
|
2393
|
+
ResultFormatter.day(decodeResult, Number(fields[i].substring(2, 4)));
|
|
2394
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[i].substring(4)));
|
|
2680
2395
|
} else {
|
|
2681
2396
|
ResultFormatter.unknown(decodeResult, fields[i], "/");
|
|
2682
2397
|
}
|
|
@@ -2727,161 +2442,554 @@ function processIdentification(decodeResult, data) {
|
|
|
2727
2442
|
decodeResult.raw.mission_number = data[2];
|
|
2728
2443
|
}
|
|
2729
2444
|
}
|
|
2730
|
-
function processDT(decodeResult, data) {
|
|
2731
|
-
if (!decodeResult.raw.arrival_icao) {
|
|
2732
|
-
ResultFormatter.arrivalAirport(decodeResult, data[0]);
|
|
2733
|
-
} else if (decodeResult.raw.arrival_icao != data[0]) {
|
|
2734
|
-
ResultFormatter.unknownArr(decodeResult, data);
|
|
2445
|
+
function processDT(decodeResult, data) {
|
|
2446
|
+
if (!decodeResult.raw.arrival_icao) {
|
|
2447
|
+
ResultFormatter.arrivalAirport(decodeResult, data[0]);
|
|
2448
|
+
} else if (decodeResult.raw.arrival_icao != data[0]) {
|
|
2449
|
+
ResultFormatter.unknownArr(decodeResult, data);
|
|
2450
|
+
}
|
|
2451
|
+
if (data.length > 1) {
|
|
2452
|
+
ResultFormatter.arrivalRunway(decodeResult, data[1]);
|
|
2453
|
+
}
|
|
2454
|
+
if (data.length > 2) {
|
|
2455
|
+
ResultFormatter.currentFuel(decodeResult, Number(data[2]));
|
|
2456
|
+
}
|
|
2457
|
+
if (data.length > 3) {
|
|
2458
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[3]));
|
|
2459
|
+
}
|
|
2460
|
+
if (data.length > 4) {
|
|
2461
|
+
ResultFormatter.remainingFuel(decodeResult, Number(data[4]));
|
|
2462
|
+
}
|
|
2463
|
+
if (data.length > 5) {
|
|
2464
|
+
ResultFormatter.unknownArr(decodeResult, data);
|
|
2465
|
+
}
|
|
2466
|
+
}
|
|
2467
|
+
function processLR(decodeResult, data) {
|
|
2468
|
+
if (data.length === 19) {
|
|
2469
|
+
ResultFormatter.unknown(decodeResult, data[1]);
|
|
2470
|
+
ResultFormatter.flightNumber(decodeResult, data[2]);
|
|
2471
|
+
ResultFormatter.departureAirport(decodeResult, data[3]);
|
|
2472
|
+
ResultFormatter.arrivalAirport(decodeResult, data[4]);
|
|
2473
|
+
ResultFormatter.arrivalRunway(decodeResult, data[5]);
|
|
2474
|
+
ResultFormatter.unknown(decodeResult, data.slice(6, 19).join(","));
|
|
2475
|
+
} else {
|
|
2476
|
+
ResultFormatter.unknown(decodeResult, data.join(","));
|
|
2477
|
+
}
|
|
2478
|
+
}
|
|
2479
|
+
function parseMessageType(decodeResult, messageType) {
|
|
2480
|
+
const parts = messageType.split("#");
|
|
2481
|
+
if (parts.length == 1) {
|
|
2482
|
+
const type = parts[0].substring(0, 3);
|
|
2483
|
+
if (type === "POS" && parts[0].length !== 3) {
|
|
2484
|
+
processPosition2(decodeResult, parts[0].substring(3).split(","));
|
|
2485
|
+
}
|
|
2486
|
+
return processMessageType(decodeResult, type);
|
|
2487
|
+
} else if (parts.length == 2) {
|
|
2488
|
+
if (parts[0].length > 0) {
|
|
2489
|
+
ResultFormatter.unknown(decodeResult, parts[0].substring(0, 3));
|
|
2490
|
+
decodeResult.raw.flight_number = parts[0].substring(3);
|
|
2491
|
+
ResultFormatter.unknown(decodeResult, parts[1].length == 5 ? parts[1].substring(0, 2) : parts[1].substring(0, 3), "#");
|
|
2492
|
+
}
|
|
2493
|
+
const type = parts[1].length == 5 ? parts[1].substring(2, 5) : parts[1].substring(3, 6);
|
|
2494
|
+
if (parts[1].substring(3, 6) === "POS" && parts[1].length > 6) {
|
|
2495
|
+
processPosition2(decodeResult, parts[1].substring(6).split(","));
|
|
2496
|
+
}
|
|
2497
|
+
processMessageType(decodeResult, type);
|
|
2498
|
+
} else {
|
|
2499
|
+
ResultFormatter.unknown(decodeResult, messageType);
|
|
2500
|
+
}
|
|
2501
|
+
}
|
|
2502
|
+
function processMessageType(decodeResult, type) {
|
|
2503
|
+
if (type === "FPN") {
|
|
2504
|
+
decodeResult.formatted.description = "Flight Plan";
|
|
2505
|
+
} else if (type === "FTX") {
|
|
2506
|
+
decodeResult.formatted.description = "Free Text";
|
|
2507
|
+
} else if (type === "INI") {
|
|
2508
|
+
decodeResult.formatted.description = "Flight Plan Initial Report";
|
|
2509
|
+
} else if (type === "POS") {
|
|
2510
|
+
decodeResult.formatted.description = "Position Report";
|
|
2511
|
+
} else if (type === "PRG") {
|
|
2512
|
+
decodeResult.formatted.description = "Progress Report";
|
|
2513
|
+
} else {
|
|
2514
|
+
decodeResult.formatted.description = "Unknown H1 Message";
|
|
2515
|
+
}
|
|
2516
|
+
}
|
|
2517
|
+
function processDC(decodeResult, data) {
|
|
2518
|
+
decodeResult.raw.message_date = data[0];
|
|
2519
|
+
if (data.length === 1) {
|
|
2520
|
+
} else if (data.length === 2) {
|
|
2521
|
+
const date = data[0].substring(2, 4) + data[0].substring(0, 2) + data[0].substring(4, 6);
|
|
2522
|
+
const time = DateTimeUtils.convertDateTimeToEpoch(data[1], data[0]);
|
|
2523
|
+
decodeResult.raw.message_timestamp = time;
|
|
2524
|
+
}
|
|
2525
|
+
}
|
|
2526
|
+
function processPS(decodeResult, data) {
|
|
2527
|
+
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[0]);
|
|
2528
|
+
if (position) {
|
|
2529
|
+
decodeResult.raw.position = position;
|
|
2530
|
+
decodeResult.formatted.items.push({
|
|
2531
|
+
type: "aircraft_position",
|
|
2532
|
+
code: "POS",
|
|
2533
|
+
label: "Aircraft Position",
|
|
2534
|
+
value: CoordinateUtils.coordinateString(position)
|
|
2535
|
+
});
|
|
2536
|
+
}
|
|
2537
|
+
if (data.length === 9) {
|
|
2538
|
+
processRoute(decodeResult, data[3], data[1], data[5], data[4], void 0);
|
|
2539
|
+
ResultFormatter.altitude(decodeResult, Number(data[2]) * 100);
|
|
2540
|
+
ResultFormatter.temperature(decodeResult, data[6]);
|
|
2541
|
+
ResultFormatter.unknown(decodeResult, data[7]);
|
|
2542
|
+
ResultFormatter.unknown(decodeResult, data[8]);
|
|
2543
|
+
}
|
|
2544
|
+
if (data.length === 14) {
|
|
2545
|
+
ResultFormatter.altitude(decodeResult, Number(data[3]) * 100);
|
|
2546
|
+
processRoute(decodeResult, data[4], data[2], data[6], data[5], void 0);
|
|
2547
|
+
ResultFormatter.temperature(decodeResult, data[7]);
|
|
2548
|
+
ResultFormatter.groundspeed(decodeResult, Number(data[10]));
|
|
2549
|
+
ResultFormatter.unknown(decodeResult, data[1]);
|
|
2550
|
+
ResultFormatter.unknown(decodeResult, data[8]);
|
|
2551
|
+
ResultFormatter.unknown(decodeResult, data[9]);
|
|
2552
|
+
ResultFormatter.unknown(decodeResult, data.slice(11).join(","));
|
|
2553
|
+
}
|
|
2554
|
+
}
|
|
2555
|
+
function processPosition2(decodeResult, data) {
|
|
2556
|
+
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[0]);
|
|
2557
|
+
if (position) {
|
|
2558
|
+
decodeResult.raw.position = position;
|
|
2559
|
+
decodeResult.formatted.items.push({
|
|
2560
|
+
type: "aircraft_position",
|
|
2561
|
+
code: "POS",
|
|
2562
|
+
label: "Aircraft Position",
|
|
2563
|
+
value: CoordinateUtils.coordinateString(position)
|
|
2564
|
+
});
|
|
2565
|
+
}
|
|
2566
|
+
if (data.length >= 10) {
|
|
2567
|
+
ResultFormatter.altitude(decodeResult, Number(data[3]) * 100);
|
|
2568
|
+
processRoute(decodeResult, data[1], data[2], data[4], data[5], data[6]);
|
|
2569
|
+
ResultFormatter.temperature(decodeResult, data[7]);
|
|
2570
|
+
ResultFormatter.unknown(decodeResult, data[8]);
|
|
2571
|
+
ResultFormatter.unknown(decodeResult, data[9]);
|
|
2572
|
+
}
|
|
2573
|
+
if (data.length >= 14) {
|
|
2574
|
+
ResultFormatter.groundspeed(decodeResult, Number(data[10]));
|
|
2575
|
+
ResultFormatter.unknown(decodeResult, data[11]);
|
|
2576
|
+
ResultFormatter.unknown(decodeResult, data[12]);
|
|
2577
|
+
ResultFormatter.unknown(decodeResult, data[13]);
|
|
2578
|
+
}
|
|
2579
|
+
}
|
|
2580
|
+
function processRoute(decodeResult, last, time, next, eta, then, date) {
|
|
2581
|
+
const lastTime = date ? DateTimeUtils.convertDateTimeToEpoch(time, date) : DateTimeUtils.convertHHMMSSToTod(time);
|
|
2582
|
+
const nextTime = date ? DateTimeUtils.convertDateTimeToEpoch(eta, date) : DateTimeUtils.convertHHMMSSToTod(eta);
|
|
2583
|
+
const timeFormat = date ? "epoch" : "tod";
|
|
2584
|
+
const lastWaypoint = RouteUtils.getWaypoint(last);
|
|
2585
|
+
lastWaypoint.time = lastTime;
|
|
2586
|
+
lastWaypoint.timeFormat = timeFormat;
|
|
2587
|
+
const nextWaypoint = RouteUtils.getWaypoint(next);
|
|
2588
|
+
nextWaypoint.time = nextTime;
|
|
2589
|
+
nextWaypoint.timeFormat = timeFormat;
|
|
2590
|
+
const thenWaypoint = RouteUtils.getWaypoint(then || "?");
|
|
2591
|
+
const waypoints = [lastWaypoint, nextWaypoint, thenWaypoint];
|
|
2592
|
+
decodeResult.raw.route = { waypoints };
|
|
2593
|
+
decodeResult.formatted.items.push({
|
|
2594
|
+
type: "aircraft_route",
|
|
2595
|
+
code: "ROUTE",
|
|
2596
|
+
label: "Aircraft Route",
|
|
2597
|
+
value: RouteUtils.routeToString(decodeResult.raw.route)
|
|
2598
|
+
});
|
|
2599
|
+
}
|
|
2600
|
+
|
|
2601
|
+
// lib/plugins/Label_4J_POS.ts
|
|
2602
|
+
var Label_4J_POS = class extends DecoderPlugin {
|
|
2603
|
+
name = "label-4j-pos";
|
|
2604
|
+
qualifiers() {
|
|
2605
|
+
return {
|
|
2606
|
+
labels: ["4J"],
|
|
2607
|
+
preambles: ["POS/"]
|
|
2608
|
+
};
|
|
2735
2609
|
}
|
|
2736
|
-
|
|
2737
|
-
|
|
2610
|
+
// copied from Label_H1.ts since i don't really want to have to have
|
|
2611
|
+
// something named like that decode more than 1 type
|
|
2612
|
+
// if we figure out a good name, i'll combine them
|
|
2613
|
+
decode(message, options = {}) {
|
|
2614
|
+
let decodeResult = this.defaultResult();
|
|
2615
|
+
decodeResult.decoder.name = this.name;
|
|
2616
|
+
decodeResult.message = message;
|
|
2617
|
+
const msg = message.text.replace(/\n|\r/g, "");
|
|
2618
|
+
const decoded = H1Helper.decodeH1Message(decodeResult, msg);
|
|
2619
|
+
decodeResult.decoded = decoded;
|
|
2620
|
+
decodeResult.decoder.decodeLevel = !decodeResult.remaining.text ? "full" : "partial";
|
|
2621
|
+
if (decodeResult.formatted.items.length === 0) {
|
|
2622
|
+
if (options.debug) {
|
|
2623
|
+
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
2624
|
+
}
|
|
2625
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
2626
|
+
decodeResult.decoded = false;
|
|
2627
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2628
|
+
}
|
|
2629
|
+
return decodeResult;
|
|
2738
2630
|
}
|
|
2739
|
-
|
|
2740
|
-
|
|
2631
|
+
};
|
|
2632
|
+
|
|
2633
|
+
// lib/plugins/Label_4N.ts
|
|
2634
|
+
var Label_4N = class extends DecoderPlugin {
|
|
2635
|
+
name = "label-4n";
|
|
2636
|
+
qualifiers() {
|
|
2637
|
+
return {
|
|
2638
|
+
labels: ["4N"]
|
|
2639
|
+
};
|
|
2741
2640
|
}
|
|
2742
|
-
|
|
2743
|
-
|
|
2641
|
+
decode(message, options = {}) {
|
|
2642
|
+
const decodeResult = this.defaultResult();
|
|
2643
|
+
decodeResult.decoder.name = this.name;
|
|
2644
|
+
decodeResult.message = message;
|
|
2645
|
+
decodeResult.formatted.description = "Airline Defined";
|
|
2646
|
+
let text = message.text;
|
|
2647
|
+
if (text.match(/^M\d{2}A\w{6}/)) {
|
|
2648
|
+
ResultFormatter.flightNumber(decodeResult, message.text.substring(4, 10).replace(/^([A-Z]+)0*/g, "$1"));
|
|
2649
|
+
text = text.substring(10);
|
|
2650
|
+
}
|
|
2651
|
+
decodeResult.decoded = true;
|
|
2652
|
+
const fields = text.split(",");
|
|
2653
|
+
if (text.length === 51) {
|
|
2654
|
+
decodeResult.raw.day = text.substring(0, 2);
|
|
2655
|
+
ResultFormatter.departureAirport(decodeResult, text.substring(8, 11));
|
|
2656
|
+
ResultFormatter.arrivalAirport(decodeResult, text.substring(13, 16));
|
|
2657
|
+
ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(text.substring(30, 45).replace(/^(.)0/, "$1")));
|
|
2658
|
+
ResultFormatter.altitude(decodeResult, Number(text.substring(48, 51)) * 100);
|
|
2659
|
+
ResultFormatter.unknownArr(decodeResult, [text.substring(2, 4), text.substring(19, 29)], " ");
|
|
2660
|
+
} else if (fields.length === 33) {
|
|
2661
|
+
decodeResult.raw.date = fields[3];
|
|
2662
|
+
if (fields[1] === "B") {
|
|
2663
|
+
ResultFormatter.position(decodeResult, { latitude: Number(fields[4]), longitude: Number(fields[5]) });
|
|
2664
|
+
ResultFormatter.altitude(decodeResult, Number(fields[6]));
|
|
2665
|
+
}
|
|
2666
|
+
ResultFormatter.departureAirport(decodeResult, fields[8]);
|
|
2667
|
+
ResultFormatter.arrivalAirport(decodeResult, fields[9]);
|
|
2668
|
+
ResultFormatter.alternateAirport(decodeResult, fields[10]);
|
|
2669
|
+
ResultFormatter.arrivalRunway(decodeResult, fields[11].split("/")[0]);
|
|
2670
|
+
if (fields[12].length > 1) {
|
|
2671
|
+
ResultFormatter.alternateRunway(decodeResult, fields[12].split("/")[0]);
|
|
2672
|
+
}
|
|
2673
|
+
ResultFormatter.checksum(decodeResult, fields[32]);
|
|
2674
|
+
ResultFormatter.unknownArr(decodeResult, [...fields.slice(1, 3), fields[7], ...fields.slice(13, 32)].filter((f) => f != ""));
|
|
2675
|
+
} else {
|
|
2676
|
+
decodeResult.decoded = false;
|
|
2677
|
+
ResultFormatter.unknown(decodeResult, text);
|
|
2678
|
+
}
|
|
2679
|
+
if (decodeResult.decoded) {
|
|
2680
|
+
if (!decodeResult.remaining.text)
|
|
2681
|
+
decodeResult.decoder.decodeLevel = "full";
|
|
2682
|
+
else
|
|
2683
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
2684
|
+
} else {
|
|
2685
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2686
|
+
}
|
|
2687
|
+
return decodeResult;
|
|
2744
2688
|
}
|
|
2745
|
-
|
|
2746
|
-
|
|
2689
|
+
};
|
|
2690
|
+
|
|
2691
|
+
// lib/plugins/Label_80.ts
|
|
2692
|
+
var Label_80 = class extends DecoderPlugin {
|
|
2693
|
+
name = "label-80";
|
|
2694
|
+
descriptions = {
|
|
2695
|
+
ALT: "Altitude",
|
|
2696
|
+
DWND: "Wind Direction",
|
|
2697
|
+
ETA: "Estimated Time of Arrival",
|
|
2698
|
+
FOB: "Fuel on Board",
|
|
2699
|
+
FL: "Flight Level",
|
|
2700
|
+
HDG: "Heading",
|
|
2701
|
+
MCH: "Aircraft Speed",
|
|
2702
|
+
NWYP: "Next Waypoint",
|
|
2703
|
+
POS: "Aircraft Position",
|
|
2704
|
+
SAT: "Static Air Temperature",
|
|
2705
|
+
SWND: "Wind Speed",
|
|
2706
|
+
TAS: "True Airspeed",
|
|
2707
|
+
WYP: "Waypoint"
|
|
2708
|
+
};
|
|
2709
|
+
qualifiers() {
|
|
2710
|
+
return {
|
|
2711
|
+
labels: ["80"],
|
|
2712
|
+
preambles: ["3N01 POSRPT"]
|
|
2713
|
+
};
|
|
2747
2714
|
}
|
|
2748
|
-
|
|
2749
|
-
|
|
2715
|
+
decode(message, options = {}) {
|
|
2716
|
+
const decodeResult = this.defaultResult();
|
|
2717
|
+
decodeResult.decoder.name = this.name;
|
|
2718
|
+
decodeResult.formatted.description = "Airline Defined Position Report";
|
|
2719
|
+
const parts = message.text.split("\n");
|
|
2720
|
+
let posRptRegex = /^3N01 POSRPT \d\d\d\d\/\d\d (?<orig>\w+)\/(?<dest>\w+) \.(?<tail>[\w-]+)(\/(?<agate>.+) (?<sta>\w+:\w+))*/;
|
|
2721
|
+
let results = parts[0].match(posRptRegex);
|
|
2722
|
+
if (!results?.groups) {
|
|
2723
|
+
decodeResult.decoded = false;
|
|
2724
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2725
|
+
return decodeResult;
|
|
2726
|
+
}
|
|
2727
|
+
if (results && results.length > 0) {
|
|
2728
|
+
ResultFormatter.departureAirport(decodeResult, results.groups.orig);
|
|
2729
|
+
ResultFormatter.arrivalAirport(decodeResult, results.groups.dest);
|
|
2730
|
+
ResultFormatter.tail(decodeResult, results.groups.tail);
|
|
2731
|
+
if (results.groups.agate) {
|
|
2732
|
+
decodeResult.raw.arrival_gate = results.groups.agate;
|
|
2733
|
+
decodeResult.formatted.items.push({
|
|
2734
|
+
type: "arrival_gate",
|
|
2735
|
+
code: "ARG",
|
|
2736
|
+
label: "Arrival Gate",
|
|
2737
|
+
value: `${results.groups.agate}`
|
|
2738
|
+
});
|
|
2739
|
+
decodeResult.raw.scheduled_time_of_arrival = results.groups.sta;
|
|
2740
|
+
decodeResult.formatted.items.push({
|
|
2741
|
+
type: "scheduled_time_of_arrival",
|
|
2742
|
+
code: "STA",
|
|
2743
|
+
label: "Scheduled Time of Arrival",
|
|
2744
|
+
value: `${results.groups.sta}`
|
|
2745
|
+
});
|
|
2746
|
+
}
|
|
2747
|
+
posRptRegex = /\/(?<field>\w+)\s(?<value>[\w\+\-:\.]+)\s*/gi;
|
|
2748
|
+
const remainingParts = parts.slice(1);
|
|
2749
|
+
for (const part of remainingParts) {
|
|
2750
|
+
const matches = part.matchAll(posRptRegex);
|
|
2751
|
+
for (const match of matches) {
|
|
2752
|
+
switch (match.groups?.field) {
|
|
2753
|
+
case "ALT": {
|
|
2754
|
+
ResultFormatter.altitude(decodeResult, Number(match.groups.value));
|
|
2755
|
+
break;
|
|
2756
|
+
}
|
|
2757
|
+
case "DWND": {
|
|
2758
|
+
decodeResult.raw.wind_direction = Number(match.groups.value);
|
|
2759
|
+
decodeResult.formatted.items.push({
|
|
2760
|
+
type: "wind_direction",
|
|
2761
|
+
code: "DWND",
|
|
2762
|
+
label: this.descriptions[match.groups.field],
|
|
2763
|
+
value: decodeResult.raw.wind_direction
|
|
2764
|
+
});
|
|
2765
|
+
break;
|
|
2766
|
+
}
|
|
2767
|
+
case "FL": {
|
|
2768
|
+
const flight_level = Number(match.groups.value);
|
|
2769
|
+
ResultFormatter.altitude(decodeResult, flight_level * 100);
|
|
2770
|
+
break;
|
|
2771
|
+
}
|
|
2772
|
+
case "FOB": {
|
|
2773
|
+
const fob = Number(match.groups.value);
|
|
2774
|
+
if (!isNaN(fob)) {
|
|
2775
|
+
ResultFormatter.currentFuel(decodeResult, fob);
|
|
2776
|
+
}
|
|
2777
|
+
break;
|
|
2778
|
+
}
|
|
2779
|
+
case "HDG": {
|
|
2780
|
+
ResultFormatter.heading(decodeResult, Number(match.groups.value));
|
|
2781
|
+
break;
|
|
2782
|
+
}
|
|
2783
|
+
case "MCH": {
|
|
2784
|
+
decodeResult.raw.mach = Number(match.groups.value) / 1e3;
|
|
2785
|
+
decodeResult.formatted.items.push({
|
|
2786
|
+
type: "mach",
|
|
2787
|
+
code: "MCH",
|
|
2788
|
+
label: this.descriptions[match.groups.field],
|
|
2789
|
+
value: `${decodeResult.raw.mach} Mach`
|
|
2790
|
+
});
|
|
2791
|
+
break;
|
|
2792
|
+
}
|
|
2793
|
+
case "NWYP": {
|
|
2794
|
+
decodeResult.raw.next_waypoint = match.groups.value;
|
|
2795
|
+
decodeResult.formatted.items.push({
|
|
2796
|
+
type: "next_waypoint",
|
|
2797
|
+
code: "NWYP",
|
|
2798
|
+
label: this.descriptions[match.groups.field],
|
|
2799
|
+
value: decodeResult.raw.next_waypoint
|
|
2800
|
+
});
|
|
2801
|
+
break;
|
|
2802
|
+
}
|
|
2803
|
+
case "POS": {
|
|
2804
|
+
const posRegex = /^(?<latd>[NS])(?<lat>.+)(?<lngd>[EW])(?<lng>.+)/;
|
|
2805
|
+
const posResult = match.groups.value.match(posRegex);
|
|
2806
|
+
const lat = Number(posResult?.groups?.lat) * (posResult?.groups?.lngd === "S" ? -1 : 1);
|
|
2807
|
+
const lon = Number(posResult?.groups?.lng) * (posResult?.groups?.lngd === "W" ? -1 : 1);
|
|
2808
|
+
const position = {
|
|
2809
|
+
latitude: Number.isInteger(lat) ? lat / 1e3 : lat / 100,
|
|
2810
|
+
longitude: Number.isInteger(lon) ? lon / 1e3 : lon / 100
|
|
2811
|
+
};
|
|
2812
|
+
ResultFormatter.position(decodeResult, position);
|
|
2813
|
+
break;
|
|
2814
|
+
}
|
|
2815
|
+
case "SWND": {
|
|
2816
|
+
decodeResult.raw.wind_speed = Number(match.groups.value);
|
|
2817
|
+
decodeResult.formatted.items.push({
|
|
2818
|
+
type: "wind_speed",
|
|
2819
|
+
code: "SWND",
|
|
2820
|
+
label: this.descriptions[match.groups.field],
|
|
2821
|
+
value: decodeResult.raw.wind_speed
|
|
2822
|
+
});
|
|
2823
|
+
break;
|
|
2824
|
+
}
|
|
2825
|
+
default: {
|
|
2826
|
+
if (match.groups?.field != void 0) {
|
|
2827
|
+
const description = this.descriptions[match.groups.field] ? this.descriptions[match.groups.field] : "Unknown";
|
|
2828
|
+
decodeResult.formatted.items.push({
|
|
2829
|
+
type: match.groups.field,
|
|
2830
|
+
code: match.groups.field,
|
|
2831
|
+
label: description || `Unknown (${match.groups.field})`,
|
|
2832
|
+
value: `${match.groups.value}`
|
|
2833
|
+
});
|
|
2834
|
+
}
|
|
2835
|
+
}
|
|
2836
|
+
}
|
|
2837
|
+
}
|
|
2838
|
+
}
|
|
2839
|
+
decodeResult.decoded = true;
|
|
2840
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
2841
|
+
}
|
|
2842
|
+
return decodeResult;
|
|
2750
2843
|
}
|
|
2751
|
-
}
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
} else {
|
|
2761
|
-
ResultFormatter.unknown(decodeResult, data.join(","));
|
|
2844
|
+
};
|
|
2845
|
+
|
|
2846
|
+
// lib/plugins/Label_83.ts
|
|
2847
|
+
var Label_83 = class extends DecoderPlugin {
|
|
2848
|
+
name = "label-83";
|
|
2849
|
+
qualifiers() {
|
|
2850
|
+
return {
|
|
2851
|
+
labels: ["83"]
|
|
2852
|
+
};
|
|
2762
2853
|
}
|
|
2763
|
-
}
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2854
|
+
decode(message, options = {}) {
|
|
2855
|
+
const decodeResult = this.defaultResult();
|
|
2856
|
+
decodeResult.decoder.name = this.name;
|
|
2857
|
+
decodeResult.message = message;
|
|
2858
|
+
decodeResult.formatted.description = "Airline Defined";
|
|
2859
|
+
let text = message.text;
|
|
2860
|
+
if (text.match(/^M\d{2}A\w{6}/)) {
|
|
2861
|
+
ResultFormatter.flightNumber(decodeResult, message.text.substring(4, 10).replace(/^([A-Z]+)0*/g, "$1"));
|
|
2862
|
+
text = text.substring(10);
|
|
2770
2863
|
}
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2864
|
+
decodeResult.decoded = true;
|
|
2865
|
+
if (text.substring(0, 10) === "4DH3 ETAT2") {
|
|
2866
|
+
const fields = text.split(/\s+/);
|
|
2867
|
+
if (fields[2].length > 5) {
|
|
2868
|
+
decodeResult.raw.day = fields[2].substring(5);
|
|
2869
|
+
}
|
|
2870
|
+
ResultFormatter.unknown(decodeResult, fields[2].substring(0, 4));
|
|
2871
|
+
const subfields = fields[3].split("/");
|
|
2872
|
+
ResultFormatter.departureAirport(decodeResult, subfields[0]);
|
|
2873
|
+
ResultFormatter.arrivalAirport(decodeResult, subfields[1]);
|
|
2874
|
+
ResultFormatter.tail(decodeResult, fields[4].replace(/\./g, ""));
|
|
2875
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[6] + "00"));
|
|
2876
|
+
} else if (text.substring(0, 5) === "001PR") {
|
|
2877
|
+
decodeResult.raw.day = text.substring(5, 7);
|
|
2878
|
+
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(text.substring(13, 28).replace(/\./g, ""));
|
|
2879
|
+
if (position) {
|
|
2880
|
+
ResultFormatter.position(decodeResult, position);
|
|
2881
|
+
}
|
|
2882
|
+
ResultFormatter.altitude(decodeResult, Number(text.substring(28, 33)));
|
|
2883
|
+
ResultFormatter.unknown(decodeResult, text.substring(33));
|
|
2884
|
+
} else {
|
|
2885
|
+
const fields = text.replace(/\s/g, "").split(",");
|
|
2886
|
+
if (fields.length === 9) {
|
|
2887
|
+
ResultFormatter.departureAirport(decodeResult, fields[0]);
|
|
2888
|
+
ResultFormatter.arrivalAirport(decodeResult, fields[1]);
|
|
2889
|
+
decodeResult.raw.day = fields[2].substring(0, 2);
|
|
2890
|
+
decodeResult.raw.time = fields[2].substring(2);
|
|
2891
|
+
ResultFormatter.position(
|
|
2892
|
+
decodeResult,
|
|
2893
|
+
{
|
|
2894
|
+
latitude: Number(fields[3].replace(/\s/g, "")),
|
|
2895
|
+
longitude: Number(fields[4].replace(/\s/g, ""))
|
|
2896
|
+
}
|
|
2897
|
+
);
|
|
2898
|
+
ResultFormatter.altitude(decodeResult, Number(fields[5]));
|
|
2899
|
+
ResultFormatter.groundspeed(decodeResult, Number(fields[6]));
|
|
2900
|
+
ResultFormatter.heading(decodeResult, Number(fields[7]));
|
|
2901
|
+
ResultFormatter.unknown(decodeResult, fields[8]);
|
|
2902
|
+
} else {
|
|
2903
|
+
decodeResult.decoded = false;
|
|
2904
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
2905
|
+
}
|
|
2777
2906
|
}
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2907
|
+
if (decodeResult.decoded) {
|
|
2908
|
+
if (!decodeResult.remaining.text)
|
|
2909
|
+
decodeResult.decoder.decodeLevel = "full";
|
|
2910
|
+
else
|
|
2911
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
2912
|
+
} else {
|
|
2913
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2781
2914
|
}
|
|
2782
|
-
|
|
2783
|
-
} else {
|
|
2784
|
-
ResultFormatter.unknown(decodeResult, messageType);
|
|
2915
|
+
return decodeResult;
|
|
2785
2916
|
}
|
|
2786
|
-
}
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
decodeResult.formatted.description = "Position Report";
|
|
2796
|
-
} else if (type === "PRG") {
|
|
2797
|
-
decodeResult.formatted.description = "Progress Report";
|
|
2798
|
-
} else {
|
|
2799
|
-
decodeResult.formatted.description = "Unknown H1 Message";
|
|
2917
|
+
};
|
|
2918
|
+
|
|
2919
|
+
// lib/plugins/Label_8E.ts
|
|
2920
|
+
var Label_8E = class extends DecoderPlugin {
|
|
2921
|
+
name = "label-8e";
|
|
2922
|
+
qualifiers() {
|
|
2923
|
+
return {
|
|
2924
|
+
labels: ["8E"]
|
|
2925
|
+
};
|
|
2800
2926
|
}
|
|
2801
|
-
}
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
const
|
|
2807
|
-
const
|
|
2808
|
-
|
|
2927
|
+
decode(message, options = {}) {
|
|
2928
|
+
const decodeResult = this.defaultResult();
|
|
2929
|
+
decodeResult.decoder.name = this.name;
|
|
2930
|
+
decodeResult.formatted.description = "ETA Report";
|
|
2931
|
+
decodeResult.message = message;
|
|
2932
|
+
const regex = /^(?<arrival_icao>\w{4}),(?<arrival_eta>\d{4})$/;
|
|
2933
|
+
const results = message.text.match(regex);
|
|
2934
|
+
if (results?.groups) {
|
|
2935
|
+
if (options.debug) {
|
|
2936
|
+
console.log(`Label 8E ETA: groups`);
|
|
2937
|
+
console.log(results.groups);
|
|
2938
|
+
}
|
|
2939
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(results.groups.arrival_eta));
|
|
2940
|
+
ResultFormatter.arrivalAirport(decodeResult, results.groups.arrival_icao);
|
|
2941
|
+
}
|
|
2942
|
+
decodeResult.decoded = true;
|
|
2943
|
+
decodeResult.decoder.decodeLevel = "full";
|
|
2944
|
+
return decodeResult;
|
|
2809
2945
|
}
|
|
2810
|
-
}
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
});
|
|
2946
|
+
};
|
|
2947
|
+
|
|
2948
|
+
// lib/plugins/Label_B6.ts
|
|
2949
|
+
var Label_B6_Forwardslash = class extends DecoderPlugin {
|
|
2950
|
+
name = "label-b6-forwardslash";
|
|
2951
|
+
qualifiers() {
|
|
2952
|
+
return {
|
|
2953
|
+
labels: ["B6"],
|
|
2954
|
+
preambles: ["/"]
|
|
2955
|
+
};
|
|
2821
2956
|
}
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2957
|
+
decode(message, options = {}) {
|
|
2958
|
+
const decodeResult = this.defaultResult();
|
|
2959
|
+
decodeResult.decoder.name = this.name;
|
|
2960
|
+
decodeResult.formatted.description = "CPDLC Message";
|
|
2961
|
+
decodeResult.message = message;
|
|
2962
|
+
if (options.debug) {
|
|
2963
|
+
console.log("CPDLC: " + message);
|
|
2964
|
+
}
|
|
2965
|
+
return decodeResult;
|
|
2828
2966
|
}
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2967
|
+
};
|
|
2968
|
+
|
|
2969
|
+
// lib/plugins/Label_ColonComma.ts
|
|
2970
|
+
var Label_ColonComma = class extends DecoderPlugin {
|
|
2971
|
+
name = "label-colon-comma";
|
|
2972
|
+
qualifiers() {
|
|
2973
|
+
return {
|
|
2974
|
+
labels: [":;"]
|
|
2975
|
+
};
|
|
2838
2976
|
}
|
|
2839
|
-
}
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
decodeResult.
|
|
2977
|
+
decode(message, options = {}) {
|
|
2978
|
+
const decodeResult = this.defaultResult();
|
|
2979
|
+
decodeResult.decoder.name = this.name;
|
|
2980
|
+
decodeResult.raw.frequency = Number(message.text) / 1e3;
|
|
2981
|
+
decodeResult.formatted.description = "Aircraft Transceiver Frequency Change";
|
|
2844
2982
|
decodeResult.formatted.items.push({
|
|
2845
|
-
type: "
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2983
|
+
type: "frequency",
|
|
2984
|
+
label: "Frequency",
|
|
2985
|
+
value: `${decodeResult.raw.frequency} MHz`,
|
|
2986
|
+
code: "FREQ"
|
|
2849
2987
|
});
|
|
2988
|
+
decodeResult.decoded = true;
|
|
2989
|
+
decodeResult.decoder.decodeLevel = "full";
|
|
2990
|
+
return decodeResult;
|
|
2850
2991
|
}
|
|
2851
|
-
|
|
2852
|
-
ResultFormatter.altitude(decodeResult, Number(data[3]) * 100);
|
|
2853
|
-
processRoute(decodeResult, data[1], data[2], data[4], data[5], data[6]);
|
|
2854
|
-
ResultFormatter.temperature(decodeResult, data[7]);
|
|
2855
|
-
ResultFormatter.unknown(decodeResult, data[8]);
|
|
2856
|
-
ResultFormatter.unknown(decodeResult, data[9]);
|
|
2857
|
-
}
|
|
2858
|
-
if (data.length >= 14) {
|
|
2859
|
-
ResultFormatter.groundspeed(decodeResult, Number(data[10]));
|
|
2860
|
-
ResultFormatter.unknown(decodeResult, data[11]);
|
|
2861
|
-
ResultFormatter.unknown(decodeResult, data[12]);
|
|
2862
|
-
ResultFormatter.unknown(decodeResult, data[13]);
|
|
2863
|
-
}
|
|
2864
|
-
}
|
|
2865
|
-
function processRoute(decodeResult, last, time, next, eta, then, date) {
|
|
2866
|
-
const lastTime = date ? DateTimeUtils.convertDateTimeToEpoch(time, date) : DateTimeUtils.convertHHMMSSToTod(time);
|
|
2867
|
-
const nextTime = date ? DateTimeUtils.convertDateTimeToEpoch(eta, date) : DateTimeUtils.convertHHMMSSToTod(eta);
|
|
2868
|
-
const timeFormat = date ? "epoch" : "tod";
|
|
2869
|
-
const lastWaypoint = RouteUtils.getWaypoint(last);
|
|
2870
|
-
lastWaypoint.time = lastTime;
|
|
2871
|
-
lastWaypoint.timeFormat = timeFormat;
|
|
2872
|
-
const nextWaypoint = RouteUtils.getWaypoint(next);
|
|
2873
|
-
nextWaypoint.time = nextTime;
|
|
2874
|
-
nextWaypoint.timeFormat = timeFormat;
|
|
2875
|
-
const thenWaypoint = RouteUtils.getWaypoint(then || "?");
|
|
2876
|
-
const waypoints = [lastWaypoint, nextWaypoint, thenWaypoint];
|
|
2877
|
-
decodeResult.raw.route = { waypoints };
|
|
2878
|
-
decodeResult.formatted.items.push({
|
|
2879
|
-
type: "aircraft_route",
|
|
2880
|
-
code: "ROUTE",
|
|
2881
|
-
label: "Aircraft Route",
|
|
2882
|
-
value: RouteUtils.routeToString(decodeResult.raw.route)
|
|
2883
|
-
});
|
|
2884
|
-
}
|
|
2992
|
+
};
|
|
2885
2993
|
|
|
2886
2994
|
// lib/plugins/Label_H1.ts
|
|
2887
2995
|
var Label_H1 = class extends DecoderPlugin {
|
|
@@ -3040,9 +3148,9 @@ var Label_H1_StarPOS = class extends DecoderPlugin {
|
|
|
3040
3148
|
decodeResult.decoder.decodeLevel = "none";
|
|
3041
3149
|
return decodeResult;
|
|
3042
3150
|
}
|
|
3043
|
-
|
|
3044
|
-
decodeResult
|
|
3045
|
-
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(msg.substring(8, 12)
|
|
3151
|
+
ResultFormatter.month(decodeResult, Number(msg.substring(4, 6)));
|
|
3152
|
+
ResultFormatter.day(decodeResult, Number(msg.substring(6, 8)));
|
|
3153
|
+
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(msg.substring(8, 12)));
|
|
3046
3154
|
ResultFormatter.position(decodeResult, {
|
|
3047
3155
|
// Deg Min, no sec
|
|
3048
3156
|
latitude: CoordinateUtils.getDirection(msg.substring(12, 13)) * (Number(msg.substring(13, 15)) + Number(msg.substring(15, 17)) / 60),
|
|
@@ -3269,7 +3377,7 @@ var Label_QR = class extends DecoderPlugin {
|
|
|
3269
3377
|
decodeResult.formatted.description = "ON Report";
|
|
3270
3378
|
ResultFormatter.departureAirport(decodeResult, message.text.substring(0, 4));
|
|
3271
3379
|
ResultFormatter.arrivalAirport(decodeResult, message.text.substring(4, 8));
|
|
3272
|
-
ResultFormatter.on(decodeResult, DateTimeUtils.convertHHMMSSToTod(message.text.substring(8, 12)
|
|
3380
|
+
ResultFormatter.on(decodeResult, DateTimeUtils.convertHHMMSSToTod(message.text.substring(8, 12)));
|
|
3273
3381
|
ResultFormatter.unknown(decodeResult, message.text.substring(12));
|
|
3274
3382
|
decodeResult.decoded = true;
|
|
3275
3383
|
if (!decodeResult.remaining.text)
|
|
@@ -3294,7 +3402,7 @@ var Label_QP = class extends DecoderPlugin {
|
|
|
3294
3402
|
decodeResult.formatted.description = "OUT Report";
|
|
3295
3403
|
ResultFormatter.departureAirport(decodeResult, message.text.substring(0, 4));
|
|
3296
3404
|
ResultFormatter.arrivalAirport(decodeResult, message.text.substring(4, 8));
|
|
3297
|
-
ResultFormatter.out(decodeResult, DateTimeUtils.convertHHMMSSToTod(message.text.substring(8, 12)
|
|
3405
|
+
ResultFormatter.out(decodeResult, DateTimeUtils.convertHHMMSSToTod(message.text.substring(8, 12)));
|
|
3298
3406
|
ResultFormatter.unknown(decodeResult, message.text.substring(12));
|
|
3299
3407
|
decodeResult.decoded = true;
|
|
3300
3408
|
if (!decodeResult.remaining.text)
|
|
@@ -3319,7 +3427,7 @@ var Label_QS = class extends DecoderPlugin {
|
|
|
3319
3427
|
decodeResult.formatted.description = "IN Report";
|
|
3320
3428
|
ResultFormatter.departureAirport(decodeResult, message.text.substring(0, 4));
|
|
3321
3429
|
ResultFormatter.arrivalAirport(decodeResult, message.text.substring(4, 8));
|
|
3322
|
-
ResultFormatter.in(decodeResult, DateTimeUtils.convertHHMMSSToTod(message.text.substring(8, 12)
|
|
3430
|
+
ResultFormatter.in(decodeResult, DateTimeUtils.convertHHMMSSToTod(message.text.substring(8, 12)));
|
|
3323
3431
|
ResultFormatter.unknown(decodeResult, message.text.substring(12));
|
|
3324
3432
|
decodeResult.decoded = true;
|
|
3325
3433
|
if (!decodeResult.remaining.text)
|
|
@@ -3346,7 +3454,7 @@ var Label_QQ = class extends DecoderPlugin {
|
|
|
3346
3454
|
ResultFormatter.departureAirport(decodeResult, message.text.substring(0, 4));
|
|
3347
3455
|
ResultFormatter.arrivalAirport(decodeResult, message.text.substring(4, 8));
|
|
3348
3456
|
if (message.text.substring(12, 19) === "\r\n001FE") {
|
|
3349
|
-
decodeResult.raw.
|
|
3457
|
+
decodeResult.raw.day = message.text.substring(19, 21);
|
|
3350
3458
|
ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(message.text.substring(21, 27)));
|
|
3351
3459
|
let latdir = message.text.substring(27, 28);
|
|
3352
3460
|
let latdeg = Number(message.text.substring(28, 30));
|
|
@@ -4220,6 +4328,7 @@ var MessageDecoder = class {
|
|
|
4220
4328
|
this.registerPlugin(new Label_4A_DIS(this));
|
|
4221
4329
|
this.registerPlugin(new Label_4A_DOOR(this));
|
|
4222
4330
|
this.registerPlugin(new Label_4A_Slash_01(this));
|
|
4331
|
+
this.registerPlugin(new Label_4J_POS(this));
|
|
4223
4332
|
this.registerPlugin(new Label_4N(this));
|
|
4224
4333
|
this.registerPlugin(new Label_B6_Forwardslash(this));
|
|
4225
4334
|
this.registerPlugin(new Label_H1_FLR(this));
|