@airframes/acars-decoder 1.6.10 → 1.6.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +349 -75
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +349 -75
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -117,6 +117,17 @@ var CoordinateUtils = class {
|
|
|
117
117
|
const lonDir = coords.longitude > 0 ? "E" : "W";
|
|
118
118
|
return `${Math.abs(coords.latitude).toFixed(3)} ${latDir}, ${Math.abs(coords.longitude).toFixed(3)} ${lonDir}`;
|
|
119
119
|
}
|
|
120
|
+
static getDirection(coord) {
|
|
121
|
+
if (coord.startsWith("N") || coord.startsWith("E")) {
|
|
122
|
+
return 1;
|
|
123
|
+
} else if (coord.startsWith("S") || coord.startsWith("W")) {
|
|
124
|
+
return -1;
|
|
125
|
+
}
|
|
126
|
+
return NaN;
|
|
127
|
+
}
|
|
128
|
+
static dmsToDecimalDegrees(degrees, minutes, seconds) {
|
|
129
|
+
return degrees + minutes / 60 + seconds / 3600;
|
|
130
|
+
}
|
|
120
131
|
};
|
|
121
132
|
|
|
122
133
|
// lib/utils/result_formatter.ts
|
|
@@ -169,6 +180,16 @@ var ResultFormatter = class {
|
|
|
169
180
|
value: decodeResult.raw.arrival_icao
|
|
170
181
|
});
|
|
171
182
|
}
|
|
183
|
+
static alternateAirport(decodeResult, value) {
|
|
184
|
+
decodeResult.raw.alternate_icao = value;
|
|
185
|
+
decodeResult.formatted.items.push({
|
|
186
|
+
type: "destination",
|
|
187
|
+
code: "ALT_DST",
|
|
188
|
+
label: "Alternate Destination",
|
|
189
|
+
value: decodeResult.raw.alternate_icao
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
// FIXME - make seconds since midnight for time of day
|
|
172
193
|
static eta(decodeResult, value) {
|
|
173
194
|
decodeResult.raw.eta_time = value;
|
|
174
195
|
decodeResult.formatted.items.push({
|
|
@@ -187,6 +208,15 @@ var ResultFormatter = class {
|
|
|
187
208
|
value: decodeResult.raw.arrival_runway
|
|
188
209
|
});
|
|
189
210
|
}
|
|
211
|
+
static alternateRunway(decodeResult, value) {
|
|
212
|
+
decodeResult.raw.alternate_runway = value;
|
|
213
|
+
decodeResult.formatted.items.push({
|
|
214
|
+
type: "runway",
|
|
215
|
+
code: "ALT_ARWY",
|
|
216
|
+
label: "Alternate Runway",
|
|
217
|
+
value: decodeResult.raw.alternate_runway
|
|
218
|
+
});
|
|
219
|
+
}
|
|
190
220
|
static currentFuel(decodeResult, value) {
|
|
191
221
|
decodeResult.raw.fuel_on_board = value;
|
|
192
222
|
decodeResult.formatted.items.push({
|
|
@@ -220,7 +250,7 @@ var ResultFormatter = class {
|
|
|
220
250
|
type: "aircraft_groundspeed",
|
|
221
251
|
code: "GSPD",
|
|
222
252
|
label: "Aircraft Groundspeed",
|
|
223
|
-
value: `${decodeResult.raw.groundspeed}`
|
|
253
|
+
value: `${decodeResult.raw.groundspeed} knots`
|
|
224
254
|
});
|
|
225
255
|
}
|
|
226
256
|
static temperature(decodeResult, value) {
|
|
@@ -241,6 +271,55 @@ var ResultFormatter = class {
|
|
|
241
271
|
value: `${decodeResult.raw.heading}`
|
|
242
272
|
});
|
|
243
273
|
}
|
|
274
|
+
static tail(decodeResult, value) {
|
|
275
|
+
decodeResult.raw.tail = value;
|
|
276
|
+
decodeResult.formatted.items.push({
|
|
277
|
+
type: "tail",
|
|
278
|
+
code: "TAIL",
|
|
279
|
+
label: "Tail",
|
|
280
|
+
value: decodeResult.raw.tail
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
static out(decodeResult, time) {
|
|
284
|
+
decodeResult.raw.out_time = time;
|
|
285
|
+
const date = new Date(time * 1e3);
|
|
286
|
+
decodeResult.formatted.items.push({
|
|
287
|
+
type: "time_of_day",
|
|
288
|
+
code: "OUT",
|
|
289
|
+
label: "Out of Gate Time",
|
|
290
|
+
value: date.toISOString().slice(11, 19)
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
static off(decodeResult, time) {
|
|
294
|
+
decodeResult.raw.off_time = time;
|
|
295
|
+
const date = new Date(time * 1e3);
|
|
296
|
+
decodeResult.formatted.items.push({
|
|
297
|
+
type: "time_of_day",
|
|
298
|
+
code: "OFF",
|
|
299
|
+
label: "Takeoff Time",
|
|
300
|
+
value: date.toISOString().slice(11, 19)
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
static on(decodeResult, time) {
|
|
304
|
+
decodeResult.raw.on_time = time;
|
|
305
|
+
const date = new Date(time * 1e3);
|
|
306
|
+
decodeResult.formatted.items.push({
|
|
307
|
+
type: "time_of_day",
|
|
308
|
+
code: "ON",
|
|
309
|
+
label: "Landing Time",
|
|
310
|
+
value: date.toISOString().slice(11, 19)
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
static in(decodeResult, time) {
|
|
314
|
+
decodeResult.raw.in_time = time;
|
|
315
|
+
const date = new Date(time * 1e3);
|
|
316
|
+
decodeResult.formatted.items.push({
|
|
317
|
+
type: "time_of_day",
|
|
318
|
+
code: "IN",
|
|
319
|
+
label: "In Gate Time",
|
|
320
|
+
value: date.toISOString().slice(11, 19)
|
|
321
|
+
});
|
|
322
|
+
}
|
|
244
323
|
static unknown(decodeResult, value) {
|
|
245
324
|
decodeResult.remaining.text += "," + value;
|
|
246
325
|
}
|
|
@@ -347,7 +426,7 @@ var Label_10_LDR = class extends DecoderPlugin {
|
|
|
347
426
|
decodeResult.message = message;
|
|
348
427
|
const parts = message.text.split(",");
|
|
349
428
|
if (parts.length < 17) {
|
|
350
|
-
if (options
|
|
429
|
+
if (options.debug) {
|
|
351
430
|
console.log(`Decoder: Unknown 10 message: ${message.text}`);
|
|
352
431
|
}
|
|
353
432
|
decodeResult.remaining.text = message.text;
|
|
@@ -365,8 +444,13 @@ var Label_10_LDR = class extends DecoderPlugin {
|
|
|
365
444
|
ResultFormatter.altitude(decodeResult, Number(parts[7]));
|
|
366
445
|
ResultFormatter.departureAirport(decodeResult, parts[9]);
|
|
367
446
|
ResultFormatter.arrivalAirport(decodeResult, parts[10]);
|
|
447
|
+
ResultFormatter.alternateAirport(decodeResult, parts[11]);
|
|
368
448
|
ResultFormatter.arrivalRunway(decodeResult, parts[12].split("/")[0]);
|
|
369
|
-
|
|
449
|
+
const altRwy = [parts[13].split("/")[0], parts[14].split("/")[0]].filter((r) => r != "").join(",");
|
|
450
|
+
if (altRwy != "") {
|
|
451
|
+
ResultFormatter.alternateRunway(decodeResult, altRwy);
|
|
452
|
+
}
|
|
453
|
+
decodeResult.remaining.text = [...parts.slice(0, 5), ...parts.slice(15)].join(",");
|
|
370
454
|
decodeResult.decoded = true;
|
|
371
455
|
decodeResult.decoder.decodeLevel = "partial";
|
|
372
456
|
return decodeResult;
|
|
@@ -390,7 +474,7 @@ var Label_10_POS = class extends DecoderPlugin {
|
|
|
390
474
|
decodeResult.message = message;
|
|
391
475
|
const parts = message.text.split(",");
|
|
392
476
|
if (parts.length !== 12) {
|
|
393
|
-
if (options
|
|
477
|
+
if (options.debug) {
|
|
394
478
|
console.log(`Decoder: Unknown 10 message: ${message.text}`);
|
|
395
479
|
}
|
|
396
480
|
decodeResult.remaining.text = message.text;
|
|
@@ -553,7 +637,7 @@ var Label_10_Slash = class extends DecoderPlugin {
|
|
|
553
637
|
decodeResult.message = message;
|
|
554
638
|
const parts = message.text.split("/");
|
|
555
639
|
if (parts.length < 17) {
|
|
556
|
-
if (options
|
|
640
|
+
if (options.debug) {
|
|
557
641
|
console.log(`Decoder: Unknown 10 message: ${message.text}`);
|
|
558
642
|
}
|
|
559
643
|
decodeResult.remaining.text = message.text;
|
|
@@ -648,6 +732,97 @@ var Label_12_N_Space = class extends DecoderPlugin {
|
|
|
648
732
|
}
|
|
649
733
|
};
|
|
650
734
|
|
|
735
|
+
// lib/plugins/Label_13Through18_Slash.ts
|
|
736
|
+
var Label_13Through18_Slash = class extends DecoderPlugin {
|
|
737
|
+
// eslint-disable-line camelcase
|
|
738
|
+
name = "label-13-18-slash";
|
|
739
|
+
qualifiers() {
|
|
740
|
+
return {
|
|
741
|
+
labels: ["13", "14", "15", "16", "17", "18"],
|
|
742
|
+
preambles: ["/"]
|
|
743
|
+
};
|
|
744
|
+
}
|
|
745
|
+
decode(message, options = {}) {
|
|
746
|
+
const decodeResult = this.defaultResult();
|
|
747
|
+
decodeResult.decoder.name = this.name;
|
|
748
|
+
decodeResult.message = message;
|
|
749
|
+
const lines = message.text.split("\r\n");
|
|
750
|
+
const parts = lines[0].split("/");
|
|
751
|
+
const labelNumber = Number(parts[1].substring(0, 2));
|
|
752
|
+
decodeResult.formatted.description = getMsgType(labelNumber);
|
|
753
|
+
if (labelNumber !== 18 && parts.length !== 4 || labelNumber === 18 && parts.length !== 7) {
|
|
754
|
+
if (options?.debug) {
|
|
755
|
+
console.log(`Decoder: Unknown OOOI message: ${message.text}`);
|
|
756
|
+
}
|
|
757
|
+
decodeResult.remaining.text = message.text;
|
|
758
|
+
decodeResult.decoded = false;
|
|
759
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
760
|
+
return decodeResult;
|
|
761
|
+
}
|
|
762
|
+
decodeResult.remaining.text = "";
|
|
763
|
+
const data = parts[2].split(" ");
|
|
764
|
+
ResultFormatter.departureAirport(decodeResult, data[1]);
|
|
765
|
+
ResultFormatter.arrivalAirport(decodeResult, data[2]);
|
|
766
|
+
decodeResult.raw.day_of_month = Number(data[3]);
|
|
767
|
+
const time = DateTimeUtils.convertHHMMSSToTod(data[4]);
|
|
768
|
+
if (labelNumber === 13) {
|
|
769
|
+
ResultFormatter.out(decodeResult, time);
|
|
770
|
+
} else if (labelNumber === 14) {
|
|
771
|
+
ResultFormatter.off(decodeResult, time);
|
|
772
|
+
} else if (labelNumber === 15) {
|
|
773
|
+
ResultFormatter.on(decodeResult, time);
|
|
774
|
+
} else if (labelNumber === 16) {
|
|
775
|
+
ResultFormatter.in(decodeResult, time);
|
|
776
|
+
}
|
|
777
|
+
if (parts.length === 7) {
|
|
778
|
+
decodeResult.remaining.text += parts.slice(4).join("/");
|
|
779
|
+
}
|
|
780
|
+
for (let i = 1; i < lines.length; i++) {
|
|
781
|
+
if (lines[i].startsWith("/LOC")) {
|
|
782
|
+
const location = lines[i].substring(5).split(",");
|
|
783
|
+
let position;
|
|
784
|
+
if (location[0].startsWith("+") || location[0].startsWith("-")) {
|
|
785
|
+
position = { latitude: Number(location[0]), longitude: Number(location[1]) };
|
|
786
|
+
} else {
|
|
787
|
+
position = {
|
|
788
|
+
latitude: CoordinateUtils.getDirection(location[0][0]) * CoordinateUtils.dmsToDecimalDegrees(Number(location[0].substring(1, 3)), Number(location[0].substring(3, 5)), Number(location[0].substring(5, 7))),
|
|
789
|
+
longitude: CoordinateUtils.getDirection(location[1][0]) * CoordinateUtils.dmsToDecimalDegrees(Number(location[1].substring(1, 4)), Number(location[1].substring(4, 6)), Number(location[1].substring(6, 8)))
|
|
790
|
+
};
|
|
791
|
+
}
|
|
792
|
+
if (!isNaN(position.latitude) && !isNaN(position.longitude)) {
|
|
793
|
+
ResultFormatter.position(decodeResult, position);
|
|
794
|
+
}
|
|
795
|
+
} else {
|
|
796
|
+
decodeResult.remaining.text += "\r\n" + lines[i];
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
decodeResult.decoded = true;
|
|
800
|
+
decodeResult.decoder.decodeLevel = decodeResult.remaining.text ? "partial" : "full";
|
|
801
|
+
return decodeResult;
|
|
802
|
+
}
|
|
803
|
+
};
|
|
804
|
+
function getMsgType(labelNumber) {
|
|
805
|
+
if (labelNumber === 13) {
|
|
806
|
+
return "Out of Gate Report";
|
|
807
|
+
}
|
|
808
|
+
if (labelNumber === 14) {
|
|
809
|
+
return "Takeoff Report";
|
|
810
|
+
}
|
|
811
|
+
if (labelNumber === 15) {
|
|
812
|
+
return "On Ground Report";
|
|
813
|
+
}
|
|
814
|
+
if (labelNumber === 16) {
|
|
815
|
+
return "In Gate Report";
|
|
816
|
+
}
|
|
817
|
+
if (labelNumber === 17) {
|
|
818
|
+
return "Post Report";
|
|
819
|
+
}
|
|
820
|
+
if (labelNumber === 18) {
|
|
821
|
+
return "Post Times Report";
|
|
822
|
+
}
|
|
823
|
+
return "Unknown";
|
|
824
|
+
}
|
|
825
|
+
|
|
651
826
|
// lib/plugins/Label_15.ts
|
|
652
827
|
var Label_15 = class extends DecoderPlugin {
|
|
653
828
|
name = "label-5z";
|
|
@@ -859,11 +1034,11 @@ var Label_20_POS = class extends DecoderPlugin {
|
|
|
859
1034
|
decodeResult.message = message;
|
|
860
1035
|
decodeResult.raw.preamble = message.text.substring(0, 3);
|
|
861
1036
|
const content = message.text.substring(3);
|
|
862
|
-
console.log("Content: " + content);
|
|
863
1037
|
const fields = content.split(",");
|
|
864
|
-
console.log("Field Count: " + fields.length);
|
|
865
1038
|
if (fields.length == 11) {
|
|
866
|
-
|
|
1039
|
+
if (options.debug) {
|
|
1040
|
+
console.log(`DEBUG: ${this.name}: Variation 1 detected`);
|
|
1041
|
+
}
|
|
867
1042
|
const rawCoords = fields[0];
|
|
868
1043
|
decodeResult.raw.position = CoordinateUtils.decodeStringCoordinates(rawCoords);
|
|
869
1044
|
if (decodeResult.raw.position) {
|
|
@@ -877,7 +1052,9 @@ var Label_20_POS = class extends DecoderPlugin {
|
|
|
877
1052
|
decodeResult.decoded = true;
|
|
878
1053
|
decodeResult.decoder.decodeLevel = "full";
|
|
879
1054
|
} else if (fields.length == 5) {
|
|
880
|
-
|
|
1055
|
+
if (options.debug) {
|
|
1056
|
+
console.log(`DEBUG: ${this.name}: Variation 2 detected`);
|
|
1057
|
+
}
|
|
881
1058
|
const rawCoords = fields[0];
|
|
882
1059
|
decodeResult.raw.position = CoordinateUtils.decodeStringCoordinates(rawCoords);
|
|
883
1060
|
if (decodeResult.raw.position) {
|
|
@@ -891,7 +1068,9 @@ var Label_20_POS = class extends DecoderPlugin {
|
|
|
891
1068
|
decodeResult.decoded = true;
|
|
892
1069
|
decodeResult.decoder.decodeLevel = "full";
|
|
893
1070
|
} else {
|
|
894
|
-
|
|
1071
|
+
if (options.debug) {
|
|
1072
|
+
console.log(`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${content}`);
|
|
1073
|
+
}
|
|
895
1074
|
decodeResult.decoded = false;
|
|
896
1075
|
decodeResult.decoder.decodeLevel = "none";
|
|
897
1076
|
}
|
|
@@ -915,9 +1094,7 @@ var Label_21_POS = class extends DecoderPlugin {
|
|
|
915
1094
|
decodeResult.message = message;
|
|
916
1095
|
decodeResult.raw.preamble = message.text.substring(0, 3);
|
|
917
1096
|
const content = message.text.substring(3);
|
|
918
|
-
console.log("Content: " + content);
|
|
919
1097
|
const fields = content.split(",");
|
|
920
|
-
console.log("Field Count: " + fields.length);
|
|
921
1098
|
if (fields.length == 9) {
|
|
922
1099
|
processPosition(decodeResult, fields[0].trim());
|
|
923
1100
|
processAlt(decodeResult, fields[3]);
|
|
@@ -933,7 +1110,9 @@ var Label_21_POS = class extends DecoderPlugin {
|
|
|
933
1110
|
decodeResult.decoded = true;
|
|
934
1111
|
decodeResult.decoder.decodeLevel = "partial";
|
|
935
1112
|
} else {
|
|
936
|
-
|
|
1113
|
+
if (options.debug) {
|
|
1114
|
+
console.log(`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${content}`);
|
|
1115
|
+
}
|
|
937
1116
|
decodeResult.decoded = false;
|
|
938
1117
|
decodeResult.decoder.decodeLevel = "none";
|
|
939
1118
|
}
|
|
@@ -1315,6 +1494,64 @@ var Label_44_POS = class extends DecoderPlugin {
|
|
|
1315
1494
|
}
|
|
1316
1495
|
};
|
|
1317
1496
|
|
|
1497
|
+
// lib/plugins/Label_4N.ts
|
|
1498
|
+
var Label_4N = class extends DecoderPlugin {
|
|
1499
|
+
name = "label-4n";
|
|
1500
|
+
qualifiers() {
|
|
1501
|
+
return {
|
|
1502
|
+
labels: ["4N"]
|
|
1503
|
+
};
|
|
1504
|
+
}
|
|
1505
|
+
decode(message, options = {}) {
|
|
1506
|
+
const decodeResult = this.defaultResult();
|
|
1507
|
+
decodeResult.decoder.name = this.name;
|
|
1508
|
+
decodeResult.message = message;
|
|
1509
|
+
decodeResult.formatted.description = "Airline Defined";
|
|
1510
|
+
let text = message.text;
|
|
1511
|
+
if (text.match(/^M\d{2}A\w{6}/)) {
|
|
1512
|
+
ResultFormatter.flightNumber(decodeResult, message.text.substring(4, 10).replace(/^([A-Z]+)0*/g, "$1"));
|
|
1513
|
+
text = text.substring(10);
|
|
1514
|
+
}
|
|
1515
|
+
decodeResult.decoded = true;
|
|
1516
|
+
const fields = text.split(",");
|
|
1517
|
+
if (text.length === 51) {
|
|
1518
|
+
decodeResult.raw.day_of_month = text.substring(0, 2);
|
|
1519
|
+
ResultFormatter.departureAirport(decodeResult, text.substring(8, 11));
|
|
1520
|
+
ResultFormatter.arrivalAirport(decodeResult, text.substring(13, 16));
|
|
1521
|
+
ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(text.substring(30, 45).replace(/^(.)0/, "$1")));
|
|
1522
|
+
ResultFormatter.altitude(decodeResult, text.substring(48, 51) * 100);
|
|
1523
|
+
decodeResult.remaining.text = [text.substring(2, 4), text.substring(19, 29)].join(" ");
|
|
1524
|
+
} else if (fields.length === 33) {
|
|
1525
|
+
decodeResult.raw.date = fields[3];
|
|
1526
|
+
if (fields[1] === "B") {
|
|
1527
|
+
ResultFormatter.position(decodeResult, { latitude: Number(fields[4]), longitude: Number(fields[5]) });
|
|
1528
|
+
ResultFormatter.altitude(decodeResult, fields[6]);
|
|
1529
|
+
}
|
|
1530
|
+
ResultFormatter.departureAirport(decodeResult, fields[8]);
|
|
1531
|
+
ResultFormatter.arrivalAirport(decodeResult, fields[9]);
|
|
1532
|
+
ResultFormatter.alternateAirport(decodeResult, fields[10]);
|
|
1533
|
+
ResultFormatter.arrivalRunway(decodeResult, fields[11].split("/")[0]);
|
|
1534
|
+
if (fields[12].length > 1) {
|
|
1535
|
+
ResultFormatter.alternateRunway(decodeResult, fields[12].split("/")[0]);
|
|
1536
|
+
}
|
|
1537
|
+
ResultFormatter.checksum(decodeResult, fields[32]);
|
|
1538
|
+
decodeResult.remaining.text = [...fields.slice(1, 3), fields[7], ...fields.slice(13, 32)].filter((f) => f != "").join(",");
|
|
1539
|
+
} else {
|
|
1540
|
+
decodeResult.decoded = false;
|
|
1541
|
+
decodeResult.remaining.text = text;
|
|
1542
|
+
}
|
|
1543
|
+
if (decodeResult.decoded) {
|
|
1544
|
+
if (decodeResult.remaining.text === "")
|
|
1545
|
+
decodeResult.decoder.decodeLevel = "full";
|
|
1546
|
+
else
|
|
1547
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
1548
|
+
} else {
|
|
1549
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1550
|
+
}
|
|
1551
|
+
return decodeResult;
|
|
1552
|
+
}
|
|
1553
|
+
};
|
|
1554
|
+
|
|
1318
1555
|
// lib/plugins/Label_80.ts
|
|
1319
1556
|
var Label_80 = class extends DecoderPlugin {
|
|
1320
1557
|
name = "label-80";
|
|
@@ -1346,27 +1583,15 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
1346
1583
|
const parts = message.text.split("\n");
|
|
1347
1584
|
let posRptRegex = /^3N01 POSRPT \d\d\d\d\/\d\d (?<orig>\w+)\/(?<dest>\w+) \.(?<tail>[\w-]+)(\/(?<agate>.+) (?<sta>\w+:\w+))*/;
|
|
1348
1585
|
let results = parts[0].match(posRptRegex);
|
|
1586
|
+
if (!results?.groups) {
|
|
1587
|
+
decodeResult.decoded = false;
|
|
1588
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1589
|
+
return decodeResult;
|
|
1590
|
+
}
|
|
1349
1591
|
if (results && results.length > 0) {
|
|
1350
|
-
decodeResult
|
|
1351
|
-
decodeResult.
|
|
1352
|
-
|
|
1353
|
-
code: "ORG",
|
|
1354
|
-
label: "Origin",
|
|
1355
|
-
value: `${results.groups.orig}`
|
|
1356
|
-
});
|
|
1357
|
-
decodeResult.raw.destination = results.groups.dest;
|
|
1358
|
-
decodeResult.formatted.items.push({
|
|
1359
|
-
type: "destination",
|
|
1360
|
-
code: "DST",
|
|
1361
|
-
label: "Destination",
|
|
1362
|
-
value: `${results.groups.dest}`
|
|
1363
|
-
});
|
|
1364
|
-
decodeResult.raw.tail = results.groups.tail;
|
|
1365
|
-
decodeResult.formatted.items.push({
|
|
1366
|
-
type: "tail",
|
|
1367
|
-
label: "Tail",
|
|
1368
|
-
value: `${results.groups.tail}`
|
|
1369
|
-
});
|
|
1592
|
+
ResultFormatter.departureAirport(decodeResult, results.groups.orig);
|
|
1593
|
+
ResultFormatter.arrivalAirport(decodeResult, results.groups.dest);
|
|
1594
|
+
ResultFormatter.tail(decodeResult, results.groups.tail);
|
|
1370
1595
|
if (results.groups.agate) {
|
|
1371
1596
|
decodeResult.raw.arrival_gate = results.groups.agate;
|
|
1372
1597
|
decodeResult.formatted.items.push({
|
|
@@ -1388,15 +1613,9 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
1388
1613
|
for (const part of remainingParts) {
|
|
1389
1614
|
const matches = part.matchAll(posRptRegex);
|
|
1390
1615
|
for (const match of matches) {
|
|
1391
|
-
switch (match.groups
|
|
1616
|
+
switch (match.groups?.field) {
|
|
1392
1617
|
case "ALT": {
|
|
1393
|
-
|
|
1394
|
-
decodeResult.formatted.items.push({
|
|
1395
|
-
type: "altitude",
|
|
1396
|
-
code: "ALT",
|
|
1397
|
-
label: this.descriptions[match.groups.field],
|
|
1398
|
-
value: `${decodeResult.raw.altitude} feet`
|
|
1399
|
-
});
|
|
1618
|
+
ResultFormatter.altitude(decodeResult, Number(match.groups.value));
|
|
1400
1619
|
break;
|
|
1401
1620
|
}
|
|
1402
1621
|
case "DWND": {
|
|
@@ -1410,9 +1629,8 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
1410
1629
|
break;
|
|
1411
1630
|
}
|
|
1412
1631
|
case "FL": {
|
|
1413
|
-
const flight_level = match.groups.value;
|
|
1414
|
-
|
|
1415
|
-
ResultFormatter.altitude(decodeResult, decodeResult.raw.altitude);
|
|
1632
|
+
const flight_level = Number(match.groups.value);
|
|
1633
|
+
ResultFormatter.altitude(decodeResult, flight_level * 100);
|
|
1416
1634
|
break;
|
|
1417
1635
|
}
|
|
1418
1636
|
case "FOB": {
|
|
@@ -1436,7 +1654,7 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
1436
1654
|
break;
|
|
1437
1655
|
}
|
|
1438
1656
|
case "MCH": {
|
|
1439
|
-
decodeResult.raw.mach = match.groups.value / 1e3;
|
|
1657
|
+
decodeResult.raw.mach = Number(match.groups.value) / 1e3;
|
|
1440
1658
|
decodeResult.formatted.items.push({
|
|
1441
1659
|
type: "mach",
|
|
1442
1660
|
code: "MCH",
|
|
@@ -1458,20 +1676,13 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
1458
1676
|
case "POS": {
|
|
1459
1677
|
const posRegex = /^(?<latd>[NS])(?<lat>.+)(?<lngd>[EW])(?<lng>.+)/;
|
|
1460
1678
|
const posResult = match.groups.value.match(posRegex);
|
|
1461
|
-
const lat = Number(posResult
|
|
1462
|
-
const lon = Number(posResult
|
|
1463
|
-
const
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
latitude,
|
|
1467
|
-
longitude
|
|
1679
|
+
const lat = Number(posResult?.groups?.lat) * (posResult?.groups?.lngd === "S" ? -1 : 1);
|
|
1680
|
+
const lon = Number(posResult?.groups?.lng) * (posResult?.groups?.lngd === "W" ? -1 : 1);
|
|
1681
|
+
const position = {
|
|
1682
|
+
latitude: Number.isInteger(lat) ? lat / 1e3 : lat / 100,
|
|
1683
|
+
longitude: Number.isInteger(lon) ? lon / 1e3 : lon / 100
|
|
1468
1684
|
};
|
|
1469
|
-
|
|
1470
|
-
type: "position",
|
|
1471
|
-
code: "POS",
|
|
1472
|
-
label: "Position",
|
|
1473
|
-
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
1474
|
-
});
|
|
1685
|
+
ResultFormatter.position(decodeResult, position);
|
|
1475
1686
|
break;
|
|
1476
1687
|
}
|
|
1477
1688
|
case "SWND": {
|
|
@@ -1485,7 +1696,7 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
1485
1696
|
break;
|
|
1486
1697
|
}
|
|
1487
1698
|
default: {
|
|
1488
|
-
if (match.groups
|
|
1699
|
+
if (match.groups?.field != void 0) {
|
|
1489
1700
|
const description = this.descriptions[match.groups.field] ? this.descriptions[match.groups.field] : "Unknown";
|
|
1490
1701
|
decodeResult.formatted.items.push({
|
|
1491
1702
|
type: match.groups.field,
|
|
@@ -1499,7 +1710,77 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
1499
1710
|
}
|
|
1500
1711
|
}
|
|
1501
1712
|
decodeResult.decoded = true;
|
|
1502
|
-
decodeResult.decodeLevel = "partial";
|
|
1713
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
1714
|
+
}
|
|
1715
|
+
return decodeResult;
|
|
1716
|
+
}
|
|
1717
|
+
};
|
|
1718
|
+
|
|
1719
|
+
// lib/plugins/Label_83.ts
|
|
1720
|
+
var Label_83 = class extends DecoderPlugin {
|
|
1721
|
+
name = "label-83";
|
|
1722
|
+
qualifiers() {
|
|
1723
|
+
return {
|
|
1724
|
+
labels: ["83"]
|
|
1725
|
+
};
|
|
1726
|
+
}
|
|
1727
|
+
decode(message, options = {}) {
|
|
1728
|
+
const decodeResult = this.defaultResult();
|
|
1729
|
+
decodeResult.decoder.name = this.name;
|
|
1730
|
+
decodeResult.message = message;
|
|
1731
|
+
decodeResult.formatted.description = "Airline Defined";
|
|
1732
|
+
let text = message.text;
|
|
1733
|
+
if (text.match(/^M\d{2}A\w{6}/)) {
|
|
1734
|
+
ResultFormatter.flightNumber(decodeResult, message.text.substring(4, 10).replace(/^([A-Z]+)0*/g, "$1"));
|
|
1735
|
+
text = text.substring(10);
|
|
1736
|
+
}
|
|
1737
|
+
decodeResult.decoded = true;
|
|
1738
|
+
if (text.substring(0, 10) === "4DH3 ETAT2") {
|
|
1739
|
+
const fields = text.split(/\s+/);
|
|
1740
|
+
if (fields[2].length > 5) {
|
|
1741
|
+
decodeResult.raw.day_of_month = fields[2].substring(5);
|
|
1742
|
+
}
|
|
1743
|
+
decodeResult.remaining.text = fields[2].substring(0, 4);
|
|
1744
|
+
const subfields = fields[3].split("/");
|
|
1745
|
+
ResultFormatter.departureAirport(decodeResult, subfields[0]);
|
|
1746
|
+
ResultFormatter.arrivalAirport(decodeResult, subfields[1]);
|
|
1747
|
+
ResultFormatter.tail(decodeResult, fields[4].replace(/\./g, ""));
|
|
1748
|
+
ResultFormatter.eta(decodeResult, fields[6] + "00");
|
|
1749
|
+
} else if (text.substring(0, 5) === "001PR") {
|
|
1750
|
+
decodeResult.raw.day_of_month = text.substring(5, 7);
|
|
1751
|
+
ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(text.substring(13, 28).replace(/\./g, "")));
|
|
1752
|
+
ResultFormatter.altitude(decodeResult, Number(text.substring(28, 33)));
|
|
1753
|
+
decodeResult.remaining.text = text.substring(33);
|
|
1754
|
+
} else {
|
|
1755
|
+
const fields = text.replace(/\s/g, "").split(",");
|
|
1756
|
+
if (fields.length === 9) {
|
|
1757
|
+
ResultFormatter.departureAirport(decodeResult, fields[0]);
|
|
1758
|
+
ResultFormatter.arrivalAirport(decodeResult, fields[1]);
|
|
1759
|
+
decodeResult.raw.day_of_month = fields[2].substring(0, 2);
|
|
1760
|
+
decodeResult.raw.time = fields[2].substring(2);
|
|
1761
|
+
ResultFormatter.position(
|
|
1762
|
+
decodeResult,
|
|
1763
|
+
{
|
|
1764
|
+
latitude: Number(fields[3].replace(/\s/g, "")),
|
|
1765
|
+
longitude: Number(fields[4].replace(/\s/g, ""))
|
|
1766
|
+
}
|
|
1767
|
+
);
|
|
1768
|
+
ResultFormatter.altitude(decodeResult, fields[5]);
|
|
1769
|
+
ResultFormatter.groundspeed(decodeResult, fields[6]);
|
|
1770
|
+
ResultFormatter.heading(decodeResult, fields[7]);
|
|
1771
|
+
decodeResult.remaining.text = fields[8];
|
|
1772
|
+
} else {
|
|
1773
|
+
decodeResult.decoded = false;
|
|
1774
|
+
decodeResult.remaining.text = message.text;
|
|
1775
|
+
}
|
|
1776
|
+
}
|
|
1777
|
+
if (decodeResult.decoded) {
|
|
1778
|
+
if (decodeResult.remaining.text === "")
|
|
1779
|
+
decodeResult.decoder.decodeLevel = "full";
|
|
1780
|
+
else
|
|
1781
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
1782
|
+
} else {
|
|
1783
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1503
1784
|
}
|
|
1504
1785
|
return decodeResult;
|
|
1505
1786
|
}
|
|
@@ -1907,13 +2188,7 @@ function processTimeOfDeparture(decodeResult, data) {
|
|
|
1907
2188
|
return false;
|
|
1908
2189
|
}
|
|
1909
2190
|
function processIdentification(decodeResult, data) {
|
|
1910
|
-
|
|
1911
|
-
decodeResult.formatted.items.push({
|
|
1912
|
-
type: "tail",
|
|
1913
|
-
code: "TAIL",
|
|
1914
|
-
label: "Tail",
|
|
1915
|
-
value: decodeResult.raw.tail
|
|
1916
|
-
});
|
|
2191
|
+
ResultFormatter.tail(decodeResult, data[0]);
|
|
1917
2192
|
if (data.length > 1) {
|
|
1918
2193
|
decodeResult.raw.flight_number = data[1];
|
|
1919
2194
|
}
|
|
@@ -2010,8 +2285,6 @@ function processPS(decodeResult, data) {
|
|
|
2010
2285
|
} else {
|
|
2011
2286
|
allKnownFields = false;
|
|
2012
2287
|
}
|
|
2013
|
-
console.log("PS data.length: ", data.length);
|
|
2014
|
-
console.log("PS data: ", data);
|
|
2015
2288
|
if (data.length === 9) {
|
|
2016
2289
|
processRoute(decodeResult, data[3], data[1], data[5], data[4], void 0);
|
|
2017
2290
|
ResultFormatter.altitude(decodeResult, Number(data[2]) * 100);
|
|
@@ -2046,8 +2319,6 @@ function processPosition2(decodeResult, data) {
|
|
|
2046
2319
|
} else {
|
|
2047
2320
|
allKnownFields = false;
|
|
2048
2321
|
}
|
|
2049
|
-
console.log("data.length: ", data.length);
|
|
2050
|
-
console.log("data: ", data);
|
|
2051
2322
|
if (data.length >= 10) {
|
|
2052
2323
|
ResultFormatter.altitude(decodeResult, Number(data[3]) * 100);
|
|
2053
2324
|
processRoute(decodeResult, data[1], data[2], data[4], data[5], data[6]);
|
|
@@ -2105,7 +2376,7 @@ var Label_H1_FPN = class extends DecoderPlugin {
|
|
|
2105
2376
|
decodeResult.decoded = true;
|
|
2106
2377
|
decodeResult.decoder.decodeLevel = fulllyDecoded ? "full" : "partial";
|
|
2107
2378
|
if (decodeResult.formatted.items.length === 0) {
|
|
2108
|
-
if (options
|
|
2379
|
+
if (options.debug) {
|
|
2109
2380
|
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
2110
2381
|
}
|
|
2111
2382
|
decodeResult.remaining.text = message.text;
|
|
@@ -2135,7 +2406,7 @@ var Label_H1_FTX = class extends DecoderPlugin {
|
|
|
2135
2406
|
decodeResult.decoded = true;
|
|
2136
2407
|
decodeResult.decoder.decodeLevel = fulllyDecoded ? "full" : "partial";
|
|
2137
2408
|
if (decodeResult.formatted.items.length === 0) {
|
|
2138
|
-
if (options
|
|
2409
|
+
if (options.debug) {
|
|
2139
2410
|
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
2140
2411
|
}
|
|
2141
2412
|
decodeResult.remaining.text = message.text;
|
|
@@ -2166,7 +2437,7 @@ var Label_H1_INI = class extends DecoderPlugin {
|
|
|
2166
2437
|
decodeResult.decoded = true;
|
|
2167
2438
|
decodeResult.decoder.decodeLevel = fulllyDecoded ? "full" : "partial";
|
|
2168
2439
|
if (decodeResult.formatted.items.length === 0) {
|
|
2169
|
-
if (options
|
|
2440
|
+
if (options.debug) {
|
|
2170
2441
|
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
2171
2442
|
}
|
|
2172
2443
|
decodeResult.remaining.text = message.text;
|
|
@@ -2255,7 +2526,7 @@ var Label_H1_POS = class extends DecoderPlugin {
|
|
|
2255
2526
|
decodeResult.decoded = true;
|
|
2256
2527
|
decodeResult.decoder.decodeLevel = fulllyDecoded ? "full" : "partial";
|
|
2257
2528
|
if (decodeResult.formatted.items.length === 0) {
|
|
2258
|
-
if (options
|
|
2529
|
+
if (options.debug) {
|
|
2259
2530
|
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
2260
2531
|
}
|
|
2261
2532
|
decodeResult.remaining.text = message.text;
|
|
@@ -3497,6 +3768,7 @@ var MessageDecoder = class {
|
|
|
3497
3768
|
this.registerPlugin(new Label_10_POS(this));
|
|
3498
3769
|
this.registerPlugin(new Label_10_Slash(this));
|
|
3499
3770
|
this.registerPlugin(new Label_12_N_Space(this));
|
|
3771
|
+
this.registerPlugin(new Label_13Through18_Slash(this));
|
|
3500
3772
|
this.registerPlugin(new Label_15(this));
|
|
3501
3773
|
this.registerPlugin(new Label_15_FST(this));
|
|
3502
3774
|
this.registerPlugin(new Label_16_N_Space(this));
|
|
@@ -3508,6 +3780,7 @@ var MessageDecoder = class {
|
|
|
3508
3780
|
this.registerPlugin(new Label_44_OFF(this));
|
|
3509
3781
|
this.registerPlugin(new Label_44_ON(this));
|
|
3510
3782
|
this.registerPlugin(new Label_44_POS(this));
|
|
3783
|
+
this.registerPlugin(new Label_4N(this));
|
|
3511
3784
|
this.registerPlugin(new Label_B6_Forwardslash(this));
|
|
3512
3785
|
this.registerPlugin(new Label_H1_FPN(this));
|
|
3513
3786
|
this.registerPlugin(new Label_H1_FLR(this));
|
|
@@ -3518,6 +3791,7 @@ var MessageDecoder = class {
|
|
|
3518
3791
|
this.registerPlugin(new Label_H1_WRN(this));
|
|
3519
3792
|
this.registerPlugin(new Label_HX(this));
|
|
3520
3793
|
this.registerPlugin(new Label_80(this));
|
|
3794
|
+
this.registerPlugin(new Label_83(this));
|
|
3521
3795
|
this.registerPlugin(new Label_8E(this));
|
|
3522
3796
|
this.registerPlugin(new Label_1M_Slash(this));
|
|
3523
3797
|
this.registerPlugin(new Label_SQ(this));
|