@airframes/acars-decoder 1.4.3 → 1.4.5

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.
Files changed (67) hide show
  1. package/dist/DateTimeUtils.d.ts +8 -0
  2. package/dist/DateTimeUtils.js +27 -0
  3. package/dist/DecoderPlugin.d.ts +3 -1
  4. package/dist/DecoderPlugin.js +3 -1
  5. package/dist/IcaoDecoder.d.ts +3 -1
  6. package/dist/IcaoDecoder.js +3 -1
  7. package/dist/MessageDecoder.d.ts +3 -1
  8. package/dist/MessageDecoder.js +5 -1
  9. package/dist/bin/acars-decoder-test.js +9 -0
  10. package/dist/index.d.ts +4 -0
  11. package/dist/index.js +20 -0
  12. package/dist/plugins/Label_16_N_Space.d.ts +11 -0
  13. package/dist/plugins/Label_16_N_Space.js +80 -0
  14. package/dist/plugins/Label_16_N_Space.test.d.ts +1 -0
  15. package/dist/plugins/Label_16_N_Space.test.js +84 -0
  16. package/dist/plugins/Label_1M_Slash.js +2 -4
  17. package/dist/plugins/Label_1M_Slash.test.js +3 -3
  18. package/dist/plugins/Label_30_Slash_EA.d.ts +11 -0
  19. package/dist/plugins/Label_30_Slash_EA.js +54 -0
  20. package/dist/plugins/Label_30_Slash_EA.test.d.ts +1 -0
  21. package/dist/plugins/Label_30_Slash_EA.test.js +35 -0
  22. package/dist/plugins/Label_8E.js +2 -9
  23. package/dist/plugins/Label_8E.test.js +3 -3
  24. package/dist/plugins/official.d.ts +2 -0
  25. package/dist/plugins/official.js +2 -0
  26. package/package.json +12 -3
  27. package/src/DateTimeUtils.ts +26 -0
  28. package/src/DecoderPlugin.ts +83 -0
  29. package/src/DecoderPluginInterface.ts +9 -0
  30. package/src/IcaoDecoder.ts +137 -0
  31. package/src/MessageDecoder.ts +117 -0
  32. package/src/bin/acars-decoder-test.ts +67 -0
  33. package/src/bin/acars-decoder.ts +23 -0
  34. package/src/index.d.ts +15 -0
  35. package/src/index.ts +4 -0
  36. package/src/plugins/Label_15.ts +45 -0
  37. package/src/plugins/Label_16_N_Space.test.ts +94 -0
  38. package/src/plugins/Label_16_N_Space.ts +91 -0
  39. package/src/plugins/Label_1M_Slash.test.ts +45 -0
  40. package/src/plugins/Label_1M_Slash.ts +69 -0
  41. package/src/plugins/Label_20_CFB.01.ts +81 -0
  42. package/src/plugins/Label_20_POS.ts +68 -0
  43. package/src/plugins/Label_30_Slash_EA.test.ts +37 -0
  44. package/src/plugins/Label_30_Slash_EA.ts +60 -0
  45. package/src/plugins/Label_44_ETA.ts +81 -0
  46. package/src/plugins/Label_44_IN.ts +81 -0
  47. package/src/plugins/Label_44_OFF.ts +88 -0
  48. package/src/plugins/Label_44_ON.ts +81 -0
  49. package/src/plugins/Label_44_POS.ts +96 -0
  50. package/src/plugins/Label_5Z.ts +125 -0
  51. package/src/plugins/Label_80.ts +215 -0
  52. package/src/plugins/Label_8E.test.ts +34 -0
  53. package/src/plugins/Label_8E.ts +55 -0
  54. package/src/plugins/Label_B6.ts +28 -0
  55. package/src/plugins/Label_ColonComma.ts +32 -0
  56. package/src/plugins/Label_H1.ts +18 -0
  57. package/src/plugins/Label_H1_M1BPOS.ts +60 -0
  58. package/src/plugins/Label_H1_M1BPRG.ts +40 -0
  59. package/src/plugins/Label_QP.ts +54 -0
  60. package/src/plugins/Label_QQ.ts +54 -0
  61. package/src/plugins/Label_QR.ts +54 -0
  62. package/src/plugins/Label_QS.ts +54 -0
  63. package/src/plugins/Label_SQ.ts +111 -0
  64. package/src/plugins/official.ts +22 -0
  65. package/tsconfig.json +2 -3
  66. package/index.d.ts +0 -17
  67. package/index.ts +0 -4
