@airframes/acars-decoder 1.6.1 → 1.6.3

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.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.latitude_direction = results.groups.lat;
192
- decodeResult.raw.latitude = Number(results.groups.lat_coord);
193
- decodeResult.raw.longitude_direction = results.groups.long;
194
- decodeResult.raw.longitude = Number(results.groups.long_coord);
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: `${results.groups.lat_coord} ${decodeResult.raw.latitude_direction}, ${results.groups.long_coord} ${decodeResult.raw.longitude_direction}`
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.latitude_direction = results.groups.lat;
362
- decodeResult.raw.latitude = Number(results.groups.lat_coord);
363
- decodeResult.raw.longitude_direction = results.groups.long;
364
- decodeResult.raw.longitude = Number(results.groups.long_coord);
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: `${decodeResult.raw.latitude} ${decodeResult.raw.latitude_direction}, ${decodeResult.raw.longitude} ${decodeResult.raw.longitude_direction}`
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.latitude_direction = results.groups.lat;
387
- decodeResult.raw.latitude = Number(results.groups.lat_coord);
388
- decodeResult.raw.longitude_direction = results.groups.long;
389
- decodeResult.raw.longitude = Number(results.groups.long_coord);
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: `${results.groups.lat_coord} ${decodeResult.raw.latitude_direction}, ${results.groups.long_coord} ${decodeResult.raw.longitude_direction}`
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
- const timestamp = `20${date.substring(4, 6)}-${date.substring(0, 2)}-${date.substring(2, 4)}T${time.substring(0, 2)}:${time.substring(2, 4)}:${time.substring(4, 6)}.000Z`;
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.formatted.items.push({
546
- type: "position",
547
- label: "Position",
548
- value: CoordinateUtils.coordinateString(decodeResult.raw.position)
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.aircraft_position = {
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: `${Math.abs(latitude).toPrecision(5)} ${posResult.groups.latd}, ${Math.abs(longitude).toPrecision(5)} ${posResult.groups.lngd}`
1061
+ value: CoordinateUtils.coordinateString(decodeResult.raw.position)
1064
1062
  });
1065
1063
  break;
1066
1064
  }
