@airframes/acars-decoder 1.2.1 → 1.3.2
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/README.md +6 -0
- package/babel.config.js +6 -0
- package/coverage/clover.xml +1722 -0
- package/coverage/coverage-final.json +23 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +131 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +196 -0
- package/coverage/lcov.info +2177 -0
- package/dist/DecoderPlugin.d.ts +16 -0
- package/dist/DecoderPlugin.js +66 -0
- package/dist/DecoderPluginInterface.d.ts +7 -0
- package/dist/DecoderPluginInterface.js +3 -0
- package/dist/IcaoDecoder.d.ts +8 -0
- package/dist/IcaoDecoder.js +106 -0
- package/dist/MessageDecoder.d.ts +12 -0
- package/dist/MessageDecoder.js +97 -0
- package/dist/bin/acars-decoder-test.d.ts +2 -0
- package/dist/bin/acars-decoder-test.js +38 -0
- package/dist/bin/acars-decoder.d.ts +2 -0
- package/dist/bin/acars-decoder.js +20 -0
- package/dist/plugins/Label_15.d.ts +11 -0
- package/dist/plugins/Label_15.js +42 -0
- package/dist/plugins/Label_20_CFB.01.d.ts +11 -0
- package/dist/plugins/Label_20_CFB.01.js +71 -0
- package/dist/plugins/Label_20_POS.d.ts +11 -0
- package/dist/plugins/Label_20_POS.js +64 -0
- package/dist/plugins/Label_44_ETA.d.ts +11 -0
- package/dist/plugins/Label_44_ETA.js +71 -0
- package/dist/plugins/Label_44_IN.d.ts +11 -0
- package/dist/plugins/Label_44_IN.js +71 -0
- package/dist/plugins/Label_44_OFF.d.ts +11 -0
- package/dist/plugins/Label_44_OFF.js +76 -0
- package/dist/plugins/Label_44_ON.d.ts +11 -0
- package/dist/plugins/Label_44_ON.js +71 -0
- package/dist/plugins/Label_44_POS.d.ts +11 -0
- package/dist/plugins/Label_44_POS.js +83 -0
- package/dist/plugins/Label_5Z.d.ts +11 -0
- package/dist/plugins/Label_5Z.js +122 -0
- package/dist/plugins/Label_80.d.ts +12 -0
- package/dist/plugins/Label_80.js +205 -0
- package/dist/plugins/Label_8E.d.ts +10 -0
- package/dist/plugins/Label_8E.js +57 -0
- package/dist/plugins/Label_B6.d.ts +11 -0
- package/dist/plugins/Label_B6.js +28 -0
- package/dist/plugins/Label_ColonComma.d.ts +10 -0
- package/dist/plugins/Label_ColonComma.js +30 -0
- package/dist/plugins/Label_H1.d.ts +9 -0
- package/dist/plugins/Label_H1.js +17 -0
- package/dist/plugins/Label_H1_M1BPOS.d.ts +11 -0
- package/dist/plugins/Label_H1_M1BPOS.js +56 -0
- package/dist/plugins/Label_H1_M1BPRG.d.ts +11 -0
- package/dist/plugins/Label_H1_M1BPRG.js +38 -0
- package/dist/plugins/Label_QP.d.ts +10 -0
- package/dist/plugins/Label_QP.js +51 -0
- package/dist/plugins/Label_QQ.d.ts +10 -0
- package/dist/plugins/Label_QQ.js +51 -0
- package/dist/plugins/Label_QR.d.ts +10 -0
- package/dist/plugins/Label_QR.js +51 -0
- package/dist/plugins/Label_QS.d.ts +10 -0
- package/dist/plugins/Label_QS.js +51 -0
- package/dist/plugins/Label_SQ.d.ts +10 -0
- package/dist/plugins/Label_SQ.js +106 -0
- package/dist/plugins/official.d.ts +19 -0
- package/dist/plugins/official.js +24 -0
- package/jest.config.ts +195 -0
- package/package.json +12 -4
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const DecoderPlugin_1 = require("../DecoderPlugin");
|
|
4
|
+
// Airline Defined
|
|
5
|
+
// 3N01 POSRPT
|
|
6
|
+
class Label_80 extends DecoderPlugin_1.DecoderPlugin {
|
|
7
|
+
constructor() {
|
|
8
|
+
super(...arguments);
|
|
9
|
+
this.name = 'label-80';
|
|
10
|
+
this.descriptions = {
|
|
11
|
+
ALT: 'Altitude',
|
|
12
|
+
DWND: 'Wind Direction',
|
|
13
|
+
ETA: 'Estimated Time of Arrival',
|
|
14
|
+
FOB: 'Fuel on Board',
|
|
15
|
+
FL: 'Flight Level',
|
|
16
|
+
HDG: 'Heading',
|
|
17
|
+
MCH: 'Aircraft Speed',
|
|
18
|
+
NWYP: 'Next Waypoint',
|
|
19
|
+
POS: 'Aircraft Position',
|
|
20
|
+
SAT: 'Static Air Temperature',
|
|
21
|
+
SWND: 'Window Speed',
|
|
22
|
+
TAS: 'True Airspeed',
|
|
23
|
+
WYP: 'Waypoint',
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
qualifiers() {
|
|
27
|
+
return {
|
|
28
|
+
labels: ['80'],
|
|
29
|
+
preambles: ['3N01 POSRPT'],
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
decode(message, options = {}) {
|
|
33
|
+
const decodeResult = this.defaultResult;
|
|
34
|
+
decodeResult.decoder.name = this.name;
|
|
35
|
+
decodeResult.formatted.description = 'Airline Defined Position Report';
|
|
36
|
+
const parts = message.text.split('\n');
|
|
37
|
+
let posRptRegex = /^3N01 POSRPT \d\d\d\d\/\d\d (?<orig>\w+)\/(?<dest>\w+) \.(?<tail>[\w-]+)(\/(?<agate>.+) (?<sta>\w+:\w+))*/; // eslint-disable-line max-len
|
|
38
|
+
let results = parts[0].match(posRptRegex);
|
|
39
|
+
if (results && results.length > 0) {
|
|
40
|
+
decodeResult.raw.origin = results.groups.orig;
|
|
41
|
+
decodeResult.formatted.items.push({
|
|
42
|
+
type: 'origin',
|
|
43
|
+
code: 'ORG',
|
|
44
|
+
label: 'Origin',
|
|
45
|
+
value: `${results.groups.orig}`,
|
|
46
|
+
});
|
|
47
|
+
decodeResult.raw.destination = results.groups.dest;
|
|
48
|
+
decodeResult.formatted.items.push({
|
|
49
|
+
type: 'destination',
|
|
50
|
+
code: 'DST',
|
|
51
|
+
label: 'Destination',
|
|
52
|
+
value: `${results.groups.dest}`,
|
|
53
|
+
});
|
|
54
|
+
decodeResult.raw.tail = results.groups.tail;
|
|
55
|
+
decodeResult.formatted.items.push({
|
|
56
|
+
type: 'tail',
|
|
57
|
+
label: 'Tail',
|
|
58
|
+
value: `${results.groups.tail}`,
|
|
59
|
+
});
|
|
60
|
+
if (results.groups.agate) {
|
|
61
|
+
decodeResult.raw.arrival_gate = results.groups.agate;
|
|
62
|
+
decodeResult.formatted.items.push({
|
|
63
|
+
type: 'arrival_gate',
|
|
64
|
+
code: 'ARG',
|
|
65
|
+
label: 'Arrival Gate',
|
|
66
|
+
value: `${results.groups.agate}`,
|
|
67
|
+
});
|
|
68
|
+
decodeResult.raw.scheduled_time_of_arrival = results.groups.sta;
|
|
69
|
+
decodeResult.formatted.items.push({
|
|
70
|
+
type: 'scheduled_time_of_arrival',
|
|
71
|
+
code: 'STA',
|
|
72
|
+
label: 'Scheduled Time of Arrival',
|
|
73
|
+
value: `${results.groups.sta}`,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
posRptRegex = /\/(?<field>\w+)\s(?<value>[\w\+\-:\.]+)\s*/gi; // eslint-disable-line no-useless-escape
|
|
77
|
+
// console.log('Regex:', posRptRegex);
|
|
78
|
+
const remainingParts = parts.slice(1);
|
|
79
|
+
// console.log("Remaining Parts:", remainingParts);
|
|
80
|
+
for (const part of remainingParts) { // eslint-disable-line no-restricted-syntax
|
|
81
|
+
// console.log('Part:', part);
|
|
82
|
+
const matches = part.matchAll(posRptRegex);
|
|
83
|
+
// console.log('Matches:', matches);
|
|
84
|
+
for (const match of matches) { // eslint-disable-line no-restricted-syntax
|
|
85
|
+
// console.log('Match:', match);
|
|
86
|
+
switch (match.groups.field) {
|
|
87
|
+
case 'ALT': {
|
|
88
|
+
decodeResult.raw.altitude = match.groups.value;
|
|
89
|
+
decodeResult.formatted.items.push({
|
|
90
|
+
type: 'altitude',
|
|
91
|
+
code: 'ALT',
|
|
92
|
+
label: this.descriptions[match.groups.field],
|
|
93
|
+
value: `${decodeResult.raw.altitude} feet`,
|
|
94
|
+
});
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
case 'DWND': {
|
|
98
|
+
decodeResult.raw.wind_direction = Number(match.groups.value);
|
|
99
|
+
decodeResult.formatted.items.push({
|
|
100
|
+
type: 'wind_direction',
|
|
101
|
+
code: 'DWND',
|
|
102
|
+
label: this.descriptions[match.groups.field],
|
|
103
|
+
value: decodeResult.raw.wind_direction,
|
|
104
|
+
});
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
case 'FL': {
|
|
108
|
+
decodeResult.raw.flight_level = match.groups.value;
|
|
109
|
+
decodeResult.formatted.items.push({
|
|
110
|
+
type: 'flight_level',
|
|
111
|
+
code: 'FL',
|
|
112
|
+
label: this.descriptions[match.groups.field],
|
|
113
|
+
value: decodeResult.raw.flight_level,
|
|
114
|
+
});
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
case 'FOB': {
|
|
118
|
+
decodeResult.raw.fuel_on_board = match.groups.value;
|
|
119
|
+
decodeResult.formatted.items.push({
|
|
120
|
+
type: 'fuel_on_board',
|
|
121
|
+
code: 'FOB',
|
|
122
|
+
label: this.descriptions[match.groups.field],
|
|
123
|
+
value: decodeResult.raw.fuel_on_board,
|
|
124
|
+
});
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
case 'HDG': {
|
|
128
|
+
decodeResult.raw.heading = Number(match.groups.value);
|
|
129
|
+
decodeResult.formatted.items.push({
|
|
130
|
+
type: 'heading',
|
|
131
|
+
code: 'HDG',
|
|
132
|
+
label: this.descriptions[match.groups.field],
|
|
133
|
+
value: decodeResult.raw.heading,
|
|
134
|
+
});
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
case 'MCH': {
|
|
138
|
+
decodeResult.raw.mach = match.groups.value / 1000;
|
|
139
|
+
decodeResult.formatted.items.push({
|
|
140
|
+
type: 'mach',
|
|
141
|
+
code: 'MCH',
|
|
142
|
+
label: this.descriptions[match.groups.field],
|
|
143
|
+
value: `${decodeResult.raw.mach} Mach`,
|
|
144
|
+
});
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
case 'NWYP': {
|
|
148
|
+
decodeResult.raw.next_waypoint = match.groups.value;
|
|
149
|
+
decodeResult.formatted.items.push({
|
|
150
|
+
type: 'next_waypoint',
|
|
151
|
+
code: 'NWYP',
|
|
152
|
+
label: this.descriptions[match.groups.field],
|
|
153
|
+
value: decodeResult.raw.next_waypoint,
|
|
154
|
+
});
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
case 'POS': {
|
|
158
|
+
const posRegex = /^(?<latd>[NS])(?<lat>.+)(?<lngd>[EW])(?<lng>.+)/;
|
|
159
|
+
const posResult = match.groups.value.match(posRegex);
|
|
160
|
+
const latitude = (Number(posResult.groups.lat) / 100) * (posResult.groups.lngd === 'S' ? -1 : 1);
|
|
161
|
+
const longitude = (Number(posResult.groups.lng) / 100) * (posResult.groups.lngd === 'W' ? -1 : 1);
|
|
162
|
+
decodeResult.raw.aircraft_position = {
|
|
163
|
+
latitude,
|
|
164
|
+
longitude,
|
|
165
|
+
};
|
|
166
|
+
decodeResult.formatted.items.push({
|
|
167
|
+
type: 'aircraft_position',
|
|
168
|
+
code: 'POS',
|
|
169
|
+
label: this.descriptions[match.groups.field],
|
|
170
|
+
value: `${(Number(posResult.groups.lat) / 100).toPrecision(5)} ${posResult.groups.latd}, ${(Number(posResult.groups.lng) / 100).toPrecision(5)} ${posResult.groups.lngd}`,
|
|
171
|
+
});
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
case 'SWND': {
|
|
175
|
+
decodeResult.raw.wind_speed = Number(match.groups.value);
|
|
176
|
+
decodeResult.formatted.items.push({
|
|
177
|
+
type: 'wind_speed',
|
|
178
|
+
code: 'SWND',
|
|
179
|
+
label: this.descriptions[match.groups.field],
|
|
180
|
+
value: decodeResult.raw.wind_speed,
|
|
181
|
+
});
|
|
182
|
+
break;
|
|
183
|
+
}
|
|
184
|
+
default: {
|
|
185
|
+
if (match.groups.field != undefined) {
|
|
186
|
+
const description = this.descriptions[match.groups.field] ? this.descriptions[match.groups.field] : 'Unknown';
|
|
187
|
+
decodeResult.formatted.items.push({
|
|
188
|
+
type: match.groups.field,
|
|
189
|
+
code: match.groups.field,
|
|
190
|
+
label: description || `Unknown (${match.groups.field})`,
|
|
191
|
+
value: `${match.groups.value}`,
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
decodeResult.decoded = true;
|
|
199
|
+
decodeResult.decodeLevel = 'partial';
|
|
200
|
+
}
|
|
201
|
+
return decodeResult;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
exports.Label_80 = Label_80;
|
|
205
|
+
exports.default = {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { DecoderPlugin } from '../DecoderPlugin';
|
|
2
|
+
export declare class Label_8E extends DecoderPlugin {
|
|
3
|
+
name: string;
|
|
4
|
+
qualifiers(): {
|
|
5
|
+
labels: string[];
|
|
6
|
+
};
|
|
7
|
+
decode(message: any, options?: any): any;
|
|
8
|
+
}
|
|
9
|
+
declare const _default: {};
|
|
10
|
+
export default _default;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const DecoderPlugin_1 = require("../DecoderPlugin");
|
|
4
|
+
// ETA
|
|
5
|
+
class Label_8E extends DecoderPlugin_1.DecoderPlugin {
|
|
6
|
+
constructor() {
|
|
7
|
+
super(...arguments);
|
|
8
|
+
this.name = 'label-8E';
|
|
9
|
+
}
|
|
10
|
+
qualifiers() {
|
|
11
|
+
return {
|
|
12
|
+
labels: ["8E"],
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
decode(message, options = {}) {
|
|
16
|
+
const decodeResult = this.defaultResult;
|
|
17
|
+
decodeResult.decoder.name = this.name;
|
|
18
|
+
decodeResult.formatted.description = 'ETA Report';
|
|
19
|
+
decodeResult.message = message;
|
|
20
|
+
// Style: EGSS,1618
|
|
21
|
+
// Match: arrival_icao,arrival_eta
|
|
22
|
+
const regex = /^(?<arrival_icao>\w{4}),(?<arrival_eta>\d{4})$/;
|
|
23
|
+
const results = message.text.match(regex);
|
|
24
|
+
if (results) {
|
|
25
|
+
if (options.debug) {
|
|
26
|
+
console.log(`Label 8E ETA: groups`);
|
|
27
|
+
console.log(results.groups);
|
|
28
|
+
}
|
|
29
|
+
decodeResult.raw.arrival_eta = new Date();
|
|
30
|
+
decodeResult.raw.arrival_eta.setUTCHours(results.groups.arrival_eta.substr(0, 2), results.groups.arrival_eta.substr(2, 2));
|
|
31
|
+
if (new Date().getUTCHours() > decodeResult.raw.arrival_eta.getUTCHours()) { // Check if ETA is in the past, which would imply it is for the next day
|
|
32
|
+
if (options.debug) {
|
|
33
|
+
console.log("Label 8E: Moving ETA to subsequent day");
|
|
34
|
+
}
|
|
35
|
+
decodeResult.raw.arrival_eta.setDate(decodeResult.raw.arrival_eta.getDate() + 1);
|
|
36
|
+
}
|
|
37
|
+
decodeResult.formatted.items.push({
|
|
38
|
+
type: 'eta',
|
|
39
|
+
code: 'ETA',
|
|
40
|
+
label: 'Estimated Time of Arrival',
|
|
41
|
+
value: decodeResult.raw.arrival_eta.toGMTString(),
|
|
42
|
+
});
|
|
43
|
+
decodeResult.raw.arrival_icao = results.groups.arrival_icao;
|
|
44
|
+
decodeResult.formatted.items.push({
|
|
45
|
+
type: 'destination',
|
|
46
|
+
code: 'DST',
|
|
47
|
+
label: 'Destination',
|
|
48
|
+
value: decodeResult.raw.arrival_icao,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
decodeResult.decoded = true;
|
|
52
|
+
decodeResult.decoder.decodeLevel = 'full';
|
|
53
|
+
return decodeResult;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
exports.Label_8E = Label_8E;
|
|
57
|
+
exports.default = {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { DecoderPlugin } from '../DecoderPlugin';
|
|
2
|
+
export declare class Label_B6_Forwardslash extends DecoderPlugin {
|
|
3
|
+
name: string;
|
|
4
|
+
qualifiers(): {
|
|
5
|
+
labels: string[];
|
|
6
|
+
preambles: string[];
|
|
7
|
+
};
|
|
8
|
+
decode(message: any, options?: any): any;
|
|
9
|
+
}
|
|
10
|
+
declare const _default: {};
|
|
11
|
+
export default _default;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const DecoderPlugin_1 = require("../DecoderPlugin");
|
|
4
|
+
// CPDLC
|
|
5
|
+
class Label_B6_Forwardslash extends DecoderPlugin_1.DecoderPlugin {
|
|
6
|
+
constructor() {
|
|
7
|
+
super(...arguments);
|
|
8
|
+
this.name = 'label-b6-forwardslash';
|
|
9
|
+
}
|
|
10
|
+
qualifiers() {
|
|
11
|
+
return {
|
|
12
|
+
labels: ['B6'],
|
|
13
|
+
preambles: ['/'],
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
decode(message, options = {}) {
|
|
17
|
+
const decodeResult = this.defaultResult;
|
|
18
|
+
decodeResult.decoder.name = this.name;
|
|
19
|
+
decodeResult.formatted.description = 'CPDLC Message';
|
|
20
|
+
decodeResult.message = message;
|
|
21
|
+
if (options.debug) {
|
|
22
|
+
console.log("CPDLC: " + message);
|
|
23
|
+
}
|
|
24
|
+
return decodeResult;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.Label_B6_Forwardslash = Label_B6_Forwardslash;
|
|
28
|
+
exports.default = {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { DecoderPlugin } from '../DecoderPlugin';
|
|
2
|
+
export declare class Label_ColonComma extends DecoderPlugin {
|
|
3
|
+
name: string;
|
|
4
|
+
qualifiers(): {
|
|
5
|
+
labels: string[];
|
|
6
|
+
};
|
|
7
|
+
decode(message: any, options?: any): any;
|
|
8
|
+
}
|
|
9
|
+
declare const _default: {};
|
|
10
|
+
export default _default;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const DecoderPlugin_1 = require("../DecoderPlugin");
|
|
4
|
+
class Label_ColonComma extends DecoderPlugin_1.DecoderPlugin {
|
|
5
|
+
constructor() {
|
|
6
|
+
super(...arguments);
|
|
7
|
+
this.name = 'label-colon-comma';
|
|
8
|
+
}
|
|
9
|
+
qualifiers() {
|
|
10
|
+
return {
|
|
11
|
+
labels: [':;'],
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
decode(message, options = {}) {
|
|
15
|
+
const decodeResult = this.defaultResult;
|
|
16
|
+
decodeResult.decoder.name = this.name;
|
|
17
|
+
decodeResult.raw.frequency = Number(message.text) / 1000;
|
|
18
|
+
decodeResult.formatted.description = 'Aircraft Transceiver Frequency Change';
|
|
19
|
+
decodeResult.formatted.items.push({
|
|
20
|
+
type: 'frequency',
|
|
21
|
+
label: 'Frequency',
|
|
22
|
+
value: `${decodeResult.raw.frequency} MHz`,
|
|
23
|
+
});
|
|
24
|
+
decodeResult.decoded = true;
|
|
25
|
+
decodeResult.decoder.decodeLevel = 'full';
|
|
26
|
+
return decodeResult;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.Label_ColonComma = Label_ColonComma;
|
|
30
|
+
exports.default = {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const DecoderPlugin_1 = require("../DecoderPlugin");
|
|
4
|
+
class Label_H1 extends DecoderPlugin_1.DecoderPlugin {
|
|
5
|
+
qualifiers() {
|
|
6
|
+
return {
|
|
7
|
+
labels: ['H1'],
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
decode(message, options = {}) {
|
|
11
|
+
const decodeResult = this.defaultResult;
|
|
12
|
+
// console.log('DECODER: H1 detected');
|
|
13
|
+
return decodeResult;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.Label_H1 = Label_H1;
|
|
17
|
+
exports.default = {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { DecoderPlugin } from '../DecoderPlugin';
|
|
2
|
+
export declare class Label_H1_M1BPOS extends DecoderPlugin {
|
|
3
|
+
name: string;
|
|
4
|
+
qualifiers(): {
|
|
5
|
+
labels: string[];
|
|
6
|
+
preambles: string[];
|
|
7
|
+
};
|
|
8
|
+
decode(message: any, options?: any): any;
|
|
9
|
+
}
|
|
10
|
+
declare const _default: {};
|
|
11
|
+
export default _default;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const DecoderPlugin_1 = require("../DecoderPlugin");
|
|
4
|
+
class Label_H1_M1BPOS extends DecoderPlugin_1.DecoderPlugin {
|
|
5
|
+
constructor() {
|
|
6
|
+
super(...arguments);
|
|
7
|
+
this.name = 'label-h1-m1bpos';
|
|
8
|
+
}
|
|
9
|
+
qualifiers() {
|
|
10
|
+
return {
|
|
11
|
+
labels: ['H1'],
|
|
12
|
+
preambles: ['#M1BPOS'],
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
decode(message, options = {}) {
|
|
16
|
+
const decodeResult = this.defaultResult;
|
|
17
|
+
decodeResult.decoder.name = this.name;
|
|
18
|
+
if (options.debug) {
|
|
19
|
+
console.log('DECODER: #M1BPOS detected');
|
|
20
|
+
}
|
|
21
|
+
const parts = message.text.replace('#M1BPOS', '').split('/');
|
|
22
|
+
const firstHalf = parts[0];
|
|
23
|
+
const secondHalf = parts[1];
|
|
24
|
+
const items = firstHalf.split(',');
|
|
25
|
+
const coordsRegex = /(?<lac>[NS])(?<la>.+)\s*(?<lnc>[EW])(?<ln>.+)/;
|
|
26
|
+
const results = items[0].match(coordsRegex);
|
|
27
|
+
if (results && results.length >= 4) {
|
|
28
|
+
decodeResult.raw.position = {
|
|
29
|
+
latitudeDirection: results.groups.lac,
|
|
30
|
+
latitude: (results.groups.la / 1000) * (results.groups.lac === 'S' ? -1 : 1),
|
|
31
|
+
longitudeDirection: results.groups.lnc,
|
|
32
|
+
longitude: (results.groups.ln / 1000) * (results.groups.lnc === 'W' ? -1 : 1),
|
|
33
|
+
};
|
|
34
|
+
let route = items.slice(1).filter((part) => !/^\d(.+)$/.test(part));
|
|
35
|
+
route = route.map((hop) => hop || '?');
|
|
36
|
+
decodeResult.raw.route = route;
|
|
37
|
+
decodeResult.formatted.description = 'Position Report';
|
|
38
|
+
decodeResult.formatted.items = {
|
|
39
|
+
coordinates: {
|
|
40
|
+
label: 'Position',
|
|
41
|
+
value: this.coordinateString(decodeResult.raw.position),
|
|
42
|
+
},
|
|
43
|
+
route: {
|
|
44
|
+
label: 'Route',
|
|
45
|
+
value: `${route.join(' > ')}`,
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
decodeResult.decoded = true;
|
|
49
|
+
decodeResult.decodeLevel = 'partial';
|
|
50
|
+
}
|
|
51
|
+
decodeResult.remaining.text = secondHalf;
|
|
52
|
+
return decodeResult;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
exports.Label_H1_M1BPOS = Label_H1_M1BPOS;
|
|
56
|
+
exports.default = {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { DecoderPlugin } from '../DecoderPlugin';
|
|
2
|
+
export declare class Label_H1_M1BPRG extends DecoderPlugin {
|
|
3
|
+
name: string;
|
|
4
|
+
qualifiers(): {
|
|
5
|
+
labels: string[];
|
|
6
|
+
preambles: string[];
|
|
7
|
+
};
|
|
8
|
+
decode(message: any, options?: any): any;
|
|
9
|
+
}
|
|
10
|
+
declare const _default: {};
|
|
11
|
+
export default _default;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const DecoderPlugin_1 = require("../DecoderPlugin");
|
|
4
|
+
class Label_H1_M1BPRG extends DecoderPlugin_1.DecoderPlugin {
|
|
5
|
+
constructor() {
|
|
6
|
+
super(...arguments);
|
|
7
|
+
this.name = 'label-h1-m1bprg';
|
|
8
|
+
}
|
|
9
|
+
qualifiers() {
|
|
10
|
+
return {
|
|
11
|
+
labels: ['H1'],
|
|
12
|
+
preambles: ['#M1BPRG'],
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
decode(message, options = {}) {
|
|
16
|
+
const decodeResult = this.defaultResult;
|
|
17
|
+
decodeResult.decoder.name = this.name;
|
|
18
|
+
// console.log('DECODER: H1 #M1BPRG detected');
|
|
19
|
+
const parts = message.text.split('/');
|
|
20
|
+
for (const part of parts) { // eslint-disable-line no-restricted-syntax
|
|
21
|
+
if (part.includes('#M')) {
|
|
22
|
+
const regex = /#M(?<fms>\w+)PRG/;
|
|
23
|
+
}
|
|
24
|
+
if (part.includes('DT')) {
|
|
25
|
+
const regex = /DT(?<dest>\w+),(?<rway>.+),(?<fuel>.+),(?<eta>.+),(?<rem>.+)/;
|
|
26
|
+
const result = message.text.match(regex);
|
|
27
|
+
// console.log('DT result');
|
|
28
|
+
// console.log(result);
|
|
29
|
+
}
|
|
30
|
+
if (part.includes('FN')) {
|
|
31
|
+
const regex = /FN(?<flight>\w+)/;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return decodeResult;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
exports.Label_H1_M1BPRG = Label_H1_M1BPRG;
|
|
38
|
+
exports.default = {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { DecoderPlugin } from '../DecoderPlugin';
|
|
2
|
+
export declare class Label_QP extends DecoderPlugin {
|
|
3
|
+
name: string;
|
|
4
|
+
qualifiers(): {
|
|
5
|
+
labels: string[];
|
|
6
|
+
};
|
|
7
|
+
decode(message: any, options?: any): any;
|
|
8
|
+
}
|
|
9
|
+
declare const _default: {};
|
|
10
|
+
export default _default;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const DecoderPlugin_1 = require("../DecoderPlugin");
|
|
4
|
+
class Label_QP extends DecoderPlugin_1.DecoderPlugin {
|
|
5
|
+
constructor() {
|
|
6
|
+
super(...arguments);
|
|
7
|
+
this.name = 'label-qp';
|
|
8
|
+
}
|
|
9
|
+
qualifiers() {
|
|
10
|
+
return {
|
|
11
|
+
labels: ['QP'],
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
decode(message, options = {}) {
|
|
15
|
+
const decodeResult = this.defaultResult;
|
|
16
|
+
decodeResult.decoder.name = this.name;
|
|
17
|
+
decodeResult.raw.origin = message.text.substring(0, 4);
|
|
18
|
+
decodeResult.raw.destination = message.text.substring(4, 8);
|
|
19
|
+
decodeResult.raw.gate_out = message.text.substring(8, 12);
|
|
20
|
+
decodeResult.remaining.text = message.text.substring(12);
|
|
21
|
+
decodeResult.formatted.description = 'OUT Report';
|
|
22
|
+
decodeResult.formatted.items = [
|
|
23
|
+
{
|
|
24
|
+
type: 'origin',
|
|
25
|
+
code: 'ORG',
|
|
26
|
+
label: 'Origin',
|
|
27
|
+
value: decodeResult.raw.origin,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
type: 'destination',
|
|
31
|
+
code: 'DST',
|
|
32
|
+
label: 'Destination',
|
|
33
|
+
value: decodeResult.raw.destination,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
type: 'gate_out',
|
|
37
|
+
code: 'GOUT',
|
|
38
|
+
label: 'Gate OUT',
|
|
39
|
+
value: decodeResult.raw.gate_out,
|
|
40
|
+
}
|
|
41
|
+
];
|
|
42
|
+
decodeResult.decoded = true;
|
|
43
|
+
if (decodeResult.remaining.text === "")
|
|
44
|
+
decodeResult.decoder.decodeLevel = 'full';
|
|
45
|
+
else
|
|
46
|
+
decodeResult.decoder.decodeLevel = 'partial';
|
|
47
|
+
return decodeResult;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
exports.Label_QP = Label_QP;
|
|
51
|
+
exports.default = {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { DecoderPlugin } from '../DecoderPlugin';
|
|
2
|
+
export declare class Label_QQ extends DecoderPlugin {
|
|
3
|
+
name: string;
|
|
4
|
+
qualifiers(): {
|
|
5
|
+
labels: string[];
|
|
6
|
+
};
|
|
7
|
+
decode(message: any, options?: any): any;
|
|
8
|
+
}
|
|
9
|
+
declare const _default: {};
|
|
10
|
+
export default _default;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const DecoderPlugin_1 = require("../DecoderPlugin");
|
|
4
|
+
class Label_QQ extends DecoderPlugin_1.DecoderPlugin {
|
|
5
|
+
constructor() {
|
|
6
|
+
super(...arguments);
|
|
7
|
+
this.name = 'label-qq';
|
|
8
|
+
}
|
|
9
|
+
qualifiers() {
|
|
10
|
+
return {
|
|
11
|
+
labels: ['QQ'],
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
decode(message, options = {}) {
|
|
15
|
+
const decodeResult = this.defaultResult;
|
|
16
|
+
decodeResult.decoder.name = this.name;
|
|
17
|
+
decodeResult.raw.origin = message.text.substring(0, 4);
|
|
18
|
+
decodeResult.raw.destination = message.text.substring(4, 8);
|
|
19
|
+
decodeResult.raw.wheels_off = message.text.substring(8, 12);
|
|
20
|
+
decodeResult.remaining.text = message.text.substring(12);
|
|
21
|
+
decodeResult.formatted.description = 'OFF Report';
|
|
22
|
+
decodeResult.formatted.items = [
|
|
23
|
+
{
|
|
24
|
+
type: 'origin',
|
|
25
|
+
code: 'ORG',
|
|
26
|
+
label: 'Origin',
|
|
27
|
+
value: decodeResult.raw.origin,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
type: 'destination',
|
|
31
|
+
code: 'DST',
|
|
32
|
+
label: 'Destination',
|
|
33
|
+
value: decodeResult.raw.destination,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
type: 'wheels_off',
|
|
37
|
+
code: 'WOFF',
|
|
38
|
+
label: 'Wheels OFF',
|
|
39
|
+
value: decodeResult.raw.wheels_off,
|
|
40
|
+
}
|
|
41
|
+
];
|
|
42
|
+
decodeResult.decoded = true;
|
|
43
|
+
if (decodeResult.remaining.text === "")
|
|
44
|
+
decodeResult.decoder.decodeLevel = 'full';
|
|
45
|
+
else
|
|
46
|
+
decodeResult.decoder.decodeLevel = 'partial';
|
|
47
|
+
return decodeResult;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
exports.Label_QQ = Label_QQ;
|
|
51
|
+
exports.default = {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { DecoderPlugin } from '../DecoderPlugin';
|
|
2
|
+
export declare class Label_QR extends DecoderPlugin {
|
|
3
|
+
name: string;
|
|
4
|
+
qualifiers(): {
|
|
5
|
+
labels: string[];
|
|
6
|
+
};
|
|
7
|
+
decode(message: any, options?: any): any;
|
|
8
|
+
}
|
|
9
|
+
declare const _default: {};
|
|
10
|
+
export default _default;
|