@airframes/acars-decoder 1.6.18 → 1.6.19
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 +1056 -931
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1053 -928
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -28,12 +28,12 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
29
|
|
|
30
30
|
// index.ts
|
|
31
|
-
var
|
|
32
|
-
__export(
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
33
|
IcaoDecoder: () => IcaoDecoder,
|
|
34
34
|
MessageDecoder: () => MessageDecoder
|
|
35
35
|
});
|
|
36
|
-
module.exports = __toCommonJS(
|
|
36
|
+
module.exports = __toCommonJS(index_exports);
|
|
37
37
|
|
|
38
38
|
// lib/IcaoDecoder.ts
|
|
39
39
|
var IcaoDecoder = class {
|
|
@@ -378,6 +378,9 @@ var ResultFormatter = class {
|
|
|
378
378
|
});
|
|
379
379
|
}
|
|
380
380
|
static altitude(decodeResult, value) {
|
|
381
|
+
if (isNaN(value)) {
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
381
384
|
decodeResult.raw.altitude = value;
|
|
382
385
|
decodeResult.formatted.items.push({
|
|
383
386
|
type: "altitude",
|
|
@@ -1267,47 +1270,13 @@ var Label_16_N_Space = class extends DecoderPlugin {
|
|
|
1267
1270
|
}
|
|
1268
1271
|
};
|
|
1269
1272
|
|
|
1270
|
-
// lib/plugins/
|
|
1271
|
-
var
|
|
1272
|
-
name = "label-
|
|
1273
|
-
qualifiers() {
|
|
1274
|
-
return {
|
|
1275
|
-
labels: ["1M"],
|
|
1276
|
-
preambles: ["/"]
|
|
1277
|
-
};
|
|
1278
|
-
}
|
|
1279
|
-
decode(message, options = {}) {
|
|
1280
|
-
const decodeResult = this.defaultResult();
|
|
1281
|
-
decodeResult.decoder.name = this.name;
|
|
1282
|
-
decodeResult.formatted.description = "ETA Report";
|
|
1283
|
-
decodeResult.message = message;
|
|
1284
|
-
const results = message.text.split(/\n|\//).slice(1);
|
|
1285
|
-
if (results) {
|
|
1286
|
-
if (options.debug) {
|
|
1287
|
-
console.log(`Label 1M ETA: results`);
|
|
1288
|
-
console.log(results);
|
|
1289
|
-
}
|
|
1290
|
-
decodeResult.raw.flight_number = results[0];
|
|
1291
|
-
ResultFormatter.departureAirport(decodeResult, results[3]);
|
|
1292
|
-
ResultFormatter.arrivalAirport(decodeResult, results[4]);
|
|
1293
|
-
ResultFormatter.alternateAirport(decodeResult, results[5]);
|
|
1294
|
-
ResultFormatter.arrivalRunway(decodeResult, results[8].replace(results[4], ""));
|
|
1295
|
-
const yymmdd = results[2];
|
|
1296
|
-
ResultFormatter.eta(decodeResult, DateTimeUtils.convertDateTimeToEpoch(results[7] + "00", yymmdd.substring(2, 4) + yymmdd.substring(4, 6) + yymmdd.substring(0, 2)), "epoch");
|
|
1297
|
-
}
|
|
1298
|
-
decodeResult.decoded = true;
|
|
1299
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
1300
|
-
return decodeResult;
|
|
1301
|
-
}
|
|
1302
|
-
};
|
|
1303
|
-
|
|
1304
|
-
// lib/plugins/Label_1L_3-line.ts
|
|
1305
|
-
var Label_1L_3Line = class extends DecoderPlugin {
|
|
1306
|
-
// eslint-disable-line camelcase
|
|
1307
|
-
name = "label-1l-3-line";
|
|
1273
|
+
// lib/plugins/Label_16_POSA1.ts
|
|
1274
|
+
var Label_16_POSA1 = class extends DecoderPlugin {
|
|
1275
|
+
name = "label-16-posa1";
|
|
1308
1276
|
qualifiers() {
|
|
1309
1277
|
return {
|
|
1310
|
-
labels: ["
|
|
1278
|
+
labels: ["16"],
|
|
1279
|
+
preambles: ["POSA1"]
|
|
1311
1280
|
};
|
|
1312
1281
|
}
|
|
1313
1282
|
decode(message, options = {}) {
|
|
@@ -1315,88 +1284,39 @@ var Label_1L_3Line = class extends DecoderPlugin {
|
|
|
1315
1284
|
decodeResult.decoder.name = this.name;
|
|
1316
1285
|
decodeResult.formatted.description = "Position Report";
|
|
1317
1286
|
decodeResult.message = message;
|
|
1318
|
-
const
|
|
1319
|
-
if (
|
|
1287
|
+
const fields = message.text.split(",");
|
|
1288
|
+
if (fields.length !== 11 || !fields[0].startsWith("POSA1")) {
|
|
1320
1289
|
if (options.debug) {
|
|
1321
|
-
console.log(`Decoder: Unknown
|
|
1290
|
+
console.log(`Decoder: Unknown 16 message: ${message.text}`);
|
|
1322
1291
|
}
|
|
1323
1292
|
decodeResult.remaining.text = message.text;
|
|
1324
1293
|
decodeResult.decoded = false;
|
|
1325
1294
|
decodeResult.decoder.decodeLevel = "none";
|
|
1326
1295
|
return decodeResult;
|
|
1327
1296
|
}
|
|
1328
|
-
|
|
1329
|
-
const
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
}
|
|
1340
|
-
const des = data.get("DES");
|
|
1341
|
-
if (des) {
|
|
1342
|
-
ResultFormatter.arrivalAirport(decodeResult, des);
|
|
1343
|
-
data.delete("DES");
|
|
1344
|
-
}
|
|
1345
|
-
const eta = data.get("ETA");
|
|
1346
|
-
if (eta) {
|
|
1347
|
-
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(eta));
|
|
1348
|
-
data.delete("ETA");
|
|
1349
|
-
}
|
|
1350
|
-
const alt = data.get("ALT");
|
|
1351
|
-
if (alt) {
|
|
1352
|
-
ResultFormatter.altitude(decodeResult, Number(alt));
|
|
1353
|
-
data.delete("ALT");
|
|
1354
|
-
}
|
|
1355
|
-
const fn = data.get("FN");
|
|
1356
|
-
if (fn) {
|
|
1357
|
-
ResultFormatter.flightNumber(decodeResult, fn);
|
|
1358
|
-
data.delete("FN");
|
|
1359
|
-
}
|
|
1360
|
-
const day = data.get("DAY");
|
|
1361
|
-
const utc = data.get("UTC");
|
|
1362
|
-
if (day && utc) {
|
|
1363
|
-
decodeResult.raw.message_timestamp = Date.parse(day + " GMT+0000") / 1e3 + DateTimeUtils.convertHHMMSSToTod(utc);
|
|
1364
|
-
data.delete("DAY");
|
|
1365
|
-
data.delete("UTC");
|
|
1366
|
-
}
|
|
1367
|
-
const lat = data.get("LAT");
|
|
1368
|
-
const lon = data.get("LON");
|
|
1369
|
-
if (lat && lon) {
|
|
1370
|
-
ResultFormatter.position(decodeResult, {
|
|
1371
|
-
latitude: CoordinateUtils.getDirection(lat[0]) * Number(lat.substring(1)),
|
|
1372
|
-
longitude: CoordinateUtils.getDirection(lon[0]) * Number(lon.substring(1))
|
|
1373
|
-
});
|
|
1374
|
-
data.delete("LAT");
|
|
1375
|
-
data.delete("LON");
|
|
1376
|
-
}
|
|
1377
|
-
let remaining = "";
|
|
1378
|
-
for (const [key, value] of data.entries()) {
|
|
1379
|
-
if (key === "") {
|
|
1380
|
-
remaining += value;
|
|
1381
|
-
} else {
|
|
1382
|
-
remaining += `/${key} ${value}`;
|
|
1383
|
-
}
|
|
1384
|
-
}
|
|
1385
|
-
decodeResult.remaining.text = remaining;
|
|
1297
|
+
ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinates(fields[0].substring(5)));
|
|
1298
|
+
const waypoint = fields[1].trim();
|
|
1299
|
+
const time = DateTimeUtils.convertHHMMSSToTod(fields[2]);
|
|
1300
|
+
ResultFormatter.altitude(decodeResult, Number(fields[3]) * 100);
|
|
1301
|
+
const nextWaypoint = fields[4].trim();
|
|
1302
|
+
const nextTime = DateTimeUtils.convertHHMMSSToTod(fields[5]);
|
|
1303
|
+
ResultFormatter.unknownArr(decodeResult, fields.slice(6), ",");
|
|
1304
|
+
ResultFormatter.route(decodeResult, { waypoints: [
|
|
1305
|
+
{ name: waypoint, time, timeFormat: "tod" },
|
|
1306
|
+
{ name: nextWaypoint, time: nextTime, timeFormat: "tod" }
|
|
1307
|
+
] });
|
|
1386
1308
|
decodeResult.decoded = true;
|
|
1387
1309
|
decodeResult.decoder.decodeLevel = "partial";
|
|
1388
1310
|
return decodeResult;
|
|
1389
1311
|
}
|
|
1390
1312
|
};
|
|
1391
1313
|
|
|
1392
|
-
// lib/plugins/
|
|
1393
|
-
var
|
|
1394
|
-
|
|
1395
|
-
name = "label-1l-070";
|
|
1314
|
+
// lib/plugins/Label_16_TOD.ts
|
|
1315
|
+
var Label_16_TOD = class extends DecoderPlugin {
|
|
1316
|
+
name = "label-16-tod";
|
|
1396
1317
|
qualifiers() {
|
|
1397
1318
|
return {
|
|
1398
|
-
labels: ["
|
|
1399
|
-
preambles: ["000000070"]
|
|
1319
|
+
labels: ["16"]
|
|
1400
1320
|
};
|
|
1401
1321
|
}
|
|
1402
1322
|
decode(message, options = {}) {
|
|
@@ -1404,340 +1324,574 @@ var Label_1L_070 = class extends DecoderPlugin {
|
|
|
1404
1324
|
decodeResult.decoder.name = this.name;
|
|
1405
1325
|
decodeResult.formatted.description = "Position Report";
|
|
1406
1326
|
decodeResult.message = message;
|
|
1407
|
-
|
|
1327
|
+
const fields = message.text.split(",");
|
|
1328
|
+
const time = DateTimeUtils.convertHHMMSSToTod(fields[0]);
|
|
1329
|
+
if (fields.length !== 5 || Number.isNaN(time)) {
|
|
1408
1330
|
if (options.debug) {
|
|
1409
|
-
console.log(`Decoder: Unknown
|
|
1331
|
+
console.log(`Decoder: Unknown 16 message: ${message.text}`);
|
|
1410
1332
|
}
|
|
1411
1333
|
decodeResult.remaining.text = message.text;
|
|
1412
1334
|
decodeResult.decoded = false;
|
|
1413
1335
|
decodeResult.decoder.decodeLevel = "none";
|
|
1414
1336
|
return decodeResult;
|
|
1415
1337
|
}
|
|
1416
|
-
|
|
1417
|
-
if (
|
|
1418
|
-
|
|
1419
|
-
console.log(`Decoder: Unknown 1L message: ${message.text}`);
|
|
1420
|
-
}
|
|
1421
|
-
decodeResult.remaining.text = message.text;
|
|
1422
|
-
decodeResult.decoded = false;
|
|
1423
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
1424
|
-
return decodeResult;
|
|
1338
|
+
ResultFormatter.time_of_day(decodeResult, time);
|
|
1339
|
+
if (fields[1] !== "") {
|
|
1340
|
+
ResultFormatter.altitude(decodeResult, Number(fields[1]));
|
|
1425
1341
|
}
|
|
1426
|
-
ResultFormatter.
|
|
1427
|
-
ResultFormatter.
|
|
1428
|
-
|
|
1429
|
-
|
|
1342
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[2]));
|
|
1343
|
+
ResultFormatter.unknown(decodeResult, fields[3]);
|
|
1344
|
+
const temp = fields[4].split("/");
|
|
1345
|
+
const posFields = temp[0].split(" ");
|
|
1430
1346
|
ResultFormatter.position(decodeResult, {
|
|
1431
|
-
latitude: CoordinateUtils.getDirection(
|
|
1432
|
-
longitude: CoordinateUtils.getDirection(
|
|
1347
|
+
latitude: CoordinateUtils.getDirection(posFields[0]) * Number(posFields[1]),
|
|
1348
|
+
longitude: CoordinateUtils.getDirection(posFields[2]) * Number(posFields[3])
|
|
1433
1349
|
});
|
|
1434
|
-
|
|
1350
|
+
if (temp.length > 1) {
|
|
1351
|
+
ResultFormatter.flightNumber(decodeResult, temp[1]);
|
|
1352
|
+
}
|
|
1435
1353
|
decodeResult.decoded = true;
|
|
1436
1354
|
decodeResult.decoder.decodeLevel = "partial";
|
|
1437
1355
|
return decodeResult;
|
|
1438
1356
|
}
|
|
1439
1357
|
};
|
|
1440
1358
|
|
|
1441
|
-
// lib/
|
|
1442
|
-
var
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1359
|
+
// lib/utils/flight_plan_utils.ts
|
|
1360
|
+
var FlightPlanUtils = class _FlightPlanUtils {
|
|
1361
|
+
/**
|
|
1362
|
+
* Processes flight plan data
|
|
1363
|
+
*
|
|
1364
|
+
* Expected format is [header, key1, val1, ... keyN, valN]
|
|
1365
|
+
*
|
|
1366
|
+
* @param decodeResult - results
|
|
1367
|
+
* @param data - original message split by ':'
|
|
1368
|
+
* @returns whether all fields were processed or not
|
|
1369
|
+
*/
|
|
1370
|
+
static processFlightPlan(decodeResult, data) {
|
|
1371
|
+
let allKnownFields = _FlightPlanUtils.parseHeader(decodeResult, data[0]);
|
|
1372
|
+
for (let i = 1; i < data.length; i += 2) {
|
|
1373
|
+
const key = data[i];
|
|
1374
|
+
const value = data[i + 1];
|
|
1375
|
+
switch (key) {
|
|
1376
|
+
case "A":
|
|
1377
|
+
addProcedure(decodeResult, value, "arrival");
|
|
1378
|
+
break;
|
|
1379
|
+
case "AA":
|
|
1380
|
+
addArrivalAirport(decodeResult, value);
|
|
1381
|
+
break;
|
|
1382
|
+
case "AP":
|
|
1383
|
+
addProcedure(decodeResult, value, "approach");
|
|
1384
|
+
break;
|
|
1385
|
+
case "CR":
|
|
1386
|
+
addCompanyRoute(decodeResult, value);
|
|
1387
|
+
break;
|
|
1388
|
+
case "D":
|
|
1389
|
+
addProcedure(decodeResult, value, "departure");
|
|
1390
|
+
break;
|
|
1391
|
+
case "DA":
|
|
1392
|
+
addDepartureAirport(decodeResult, value);
|
|
1393
|
+
break;
|
|
1394
|
+
case "F":
|
|
1395
|
+
addRoute(decodeResult, value);
|
|
1396
|
+
break;
|
|
1397
|
+
case "R":
|
|
1398
|
+
addRunway(decodeResult, value);
|
|
1399
|
+
break;
|
|
1400
|
+
// case 'WS': // something about routes, has altitude, so current parsing won't work
|
|
1401
|
+
// break;
|
|
1402
|
+
default:
|
|
1403
|
+
if (allKnownFields) {
|
|
1404
|
+
decodeResult.remaining.text = "";
|
|
1405
|
+
allKnownFields = false;
|
|
1406
|
+
}
|
|
1407
|
+
decodeResult.remaining.text += `:${key}:${value}`;
|
|
1408
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
1459
1409
|
}
|
|
1460
|
-
decodeResult.remaining.text = message.text;
|
|
1461
|
-
decodeResult.decoded = false;
|
|
1462
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
1463
|
-
return decodeResult;
|
|
1464
1410
|
}
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1411
|
+
return allKnownFields;
|
|
1412
|
+
}
|
|
1413
|
+
static parseHeader(decodeResult, header) {
|
|
1414
|
+
let allKnownFields = true;
|
|
1415
|
+
if (header.startsWith("RF")) {
|
|
1416
|
+
decodeResult.formatted.items.push({
|
|
1417
|
+
type: "status",
|
|
1418
|
+
code: "ROUTE_STATUS",
|
|
1419
|
+
label: "Route Status",
|
|
1420
|
+
value: "Route Filed"
|
|
1421
|
+
});
|
|
1422
|
+
decodeResult.raw.route_status = "RF";
|
|
1423
|
+
if (header.length > 2) {
|
|
1424
|
+
addRoute(decodeResult, header.substring(2));
|
|
1469
1425
|
}
|
|
1470
|
-
|
|
1471
|
-
decodeResult.
|
|
1472
|
-
decodeResult.
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1426
|
+
} else if (header.startsWith("RP")) {
|
|
1427
|
+
decodeResult.raw.route_status = "RP";
|
|
1428
|
+
decodeResult.formatted.items.push({
|
|
1429
|
+
type: "status",
|
|
1430
|
+
code: "ROUTE_STATUS",
|
|
1431
|
+
label: "Route Status",
|
|
1432
|
+
value: "Route Planned"
|
|
1433
|
+
});
|
|
1434
|
+
decodeResult.raw.route_status = header;
|
|
1435
|
+
} else if (header.startsWith("RI")) {
|
|
1436
|
+
decodeResult.raw.route_status = "RI";
|
|
1437
|
+
decodeResult.formatted.items.push({
|
|
1438
|
+
type: "status",
|
|
1439
|
+
code: "ROUTE_STATUS",
|
|
1440
|
+
label: "Route Status",
|
|
1441
|
+
value: "Route Inactive"
|
|
1442
|
+
});
|
|
1443
|
+
} else {
|
|
1444
|
+
decodeResult.remaining.text += header;
|
|
1445
|
+
allKnownFields = false;
|
|
1478
1446
|
}
|
|
1479
|
-
|
|
1480
|
-
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(hhmmss));
|
|
1481
|
-
const fl = parts[1].substring(6, 9);
|
|
1482
|
-
ResultFormatter.altitude(decodeResult, Number(fl) * 100);
|
|
1483
|
-
const next = parts[1].substring(9);
|
|
1484
|
-
ResultFormatter.route(decodeResult, { waypoints: [{ name: next.trim() }] });
|
|
1485
|
-
decodeResult.remaining.text = parts.slice(2).join(",");
|
|
1486
|
-
decodeResult.decoded = true;
|
|
1487
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
1488
|
-
return decodeResult;
|
|
1447
|
+
return allKnownFields;
|
|
1489
1448
|
}
|
|
1490
1449
|
};
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
};
|
|
1450
|
+
function addArrivalAirport(decodeResult, value) {
|
|
1451
|
+
ResultFormatter.arrivalAirport(decodeResult, value);
|
|
1452
|
+
}
|
|
1453
|
+
function addDepartureAirport(decodeResult, value) {
|
|
1454
|
+
ResultFormatter.departureAirport(decodeResult, value);
|
|
1455
|
+
}
|
|
1456
|
+
function addRunway(decodeResult, value) {
|
|
1457
|
+
if (value.length === 8) {
|
|
1458
|
+
ResultFormatter.arrivalRunway(decodeResult, value.substring(4, 7));
|
|
1501
1459
|
}
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1460
|
+
ResultFormatter.departureRunway(decodeResult, value.substring(0, 3));
|
|
1461
|
+
}
|
|
1462
|
+
function addRoute(decodeResult, value) {
|
|
1463
|
+
const route = value.split(".");
|
|
1464
|
+
ResultFormatter.route(decodeResult, { waypoints: route.map((leg) => RouteUtils.getWaypoint(leg)) });
|
|
1465
|
+
}
|
|
1466
|
+
function addProcedure(decodeResult, value, type) {
|
|
1467
|
+
if (decodeResult.raw.procedures === void 0) {
|
|
1468
|
+
decodeResult.raw.procedures = [];
|
|
1469
|
+
}
|
|
1470
|
+
const data = value.split(".");
|
|
1471
|
+
let waypoints;
|
|
1472
|
+
if (data.length > 1) {
|
|
1473
|
+
waypoints = data.slice(1).map((leg) => RouteUtils.getWaypoint(leg));
|
|
1474
|
+
}
|
|
1475
|
+
const route = { name: data[0], waypoints };
|
|
1476
|
+
decodeResult.raw.procedures.push({ type, route });
|
|
1477
|
+
const procedureName = type.substring(0, 1).toUpperCase() + type.slice(1);
|
|
1478
|
+
let procedureValue = route.name;
|
|
1479
|
+
decodeResult.formatted.items.push({
|
|
1480
|
+
type: `procedure`,
|
|
1481
|
+
code: "proc",
|
|
1482
|
+
label: `${procedureName} Procedure`,
|
|
1483
|
+
value: RouteUtils.routeToString(route)
|
|
1484
|
+
});
|
|
1485
|
+
}
|
|
1486
|
+
function addCompanyRoute(decodeResult, value) {
|
|
1487
|
+
const segments = value.split(".");
|
|
1488
|
+
const parens_idx = segments[0].indexOf("(");
|
|
1489
|
+
let name;
|
|
1490
|
+
let runway;
|
|
1491
|
+
if (parens_idx === -1) {
|
|
1492
|
+
name = segments[0];
|
|
1493
|
+
} else {
|
|
1494
|
+
name = segments[0].slice(0, parens_idx);
|
|
1495
|
+
runway = segments[0].slice(parens_idx + 1, segments[0].indexOf(")"));
|
|
1496
|
+
}
|
|
1497
|
+
let waypoints;
|
|
1498
|
+
if (segments.length > 1) {
|
|
1499
|
+
waypoints = segments.slice(1).map((leg) => RouteUtils.getWaypoint(leg));
|
|
1500
|
+
}
|
|
1501
|
+
decodeResult.raw.company_route = {
|
|
1502
|
+
name,
|
|
1503
|
+
runway,
|
|
1504
|
+
waypoints
|
|
1505
|
+
};
|
|
1506
|
+
decodeResult.formatted.items.push({
|
|
1507
|
+
type: "company_route",
|
|
1508
|
+
code: "CR",
|
|
1509
|
+
label: "Company Route",
|
|
1510
|
+
value: RouteUtils.routeToString(decodeResult.raw.company_route)
|
|
1511
|
+
});
|
|
1512
|
+
}
|
|
1513
|
+
|
|
1514
|
+
// lib/utils/h1_helper.ts
|
|
1515
|
+
var H1Helper = class _H1Helper {
|
|
1516
|
+
static decodeH1Message(decodeResult, message) {
|
|
1517
|
+
const checksum = message.slice(-4);
|
|
1518
|
+
const data = message.slice(0, message.length - 4);
|
|
1519
|
+
const fields = data.split("/");
|
|
1520
|
+
const canDecode = parseMessageType(decodeResult, fields[0]);
|
|
1521
|
+
if (!canDecode) {
|
|
1513
1522
|
decodeResult.decoded = false;
|
|
1514
1523
|
decodeResult.decoder.decodeLevel = "none";
|
|
1515
|
-
return
|
|
1524
|
+
return false;
|
|
1516
1525
|
}
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1526
|
+
for (let i = 1; i < fields.length; ++i) {
|
|
1527
|
+
if (fields[i].startsWith("FN")) {
|
|
1528
|
+
decodeResult.raw.flight_number = fields[i].substring(2);
|
|
1529
|
+
} else if (fields[i].startsWith("SN")) {
|
|
1530
|
+
decodeResult.raw.serial_number = fields[i].substring(2);
|
|
1531
|
+
} else if (fields[i].startsWith("DC")) {
|
|
1532
|
+
processDC(decodeResult, fields[i].substring(2).split(","));
|
|
1533
|
+
} else if (fields[i].startsWith("TS")) {
|
|
1534
|
+
_H1Helper.processTS(decodeResult, fields[i].substring(2).split(","));
|
|
1535
|
+
} else if (fields[i].startsWith("PS")) {
|
|
1536
|
+
_H1Helper.processPS(decodeResult, fields[i].substring(2).split(","));
|
|
1537
|
+
} else if (fields[i].startsWith("DT")) {
|
|
1538
|
+
const data2 = fields[i].substring(2).split(",");
|
|
1539
|
+
processDT(decodeResult, data2);
|
|
1540
|
+
} else if (fields[i].startsWith("ID")) {
|
|
1541
|
+
processIdentification(decodeResult, fields[i].substring(2).split(","));
|
|
1542
|
+
} else if (fields[i].startsWith("LR")) {
|
|
1543
|
+
const data2 = fields[i].substring(2).split(",");
|
|
1544
|
+
processLR(decodeResult, data2);
|
|
1545
|
+
} else if (fields[i].startsWith("RI") || fields[i].startsWith("RF") || fields[i].startsWith("RP")) {
|
|
1546
|
+
FlightPlanUtils.processFlightPlan(decodeResult, fields[i].split(":"));
|
|
1547
|
+
} else if (fields[i].startsWith("PR")) {
|
|
1548
|
+
ResultFormatter.unknown(decodeResult, fields[i], "/");
|
|
1549
|
+
} else if (fields[i].startsWith("AF")) {
|
|
1550
|
+
processAirField(decodeResult, fields[i].substring(2).split(","));
|
|
1551
|
+
} else if (fields[i].startsWith("TD")) {
|
|
1552
|
+
processTimeOfDeparture(decodeResult, fields[i].substring(2).split(","));
|
|
1553
|
+
} else if (fields[i].startsWith("FX")) {
|
|
1554
|
+
ResultFormatter.freetext(decodeResult, fields[i].substring(2));
|
|
1555
|
+
} else if (fields[i].startsWith("ET")) {
|
|
1556
|
+
if (fields[i].length === 7) {
|
|
1557
|
+
ResultFormatter.day(decodeResult, Number(fields[i].substring(2, 3)));
|
|
1558
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[i].substring(3)));
|
|
1559
|
+
} else if (fields[i].length === 8) {
|
|
1560
|
+
ResultFormatter.day(decodeResult, Number(fields[i].substring(2, 4)));
|
|
1561
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[i].substring(4)));
|
|
1562
|
+
} else {
|
|
1563
|
+
ResultFormatter.unknown(decodeResult, fields[i], "/");
|
|
1564
|
+
}
|
|
1565
|
+
} else if (fields[i].startsWith("WD")) {
|
|
1566
|
+
processWindData(decodeResult, fields[i].substring(2));
|
|
1567
|
+
} else {
|
|
1568
|
+
ResultFormatter.unknown(decodeResult, fields[i], "/");
|
|
1569
|
+
}
|
|
1523
1570
|
}
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
longitude: Number(data.get("LON"))
|
|
1527
|
-
};
|
|
1528
|
-
data.delete("LAT");
|
|
1529
|
-
data.delete("LON");
|
|
1530
|
-
ResultFormatter.position(decodeResult, position);
|
|
1531
|
-
const utc = data.get("UTC");
|
|
1532
|
-
if (utc) {
|
|
1533
|
-
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(utc));
|
|
1534
|
-
data.delete("UTC");
|
|
1571
|
+
if (decodeResult.formatted.items.length > 0) {
|
|
1572
|
+
ResultFormatter.checksum(decodeResult, checksum);
|
|
1535
1573
|
}
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1574
|
+
return true;
|
|
1575
|
+
}
|
|
1576
|
+
static processPS(decodeResult, data) {
|
|
1577
|
+
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[0]);
|
|
1578
|
+
if (position) {
|
|
1579
|
+
decodeResult.raw.position = position;
|
|
1580
|
+
decodeResult.formatted.items.push({
|
|
1581
|
+
type: "aircraft_position",
|
|
1582
|
+
code: "POS",
|
|
1583
|
+
label: "Aircraft Position",
|
|
1584
|
+
value: CoordinateUtils.coordinateString(position)
|
|
1585
|
+
});
|
|
1540
1586
|
}
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
ResultFormatter.
|
|
1544
|
-
|
|
1587
|
+
if (data.length === 9) {
|
|
1588
|
+
processRoute(decodeResult, data[3], data[1], data[5], data[4], void 0);
|
|
1589
|
+
ResultFormatter.altitude(decodeResult, Number(data[2]) * 100);
|
|
1590
|
+
ResultFormatter.temperature(decodeResult, data[6]);
|
|
1591
|
+
ResultFormatter.unknown(decodeResult, data[7]);
|
|
1592
|
+
ResultFormatter.unknown(decodeResult, data[8]);
|
|
1545
1593
|
}
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1594
|
+
if (data.length === 14) {
|
|
1595
|
+
ResultFormatter.altitude(decodeResult, Number(data[3]) * 100);
|
|
1596
|
+
processRoute(decodeResult, data[1], data[2], data[4], data[5], data[6]);
|
|
1597
|
+
ResultFormatter.temperature(decodeResult, data[7]);
|
|
1598
|
+
ResultFormatter.unknownArr(decodeResult, data.slice(8));
|
|
1550
1599
|
}
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1600
|
+
}
|
|
1601
|
+
static processPosition(decodeResult, data) {
|
|
1602
|
+
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[0]);
|
|
1603
|
+
if (position) {
|
|
1604
|
+
ResultFormatter.position(decodeResult, position);
|
|
1554
1605
|
}
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1606
|
+
if (data.length >= 10) {
|
|
1607
|
+
ResultFormatter.altitude(decodeResult, Number(data[3]) * 100);
|
|
1608
|
+
processRoute(decodeResult, data[1], data[2], data[4], data[5], data[6]);
|
|
1609
|
+
ResultFormatter.temperature(decodeResult, data[7]);
|
|
1610
|
+
ResultFormatter.unknown(decodeResult, data[8]);
|
|
1611
|
+
ResultFormatter.unknown(decodeResult, data[9]);
|
|
1612
|
+
}
|
|
1613
|
+
if (data.length >= 14) {
|
|
1614
|
+
ResultFormatter.unknownArr(decodeResult, data.slice(10));
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1617
|
+
static processTS(decodeResult, data) {
|
|
1618
|
+
let time = DateTimeUtils.convertDateTimeToEpoch(data[0], data[1]);
|
|
1619
|
+
if (Number.isNaN(time)) {
|
|
1620
|
+
const date = data[1].substring(2, 4) + data[1].substring(0, 2) + data[1].substring(4, 6);
|
|
1621
|
+
time = DateTimeUtils.convertDateTimeToEpoch(data[0], date);
|
|
1622
|
+
}
|
|
1623
|
+
decodeResult.raw.message_date = data[1];
|
|
1624
|
+
decodeResult.raw.message_timestamp = time;
|
|
1559
1625
|
}
|
|
1560
1626
|
};
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
labels: ["20"],
|
|
1568
|
-
preambles: ["POS"]
|
|
1569
|
-
};
|
|
1627
|
+
function processAirField(decodeResult, data) {
|
|
1628
|
+
if (data.length === 2) {
|
|
1629
|
+
ResultFormatter.departureAirport(decodeResult, data[0]);
|
|
1630
|
+
ResultFormatter.arrivalAirport(decodeResult, data[1]);
|
|
1631
|
+
} else {
|
|
1632
|
+
ResultFormatter.unknown(decodeResult, data.join(","), "AF/");
|
|
1570
1633
|
}
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
decodeResult.
|
|
1575
|
-
decodeResult.
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
}
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1634
|
+
}
|
|
1635
|
+
function processTimeOfDeparture(decodeResult, data) {
|
|
1636
|
+
if (data.length === 2) {
|
|
1637
|
+
decodeResult.raw.plannedDepartureTime = data[0];
|
|
1638
|
+
decodeResult.formatted.items.push({
|
|
1639
|
+
type: "ptd",
|
|
1640
|
+
code: "ptd",
|
|
1641
|
+
label: "Planned Departure Time",
|
|
1642
|
+
value: `YYYY-MM-${data[0].substring(0, 2)}T${data[0].substring(2, 4)}:${data[0].substring(4)}:00Z`
|
|
1643
|
+
});
|
|
1644
|
+
decodeResult.raw.plannedDepartureTime = data[1];
|
|
1645
|
+
decodeResult.formatted.items.push({
|
|
1646
|
+
type: "etd",
|
|
1647
|
+
code: "etd",
|
|
1648
|
+
label: "Estimated Departure Time",
|
|
1649
|
+
value: `${data[1].substring(0, 2)}:${data[1].substring(2)}`
|
|
1650
|
+
});
|
|
1651
|
+
} else {
|
|
1652
|
+
ResultFormatter.unknown(decodeResult, data.join(","), "/TD");
|
|
1653
|
+
}
|
|
1654
|
+
}
|
|
1655
|
+
function processIdentification(decodeResult, data) {
|
|
1656
|
+
ResultFormatter.tail(decodeResult, data[0]);
|
|
1657
|
+
if (data.length > 1) {
|
|
1658
|
+
ResultFormatter.flightNumber(decodeResult, data[1]);
|
|
1659
|
+
}
|
|
1660
|
+
if (data.length > 2) {
|
|
1661
|
+
decodeResult.raw.mission_number = data[2];
|
|
1662
|
+
}
|
|
1663
|
+
}
|
|
1664
|
+
function processDT(decodeResult, data) {
|
|
1665
|
+
if (!decodeResult.raw.arrival_icao) {
|
|
1666
|
+
ResultFormatter.arrivalAirport(decodeResult, data[0]);
|
|
1667
|
+
} else if (decodeResult.raw.arrival_icao != data[0]) {
|
|
1668
|
+
ResultFormatter.unknownArr(decodeResult, data);
|
|
1669
|
+
}
|
|
1670
|
+
if (data.length > 1) {
|
|
1671
|
+
ResultFormatter.arrivalRunway(decodeResult, data[1]);
|
|
1672
|
+
}
|
|
1673
|
+
if (data.length > 2) {
|
|
1674
|
+
ResultFormatter.currentFuel(decodeResult, Number(data[2]));
|
|
1675
|
+
}
|
|
1676
|
+
if (data.length > 3) {
|
|
1677
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[3]));
|
|
1678
|
+
}
|
|
1679
|
+
if (data.length > 4) {
|
|
1680
|
+
ResultFormatter.remainingFuel(decodeResult, Number(data[4]));
|
|
1681
|
+
}
|
|
1682
|
+
if (data.length > 5) {
|
|
1683
|
+
ResultFormatter.unknownArr(decodeResult, data);
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1686
|
+
function processLR(decodeResult, data) {
|
|
1687
|
+
if (data.length === 19) {
|
|
1688
|
+
ResultFormatter.unknown(decodeResult, data[1]);
|
|
1689
|
+
ResultFormatter.flightNumber(decodeResult, data[2]);
|
|
1690
|
+
ResultFormatter.departureAirport(decodeResult, data[3]);
|
|
1691
|
+
ResultFormatter.arrivalAirport(decodeResult, data[4]);
|
|
1692
|
+
ResultFormatter.arrivalRunway(decodeResult, data[5]);
|
|
1693
|
+
ResultFormatter.unknown(decodeResult, data.slice(6, 19).join(","));
|
|
1694
|
+
} else {
|
|
1695
|
+
ResultFormatter.unknown(decodeResult, data.join(","));
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
function parseMessageType(decodeResult, messageType) {
|
|
1699
|
+
const parts = messageType.split("#");
|
|
1700
|
+
if (parts.length == 1) {
|
|
1701
|
+
if (parts[0].startsWith("POS")) {
|
|
1702
|
+
H1Helper.processPosition(decodeResult, parts[0].substring(3).split(","));
|
|
1703
|
+
return processMessageType(decodeResult, "POS");
|
|
1704
|
+
} else if (parts[0].length === 13) {
|
|
1705
|
+
if (processMessageType(decodeResult, parts[0].substring(10))) {
|
|
1706
|
+
ResultFormatter.unknown(decodeResult, parts[0].substring(0, 4));
|
|
1707
|
+
ResultFormatter.flightNumber(decodeResult, parts[0].slice(4, 10));
|
|
1708
|
+
return true;
|
|
1600
1709
|
}
|
|
1601
|
-
decodeResult.decoded = false;
|
|
1602
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
1603
1710
|
}
|
|
1604
|
-
return decodeResult;
|
|
1711
|
+
return processMessageType(decodeResult, parts[0].substring(0, 3));
|
|
1712
|
+
} else if (parts.length == 2) {
|
|
1713
|
+
if (parts[0].length > 0) {
|
|
1714
|
+
ResultFormatter.unknown(decodeResult, parts[0].substring(0, 4));
|
|
1715
|
+
ResultFormatter.flightNumber(decodeResult, parts[0].substring(4));
|
|
1716
|
+
ResultFormatter.unknown(decodeResult, parts[1].length == 5 ? parts[1].substring(0, 2) : parts[1].substring(0, 3), "#");
|
|
1717
|
+
}
|
|
1718
|
+
const type = parts[1].length == 5 ? parts[1].substring(2, 5) : parts[1].substring(3, 6);
|
|
1719
|
+
if (parts[1].substring(3, 6) === "POS" && parts[1].length > 6) {
|
|
1720
|
+
H1Helper.processPosition(decodeResult, parts[1].substring(6).split(","));
|
|
1721
|
+
}
|
|
1722
|
+
return processMessageType(decodeResult, type);
|
|
1723
|
+
} else {
|
|
1724
|
+
ResultFormatter.unknown(decodeResult, messageType);
|
|
1725
|
+
return false;
|
|
1605
1726
|
}
|
|
1606
|
-
}
|
|
1727
|
+
}
|
|
1728
|
+
function processMessageType(decodeResult, type) {
|
|
1729
|
+
if (type === "FPN") {
|
|
1730
|
+
decodeResult.formatted.description = "Flight Plan";
|
|
1731
|
+
} else if (type === "FTX") {
|
|
1732
|
+
decodeResult.formatted.description = "Free Text";
|
|
1733
|
+
} else if (type === "INI") {
|
|
1734
|
+
decodeResult.formatted.description = "Flight Plan Initial Report";
|
|
1735
|
+
} else if (type === "POS") {
|
|
1736
|
+
decodeResult.formatted.description = "Position Report";
|
|
1737
|
+
} else if (type === "PRG") {
|
|
1738
|
+
decodeResult.formatted.description = "Progress Report";
|
|
1739
|
+
} else if (type === "PWI") {
|
|
1740
|
+
decodeResult.formatted.description = "Weather Report";
|
|
1741
|
+
} else {
|
|
1742
|
+
decodeResult.formatted.description = "Unknown H1 Message";
|
|
1743
|
+
return false;
|
|
1744
|
+
}
|
|
1745
|
+
return true;
|
|
1746
|
+
}
|
|
1747
|
+
function processDC(decodeResult, data) {
|
|
1748
|
+
decodeResult.raw.message_date = data[0];
|
|
1749
|
+
if (data.length === 1) {
|
|
1750
|
+
} else if (data.length === 2) {
|
|
1751
|
+
const date = data[0].substring(2, 4) + data[0].substring(0, 2) + data[0].substring(4, 6);
|
|
1752
|
+
const time = DateTimeUtils.convertDateTimeToEpoch(data[1], data[0]);
|
|
1753
|
+
decodeResult.raw.message_timestamp = time;
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
function processRoute(decodeResult, last, time, next, eta, then, date) {
|
|
1757
|
+
const lastTime = date ? DateTimeUtils.convertDateTimeToEpoch(time, date) : DateTimeUtils.convertHHMMSSToTod(time);
|
|
1758
|
+
const nextTime = date ? DateTimeUtils.convertDateTimeToEpoch(eta, date) : DateTimeUtils.convertHHMMSSToTod(eta);
|
|
1759
|
+
const timeFormat = date ? "epoch" : "tod";
|
|
1760
|
+
const lastWaypoint = RouteUtils.getWaypoint(last);
|
|
1761
|
+
lastWaypoint.time = lastTime;
|
|
1762
|
+
lastWaypoint.timeFormat = timeFormat;
|
|
1763
|
+
const nextWaypoint = RouteUtils.getWaypoint(next);
|
|
1764
|
+
nextWaypoint.time = nextTime;
|
|
1765
|
+
nextWaypoint.timeFormat = timeFormat;
|
|
1766
|
+
const thenWaypoint = RouteUtils.getWaypoint(then || "?");
|
|
1767
|
+
const waypoints = [lastWaypoint, nextWaypoint, thenWaypoint];
|
|
1768
|
+
decodeResult.raw.route = { waypoints };
|
|
1769
|
+
decodeResult.formatted.items.push({
|
|
1770
|
+
type: "aircraft_route",
|
|
1771
|
+
code: "ROUTE",
|
|
1772
|
+
label: "Aircraft Route",
|
|
1773
|
+
value: RouteUtils.routeToString(decodeResult.raw.route)
|
|
1774
|
+
});
|
|
1775
|
+
}
|
|
1776
|
+
function processWindData(decodeResult, message) {
|
|
1777
|
+
if (decodeResult.raw.wind_data === void 0) {
|
|
1778
|
+
decodeResult.raw.wind_data = [];
|
|
1779
|
+
}
|
|
1780
|
+
const flightLevel = Number(message.slice(0, 3));
|
|
1781
|
+
const fields = message.slice(4).split(".");
|
|
1782
|
+
fields.forEach((field) => {
|
|
1783
|
+
const data = field.split(",");
|
|
1784
|
+
const waypoint = data[0];
|
|
1785
|
+
const windData = data[1];
|
|
1786
|
+
const windDirection = Number(windData.slice(0, 3));
|
|
1787
|
+
const windSpeed = Number(windData.slice(3));
|
|
1788
|
+
if (data.length === 3) {
|
|
1789
|
+
const tempData = data[2];
|
|
1790
|
+
const tempFlightLevel = Number(tempData.slice(0, 3));
|
|
1791
|
+
const tempString = tempData.slice(3);
|
|
1792
|
+
const tempDegrees = Number(tempString.substring(1)) * (tempString.charAt(0) === "M" ? -1 : 1);
|
|
1793
|
+
decodeResult.raw.wind_data.push({
|
|
1794
|
+
waypoint,
|
|
1795
|
+
flightLevel,
|
|
1796
|
+
windDirection,
|
|
1797
|
+
windSpeed,
|
|
1798
|
+
temperature: {
|
|
1799
|
+
flightLevel: tempFlightLevel,
|
|
1800
|
+
degreesC: tempDegrees
|
|
1801
|
+
}
|
|
1802
|
+
});
|
|
1803
|
+
decodeResult.formatted.items.push({
|
|
1804
|
+
type: "wind_data",
|
|
1805
|
+
code: "WIND",
|
|
1806
|
+
label: "Wind Data",
|
|
1807
|
+
value: `${waypoint} at FL${flightLevel}: ${windDirection}\xB0 at ${windSpeed}kt, ${tempDegrees}\xB0C at FL${tempFlightLevel}`
|
|
1808
|
+
});
|
|
1809
|
+
} else {
|
|
1810
|
+
decodeResult.raw.wind_data.push({
|
|
1811
|
+
waypoint,
|
|
1812
|
+
flightLevel,
|
|
1813
|
+
windDirection,
|
|
1814
|
+
windSpeed
|
|
1815
|
+
});
|
|
1816
|
+
decodeResult.formatted.items.push({
|
|
1817
|
+
type: "wind_data",
|
|
1818
|
+
code: "WIND",
|
|
1819
|
+
label: "Wind Data",
|
|
1820
|
+
value: `${waypoint} at FL${flightLevel}: ${windDirection}\xB0 at ${windSpeed}kt`
|
|
1821
|
+
});
|
|
1822
|
+
}
|
|
1823
|
+
});
|
|
1824
|
+
}
|
|
1607
1825
|
|
|
1608
|
-
// lib/plugins/
|
|
1609
|
-
var
|
|
1610
|
-
name = "label-
|
|
1826
|
+
// lib/plugins/Label_1J_2J_FTX.ts
|
|
1827
|
+
var Label_1J_2J_FTX = class extends DecoderPlugin {
|
|
1828
|
+
name = "label-1j-2j-ftx";
|
|
1611
1829
|
qualifiers() {
|
|
1612
1830
|
return {
|
|
1613
|
-
labels: ["
|
|
1614
|
-
preambles: ["POS"]
|
|
1831
|
+
labels: ["1J", "2J"]
|
|
1615
1832
|
};
|
|
1616
1833
|
}
|
|
1617
1834
|
decode(message, options = {}) {
|
|
1618
|
-
|
|
1835
|
+
let decodeResult = this.defaultResult();
|
|
1619
1836
|
decodeResult.decoder.name = this.name;
|
|
1620
|
-
decodeResult.formatted.description = "Position Report";
|
|
1621
1837
|
decodeResult.message = message;
|
|
1622
|
-
|
|
1623
|
-
const
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[2]));
|
|
1628
|
-
ResultFormatter.altitude(decodeResult, Number(fields[3]));
|
|
1629
|
-
ResultFormatter.temperature(decodeResult, fields[6].replace(/ /g, ""));
|
|
1630
|
-
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[7]));
|
|
1631
|
-
ResultFormatter.arrivalAirport(decodeResult, fields[8]);
|
|
1632
|
-
ResultFormatter.unknownArr(decodeResult, [fields[1], fields[4], fields[5]]);
|
|
1633
|
-
decodeResult.decoded = true;
|
|
1634
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
1635
|
-
} else {
|
|
1838
|
+
const msg = message.text.replace(/\n|\r/g, "");
|
|
1839
|
+
const decoded = H1Helper.decodeH1Message(decodeResult, msg);
|
|
1840
|
+
decodeResult.decoded = decoded;
|
|
1841
|
+
decodeResult.decoder.decodeLevel = !decodeResult.remaining.text ? "full" : "partial";
|
|
1842
|
+
if (decodeResult.formatted.items.length === 0) {
|
|
1636
1843
|
if (options.debug) {
|
|
1637
|
-
console.log(`
|
|
1844
|
+
console.log(`Decoder: Unknown 1J/2J message: ${message.text}`);
|
|
1638
1845
|
}
|
|
1846
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
1639
1847
|
decodeResult.decoded = false;
|
|
1640
1848
|
decodeResult.decoder.decodeLevel = "none";
|
|
1641
1849
|
}
|
|
1642
1850
|
return decodeResult;
|
|
1643
1851
|
}
|
|
1644
1852
|
};
|
|
1645
|
-
function processPosition(decodeResult, value) {
|
|
1646
|
-
if (value.length !== 16 && value[0] !== "N" && value[0] !== "S" && value[8] !== "W" && value[8] !== "E") {
|
|
1647
|
-
return;
|
|
1648
|
-
}
|
|
1649
|
-
const latDir = value[0] === "N" ? 1 : -1;
|
|
1650
|
-
const lonDir = value[8] === "E" ? 1 : -1;
|
|
1651
|
-
const position = {
|
|
1652
|
-
latitude: latDir * Number(value.substring(1, 7)),
|
|
1653
|
-
longitude: lonDir * Number(value.substring(9, 15))
|
|
1654
|
-
};
|
|
1655
|
-
ResultFormatter.position(decodeResult, position);
|
|
1656
|
-
}
|
|
1657
1853
|
|
|
1658
|
-
// lib/plugins/
|
|
1659
|
-
var
|
|
1660
|
-
name = "label-
|
|
1854
|
+
// lib/plugins/Label_1M_Slash.ts
|
|
1855
|
+
var Label_1M_Slash = class extends DecoderPlugin {
|
|
1856
|
+
name = "label-1m-slash";
|
|
1661
1857
|
qualifiers() {
|
|
1662
1858
|
return {
|
|
1663
|
-
labels: ["
|
|
1664
|
-
preambles: ["
|
|
1859
|
+
labels: ["1M"],
|
|
1860
|
+
preambles: ["/"]
|
|
1665
1861
|
};
|
|
1666
1862
|
}
|
|
1667
1863
|
decode(message, options = {}) {
|
|
1668
1864
|
const decodeResult = this.defaultResult();
|
|
1669
1865
|
decodeResult.decoder.name = this.name;
|
|
1670
|
-
decodeResult.formatted.description = "
|
|
1866
|
+
decodeResult.formatted.description = "ETA Report";
|
|
1671
1867
|
decodeResult.message = message;
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
if (fields.length != 2) {
|
|
1675
|
-
decodeResult.decoded = false;
|
|
1676
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
1677
|
-
return decodeResult;
|
|
1678
|
-
}
|
|
1679
|
-
ResultFormatter.flightNumber(decodeResult, fields[0]);
|
|
1680
|
-
ResultFormatter.departureDay(decodeResult, Number(fields[1].substring(0, 2)));
|
|
1681
|
-
ResultFormatter.arrivalDay(decodeResult, Number(fields[1].substring(2, 4)));
|
|
1682
|
-
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(4, 8)));
|
|
1683
|
-
ResultFormatter.departureAirport(decodeResult, fields[1].substring(8, 12));
|
|
1684
|
-
ResultFormatter.arrivalAirport(decodeResult, fields[1].substring(12, 16));
|
|
1685
|
-
ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(16, 22)));
|
|
1686
|
-
ResultFormatter.unknown(decodeResult, fields[1].substring(22));
|
|
1687
|
-
decodeResult.decoded = true;
|
|
1688
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
1689
|
-
} else if (message.text.startsWith("OFF02\r\n")) {
|
|
1690
|
-
const fields = message.text.substring(7).split(",");
|
|
1691
|
-
if (fields.length != 4) {
|
|
1692
|
-
decodeResult.decoded = false;
|
|
1693
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
1694
|
-
return decodeResult;
|
|
1695
|
-
}
|
|
1696
|
-
ResultFormatter.departureAirport(decodeResult, fields[0]);
|
|
1697
|
-
ResultFormatter.arrivalAirport(decodeResult, fields[1]);
|
|
1698
|
-
ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[2]));
|
|
1699
|
-
ResultFormatter.unknown(decodeResult, fields[3]);
|
|
1700
|
-
decodeResult.decoded = true;
|
|
1701
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
1702
|
-
} else if (message.text.startsWith("OFF02")) {
|
|
1703
|
-
const fields = message.text.substring(5).split("/");
|
|
1704
|
-
if (fields.length != 2) {
|
|
1705
|
-
decodeResult.decoded = false;
|
|
1706
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
1707
|
-
return decodeResult;
|
|
1708
|
-
}
|
|
1709
|
-
ResultFormatter.flightNumber(decodeResult, fields[0]);
|
|
1710
|
-
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(fields[1].substring(0, 14));
|
|
1711
|
-
if (position) {
|
|
1712
|
-
ResultFormatter.position(decodeResult, position);
|
|
1713
|
-
}
|
|
1714
|
-
ResultFormatter.day(decodeResult, Number(fields[1].substring(14, 16)));
|
|
1715
|
-
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(16, 20)));
|
|
1716
|
-
ResultFormatter.departureAirport(decodeResult, fields[1].substring(20, 24));
|
|
1717
|
-
ResultFormatter.arrivalAirport(decodeResult, fields[1].substring(24, 28));
|
|
1718
|
-
ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(28, 32)));
|
|
1719
|
-
ResultFormatter.unknown(decodeResult, fields[1].substring(32, 36));
|
|
1720
|
-
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(36, 40)));
|
|
1721
|
-
decodeResult.decoded = true;
|
|
1722
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
1723
|
-
} else {
|
|
1868
|
+
const results = message.text.split(/\n|\//).slice(1);
|
|
1869
|
+
if (results) {
|
|
1724
1870
|
if (options.debug) {
|
|
1725
|
-
console.log(`
|
|
1871
|
+
console.log(`Label 1M ETA: results`);
|
|
1872
|
+
console.log(results);
|
|
1726
1873
|
}
|
|
1727
|
-
decodeResult.
|
|
1728
|
-
decodeResult
|
|
1874
|
+
decodeResult.raw.flight_number = results[0];
|
|
1875
|
+
ResultFormatter.departureAirport(decodeResult, results[3]);
|
|
1876
|
+
ResultFormatter.arrivalAirport(decodeResult, results[4]);
|
|
1877
|
+
ResultFormatter.alternateAirport(decodeResult, results[5]);
|
|
1878
|
+
ResultFormatter.arrivalRunway(decodeResult, results[8].replace(results[4], ""));
|
|
1879
|
+
const yymmdd = results[2];
|
|
1880
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertDateTimeToEpoch(results[7] + "00", yymmdd.substring(2, 4) + yymmdd.substring(4, 6) + yymmdd.substring(0, 2)), "epoch");
|
|
1729
1881
|
}
|
|
1882
|
+
decodeResult.decoded = true;
|
|
1883
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
1730
1884
|
return decodeResult;
|
|
1731
1885
|
}
|
|
1732
1886
|
};
|
|
1733
1887
|
|
|
1734
|
-
// lib/plugins/
|
|
1735
|
-
var
|
|
1736
|
-
|
|
1888
|
+
// lib/plugins/Label_1L_3-line.ts
|
|
1889
|
+
var Label_1L_3Line = class extends DecoderPlugin {
|
|
1890
|
+
// eslint-disable-line camelcase
|
|
1891
|
+
name = "label-1l-3-line";
|
|
1737
1892
|
qualifiers() {
|
|
1738
1893
|
return {
|
|
1739
|
-
labels: ["
|
|
1740
|
-
preambles: ["N", "S"]
|
|
1894
|
+
labels: ["1L"]
|
|
1741
1895
|
};
|
|
1742
1896
|
}
|
|
1743
1897
|
decode(message, options = {}) {
|
|
@@ -1745,653 +1899,618 @@ var Label_22_POS = class extends DecoderPlugin {
|
|
|
1745
1899
|
decodeResult.decoder.name = this.name;
|
|
1746
1900
|
decodeResult.formatted.description = "Position Report";
|
|
1747
1901
|
decodeResult.message = message;
|
|
1748
|
-
const
|
|
1749
|
-
if (
|
|
1902
|
+
const lines = message.text.split("\r\n");
|
|
1903
|
+
if (lines.length !== 3) {
|
|
1750
1904
|
if (options.debug) {
|
|
1751
|
-
console.log(`
|
|
1905
|
+
console.log(`Decoder: Unknown 1L message: ${message.text}`);
|
|
1752
1906
|
}
|
|
1907
|
+
decodeResult.remaining.text = message.text;
|
|
1753
1908
|
decodeResult.decoded = false;
|
|
1754
1909
|
decodeResult.decoder.decodeLevel = "none";
|
|
1755
1910
|
return decodeResult;
|
|
1756
1911
|
}
|
|
1757
|
-
const
|
|
1758
|
-
const
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1912
|
+
const parts = message.text.replaceAll("\r\n", "/").split("/");
|
|
1913
|
+
const data = /* @__PURE__ */ new Map();
|
|
1914
|
+
data.set("", parts[0]);
|
|
1915
|
+
for (let i = 1; i < parts.length; i++) {
|
|
1916
|
+
const part = parts[i].split(" ");
|
|
1917
|
+
data.set(part[0], part.slice(1).join(" "));
|
|
1918
|
+
}
|
|
1919
|
+
const dep = data.get("DEP");
|
|
1920
|
+
if (dep) {
|
|
1921
|
+
ResultFormatter.departureAirport(decodeResult, dep);
|
|
1922
|
+
data.delete("DEP");
|
|
1923
|
+
}
|
|
1924
|
+
const des = data.get("DES");
|
|
1925
|
+
if (des) {
|
|
1926
|
+
ResultFormatter.arrivalAirport(decodeResult, des);
|
|
1927
|
+
data.delete("DES");
|
|
1928
|
+
}
|
|
1929
|
+
const eta = data.get("ETA");
|
|
1930
|
+
if (eta) {
|
|
1931
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(eta));
|
|
1932
|
+
data.delete("ETA");
|
|
1933
|
+
}
|
|
1934
|
+
const alt = data.get("ALT");
|
|
1935
|
+
if (alt) {
|
|
1936
|
+
ResultFormatter.altitude(decodeResult, Number(alt));
|
|
1937
|
+
data.delete("ALT");
|
|
1938
|
+
}
|
|
1939
|
+
const fn = data.get("FN");
|
|
1940
|
+
if (fn) {
|
|
1941
|
+
ResultFormatter.flightNumber(decodeResult, fn);
|
|
1942
|
+
data.delete("FN");
|
|
1943
|
+
}
|
|
1944
|
+
const day = data.get("DAY");
|
|
1945
|
+
const utc = data.get("UTC");
|
|
1946
|
+
if (day && utc) {
|
|
1947
|
+
decodeResult.raw.message_timestamp = Date.parse(day + " GMT+0000") / 1e3 + DateTimeUtils.convertHHMMSSToTod(utc);
|
|
1948
|
+
data.delete("DAY");
|
|
1949
|
+
data.delete("UTC");
|
|
1950
|
+
}
|
|
1951
|
+
const lat = data.get("LAT");
|
|
1952
|
+
const lon = data.get("LON");
|
|
1953
|
+
if (lat && lon) {
|
|
1954
|
+
ResultFormatter.position(decodeResult, {
|
|
1955
|
+
latitude: CoordinateUtils.getDirection(lat[0]) * Number(lat.substring(1)),
|
|
1956
|
+
longitude: CoordinateUtils.getDirection(lon[0]) * Number(lon.substring(1))
|
|
1957
|
+
});
|
|
1958
|
+
data.delete("LAT");
|
|
1959
|
+
data.delete("LON");
|
|
1960
|
+
}
|
|
1961
|
+
let remaining = "";
|
|
1962
|
+
for (const [key, value] of data.entries()) {
|
|
1963
|
+
if (key === "") {
|
|
1964
|
+
remaining += value;
|
|
1965
|
+
} else {
|
|
1966
|
+
remaining += `/${key} ${value}`;
|
|
1967
|
+
}
|
|
1968
|
+
}
|
|
1969
|
+
decodeResult.remaining.text = remaining;
|
|
1768
1970
|
decodeResult.decoded = true;
|
|
1769
1971
|
decodeResult.decoder.decodeLevel = "partial";
|
|
1770
1972
|
return decodeResult;
|
|
1771
1973
|
}
|
|
1772
1974
|
};
|
|
1773
1975
|
|
|
1774
|
-
// lib/plugins/
|
|
1775
|
-
var
|
|
1776
|
-
|
|
1976
|
+
// lib/plugins/Label_1L_070.ts
|
|
1977
|
+
var Label_1L_070 = class extends DecoderPlugin {
|
|
1978
|
+
// eslint-disable-line camelcase
|
|
1979
|
+
name = "label-1l-070";
|
|
1777
1980
|
qualifiers() {
|
|
1778
1981
|
return {
|
|
1779
|
-
labels: ["
|
|
1982
|
+
labels: ["1L"],
|
|
1983
|
+
preambles: ["000000070"]
|
|
1780
1984
|
};
|
|
1781
1985
|
}
|
|
1782
1986
|
decode(message, options = {}) {
|
|
1783
|
-
|
|
1987
|
+
const decodeResult = this.defaultResult();
|
|
1784
1988
|
decodeResult.decoder.name = this.name;
|
|
1785
|
-
decodeResult.formatted.description = "
|
|
1989
|
+
decodeResult.formatted.description = "Position Report";
|
|
1786
1990
|
decodeResult.message = message;
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
if (header.length == 0) {
|
|
1791
|
-
ResultFormatter.unknown(decodeResult, message.text);
|
|
1792
|
-
decodeResult.decoded = false;
|
|
1793
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
1794
|
-
return decodeResult;
|
|
1795
|
-
}
|
|
1796
|
-
if (header[0].length > 0) {
|
|
1797
|
-
ResultFormatter.unknown(decodeResult, header[0].substring(0, 4));
|
|
1798
|
-
ResultFormatter.flightNumber(decodeResult, header[0].substring(4));
|
|
1799
|
-
}
|
|
1800
|
-
console.log(header[1]);
|
|
1801
|
-
if (header[1].length === 4) {
|
|
1802
|
-
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(header[1]));
|
|
1803
|
-
} else {
|
|
1804
|
-
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(header[1]));
|
|
1805
|
-
}
|
|
1806
|
-
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[1]));
|
|
1807
|
-
const lat = parts[2].replaceAll(" ", "");
|
|
1808
|
-
const lon = parts[3].replaceAll(" ", "");
|
|
1809
|
-
if (lat[0] === "N" || lat[0] === "S") {
|
|
1810
|
-
ResultFormatter.position(decodeResult, {
|
|
1811
|
-
latitude: CoordinateUtils.getDirection(lat[0]) * Number(lat.substring(1)),
|
|
1812
|
-
longitude: CoordinateUtils.getDirection(lon[0]) * Number(lon.substring(1))
|
|
1813
|
-
});
|
|
1814
|
-
} else {
|
|
1815
|
-
ResultFormatter.position(decodeResult, { latitude: Number(lat), longitude: Number(lon) });
|
|
1991
|
+
if (!message.text.startsWith("000000070")) {
|
|
1992
|
+
if (options.debug) {
|
|
1993
|
+
console.log(`Decoder: Unknown 1L message: ${message.text}`);
|
|
1816
1994
|
}
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
decodeResult
|
|
1821
|
-
|
|
1822
|
-
|
|
1995
|
+
decodeResult.remaining.text = message.text;
|
|
1996
|
+
decodeResult.decoded = false;
|
|
1997
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1998
|
+
return decodeResult;
|
|
1999
|
+
}
|
|
2000
|
+
const parts = message.text.substring(9).split(",");
|
|
2001
|
+
if (parts.length !== 7) {
|
|
1823
2002
|
if (options.debug) {
|
|
1824
|
-
console.log(`Decoder: Unknown
|
|
2003
|
+
console.log(`Decoder: Unknown 1L message: ${message.text}`);
|
|
1825
2004
|
}
|
|
1826
|
-
|
|
2005
|
+
decodeResult.remaining.text = message.text;
|
|
1827
2006
|
decodeResult.decoded = false;
|
|
1828
2007
|
decodeResult.decoder.decodeLevel = "none";
|
|
2008
|
+
return decodeResult;
|
|
1829
2009
|
}
|
|
2010
|
+
ResultFormatter.departureAirport(decodeResult, parts[0]);
|
|
2011
|
+
ResultFormatter.arrivalAirport(decodeResult, parts[1]);
|
|
2012
|
+
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[2]));
|
|
2013
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[3]));
|
|
2014
|
+
ResultFormatter.position(decodeResult, {
|
|
2015
|
+
latitude: CoordinateUtils.getDirection(parts[4][0]) * Number(parts[4].substring(1)),
|
|
2016
|
+
longitude: CoordinateUtils.getDirection(parts[5][0]) * Number(parts[5].substring(1))
|
|
2017
|
+
});
|
|
2018
|
+
decodeResult.remaining.text = parts[6];
|
|
2019
|
+
decodeResult.decoded = true;
|
|
2020
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
1830
2021
|
return decodeResult;
|
|
1831
2022
|
}
|
|
1832
2023
|
};
|
|
1833
2024
|
|
|
1834
|
-
// lib/plugins/
|
|
1835
|
-
var
|
|
1836
|
-
|
|
2025
|
+
// lib/plugins/Label_1L_660.ts
|
|
2026
|
+
var Label_1L_660 = class extends DecoderPlugin {
|
|
2027
|
+
// eslint-disable-line camelcase
|
|
2028
|
+
name = "label-1l-660";
|
|
1837
2029
|
qualifiers() {
|
|
1838
2030
|
return {
|
|
1839
|
-
labels: ["
|
|
2031
|
+
labels: ["1L"],
|
|
2032
|
+
preambles: ["000000660"]
|
|
1840
2033
|
};
|
|
1841
2034
|
}
|
|
1842
2035
|
decode(message, options = {}) {
|
|
1843
|
-
|
|
2036
|
+
const decodeResult = this.defaultResult();
|
|
1844
2037
|
decodeResult.decoder.name = this.name;
|
|
1845
|
-
decodeResult.formatted.description = "
|
|
2038
|
+
decodeResult.formatted.description = "Position Report";
|
|
1846
2039
|
decodeResult.message = message;
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
if (header.length == 0) {
|
|
1851
|
-
ResultFormatter.unknown(decodeResult, message.text);
|
|
1852
|
-
decodeResult.decoded = false;
|
|
1853
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
1854
|
-
return decodeResult;
|
|
1855
|
-
}
|
|
1856
|
-
if (header[0].length > 0) {
|
|
1857
|
-
ResultFormatter.unknown(decodeResult, header[0].substring(0, 4));
|
|
1858
|
-
ResultFormatter.flightNumber(decodeResult, header[0].substring(4));
|
|
2040
|
+
if (!message.text.startsWith("000000660")) {
|
|
2041
|
+
if (options.debug) {
|
|
2042
|
+
console.log(`Decoder: Unknown 1L message: ${message.text}`);
|
|
1859
2043
|
}
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
ResultFormatter.heading(decodeResult, Number(parts[7]));
|
|
1868
|
-
ResultFormatter.unknown(decodeResult, parts[8]);
|
|
1869
|
-
ResultFormatter.unknown(decodeResult, parts[9]);
|
|
1870
|
-
decodeResult.decoded = true;
|
|
1871
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
1872
|
-
} else {
|
|
2044
|
+
decodeResult.remaining.text = message.text;
|
|
2045
|
+
decodeResult.decoded = false;
|
|
2046
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2047
|
+
return decodeResult;
|
|
2048
|
+
}
|
|
2049
|
+
const parts = message.text.substring(9).split(",");
|
|
2050
|
+
if (parts.length !== 5) {
|
|
1873
2051
|
if (options.debug) {
|
|
1874
|
-
console.log(`Decoder: Unknown
|
|
2052
|
+
console.log(`Decoder: Unknown 1L message: ${message.text}`);
|
|
1875
2053
|
}
|
|
1876
|
-
|
|
2054
|
+
decodeResult.remaining.text = message.text;
|
|
1877
2055
|
decodeResult.decoded = false;
|
|
1878
2056
|
decodeResult.decoder.decodeLevel = "none";
|
|
2057
|
+
return decodeResult;
|
|
2058
|
+
}
|
|
2059
|
+
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(parts[0]);
|
|
2060
|
+
if (position) {
|
|
2061
|
+
ResultFormatter.position(decodeResult, position);
|
|
1879
2062
|
}
|
|
2063
|
+
const hhmmss = parts[1].substring(0, 6);
|
|
2064
|
+
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(hhmmss));
|
|
2065
|
+
const fl = parts[1].substring(6, 9);
|
|
2066
|
+
ResultFormatter.altitude(decodeResult, Number(fl) * 100);
|
|
2067
|
+
const next = parts[1].substring(9);
|
|
2068
|
+
ResultFormatter.route(decodeResult, { waypoints: [{ name: next.trim() }] });
|
|
2069
|
+
decodeResult.remaining.text = parts.slice(2).join(",");
|
|
2070
|
+
decodeResult.decoded = true;
|
|
2071
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
1880
2072
|
return decodeResult;
|
|
1881
2073
|
}
|
|
1882
2074
|
};
|
|
1883
2075
|
|
|
1884
|
-
// lib/plugins/
|
|
1885
|
-
var
|
|
1886
|
-
|
|
2076
|
+
// lib/plugins/Label_1L_Slash.ts
|
|
2077
|
+
var Label_1L_Slash = class extends DecoderPlugin {
|
|
2078
|
+
// eslint-disable-line camelcase
|
|
2079
|
+
name = "label-1l-1-line";
|
|
1887
2080
|
qualifiers() {
|
|
1888
2081
|
return {
|
|
1889
|
-
labels: ["
|
|
2082
|
+
labels: ["1L"],
|
|
2083
|
+
preambles: ["+", "-"]
|
|
1890
2084
|
};
|
|
1891
2085
|
}
|
|
1892
2086
|
decode(message, options = {}) {
|
|
1893
|
-
|
|
2087
|
+
const decodeResult = this.defaultResult();
|
|
1894
2088
|
decodeResult.decoder.name = this.name;
|
|
1895
|
-
decodeResult.formatted.description = "
|
|
2089
|
+
decodeResult.formatted.description = "Position Report";
|
|
1896
2090
|
decodeResult.message = message;
|
|
1897
|
-
const parts = message.text.split("
|
|
1898
|
-
if (parts.length
|
|
1899
|
-
const header = parts[0].split("FM5 ");
|
|
1900
|
-
if (header.length == 0) {
|
|
1901
|
-
ResultFormatter.unknown(decodeResult, message.text);
|
|
1902
|
-
decodeResult.decoded = false;
|
|
1903
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
1904
|
-
return decodeResult;
|
|
1905
|
-
}
|
|
1906
|
-
ResultFormatter.departureAirport(decodeResult, header[1]);
|
|
1907
|
-
ResultFormatter.arrivalAirport(decodeResult, parts[1]);
|
|
1908
|
-
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[2]));
|
|
1909
|
-
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[3]));
|
|
1910
|
-
ResultFormatter.position(decodeResult, { latitude: Number(parts[4].replaceAll(" ", "")), longitude: Number(parts[5].replaceAll(" ", "")) });
|
|
1911
|
-
ResultFormatter.altitude(decodeResult, Number(parts[6]));
|
|
1912
|
-
ResultFormatter.unknown(decodeResult, parts[7]);
|
|
1913
|
-
ResultFormatter.unknown(decodeResult, parts[8]);
|
|
1914
|
-
ResultFormatter.unknown(decodeResult, parts[9]);
|
|
1915
|
-
ResultFormatter.flightNumber(decodeResult, parts[10].trim());
|
|
1916
|
-
ResultFormatter.unknown(decodeResult, parts[11]);
|
|
1917
|
-
decodeResult.decoded = true;
|
|
1918
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
1919
|
-
} else {
|
|
2091
|
+
const parts = message.text.split("/");
|
|
2092
|
+
if (parts.length !== 7) {
|
|
1920
2093
|
if (options.debug) {
|
|
1921
|
-
console.log(`Decoder: Unknown
|
|
2094
|
+
console.log(`Decoder: Unknown 1L message: ${message.text}`);
|
|
1922
2095
|
}
|
|
1923
|
-
|
|
2096
|
+
decodeResult.remaining.text = message.text;
|
|
1924
2097
|
decodeResult.decoded = false;
|
|
1925
2098
|
decodeResult.decoder.decodeLevel = "none";
|
|
2099
|
+
return decodeResult;
|
|
2100
|
+
}
|
|
2101
|
+
const data = /* @__PURE__ */ new Map();
|
|
2102
|
+
data.set("LAT", parts[0].replaceAll(" ", ""));
|
|
2103
|
+
data.set("LON", parts[1].replaceAll(" ", ""));
|
|
2104
|
+
for (let i = 2; i < parts.length; i++) {
|
|
2105
|
+
const part = parts[i].split(" ");
|
|
2106
|
+
data.set(part[0], part.slice(1).join(" "));
|
|
2107
|
+
}
|
|
2108
|
+
const position = {
|
|
2109
|
+
latitude: Number(data.get("LAT")),
|
|
2110
|
+
longitude: Number(data.get("LON"))
|
|
2111
|
+
};
|
|
2112
|
+
data.delete("LAT");
|
|
2113
|
+
data.delete("LON");
|
|
2114
|
+
ResultFormatter.position(decodeResult, position);
|
|
2115
|
+
const utc = data.get("UTC");
|
|
2116
|
+
if (utc) {
|
|
2117
|
+
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(utc));
|
|
2118
|
+
data.delete("UTC");
|
|
2119
|
+
}
|
|
2120
|
+
const alt = data.get("ALT");
|
|
2121
|
+
if (alt) {
|
|
2122
|
+
ResultFormatter.altitude(decodeResult, Number(alt));
|
|
2123
|
+
data.delete("ALT");
|
|
2124
|
+
}
|
|
2125
|
+
const fob = data.get("FOB");
|
|
2126
|
+
if (fob) {
|
|
2127
|
+
ResultFormatter.currentFuel(decodeResult, Number(fob));
|
|
2128
|
+
data.delete("FOB");
|
|
2129
|
+
}
|
|
2130
|
+
const eta = data.get("ETA");
|
|
2131
|
+
if (eta) {
|
|
2132
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(eta));
|
|
2133
|
+
data.delete("ETA");
|
|
2134
|
+
}
|
|
2135
|
+
let remaining = "";
|
|
2136
|
+
for (const [key, value] of data.entries()) {
|
|
2137
|
+
remaining += `/${key} ${value}`;
|
|
1926
2138
|
}
|
|
2139
|
+
decodeResult.remaining.text = remaining;
|
|
2140
|
+
decodeResult.decoded = true;
|
|
2141
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
1927
2142
|
return decodeResult;
|
|
1928
2143
|
}
|
|
1929
2144
|
};
|
|
1930
2145
|
|
|
1931
|
-
// lib/
|
|
1932
|
-
var
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
* @param data - original message split by ':'
|
|
1940
|
-
* @returns whether all fields were processed or not
|
|
1941
|
-
*/
|
|
1942
|
-
static processFlightPlan(decodeResult, data) {
|
|
1943
|
-
let allKnownFields = _FlightPlanUtils.parseHeader(decodeResult, data[0]);
|
|
1944
|
-
for (let i = 1; i < data.length; i += 2) {
|
|
1945
|
-
const key = data[i];
|
|
1946
|
-
const value = data[i + 1];
|
|
1947
|
-
switch (key) {
|
|
1948
|
-
case "A":
|
|
1949
|
-
addProcedure(decodeResult, value, "arrival");
|
|
1950
|
-
break;
|
|
1951
|
-
case "AA":
|
|
1952
|
-
addArrivalAirport(decodeResult, value);
|
|
1953
|
-
break;
|
|
1954
|
-
case "AP":
|
|
1955
|
-
addProcedure(decodeResult, value, "approach");
|
|
1956
|
-
break;
|
|
1957
|
-
case "CR":
|
|
1958
|
-
addCompanyRoute(decodeResult, value);
|
|
1959
|
-
break;
|
|
1960
|
-
case "D":
|
|
1961
|
-
addProcedure(decodeResult, value, "departure");
|
|
1962
|
-
break;
|
|
1963
|
-
case "DA":
|
|
1964
|
-
addDepartureAirport(decodeResult, value);
|
|
1965
|
-
break;
|
|
1966
|
-
case "F":
|
|
1967
|
-
addRoute(decodeResult, value);
|
|
1968
|
-
break;
|
|
1969
|
-
case "R":
|
|
1970
|
-
addRunway(decodeResult, value);
|
|
1971
|
-
break;
|
|
1972
|
-
// case 'WS': // something about routes, has altitude, so current parsing won't work
|
|
1973
|
-
// break;
|
|
1974
|
-
default:
|
|
1975
|
-
if (allKnownFields) {
|
|
1976
|
-
decodeResult.remaining.text = "";
|
|
1977
|
-
allKnownFields = false;
|
|
1978
|
-
}
|
|
1979
|
-
decodeResult.remaining.text += `:${key}:${value}`;
|
|
1980
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
1981
|
-
}
|
|
1982
|
-
}
|
|
1983
|
-
return allKnownFields;
|
|
2146
|
+
// lib/plugins/Label_20_POS.ts
|
|
2147
|
+
var Label_20_POS = class extends DecoderPlugin {
|
|
2148
|
+
name = "label-20-pos";
|
|
2149
|
+
qualifiers() {
|
|
2150
|
+
return {
|
|
2151
|
+
labels: ["20"],
|
|
2152
|
+
preambles: ["POS"]
|
|
2153
|
+
};
|
|
1984
2154
|
}
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
addRoute(decodeResult, header.substring(2));
|
|
2155
|
+
decode(message, options = {}) {
|
|
2156
|
+
const decodeResult = this.defaultResult();
|
|
2157
|
+
decodeResult.decoder.name = this.name;
|
|
2158
|
+
decodeResult.formatted.description = "Position Report";
|
|
2159
|
+
decodeResult.message = message;
|
|
2160
|
+
decodeResult.raw.preamble = message.text.substring(0, 3);
|
|
2161
|
+
const content = message.text.substring(3);
|
|
2162
|
+
const fields = content.split(",");
|
|
2163
|
+
if (fields.length == 11) {
|
|
2164
|
+
if (options.debug) {
|
|
2165
|
+
console.log(`DEBUG: ${this.name}: Variation 1 detected`);
|
|
1997
2166
|
}
|
|
1998
|
-
|
|
1999
|
-
decodeResult.
|
|
2000
|
-
decodeResult.
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
}
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
label: "Route Status",
|
|
2013
|
-
value: "Route Inactive"
|
|
2014
|
-
});
|
|
2167
|
+
const rawCoords = fields[0];
|
|
2168
|
+
ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinates(rawCoords));
|
|
2169
|
+
decodeResult.decoded = true;
|
|
2170
|
+
decodeResult.decoder.decodeLevel = "full";
|
|
2171
|
+
} else if (fields.length == 5) {
|
|
2172
|
+
if (options.debug) {
|
|
2173
|
+
console.log(`DEBUG: ${this.name}: Variation 2 detected`);
|
|
2174
|
+
}
|
|
2175
|
+
const position = CoordinateUtils.decodeStringCoordinates(fields[0]);
|
|
2176
|
+
if (position) {
|
|
2177
|
+
ResultFormatter.position(decodeResult, position);
|
|
2178
|
+
}
|
|
2179
|
+
decodeResult.decoded = true;
|
|
2180
|
+
decodeResult.decoder.decodeLevel = "full";
|
|
2015
2181
|
} else {
|
|
2016
|
-
|
|
2017
|
-
|
|
2182
|
+
if (options.debug) {
|
|
2183
|
+
console.log(`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${content}`);
|
|
2184
|
+
}
|
|
2185
|
+
decodeResult.decoded = false;
|
|
2186
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2018
2187
|
}
|
|
2019
|
-
return
|
|
2188
|
+
return decodeResult;
|
|
2020
2189
|
}
|
|
2021
2190
|
};
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
}
|
|
2032
|
-
ResultFormatter.departureRunway(decodeResult, value.substring(0, 3));
|
|
2033
|
-
}
|
|
2034
|
-
function addRoute(decodeResult, value) {
|
|
2035
|
-
const route = value.split(".");
|
|
2036
|
-
ResultFormatter.route(decodeResult, { waypoints: route.map((leg) => RouteUtils.getWaypoint(leg)) });
|
|
2037
|
-
}
|
|
2038
|
-
function addProcedure(decodeResult, value, type) {
|
|
2039
|
-
if (decodeResult.raw.procedures === void 0) {
|
|
2040
|
-
decodeResult.raw.procedures = [];
|
|
2041
|
-
}
|
|
2042
|
-
const data = value.split(".");
|
|
2043
|
-
let waypoints;
|
|
2044
|
-
if (data.length > 1) {
|
|
2045
|
-
waypoints = data.slice(1).map((leg) => RouteUtils.getWaypoint(leg));
|
|
2191
|
+
|
|
2192
|
+
// lib/plugins/Label_21_POS.ts
|
|
2193
|
+
var Label_21_POS = class extends DecoderPlugin {
|
|
2194
|
+
name = "label-21-pos";
|
|
2195
|
+
qualifiers() {
|
|
2196
|
+
return {
|
|
2197
|
+
labels: ["21"],
|
|
2198
|
+
preambles: ["POS"]
|
|
2199
|
+
};
|
|
2046
2200
|
}
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2201
|
+
decode(message, options = {}) {
|
|
2202
|
+
const decodeResult = this.defaultResult();
|
|
2203
|
+
decodeResult.decoder.name = this.name;
|
|
2204
|
+
decodeResult.formatted.description = "Position Report";
|
|
2205
|
+
decodeResult.message = message;
|
|
2206
|
+
decodeResult.raw.preamble = message.text.substring(0, 3);
|
|
2207
|
+
const content = message.text.substring(3);
|
|
2208
|
+
const fields = content.split(",");
|
|
2209
|
+
if (fields.length == 9) {
|
|
2210
|
+
processPosition(decodeResult, fields[0].trim());
|
|
2211
|
+
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[2]));
|
|
2212
|
+
ResultFormatter.altitude(decodeResult, Number(fields[3]));
|
|
2213
|
+
ResultFormatter.temperature(decodeResult, fields[6].replace(/ /g, ""));
|
|
2214
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[7]));
|
|
2215
|
+
ResultFormatter.arrivalAirport(decodeResult, fields[8]);
|
|
2216
|
+
ResultFormatter.unknownArr(decodeResult, [fields[1], fields[4], fields[5]]);
|
|
2217
|
+
decodeResult.decoded = true;
|
|
2218
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
2219
|
+
} else {
|
|
2220
|
+
if (options.debug) {
|
|
2221
|
+
console.log(`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${content}`);
|
|
2222
|
+
}
|
|
2223
|
+
decodeResult.decoded = false;
|
|
2224
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2225
|
+
}
|
|
2226
|
+
return decodeResult;
|
|
2068
2227
|
}
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2228
|
+
};
|
|
2229
|
+
function processPosition(decodeResult, value) {
|
|
2230
|
+
if (value.length !== 16 && value[0] !== "N" && value[0] !== "S" && value[8] !== "W" && value[8] !== "E") {
|
|
2231
|
+
return;
|
|
2072
2232
|
}
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2233
|
+
const latDir = value[0] === "N" ? 1 : -1;
|
|
2234
|
+
const lonDir = value[8] === "E" ? 1 : -1;
|
|
2235
|
+
const position = {
|
|
2236
|
+
latitude: latDir * Number(value.substring(1, 7)),
|
|
2237
|
+
longitude: lonDir * Number(value.substring(9, 15))
|
|
2077
2238
|
};
|
|
2078
|
-
|
|
2079
|
-
type: "company_route",
|
|
2080
|
-
code: "CR",
|
|
2081
|
-
label: "Company Route",
|
|
2082
|
-
value: RouteUtils.routeToString(decodeResult.raw.company_route)
|
|
2083
|
-
});
|
|
2239
|
+
ResultFormatter.position(decodeResult, position);
|
|
2084
2240
|
}
|
|
2085
2241
|
|
|
2086
|
-
// lib/
|
|
2087
|
-
var
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2242
|
+
// lib/plugins/Label_22_OFF.ts
|
|
2243
|
+
var Label_22_OFF = class extends DecoderPlugin {
|
|
2244
|
+
name = "label-22-off";
|
|
2245
|
+
qualifiers() {
|
|
2246
|
+
return {
|
|
2247
|
+
labels: ["22"],
|
|
2248
|
+
preambles: ["OFF"]
|
|
2249
|
+
};
|
|
2250
|
+
}
|
|
2251
|
+
decode(message, options = {}) {
|
|
2252
|
+
const decodeResult = this.defaultResult();
|
|
2253
|
+
decodeResult.decoder.name = this.name;
|
|
2254
|
+
decodeResult.formatted.description = "Takeoff Report";
|
|
2255
|
+
decodeResult.message = message;
|
|
2256
|
+
if (message.text.startsWith("OFF01")) {
|
|
2257
|
+
const fields = message.text.substring(5).split("/");
|
|
2258
|
+
if (fields.length != 2) {
|
|
2259
|
+
decodeResult.decoded = false;
|
|
2260
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2261
|
+
return decodeResult;
|
|
2262
|
+
}
|
|
2263
|
+
ResultFormatter.flightNumber(decodeResult, fields[0]);
|
|
2264
|
+
ResultFormatter.departureDay(decodeResult, Number(fields[1].substring(0, 2)));
|
|
2265
|
+
ResultFormatter.arrivalDay(decodeResult, Number(fields[1].substring(2, 4)));
|
|
2266
|
+
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(4, 8)));
|
|
2267
|
+
ResultFormatter.departureAirport(decodeResult, fields[1].substring(8, 12));
|
|
2268
|
+
ResultFormatter.arrivalAirport(decodeResult, fields[1].substring(12, 16));
|
|
2269
|
+
ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(16, 22)));
|
|
2270
|
+
ResultFormatter.unknown(decodeResult, fields[1].substring(22));
|
|
2271
|
+
decodeResult.decoded = true;
|
|
2272
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
2273
|
+
} else if (message.text.startsWith("OFF02\r\n")) {
|
|
2274
|
+
const fields = message.text.substring(7).split(",");
|
|
2275
|
+
if (fields.length != 4) {
|
|
2276
|
+
decodeResult.decoded = false;
|
|
2277
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2278
|
+
return decodeResult;
|
|
2279
|
+
}
|
|
2280
|
+
ResultFormatter.departureAirport(decodeResult, fields[0]);
|
|
2281
|
+
ResultFormatter.arrivalAirport(decodeResult, fields[1]);
|
|
2282
|
+
ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[2]));
|
|
2283
|
+
ResultFormatter.unknown(decodeResult, fields[3]);
|
|
2284
|
+
decodeResult.decoded = true;
|
|
2285
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
2286
|
+
} else if (message.text.startsWith("OFF02")) {
|
|
2287
|
+
const fields = message.text.substring(5).split("/");
|
|
2288
|
+
if (fields.length != 2) {
|
|
2289
|
+
decodeResult.decoded = false;
|
|
2290
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2291
|
+
return decodeResult;
|
|
2292
|
+
}
|
|
2293
|
+
ResultFormatter.flightNumber(decodeResult, fields[0]);
|
|
2294
|
+
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(fields[1].substring(0, 14));
|
|
2295
|
+
if (position) {
|
|
2296
|
+
ResultFormatter.position(decodeResult, position);
|
|
2297
|
+
}
|
|
2298
|
+
ResultFormatter.day(decodeResult, Number(fields[1].substring(14, 16)));
|
|
2299
|
+
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(16, 20)));
|
|
2300
|
+
ResultFormatter.departureAirport(decodeResult, fields[1].substring(20, 24));
|
|
2301
|
+
ResultFormatter.arrivalAirport(decodeResult, fields[1].substring(24, 28));
|
|
2302
|
+
ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(28, 32)));
|
|
2303
|
+
ResultFormatter.unknown(decodeResult, fields[1].substring(32, 36));
|
|
2304
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(36, 40)));
|
|
2305
|
+
decodeResult.decoded = true;
|
|
2306
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
2307
|
+
} else {
|
|
2308
|
+
if (options.debug) {
|
|
2309
|
+
console.log(`DEBUG: ${this.name}: Unknown variation.`);
|
|
2310
|
+
}
|
|
2094
2311
|
decodeResult.decoded = false;
|
|
2095
2312
|
decodeResult.decoder.decodeLevel = "none";
|
|
2096
|
-
return false;
|
|
2097
2313
|
}
|
|
2098
|
-
|
|
2099
|
-
if (fields[i].startsWith("FN")) {
|
|
2100
|
-
decodeResult.raw.flight_number = fields[i].substring(2);
|
|
2101
|
-
} else if (fields[i].startsWith("SN")) {
|
|
2102
|
-
decodeResult.raw.serial_number = fields[i].substring(2);
|
|
2103
|
-
} else if (fields[i].startsWith("DC")) {
|
|
2104
|
-
processDC(decodeResult, fields[i].substring(2).split(","));
|
|
2105
|
-
} else if (fields[i].startsWith("TS")) {
|
|
2106
|
-
_H1Helper.processTS(decodeResult, fields[i].substring(2).split(","));
|
|
2107
|
-
} else if (fields[i].startsWith("PS")) {
|
|
2108
|
-
_H1Helper.processPS(decodeResult, fields[i].substring(2).split(","));
|
|
2109
|
-
} else if (fields[i].startsWith("DT")) {
|
|
2110
|
-
const data2 = fields[i].substring(2).split(",");
|
|
2111
|
-
processDT(decodeResult, data2);
|
|
2112
|
-
} else if (fields[i].startsWith("ID")) {
|
|
2113
|
-
processIdentification(decodeResult, fields[i].substring(2).split(","));
|
|
2114
|
-
} else if (fields[i].startsWith("LR")) {
|
|
2115
|
-
const data2 = fields[i].substring(2).split(",");
|
|
2116
|
-
processLR(decodeResult, data2);
|
|
2117
|
-
} else if (fields[i].startsWith("RI") || fields[i].startsWith("RF") || fields[i].startsWith("RP")) {
|
|
2118
|
-
FlightPlanUtils.processFlightPlan(decodeResult, fields[i].split(":"));
|
|
2119
|
-
} else if (fields[i].startsWith("PR")) {
|
|
2120
|
-
ResultFormatter.unknown(decodeResult, fields[i], "/");
|
|
2121
|
-
} else if (fields[i].startsWith("AF")) {
|
|
2122
|
-
processAirField(decodeResult, fields[i].substring(2).split(","));
|
|
2123
|
-
} else if (fields[i].startsWith("TD")) {
|
|
2124
|
-
processTimeOfDeparture(decodeResult, fields[i].substring(2).split(","));
|
|
2125
|
-
} else if (fields[i].startsWith("FX")) {
|
|
2126
|
-
ResultFormatter.freetext(decodeResult, fields[i].substring(2));
|
|
2127
|
-
} else if (fields[i].startsWith("ET")) {
|
|
2128
|
-
if (fields[i].length === 7) {
|
|
2129
|
-
ResultFormatter.day(decodeResult, Number(fields[i].substring(2, 3)));
|
|
2130
|
-
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[i].substring(3)));
|
|
2131
|
-
} else if (fields[i].length === 8) {
|
|
2132
|
-
ResultFormatter.day(decodeResult, Number(fields[i].substring(2, 4)));
|
|
2133
|
-
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[i].substring(4)));
|
|
2134
|
-
} else {
|
|
2135
|
-
ResultFormatter.unknown(decodeResult, fields[i], "/");
|
|
2136
|
-
}
|
|
2137
|
-
} else if (fields[i].startsWith("WD")) {
|
|
2138
|
-
processWindData(decodeResult, fields[i].substring(2));
|
|
2139
|
-
} else {
|
|
2140
|
-
ResultFormatter.unknown(decodeResult, fields[i], "/");
|
|
2141
|
-
}
|
|
2142
|
-
}
|
|
2143
|
-
if (decodeResult.formatted.items.length > 0) {
|
|
2144
|
-
ResultFormatter.checksum(decodeResult, checksum);
|
|
2145
|
-
}
|
|
2146
|
-
return true;
|
|
2147
|
-
}
|
|
2148
|
-
static processPS(decodeResult, data) {
|
|
2149
|
-
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[0]);
|
|
2150
|
-
if (position) {
|
|
2151
|
-
decodeResult.raw.position = position;
|
|
2152
|
-
decodeResult.formatted.items.push({
|
|
2153
|
-
type: "aircraft_position",
|
|
2154
|
-
code: "POS",
|
|
2155
|
-
label: "Aircraft Position",
|
|
2156
|
-
value: CoordinateUtils.coordinateString(position)
|
|
2157
|
-
});
|
|
2158
|
-
}
|
|
2159
|
-
if (data.length === 9) {
|
|
2160
|
-
processRoute(decodeResult, data[3], data[1], data[5], data[4], void 0);
|
|
2161
|
-
ResultFormatter.altitude(decodeResult, Number(data[2]) * 100);
|
|
2162
|
-
ResultFormatter.temperature(decodeResult, data[6]);
|
|
2163
|
-
ResultFormatter.unknown(decodeResult, data[7]);
|
|
2164
|
-
ResultFormatter.unknown(decodeResult, data[8]);
|
|
2165
|
-
}
|
|
2166
|
-
if (data.length === 14) {
|
|
2167
|
-
ResultFormatter.altitude(decodeResult, Number(data[3]) * 100);
|
|
2168
|
-
processRoute(decodeResult, data[1], data[2], data[4], data[5], data[6]);
|
|
2169
|
-
ResultFormatter.temperature(decodeResult, data[7]);
|
|
2170
|
-
ResultFormatter.unknownArr(decodeResult, data.slice(8));
|
|
2171
|
-
}
|
|
2172
|
-
}
|
|
2173
|
-
static processPosition(decodeResult, data) {
|
|
2174
|
-
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[0]);
|
|
2175
|
-
if (position) {
|
|
2176
|
-
ResultFormatter.position(decodeResult, position);
|
|
2177
|
-
}
|
|
2178
|
-
if (data.length >= 10) {
|
|
2179
|
-
ResultFormatter.altitude(decodeResult, Number(data[3]) * 100);
|
|
2180
|
-
processRoute(decodeResult, data[1], data[2], data[4], data[5], data[6]);
|
|
2181
|
-
ResultFormatter.temperature(decodeResult, data[7]);
|
|
2182
|
-
ResultFormatter.unknown(decodeResult, data[8]);
|
|
2183
|
-
ResultFormatter.unknown(decodeResult, data[9]);
|
|
2184
|
-
}
|
|
2185
|
-
if (data.length >= 14) {
|
|
2186
|
-
ResultFormatter.unknownArr(decodeResult, data.slice(10));
|
|
2187
|
-
}
|
|
2188
|
-
}
|
|
2189
|
-
static processTS(decodeResult, data) {
|
|
2190
|
-
let time = DateTimeUtils.convertDateTimeToEpoch(data[0], data[1]);
|
|
2191
|
-
if (Number.isNaN(time)) {
|
|
2192
|
-
const date = data[1].substring(2, 4) + data[1].substring(0, 2) + data[1].substring(4, 6);
|
|
2193
|
-
time = DateTimeUtils.convertDateTimeToEpoch(data[0], date);
|
|
2194
|
-
}
|
|
2195
|
-
decodeResult.raw.message_date = data[1];
|
|
2196
|
-
decodeResult.raw.message_timestamp = time;
|
|
2314
|
+
return decodeResult;
|
|
2197
2315
|
}
|
|
2198
2316
|
};
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
if (data.length === 2) {
|
|
2209
|
-
decodeResult.raw.plannedDepartureTime = data[0];
|
|
2210
|
-
decodeResult.formatted.items.push({
|
|
2211
|
-
type: "ptd",
|
|
2212
|
-
code: "ptd",
|
|
2213
|
-
label: "Planned Departure Time",
|
|
2214
|
-
value: `YYYY-MM-${data[0].substring(0, 2)}T${data[0].substring(2, 4)}:${data[0].substring(4)}:00Z`
|
|
2215
|
-
});
|
|
2216
|
-
decodeResult.raw.plannedDepartureTime = data[1];
|
|
2217
|
-
decodeResult.formatted.items.push({
|
|
2218
|
-
type: "etd",
|
|
2219
|
-
code: "etd",
|
|
2220
|
-
label: "Estimated Departure Time",
|
|
2221
|
-
value: `${data[1].substring(0, 2)}:${data[1].substring(2)}`
|
|
2222
|
-
});
|
|
2223
|
-
} else {
|
|
2224
|
-
ResultFormatter.unknown(decodeResult, data.join(","), "/TD");
|
|
2225
|
-
}
|
|
2226
|
-
}
|
|
2227
|
-
function processIdentification(decodeResult, data) {
|
|
2228
|
-
ResultFormatter.tail(decodeResult, data[0]);
|
|
2229
|
-
if (data.length > 1) {
|
|
2230
|
-
ResultFormatter.flightNumber(decodeResult, data[1]);
|
|
2231
|
-
}
|
|
2232
|
-
if (data.length > 2) {
|
|
2233
|
-
decodeResult.raw.mission_number = data[2];
|
|
2234
|
-
}
|
|
2235
|
-
}
|
|
2236
|
-
function processDT(decodeResult, data) {
|
|
2237
|
-
if (!decodeResult.raw.arrival_icao) {
|
|
2238
|
-
ResultFormatter.arrivalAirport(decodeResult, data[0]);
|
|
2239
|
-
} else if (decodeResult.raw.arrival_icao != data[0]) {
|
|
2240
|
-
ResultFormatter.unknownArr(decodeResult, data);
|
|
2241
|
-
}
|
|
2242
|
-
if (data.length > 1) {
|
|
2243
|
-
ResultFormatter.arrivalRunway(decodeResult, data[1]);
|
|
2244
|
-
}
|
|
2245
|
-
if (data.length > 2) {
|
|
2246
|
-
ResultFormatter.currentFuel(decodeResult, Number(data[2]));
|
|
2247
|
-
}
|
|
2248
|
-
if (data.length > 3) {
|
|
2249
|
-
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[3]));
|
|
2250
|
-
}
|
|
2251
|
-
if (data.length > 4) {
|
|
2252
|
-
ResultFormatter.remainingFuel(decodeResult, Number(data[4]));
|
|
2253
|
-
}
|
|
2254
|
-
if (data.length > 5) {
|
|
2255
|
-
ResultFormatter.unknownArr(decodeResult, data);
|
|
2256
|
-
}
|
|
2257
|
-
}
|
|
2258
|
-
function processLR(decodeResult, data) {
|
|
2259
|
-
if (data.length === 19) {
|
|
2260
|
-
ResultFormatter.unknown(decodeResult, data[1]);
|
|
2261
|
-
ResultFormatter.flightNumber(decodeResult, data[2]);
|
|
2262
|
-
ResultFormatter.departureAirport(decodeResult, data[3]);
|
|
2263
|
-
ResultFormatter.arrivalAirport(decodeResult, data[4]);
|
|
2264
|
-
ResultFormatter.arrivalRunway(decodeResult, data[5]);
|
|
2265
|
-
ResultFormatter.unknown(decodeResult, data.slice(6, 19).join(","));
|
|
2266
|
-
} else {
|
|
2267
|
-
ResultFormatter.unknown(decodeResult, data.join(","));
|
|
2317
|
+
|
|
2318
|
+
// lib/plugins/Label_22_POS.ts
|
|
2319
|
+
var Label_22_POS = class extends DecoderPlugin {
|
|
2320
|
+
name = "label-22-pos";
|
|
2321
|
+
qualifiers() {
|
|
2322
|
+
return {
|
|
2323
|
+
labels: ["22"],
|
|
2324
|
+
preambles: ["N", "S"]
|
|
2325
|
+
};
|
|
2268
2326
|
}
|
|
2269
|
-
}
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
} else if (parts.length == 2) {
|
|
2283
|
-
if (parts[0].length > 0) {
|
|
2284
|
-
ResultFormatter.unknown(decodeResult, parts[0].substring(0, 4));
|
|
2285
|
-
ResultFormatter.flightNumber(decodeResult, parts[0].substring(4));
|
|
2286
|
-
ResultFormatter.unknown(decodeResult, parts[1].length == 5 ? parts[1].substring(0, 2) : parts[1].substring(0, 3), "#");
|
|
2327
|
+
decode(message, options = {}) {
|
|
2328
|
+
const decodeResult = this.defaultResult();
|
|
2329
|
+
decodeResult.decoder.name = this.name;
|
|
2330
|
+
decodeResult.formatted.description = "Position Report";
|
|
2331
|
+
decodeResult.message = message;
|
|
2332
|
+
const fields = message.text.split(",");
|
|
2333
|
+
if (fields.length !== 11) {
|
|
2334
|
+
if (options.debug) {
|
|
2335
|
+
console.log(`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${fields.join(",")}`);
|
|
2336
|
+
}
|
|
2337
|
+
decodeResult.decoded = false;
|
|
2338
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2339
|
+
return decodeResult;
|
|
2287
2340
|
}
|
|
2288
|
-
const
|
|
2289
|
-
|
|
2290
|
-
|
|
2341
|
+
const latStr = fields[0].substring(1, 8);
|
|
2342
|
+
const lonStr = fields[0].substring(9);
|
|
2343
|
+
const lat = Number(latStr) / 1e4;
|
|
2344
|
+
const lon = Number(lonStr) / 1e4;
|
|
2345
|
+
ResultFormatter.position(decodeResult, {
|
|
2346
|
+
latitude: CoordinateUtils.getDirection(fields[0][0]) * lat,
|
|
2347
|
+
longitude: CoordinateUtils.getDirection(fields[0][8]) * lon
|
|
2348
|
+
});
|
|
2349
|
+
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[2]));
|
|
2350
|
+
ResultFormatter.altitude(decodeResult, Number(fields[3]));
|
|
2351
|
+
ResultFormatter.unknownArr(decodeResult, [fields[1], ...fields.slice(4)]);
|
|
2352
|
+
decodeResult.decoded = true;
|
|
2353
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
2354
|
+
return decodeResult;
|
|
2355
|
+
}
|
|
2356
|
+
};
|
|
2357
|
+
|
|
2358
|
+
// lib/plugins/Label_2P_FM3.ts
|
|
2359
|
+
var Label_2P_FM3 = class extends DecoderPlugin {
|
|
2360
|
+
name = "label-2p-fm3";
|
|
2361
|
+
qualifiers() {
|
|
2362
|
+
return {
|
|
2363
|
+
labels: ["2P"]
|
|
2364
|
+
};
|
|
2365
|
+
}
|
|
2366
|
+
decode(message, options = {}) {
|
|
2367
|
+
let decodeResult = this.defaultResult();
|
|
2368
|
+
decodeResult.decoder.name = this.name;
|
|
2369
|
+
decodeResult.formatted.description = "Flight Report";
|
|
2370
|
+
decodeResult.message = message;
|
|
2371
|
+
const parts = message.text.split(",");
|
|
2372
|
+
if (parts.length === 7) {
|
|
2373
|
+
const header = parts[0].split("FM3 ");
|
|
2374
|
+
if (header.length == 0) {
|
|
2375
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
2376
|
+
decodeResult.decoded = false;
|
|
2377
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2378
|
+
return decodeResult;
|
|
2379
|
+
}
|
|
2380
|
+
if (header[0].length > 0) {
|
|
2381
|
+
ResultFormatter.unknown(decodeResult, header[0].substring(0, 4));
|
|
2382
|
+
ResultFormatter.flightNumber(decodeResult, header[0].substring(4));
|
|
2383
|
+
}
|
|
2384
|
+
console.log(header[1]);
|
|
2385
|
+
if (header[1].length === 4) {
|
|
2386
|
+
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(header[1]));
|
|
2387
|
+
} else {
|
|
2388
|
+
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(header[1]));
|
|
2389
|
+
}
|
|
2390
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[1]));
|
|
2391
|
+
const lat = parts[2].replaceAll(" ", "");
|
|
2392
|
+
const lon = parts[3].replaceAll(" ", "");
|
|
2393
|
+
if (lat[0] === "N" || lat[0] === "S") {
|
|
2394
|
+
ResultFormatter.position(decodeResult, {
|
|
2395
|
+
latitude: CoordinateUtils.getDirection(lat[0]) * Number(lat.substring(1)),
|
|
2396
|
+
longitude: CoordinateUtils.getDirection(lon[0]) * Number(lon.substring(1))
|
|
2397
|
+
});
|
|
2398
|
+
} else {
|
|
2399
|
+
ResultFormatter.position(decodeResult, { latitude: Number(lat), longitude: Number(lon) });
|
|
2400
|
+
}
|
|
2401
|
+
ResultFormatter.altitude(decodeResult, Number(parts[4]));
|
|
2402
|
+
ResultFormatter.unknown(decodeResult, parts[5]);
|
|
2403
|
+
ResultFormatter.unknown(decodeResult, parts[6]);
|
|
2404
|
+
decodeResult.decoded = true;
|
|
2405
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
2406
|
+
} else {
|
|
2407
|
+
if (options.debug) {
|
|
2408
|
+
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
2409
|
+
}
|
|
2410
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
2411
|
+
decodeResult.decoded = false;
|
|
2412
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2291
2413
|
}
|
|
2292
|
-
return
|
|
2293
|
-
} else {
|
|
2294
|
-
ResultFormatter.unknown(decodeResult, messageType);
|
|
2295
|
-
return false;
|
|
2414
|
+
return decodeResult;
|
|
2296
2415
|
}
|
|
2297
|
-
}
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
decodeResult.formatted.description = "Position Report";
|
|
2307
|
-
} else if (type === "PRG") {
|
|
2308
|
-
decodeResult.formatted.description = "Progress Report";
|
|
2309
|
-
} else if (type === "PWI") {
|
|
2310
|
-
decodeResult.formatted.description = "Weather Report";
|
|
2311
|
-
} else {
|
|
2312
|
-
decodeResult.formatted.description = "Unknown H1 Message";
|
|
2313
|
-
return false;
|
|
2416
|
+
};
|
|
2417
|
+
|
|
2418
|
+
// lib/plugins/Label_2P_FM4.ts
|
|
2419
|
+
var Label_2P_FM4 = class extends DecoderPlugin {
|
|
2420
|
+
name = "label-2p-fm4";
|
|
2421
|
+
qualifiers() {
|
|
2422
|
+
return {
|
|
2423
|
+
labels: ["2P"]
|
|
2424
|
+
};
|
|
2314
2425
|
}
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2426
|
+
decode(message, options = {}) {
|
|
2427
|
+
let decodeResult = this.defaultResult();
|
|
2428
|
+
decodeResult.decoder.name = this.name;
|
|
2429
|
+
decodeResult.formatted.description = "Flight Report";
|
|
2430
|
+
decodeResult.message = message;
|
|
2431
|
+
const parts = message.text.split(",");
|
|
2432
|
+
if (parts.length === 10) {
|
|
2433
|
+
const header = parts[0].split("FM4");
|
|
2434
|
+
if (header.length == 0) {
|
|
2435
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
2436
|
+
decodeResult.decoded = false;
|
|
2437
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2438
|
+
return decodeResult;
|
|
2439
|
+
}
|
|
2440
|
+
if (header[0].length > 0) {
|
|
2441
|
+
ResultFormatter.unknown(decodeResult, header[0].substring(0, 4));
|
|
2442
|
+
ResultFormatter.flightNumber(decodeResult, header[0].substring(4));
|
|
2443
|
+
}
|
|
2444
|
+
ResultFormatter.departureAirport(decodeResult, header[1]);
|
|
2445
|
+
ResultFormatter.arrivalAirport(decodeResult, parts[1]);
|
|
2446
|
+
ResultFormatter.day(decodeResult, Number(parts[2].substring(0, 2)));
|
|
2447
|
+
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[2].substring(2)));
|
|
2448
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[3]));
|
|
2449
|
+
ResultFormatter.position(decodeResult, { latitude: Number(parts[4].replaceAll(" ", "")), longitude: Number(parts[5].replaceAll(" ", "")) });
|
|
2450
|
+
ResultFormatter.altitude(decodeResult, Number(parts[6]));
|
|
2451
|
+
ResultFormatter.heading(decodeResult, Number(parts[7]));
|
|
2452
|
+
ResultFormatter.unknown(decodeResult, parts[8]);
|
|
2453
|
+
ResultFormatter.unknown(decodeResult, parts[9]);
|
|
2454
|
+
decodeResult.decoded = true;
|
|
2455
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
2456
|
+
} else {
|
|
2457
|
+
if (options.debug) {
|
|
2458
|
+
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
2459
|
+
}
|
|
2460
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
2461
|
+
decodeResult.decoded = false;
|
|
2462
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2463
|
+
}
|
|
2464
|
+
return decodeResult;
|
|
2324
2465
|
}
|
|
2325
|
-
}
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
nextWaypoint.time = nextTime;
|
|
2335
|
-
nextWaypoint.timeFormat = timeFormat;
|
|
2336
|
-
const thenWaypoint = RouteUtils.getWaypoint(then || "?");
|
|
2337
|
-
const waypoints = [lastWaypoint, nextWaypoint, thenWaypoint];
|
|
2338
|
-
decodeResult.raw.route = { waypoints };
|
|
2339
|
-
decodeResult.formatted.items.push({
|
|
2340
|
-
type: "aircraft_route",
|
|
2341
|
-
code: "ROUTE",
|
|
2342
|
-
label: "Aircraft Route",
|
|
2343
|
-
value: RouteUtils.routeToString(decodeResult.raw.route)
|
|
2344
|
-
});
|
|
2345
|
-
}
|
|
2346
|
-
function processWindData(decodeResult, message) {
|
|
2347
|
-
if (decodeResult.raw.wind_data === void 0) {
|
|
2348
|
-
decodeResult.raw.wind_data = [];
|
|
2466
|
+
};
|
|
2467
|
+
|
|
2468
|
+
// lib/plugins/Label_2P_FM5.ts
|
|
2469
|
+
var Label_2P_FM5 = class extends DecoderPlugin {
|
|
2470
|
+
name = "label-2p-fm5";
|
|
2471
|
+
qualifiers() {
|
|
2472
|
+
return {
|
|
2473
|
+
labels: ["2P"]
|
|
2474
|
+
};
|
|
2349
2475
|
}
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
const
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
decodeResult.
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
value: `${waypoint} at FL${flightLevel}: ${windDirection}\xB0 at ${windSpeed}kt, ${tempDegrees}\xB0C at FL${tempFlightLevel}`
|
|
2378
|
-
});
|
|
2476
|
+
decode(message, options = {}) {
|
|
2477
|
+
let decodeResult = this.defaultResult();
|
|
2478
|
+
decodeResult.decoder.name = this.name;
|
|
2479
|
+
decodeResult.formatted.description = "Flight Report";
|
|
2480
|
+
decodeResult.message = message;
|
|
2481
|
+
const parts = message.text.split(",");
|
|
2482
|
+
if (parts.length === 12) {
|
|
2483
|
+
const header = parts[0].split("FM5 ");
|
|
2484
|
+
if (header.length == 0) {
|
|
2485
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
2486
|
+
decodeResult.decoded = false;
|
|
2487
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2488
|
+
return decodeResult;
|
|
2489
|
+
}
|
|
2490
|
+
ResultFormatter.departureAirport(decodeResult, header[1]);
|
|
2491
|
+
ResultFormatter.arrivalAirport(decodeResult, parts[1]);
|
|
2492
|
+
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[2]));
|
|
2493
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[3]));
|
|
2494
|
+
ResultFormatter.position(decodeResult, { latitude: Number(parts[4].replaceAll(" ", "")), longitude: Number(parts[5].replaceAll(" ", "")) });
|
|
2495
|
+
ResultFormatter.altitude(decodeResult, Number(parts[6]));
|
|
2496
|
+
ResultFormatter.unknown(decodeResult, parts[7]);
|
|
2497
|
+
ResultFormatter.unknown(decodeResult, parts[8]);
|
|
2498
|
+
ResultFormatter.unknown(decodeResult, parts[9]);
|
|
2499
|
+
ResultFormatter.flightNumber(decodeResult, parts[10].trim());
|
|
2500
|
+
ResultFormatter.unknown(decodeResult, parts[11]);
|
|
2501
|
+
decodeResult.decoded = true;
|
|
2502
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
2379
2503
|
} else {
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
decodeResult.formatted.items.push({
|
|
2387
|
-
type: "wind_data",
|
|
2388
|
-
code: "WIND",
|
|
2389
|
-
label: "Wind Data",
|
|
2390
|
-
value: `${waypoint} at FL${flightLevel}: ${windDirection}\xB0 at ${windSpeed}kt`
|
|
2391
|
-
});
|
|
2504
|
+
if (options.debug) {
|
|
2505
|
+
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
2506
|
+
}
|
|
2507
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
2508
|
+
decodeResult.decoded = false;
|
|
2509
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2392
2510
|
}
|
|
2393
|
-
|
|
2394
|
-
}
|
|
2511
|
+
return decodeResult;
|
|
2512
|
+
}
|
|
2513
|
+
};
|
|
2395
2514
|
|
|
2396
2515
|
// lib/plugins/Label_2P_POS.ts
|
|
2397
2516
|
var Label_2P_POS = class extends DecoderPlugin {
|
|
@@ -2760,7 +2879,10 @@ var Label_4A = class extends DecoderPlugin {
|
|
|
2760
2879
|
ResultFormatter.callsign(decodeResult, fields[3]);
|
|
2761
2880
|
ResultFormatter.departureAirport(decodeResult, fields[4]);
|
|
2762
2881
|
ResultFormatter.arrivalAirport(decodeResult, fields[5]);
|
|
2763
|
-
|
|
2882
|
+
const alt = text.substring(48, 51);
|
|
2883
|
+
if (alt !== "") {
|
|
2884
|
+
ResultFormatter.altitude(decodeResult, Number(alt) * 100);
|
|
2885
|
+
}
|
|
2764
2886
|
ResultFormatter.unknownArr(decodeResult, fields.slice(8));
|
|
2765
2887
|
} else if (fields.length === 6) {
|
|
2766
2888
|
if (fields[0].match(/^[NS]/)) {
|
|
@@ -4835,6 +4957,9 @@ var MessageDecoder = class {
|
|
|
4835
4957
|
this.registerPlugin(new Label_15(this));
|
|
4836
4958
|
this.registerPlugin(new Label_15_FST(this));
|
|
4837
4959
|
this.registerPlugin(new Label_16_N_Space(this));
|
|
4960
|
+
this.registerPlugin(new Label_16_POSA1(this));
|
|
4961
|
+
this.registerPlugin(new Label_16_TOD(this));
|
|
4962
|
+
this.registerPlugin(new Label_1J_2J_FTX(this));
|
|
4838
4963
|
this.registerPlugin(new Label_1L_3Line(this));
|
|
4839
4964
|
this.registerPlugin(new Label_1L_070(this));
|
|
4840
4965
|
this.registerPlugin(new Label_1L_660(this));
|