@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.js
CHANGED
|
@@ -75,10 +75,13 @@ var DateTimeUtils = class {
|
|
|
75
75
|
}
|
|
76
76
|
/**
|
|
77
77
|
*
|
|
78
|
-
* @param time HHMMSS
|
|
78
|
+
* @param time HHMMSS or HHMM
|
|
79
79
|
* @returns seconds since midnight
|
|
80
80
|
*/
|
|
81
81
|
static convertHHMMSSToTod(time) {
|
|
82
|
+
if (time.length === 4) {
|
|
83
|
+
time += "00";
|
|
84
|
+
}
|
|
82
85
|
const h = Number(time.substring(0, 2));
|
|
83
86
|
const m = Number(time.substring(2, 4));
|
|
84
87
|
const s = Number(time.substring(4, 6));
|
|
@@ -603,27 +606,36 @@ var ResultFormatter = class {
|
|
|
603
606
|
});
|
|
604
607
|
}
|
|
605
608
|
static day(decodeResult, day) {
|
|
606
|
-
decodeResult.raw.
|
|
609
|
+
decodeResult.raw.day = day;
|
|
607
610
|
decodeResult.formatted.items.push({
|
|
608
|
-
type: "
|
|
611
|
+
type: "day",
|
|
609
612
|
code: "MSG_DAY",
|
|
610
613
|
label: "Day of Month",
|
|
611
614
|
value: `${day}`
|
|
612
615
|
});
|
|
613
616
|
}
|
|
617
|
+
static month(decodeResult, month) {
|
|
618
|
+
decodeResult.raw.month = month;
|
|
619
|
+
decodeResult.formatted.items.push({
|
|
620
|
+
type: "month",
|
|
621
|
+
code: "MSG_MON",
|
|
622
|
+
label: "Month of Year",
|
|
623
|
+
value: `${month}`
|
|
624
|
+
});
|
|
625
|
+
}
|
|
614
626
|
static departureDay(decodeResult, day) {
|
|
615
|
-
decodeResult.raw.
|
|
627
|
+
decodeResult.raw.departure_day = day;
|
|
616
628
|
decodeResult.formatted.items.push({
|
|
617
|
-
type: "
|
|
629
|
+
type: "day",
|
|
618
630
|
code: "DEP_DAY",
|
|
619
631
|
label: "Departure Day",
|
|
620
632
|
value: `${day}`
|
|
621
633
|
});
|
|
622
634
|
}
|
|
623
635
|
static arrivalDay(decodeResult, day) {
|
|
624
|
-
decodeResult.raw.
|
|
636
|
+
decodeResult.raw.arrival_day = day;
|
|
625
637
|
decodeResult.formatted.items.push({
|
|
626
|
-
type: "
|
|
638
|
+
type: "day",
|
|
627
639
|
code: "ARR_DAY",
|
|
628
640
|
label: "Arrival Day",
|
|
629
641
|
value: `${day}`
|
|
@@ -718,14 +730,14 @@ var Label_5Z_Slash = class extends DecoderPlugin {
|
|
|
718
730
|
const info = data[2].split(" ");
|
|
719
731
|
ResultFormatter.departureAirport(decodeResult, info[1]);
|
|
720
732
|
ResultFormatter.arrivalAirport(decodeResult, info[2]);
|
|
721
|
-
decodeResult.raw.
|
|
733
|
+
decodeResult.raw.day = Number(info[3]);
|
|
722
734
|
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(info[4]));
|
|
723
735
|
ResultFormatter.arrivalRunway(decodeResult, info[5].slice(1));
|
|
724
736
|
ResultFormatter.unknownArr(decodeResult, data.slice(3), "/");
|
|
725
737
|
} else if (type === "B3") {
|
|
726
738
|
ResultFormatter.departureAirport(decodeResult, header[1].substring(0, 3), "IATA");
|
|
727
739
|
ResultFormatter.arrivalAirport(decodeResult, header[1].substring(3), "IATA");
|
|
728
|
-
decodeResult.raw.
|
|
740
|
+
decodeResult.raw.day = Number(header[2]);
|
|
729
741
|
ResultFormatter.arrivalRunway(decodeResult, header[3].slice(1));
|
|
730
742
|
if (header.length > 4) {
|
|
731
743
|
ResultFormatter.unknownArr(decodeResult, header.slice(4), "/");
|
|
@@ -734,7 +746,7 @@ var Label_5Z_Slash = class extends DecoderPlugin {
|
|
|
734
746
|
const info = data[2].split(" ");
|
|
735
747
|
ResultFormatter.departureAirport(decodeResult, info[1]);
|
|
736
748
|
ResultFormatter.arrivalAirport(decodeResult, info[2]);
|
|
737
|
-
decodeResult.raw.
|
|
749
|
+
decodeResult.raw.day = Number(info[3]);
|
|
738
750
|
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(info[4]));
|
|
739
751
|
ResultFormatter.unknownArr(decodeResult, info.slice(5), " ");
|
|
740
752
|
} else if (type === "C3") {
|
|
@@ -744,10 +756,10 @@ var Label_5Z_Slash = class extends DecoderPlugin {
|
|
|
744
756
|
const airports = data[2].split(" ");
|
|
745
757
|
ResultFormatter.departureAirport(decodeResult, airports[1]);
|
|
746
758
|
ResultFormatter.arrivalAirport(decodeResult, airports[2]);
|
|
747
|
-
decodeResult.raw.
|
|
759
|
+
decodeResult.raw.day = Number(airports[3]);
|
|
748
760
|
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(airports[4]));
|
|
749
761
|
const estimates = data[3].split(" ");
|
|
750
|
-
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(estimates[1]
|
|
762
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(estimates[1]));
|
|
751
763
|
ResultFormatter.unknown(decodeResult, estimates[2]);
|
|
752
764
|
} else {
|
|
753
765
|
if (options.debug) {
|
|
@@ -891,16 +903,16 @@ var Label_10_Slash = class extends DecoderPlugin {
|
|
|
891
903
|
ResultFormatter.heading(decodeResult, Number(parts[5]));
|
|
892
904
|
ResultFormatter.altitude(decodeResult, 100 * Number(parts[6]));
|
|
893
905
|
ResultFormatter.arrivalAirport(decodeResult, parts[7]);
|
|
894
|
-
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[8]
|
|
906
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[8]));
|
|
895
907
|
const waypoints = [{
|
|
896
908
|
name: parts[11]
|
|
897
909
|
}, {
|
|
898
910
|
name: parts[12],
|
|
899
|
-
time: DateTimeUtils.convertHHMMSSToTod(parts[13]
|
|
911
|
+
time: DateTimeUtils.convertHHMMSSToTod(parts[13]),
|
|
900
912
|
timeFormat: "tod"
|
|
901
913
|
}, {
|
|
902
914
|
name: parts[14],
|
|
903
|
-
time: DateTimeUtils.convertHHMMSSToTod(parts[15]
|
|
915
|
+
time: DateTimeUtils.convertHHMMSSToTod(parts[15]),
|
|
904
916
|
timeFormat: "tod"
|
|
905
917
|
}];
|
|
906
918
|
ResultFormatter.route(decodeResult, { waypoints });
|
|
@@ -920,7 +932,7 @@ var Label_12_N_Space = class extends DecoderPlugin {
|
|
|
920
932
|
qualifiers() {
|
|
921
933
|
return {
|
|
922
934
|
labels: ["12"],
|
|
923
|
-
preambles: ["N "]
|
|
935
|
+
preambles: ["N ", "S "]
|
|
924
936
|
};
|
|
925
937
|
}
|
|
926
938
|
decode(message, options = {}) {
|
|
@@ -986,7 +998,7 @@ var Label_13Through18_Slash = class extends DecoderPlugin {
|
|
|
986
998
|
const data = parts[2].split(" ");
|
|
987
999
|
ResultFormatter.departureAirport(decodeResult, data[1]);
|
|
988
1000
|
ResultFormatter.arrivalAirport(decodeResult, data[2]);
|
|
989
|
-
decodeResult.raw.
|
|
1001
|
+
decodeResult.raw.day = Number(data[3]);
|
|
990
1002
|
const time = DateTimeUtils.convertHHMMSSToTod(data[4]);
|
|
991
1003
|
if (labelNumber === 13) {
|
|
992
1004
|
ResultFormatter.out(decodeResult, time);
|
|
@@ -1046,7 +1058,7 @@ function getMsgType(labelNumber) {
|
|
|
1046
1058
|
|
|
1047
1059
|
// lib/plugins/Label_15.ts
|
|
1048
1060
|
var Label_15 = class extends DecoderPlugin {
|
|
1049
|
-
name = "label-
|
|
1061
|
+
name = "label-15";
|
|
1050
1062
|
qualifiers() {
|
|
1051
1063
|
return {
|
|
1052
1064
|
labels: ["15"],
|
|
@@ -1057,10 +1069,28 @@ var Label_15 = class extends DecoderPlugin {
|
|
|
1057
1069
|
const decodeResult = this.defaultResult();
|
|
1058
1070
|
decodeResult.decoder.name = this.name;
|
|
1059
1071
|
decodeResult.formatted.description = "Position Report";
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
ResultFormatter.position(decodeResult, CoordinateUtils.
|
|
1072
|
+
decodeResult.message = message;
|
|
1073
|
+
if (message.text.startsWith("(2") && message.text.endsWith("(Z")) {
|
|
1074
|
+
const between = message.text.substring(2, message.text.length - 2);
|
|
1075
|
+
ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(between.substring(0, 13)));
|
|
1076
|
+
if (between.length === 25) {
|
|
1077
|
+
ResultFormatter.unknown(decodeResult, between.substring(13, 19));
|
|
1078
|
+
const alt = between.substring(19, 22);
|
|
1079
|
+
if (alt != "---") {
|
|
1080
|
+
ResultFormatter.altitude(decodeResult, 100 * Number(alt));
|
|
1081
|
+
}
|
|
1082
|
+
ResultFormatter.temperature(decodeResult, between.substring(22).replace(" ", "0"));
|
|
1083
|
+
} else {
|
|
1084
|
+
ResultFormatter.unknown(decodeResult, between.substring(13));
|
|
1085
|
+
}
|
|
1086
|
+
} else {
|
|
1087
|
+
if (options.debug) {
|
|
1088
|
+
console.log(`Decoder: Unknown 15 message: ${message.text}`);
|
|
1089
|
+
}
|
|
1090
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
1091
|
+
decodeResult.decoded = false;
|
|
1092
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1093
|
+
return decodeResult;
|
|
1064
1094
|
}
|
|
1065
1095
|
decodeResult.decoded = true;
|
|
1066
1096
|
decodeResult.decoder.decodeLevel = "partial";
|
|
@@ -1113,7 +1143,7 @@ var Label_16_N_Space = class extends DecoderPlugin {
|
|
|
1113
1143
|
qualifiers() {
|
|
1114
1144
|
return {
|
|
1115
1145
|
labels: ["16"],
|
|
1116
|
-
preambles: ["N "]
|
|
1146
|
+
preambles: ["N ", "S "]
|
|
1117
1147
|
};
|
|
1118
1148
|
}
|
|
1119
1149
|
decode(message, options = {}) {
|
|
@@ -1243,7 +1273,7 @@ var Label_1L_3Line = class extends DecoderPlugin {
|
|
|
1243
1273
|
}
|
|
1244
1274
|
const eta = data.get("ETA");
|
|
1245
1275
|
if (eta) {
|
|
1246
|
-
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(eta
|
|
1276
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(eta));
|
|
1247
1277
|
data.delete("ETA");
|
|
1248
1278
|
}
|
|
1249
1279
|
const alt = data.get("ALT");
|
|
@@ -1324,8 +1354,8 @@ var Label_1L_070 = class extends DecoderPlugin {
|
|
|
1324
1354
|
}
|
|
1325
1355
|
ResultFormatter.departureAirport(decodeResult, parts[0]);
|
|
1326
1356
|
ResultFormatter.arrivalAirport(decodeResult, parts[1]);
|
|
1327
|
-
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[2]
|
|
1328
|
-
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[3]
|
|
1357
|
+
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[2]));
|
|
1358
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[3]));
|
|
1329
1359
|
ResultFormatter.position(decodeResult, {
|
|
1330
1360
|
latitude: CoordinateUtils.getDirection(parts[4][0]) * Number(parts[4].substring(1)),
|
|
1331
1361
|
longitude: CoordinateUtils.getDirection(parts[5][0]) * Number(parts[5].substring(1))
|
|
@@ -1445,7 +1475,7 @@ var Label_1L_Slash = class extends DecoderPlugin {
|
|
|
1445
1475
|
}
|
|
1446
1476
|
const eta = data.get("ETA");
|
|
1447
1477
|
if (eta) {
|
|
1448
|
-
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(eta
|
|
1478
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(eta));
|
|
1449
1479
|
data.delete("ETA");
|
|
1450
1480
|
}
|
|
1451
1481
|
let remaining = "";
|
|
@@ -1579,7 +1609,7 @@ var Label_22_OFF = class extends DecoderPlugin {
|
|
|
1579
1609
|
ResultFormatter.flightNumber(decodeResult, fields[0]);
|
|
1580
1610
|
ResultFormatter.departureDay(decodeResult, Number(fields[1].substring(0, 2)));
|
|
1581
1611
|
ResultFormatter.arrivalDay(decodeResult, Number(fields[1].substring(2, 4)));
|
|
1582
|
-
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(4, 8)
|
|
1612
|
+
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(4, 8)));
|
|
1583
1613
|
ResultFormatter.departureAirport(decodeResult, fields[1].substring(8, 12));
|
|
1584
1614
|
ResultFormatter.arrivalAirport(decodeResult, fields[1].substring(12, 16));
|
|
1585
1615
|
ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(16, 22)));
|
|
@@ -1595,7 +1625,7 @@ var Label_22_OFF = class extends DecoderPlugin {
|
|
|
1595
1625
|
}
|
|
1596
1626
|
ResultFormatter.departureAirport(decodeResult, fields[0]);
|
|
1597
1627
|
ResultFormatter.arrivalAirport(decodeResult, fields[1]);
|
|
1598
|
-
ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[2]
|
|
1628
|
+
ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[2]));
|
|
1599
1629
|
ResultFormatter.unknown(decodeResult, fields[3]);
|
|
1600
1630
|
decodeResult.decoded = true;
|
|
1601
1631
|
decodeResult.decoder.decodeLevel = "partial";
|
|
@@ -1612,12 +1642,12 @@ var Label_22_OFF = class extends DecoderPlugin {
|
|
|
1612
1642
|
ResultFormatter.position(decodeResult, position);
|
|
1613
1643
|
}
|
|
1614
1644
|
ResultFormatter.day(decodeResult, Number(fields[1].substring(14, 16)));
|
|
1615
|
-
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(16, 20)
|
|
1645
|
+
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(16, 20)));
|
|
1616
1646
|
ResultFormatter.departureAirport(decodeResult, fields[1].substring(20, 24));
|
|
1617
1647
|
ResultFormatter.arrivalAirport(decodeResult, fields[1].substring(24, 28));
|
|
1618
|
-
ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(28, 32)
|
|
1648
|
+
ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(28, 32)));
|
|
1619
1649
|
ResultFormatter.unknown(decodeResult, fields[1].substring(32, 36));
|
|
1620
|
-
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(36, 40)
|
|
1650
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(36, 40)));
|
|
1621
1651
|
decodeResult.decoded = true;
|
|
1622
1652
|
decodeResult.decoder.decodeLevel = "partial";
|
|
1623
1653
|
} else {
|
|
@@ -1699,7 +1729,7 @@ var Label_24_Slash = class extends DecoderPlugin {
|
|
|
1699
1729
|
longitude: (lon[0] === "E" ? 1 : -1) * Number(lon.substring(1))
|
|
1700
1730
|
};
|
|
1701
1731
|
ResultFormatter.position(decodeResult, position);
|
|
1702
|
-
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[8]
|
|
1732
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[8]));
|
|
1703
1733
|
ResultFormatter.unknown(decodeResult, fields[7]);
|
|
1704
1734
|
decodeResult.decoded = true;
|
|
1705
1735
|
decodeResult.decoder.decodeLevel = "partial";
|
|
@@ -1735,7 +1765,7 @@ var Label_30_Slash_EA = class extends DecoderPlugin {
|
|
|
1735
1765
|
console.log(results);
|
|
1736
1766
|
}
|
|
1737
1767
|
}
|
|
1738
|
-
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(results[0].substr(2, 4)
|
|
1768
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(results[0].substr(2, 4)));
|
|
1739
1769
|
if (results[1].substring(0, 2) === "DS") {
|
|
1740
1770
|
ResultFormatter.arrivalAirport(decodeResult, results[1].substring(2, 6));
|
|
1741
1771
|
ResultFormatter.unknown(decodeResult, "/".concat(results[2]));
|
|
@@ -1762,22 +1792,35 @@ var Label_44_ETA = class extends DecoderPlugin {
|
|
|
1762
1792
|
decodeResult.decoder.name = this.name;
|
|
1763
1793
|
decodeResult.formatted.description = "ETA Report";
|
|
1764
1794
|
decodeResult.message = message;
|
|
1765
|
-
const
|
|
1766
|
-
|
|
1767
|
-
if (results?.groups) {
|
|
1795
|
+
const data = message.text.split(",");
|
|
1796
|
+
if (data.length >= 9) {
|
|
1768
1797
|
if (options.debug) {
|
|
1769
1798
|
console.log(`Label 44 ETA Report: groups`);
|
|
1770
|
-
console.log(
|
|
1799
|
+
console.log(data);
|
|
1771
1800
|
}
|
|
1772
|
-
ResultFormatter.position(decodeResult, CoordinateUtils.
|
|
1773
|
-
ResultFormatter.
|
|
1774
|
-
ResultFormatter.
|
|
1775
|
-
decodeResult
|
|
1776
|
-
|
|
1777
|
-
);
|
|
1778
|
-
|
|
1779
|
-
|
|
1801
|
+
ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1]));
|
|
1802
|
+
ResultFormatter.altitude(decodeResult, 100 * Number(data[2]));
|
|
1803
|
+
ResultFormatter.departureAirport(decodeResult, data[3]);
|
|
1804
|
+
ResultFormatter.arrivalAirport(decodeResult, data[4]);
|
|
1805
|
+
ResultFormatter.month(decodeResult, Number(data[5].substring(0, 2)));
|
|
1806
|
+
ResultFormatter.day(decodeResult, Number(data[5].substring(2, 4)));
|
|
1807
|
+
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[6]));
|
|
1808
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[7]));
|
|
1809
|
+
const fuel = Number(data[8]);
|
|
1810
|
+
if (!isNaN(fuel)) {
|
|
1811
|
+
ResultFormatter.remainingFuel(decodeResult, Number(fuel));
|
|
1812
|
+
}
|
|
1813
|
+
if (data.length > 9) {
|
|
1814
|
+
ResultFormatter.unknownArr(decodeResult, data.slice(9));
|
|
1815
|
+
}
|
|
1816
|
+
} else {
|
|
1817
|
+
if (options.debug) {
|
|
1818
|
+
console.log(`Decoder: Unknown 44 message: ${message.text}`);
|
|
1780
1819
|
}
|
|
1820
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
1821
|
+
decodeResult.decoded = false;
|
|
1822
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1823
|
+
return decodeResult;
|
|
1781
1824
|
}
|
|
1782
1825
|
decodeResult.decoded = true;
|
|
1783
1826
|
decodeResult.decoder.decodeLevel = "full";
|
|
@@ -1799,22 +1842,33 @@ var Label_44_IN = class extends DecoderPlugin {
|
|
|
1799
1842
|
decodeResult.decoder.name = this.name;
|
|
1800
1843
|
decodeResult.formatted.description = "In Air Report";
|
|
1801
1844
|
decodeResult.message = message;
|
|
1802
|
-
const
|
|
1803
|
-
|
|
1804
|
-
if (results?.groups) {
|
|
1845
|
+
const data = message.text.split(",");
|
|
1846
|
+
if (data.length >= 7) {
|
|
1805
1847
|
if (options.debug) {
|
|
1806
1848
|
console.log(`Label 44 In Air Report: groups`);
|
|
1807
|
-
console.log(
|
|
1849
|
+
console.log(data);
|
|
1808
1850
|
}
|
|
1809
|
-
ResultFormatter.position(decodeResult, CoordinateUtils.
|
|
1810
|
-
ResultFormatter.departureAirport(decodeResult,
|
|
1811
|
-
ResultFormatter.arrivalAirport(decodeResult,
|
|
1812
|
-
decodeResult
|
|
1813
|
-
|
|
1814
|
-
);
|
|
1815
|
-
|
|
1816
|
-
|
|
1851
|
+
ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1]));
|
|
1852
|
+
ResultFormatter.departureAirport(decodeResult, data[2]);
|
|
1853
|
+
ResultFormatter.arrivalAirport(decodeResult, data[3]);
|
|
1854
|
+
ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
|
|
1855
|
+
ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
|
|
1856
|
+
ResultFormatter.in(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[5]));
|
|
1857
|
+
const fuel = Number(data[6]);
|
|
1858
|
+
if (!isNaN(fuel)) {
|
|
1859
|
+
ResultFormatter.remainingFuel(decodeResult, Number(fuel));
|
|
1860
|
+
}
|
|
1861
|
+
if (data.length > 7) {
|
|
1862
|
+
ResultFormatter.unknownArr(decodeResult, data.slice(7));
|
|
1863
|
+
}
|
|
1864
|
+
} else {
|
|
1865
|
+
if (options.debug) {
|
|
1866
|
+
console.log(`Decoder: Unknown 44 message: ${message.text}`);
|
|
1817
1867
|
}
|
|
1868
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
1869
|
+
decodeResult.decoded = false;
|
|
1870
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1871
|
+
return decodeResult;
|
|
1818
1872
|
}
|
|
1819
1873
|
decodeResult.decoded = true;
|
|
1820
1874
|
decodeResult.decoder.decodeLevel = "full";
|
|
@@ -1836,25 +1890,34 @@ var Label_44_OFF = class extends DecoderPlugin {
|
|
|
1836
1890
|
decodeResult.decoder.name = this.name;
|
|
1837
1891
|
decodeResult.formatted.description = "Off Runway Report";
|
|
1838
1892
|
decodeResult.message = message;
|
|
1839
|
-
const
|
|
1840
|
-
|
|
1841
|
-
if (results?.groups) {
|
|
1893
|
+
const data = message.text.split(",");
|
|
1894
|
+
if (data.length >= 8) {
|
|
1842
1895
|
if (options.debug) {
|
|
1843
1896
|
console.log(`Label 44 Off Runway Report: groups`);
|
|
1844
|
-
console.log(
|
|
1897
|
+
console.log(data);
|
|
1845
1898
|
}
|
|
1846
|
-
ResultFormatter.position(decodeResult, CoordinateUtils.
|
|
1847
|
-
ResultFormatter.departureAirport(decodeResult,
|
|
1848
|
-
ResultFormatter.arrivalAirport(decodeResult,
|
|
1849
|
-
decodeResult
|
|
1850
|
-
|
|
1851
|
-
);
|
|
1852
|
-
decodeResult
|
|
1853
|
-
|
|
1854
|
-
)
|
|
1855
|
-
|
|
1856
|
-
|
|
1899
|
+
ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1]));
|
|
1900
|
+
ResultFormatter.departureAirport(decodeResult, data[2]);
|
|
1901
|
+
ResultFormatter.arrivalAirport(decodeResult, data[3]);
|
|
1902
|
+
ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
|
|
1903
|
+
ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
|
|
1904
|
+
ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[5]));
|
|
1905
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[6]));
|
|
1906
|
+
const fuel = Number(data[7]);
|
|
1907
|
+
if (!isNaN(fuel)) {
|
|
1908
|
+
ResultFormatter.remainingFuel(decodeResult, Number(fuel));
|
|
1909
|
+
}
|
|
1910
|
+
if (data.length > 8) {
|
|
1911
|
+
ResultFormatter.unknownArr(decodeResult, data.slice(8));
|
|
1912
|
+
}
|
|
1913
|
+
} else {
|
|
1914
|
+
if (options.debug) {
|
|
1915
|
+
console.log(`Decoder: Unknown 44 message: ${message.text}`);
|
|
1857
1916
|
}
|
|
1917
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
1918
|
+
decodeResult.decoded = false;
|
|
1919
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1920
|
+
return decodeResult;
|
|
1858
1921
|
}
|
|
1859
1922
|
decodeResult.decoded = true;
|
|
1860
1923
|
decodeResult.decoder.decodeLevel = "full";
|
|
@@ -1876,22 +1939,33 @@ var Label_44_ON = class extends DecoderPlugin {
|
|
|
1876
1939
|
decodeResult.decoder.name = this.name;
|
|
1877
1940
|
decodeResult.formatted.description = "On Runway Report";
|
|
1878
1941
|
decodeResult.message = message;
|
|
1879
|
-
const
|
|
1880
|
-
|
|
1881
|
-
if (results?.groups) {
|
|
1942
|
+
const data = message.text.split(",");
|
|
1943
|
+
if (data.length >= 7) {
|
|
1882
1944
|
if (options.debug) {
|
|
1883
1945
|
console.log(`Label 44 On Runway Report: groups`);
|
|
1884
|
-
console.log(
|
|
1946
|
+
console.log(data);
|
|
1885
1947
|
}
|
|
1886
|
-
ResultFormatter.position(decodeResult, CoordinateUtils.
|
|
1887
|
-
ResultFormatter.departureAirport(decodeResult,
|
|
1888
|
-
ResultFormatter.arrivalAirport(decodeResult,
|
|
1889
|
-
decodeResult
|
|
1890
|
-
|
|
1891
|
-
);
|
|
1892
|
-
|
|
1893
|
-
|
|
1948
|
+
ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1]));
|
|
1949
|
+
ResultFormatter.departureAirport(decodeResult, data[2]);
|
|
1950
|
+
ResultFormatter.arrivalAirport(decodeResult, data[3]);
|
|
1951
|
+
ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
|
|
1952
|
+
ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
|
|
1953
|
+
ResultFormatter.on(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[5]));
|
|
1954
|
+
const fuel = Number(data[6]);
|
|
1955
|
+
if (!isNaN(fuel)) {
|
|
1956
|
+
ResultFormatter.remainingFuel(decodeResult, Number(fuel));
|
|
1957
|
+
}
|
|
1958
|
+
if (data.length > 7) {
|
|
1959
|
+
ResultFormatter.unknownArr(decodeResult, data.slice(7));
|
|
1960
|
+
}
|
|
1961
|
+
} else {
|
|
1962
|
+
if (options.debug) {
|
|
1963
|
+
console.log(`Decoder: Unknown 44 message: ${message.text}`);
|
|
1894
1964
|
}
|
|
1965
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
1966
|
+
decodeResult.decoded = false;
|
|
1967
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1968
|
+
return decodeResult;
|
|
1895
1969
|
}
|
|
1896
1970
|
decodeResult.decoded = true;
|
|
1897
1971
|
decodeResult.decoder.decodeLevel = "full";
|
|
@@ -2150,456 +2224,95 @@ var Label_4A_Slash_01 = class extends DecoderPlugin {
|
|
|
2150
2224
|
}
|
|
2151
2225
|
};
|
|
2152
2226
|
|
|
2153
|
-
// lib/
|
|
2154
|
-
var
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
let
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2227
|
+
// lib/utils/flight_plan_utils.ts
|
|
2228
|
+
var FlightPlanUtils = class _FlightPlanUtils {
|
|
2229
|
+
/**
|
|
2230
|
+
* Processes flight plan data
|
|
2231
|
+
*
|
|
2232
|
+
* Expected format is [header, key1, val1, ... keyN, valN]
|
|
2233
|
+
*
|
|
2234
|
+
* @param decodeResult - results
|
|
2235
|
+
* @param data - original message split by ':'
|
|
2236
|
+
* @returns whether all fields were processed or not
|
|
2237
|
+
*/
|
|
2238
|
+
static processFlightPlan(decodeResult, data) {
|
|
2239
|
+
let allKnownFields = _FlightPlanUtils.parseHeader(decodeResult, data[0]);
|
|
2240
|
+
for (let i = 1; i < data.length; i += 2) {
|
|
2241
|
+
const key = data[i];
|
|
2242
|
+
const value = data[i + 1];
|
|
2243
|
+
switch (key) {
|
|
2244
|
+
case "A":
|
|
2245
|
+
addProcedure(decodeResult, value, "arrival");
|
|
2246
|
+
break;
|
|
2247
|
+
case "AA":
|
|
2248
|
+
addArrivalAirport(decodeResult, value);
|
|
2249
|
+
break;
|
|
2250
|
+
case "AP":
|
|
2251
|
+
addProcedure(decodeResult, value, "approach");
|
|
2252
|
+
break;
|
|
2253
|
+
case "CR":
|
|
2254
|
+
addCompanyRoute(decodeResult, value);
|
|
2255
|
+
break;
|
|
2256
|
+
case "D":
|
|
2257
|
+
addProcedure(decodeResult, value, "departure");
|
|
2258
|
+
break;
|
|
2259
|
+
case "DA":
|
|
2260
|
+
addDepartureAirport(decodeResult, value);
|
|
2261
|
+
break;
|
|
2262
|
+
case "F":
|
|
2263
|
+
addRoute(decodeResult, value);
|
|
2264
|
+
break;
|
|
2265
|
+
case "R":
|
|
2266
|
+
addRunway(decodeResult, value);
|
|
2267
|
+
break;
|
|
2268
|
+
// case 'WS': // something about routes, has altitude, so current parsing won't work
|
|
2269
|
+
// break;
|
|
2270
|
+
default:
|
|
2271
|
+
if (allKnownFields) {
|
|
2272
|
+
decodeResult.remaining.text = "";
|
|
2273
|
+
allKnownFields = false;
|
|
2274
|
+
}
|
|
2275
|
+
decodeResult.remaining.text += `:${key}:${value}`;
|
|
2276
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
2192
2277
|
}
|
|
2193
|
-
ResultFormatter.checksum(decodeResult, fields[32]);
|
|
2194
|
-
ResultFormatter.unknownArr(decodeResult, [...fields.slice(1, 3), fields[7], ...fields.slice(13, 32)].filter((f) => f != ""));
|
|
2195
|
-
} else {
|
|
2196
|
-
decodeResult.decoded = false;
|
|
2197
|
-
ResultFormatter.unknown(decodeResult, text);
|
|
2198
2278
|
}
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2279
|
+
return allKnownFields;
|
|
2280
|
+
}
|
|
2281
|
+
static parseHeader(decodeResult, header) {
|
|
2282
|
+
let allKnownFields = true;
|
|
2283
|
+
if (header.startsWith("RF")) {
|
|
2284
|
+
decodeResult.formatted.items.push({
|
|
2285
|
+
type: "status",
|
|
2286
|
+
code: "ROUTE_STATUS",
|
|
2287
|
+
label: "Route Status",
|
|
2288
|
+
value: "Route Filed"
|
|
2289
|
+
});
|
|
2290
|
+
decodeResult.raw.route_status = "RF";
|
|
2291
|
+
if (header.length > 2) {
|
|
2292
|
+
addRoute(decodeResult, header.substring(2));
|
|
2293
|
+
}
|
|
2294
|
+
} else if (header.startsWith("RP")) {
|
|
2295
|
+
decodeResult.raw.route_status = "RP";
|
|
2296
|
+
decodeResult.formatted.items.push({
|
|
2297
|
+
type: "status",
|
|
2298
|
+
code: "ROUTE_STATUS",
|
|
2299
|
+
label: "Route Status",
|
|
2300
|
+
value: "Route Planned"
|
|
2301
|
+
});
|
|
2302
|
+
decodeResult.raw.route_status = header;
|
|
2303
|
+
} else if (header.startsWith("RI")) {
|
|
2304
|
+
decodeResult.raw.route_status = "RI";
|
|
2305
|
+
decodeResult.formatted.items.push({
|
|
2306
|
+
type: "status",
|
|
2307
|
+
code: "ROUTE_STATUS",
|
|
2308
|
+
label: "Route Status",
|
|
2309
|
+
value: "Route Inactive"
|
|
2310
|
+
});
|
|
2204
2311
|
} else {
|
|
2205
|
-
decodeResult.
|
|
2312
|
+
decodeResult.remaining.text += header;
|
|
2313
|
+
allKnownFields = false;
|
|
2206
2314
|
}
|
|
2207
|
-
return
|
|
2208
|
-
}
|
|
2209
|
-
};
|
|
2210
|
-
|
|
2211
|
-
// lib/plugins/Label_80.ts
|
|
2212
|
-
var Label_80 = class extends DecoderPlugin {
|
|
2213
|
-
name = "label-80";
|
|
2214
|
-
descriptions = {
|
|
2215
|
-
ALT: "Altitude",
|
|
2216
|
-
DWND: "Wind Direction",
|
|
2217
|
-
ETA: "Estimated Time of Arrival",
|
|
2218
|
-
FOB: "Fuel on Board",
|
|
2219
|
-
FL: "Flight Level",
|
|
2220
|
-
HDG: "Heading",
|
|
2221
|
-
MCH: "Aircraft Speed",
|
|
2222
|
-
NWYP: "Next Waypoint",
|
|
2223
|
-
POS: "Aircraft Position",
|
|
2224
|
-
SAT: "Static Air Temperature",
|
|
2225
|
-
SWND: "Wind Speed",
|
|
2226
|
-
TAS: "True Airspeed",
|
|
2227
|
-
WYP: "Waypoint"
|
|
2228
|
-
};
|
|
2229
|
-
qualifiers() {
|
|
2230
|
-
return {
|
|
2231
|
-
labels: ["80"],
|
|
2232
|
-
preambles: ["3N01 POSRPT"]
|
|
2233
|
-
};
|
|
2234
|
-
}
|
|
2235
|
-
decode(message, options = {}) {
|
|
2236
|
-
const decodeResult = this.defaultResult();
|
|
2237
|
-
decodeResult.decoder.name = this.name;
|
|
2238
|
-
decodeResult.formatted.description = "Airline Defined Position Report";
|
|
2239
|
-
const parts = message.text.split("\n");
|
|
2240
|
-
let posRptRegex = /^3N01 POSRPT \d\d\d\d\/\d\d (?<orig>\w+)\/(?<dest>\w+) \.(?<tail>[\w-]+)(\/(?<agate>.+) (?<sta>\w+:\w+))*/;
|
|
2241
|
-
let results = parts[0].match(posRptRegex);
|
|
2242
|
-
if (!results?.groups) {
|
|
2243
|
-
decodeResult.decoded = false;
|
|
2244
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
2245
|
-
return decodeResult;
|
|
2246
|
-
}
|
|
2247
|
-
if (results && results.length > 0) {
|
|
2248
|
-
ResultFormatter.departureAirport(decodeResult, results.groups.orig);
|
|
2249
|
-
ResultFormatter.arrivalAirport(decodeResult, results.groups.dest);
|
|
2250
|
-
ResultFormatter.tail(decodeResult, results.groups.tail);
|
|
2251
|
-
if (results.groups.agate) {
|
|
2252
|
-
decodeResult.raw.arrival_gate = results.groups.agate;
|
|
2253
|
-
decodeResult.formatted.items.push({
|
|
2254
|
-
type: "arrival_gate",
|
|
2255
|
-
code: "ARG",
|
|
2256
|
-
label: "Arrival Gate",
|
|
2257
|
-
value: `${results.groups.agate}`
|
|
2258
|
-
});
|
|
2259
|
-
decodeResult.raw.scheduled_time_of_arrival = results.groups.sta;
|
|
2260
|
-
decodeResult.formatted.items.push({
|
|
2261
|
-
type: "scheduled_time_of_arrival",
|
|
2262
|
-
code: "STA",
|
|
2263
|
-
label: "Scheduled Time of Arrival",
|
|
2264
|
-
value: `${results.groups.sta}`
|
|
2265
|
-
});
|
|
2266
|
-
}
|
|
2267
|
-
posRptRegex = /\/(?<field>\w+)\s(?<value>[\w\+\-:\.]+)\s*/gi;
|
|
2268
|
-
const remainingParts = parts.slice(1);
|
|
2269
|
-
for (const part of remainingParts) {
|
|
2270
|
-
const matches = part.matchAll(posRptRegex);
|
|
2271
|
-
for (const match of matches) {
|
|
2272
|
-
switch (match.groups?.field) {
|
|
2273
|
-
case "ALT": {
|
|
2274
|
-
ResultFormatter.altitude(decodeResult, Number(match.groups.value));
|
|
2275
|
-
break;
|
|
2276
|
-
}
|
|
2277
|
-
case "DWND": {
|
|
2278
|
-
decodeResult.raw.wind_direction = Number(match.groups.value);
|
|
2279
|
-
decodeResult.formatted.items.push({
|
|
2280
|
-
type: "wind_direction",
|
|
2281
|
-
code: "DWND",
|
|
2282
|
-
label: this.descriptions[match.groups.field],
|
|
2283
|
-
value: decodeResult.raw.wind_direction
|
|
2284
|
-
});
|
|
2285
|
-
break;
|
|
2286
|
-
}
|
|
2287
|
-
case "FL": {
|
|
2288
|
-
const flight_level = Number(match.groups.value);
|
|
2289
|
-
ResultFormatter.altitude(decodeResult, flight_level * 100);
|
|
2290
|
-
break;
|
|
2291
|
-
}
|
|
2292
|
-
case "FOB": {
|
|
2293
|
-
const fob = Number(match.groups.value);
|
|
2294
|
-
if (!isNaN(fob)) {
|
|
2295
|
-
ResultFormatter.currentFuel(decodeResult, fob);
|
|
2296
|
-
}
|
|
2297
|
-
break;
|
|
2298
|
-
}
|
|
2299
|
-
case "HDG": {
|
|
2300
|
-
ResultFormatter.heading(decodeResult, Number(match.groups.value));
|
|
2301
|
-
break;
|
|
2302
|
-
}
|
|
2303
|
-
case "MCH": {
|
|
2304
|
-
decodeResult.raw.mach = Number(match.groups.value) / 1e3;
|
|
2305
|
-
decodeResult.formatted.items.push({
|
|
2306
|
-
type: "mach",
|
|
2307
|
-
code: "MCH",
|
|
2308
|
-
label: this.descriptions[match.groups.field],
|
|
2309
|
-
value: `${decodeResult.raw.mach} Mach`
|
|
2310
|
-
});
|
|
2311
|
-
break;
|
|
2312
|
-
}
|
|
2313
|
-
case "NWYP": {
|
|
2314
|
-
decodeResult.raw.next_waypoint = match.groups.value;
|
|
2315
|
-
decodeResult.formatted.items.push({
|
|
2316
|
-
type: "next_waypoint",
|
|
2317
|
-
code: "NWYP",
|
|
2318
|
-
label: this.descriptions[match.groups.field],
|
|
2319
|
-
value: decodeResult.raw.next_waypoint
|
|
2320
|
-
});
|
|
2321
|
-
break;
|
|
2322
|
-
}
|
|
2323
|
-
case "POS": {
|
|
2324
|
-
const posRegex = /^(?<latd>[NS])(?<lat>.+)(?<lngd>[EW])(?<lng>.+)/;
|
|
2325
|
-
const posResult = match.groups.value.match(posRegex);
|
|
2326
|
-
const lat = Number(posResult?.groups?.lat) * (posResult?.groups?.lngd === "S" ? -1 : 1);
|
|
2327
|
-
const lon = Number(posResult?.groups?.lng) * (posResult?.groups?.lngd === "W" ? -1 : 1);
|
|
2328
|
-
const position = {
|
|
2329
|
-
latitude: Number.isInteger(lat) ? lat / 1e3 : lat / 100,
|
|
2330
|
-
longitude: Number.isInteger(lon) ? lon / 1e3 : lon / 100
|
|
2331
|
-
};
|
|
2332
|
-
ResultFormatter.position(decodeResult, position);
|
|
2333
|
-
break;
|
|
2334
|
-
}
|
|
2335
|
-
case "SWND": {
|
|
2336
|
-
decodeResult.raw.wind_speed = Number(match.groups.value);
|
|
2337
|
-
decodeResult.formatted.items.push({
|
|
2338
|
-
type: "wind_speed",
|
|
2339
|
-
code: "SWND",
|
|
2340
|
-
label: this.descriptions[match.groups.field],
|
|
2341
|
-
value: decodeResult.raw.wind_speed
|
|
2342
|
-
});
|
|
2343
|
-
break;
|
|
2344
|
-
}
|
|
2345
|
-
default: {
|
|
2346
|
-
if (match.groups?.field != void 0) {
|
|
2347
|
-
const description = this.descriptions[match.groups.field] ? this.descriptions[match.groups.field] : "Unknown";
|
|
2348
|
-
decodeResult.formatted.items.push({
|
|
2349
|
-
type: match.groups.field,
|
|
2350
|
-
code: match.groups.field,
|
|
2351
|
-
label: description || `Unknown (${match.groups.field})`,
|
|
2352
|
-
value: `${match.groups.value}`
|
|
2353
|
-
});
|
|
2354
|
-
}
|
|
2355
|
-
}
|
|
2356
|
-
}
|
|
2357
|
-
}
|
|
2358
|
-
}
|
|
2359
|
-
decodeResult.decoded = true;
|
|
2360
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
2361
|
-
}
|
|
2362
|
-
return decodeResult;
|
|
2363
|
-
}
|
|
2364
|
-
};
|
|
2365
|
-
|
|
2366
|
-
// lib/plugins/Label_83.ts
|
|
2367
|
-
var Label_83 = class extends DecoderPlugin {
|
|
2368
|
-
name = "label-83";
|
|
2369
|
-
qualifiers() {
|
|
2370
|
-
return {
|
|
2371
|
-
labels: ["83"]
|
|
2372
|
-
};
|
|
2373
|
-
}
|
|
2374
|
-
decode(message, options = {}) {
|
|
2375
|
-
const decodeResult = this.defaultResult();
|
|
2376
|
-
decodeResult.decoder.name = this.name;
|
|
2377
|
-
decodeResult.message = message;
|
|
2378
|
-
decodeResult.formatted.description = "Airline Defined";
|
|
2379
|
-
let text = message.text;
|
|
2380
|
-
if (text.match(/^M\d{2}A\w{6}/)) {
|
|
2381
|
-
ResultFormatter.flightNumber(decodeResult, message.text.substring(4, 10).replace(/^([A-Z]+)0*/g, "$1"));
|
|
2382
|
-
text = text.substring(10);
|
|
2383
|
-
}
|
|
2384
|
-
decodeResult.decoded = true;
|
|
2385
|
-
if (text.substring(0, 10) === "4DH3 ETAT2") {
|
|
2386
|
-
const fields = text.split(/\s+/);
|
|
2387
|
-
if (fields[2].length > 5) {
|
|
2388
|
-
decodeResult.raw.day_of_month = fields[2].substring(5);
|
|
2389
|
-
}
|
|
2390
|
-
ResultFormatter.unknown(decodeResult, fields[2].substring(0, 4));
|
|
2391
|
-
const subfields = fields[3].split("/");
|
|
2392
|
-
ResultFormatter.departureAirport(decodeResult, subfields[0]);
|
|
2393
|
-
ResultFormatter.arrivalAirport(decodeResult, subfields[1]);
|
|
2394
|
-
ResultFormatter.tail(decodeResult, fields[4].replace(/\./g, ""));
|
|
2395
|
-
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[6] + "00"));
|
|
2396
|
-
} else if (text.substring(0, 5) === "001PR") {
|
|
2397
|
-
decodeResult.raw.day_of_month = text.substring(5, 7);
|
|
2398
|
-
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(text.substring(13, 28).replace(/\./g, ""));
|
|
2399
|
-
if (position) {
|
|
2400
|
-
ResultFormatter.position(decodeResult, position);
|
|
2401
|
-
}
|
|
2402
|
-
ResultFormatter.altitude(decodeResult, Number(text.substring(28, 33)));
|
|
2403
|
-
ResultFormatter.unknown(decodeResult, text.substring(33));
|
|
2404
|
-
} else {
|
|
2405
|
-
const fields = text.replace(/\s/g, "").split(",");
|
|
2406
|
-
if (fields.length === 9) {
|
|
2407
|
-
ResultFormatter.departureAirport(decodeResult, fields[0]);
|
|
2408
|
-
ResultFormatter.arrivalAirport(decodeResult, fields[1]);
|
|
2409
|
-
decodeResult.raw.day_of_month = fields[2].substring(0, 2);
|
|
2410
|
-
decodeResult.raw.time = fields[2].substring(2);
|
|
2411
|
-
ResultFormatter.position(
|
|
2412
|
-
decodeResult,
|
|
2413
|
-
{
|
|
2414
|
-
latitude: Number(fields[3].replace(/\s/g, "")),
|
|
2415
|
-
longitude: Number(fields[4].replace(/\s/g, ""))
|
|
2416
|
-
}
|
|
2417
|
-
);
|
|
2418
|
-
ResultFormatter.altitude(decodeResult, Number(fields[5]));
|
|
2419
|
-
ResultFormatter.groundspeed(decodeResult, Number(fields[6]));
|
|
2420
|
-
ResultFormatter.heading(decodeResult, Number(fields[7]));
|
|
2421
|
-
ResultFormatter.unknown(decodeResult, fields[8]);
|
|
2422
|
-
} else {
|
|
2423
|
-
decodeResult.decoded = false;
|
|
2424
|
-
ResultFormatter.unknown(decodeResult, message.text);
|
|
2425
|
-
}
|
|
2426
|
-
}
|
|
2427
|
-
if (decodeResult.decoded) {
|
|
2428
|
-
if (!decodeResult.remaining.text)
|
|
2429
|
-
decodeResult.decoder.decodeLevel = "full";
|
|
2430
|
-
else
|
|
2431
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
2432
|
-
} else {
|
|
2433
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
2434
|
-
}
|
|
2435
|
-
return decodeResult;
|
|
2436
|
-
}
|
|
2437
|
-
};
|
|
2438
|
-
|
|
2439
|
-
// lib/plugins/Label_8E.ts
|
|
2440
|
-
var Label_8E = class extends DecoderPlugin {
|
|
2441
|
-
name = "label-8e";
|
|
2442
|
-
qualifiers() {
|
|
2443
|
-
return {
|
|
2444
|
-
labels: ["8E"]
|
|
2445
|
-
};
|
|
2446
|
-
}
|
|
2447
|
-
decode(message, options = {}) {
|
|
2448
|
-
const decodeResult = this.defaultResult();
|
|
2449
|
-
decodeResult.decoder.name = this.name;
|
|
2450
|
-
decodeResult.formatted.description = "ETA Report";
|
|
2451
|
-
decodeResult.message = message;
|
|
2452
|
-
const regex = /^(?<arrival_icao>\w{4}),(?<arrival_eta>\d{4})$/;
|
|
2453
|
-
const results = message.text.match(regex);
|
|
2454
|
-
if (results?.groups) {
|
|
2455
|
-
if (options.debug) {
|
|
2456
|
-
console.log(`Label 8E ETA: groups`);
|
|
2457
|
-
console.log(results.groups);
|
|
2458
|
-
}
|
|
2459
|
-
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(results.groups.arrival_eta + "00"));
|
|
2460
|
-
ResultFormatter.arrivalAirport(decodeResult, results.groups.arrival_icao);
|
|
2461
|
-
}
|
|
2462
|
-
decodeResult.decoded = true;
|
|
2463
|
-
decodeResult.decoder.decodeLevel = "full";
|
|
2464
|
-
return decodeResult;
|
|
2465
|
-
}
|
|
2466
|
-
};
|
|
2467
|
-
|
|
2468
|
-
// lib/plugins/Label_B6.ts
|
|
2469
|
-
var Label_B6_Forwardslash = class extends DecoderPlugin {
|
|
2470
|
-
name = "label-b6-forwardslash";
|
|
2471
|
-
qualifiers() {
|
|
2472
|
-
return {
|
|
2473
|
-
labels: ["B6"],
|
|
2474
|
-
preambles: ["/"]
|
|
2475
|
-
};
|
|
2476
|
-
}
|
|
2477
|
-
decode(message, options = {}) {
|
|
2478
|
-
const decodeResult = this.defaultResult();
|
|
2479
|
-
decodeResult.decoder.name = this.name;
|
|
2480
|
-
decodeResult.formatted.description = "CPDLC Message";
|
|
2481
|
-
decodeResult.message = message;
|
|
2482
|
-
if (options.debug) {
|
|
2483
|
-
console.log("CPDLC: " + message);
|
|
2484
|
-
}
|
|
2485
|
-
return decodeResult;
|
|
2486
|
-
}
|
|
2487
|
-
};
|
|
2488
|
-
|
|
2489
|
-
// lib/plugins/Label_ColonComma.ts
|
|
2490
|
-
var Label_ColonComma = class extends DecoderPlugin {
|
|
2491
|
-
name = "label-colon-comma";
|
|
2492
|
-
qualifiers() {
|
|
2493
|
-
return {
|
|
2494
|
-
labels: [":;"]
|
|
2495
|
-
};
|
|
2496
|
-
}
|
|
2497
|
-
decode(message, options = {}) {
|
|
2498
|
-
const decodeResult = this.defaultResult();
|
|
2499
|
-
decodeResult.decoder.name = this.name;
|
|
2500
|
-
decodeResult.raw.frequency = Number(message.text) / 1e3;
|
|
2501
|
-
decodeResult.formatted.description = "Aircraft Transceiver Frequency Change";
|
|
2502
|
-
decodeResult.formatted.items.push({
|
|
2503
|
-
type: "frequency",
|
|
2504
|
-
label: "Frequency",
|
|
2505
|
-
value: `${decodeResult.raw.frequency} MHz`,
|
|
2506
|
-
code: "FREQ"
|
|
2507
|
-
});
|
|
2508
|
-
decodeResult.decoded = true;
|
|
2509
|
-
decodeResult.decoder.decodeLevel = "full";
|
|
2510
|
-
return decodeResult;
|
|
2511
|
-
}
|
|
2512
|
-
};
|
|
2513
|
-
|
|
2514
|
-
// lib/utils/flight_plan_utils.ts
|
|
2515
|
-
var FlightPlanUtils = class _FlightPlanUtils {
|
|
2516
|
-
/**
|
|
2517
|
-
* Processes flight plan data
|
|
2518
|
-
*
|
|
2519
|
-
* Expected format is [header, key1, val1, ... keyN, valN]
|
|
2520
|
-
*
|
|
2521
|
-
* @param decodeResult - results
|
|
2522
|
-
* @param data - original message split by ':'
|
|
2523
|
-
* @returns whether all fields were processed or not
|
|
2524
|
-
*/
|
|
2525
|
-
static processFlightPlan(decodeResult, data) {
|
|
2526
|
-
let allKnownFields = _FlightPlanUtils.parseHeader(decodeResult, data[0]);
|
|
2527
|
-
for (let i = 1; i < data.length; i += 2) {
|
|
2528
|
-
const key = data[i];
|
|
2529
|
-
const value = data[i + 1];
|
|
2530
|
-
switch (key) {
|
|
2531
|
-
case "A":
|
|
2532
|
-
addProcedure(decodeResult, value, "arrival");
|
|
2533
|
-
break;
|
|
2534
|
-
case "AA":
|
|
2535
|
-
addArrivalAirport(decodeResult, value);
|
|
2536
|
-
break;
|
|
2537
|
-
case "AP":
|
|
2538
|
-
addProcedure(decodeResult, value, "approach");
|
|
2539
|
-
break;
|
|
2540
|
-
case "CR":
|
|
2541
|
-
addCompanyRoute(decodeResult, value);
|
|
2542
|
-
break;
|
|
2543
|
-
case "D":
|
|
2544
|
-
addProcedure(decodeResult, value, "departure");
|
|
2545
|
-
break;
|
|
2546
|
-
case "DA":
|
|
2547
|
-
addDepartureAirport(decodeResult, value);
|
|
2548
|
-
break;
|
|
2549
|
-
case "F":
|
|
2550
|
-
addRoute(decodeResult, value);
|
|
2551
|
-
break;
|
|
2552
|
-
case "R":
|
|
2553
|
-
addRunway(decodeResult, value);
|
|
2554
|
-
break;
|
|
2555
|
-
// case 'WS': // something about routes, has altitude, so current parsing won't work
|
|
2556
|
-
// break;
|
|
2557
|
-
default:
|
|
2558
|
-
if (allKnownFields) {
|
|
2559
|
-
decodeResult.remaining.text = "";
|
|
2560
|
-
allKnownFields = false;
|
|
2561
|
-
}
|
|
2562
|
-
decodeResult.remaining.text += `:${key}:${value}`;
|
|
2563
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
2564
|
-
}
|
|
2565
|
-
}
|
|
2566
|
-
return allKnownFields;
|
|
2567
|
-
}
|
|
2568
|
-
static parseHeader(decodeResult, header) {
|
|
2569
|
-
let allKnownFields = true;
|
|
2570
|
-
if (header.startsWith("RF")) {
|
|
2571
|
-
decodeResult.formatted.items.push({
|
|
2572
|
-
type: "status",
|
|
2573
|
-
code: "ROUTE_STATUS",
|
|
2574
|
-
label: "Route Status",
|
|
2575
|
-
value: "Route Filed"
|
|
2576
|
-
});
|
|
2577
|
-
decodeResult.raw.route_status = "RF";
|
|
2578
|
-
if (header.length > 2) {
|
|
2579
|
-
addRoute(decodeResult, header.substring(2));
|
|
2580
|
-
}
|
|
2581
|
-
} else if (header.startsWith("RP")) {
|
|
2582
|
-
decodeResult.raw.route_status = "RP";
|
|
2583
|
-
decodeResult.formatted.items.push({
|
|
2584
|
-
type: "status",
|
|
2585
|
-
code: "ROUTE_STATUS",
|
|
2586
|
-
label: "Route Status",
|
|
2587
|
-
value: "Route Planned"
|
|
2588
|
-
});
|
|
2589
|
-
decodeResult.raw.route_status = header;
|
|
2590
|
-
} else if (header.startsWith("RI")) {
|
|
2591
|
-
decodeResult.raw.route_status = "RI";
|
|
2592
|
-
decodeResult.formatted.items.push({
|
|
2593
|
-
type: "status",
|
|
2594
|
-
code: "ROUTE_STATUS",
|
|
2595
|
-
label: "Route Status",
|
|
2596
|
-
value: "Route Inactive"
|
|
2597
|
-
});
|
|
2598
|
-
} else {
|
|
2599
|
-
decodeResult.remaining.text += header;
|
|
2600
|
-
allKnownFields = false;
|
|
2601
|
-
}
|
|
2602
|
-
return allKnownFields;
|
|
2315
|
+
return allKnownFields;
|
|
2603
2316
|
}
|
|
2604
2317
|
};
|
|
2605
2318
|
function addArrivalAirport(decodeResult, value) {
|
|
@@ -2711,9 +2424,11 @@ var H1Helper = class {
|
|
|
2711
2424
|
ResultFormatter.freetext(decodeResult, fields[i].substring(2));
|
|
2712
2425
|
} else if (fields[i].startsWith("ET")) {
|
|
2713
2426
|
if (fields[i].length === 7) {
|
|
2714
|
-
ResultFormatter.
|
|
2427
|
+
ResultFormatter.day(decodeResult, Number(fields[i].substring(2, 3)));
|
|
2428
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[i].substring(3)));
|
|
2715
2429
|
} else if (fields[i].length === 8) {
|
|
2716
|
-
ResultFormatter.
|
|
2430
|
+
ResultFormatter.day(decodeResult, Number(fields[i].substring(2, 4)));
|
|
2431
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[i].substring(4)));
|
|
2717
2432
|
} else {
|
|
2718
2433
|
ResultFormatter.unknown(decodeResult, fields[i], "/");
|
|
2719
2434
|
}
|
|
@@ -2764,161 +2479,554 @@ function processIdentification(decodeResult, data) {
|
|
|
2764
2479
|
decodeResult.raw.mission_number = data[2];
|
|
2765
2480
|
}
|
|
2766
2481
|
}
|
|
2767
|
-
function processDT(decodeResult, data) {
|
|
2768
|
-
if (!decodeResult.raw.arrival_icao) {
|
|
2769
|
-
ResultFormatter.arrivalAirport(decodeResult, data[0]);
|
|
2770
|
-
} else if (decodeResult.raw.arrival_icao != data[0]) {
|
|
2771
|
-
ResultFormatter.unknownArr(decodeResult, data);
|
|
2482
|
+
function processDT(decodeResult, data) {
|
|
2483
|
+
if (!decodeResult.raw.arrival_icao) {
|
|
2484
|
+
ResultFormatter.arrivalAirport(decodeResult, data[0]);
|
|
2485
|
+
} else if (decodeResult.raw.arrival_icao != data[0]) {
|
|
2486
|
+
ResultFormatter.unknownArr(decodeResult, data);
|
|
2487
|
+
}
|
|
2488
|
+
if (data.length > 1) {
|
|
2489
|
+
ResultFormatter.arrivalRunway(decodeResult, data[1]);
|
|
2490
|
+
}
|
|
2491
|
+
if (data.length > 2) {
|
|
2492
|
+
ResultFormatter.currentFuel(decodeResult, Number(data[2]));
|
|
2493
|
+
}
|
|
2494
|
+
if (data.length > 3) {
|
|
2495
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[3]));
|
|
2496
|
+
}
|
|
2497
|
+
if (data.length > 4) {
|
|
2498
|
+
ResultFormatter.remainingFuel(decodeResult, Number(data[4]));
|
|
2499
|
+
}
|
|
2500
|
+
if (data.length > 5) {
|
|
2501
|
+
ResultFormatter.unknownArr(decodeResult, data);
|
|
2502
|
+
}
|
|
2503
|
+
}
|
|
2504
|
+
function processLR(decodeResult, data) {
|
|
2505
|
+
if (data.length === 19) {
|
|
2506
|
+
ResultFormatter.unknown(decodeResult, data[1]);
|
|
2507
|
+
ResultFormatter.flightNumber(decodeResult, data[2]);
|
|
2508
|
+
ResultFormatter.departureAirport(decodeResult, data[3]);
|
|
2509
|
+
ResultFormatter.arrivalAirport(decodeResult, data[4]);
|
|
2510
|
+
ResultFormatter.arrivalRunway(decodeResult, data[5]);
|
|
2511
|
+
ResultFormatter.unknown(decodeResult, data.slice(6, 19).join(","));
|
|
2512
|
+
} else {
|
|
2513
|
+
ResultFormatter.unknown(decodeResult, data.join(","));
|
|
2514
|
+
}
|
|
2515
|
+
}
|
|
2516
|
+
function parseMessageType(decodeResult, messageType) {
|
|
2517
|
+
const parts = messageType.split("#");
|
|
2518
|
+
if (parts.length == 1) {
|
|
2519
|
+
const type = parts[0].substring(0, 3);
|
|
2520
|
+
if (type === "POS" && parts[0].length !== 3) {
|
|
2521
|
+
processPosition2(decodeResult, parts[0].substring(3).split(","));
|
|
2522
|
+
}
|
|
2523
|
+
return processMessageType(decodeResult, type);
|
|
2524
|
+
} else if (parts.length == 2) {
|
|
2525
|
+
if (parts[0].length > 0) {
|
|
2526
|
+
ResultFormatter.unknown(decodeResult, parts[0].substring(0, 3));
|
|
2527
|
+
decodeResult.raw.flight_number = parts[0].substring(3);
|
|
2528
|
+
ResultFormatter.unknown(decodeResult, parts[1].length == 5 ? parts[1].substring(0, 2) : parts[1].substring(0, 3), "#");
|
|
2529
|
+
}
|
|
2530
|
+
const type = parts[1].length == 5 ? parts[1].substring(2, 5) : parts[1].substring(3, 6);
|
|
2531
|
+
if (parts[1].substring(3, 6) === "POS" && parts[1].length > 6) {
|
|
2532
|
+
processPosition2(decodeResult, parts[1].substring(6).split(","));
|
|
2533
|
+
}
|
|
2534
|
+
processMessageType(decodeResult, type);
|
|
2535
|
+
} else {
|
|
2536
|
+
ResultFormatter.unknown(decodeResult, messageType);
|
|
2537
|
+
}
|
|
2538
|
+
}
|
|
2539
|
+
function processMessageType(decodeResult, type) {
|
|
2540
|
+
if (type === "FPN") {
|
|
2541
|
+
decodeResult.formatted.description = "Flight Plan";
|
|
2542
|
+
} else if (type === "FTX") {
|
|
2543
|
+
decodeResult.formatted.description = "Free Text";
|
|
2544
|
+
} else if (type === "INI") {
|
|
2545
|
+
decodeResult.formatted.description = "Flight Plan Initial Report";
|
|
2546
|
+
} else if (type === "POS") {
|
|
2547
|
+
decodeResult.formatted.description = "Position Report";
|
|
2548
|
+
} else if (type === "PRG") {
|
|
2549
|
+
decodeResult.formatted.description = "Progress Report";
|
|
2550
|
+
} else {
|
|
2551
|
+
decodeResult.formatted.description = "Unknown H1 Message";
|
|
2552
|
+
}
|
|
2553
|
+
}
|
|
2554
|
+
function processDC(decodeResult, data) {
|
|
2555
|
+
decodeResult.raw.message_date = data[0];
|
|
2556
|
+
if (data.length === 1) {
|
|
2557
|
+
} else if (data.length === 2) {
|
|
2558
|
+
const date = data[0].substring(2, 4) + data[0].substring(0, 2) + data[0].substring(4, 6);
|
|
2559
|
+
const time = DateTimeUtils.convertDateTimeToEpoch(data[1], data[0]);
|
|
2560
|
+
decodeResult.raw.message_timestamp = time;
|
|
2561
|
+
}
|
|
2562
|
+
}
|
|
2563
|
+
function processPS(decodeResult, data) {
|
|
2564
|
+
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[0]);
|
|
2565
|
+
if (position) {
|
|
2566
|
+
decodeResult.raw.position = position;
|
|
2567
|
+
decodeResult.formatted.items.push({
|
|
2568
|
+
type: "aircraft_position",
|
|
2569
|
+
code: "POS",
|
|
2570
|
+
label: "Aircraft Position",
|
|
2571
|
+
value: CoordinateUtils.coordinateString(position)
|
|
2572
|
+
});
|
|
2573
|
+
}
|
|
2574
|
+
if (data.length === 9) {
|
|
2575
|
+
processRoute(decodeResult, data[3], data[1], data[5], data[4], void 0);
|
|
2576
|
+
ResultFormatter.altitude(decodeResult, Number(data[2]) * 100);
|
|
2577
|
+
ResultFormatter.temperature(decodeResult, data[6]);
|
|
2578
|
+
ResultFormatter.unknown(decodeResult, data[7]);
|
|
2579
|
+
ResultFormatter.unknown(decodeResult, data[8]);
|
|
2580
|
+
}
|
|
2581
|
+
if (data.length === 14) {
|
|
2582
|
+
ResultFormatter.altitude(decodeResult, Number(data[3]) * 100);
|
|
2583
|
+
processRoute(decodeResult, data[4], data[2], data[6], data[5], void 0);
|
|
2584
|
+
ResultFormatter.temperature(decodeResult, data[7]);
|
|
2585
|
+
ResultFormatter.groundspeed(decodeResult, Number(data[10]));
|
|
2586
|
+
ResultFormatter.unknown(decodeResult, data[1]);
|
|
2587
|
+
ResultFormatter.unknown(decodeResult, data[8]);
|
|
2588
|
+
ResultFormatter.unknown(decodeResult, data[9]);
|
|
2589
|
+
ResultFormatter.unknown(decodeResult, data.slice(11).join(","));
|
|
2590
|
+
}
|
|
2591
|
+
}
|
|
2592
|
+
function processPosition2(decodeResult, data) {
|
|
2593
|
+
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[0]);
|
|
2594
|
+
if (position) {
|
|
2595
|
+
decodeResult.raw.position = position;
|
|
2596
|
+
decodeResult.formatted.items.push({
|
|
2597
|
+
type: "aircraft_position",
|
|
2598
|
+
code: "POS",
|
|
2599
|
+
label: "Aircraft Position",
|
|
2600
|
+
value: CoordinateUtils.coordinateString(position)
|
|
2601
|
+
});
|
|
2602
|
+
}
|
|
2603
|
+
if (data.length >= 10) {
|
|
2604
|
+
ResultFormatter.altitude(decodeResult, Number(data[3]) * 100);
|
|
2605
|
+
processRoute(decodeResult, data[1], data[2], data[4], data[5], data[6]);
|
|
2606
|
+
ResultFormatter.temperature(decodeResult, data[7]);
|
|
2607
|
+
ResultFormatter.unknown(decodeResult, data[8]);
|
|
2608
|
+
ResultFormatter.unknown(decodeResult, data[9]);
|
|
2609
|
+
}
|
|
2610
|
+
if (data.length >= 14) {
|
|
2611
|
+
ResultFormatter.groundspeed(decodeResult, Number(data[10]));
|
|
2612
|
+
ResultFormatter.unknown(decodeResult, data[11]);
|
|
2613
|
+
ResultFormatter.unknown(decodeResult, data[12]);
|
|
2614
|
+
ResultFormatter.unknown(decodeResult, data[13]);
|
|
2615
|
+
}
|
|
2616
|
+
}
|
|
2617
|
+
function processRoute(decodeResult, last, time, next, eta, then, date) {
|
|
2618
|
+
const lastTime = date ? DateTimeUtils.convertDateTimeToEpoch(time, date) : DateTimeUtils.convertHHMMSSToTod(time);
|
|
2619
|
+
const nextTime = date ? DateTimeUtils.convertDateTimeToEpoch(eta, date) : DateTimeUtils.convertHHMMSSToTod(eta);
|
|
2620
|
+
const timeFormat = date ? "epoch" : "tod";
|
|
2621
|
+
const lastWaypoint = RouteUtils.getWaypoint(last);
|
|
2622
|
+
lastWaypoint.time = lastTime;
|
|
2623
|
+
lastWaypoint.timeFormat = timeFormat;
|
|
2624
|
+
const nextWaypoint = RouteUtils.getWaypoint(next);
|
|
2625
|
+
nextWaypoint.time = nextTime;
|
|
2626
|
+
nextWaypoint.timeFormat = timeFormat;
|
|
2627
|
+
const thenWaypoint = RouteUtils.getWaypoint(then || "?");
|
|
2628
|
+
const waypoints = [lastWaypoint, nextWaypoint, thenWaypoint];
|
|
2629
|
+
decodeResult.raw.route = { waypoints };
|
|
2630
|
+
decodeResult.formatted.items.push({
|
|
2631
|
+
type: "aircraft_route",
|
|
2632
|
+
code: "ROUTE",
|
|
2633
|
+
label: "Aircraft Route",
|
|
2634
|
+
value: RouteUtils.routeToString(decodeResult.raw.route)
|
|
2635
|
+
});
|
|
2636
|
+
}
|
|
2637
|
+
|
|
2638
|
+
// lib/plugins/Label_4J_POS.ts
|
|
2639
|
+
var Label_4J_POS = class extends DecoderPlugin {
|
|
2640
|
+
name = "label-4j-pos";
|
|
2641
|
+
qualifiers() {
|
|
2642
|
+
return {
|
|
2643
|
+
labels: ["4J"],
|
|
2644
|
+
preambles: ["POS/"]
|
|
2645
|
+
};
|
|
2772
2646
|
}
|
|
2773
|
-
|
|
2774
|
-
|
|
2647
|
+
// copied from Label_H1.ts since i don't really want to have to have
|
|
2648
|
+
// something named like that decode more than 1 type
|
|
2649
|
+
// if we figure out a good name, i'll combine them
|
|
2650
|
+
decode(message, options = {}) {
|
|
2651
|
+
let decodeResult = this.defaultResult();
|
|
2652
|
+
decodeResult.decoder.name = this.name;
|
|
2653
|
+
decodeResult.message = message;
|
|
2654
|
+
const msg = message.text.replace(/\n|\r/g, "");
|
|
2655
|
+
const decoded = H1Helper.decodeH1Message(decodeResult, msg);
|
|
2656
|
+
decodeResult.decoded = decoded;
|
|
2657
|
+
decodeResult.decoder.decodeLevel = !decodeResult.remaining.text ? "full" : "partial";
|
|
2658
|
+
if (decodeResult.formatted.items.length === 0) {
|
|
2659
|
+
if (options.debug) {
|
|
2660
|
+
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
2661
|
+
}
|
|
2662
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
2663
|
+
decodeResult.decoded = false;
|
|
2664
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2665
|
+
}
|
|
2666
|
+
return decodeResult;
|
|
2775
2667
|
}
|
|
2776
|
-
|
|
2777
|
-
|
|
2668
|
+
};
|
|
2669
|
+
|
|
2670
|
+
// lib/plugins/Label_4N.ts
|
|
2671
|
+
var Label_4N = class extends DecoderPlugin {
|
|
2672
|
+
name = "label-4n";
|
|
2673
|
+
qualifiers() {
|
|
2674
|
+
return {
|
|
2675
|
+
labels: ["4N"]
|
|
2676
|
+
};
|
|
2778
2677
|
}
|
|
2779
|
-
|
|
2780
|
-
|
|
2678
|
+
decode(message, options = {}) {
|
|
2679
|
+
const decodeResult = this.defaultResult();
|
|
2680
|
+
decodeResult.decoder.name = this.name;
|
|
2681
|
+
decodeResult.message = message;
|
|
2682
|
+
decodeResult.formatted.description = "Airline Defined";
|
|
2683
|
+
let text = message.text;
|
|
2684
|
+
if (text.match(/^M\d{2}A\w{6}/)) {
|
|
2685
|
+
ResultFormatter.flightNumber(decodeResult, message.text.substring(4, 10).replace(/^([A-Z]+)0*/g, "$1"));
|
|
2686
|
+
text = text.substring(10);
|
|
2687
|
+
}
|
|
2688
|
+
decodeResult.decoded = true;
|
|
2689
|
+
const fields = text.split(",");
|
|
2690
|
+
if (text.length === 51) {
|
|
2691
|
+
decodeResult.raw.day = text.substring(0, 2);
|
|
2692
|
+
ResultFormatter.departureAirport(decodeResult, text.substring(8, 11));
|
|
2693
|
+
ResultFormatter.arrivalAirport(decodeResult, text.substring(13, 16));
|
|
2694
|
+
ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(text.substring(30, 45).replace(/^(.)0/, "$1")));
|
|
2695
|
+
ResultFormatter.altitude(decodeResult, Number(text.substring(48, 51)) * 100);
|
|
2696
|
+
ResultFormatter.unknownArr(decodeResult, [text.substring(2, 4), text.substring(19, 29)], " ");
|
|
2697
|
+
} else if (fields.length === 33) {
|
|
2698
|
+
decodeResult.raw.date = fields[3];
|
|
2699
|
+
if (fields[1] === "B") {
|
|
2700
|
+
ResultFormatter.position(decodeResult, { latitude: Number(fields[4]), longitude: Number(fields[5]) });
|
|
2701
|
+
ResultFormatter.altitude(decodeResult, Number(fields[6]));
|
|
2702
|
+
}
|
|
2703
|
+
ResultFormatter.departureAirport(decodeResult, fields[8]);
|
|
2704
|
+
ResultFormatter.arrivalAirport(decodeResult, fields[9]);
|
|
2705
|
+
ResultFormatter.alternateAirport(decodeResult, fields[10]);
|
|
2706
|
+
ResultFormatter.arrivalRunway(decodeResult, fields[11].split("/")[0]);
|
|
2707
|
+
if (fields[12].length > 1) {
|
|
2708
|
+
ResultFormatter.alternateRunway(decodeResult, fields[12].split("/")[0]);
|
|
2709
|
+
}
|
|
2710
|
+
ResultFormatter.checksum(decodeResult, fields[32]);
|
|
2711
|
+
ResultFormatter.unknownArr(decodeResult, [...fields.slice(1, 3), fields[7], ...fields.slice(13, 32)].filter((f) => f != ""));
|
|
2712
|
+
} else {
|
|
2713
|
+
decodeResult.decoded = false;
|
|
2714
|
+
ResultFormatter.unknown(decodeResult, text);
|
|
2715
|
+
}
|
|
2716
|
+
if (decodeResult.decoded) {
|
|
2717
|
+
if (!decodeResult.remaining.text)
|
|
2718
|
+
decodeResult.decoder.decodeLevel = "full";
|
|
2719
|
+
else
|
|
2720
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
2721
|
+
} else {
|
|
2722
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2723
|
+
}
|
|
2724
|
+
return decodeResult;
|
|
2781
2725
|
}
|
|
2782
|
-
|
|
2783
|
-
|
|
2726
|
+
};
|
|
2727
|
+
|
|
2728
|
+
// lib/plugins/Label_80.ts
|
|
2729
|
+
var Label_80 = class extends DecoderPlugin {
|
|
2730
|
+
name = "label-80";
|
|
2731
|
+
descriptions = {
|
|
2732
|
+
ALT: "Altitude",
|
|
2733
|
+
DWND: "Wind Direction",
|
|
2734
|
+
ETA: "Estimated Time of Arrival",
|
|
2735
|
+
FOB: "Fuel on Board",
|
|
2736
|
+
FL: "Flight Level",
|
|
2737
|
+
HDG: "Heading",
|
|
2738
|
+
MCH: "Aircraft Speed",
|
|
2739
|
+
NWYP: "Next Waypoint",
|
|
2740
|
+
POS: "Aircraft Position",
|
|
2741
|
+
SAT: "Static Air Temperature",
|
|
2742
|
+
SWND: "Wind Speed",
|
|
2743
|
+
TAS: "True Airspeed",
|
|
2744
|
+
WYP: "Waypoint"
|
|
2745
|
+
};
|
|
2746
|
+
qualifiers() {
|
|
2747
|
+
return {
|
|
2748
|
+
labels: ["80"],
|
|
2749
|
+
preambles: ["3N01 POSRPT"]
|
|
2750
|
+
};
|
|
2784
2751
|
}
|
|
2785
|
-
|
|
2786
|
-
|
|
2752
|
+
decode(message, options = {}) {
|
|
2753
|
+
const decodeResult = this.defaultResult();
|
|
2754
|
+
decodeResult.decoder.name = this.name;
|
|
2755
|
+
decodeResult.formatted.description = "Airline Defined Position Report";
|
|
2756
|
+
const parts = message.text.split("\n");
|
|
2757
|
+
let posRptRegex = /^3N01 POSRPT \d\d\d\d\/\d\d (?<orig>\w+)\/(?<dest>\w+) \.(?<tail>[\w-]+)(\/(?<agate>.+) (?<sta>\w+:\w+))*/;
|
|
2758
|
+
let results = parts[0].match(posRptRegex);
|
|
2759
|
+
if (!results?.groups) {
|
|
2760
|
+
decodeResult.decoded = false;
|
|
2761
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2762
|
+
return decodeResult;
|
|
2763
|
+
}
|
|
2764
|
+
if (results && results.length > 0) {
|
|
2765
|
+
ResultFormatter.departureAirport(decodeResult, results.groups.orig);
|
|
2766
|
+
ResultFormatter.arrivalAirport(decodeResult, results.groups.dest);
|
|
2767
|
+
ResultFormatter.tail(decodeResult, results.groups.tail);
|
|
2768
|
+
if (results.groups.agate) {
|
|
2769
|
+
decodeResult.raw.arrival_gate = results.groups.agate;
|
|
2770
|
+
decodeResult.formatted.items.push({
|
|
2771
|
+
type: "arrival_gate",
|
|
2772
|
+
code: "ARG",
|
|
2773
|
+
label: "Arrival Gate",
|
|
2774
|
+
value: `${results.groups.agate}`
|
|
2775
|
+
});
|
|
2776
|
+
decodeResult.raw.scheduled_time_of_arrival = results.groups.sta;
|
|
2777
|
+
decodeResult.formatted.items.push({
|
|
2778
|
+
type: "scheduled_time_of_arrival",
|
|
2779
|
+
code: "STA",
|
|
2780
|
+
label: "Scheduled Time of Arrival",
|
|
2781
|
+
value: `${results.groups.sta}`
|
|
2782
|
+
});
|
|
2783
|
+
}
|
|
2784
|
+
posRptRegex = /\/(?<field>\w+)\s(?<value>[\w\+\-:\.]+)\s*/gi;
|
|
2785
|
+
const remainingParts = parts.slice(1);
|
|
2786
|
+
for (const part of remainingParts) {
|
|
2787
|
+
const matches = part.matchAll(posRptRegex);
|
|
2788
|
+
for (const match of matches) {
|
|
2789
|
+
switch (match.groups?.field) {
|
|
2790
|
+
case "ALT": {
|
|
2791
|
+
ResultFormatter.altitude(decodeResult, Number(match.groups.value));
|
|
2792
|
+
break;
|
|
2793
|
+
}
|
|
2794
|
+
case "DWND": {
|
|
2795
|
+
decodeResult.raw.wind_direction = Number(match.groups.value);
|
|
2796
|
+
decodeResult.formatted.items.push({
|
|
2797
|
+
type: "wind_direction",
|
|
2798
|
+
code: "DWND",
|
|
2799
|
+
label: this.descriptions[match.groups.field],
|
|
2800
|
+
value: decodeResult.raw.wind_direction
|
|
2801
|
+
});
|
|
2802
|
+
break;
|
|
2803
|
+
}
|
|
2804
|
+
case "FL": {
|
|
2805
|
+
const flight_level = Number(match.groups.value);
|
|
2806
|
+
ResultFormatter.altitude(decodeResult, flight_level * 100);
|
|
2807
|
+
break;
|
|
2808
|
+
}
|
|
2809
|
+
case "FOB": {
|
|
2810
|
+
const fob = Number(match.groups.value);
|
|
2811
|
+
if (!isNaN(fob)) {
|
|
2812
|
+
ResultFormatter.currentFuel(decodeResult, fob);
|
|
2813
|
+
}
|
|
2814
|
+
break;
|
|
2815
|
+
}
|
|
2816
|
+
case "HDG": {
|
|
2817
|
+
ResultFormatter.heading(decodeResult, Number(match.groups.value));
|
|
2818
|
+
break;
|
|
2819
|
+
}
|
|
2820
|
+
case "MCH": {
|
|
2821
|
+
decodeResult.raw.mach = Number(match.groups.value) / 1e3;
|
|
2822
|
+
decodeResult.formatted.items.push({
|
|
2823
|
+
type: "mach",
|
|
2824
|
+
code: "MCH",
|
|
2825
|
+
label: this.descriptions[match.groups.field],
|
|
2826
|
+
value: `${decodeResult.raw.mach} Mach`
|
|
2827
|
+
});
|
|
2828
|
+
break;
|
|
2829
|
+
}
|
|
2830
|
+
case "NWYP": {
|
|
2831
|
+
decodeResult.raw.next_waypoint = match.groups.value;
|
|
2832
|
+
decodeResult.formatted.items.push({
|
|
2833
|
+
type: "next_waypoint",
|
|
2834
|
+
code: "NWYP",
|
|
2835
|
+
label: this.descriptions[match.groups.field],
|
|
2836
|
+
value: decodeResult.raw.next_waypoint
|
|
2837
|
+
});
|
|
2838
|
+
break;
|
|
2839
|
+
}
|
|
2840
|
+
case "POS": {
|
|
2841
|
+
const posRegex = /^(?<latd>[NS])(?<lat>.+)(?<lngd>[EW])(?<lng>.+)/;
|
|
2842
|
+
const posResult = match.groups.value.match(posRegex);
|
|
2843
|
+
const lat = Number(posResult?.groups?.lat) * (posResult?.groups?.lngd === "S" ? -1 : 1);
|
|
2844
|
+
const lon = Number(posResult?.groups?.lng) * (posResult?.groups?.lngd === "W" ? -1 : 1);
|
|
2845
|
+
const position = {
|
|
2846
|
+
latitude: Number.isInteger(lat) ? lat / 1e3 : lat / 100,
|
|
2847
|
+
longitude: Number.isInteger(lon) ? lon / 1e3 : lon / 100
|
|
2848
|
+
};
|
|
2849
|
+
ResultFormatter.position(decodeResult, position);
|
|
2850
|
+
break;
|
|
2851
|
+
}
|
|
2852
|
+
case "SWND": {
|
|
2853
|
+
decodeResult.raw.wind_speed = Number(match.groups.value);
|
|
2854
|
+
decodeResult.formatted.items.push({
|
|
2855
|
+
type: "wind_speed",
|
|
2856
|
+
code: "SWND",
|
|
2857
|
+
label: this.descriptions[match.groups.field],
|
|
2858
|
+
value: decodeResult.raw.wind_speed
|
|
2859
|
+
});
|
|
2860
|
+
break;
|
|
2861
|
+
}
|
|
2862
|
+
default: {
|
|
2863
|
+
if (match.groups?.field != void 0) {
|
|
2864
|
+
const description = this.descriptions[match.groups.field] ? this.descriptions[match.groups.field] : "Unknown";
|
|
2865
|
+
decodeResult.formatted.items.push({
|
|
2866
|
+
type: match.groups.field,
|
|
2867
|
+
code: match.groups.field,
|
|
2868
|
+
label: description || `Unknown (${match.groups.field})`,
|
|
2869
|
+
value: `${match.groups.value}`
|
|
2870
|
+
});
|
|
2871
|
+
}
|
|
2872
|
+
}
|
|
2873
|
+
}
|
|
2874
|
+
}
|
|
2875
|
+
}
|
|
2876
|
+
decodeResult.decoded = true;
|
|
2877
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
2878
|
+
}
|
|
2879
|
+
return decodeResult;
|
|
2787
2880
|
}
|
|
2788
|
-
}
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
} else {
|
|
2798
|
-
ResultFormatter.unknown(decodeResult, data.join(","));
|
|
2881
|
+
};
|
|
2882
|
+
|
|
2883
|
+
// lib/plugins/Label_83.ts
|
|
2884
|
+
var Label_83 = class extends DecoderPlugin {
|
|
2885
|
+
name = "label-83";
|
|
2886
|
+
qualifiers() {
|
|
2887
|
+
return {
|
|
2888
|
+
labels: ["83"]
|
|
2889
|
+
};
|
|
2799
2890
|
}
|
|
2800
|
-
}
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2891
|
+
decode(message, options = {}) {
|
|
2892
|
+
const decodeResult = this.defaultResult();
|
|
2893
|
+
decodeResult.decoder.name = this.name;
|
|
2894
|
+
decodeResult.message = message;
|
|
2895
|
+
decodeResult.formatted.description = "Airline Defined";
|
|
2896
|
+
let text = message.text;
|
|
2897
|
+
if (text.match(/^M\d{2}A\w{6}/)) {
|
|
2898
|
+
ResultFormatter.flightNumber(decodeResult, message.text.substring(4, 10).replace(/^([A-Z]+)0*/g, "$1"));
|
|
2899
|
+
text = text.substring(10);
|
|
2807
2900
|
}
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2901
|
+
decodeResult.decoded = true;
|
|
2902
|
+
if (text.substring(0, 10) === "4DH3 ETAT2") {
|
|
2903
|
+
const fields = text.split(/\s+/);
|
|
2904
|
+
if (fields[2].length > 5) {
|
|
2905
|
+
decodeResult.raw.day = fields[2].substring(5);
|
|
2906
|
+
}
|
|
2907
|
+
ResultFormatter.unknown(decodeResult, fields[2].substring(0, 4));
|
|
2908
|
+
const subfields = fields[3].split("/");
|
|
2909
|
+
ResultFormatter.departureAirport(decodeResult, subfields[0]);
|
|
2910
|
+
ResultFormatter.arrivalAirport(decodeResult, subfields[1]);
|
|
2911
|
+
ResultFormatter.tail(decodeResult, fields[4].replace(/\./g, ""));
|
|
2912
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[6] + "00"));
|
|
2913
|
+
} else if (text.substring(0, 5) === "001PR") {
|
|
2914
|
+
decodeResult.raw.day = text.substring(5, 7);
|
|
2915
|
+
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(text.substring(13, 28).replace(/\./g, ""));
|
|
2916
|
+
if (position) {
|
|
2917
|
+
ResultFormatter.position(decodeResult, position);
|
|
2918
|
+
}
|
|
2919
|
+
ResultFormatter.altitude(decodeResult, Number(text.substring(28, 33)));
|
|
2920
|
+
ResultFormatter.unknown(decodeResult, text.substring(33));
|
|
2921
|
+
} else {
|
|
2922
|
+
const fields = text.replace(/\s/g, "").split(",");
|
|
2923
|
+
if (fields.length === 9) {
|
|
2924
|
+
ResultFormatter.departureAirport(decodeResult, fields[0]);
|
|
2925
|
+
ResultFormatter.arrivalAirport(decodeResult, fields[1]);
|
|
2926
|
+
decodeResult.raw.day = fields[2].substring(0, 2);
|
|
2927
|
+
decodeResult.raw.time = fields[2].substring(2);
|
|
2928
|
+
ResultFormatter.position(
|
|
2929
|
+
decodeResult,
|
|
2930
|
+
{
|
|
2931
|
+
latitude: Number(fields[3].replace(/\s/g, "")),
|
|
2932
|
+
longitude: Number(fields[4].replace(/\s/g, ""))
|
|
2933
|
+
}
|
|
2934
|
+
);
|
|
2935
|
+
ResultFormatter.altitude(decodeResult, Number(fields[5]));
|
|
2936
|
+
ResultFormatter.groundspeed(decodeResult, Number(fields[6]));
|
|
2937
|
+
ResultFormatter.heading(decodeResult, Number(fields[7]));
|
|
2938
|
+
ResultFormatter.unknown(decodeResult, fields[8]);
|
|
2939
|
+
} else {
|
|
2940
|
+
decodeResult.decoded = false;
|
|
2941
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
2942
|
+
}
|
|
2814
2943
|
}
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2944
|
+
if (decodeResult.decoded) {
|
|
2945
|
+
if (!decodeResult.remaining.text)
|
|
2946
|
+
decodeResult.decoder.decodeLevel = "full";
|
|
2947
|
+
else
|
|
2948
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
2949
|
+
} else {
|
|
2950
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2818
2951
|
}
|
|
2819
|
-
|
|
2820
|
-
} else {
|
|
2821
|
-
ResultFormatter.unknown(decodeResult, messageType);
|
|
2952
|
+
return decodeResult;
|
|
2822
2953
|
}
|
|
2823
|
-
}
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
decodeResult.formatted.description = "Position Report";
|
|
2833
|
-
} else if (type === "PRG") {
|
|
2834
|
-
decodeResult.formatted.description = "Progress Report";
|
|
2835
|
-
} else {
|
|
2836
|
-
decodeResult.formatted.description = "Unknown H1 Message";
|
|
2954
|
+
};
|
|
2955
|
+
|
|
2956
|
+
// lib/plugins/Label_8E.ts
|
|
2957
|
+
var Label_8E = class extends DecoderPlugin {
|
|
2958
|
+
name = "label-8e";
|
|
2959
|
+
qualifiers() {
|
|
2960
|
+
return {
|
|
2961
|
+
labels: ["8E"]
|
|
2962
|
+
};
|
|
2837
2963
|
}
|
|
2838
|
-
}
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
const
|
|
2844
|
-
const
|
|
2845
|
-
|
|
2964
|
+
decode(message, options = {}) {
|
|
2965
|
+
const decodeResult = this.defaultResult();
|
|
2966
|
+
decodeResult.decoder.name = this.name;
|
|
2967
|
+
decodeResult.formatted.description = "ETA Report";
|
|
2968
|
+
decodeResult.message = message;
|
|
2969
|
+
const regex = /^(?<arrival_icao>\w{4}),(?<arrival_eta>\d{4})$/;
|
|
2970
|
+
const results = message.text.match(regex);
|
|
2971
|
+
if (results?.groups) {
|
|
2972
|
+
if (options.debug) {
|
|
2973
|
+
console.log(`Label 8E ETA: groups`);
|
|
2974
|
+
console.log(results.groups);
|
|
2975
|
+
}
|
|
2976
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(results.groups.arrival_eta));
|
|
2977
|
+
ResultFormatter.arrivalAirport(decodeResult, results.groups.arrival_icao);
|
|
2978
|
+
}
|
|
2979
|
+
decodeResult.decoded = true;
|
|
2980
|
+
decodeResult.decoder.decodeLevel = "full";
|
|
2981
|
+
return decodeResult;
|
|
2846
2982
|
}
|
|
2847
|
-
}
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
});
|
|
2983
|
+
};
|
|
2984
|
+
|
|
2985
|
+
// lib/plugins/Label_B6.ts
|
|
2986
|
+
var Label_B6_Forwardslash = class extends DecoderPlugin {
|
|
2987
|
+
name = "label-b6-forwardslash";
|
|
2988
|
+
qualifiers() {
|
|
2989
|
+
return {
|
|
2990
|
+
labels: ["B6"],
|
|
2991
|
+
preambles: ["/"]
|
|
2992
|
+
};
|
|
2858
2993
|
}
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2994
|
+
decode(message, options = {}) {
|
|
2995
|
+
const decodeResult = this.defaultResult();
|
|
2996
|
+
decodeResult.decoder.name = this.name;
|
|
2997
|
+
decodeResult.formatted.description = "CPDLC Message";
|
|
2998
|
+
decodeResult.message = message;
|
|
2999
|
+
if (options.debug) {
|
|
3000
|
+
console.log("CPDLC: " + message);
|
|
3001
|
+
}
|
|
3002
|
+
return decodeResult;
|
|
2865
3003
|
}
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
3004
|
+
};
|
|
3005
|
+
|
|
3006
|
+
// lib/plugins/Label_ColonComma.ts
|
|
3007
|
+
var Label_ColonComma = class extends DecoderPlugin {
|
|
3008
|
+
name = "label-colon-comma";
|
|
3009
|
+
qualifiers() {
|
|
3010
|
+
return {
|
|
3011
|
+
labels: [":;"]
|
|
3012
|
+
};
|
|
2875
3013
|
}
|
|
2876
|
-
}
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
decodeResult.
|
|
3014
|
+
decode(message, options = {}) {
|
|
3015
|
+
const decodeResult = this.defaultResult();
|
|
3016
|
+
decodeResult.decoder.name = this.name;
|
|
3017
|
+
decodeResult.raw.frequency = Number(message.text) / 1e3;
|
|
3018
|
+
decodeResult.formatted.description = "Aircraft Transceiver Frequency Change";
|
|
2881
3019
|
decodeResult.formatted.items.push({
|
|
2882
|
-
type: "
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
3020
|
+
type: "frequency",
|
|
3021
|
+
label: "Frequency",
|
|
3022
|
+
value: `${decodeResult.raw.frequency} MHz`,
|
|
3023
|
+
code: "FREQ"
|
|
2886
3024
|
});
|
|
3025
|
+
decodeResult.decoded = true;
|
|
3026
|
+
decodeResult.decoder.decodeLevel = "full";
|
|
3027
|
+
return decodeResult;
|
|
2887
3028
|
}
|
|
2888
|
-
|
|
2889
|
-
ResultFormatter.altitude(decodeResult, Number(data[3]) * 100);
|
|
2890
|
-
processRoute(decodeResult, data[1], data[2], data[4], data[5], data[6]);
|
|
2891
|
-
ResultFormatter.temperature(decodeResult, data[7]);
|
|
2892
|
-
ResultFormatter.unknown(decodeResult, data[8]);
|
|
2893
|
-
ResultFormatter.unknown(decodeResult, data[9]);
|
|
2894
|
-
}
|
|
2895
|
-
if (data.length >= 14) {
|
|
2896
|
-
ResultFormatter.groundspeed(decodeResult, Number(data[10]));
|
|
2897
|
-
ResultFormatter.unknown(decodeResult, data[11]);
|
|
2898
|
-
ResultFormatter.unknown(decodeResult, data[12]);
|
|
2899
|
-
ResultFormatter.unknown(decodeResult, data[13]);
|
|
2900
|
-
}
|
|
2901
|
-
}
|
|
2902
|
-
function processRoute(decodeResult, last, time, next, eta, then, date) {
|
|
2903
|
-
const lastTime = date ? DateTimeUtils.convertDateTimeToEpoch(time, date) : DateTimeUtils.convertHHMMSSToTod(time);
|
|
2904
|
-
const nextTime = date ? DateTimeUtils.convertDateTimeToEpoch(eta, date) : DateTimeUtils.convertHHMMSSToTod(eta);
|
|
2905
|
-
const timeFormat = date ? "epoch" : "tod";
|
|
2906
|
-
const lastWaypoint = RouteUtils.getWaypoint(last);
|
|
2907
|
-
lastWaypoint.time = lastTime;
|
|
2908
|
-
lastWaypoint.timeFormat = timeFormat;
|
|
2909
|
-
const nextWaypoint = RouteUtils.getWaypoint(next);
|
|
2910
|
-
nextWaypoint.time = nextTime;
|
|
2911
|
-
nextWaypoint.timeFormat = timeFormat;
|
|
2912
|
-
const thenWaypoint = RouteUtils.getWaypoint(then || "?");
|
|
2913
|
-
const waypoints = [lastWaypoint, nextWaypoint, thenWaypoint];
|
|
2914
|
-
decodeResult.raw.route = { waypoints };
|
|
2915
|
-
decodeResult.formatted.items.push({
|
|
2916
|
-
type: "aircraft_route",
|
|
2917
|
-
code: "ROUTE",
|
|
2918
|
-
label: "Aircraft Route",
|
|
2919
|
-
value: RouteUtils.routeToString(decodeResult.raw.route)
|
|
2920
|
-
});
|
|
2921
|
-
}
|
|
3029
|
+
};
|
|
2922
3030
|
|
|
2923
3031
|
// lib/plugins/Label_H1.ts
|
|
2924
3032
|
var Label_H1 = class extends DecoderPlugin {
|
|
@@ -3077,9 +3185,9 @@ var Label_H1_StarPOS = class extends DecoderPlugin {
|
|
|
3077
3185
|
decodeResult.decoder.decodeLevel = "none";
|
|
3078
3186
|
return decodeResult;
|
|
3079
3187
|
}
|
|
3080
|
-
|
|
3081
|
-
decodeResult
|
|
3082
|
-
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(msg.substring(8, 12)
|
|
3188
|
+
ResultFormatter.month(decodeResult, Number(msg.substring(4, 6)));
|
|
3189
|
+
ResultFormatter.day(decodeResult, Number(msg.substring(6, 8)));
|
|
3190
|
+
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(msg.substring(8, 12)));
|
|
3083
3191
|
ResultFormatter.position(decodeResult, {
|
|
3084
3192
|
// Deg Min, no sec
|
|
3085
3193
|
latitude: CoordinateUtils.getDirection(msg.substring(12, 13)) * (Number(msg.substring(13, 15)) + Number(msg.substring(15, 17)) / 60),
|
|
@@ -3306,7 +3414,7 @@ var Label_QR = class extends DecoderPlugin {
|
|
|
3306
3414
|
decodeResult.formatted.description = "ON Report";
|
|
3307
3415
|
ResultFormatter.departureAirport(decodeResult, message.text.substring(0, 4));
|
|
3308
3416
|
ResultFormatter.arrivalAirport(decodeResult, message.text.substring(4, 8));
|
|
3309
|
-
ResultFormatter.on(decodeResult, DateTimeUtils.convertHHMMSSToTod(message.text.substring(8, 12)
|
|
3417
|
+
ResultFormatter.on(decodeResult, DateTimeUtils.convertHHMMSSToTod(message.text.substring(8, 12)));
|
|
3310
3418
|
ResultFormatter.unknown(decodeResult, message.text.substring(12));
|
|
3311
3419
|
decodeResult.decoded = true;
|
|
3312
3420
|
if (!decodeResult.remaining.text)
|
|
@@ -3331,7 +3439,7 @@ var Label_QP = class extends DecoderPlugin {
|
|
|
3331
3439
|
decodeResult.formatted.description = "OUT Report";
|
|
3332
3440
|
ResultFormatter.departureAirport(decodeResult, message.text.substring(0, 4));
|
|
3333
3441
|
ResultFormatter.arrivalAirport(decodeResult, message.text.substring(4, 8));
|
|
3334
|
-
ResultFormatter.out(decodeResult, DateTimeUtils.convertHHMMSSToTod(message.text.substring(8, 12)
|
|
3442
|
+
ResultFormatter.out(decodeResult, DateTimeUtils.convertHHMMSSToTod(message.text.substring(8, 12)));
|
|
3335
3443
|
ResultFormatter.unknown(decodeResult, message.text.substring(12));
|
|
3336
3444
|
decodeResult.decoded = true;
|
|
3337
3445
|
if (!decodeResult.remaining.text)
|
|
@@ -3356,7 +3464,7 @@ var Label_QS = class extends DecoderPlugin {
|
|
|
3356
3464
|
decodeResult.formatted.description = "IN Report";
|
|
3357
3465
|
ResultFormatter.departureAirport(decodeResult, message.text.substring(0, 4));
|
|
3358
3466
|
ResultFormatter.arrivalAirport(decodeResult, message.text.substring(4, 8));
|
|
3359
|
-
ResultFormatter.in(decodeResult, DateTimeUtils.convertHHMMSSToTod(message.text.substring(8, 12)
|
|
3467
|
+
ResultFormatter.in(decodeResult, DateTimeUtils.convertHHMMSSToTod(message.text.substring(8, 12)));
|
|
3360
3468
|
ResultFormatter.unknown(decodeResult, message.text.substring(12));
|
|
3361
3469
|
decodeResult.decoded = true;
|
|
3362
3470
|
if (!decodeResult.remaining.text)
|
|
@@ -3383,7 +3491,7 @@ var Label_QQ = class extends DecoderPlugin {
|
|
|
3383
3491
|
ResultFormatter.departureAirport(decodeResult, message.text.substring(0, 4));
|
|
3384
3492
|
ResultFormatter.arrivalAirport(decodeResult, message.text.substring(4, 8));
|
|
3385
3493
|
if (message.text.substring(12, 19) === "\r\n001FE") {
|
|
3386
|
-
decodeResult.raw.
|
|
3494
|
+
decodeResult.raw.day = message.text.substring(19, 21);
|
|
3387
3495
|
ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(message.text.substring(21, 27)));
|
|
3388
3496
|
let latdir = message.text.substring(27, 28);
|
|
3389
3497
|
let latdeg = Number(message.text.substring(28, 30));
|
|
@@ -4257,6 +4365,7 @@ var MessageDecoder = class {
|
|
|
4257
4365
|
this.registerPlugin(new Label_4A_DIS(this));
|
|
4258
4366
|
this.registerPlugin(new Label_4A_DOOR(this));
|
|
4259
4367
|
this.registerPlugin(new Label_4A_Slash_01(this));
|
|
4368
|
+
this.registerPlugin(new Label_4J_POS(this));
|
|
4260
4369
|
this.registerPlugin(new Label_4N(this));
|
|
4261
4370
|
this.registerPlugin(new Label_B6_Forwardslash(this));
|
|
4262
4371
|
this.registerPlugin(new Label_H1_FLR(this));
|