@@ -0,0 +1,45 @@
1
+ import { MessageDecoder } from '../MessageDecoder';
2
+ import { Label_1M_Slash } from './Label_1M_Slash';
3
+
4
+ test('decodes Label 8E sample 1', () => {
5
+ const decoder = new MessageDecoder();
6
+ const decoderPlugin = new Label_1M_Slash(decoder);
7
+
8
+ expect(decoderPlugin.decode).toBeDefined();
9
+ expect(decoderPlugin.name).toBe('label-1m-slash');
10
+ expect(decoderPlugin.qualifiers).toBeDefined();
11
+ expect(decoderPlugin.qualifiers()).toEqual({
12
+ labels: ['1M'],
13
+ preambles: ['/'],
14
+ });
15
+
16
+ const text = '/BA0843/ETA01/230822/LDSP/EGLL/EGSS/2JK0\n1940/EGLL27L/10';
17
+ const decodeResult = decoderPlugin.decode({ text: text });
18
+ console.log(JSON.stringify(decodeResult, null, 2));
19
+
20
+ expect(decodeResult.decoded).toBe(true);
21
+ expect(decodeResult.decoder.decodeLevel).toBe('partial');
22
+ expect(decodeResult.decoder.name).toBe('label-1m-slash');
23
+ expect(decodeResult.formatted.description).toBe('ETA Report');
24
+ expect(decodeResult.message.text).toBe(text);
25
+ expect(decodeResult.raw.alternate_icao).toBe('EGSS');
26
+ expect(decodeResult.raw.arrival_icao).toBe('EGLL');
27
+ expect(decodeResult.raw.arrival_runway).toBe('27L');
28
+ expect(decodeResult.raw.departure_icao).toBe('LDSP');
29
+ expect(decodeResult.raw.flight_number).toBe('BA0843');
30
+ expect(decodeResult.formatted.items.length).toBe(3);
31
+ expect(decodeResult.formatted.items[0].type).toBe('eta');
32
+ expect(decodeResult.formatted.items[0].code).toBe('ETA');
33
+ expect(decodeResult.formatted.items[0].label).toBe('Estimated Time of Arrival');
34
+ // Check for the minutes as typescript doesn't have a UTC time string method
35
+ // so the hour will depend on the test host timezone.
36
+ expect((decodeResult.formatted.items[0].value as string).includes('40')).toBe(true);
37
+ expect(decodeResult.formatted.items[1].type).toBe('destination');
38
+ expect(decodeResult.formatted.items[1].code).toBe('DST');
39
+ expect(decodeResult.formatted.items[1].label).toBe('Destination');
40
+ expect(decodeResult.formatted.items[1].value).toBe('EGLL');
41
+ expect(decodeResult.formatted.items[2].type).toBe('origin');
42
+ expect(decodeResult.formatted.items[2].code).toBe('ORG');
43
+ expect(decodeResult.formatted.items[2].label).toBe('Origin');
44
+ expect(decodeResult.formatted.items[2].value).toBe('LDSP');
45
+ });
@@ -0,0 +1,69 @@
1
+ import { DateTimeUtils } from '../DateTimeUtils';
2
+ import { DecoderPlugin } from '../DecoderPlugin';
3
+
4
+ export class Label_1M_Slash extends DecoderPlugin {
5
+ name = 'label-1m-slash';
6
+
7
+ qualifiers() { // eslint-disable-line class-methods-use-this
8
+ return {
9
+ labels: ["1M"],
10
+ preambles: ['/'],
11
+ };
12
+ }
13
+
14
+ decode(message: any, options: any = {}) : any {
15
+ const decodeResult: any = this.defaultResult;
16
+ decodeResult.decoder.name = this.name;
17
+ decodeResult.formatted.description = 'ETA Report';
18
+ decodeResult.message = message;
19
+
20
+ // Style: /BA0843/ETA01/230822/LDSP/EGLL/EGSS/2JK0(NEW LINE)1940/EGLL27L/10
21
+ const results = message.text.split(/\n|\//).slice(1); // Split by / and new line
22
+
23
+ if (results) {
24
+ if (options.debug) {
25
+ console.log(`Label 1M ETA: results`);
26
+ console.log(results);
27
+ }
28
+
29
+ decodeResult.raw.flight_number = results[0];
30
+ // results[1]: ETA01 (???)
31
+ // results[2]: 230822 - UTC date of eta
32
+ decodeResult.raw.departure_icao = results[3];
33
+ decodeResult.raw.arrival_icao = results[4];
34
+ decodeResult.raw.alternate_icao = results[5];
35
+ // results[6]: 2JK0 (???)
36
+ // results[7] 1940 - UTC eta
37
+ decodeResult.raw.arrival_runway = results[8].replace(decodeResult.raw.arrival_icao, ""); // results[8] EGLL27L
38
+ // results[9]: 10(space) (???)
39
+
40
+ decodeResult.formatted.items.push({
41
+ type: 'eta',
42
+ code: 'ETA',
43
+ label: 'Estimated Time of Arrival',
44
+ value: DateTimeUtils.UTCDateTimeToString(results[2], results[7]),
45
+ });
46
+
47
+ decodeResult.formatted.items.push({
48
+ type: 'destination',
49
+ code: 'DST',
50
+ label: 'Destination',
51
+ value: decodeResult.raw.arrival_icao,
52
+ });
53
+
54
+ decodeResult.formatted.items.push({
55
+ type: 'origin',
56
+ code: 'ORG',
57
+ label: 'Origin',
58
+ value: decodeResult.raw.departure_icao,
59
+ });
60
+ }
61
+
62
+ decodeResult.decoded = true;
63
+ decodeResult.decoder.decodeLevel = 'partial';
64
+
65
+ return decodeResult;
66
+ }
67
+ }
68
+
69
+ export default {};
@@ -0,0 +1,81 @@
1
+ import { DecoderPlugin } from '../DecoderPlugin';
2
+
3
+ // In Air Report
4
+ export class Label_20_CFB01 extends DecoderPlugin {
5
+ name = 'label-20-cfb01';
6
+
7
+ qualifiers() { // eslint-disable-line class-methods-use-this
8
+ return {
9
+ labels: ['20'],
10
+ preambles: ['#CFB.01'],
11
+ };
12
+ }
13
+
14
+ decode(message: any, options: any = {}) : any {
15
+ const decodeResult: any = this.defaultResult;
16
+ decodeResult.decoder.name = this.name;
17
+ decodeResult.formatted.description = 'Crew Flight Bag Message';
18
+ decodeResult.message = message;
19
+
20
+ // Style: IN02,N38338W121179,KMHR,KPDX,0806,2355,005.1
21
+ // Match: IN02,coords,departure_icao,arrival_icao,current_date,current_time,fuel_in_tons
22
+ const regex = /^IN02,(?<unsplit_coords>.*),(?<departure_icao>.*),(?<arrival_icao>.*),(?<current_date>.*),(?<current_time>.*),(?<fuel_in_tons>.*)$/;
23
+ const results = message.text.match(regex);
24
+ if (results) {
25
+ if (options.debug) {
26
+ console.log(`Label 44 ETA Report: groups`);
27
+ console.log(results.groups);
28
+ }
29
+
30
+ const coordsRegex = /(?<lac>[NS])(?<la>.+)\s*(?<lnc>[EW])(?<ln>.+)/;
31
+ const coordsResults = results.groups.unsplit_coords.match(coordsRegex);
32
+
33
+ decodeResult.raw.latitude_direction = coordsResults.groups.lac;
34
+ decodeResult.raw.latitude = Number(coordsResults.groups.la) / 1000;
35
+ decodeResult.raw.longitude_direction = coordsResults.groups.lnc;
36
+ decodeResult.raw.longitude = Number(coordsResults.groups.ln) / 1000;
37
+ decodeResult.raw.departure_icao = results.groups.departure_icao;
38
+ decodeResult.raw.arrival_icao = results.groups.arrival_icao;
39
+ decodeResult.raw.current_time = Date.parse(
40
+ new Date().getFullYear() + "-" +
41
+ results.groups.current_date.substr(0, 2) + "-" +
42
+ results.groups.current_date.substr(2, 2) + "T" +
43
+ results.groups.current_time.substr(0, 2) + ":" +
44
+ results.groups.current_time.substr(2, 2) + ":00Z"
45
+ );
46
+
47
+ if (results.groups.fuel_in_tons != '***' && results.groups.fuel_in_tons != '****') {
48
+ decodeResult.raw.fuel_in_tons = Number(results.groups.fuel_in_tons);
49
+ }
50
+
51
+ decodeResult.formatted.items.push({
52
+ type: 'aircraft_position',
53
+ code: 'POS',
54
+ label: 'Aircraft Position',
55
+ value: `${decodeResult.raw.latitude} ${decodeResult.raw.latitude_direction}, ${decodeResult.raw.longitude} ${decodeResult.raw.longitude_direction}`,
56
+ });
57
+
58
+ decodeResult.formatted.items.push({
59
+ type: 'origin',
60
+ code: 'ORG',
61
+ label: 'Origin',
62
+ value: decodeResult.raw.departure_icao,
63
+ });
64
+
65
+ decodeResult.formatted.items.push({
66
+ type: 'destination',
67
+ code: 'DST',
68
+ label: 'Destination',
69
+ value: decodeResult.raw.arrival_icao,
70
+ });
71
+
72
+ }
73
+
74
+ decodeResult.decoded = true;
75
+ decodeResult.decoder.decodeLevel = 'full';
76
+
77
+ return decodeResult;
78
+ }
79
+ }
80
+
81
+ export default {};
@@ -0,0 +1,68 @@
1
+ import { DecoderPlugin } from '../DecoderPlugin';
2
+
3
+ // Position Report
4
+ export class Label_20_POS extends DecoderPlugin {
5
+ name = 'label-20-pos';
6
+
7
+ qualifiers() { // eslint-disable-line class-methods-use-this
8
+ return {
9
+ labels: ['20'],
10
+ preambles: ['POS'],
11
+ };
12
+ }
13
+
14
+ decode(message: any, options: any = {}) : any {
15
+ const decodeResult: any = this.defaultResult;
16
+ decodeResult.decoder.name = this.name;
17
+ decodeResult.formatted.description = 'Position Report';
18
+ decodeResult.message = message;
19
+
20
+ decodeResult.raw.preamble = message.text.substring(0, 3);
21
+
22
+ const content = message.text.substring(3);
23
+ console.log('Content: ' + content);
24
+
25
+ const fields = content.split(',');
26
+ console.log('Field Count: ' + fields.length);
27
+
28
+ if (fields.length == 11) {
29
+ // N38160W077075,,211733,360,OTT,212041,,N42,19689,40,544
30
+ console.log(`DEBUG: ${this.name}: Variation 1 detected`);
31
+
32
+ // Field 1: Coordinates
33
+ const rawCoords = fields[0];
34
+ decodeResult.raw.position = this.decodeStringCoordinates(rawCoords);
35
+ decodeResult.formatted.items.push({
36
+ type: 'position',
37
+ label: 'Position',
38
+ value: this.coordinateString(decodeResult.raw.position),
39
+ });
40
+
41
+ decodeResult.decoded = true;
42
+ decodeResult.decoder.decodeLevel = 'full';
43
+ } else if (fields.length == 5) {
44
+ // N38160W077075,,211733,360,OTT
45
+ console.log(`DEBUG: ${this.name}: Variation 2 detected`);
46
+
47
+ // Field 1: Coordinates
48
+ const rawCoords = fields[0];
49
+ decodeResult.raw.position = this.decodeStringCoordinates(rawCoords);
50
+ decodeResult.formatted.items.push({
51
+ type: 'position',
52
+ label: 'Position',
53
+ value: this.coordinateString(decodeResult.raw.position),
54
+ });
55
+
56
+ decodeResult.decoded = true;
57
+ decodeResult.decoder.decodeLevel = 'full';
58
+ } else {
59
+ // Unknown!
60
+ console.log(`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${content}`);
61
+ decodeResult.decoded = false;
62
+ decodeResult.decoder.decodeLevel = 'none';
63
+ }
64
+ return decodeResult;
65
+ }
66
+ }
67
+
68
+ export default {};
@@ -0,0 +1,37 @@
1
+ import { MessageDecoder } from '../MessageDecoder';
2
+ import { Label_30_Slash_EA } from './Label_30_Slash_EA';
3
+
4
+ test('decodes Label 30 sample 1', () => {
5
+ const decoder = new MessageDecoder();
6
+ const decoderPlugin = new Label_30_Slash_EA(decoder);
7
+
8
+ expect(decoderPlugin.decode).toBeDefined();
9
+ expect(decoderPlugin.name).toBe('label-30-slash-ea');
10
+ expect(decoderPlugin.qualifiers).toBeDefined();
11
+ expect(decoderPlugin.qualifiers()).toEqual({
12
+ labels: ['30'],
13
+ preambles: ['/EA'],
14
+ });
15
+
16
+ const text = '/EA1719/DSKSFO/SK23';
17
+ const decodeResult = decoderPlugin.decode({ text: text });
18
+ console.log(JSON.stringify(decodeResult, null, 2));
19
+
20
+ expect(decodeResult.decoded).toBe(true);
21
+ expect(decodeResult.decoder.decodeLevel).toBe('partial');
22
+ expect(decodeResult.decoder.name).toBe('label-30-slash-ea');
23
+ expect(decodeResult.formatted.description).toBe('ETA Report');
24
+ expect(decodeResult.message.text).toBe(text);
25
+ expect(decodeResult.raw.arrival_icao).toBe('KSFO');
26
+ expect(decodeResult.formatted.items.length).toBe(2);
27
+ expect(decodeResult.formatted.items[0].type).toBe('eta');
28
+ expect(decodeResult.formatted.items[0].code).toBe('ETA');
29
+ expect(decodeResult.formatted.items[0].label).toBe('Estimated Time of Arrival');
30
+ // This test is a bit rough as typescript doesn't have a UTC time string
31
+ // method so the hour will be depend on the test host timezone.
32
+ expect((decodeResult.formatted.items[0].value as string).includes('19')).toBe(true);
33
+ expect(decodeResult.formatted.items[1].type).toBe('destination');
34
+ expect(decodeResult.formatted.items[1].code).toBe('DST');
35
+ expect(decodeResult.formatted.items[1].label).toBe('Destination');
36
+ expect(decodeResult.formatted.items[1].value).toBe('KSFO');
37
+ });
@@ -0,0 +1,60 @@
1
+ import { DateTimeUtils } from '../DateTimeUtils';
2
+ import { DecoderPlugin } from '../DecoderPlugin';
3
+
4
+ export class Label_30_Slash_EA extends DecoderPlugin {
5
+ name = 'label-30-slash-ea';
6
+
7
+ qualifiers() { // eslint-disable-line class-methods-use-this
8
+ return {
9
+ labels: ["30"],
10
+ preambles: ['/EA'],
11
+ };
12
+ }
13
+
14
+ decode(message: any, options: any = {}) : any {
15
+ const decodeResult: any = this.defaultResult;
16
+ decodeResult.decoder.name = this.name;
17
+ decodeResult.formatted.description = 'ETA Report';
18
+ decodeResult.message = message;
19
+
20
+ // Style: /EA1830/DSKSFO/SK24
21
+ const results = message.text.split(/\n|\//).slice(1); // Split by / and new line
22
+
23
+ if (results) {
24
+ if (options.debug) {
25
+ console.log(`Label 30 EA: results`);
26
+ console.log(results);
27
+ }
28
+ }
29
+
30
+ decodeResult.formatted.items.push({
31
+ type: 'eta',
32
+ code: 'ETA',
33
+ label: 'Estimated Time of Arrival',
34
+ value: DateTimeUtils.UTCToString(results[0].substr(2, 4)),
35
+ });
36
+
37
+ if (results[1].substr(0, 2) === "DS") {
38
+ decodeResult.raw.arrival_icao = results[1].substr(2, 4);
39
+ decodeResult.formatted.items.push({
40
+ type: 'destination',
41
+ code: 'DST',
42
+ label: 'Destination',
43
+ value: decodeResult.raw.arrival_icao,
44
+ });
45
+
46
+ // We don't know what the /SK section means. We have seen various numbers
47
+ // after the /SK.
48
+ decodeResult.remaining.text = "/".concat(results[2]);
49
+ } else {
50
+ decodeResult.remaining.text = "/".concat(results[1], "/", results[2])
51
+ }
52
+
53
+ decodeResult.decoded = true;
54
+ decodeResult.decoder.decodeLevel = 'partial';
55
+
56
+ return decodeResult;
57
+ }
58
+ }
59
+
60
+ export default {};
@@ -0,0 +1,81 @@
1
+ import { DecoderPlugin } from '../DecoderPlugin';
2
+
3
+ // In Air Report
4
+ export class Label_44_ETA extends DecoderPlugin {
5
+ name = 'label-44-eta';
6
+
7
+ qualifiers() { // eslint-disable-line class-methods-use-this
8
+ return {
9
+ labels: ['44'],
10
+ preambles: ['00ETA01', '00ETA02', '00ETA03', 'ETA01', 'ETA02', 'ETA03'],
11
+ };
12
+ }
13
+
14
+ decode(message: any, options: any = {}) : any {
15
+ const decodeResult: any = this.defaultResult;
16
+ decodeResult.decoder.name = this.name;
17
+ decodeResult.formatted.description = 'ETA Report';
18
+ decodeResult.message = message;
19
+
20
+ // Style: IN02,N38338W121179,KMHR,KPDX,0806,2355,005.1
21
+ // Match: IN02,coords,departure_icao,arrival_icao,current_date,current_time,fuel_in_tons
22
+ const regex = /^IN02,(?<unsplit_coords>.*),(?<departure_icao>.*),(?<arrival_icao>.*),(?<current_date>.*),(?<current_time>.*),(?<fuel_in_tons>.*)$/;
23
+ const results = message.text.match(regex);
24
+ if (results) {
25
+ if (options.debug) {
26
+ console.log(`Label 44 ETA Report: groups`);
27
+ console.log(results.groups);
28
+ }
29
+
30
+ const coordsRegex = /(?<lac>[NS])(?<la>.+)\s*(?<lnc>[EW])(?<ln>.+)/;
31
+ const coordsResults = results.groups.unsplit_coords.match(coordsRegex);
32
+
33
+ decodeResult.raw.latitude_direction = coordsResults.groups.lac;
34
+ decodeResult.raw.latitude = Number(coordsResults.groups.la) / 1000;
35
+ decodeResult.raw.longitude_direction = coordsResults.groups.lnc;
36
+ decodeResult.raw.longitude = Number(coordsResults.groups.ln) / 1000;
37
+ decodeResult.raw.departure_icao = results.groups.departure_icao;
38
+ decodeResult.raw.arrival_icao = results.groups.arrival_icao;
39
+ decodeResult.raw.current_time = Date.parse(
40
+ new Date().getFullYear() + "-" +
41
+ results.groups.current_date.substr(0, 2) + "-" +
42
+ results.groups.current_date.substr(2, 2) + "T" +
43
+ results.groups.current_time.substr(0, 2) + ":" +
44
+ results.groups.current_time.substr(2, 2) + ":00Z"
45
+ );
46
+
47
+ if (results.groups.fuel_in_tons != '***' && results.groups.fuel_in_tons != '****') {
48
+ decodeResult.raw.fuel_in_tons = Number(results.groups.fuel_in_tons);
49
+ }
50
+
51
+ decodeResult.formatted.items.push({
52
+ type: 'aircraft_position',
53
+ code: 'POS',
54
+ label: 'Aircraft Position',
55
+ value: `${decodeResult.raw.latitude} ${decodeResult.raw.latitude_direction}, ${decodeResult.raw.longitude} ${decodeResult.raw.longitude_direction}`,
56
+ });
57
+
58
+ decodeResult.formatted.items.push({
59
+ type: 'origin',
60
+ code: 'ORG',
61
+ label: 'Origin',
62
+ value: decodeResult.raw.departure_icao,
63
+ });
64
+
65
+ decodeResult.formatted.items.push({
66
+ type: 'destination',
67
+ code: 'DST',
68
+ label: 'Destination',
69
+ value: decodeResult.raw.arrival_icao,
70
+ });
71
+
72
+ }
73
+
74
+ decodeResult.decoded = true;
75
+ decodeResult.decoder.decodeLevel = 'full';
76
+
77
+ return decodeResult;
78
+ }
79
+ }
80
+
81
+ export default {};
@@ -0,0 +1,81 @@
1
+ import { DecoderPlugin } from '../DecoderPlugin';
2
+
3
+ // In Air Report
4
+ export class Label_44_IN extends DecoderPlugin {
5
+ name = 'label-44-in';
6
+
7
+ qualifiers() { // eslint-disable-line class-methods-use-this
8
+ return {
9
+ labels: ['44'],
10
+ preambles: ['00IN01', '00IN02', '00IN03', 'IN01', 'IN02', 'IN03'],
11
+ };
12
+ }
13
+
14
+ decode(message: any, options: any = {}) : any {
15
+ const decodeResult: any = this.defaultResult;
16
+ decodeResult.decoder.name = this.name;
17
+ decodeResult.formatted.description = 'In Air Report';
18
+ decodeResult.message = message;
19
+
20
+ // Style: IN02,N38338W121179,KMHR,KPDX,0806,2355,005.1
21
+ // Match: IN02,coords,departure_icao,arrival_icao,current_date,current_time,fuel_in_tons
22
+ const regex = /^IN02,(?<unsplit_coords>.*),(?<departure_icao>.*),(?<arrival_icao>.*),(?<current_date>.*),(?<current_time>.*),(?<fuel_in_tons>.*)$/;
23
+ const results = message.text.match(regex);
24
+ if (results) {
25
+ if (options.debug) {
26
+ console.log(`Label 44 In Air Report: groups`);
27
+ console.log(results.groups);
28
+ }
29
+
30
+ const coordsRegex = /(?<lac>[NS])(?<la>.+)\s*(?<lnc>[EW])(?<ln>.+)/;
31
+ const coordsResults = results.groups.unsplit_coords.match(coordsRegex);
32
+
33
+ decodeResult.raw.latitude_direction = coordsResults.groups.lac;
34
+ decodeResult.raw.latitude = Number(coordsResults.groups.la) / 1000;
35
+ decodeResult.raw.longitude_direction = coordsResults.groups.lnc;
36
+ decodeResult.raw.longitude = Number(coordsResults.groups.ln) / 1000;
37
+ decodeResult.raw.departure_icao = results.groups.departure_icao;
38
+ decodeResult.raw.arrival_icao = results.groups.arrival_icao;
39
+ decodeResult.raw.current_time = Date.parse(
40
+ new Date().getFullYear() + "-" +
41
+ results.groups.current_date.substr(0, 2) + "-" +
42
+ results.groups.current_date.substr(2, 2) + "T" +
43
+ results.groups.current_time.substr(0, 2) + ":" +
44
+ results.groups.current_time.substr(2, 2) + ":00Z"
45
+ );
46
+
47
+ if (results.groups.fuel_in_tons != '***' && results.groups.fuel_in_tons != '****') {
48
+ decodeResult.raw.fuel_in_tons = Number(results.groups.fuel_in_tons);
49
+ }
50
+
51
+ decodeResult.formatted.items.push({
52
+ type: 'aircraft_position',
53
+ code: 'POS',
54
+ label: 'Aircraft Position',
55
+ value: `${decodeResult.raw.latitude} ${decodeResult.raw.latitude_direction}, ${decodeResult.raw.longitude} ${decodeResult.raw.longitude_direction}`,
56
+ });
57
+
58
+ decodeResult.formatted.items.push({
59
+ type: 'origin',
60
+ code: 'ORG',
61
+ label: 'Origin',
62
+ value: decodeResult.raw.departure_icao,
63
+ });
64
+
65
+ decodeResult.formatted.items.push({
66
+ type: 'destination',
67
+ code: 'DST',
68
+ label: 'Destination',
69
+ value: decodeResult.raw.arrival_icao,
70
+ });
71
+
72
+ }
73
+
74
+ decodeResult.decoded = true;
75
+ decodeResult.decoder.decodeLevel = 'full';
76
+
77
+ return decodeResult;
78
+ }
79
+ }
80
+
81
+ export default {};
@@ -0,0 +1,88 @@
1
+ import { DecoderPlugin } from '../DecoderPlugin';
2
+
3
+ // Off Runway Report
4
+ export class Label_44_OFF extends DecoderPlugin {
5
+ name = 'label-44-off';
6
+
7
+ qualifiers() { // eslint-disable-line class-methods-use-this
8
+ return {
9
+ labels: ['44'],
10
+ preambles: ['00OFF01', '00OFF02', '00OFF03', 'OFF01', 'OFF02', 'OFF03'],
11
+ };
12
+ }
13
+
14
+ decode(message: any, options: any = {}) : any {
15
+ const decodeResult: any = this.defaultResult;
16
+ decodeResult.decoder.name = this.name;
17
+ decodeResult.formatted.description = 'Off Runway Report';
18
+ decodeResult.message = message;
19
+
20
+ // Style: OFF02,N38334W121176,KMHR,KPDX,0807,0014,0123,004.9
21
+ // Match: OFF02,coords,departure_icao,arrival_icao,current_date,current_time,eta_time,fuel_in_tons
22
+ const regex = /^ON02,(?<unsplit_coords>.*),(?<departure_icao>.*),(?<arrival_icao>.*),(?<current_date>.*),(?<current_time>.*),(?<eta_time>.*),(?<fuel_in_tons>.*)$/;
23
+ const results = message.text.match(regex);
24
+ if (results) {
25
+ if (options.debug) {
26
+ console.log(`Label 44 Off Runway Report: groups`);
27
+ console.log(results.groups);
28
+ }
29
+
30
+ const coordsRegex = /(?<lac>[NS])(?<la>.+)\s*(?<lnc>[EW])(?<ln>.+)/;
31
+ const coordsResults = results.groups.unsplit_coords.match(coordsRegex);
32
+
33
+ decodeResult.raw.latitude_direction = coordsResults.groups.lac;
34
+ decodeResult.raw.latitude = Number(coordsResults.groups.la) / 1000;
35
+ decodeResult.raw.longitude_direction = coordsResults.groups.lnc;
36
+ decodeResult.raw.longitude = Number(coordsResults.groups.ln) / 1000;
37
+ decodeResult.raw.departure_icao = results.groups.departure_icao;
38
+ decodeResult.raw.arrival_icao = results.groups.arrival_icao;
39
+ decodeResult.raw.current_time = Date.parse(
40
+ new Date().getFullYear() + "-" +
41
+ results.groups.current_date.substr(0, 2) + "-" +
42
+ results.groups.current_date.substr(2, 2) + "T" +
43
+ results.groups.current_time.substr(0, 2) + ":" +
44
+ results.groups.current_time.substr(2, 2) + ":00Z"
45
+ );
46
+ decodeResult.raw.eta_time = Date.parse(
47
+ new Date().getFullYear() + "-" +
48
+ results.groups.current_date.substr(0, 2) + "-" +
49
+ results.groups.current_date.substr(2, 2) + "T" +
50
+ results.groups.eta_time.substr(0, 2) + ":" +
51
+ results.groups.eta_time.substr(2, 2) + ":00Z"
52
+ );
53
+
54
+ if (results.groups.fuel_in_tons != '***' && results.groups.fuel_in_tons != '****') {
55
+ decodeResult.raw.fuel_in_tons = Number(results.groups.fuel_in_tons);
56
+ }
57
+
58
+ decodeResult.formatted.items.push({
59
+ type: 'aircraft_position',
60
+ code: 'POS',
61
+ label: 'Aircraft Position',
62
+ value: `${decodeResult.raw.latitude} ${decodeResult.raw.latitude_direction}, ${decodeResult.raw.longitude} ${decodeResult.raw.longitude_direction}`,
63
+ });
64
+
65
+ decodeResult.formatted.items.push({
66
+ type: 'origin',
67
+ code: 'ORG',
68
+ label: 'Origin',
69
+ value: decodeResult.raw.departure_icao,
70
+ });
71
+
72
+ decodeResult.formatted.items.push({
73
+ type: 'destination',
74
+ code: 'DST',
75
+ label: 'Destination',
76
+ value: decodeResult.raw.arrival_icao,
77
+ });
78
+
79
+ }
80
+
81
+ decodeResult.decoded = true;
82
+ decodeResult.decoder.decodeLevel = 'full';
83
+
84
+ return decodeResult;
85
+ }
86
+ }
87
+
88
+ export default {};