Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

initial H1 PWI decoding #138

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
53 changes: 53 additions & 0 deletions lib/plugins/Label_H1_PWI.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { MessageDecoder } from '../MessageDecoder';
import { Label_H1_PWI } from './Label_H1_PWI';

describe('Label_H1_PWI', () => {
let plugin: Label_H1_PWI;

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

test('matches Label H1 Preamble PWI qualifiers', () => {
expect(plugin.decode).toBeDefined();
expect(plugin.name).toBe('label-h1-pwi');
expect(plugin.qualifiers).toBeDefined();
expect(plugin.qualifiers()).toEqual({
labels: ['H1'],
preambles: ['PWI'],
});
});


test('decodes Label H1 Preamble PWI valid', () => {
const text = 'PWI/WD390,COLZI,258070.AWYAT,252071.IPTAY,250065.CHOPZ,244069.MGMRY,234065.CATLN,230060/WD340,COLZI,256073,340M41.AWYAT,252070,340M41.IPTAY,244059,340M41.CHOPZ,240059,340M41.MGMRY,232056,340M41.CATLN,218053,340M40/WD300,COLZI,256065.AWYAT,254062.IPTAY,250051.CHOPZ,248050.MGMRY,232044.CATLN,222047/WD240,COLZI,260045.AWYAT,258048.IPTAY,254043.CHOPZ,256041.MGMRY,238035.CATLN,226034/DD300214059.240214040.180236024.100250018:,,,,/CB300246040.240246017.180226015.1002100080338'
const decodeResult = plugin.decode({ text: text });

expect(decodeResult.decoded).toBe(true);
expect(decodeResult.decoder.decodeLevel).toBe('partial');
expect(decodeResult.formatted.items.length).toBe(25);
expect(decodeResult.formatted.items[0].type).toBe('wind_data');
expect(decodeResult.formatted.items[0].code).toBe('WIND');
expect(decodeResult.formatted.items[0].label).toBe('Wind Data');
expect(decodeResult.formatted.items[0].value).toBe('COLZI at FL390: 258° at 70kt');
expect(decodeResult.formatted.items[1].type).toBe('wind_data');
expect(decodeResult.formatted.items[1].code).toBe('WIND');
expect(decodeResult.formatted.items[1].label).toBe('Wind Data');
expect(decodeResult.formatted.items[1].value).toBe('AWYAT at FL390: 252° at 71kt');
expect(decodeResult.formatted.items[24].label).toBe('Message Checksum');
expect(decodeResult.formatted.items[24].value).toBe('0x0338');
});

test('decodes Label H1 Preamble POS <invalid>', () => {

const text = 'PWI 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-h1-pwi');
expect(decodeResult.formatted.description).toBe('Weather Report');
expect(decodeResult.message.text).toBe(text);
});
});
37 changes: 37 additions & 0 deletions lib/plugins/Label_H1_PWI.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { DecoderPlugin } from '../DecoderPlugin';
import { DecodeResult, Message, Options } from '../DecoderPluginInterface';
import { H1Helper } from '../utils/h1_helper';

export class Label_H1_PWI extends DecoderPlugin { // eslint-disable-line camelcase
name = 'label-h1-pwi';

qualifiers() { // eslint-disable-line class-methods-use-this
return {
labels: ['H1'],
preambles: ['PWI'],
};
}

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

const fulllyDecoded = H1Helper.decodeH1Message(decodeResult, message.text);
decodeResult.decoded = true;
decodeResult.decoder.decodeLevel = fulllyDecoded ? 'full' : 'partial';
if (decodeResult.formatted.items.length === 0) {
if (options?.debug) {
console.log(`Decoder: Unknown H1 message: ${message.text}`);
}
decodeResult.remaining.text = message.text;
decodeResult.decoded = false;
decodeResult.decoder.decodeLevel = 'none';
}
return decodeResult;
}
}

export default {};
54 changes: 54 additions & 0 deletions lib/utils/h1_helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ export class H1Helper {
label: 'Free Text',
value: decodeResult.raw.free_text,
});
} else if (fields[i].startsWith('WD')) {
const wd = processWindData(decodeResult, fields[i].substring(2)); // Strip off WD
allKnownFields = allKnownFields && wd;
} else {
decodeResult.remaining.text += '/' + fields[i];
allKnownFields = false
Expand Down Expand Up @@ -220,6 +223,57 @@ function processDC(decodeResult: DecodeResult, data: string[]): boolean {
}
return true;
}
function processWindData(decodeResult: DecodeResult, message: string): boolean {
if (decodeResult.raw.wind_data === undefined) {
decodeResult.raw.wind_data = [];
}
const flightLevel = Number(message.slice(0, 3));
const fields = message.slice(4).split('.'); // strip off altitude and comma
fields.forEach((field) => {
const data = field.split(',');
const waypoint = data[0];
const windData = data[1];
const windDirection = Number(windData.slice(0, 3));
const windSpeed = Number(windData.slice(3));

if (data.length === 3) {
const tempData = data[2];
const tempFlightLevel = Number(tempData.slice(0, 3));
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note that this usually matches flightLevel, sometimes it does not

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When it isn't matching flight level, what is it? Or is that still a mystery?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought i found a message that had the temp at a lower flight level, but now i can't find it

const tempString = tempData.slice(3);
const tempDegrees = Number(tempString.substring(1)) * (tempString.charAt(0) === 'M' ? -1 : 1);
decodeResult.raw.wind_data.push({
waypoint: waypoint,
flightLevel: flightLevel,
windDirection: windDirection,
windSpeed: windSpeed,
temperature: {
flightLevel: tempFlightLevel,
degreesC: tempDegrees
},
});
decodeResult.formatted.items.push({
type: 'wind_data',
code: 'WIND',
label: 'Wind Data',
value: `${waypoint} at FL${flightLevel}: ${windDirection}° at ${windSpeed}kt, ${tempDegrees}°C at FL${tempFlightLevel}`,
});
} else {
decodeResult.raw.wind_data.push({
waypoint: waypoint,
flightLevel: flightLevel,
windDirection: windDirection,
windSpeed: windSpeed,
});
decodeResult.formatted.items.push({
type: 'wind_data',
code: 'WIND',
label: 'Wind Data',
value: `${waypoint} at FL${flightLevel}: ${windDirection}° at ${windSpeed}kt`,
});
}
});
return true;
}

function processPS(decodeResult: DecodeResult, data: string[]): boolean {
let allKnownFields = true;
Expand Down