@@ -1203,7 +1201,7 @@ 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.latLonToCoordinateString(waypoint.latitude, waypoint.longitude)})`;
1204
+ s += `(${CoordinateUtils.coordinateString({ latitude: waypoint.latitude, longitude: waypoint.longitude })})`;
1207
1205
  }
1208
1206
  if (waypoint.time && waypoint.timeFormat) {
1209
1207
  s += `@${_RouteUtils.timestampToString(waypoint.time, waypoint.timeFormat)}`;
@@ -1214,11 +1212,15 @@ var RouteUtils = class _RouteUtils {
1214
1212
  const waypoint = leg.split(",");
1215
1213
  if (waypoint.length == 2) {
1216
1214
  const position = CoordinateUtils.decodeStringCoordinates(waypoint[1]);
1217
- return { name: waypoint[0], latitude: position.latitude, longitude: position.longitude };
1215
+ if (position) {
1216
+ return { name: waypoint[0], latitude: position.latitude, longitude: position.longitude };
1217
+ }
1218
1218
  }
1219
1219
  if (leg.length == 14) {
1220
1220
  const position = CoordinateUtils.decodeStringCoordinates(leg);
1221
- return { name: waypoint[0], latitude: position.latitude, longitude: position.longitude };
1221
+ if (position) {
1222
+ return { name: waypoint[0], latitude: position.latitude, longitude: position.longitude };
1223
+ }
1222
1224
  }
1223
1225
  return { name: leg };
1224
1226
  }
@@ -1471,7 +1473,6 @@ var Label_H1_POS = class extends DecoderPlugin {
1471
1473
  decodeResult.message = message;
1472
1474
  const checksum = message.text.slice(-4);
1473
1475
  const parts = message.text.replace("#M1B", "").replace("POS", "").slice(0, -4).split(",");
1474
- console.log(parts);
1475
1476
  if (parts.length == 1 && parts[0].startsWith("/RF")) {
1476
1477
  decodeResult.raw.route_status == "RF";
1477
1478
  decodeResult.formatted.items.push({
@@ -1527,6 +1528,40 @@ var Label_H1_POS = class extends DecoderPlugin {
1527
1528
  processChecksum(decodeResult, checksum);
1528
1529
  decodeResult.decoded = true;
1529
1530
  decodeResult.decoder.decodeLevel = "partial";
1531
+ } else if (parts.length === 15) {
1532
+ decodeResult.remaining.text = "";
1533
+ processUnknown(decodeResult, parts[0]);
1534
+ processUnknown(decodeResult, parts[1]);
1535
+ let date = void 0;
1536
+ if (parts[2].startsWith("/DC")) {
1537
+ date = parts[2].substring(3);
1538
+ } else {
1539
+ processUnknown(decodeResult, parts[2]);
1540
+ }
1541
+ processUnknown(decodeResult, parts[3]);
1542
+ const fields = parts[4].split("/");
1543
+ for (let i = 0; i < fields.length; ++i) {
1544
+ const field = fields[i];
1545
+ if (field.startsWith("PS")) {
1546
+ processPosition(decodeResult, field.substring(2));
1547
+ } else {
1548
+ if (i === 0) {
1549
+ processUnknown(decodeResult, field);
1550
+ } else {
1551
+ processUnknown(decodeResult, "/" + field);
1552
+ }
1553
+ }
1554
+ }
1555
+ processRoute(decodeResult, parts[7], parts[5], parts[9], parts[8], void 0, date);
1556
+ processAlt(decodeResult, parts[6]);
1557
+ processTemp(decodeResult, parts[10]);
1558
+ processUnknown(decodeResult, parts[11]);
1559
+ processUnknown(decodeResult, parts[12]);
1560
+ processUnknown(decodeResult, parts[13]);
1561
+ processUnknown(decodeResult, parts[14]);
1562
+ processChecksum(decodeResult, checksum);
1563
+ decodeResult.decoded = true;
1564
+ decodeResult.decoder.decodeLevel = "partial";
1530
1565
  } else if (parts.length === 32) {
1531
1566
  decodeResult.remaining.text = "";
1532
1567
  processPosition(decodeResult, parts[0]);
@@ -1547,7 +1582,7 @@ var Label_H1_POS = class extends DecoderPlugin {
1547
1582
  processAlt(decodeResult, parts[22]);
1548
1583
  processUnknown(decodeResult, parts.slice(23, 31).join(","));
1549
1584
  const allProcessed = FlightPlanUtils.processFlightPlan(decodeResult, (parts[31] + checksum).split(":"));
1550
- processRoute(decodeResult, past, time, next, eta, "?");
1585
+ processRoute(decodeResult, past, time, next, eta);
1551
1586
  decodeResult.decoded = true;
1552
1587
  decodeResult.decoder.decodeLevel = "partial";
1553
1588
  } else {
@@ -1566,16 +1601,15 @@ function processUnknown(decodeResult, value) {
1566
1601
  }
1567
1602
  function processPosition(decodeResult, value) {
1568
1603
  const position = CoordinateUtils.decodeStringCoordinates(value);
1569
- decodeResult.raw.latitude_direction = position.latitudeDirection;
1570
- decodeResult.raw.latitude = Math.abs(position.latitude);
1571
- decodeResult.raw.longitude_direction = position.longitudeDirection;
1572
- decodeResult.raw.longitude = Math.abs(position.longitude);
1573
- decodeResult.formatted.items.push({
1574
- type: "aircraft_position",
1575
- code: "POS",
1576
- label: "Aircraft Position",
1577
- value: CoordinateUtils.coordinateString(position)
1578
- });
1604
+ if (position) {
1605
+ decodeResult.raw.position = position;
1606
+ decodeResult.formatted.items.push({
1607
+ type: "aircraft_position",
1608
+ code: "POS",
1609
+ label: "Aircraft Position",
1610
+ value: CoordinateUtils.coordinateString(position)
1611
+ });
1612
+ }
1579
1613
  }
1580
1614
  function processAlt(decodeResult, value) {
1581
1615
  decodeResult.raw.altitude = Number(value) * 100;
@@ -1613,16 +1647,14 @@ function processGndspd(decodeResult, value) {
1613
1647
  });
1614
1648
  }
1615
1649
  function processRoute(decodeResult, last, time, next, eta, then, date) {
1616
- let waypoints;
1617
- waypoints = date === void 0 ? [
1618
- { name: last || "?,", time: DateTimeUtils.convertHHMMSSToTod(time), timeFormat: "tod" },
1619
- { name: next || "?", time: DateTimeUtils.convertHHMMSSToTod(eta), timeFormat: "tod" },
1620
- { name: then || "?" }
1621
- ] : [
1622
- { name: last || "?,", time: DateTimeUtils.convertDateTimeToEpoch(time, date), timeFormat: "epoch" },
1623
- { name: next || "?", time: DateTimeUtils.convertDateTimeToEpoch(eta, date), timeFormat: "epoch" },
1624
- { name: then || "?" }
1625
- ];
1650
+ const lastCoords = CoordinateUtils.decodeStringCoordinates(last);
1651
+ const nextCoords = CoordinateUtils.decodeStringCoordinates(next);
1652
+ const lastTime = date ? DateTimeUtils.convertDateTimeToEpoch(time, date) : DateTimeUtils.convertHHMMSSToTod(time);
1653
+ const nextTime = date ? DateTimeUtils.convertDateTimeToEpoch(eta, date) : DateTimeUtils.convertHHMMSSToTod(eta);
1654
+ const timeFormat = date ? "epoch" : "tod";
1655
+ const lastWaypoint = lastCoords ? { name: "", latitude: lastCoords.latitude, longitude: lastCoords.longitude, time: lastTime, timeFormat } : { name: last, time: lastTime, timeFormat };
1656
+ const nextWaypoint = nextCoords ? { name: "", latitude: nextCoords.latitude, longitude: nextCoords.longitude, time: nextTime, timeFormat } : { name: next, time: nextTime, timeFormat };
1657
+ const waypoints = [lastWaypoint, nextWaypoint, { name: then || "?" }];
1626
1658
  decodeResult.raw.route = { waypoints };
1627
1659
  decodeResult.formatted.items.push({
1628
1660
  type: "aircraft_route",
@@ -1641,6 +1673,62 @@ function processChecksum(decodeResult, value) {
1641
1673
  });
1642
1674
  }
1643
1675
 
1676
+ // lib/plugins/Label_H1_WRN.ts
1677
+ var Label_H1_WRN = class extends DecoderPlugin {
1678
+ name = "label-h1-wrn";
1679
+ qualifiers() {
1680
+ return {
1681
+ labels: ["H1"],
1682
+ preambles: ["WRN", "#CFBWRN"]
1683
+ };
1684
+ }
1685
+ decode(message, options = {}) {
1686
+ let decodeResult = this.defaultResult;
1687
+ decodeResult.decoder.name = this.name;
1688
+ decodeResult.formatted.description = "Warning Message";
1689
+ decodeResult.message = message;
1690
+ const parts = message.text.split("/WN");
1691
+ if (parts.length > 1) {
1692
+ decodeResult.remaining.text = "";
1693
+ const fields = parts[0].split("/");
1694
+ for (let i = 1; i < fields.length; i++) {
1695
+ const field = fields[i];
1696
+ if (field.startsWith("PN")) {
1697
+ processUnknown2(decodeResult, "/" + field);
1698
+ } else {
1699
+ processUnknown2(decodeResult, "/" + field);
1700
+ }
1701
+ }
1702
+ const data = parts[1].substring(0, 20);
1703
+ const msg = parts[1].substring(20);
1704
+ const datetime = data.substring(0, 12);
1705
+ const date = datetime.substring(4, 6) + datetime.substring(2, 4) + datetime.substring(0, 2);
1706
+ processUnknown2(decodeResult, data.substring(12));
1707
+ decodeResult.raw.message_timestamp = DateTimeUtils.convertDateTimeToEpoch(datetime.substring(6), date);
1708
+ decodeResult.raw.warning_message = msg;
1709
+ decodeResult.formatted.items.push({
1710
+ type: "warning",
1711
+ code: "WRN",
1712
+ label: "Warning Message",
1713
+ value: decodeResult.raw.warning_message
1714
+ });
1715
+ decodeResult.decoded = true;
1716
+ decodeResult.decoder.decodeLevel = "partial";
1717
+ } else {
1718
+ if (options.debug) {
1719
+ console.log(`Decoder: Unknown H1 message: ${message.text}`);
1720
+ }
1721
+ decodeResult.remaining.text = message.text;
1722
+ decodeResult.decoded = false;
1723
+ decodeResult.decoder.decodeLevel = "none";
1724
+ }
1725
+ return decodeResult;
1726
+ }
1727
+ };
1728
+ function processUnknown2(decodeResult, value) {
1729
+ decodeResult.remaining.text += value;
1730
+ }
1731
+
1644
1732
  // lib/plugins/Label_SQ.ts
1645
1733
  var Label_SQ = class extends DecoderPlugin {
1646
1734
  name = "label-sq";
@@ -2744,6 +2832,7 @@ var MessageDecoder = class {
2744
2832
  this.registerPlugin(new Label_B6_Forwardslash(this));
2745
2833
  this.registerPlugin(new Label_H1_FPN(this));
2746
2834
  this.registerPlugin(new Label_H1_POS(this));
2835
+ this.registerPlugin(new Label_H1_WRN(this));
2747
2836
  this.registerPlugin(new Label_80(this));
2748
2837
  this.registerPlugin(new Label_8E(this));
2749
2838
  this.registerPlugin(new Label_1M_Slash(this));