Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion lib/MessageDecoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ export class MessageDecoder {
this.registerPlugin(new Plugins.Label_H1_OHMA(this));
this.registerPlugin(new Plugins.Label_H1_WRN(this));
this.registerPlugin(new Plugins.Label_H1(this));
this.registerPlugin(new Plugins.Label_H1_Slash(this));
this.registerPlugin(new Plugins.Label_H1_StarPOS(this));
this.registerPlugin(new Plugins.Label_HX(this));
this.registerPlugin(new Plugins.Label_58(this));
Expand Down
16 changes: 15 additions & 1 deletion lib/plugins/Label_H1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,21 @@ export class Label_H1 extends DecoderPlugin {
const msg = message.text.replace(/\n|\r/g, '');
const parts = msg.split('#');
let decoded = false;
if (parts.length === 1) {
if (msg.startsWith('/')) {
const headerData = msg.split('.');
const decoded = H1Helper.decodeH1Message(
decodeResult,
headerData.slice(1).join('.'),
); // skip up to # and then a little more
if (decoded) {
decodeResult.remaining.text =
headerData[0] + '.' + decodeResult.remaining.text;
decodeResult.decoded = decoded;
decodeResult.decoder.decodeLevel = 'partial';
}

return decodeResult;
} else if (parts.length === 1) {
decoded = H1Helper.decodeH1Message(decodeResult, msg);
} else if (parts.length == 2) {
const offset = isNaN(parseInt(parts[1][1])) ? 3 : 4;
Expand Down
16 changes: 12 additions & 4 deletions lib/plugins/Label_H1_POS.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -488,15 +488,23 @@ describe('Label_H1 POS', () => {
);
});

test('does not decode /.POS', () => {
test('decodes /.POS', () => {
// https://app.airframes.io/messages/2500488708
message.text =
'/.POS/TS100316,210324/PSS35333W058220,,100316,250,S37131W059150,101916,S39387W060377,M23,27282,241,780,MANUAL,0,813E711';
const decodeResult = plugin.decode(message);

expect(decodeResult.decoded).toBe(false);
expect(decodeResult.decoder.decodeLevel).toBe('none');
expect(decodeResult.formatted.description).toBe('Unknown');
expect(decodeResult.decoded).toBe(true);
expect(decodeResult.decoder.decodeLevel).toBe('partial');
expect(decodeResult.formatted.description).toBe('Position Report');
expect(decodeResult.raw.message_timestamp).toBe(1711015396);
expect(decodeResult.raw.position.latitude).toBeCloseTo(-35.555, 3);
expect(decodeResult.raw.position.longitude).toBeCloseTo(-58.367, 3);
expect(decodeResult.raw.altitude).toBe(25000);
expect(decodeResult.raw.route.waypoints.length).toBe(3);
expect(decodeResult.raw.checksum).toBe(0xe711);
expect(decodeResult.formatted.items.length).toBe(5);
expect(decodeResult.remaining.text).toBe('/.27282,241,780,MANUAL,0,813');
});

test('decodes duplicate data', () => {
Expand Down
66 changes: 66 additions & 0 deletions lib/plugins/Label_H1_REJ.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { MessageDecoder } from '../MessageDecoder';
import { Label_H1 } from './Label_H1';

describe('Label H1 Preamble REJ', () => {
let plugin: Label_H1;
const message = { label: 'H1', text: '' };

beforeEach(() => {
const decoder = new MessageDecoder();
plugin = new Label_H1(decoder);
});

test('decodes PWI variant 1', () => {
message.text = 'REJPWI,141147,A,70,MCRAY,97E16';
const decodeResult = plugin.decode(message);

expect(decodeResult.decoded).toBe(true);
expect(decodeResult.decoder.decodeLevel).toBe('partial');
expect(decodeResult.raw.checksum).toBe(0x7e16);
expect(decodeResult.formatted.items.length).toBe(1);
expect(decodeResult.remaining.text).toBe('141147,A,70,MCRAY,9');
});

test('decodes PWI variant 2', () => {
message.text =
'/HDQDLUA.REJPWI,104916,053,,CB007,CLIMB.053,,CB007,CLIMB.053,,CB007,CLIMB.053,,CB007,CLIMB.053,,CB007,CRUISE/GAHDQDLUA/TS113028,070226FE61';
const decodeResult = plugin.decode(message);

expect(decodeResult.decoded).toBe(true);
expect(decodeResult.decoder.decodeLevel).toBe('partial');
expect(decodeResult.raw.ground_address).toBe('HDQDLUA');
expect(decodeResult.raw.checksum).toBe(0xfe61);
expect(decodeResult.formatted.items.length).toBe(2);
expect(decodeResult.remaining.text).toBe(
'/HDQDLUA.104916,053,,CB007,CLIMB.053,,CB007,CLIMB.053,,CB007,CLIMB.053,,CB007,CLIMB.053,,CB007,CRUISE',
);
});

test('decodes POS variant 1', () => {
message.text =
'REJPOS,100719,130,219,RF005,N36089W076173/TS100719,090226E850';
const decodeResult = plugin.decode(message);

expect(decodeResult.decoded).toBe(true);
expect(decodeResult.decoder.decodeLevel).toBe('partial');
expect(decodeResult.raw.checksum).toBe(0xe850);
expect(decodeResult.formatted.items.length).toBe(1);
expect(decodeResult.remaining.text).toBe(
'100719,130,219,RF005,N36089W076173',
);
});

test('decodes POS variant 2', () => {
message.text =
'REJPOS,041509,130,219,RF005,SWANN.130,219,RF005,BROSS.130,219,RF005,MYFOO.130,219,RF005,YAHOO.130,219,RF005,4650N.130,219,RF005,4840N.130,219,RF005,5030N.130,219,RF005,5120NA55A';
const decodeResult = plugin.decode(message);

expect(decodeResult.decoded).toBe(true);
expect(decodeResult.decoder.decodeLevel).toBe('partial');
expect(decodeResult.raw.checksum).toBe(0xa55a);
expect(decodeResult.formatted.items.length).toBe(1);
expect(decodeResult.remaining.text).toBe(
'041509,130,219,RF005,SWANN.130,219,RF005,BROSS.130,219,RF005,MYFOO.130,219,RF005,YAHOO.130,219,RF005,4650N.130,219,RF005,4840N.130,219,RF005,5030N.130,219,RF005,5120N',
);
});
});
71 changes: 71 additions & 0 deletions lib/plugins/Label_H1_REQ.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { MessageDecoder } from '../MessageDecoder';
import { Label_H1 } from './Label_H1';

describe('Label H1 preamble REQ', () => {
let plugin: Label_H1;
const message = { label: 'H1', text: '' };

beforeEach(() => {
const decoder = new MessageDecoder();
plugin = new Label_H1(decoder);
});

test('decodes PWI', () => {
message.text =
'REQPWI/WQ320:GEQUE.HACKS.XUB.VHP.KK60K.KIVDE.KK60E.KOVJY.KD54Y.ACZES.KD48S.DVC.KITTN.KATTS.RUMPS.OAL.INYOE.DYAMD/DQ320/SPGEQUE77CE';
const decodeResult = plugin.decode(message);

expect(decodeResult.decoded).toBe(true);
expect(decodeResult.decoder.decodeLevel).toBe('full');
expect(decodeResult.raw.requested_alts).toStrictEqual([32000]);
expect(decodeResult.raw.desired_alt).toBe(32000);
expect(decodeResult.raw.start_point).toBe('GEQUE');
expect(decodeResult.raw.route.waypoints).toStrictEqual([
{ name: 'GEQUE' },
{ name: 'HACKS' },
{ name: 'XUB' },
{ name: 'VHP' },
{ name: 'KK60K' },
{ name: 'KIVDE' },
{ name: 'KK60E' },
{ name: 'KOVJY' },
{ name: 'KD54Y' },
{ name: 'ACZES' },
{ name: 'KD48S' },
{ name: 'DVC' },
{ name: 'KITTN' },
{ name: 'KATTS' },
{ name: 'RUMPS' },
{ name: 'OAL' },
{ name: 'INYOE' },
{ name: 'DYAMD' },
]);
expect(decodeResult.raw.checksum).toBe(0x77ce);
expect(decodeResult.formatted.items.length).toBe(5);
});

test('decodes POS', () => {
message.text = 'REQPOS037B';
const decodeResult = plugin.decode(message);

expect(decodeResult.decoded).toBe(true);
expect(decodeResult.decoder.decodeLevel).toBe('full');
expect(decodeResult.raw.checksum).toBe(0x037b);
expect(decodeResult.formatted.items.length).toBe(1);
expect(decodeResult.remaining.text).toBeUndefined();
});

test('decodes FPN', () => {
message.text = 'REQFPN/RN10001/RS:FP:Z5585 9736';
const decodeResult = plugin.decode(message);

expect(decodeResult.decoded).toBe(true);
expect(decodeResult.decoder.decodeLevel).toBe('full');
expect(decodeResult.raw.route_number).toBe('10001');
expect(decodeResult.raw.route_status).toBe('RS');
expect(decodeResult.raw.flight_plan).toBe('Z5585');
expect(decodeResult.raw.checksum).toBe(0x9736);
expect(decodeResult.formatted.items.length).toBe(4);
expect(decodeResult.remaining.text).toBeUndefined();
});
});
34 changes: 34 additions & 0 deletions lib/plugins/Label_H1_RES.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { MessageDecoder } from '../MessageDecoder';
import { Label_H1 } from './Label_H1';

describe('Label H1 Preamble RES', () => {
let plugin: Label_H1;
const message = { label: 'H1', text: '' };

beforeEach(() => {
const decoder = new MessageDecoder();
plugin = new Label_H1(decoder);
});

test('decodes PWI', () => {
message.text = 'RESPWI/AC,5B/TS140956,070226/DI140953,140956,140956128C';
const decodeResult = plugin.decode(message);

expect(decodeResult.decoded).toBe(true);
expect(decodeResult.decoder.decodeLevel).toBe('partial');
expect(decodeResult.raw.checksum).toBe(0x128c);
expect(decodeResult.formatted.items.length).toBe(1);
expect(decodeResult.remaining.text).toBe('AC,5B/DI140953,140956,140956');
});

test('decodes POS', () => {
message.text = 'RESPOS/AK,0711909';
const decodeResult = plugin.decode(message);

expect(decodeResult.decoded).toBe(true);
expect(decodeResult.decoder.decodeLevel).toBe('partial');
expect(decodeResult.raw.checksum).toBe(0x1909);
expect(decodeResult.formatted.items.length).toBe(1);
expect(decodeResult.remaining.text).toBe('AK,071');
});
});
45 changes: 14 additions & 31 deletions lib/plugins/Label_H1_Slash.test.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,13 @@
import { MessageDecoder } from '../MessageDecoder';
import { Label_H1_Slash } from './Label_H1_Slash';
import { Label_H1 } from './Label_H1';

describe('Label H1 /', () => {
let plugin: Label_H1_Slash;
let plugin: Label_H1;
const message = { label: 'H1', text: '' };

beforeEach(() => {
const decoder = new MessageDecoder();
plugin = new Label_H1_Slash(decoder);
});

test('matches qualifiers', () => {
expect(plugin.decode).toBeDefined();
expect(plugin.name).toBe('label-h1-slash');
expect(plugin.qualifiers).toBeDefined();
expect(plugin.qualifiers()).toEqual({
labels: ['H1'],
preambles: ['/'],
});
plugin = new Label_H1(decoder);
});

test('decodes variant 1', () => {
Expand Down Expand Up @@ -45,7 +35,7 @@ describe('Label H1 /', () => {
expect(decodeResult.formatted.items[3].value).toBe('-23 degrees');
expect(decodeResult.formatted.items[4].label).toBe('Message Checksum');
expect(decodeResult.formatted.items[4].value).toBe('0xe711');
expect(decodeResult.remaining.text).toBe('27282,241,780,MANUAL,0,813');
expect(decodeResult.remaining.text).toBe('/.27282,241,780,MANUAL,0,813');
});

test('decodes variant 2', () => {
Expand All @@ -57,22 +47,15 @@ describe('Label H1 /', () => {
expect(decodeResult.decoder.decodeLevel).toBe('partial');
expect(decodeResult.formatted.description).toBe('Position Report');
expect(decodeResult.raw.message_timestamp).toBe(1731592673);
expect(decodeResult.formatted.items.length).toBe(5);
expect(decodeResult.formatted.items[0].label).toBe('Aircraft Position');
expect(decodeResult.formatted.items[0].value).toBe('38.553 N, 80.137 W');
expect(decodeResult.formatted.items[1].label).toBe('Altitude');
expect(decodeResult.formatted.items[1].value).toBe('32000 feet');
expect(decodeResult.formatted.items[2].label).toBe('Aircraft Route');
expect(decodeResult.formatted.items[2].value).toBe(
'RONZZ@13:57:53 > LEVII@14:04:54 > WISTA',
);
expect(decodeResult.formatted.items[3].label).toBe(
'Outside Air Temperature (C)',
);
expect(decodeResult.formatted.items[3].value).toBe('-45 degrees');
expect(decodeResult.formatted.items[4].label).toBe('Message Checksum');
expect(decodeResult.formatted.items[4].value).toBe('0x0721');
expect(decodeResult.remaining.text).toBe('HDQDLUA,20967,194/GAHDQDLUA/CA');
expect(decodeResult.raw.position.latitude).toBeCloseTo(38.553, 3);
expect(decodeResult.raw.position.longitude).toBeCloseTo(-80.137, 3);
expect(decodeResult.raw.route.waypoints.length).toBe(3);
expect(decodeResult.raw.altitude).toBe(32000);
expect(decodeResult.raw.outside_air_temperature).toBe(-45);
expect(decodeResult.raw.ground_address).toBe('HDQDLUA');
expect(decodeResult.raw.checksum).toBe(0x0721);
expect(decodeResult.formatted.items.length).toBe(6);
expect(decodeResult.remaining.text).toBe('/HDQDLUA.20967,194/CA');
});

test('decodes variant 3', () => {
Expand All @@ -99,7 +82,7 @@ describe('Label H1 /', () => {
expect(decodeResult.formatted.items[3].value).toBe('-56 degrees');
expect(decodeResult.formatted.items[4].label).toBe('Message Checksum');
expect(decodeResult.formatted.items[4].value).toBe('0x6763');
expect(decodeResult.remaining.text).toBe('24739,127');
expect(decodeResult.remaining.text).toBe('/.24739,127');
});

test('does not decode invalid', () => {
Expand Down
88 changes: 0 additions & 88 deletions lib/plugins/Label_H1_Slash.ts

This file was deleted.

Loading