diff --git a/lib/MessageDecoder.ts b/lib/MessageDecoder.ts index 3c928d0..757233e 100644 --- a/lib/MessageDecoder.ts +++ b/lib/MessageDecoder.ts @@ -48,6 +48,7 @@ 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_StarPOS(this)); this.registerPlugin(new Plugins.Label_HX(this)); this.registerPlugin(new Plugins.Label_80(this)); this.registerPlugin(new Plugins.Label_83(this)); diff --git a/lib/plugins/Label_H1_StarPOS.test.ts b/lib/plugins/Label_H1_StarPOS.test.ts new file mode 100644 index 0000000..1684e78 --- /dev/null +++ b/lib/plugins/Label_H1_StarPOS.test.ts @@ -0,0 +1,49 @@ +import { MessageDecoder } from '../MessageDecoder'; +import { Label_H1_StarPOS } from './Label_H1_StarPOS'; + +describe('Label H1 *POS', () => { + + let plugin: Label_H1_StarPOS; + + beforeEach(() => { + const decoder = new MessageDecoder(); + plugin = new Label_H1_StarPOS(decoder); + }); + + test('decodes variant 1', () => { + + const text = '*POS10300950N3954W07759363312045802M5230175'; + const decodeResult = plugin.decode({ text: text }); + + expect(decodeResult.decoded).toBe(true); + expect(decodeResult.decoder.decodeLevel).toBe('partial'); + expect(decodeResult.message.text).toBe(text); + expect(decodeResult.raw.day_of_month).toBe(30); + expect(decodeResult.raw.month).toBe(10); + expect(decodeResult.raw.time_of_day).toBe(35400); + expect(decodeResult.raw.position.latitude).toBe(39.900000); + expect(decodeResult.raw.position.longitude).toBe(-77.98333333333333); + expect(decodeResult.raw.altitude).toBe(36331); + expect(decodeResult.formatted.items.length).toBe(3); + expect(decodeResult.formatted.items[0].label).toBe('Message Timestamp'); + expect(decodeResult.formatted.items[0].value).toBe('09:50:00'); + expect(decodeResult.formatted.items[1].label).toBe('Aircraft Position'); + expect(decodeResult.formatted.items[1].value).toBe('39.900 N, 77.983 W'); + expect(decodeResult.formatted.items[2].label).toBe('Altitude'); + expect(decodeResult.formatted.items[2].value).toBe('36331 feet'); + + expect(decodeResult.remaining.text).toBe('2045802M5230175'); + }); + + + test('does not decode ', () => { + + const text = '*POS Bogus message'; + const decodeResult = plugin.decode({ text: text }); + + expect(decodeResult.decoded).toBe(false); + expect(decodeResult.decoder.decodeLevel).toBe('none'); + expect(decodeResult.formatted.description).toBe('Position Report'); + expect(decodeResult.formatted.items.length).toBe(0); + }); +}); diff --git a/lib/plugins/Label_H1_StarPOS.ts b/lib/plugins/Label_H1_StarPOS.ts new file mode 100644 index 0000000..6eaf8eb --- /dev/null +++ b/lib/plugins/Label_H1_StarPOS.ts @@ -0,0 +1,49 @@ +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'; + +export class Label_H1_StarPOS extends DecoderPlugin { + name = 'label-h1-star-pos'; + qualifiers() { // eslint-disable-line class-methods-use-this + return { + labels: ['H1'], + preambles: ['*POS'], + }; + } + + decode(message: Message, options: Options = {}) : DecodeResult { + let decodeResult = this.defaultResult(); + decodeResult.decoder.name = this.name; + decodeResult.formatted.description = 'Position Report'; + decodeResult.message = message; + + const msg = message.text; + // assuming fixed length until other variants found + if (msg.length !== 43 || !msg.startsWith('*POS')) { + if (options.debug) { + console.log(`Decoder: Unknown H1 message: ${msg}`); + } + ResultFormatter.unknown(decodeResult, msg); + decodeResult.decoded = false; + decodeResult.decoder.decodeLevel = 'none'; + return decodeResult; + } + + decodeResult.raw.month = Number(msg.substring(4, 6)); + decodeResult.raw.day_of_month = Number(msg.substring(6, 8)); + ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(msg.substring(8, 12) + '00')); + ResultFormatter.position(decodeResult, { // Deg Min, no sec + latitude: CoordinateUtils.getDirection(msg.substring(12,13)) * (Number(msg.substring(13, 15)) + Number(msg.substring(15, 17))/60), + longitude: CoordinateUtils.getDirection(msg.substring(17,18)) * (Number(msg.substring(18, 21)) + Number(msg.substring(21, 23))/60) + }); + ResultFormatter.altitude(decodeResult, Number(msg.substring(23, 28))); + ResultFormatter.unknown(decodeResult, msg.substring(28)); + decodeResult.decoded = true; + decodeResult.decoder.decodeLevel = 'partial'; + return decodeResult; + } +} + +export default {}; diff --git a/lib/plugins/official.ts b/lib/plugins/official.ts index 4bf5217..ccbaf82 100644 --- a/lib/plugins/official.ts +++ b/lib/plugins/official.ts @@ -33,10 +33,11 @@ export * from './Label_83'; export * from './Label_8E'; export * from './Label_B6'; export * from './Label_ColonComma'; +export * from './Label_H1'; export * from './Label_H1_FLR'; export * from './Label_H1_OHMA'; +export * from './Label_H1_StarPOS'; export * from './Label_H1_WRN'; -export * from './Label_H1'; export * from './Label_HX'; export * from './Label_SQ'; export * from './Label_QR';