Skip to content

Commit

Permalink
adding OHMA decoding
Browse files Browse the repository at this point in the history
used on 737 MAX
  • Loading branch information
makrsmark committed Aug 2, 2024
1 parent 3a077e1 commit b6e4ad8
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 0 deletions.
53 changes: 53 additions & 0 deletions lib/plugins/Label_H1_OHMA.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { MessageDecoder } from '../MessageDecoder';
import { Label_H1_OHMA } from './Label_H1_OHMA';

test('matches Label H1 Preamble OHMA qualifiers', () => {
const decoder = new MessageDecoder();
const decoderPlugin = new Label_H1_OHMA(decoder);

expect(decoderPlugin.decode).toBeDefined();
expect(decoderPlugin.name).toBe('label-h1-ohma');
expect(decoderPlugin.qualifiers).toBeDefined();
expect(decoderPlugin.qualifiers()).toEqual({
labels: ['H1'],
preambles: ['OHMA'],
});
});

test('decodes Label H1 Preamble OHMA valid', () => {
const decoder = new MessageDecoder();
const decoderPlugin = new Label_H1_OHMA(decoder);

// https://app.airframes.io/messages/3126721669
const text = 'OHMAeJy1Ul2PojAU/SubPiuhlA/ljQHMkAElgDuTXTakqx2nCaAp1WQz8b/vFXTGEcw+LX26veece88p7+jARMO3NbKRpqhohCrWNHTDoH7P0arkrJbBOkd2jhaPkZOjUX6BeFSytqGpmj5WJ2NVyzC2ydTWiWJN9B8teE0lBRSIUS52Ja1ZA+VPqCXl5Xxf/WaiVZkTyzD0bsB2zcr2si1fS755kxfamu2okHvBHNDbCukCuMU+PSzSFk+F4Ada9vqLxLvSuxq9dELDtK56IdukEqZkvOpbVG0VXIJFYnYW2QFCuqzXFm5Jm+YcG2xLKyYFX32CB3V70XXQPzv2EX8R+Vn3BrxuJK1XH2HW9KxYyRgWv5gDJCSx72CnOH8dR1/RLhXl9+4f6MF1xRhgJPuSNUzeI1nE+hY5L7ZtO4/RmFjRQwj+4MNqCJf4pNhp/reosggXbhjEke8Fzrxwk2WQ+kUSZ8U/wgNi5kcxhpy9G2PENBVtqt+kcSZoQ4QJViyTDBO8YDYb4GBDwQTfUOIIx4mfpsvEH1xMhzHmfc7gbkTR1R7HcZ9m4eL53m5YmeAhTjA/jbrDMhULT08P3p0jOv4FG0dfvQ==';
const decodeResult = decoderPlugin.decode({ text: text });
console.log(JSON.stringify(decodeResult, null, 2));

expect(decodeResult.decoded).toBe(true);
expect(decodeResult.decoder.decodeLevel).toBe('full');
expect(decodeResult.decoder.name).toBe('label-h1-ohma');
expect(decodeResult.formatted.description).toBe('OHMA Message');
expect(decodeResult.message.text).toBe(text);
expect(decodeResult.raw.ohma).toBe('{\"version\":\"2.0\",\"message\":\"{\\\"clientId\\\":\\\"OHMA\\\",\\\"messageDate\\\":\\\"2024-08-02T11:39:43.784Z\\\",\\\"data\\\":{\\\"airplanes\\\":[{\\\"tailNumber\\\":\\\"N37554\\\",\\\"model\\\":\\\"\\\",\\\"flights\\\":[{\\\"departureAirportCode\\\":\\\"KBOS\\\",\\\"arrivalAirportCode\\\":\\\"KORD\\\",\\\"flightNumber\\\":\\\"UAL567\\\",\\\"flightLegStartTime\\\":\\\"2024-08-02T10:01:33.736Z\\\",\\\"events\\\":[{\\\"eventClassId\\\":\\\"parametric\\\",\\\"eventTime\\\":\\\"2024-08-02T11:39:43.784Z\\\",\\\"eventType\\\":\\\"OHMA_META\\\",\\\"instances\\\":[{\\\"name\\\":\\\"mtPartNumber\\\",\\\"values\\\":[\\\"\\\"]},{\\\"name\\\":\\\"mtCarlVersion\\\",\\\"values\\\":[\\\"4.5\\\"]},{\\\"name\\\":\\\"mtRulesetVersion\\\",\\\"values\\\":[\\\"737 MAX:::AHM-37MBL8-000010L:::1\\\"]}]},{\\\"eventClassId\\\":\\\"parametric\\\",\\\"eventTime\\\":\\\"2024-08-02T11:39:43.784Z\\\",\\\"eventType\\\":\\\"TM1_CLIPMEDIAN_CRUISE_RPT_A\\\",\\\"instances\\\":[{\\\"name\\\":\\\"TM1TEMP1_MED\\\",\\\"values\\\":[366.294]},{\\\"name\\\":\\\"TM1TEMP2_MED\\\",\\\"values\\\":[381.763]},{\\\"name\\\":\\\"TM1TEMPDIFF_MED\\\",\\\"values\\\":[15.131]},{\\\"name\\\":\\\"PM1PRESSURE1_MED\\\",\\\"values\\\":[34.766]},{\\\"name\\\":\\\"PM1PRESSURE2_MED\\\",\\\"values\\\":[33.406]},{\\\"name\\\":\\\"PACKFLOWDIFF_MED\\\",\\\"values\\\":[11.816]},{\\\"name\\\":\\\"PACKINPRESDIFF_MED\\\",\\\"values\\\":[6.719]}]}]}]}]}}\"}');
expect(decodeResult.formatted.items.length).toBe(1);
expect(decodeResult.formatted.items[0].type).toBe('ohma');
expect(decodeResult.formatted.items[0].code).toBe('OHMA');
expect(decodeResult.formatted.items[0].label).toBe('OHMA Downlink');
expect(decodeResult.formatted.items[0].value.length).toBe(2658)}); // instead of comparing to a giant json obj


