From 0b9ca2e9b0d69d24c631ac7acea6496ac5e1d074 Mon Sep 17 00:00:00 2001 From: Mark Bumiller Date: Wed, 4 Mar 2026 18:31:03 -0500 Subject: [PATCH 1/3] fix date codes make convertDateTimeToEpoch be in a reasonable format fix code/tests accordingly --- lib/DateTimeUtils.ts | 4 ++-- lib/plugins/Label_15.ts | 6 +----- lib/plugins/Label_1J_2J_FTX.test.ts | 2 +- lib/plugins/Label_1M_Slash.ts | 4 ++-- lib/plugins/Label_24_Slash.ts | 6 +++--- lib/plugins/Label_4J_POS.test.ts | 1 - lib/plugins/Label_H1_FLR.test.ts | 12 ++++++------ lib/plugins/Label_H1_INR.test.ts | 30 +++++++++++++++++++++++++++++ lib/plugins/Label_H1_WRN.test.ts | 2 +- 9 files changed, 46 insertions(+), 21 deletions(-) create mode 100644 lib/plugins/Label_H1_INR.test.ts diff --git a/lib/DateTimeUtils.ts b/lib/DateTimeUtils.ts index 2cf5540..7babbb8 100644 --- a/lib/DateTimeUtils.ts +++ b/lib/DateTimeUtils.ts @@ -50,7 +50,7 @@ export class DateTimeUtils { /** * * @param time HHMMSS - * @param date MMDDYY or MMDDYYYY + * @param date DDMMYY or DDMMYYYY * @returns seconds since epoch */ public static convertDateTimeToEpoch(time: string, date: string): number { @@ -58,7 +58,7 @@ export class DateTimeUtils { if (date.length === 6) { date = date.substring(0, 4) + `20${date.substring(4, 6)}`; } - const timestamp = `${date.substring(4, 8)}-${date.substring(0, 2)}-${date.substring(2, 4)}T${time.substring(0, 2)}:${time.substring(2, 4)}:${time.substring(4, 6)}.000Z`; + const timestamp = `${date.substring(4, 8)}-${date.substring(2, 4)}-${date.substring(0, 2)}T${time.substring(0, 2)}:${time.substring(2, 4)}:${time.substring(4, 6)}.000Z`; const millis = Date.parse(timestamp); return millis / 1000; } diff --git a/lib/plugins/Label_15.ts b/lib/plugins/Label_15.ts index dc9bd59..ca938bc 100644 --- a/lib/plugins/Label_15.ts +++ b/lib/plugins/Label_15.ts @@ -45,13 +45,9 @@ export class Label_15 extends DecoderPlugin { const ddmmyy = between.substring(16, 22); const hhmm = between.substring(22, 26); if (ddmmyy != '------') { - const mmddyy = - ddmmyy.substring(2, 4) + - ddmmyy.substring(0, 2) + - ddmmyy.substring(4); ResultFormatter.off( decodeResult, - DateTimeUtils.convertDateTimeToEpoch(hhmm + '00', mmddyy), + DateTimeUtils.convertDateTimeToEpoch(hhmm + '00', ddmmyy), 'epoch', ); } else { diff --git a/lib/plugins/Label_1J_2J_FTX.test.ts b/lib/plugins/Label_1J_2J_FTX.test.ts index d059dba..6436054 100644 --- a/lib/plugins/Label_1J_2J_FTX.test.ts +++ b/lib/plugins/Label_1J_2J_FTX.test.ts @@ -43,7 +43,7 @@ describe('Label 1J/2J FTX', () => { expect(decodeResult.raw.tail).toBe('50007B'); expect(decodeResult.raw.flight_number).toBe('RCH4086'); expect(decodeResult.raw.mission_number).toBe('ABB02R70E037'); - expect(decodeResult.raw.message_timestamp).toBe(1759367848); + expect(decodeResult.raw.message_timestamp).toBe(1739150248); expect(decodeResult.raw.fuel_on_board).toBe(1791); expect(decodeResult.raw.freetext).toBe( 'GOOD EVENING PLEASE PASS US THE SUPER BOWL SCORE WHEN ABLE. THANK YOU', diff --git a/lib/plugins/Label_1M_Slash.ts b/lib/plugins/Label_1M_Slash.ts index 7d972a3..44bb61b 100644 --- a/lib/plugins/Label_1M_Slash.ts +++ b/lib/plugins/Label_1M_Slash.ts @@ -47,8 +47,8 @@ export class Label_1M_Slash extends DecoderPlugin { decodeResult, DateTimeUtils.convertDateTimeToEpoch( results[7] + '00', - yymmdd.substring(2, 4) + - yymmdd.substring(4, 6) + + yymmdd.substring(4, 6) + + yymmdd.substring(2, 4) + yymmdd.substring(0, 2), ), 'epoch', diff --git a/lib/plugins/Label_24_Slash.ts b/lib/plugins/Label_24_Slash.ts index 0e5bc1f..8a1bea1 100644 --- a/lib/plugins/Label_24_Slash.ts +++ b/lib/plugins/Label_24_Slash.ts @@ -24,14 +24,14 @@ export class Label_24_Slash extends DecoderPlugin { if (fields.length == 10 && fields[0] == '' && fields[9] == '') { // begin and ends with `/` - const mmddyy = - fields[1].substring(4, 6) + + const ddmmyy = fields[1].substring(2, 4) + + fields[1].substring(4, 6) + fields[1].substring(0, 2); // YYDDMM const hhmmss = fields[2] + '00'; decodeResult.raw.message_timestamp = DateTimeUtils.convertDateTimeToEpoch( hhmmss, - mmddyy, + ddmmyy, ); ResultFormatter.flightNumber(decodeResult, fields[3]); ResultFormatter.altitude(decodeResult, Number(fields[4])); diff --git a/lib/plugins/Label_4J_POS.test.ts b/lib/plugins/Label_4J_POS.test.ts index acc5ac3..0f29ff0 100644 --- a/lib/plugins/Label_4J_POS.test.ts +++ b/lib/plugins/Label_4J_POS.test.ts @@ -33,7 +33,6 @@ describe('Label 4J POS', () => { expect(decodeResult.raw.tail).toBe('91459S'); expect(decodeResult.raw.flight_number).toBe('BANKR31'); expect(decodeResult.raw.mission_number).toBe(''); - expect(decodeResult.raw.message_date).toBe('03032024'); expect(decodeResult.raw.day).toBe(3); expect(decodeResult.raw.eta_time).toBe(56340); expect(decodeResult.raw.position.latitude).toBeCloseTo(39.462, 3); diff --git a/lib/plugins/Label_H1_FLR.test.ts b/lib/plugins/Label_H1_FLR.test.ts index 82394c2..7d21ae9 100644 --- a/lib/plugins/Label_H1_FLR.test.ts +++ b/lib/plugins/Label_H1_FLR.test.ts @@ -30,7 +30,7 @@ describe('Label H1 Preamble FLR', () => { expect(decodeResult.decoder.name).toBe('label-h1-flr'); expect(decodeResult.formatted.description).toBe('Fault Log Report'); expect(decodeResult.message).toBe(message); - expect(decodeResult.raw.message_timestamp).toBe(1712143380); + expect(decodeResult.raw.message_timestamp).toBe(1709551380); expect(decodeResult.formatted.items.length).toBe(1); expect(decodeResult.formatted.items[0].type).toBe('fault'); expect(decodeResult.formatted.items[0].code).toBe('FR'); @@ -52,7 +52,7 @@ describe('Label H1 Preamble FLR', () => { expect(decodeResult.decoder.name).toBe('label-h1-flr'); expect(decodeResult.formatted.description).toBe('Fault Log Report'); expect(decodeResult.message).toBe(message); - expect(decodeResult.raw.message_timestamp).toBe(1712142240); + expect(decodeResult.raw.message_timestamp).toBe(1709550240); expect(decodeResult.formatted.items.length).toBe(1); expect(decodeResult.formatted.items[0].type).toBe('fault'); expect(decodeResult.formatted.items[0].code).toBe('FR'); @@ -73,7 +73,7 @@ describe('Label H1 Preamble FLR', () => { expect(decodeResult.decoder.name).toBe('label-h1-flr'); expect(decodeResult.formatted.description).toBe('Fault Log Report'); expect(decodeResult.message).toBe(message); - expect(decodeResult.raw.message_timestamp).toBe(1712138160); + expect(decodeResult.raw.message_timestamp).toBe(1709546160); expect(decodeResult.formatted.items.length).toBe(1); expect(decodeResult.formatted.items[0].type).toBe('fault'); expect(decodeResult.formatted.items[0].code).toBe('FR'); @@ -92,7 +92,7 @@ describe('Label H1 Preamble FLR', () => { expect(decodeResult.decoder.name).toBe('label-h1-flr'); expect(decodeResult.formatted.description).toBe('Fault Log Report'); expect(decodeResult.message).toBe(message); - expect(decodeResult.raw.message_timestamp).toBe(1712138580); + expect(decodeResult.raw.message_timestamp).toBe(1709546580); expect(decodeResult.formatted.items.length).toBe(1); expect(decodeResult.formatted.items[0].type).toBe('fault'); expect(decodeResult.formatted.items[0].code).toBe('FR'); @@ -103,7 +103,7 @@ describe('Label H1 Preamble FLR', () => { expect(decodeResult.remaining.text).toBe('38316206'); }); - test('decodes Label H1 Preamble FLR LQD', () => { + test('decodes Label H1 Preamble #CFB', () => { // https://app.airframes.io/messages/2437260976 message.text = '#CFBFLR/FR24030412400034723406ATC1(1SH1)/TCAS(1000SG) /IDTCAS '; @@ -114,7 +114,7 @@ describe('Label H1 Preamble FLR', () => { expect(decodeResult.decoder.name).toBe('label-h1-flr'); expect(decodeResult.formatted.description).toBe('Fault Log Report'); expect(decodeResult.message).toBe(message); - expect(decodeResult.raw.message_timestamp).toBe(1712148000); + expect(decodeResult.raw.message_timestamp).toBe(1709556000); expect(decodeResult.formatted.items.length).toBe(1); expect(decodeResult.formatted.items[0].type).toBe('fault'); expect(decodeResult.formatted.items[0].code).toBe('FR'); diff --git a/lib/plugins/Label_H1_INR.test.ts b/lib/plugins/Label_H1_INR.test.ts new file mode 100644 index 0000000..d1a6ad3 --- /dev/null +++ b/lib/plugins/Label_H1_INR.test.ts @@ -0,0 +1,30 @@ +import { MessageDecoder } from '../MessageDecoder'; +import { Label_H1 } from './Label_H1'; + +describe('Label_H1 INR', () => { + let plugin: Label_H1; + const message = { label: 'H1', text: '' }; + + beforeEach(() => { + const decoder = new MessageDecoder(); + plugin = new Label_H1(decoder); + }); + + test('decodes valid', () => { + // https://app.airframes.io/messages/6248968588 + message.text = + 'INR/ID91511S,,/DC04032026,143534/MR19,/NR,,,,,,,,950,0/ET041505/FB983/VR32BF4C'; + const decodeResult = plugin.decode(message); + + expect(decodeResult.decoded).toBe(true); + expect(decodeResult.decoder.decodeLevel).toBe('partial'); + expect(decodeResult.raw.tail).toBe('91511S'); + expect(decodeResult.raw.message_timestamp).toBe(1772634934); + expect(decodeResult.raw.day).toBe(4); + expect(decodeResult.raw.eta_time).toBe(54300); + expect(decodeResult.raw.fuel_on_board).toBe(983); + expect(decodeResult.raw.checksum).toBe(0xbf4c); + expect(decodeResult.formatted.items.length).toBe(6); + expect(decodeResult.remaining.text).toBe('MR19,/NR,,,,,,,,950,0'); + }); +}); diff --git a/lib/plugins/Label_H1_WRN.test.ts b/lib/plugins/Label_H1_WRN.test.ts index f6599f0..7d09d42 100644 --- a/lib/plugins/Label_H1_WRN.test.ts +++ b/lib/plugins/Label_H1_WRN.test.ts @@ -30,7 +30,7 @@ describe('Label H1 WRN', () => { expect(decodeResult.decoder.name).toBe('label-h1-wrn'); expect(decodeResult.formatted.description).toBe('Warning Message'); expect(decodeResult.message).toBe(message); - expect(decodeResult.raw.message_timestamp).toBe(1712105880); + expect(decodeResult.raw.message_timestamp).toBe(1709513880); expect(decodeResult.formatted.items.length).toBe(1); expect(decodeResult.formatted.items[0].type).toBe('warning'); expect(decodeResult.formatted.items[0].code).toBe('WRN'); From aa25fd247dfd9671bf8a2fb317600d845162f3e0 Mon Sep 17 00:00:00 2001 From: Mark Bumiller Date: Wed, 4 Mar 2026 21:30:46 -0500 Subject: [PATCH 2/3] adding known messages --- lib/utils/h1_helper.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/utils/h1_helper.ts b/lib/utils/h1_helper.ts index c8f7f0e..52cc235 100644 --- a/lib/utils/h1_helper.ts +++ b/lib/utils/h1_helper.ts @@ -382,6 +382,8 @@ function processMessageType(decodeResult: DecodeResult, type: string): boolean { decodeResult.formatted.description = 'Free Text'; } else if (type === 'INI') { decodeResult.formatted.description = 'Initial Report'; + } else if (type === 'INR') { + decodeResult.formatted.description = 'In-Range Report'; } else if (type === 'LDI') { decodeResult.formatted.description = 'Load Distribution Information'; } else if (type === 'PER') { @@ -392,6 +394,8 @@ function processMessageType(decodeResult: DecodeResult, type: string): boolean { decodeResult.formatted.description = 'Progress Report'; } else if (type === 'PWI') { decodeResult.formatted.description = 'Pilot Weather Information'; + } else if (type === 'WXR') { + decodeResult.formatted.description = 'Weather Report'; } else if (type === 'REJ') { decodeResult.formatted.description = 'Reject'; } else if (type === 'REQ') { @@ -406,8 +410,6 @@ function processMessageType(decodeResult: DecodeResult, type: string): boolean { } function processDateCode(decodeResult: DecodeResult, data: string[]) { - decodeResult.raw.message_date = data[0]; // DDMMYYYY; - if (data.length === 1) { // noop? } else if (data.length === 2) { From 5b89861143a6a73a82bd65bbb003b0c1e9e3f7dc Mon Sep 17 00:00:00 2001 From: Mark Bumiller Date: Wed, 4 Mar 2026 21:35:38 -0500 Subject: [PATCH 3/3] fix --- lib/plugins/Label_16_AUTPOS.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/plugins/Label_16_AUTPOS.ts b/lib/plugins/Label_16_AUTPOS.ts index 7b8c343..258eaf9 100644 --- a/lib/plugins/Label_16_AUTPOS.ts +++ b/lib/plugins/Label_16_AUTPOS.ts @@ -111,10 +111,10 @@ export class Label_16_AUTPOS extends DecoderPlugin { const yy = dat.slice(0, 2); const mm = dat.slice(2, 4); const dd = dat.slice(4, 6); - const mmddyy = `${mm}${dd}${yy}`; + const ddmmyy = `${dd}${mm}${yy}`; ResultFormatter.timestamp( decodeResult, - DateTimeUtils.convertDateTimeToEpoch(tim, mmddyy), + DateTimeUtils.convertDateTimeToEpoch(tim, ddmmyy), ); } return decodeResult;