@airframes/acars-decoder 1.6.8 → 1.6.10
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 +769 -411
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +769 -411
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -97,6 +97,192 @@ var DecoderPlugin = class {
|
|
|
97
97
|
}
|
|
98
98
|
};
|
|
99
99
|
|
|
100
|
+
// lib/utils/coordinate_utils.ts
|
|
101
|
+
var CoordinateUtils = class {
|
|
102
|
+
/**
|
|
103
|
+
* Decode a string of coordinates into an object with latitude and longitude in millidegrees
|
|
104
|
+
* @param stringCoords - The string of coordinates to decode
|
|
105
|
+
*
|
|
106
|
+
* @returns An object with latitude and longitude properties
|
|
107
|
+
*/
|
|
108
|
+
static decodeStringCoordinates(stringCoords) {
|
|
109
|
+
var results = {};
|
|
110
|
+
const firstChar = stringCoords.substring(0, 1);
|
|
111
|
+
let middleChar = stringCoords.substring(6, 7);
|
|
112
|
+
let longitudeChars = stringCoords.substring(7, 13);
|
|
113
|
+
if (middleChar == " ") {
|
|
114
|
+
middleChar = stringCoords.substring(7, 8);
|
|
115
|
+
longitudeChars = stringCoords.substring(8, 14);
|
|
116
|
+
}
|
|
117
|
+
if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
|
|
118
|
+
results.latitude = Number(stringCoords.substring(1, 6)) / 1e3 * (firstChar === "S" ? -1 : 1);
|
|
119
|
+
results.longitude = Number(longitudeChars) / 1e3 * (middleChar === "W" ? -1 : 1);
|
|
120
|
+
} else {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
return results;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Decode a string of coordinates into an object with latitude and longitude in degrees and decimal minutes
|
|
127
|
+
* @param stringCoords - The string of coordinates to decode
|
|
128
|
+
*
|
|
129
|
+
* @returns An object with latitude and longitude properties
|
|
130
|
+
*/
|
|
131
|
+
static decodeStringCoordinatesDecimalMinutes(stringCoords) {
|
|
132
|
+
var results = {};
|
|
133
|
+
const firstChar = stringCoords.substring(0, 1);
|
|
134
|
+
let middleChar = stringCoords.substring(6, 7);
|
|
135
|
+
let longitudeChars = stringCoords.substring(7, 13);
|
|
136
|
+
if (middleChar == " ") {
|
|
137
|
+
middleChar = stringCoords.substring(7, 8);
|
|
138
|
+
longitudeChars = stringCoords.substring(8, 14);
|
|
139
|
+
}
|
|
140
|
+
const latDeg = Math.trunc(Number(stringCoords.substring(1, 6)) / 1e3);
|
|
141
|
+
const latMin = Number(stringCoords.substring(1, 6)) % 1e3 / 10;
|
|
142
|
+
const lonDeg = Math.trunc(Number(longitudeChars) / 1e3);
|
|
143
|
+
const lonMin = Number(longitudeChars) % 1e3 / 10;
|
|
144
|
+
if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
|
|
145
|
+
results.latitude = (latDeg + latMin / 60) * (firstChar === "S" ? -1 : 1);
|
|
146
|
+
results.longitude = (lonDeg + lonMin / 60) * (middleChar === "W" ? -1 : 1);
|
|
147
|
+
} else {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
return results;
|
|
151
|
+
}
|
|
152
|
+
static coordinateString(coords) {
|
|
153
|
+
const latDir = coords.latitude > 0 ? "N" : "S";
|
|
154
|
+
const lonDir = coords.longitude > 0 ? "E" : "W";
|
|
155
|
+
return `${Math.abs(coords.latitude).toFixed(3)} ${latDir}, ${Math.abs(coords.longitude).toFixed(3)} ${lonDir}`;
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
// lib/utils/result_formatter.ts
|
|
160
|
+
var ResultFormatter = class {
|
|
161
|
+
static position(decodeResult, value) {
|
|
162
|
+
decodeResult.raw.position = value;
|
|
163
|
+
decodeResult.formatted.items.push({
|
|
164
|
+
type: "aircraft_position",
|
|
165
|
+
code: "POS",
|
|
166
|
+
label: "Aircraft Position",
|
|
167
|
+
value: CoordinateUtils.coordinateString(value)
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
static altitude(decodeResult, value) {
|
|
171
|
+
decodeResult.raw.altitude = value;
|
|
172
|
+
decodeResult.formatted.items.push({
|
|
173
|
+
type: "altitude",
|
|
174
|
+
code: "ALT",
|
|
175
|
+
label: "Altitude",
|
|
176
|
+
value: `${decodeResult.raw.altitude} feet`
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
static flightNumber(decodeResult, value) {
|
|
180
|
+
decodeResult.raw.flight_number = value;
|
|
181
|
+
}
|
|
182
|
+
static departureAirport(decodeResult, value) {
|
|
183
|
+
decodeResult.raw.departure_icao = value;
|
|
184
|
+
decodeResult.formatted.items.push({
|
|
185
|
+
type: "origin",
|
|
186
|
+
code: "ORG",
|
|
187
|
+
label: "Origin",
|
|
188
|
+
value: decodeResult.raw.departure_icao
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
static departureRunway(decodeResult, value) {
|
|
192
|
+
decodeResult.raw.departure_runway = value;
|
|
193
|
+
decodeResult.formatted.items.push({
|
|
194
|
+
type: "runway",
|
|
195
|
+
code: "DEPRWY",
|
|
196
|
+
label: "Departure Runway",
|
|
197
|
+
value: decodeResult.raw.departure_runway
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
static arrivalAirport(decodeResult, value) {
|
|
201
|
+
decodeResult.raw.arrival_icao = value;
|
|
202
|
+
decodeResult.formatted.items.push({
|
|
203
|
+
type: "destination",
|
|
204
|
+
code: "DST",
|
|
205
|
+
label: "Destination",
|
|
206
|
+
value: decodeResult.raw.arrival_icao
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
static eta(decodeResult, value) {
|
|
210
|
+
decodeResult.raw.eta_time = value;
|
|
211
|
+
decodeResult.formatted.items.push({
|
|
212
|
+
type: "eta",
|
|
213
|
+
code: "ETA",
|
|
214
|
+
label: "Estimated Time of Arrival",
|
|
215
|
+
value: value.substring(0, 2) + ":" + value.substring(2, 4) + ":" + value.substring(4, 6)
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
static arrivalRunway(decodeResult, value) {
|
|
219
|
+
decodeResult.raw.arrival_runway = value;
|
|
220
|
+
decodeResult.formatted.items.push({
|
|
221
|
+
type: "runway",
|
|
222
|
+
code: "ARWY",
|
|
223
|
+
label: "Arrival Runway",
|
|
224
|
+
value: decodeResult.raw.arrival_runway
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
static currentFuel(decodeResult, value) {
|
|
228
|
+
decodeResult.raw.fuel_on_board = value;
|
|
229
|
+
decodeResult.formatted.items.push({
|
|
230
|
+
type: "fuel_on_board",
|
|
231
|
+
code: "FOB",
|
|
232
|
+
label: "Fuel On Board",
|
|
233
|
+
value: decodeResult.raw.fuel_on_board.toString()
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
static remainingFuel(decodeResult, value) {
|
|
237
|
+
decodeResult.raw.fuel_remaining = value;
|
|
238
|
+
decodeResult.formatted.items.push({
|
|
239
|
+
type: "fuel_remaining",
|
|
240
|
+
code: "FUEL",
|
|
241
|
+
label: "Fuel Remaining",
|
|
242
|
+
value: decodeResult.raw.fuel_remaining.toString()
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
static checksum(decodeResult, value) {
|
|
246
|
+
decodeResult.raw.checksum = Number("0x" + value);
|
|
247
|
+
decodeResult.formatted.items.push({
|
|
248
|
+
type: "message_checksum",
|
|
249
|
+
code: "CHECKSUM",
|
|
250
|
+
label: "Message Checksum",
|
|
251
|
+
value: "0x" + ("0000" + decodeResult.raw.checksum.toString(16)).slice(-4)
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
static groundspeed(decodeResult, value) {
|
|
255
|
+
decodeResult.raw.groundspeed = value;
|
|
256
|
+
decodeResult.formatted.items.push({
|
|
257
|
+
type: "aircraft_groundspeed",
|
|
258
|
+
code: "GSPD",
|
|
259
|
+
label: "Aircraft Groundspeed",
|
|
260
|
+
value: `${decodeResult.raw.groundspeed}`
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
static temperature(decodeResult, value) {
|
|
264
|
+
decodeResult.raw.outside_air_temperature = Number(value.substring(1)) * (value.charAt(0) === "M" ? -1 : 1);
|
|
265
|
+
decodeResult.formatted.items.push({
|
|
266
|
+
type: "outside_air_temperature",
|
|
267
|
+
code: "OATEMP",
|
|
268
|
+
label: "Outside Air Temperature (C)",
|
|
269
|
+
value: `${decodeResult.raw.outside_air_temperature}`
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
static heading(decodeResult, value) {
|
|
273
|
+
decodeResult.raw.heading = value;
|
|
274
|
+
decodeResult.formatted.items.push({
|
|
275
|
+
type: "heading",
|
|
276
|
+
code: "HDG",
|
|
277
|
+
label: "Heading",
|
|
278
|
+
value: `${decodeResult.raw.heading}`
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
static unknown(decodeResult, value) {
|
|
282
|
+
decodeResult.remaining.text += "," + value;
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
|
|
100
286
|
// lib/plugins/Label_5Z.ts
|
|
101
287
|
var Label_5Z = class extends DecoderPlugin {
|
|
102
288
|
name = "label-5z";
|
|
@@ -156,34 +342,9 @@ var Label_5Z = class extends DecoderPlugin {
|
|
|
156
342
|
const rdcRegex = /^(?<from>\w\w\w)(?<to>\w\w\w) (?<unknown1>\d\d) R(?<runway>.+) G(?<unknown2>.+)$/;
|
|
157
343
|
results = remainder.match(rdcRegex);
|
|
158
344
|
if (results) {
|
|
159
|
-
decodeResult
|
|
160
|
-
decodeResult.
|
|
161
|
-
|
|
162
|
-
label: "Origin",
|
|
163
|
-
value: `${results.groups.from}`
|
|
164
|
-
});
|
|
165
|
-
decodeResult.raw.destination = results.groups.to;
|
|
166
|
-
decodeResult.formatted.items.push({
|
|
167
|
-
type: "destination",
|
|
168
|
-
label: "Destination",
|
|
169
|
-
value: `${results.groups.to}`
|
|
170
|
-
});
|
|
171
|
-
decodeResult.formatted.items.push({
|
|
172
|
-
type: "unknown1",
|
|
173
|
-
label: "Unknown Field 1",
|
|
174
|
-
value: `${results.groups.unknown1}`
|
|
175
|
-
});
|
|
176
|
-
decodeResult.raw.runway = results.groups.runway;
|
|
177
|
-
decodeResult.formatted.items.push({
|
|
178
|
-
type: "runway",
|
|
179
|
-
label: "Runway",
|
|
180
|
-
value: `${results.groups.runway}`
|
|
181
|
-
});
|
|
182
|
-
decodeResult.formatted.items.push({
|
|
183
|
-
type: "unknown2",
|
|
184
|
-
label: "Unknown Field 2",
|
|
185
|
-
value: `${results.groups.unknown2}`
|
|
186
|
-
});
|
|
345
|
+
ResultFormatter.departureAirport(decodeResult, results.groups.from);
|
|
346
|
+
ResultFormatter.arrivalAirport(decodeResult, results.groups.to);
|
|
347
|
+
ResultFormatter.arrivalRunway(decodeResult, results.groups.runway);
|
|
187
348
|
} else {
|
|
188
349
|
if (options.debug) {
|
|
189
350
|
console.log(`Decoder: Unkown 5Z RDC format: ${remainder}`);
|
|
@@ -206,62 +367,273 @@ var Label_5Z = class extends DecoderPlugin {
|
|
|
206
367
|
}
|
|
207
368
|
};
|
|
208
369
|
|
|
209
|
-
// lib/
|
|
210
|
-
var
|
|
370
|
+
// lib/plugins/Label_10_LDR.ts
|
|
371
|
+
var Label_10_LDR = class extends DecoderPlugin {
|
|
372
|
+
// eslint-disable-line camelcase
|
|
373
|
+
name = "label-10-ldr";
|
|
374
|
+
qualifiers() {
|
|
375
|
+
return {
|
|
376
|
+
labels: ["10"],
|
|
377
|
+
preambles: ["LDR"]
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
decode(message, options = {}) {
|
|
381
|
+
const decodeResult = this.defaultResult();
|
|
382
|
+
decodeResult.decoder.name = this.name;
|
|
383
|
+
decodeResult.formatted.description = "Position Report";
|
|
384
|
+
decodeResult.message = message;
|
|
385
|
+
const parts = message.text.split(",");
|
|
386
|
+
if (parts.length < 17) {
|
|
387
|
+
if (options?.debug) {
|
|
388
|
+
console.log(`Decoder: Unknown 10 message: ${message.text}`);
|
|
389
|
+
}
|
|
390
|
+
decodeResult.remaining.text = message.text;
|
|
391
|
+
decodeResult.decoded = false;
|
|
392
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
393
|
+
return decodeResult;
|
|
394
|
+
}
|
|
395
|
+
const lat = parts[5];
|
|
396
|
+
const lon = parts[6];
|
|
397
|
+
const position = {
|
|
398
|
+
latitude: (lat[0] === "N" ? 1 : -1) * Number(lat.substring(1).trim()),
|
|
399
|
+
longitude: (lon[0] === "E" ? 1 : -1) * Number(lon.substring(1).trim())
|
|
400
|
+
};
|
|
401
|
+
ResultFormatter.position(decodeResult, position);
|
|
402
|
+
ResultFormatter.altitude(decodeResult, Number(parts[7]));
|
|
403
|
+
ResultFormatter.departureAirport(decodeResult, parts[9]);
|
|
404
|
+
ResultFormatter.arrivalAirport(decodeResult, parts[10]);
|
|
405
|
+
ResultFormatter.arrivalRunway(decodeResult, parts[12].split("/")[0]);
|
|
406
|
+
decodeResult.remaining.text = [...parts.slice(0, 5), parts[11], ...parts.slice(13)].join(",");
|
|
407
|
+
decodeResult.decoded = true;
|
|
408
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
409
|
+
return decodeResult;
|
|
410
|
+
}
|
|
411
|
+
};
|
|
412
|
+
|
|
413
|
+
// lib/plugins/Label_10_POS.ts
|
|
414
|
+
var Label_10_POS = class extends DecoderPlugin {
|
|
415
|
+
// eslint-disable-line camelcase
|
|
416
|
+
name = "label-10-pos";
|
|
417
|
+
qualifiers() {
|
|
418
|
+
return {
|
|
419
|
+
labels: ["10"],
|
|
420
|
+
preambles: ["POS"]
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
decode(message, options = {}) {
|
|
424
|
+
const decodeResult = this.defaultResult();
|
|
425
|
+
decodeResult.decoder.name = this.name;
|
|
426
|
+
decodeResult.formatted.description = "Position Report";
|
|
427
|
+
decodeResult.message = message;
|
|
428
|
+
const parts = message.text.split(",");
|
|
429
|
+
if (parts.length !== 12) {
|
|
430
|
+
if (options?.debug) {
|
|
431
|
+
console.log(`Decoder: Unknown 10 message: ${message.text}`);
|
|
432
|
+
}
|
|
433
|
+
decodeResult.remaining.text = message.text;
|
|
434
|
+
decodeResult.decoded = false;
|
|
435
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
436
|
+
return decodeResult;
|
|
437
|
+
}
|
|
438
|
+
const lat = parts[1].trim();
|
|
439
|
+
const lon = parts[2].trim();
|
|
440
|
+
const position = {
|
|
441
|
+
latitude: (lat[0] === "N" ? 1 : -1) * Number(lat.substring(1).trim()) / 100,
|
|
442
|
+
longitude: (lon[0] === "E" ? 1 : -1) * Number(lon.substring(1).trim()) / 100
|
|
443
|
+
};
|
|
444
|
+
ResultFormatter.position(decodeResult, position);
|
|
445
|
+
ResultFormatter.altitude(decodeResult, Number(parts[7]));
|
|
446
|
+
decodeResult.remaining.text = [parts[0], ...parts.slice(3, 7), ...parts.slice(8)].join(",");
|
|
447
|
+
decodeResult.decoded = true;
|
|
448
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
449
|
+
return decodeResult;
|
|
450
|
+
}
|
|
451
|
+
};
|
|
452
|
+
|
|
453
|
+
// lib/DateTimeUtils.ts
|
|
454
|
+
var DateTimeUtils = class {
|
|
455
|
+
// Expects a four digit UTC time string (HHMM)
|
|
456
|
+
static UTCToString(UTCString) {
|
|
457
|
+
let utcDate = /* @__PURE__ */ new Date();
|
|
458
|
+
utcDate.setUTCHours(+UTCString.substr(0, 2), +UTCString.substr(2, 2), 0);
|
|
459
|
+
return utcDate.toTimeString();
|
|
460
|
+
}
|
|
461
|
+
// Expects a six digit date string and a four digit UTC time string
|
|
462
|
+
// (DDMMYY) (HHMM)
|
|
463
|
+
static UTCDateTimeToString(dateString, timeString) {
|
|
464
|
+
let utcDate = /* @__PURE__ */ new Date();
|
|
465
|
+
utcDate.setUTCDate(+dateString.substr(0, 2));
|
|
466
|
+
utcDate.setUTCMonth(+dateString.substr(2, 2));
|
|
467
|
+
if (dateString.length === 6) {
|
|
468
|
+
utcDate.setUTCFullYear(2e3 + +dateString.substr(4, 2));
|
|
469
|
+
}
|
|
470
|
+
if (timeString.length === 6) {
|
|
471
|
+
utcDate.setUTCHours(+timeString.substr(0, 2), +timeString.substr(2, 2), +timeString.substr(4, 2));
|
|
472
|
+
} else {
|
|
473
|
+
utcDate.setUTCHours(+timeString.substr(0, 2), +timeString.substr(2, 2), 0);
|
|
474
|
+
}
|
|
475
|
+
return utcDate.toUTCString();
|
|
476
|
+
}
|
|
211
477
|
/**
|
|
212
|
-
* Decode a string of coordinates into an object with latitude and longitude in millidegrees
|
|
213
|
-
* @param stringCoords - The string of coordinates to decode
|
|
214
478
|
*
|
|
215
|
-
* @
|
|
479
|
+
* @param time HHMMSS
|
|
480
|
+
* @returns seconds since midnight
|
|
216
481
|
*/
|
|
217
|
-
static
|
|
218
|
-
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
482
|
+
static convertHHMMSSToTod(time) {
|
|
483
|
+
const h = Number(time.substring(0, 2));
|
|
484
|
+
const m = Number(time.substring(2, 4));
|
|
485
|
+
const s = Number(time.substring(4, 6));
|
|
486
|
+
const tod = h * 3600 + m * 60 + s;
|
|
487
|
+
return tod;
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
*
|
|
491
|
+
* @param time HHMMSS
|
|
492
|
+
* @param date MMDDYY or MMDDYYYY
|
|
493
|
+
* @returns seconds since epoch
|
|
494
|
+
*/
|
|
495
|
+
static convertDateTimeToEpoch(time, date) {
|
|
496
|
+
if (date.length === 6) {
|
|
497
|
+
date = date.substring(0, 4) + `20${date.substring(4, 6)}`;
|
|
225
498
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
499
|
+
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`;
|
|
500
|
+
const millis = Date.parse(timestamp);
|
|
501
|
+
return millis / 1e3;
|
|
502
|
+
}
|
|
503
|
+
};
|
|
504
|
+
|
|
505
|
+
// lib/utils/route_utils.ts
|
|
506
|
+
var RouteUtils = class _RouteUtils {
|
|
507
|
+
static routeToString(route) {
|
|
508
|
+
let str = "";
|
|
509
|
+
if (route.name) {
|
|
510
|
+
str += route.name;
|
|
231
511
|
}
|
|
232
|
-
|
|
512
|
+
if (route.runway) {
|
|
513
|
+
str += `(${route.runway})`;
|
|
514
|
+
}
|
|
515
|
+
if (str.length !== 0 && route.waypoints && route.waypoints.length === 1) {
|
|
516
|
+
str += " starting at ";
|
|
517
|
+
} else if (str.length !== 0 && route.waypoints) {
|
|
518
|
+
str += ": ";
|
|
519
|
+
}
|
|
520
|
+
if (route.waypoints) {
|
|
521
|
+
str += _RouteUtils.waypointsToString(route.waypoints);
|
|
522
|
+
}
|
|
523
|
+
return str;
|
|
233
524
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
525
|
+
static waypointToString(waypoint) {
|
|
526
|
+
let s = waypoint.name;
|
|
527
|
+
if (waypoint.latitude && waypoint.longitude) {
|
|
528
|
+
s += `(${CoordinateUtils.coordinateString({ latitude: waypoint.latitude, longitude: waypoint.longitude })})`;
|
|
529
|
+
}
|
|
530
|
+
if (waypoint.offset) {
|
|
531
|
+
s += `[${waypoint.offset.bearing}\xB0 ${waypoint.offset.distance}nm]`;
|
|
532
|
+
}
|
|
533
|
+
if (waypoint.time && waypoint.timeFormat) {
|
|
534
|
+
s += `@${_RouteUtils.timestampToString(waypoint.time, waypoint.timeFormat)}`;
|
|
535
|
+
}
|
|
536
|
+
return s;
|
|
537
|
+
}
|
|
538
|
+
static getWaypoint(leg) {
|
|
539
|
+
const regex = leg.match(/^([A-Z]+)(\d{3})-(\d{4})$/);
|
|
540
|
+
if (regex?.length == 4) {
|
|
541
|
+
return { name: regex[1], offset: { bearing: parseInt(regex[2]), distance: parseInt(regex[3]) / 10 } };
|
|
542
|
+
}
|
|
543
|
+
const waypoint = leg.split(",");
|
|
544
|
+
if (waypoint.length == 2) {
|
|
545
|
+
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(waypoint[1]);
|
|
546
|
+
if (position) {
|
|
547
|
+
return { name: waypoint[0], latitude: position.latitude, longitude: position.longitude };
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
if (leg.length == 13 || leg.length == 14) {
|
|
551
|
+
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(leg);
|
|
552
|
+
const name = waypoint.length == 2 ? waypoint[0] : "";
|
|
553
|
+
if (position) {
|
|
554
|
+
return { name, latitude: position.latitude, longitude: position.longitude };
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
return { name: leg };
|
|
558
|
+
}
|
|
559
|
+
// move out if we want public
|
|
560
|
+
static timestampToString(time, format) {
|
|
561
|
+
const date = new Date(time * 1e3);
|
|
562
|
+
if (format == "tod") {
|
|
563
|
+
return date.toISOString().slice(11, 19);
|
|
248
564
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
if ((
|
|
254
|
-
|
|
255
|
-
results.longitude = (lonDeg + lonMin / 60) * (middleChar === "W" ? -1 : 1);
|
|
256
|
-
} else {
|
|
257
|
-
return;
|
|
565
|
+
return date.toISOString().slice(0, -5) + "Z";
|
|
566
|
+
}
|
|
567
|
+
static waypointsToString(waypoints) {
|
|
568
|
+
let str = waypoints.map((x) => _RouteUtils.waypointToString(x)).join(" > ").replaceAll("> >", ">>");
|
|
569
|
+
if (str.startsWith(" > ")) {
|
|
570
|
+
str = ">>" + str.slice(2);
|
|
258
571
|
}
|
|
259
|
-
return
|
|
572
|
+
return str;
|
|
260
573
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
574
|
+
};
|
|
575
|
+
|
|
576
|
+
// lib/plugins/Label_10_Slash.ts
|
|
577
|
+
var Label_10_Slash = class extends DecoderPlugin {
|
|
578
|
+
// eslint-disable-line camelcase
|
|
579
|
+
name = "label-10-slash";
|
|
580
|
+
qualifiers() {
|
|
581
|
+
return {
|
|
582
|
+
labels: ["10"],
|
|
583
|
+
preambles: ["/"]
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
decode(message, options = {}) {
|
|
587
|
+
const decodeResult = this.defaultResult();
|
|
588
|
+
decodeResult.decoder.name = this.name;
|
|
589
|
+
decodeResult.formatted.description = "Position Report";
|
|
590
|
+
decodeResult.message = message;
|
|
591
|
+
const parts = message.text.split("/");
|
|
592
|
+
if (parts.length < 17) {
|
|
593
|
+
if (options?.debug) {
|
|
594
|
+
console.log(`Decoder: Unknown 10 message: ${message.text}`);
|
|
595
|
+
}
|
|
596
|
+
decodeResult.remaining.text = message.text;
|
|
597
|
+
decodeResult.decoded = false;
|
|
598
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
599
|
+
return decodeResult;
|
|
600
|
+
}
|
|
601
|
+
const lat = parts[1];
|
|
602
|
+
const lon = parts[2];
|
|
603
|
+
const position = {
|
|
604
|
+
latitude: (lat[0] === "N" ? 1 : -1) * Number(lat.substring(1)),
|
|
605
|
+
longitude: (lon[0] === "E" ? 1 : -1) * Number(lon.substring(1))
|
|
606
|
+
};
|
|
607
|
+
ResultFormatter.position(decodeResult, position);
|
|
608
|
+
ResultFormatter.heading(decodeResult, Number(parts[5]));
|
|
609
|
+
ResultFormatter.altitude(decodeResult, 100 * Number(parts[6]));
|
|
610
|
+
ResultFormatter.arrivalAirport(decodeResult, parts[7]);
|
|
611
|
+
ResultFormatter.eta(decodeResult, parts[8] + "00");
|
|
612
|
+
const waypoints = [{
|
|
613
|
+
name: parts[11]
|
|
614
|
+
}, {
|
|
615
|
+
name: parts[12],
|
|
616
|
+
time: DateTimeUtils.convertHHMMSSToTod(parts[13] + "00"),
|
|
617
|
+
timeFormat: "tod"
|
|
618
|
+
}, {
|
|
619
|
+
name: parts[14],
|
|
620
|
+
time: DateTimeUtils.convertHHMMSSToTod(parts[15] + "00"),
|
|
621
|
+
timeFormat: "tod"
|
|
622
|
+
}];
|
|
623
|
+
decodeResult.raw.route = { waypoints };
|
|
624
|
+
decodeResult.formatted.items.push({
|
|
625
|
+
type: "aircraft_route",
|
|
626
|
+
code: "ROUTE",
|
|
627
|
+
label: "Aircraft Route",
|
|
628
|
+
value: RouteUtils.routeToString(decodeResult.raw.route)
|
|
629
|
+
});
|
|
630
|
+
if (parts[16]) {
|
|
631
|
+
ResultFormatter.departureAirport(decodeResult, parts[16]);
|
|
632
|
+
}
|
|
633
|
+
decodeResult.remaining.text = [parts[3], parts[4], ...parts.slice(9, 11), ...parts.slice(17)].join("/");
|
|
634
|
+
decodeResult.decoded = true;
|
|
635
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
636
|
+
return decodeResult;
|
|
265
637
|
}
|
|
266
638
|
};
|
|
267
639
|
|
|
@@ -290,19 +662,14 @@ var Label_12_N_Space = class extends DecoderPlugin {
|
|
|
290
662
|
latitude: Number(results.groups.lat_coord) * (results.groups.lat == "N" ? 1 : -1),
|
|
291
663
|
longitude: Number(results.groups.long_coord) * (results.groups.long == "E" ? 1 : -1)
|
|
292
664
|
};
|
|
293
|
-
|
|
665
|
+
const altitude = results.groups.alt == "GRD" || results.groups.alt == "***" ? 0 : Number(results.groups.alt);
|
|
294
666
|
decodeResult.formatted.items.push({
|
|
295
667
|
type: "aircraft_position",
|
|
296
668
|
code: "POS",
|
|
297
669
|
label: "Aircraft Position",
|
|
298
670
|
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
299
671
|
});
|
|
300
|
-
|
|
301
|
-
type: "flight_level",
|
|
302
|
-
code: "FL",
|
|
303
|
-
label: "Flight Level",
|
|
304
|
-
value: decodeResult.raw.flight_level
|
|
305
|
-
});
|
|
672
|
+
ResultFormatter.altitude(decodeResult, altitude);
|
|
306
673
|
decodeResult.remaining.text = `,${results.groups.unkwn1} ,${results.groups.unkwn2}, ${results.groups.unkwn3}`;
|
|
307
674
|
decodeResult.decoded = true;
|
|
308
675
|
decodeResult.decoder.decodeLevel = "partial";
|
|
@@ -364,39 +731,35 @@ var Label_15_FST = class extends DecoderPlugin {
|
|
|
364
731
|
decodeResult.decoder.name = this.name;
|
|
365
732
|
decodeResult.formatted.description = "Position Report";
|
|
366
733
|
decodeResult.message = message;
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
734
|
+
const parts = message.text.split(" ");
|
|
735
|
+
const header = parts[0];
|
|
736
|
+
decodeResult.raw.departure_icao = header.substring(5, 9);
|
|
737
|
+
decodeResult.raw.arrival_icao = header.substring(9, 13);
|
|
738
|
+
const stringCoords = header.substring(13);
|
|
370
739
|
const firstChar = stringCoords.substring(0, 1);
|
|
371
740
|
const middleChar = stringCoords.substring(7, 8);
|
|
372
741
|
decodeResult.raw.position = {};
|
|
373
742
|
if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
|
|
374
743
|
decodeResult.raw.position.latitude = Number(stringCoords.substring(1, 7)) / 1e4 * (firstChar === "S" ? -1 : 1);
|
|
375
|
-
decodeResult.raw.position.longitude = Number(stringCoords.substring(8,
|
|
744
|
+
decodeResult.raw.position.longitude = Number(stringCoords.substring(8, 15)) / 1e4 * (middleChar === "W" ? -1 : 1);
|
|
745
|
+
decodeResult.raw.altitude = Number(stringCoords.substring(15)) * 100;
|
|
376
746
|
} else {
|
|
377
747
|
decodeResult.decoded = false;
|
|
378
748
|
decodeResult.decoder.decodeLevel = "none";
|
|
379
749
|
return decodeResult;
|
|
380
750
|
}
|
|
381
751
|
decodeResult.formatted.items.push({
|
|
382
|
-
type: "
|
|
383
|
-
|
|
752
|
+
type: "aircraft_position",
|
|
753
|
+
code: "POS",
|
|
754
|
+
label: "Aircraft Position",
|
|
384
755
|
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
385
756
|
});
|
|
386
|
-
decodeResult.
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
value: decodeResult.raw.departure_icao
|
|
391
|
-
});
|
|
392
|
-
decodeResult.formatted.items.push({
|
|
393
|
-
type: "destination",
|
|
394
|
-
code: "DST",
|
|
395
|
-
label: "Destination",
|
|
396
|
-
value: decodeResult.raw.arrival_icao
|
|
397
|
-
});
|
|
757
|
+
ResultFormatter.altitude(decodeResult, decodeResult.raw.altitude);
|
|
758
|
+
ResultFormatter.departureAirport(decodeResult, decodeResult.raw.departure_icao);
|
|
759
|
+
ResultFormatter.arrivalAirport(decodeResult, decodeResult.raw.arrival_icao);
|
|
760
|
+
decodeResult.remaining.text = parts.slice(1).join(" ");
|
|
398
761
|
decodeResult.decoded = true;
|
|
399
|
-
decodeResult.decoder.decodeLevel = "
|
|
762
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
400
763
|
return decodeResult;
|
|
401
764
|
}
|
|
402
765
|
};
|
|
@@ -427,19 +790,14 @@ var Label_16_N_Space = class extends DecoderPlugin {
|
|
|
427
790
|
latitude: Number(results.groups.lat_coord) * (results.groups.lat == "N" ? 1 : -1),
|
|
428
791
|
longitude: Number(results.groups.long_coord) * (results.groups.long == "E" ? 1 : -1)
|
|
429
792
|
};
|
|
430
|
-
|
|
793
|
+
const altitude = results.groups.alt == "GRD" || results.groups.alt == "***" ? 0 : Number(results.groups.alt);
|
|
431
794
|
decodeResult.formatted.items.push({
|
|
432
795
|
type: "aircraft_position",
|
|
433
796
|
code: "POS",
|
|
434
797
|
label: "Aircraft Position",
|
|
435
798
|
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
436
799
|
});
|
|
437
|
-
|
|
438
|
-
type: "flight_level",
|
|
439
|
-
code: "FL",
|
|
440
|
-
label: "Flight Level",
|
|
441
|
-
value: decodeResult.raw.flight_level
|
|
442
|
-
});
|
|
800
|
+
ResultFormatter.altitude(decodeResult, altitude);
|
|
443
801
|
decodeResult.remaining.text = `,${results.groups.unkwn1} ,${results.groups.unkwn2}`;
|
|
444
802
|
decodeResult.decoded = true;
|
|
445
803
|
decodeResult.decoder.decodeLevel = "partial";
|
|
@@ -472,58 +830,6 @@ var Label_16_N_Space = class extends DecoderPlugin {
|
|
|
472
830
|
}
|
|
473
831
|
};
|
|
474
832
|
|
|
475
|
-
// lib/DateTimeUtils.ts
|
|
476
|
-
var DateTimeUtils = class {
|
|
477
|
-
// Expects a four digit UTC time string (HHMM)
|
|
478
|
-
static UTCToString(UTCString) {
|
|
479
|
-
let utcDate = /* @__PURE__ */ new Date();
|
|
480
|
-
utcDate.setUTCHours(+UTCString.substr(0, 2), +UTCString.substr(2, 2), 0);
|
|
481
|
-
return utcDate.toTimeString();
|
|
482
|
-
}
|
|
483
|
-
// Expects a six digit date string and a four digit UTC time string
|
|
484
|
-
// (DDMMYY) (HHMM)
|
|
485
|
-
static UTCDateTimeToString(dateString, timeString) {
|
|
486
|
-
let utcDate = /* @__PURE__ */ new Date();
|
|
487
|
-
utcDate.setUTCDate(+dateString.substr(0, 2));
|
|
488
|
-
utcDate.setUTCMonth(+dateString.substr(2, 2));
|
|
489
|
-
if (dateString.length === 6) {
|
|
490
|
-
utcDate.setUTCFullYear(2e3 + +dateString.substr(4, 2));
|
|
491
|
-
}
|
|
492
|
-
if (timeString.length === 6) {
|
|
493
|
-
utcDate.setUTCHours(+timeString.substr(0, 2), +timeString.substr(2, 2), +timeString.substr(4, 2));
|
|
494
|
-
} else {
|
|
495
|
-
utcDate.setUTCHours(+timeString.substr(0, 2), +timeString.substr(2, 2), 0);
|
|
496
|
-
}
|
|
497
|
-
return utcDate.toUTCString();
|
|
498
|
-
}
|
|
499
|
-
/**
|
|
500
|
-
*
|
|
501
|
-
* @param time HHMMSS
|
|
502
|
-
* @returns seconds since midnight
|
|
503
|
-
*/
|
|
504
|
-
static convertHHMMSSToTod(time) {
|
|
505
|
-
const h = Number(time.substring(0, 2));
|
|
506
|
-
const m = Number(time.substring(2, 4));
|
|
507
|
-
const s = Number(time.substring(4, 6));
|
|
508
|
-
const tod = h * 3600 + m * 60 + s;
|
|
509
|
-
return tod;
|
|
510
|
-
}
|
|
511
|
-
/**
|
|
512
|
-
*
|
|
513
|
-
* @param time HHMMSS
|
|
514
|
-
* @param date MMDDYY or MMDDYYYY
|
|
515
|
-
* @returns seconds since epoch
|
|
516
|
-
*/
|
|
517
|
-
static convertDateTimeToEpoch(time, date) {
|
|
518
|
-
if (date.length === 6) {
|
|
519
|
-
date = date.substring(0, 4) + `20${date.substring(4, 6)}`;
|
|
520
|
-
}
|
|
521
|
-
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`;
|
|
522
|
-
const millis = Date.parse(timestamp);
|
|
523
|
-
return millis / 1e3;
|
|
524
|
-
}
|
|
525
|
-
};
|
|
526
|
-
|
|
527
833
|
// lib/plugins/Label_1M_Slash.ts
|
|
528
834
|
var Label_1M_Slash = class extends DecoderPlugin {
|
|
529
835
|
name = "label-1m-slash";
|
|
@@ -600,6 +906,7 @@ var Label_20_POS = class extends DecoderPlugin {
|
|
|
600
906
|
if (decodeResult.raw.position) {
|
|
601
907
|
decodeResult.formatted.items.push({
|
|
602
908
|
type: "position",
|
|
909
|
+
code: "POS",
|
|
603
910
|
label: "Position",
|
|
604
911
|
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
605
912
|
});
|
|
@@ -613,6 +920,7 @@ var Label_20_POS = class extends DecoderPlugin {
|
|
|
613
920
|
if (decodeResult.raw.position) {
|
|
614
921
|
decodeResult.formatted.items.push({
|
|
615
922
|
type: "position",
|
|
923
|
+
code: "POS",
|
|
616
924
|
label: "Position",
|
|
617
925
|
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
618
926
|
});
|
|
@@ -652,7 +960,7 @@ var Label_21_POS = class extends DecoderPlugin {
|
|
|
652
960
|
processAlt(decodeResult, fields[3]);
|
|
653
961
|
processTemp(decodeResult, fields[6]);
|
|
654
962
|
processArrvApt(decodeResult, fields[8]);
|
|
655
|
-
decodeResult.
|
|
963
|
+
decodeResult.remaining.text = [
|
|
656
964
|
fields[1],
|
|
657
965
|
fields[2],
|
|
658
966
|
fields[4],
|
|
@@ -1016,9 +1324,7 @@ var Label_44_POS = class extends DecoderPlugin {
|
|
|
1016
1324
|
console.log(results.groups);
|
|
1017
1325
|
}
|
|
1018
1326
|
decodeResult.raw.position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(results.groups.unsplit_coords);
|
|
1019
|
-
|
|
1020
|
-
decodeResult.raw.departure_icao = results.groups.departure_icao;
|
|
1021
|
-
decodeResult.raw.arrival_icao = results.groups.arrival_icao;
|
|
1327
|
+
const flight_level = results.groups.flight_level_or_ground == "GRD" || results.groups.flight_level_or_ground == "***" ? 0 : Number(results.groups.flight_level_or_ground);
|
|
1022
1328
|
decodeResult.raw.current_time = Date.parse(
|
|
1023
1329
|
(/* @__PURE__ */ new Date()).getFullYear() + "-" + results.groups.current_date.substr(0, 2) + "-" + results.groups.current_date.substr(2, 2) + "T" + results.groups.current_time.substr(0, 2) + ":" + results.groups.current_time.substr(2, 2) + ":00Z"
|
|
1024
1330
|
);
|
|
@@ -1036,24 +1342,9 @@ var Label_44_POS = class extends DecoderPlugin {
|
|
|
1036
1342
|
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
1037
1343
|
});
|
|
1038
1344
|
}
|
|
1039
|
-
decodeResult.
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
label: "Origin",
|
|
1043
|
-
value: decodeResult.raw.departure_icao
|
|
1044
|
-
});
|
|
1045
|
-
decodeResult.formatted.items.push({
|
|
1046
|
-
type: "destination",
|
|
1047
|
-
code: "DST",
|
|
1048
|
-
label: "Destination",
|
|
1049
|
-
value: decodeResult.raw.arrival_icao
|
|
1050
|
-
});
|
|
1051
|
-
decodeResult.formatted.items.push({
|
|
1052
|
-
type: "flight_level",
|
|
1053
|
-
code: "FL",
|
|
1054
|
-
label: "Flight Level",
|
|
1055
|
-
value: decodeResult.raw.flight_level
|
|
1056
|
-
});
|
|
1345
|
+
ResultFormatter.departureAirport(decodeResult, results.groups.departure_icao);
|
|
1346
|
+
ResultFormatter.arrivalAirport(decodeResult, results.groups.arrival_icao);
|
|
1347
|
+
ResultFormatter.altitude(decodeResult, flight_level * 100);
|
|
1057
1348
|
}
|
|
1058
1349
|
decodeResult.decoded = true;
|
|
1059
1350
|
decodeResult.decoder.decodeLevel = "full";
|
|
@@ -1156,13 +1447,9 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
1156
1447
|
break;
|
|
1157
1448
|
}
|
|
1158
1449
|
case "FL": {
|
|
1159
|
-
|
|
1160
|
-
decodeResult.
|
|
1161
|
-
|
|
1162
|
-
code: "FL",
|
|
1163
|
-
label: this.descriptions[match.groups.field],
|
|
1164
|
-
value: decodeResult.raw.flight_level
|
|
1165
|
-
});
|
|
1450
|
+
const flight_level = match.groups.value;
|
|
1451
|
+
decodeResult.raw.altitude = flight_level * 100;
|
|
1452
|
+
ResultFormatter.altitude(decodeResult, decodeResult.raw.altitude);
|
|
1166
1453
|
break;
|
|
1167
1454
|
}
|
|
1168
1455
|
case "FOB": {
|
|
@@ -1328,194 +1615,73 @@ var Label_ColonComma = class extends DecoderPlugin {
|
|
|
1328
1615
|
const decodeResult = this.defaultResult();
|
|
1329
1616
|
decodeResult.decoder.name = this.name;
|
|
1330
1617
|
decodeResult.raw.frequency = Number(message.text) / 1e3;
|
|
1331
|
-
decodeResult.formatted.description = "Aircraft Transceiver Frequency Change";
|
|
1332
|
-
decodeResult.formatted.items.push({
|
|
1333
|
-
type: "frequency",
|
|
1334
|
-
label: "Frequency",
|
|
1335
|
-
value: `${decodeResult.raw.frequency} MHz`
|
|
1336
|
-
});
|
|
1337
|
-
decodeResult.decoded = true;
|
|
1338
|
-
decodeResult.decoder.decodeLevel = "full";
|
|
1339
|
-
return decodeResult;
|
|
1340
|
-
}
|
|
1341
|
-
};
|
|
1342
|
-
|
|
1343
|
-
// lib/utils/result_formatter.ts
|
|
1344
|
-
var ResultFormatter = class {
|
|
1345
|
-
static altitude(decodeResult, value) {
|
|
1346
|
-
decodeResult.raw.altitude = value;
|
|
1347
|
-
decodeResult.formatted.items.push({
|
|
1348
|
-
type: "altitude",
|
|
1349
|
-
code: "ALT",
|
|
1350
|
-
label: "Altitude",
|
|
1351
|
-
value: `${decodeResult.raw.altitude} feet`
|
|
1352
|
-
});
|
|
1353
|
-
}
|
|
1354
|
-
static flightNumber(decodeResult, value) {
|
|
1355
|
-
decodeResult.raw.flight_number = value;
|
|
1356
|
-
}
|
|
1357
|
-
static departureAirport(decodeResult, value) {
|
|
1358
|
-
decodeResult.raw.departure_icao = value;
|
|
1359
|
-
decodeResult.formatted.items.push({
|
|
1360
|
-
type: "origin",
|
|
1361
|
-
code: "ORG",
|
|
1362
|
-
label: "Origin",
|
|
1363
|
-
value: decodeResult.raw.departure_icao
|
|
1364
|
-
});
|
|
1365
|
-
}
|
|
1366
|
-
static departureRunway(decodeResult, value) {
|
|
1367
|
-
decodeResult.raw.departure_runway = value;
|
|
1368
|
-
decodeResult.formatted.items.push({
|
|
1369
|
-
type: "runway",
|
|
1370
|
-
code: "DEPRWY",
|
|
1371
|
-
label: "Departure Runway",
|
|
1372
|
-
value: decodeResult.raw.departure_runway
|
|
1373
|
-
});
|
|
1374
|
-
}
|
|
1375
|
-
static arrivalAirport(decodeResult, value) {
|
|
1376
|
-
decodeResult.raw.arrival_icao = value;
|
|
1377
|
-
decodeResult.formatted.items.push({
|
|
1378
|
-
type: "destination",
|
|
1379
|
-
code: "DST",
|
|
1380
|
-
label: "Destination",
|
|
1381
|
-
value: decodeResult.raw.arrival_icao
|
|
1382
|
-
});
|
|
1383
|
-
}
|
|
1384
|
-
static eta(decodeResult, value) {
|
|
1385
|
-
decodeResult.formatted.items.push({
|
|
1386
|
-
type: "eta",
|
|
1387
|
-
code: "ETA",
|
|
1388
|
-
label: "Estimated Time of Arrival",
|
|
1389
|
-
value: value.substring(0, 2) + ":" + value.substring(2, 4) + ":" + value.substring(4, 6)
|
|
1390
|
-
});
|
|
1391
|
-
}
|
|
1392
|
-
static arrivalRunway(decodeResult, value) {
|
|
1393
|
-
decodeResult.raw.arrival_runway = value;
|
|
1394
|
-
decodeResult.formatted.items.push({
|
|
1395
|
-
type: "runway",
|
|
1396
|
-
label: "Arrival Runway",
|
|
1397
|
-
value: decodeResult.raw.arrival_runway
|
|
1398
|
-
});
|
|
1399
|
-
}
|
|
1400
|
-
static currentFuel(decodeResult, value) {
|
|
1401
|
-
decodeResult.raw.fuel_on_board = value;
|
|
1402
|
-
decodeResult.formatted.items.push({
|
|
1403
|
-
type: "fuel_on_board",
|
|
1404
|
-
code: "FOB",
|
|
1405
|
-
label: "Fuel On Board",
|
|
1406
|
-
value: decodeResult.raw.fuel_on_board.toString()
|
|
1407
|
-
});
|
|
1408
|
-
}
|
|
1409
|
-
static remainingFuel(decodeResult, value) {
|
|
1410
|
-
decodeResult.raw.fuel_remaining = value;
|
|
1411
|
-
decodeResult.formatted.items.push({
|
|
1412
|
-
type: "fuel_remaining",
|
|
1413
|
-
label: "Fuel Remaining",
|
|
1414
|
-
value: decodeResult.raw.fuel_remaining.toString()
|
|
1415
|
-
});
|
|
1416
|
-
}
|
|
1417
|
-
static checksum(decodeResult, value) {
|
|
1418
|
-
decodeResult.raw.checksum = Number("0x" + value);
|
|
1419
|
-
decodeResult.formatted.items.push({
|
|
1420
|
-
type: "message_checksum",
|
|
1421
|
-
code: "CHECKSUM",
|
|
1422
|
-
label: "Message Checksum",
|
|
1423
|
-
value: "0x" + ("0000" + decodeResult.raw.checksum.toString(16)).slice(-4)
|
|
1424
|
-
});
|
|
1425
|
-
}
|
|
1426
|
-
static groundspeed(decodeResult, value) {
|
|
1427
|
-
decodeResult.raw.groundspeed = value;
|
|
1428
|
-
decodeResult.formatted.items.push({
|
|
1429
|
-
type: "aircraft_groundspeed",
|
|
1430
|
-
code: "GSPD",
|
|
1431
|
-
label: "Aircraft Groundspeed",
|
|
1432
|
-
value: `${decodeResult.raw.groundspeed}`
|
|
1433
|
-
});
|
|
1434
|
-
}
|
|
1435
|
-
static temperature(decodeResult, value) {
|
|
1436
|
-
decodeResult.raw.outside_air_temperature = Number(value.substring(1)) * (value.charAt(0) === "M" ? -1 : 1);
|
|
1437
|
-
decodeResult.formatted.items.push({
|
|
1438
|
-
type: "outside_air_temperature",
|
|
1439
|
-
code: "OATEMP",
|
|
1440
|
-
label: "Outside Air Temperature (C)",
|
|
1441
|
-
value: `${decodeResult.raw.outside_air_temperature}`
|
|
1618
|
+
decodeResult.formatted.description = "Aircraft Transceiver Frequency Change";
|
|
1619
|
+
decodeResult.formatted.items.push({
|
|
1620
|
+
type: "frequency",
|
|
1621
|
+
label: "Frequency",
|
|
1622
|
+
value: `${decodeResult.raw.frequency} MHz`
|
|
1442
1623
|
});
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
decodeResult
|
|
1624
|
+
decodeResult.decoded = true;
|
|
1625
|
+
decodeResult.decoder.decodeLevel = "full";
|
|
1626
|
+
return decodeResult;
|
|
1446
1627
|
}
|
|
1447
1628
|
};
|
|
1448
1629
|
|
|
1449
|
-
// lib/
|
|
1450
|
-
var
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
str += `(${route.runway})`;
|
|
1458
|
-
}
|
|
1459
|
-
if (str.length !== 0 && route.waypoints && route.waypoints.length === 1) {
|
|
1460
|
-
str += " starting at ";
|
|
1461
|
-
} else if (str.length !== 0 && route.waypoints) {
|
|
1462
|
-
str += ": ";
|
|
1463
|
-
}
|
|
1464
|
-
if (route.waypoints) {
|
|
1465
|
-
str += _RouteUtils.waypointsToString(route.waypoints);
|
|
1466
|
-
}
|
|
1467
|
-
return str;
|
|
1468
|
-
}
|
|
1469
|
-
static waypointToString(waypoint) {
|
|
1470
|
-
let s = waypoint.name;
|
|
1471
|
-
if (waypoint.latitude && waypoint.longitude) {
|
|
1472
|
-
s += `(${CoordinateUtils.coordinateString({ latitude: waypoint.latitude, longitude: waypoint.longitude })})`;
|
|
1473
|
-
}
|
|
1474
|
-
if (waypoint.offset) {
|
|
1475
|
-
s += `[${waypoint.offset.bearing}\xB0 ${waypoint.offset.distance}nm]`;
|
|
1476
|
-
}
|
|
1477
|
-
if (waypoint.time && waypoint.timeFormat) {
|
|
1478
|
-
s += `@${_RouteUtils.timestampToString(waypoint.time, waypoint.timeFormat)}`;
|
|
1479
|
-
}
|
|
1480
|
-
return s;
|
|
1630
|
+
// lib/plugins/Label_H1_FLR.ts
|
|
1631
|
+
var Label_H1_FLR = class extends DecoderPlugin {
|
|
1632
|
+
name = "label-h1-flr";
|
|
1633
|
+
qualifiers() {
|
|
1634
|
+
return {
|
|
1635
|
+
labels: ["H1"],
|
|
1636
|
+
preambles: ["FLR", "#CFBFLR"]
|
|
1637
|
+
};
|
|
1481
1638
|
}
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
const
|
|
1488
|
-
if (
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1639
|
+
decode(message, options = {}) {
|
|
1640
|
+
let decodeResult = this.defaultResult();
|
|
1641
|
+
decodeResult.decoder.name = this.name;
|
|
1642
|
+
decodeResult.formatted.description = "Fault Log Report";
|
|
1643
|
+
decodeResult.message = message;
|
|
1644
|
+
const parts = message.text.split("/FR");
|
|
1645
|
+
if (parts.length > 1) {
|
|
1646
|
+
decodeResult.remaining.text = "";
|
|
1647
|
+
const fields = parts[0].split("/");
|
|
1648
|
+
for (let i = 1; i < fields.length; i++) {
|
|
1649
|
+
const field = fields[i];
|
|
1650
|
+
if (field.startsWith("PN")) {
|
|
1651
|
+
processUnknown(decodeResult, "/" + field);
|
|
1652
|
+
} else {
|
|
1653
|
+
processUnknown(decodeResult, "/" + field);
|
|
1654
|
+
}
|
|
1492
1655
|
}
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
const
|
|
1496
|
-
const
|
|
1497
|
-
|
|
1498
|
-
|
|
1656
|
+
const data = parts[1].substring(0, 20);
|
|
1657
|
+
const msg = parts[1].substring(20);
|
|
1658
|
+
const datetime = data.substring(0, 12);
|
|
1659
|
+
const date = datetime.substring(4, 6) + datetime.substring(2, 4) + datetime.substring(0, 2);
|
|
1660
|
+
processUnknown(decodeResult, data.substring(12));
|
|
1661
|
+
decodeResult.raw.message_timestamp = DateTimeUtils.convertDateTimeToEpoch(datetime.substring(6), date);
|
|
1662
|
+
decodeResult.raw.fault_message = msg;
|
|
1663
|
+
decodeResult.formatted.items.push({
|
|
1664
|
+
type: "fault",
|
|
1665
|
+
code: "FR",
|
|
1666
|
+
label: "Fault Report",
|
|
1667
|
+
value: decodeResult.raw.fault_message
|
|
1668
|
+
});
|
|
1669
|
+
decodeResult.decoded = true;
|
|
1670
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
1671
|
+
} else {
|
|
1672
|
+
if (options.debug) {
|
|
1673
|
+
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
1499
1674
|
}
|
|
1675
|
+
decodeResult.remaining.text = message.text;
|
|
1676
|
+
decodeResult.decoded = false;
|
|
1677
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1500
1678
|
}
|
|
1501
|
-
return
|
|
1502
|
-
}
|
|
1503
|
-
// move out if we want public
|
|
1504
|
-
static timestampToString(time, format) {
|
|
1505
|
-
const date = new Date(time * 1e3);
|
|
1506
|
-
if (format == "tod") {
|
|
1507
|
-
return date.toISOString().slice(11, 19);
|
|
1508
|
-
}
|
|
1509
|
-
return date.toISOString().slice(0, -5) + "Z";
|
|
1510
|
-
}
|
|
1511
|
-
static waypointsToString(waypoints) {
|
|
1512
|
-
let str = waypoints.map((x) => _RouteUtils.waypointToString(x)).join(" > ").replaceAll("> >", ">>");
|
|
1513
|
-
if (str.startsWith(" > ")) {
|
|
1514
|
-
str = ">>" + str.slice(2);
|
|
1515
|
-
}
|
|
1516
|
-
return str;
|
|
1679
|
+
return decodeResult;
|
|
1517
1680
|
}
|
|
1518
1681
|
};
|
|
1682
|
+
function processUnknown(decodeResult, value) {
|
|
1683
|
+
decodeResult.remaining.text += value;
|
|
1684
|
+
}
|
|
1519
1685
|
|
|
1520
1686
|
// lib/utils/flight_plan_utils.ts
|
|
1521
1687
|
var FlightPlanUtils = class _FlightPlanUtils {
|
|
@@ -1708,21 +1874,7 @@ var H1Helper = class {
|
|
|
1708
1874
|
const dt = processDT(decodeResult, data2);
|
|
1709
1875
|
allKnownFields = allKnownFields && dt;
|
|
1710
1876
|
} else if (fields[i].startsWith("ID")) {
|
|
1711
|
-
|
|
1712
|
-
decodeResult.raw.tail = data2[0];
|
|
1713
|
-
decodeResult.formatted.items.push({
|
|
1714
|
-
type: "tail",
|
|
1715
|
-
code: "TAIL",
|
|
1716
|
-
label: "Tail",
|
|
1717
|
-
value: decodeResult.raw.tail
|
|
1718
|
-
});
|
|
1719
|
-
if (data2.length > 1) {
|
|
1720
|
-
decodeResult.raw.flight_number = data2[1];
|
|
1721
|
-
}
|
|
1722
|
-
if (data2.length > 2) {
|
|
1723
|
-
allKnownFields = false;
|
|
1724
|
-
decodeResult.remaining.text += "," + data2.slice(2).join(",");
|
|
1725
|
-
}
|
|
1877
|
+
processIdentification(decodeResult, fields[i].substring(2).split(","));
|
|
1726
1878
|
} else if (fields[i].startsWith("LR")) {
|
|
1727
1879
|
const data2 = fields[i].substring(2).split(",");
|
|
1728
1880
|
const lr = processLR(decodeResult, data2);
|
|
@@ -1736,6 +1888,20 @@ var H1Helper = class {
|
|
|
1736
1888
|
} else if (fields[i].startsWith("PS")) {
|
|
1737
1889
|
allKnownFields = false;
|
|
1738
1890
|
decodeResult.remaining.text += fields[i];
|
|
1891
|
+
} else if (fields[i].startsWith("AF")) {
|
|
1892
|
+
const af = processAirField(decodeResult, fields[i].substring(2).split(","));
|
|
1893
|
+
allKnownFields = allKnownFields && af;
|
|
1894
|
+
} else if (fields[i].startsWith("TD")) {
|
|
1895
|
+
const td = processTimeOfDeparture(decodeResult, fields[i].substring(2).split(","));
|
|
1896
|
+
allKnownFields = allKnownFields && td;
|
|
1897
|
+
} else if (fields[i].startsWith("FX")) {
|
|
1898
|
+
decodeResult.raw.free_text = fields[i].substring(2);
|
|
1899
|
+
decodeResult.formatted.items.push({
|
|
1900
|
+
type: "text",
|
|
1901
|
+
code: "TEXT",
|
|
1902
|
+
label: "Free Text",
|
|
1903
|
+
value: decodeResult.raw.free_text
|
|
1904
|
+
});
|
|
1739
1905
|
} else {
|
|
1740
1906
|
decodeResult.remaining.text += "/" + fields[i];
|
|
1741
1907
|
allKnownFields = false;
|
|
@@ -1747,6 +1913,51 @@ var H1Helper = class {
|
|
|
1747
1913
|
return allKnownFields;
|
|
1748
1914
|
}
|
|
1749
1915
|
};
|
|
1916
|
+
function processAirField(decodeResult, data) {
|
|
1917
|
+
if (data.length === 2) {
|
|
1918
|
+
ResultFormatter.departureAirport(decodeResult, data[0]);
|
|
1919
|
+
ResultFormatter.arrivalAirport(decodeResult, data[1]);
|
|
1920
|
+
return true;
|
|
1921
|
+
}
|
|
1922
|
+
decodeResult.remaining.text += "AF/" + data.join(",");
|
|
1923
|
+
return false;
|
|
1924
|
+
}
|
|
1925
|
+
function processTimeOfDeparture(decodeResult, data) {
|
|
1926
|
+
if (data.length === 2) {
|
|
1927
|
+
decodeResult.raw.plannedDepartureTime = data[0];
|
|
1928
|
+
decodeResult.formatted.items.push({
|
|
1929
|
+
type: "ptd",
|
|
1930
|
+
code: "ptd",
|
|
1931
|
+
label: "Planned Departure Time",
|
|
1932
|
+
value: `YYYY-MM-${data[0].substring(0, 2)}T${data[0].substring(2, 4)}:${data[0].substring(4)}:00Z`
|
|
1933
|
+
});
|
|
1934
|
+
decodeResult.raw.plannedDepartureTime = data[1];
|
|
1935
|
+
decodeResult.formatted.items.push({
|
|
1936
|
+
type: "etd",
|
|
1937
|
+
code: "etd",
|
|
1938
|
+
label: "Estimated Departure Time",
|
|
1939
|
+
value: `${data[1].substring(0, 2)}:${data[1].substring(2)}`
|
|
1940
|
+
});
|
|
1941
|
+
return true;
|
|
1942
|
+
}
|
|
1943
|
+
decodeResult.remaining.text += "/TD" + data.join(",");
|
|
1944
|
+
return false;
|
|
1945
|
+
}
|
|
1946
|
+
function processIdentification(decodeResult, data) {
|
|
1947
|
+
decodeResult.raw.tail = data[0];
|
|
1948
|
+
decodeResult.formatted.items.push({
|
|
1949
|
+
type: "tail",
|
|
1950
|
+
code: "TAIL",
|
|
1951
|
+
label: "Tail",
|
|
1952
|
+
value: decodeResult.raw.tail
|
|
1953
|
+
});
|
|
1954
|
+
if (data.length > 1) {
|
|
1955
|
+
decodeResult.raw.flight_number = data[1];
|
|
1956
|
+
}
|
|
1957
|
+
if (data.length > 2) {
|
|
1958
|
+
decodeResult.raw.mission_number = data[2];
|
|
1959
|
+
}
|
|
1960
|
+
}
|
|
1750
1961
|
function processDT(decodeResult, data) {
|
|
1751
1962
|
let allKnownFields = true;
|
|
1752
1963
|
if (!decodeResult.raw.arrival_icao) {
|
|
@@ -1824,7 +2035,7 @@ function processDC(decodeResult, data) {
|
|
|
1824
2035
|
}
|
|
1825
2036
|
function processPS(decodeResult, data) {
|
|
1826
2037
|
let allKnownFields = true;
|
|
1827
|
-
const position = CoordinateUtils.
|
|
2038
|
+
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[0]);
|
|
1828
2039
|
if (position) {
|
|
1829
2040
|
decodeResult.raw.position = position;
|
|
1830
2041
|
decodeResult.formatted.items.push({
|
|
@@ -1860,7 +2071,7 @@ function processPS(decodeResult, data) {
|
|
|
1860
2071
|
}
|
|
1861
2072
|
function processPosition2(decodeResult, data) {
|
|
1862
2073
|
let allKnownFields = true;
|
|
1863
|
-
const position = CoordinateUtils.
|
|
2074
|
+
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[0]);
|
|
1864
2075
|
if (position) {
|
|
1865
2076
|
decodeResult.raw.position = position;
|
|
1866
2077
|
decodeResult.formatted.items.push({
|
|
@@ -1942,6 +2153,67 @@ var Label_H1_FPN = class extends DecoderPlugin {
|
|
|
1942
2153
|
}
|
|
1943
2154
|
};
|
|
1944
2155
|
|
|
2156
|
+
// lib/plugins/Label_H1_FTX.ts
|
|
2157
|
+
var Label_H1_FTX = class extends DecoderPlugin {
|
|
2158
|
+
name = "label-h1-ftx";
|
|
2159
|
+
qualifiers() {
|
|
2160
|
+
return {
|
|
2161
|
+
labels: ["H1"],
|
|
2162
|
+
preambles: ["FTX", "- #MDFTX"]
|
|
2163
|
+
};
|
|
2164
|
+
}
|
|
2165
|
+
decode(message, options = {}) {
|
|
2166
|
+
let decodeResult = this.defaultResult();
|
|
2167
|
+
decodeResult.decoder.name = this.name;
|
|
2168
|
+
decodeResult.formatted.description = "Free Text";
|
|
2169
|
+
decodeResult.message = message;
|
|
2170
|
+
decodeResult.remaining.text = "";
|
|
2171
|
+
const fulllyDecoded = H1Helper.decodeH1Message(decodeResult, message.text);
|
|
2172
|
+
decodeResult.decoded = true;
|
|
2173
|
+
decodeResult.decoder.decodeLevel = fulllyDecoded ? "full" : "partial";
|
|
2174
|
+
if (decodeResult.formatted.items.length === 0) {
|
|
2175
|
+
if (options?.debug) {
|
|
2176
|
+
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
2177
|
+
}
|
|
2178
|
+
decodeResult.remaining.text = message.text;
|
|
2179
|
+
decodeResult.decoded = false;
|
|
2180
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2181
|
+
}
|
|
2182
|
+
return decodeResult;
|
|
2183
|
+
}
|
|
2184
|
+
};
|
|
2185
|
+
|
|
2186
|
+
// lib/plugins/Label_H1_INI.ts
|
|
2187
|
+
var Label_H1_INI = class extends DecoderPlugin {
|
|
2188
|
+
// eslint-disable-line camelcase
|
|
2189
|
+
name = "label-h1-ini";
|
|
2190
|
+
qualifiers() {
|
|
2191
|
+
return {
|
|
2192
|
+
labels: ["H1"],
|
|
2193
|
+
preambles: ["INI", "- #MDINI"]
|
|
2194
|
+
};
|
|
2195
|
+
}
|
|
2196
|
+
decode(message, options = {}) {
|
|
2197
|
+
const decodeResult = this.defaultResult();
|
|
2198
|
+
decodeResult.decoder.name = this.name;
|
|
2199
|
+
decodeResult.formatted.description = "Flight Plan Initial Report";
|
|
2200
|
+
decodeResult.message = message;
|
|
2201
|
+
decodeResult.remaining.text = "";
|
|
2202
|
+
const fulllyDecoded = H1Helper.decodeH1Message(decodeResult, message.text);
|
|
2203
|
+
decodeResult.decoded = true;
|
|
2204
|
+
decodeResult.decoder.decodeLevel = fulllyDecoded ? "full" : "partial";
|
|
2205
|
+
if (decodeResult.formatted.items.length === 0) {
|
|
2206
|
+
if (options?.debug) {
|
|
2207
|
+
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
2208
|
+
}
|
|
2209
|
+
decodeResult.remaining.text = message.text;
|
|
2210
|
+
decodeResult.decoded = false;
|
|
2211
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2212
|
+
}
|
|
2213
|
+
return decodeResult;
|
|
2214
|
+
}
|
|
2215
|
+
};
|
|
2216
|
+
|
|
1945
2217
|
// lib/plugins/Label_H1_OHMA.ts
|
|
1946
2218
|
var zlib = __toESM(require("minizlib"));
|
|
1947
2219
|
var Label_H1_OHMA = class extends DecoderPlugin {
|
|
@@ -2052,16 +2324,16 @@ var Label_H1_WRN = class extends DecoderPlugin {
|
|
|
2052
2324
|
for (let i = 1; i < fields.length; i++) {
|
|
2053
2325
|
const field = fields[i];
|
|
2054
2326
|
if (field.startsWith("PN")) {
|
|
2055
|
-
|
|
2327
|
+
processUnknown2(decodeResult, "/" + field);
|
|
2056
2328
|
} else {
|
|
2057
|
-
|
|
2329
|
+
processUnknown2(decodeResult, "/" + field);
|
|
2058
2330
|
}
|
|
2059
2331
|
}
|
|
2060
2332
|
const data = parts[1].substring(0, 20);
|
|
2061
2333
|
const msg = parts[1].substring(20);
|
|
2062
2334
|
const datetime = data.substring(0, 12);
|
|
2063
2335
|
const date = datetime.substring(4, 6) + datetime.substring(2, 4) + datetime.substring(0, 2);
|
|
2064
|
-
|
|
2336
|
+
processUnknown2(decodeResult, data.substring(12));
|
|
2065
2337
|
decodeResult.raw.message_timestamp = DateTimeUtils.convertDateTimeToEpoch(datetime.substring(6), date);
|
|
2066
2338
|
decodeResult.raw.warning_message = msg;
|
|
2067
2339
|
decodeResult.formatted.items.push({
|
|
@@ -2083,10 +2355,64 @@ var Label_H1_WRN = class extends DecoderPlugin {
|
|
|
2083
2355
|
return decodeResult;
|
|
2084
2356
|
}
|
|
2085
2357
|
};
|
|
2086
|
-
function
|
|
2358
|
+
function processUnknown2(decodeResult, value) {
|
|
2087
2359
|
decodeResult.remaining.text += value;
|
|
2088
2360
|
}
|
|
2089
2361
|
|
|
2362
|
+
// lib/plugins/Label_HX.ts
|
|
2363
|
+
var Label_HX = class extends DecoderPlugin {
|
|
2364
|
+
name = "label-hx";
|
|
2365
|
+
qualifiers() {
|
|
2366
|
+
return {
|
|
2367
|
+
labels: ["HX"],
|
|
2368
|
+
preambles: ["RA FMT LOCATION", "RA FMT 43"]
|
|
2369
|
+
};
|
|
2370
|
+
}
|
|
2371
|
+
decode(message, options = {}) {
|
|
2372
|
+
const decodeResult = this.defaultResult();
|
|
2373
|
+
decodeResult.decoder.name = this.name;
|
|
2374
|
+
decodeResult.message = message;
|
|
2375
|
+
decodeResult.formatted.description = "Undelivered Uplink Report";
|
|
2376
|
+
const parts = message.text.split(" ");
|
|
2377
|
+
decodeResult.decoded = true;
|
|
2378
|
+
if (parts[2] === "LOCATION") {
|
|
2379
|
+
let latdir = parts[3].substring(0, 1);
|
|
2380
|
+
let latdeg = Number(parts[3].substring(1, 3));
|
|
2381
|
+
let latmin = Number(parts[3].substring(3, 7));
|
|
2382
|
+
let londir = parts[4].substring(0, 1);
|
|
2383
|
+
let londeg = Number(parts[4].substring(1, 4));
|
|
2384
|
+
let lonmin = Number(parts[4].substring(4, 8));
|
|
2385
|
+
decodeResult.raw.position = {
|
|
2386
|
+
latitude: (latdeg + latmin / 60) * (latdir === "N" ? 1 : -1),
|
|
2387
|
+
longitude: (londeg + lonmin / 60) * (londir === "E" ? 1 : -1)
|
|
2388
|
+
};
|
|
2389
|
+
decodeResult.remaining.text = parts.slice(5).join(" ");
|
|
2390
|
+
} else if (parts[2] === "43") {
|
|
2391
|
+
ResultFormatter.departureAirport(decodeResult, parts[3]);
|
|
2392
|
+
decodeResult.remaining.text = parts.slice(4).join(" ");
|
|
2393
|
+
} else {
|
|
2394
|
+
decodeResult.decoded = false;
|
|
2395
|
+
}
|
|
2396
|
+
if (decodeResult.raw.position) {
|
|
2397
|
+
decodeResult.formatted.items.push({
|
|
2398
|
+
type: "aircraft_position",
|
|
2399
|
+
code: "POS",
|
|
2400
|
+
label: "Aircraft Position",
|
|
2401
|
+
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
2402
|
+
});
|
|
2403
|
+
}
|
|
2404
|
+
if (decodeResult.decoded) {
|
|
2405
|
+
if (decodeResult.remaining.text === "")
|
|
2406
|
+
decodeResult.decoder.decodeLevel = "full";
|
|
2407
|
+
else
|
|
2408
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
2409
|
+
} else {
|
|
2410
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2411
|
+
}
|
|
2412
|
+
return decodeResult;
|
|
2413
|
+
}
|
|
2414
|
+
};
|
|
2415
|
+
|
|
2090
2416
|
// lib/plugins/Label_SQ.ts
|
|
2091
2417
|
var Label_SQ = class extends DecoderPlugin {
|
|
2092
2418
|
name = "label-sq";
|
|
@@ -2127,11 +2453,13 @@ var Label_SQ = class extends DecoderPlugin {
|
|
|
2127
2453
|
decodeResult.formatted.items = [
|
|
2128
2454
|
{
|
|
2129
2455
|
type: "network",
|
|
2456
|
+
code: "NETT",
|
|
2130
2457
|
label: "Network",
|
|
2131
2458
|
value: formattedNetwork
|
|
2132
2459
|
},
|
|
2133
2460
|
{
|
|
2134
2461
|
type: "version",
|
|
2462
|
+
code: "VER",
|
|
2135
2463
|
label: "Version",
|
|
2136
2464
|
value: decodeResult.raw.version
|
|
2137
2465
|
}
|
|
@@ -2140,6 +2468,7 @@ var Label_SQ = class extends DecoderPlugin {
|
|
|
2140
2468
|
if (decodeResult.raw.groundStation.icaoCode && decodeResult.raw.groundStation.number) {
|
|
2141
2469
|
decodeResult.formatted.items.push({
|
|
2142
2470
|
type: "ground_station",
|
|
2471
|
+
code: "GNDSTN",
|
|
2143
2472
|
label: "Ground Station",
|
|
2144
2473
|
value: `${decodeResult.raw.groundStation.icaoCode}${decodeResult.raw.groundStation.number}`
|
|
2145
2474
|
});
|
|
@@ -2147,6 +2476,7 @@ var Label_SQ = class extends DecoderPlugin {
|
|
|
2147
2476
|
if (decodeResult.raw.groundStation.iataCode) {
|
|
2148
2477
|
decodeResult.formatted.items.push({
|
|
2149
2478
|
type: "iataCode",
|
|
2479
|
+
code: "IATA",
|
|
2150
2480
|
label: "IATA",
|
|
2151
2481
|
value: decodeResult.raw.groundStation.iataCode
|
|
2152
2482
|
});
|
|
@@ -2154,6 +2484,7 @@ var Label_SQ = class extends DecoderPlugin {
|
|
|
2154
2484
|
if (decodeResult.raw.groundStation.icaoCode) {
|
|
2155
2485
|
decodeResult.formatted.items.push({
|
|
2156
2486
|
type: "icaoCode",
|
|
2487
|
+
code: "ICAO",
|
|
2157
2488
|
label: "ICAO",
|
|
2158
2489
|
value: decodeResult.raw.groundStation.icaoCode
|
|
2159
2490
|
});
|
|
@@ -2161,6 +2492,7 @@ var Label_SQ = class extends DecoderPlugin {
|
|
|
2161
2492
|
if (decodeResult.raw.groundStation.coordinates.latitude) {
|
|
2162
2493
|
decodeResult.formatted.items.push({
|
|
2163
2494
|
type: "coordinates",
|
|
2495
|
+
code: "COORD",
|
|
2164
2496
|
label: "Ground Station Location",
|
|
2165
2497
|
value: `${decodeResult.raw.groundStation.coordinates.latitude}, ${decodeResult.raw.groundStation.coordinates.longitude}`
|
|
2166
2498
|
});
|
|
@@ -2168,6 +2500,7 @@ var Label_SQ = class extends DecoderPlugin {
|
|
|
2168
2500
|
if (decodeResult.raw.groundStation.airport) {
|
|
2169
2501
|
decodeResult.formatted.items.push({
|
|
2170
2502
|
type: "airport",
|
|
2503
|
+
code: "APT",
|
|
2171
2504
|
label: "Airport",
|
|
2172
2505
|
value: `${decodeResult.raw.groundStation.airport.name} (${decodeResult.raw.groundStation.airport.icao}) in ${decodeResult.raw.groundStation.airport.location}`
|
|
2173
2506
|
});
|
|
@@ -2176,6 +2509,7 @@ var Label_SQ = class extends DecoderPlugin {
|
|
|
2176
2509
|
if (decodeResult.raw.vdlFrequency) {
|
|
2177
2510
|
decodeResult.formatted.items.push({
|
|
2178
2511
|
type: "vdlFrequency",
|
|
2512
|
+
code: "VDLFRQ",
|
|
2179
2513
|
label: "VDL Frequency",
|
|
2180
2514
|
value: `${decodeResult.raw.vdlFrequency} MHz`
|
|
2181
2515
|
});
|
|
@@ -2332,31 +2666,48 @@ var Label_QQ = class extends DecoderPlugin {
|
|
|
2332
2666
|
decode(message, options = {}) {
|
|
2333
2667
|
const decodeResult = this.defaultResult();
|
|
2334
2668
|
decodeResult.decoder.name = this.name;
|
|
2335
|
-
decodeResult.
|
|
2336
|
-
decodeResult.raw.destination = message.text.substring(4, 8);
|
|
2337
|
-
decodeResult.raw.wheels_off = message.text.substring(8, 12);
|
|
2338
|
-
decodeResult.remaining.text = message.text.substring(12);
|
|
2669
|
+
decodeResult.message = message;
|
|
2339
2670
|
decodeResult.formatted.description = "OFF Report";
|
|
2340
|
-
decodeResult.
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2671
|
+
ResultFormatter.departureAirport(decodeResult, message.text.substring(0, 4));
|
|
2672
|
+
ResultFormatter.arrivalAirport(decodeResult, message.text.substring(4, 8));
|
|
2673
|
+
decodeResult.raw.wheels_off = message.text.substring(8, 12);
|
|
2674
|
+
if (message.text.substring(12, 19) === "\r\n001FE") {
|
|
2675
|
+
decodeResult.raw.day_of_month = message.text.substring(19, 21);
|
|
2676
|
+
decodeResult.raw.wheels_off = message.text.substring(21, 27);
|
|
2677
|
+
let latdir = message.text.substring(27, 28);
|
|
2678
|
+
let latdeg = Number(message.text.substring(28, 30));
|
|
2679
|
+
let latmin = Number(message.text.substring(30, 34));
|
|
2680
|
+
let londir = message.text.substring(34, 35);
|
|
2681
|
+
let londeg = Number(message.text.substring(35, 38));
|
|
2682
|
+
let lonmin = Number(message.text.substring(38, 42));
|
|
2683
|
+
decodeResult.raw.position = {
|
|
2684
|
+
latitude: (latdeg + latmin / 60) * (latdir === "N" ? 1 : -1),
|
|
2685
|
+
longitude: (londeg + lonmin / 60) * (londir === "E" ? 1 : -1)
|
|
2686
|
+
};
|
|
2687
|
+
decodeResult.remaining.text = message.text.substring(42, 45);
|
|
2688
|
+
if (decodeResult.remaining.text !== "---") {
|
|
2689
|
+
ResultFormatter.groundspeed(decodeResult, message.text.substring(45, 48));
|
|
2690
|
+
} else {
|
|
2691
|
+
ResultFormatter.unknown(decodeResult, message.text.substring(45, 48));
|
|
2358
2692
|
}
|
|
2359
|
-
|
|
2693
|
+
ResultFormatter.unknown(decodeResult, message.text.substring(48));
|
|
2694
|
+
} else {
|
|
2695
|
+
decodeResult.remaining.text = message.text.substring(12);
|
|
2696
|
+
}
|
|
2697
|
+
decodeResult.formatted.items.push({
|
|
2698
|
+
type: "wheels_off",
|
|
2699
|
+
code: "WOFF",
|
|
2700
|
+
label: "Wheels OFF",
|
|
2701
|
+
value: decodeResult.raw.wheels_off
|
|
2702
|
+
});
|
|
2703
|
+
if (decodeResult.raw.position) {
|
|
2704
|
+
decodeResult.formatted.items.push({
|
|
2705
|
+
type: "aircraft_position",
|
|
2706
|
+
code: "POS",
|
|
2707
|
+
label: "Aircraft Position",
|
|
2708
|
+
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
2709
|
+
});
|
|
2710
|
+
}
|
|
2360
2711
|
decodeResult.decoded = true;
|
|
2361
2712
|
if (decodeResult.remaining.text === "")
|
|
2362
2713
|
decodeResult.decoder.decodeLevel = "full";
|
|
@@ -3179,6 +3530,9 @@ var MessageDecoder = class {
|
|
|
3179
3530
|
this.debug = false;
|
|
3180
3531
|
this.registerPlugin(new Label_ColonComma(this));
|
|
3181
3532
|
this.registerPlugin(new Label_5Z(this));
|
|
3533
|
+
this.registerPlugin(new Label_10_LDR(this));
|
|
3534
|
+
this.registerPlugin(new Label_10_POS(this));
|
|
3535
|
+
this.registerPlugin(new Label_10_Slash(this));
|
|
3182
3536
|
this.registerPlugin(new Label_12_N_Space(this));
|
|
3183
3537
|
this.registerPlugin(new Label_15(this));
|
|
3184
3538
|
this.registerPlugin(new Label_15_FST(this));
|
|
@@ -3193,9 +3547,13 @@ var MessageDecoder = class {
|
|
|
3193
3547
|
this.registerPlugin(new Label_44_POS(this));
|
|
3194
3548
|
this.registerPlugin(new Label_B6_Forwardslash(this));
|
|
3195
3549
|
this.registerPlugin(new Label_H1_FPN(this));
|
|
3550
|
+
this.registerPlugin(new Label_H1_FLR(this));
|
|
3551
|
+
this.registerPlugin(new Label_H1_FTX(this));
|
|
3552
|
+
this.registerPlugin(new Label_H1_INI(this));
|
|
3196
3553
|
this.registerPlugin(new Label_H1_OHMA(this));
|
|
3197
3554
|
this.registerPlugin(new Label_H1_POS(this));
|
|
3198
3555
|
this.registerPlugin(new Label_H1_WRN(this));
|
|
3556
|
+
this.registerPlugin(new Label_HX(this));
|
|
3199
3557
|
this.registerPlugin(new Label_80(this));
|
|
3200
3558
|
this.registerPlugin(new Label_8E(this));
|
|
3201
3559
|
this.registerPlugin(new Label_1M_Slash(this));
|