@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.mjs
CHANGED
|
@@ -167,6 +167,32 @@ var Label_5Z = class extends DecoderPlugin {
|
|
|
167
167
|
}
|
|
168
168
|
};
|
|
169
169
|
|
|
170
|
+
// lib/utils/coordinate_utils.ts
|
|
171
|
+
var CoordinateUtils = class {
|
|
172
|
+
static decodeStringCoordinates(stringCoords) {
|
|
173
|
+
var results = {};
|
|
174
|
+
const firstChar = stringCoords.substring(0, 1);
|
|
175
|
+
let middleChar = stringCoords.substring(6, 7);
|
|
176
|
+
let longitudeChars = stringCoords.substring(7, 13);
|
|
177
|
+
if (middleChar == " ") {
|
|
178
|
+
middleChar = stringCoords.substring(7, 8);
|
|
179
|
+
longitudeChars = stringCoords.substring(8, 14);
|
|
180
|
+
}
|
|
181
|
+
if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
|
|
182
|
+
results.latitude = Number(stringCoords.substring(1, 6)) / 1e3 * (firstChar === "S" ? -1 : 1);
|
|
183
|
+
results.longitude = Number(longitudeChars) / 1e3 * (middleChar === "W" ? -1 : 1);
|
|
184
|
+
} else {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
return results;
|
|
188
|
+
}
|
|
189
|
+
static coordinateString(coords) {
|
|
190
|
+
const latDir = coords.latitude > 0 ? "N" : "S";
|
|
191
|
+
const lonDir = coords.longitude > 0 ? "E" : "W";
|
|
192
|
+
return `${Math.abs(coords.latitude).toFixed(3)} ${latDir}, ${Math.abs(coords.longitude).toFixed(3)} ${lonDir}`;
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
|
|
170
196
|
// lib/plugins/Label_12_N_Space.ts
|
|
171
197
|
var Label_12_N_Space = class extends DecoderPlugin {
|
|
172
198
|
name = "label-12-n-space";
|
|
@@ -188,16 +214,16 @@ var Label_12_N_Space = class extends DecoderPlugin {
|
|
|
188
214
|
console.log(`Label 12 N : results`);
|
|
189
215
|
console.log(results);
|
|
190
216
|
}
|
|
191
|
-
decodeResult.raw.
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
217
|
+
decodeResult.raw.position = {
|
|
218
|
+
latitude: Number(results.groups.lat_coord) * (results.groups.lat == "N" ? 1 : -1),
|
|
219
|
+
longitude: Number(results.groups.long_coord) * (results.groups.long == "E" ? 1 : -1)
|
|
220
|
+
};
|
|
195
221
|
decodeResult.raw.flight_level = results.groups.alt == "GRD" || results.groups.alt == "***" ? "0" : Number(results.groups.alt);
|
|
196
222
|
decodeResult.formatted.items.push({
|
|
197
223
|
type: "aircraft_position",
|
|
198
224
|
code: "POS",
|
|
199
225
|
label: "Aircraft Position",
|
|
200
|
-
value:
|
|
226
|
+
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
201
227
|
});
|
|
202
228
|
decodeResult.formatted.items.push({
|
|
203
229
|
type: "flight_level",
|
|
@@ -220,37 +246,6 @@ var Label_12_N_Space = class extends DecoderPlugin {
|
|
|
220
246
|
}
|
|
221
247
|
};
|
|
222
248
|
|
|
223
|
-
// lib/utils/coordinate_utils.ts
|
|
224
|
-
var CoordinateUtils = class {
|
|
225
|
-
static decodeStringCoordinates(stringCoords) {
|
|
226
|
-
var results = {};
|
|
227
|
-
const firstChar = stringCoords.substring(0, 1);
|
|
228
|
-
let middleChar = stringCoords.substring(6, 7);
|
|
229
|
-
let longitudeChars = stringCoords.substring(7, 13);
|
|
230
|
-
if (middleChar == " ") {
|
|
231
|
-
middleChar = stringCoords.substring(7, 8);
|
|
232
|
-
longitudeChars = stringCoords.substring(8, 14);
|
|
233
|
-
}
|
|
234
|
-
if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
|
|
235
|
-
results.latitudeDirection = firstChar;
|
|
236
|
-
results.latitude = Number(stringCoords.substring(1, 6)) / 1e3 * (firstChar === "S" ? -1 : 1);
|
|
237
|
-
results.longitudeDirection = middleChar;
|
|
238
|
-
results.longitude = Number(longitudeChars) / 1e3 * (middleChar === "W" ? -1 : 1);
|
|
239
|
-
} else {
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
return results;
|
|
243
|
-
}
|
|
244
|
-
static coordinateString(coords) {
|
|
245
|
-
return `${Math.abs(coords.latitude)} ${coords.latitudeDirection}, ${Math.abs(coords.longitude)} ${coords.longitudeDirection}`;
|
|
246
|
-
}
|
|
247
|
-
static latLonToCoordinateString(lat, lon) {
|
|
248
|
-
const latDir = lat > 0 ? "N" : "S";
|
|
249
|
-
const lonDir = lon > 0 ? "E" : "W";
|
|
250
|
-
return `${Math.abs(lat)} ${latDir}, ${Math.abs(lon)} ${lonDir}`;
|
|
251
|
-
}
|
|
252
|
-
};
|
|
253
|
-
|
|
254
249
|
// lib/plugins/Label_15.ts
|
|
255
250
|
var Label_15 = class extends DecoderPlugin {
|
|
256
251
|
name = "label-5z";
|
|
@@ -304,9 +299,7 @@ var Label_15_FST = class extends DecoderPlugin {
|
|
|
304
299
|
const middleChar = stringCoords.substring(7, 8);
|
|
305
300
|
decodeResult.raw.position = {};
|
|
306
301
|
if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
|
|
307
|
-
decodeResult.raw.position.latitudeDirection = firstChar;
|
|
308
302
|
decodeResult.raw.position.latitude = Number(stringCoords.substring(1, 7)) / 1e4 * (firstChar === "S" ? -1 : 1);
|
|
309
|
-
decodeResult.raw.position.longitudeDirection = middleChar;
|
|
310
303
|
decodeResult.raw.position.longitude = Number(stringCoords.substring(8, 26)) / 1e5 * (middleChar === "W" ? -1 : 1);
|
|
311
304
|
} else {
|
|
312
305
|
decodeResult.decoded = false;
|
|
@@ -358,16 +351,16 @@ var Label_16_N_Space = class extends DecoderPlugin {
|
|
|
358
351
|
console.log(`Label 16 N : results`);
|
|
359
352
|
console.log(results);
|
|
360
353
|
}
|
|
361
|
-
decodeResult.raw.
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
354
|
+
decodeResult.raw.position = {
|
|
355
|
+
latitude: Number(results.groups.lat_coord) * (results.groups.lat == "N" ? 1 : -1),
|
|
356
|
+
longitude: Number(results.groups.long_coord) * (results.groups.long == "E" ? 1 : -1)
|
|
357
|
+
};
|
|
365
358
|
decodeResult.raw.flight_level = results.groups.alt == "GRD" || results.groups.alt == "***" ? "0" : Number(results.groups.alt);
|
|
366
359
|
decodeResult.formatted.items.push({
|
|
367
360
|
type: "aircraft_position",
|
|
368
361
|
code: "POS",
|
|
369
362
|
label: "Aircraft Position",
|
|
370
|
-
value:
|
|
363
|
+
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
371
364
|
});
|
|
372
365
|
decodeResult.formatted.items.push({
|
|
373
366
|
type: "flight_level",
|
|
@@ -383,15 +376,15 @@ var Label_16_N_Space = class extends DecoderPlugin {
|
|
|
383
376
|
console.log(`Label 16 N : results`);
|
|
384
377
|
console.log(results);
|
|
385
378
|
}
|
|
386
|
-
decodeResult.raw.
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
379
|
+
decodeResult.raw.position = {
|
|
380
|
+
latitude: Number(results.groups.lat_coord) * (results.groups.lat == "N" ? 1 : -1),
|
|
381
|
+
longitude: Number(results.groups.long_coord) * (results.groups.long == "E" ? 1 : -1)
|
|
382
|
+
};
|
|
390
383
|
decodeResult.formatted.items.push({
|
|
391
384
|
type: "aircraft_position",
|
|
392
385
|
code: "POS",
|
|
393
386
|
label: "Aircraft Position",
|
|
394
|
-
value:
|
|
387
|
+
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
395
388
|
});
|
|
396
389
|
decodeResult.decoded = true;
|
|
397
390
|
decodeResult.decoder.decodeLevel = "full";
|
|
@@ -446,11 +439,14 @@ var DateTimeUtils = class {
|
|
|
446
439
|
/**
|
|
447
440
|
*
|
|
448
441
|
* @param time HHMMSS
|
|
449
|
-
* @param date MMDDYY
|
|
442
|
+
* @param date MMDDYY or MMDDYYYY
|
|
450
443
|
* @returns seconds since epoch
|
|
451
444
|
*/
|
|
452
445
|
static convertDateTimeToEpoch(time, date) {
|
|
453
|
-
|
|
446
|
+
if (date.length === 6) {
|
|
447
|
+
date = date.substring(0, 4) + `20${date.substring(4, 6)}`;
|
|
448
|
+
}
|
|
449
|
+
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`;
|
|
454
450
|
const millis = Date.parse(timestamp);
|
|
455
451
|
return millis / 1e3;
|
|
456
452
|
}
|
|
@@ -542,11 +538,13 @@ var Label_20_POS = class extends DecoderPlugin {
|
|
|
542
538
|
console.log(`DEBUG: ${this.name}: Variation 2 detected`);
|
|
543
539
|
const rawCoords = fields[0];
|
|
544
540
|
decodeResult.raw.position = CoordinateUtils.decodeStringCoordinates(rawCoords);
|
|
545
|
-
decodeResult.
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
541
|
+
if (decodeResult.raw.position) {
|
|
542
|
+
decodeResult.formatted.items.push({
|
|
543
|
+
type: "position",
|
|
544
|
+
label: "Position",
|
|
545
|
+
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
546
|
+
});
|
|
547
|
+
}
|
|
550
548
|
decodeResult.decoded = true;
|
|
551
549
|
decodeResult.decoder.decodeLevel = "full";
|
|
552
550
|
} else {
|
|
@@ -1052,7 +1050,7 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
1052
1050
|
const lon = Number(posResult.groups.lng) * (posResult.groups.lngd === "W" ? -1 : 1);
|
|
1053
1051
|
const latitude = Number.isInteger(lat) ? lat / 1e3 : lat / 100;
|
|
1054
1052
|
const longitude = Number.isInteger(lon) ? lon / 1e3 : lon / 100;
|
|
1055
|
-
decodeResult.raw.
|
|
1053
|
+
decodeResult.raw.position = {
|
|
1056
1054
|
latitude,
|
|
1057
1055
|
longitude
|
|
1058
1056
|
};
|
|
@@ -1060,7 +1058,7 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
1060
1058
|
type: "position",
|
|
1061
1059
|
code: "POS",
|
|
1062
1060
|
label: "Position",
|
|
1063
|
-
value:
|
|
1061
|
+
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
1064
1062
|
});
|
|
1065
1063
|
break;
|
|
1066
1064
|
}
|
|
@@ -1203,7 +1201,10 @@ var RouteUtils = class _RouteUtils {
|
|
|
1203
1201
|
static waypointToString(waypoint) {
|
|
1204
1202
|
let s = waypoint.name;
|
|
1205
1203
|
if (waypoint.latitude && waypoint.longitude) {
|
|
1206
|
-
s += `(${CoordinateUtils.
|
|
1204
|
+
s += `(${CoordinateUtils.coordinateString({ latitude: waypoint.latitude, longitude: waypoint.longitude })})`;
|
|
1205
|
+
}
|
|
1206
|
+
if (waypoint.offset) {
|
|
1207
|
+
s += `[${waypoint.offset.bearing}\xB0 ${waypoint.offset.distance}nm]`;
|
|
1207
1208
|
}
|
|
1208
1209
|
if (waypoint.time && waypoint.timeFormat) {
|
|
1209
1210
|
s += `@${_RouteUtils.timestampToString(waypoint.time, waypoint.timeFormat)}`;
|
|
@@ -1211,14 +1212,23 @@ var RouteUtils = class _RouteUtils {
|
|
|
1211
1212
|
return s;
|
|
1212
1213
|
}
|
|
1213
1214
|
static getWaypoint(leg) {
|
|
1215
|
+
const regex = leg.match(/^([A-Z]+)(\d{3})-(\d{4})$/);
|
|
1216
|
+
if (regex?.length == 4) {
|
|
1217
|
+
return { name: regex[1], offset: { bearing: parseInt(regex[2]), distance: parseInt(regex[3]) / 10 } };
|
|
1218
|
+
}
|
|
1214
1219
|
const waypoint = leg.split(",");
|
|
1215
1220
|
if (waypoint.length == 2) {
|
|
1216
1221
|
const position = CoordinateUtils.decodeStringCoordinates(waypoint[1]);
|
|
1217
|
-
|
|
1222
|
+
if (position) {
|
|
1223
|
+
return { name: waypoint[0], latitude: position.latitude, longitude: position.longitude };
|
|
1224
|
+
}
|
|
1218
1225
|
}
|
|
1219
|
-
if (leg.length == 14) {
|
|
1226
|
+
if (leg.length == 13 || leg.length == 14) {
|
|
1220
1227
|
const position = CoordinateUtils.decodeStringCoordinates(leg);
|
|
1221
|
-
|
|
1228
|
+
const name = waypoint.length == 2 ? waypoint[0] : "";
|
|
1229
|
+
if (position) {
|
|
1230
|
+
return { name, latitude: position.latitude, longitude: position.longitude };
|
|
1231
|
+
}
|
|
1222
1232
|
}
|
|
1223
1233
|
return { name: leg };
|
|
1224
1234
|
}
|
|
@@ -1278,7 +1288,7 @@ var FlightPlanUtils = class {
|
|
|
1278
1288
|
addRoute(decodeResult, value);
|
|
1279
1289
|
break;
|
|
1280
1290
|
case "R":
|
|
1281
|
-
|
|
1291
|
+
addRunway(decodeResult, value);
|
|
1282
1292
|
break;
|
|
1283
1293
|
default:
|
|
1284
1294
|
if (allKnownFields) {
|
|
@@ -1292,41 +1302,106 @@ var FlightPlanUtils = class {
|
|
|
1292
1302
|
return allKnownFields;
|
|
1293
1303
|
}
|
|
1294
1304
|
};
|
|
1305
|
+
function parseMessageType(decodeResult, messageType) {
|
|
1306
|
+
let decoded = true;
|
|
1307
|
+
const parts = messageType.split("#");
|
|
1308
|
+
if (parts.length == 1) {
|
|
1309
|
+
if (parts[0].startsWith("POS") && parts[0].length !== 3 && !parts[0].startsWith("POS/")) {
|
|
1310
|
+
decoded = processPosition(decodeResult, parts[0].substring(3));
|
|
1311
|
+
}
|
|
1312
|
+
return decoded;
|
|
1313
|
+
} else if (parts.length == 2) {
|
|
1314
|
+
if (parts[0].length > 0) {
|
|
1315
|
+
decodeResult.remaining.text += parts[0].substring(0, 3);
|
|
1316
|
+
decodeResult.raw.flight_number = parts[0].substring(3);
|
|
1317
|
+
decodeResult.remaining.text += "#" + parts[1].substring(0, 3);
|
|
1318
|
+
}
|
|
1319
|
+
if (parts[1].substring(3, 6) === "POS" && parts[1].length !== 6 && parts[1].substring(3, 7) !== "POS/") {
|
|
1320
|
+
decoded = processPosition(decodeResult, parts[1].substring(6));
|
|
1321
|
+
}
|
|
1322
|
+
decodeResult.raw.message_type = messageType;
|
|
1323
|
+
return decoded;
|
|
1324
|
+
}
|
|
1325
|
+
decodeResult.remaining.text += messageType;
|
|
1326
|
+
return false;
|
|
1327
|
+
}
|
|
1295
1328
|
function parseHeader(decodeResult, header) {
|
|
1296
1329
|
let allKnownFields = true;
|
|
1297
1330
|
const fields = header.split("/");
|
|
1298
|
-
|
|
1331
|
+
allKnownFields = allKnownFields && parseMessageType(decodeResult, fields[0]);
|
|
1332
|
+
for (let i = 1; i < fields.length; ++i) {
|
|
1299
1333
|
if (fields[i].startsWith("FN")) {
|
|
1300
1334
|
decodeResult.raw.flight_number = fields[i].substring(2);
|
|
1301
1335
|
} else if (fields[i].startsWith("SN")) {
|
|
1302
1336
|
decodeResult.raw.serial_number = fields[i].substring(2);
|
|
1303
1337
|
} else if (fields[i].startsWith("TS")) {
|
|
1304
1338
|
const ts = fields[i].substring(2).split(",");
|
|
1305
|
-
|
|
1339
|
+
let time = DateTimeUtils.convertDateTimeToEpoch(ts[0], ts[1]);
|
|
1340
|
+
if (Number.isNaN(time)) {
|
|
1341
|
+
const date = ts[1].substring(2, 4) + ts[1].substring(0, 2) + ts[1].substring(4, 6);
|
|
1342
|
+
time = DateTimeUtils.convertDateTimeToEpoch(ts[0], date);
|
|
1343
|
+
}
|
|
1344
|
+
decodeResult.raw.message_timestamp = time;
|
|
1345
|
+
} else if (fields[i].startsWith("PS")) {
|
|
1346
|
+
const pos = fields[i].substring(2);
|
|
1347
|
+
allKnownFields == allKnownFields && processPosition(decodeResult, pos);
|
|
1348
|
+
} else if (fields[i].startsWith("DT")) {
|
|
1349
|
+
const icao = fields[i].substring(2);
|
|
1350
|
+
decodeResult.raw.arrival_icao = icao;
|
|
1351
|
+
decodeResult.formatted.items.push({
|
|
1352
|
+
type: "destination",
|
|
1353
|
+
code: "DST",
|
|
1354
|
+
label: "Destination",
|
|
1355
|
+
value: decodeResult.raw.arrival_icao
|
|
1356
|
+
});
|
|
1357
|
+
} else if (fields[i].startsWith("RF")) {
|
|
1358
|
+
decodeResult.formatted.items.push({
|
|
1359
|
+
type: "status",
|
|
1360
|
+
code: "ROUTE_STATUS",
|
|
1361
|
+
label: "Route Status",
|
|
1362
|
+
value: "Route Filed"
|
|
1363
|
+
});
|
|
1364
|
+
decodeResult.raw.route_status = "RF";
|
|
1365
|
+
if (fields[i].length > 2) {
|
|
1366
|
+
addRoute(decodeResult, fields[i].substring(2));
|
|
1367
|
+
}
|
|
1368
|
+
} else if (fields[i] == "RP") {
|
|
1369
|
+
decodeResult.raw.route_status = "RP";
|
|
1370
|
+
decodeResult.formatted.items.push({
|
|
1371
|
+
type: "status",
|
|
1372
|
+
code: "ROUTE_STATUS",
|
|
1373
|
+
label: "Route Status",
|
|
1374
|
+
value: "Route Planned"
|
|
1375
|
+
});
|
|
1376
|
+
decodeResult.raw.route_status = fields[i];
|
|
1377
|
+
} else if (fields[i] == "RI") {
|
|
1378
|
+
decodeResult.raw.route_status = "RI";
|
|
1379
|
+
decodeResult.formatted.items.push({
|
|
1380
|
+
type: "status",
|
|
1381
|
+
code: "ROUTE_STATUS",
|
|
1382
|
+
label: "Route Status",
|
|
1383
|
+
value: "Route Inactive"
|
|
1384
|
+
});
|
|
1306
1385
|
} else {
|
|
1307
1386
|
decodeResult.remaining.text += "/" + fields[i];
|
|
1308
1387
|
allKnownFields = false;
|
|
1309
1388
|
}
|
|
1310
1389
|
}
|
|
1311
|
-
decodeResult.raw.route_status = fields[fields.length - 1];
|
|
1312
|
-
var text;
|
|
1313
|
-
if (decodeResult.raw.route_status == "RP") {
|
|
1314
|
-
text = "Route Planned";
|
|
1315
|
-
} else if (decodeResult.raw.route_status == "RI") {
|
|
1316
|
-
text = "Route Inactive";
|
|
1317
|
-
} else if (decodeResult.raw.route_status == "RF") {
|
|
1318
|
-
text = "Route Filed";
|
|
1319
|
-
} else {
|
|
1320
|
-
text = decodeResult.raw.route_status;
|
|
1321
|
-
}
|
|
1322
|
-
decodeResult.formatted.items.push({
|
|
1323
|
-
type: "status",
|
|
1324
|
-
code: "ROUTE_STATUS",
|
|
1325
|
-
label: "Route Status",
|
|
1326
|
-
value: text
|
|
1327
|
-
});
|
|
1328
1390
|
return allKnownFields;
|
|
1329
1391
|
}
|
|
1392
|
+
function processPosition(decodeResult, value) {
|
|
1393
|
+
const position = CoordinateUtils.decodeStringCoordinates(value);
|
|
1394
|
+
if (position) {
|
|
1395
|
+
decodeResult.raw.position = position;
|
|
1396
|
+
decodeResult.formatted.items.push({
|
|
1397
|
+
type: "aircraft_position",
|
|
1398
|
+
code: "POS",
|
|
1399
|
+
label: "Aircraft Position",
|
|
1400
|
+
value: CoordinateUtils.coordinateString(position)
|
|
1401
|
+
});
|
|
1402
|
+
}
|
|
1403
|
+
return !!position;
|
|
1404
|
+
}
|
|
1330
1405
|
function addArrivalAirport(decodeResult, value) {
|
|
1331
1406
|
decodeResult.raw.arrival_icao = value;
|
|
1332
1407
|
decodeResult.formatted.items.push({
|
|
@@ -1345,12 +1420,20 @@ function addDepartureAirport(decodeResult, value) {
|
|
|
1345
1420
|
value: decodeResult.raw.departure_icao
|
|
1346
1421
|
});
|
|
1347
1422
|
}
|
|
1348
|
-
function
|
|
1349
|
-
|
|
1423
|
+
function addRunway(decodeResult, value) {
|
|
1424
|
+
if (value.length === 8) {
|
|
1425
|
+
decodeResult.raw.arrival_runway = value.substring(4, 7);
|
|
1426
|
+
decodeResult.formatted.items.push({
|
|
1427
|
+
type: "runway",
|
|
1428
|
+
label: "Arrival Runway",
|
|
1429
|
+
value: decodeResult.raw.arrival_runway
|
|
1430
|
+
});
|
|
1431
|
+
}
|
|
1432
|
+
decodeResult.raw.departure_runway = value.substring(0, 3);
|
|
1350
1433
|
decodeResult.formatted.items.push({
|
|
1351
1434
|
type: "runway",
|
|
1352
|
-
label: "Runway",
|
|
1353
|
-
value: decodeResult.raw.
|
|
1435
|
+
label: "Departure Runway",
|
|
1436
|
+
value: decodeResult.raw.departure_runway
|
|
1354
1437
|
});
|
|
1355
1438
|
}
|
|
1356
1439
|
function addRoute(decodeResult, value) {
|
|
@@ -1460,7 +1543,7 @@ var Label_H1_POS = class extends DecoderPlugin {
|
|
|
1460
1543
|
qualifiers() {
|
|
1461
1544
|
return {
|
|
1462
1545
|
labels: ["H1"],
|
|
1463
|
-
preambles: ["POS", "#M1BPOS"]
|
|
1546
|
+
preambles: ["POS", "#M1BPOS", "/.POS"]
|
|
1464
1547
|
//TODO - support data before #
|
|
1465
1548
|
};
|
|
1466
1549
|
}
|
|
@@ -1469,30 +1552,25 @@ var Label_H1_POS = class extends DecoderPlugin {
|
|
|
1469
1552
|
decodeResult.decoder.name = this.name;
|
|
1470
1553
|
decodeResult.formatted.description = "Position Report";
|
|
1471
1554
|
decodeResult.message = message;
|
|
1555
|
+
decodeResult.remaining.text = "";
|
|
1472
1556
|
const checksum = message.text.slice(-4);
|
|
1473
|
-
const
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
});
|
|
1490
|
-
processChecksum(decodeResult, checksum);
|
|
1491
|
-
decodeResult.decoded = true;
|
|
1492
|
-
decodeResult.decoder.decodeLevel = "full";
|
|
1557
|
+
const header = findHeader(message.text.slice(0, -4));
|
|
1558
|
+
const decoded = FlightPlanUtils.processFlightPlan(decodeResult, header.split(":"));
|
|
1559
|
+
const parts = message.text.replace(header, "").slice(0, -4).split(",");
|
|
1560
|
+
if (parts.length == 1) {
|
|
1561
|
+
if (decoded) {
|
|
1562
|
+
processChecksum(decodeResult, checksum);
|
|
1563
|
+
decodeResult.decoded = true;
|
|
1564
|
+
decodeResult.decoder.decodeLevel = "full";
|
|
1565
|
+
} else if (decodeResult.remaining.text.length > 0) {
|
|
1566
|
+
processChecksum(decodeResult, checksum);
|
|
1567
|
+
decodeResult.decoded = true;
|
|
1568
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
1569
|
+
} else {
|
|
1570
|
+
decodeResult.decoded = false;
|
|
1571
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1572
|
+
}
|
|
1493
1573
|
} else if (parts.length === 10) {
|
|
1494
|
-
decodeResult.remaining.text = "";
|
|
1495
|
-
processPosition(decodeResult, parts[0]);
|
|
1496
1574
|
processAlt(decodeResult, parts[3]);
|
|
1497
1575
|
processRoute(decodeResult, parts[1], parts[2], parts[4], parts[5], parts[6]);
|
|
1498
1576
|
processTemp(decodeResult, parts[7]);
|
|
@@ -1502,8 +1580,6 @@ var Label_H1_POS = class extends DecoderPlugin {
|
|
|
1502
1580
|
decodeResult.decoded = true;
|
|
1503
1581
|
decodeResult.decoder.decodeLevel = "partial";
|
|
1504
1582
|
} else if (parts.length === 11) {
|
|
1505
|
-
decodeResult.remaining.text = "";
|
|
1506
|
-
processPosition(decodeResult, parts[0]);
|
|
1507
1583
|
processAlt(decodeResult, parts[3]);
|
|
1508
1584
|
processRoute(decodeResult, parts[1], parts[2], parts[4], parts[5], parts[6], parts[10]);
|
|
1509
1585
|
processTemp(decodeResult, parts[7]);
|
|
@@ -1512,9 +1588,18 @@ var Label_H1_POS = class extends DecoderPlugin {
|
|
|
1512
1588
|
processChecksum(decodeResult, checksum);
|
|
1513
1589
|
decodeResult.decoded = true;
|
|
1514
1590
|
decodeResult.decoder.decodeLevel = "partial";
|
|
1591
|
+
} else if (parts.length === 12) {
|
|
1592
|
+
const date = parts[11].substring(2, 4) + parts[11].substring(0, 2) + parts[11].substring(4, 6);
|
|
1593
|
+
processUnknown(decodeResult, parts[3]);
|
|
1594
|
+
processRoute(decodeResult, parts[1], parts[2], parts[4], parts[5], parts[6], date);
|
|
1595
|
+
processTemp(decodeResult, parts[7]);
|
|
1596
|
+
processUnknown(decodeResult, parts[8]);
|
|
1597
|
+
processUnknown(decodeResult, parts[9]);
|
|
1598
|
+
processUnknown(decodeResult, parts[10]);
|
|
1599
|
+
processChecksum(decodeResult, checksum);
|
|
1600
|
+
decodeResult.decoded = true;
|
|
1601
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
1515
1602
|
} else if (parts.length === 14) {
|
|
1516
|
-
decodeResult.remaining.text = "";
|
|
1517
|
-
processPosition(decodeResult, parts[0]);
|
|
1518
1603
|
processAlt(decodeResult, parts[3]);
|
|
1519
1604
|
processRoute(decodeResult, parts[1], parts[2], parts[4], parts[5], parts[6]);
|
|
1520
1605
|
processTemp(decodeResult, parts[7]);
|
|
@@ -1527,9 +1612,48 @@ var Label_H1_POS = class extends DecoderPlugin {
|
|
|
1527
1612
|
processChecksum(decodeResult, checksum);
|
|
1528
1613
|
decodeResult.decoded = true;
|
|
1529
1614
|
decodeResult.decoder.decodeLevel = "partial";
|
|
1615
|
+
} else if (parts.length === 15) {
|
|
1616
|
+
processUnknown(decodeResult, parts[1]);
|
|
1617
|
+
let date = void 0;
|
|
1618
|
+
if (parts[2].startsWith("/DC")) {
|
|
1619
|
+
date = parts[2].substring(3);
|
|
1620
|
+
} else {
|
|
1621
|
+
processUnknown(decodeResult, parts[2]);
|
|
1622
|
+
}
|
|
1623
|
+
processUnknown(decodeResult, parts[3]);
|
|
1624
|
+
const fields = parts[4].split("/");
|
|
1625
|
+
for (let i = 0; i < fields.length; ++i) {
|
|
1626
|
+
const field = fields[i];
|
|
1627
|
+
if (field.startsWith("PS")) {
|
|
1628
|
+
processPosition2(decodeResult, field.substring(2));
|
|
1629
|
+
} else {
|
|
1630
|
+
if (i === 0) {
|
|
1631
|
+
processUnknown(decodeResult, field);
|
|
1632
|
+
} else {
|
|
1633
|
+
processUnknown(decodeResult, "/" + field);
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
processRoute(decodeResult, parts[7], parts[5], parts[9], parts[8], void 0, date);
|
|
1638
|
+
processAlt(decodeResult, parts[6]);
|
|
1639
|
+
processTemp(decodeResult, parts[10]);
|
|
1640
|
+
processUnknown(decodeResult, parts[11]);
|
|
1641
|
+
processUnknown(decodeResult, parts[12]);
|
|
1642
|
+
processUnknown(decodeResult, parts[13]);
|
|
1643
|
+
processUnknown(decodeResult, parts[14]);
|
|
1644
|
+
processChecksum(decodeResult, checksum);
|
|
1645
|
+
decodeResult.decoded = true;
|
|
1646
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
1647
|
+
} else if (parts.length === 21) {
|
|
1648
|
+
processRunway(decodeResult, parts[1]);
|
|
1649
|
+
processUnknown(decodeResult, parts.slice(2, 11).join(","));
|
|
1650
|
+
processTemp(decodeResult, parts[11]);
|
|
1651
|
+
processUnknown(decodeResult, parts.slice(12, 20).join(","));
|
|
1652
|
+
FlightPlanUtils.processFlightPlan(decodeResult, parts[20].split(":"));
|
|
1653
|
+
processChecksum(decodeResult, checksum);
|
|
1654
|
+
decodeResult.decoded = true;
|
|
1655
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
1530
1656
|
} else if (parts.length === 32) {
|
|
1531
|
-
decodeResult.remaining.text = "";
|
|
1532
|
-
processPosition(decodeResult, parts[0]);
|
|
1533
1657
|
processRunway(decodeResult, parts[1]);
|
|
1534
1658
|
const time = parts[2];
|
|
1535
1659
|
processUnknown(decodeResult, parts[3]);
|
|
@@ -1547,14 +1671,14 @@ var Label_H1_POS = class extends DecoderPlugin {
|
|
|
1547
1671
|
processAlt(decodeResult, parts[22]);
|
|
1548
1672
|
processUnknown(decodeResult, parts.slice(23, 31).join(","));
|
|
1549
1673
|
const allProcessed = FlightPlanUtils.processFlightPlan(decodeResult, (parts[31] + checksum).split(":"));
|
|
1550
|
-
processRoute(decodeResult, past, time, next, eta
|
|
1674
|
+
processRoute(decodeResult, past, time, next, eta);
|
|
1551
1675
|
decodeResult.decoded = true;
|
|
1552
1676
|
decodeResult.decoder.decodeLevel = "partial";
|
|
1553
1677
|
} else {
|
|
1554
1678
|
if (options.debug) {
|
|
1555
1679
|
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
1556
1680
|
}
|
|
1557
|
-
decodeResult.remaining.text
|
|
1681
|
+
decodeResult.remaining.text += message.text;
|
|
1558
1682
|
decodeResult.decoded = false;
|
|
1559
1683
|
decodeResult.decoder.decodeLevel = "none";
|
|
1560
1684
|
}
|
|
@@ -1564,18 +1688,17 @@ var Label_H1_POS = class extends DecoderPlugin {
|
|
|
1564
1688
|
function processUnknown(decodeResult, value) {
|
|
1565
1689
|
decodeResult.remaining.text += "," + value;
|
|
1566
1690
|
}
|
|
1567
|
-
function
|
|
1691
|
+
function processPosition2(decodeResult, value) {
|
|
1568
1692
|
const position = CoordinateUtils.decodeStringCoordinates(value);
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
});
|
|
1693
|
+
if (position) {
|
|
1694
|
+
decodeResult.raw.position = position;
|
|
1695
|
+
decodeResult.formatted.items.push({
|
|
1696
|
+
type: "aircraft_position",
|
|
1697
|
+
code: "POS",
|
|
1698
|
+
label: "Aircraft Position",
|
|
1699
|
+
value: CoordinateUtils.coordinateString(position)
|
|
1700
|
+
});
|
|
1701
|
+
}
|
|
1579
1702
|
}
|
|
1580
1703
|
function processAlt(decodeResult, value) {
|
|
1581
1704
|
decodeResult.raw.altitude = Number(value) * 100;
|
|
@@ -1596,11 +1719,11 @@ function processTemp(decodeResult, value) {
|
|
|
1596
1719
|
});
|
|
1597
1720
|
}
|
|
1598
1721
|
function processRunway(decodeResult, value) {
|
|
1599
|
-
decodeResult.raw.
|
|
1722
|
+
decodeResult.raw.arrival_runway = value.replace("RW", "");
|
|
1600
1723
|
decodeResult.formatted.items.push({
|
|
1601
1724
|
type: "runway",
|
|
1602
|
-
label: "Runway",
|
|
1603
|
-
value: decodeResult.raw.
|
|
1725
|
+
label: "Arrival Runway",
|
|
1726
|
+
value: decodeResult.raw.arrival_runway
|
|
1604
1727
|
});
|
|
1605
1728
|
}
|
|
1606
1729
|
function processGndspd(decodeResult, value) {
|
|
@@ -1613,16 +1736,17 @@ function processGndspd(decodeResult, value) {
|
|
|
1613
1736
|
});
|
|
1614
1737
|
}
|
|
1615
1738
|
function processRoute(decodeResult, last, time, next, eta, then, date) {
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1739
|
+
const lastTime = date ? DateTimeUtils.convertDateTimeToEpoch(time, date) : DateTimeUtils.convertHHMMSSToTod(time);
|
|
1740
|
+
const nextTime = date ? DateTimeUtils.convertDateTimeToEpoch(eta, date) : DateTimeUtils.convertHHMMSSToTod(eta);
|
|
1741
|
+
const timeFormat = date ? "epoch" : "tod";
|
|
1742
|
+
const lastWaypoint = RouteUtils.getWaypoint(last);
|
|
1743
|
+
lastWaypoint.time = lastTime;
|
|
1744
|
+
lastWaypoint.timeFormat = timeFormat;
|
|
1745
|
+
const nextWaypoint = RouteUtils.getWaypoint(next);
|
|
1746
|
+
nextWaypoint.time = nextTime;
|
|
1747
|
+
nextWaypoint.timeFormat = timeFormat;
|
|
1748
|
+
const thenWaypoint = RouteUtils.getWaypoint(then || "?");
|
|
1749
|
+
const waypoints = [lastWaypoint, nextWaypoint, thenWaypoint];
|
|
1626
1750
|
decodeResult.raw.route = { waypoints };
|
|
1627
1751
|
decodeResult.formatted.items.push({
|
|
1628
1752
|
type: "aircraft_route",
|
|
@@ -1640,6 +1764,70 @@ function processChecksum(decodeResult, value) {
|
|
|
1640
1764
|
value: "0x" + ("0000" + decodeResult.raw.checksum.toString(16)).slice(-4)
|
|
1641
1765
|
});
|
|
1642
1766
|
}
|
|
1767
|
+
function findHeader(text) {
|
|
1768
|
+
const parts = text.split(",");
|
|
1769
|
+
const header = parts[0];
|
|
1770
|
+
if (header.indexOf("/TS") === -1) {
|
|
1771
|
+
return header;
|
|
1772
|
+
}
|
|
1773
|
+
return parts[0] + "," + parts[1];
|
|
1774
|
+
}
|
|
1775
|
+
|
|
1776
|
+
// lib/plugins/Label_H1_WRN.ts
|
|
1777
|
+
var Label_H1_WRN = class extends DecoderPlugin {
|
|
1778
|
+
name = "label-h1-wrn";
|
|
1779
|
+
qualifiers() {
|
|
1780
|
+
return {
|
|
1781
|
+
labels: ["H1"],
|
|
1782
|
+
preambles: ["WRN", "#CFBWRN"]
|
|
1783
|
+
};
|
|
1784
|
+
}
|
|
1785
|
+
decode(message, options = {}) {
|
|
1786
|
+
let decodeResult = this.defaultResult;
|
|
1787
|
+
decodeResult.decoder.name = this.name;
|
|
1788
|
+
decodeResult.formatted.description = "Warning Message";
|
|
1789
|
+
decodeResult.message = message;
|
|
1790
|
+
const parts = message.text.split("/WN");
|
|
1791
|
+
if (parts.length > 1) {
|
|
1792
|
+
decodeResult.remaining.text = "";
|
|
1793
|
+
const fields = parts[0].split("/");
|
|
1794
|
+
for (let i = 1; i < fields.length; i++) {
|
|
1795
|
+
const field = fields[i];
|
|
1796
|
+
if (field.startsWith("PN")) {
|
|
1797
|
+
processUnknown2(decodeResult, "/" + field);
|
|
1798
|
+
} else {
|
|
1799
|
+
processUnknown2(decodeResult, "/" + field);
|
|
1800
|
+
}
|
|
1801
|
+
}
|
|
1802
|
+
const data = parts[1].substring(0, 20);
|
|
1803
|
+
const msg = parts[1].substring(20);
|
|
1804
|
+
const datetime = data.substring(0, 12);
|
|
1805
|
+
const date = datetime.substring(4, 6) + datetime.substring(2, 4) + datetime.substring(0, 2);
|
|
1806
|
+
processUnknown2(decodeResult, data.substring(12));
|
|
1807
|
+
decodeResult.raw.message_timestamp = DateTimeUtils.convertDateTimeToEpoch(datetime.substring(6), date);
|
|
1808
|
+
decodeResult.raw.warning_message = msg;
|
|
1809
|
+
decodeResult.formatted.items.push({
|
|
1810
|
+
type: "warning",
|
|
1811
|
+
code: "WRN",
|
|
1812
|
+
label: "Warning Message",
|
|
1813
|
+
value: decodeResult.raw.warning_message
|
|
1814
|
+
});
|
|
1815
|
+
decodeResult.decoded = true;
|
|
1816
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
1817
|
+
} else {
|
|
1818
|
+
if (options.debug) {
|
|
1819
|
+
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
1820
|
+
}
|
|
1821
|
+
decodeResult.remaining.text = message.text;
|
|
1822
|
+
decodeResult.decoded = false;
|
|
1823
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1824
|
+
}
|
|
1825
|
+
return decodeResult;
|
|
1826
|
+
}
|
|
1827
|
+
};
|
|
1828
|
+
function processUnknown2(decodeResult, value) {
|
|
1829
|
+
decodeResult.remaining.text += value;
|
|
1830
|
+
}
|
|
1643
1831
|
|
|
1644
1832
|
// lib/plugins/Label_SQ.ts
|
|
1645
1833
|
var Label_SQ = class extends DecoderPlugin {
|
|
@@ -1922,7 +2110,7 @@ var Label_QQ = class extends DecoderPlugin {
|
|
|
1922
2110
|
|
|
1923
2111
|
// lib/utils/miam.ts
|
|
1924
2112
|
import * as Base85 from "base85";
|
|
1925
|
-
import * as
|
|
2113
|
+
import * as zlib from "minizlib";
|
|
1926
2114
|
var MIAMCoreV1CRCLength = 4;
|
|
1927
2115
|
var MIAMCoreV2CRCLength = 2;
|
|
1928
2116
|
var MIAMCoreUtils = class {
|
|
@@ -2632,7 +2820,10 @@ var MIAMCoreUtils = class {
|
|
|
2632
2820
|
if (body !== void 0 && body.length > 0) {
|
|
2633
2821
|
if ([1 /* Deflate */, 1 /* Deflate */].indexOf(pduCompression) >= 0) {
|
|
2634
2822
|
try {
|
|
2635
|
-
|
|
2823
|
+
const decompress = new zlib.InflateRaw({ windowBits: 15 });
|
|
2824
|
+
decompress.write(body);
|
|
2825
|
+
decompress.flush(zlib.constants.Z_SYNC_FLUSH);
|
|
2826
|
+
pduData = decompress.read();
|
|
2636
2827
|
} catch (e) {
|
|
2637
2828
|
pduErrors.push("Inflation failed for body: " + e);
|
|
2638
2829
|
}
|
|
@@ -2744,6 +2935,7 @@ var MessageDecoder = class {
|
|
|
2744
2935
|
this.registerPlugin(new Label_B6_Forwardslash(this));
|
|
2745
2936
|
this.registerPlugin(new Label_H1_FPN(this));
|
|
2746
2937
|
this.registerPlugin(new Label_H1_POS(this));
|
|
2938
|
+
this.registerPlugin(new Label_H1_WRN(this));
|
|
2747
2939
|
this.registerPlugin(new Label_80(this));
|
|
2748
2940
|
this.registerPlugin(new Label_8E(this));
|
|
2749
2941
|
this.registerPlugin(new Label_1M_Slash(this));
|