@airframes/acars-decoder 1.6.7 → 1.6.8
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 +528 -369
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +528 -369
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -208,6 +208,12 @@ var Label_5Z = class extends DecoderPlugin {
|
|
|
208
208
|
|
|
209
209
|
// lib/utils/coordinate_utils.ts
|
|
210
210
|
var CoordinateUtils = class {
|
|
211
|
+
/**
|
|
212
|
+
* Decode a string of coordinates into an object with latitude and longitude in millidegrees
|
|
213
|
+
* @param stringCoords - The string of coordinates to decode
|
|
214
|
+
*
|
|
215
|
+
* @returns An object with latitude and longitude properties
|
|
216
|
+
*/
|
|
211
217
|
static decodeStringCoordinates(stringCoords) {
|
|
212
218
|
var results = {};
|
|
213
219
|
const firstChar = stringCoords.substring(0, 1);
|
|
@@ -225,6 +231,33 @@ var CoordinateUtils = class {
|
|
|
225
231
|
}
|
|
226
232
|
return results;
|
|
227
233
|
}
|
|
234
|
+
/**
|
|
235
|
+
* Decode a string of coordinates into an object with latitude and longitude in degrees and decimal minutes
|
|
236
|
+
* @param stringCoords - The string of coordinates to decode
|
|
237
|
+
*
|
|
238
|
+
* @returns An object with latitude and longitude properties
|
|
239
|
+
*/
|
|
240
|
+
static decodeStringCoordinatesDecimalMinutes(stringCoords) {
|
|
241
|
+
var results = {};
|
|
242
|
+
const firstChar = stringCoords.substring(0, 1);
|
|
243
|
+
let middleChar = stringCoords.substring(6, 7);
|
|
244
|
+
let longitudeChars = stringCoords.substring(7, 13);
|
|
245
|
+
if (middleChar == " ") {
|
|
246
|
+
middleChar = stringCoords.substring(7, 8);
|
|
247
|
+
longitudeChars = stringCoords.substring(8, 14);
|
|
248
|
+
}
|
|
249
|
+
const latDeg = Math.trunc(Number(stringCoords.substring(1, 6)) / 1e3);
|
|
250
|
+
const latMin = Number(stringCoords.substring(1, 6)) % 1e3 / 10;
|
|
251
|
+
const lonDeg = Math.trunc(Number(longitudeChars) / 1e3);
|
|
252
|
+
const lonMin = Number(longitudeChars) % 1e3 / 10;
|
|
253
|
+
if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
|
|
254
|
+
results.latitude = (latDeg + latMin / 60) * (firstChar === "S" ? -1 : 1);
|
|
255
|
+
results.longitude = (lonDeg + lonMin / 60) * (middleChar === "W" ? -1 : 1);
|
|
256
|
+
} else {
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
return results;
|
|
260
|
+
}
|
|
228
261
|
static coordinateString(coords) {
|
|
229
262
|
const latDir = coords.latitude > 0 ? "N" : "S";
|
|
230
263
|
const lonDir = coords.longitude > 0 ? "E" : "W";
|
|
@@ -595,6 +628,96 @@ var Label_20_POS = class extends DecoderPlugin {
|
|
|
595
628
|
}
|
|
596
629
|
};
|
|
597
630
|
|
|
631
|
+
// lib/plugins/Label_21_POS.ts
|
|
632
|
+
var Label_21_POS = class extends DecoderPlugin {
|
|
633
|
+
name = "label-21-pos";
|
|
634
|
+
qualifiers() {
|
|
635
|
+
return {
|
|
636
|
+
labels: ["21"],
|
|
637
|
+
preambles: ["POS"]
|
|
638
|
+
};
|
|
639
|
+
}
|
|
640
|
+
decode(message, options = {}) {
|
|
641
|
+
const decodeResult = this.defaultResult();
|
|
642
|
+
decodeResult.decoder.name = this.name;
|
|
643
|
+
decodeResult.formatted.description = "Position Report";
|
|
644
|
+
decodeResult.message = message;
|
|
645
|
+
decodeResult.raw.preamble = message.text.substring(0, 3);
|
|
646
|
+
const content = message.text.substring(3);
|
|
647
|
+
console.log("Content: " + content);
|
|
648
|
+
const fields = content.split(",");
|
|
649
|
+
console.log("Field Count: " + fields.length);
|
|
650
|
+
if (fields.length == 9) {
|
|
651
|
+
processPosition(decodeResult, fields[0].trim());
|
|
652
|
+
processAlt(decodeResult, fields[3]);
|
|
653
|
+
processTemp(decodeResult, fields[6]);
|
|
654
|
+
processArrvApt(decodeResult, fields[8]);
|
|
655
|
+
decodeResult.raw.remaining = [
|
|
656
|
+
fields[1],
|
|
657
|
+
fields[2],
|
|
658
|
+
fields[4],
|
|
659
|
+
fields[5],
|
|
660
|
+
fields[7]
|
|
661
|
+
].join(",");
|
|
662
|
+
decodeResult.decoded = true;
|
|
663
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
664
|
+
} else {
|
|
665
|
+
console.log(`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${content}`);
|
|
666
|
+
decodeResult.decoded = false;
|
|
667
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
668
|
+
}
|
|
669
|
+
return decodeResult;
|
|
670
|
+
}
|
|
671
|
+
};
|
|
672
|
+
function processPosition(decodeResult, value) {
|
|
673
|
+
if (value.length !== 16 && value[0] !== "N" && value[0] !== "S" && value[8] !== "W" && value[8] !== "E") {
|
|
674
|
+
return false;
|
|
675
|
+
}
|
|
676
|
+
const latDir = value[0] === "N" ? 1 : -1;
|
|
677
|
+
const lonDir = value[8] === "E" ? 1 : -1;
|
|
678
|
+
const position = {
|
|
679
|
+
latitude: latDir * Number(value.substring(1, 7)),
|
|
680
|
+
longitude: lonDir * Number(value.substring(9, 15))
|
|
681
|
+
};
|
|
682
|
+
if (position) {
|
|
683
|
+
decodeResult.raw.position = position;
|
|
684
|
+
decodeResult.formatted.items.push({
|
|
685
|
+
type: "aircraft_position",
|
|
686
|
+
code: "POS",
|
|
687
|
+
label: "Aircraft Position",
|
|
688
|
+
value: CoordinateUtils.coordinateString(position)
|
|
689
|
+
});
|
|
690
|
+
}
|
|
691
|
+
return !!position;
|
|
692
|
+
}
|
|
693
|
+
function processAlt(decodeResult, value) {
|
|
694
|
+
decodeResult.raw.altitude = Number(value);
|
|
695
|
+
decodeResult.formatted.items.push({
|
|
696
|
+
type: "altitude",
|
|
697
|
+
code: "ALT",
|
|
698
|
+
label: "Altitude",
|
|
699
|
+
value: `${decodeResult.raw.altitude} feet`
|
|
700
|
+
});
|
|
701
|
+
}
|
|
702
|
+
function processTemp(decodeResult, value) {
|
|
703
|
+
decodeResult.raw.outside_air_temperature = Number(value.substring(1)) * (value.charAt(0) === "M" ? -1 : 1);
|
|
704
|
+
decodeResult.formatted.items.push({
|
|
705
|
+
type: "outside_air_temperature",
|
|
706
|
+
code: "OATEMP",
|
|
707
|
+
label: "Outside Air Temperature (C)",
|
|
708
|
+
value: `${decodeResult.raw.outside_air_temperature}`
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
function processArrvApt(decodeResult, value) {
|
|
712
|
+
decodeResult.raw.arrival_icao = value;
|
|
713
|
+
decodeResult.formatted.items.push({
|
|
714
|
+
type: "destination",
|
|
715
|
+
code: "DST",
|
|
716
|
+
label: "Destination",
|
|
717
|
+
value: decodeResult.raw.arrival_icao
|
|
718
|
+
});
|
|
719
|
+
}
|
|
720
|
+
|
|
598
721
|
// lib/plugins/Label_30_Slash_EA.ts
|
|
599
722
|
var Label_30_Slash_EA = class extends DecoderPlugin {
|
|
600
723
|
name = "label-30-slash-ea";
|
|
@@ -892,7 +1015,7 @@ var Label_44_POS = class extends DecoderPlugin {
|
|
|
892
1015
|
console.log(`Label 44 Position Report: groups`);
|
|
893
1016
|
console.log(results.groups);
|
|
894
1017
|
}
|
|
895
|
-
decodeResult.raw.position = CoordinateUtils.
|
|
1018
|
+
decodeResult.raw.position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(results.groups.unsplit_coords);
|
|
896
1019
|
decodeResult.raw.flight_level = results.groups.flight_level_or_ground == "GRD" || results.groups.flight_level_or_ground == "***" ? "0" : Number(results.groups.flight_level_or_ground);
|
|
897
1020
|
decodeResult.raw.departure_icao = results.groups.departure_icao;
|
|
898
1021
|
decodeResult.raw.arrival_icao = results.groups.arrival_icao;
|
|
@@ -907,9 +1030,9 @@ var Label_44_POS = class extends DecoderPlugin {
|
|
|
907
1030
|
}
|
|
908
1031
|
if (decodeResult.raw.position) {
|
|
909
1032
|
decodeResult.formatted.items.push({
|
|
910
|
-
type: "
|
|
1033
|
+
type: "aircraft_position",
|
|
911
1034
|
code: "POS",
|
|
912
|
-
label: "Position",
|
|
1035
|
+
label: "Aircraft Position",
|
|
913
1036
|
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
914
1037
|
});
|
|
915
1038
|
}
|
|
@@ -1217,6 +1340,112 @@ var Label_ColonComma = class extends DecoderPlugin {
|
|
|
1217
1340
|
}
|
|
1218
1341
|
};
|
|
1219
1342
|
|
|
1343
|
+
// lib/utils/result_formatter.ts
|
|
1344
|
+
var ResultFormatter = class {
|
|
1345
|
+
static altitude(decodeResult, value) {
|
|
1346
|
+
decodeResult.raw.altitude = value;
|
|
1347
|
+
decodeResult.formatted.items.push({
|
|
1348
|
+
type: "altitude",
|
|
1349
|
+
code: "ALT",
|
|
1350
|
+
label: "Altitude",
|
|
1351
|
+
value: `${decodeResult.raw.altitude} feet`
|
|
1352
|
+
});
|
|
1353
|
+
}
|
|
1354
|
+
static flightNumber(decodeResult, value) {
|
|
1355
|
+
decodeResult.raw.flight_number = value;
|
|
1356
|
+
}
|
|
1357
|
+
static departureAirport(decodeResult, value) {
|
|
1358
|
+
decodeResult.raw.departure_icao = value;
|
|
1359
|
+
decodeResult.formatted.items.push({
|
|
1360
|
+
type: "origin",
|
|
1361
|
+
code: "ORG",
|
|
1362
|
+
label: "Origin",
|
|
1363
|
+
value: decodeResult.raw.departure_icao
|
|
1364
|
+
});
|
|
1365
|
+
}
|
|
1366
|
+
static departureRunway(decodeResult, value) {
|
|
1367
|
+
decodeResult.raw.departure_runway = value;
|
|
1368
|
+
decodeResult.formatted.items.push({
|
|
1369
|
+
type: "runway",
|
|
1370
|
+
code: "DEPRWY",
|
|
1371
|
+
label: "Departure Runway",
|
|
1372
|
+
value: decodeResult.raw.departure_runway
|
|
1373
|
+
});
|
|
1374
|
+
}
|
|
1375
|
+
static arrivalAirport(decodeResult, value) {
|
|
1376
|
+
decodeResult.raw.arrival_icao = value;
|
|
1377
|
+
decodeResult.formatted.items.push({
|
|
1378
|
+
type: "destination",
|
|
1379
|
+
code: "DST",
|
|
1380
|
+
label: "Destination",
|
|
1381
|
+
value: decodeResult.raw.arrival_icao
|
|
1382
|
+
});
|
|
1383
|
+
}
|
|
1384
|
+
static eta(decodeResult, value) {
|
|
1385
|
+
decodeResult.formatted.items.push({
|
|
1386
|
+
type: "eta",
|
|
1387
|
+
code: "ETA",
|
|
1388
|
+
label: "Estimated Time of Arrival",
|
|
1389
|
+
value: value.substring(0, 2) + ":" + value.substring(2, 4) + ":" + value.substring(4, 6)
|
|
1390
|
+
});
|
|
1391
|
+
}
|
|
1392
|
+
static arrivalRunway(decodeResult, value) {
|
|
1393
|
+
decodeResult.raw.arrival_runway = value;
|
|
1394
|
+
decodeResult.formatted.items.push({
|
|
1395
|
+
type: "runway",
|
|
1396
|
+
label: "Arrival Runway",
|
|
1397
|
+
value: decodeResult.raw.arrival_runway
|
|
1398
|
+
});
|
|
1399
|
+
}
|
|
1400
|
+
static currentFuel(decodeResult, value) {
|
|
1401
|
+
decodeResult.raw.fuel_on_board = value;
|
|
1402
|
+
decodeResult.formatted.items.push({
|
|
1403
|
+
type: "fuel_on_board",
|
|
1404
|
+
code: "FOB",
|
|
1405
|
+
label: "Fuel On Board",
|
|
1406
|
+
value: decodeResult.raw.fuel_on_board.toString()
|
|
1407
|
+
});
|
|
1408
|
+
}
|
|
1409
|
+
static remainingFuel(decodeResult, value) {
|
|
1410
|
+
decodeResult.raw.fuel_remaining = value;
|
|
1411
|
+
decodeResult.formatted.items.push({
|
|
1412
|
+
type: "fuel_remaining",
|
|
1413
|
+
label: "Fuel Remaining",
|
|
1414
|
+
value: decodeResult.raw.fuel_remaining.toString()
|
|
1415
|
+
});
|
|
1416
|
+
}
|
|
1417
|
+
static checksum(decodeResult, value) {
|
|
1418
|
+
decodeResult.raw.checksum = Number("0x" + value);
|
|
1419
|
+
decodeResult.formatted.items.push({
|
|
1420
|
+
type: "message_checksum",
|
|
1421
|
+
code: "CHECKSUM",
|
|
1422
|
+
label: "Message Checksum",
|
|
1423
|
+
value: "0x" + ("0000" + decodeResult.raw.checksum.toString(16)).slice(-4)
|
|
1424
|
+
});
|
|
1425
|
+
}
|
|
1426
|
+
static groundspeed(decodeResult, value) {
|
|
1427
|
+
decodeResult.raw.groundspeed = value;
|
|
1428
|
+
decodeResult.formatted.items.push({
|
|
1429
|
+
type: "aircraft_groundspeed",
|
|
1430
|
+
code: "GSPD",
|
|
1431
|
+
label: "Aircraft Groundspeed",
|
|
1432
|
+
value: `${decodeResult.raw.groundspeed}`
|
|
1433
|
+
});
|
|
1434
|
+
}
|
|
1435
|
+
static temperature(decodeResult, value) {
|
|
1436
|
+
decodeResult.raw.outside_air_temperature = Number(value.substring(1)) * (value.charAt(0) === "M" ? -1 : 1);
|
|
1437
|
+
decodeResult.formatted.items.push({
|
|
1438
|
+
type: "outside_air_temperature",
|
|
1439
|
+
code: "OATEMP",
|
|
1440
|
+
label: "Outside Air Temperature (C)",
|
|
1441
|
+
value: `${decodeResult.raw.outside_air_temperature}`
|
|
1442
|
+
});
|
|
1443
|
+
}
|
|
1444
|
+
static unknown(decodeResult, value) {
|
|
1445
|
+
decodeResult.remaining.text += "," + value;
|
|
1446
|
+
}
|
|
1447
|
+
};
|
|
1448
|
+
|
|
1220
1449
|
// lib/utils/route_utils.ts
|
|
1221
1450
|
var RouteUtils = class _RouteUtils {
|
|
1222
1451
|
static routeToString(route) {
|
|
@@ -1257,13 +1486,13 @@ var RouteUtils = class _RouteUtils {
|
|
|
1257
1486
|
}
|
|
1258
1487
|
const waypoint = leg.split(",");
|
|
1259
1488
|
if (waypoint.length == 2) {
|
|
1260
|
-
const position = CoordinateUtils.
|
|
1489
|
+
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(waypoint[1]);
|
|
1261
1490
|
if (position) {
|
|
1262
1491
|
return { name: waypoint[0], latitude: position.latitude, longitude: position.longitude };
|
|
1263
1492
|
}
|
|
1264
1493
|
}
|
|
1265
1494
|
if (leg.length == 13 || leg.length == 14) {
|
|
1266
|
-
const position = CoordinateUtils.
|
|
1495
|
+
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(leg);
|
|
1267
1496
|
const name = waypoint.length == 2 ? waypoint[0] : "";
|
|
1268
1497
|
if (position) {
|
|
1269
1498
|
return { name, latitude: position.latitude, longitude: position.longitude };
|
|
@@ -1342,13 +1571,126 @@ var FlightPlanUtils = class _FlightPlanUtils {
|
|
|
1342
1571
|
}
|
|
1343
1572
|
static parseHeader(decodeResult, header) {
|
|
1344
1573
|
let allKnownFields = true;
|
|
1345
|
-
|
|
1574
|
+
if (header.startsWith("RF")) {
|
|
1575
|
+
decodeResult.formatted.items.push({
|
|
1576
|
+
type: "status",
|
|
1577
|
+
code: "ROUTE_STATUS",
|
|
1578
|
+
label: "Route Status",
|
|
1579
|
+
value: "Route Filed"
|
|
1580
|
+
});
|
|
1581
|
+
decodeResult.raw.route_status = "RF";
|
|
1582
|
+
if (header.length > 2) {
|
|
1583
|
+
addRoute(decodeResult, header.substring(2));
|
|
1584
|
+
}
|
|
1585
|
+
} else if (header.startsWith("RP")) {
|
|
1586
|
+
decodeResult.raw.route_status = "RP";
|
|
1587
|
+
decodeResult.formatted.items.push({
|
|
1588
|
+
type: "status",
|
|
1589
|
+
code: "ROUTE_STATUS",
|
|
1590
|
+
label: "Route Status",
|
|
1591
|
+
value: "Route Planned"
|
|
1592
|
+
});
|
|
1593
|
+
decodeResult.raw.route_status = header;
|
|
1594
|
+
} else if (header.startsWith("RI")) {
|
|
1595
|
+
decodeResult.raw.route_status = "RI";
|
|
1596
|
+
decodeResult.formatted.items.push({
|
|
1597
|
+
type: "status",
|
|
1598
|
+
code: "ROUTE_STATUS",
|
|
1599
|
+
label: "Route Status",
|
|
1600
|
+
value: "Route Inactive"
|
|
1601
|
+
});
|
|
1602
|
+
} else {
|
|
1603
|
+
decodeResult.remaining.text += header;
|
|
1604
|
+
allKnownFields = false;
|
|
1605
|
+
}
|
|
1606
|
+
return allKnownFields;
|
|
1607
|
+
}
|
|
1608
|
+
};
|
|
1609
|
+
function addArrivalAirport(decodeResult, value) {
|
|
1610
|
+
ResultFormatter.arrivalAirport(decodeResult, value);
|
|
1611
|
+
}
|
|
1612
|
+
function addDepartureAirport(decodeResult, value) {
|
|
1613
|
+
ResultFormatter.departureAirport(decodeResult, value);
|
|
1614
|
+
}
|
|
1615
|
+
function addRunway(decodeResult, value) {
|
|
1616
|
+
if (value.length === 8) {
|
|
1617
|
+
ResultFormatter.arrivalRunway(decodeResult, value.substring(4, 7));
|
|
1618
|
+
}
|
|
1619
|
+
ResultFormatter.departureRunway(decodeResult, value.substring(0, 3));
|
|
1620
|
+
}
|
|
1621
|
+
function addRoute(decodeResult, value) {
|
|
1622
|
+
const route = value.split(".");
|
|
1623
|
+
decodeResult.raw.route = { waypoints: route.map((leg) => RouteUtils.getWaypoint(leg)) };
|
|
1624
|
+
decodeResult.formatted.items.push({
|
|
1625
|
+
type: "aircraft_route",
|
|
1626
|
+
code: "ROUTE",
|
|
1627
|
+
label: "Aircraft Route",
|
|
1628
|
+
value: RouteUtils.routeToString(decodeResult.raw.route)
|
|
1629
|
+
});
|
|
1630
|
+
}
|
|
1631
|
+
function addProcedure(decodeResult, value, type) {
|
|
1632
|
+
if (decodeResult.raw.procedures === void 0) {
|
|
1633
|
+
decodeResult.raw.procedures = [];
|
|
1634
|
+
}
|
|
1635
|
+
const data = value.split(".");
|
|
1636
|
+
let waypoints;
|
|
1637
|
+
if (data.length > 1) {
|
|
1638
|
+
waypoints = data.slice(1).map((leg) => RouteUtils.getWaypoint(leg));
|
|
1639
|
+
}
|
|
1640
|
+
const route = { name: data[0], waypoints };
|
|
1641
|
+
decodeResult.raw.procedures.push({ type, route });
|
|
1642
|
+
const procedureName = type.substring(0, 1).toUpperCase() + type.slice(1);
|
|
1643
|
+
let procedureValue = route.name;
|
|
1644
|
+
decodeResult.formatted.items.push({
|
|
1645
|
+
type: `procedure`,
|
|
1646
|
+
code: "proc",
|
|
1647
|
+
label: `${procedureName} Procedure`,
|
|
1648
|
+
value: RouteUtils.routeToString(route)
|
|
1649
|
+
});
|
|
1650
|
+
}
|
|
1651
|
+
function addCompanyRoute(decodeResult, value) {
|
|
1652
|
+
const segments = value.split(".");
|
|
1653
|
+
const parens_idx = segments[0].indexOf("(");
|
|
1654
|
+
let name;
|
|
1655
|
+
let runway;
|
|
1656
|
+
if (parens_idx === -1) {
|
|
1657
|
+
name = segments[0];
|
|
1658
|
+
} else {
|
|
1659
|
+
name = segments[0].slice(0, parens_idx);
|
|
1660
|
+
runway = segments[0].slice(parens_idx + 1, segments[0].indexOf(")"));
|
|
1661
|
+
}
|
|
1662
|
+
let waypoints;
|
|
1663
|
+
if (segments.length > 1) {
|
|
1664
|
+
waypoints = segments.slice(1).map((leg) => RouteUtils.getWaypoint(leg));
|
|
1665
|
+
}
|
|
1666
|
+
decodeResult.raw.company_route = {
|
|
1667
|
+
name,
|
|
1668
|
+
runway,
|
|
1669
|
+
waypoints
|
|
1670
|
+
};
|
|
1671
|
+
decodeResult.formatted.items.push({
|
|
1672
|
+
type: "company_route",
|
|
1673
|
+
code: "CR",
|
|
1674
|
+
label: "Company Route",
|
|
1675
|
+
value: RouteUtils.routeToString(decodeResult.raw.company_route)
|
|
1676
|
+
});
|
|
1677
|
+
}
|
|
1678
|
+
|
|
1679
|
+
// lib/utils/h1_helper.ts
|
|
1680
|
+
var H1Helper = class {
|
|
1681
|
+
static decodeH1Message(decodeResult, message) {
|
|
1682
|
+
let allKnownFields = true;
|
|
1683
|
+
const checksum = message.slice(-4);
|
|
1684
|
+
const data = message.slice(0, message.length - 4);
|
|
1685
|
+
const fields = data.split("/");
|
|
1346
1686
|
allKnownFields = allKnownFields && parseMessageType(decodeResult, fields[0]);
|
|
1347
1687
|
for (let i = 1; i < fields.length; ++i) {
|
|
1348
1688
|
if (fields[i].startsWith("FN")) {
|
|
1349
1689
|
decodeResult.raw.flight_number = fields[i].substring(2);
|
|
1350
1690
|
} else if (fields[i].startsWith("SN")) {
|
|
1351
1691
|
decodeResult.raw.serial_number = fields[i].substring(2);
|
|
1692
|
+
} else if (fields[i].startsWith("DC")) {
|
|
1693
|
+
processDC(decodeResult, fields[i].substring(2).split(","));
|
|
1352
1694
|
} else if (fields[i].startsWith("TS")) {
|
|
1353
1695
|
const ts = fields[i].substring(2).split(",");
|
|
1354
1696
|
let time = DateTimeUtils.convertDateTimeToEpoch(ts[0], ts[1]);
|
|
@@ -1356,69 +1698,101 @@ var FlightPlanUtils = class _FlightPlanUtils {
|
|
|
1356
1698
|
const date = ts[1].substring(2, 4) + ts[1].substring(0, 2) + ts[1].substring(4, 6);
|
|
1357
1699
|
time = DateTimeUtils.convertDateTimeToEpoch(ts[0], date);
|
|
1358
1700
|
}
|
|
1701
|
+
decodeResult.raw.message_date = ts[1];
|
|
1359
1702
|
decodeResult.raw.message_timestamp = time;
|
|
1360
1703
|
} else if (fields[i].startsWith("PS")) {
|
|
1361
|
-
const pos = fields[i].substring(2);
|
|
1362
|
-
allKnownFields == allKnownFields &&
|
|
1704
|
+
const pos = processPS(decodeResult, fields[i].substring(2).split(","));
|
|
1705
|
+
allKnownFields == allKnownFields && pos;
|
|
1363
1706
|
} else if (fields[i].startsWith("DT")) {
|
|
1364
|
-
const
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
type: "destination",
|
|
1368
|
-
code: "DST",
|
|
1369
|
-
label: "Destination",
|
|
1370
|
-
value: decodeResult.raw.arrival_icao
|
|
1371
|
-
});
|
|
1707
|
+
const data2 = fields[i].substring(2).split(",");
|
|
1708
|
+
const dt = processDT(decodeResult, data2);
|
|
1709
|
+
allKnownFields = allKnownFields && dt;
|
|
1372
1710
|
} else if (fields[i].startsWith("ID")) {
|
|
1373
|
-
const
|
|
1374
|
-
decodeResult.raw.tail =
|
|
1711
|
+
const data2 = fields[i].substring(2).split(",");
|
|
1712
|
+
decodeResult.raw.tail = data2[0];
|
|
1375
1713
|
decodeResult.formatted.items.push({
|
|
1376
1714
|
type: "tail",
|
|
1715
|
+
code: "TAIL",
|
|
1377
1716
|
label: "Tail",
|
|
1378
1717
|
value: decodeResult.raw.tail
|
|
1379
1718
|
});
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
type: "status",
|
|
1383
|
-
code: "ROUTE_STATUS",
|
|
1384
|
-
label: "Route Status",
|
|
1385
|
-
value: "Route Filed"
|
|
1386
|
-
});
|
|
1387
|
-
decodeResult.raw.route_status = "RF";
|
|
1388
|
-
if (fields[i].length > 2) {
|
|
1389
|
-
addRoute(decodeResult, fields[i].substring(2));
|
|
1719
|
+
if (data2.length > 1) {
|
|
1720
|
+
decodeResult.raw.flight_number = data2[1];
|
|
1390
1721
|
}
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1722
|
+
if (data2.length > 2) {
|
|
1723
|
+
allKnownFields = false;
|
|
1724
|
+
decodeResult.remaining.text += "," + data2.slice(2).join(",");
|
|
1725
|
+
}
|
|
1726
|
+
} else if (fields[i].startsWith("LR")) {
|
|
1727
|
+
const data2 = fields[i].substring(2).split(",");
|
|
1728
|
+
const lr = processLR(decodeResult, data2);
|
|
1729
|
+
allKnownFields = allKnownFields && lr;
|
|
1730
|
+
} else if (fields[i].startsWith("RI") || fields[i].startsWith("RF") || fields[i].startsWith("RP")) {
|
|
1731
|
+
const fp = FlightPlanUtils.processFlightPlan(decodeResult, fields[i].split(":"));
|
|
1732
|
+
allKnownFields = allKnownFields && fp;
|
|
1733
|
+
} else if (fields[i].startsWith("PR")) {
|
|
1734
|
+
allKnownFields = false;
|
|
1735
|
+
decodeResult.remaining.text += "/" + fields[i];
|
|
1736
|
+
} else if (fields[i].startsWith("PS")) {
|
|
1737
|
+
allKnownFields = false;
|
|
1738
|
+
decodeResult.remaining.text += fields[i];
|
|
1408
1739
|
} else {
|
|
1409
1740
|
decodeResult.remaining.text += "/" + fields[i];
|
|
1410
1741
|
allKnownFields = false;
|
|
1411
1742
|
}
|
|
1412
1743
|
}
|
|
1744
|
+
if (decodeResult.formatted.items.length > 0) {
|
|
1745
|
+
ResultFormatter.checksum(decodeResult, checksum);
|
|
1746
|
+
}
|
|
1413
1747
|
return allKnownFields;
|
|
1414
1748
|
}
|
|
1415
1749
|
};
|
|
1750
|
+
function processDT(decodeResult, data) {
|
|
1751
|
+
let allKnownFields = true;
|
|
1752
|
+
if (!decodeResult.raw.arrival_icao) {
|
|
1753
|
+
ResultFormatter.arrivalAirport(decodeResult, data[0]);
|
|
1754
|
+
} else if (decodeResult.raw.arrival_icao != data[0]) {
|
|
1755
|
+
decodeResult.remaining.text += "/" + data;
|
|
1756
|
+
}
|
|
1757
|
+
if (data.length > 1) {
|
|
1758
|
+
ResultFormatter.arrivalRunway(decodeResult, data[1]);
|
|
1759
|
+
}
|
|
1760
|
+
if (data.length > 2) {
|
|
1761
|
+
ResultFormatter.currentFuel(decodeResult, Number(data[2]));
|
|
1762
|
+
}
|
|
1763
|
+
if (data.length > 3) {
|
|
1764
|
+
ResultFormatter.eta(decodeResult, data[3]);
|
|
1765
|
+
}
|
|
1766
|
+
if (data.length > 4) {
|
|
1767
|
+
ResultFormatter.remainingFuel(decodeResult, Number(data[4]));
|
|
1768
|
+
}
|
|
1769
|
+
if (data.length > 5) {
|
|
1770
|
+
allKnownFields = false;
|
|
1771
|
+
decodeResult.remaining.text += "," + data.slice(5).join(",");
|
|
1772
|
+
}
|
|
1773
|
+
return allKnownFields;
|
|
1774
|
+
}
|
|
1775
|
+
function processLR(decodeResult, data) {
|
|
1776
|
+
let allKnownFields = true;
|
|
1777
|
+
if (data.length === 19) {
|
|
1778
|
+
ResultFormatter.unknown(decodeResult, data[1]);
|
|
1779
|
+
ResultFormatter.flightNumber(decodeResult, data[2]);
|
|
1780
|
+
ResultFormatter.departureAirport(decodeResult, data[3]);
|
|
1781
|
+
ResultFormatter.arrivalAirport(decodeResult, data[4]);
|
|
1782
|
+
ResultFormatter.arrivalRunway(decodeResult, data[5]);
|
|
1783
|
+
ResultFormatter.unknown(decodeResult, data.slice(6, 19).join(","));
|
|
1784
|
+
allKnownFields = false;
|
|
1785
|
+
} else {
|
|
1786
|
+
allKnownFields = false;
|
|
1787
|
+
}
|
|
1788
|
+
return allKnownFields;
|
|
1789
|
+
}
|
|
1416
1790
|
function parseMessageType(decodeResult, messageType) {
|
|
1417
1791
|
let decoded = true;
|
|
1418
1792
|
const parts = messageType.split("#");
|
|
1419
1793
|
if (parts.length == 1) {
|
|
1420
1794
|
if (parts[0].startsWith("POS") && parts[0].length !== 3 && !parts[0].startsWith("POS/")) {
|
|
1421
|
-
decoded =
|
|
1795
|
+
decoded = processPosition2(decodeResult, parts[0].substring(3).split(","));
|
|
1422
1796
|
}
|
|
1423
1797
|
return decoded;
|
|
1424
1798
|
} else if (parts.length == 2) {
|
|
@@ -1428,7 +1802,7 @@ function parseMessageType(decodeResult, messageType) {
|
|
|
1428
1802
|
decodeResult.remaining.text += "#" + parts[1].substring(0, 3);
|
|
1429
1803
|
}
|
|
1430
1804
|
if (parts[1].substring(3, 6) === "POS" && parts[1].length !== 6 && parts[1].substring(3, 7) !== "POS/") {
|
|
1431
|
-
decoded =
|
|
1805
|
+
decoded = processPosition2(decodeResult, parts[1].substring(6).split(","));
|
|
1432
1806
|
}
|
|
1433
1807
|
decodeResult.raw.message_type = messageType;
|
|
1434
1808
|
return decoded;
|
|
@@ -1436,8 +1810,21 @@ function parseMessageType(decodeResult, messageType) {
|
|
|
1436
1810
|
decodeResult.remaining.text += messageType;
|
|
1437
1811
|
return false;
|
|
1438
1812
|
}
|
|
1439
|
-
function
|
|
1440
|
-
|
|
1813
|
+
function processDC(decodeResult, data) {
|
|
1814
|
+
decodeResult.raw.message_date = data[0];
|
|
1815
|
+
if (data.length === 1) {
|
|
1816
|
+
} else if (data.length === 2) {
|
|
1817
|
+
const date = data[0].substring(2, 4) + data[0].substring(0, 2) + data[0].substring(4, 6);
|
|
1818
|
+
const time = DateTimeUtils.convertDateTimeToEpoch(data[1], data[0]);
|
|
1819
|
+
decodeResult.raw.message_timestamp = time;
|
|
1820
|
+
} else {
|
|
1821
|
+
return false;
|
|
1822
|
+
}
|
|
1823
|
+
return true;
|
|
1824
|
+
}
|
|
1825
|
+
function processPS(decodeResult, data) {
|
|
1826
|
+
let allKnownFields = true;
|
|
1827
|
+
const position = CoordinateUtils.decodeStringCoordinates(data[0]);
|
|
1441
1828
|
if (position) {
|
|
1442
1829
|
decodeResult.raw.position = position;
|
|
1443
1830
|
decodeResult.formatted.items.push({
|
|
@@ -1446,46 +1833,76 @@ function processPosition(decodeResult, value) {
|
|
|
1446
1833
|
label: "Aircraft Position",
|
|
1447
1834
|
value: CoordinateUtils.coordinateString(position)
|
|
1448
1835
|
});
|
|
1449
|
-
}
|
|
1450
|
-
|
|
1451
|
-
}
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
}
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1836
|
+
} else {
|
|
1837
|
+
allKnownFields = false;
|
|
1838
|
+
}
|
|
1839
|
+
console.log("PS data.length: ", data.length);
|
|
1840
|
+
console.log("PS data: ", data);
|
|
1841
|
+
if (data.length === 9) {
|
|
1842
|
+
processRoute(decodeResult, data[3], data[1], data[5], data[4], void 0);
|
|
1843
|
+
ResultFormatter.altitude(decodeResult, Number(data[2]) * 100);
|
|
1844
|
+
ResultFormatter.temperature(decodeResult, data[6]);
|
|
1845
|
+
ResultFormatter.unknown(decodeResult, data[7]);
|
|
1846
|
+
ResultFormatter.unknown(decodeResult, data[8]);
|
|
1847
|
+
}
|
|
1848
|
+
if (data.length === 14) {
|
|
1849
|
+
ResultFormatter.altitude(decodeResult, Number(data[3]) * 100);
|
|
1850
|
+
processRoute(decodeResult, data[4], data[2], data[6], data[5], void 0);
|
|
1851
|
+
ResultFormatter.temperature(decodeResult, data[7]);
|
|
1852
|
+
ResultFormatter.groundspeed(decodeResult, Number(data[10]));
|
|
1853
|
+
ResultFormatter.unknown(decodeResult, data[1]);
|
|
1854
|
+
ResultFormatter.unknown(decodeResult, data[8]);
|
|
1855
|
+
ResultFormatter.unknown(decodeResult, data[9]);
|
|
1856
|
+
ResultFormatter.unknown(decodeResult, data.slice(11).join(","));
|
|
1857
|
+
}
|
|
1858
|
+
allKnownFields = false;
|
|
1859
|
+
return allKnownFields;
|
|
1469
1860
|
}
|
|
1470
|
-
function
|
|
1471
|
-
|
|
1472
|
-
|
|
1861
|
+
function processPosition2(decodeResult, data) {
|
|
1862
|
+
let allKnownFields = true;
|
|
1863
|
+
const position = CoordinateUtils.decodeStringCoordinates(data[0]);
|
|
1864
|
+
if (position) {
|
|
1865
|
+
decodeResult.raw.position = position;
|
|
1473
1866
|
decodeResult.formatted.items.push({
|
|
1474
|
-
type: "
|
|
1475
|
-
|
|
1476
|
-
|
|
1867
|
+
type: "aircraft_position",
|
|
1868
|
+
code: "POS",
|
|
1869
|
+
label: "Aircraft Position",
|
|
1870
|
+
value: CoordinateUtils.coordinateString(position)
|
|
1477
1871
|
});
|
|
1478
|
-
}
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1872
|
+
} else {
|
|
1873
|
+
allKnownFields = false;
|
|
1874
|
+
}
|
|
1875
|
+
console.log("data.length: ", data.length);
|
|
1876
|
+
console.log("data: ", data);
|
|
1877
|
+
if (data.length >= 10) {
|
|
1878
|
+
ResultFormatter.altitude(decodeResult, Number(data[3]) * 100);
|
|
1879
|
+
processRoute(decodeResult, data[1], data[2], data[4], data[5], data[6]);
|
|
1880
|
+
ResultFormatter.temperature(decodeResult, data[7]);
|
|
1881
|
+
ResultFormatter.unknown(decodeResult, data[8]);
|
|
1882
|
+
ResultFormatter.unknown(decodeResult, data[9]);
|
|
1883
|
+
}
|
|
1884
|
+
if (data.length >= 14) {
|
|
1885
|
+
ResultFormatter.groundspeed(decodeResult, Number(data[10]));
|
|
1886
|
+
ResultFormatter.unknown(decodeResult, data[11]);
|
|
1887
|
+
ResultFormatter.unknown(decodeResult, data[12]);
|
|
1888
|
+
ResultFormatter.unknown(decodeResult, data[13]);
|
|
1889
|
+
}
|
|
1890
|
+
allKnownFields = false;
|
|
1891
|
+
return allKnownFields;
|
|
1485
1892
|
}
|
|
1486
|
-
function
|
|
1487
|
-
const
|
|
1488
|
-
|
|
1893
|
+
function processRoute(decodeResult, last, time, next, eta, then, date) {
|
|
1894
|
+
const lastTime = date ? DateTimeUtils.convertDateTimeToEpoch(time, date) : DateTimeUtils.convertHHMMSSToTod(time);
|
|
1895
|
+
const nextTime = date ? DateTimeUtils.convertDateTimeToEpoch(eta, date) : DateTimeUtils.convertHHMMSSToTod(eta);
|
|
1896
|
+
const timeFormat = date ? "epoch" : "tod";
|
|
1897
|
+
const lastWaypoint = RouteUtils.getWaypoint(last);
|
|
1898
|
+
lastWaypoint.time = lastTime;
|
|
1899
|
+
lastWaypoint.timeFormat = timeFormat;
|
|
1900
|
+
const nextWaypoint = RouteUtils.getWaypoint(next);
|
|
1901
|
+
nextWaypoint.time = nextTime;
|
|
1902
|
+
nextWaypoint.timeFormat = timeFormat;
|
|
1903
|
+
const thenWaypoint = RouteUtils.getWaypoint(then || "?");
|
|
1904
|
+
const waypoints = [lastWaypoint, nextWaypoint, thenWaypoint];
|
|
1905
|
+
decodeResult.raw.route = { waypoints };
|
|
1489
1906
|
decodeResult.formatted.items.push({
|
|
1490
1907
|
type: "aircraft_route",
|
|
1491
1908
|
code: "ROUTE",
|
|
@@ -1493,53 +1910,6 @@ function addRoute(decodeResult, value) {
|
|
|
1493
1910
|
value: RouteUtils.routeToString(decodeResult.raw.route)
|
|
1494
1911
|
});
|
|
1495
1912
|
}
|
|
1496
|
-
function addProcedure(decodeResult, value, type) {
|
|
1497
|
-
if (decodeResult.raw.procedures === void 0) {
|
|
1498
|
-
decodeResult.raw.procedures = [];
|
|
1499
|
-
}
|
|
1500
|
-
const data = value.split(".");
|
|
1501
|
-
let waypoints;
|
|
1502
|
-
if (data.length > 1) {
|
|
1503
|
-
waypoints = data.slice(1).map((leg) => RouteUtils.getWaypoint(leg));
|
|
1504
|
-
}
|
|
1505
|
-
const route = { name: data[0], waypoints };
|
|
1506
|
-
decodeResult.raw.procedures.push({ type, route });
|
|
1507
|
-
const procedureName = type.substring(0, 1).toUpperCase() + type.slice(1);
|
|
1508
|
-
let procedureValue = route.name;
|
|
1509
|
-
decodeResult.formatted.items.push({
|
|
1510
|
-
type: `procedure`,
|
|
1511
|
-
code: "proc",
|
|
1512
|
-
label: `${procedureName} Procedure`,
|
|
1513
|
-
value: RouteUtils.routeToString(route)
|
|
1514
|
-
});
|
|
1515
|
-
}
|
|
1516
|
-
function addCompanyRoute(decodeResult, value) {
|
|
1517
|
-
const segments = value.split(".");
|
|
1518
|
-
const parens_idx = segments[0].indexOf("(");
|
|
1519
|
-
let name;
|
|
1520
|
-
let runway;
|
|
1521
|
-
if (parens_idx === -1) {
|
|
1522
|
-
name = segments[0];
|
|
1523
|
-
} else {
|
|
1524
|
-
name = segments[0].slice(0, parens_idx);
|
|
1525
|
-
runway = segments[0].slice(parens_idx + 1, segments[0].indexOf(")"));
|
|
1526
|
-
}
|
|
1527
|
-
let waypoints;
|
|
1528
|
-
if (segments.length > 1) {
|
|
1529
|
-
waypoints = segments.slice(1).map((leg) => RouteUtils.getWaypoint(leg));
|
|
1530
|
-
}
|
|
1531
|
-
decodeResult.raw.company_route = {
|
|
1532
|
-
name,
|
|
1533
|
-
runway,
|
|
1534
|
-
waypoints
|
|
1535
|
-
};
|
|
1536
|
-
decodeResult.formatted.items.push({
|
|
1537
|
-
type: "company_route",
|
|
1538
|
-
code: "CR",
|
|
1539
|
-
label: "Company Route",
|
|
1540
|
-
value: RouteUtils.routeToString(decodeResult.raw.company_route)
|
|
1541
|
-
});
|
|
1542
|
-
}
|
|
1543
1913
|
|
|
1544
1914
|
// lib/plugins/Label_H1_FPN.ts
|
|
1545
1915
|
var Label_H1_FPN = class extends DecoderPlugin {
|
|
@@ -1555,15 +1925,12 @@ var Label_H1_FPN = class extends DecoderPlugin {
|
|
|
1555
1925
|
decodeResult.decoder.name = this.name;
|
|
1556
1926
|
decodeResult.formatted.description = "Flight Plan";
|
|
1557
1927
|
decodeResult.message = message;
|
|
1928
|
+
decodeResult.remaining.text = "";
|
|
1558
1929
|
const msg = message.text.replace(/\n|\r/g, "");
|
|
1559
|
-
const
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
addChecksum(decodeResult, checksum);
|
|
1564
|
-
decodeResult.decoded = true;
|
|
1565
|
-
decodeResult.decoder.decodeLevel = fulllyDecoded ? "full" : "partial";
|
|
1566
|
-
} else {
|
|
1930
|
+
const fulllyDecoded = H1Helper.decodeH1Message(decodeResult, msg);
|
|
1931
|
+
decodeResult.decoded = true;
|
|
1932
|
+
decodeResult.decoder.decodeLevel = fulllyDecoded ? "full" : "partial";
|
|
1933
|
+
if (decodeResult.formatted.items.length === 0) {
|
|
1567
1934
|
if (options?.debug) {
|
|
1568
1935
|
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
1569
1936
|
}
|
|
@@ -1574,15 +1941,6 @@ var Label_H1_FPN = class extends DecoderPlugin {
|
|
|
1574
1941
|
return decodeResult;
|
|
1575
1942
|
}
|
|
1576
1943
|
};
|
|
1577
|
-
function addChecksum(decodeResult, value) {
|
|
1578
|
-
decodeResult.raw.checksum = Number("0x" + value);
|
|
1579
|
-
decodeResult.formatted.items.push({
|
|
1580
|
-
type: "message_checksum",
|
|
1581
|
-
code: "CHECKSUM",
|
|
1582
|
-
label: "Message Checksum",
|
|
1583
|
-
value: "0x" + ("0000" + decodeResult.raw.checksum.toString(16)).slice(-4)
|
|
1584
|
-
});
|
|
1585
|
-
}
|
|
1586
1944
|
|
|
1587
1945
|
// lib/plugins/Label_H1_OHMA.ts
|
|
1588
1946
|
var zlib = __toESM(require("minizlib"));
|
|
@@ -1608,13 +1966,18 @@ var Label_H1_OHMA = class extends DecoderPlugin {
|
|
|
1608
1966
|
decompress.flush(zlib.constants.Z_SYNC_FLUSH);
|
|
1609
1967
|
const result = decompress.read();
|
|
1610
1968
|
const jsonText = result.toString();
|
|
1611
|
-
const json = JSON.parse(jsonText);
|
|
1612
1969
|
let formattedMsg;
|
|
1613
|
-
|
|
1614
|
-
|
|
1970
|
+
let jsonMessage;
|
|
1971
|
+
try {
|
|
1972
|
+
jsonMessage = JSON.parse(jsonText).message;
|
|
1973
|
+
} catch {
|
|
1974
|
+
jsonMessage = jsonText;
|
|
1975
|
+
}
|
|
1976
|
+
try {
|
|
1977
|
+
const ohmaMsg = JSON.parse(jsonMessage);
|
|
1615
1978
|
formattedMsg = JSON.stringify(ohmaMsg, null, 2);
|
|
1616
|
-
}
|
|
1617
|
-
formattedMsg =
|
|
1979
|
+
} catch {
|
|
1980
|
+
formattedMsg = jsonMessage;
|
|
1618
1981
|
}
|
|
1619
1982
|
decodeResult.decoded = true;
|
|
1620
1983
|
decodeResult.decoder.decodeLevel = "full";
|
|
@@ -1653,225 +2016,20 @@ var Label_H1_POS = class extends DecoderPlugin {
|
|
|
1653
2016
|
decodeResult.formatted.description = "Position Report";
|
|
1654
2017
|
decodeResult.message = message;
|
|
1655
2018
|
decodeResult.remaining.text = "";
|
|
1656
|
-
const
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
if (decoded) {
|
|
1662
|
-
processChecksum(decodeResult, checksum);
|
|
1663
|
-
decodeResult.decoded = true;
|
|
1664
|
-
decodeResult.decoder.decodeLevel = "full";
|
|
1665
|
-
} else if (decodeResult.remaining.text.length > 0) {
|
|
1666
|
-
processChecksum(decodeResult, checksum);
|
|
1667
|
-
decodeResult.decoded = true;
|
|
1668
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
1669
|
-
} else {
|
|
1670
|
-
decodeResult.decoded = false;
|
|
1671
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
1672
|
-
}
|
|
1673
|
-
} else if (parts.length === 10) {
|
|
1674
|
-
processAlt(decodeResult, parts[3]);
|
|
1675
|
-
processRoute(decodeResult, parts[1], parts[2], parts[4], parts[5], parts[6]);
|
|
1676
|
-
processTemp(decodeResult, parts[7]);
|
|
1677
|
-
processUnknown(decodeResult, parts[8]);
|
|
1678
|
-
processUnknown(decodeResult, parts[9]);
|
|
1679
|
-
processChecksum(decodeResult, checksum);
|
|
1680
|
-
decodeResult.decoded = true;
|
|
1681
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
1682
|
-
} else if (parts.length === 11) {
|
|
1683
|
-
processAlt(decodeResult, parts[3]);
|
|
1684
|
-
processRoute(decodeResult, parts[1], parts[2], parts[4], parts[5], parts[6], parts[10]);
|
|
1685
|
-
processTemp(decodeResult, parts[7]);
|
|
1686
|
-
processUnknown(decodeResult, parts[8]);
|
|
1687
|
-
processUnknown(decodeResult, parts[9]);
|
|
1688
|
-
processChecksum(decodeResult, checksum);
|
|
1689
|
-
decodeResult.decoded = true;
|
|
1690
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
1691
|
-
} else if (parts.length === 12) {
|
|
1692
|
-
const date = parts[11].substring(2, 4) + parts[11].substring(0, 2) + parts[11].substring(4, 6);
|
|
1693
|
-
processUnknown(decodeResult, parts[3]);
|
|
1694
|
-
processRoute(decodeResult, parts[1], parts[2], parts[4], parts[5], parts[6], date);
|
|
1695
|
-
processTemp(decodeResult, parts[7]);
|
|
1696
|
-
processUnknown(decodeResult, parts[8]);
|
|
1697
|
-
processUnknown(decodeResult, parts[9]);
|
|
1698
|
-
processUnknown(decodeResult, parts[10]);
|
|
1699
|
-
processChecksum(decodeResult, checksum);
|
|
1700
|
-
decodeResult.decoded = true;
|
|
1701
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
1702
|
-
} else if (parts.length === 14) {
|
|
1703
|
-
processAlt(decodeResult, parts[3]);
|
|
1704
|
-
processRoute(decodeResult, parts[1], parts[2], parts[4], parts[5], parts[6]);
|
|
1705
|
-
processTemp(decodeResult, parts[7]);
|
|
1706
|
-
processUnknown(decodeResult, parts[8]);
|
|
1707
|
-
processUnknown(decodeResult, parts[9]);
|
|
1708
|
-
processGndspd(decodeResult, parts[10]);
|
|
1709
|
-
processUnknown(decodeResult, parts[11]);
|
|
1710
|
-
processUnknown(decodeResult, parts[12]);
|
|
1711
|
-
processUnknown(decodeResult, parts[13]);
|
|
1712
|
-
processChecksum(decodeResult, checksum);
|
|
1713
|
-
decodeResult.decoded = true;
|
|
1714
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
1715
|
-
} else if (parts.length === 15) {
|
|
1716
|
-
decodeResult.raw.flight_number = parts[1];
|
|
1717
|
-
let date = void 0;
|
|
1718
|
-
if (parts[2].startsWith("/DC")) {
|
|
1719
|
-
date = parts[2].substring(3);
|
|
1720
|
-
} else {
|
|
1721
|
-
processUnknown(decodeResult, parts[2]);
|
|
1722
|
-
}
|
|
1723
|
-
processUnknown(decodeResult, parts[3]);
|
|
1724
|
-
const fields = parts[4].split("/");
|
|
1725
|
-
for (let i = 0; i < fields.length; ++i) {
|
|
1726
|
-
const field = fields[i];
|
|
1727
|
-
if (field.startsWith("PS")) {
|
|
1728
|
-
processPosition2(decodeResult, field.substring(2));
|
|
1729
|
-
} else {
|
|
1730
|
-
if (i === 0) {
|
|
1731
|
-
processUnknown(decodeResult, field);
|
|
1732
|
-
} else {
|
|
1733
|
-
processUnknown(decodeResult, "/" + field);
|
|
1734
|
-
}
|
|
1735
|
-
}
|
|
1736
|
-
}
|
|
1737
|
-
processRoute(decodeResult, parts[7], parts[5], parts[9], parts[8], void 0, date);
|
|
1738
|
-
processAlt(decodeResult, parts[6]);
|
|
1739
|
-
processTemp(decodeResult, parts[10]);
|
|
1740
|
-
processUnknown(decodeResult, parts[11]);
|
|
1741
|
-
processUnknown(decodeResult, parts[12]);
|
|
1742
|
-
processUnknown(decodeResult, parts[13]);
|
|
1743
|
-
processUnknown(decodeResult, parts[14]);
|
|
1744
|
-
processChecksum(decodeResult, checksum);
|
|
1745
|
-
decodeResult.decoded = true;
|
|
1746
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
1747
|
-
} else if (parts.length === 21) {
|
|
1748
|
-
processRunway(decodeResult, parts[1]);
|
|
1749
|
-
processUnknown(decodeResult, parts.slice(2, 11).join(","));
|
|
1750
|
-
processTemp(decodeResult, parts[11]);
|
|
1751
|
-
processUnknown(decodeResult, parts.slice(12, 20).join(","));
|
|
1752
|
-
FlightPlanUtils.processFlightPlan(decodeResult, parts[20].split(":"));
|
|
1753
|
-
processChecksum(decodeResult, checksum);
|
|
1754
|
-
decodeResult.decoded = true;
|
|
1755
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
1756
|
-
} else if (parts.length === 32) {
|
|
1757
|
-
processRunway(decodeResult, parts[1]);
|
|
1758
|
-
const time = parts[2];
|
|
1759
|
-
processUnknown(decodeResult, parts[3]);
|
|
1760
|
-
const past = parts[4];
|
|
1761
|
-
processUnknown(decodeResult, parts[5]);
|
|
1762
|
-
const eta = parts[6];
|
|
1763
|
-
const next = parts[7];
|
|
1764
|
-
processUnknown(decodeResult, parts.slice(8, 14).join(","));
|
|
1765
|
-
processUnknown(decodeResult, parts[16]);
|
|
1766
|
-
processUnknown(decodeResult, parts[17]);
|
|
1767
|
-
processUnknown(decodeResult, parts[18]);
|
|
1768
|
-
processGndspd(decodeResult, parts[19]);
|
|
1769
|
-
processUnknown(decodeResult, parts[20]);
|
|
1770
|
-
processUnknown(decodeResult, parts[21]);
|
|
1771
|
-
processAlt(decodeResult, parts[22]);
|
|
1772
|
-
processUnknown(decodeResult, parts.slice(23, 31).join(","));
|
|
1773
|
-
const allProcessed = FlightPlanUtils.processFlightPlan(decodeResult, (parts[31] + checksum).split(":"));
|
|
1774
|
-
processRoute(decodeResult, past, time, next, eta);
|
|
1775
|
-
decodeResult.decoded = true;
|
|
1776
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
1777
|
-
} else {
|
|
1778
|
-
if (options.debug) {
|
|
2019
|
+
const fulllyDecoded = H1Helper.decodeH1Message(decodeResult, message.text);
|
|
2020
|
+
decodeResult.decoded = true;
|
|
2021
|
+
decodeResult.decoder.decodeLevel = fulllyDecoded ? "full" : "partial";
|
|
2022
|
+
if (decodeResult.formatted.items.length === 0) {
|
|
2023
|
+
if (options?.debug) {
|
|
1779
2024
|
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
1780
2025
|
}
|
|
1781
|
-
decodeResult.remaining.text
|
|
2026
|
+
decodeResult.remaining.text = message.text;
|
|
1782
2027
|
decodeResult.decoded = false;
|
|
1783
2028
|
decodeResult.decoder.decodeLevel = "none";
|
|
1784
2029
|
}
|
|
1785
2030
|
return decodeResult;
|
|
1786
2031
|
}
|
|
1787
2032
|
};
|
|
1788
|
-
function processUnknown(decodeResult, value) {
|
|
1789
|
-
decodeResult.remaining.text += "," + value;
|
|
1790
|
-
}
|
|
1791
|
-
function processPosition2(decodeResult, value) {
|
|
1792
|
-
const position = CoordinateUtils.decodeStringCoordinates(value);
|
|
1793
|
-
if (position) {
|
|
1794
|
-
decodeResult.raw.position = position;
|
|
1795
|
-
decodeResult.formatted.items.push({
|
|
1796
|
-
type: "aircraft_position",
|
|
1797
|
-
code: "POS",
|
|
1798
|
-
label: "Aircraft Position",
|
|
1799
|
-
value: CoordinateUtils.coordinateString(position)
|
|
1800
|
-
});
|
|
1801
|
-
}
|
|
1802
|
-
}
|
|
1803
|
-
function processAlt(decodeResult, value) {
|
|
1804
|
-
decodeResult.raw.altitude = Number(value) * 100;
|
|
1805
|
-
decodeResult.formatted.items.push({
|
|
1806
|
-
type: "altitude",
|
|
1807
|
-
code: "ALT",
|
|
1808
|
-
label: "Altitude",
|
|
1809
|
-
value: `${decodeResult.raw.altitude} feet`
|
|
1810
|
-
});
|
|
1811
|
-
}
|
|
1812
|
-
function processTemp(decodeResult, value) {
|
|
1813
|
-
decodeResult.raw.outside_air_temperature = Number(value.substring(1)) * (value.charAt(0) === "M" ? -1 : 1);
|
|
1814
|
-
decodeResult.formatted.items.push({
|
|
1815
|
-
type: "outside_air_temperature",
|
|
1816
|
-
code: "OATEMP",
|
|
1817
|
-
label: "Outside Air Temperature (C)",
|
|
1818
|
-
value: `${decodeResult.raw.outside_air_temperature}`
|
|
1819
|
-
});
|
|
1820
|
-
}
|
|
1821
|
-
function processRunway(decodeResult, value) {
|
|
1822
|
-
decodeResult.raw.arrival_runway = value.replace("RW", "");
|
|
1823
|
-
decodeResult.formatted.items.push({
|
|
1824
|
-
type: "runway",
|
|
1825
|
-
label: "Arrival Runway",
|
|
1826
|
-
value: decodeResult.raw.arrival_runway
|
|
1827
|
-
});
|
|
1828
|
-
}
|
|
1829
|
-
function processGndspd(decodeResult, value) {
|
|
1830
|
-
decodeResult.raw.groundspeed = Number(value);
|
|
1831
|
-
decodeResult.formatted.items.push({
|
|
1832
|
-
type: "aircraft_groundspeed",
|
|
1833
|
-
code: "GSPD",
|
|
1834
|
-
label: "Aircraft Groundspeed",
|
|
1835
|
-
value: `${decodeResult.raw.groundspeed}`
|
|
1836
|
-
});
|
|
1837
|
-
}
|
|
1838
|
-
function processRoute(decodeResult, last, time, next, eta, then, date) {
|
|
1839
|
-
const lastTime = date ? DateTimeUtils.convertDateTimeToEpoch(time, date) : DateTimeUtils.convertHHMMSSToTod(time);
|
|
1840
|
-
const nextTime = date ? DateTimeUtils.convertDateTimeToEpoch(eta, date) : DateTimeUtils.convertHHMMSSToTod(eta);
|
|
1841
|
-
const timeFormat = date ? "epoch" : "tod";
|
|
1842
|
-
const lastWaypoint = RouteUtils.getWaypoint(last);
|
|
1843
|
-
lastWaypoint.time = lastTime;
|
|
1844
|
-
lastWaypoint.timeFormat = timeFormat;
|
|
1845
|
-
const nextWaypoint = RouteUtils.getWaypoint(next);
|
|
1846
|
-
nextWaypoint.time = nextTime;
|
|
1847
|
-
nextWaypoint.timeFormat = timeFormat;
|
|
1848
|
-
const thenWaypoint = RouteUtils.getWaypoint(then || "?");
|
|
1849
|
-
const waypoints = [lastWaypoint, nextWaypoint, thenWaypoint];
|
|
1850
|
-
decodeResult.raw.route = { waypoints };
|
|
1851
|
-
decodeResult.formatted.items.push({
|
|
1852
|
-
type: "aircraft_route",
|
|
1853
|
-
code: "ROUTE",
|
|
1854
|
-
label: "Aircraft Route",
|
|
1855
|
-
value: RouteUtils.routeToString(decodeResult.raw.route)
|
|
1856
|
-
});
|
|
1857
|
-
}
|
|
1858
|
-
function processChecksum(decodeResult, value) {
|
|
1859
|
-
decodeResult.raw.checksum = Number("0x" + value);
|
|
1860
|
-
decodeResult.formatted.items.push({
|
|
1861
|
-
type: "message_checksum",
|
|
1862
|
-
code: "CHECKSUM",
|
|
1863
|
-
label: "Message Checksum",
|
|
1864
|
-
value: "0x" + ("0000" + decodeResult.raw.checksum.toString(16)).slice(-4)
|
|
1865
|
-
});
|
|
1866
|
-
}
|
|
1867
|
-
function findHeader(text) {
|
|
1868
|
-
const parts = text.split(",");
|
|
1869
|
-
const header = parts[0];
|
|
1870
|
-
if (header.indexOf("/TS") === -1) {
|
|
1871
|
-
return header;
|
|
1872
|
-
}
|
|
1873
|
-
return parts[0] + "," + parts[1];
|
|
1874
|
-
}
|
|
1875
2033
|
|
|
1876
2034
|
// lib/plugins/Label_H1_WRN.ts
|
|
1877
2035
|
var Label_H1_WRN = class extends DecoderPlugin {
|
|
@@ -1894,16 +2052,16 @@ var Label_H1_WRN = class extends DecoderPlugin {
|
|
|
1894
2052
|
for (let i = 1; i < fields.length; i++) {
|
|
1895
2053
|
const field = fields[i];
|
|
1896
2054
|
if (field.startsWith("PN")) {
|
|
1897
|
-
|
|
2055
|
+
processUnknown(decodeResult, "/" + field);
|
|
1898
2056
|
} else {
|
|
1899
|
-
|
|
2057
|
+
processUnknown(decodeResult, "/" + field);
|
|
1900
2058
|
}
|
|
1901
2059
|
}
|
|
1902
2060
|
const data = parts[1].substring(0, 20);
|
|
1903
2061
|
const msg = parts[1].substring(20);
|
|
1904
2062
|
const datetime = data.substring(0, 12);
|
|
1905
2063
|
const date = datetime.substring(4, 6) + datetime.substring(2, 4) + datetime.substring(0, 2);
|
|
1906
|
-
|
|
2064
|
+
processUnknown(decodeResult, data.substring(12));
|
|
1907
2065
|
decodeResult.raw.message_timestamp = DateTimeUtils.convertDateTimeToEpoch(datetime.substring(6), date);
|
|
1908
2066
|
decodeResult.raw.warning_message = msg;
|
|
1909
2067
|
decodeResult.formatted.items.push({
|
|
@@ -1925,7 +2083,7 @@ var Label_H1_WRN = class extends DecoderPlugin {
|
|
|
1925
2083
|
return decodeResult;
|
|
1926
2084
|
}
|
|
1927
2085
|
};
|
|
1928
|
-
function
|
|
2086
|
+
function processUnknown(decodeResult, value) {
|
|
1929
2087
|
decodeResult.remaining.text += value;
|
|
1930
2088
|
}
|
|
1931
2089
|
|
|
@@ -3026,6 +3184,7 @@ var MessageDecoder = class {
|
|
|
3026
3184
|
this.registerPlugin(new Label_15_FST(this));
|
|
3027
3185
|
this.registerPlugin(new Label_16_N_Space(this));
|
|
3028
3186
|
this.registerPlugin(new Label_20_POS(this));
|
|
3187
|
+
this.registerPlugin(new Label_21_POS(this));
|
|
3029
3188
|
this.registerPlugin(new Label_30_Slash_EA(this));
|
|
3030
3189
|
this.registerPlugin(new Label_44_ETA(this));
|
|
3031
3190
|
this.registerPlugin(new Label_44_IN(this));
|