From f22cf6a06faa2838131b6e4d4420b6c897ade32a Mon Sep 17 00:00:00 2001 From: Mark Bumiller Date: Fri, 15 Nov 2024 09:59:14 -0500 Subject: [PATCH] Adding Label 58 decoding fixes https://github.com/airframesio/acars-decoder-typescript/issues/148 --- lib/MessageDecoder.ts | 1 + lib/plugins/Label_58.test.ts | 58 ++++++++++++++++++++++++++++++++++++ lib/plugins/Label_58.ts | 53 ++++++++++++++++++++++++++++++++ lib/plugins/official.ts | 1 + 4 files changed, 113 insertions(+) create mode 100644 lib/plugins/Label_58.test.ts create mode 100644 lib/plugins/Label_58.ts diff --git a/lib/MessageDecoder.ts b/lib/MessageDecoder.ts index 959f472..8ff6618 100644 --- a/lib/MessageDecoder.ts +++ b/lib/MessageDecoder.ts @@ -53,6 +53,7 @@ export class MessageDecoder { this.registerPlugin(new Plugins.Label_H1(this)); this.registerPlugin(new Plugins.Label_H1_StarPOS(this)); this.registerPlugin(new Plugins.Label_HX(this)); + this.registerPlugin(new Plugins.Label_58(this)); this.registerPlugin(new Plugins.Label_80(this)); this.registerPlugin(new Plugins.Label_83(this)); this.registerPlugin(new Plugins.Label_8E(this)); diff --git a/lib/plugins/Label_58.test.ts b/lib/plugins/Label_58.test.ts new file mode 100644 index 0000000..6b84b25 --- /dev/null +++ b/lib/plugins/Label_58.test.ts @@ -0,0 +1,58 @@ +import { MessageDecoder } from '../MessageDecoder'; +import { Label_58 } from './Label_58'; + +describe('Label_58', () => { + let plugin: Label_58; + + beforeEach(() => { + const decoder = new MessageDecoder(); + plugin = new Label_58(decoder); + }); + + test('matches qualifiers', () => { + expect(plugin.decode).toBeDefined(); + expect(plugin.name).toBe('label-58'); + expect(plugin.qualifiers).toBeDefined(); + expect(plugin.qualifiers()).toEqual({ + labels: ['58'], + }); + }); + + test('decodes variant 1', () => { + const text = 'OG0704/06/230942/N39.214/W76.106/22683/N/' + const decodeResult = plugin.decode({ text: text }); + + expect(decodeResult.decoded).toBe(true); + expect(decodeResult.decoder.decodeLevel).toBe('partial'); + expect(decodeResult.raw.flight_number).toBe('OG0704'); + expect(decodeResult.raw.day).toBe(6); + expect(decodeResult.raw.time_of_day).toBe(83382); + expect(decodeResult.raw.position.latitude).toBe(39.214); + expect(decodeResult.raw.position.longitude).toBe(-76.106); + expect(decodeResult.raw.altitude).toBe(22683); + expect(decodeResult.formatted.items.length).toBe(5); + expect(decodeResult.formatted.items[0].label).toBe('Flight Number'); + expect(decodeResult.formatted.items[0].value).toBe('OG0704'); + expect(decodeResult.formatted.items[1].label).toBe('Day of Month'); + expect(decodeResult.formatted.items[1].value).toBe('6'); + expect(decodeResult.formatted.items[2].label).toBe('Message Timestamp'); + expect(decodeResult.formatted.items[2].value).toBe('23:09:42'); + expect(decodeResult.formatted.items[3].label).toBe('Aircraft Position'); + expect(decodeResult.formatted.items[3].value).toBe('39.214 N, 76.106 W'); + expect(decodeResult.formatted.items[4].label).toBe('Altitude'); + expect(decodeResult.formatted.items[4].value).toBe('22683 feet'); + expect(decodeResult.remaining.text).toBe('N/'); + }); + + test('does not decode ', () => { + + const text = 'Bogus/message'; + const decodeResult = plugin.decode({ text: text }); + + expect(decodeResult.decoded).toBe(false); + expect(decodeResult.decoder.decodeLevel).toBe('none'); + expect(decodeResult.decoder.name).toBe('label-58'); + expect(decodeResult.formatted.description).toBe('Position Report'); + expect(decodeResult.message.text).toBe(text); + }); +}); \ No newline at end of file diff --git a/lib/plugins/Label_58.ts b/lib/plugins/Label_58.ts new file mode 100644 index 0000000..64382b8 --- /dev/null +++ b/lib/plugins/Label_58.ts @@ -0,0 +1,53 @@ +import { DateTimeUtils } from '../DateTimeUtils'; +import { DecoderPlugin } from '../DecoderPlugin'; +import { DecodeResult, Message, Options } from '../DecoderPluginInterface'; +import { CoordinateUtils } from '../utils/coordinate_utils'; +import { ResultFormatter } from '../utils/result_formatter'; + +// General Aviation Position Report +export class Label_58 extends DecoderPlugin { + name = 'label-58'; + + qualifiers() { // eslint-disable-line class-methods-use-this + return { + labels: ['58'], + }; + } + + decode(message: Message, options: Options = {}): DecodeResult { + const decodeResult = this.defaultResult(); + decodeResult.decoder.name = this.name; + decodeResult.formatted.description = 'Position Report'; + decodeResult.message = message; + + const data = message.text.split('/'); + if (data.length === 8) { + ResultFormatter.flightNumber(decodeResult, data[0]); + ResultFormatter.day(decodeResult, Number(data[1])); + ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[2])); + const lat = data[3]; + const lon = data[4]; + ResultFormatter.position(decodeResult, { + latitude: CoordinateUtils.getDirection(lat[0]) * Number(lat.substring(1)), + longitude:CoordinateUtils.getDirection(lon[0]) * Number(lon.substring(1)) + }); + ResultFormatter.altitude(decodeResult, Number(data[5])); + ResultFormatter.unknown(decodeResult, data[6], '/'); + ResultFormatter.unknown(decodeResult, data[7], '/'); + } else { + if (options.debug) { + console.log(`Decoder: Unknown 58 message: ${message.text}`); + } + ResultFormatter.unknown(decodeResult, message.text); + decodeResult.decoded = false; + decodeResult.decoder.decodeLevel = 'none'; + return decodeResult; + } + + decodeResult.decoded = true; + decodeResult.decoder.decodeLevel = 'partial'; + return decodeResult; + } +} + +export default {}; diff --git a/lib/plugins/official.ts b/lib/plugins/official.ts index ccb7b0e..9ec6bf6 100644 --- a/lib/plugins/official.ts +++ b/lib/plugins/official.ts @@ -31,6 +31,7 @@ export * from './Label_4A_Slash_01'; export * from './Label_4J_POS'; export * from './Label_4N'; export * from './Label_4T_AGFSR'; +export * from './Label_58'; export * from './Label_80'; export * from './Label_83'; export * from './Label_8E';