@airframes/acars-decoder 1.6.2 → 1.6.4
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.d.mts +63 -1
- package/dist/index.d.ts +63 -1
- package/dist/index.js +334 -142
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +334 -142
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -3
package/dist/index.js
CHANGED
|
@@ -204,6 +204,32 @@ var Label_5Z = class extends DecoderPlugin {
|
|
|
204
204
|
}
|
|
205
205
|
};
|
|
206
206
|
|
|
207
|
+
// lib/utils/coordinate_utils.ts
|
|
208
|
+
var CoordinateUtils = class {
|
|
209
|
+
static decodeStringCoordinates(stringCoords) {
|
|
210
|
+
var results = {};
|
|
211
|
+
const firstChar = stringCoords.substring(0, 1);
|
|
212
|
+
let middleChar = stringCoords.substring(6, 7);
|
|
213
|
+
let longitudeChars = stringCoords.substring(7, 13);
|
|
214
|
+
if (middleChar == " ") {
|
|
215
|
+
middleChar = stringCoords.substring(7, 8);
|
|
216
|
+
longitudeChars = stringCoords.substring(8, 14);
|
|
217
|
+
}
|
|
218
|
+
if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
|
|
219
|
+
results.latitude = Number(stringCoords.substring(1, 6)) / 1e3 * (firstChar === "S" ? -1 : 1);
|
|
220
|
+
results.longitude = Number(longitudeChars) / 1e3 * (middleChar === "W" ? -1 : 1);
|
|
221
|
+
} else {
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
return results;
|
|
225
|
+
}
|
|
226
|
+
static coordinateString(coords) {
|
|
227
|
+
const latDir = coords.latitude > 0 ? "N" : "S";
|
|
228
|
+
const lonDir = coords.longitude > 0 ? "E" : "W";
|
|
229
|
+
return `${Math.abs(coords.latitude).toFixed(3)} ${latDir}, ${Math.abs(coords.longitude).toFixed(3)} ${lonDir}`;
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
|
|
207
233
|
// lib/plugins/Label_12_N_Space.ts
|
|
208
234
|
var Label_12_N_Space = class extends DecoderPlugin {
|
|
209
235
|
name = "label-12-n-space";
|
|
@@ -225,16 +251,16 @@ var Label_12_N_Space = class extends DecoderPlugin {
|
|
|
225
251
|
console.log(`Label 12 N : results`);
|
|
226
252
|
console.log(results);
|
|
227
253
|
}
|
|
228
|
-
decodeResult.raw.
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
254
|
+
decodeResult.raw.position = {
|
|
255
|
+
latitude: Number(results.groups.lat_coord) * (results.groups.lat == "N" ? 1 : -1),
|
|
256
|
+
longitude: Number(results.groups.long_coord) * (results.groups.long == "E" ? 1 : -1)
|
|
257
|
+
};
|
|
232
258
|
decodeResult.raw.flight_level = results.groups.alt == "GRD" || results.groups.alt == "***" ? "0" : Number(results.groups.alt);
|
|
233
259
|
decodeResult.formatted.items.push({
|
|
234
260
|
type: "aircraft_position",
|
|
235
261
|
code: "POS",
|
|
236
262
|
label: "Aircraft Position",
|
|
237
|
-
value:
|
|
263
|
+
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
238
264
|
});
|
|
239
265
|
decodeResult.formatted.items.push({
|
|
240
266
|
type: "flight_level",
|
|
@@ -257,37 +283,6 @@ var Label_12_N_Space = class extends DecoderPlugin {
|
|
|
257
283
|
}
|
|
258
284
|
};
|
|
259
285
|
|
|
260
|
-
// lib/utils/coordinate_utils.ts
|
|
261
|
-
var CoordinateUtils = class {
|
|
262
|
-
static decodeStringCoordinates(stringCoords) {
|
|
263
|
-
var results = {};
|
|
264
|
-
const firstChar = stringCoords.substring(0, 1);
|
|
265
|
-
let middleChar = stringCoords.substring(6, 7);
|
|
266
|
-
let longitudeChars = stringCoords.substring(7, 13);
|
|
267
|
-
if (middleChar == " ") {
|
|
268
|
-
middleChar = stringCoords.substring(7, 8);
|
|
269
|
-
longitudeChars = stringCoords.substring(8, 14);
|
|
270
|
-
}
|
|
271
|
-
if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
|
|
272
|
-
results.latitudeDirection = firstChar;
|
|
273
|
-
results.latitude = Number(stringCoords.substring(1, 6)) / 1e3 * (firstChar === "S" ? -1 : 1);
|
|
274
|
-
results.longitudeDirection = middleChar;
|
|
275
|
-
results.longitude = Number(longitudeChars) / 1e3 * (middleChar === "W" ? -1 : 1);
|
|
276
|
-
} else {
|
|
277
|
-
return;
|
|
278
|
-
}
|
|
279
|
-
return results;
|
|
280
|
-
}
|
|
281
|
-
static coordinateString(coords) {
|
|
282
|
-
return `${Math.abs(coords.latitude)} ${coords.latitudeDirection}, ${Math.abs(coords.longitude)} ${coords.longitudeDirection}`;
|
|
283
|
-
}
|
|
284
|
-
static latLonToCoordinateString(lat, lon) {
|
|
285
|
-
const latDir = lat > 0 ? "N" : "S";
|
|
286
|
-
const lonDir = lon > 0 ? "E" : "W";
|
|
287
|
-
return `${Math.abs(lat)} ${latDir}, ${Math.abs(lon)} ${lonDir}`;
|
|
288
|
-
}
|
|
289
|
-
};
|
|
290
|
-
|
|
291
286
|
// lib/plugins/Label_15.ts
|
|
292
287
|
var Label_15 = class extends DecoderPlugin {
|
|
293
288
|
name = "label-5z";
|
|
@@ -341,9 +336,7 @@ var Label_15_FST = class extends DecoderPlugin {
|
|
|
341
336
|
const middleChar = stringCoords.substring(7, 8);
|
|
342
337
|
decodeResult.raw.position = {};
|
|
343
338
|
if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
|
|
344
|
-
decodeResult.raw.position.latitudeDirection = firstChar;
|
|
345
339
|
decodeResult.raw.position.latitude = Number(stringCoords.substring(1, 7)) / 1e4 * (firstChar === "S" ? -1 : 1);
|
|
346
|
-
decodeResult.raw.position.longitudeDirection = middleChar;
|
|
347
340
|
decodeResult.raw.position.longitude = Number(stringCoords.substring(8, 26)) / 1e5 * (middleChar === "W" ? -1 : 1);
|
|
348
341
|
} else {
|
|
349
342
|
decodeResult.decoded = false;
|
|
@@ -395,16 +388,16 @@ var Label_16_N_Space = class extends DecoderPlugin {
|
|
|
395
388
|
console.log(`Label 16 N : results`);
|
|
396
389
|
console.log(results);
|
|
397
390
|
}
|
|
398
|
-
decodeResult.raw.
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
391
|
+
decodeResult.raw.position = {
|
|
392
|
+
latitude: Number(results.groups.lat_coord) * (results.groups.lat == "N" ? 1 : -1),
|
|
393
|
+
longitude: Number(results.groups.long_coord) * (results.groups.long == "E" ? 1 : -1)
|
|
394
|
+
};
|
|
402
395
|
decodeResult.raw.flight_level = results.groups.alt == "GRD" || results.groups.alt == "***" ? "0" : Number(results.groups.alt);
|
|
403
396
|
decodeResult.formatted.items.push({
|
|
404
397
|
type: "aircraft_position",
|
|
405
398
|
code: "POS",
|
|
406
399
|
label: "Aircraft Position",
|
|
407
|
-
value:
|
|
400
|
+
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
408
401
|
});
|
|
409
402
|
decodeResult.formatted.items.push({
|
|
410
403
|
type: "flight_level",
|
|
@@ -420,15 +413,15 @@ var Label_16_N_Space = class extends DecoderPlugin {
|
|
|
420
413
|
console.log(`Label 16 N : results`);
|
|
421
414
|
console.log(results);
|
|
422
415
|
}
|
|
423
|
-
decodeResult.raw.
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
416
|
+
decodeResult.raw.position = {
|
|
417
|
+
latitude: Number(results.groups.lat_coord) * (results.groups.lat == "N" ? 1 : -1),
|
|
418
|
+
longitude: Number(results.groups.long_coord) * (results.groups.long == "E" ? 1 : -1)
|
|
419
|
+
};
|
|
427
420
|
decodeResult.formatted.items.push({
|
|
428
421
|
type: "aircraft_position",
|
|
429
422
|
code: "POS",
|
|
430
423
|
label: "Aircraft Position",
|
|
431
|
-
value:
|
|
424
|
+
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
432
425
|
});
|
|
433
426
|
decodeResult.decoded = true;
|
|
434
427
|
decodeResult.decoder.decodeLevel = "full";
|
|
@@ -483,11 +476,14 @@ var DateTimeUtils = class {
|
|
|
483
476
|
/**
|
|
484
477
|
*
|
|
485
478
|
* @param time HHMMSS
|
|
486
|
-
* @param date MMDDYY
|
|
479
|
+
* @param date MMDDYY or MMDDYYYY
|
|
487
480
|
* @returns seconds since epoch
|
|
488
481
|
*/
|
|
489
482
|
static convertDateTimeToEpoch(time, date) {
|
|
490
|
-
|
|
483
|
+
if (date.length === 6) {
|
|
484
|
+
date = date.substring(0, 4) + `20${date.substring(4, 6)}`;
|
|
485
|
+
}
|
|
486
|
+
const timestamp = `${date.substring(4, 8)}-${date.substring(0, 2)}-${date.substring(2, 4)}T${time.substring(0, 2)}:${time.substring(2, 4)}:${time.substring(4, 6)}.000Z`;
|
|
491
487
|
const millis = Date.parse(timestamp);
|
|
492
488
|
return millis / 1e3;
|
|
493
489
|
}
|
|
@@ -579,11 +575,13 @@ var Label_20_POS = class extends DecoderPlugin {
|
|
|
579
575
|
console.log(`DEBUG: ${this.name}: Variation 2 detected`);
|
|
580
576
|
const rawCoords = fields[0];
|
|
581
577
|
decodeResult.raw.position = CoordinateUtils.decodeStringCoordinates(rawCoords);
|
|
582
|
-
decodeResult.
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
578
|
+
if (decodeResult.raw.position) {
|
|
579
|
+
decodeResult.formatted.items.push({
|
|
580
|
+
type: "position",
|
|
581
|
+
label: "Position",
|
|
582
|
+
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
583
|
+
});
|
|
584
|
+
}
|
|
587
585
|
decodeResult.decoded = true;
|
|
588
586
|
decodeResult.decoder.decodeLevel = "full";
|
|
589
587
|
} else {
|
|
@@ -1089,7 +1087,7 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
1089
1087
|
const lon = Number(posResult.groups.lng) * (posResult.groups.lngd === "W" ? -1 : 1);
|
|
1090
1088
|
const latitude = Number.isInteger(lat) ? lat / 1e3 : lat / 100;
|
|
1091
1089
|
const longitude = Number.isInteger(lon) ? lon / 1e3 : lon / 100;
|
|
1092
|
-
decodeResult.raw.
|
|
1090
|
+
decodeResult.raw.position = {
|
|
1093
1091
|
latitude,
|
|
1094
1092
|
longitude
|
|
1095
1093
|
};
|
|
@@ -1097,7 +1095,7 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
1097
1095
|
type: "position",
|
|
1098
1096
|
code: "POS",
|
|
1099
1097
|
label: "Position",
|
|
1100
|
-
value:
|
|
1098
|
+
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
1101
1099
|
});
|
|
1102
1100
|
break;
|
|
1103
1101
|
}
|
|
@@ -1240,7 +1238,10 @@ var RouteUtils = class _RouteUtils {
|
|
|
1240
1238
|
static waypointToString(waypoint) {
|
|
1241
1239
|
let s = waypoint.name;
|
|
1242
1240
|
if (waypoint.latitude && waypoint.longitude) {
|
|
1243
|
-
s += `(${CoordinateUtils.
|
|
1241
|
+
s += `(${CoordinateUtils.coordinateString({ latitude: waypoint.latitude, longitude: waypoint.longitude })})`;
|
|
1242
|
+
}
|
|
1243
|
+
if (waypoint.offset) {
|
|
1244
|
+
s += `[${waypoint.offset.bearing}\xB0 ${waypoint.offset.distance}nm]`;
|
|
1244
1245
|
}
|
|
1245
1246
|
if (waypoint.time && waypoint.timeFormat) {
|
|
1246
1247
|
s += `@${_RouteUtils.timestampToString(waypoint.time, waypoint.timeFormat)}`;
|
|
@@ -1248,14 +1249,23 @@ var RouteUtils = class _RouteUtils {
|
|
|
1248
1249
|
return s;
|
|
1249
1250
|
}
|
|
1250
1251
|
static getWaypoint(leg) {
|
|
1252
|
+
const regex = leg.match(/^([A-Z]+)(\d{3})-(\d{4})$/);
|
|
1253
|
+
if (regex?.length == 4) {
|
|
1254
|
+
return { name: regex[1], offset: { bearing: parseInt(regex[2]), distance: parseInt(regex[3]) / 10 } };
|
|
1255
|
+
}
|
|
1251
1256
|
const waypoint = leg.split(",");
|
|
1252
1257
|
if (waypoint.length == 2) {
|
|
1253
1258
|
const position = CoordinateUtils.decodeStringCoordinates(waypoint[1]);
|
|
1254
|
-
|
|
1259
|
+
if (position) {
|
|
1260
|
+
return { name: waypoint[0], latitude: position.latitude, longitude: position.longitude };
|
|
1261
|
+
}
|
|
1255
1262
|
}
|
|
1256
|
-
if (leg.length == 14) {
|
|
1263
|
+
if (leg.length == 13 || leg.length == 14) {
|
|
1257
1264
|
const position = CoordinateUtils.decodeStringCoordinates(leg);
|
|
1258
|
-
|
|
1265
|
+
const name = waypoint.length == 2 ? waypoint[0] : "";
|
|
1266
|
+
if (position) {
|
|
1267
|
+
return { name, latitude: position.latitude, longitude: position.longitude };
|
|
1268
|
+
}
|
|
1259
1269
|
}
|
|
1260
1270
|
return { name: leg };
|
|
1261
1271
|
}
|
|
@@ -1315,7 +1325,7 @@ var FlightPlanUtils = class {
|
|
|
1315
1325
|
addRoute(decodeResult, value);
|
|
1316
1326
|
break;
|
|
1317
1327
|
case "R":
|
|
1318
|
-
|
|
1328
|
+
addRunway(decodeResult, value);
|
|
1319
1329
|
break;
|
|
1320
1330
|
default:
|
|
1321
1331
|
if (allKnownFields) {
|
|
@@ -1329,41 +1339,106 @@ var FlightPlanUtils = class {
|
|
|
1329
1339
|
return allKnownFields;
|
|
1330
1340
|
}
|
|
1331
1341
|
};
|
|
1342
|
+
function parseMessageType(decodeResult, messageType) {
|
|
1343
|
+
let decoded = true;
|
|
1344
|
+
const parts = messageType.split("#");
|
|
1345
|
+
if (parts.length == 1) {
|
|
1346
|
+
if (parts[0].startsWith("POS") && parts[0].length !== 3 && !parts[0].startsWith("POS/")) {
|
|
1347
|
+
decoded = processPosition(decodeResult, parts[0].substring(3));
|
|
1348
|
+
}
|
|
1349
|
+
return decoded;
|
|
1350
|
+
} else if (parts.length == 2) {
|
|
1351
|
+
if (parts[0].length > 0) {
|
|
1352
|
+
decodeResult.remaining.text += parts[0].substring(0, 3);
|
|
1353
|
+
decodeResult.raw.flight_number = parts[0].substring(3);
|
|
1354
|
+
decodeResult.remaining.text += "#" + parts[1].substring(0, 3);
|
|
1355
|
+
}
|
|
1356
|
+
if (parts[1].substring(3, 6) === "POS" && parts[1].length !== 6 && parts[1].substring(3, 7) !== "POS/") {
|
|
1357
|
+
decoded = processPosition(decodeResult, parts[1].substring(6));
|
|
1358
|
+
}
|
|
1359
|
+
decodeResult.raw.message_type = messageType;
|
|
1360
|
+
return decoded;
|
|
1361
|
+
}
|
|
1362
|
+
decodeResult.remaining.text += messageType;
|
|
1363
|
+
return false;
|
|
1364
|
+
}
|
|
1332
1365
|
function parseHeader(decodeResult, header) {
|
|
1333
1366
|
let allKnownFields = true;
|
|
1334
1367
|
const fields = header.split("/");
|
|
1335
|
-
|
|
1368
|
+
allKnownFields = allKnownFields && parseMessageType(decodeResult, fields[0]);
|
|
1369
|
+
for (let i = 1; i < fields.length; ++i) {
|
|
1336
1370
|
if (fields[i].startsWith("FN")) {
|
|
1337
1371
|
decodeResult.raw.flight_number = fields[i].substring(2);
|
|
1338
1372
|
} else if (fields[i].startsWith("SN")) {
|
|
1339
1373
|
decodeResult.raw.serial_number = fields[i].substring(2);
|
|
1340
1374
|
} else if (fields[i].startsWith("TS")) {
|
|
1341
1375
|
const ts = fields[i].substring(2).split(",");
|
|
1342
|
-
|
|
1376
|
+
let time = DateTimeUtils.convertDateTimeToEpoch(ts[0], ts[1]);
|
|
1377
|
+
if (Number.isNaN(time)) {
|
|
1378
|
+
const date = ts[1].substring(2, 4) + ts[1].substring(0, 2) + ts[1].substring(4, 6);
|
|
1379
|
+
time = DateTimeUtils.convertDateTimeToEpoch(ts[0], date);
|
|
1380
|
+
}
|
|
1381
|
+
decodeResult.raw.message_timestamp = time;
|
|
1382
|
+
} else if (fields[i].startsWith("PS")) {
|
|
1383
|
+
const pos = fields[i].substring(2);
|
|
1384
|
+
allKnownFields == allKnownFields && processPosition(decodeResult, pos);
|
|
1385
|
+
} else if (fields[i].startsWith("DT")) {
|
|
1386
|
+
const icao = fields[i].substring(2);
|
|
1387
|
+
decodeResult.raw.arrival_icao = icao;
|
|
1388
|
+
decodeResult.formatted.items.push({
|
|
1389
|
+
type: "destination",
|
|
1390
|
+
code: "DST",
|
|
1391
|
+
label: "Destination",
|
|
1392
|
+
value: decodeResult.raw.arrival_icao
|
|
1393
|
+
});
|
|
1394
|
+
} else if (fields[i].startsWith("RF")) {
|
|
1395
|
+
decodeResult.formatted.items.push({
|
|
1396
|
+
type: "status",
|
|
1397
|
+
code: "ROUTE_STATUS",
|
|
1398
|
+
label: "Route Status",
|
|
1399
|
+
value: "Route Filed"
|
|
1400
|
+
});
|
|
1401
|
+
decodeResult.raw.route_status = "RF";
|
|
1402
|
+
if (fields[i].length > 2) {
|
|
1403
|
+
addRoute(decodeResult, fields[i].substring(2));
|
|
1404
|
+
}
|
|
1405
|
+
} else if (fields[i] == "RP") {
|
|
1406
|
+
decodeResult.raw.route_status = "RP";
|
|
1407
|
+
decodeResult.formatted.items.push({
|
|
1408
|
+
type: "status",
|
|
1409
|
+
code: "ROUTE_STATUS",
|
|
1410
|
+
label: "Route Status",
|
|
1411
|
+
value: "Route Planned"
|
|
1412
|
+
});
|
|
1413
|
+
decodeResult.raw.route_status = fields[i];
|
|
1414
|
+
} else if (fields[i] == "RI") {
|
|
1415
|
+
decodeResult.raw.route_status = "RI";
|
|
1416
|
+
decodeResult.formatted.items.push({
|
|
1417
|
+
type: "status",
|
|
1418
|
+
code: "ROUTE_STATUS",
|
|
1419
|
+
label: "Route Status",
|
|
1420
|
+
value: "Route Inactive"
|
|
1421
|
+
});
|
|
1343
1422
|
} else {
|
|
1344
1423
|
decodeResult.remaining.text += "/" + fields[i];
|
|
1345
1424
|
allKnownFields = false;
|
|
1346
1425
|
}
|
|
1347
1426
|
}
|
|
1348
|
-
decodeResult.raw.route_status = fields[fields.length - 1];
|
|
1349
|
-
var text;
|
|
1350
|
-
if (decodeResult.raw.route_status == "RP") {
|
|
1351
|
-
text = "Route Planned";
|
|
1352
|
-
} else if (decodeResult.raw.route_status == "RI") {
|
|
1353
|
-
text = "Route Inactive";
|
|
1354
|
-
} else if (decodeResult.raw.route_status == "RF") {
|
|
1355
|
-
text = "Route Filed";
|
|
1356
|
-
} else {
|
|
1357
|
-
text = decodeResult.raw.route_status;
|
|
1358
|
-
}
|
|
1359
|
-
decodeResult.formatted.items.push({
|
|
1360
|
-
type: "status",
|
|
1361
|
-
code: "ROUTE_STATUS",
|
|
1362
|
-
label: "Route Status",
|
|
1363
|
-
value: text
|
|
1364
|
-
});
|
|
1365
1427
|
return allKnownFields;
|
|
1366
1428
|
}
|
|
1429
|
+
function processPosition(decodeResult, value) {
|
|
1430
|
+
const position = CoordinateUtils.decodeStringCoordinates(value);
|
|
1431
|
+
if (position) {
|
|
1432
|
+
decodeResult.raw.position = position;
|
|
1433
|
+
decodeResult.formatted.items.push({
|
|
1434
|
+
type: "aircraft_position",
|
|
1435
|
+
code: "POS",
|
|
1436
|
+
label: "Aircraft Position",
|
|
1437
|
+
value: CoordinateUtils.coordinateString(position)
|
|
1438
|
+
});
|
|
1439
|
+
}
|
|
1440
|
+
return !!position;
|
|
1441
|
+
}
|
|
1367
1442
|
function addArrivalAirport(decodeResult, value) {
|
|
1368
1443
|
decodeResult.raw.arrival_icao = value;
|
|
1369
1444
|
decodeResult.formatted.items.push({
|
|
@@ -1382,12 +1457,20 @@ function addDepartureAirport(decodeResult, value) {
|
|
|
1382
1457
|
value: decodeResult.raw.departure_icao
|
|
1383
1458
|
});
|
|
1384
1459
|
}
|
|
1385
|
-
function
|
|
1386
|
-
|
|
1460
|
+
function addRunway(decodeResult, value) {
|
|
1461
|
+
if (value.length === 8) {
|
|
1462
|
+
decodeResult.raw.arrival_runway = value.substring(4, 7);
|
|
1463
|
+
decodeResult.formatted.items.push({
|
|
1464
|
+
type: "runway",
|
|
1465
|
+
label: "Arrival Runway",
|
|
1466
|
+
value: decodeResult.raw.arrival_runway
|
|
1467
|
+
});
|
|
1468
|
+
}
|
|
1469
|
+
decodeResult.raw.departure_runway = value.substring(0, 3);
|
|
1387
1470
|
decodeResult.formatted.items.push({
|
|
1388
1471
|
type: "runway",
|
|
1389
|
-
label: "Runway",
|
|
1390
|
-
value: decodeResult.raw.
|
|
1472
|
+
label: "Departure Runway",
|
|
1473
|
+
value: decodeResult.raw.departure_runway
|
|
1391
1474
|
});
|
|
1392
1475
|
}
|
|
1393
1476
|
function addRoute(decodeResult, value) {
|
|
@@ -1497,7 +1580,7 @@ var Label_H1_POS = class extends DecoderPlugin {
|
|
|
1497
1580
|
qualifiers() {
|
|
1498
1581
|
return {
|
|
1499
1582
|
labels: ["H1"],
|
|
1500
|
-
preambles: ["POS", "#M1BPOS"]
|
|
1583
|
+
preambles: ["POS", "#M1BPOS", "/.POS"]
|
|
1501
1584
|
//TODO - support data before #
|
|
1502
1585
|
};
|
|
1503
1586
|
}
|
|
@@ -1506,30 +1589,25 @@ var Label_H1_POS = class extends DecoderPlugin {
|
|
|
1506
1589
|
decodeResult.decoder.name = this.name;
|
|
1507
1590
|
decodeResult.formatted.description = "Position Report";
|
|
1508
1591
|
decodeResult.message = message;
|
|
1592
|
+
decodeResult.remaining.text = "";
|
|
1509
1593
|
const checksum = message.text.slice(-4);
|
|
1510
|
-
const
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
});
|
|
1527
|
-
processChecksum(decodeResult, checksum);
|
|
1528
|
-
decodeResult.decoded = true;
|
|
1529
|
-
decodeResult.decoder.decodeLevel = "full";
|
|
1594
|
+
const header = findHeader(message.text.slice(0, -4));
|
|
1595
|
+
const decoded = FlightPlanUtils.processFlightPlan(decodeResult, header.split(":"));
|
|
1596
|
+
const parts = message.text.replace(header, "").slice(0, -4).split(",");
|
|
1597
|
+
if (parts.length == 1) {
|
|
1598
|
+
if (decoded) {
|
|
1599
|
+
processChecksum(decodeResult, checksum);
|
|
1600
|
+
decodeResult.decoded = true;
|
|
1601
|
+
decodeResult.decoder.decodeLevel = "full";
|
|
1602
|
+
} else if (decodeResult.remaining.text.length > 0) {
|
|
1603
|
+
processChecksum(decodeResult, checksum);
|
|
1604
|
+
decodeResult.decoded = true;
|
|
1605
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
1606
|
+
} else {
|
|
1607
|
+
decodeResult.decoded = false;
|
|
1608
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1609
|
+
}
|
|
1530
1610
|
} else if (parts.length === 10) {
|
|
1531
|
-
decodeResult.remaining.text = "";
|
|
1532
|
-
processPosition(decodeResult, parts[0]);
|
|
1533
1611
|
processAlt(decodeResult, parts[3]);
|
|
1534
1612
|
processRoute(decodeResult, parts[1], parts[2], parts[4], parts[5], parts[6]);
|
|
1535
1613
|
processTemp(decodeResult, parts[7]);
|
|
@@ -1539,8 +1617,6 @@ var Label_H1_POS = class extends DecoderPlugin {
|
|
|
1539
1617
|
decodeResult.decoded = true;
|
|
1540
1618
|
decodeResult.decoder.decodeLevel = "partial";
|
|
1541
1619
|
} else if (parts.length === 11) {
|
|
1542
|
-
decodeResult.remaining.text = "";
|
|
1543
|
-
processPosition(decodeResult, parts[0]);
|
|
1544
1620
|
processAlt(decodeResult, parts[3]);
|
|
1545
1621
|
processRoute(decodeResult, parts[1], parts[2], parts[4], parts[5], parts[6], parts[10]);
|
|
1546
1622
|
processTemp(decodeResult, parts[7]);
|
|
@@ -1549,9 +1625,18 @@ var Label_H1_POS = class extends DecoderPlugin {
|
|
|
1549
1625
|
processChecksum(decodeResult, checksum);
|
|
1550
1626
|
decodeResult.decoded = true;
|
|
1551
1627
|
decodeResult.decoder.decodeLevel = "partial";
|
|
1628
|
+
} else if (parts.length === 12) {
|
|
1629
|
+
const date = parts[11].substring(2, 4) + parts[11].substring(0, 2) + parts[11].substring(4, 6);
|
|
1630
|
+
processUnknown(decodeResult, parts[3]);
|
|
1631
|
+
processRoute(decodeResult, parts[1], parts[2], parts[4], parts[5], parts[6], date);
|
|
1632
|
+
processTemp(decodeResult, parts[7]);
|
|
1633
|
+
processUnknown(decodeResult, parts[8]);
|
|
1634
|
+
processUnknown(decodeResult, parts[9]);
|
|
1635
|
+
processUnknown(decodeResult, parts[10]);
|
|
1636
|
+
processChecksum(decodeResult, checksum);
|
|
1637
|
+
decodeResult.decoded = true;
|
|
1638
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
1552
1639
|
} else if (parts.length === 14) {
|
|
1553
|
-
decodeResult.remaining.text = "";
|
|
1554
|
-
processPosition(decodeResult, parts[0]);
|
|
1555
1640
|
processAlt(decodeResult, parts[3]);
|
|
1556
1641
|
processRoute(decodeResult, parts[1], parts[2], parts[4], parts[5], parts[6]);
|
|
1557
1642
|
processTemp(decodeResult, parts[7]);
|
|
@@ -1564,9 +1649,48 @@ var Label_H1_POS = class extends DecoderPlugin {
|
|
|
1564
1649
|
processChecksum(decodeResult, checksum);
|
|
1565
1650
|
decodeResult.decoded = true;
|
|
1566
1651
|
decodeResult.decoder.decodeLevel = "partial";
|
|
1652
|
+
} else if (parts.length === 15) {
|
|
1653
|
+
processUnknown(decodeResult, parts[1]);
|
|
1654
|
+
let date = void 0;
|
|
1655
|
+
if (parts[2].startsWith("/DC")) {
|
|
1656
|
+
date = parts[2].substring(3);
|
|
1657
|
+
} else {
|
|
1658
|
+
processUnknown(decodeResult, parts[2]);
|
|
1659
|
+
}
|
|
1660
|
+
processUnknown(decodeResult, parts[3]);
|
|
1661
|
+
const fields = parts[4].split("/");
|
|
1662
|
+
for (let i = 0; i < fields.length; ++i) {
|
|
1663
|
+
const field = fields[i];
|
|
1664
|
+
if (field.startsWith("PS")) {
|
|
1665
|
+
processPosition2(decodeResult, field.substring(2));
|
|
1666
|
+
} else {
|
|
1667
|
+
if (i === 0) {
|
|
1668
|
+
processUnknown(decodeResult, field);
|
|
1669
|
+
} else {
|
|
1670
|
+
processUnknown(decodeResult, "/" + field);
|
|
1671
|
+
}
|
|
1672
|
+
}
|
|
1673
|
+
}
|
|
1674
|
+
processRoute(decodeResult, parts[7], parts[5], parts[9], parts[8], void 0, date);
|
|
1675
|
+
processAlt(decodeResult, parts[6]);
|
|
1676
|
+
processTemp(decodeResult, parts[10]);
|
|
1677
|
+
processUnknown(decodeResult, parts[11]);
|
|
1678
|
+
processUnknown(decodeResult, parts[12]);
|
|
1679
|
+
processUnknown(decodeResult, parts[13]);
|
|
1680
|
+
processUnknown(decodeResult, parts[14]);
|
|
1681
|
+
processChecksum(decodeResult, checksum);
|
|
1682
|
+
decodeResult.decoded = true;
|
|
1683
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
1684
|
+
} else if (parts.length === 21) {
|
|
1685
|
+
processRunway(decodeResult, parts[1]);
|
|
1686
|
+
processUnknown(decodeResult, parts.slice(2, 11).join(","));
|
|
1687
|
+
processTemp(decodeResult, parts[11]);
|
|
1688
|
+
processUnknown(decodeResult, parts.slice(12, 20).join(","));
|
|
1689
|
+
FlightPlanUtils.processFlightPlan(decodeResult, parts[20].split(":"));
|
|
1690
|
+
processChecksum(decodeResult, checksum);
|
|
1691
|
+
decodeResult.decoded = true;
|
|
1692
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
1567
1693
|
} else if (parts.length === 32) {
|
|
1568
|
-
decodeResult.remaining.text = "";
|
|
1569
|
-
processPosition(decodeResult, parts[0]);
|
|
1570
1694
|
processRunway(decodeResult, parts[1]);
|
|
1571
1695
|
const time = parts[2];
|
|
1572
1696
|
processUnknown(decodeResult, parts[3]);
|
|
@@ -1584,14 +1708,14 @@ var Label_H1_POS = class extends DecoderPlugin {
|
|
|
1584
1708
|
processAlt(decodeResult, parts[22]);
|
|
1585
1709
|
processUnknown(decodeResult, parts.slice(23, 31).join(","));
|
|
1586
1710
|
const allProcessed = FlightPlanUtils.processFlightPlan(decodeResult, (parts[31] + checksum).split(":"));
|
|
1587
|
-
processRoute(decodeResult, past, time, next, eta
|
|
1711
|
+
processRoute(decodeResult, past, time, next, eta);
|
|
1588
1712
|
decodeResult.decoded = true;
|
|
1589
1713
|
decodeResult.decoder.decodeLevel = "partial";
|
|
1590
1714
|
} else {
|
|
1591
1715
|
if (options.debug) {
|
|
1592
1716
|
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
1593
1717
|
}
|
|
1594
|
-
decodeResult.remaining.text
|
|
1718
|
+
decodeResult.remaining.text += message.text;
|
|
1595
1719
|
decodeResult.decoded = false;
|
|
1596
1720
|
decodeResult.decoder.decodeLevel = "none";
|
|
1597
1721
|
}
|
|
@@ -1601,18 +1725,17 @@ var Label_H1_POS = class extends DecoderPlugin {
|
|
|
1601
1725
|
function processUnknown(decodeResult, value) {
|
|
1602
1726
|
decodeResult.remaining.text += "," + value;
|
|
1603
1727
|
}
|
|
1604
|
-
function
|
|
1728
|
+
function processPosition2(decodeResult, value) {
|
|
1605
1729
|
const position = CoordinateUtils.decodeStringCoordinates(value);
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
});
|
|
1730
|
+
if (position) {
|
|
1731
|
+
decodeResult.raw.position = position;
|
|
1732
|
+
decodeResult.formatted.items.push({
|
|
1733
|
+
type: "aircraft_position",
|
|
1734
|
+
code: "POS",
|
|
1735
|
+
label: "Aircraft Position",
|
|
1736
|
+
value: CoordinateUtils.coordinateString(position)
|
|
1737
|
+
});
|
|
1738
|
+
}
|
|
1616
1739
|
}
|
|
1617
1740
|
function processAlt(decodeResult, value) {
|
|
1618
1741
|
decodeResult.raw.altitude = Number(value) * 100;
|
|
@@ -1633,11 +1756,11 @@ function processTemp(decodeResult, value) {
|
|
|
1633
1756
|
});
|
|
1634
1757
|
}
|
|
1635
1758
|
function processRunway(decodeResult, value) {
|
|
1636
|
-
decodeResult.raw.
|
|
1759
|
+
decodeResult.raw.arrival_runway = value.replace("RW", "");
|
|
1637
1760
|
decodeResult.formatted.items.push({
|
|
1638
1761
|
type: "runway",
|
|
1639
|
-
label: "Runway",
|
|
1640
|
-
value: decodeResult.raw.
|
|
1762
|
+
label: "Arrival Runway",
|
|
1763
|
+
value: decodeResult.raw.arrival_runway
|
|
1641
1764
|
});
|
|
1642
1765
|
}
|
|
1643
1766
|
function processGndspd(decodeResult, value) {
|
|
@@ -1650,16 +1773,17 @@ function processGndspd(decodeResult, value) {
|
|
|
1650
1773
|
});
|
|
1651
1774
|
}
|
|
1652
1775
|
function processRoute(decodeResult, last, time, next, eta, then, date) {
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1776
|
+
const lastTime = date ? DateTimeUtils.convertDateTimeToEpoch(time, date) : DateTimeUtils.convertHHMMSSToTod(time);
|
|
1777
|
+
const nextTime = date ? DateTimeUtils.convertDateTimeToEpoch(eta, date) : DateTimeUtils.convertHHMMSSToTod(eta);
|
|
1778
|
+
const timeFormat = date ? "epoch" : "tod";
|
|
1779
|
+
const lastWaypoint = RouteUtils.getWaypoint(last);
|
|
1780
|
+
lastWaypoint.time = lastTime;
|
|
1781
|
+
lastWaypoint.timeFormat = timeFormat;
|
|
1782
|
+
const nextWaypoint = RouteUtils.getWaypoint(next);
|
|
1783
|
+
nextWaypoint.time = nextTime;
|
|
1784
|
+
nextWaypoint.timeFormat = timeFormat;
|
|
1785
|
+
const thenWaypoint = RouteUtils.getWaypoint(then || "?");
|
|
1786
|
+
const waypoints = [lastWaypoint, nextWaypoint, thenWaypoint];
|
|
1663
1787
|
decodeResult.raw.route = { waypoints };
|
|
1664
1788
|
decodeResult.formatted.items.push({
|
|
1665
1789
|
type: "aircraft_route",
|
|
@@ -1677,6 +1801,70 @@ function processChecksum(decodeResult, value) {
|
|
|
1677
1801
|
value: "0x" + ("0000" + decodeResult.raw.checksum.toString(16)).slice(-4)
|
|
1678
1802
|
});
|
|
1679
1803
|
}
|
|
1804
|
+
function findHeader(text) {
|
|
1805
|
+
const parts = text.split(",");
|
|
1806
|
+
const header = parts[0];
|
|
1807
|
+
if (header.indexOf("/TS") === -1) {
|
|
1808
|
+
return header;
|
|
1809
|
+
}
|
|
1810
|
+
return parts[0] + "," + parts[1];
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1813
|
+
// lib/plugins/Label_H1_WRN.ts
|
|
1814
|
+
var Label_H1_WRN = class extends DecoderPlugin {
|
|
1815
|
+
name = "label-h1-wrn";
|
|
1816
|
+
qualifiers() {
|
|
1817
|
+
return {
|
|
1818
|
+
labels: ["H1"],
|
|
1819
|
+
preambles: ["WRN", "#CFBWRN"]
|
|
1820
|
+
};
|
|
1821
|
+
}
|
|
1822
|
+
decode(message, options = {}) {
|
|
1823
|
+
let decodeResult = this.defaultResult;
|
|
1824
|
+
decodeResult.decoder.name = this.name;
|
|
1825
|
+
decodeResult.formatted.description = "Warning Message";
|
|
1826
|
+
decodeResult.message = message;
|
|
1827
|
+
const parts = message.text.split("/WN");
|
|
1828
|
+
if (parts.length > 1) {
|
|
1829
|
+
decodeResult.remaining.text = "";
|
|
1830
|
+
const fields = parts[0].split("/");
|
|
1831
|
+
for (let i = 1; i < fields.length; i++) {
|
|
1832
|
+
const field = fields[i];
|
|
1833
|
+
if (field.startsWith("PN")) {
|
|
1834
|
+
processUnknown2(decodeResult, "/" + field);
|
|
1835
|
+
} else {
|
|
1836
|
+
processUnknown2(decodeResult, "/" + field);
|
|
1837
|
+
}
|
|
1838
|
+
}
|
|
1839
|
+
const data = parts[1].substring(0, 20);
|
|
1840
|
+
const msg = parts[1].substring(20);
|
|
1841
|
+
const datetime = data.substring(0, 12);
|
|
1842
|
+
const date = datetime.substring(4, 6) + datetime.substring(2, 4) + datetime.substring(0, 2);
|
|
1843
|
+
processUnknown2(decodeResult, data.substring(12));
|
|
1844
|
+
decodeResult.raw.message_timestamp = DateTimeUtils.convertDateTimeToEpoch(datetime.substring(6), date);
|
|
1845
|
+
decodeResult.raw.warning_message = msg;
|
|
1846
|
+
decodeResult.formatted.items.push({
|
|
1847
|
+
type: "warning",
|
|
1848
|
+
code: "WRN",
|
|
1849
|
+
label: "Warning Message",
|
|
1850
|
+
value: decodeResult.raw.warning_message
|
|
1851
|
+
});
|
|
1852
|
+
decodeResult.decoded = true;
|
|
1853
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
1854
|
+
} else {
|
|
1855
|
+
if (options.debug) {
|
|
1856
|
+
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
1857
|
+
}
|
|
1858
|
+
decodeResult.remaining.text = message.text;
|
|
1859
|
+
decodeResult.decoded = false;
|
|
1860
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1861
|
+
}
|
|
1862
|
+
return decodeResult;
|
|
1863
|
+
}
|
|
1864
|
+
};
|
|
1865
|
+
function processUnknown2(decodeResult, value) {
|
|
1866
|
+
decodeResult.remaining.text += value;
|
|
1867
|
+
}
|
|
1680
1868
|
|
|
1681
1869
|
// lib/plugins/Label_SQ.ts
|
|
1682
1870
|
var Label_SQ = class extends DecoderPlugin {
|
|
@@ -1959,7 +2147,7 @@ var Label_QQ = class extends DecoderPlugin {
|
|
|
1959
2147
|
|
|
1960
2148
|
// lib/utils/miam.ts
|
|
1961
2149
|
var Base85 = __toESM(require("base85"));
|
|
1962
|
-
var
|
|
2150
|
+
var zlib = __toESM(require("minizlib"));
|
|
1963
2151
|
var MIAMCoreV1CRCLength = 4;
|
|
1964
2152
|
var MIAMCoreV2CRCLength = 2;
|
|
1965
2153
|
var MIAMCoreUtils = class {
|
|
@@ -2669,7 +2857,10 @@ var MIAMCoreUtils = class {
|
|
|
2669
2857
|
if (body !== void 0 && body.length > 0) {
|
|
2670
2858
|
if ([1 /* Deflate */, 1 /* Deflate */].indexOf(pduCompression) >= 0) {
|
|
2671
2859
|
try {
|
|
2672
|
-
|
|
2860
|
+
const decompress = new zlib.InflateRaw({ windowBits: 15 });
|
|
2861
|
+
decompress.write(body);
|
|
2862
|
+
decompress.flush(zlib.constants.Z_SYNC_FLUSH);
|
|
2863
|
+
pduData = decompress.read();
|
|
2673
2864
|
} catch (e) {
|
|
2674
2865
|
pduErrors.push("Inflation failed for body: " + e);
|
|
2675
2866
|
}
|
|
@@ -2781,6 +2972,7 @@ var MessageDecoder = class {
|
|
|
2781
2972
|
this.registerPlugin(new Label_B6_Forwardslash(this));
|
|
2782
2973
|
this.registerPlugin(new Label_H1_FPN(this));
|
|
2783
2974
|
this.registerPlugin(new Label_H1_POS(this));
|
|
2975
|
+
this.registerPlugin(new Label_H1_WRN(this));
|
|
2784
2976
|
this.registerPlugin(new Label_80(this));
|
|
2785
2977
|
this.registerPlugin(new Label_8E(this));
|
|
2786
2978
|
this.registerPlugin(new Label_1M_Slash(this));
|