test('decodes Label H1 Preamble OHMA invalid', () => {
const decoder = new MessageDecoder();
const decoderPlugin = new Label_H1_OHMA(decoder);

const text = 'OHMA <Invalid text>';
const decodeResult = decoderPlugin.decode({ text: text });
console.log(JSON.stringify(decodeResult, null, 2));

expect(decodeResult.decoded).toBe(false);
expect(decodeResult.decoder.decodeLevel).toBe('none');
expect(decodeResult.decoder.name).toBe('label-h1-ohma');
expect(decodeResult.formatted.description).toBe('OHMA Message');
expect(decodeResult.message.text).toBe(text);
expect(decodeResult.remaining.text).toBe(text);
});
59 changes: 59 additions & 0 deletions lib/plugins/Label_H1_OHMA.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { DecoderPlugin } from '../DecoderPlugin';
import { DecodeResult, Message, Options } from '../DecoderPluginInterface';

import * as zlib from "minizlib";

export class Label_H1_OHMA extends DecoderPlugin {
name = 'label-h1-ohma';

qualifiers() { // eslint-disable-line class-methods-use-this
return {
labels: ["H1"],
preambles: ['OHMA'], //TODO - support data before #
};
}

decode(message: Message, options: Options = {}) : DecodeResult {
let decodeResult: any = this.defaultResult;
decodeResult.decoder.name = this.name;
decodeResult.formatted.description = 'OHMA Message';
decodeResult.message = message;
decodeResult.remaining.text = '';

const data = message.text.slice(4);

try {
const compressedBuffer = Buffer.from(data, 'base64');
const decompress = new zlib.Inflate({windowBits: 15});
decompress.write(compressedBuffer);
decompress.flush(zlib.constants.Z_SYNC_FLUSH);
const result = decompress.read();
const jsonText = result.toString();
const json = JSON.parse(jsonText);
const ohmaMsg = JSON.parse(json.message);

decodeResult.decoded = true;
decodeResult.decoder.decodeLevel = 'full';
decodeResult.raw.ohma = jsonText;
decodeResult.formatted.items.push({
type: 'ohma',
code: 'OHMA' ,
label: 'OHMA Downlink',
value: JSON.stringify(ohmaMsg, null, 2)
});
} catch {
// Unknown
if (options.debug) {
console.log(`Decoder: Unknown H1 OHMA message: ${message.text}`);
}
decodeResult.remaining.text += message.text;
decodeResult.decoded = false;
decodeResult.decoder.decodeLevel = 'none';
}

return decodeResult;
}
}

export default {};

0 comments on commit b6e4ad8

Please sign in to comment.