@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.mjs
CHANGED
|
@@ -171,6 +171,12 @@ var Label_5Z = class extends DecoderPlugin {
|
|
|
171
171
|
|
|
172
172
|
// lib/utils/coordinate_utils.ts
|
|
173
173
|
var CoordinateUtils = class {
|
|
174
|
+
/**
|
|
175
|
+
* Decode a string of coordinates into an object with latitude and longitude in millidegrees
|
|
176
|
+
* @param stringCoords - The string of coordinates to decode
|
|
177
|
+
*
|
|
178
|
+
* @returns An object with latitude and longitude properties
|
|
179
|
+
*/
|
|
174
180
|
static decodeStringCoordinates(stringCoords) {
|
|
175
181
|
var results = {};
|
|
176
182
|
const firstChar = stringCoords.substring(0, 1);
|
|
@@ -188,6 +194,33 @@ var CoordinateUtils = class {
|
|
|
188
194
|
}
|
|
189
195
|
return results;
|
|
190
196
|
}
|
|
197
|
+
/**
|
|
198
|
+
* Decode a string of coordinates into an object with latitude and longitude in degrees and decimal minutes
|
|
199
|
+
* @param stringCoords - The string of coordinates to decode
|
|
200
|
+
*
|
|
201
|
+
* @returns An object with latitude and longitude properties
|
|
202
|
+
*/
|
|
203
|
+
static decodeStringCoordinatesDecimalMinutes(stringCoords) {
|
|
204
|
+
var results = {};
|
|
205
|
+
const firstChar = stringCoords.substring(0, 1);
|
|
206
|
+
let middleChar = stringCoords.substring(6, 7);
|
|
207
|
+
let longitudeChars = stringCoords.substring(7, 13);
|
|
208
|
+
if (middleChar == " ") {
|
|
209
|
+
middleChar = stringCoords.substring(7, 8);
|
|
210
|
+
longitudeChars = stringCoords.substring(8, 14);
|
|
211
|
+
}
|
|
212
|
+
const latDeg = Math.trunc(Number(stringCoords.substring(1, 6)) / 1e3);
|
|
213
|
+
const latMin = Number(stringCoords.substring(1, 6)) % 1e3 / 10;
|
|
214
|
+
const lonDeg = Math.trunc(Number(longitudeChars) / 1e3);
|
|
215
|
+
const lonMin = Number(longitudeChars) % 1e3 / 10;
|
|
216
|
+
if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
|
|
217
|
+
results.latitude = (latDeg + latMin / 60) * (firstChar === "S" ? -1 : 1);
|
|
218
|
+
results.longitude = (lonDeg + lonMin / 60) * (middleChar === "W" ? -1 : 1);
|
|
219
|
+
} else {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
return results;
|
|
223
|
+
}
|
|
191
224
|
static coordinateString(coords) {
|
|
192
225
|
const latDir = coords.latitude > 0 ? "N" : "S";
|
|
193
226
|
const lonDir = coords.longitude > 0 ? "E" : "W";
|
|
@@ -558,6 +591,96 @@ var Label_20_POS = class extends DecoderPlugin {
|
|
|
558
591
|
}
|
|
559
592
|
};
|
|
560
593
|
|
|
594
|
+
// lib/plugins/Label_21_POS.ts
|
|
595
|
+
var Label_21_POS = class extends DecoderPlugin {
|
|
596
|
+
name = "label-21-pos";
|
|
597
|
+
qualifiers() {
|
|
598
|
+
return {
|
|
599
|
+
labels: ["21"],
|
|
600
|
+
preambles: ["POS"]
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
decode(message, options = {}) {
|
|
604
|
+
const decodeResult = this.defaultResult();
|
|
605
|
+
decodeResult.decoder.name = this.name;
|
|
606
|
+
decodeResult.formatted.description = "Position Report";
|
|
607
|
+
decodeResult.message = message;
|
|
608
|
+
decodeResult.raw.preamble = message.text.substring(0, 3);
|
|
609
|
+
const content = message.text.substring(3);
|
|
610
|
+
console.log("Content: " + content);
|
|
611
|
+
const fields = content.split(",");
|
|
612
|
+
console.log("Field Count: " + fields.length);
|
|
613
|
+
if (fields.length == 9) {
|
|
614
|
+
processPosition(decodeResult, fields[0].trim());
|
|
615
|
+
processAlt(decodeResult, fields[3]);
|
|
616
|
+
processTemp(decodeResult, fields[6]);
|
|
617
|
+
processArrvApt(decodeResult, fields[8]);
|
|
618
|
+
decodeResult.raw.remaining = [
|
|
619
|
+
fields[1],
|
|
620
|
+
fields[2],
|
|
621
|
+
fields[4],
|
|
622
|
+
fields[5],
|
|
623
|
+
fields[7]
|
|
624
|
+
].join(",");
|
|
625
|
+
decodeResult.decoded = true;
|
|
626
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
627
|
+
} else {
|
|
628
|
+
console.log(`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${content}`);
|
|
629
|
+
decodeResult.decoded = false;
|
|
630
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
631
|
+
}
|
|
632
|
+
return decodeResult;
|
|
633
|
+
}
|
|
634
|
+
};
|
|
635
|
+
function processPosition(decodeResult, value) {
|
|
636
|
+
if (value.length !== 16 && value[0] !== "N" && value[0] !== "S" && value[8] !== "W" && value[8] !== "E") {
|
|
637
|
+
return false;
|
|
638
|
+
}
|
|
639
|
+
const latDir = value[0] === "N" ? 1 : -1;
|
|
640
|
+
const lonDir = value[8] === "E" ? 1 : -1;
|
|
641
|
+
const position = {
|
|
642
|
+
latitude: latDir * Number(value.substring(1, 7)),
|
|
643
|
+
longitude: lonDir * Number(value.substring(9, 15))
|
|
644
|
+
};
|
|
645
|
+
if (position) {
|
|
646
|
+
decodeResult.raw.position = position;
|
|
647
|
+
decodeResult.formatted.items.push({
|
|
648
|
+
type: "aircraft_position",
|
|
649
|
+
code: "POS",
|
|
650
|
+
label: "Aircraft Position",
|
|
651
|
+
value: CoordinateUtils.coordinateString(position)
|
|
652
|
+
});
|
|
653
|
+
}
|
|
654
|
+
return !!position;
|
|
655
|
+
}
|
|
656
|
+
function processAlt(decodeResult, value) {
|
|
657
|
+
decodeResult.raw.altitude = Number(value);
|
|
658
|
+
decodeResult.formatted.items.push({
|
|
659
|
+
type: "altitude",
|
|
660
|
+
code: "ALT",
|
|
661
|
+
label: "Altitude",
|
|
662
|
+
value: `${decodeResult.raw.altitude} feet`
|
|
663
|
+
});
|
|
664
|
+
}
|
|
665
|
+
function processTemp(decodeResult, value) {
|
|
666
|
+
decodeResult.raw.outside_air_temperature = Number(value.substring(1)) * (value.charAt(0) === "M" ? -1 : 1);
|
|
667
|
+
decodeResult.formatted.items.push({
|
|
668
|
+
type: "outside_air_temperature",
|
|
669
|
+
code: "OATEMP",
|
|
670
|
+
label: "Outside Air Temperature (C)",
|
|
671
|
+
value: `${decodeResult.raw.outside_air_temperature}`
|
|
672
|
+
});
|
|
673
|
+
}
|
|
674
|
+
function processArrvApt(decodeResult, value) {
|
|
675
|
+
decodeResult.raw.arrival_icao = value;
|
|
676
|
+
decodeResult.formatted.items.push({
|
|
677
|
+
type: "destination",
|
|
678
|
+
code: "DST",
|
|
679
|
+
label: "Destination",
|
|
680
|
+
value: decodeResult.raw.arrival_icao
|
|
681
|
+
});
|
|
682
|
+
}
|
|
683
|
+
|
|
561
684
|
// lib/plugins/Label_30_Slash_EA.ts
|
|
562
685
|
var Label_30_Slash_EA = class extends DecoderPlugin {
|
|
563
686
|
name = "label-30-slash-ea";
|
|
@@ -855,7 +978,7 @@ var Label_44_POS = class extends DecoderPlugin {
|
|
|
855
978
|
console.log(`Label 44 Position Report: groups`);
|
|
856
979
|
console.log(results.groups);
|
|
857
980
|
}
|
|
858
|
-
decodeResult.raw.position = CoordinateUtils.
|
|
981
|
+
decodeResult.raw.position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(results.groups.unsplit_coords);
|
|
859
982
|
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);
|
|
860
983
|
decodeResult.raw.departure_icao = results.groups.departure_icao;
|
|
861
984
|
decodeResult.raw.arrival_icao = results.groups.arrival_icao;
|
|
@@ -870,9 +993,9 @@ var Label_44_POS = class extends DecoderPlugin {
|
|
|
870
993
|
}
|
|
871
994
|
if (decodeResult.raw.position) {
|
|
872
995
|
decodeResult.formatted.items.push({
|
|
873
|
-
type: "
|
|
996
|
+
type: "aircraft_position",
|
|
874
997
|
code: "POS",
|
|
875
|
-
label: "Position",
|
|
998
|
+
label: "Aircraft Position",
|
|
876
999
|
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
877
1000
|
});
|
|
878
1001
|
}
|
|
@@ -1180,6 +1303,112 @@ var Label_ColonComma = class extends DecoderPlugin {
|
|
|
1180
1303
|
}
|
|
1181
1304
|
};
|
|
1182
1305
|
|
|
1306
|
+
// lib/utils/result_formatter.ts
|
|
1307
|
+
var ResultFormatter = class {
|
|
1308
|
+
static altitude(decodeResult, value) {
|
|
1309
|
+
decodeResult.raw.altitude = value;
|
|
1310
|
+
decodeResult.formatted.items.push({
|
|
1311
|
+
type: "altitude",
|
|
1312
|
+
code: "ALT",
|
|
1313
|
+
label: "Altitude",
|
|
1314
|
+
value: `${decodeResult.raw.altitude} feet`
|
|
1315
|
+
});
|
|
1316
|
+
}
|
|
1317
|
+
static flightNumber(decodeResult, value) {
|
|
1318
|
+
decodeResult.raw.flight_number = value;
|
|
1319
|
+
}
|
|
1320
|
+
static departureAirport(decodeResult, value) {
|
|
1321
|
+
decodeResult.raw.departure_icao = value;
|
|
1322
|
+
decodeResult.formatted.items.push({
|
|
1323
|
+
type: "origin",
|
|
1324
|
+
code: "ORG",
|
|
1325
|
+
label: "Origin",
|
|
1326
|
+
value: decodeResult.raw.departure_icao
|
|
1327
|
+
});
|
|
1328
|
+
}
|
|
1329
|
+
static departureRunway(decodeResult, value) {
|
|
1330
|
+
decodeResult.raw.departure_runway = value;
|
|
1331
|
+
decodeResult.formatted.items.push({
|
|
1332
|
+
type: "runway",
|
|
1333
|
+
code: "DEPRWY",
|
|
1334
|
+
label: "Departure Runway",
|
|
1335
|
+
value: decodeResult.raw.departure_runway
|
|
1336
|
+
});
|
|
1337
|
+
}
|
|
1338
|
+
static arrivalAirport(decodeResult, value) {
|
|
1339
|
+
decodeResult.raw.arrival_icao = value;
|
|
1340
|
+
decodeResult.formatted.items.push({
|
|
1341
|
+
type: "destination",
|
|
1342
|
+
code: "DST",
|
|
1343
|
+
label: "Destination",
|
|
1344
|
+
value: decodeResult.raw.arrival_icao
|
|
1345
|
+
});
|
|
1346
|
+
}
|
|
1347
|
+
static eta(decodeResult, value) {
|
|
1348
|
+
decodeResult.formatted.items.push({
|
|
1349
|
+
type: "eta",
|
|
1350
|
+
code: "ETA",
|
|
1351
|
+
label: "Estimated Time of Arrival",
|
|
1352
|
+
value: value.substring(0, 2) + ":" + value.substring(2, 4) + ":" + value.substring(4, 6)
|
|
1353
|
+
});
|
|
1354
|
+
}
|
|
1355
|
+
static arrivalRunway(decodeResult, value) {
|
|
1356
|
+
decodeResult.raw.arrival_runway = value;
|
|
1357
|
+
decodeResult.formatted.items.push({
|
|
1358
|
+
type: "runway",
|
|
1359
|
+
label: "Arrival Runway",
|
|
1360
|
+
value: decodeResult.raw.arrival_runway
|
|
1361
|
+
});
|
|
1362
|
+
}
|
|
1363
|
+
static currentFuel(decodeResult, value) {
|
|
1364
|
+
decodeResult.raw.fuel_on_board = value;
|
|
1365
|
+
decodeResult.formatted.items.push({
|
|
1366
|
+
type: "fuel_on_board",
|
|
1367
|
+
code: "FOB",
|
|
1368
|
+
label: "Fuel On Board",
|
|
1369
|
+
value: decodeResult.raw.fuel_on_board.toString()
|
|
1370
|
+
});
|
|
1371
|
+
}
|
|
1372
|
+
static remainingFuel(decodeResult, value) {
|
|
1373
|
+
decodeResult.raw.fuel_remaining = value;
|
|
1374
|
+
decodeResult.formatted.items.push({
|
|
1375
|
+
type: "fuel_remaining",
|
|
1376
|
+
label: "Fuel Remaining",
|
|
1377
|
+
value: decodeResult.raw.fuel_remaining.toString()
|
|
1378
|
+
});
|
|
1379
|
+
}
|
|
1380
|
+
static checksum(decodeResult, value) {
|
|
1381
|
+
decodeResult.raw.checksum = Number("0x" + value);
|
|
1382
|
+
decodeResult.formatted.items.push({
|
|
1383
|
+
type: "message_checksum",
|
|
1384
|
+
code: "CHECKSUM",
|
|
1385
|
+
label: "Message Checksum",
|
|
1386
|
+
value: "0x" + ("0000" + decodeResult.raw.checksum.toString(16)).slice(-4)
|
|
1387
|
+
});
|
|
1388
|
+
}
|
|
1389
|
+
static groundspeed(decodeResult, value) {
|
|
1390
|
+
decodeResult.raw.groundspeed = value;
|
|
1391
|
+
decodeResult.formatted.items.push({
|
|
1392
|
+
type: "aircraft_groundspeed",
|
|
1393
|
+
code: "GSPD",
|
|
1394
|
+
label: "Aircraft Groundspeed",
|
|
1395
|
+
value: `${decodeResult.raw.groundspeed}`
|
|
1396
|
+
});
|
|
1397
|
+
}
|
|
1398
|
+
static temperature(decodeResult, value) {
|
|
1399
|
+
decodeResult.raw.outside_air_temperature = Number(value.substring(1)) * (value.charAt(0) === "M" ? -1 : 1);
|
|
1400
|
+
decodeResult.formatted.items.push({
|
|
1401
|
+
type: "outside_air_temperature",
|
|
1402
|
+
code: "OATEMP",
|
|
1403
|
+
label: "Outside Air Temperature (C)",
|
|
1404
|
+
value: `${decodeResult.raw.outside_air_temperature}`
|
|
1405
|
+
});
|
|
1406
|
+
}
|
|
1407
|
+
static unknown(decodeResult, value) {
|
|
1408
|
+
decodeResult.remaining.text += "," + value;
|
|
1409
|
+
}
|
|
1410
|
+
};
|
|
1411
|
+
|
|
1183
1412
|
// lib/utils/route_utils.ts
|
|
1184
1413
|
var RouteUtils = class _RouteUtils {
|
|
1185
1414
|
static routeToString(route) {
|
|
@@ -1220,13 +1449,13 @@ var RouteUtils = class _RouteUtils {
|
|
|
1220
1449
|
}
|
|
1221
1450
|
const waypoint = leg.split(",");
|
|
1222
1451
|
if (waypoint.length == 2) {
|
|
1223
|
-
const position = CoordinateUtils.
|
|
1452
|
+
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(waypoint[1]);
|
|
1224
1453
|
if (position) {
|
|
1225
1454
|
return { name: waypoint[0], latitude: position.latitude, longitude: position.longitude };
|
|
1226
1455
|
}
|
|
1227
1456
|
}
|
|
1228
1457
|
if (leg.length == 13 || leg.length == 14) {
|
|
1229
|
-
const position = CoordinateUtils.
|
|
1458
|
+
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(leg);
|
|
1230
1459
|
const name = waypoint.length == 2 ? waypoint[0] : "";
|
|
1231
1460
|
if (position) {
|
|
1232
1461
|
return { name, latitude: position.latitude, longitude: position.longitude };
|
|
@@ -1305,13 +1534,126 @@ var FlightPlanUtils = class _FlightPlanUtils {
|
|
|
1305
1534
|
}
|
|
1306
1535
|
static parseHeader(decodeResult, header) {
|
|
1307
1536
|
let allKnownFields = true;
|
|
1308
|
-
|
|
1537
|
+
if (header.startsWith("RF")) {
|
|
1538
|
+
decodeResult.formatted.items.push({
|
|
1539
|
+
type: "status",
|
|
1540
|
+
code: "ROUTE_STATUS",
|
|
1541
|
+
label: "Route Status",
|
|
1542
|
+
value: "Route Filed"
|
|
1543
|
+
});
|
|
1544
|
+
decodeResult.raw.route_status = "RF";
|
|
1545
|
+
if (header.length > 2) {
|
|
1546
|
+
addRoute(decodeResult, header.substring(2));
|
|
1547
|
+
}
|
|
1548
|
+
} else if (header.startsWith("RP")) {
|
|
1549
|
+
decodeResult.raw.route_status = "RP";
|
|
1550
|
+
decodeResult.formatted.items.push({
|
|
1551
|
+
type: "status",
|
|
1552
|
+
code: "ROUTE_STATUS",
|
|
1553
|
+
label: "Route Status",
|
|
1554
|
+
value: "Route Planned"
|
|
1555
|
+
});
|
|
1556
|
+
decodeResult.raw.route_status = header;
|
|
1557
|
+
} else if (header.startsWith("RI")) {
|
|
1558
|
+
decodeResult.raw.route_status = "RI";
|
|
1559
|
+
decodeResult.formatted.items.push({
|
|
1560
|
+
type: "status",
|
|
1561
|
+
code: "ROUTE_STATUS",
|
|
1562
|
+
label: "Route Status",
|
|
1563
|
+
value: "Route Inactive"
|
|
1564
|
+
});
|
|
1565
|
+
} else {
|
|
1566
|
+
decodeResult.remaining.text += header;
|
|
1567
|
+
allKnownFields = false;
|
|
1568
|
+
}
|
|
1569
|
+
return allKnownFields;
|
|
1570
|
+
}
|
|
1571
|
+
};
|
|
1572
|
+
function addArrivalAirport(decodeResult, value) {
|
|
1573
|
+
ResultFormatter.arrivalAirport(decodeResult, value);
|
|
1574
|
+
}
|
|
1575
|
+
function addDepartureAirport(decodeResult, value) {
|
|
1576
|
+
ResultFormatter.departureAirport(decodeResult, value);
|
|
1577
|
+
}
|
|
1578
|
+
function addRunway(decodeResult, value) {
|
|
1579
|
+
if (value.length === 8) {
|
|
1580
|
+
ResultFormatter.arrivalRunway(decodeResult, value.substring(4, 7));
|
|
1581
|
+
}
|
|
1582
|
+
ResultFormatter.departureRunway(decodeResult, value.substring(0, 3));
|
|
1583
|
+
}
|
|
1584
|
+
function addRoute(decodeResult, value) {
|
|
1585
|
+
const route = value.split(".");
|
|
1586
|
+
decodeResult.raw.route = { waypoints: route.map((leg) => RouteUtils.getWaypoint(leg)) };
|
|
1587
|
+
decodeResult.formatted.items.push({
|
|
1588
|
+
type: "aircraft_route",
|
|
1589
|
+
code: "ROUTE",
|
|
1590
|
+
label: "Aircraft Route",
|
|
1591
|
+
value: RouteUtils.routeToString(decodeResult.raw.route)
|
|
1592
|
+
});
|
|
1593
|
+
}
|
|
1594
|
+
function addProcedure(decodeResult, value, type) {
|
|
1595
|
+
if (decodeResult.raw.procedures === void 0) {
|
|
1596
|
+
decodeResult.raw.procedures = [];
|
|
1597
|
+
}
|
|
1598
|
+
const data = value.split(".");
|
|
1599
|
+
let waypoints;
|
|
1600
|
+
if (data.length > 1) {
|
|
1601
|
+
waypoints = data.slice(1).map((leg) => RouteUtils.getWaypoint(leg));
|
|
1602
|
+
}
|
|
1603
|
+
const route = { name: data[0], waypoints };
|
|
1604
|
+
decodeResult.raw.procedures.push({ type, route });
|
|
1605
|
+
const procedureName = type.substring(0, 1).toUpperCase() + type.slice(1);
|
|
1606
|
+
let procedureValue = route.name;
|
|
1607
|
+
decodeResult.formatted.items.push({
|
|
1608
|
+
type: `procedure`,
|
|
1609
|
+
code: "proc",
|
|
1610
|
+
label: `${procedureName} Procedure`,
|
|
1611
|
+
value: RouteUtils.routeToString(route)
|
|
1612
|
+
});
|
|
1613
|
+
}
|
|
1614
|
+
function addCompanyRoute(decodeResult, value) {
|
|
1615
|
+
const segments = value.split(".");
|
|
1616
|
+
const parens_idx = segments[0].indexOf("(");
|
|
1617
|
+
let name;
|
|
1618
|
+
let runway;
|
|
1619
|
+
if (parens_idx === -1) {
|
|
1620
|
+
name = segments[0];
|
|
1621
|
+
} else {
|
|
1622
|
+
name = segments[0].slice(0, parens_idx);
|
|
1623
|
+
runway = segments[0].slice(parens_idx + 1, segments[0].indexOf(")"));
|
|
1624
|
+
}
|
|
1625
|
+
let waypoints;
|
|
1626
|
+
if (segments.length > 1) {
|
|
1627
|
+
waypoints = segments.slice(1).map((leg) => RouteUtils.getWaypoint(leg));
|
|
1628
|
+
}
|
|
1629
|
+
decodeResult.raw.company_route = {
|
|
1630
|
+
name,
|
|
1631
|
+
runway,
|
|
1632
|
+
waypoints
|
|
1633
|
+
};
|
|
1634
|
+
decodeResult.formatted.items.push({
|
|
1635
|
+
type: "company_route",
|
|
1636
|
+
code: "CR",
|
|
1637
|
+
label: "Company Route",
|
|
1638
|
+
value: RouteUtils.routeToString(decodeResult.raw.company_route)
|
|
1639
|
+
});
|
|
1640
|
+
}
|
|
1641
|
+
|
|
1642
|
+
// lib/utils/h1_helper.ts
|
|
1643
|
+
var H1Helper = class {
|
|
1644
|
+
static decodeH1Message(decodeResult, message) {
|
|
1645
|
+
let allKnownFields = true;
|
|
1646
|
+
const checksum = message.slice(-4);
|
|
1647
|
+
const data = message.slice(0, message.length - 4);
|
|
1648
|
+
const fields = data.split("/");
|
|
1309
1649
|
allKnownFields = allKnownFields && parseMessageType(decodeResult, fields[0]);
|
|
1310
1650
|
for (let i = 1; i < fields.length; ++i) {
|
|
1311
1651
|
if (fields[i].startsWith("FN")) {
|
|
1312
1652
|
decodeResult.raw.flight_number = fields[i].substring(2);
|
|
1313
1653
|
} else if (fields[i].startsWith("SN")) {
|
|
1314
1654
|
decodeResult.raw.serial_number = fields[i].substring(2);
|
|
1655
|
+
} else if (fields[i].startsWith("DC")) {
|
|
1656
|
+
processDC(decodeResult, fields[i].substring(2).split(","));
|
|
1315
1657
|
} else if (fields[i].startsWith("TS")) {
|
|
1316
1658
|
const ts = fields[i].substring(2).split(",");
|
|
1317
1659
|
let time = DateTimeUtils.convertDateTimeToEpoch(ts[0], ts[1]);
|
|
@@ -1319,69 +1661,101 @@ var FlightPlanUtils = class _FlightPlanUtils {
|
|
|
1319
1661
|
const date = ts[1].substring(2, 4) + ts[1].substring(0, 2) + ts[1].substring(4, 6);
|
|
1320
1662
|
time = DateTimeUtils.convertDateTimeToEpoch(ts[0], date);
|
|
1321
1663
|
}
|
|
1664
|
+
decodeResult.raw.message_date = ts[1];
|
|
1322
1665
|
decodeResult.raw.message_timestamp = time;
|
|
1323
1666
|
} else if (fields[i].startsWith("PS")) {
|
|
1324
|
-
const pos = fields[i].substring(2);
|
|
1325
|
-
allKnownFields == allKnownFields &&
|
|
1667
|
+
const pos = processPS(decodeResult, fields[i].substring(2).split(","));
|
|
1668
|
+
allKnownFields == allKnownFields && pos;
|
|
1326
1669
|
} else if (fields[i].startsWith("DT")) {
|
|
1327
|
-
const
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
type: "destination",
|
|
1331
|
-
code: "DST",
|
|
1332
|
-
label: "Destination",
|
|
1333
|
-
value: decodeResult.raw.arrival_icao
|
|
1334
|
-
});
|
|
1670
|
+
const data2 = fields[i].substring(2).split(",");
|
|
1671
|
+
const dt = processDT(decodeResult, data2);
|
|
1672
|
+
allKnownFields = allKnownFields && dt;
|
|
1335
1673
|
} else if (fields[i].startsWith("ID")) {
|
|
1336
|
-
const
|
|
1337
|
-
decodeResult.raw.tail =
|
|
1674
|
+
const data2 = fields[i].substring(2).split(",");
|
|
1675
|
+
decodeResult.raw.tail = data2[0];
|
|
1338
1676
|
decodeResult.formatted.items.push({
|
|
1339
1677
|
type: "tail",
|
|
1678
|
+
code: "TAIL",
|
|
1340
1679
|
label: "Tail",
|
|
1341
1680
|
value: decodeResult.raw.tail
|
|
1342
1681
|
});
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
type: "status",
|
|
1346
|
-
code: "ROUTE_STATUS",
|
|
1347
|
-
label: "Route Status",
|
|
1348
|
-
value: "Route Filed"
|
|
1349
|
-
});
|
|
1350
|
-
decodeResult.raw.route_status = "RF";
|
|
1351
|
-
if (fields[i].length > 2) {
|
|
1352
|
-
addRoute(decodeResult, fields[i].substring(2));
|
|
1682
|
+
if (data2.length > 1) {
|
|
1683
|
+
decodeResult.raw.flight_number = data2[1];
|
|
1353
1684
|
}
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1685
|
+
if (data2.length > 2) {
|
|
1686
|
+
allKnownFields = false;
|
|
1687
|
+
decodeResult.remaining.text += "," + data2.slice(2).join(",");
|
|
1688
|
+
}
|
|
1689
|
+
} else if (fields[i].startsWith("LR")) {
|
|
1690
|
+
const data2 = fields[i].substring(2).split(",");
|
|
1691
|
+
const lr = processLR(decodeResult, data2);
|
|
1692
|
+
allKnownFields = allKnownFields && lr;
|
|
1693
|
+
} else if (fields[i].startsWith("RI") || fields[i].startsWith("RF") || fields[i].startsWith("RP")) {
|
|
1694
|
+
const fp = FlightPlanUtils.processFlightPlan(decodeResult, fields[i].split(":"));
|
|
1695
|
+
allKnownFields = allKnownFields && fp;
|
|
1696
|
+
} else if (fields[i].startsWith("PR")) {
|
|
1697
|
+
allKnownFields = false;
|
|
1698
|
+
decodeResult.remaining.text += "/" + fields[i];
|
|
1699
|
+
} else if (fields[i].startsWith("PS")) {
|
|
1700
|
+
allKnownFields = false;
|
|
1701
|
+
decodeResult.remaining.text += fields[i];
|
|
1371
1702
|
} else {
|
|
1372
1703
|
decodeResult.remaining.text += "/" + fields[i];
|
|
1373
1704
|
allKnownFields = false;
|
|
1374
1705
|
}
|
|
1375
1706
|
}
|
|
1707
|
+
if (decodeResult.formatted.items.length > 0) {
|
|
1708
|
+
ResultFormatter.checksum(decodeResult, checksum);
|
|
1709
|
+
}
|
|
1376
1710
|
return allKnownFields;
|
|
1377
1711
|
}
|
|
1378
1712
|
};
|
|
1713
|
+
function processDT(decodeResult, data) {
|
|
1714
|
+
let allKnownFields = true;
|
|
1715
|
+
if (!decodeResult.raw.arrival_icao) {
|
|
1716
|
+
ResultFormatter.arrivalAirport(decodeResult, data[0]);
|
|
1717
|
+
} else if (decodeResult.raw.arrival_icao != data[0]) {
|
|
1718
|
+
decodeResult.remaining.text += "/" + data;
|
|
1719
|
+
}
|
|
1720
|
+
if (data.length > 1) {
|
|
1721
|
+
ResultFormatter.arrivalRunway(decodeResult, data[1]);
|
|
1722
|
+
}
|
|
1723
|
+
if (data.length > 2) {
|
|
1724
|
+
ResultFormatter.currentFuel(decodeResult, Number(data[2]));
|
|
1725
|
+
}
|
|
1726
|
+
if (data.length > 3) {
|
|
1727
|
+
ResultFormatter.eta(decodeResult, data[3]);
|
|
1728
|
+
}
|
|
1729
|
+
if (data.length > 4) {
|
|
1730
|
+
ResultFormatter.remainingFuel(decodeResult, Number(data[4]));
|
|
1731
|
+
}
|
|
1732
|
+
if (data.length > 5) {
|
|
1733
|
+
allKnownFields = false;
|
|
1734
|
+
decodeResult.remaining.text += "," + data.slice(5).join(",");
|
|
1735
|
+
}
|
|
1736
|
+
return allKnownFields;
|
|
1737
|
+
}
|
|
1738
|
+
function processLR(decodeResult, data) {
|
|
1739
|
+
let allKnownFields = true;
|
|
1740
|
+
if (data.length === 19) {
|
|
1741
|
+
ResultFormatter.unknown(decodeResult, data[1]);
|
|
1742
|
+
ResultFormatter.flightNumber(decodeResult, data[2]);
|
|
1743
|
+
ResultFormatter.departureAirport(decodeResult, data[3]);
|
|
1744
|
+
ResultFormatter.arrivalAirport(decodeResult, data[4]);
|
|
1745
|
+
ResultFormatter.arrivalRunway(decodeResult, data[5]);
|
|
1746
|
+
ResultFormatter.unknown(decodeResult, data.slice(6, 19).join(","));
|
|
1747
|
+
allKnownFields = false;
|
|
1748
|
+
} else {
|
|
1749
|
+
allKnownFields = false;
|
|
1750
|
+
}
|
|
1751
|
+
return allKnownFields;
|
|
1752
|
+
}
|
|
1379
1753
|
function parseMessageType(decodeResult, messageType) {
|
|
1380
1754
|
let decoded = true;
|
|
1381
1755
|
const parts = messageType.split("#");
|
|
1382
1756
|
if (parts.length == 1) {
|
|
1383
1757
|
if (parts[0].startsWith("POS") && parts[0].length !== 3 && !parts[0].startsWith("POS/")) {
|
|
1384
|
-
decoded =
|
|
1758
|
+
decoded = processPosition2(decodeResult, parts[0].substring(3).split(","));
|
|
1385
1759
|
}
|
|
1386
1760
|
return decoded;
|
|
1387
1761
|
} else if (parts.length == 2) {
|
|
@@ -1391,7 +1765,7 @@ function parseMessageType(decodeResult, messageType) {
|
|
|
1391
1765
|
decodeResult.remaining.text += "#" + parts[1].substring(0, 3);
|
|
1392
1766
|
}
|
|
1393
1767
|
if (parts[1].substring(3, 6) === "POS" && parts[1].length !== 6 && parts[1].substring(3, 7) !== "POS/") {
|
|
1394
|
-
decoded =
|
|
1768
|
+
decoded = processPosition2(decodeResult, parts[1].substring(6).split(","));
|
|
1395
1769
|
}
|
|
1396
1770
|
decodeResult.raw.message_type = messageType;
|
|
1397
1771
|
return decoded;
|
|
@@ -1399,8 +1773,21 @@ function parseMessageType(decodeResult, messageType) {
|
|
|
1399
1773
|
decodeResult.remaining.text += messageType;
|
|
1400
1774
|
return false;
|
|
1401
1775
|
}
|
|
1402
|
-
function
|
|
1403
|
-
|
|
1776
|
+
function processDC(decodeResult, data) {
|
|
1777
|
+
decodeResult.raw.message_date = data[0];
|
|
1778
|
+
if (data.length === 1) {
|
|
1779
|
+
} else if (data.length === 2) {
|
|
1780
|
+
const date = data[0].substring(2, 4) + data[0].substring(0, 2) + data[0].substring(4, 6);
|
|
1781
|
+
const time = DateTimeUtils.convertDateTimeToEpoch(data[1], data[0]);
|
|
1782
|
+
decodeResult.raw.message_timestamp = time;
|
|
1783
|
+
} else {
|
|
1784
|
+
return false;
|
|
1785
|
+
}
|
|
1786
|
+
return true;
|
|
1787
|
+
}
|
|
1788
|
+
function processPS(decodeResult, data) {
|
|
1789
|
+
let allKnownFields = true;
|
|
1790
|
+
const position = CoordinateUtils.decodeStringCoordinates(data[0]);
|
|
1404
1791
|
if (position) {
|
|
1405
1792
|
decodeResult.raw.position = position;
|
|
1406
1793
|
decodeResult.formatted.items.push({
|
|
@@ -1409,46 +1796,76 @@ function processPosition(decodeResult, value) {
|
|
|
1409
1796
|
label: "Aircraft Position",
|
|
1410
1797
|
value: CoordinateUtils.coordinateString(position)
|
|
1411
1798
|
});
|
|
1412
|
-
}
|
|
1413
|
-
|
|
1414
|
-
}
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
}
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1799
|
+
} else {
|
|
1800
|
+
allKnownFields = false;
|
|
1801
|
+
}
|
|
1802
|
+
console.log("PS data.length: ", data.length);
|
|
1803
|
+
console.log("PS data: ", data);
|
|
1804
|
+
if (data.length === 9) {
|
|
1805
|
+
processRoute(decodeResult, data[3], data[1], data[5], data[4], void 0);
|
|
1806
|
+
ResultFormatter.altitude(decodeResult, Number(data[2]) * 100);
|
|
1807
|
+
ResultFormatter.temperature(decodeResult, data[6]);
|
|
1808
|
+
ResultFormatter.unknown(decodeResult, data[7]);
|
|
1809
|
+
ResultFormatter.unknown(decodeResult, data[8]);
|
|
1810
|
+
}
|
|
1811
|
+
if (data.length === 14) {
|
|
1812
|
+
ResultFormatter.altitude(decodeResult, Number(data[3]) * 100);
|
|
1813
|
+
processRoute(decodeResult, data[4], data[2], data[6], data[5], void 0);
|
|
1814
|
+
ResultFormatter.temperature(decodeResult, data[7]);
|
|
1815
|
+
ResultFormatter.groundspeed(decodeResult, Number(data[10]));
|
|
1816
|
+
ResultFormatter.unknown(decodeResult, data[1]);
|
|
1817
|
+
ResultFormatter.unknown(decodeResult, data[8]);
|
|
1818
|
+
ResultFormatter.unknown(decodeResult, data[9]);
|
|
1819
|
+
ResultFormatter.unknown(decodeResult, data.slice(11).join(","));
|
|
1820
|
+
}
|
|
1821
|
+
allKnownFields = false;
|
|
1822
|
+
return allKnownFields;
|
|
1432
1823
|
}
|
|
1433
|
-
function
|
|
1434
|
-
|
|
1435
|
-
|
|
1824
|
+
function processPosition2(decodeResult, data) {
|
|
1825
|
+
let allKnownFields = true;
|
|
1826
|
+
const position = CoordinateUtils.decodeStringCoordinates(data[0]);
|
|
1827
|
+
if (position) {
|
|
1828
|
+
decodeResult.raw.position = position;
|
|
1436
1829
|
decodeResult.formatted.items.push({
|
|
1437
|
-
type: "
|
|
1438
|
-
|
|
1439
|
-
|
|
1830
|
+
type: "aircraft_position",
|
|
1831
|
+
code: "POS",
|
|
1832
|
+
label: "Aircraft Position",
|
|
1833
|
+
value: CoordinateUtils.coordinateString(position)
|
|
1440
1834
|
});
|
|
1441
|
-
}
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1835
|
+
} else {
|
|
1836
|
+
allKnownFields = false;
|
|
1837
|
+
}
|
|
1838
|
+
console.log("data.length: ", data.length);
|
|
1839
|
+
console.log("data: ", data);
|
|
1840
|
+
if (data.length >= 10) {
|
|
1841
|
+
ResultFormatter.altitude(decodeResult, Number(data[3]) * 100);
|
|
1842
|
+
processRoute(decodeResult, data[1], data[2], data[4], data[5], data[6]);
|
|
1843
|
+
ResultFormatter.temperature(decodeResult, data[7]);
|
|
1844
|
+
ResultFormatter.unknown(decodeResult, data[8]);
|
|
1845
|
+
ResultFormatter.unknown(decodeResult, data[9]);
|
|
1846
|
+
}
|
|
1847
|
+
if (data.length >= 14) {
|
|
1848
|
+
ResultFormatter.groundspeed(decodeResult, Number(data[10]));
|
|
1849
|
+
ResultFormatter.unknown(decodeResult, data[11]);
|
|
1850
|
+
ResultFormatter.unknown(decodeResult, data[12]);
|
|
1851
|
+
ResultFormatter.unknown(decodeResult, data[13]);
|
|
1852
|
+
}
|
|
1853
|
+
allKnownFields = false;
|
|
1854
|
+
return allKnownFields;
|
|
1448
1855
|
}
|
|
1449
|
-
function
|
|
1450
|
-
const
|
|
1451
|
-
|
|
1856
|
+
function processRoute(decodeResult, last, time, next, eta, then, date) {
|
|
1857
|
+
const lastTime = date ? DateTimeUtils.convertDateTimeToEpoch(time, date) : DateTimeUtils.convertHHMMSSToTod(time);
|
|
1858
|
+
const nextTime = date ? DateTimeUtils.convertDateTimeToEpoch(eta, date) : DateTimeUtils.convertHHMMSSToTod(eta);
|
|
1859
|
+
const timeFormat = date ? "epoch" : "tod";
|
|
1860
|
+
const lastWaypoint = RouteUtils.getWaypoint(last);
|
|
1861
|
+
lastWaypoint.time = lastTime;
|
|
1862
|
+
lastWaypoint.timeFormat = timeFormat;
|
|
1863
|
+
const nextWaypoint = RouteUtils.getWaypoint(next);
|
|
1864
|
+
nextWaypoint.time = nextTime;
|
|
1865
|
+
nextWaypoint.timeFormat = timeFormat;
|
|
1866
|
+
const thenWaypoint = RouteUtils.getWaypoint(then || "?");
|
|
1867
|
+
const waypoints = [lastWaypoint, nextWaypoint, thenWaypoint];
|
|
1868
|
+
decodeResult.raw.route = { waypoints };
|
|
1452
1869
|
decodeResult.formatted.items.push({
|
|
1453
1870
|
type: "aircraft_route",
|
|
1454
1871
|
code: "ROUTE",
|
|
@@ -1456,53 +1873,6 @@ function addRoute(decodeResult, value) {
|
|
|
1456
1873
|
value: RouteUtils.routeToString(decodeResult.raw.route)
|
|
1457
1874
|
});
|
|
1458
1875
|
}
|
|
1459
|
-
function addProcedure(decodeResult, value, type) {
|
|
1460
|
-
if (decodeResult.raw.procedures === void 0) {
|
|
1461
|
-
decodeResult.raw.procedures = [];
|
|
1462
|
-
}
|
|
1463
|
-
const data = value.split(".");
|
|
1464
|
-
let waypoints;
|
|
1465
|
-
if (data.length > 1) {
|
|
1466
|
-
waypoints = data.slice(1).map((leg) => RouteUtils.getWaypoint(leg));
|
|
1467
|
-
}
|
|
1468
|
-
const route = { name: data[0], waypoints };
|
|
1469
|
-
decodeResult.raw.procedures.push({ type, route });
|
|
1470
|
-
const procedureName = type.substring(0, 1).toUpperCase() + type.slice(1);
|
|
1471
|
-
let procedureValue = route.name;
|
|
1472
|
-
decodeResult.formatted.items.push({
|
|
1473
|
-
type: `procedure`,
|
|
1474
|
-
code: "proc",
|
|
1475
|
-
label: `${procedureName} Procedure`,
|
|
1476
|
-
value: RouteUtils.routeToString(route)
|
|
1477
|
-
});
|
|
1478
|
-
}
|
|
1479
|
-
function addCompanyRoute(decodeResult, value) {
|
|
1480
|
-
const segments = value.split(".");
|
|
1481
|
-
const parens_idx = segments[0].indexOf("(");
|
|
1482
|
-
let name;
|
|
1483
|
-
let runway;
|
|
1484
|
-
if (parens_idx === -1) {
|
|
1485
|
-
name = segments[0];
|
|
1486
|
-
} else {
|
|
1487
|
-
name = segments[0].slice(0, parens_idx);
|
|
1488
|
-
runway = segments[0].slice(parens_idx + 1, segments[0].indexOf(")"));
|
|
1489
|
-
}
|
|
1490
|
-
let waypoints;
|
|
1491
|
-
if (segments.length > 1) {
|
|
1492
|
-
waypoints = segments.slice(1).map((leg) => RouteUtils.getWaypoint(leg));
|
|
1493
|
-
}
|
|
1494
|
-
decodeResult.raw.company_route = {
|
|
1495
|
-
name,
|
|
1496
|
-
runway,
|
|
1497
|
-
waypoints
|
|
1498
|
-
};
|
|
1499
|
-
decodeResult.formatted.items.push({
|
|
1500
|
-
type: "company_route",
|
|
1501
|
-
code: "CR",
|
|
1502
|
-
label: "Company Route",
|
|
1503
|
-
value: RouteUtils.routeToString(decodeResult.raw.company_route)
|
|
1504
|
-
});
|
|
1505
|
-
}
|
|
1506
1876
|
|
|
1507
1877
|
// lib/plugins/Label_H1_FPN.ts
|
|
1508
1878
|
var Label_H1_FPN = class extends DecoderPlugin {
|
|
@@ -1518,15 +1888,12 @@ var Label_H1_FPN = class extends DecoderPlugin {
|
|
|
1518
1888
|
decodeResult.decoder.name = this.name;
|
|
1519
1889
|
decodeResult.formatted.description = "Flight Plan";
|
|
1520
1890
|
decodeResult.message = message;
|
|
1891
|
+
decodeResult.remaining.text = "";
|
|
1521
1892
|
const msg = message.text.replace(/\n|\r/g, "");
|
|
1522
|
-
const
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
addChecksum(decodeResult, checksum);
|
|
1527
|
-
decodeResult.decoded = true;
|
|
1528
|
-
decodeResult.decoder.decodeLevel = fulllyDecoded ? "full" : "partial";
|
|
1529
|
-
} else {
|
|
1893
|
+
const fulllyDecoded = H1Helper.decodeH1Message(decodeResult, msg);
|
|
1894
|
+
decodeResult.decoded = true;
|
|
1895
|
+
decodeResult.decoder.decodeLevel = fulllyDecoded ? "full" : "partial";
|
|
1896
|
+
if (decodeResult.formatted.items.length === 0) {
|
|
1530
1897
|
if (options?.debug) {
|
|
1531
1898
|
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
1532
1899
|
}
|
|
@@ -1537,15 +1904,6 @@ var Label_H1_FPN = class extends DecoderPlugin {
|
|
|
1537
1904
|
return decodeResult;
|
|
1538
1905
|
}
|
|
1539
1906
|
};
|
|
1540
|
-
function addChecksum(decodeResult, value) {
|
|
1541
|
-
decodeResult.raw.checksum = Number("0x" + value);
|
|
1542
|
-
decodeResult.formatted.items.push({
|
|
1543
|
-
type: "message_checksum",
|
|
1544
|
-
code: "CHECKSUM",
|
|
1545
|
-
label: "Message Checksum",
|
|
1546
|
-
value: "0x" + ("0000" + decodeResult.raw.checksum.toString(16)).slice(-4)
|
|
1547
|
-
});
|
|
1548
|
-
}
|
|
1549
1907
|
|
|
1550
1908
|
// lib/plugins/Label_H1_OHMA.ts
|
|
1551
1909
|
import * as zlib from "minizlib";
|
|
@@ -1571,13 +1929,18 @@ var Label_H1_OHMA = class extends DecoderPlugin {
|
|
|
1571
1929
|
decompress.flush(zlib.constants.Z_SYNC_FLUSH);
|
|
1572
1930
|
const result = decompress.read();
|
|
1573
1931
|
const jsonText = result.toString();
|
|
1574
|
-
const json = JSON.parse(jsonText);
|
|
1575
1932
|
let formattedMsg;
|
|
1576
|
-
|
|
1577
|
-
|
|
1933
|
+
let jsonMessage;
|
|
1934
|
+
try {
|
|
1935
|
+
jsonMessage = JSON.parse(jsonText).message;
|
|
1936
|
+
} catch {
|
|
1937
|
+
jsonMessage = jsonText;
|
|
1938
|
+
}
|
|
1939
|
+
try {
|
|
1940
|
+
const ohmaMsg = JSON.parse(jsonMessage);
|
|
1578
1941
|
formattedMsg = JSON.stringify(ohmaMsg, null, 2);
|
|
1579
|
-
}
|
|
1580
|
-
formattedMsg =
|
|
1942
|
+
} catch {
|
|
1943
|
+
formattedMsg = jsonMessage;
|
|
1581
1944
|
}
|
|
1582
1945
|
decodeResult.decoded = true;
|
|
1583
1946
|
decodeResult.decoder.decodeLevel = "full";
|
|
@@ -1616,225 +1979,20 @@ var Label_H1_POS = class extends DecoderPlugin {
|
|
|
1616
1979
|
decodeResult.formatted.description = "Position Report";
|
|
1617
1980
|
decodeResult.message = message;
|
|
1618
1981
|
decodeResult.remaining.text = "";
|
|
1619
|
-
const
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
if (decoded) {
|
|
1625
|
-
processChecksum(decodeResult, checksum);
|
|
1626
|
-
decodeResult.decoded = true;
|
|
1627
|
-
decodeResult.decoder.decodeLevel = "full";
|
|
1628
|
-
} else if (decodeResult.remaining.text.length > 0) {
|
|
1629
|
-
processChecksum(decodeResult, checksum);
|
|
1630
|
-
decodeResult.decoded = true;
|
|
1631
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
1632
|
-
} else {
|
|
1633
|
-
decodeResult.decoded = false;
|
|
1634
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
1635
|
-
}
|
|
1636
|
-
} else if (parts.length === 10) {
|
|
1637
|
-
processAlt(decodeResult, parts[3]);
|
|
1638
|
-
processRoute(decodeResult, parts[1], parts[2], parts[4], parts[5], parts[6]);
|
|
1639
|
-
processTemp(decodeResult, parts[7]);
|
|
1640
|
-
processUnknown(decodeResult, parts[8]);
|
|
1641
|
-
processUnknown(decodeResult, parts[9]);
|
|
1642
|
-
processChecksum(decodeResult, checksum);
|
|
1643
|
-
decodeResult.decoded = true;
|
|
1644
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
1645
|
-
} else if (parts.length === 11) {
|
|
1646
|
-
processAlt(decodeResult, parts[3]);
|
|
1647
|
-
processRoute(decodeResult, parts[1], parts[2], parts[4], parts[5], parts[6], parts[10]);
|
|
1648
|
-
processTemp(decodeResult, parts[7]);
|
|
1649
|
-
processUnknown(decodeResult, parts[8]);
|
|
1650
|
-
processUnknown(decodeResult, parts[9]);
|
|
1651
|
-
processChecksum(decodeResult, checksum);
|
|
1652
|
-
decodeResult.decoded = true;
|
|
1653
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
1654
|
-
} else if (parts.length === 12) {
|
|
1655
|
-
const date = parts[11].substring(2, 4) + parts[11].substring(0, 2) + parts[11].substring(4, 6);
|
|
1656
|
-
processUnknown(decodeResult, parts[3]);
|
|
1657
|
-
processRoute(decodeResult, parts[1], parts[2], parts[4], parts[5], parts[6], date);
|
|
1658
|
-
processTemp(decodeResult, parts[7]);
|
|
1659
|
-
processUnknown(decodeResult, parts[8]);
|
|
1660
|
-
processUnknown(decodeResult, parts[9]);
|
|
1661
|
-
processUnknown(decodeResult, parts[10]);
|
|
1662
|
-
processChecksum(decodeResult, checksum);
|
|
1663
|
-
decodeResult.decoded = true;
|
|
1664
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
1665
|
-
} else if (parts.length === 14) {
|
|
1666
|
-
processAlt(decodeResult, parts[3]);
|
|
1667
|
-
processRoute(decodeResult, parts[1], parts[2], parts[4], parts[5], parts[6]);
|
|
1668
|
-
processTemp(decodeResult, parts[7]);
|
|
1669
|
-
processUnknown(decodeResult, parts[8]);
|
|
1670
|
-
processUnknown(decodeResult, parts[9]);
|
|
1671
|
-
processGndspd(decodeResult, parts[10]);
|
|
1672
|
-
processUnknown(decodeResult, parts[11]);
|
|
1673
|
-
processUnknown(decodeResult, parts[12]);
|
|
1674
|
-
processUnknown(decodeResult, parts[13]);
|
|
1675
|
-
processChecksum(decodeResult, checksum);
|
|
1676
|
-
decodeResult.decoded = true;
|
|
1677
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
1678
|
-
} else if (parts.length === 15) {
|
|
1679
|
-
decodeResult.raw.flight_number = parts[1];
|
|
1680
|
-
let date = void 0;
|
|
1681
|
-
if (parts[2].startsWith("/DC")) {
|
|
1682
|
-
date = parts[2].substring(3);
|
|
1683
|
-
} else {
|
|
1684
|
-
processUnknown(decodeResult, parts[2]);
|
|
1685
|
-
}
|
|
1686
|
-
processUnknown(decodeResult, parts[3]);
|
|
1687
|
-
const fields = parts[4].split("/");
|
|
1688
|
-
for (let i = 0; i < fields.length; ++i) {
|
|
1689
|
-
const field = fields[i];
|
|
1690
|
-
if (field.startsWith("PS")) {
|
|
1691
|
-
processPosition2(decodeResult, field.substring(2));
|
|
1692
|
-
} else {
|
|
1693
|
-
if (i === 0) {
|
|
1694
|
-
processUnknown(decodeResult, field);
|
|
1695
|
-
} else {
|
|
1696
|
-
processUnknown(decodeResult, "/" + field);
|
|
1697
|
-
}
|
|
1698
|
-
}
|
|
1699
|
-
}
|
|
1700
|
-
processRoute(decodeResult, parts[7], parts[5], parts[9], parts[8], void 0, date);
|
|
1701
|
-
processAlt(decodeResult, parts[6]);
|
|
1702
|
-
processTemp(decodeResult, parts[10]);
|
|
1703
|
-
processUnknown(decodeResult, parts[11]);
|
|
1704
|
-
processUnknown(decodeResult, parts[12]);
|
|
1705
|
-
processUnknown(decodeResult, parts[13]);
|
|
1706
|
-
processUnknown(decodeResult, parts[14]);
|
|
1707
|
-
processChecksum(decodeResult, checksum);
|
|
1708
|
-
decodeResult.decoded = true;
|
|
1709
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
1710
|
-
} else if (parts.length === 21) {
|
|
1711
|
-
processRunway(decodeResult, parts[1]);
|
|
1712
|
-
processUnknown(decodeResult, parts.slice(2, 11).join(","));
|
|
1713
|
-
processTemp(decodeResult, parts[11]);
|
|
1714
|
-
processUnknown(decodeResult, parts.slice(12, 20).join(","));
|
|
1715
|
-
FlightPlanUtils.processFlightPlan(decodeResult, parts[20].split(":"));
|
|
1716
|
-
processChecksum(decodeResult, checksum);
|
|
1717
|
-
decodeResult.decoded = true;
|
|
1718
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
1719
|
-
} else if (parts.length === 32) {
|
|
1720
|
-
processRunway(decodeResult, parts[1]);
|
|
1721
|
-
const time = parts[2];
|
|
1722
|
-
processUnknown(decodeResult, parts[3]);
|
|
1723
|
-
const past = parts[4];
|
|
1724
|
-
processUnknown(decodeResult, parts[5]);
|
|
1725
|
-
const eta = parts[6];
|
|
1726
|
-
const next = parts[7];
|
|
1727
|
-
processUnknown(decodeResult, parts.slice(8, 14).join(","));
|
|
1728
|
-
processUnknown(decodeResult, parts[16]);
|
|
1729
|
-
processUnknown(decodeResult, parts[17]);
|
|
1730
|
-
processUnknown(decodeResult, parts[18]);
|
|
1731
|
-
processGndspd(decodeResult, parts[19]);
|
|
1732
|
-
processUnknown(decodeResult, parts[20]);
|
|
1733
|
-
processUnknown(decodeResult, parts[21]);
|
|
1734
|
-
processAlt(decodeResult, parts[22]);
|
|
1735
|
-
processUnknown(decodeResult, parts.slice(23, 31).join(","));
|
|
1736
|
-
const allProcessed = FlightPlanUtils.processFlightPlan(decodeResult, (parts[31] + checksum).split(":"));
|
|
1737
|
-
processRoute(decodeResult, past, time, next, eta);
|
|
1738
|
-
decodeResult.decoded = true;
|
|
1739
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
1740
|
-
} else {
|
|
1741
|
-
if (options.debug) {
|
|
1982
|
+
const fulllyDecoded = H1Helper.decodeH1Message(decodeResult, message.text);
|
|
1983
|
+
decodeResult.decoded = true;
|
|
1984
|
+
decodeResult.decoder.decodeLevel = fulllyDecoded ? "full" : "partial";
|
|
1985
|
+
if (decodeResult.formatted.items.length === 0) {
|
|
1986
|
+
if (options?.debug) {
|
|
1742
1987
|
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
1743
1988
|
}
|
|
1744
|
-
decodeResult.remaining.text
|
|
1989
|
+
decodeResult.remaining.text = message.text;
|
|
1745
1990
|
decodeResult.decoded = false;
|
|
1746
1991
|
decodeResult.decoder.decodeLevel = "none";
|
|
1747
1992
|
}
|
|
1748
1993
|
return decodeResult;
|
|
1749
1994
|
}
|
|
1750
1995
|
};
|
|
1751
|
-
function processUnknown(decodeResult, value) {
|
|
1752
|
-
decodeResult.remaining.text += "," + value;
|
|
1753
|
-
}
|
|
1754
|
-
function processPosition2(decodeResult, value) {
|
|
1755
|
-
const position = CoordinateUtils.decodeStringCoordinates(value);
|
|
1756
|
-
if (position) {
|
|
1757
|
-
decodeResult.raw.position = position;
|
|
1758
|
-
decodeResult.formatted.items.push({
|
|
1759
|
-
type: "aircraft_position",
|
|
1760
|
-
code: "POS",
|
|
1761
|
-
label: "Aircraft Position",
|
|
1762
|
-
value: CoordinateUtils.coordinateString(position)
|
|
1763
|
-
});
|
|
1764
|
-
}
|
|
1765
|
-
}
|
|
1766
|
-
function processAlt(decodeResult, value) {
|
|
1767
|
-
decodeResult.raw.altitude = Number(value) * 100;
|
|
1768
|
-
decodeResult.formatted.items.push({
|
|
1769
|
-
type: "altitude",
|
|
1770
|
-
code: "ALT",
|
|
1771
|
-
label: "Altitude",
|
|
1772
|
-
value: `${decodeResult.raw.altitude} feet`
|
|
1773
|
-
});
|
|
1774
|
-
}
|
|
1775
|
-
function processTemp(decodeResult, value) {
|
|
1776
|
-
decodeResult.raw.outside_air_temperature = Number(value.substring(1)) * (value.charAt(0) === "M" ? -1 : 1);
|
|
1777
|
-
decodeResult.formatted.items.push({
|
|
1778
|
-
type: "outside_air_temperature",
|
|
1779
|
-
code: "OATEMP",
|
|
1780
|
-
label: "Outside Air Temperature (C)",
|
|
1781
|
-
value: `${decodeResult.raw.outside_air_temperature}`
|
|
1782
|
-
});
|
|
1783
|
-
}
|
|
1784
|
-
function processRunway(decodeResult, value) {
|
|
1785
|
-
decodeResult.raw.arrival_runway = value.replace("RW", "");
|
|
1786
|
-
decodeResult.formatted.items.push({
|
|
1787
|
-
type: "runway",
|
|
1788
|
-
label: "Arrival Runway",
|
|
1789
|
-
value: decodeResult.raw.arrival_runway
|
|
1790
|
-
});
|
|
1791
|
-
}
|
|
1792
|
-
function processGndspd(decodeResult, value) {
|
|
1793
|
-
decodeResult.raw.groundspeed = Number(value);
|
|
1794
|
-
decodeResult.formatted.items.push({
|
|
1795
|
-
type: "aircraft_groundspeed",
|
|
1796
|
-
code: "GSPD",
|
|
1797
|
-
label: "Aircraft Groundspeed",
|
|
1798
|
-
value: `${decodeResult.raw.groundspeed}`
|
|
1799
|
-
});
|
|
1800
|
-
}
|
|
1801
|
-
function processRoute(decodeResult, last, time, next, eta, then, date) {
|
|
1802
|
-
const lastTime = date ? DateTimeUtils.convertDateTimeToEpoch(time, date) : DateTimeUtils.convertHHMMSSToTod(time);
|
|
1803
|
-
const nextTime = date ? DateTimeUtils.convertDateTimeToEpoch(eta, date) : DateTimeUtils.convertHHMMSSToTod(eta);
|
|
1804
|
-
const timeFormat = date ? "epoch" : "tod";
|
|
1805
|
-
const lastWaypoint = RouteUtils.getWaypoint(last);
|
|
1806
|
-
lastWaypoint.time = lastTime;
|
|
1807
|
-
lastWaypoint.timeFormat = timeFormat;
|
|
1808
|
-
const nextWaypoint = RouteUtils.getWaypoint(next);
|
|
1809
|
-
nextWaypoint.time = nextTime;
|
|
1810
|
-
nextWaypoint.timeFormat = timeFormat;
|
|
1811
|
-
const thenWaypoint = RouteUtils.getWaypoint(then || "?");
|
|
1812
|
-
const waypoints = [lastWaypoint, nextWaypoint, thenWaypoint];
|
|
1813
|
-
decodeResult.raw.route = { waypoints };
|
|
1814
|
-
decodeResult.formatted.items.push({
|
|
1815
|
-
type: "aircraft_route",
|
|
1816
|
-
code: "ROUTE",
|
|
1817
|
-
label: "Aircraft Route",
|
|
1818
|
-
value: RouteUtils.routeToString(decodeResult.raw.route)
|
|
1819
|
-
});
|
|
1820
|
-
}
|
|
1821
|
-
function processChecksum(decodeResult, value) {
|
|
1822
|
-
decodeResult.raw.checksum = Number("0x" + value);
|
|
1823
|
-
decodeResult.formatted.items.push({
|
|
1824
|
-
type: "message_checksum",
|
|
1825
|
-
code: "CHECKSUM",
|
|
1826
|
-
label: "Message Checksum",
|
|
1827
|
-
value: "0x" + ("0000" + decodeResult.raw.checksum.toString(16)).slice(-4)
|
|
1828
|
-
});
|
|
1829
|
-
}
|
|
1830
|
-
function findHeader(text) {
|
|
1831
|
-
const parts = text.split(",");
|
|
1832
|
-
const header = parts[0];
|
|
1833
|
-
if (header.indexOf("/TS") === -1) {
|
|
1834
|
-
return header;
|
|
1835
|
-
}
|
|
1836
|
-
return parts[0] + "," + parts[1];
|
|
1837
|
-
}
|
|
1838
1996
|
|
|
1839
1997
|
// lib/plugins/Label_H1_WRN.ts
|
|
1840
1998
|
var Label_H1_WRN = class extends DecoderPlugin {
|
|
@@ -1857,16 +2015,16 @@ var Label_H1_WRN = class extends DecoderPlugin {
|
|
|
1857
2015
|
for (let i = 1; i < fields.length; i++) {
|
|
1858
2016
|
const field = fields[i];
|
|
1859
2017
|
if (field.startsWith("PN")) {
|
|
1860
|
-
|
|
2018
|
+
processUnknown(decodeResult, "/" + field);
|
|
1861
2019
|
} else {
|
|
1862
|
-
|
|
2020
|
+
processUnknown(decodeResult, "/" + field);
|
|
1863
2021
|
}
|
|
1864
2022
|
}
|
|
1865
2023
|
const data = parts[1].substring(0, 20);
|
|
1866
2024
|
const msg = parts[1].substring(20);
|
|
1867
2025
|
const datetime = data.substring(0, 12);
|
|
1868
2026
|
const date = datetime.substring(4, 6) + datetime.substring(2, 4) + datetime.substring(0, 2);
|
|
1869
|
-
|
|
2027
|
+
processUnknown(decodeResult, data.substring(12));
|
|
1870
2028
|
decodeResult.raw.message_timestamp = DateTimeUtils.convertDateTimeToEpoch(datetime.substring(6), date);
|
|
1871
2029
|
decodeResult.raw.warning_message = msg;
|
|
1872
2030
|
decodeResult.formatted.items.push({
|
|
@@ -1888,7 +2046,7 @@ var Label_H1_WRN = class extends DecoderPlugin {
|
|
|
1888
2046
|
return decodeResult;
|
|
1889
2047
|
}
|
|
1890
2048
|
};
|
|
1891
|
-
function
|
|
2049
|
+
function processUnknown(decodeResult, value) {
|
|
1892
2050
|
decodeResult.remaining.text += value;
|
|
1893
2051
|
}
|
|
1894
2052
|
|
|
@@ -2989,6 +3147,7 @@ var MessageDecoder = class {
|
|
|
2989
3147
|
this.registerPlugin(new Label_15_FST(this));
|
|
2990
3148
|
this.registerPlugin(new Label_16_N_Space(this));
|
|
2991
3149
|
this.registerPlugin(new Label_20_POS(this));
|
|
3150
|
+
this.registerPlugin(new Label_21_POS(this));
|
|
2992
3151
|
this.registerPlugin(new Label_30_Slash_EA(this));
|
|
2993
3152
|
this.registerPlugin(new Label_44_ETA(this));
|
|
2994
3153
|
this.registerPlugin(new Label_44_IN(this));
|