@airframes/acars-decoder 1.8.10 → 1.8.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1644 -1652
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1644 -1652
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -441,15 +441,6 @@ var ResultFormatter = class {
|
|
|
441
441
|
value: `${from} -> ${to}`
|
|
442
442
|
});
|
|
443
443
|
}
|
|
444
|
-
static freetext(decodeResult, value) {
|
|
445
|
-
decodeResult.raw.freetext = value;
|
|
446
|
-
decodeResult.formatted.items.push({
|
|
447
|
-
type: "freetext",
|
|
448
|
-
code: "FREE_TEXT",
|
|
449
|
-
label: "Free Text",
|
|
450
|
-
value
|
|
451
|
-
});
|
|
452
|
-
}
|
|
453
444
|
static door_event(decodeResult, name, state) {
|
|
454
445
|
decodeResult.raw.door_event = {
|
|
455
446
|
door: name,
|
|
@@ -966,6 +957,24 @@ var ResultFormatter = class {
|
|
|
966
957
|
value: DateTimeUtils.timestampToString(value, "epoch")
|
|
967
958
|
});
|
|
968
959
|
}
|
|
960
|
+
static sequenceNumber(decodeResult, value) {
|
|
961
|
+
decodeResult.raw.sequence_number = value;
|
|
962
|
+
decodeResult.formatted.items.push({
|
|
963
|
+
type: "sequence",
|
|
964
|
+
code: "SEQ",
|
|
965
|
+
label: "Sequence Number",
|
|
966
|
+
value: decodeResult.raw.sequence_number
|
|
967
|
+
});
|
|
968
|
+
}
|
|
969
|
+
static sequenceResponse(decodeResult, value) {
|
|
970
|
+
decodeResult.raw.sequence_response = value;
|
|
971
|
+
decodeResult.formatted.items.push({
|
|
972
|
+
type: "sequence",
|
|
973
|
+
code: "SEQ_RESP",
|
|
974
|
+
label: "Sequence Response",
|
|
975
|
+
value: decodeResult.raw.sequence_response
|
|
976
|
+
});
|
|
977
|
+
}
|
|
969
978
|
static unknown(decodeResult, value, sep = ",") {
|
|
970
979
|
if (!decodeResult.remaining.text) decodeResult.remaining.text = value;
|
|
971
980
|
else decodeResult.remaining.text += sep + value;
|
|
@@ -1867,890 +1876,546 @@ var Label_16_TOD = class extends DecoderPlugin {
|
|
|
1867
1876
|
}
|
|
1868
1877
|
};
|
|
1869
1878
|
|
|
1870
|
-
// lib/
|
|
1871
|
-
var
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
* @param data - original message split by ':'
|
|
1879
|
-
* @returns whether all fields were processed or not
|
|
1880
|
-
*/
|
|
1881
|
-
static processFlightPlan(decodeResult, data) {
|
|
1882
|
-
let allKnownFields = _FlightPlanUtils.parseHeader(decodeResult, data[0]);
|
|
1883
|
-
for (let i = 1; i < data.length; i += 2) {
|
|
1884
|
-
const key = data[i];
|
|
1885
|
-
const value = data[i + 1];
|
|
1886
|
-
switch (key) {
|
|
1887
|
-
case "A":
|
|
1888
|
-
_FlightPlanUtils.addProcedure(decodeResult, value, "arrival");
|
|
1889
|
-
break;
|
|
1890
|
-
case "AA":
|
|
1891
|
-
addArrivalAirport(decodeResult, value);
|
|
1892
|
-
break;
|
|
1893
|
-
case "AP":
|
|
1894
|
-
_FlightPlanUtils.addProcedure(decodeResult, value, "approach");
|
|
1895
|
-
break;
|
|
1896
|
-
case "CR":
|
|
1897
|
-
addCompanyRoute(decodeResult, value);
|
|
1898
|
-
break;
|
|
1899
|
-
case "D":
|
|
1900
|
-
_FlightPlanUtils.addProcedure(decodeResult, value, "departure");
|
|
1901
|
-
break;
|
|
1902
|
-
case "DA":
|
|
1903
|
-
addDepartureAirport(decodeResult, value);
|
|
1904
|
-
break;
|
|
1905
|
-
case "F":
|
|
1906
|
-
addRoute(decodeResult, value);
|
|
1907
|
-
break;
|
|
1908
|
-
case "FP":
|
|
1909
|
-
ResultFormatter.flightPlan(decodeResult, value.trim());
|
|
1910
|
-
break;
|
|
1911
|
-
case "R":
|
|
1912
|
-
addRunway(decodeResult, value);
|
|
1913
|
-
break;
|
|
1914
|
-
// case 'WS': // something about routes, has altitude, so current parsing won't work
|
|
1915
|
-
// break;
|
|
1916
|
-
default:
|
|
1917
|
-
if (allKnownFields) {
|
|
1918
|
-
decodeResult.remaining.text = "";
|
|
1919
|
-
allKnownFields = false;
|
|
1920
|
-
}
|
|
1921
|
-
decodeResult.remaining.text += `:${key}:${value}`;
|
|
1922
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
1923
|
-
}
|
|
1924
|
-
}
|
|
1925
|
-
return allKnownFields;
|
|
1879
|
+
// lib/plugins/Label_1M_Slash.ts
|
|
1880
|
+
var Label_1M_Slash = class extends DecoderPlugin {
|
|
1881
|
+
name = "label-1m-slash";
|
|
1882
|
+
qualifiers() {
|
|
1883
|
+
return {
|
|
1884
|
+
labels: ["1M"],
|
|
1885
|
+
preambles: ["/"]
|
|
1886
|
+
};
|
|
1926
1887
|
}
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
if (header.length > 2) {
|
|
1938
|
-
addRoute(decodeResult, header.substring(2));
|
|
1888
|
+
decode(message, options = {}) {
|
|
1889
|
+
const decodeResult = this.defaultResult();
|
|
1890
|
+
decodeResult.decoder.name = this.name;
|
|
1891
|
+
decodeResult.formatted.description = "ETA Report";
|
|
1892
|
+
decodeResult.message = message;
|
|
1893
|
+
const results = message.text.split(/\n|\//).slice(1);
|
|
1894
|
+
if (results) {
|
|
1895
|
+
if (options.debug) {
|
|
1896
|
+
console.log("Label 1M ETA: results");
|
|
1897
|
+
console.log(results);
|
|
1939
1898
|
}
|
|
1940
|
-
|
|
1941
|
-
decodeResult
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
} else if (header.startsWith("RM")) {
|
|
1958
|
-
decodeResult.raw.route_status = "RM";
|
|
1959
|
-
decodeResult.formatted.items.push({
|
|
1960
|
-
type: "status",
|
|
1961
|
-
code: "ROUTE_STATUS",
|
|
1962
|
-
label: "Route Status",
|
|
1963
|
-
value: "Route Mapped"
|
|
1964
|
-
});
|
|
1965
|
-
} else if (header.startsWith("RS")) {
|
|
1966
|
-
decodeResult.raw.route_status = "RS";
|
|
1967
|
-
decodeResult.formatted.items.push({
|
|
1968
|
-
type: "status",
|
|
1969
|
-
code: "ROUTE_STATUS",
|
|
1970
|
-
label: "Route Status",
|
|
1971
|
-
value: "Route Saved"
|
|
1972
|
-
});
|
|
1973
|
-
} else {
|
|
1974
|
-
decodeResult.remaining.text += header;
|
|
1975
|
-
allKnownFields = false;
|
|
1976
|
-
}
|
|
1977
|
-
return allKnownFields;
|
|
1978
|
-
}
|
|
1979
|
-
static addProcedure(decodeResult, value, type) {
|
|
1980
|
-
if (decodeResult.raw.procedures === void 0) {
|
|
1981
|
-
decodeResult.raw.procedures = [];
|
|
1982
|
-
}
|
|
1983
|
-
const data = value.split(".");
|
|
1984
|
-
let waypoints;
|
|
1985
|
-
if (data.length > 1) {
|
|
1986
|
-
waypoints = data.slice(1).map((leg) => RouteUtils.getWaypoint(leg));
|
|
1899
|
+
decodeResult.raw.flight_number = results[0];
|
|
1900
|
+
ResultFormatter.departureAirport(decodeResult, results[3]);
|
|
1901
|
+
ResultFormatter.arrivalAirport(decodeResult, results[4]);
|
|
1902
|
+
ResultFormatter.alternateAirport(decodeResult, results[5]);
|
|
1903
|
+
ResultFormatter.arrivalRunway(
|
|
1904
|
+
decodeResult,
|
|
1905
|
+
results[8].replace(results[4], "")
|
|
1906
|
+
);
|
|
1907
|
+
const yymmdd = results[2];
|
|
1908
|
+
ResultFormatter.eta(
|
|
1909
|
+
decodeResult,
|
|
1910
|
+
DateTimeUtils.convertDateTimeToEpoch(
|
|
1911
|
+
results[7] + "00",
|
|
1912
|
+
yymmdd.substring(4, 6) + yymmdd.substring(2, 4) + yymmdd.substring(0, 2)
|
|
1913
|
+
),
|
|
1914
|
+
"epoch"
|
|
1915
|
+
);
|
|
1987
1916
|
}
|
|
1988
|
-
|
|
1989
|
-
decodeResult.
|
|
1990
|
-
|
|
1991
|
-
decodeResult.formatted.items.push({
|
|
1992
|
-
type: "procedure",
|
|
1993
|
-
code: "proc",
|
|
1994
|
-
label: `${procedureName} Procedure`,
|
|
1995
|
-
value: RouteUtils.routeToString(route)
|
|
1996
|
-
});
|
|
1917
|
+
decodeResult.decoded = true;
|
|
1918
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
1919
|
+
return decodeResult;
|
|
1997
1920
|
}
|
|
1998
1921
|
};
|
|
1999
|
-
function addArrivalAirport(decodeResult, value) {
|
|
2000
|
-
ResultFormatter.arrivalAirport(decodeResult, value);
|
|
2001
|
-
}
|
|
2002
|
-
function addDepartureAirport(decodeResult, value) {
|
|
2003
|
-
ResultFormatter.departureAirport(decodeResult, value);
|
|
2004
|
-
}
|
|
2005
|
-
function addRunway(decodeResult, value) {
|
|
2006
|
-
if (value.length === 8) {
|
|
2007
|
-
ResultFormatter.arrivalRunway(decodeResult, value.substring(4, 7));
|
|
2008
|
-
}
|
|
2009
|
-
ResultFormatter.departureRunway(decodeResult, value.substring(0, 3));
|
|
2010
|
-
}
|
|
2011
|
-
function addRoute(decodeResult, value) {
|
|
2012
|
-
const route = value.split(".");
|
|
2013
|
-
ResultFormatter.route(decodeResult, {
|
|
2014
|
-
waypoints: route.map((leg) => RouteUtils.getWaypoint(leg))
|
|
2015
|
-
});
|
|
2016
|
-
}
|
|
2017
|
-
function addCompanyRoute(decodeResult, value) {
|
|
2018
|
-
const segments = value.split(".");
|
|
2019
|
-
const parens_idx = segments[0].indexOf("(");
|
|
2020
|
-
let name;
|
|
2021
|
-
let runway;
|
|
2022
|
-
if (parens_idx === -1) {
|
|
2023
|
-
name = segments[0];
|
|
2024
|
-
} else {
|
|
2025
|
-
name = segments[0].slice(0, parens_idx);
|
|
2026
|
-
runway = segments[0].slice(parens_idx + 1, segments[0].indexOf(")"));
|
|
2027
|
-
}
|
|
2028
|
-
let waypoints;
|
|
2029
|
-
if (segments.length > 1) {
|
|
2030
|
-
waypoints = segments.slice(1).map((leg) => RouteUtils.getWaypoint(leg));
|
|
2031
|
-
}
|
|
2032
|
-
decodeResult.raw.company_route = {
|
|
2033
|
-
name,
|
|
2034
|
-
runway,
|
|
2035
|
-
waypoints
|
|
2036
|
-
};
|
|
2037
|
-
decodeResult.formatted.items.push({
|
|
2038
|
-
type: "company_route",
|
|
2039
|
-
code: "CR",
|
|
2040
|
-
label: "Company Route",
|
|
2041
|
-
value: RouteUtils.routeToString(decodeResult.raw.company_route)
|
|
2042
|
-
});
|
|
2043
|
-
}
|
|
2044
1922
|
|
|
2045
|
-
// lib/
|
|
2046
|
-
var
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
1923
|
+
// lib/plugins/Label_1L_3-line.ts
|
|
1924
|
+
var Label_1L_3Line = class extends DecoderPlugin {
|
|
1925
|
+
name = "label-1l-3-line";
|
|
1926
|
+
qualifiers() {
|
|
1927
|
+
return {
|
|
1928
|
+
labels: ["1L"]
|
|
1929
|
+
};
|
|
1930
|
+
}
|
|
1931
|
+
decode(message, options = {}) {
|
|
1932
|
+
const decodeResult = this.defaultResult();
|
|
1933
|
+
decodeResult.decoder.name = this.name;
|
|
1934
|
+
decodeResult.formatted.description = "Position Report";
|
|
1935
|
+
decodeResult.message = message;
|
|
1936
|
+
const lines = message.text.split("\r\n");
|
|
1937
|
+
if (lines.length !== 3) {
|
|
1938
|
+
if (options.debug) {
|
|
1939
|
+
console.log(`Decoder: Unknown 1L message: ${message.text}`);
|
|
1940
|
+
}
|
|
1941
|
+
decodeResult.remaining.text = message.text;
|
|
2056
1942
|
decodeResult.decoded = false;
|
|
2057
1943
|
decodeResult.decoder.decodeLevel = "none";
|
|
2058
|
-
return
|
|
1944
|
+
return decodeResult;
|
|
2059
1945
|
}
|
|
2060
|
-
const
|
|
2061
|
-
const
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
1946
|
+
const parts = message.text.replaceAll("\r\n", "/").split("/");
|
|
1947
|
+
const data = /* @__PURE__ */ new Map();
|
|
1948
|
+
data.set("", parts[0]);
|
|
1949
|
+
for (let i = 1; i < parts.length; i++) {
|
|
1950
|
+
const part = parts[i].split(" ");
|
|
1951
|
+
data.set(part[0], part.slice(1).join(" "));
|
|
2066
1952
|
}
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
case "AF":
|
|
2072
|
-
processAirField(decodeResult, data2.split(","));
|
|
2073
|
-
break;
|
|
2074
|
-
case "AK":
|
|
2075
|
-
ResultFormatter.unknown(decodeResult, fields[i], "/");
|
|
2076
|
-
break;
|
|
2077
|
-
case "CG":
|
|
2078
|
-
processCenterOfGravity(decodeResult, data2.split(","));
|
|
2079
|
-
break;
|
|
2080
|
-
case "DC":
|
|
2081
|
-
processDateCode(decodeResult, data2.split(","));
|
|
2082
|
-
break;
|
|
2083
|
-
case "DI":
|
|
2084
|
-
ResultFormatter.unknown(decodeResult, fields[i], "/");
|
|
2085
|
-
break;
|
|
2086
|
-
case "DT":
|
|
2087
|
-
processDT(decodeResult, data2.split(","));
|
|
2088
|
-
break;
|
|
2089
|
-
case "DQ":
|
|
2090
|
-
ResultFormatter.desiredAltitude(
|
|
2091
|
-
decodeResult,
|
|
2092
|
-
parseInt(data2, 10) * 100
|
|
2093
|
-
);
|
|
2094
|
-
break;
|
|
2095
|
-
case "ET":
|
|
2096
|
-
processETA(data2, decodeResult, fields, i);
|
|
2097
|
-
break;
|
|
2098
|
-
case "FB":
|
|
2099
|
-
ResultFormatter.currentFuel(decodeResult, parseInt(data2, 10));
|
|
2100
|
-
break;
|
|
2101
|
-
case "FN":
|
|
2102
|
-
decodeResult.raw.flight_number = data2;
|
|
2103
|
-
break;
|
|
2104
|
-
case "FX":
|
|
2105
|
-
ResultFormatter.freetext(decodeResult, data2);
|
|
2106
|
-
break;
|
|
2107
|
-
case "GA":
|
|
2108
|
-
ResultFormatter.groundAddress(decodeResult, data2);
|
|
2109
|
-
break;
|
|
2110
|
-
case "ID":
|
|
2111
|
-
processIdentification(decodeResult, data2.split(","));
|
|
2112
|
-
break;
|
|
2113
|
-
case "LR":
|
|
2114
|
-
processLandingReport(decodeResult, data2.split(","));
|
|
2115
|
-
break;
|
|
2116
|
-
case "PR":
|
|
2117
|
-
ResultFormatter.unknown(decodeResult, fields[i], "/");
|
|
2118
|
-
break;
|
|
2119
|
-
case "PS":
|
|
2120
|
-
_H1Helper.processPS(decodeResult, data2.split(","));
|
|
2121
|
-
break;
|
|
2122
|
-
case "RF":
|
|
2123
|
-
case "RI":
|
|
2124
|
-
case "RM":
|
|
2125
|
-
case "RP":
|
|
2126
|
-
case "RS":
|
|
2127
|
-
FlightPlanUtils.processFlightPlan(decodeResult, fields[i].split(":"));
|
|
2128
|
-
break;
|
|
2129
|
-
case "RN":
|
|
2130
|
-
ResultFormatter.routeNumber(decodeResult, data2);
|
|
2131
|
-
break;
|
|
2132
|
-
case "RW":
|
|
2133
|
-
processRunway(decodeResult, data2.split(":"));
|
|
2134
|
-
break;
|
|
2135
|
-
case "SN":
|
|
2136
|
-
decodeResult.raw.serial_number = data2;
|
|
2137
|
-
break;
|
|
2138
|
-
case "SP":
|
|
2139
|
-
ResultFormatter.startPoint(decodeResult, data2);
|
|
2140
|
-
break;
|
|
2141
|
-
case "TD":
|
|
2142
|
-
processTimeOfDeparture(decodeResult, data2.split(","));
|
|
2143
|
-
break;
|
|
2144
|
-
case "TS":
|
|
2145
|
-
_H1Helper.processTimeStamp(decodeResult, data2.split(","));
|
|
2146
|
-
break;
|
|
2147
|
-
case "VR":
|
|
2148
|
-
ResultFormatter.version(decodeResult, parseInt(data2, 10) / 10);
|
|
2149
|
-
break;
|
|
2150
|
-
case "WD":
|
|
2151
|
-
processWindData(decodeResult, data2);
|
|
2152
|
-
break;
|
|
2153
|
-
case "WQ":
|
|
2154
|
-
processWeatherQuery(decodeResult, data2.split(":"));
|
|
2155
|
-
break;
|
|
2156
|
-
default:
|
|
2157
|
-
ResultFormatter.unknown(decodeResult, fields[i], "/");
|
|
2158
|
-
}
|
|
2159
|
-
}
|
|
2160
|
-
ResultFormatter.checksumAlgorithm(decodeResult, checksumAlgorithmUsed);
|
|
2161
|
-
ResultFormatter.checksum(decodeResult, checksum);
|
|
2162
|
-
return true;
|
|
2163
|
-
}
|
|
2164
|
-
static processPS(decodeResult, data) {
|
|
2165
|
-
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(
|
|
2166
|
-
data[0]
|
|
2167
|
-
);
|
|
2168
|
-
if (position) {
|
|
2169
|
-
ResultFormatter.position(decodeResult, position);
|
|
1953
|
+
const dep = data.get("DEP");
|
|
1954
|
+
if (dep) {
|
|
1955
|
+
ResultFormatter.departureAirport(decodeResult, dep);
|
|
1956
|
+
data.delete("DEP");
|
|
2170
1957
|
}
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
ResultFormatter.
|
|
2174
|
-
|
|
2175
|
-
ResultFormatter.unknown(decodeResult, data[7]);
|
|
2176
|
-
ResultFormatter.unknown(decodeResult, data[8]);
|
|
1958
|
+
const des = data.get("DES");
|
|
1959
|
+
if (des) {
|
|
1960
|
+
ResultFormatter.arrivalAirport(decodeResult, des);
|
|
1961
|
+
data.delete("DES");
|
|
2177
1962
|
}
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
ResultFormatter.unknownArr(decodeResult, data.slice(8));
|
|
1963
|
+
const eta = data.get("ETA");
|
|
1964
|
+
if (eta) {
|
|
1965
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(eta));
|
|
1966
|
+
data.delete("ETA");
|
|
2183
1967
|
}
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
data
|
|
2188
|
-
);
|
|
2189
|
-
if (position) {
|
|
2190
|
-
ResultFormatter.position(decodeResult, position);
|
|
1968
|
+
const alt = data.get("ALT");
|
|
1969
|
+
if (alt) {
|
|
1970
|
+
ResultFormatter.altitude(decodeResult, Number(alt));
|
|
1971
|
+
data.delete("ALT");
|
|
2191
1972
|
}
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
ResultFormatter.unknown(decodeResult, data[8]);
|
|
2197
|
-
ResultFormatter.unknown(decodeResult, data[9]);
|
|
1973
|
+
const fn = data.get("FN");
|
|
1974
|
+
if (fn) {
|
|
1975
|
+
ResultFormatter.flightNumber(decodeResult, fn);
|
|
1976
|
+
data.delete("FN");
|
|
2198
1977
|
}
|
|
2199
|
-
|
|
2200
|
-
|
|
1978
|
+
const day = data.get("DAY");
|
|
1979
|
+
const utc = data.get("UTC");
|
|
1980
|
+
if (day && utc) {
|
|
1981
|
+
decodeResult.raw.message_timestamp = Date.parse(day + " GMT+0000") / 1e3 + DateTimeUtils.convertHHMMSSToTod(utc);
|
|
1982
|
+
data.delete("DAY");
|
|
1983
|
+
data.delete("UTC");
|
|
2201
1984
|
}
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
if (
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
1985
|
+
const lat = data.get("LAT");
|
|
1986
|
+
const lon = data.get("LON");
|
|
1987
|
+
if (lat && lon) {
|
|
1988
|
+
ResultFormatter.position(decodeResult, {
|
|
1989
|
+
latitude: CoordinateUtils.getDirection(lat[0]) * Number(lat.substring(1)),
|
|
1990
|
+
longitude: CoordinateUtils.getDirection(lon[0]) * Number(lon.substring(1))
|
|
1991
|
+
});
|
|
1992
|
+
data.delete("LAT");
|
|
1993
|
+
data.delete("LON");
|
|
2208
1994
|
}
|
|
2209
|
-
let
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
1995
|
+
let remaining = "";
|
|
1996
|
+
for (const [key, value] of data.entries()) {
|
|
1997
|
+
if (key === "") {
|
|
1998
|
+
remaining += value;
|
|
1999
|
+
} else {
|
|
2000
|
+
remaining += `/${key} ${value}`;
|
|
2001
|
+
}
|
|
2216
2002
|
}
|
|
2217
|
-
decodeResult.
|
|
2003
|
+
decodeResult.remaining.text = remaining;
|
|
2004
|
+
decodeResult.decoded = true;
|
|
2005
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
2006
|
+
return decodeResult;
|
|
2218
2007
|
}
|
|
2219
2008
|
};
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2009
|
+
|
|
2010
|
+
// lib/plugins/Label_1L_070.ts
|
|
2011
|
+
var Label_1L_070 = class extends DecoderPlugin {
|
|
2012
|
+
name = "label-1l-070";
|
|
2013
|
+
qualifiers() {
|
|
2014
|
+
return {
|
|
2015
|
+
labels: ["1L"],
|
|
2016
|
+
preambles: ["000000070"]
|
|
2017
|
+
};
|
|
2018
|
+
}
|
|
2019
|
+
decode(message, options = {}) {
|
|
2020
|
+
const decodeResult = this.defaultResult();
|
|
2021
|
+
decodeResult.decoder.name = this.name;
|
|
2022
|
+
decodeResult.formatted.description = "Position Report";
|
|
2023
|
+
decodeResult.message = message;
|
|
2024
|
+
if (!message.text.startsWith("000000070")) {
|
|
2025
|
+
if (options.debug) {
|
|
2026
|
+
console.log(`Decoder: Unknown 1L message: ${message.text}`);
|
|
2027
|
+
}
|
|
2028
|
+
decodeResult.remaining.text = message.text;
|
|
2029
|
+
decodeResult.decoded = false;
|
|
2030
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2031
|
+
return decodeResult;
|
|
2032
|
+
}
|
|
2033
|
+
const parts = message.text.substring(9).split(",");
|
|
2034
|
+
if (parts.length !== 7) {
|
|
2035
|
+
if (options.debug) {
|
|
2036
|
+
console.log(`Decoder: Unknown 1L message: ${message.text}`);
|
|
2037
|
+
}
|
|
2038
|
+
decodeResult.remaining.text = message.text;
|
|
2039
|
+
decodeResult.decoded = false;
|
|
2040
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2041
|
+
return decodeResult;
|
|
2042
|
+
}
|
|
2043
|
+
ResultFormatter.departureAirport(decodeResult, parts[0]);
|
|
2044
|
+
ResultFormatter.arrivalAirport(decodeResult, parts[1]);
|
|
2045
|
+
ResultFormatter.time_of_day(
|
|
2224
2046
|
decodeResult,
|
|
2225
|
-
DateTimeUtils.convertHHMMSSToTod(
|
|
2047
|
+
DateTimeUtils.convertHHMMSSToTod(parts[2])
|
|
2226
2048
|
);
|
|
2227
|
-
} else if (data.length === 6) {
|
|
2228
|
-
ResultFormatter.day(decodeResult, Number(data.substring(0, 2)));
|
|
2229
2049
|
ResultFormatter.eta(
|
|
2230
2050
|
decodeResult,
|
|
2231
|
-
DateTimeUtils.convertHHMMSSToTod(
|
|
2051
|
+
DateTimeUtils.convertHHMMSSToTod(parts[3])
|
|
2232
2052
|
);
|
|
2233
|
-
|
|
2234
|
-
|
|
2053
|
+
ResultFormatter.position(decodeResult, {
|
|
2054
|
+
latitude: CoordinateUtils.getDirection(parts[4][0]) * Number(parts[4].substring(1)),
|
|
2055
|
+
longitude: CoordinateUtils.getDirection(parts[5][0]) * Number(parts[5].substring(1))
|
|
2056
|
+
});
|
|
2057
|
+
decodeResult.remaining.text = parts[6];
|
|
2058
|
+
decodeResult.decoded = true;
|
|
2059
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
2060
|
+
return decodeResult;
|
|
2235
2061
|
}
|
|
2236
|
-
}
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2062
|
+
};
|
|
2063
|
+
|
|
2064
|
+
// lib/plugins/Label_1L_660.ts
|
|
2065
|
+
var Label_1L_660 = class extends DecoderPlugin {
|
|
2066
|
+
name = "label-1l-660";
|
|
2067
|
+
qualifiers() {
|
|
2068
|
+
return {
|
|
2069
|
+
labels: ["1L"],
|
|
2070
|
+
preambles: ["000000660"]
|
|
2071
|
+
};
|
|
2243
2072
|
}
|
|
2244
|
-
}
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
decodeResult.
|
|
2248
|
-
decodeResult.
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
code: "etd",
|
|
2258
|
-
label: "Estimated Departure Time",
|
|
2259
|
-
value: `${data[1].substring(0, 2)}:${data[1].substring(2)}`
|
|
2260
|
-
});
|
|
2261
|
-
} else {
|
|
2262
|
-
ResultFormatter.unknown(decodeResult, data.join(","), "/TD");
|
|
2263
|
-
}
|
|
2264
|
-
}
|
|
2265
|
-
function processIdentification(decodeResult, data) {
|
|
2266
|
-
ResultFormatter.tail(decodeResult, data[0]);
|
|
2267
|
-
if (data.length > 1) {
|
|
2268
|
-
ResultFormatter.flightNumber(decodeResult, data[1]);
|
|
2269
|
-
}
|
|
2270
|
-
if (data.length > 2) {
|
|
2271
|
-
decodeResult.raw.mission_number = data[2];
|
|
2272
|
-
}
|
|
2273
|
-
}
|
|
2274
|
-
function processDT(decodeResult, data) {
|
|
2275
|
-
if (data.length === 9) {
|
|
2276
|
-
ResultFormatter.unknown(decodeResult, data[0]);
|
|
2277
|
-
if (!decodeResult.raw.arrival_icao) {
|
|
2278
|
-
ResultFormatter.arrivalAirport(decodeResult, data[1]);
|
|
2073
|
+
decode(message, options = {}) {
|
|
2074
|
+
const decodeResult = this.defaultResult();
|
|
2075
|
+
decodeResult.decoder.name = this.name;
|
|
2076
|
+
decodeResult.formatted.description = "Position Report";
|
|
2077
|
+
decodeResult.message = message;
|
|
2078
|
+
if (!message.text.startsWith("000000660")) {
|
|
2079
|
+
if (options.debug) {
|
|
2080
|
+
console.log(`Decoder: Unknown 1L message: ${message.text}`);
|
|
2081
|
+
}
|
|
2082
|
+
decodeResult.remaining.text = message.text;
|
|
2083
|
+
decodeResult.decoded = false;
|
|
2084
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2085
|
+
return decodeResult;
|
|
2279
2086
|
}
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
decodeResult
|
|
2289
|
-
|
|
2087
|
+
const parts = message.text.substring(9).split(",");
|
|
2088
|
+
if (parts.length !== 5) {
|
|
2089
|
+
if (options.debug) {
|
|
2090
|
+
console.log(`Decoder: Unknown 1L message: ${message.text}`);
|
|
2091
|
+
}
|
|
2092
|
+
decodeResult.remaining.text = message.text;
|
|
2093
|
+
decodeResult.decoded = false;
|
|
2094
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2095
|
+
return decodeResult;
|
|
2096
|
+
}
|
|
2097
|
+
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(
|
|
2098
|
+
parts[0]
|
|
2290
2099
|
);
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
return;
|
|
2294
|
-
}
|
|
2295
|
-
if (data.length === 4 || data.length === 5) {
|
|
2296
|
-
if (!decodeResult.raw.arrival_icao) {
|
|
2297
|
-
ResultFormatter.arrivalAirport(decodeResult, data[0]);
|
|
2100
|
+
if (position) {
|
|
2101
|
+
ResultFormatter.position(decodeResult, position);
|
|
2298
2102
|
}
|
|
2299
|
-
|
|
2300
|
-
ResultFormatter.
|
|
2301
|
-
ResultFormatter.eta(
|
|
2103
|
+
const hhmmss = parts[1].substring(0, 6);
|
|
2104
|
+
ResultFormatter.time_of_day(
|
|
2302
2105
|
decodeResult,
|
|
2303
|
-
DateTimeUtils.convertHHMMSSToTod(
|
|
2106
|
+
DateTimeUtils.convertHHMMSSToTod(hhmmss)
|
|
2304
2107
|
);
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2108
|
+
const fl = parts[1].substring(6, 9);
|
|
2109
|
+
ResultFormatter.altitude(decodeResult, Number(fl) * 100);
|
|
2110
|
+
const next = parts[1].substring(9);
|
|
2111
|
+
ResultFormatter.route(decodeResult, { waypoints: [{ name: next.trim() }] });
|
|
2112
|
+
decodeResult.remaining.text = parts.slice(2).join(",");
|
|
2113
|
+
decodeResult.decoded = true;
|
|
2114
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
2115
|
+
return decodeResult;
|
|
2309
2116
|
}
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
} else {
|
|
2321
|
-
ResultFormatter.unknown(decodeResult, data.join(","));
|
|
2117
|
+
};
|
|
2118
|
+
|
|
2119
|
+
// lib/plugins/Label_1L_Slash.ts
|
|
2120
|
+
var Label_1L_Slash = class extends DecoderPlugin {
|
|
2121
|
+
name = "label-1l-1-line";
|
|
2122
|
+
qualifiers() {
|
|
2123
|
+
return {
|
|
2124
|
+
labels: ["1L"],
|
|
2125
|
+
preambles: ["+", "-"]
|
|
2126
|
+
};
|
|
2322
2127
|
}
|
|
2323
|
-
}
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2128
|
+
decode(message, options = {}) {
|
|
2129
|
+
const decodeResult = this.defaultResult();
|
|
2130
|
+
decodeResult.decoder.name = this.name;
|
|
2131
|
+
decodeResult.formatted.description = "Position Report";
|
|
2132
|
+
decodeResult.message = message;
|
|
2133
|
+
const parts = message.text.split("/");
|
|
2134
|
+
if (parts.length !== 7) {
|
|
2135
|
+
if (options.debug) {
|
|
2136
|
+
console.log(`Decoder: Unknown 1L message: ${message.text}`);
|
|
2137
|
+
}
|
|
2138
|
+
decodeResult.remaining.text = message.text;
|
|
2139
|
+
decodeResult.decoded = false;
|
|
2140
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2141
|
+
return decodeResult;
|
|
2328
2142
|
}
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2143
|
+
const data = /* @__PURE__ */ new Map();
|
|
2144
|
+
data.set("LAT", parts[0].replaceAll(" ", ""));
|
|
2145
|
+
data.set("LON", parts[1].replaceAll(" ", ""));
|
|
2146
|
+
for (let i = 2; i < parts.length; i++) {
|
|
2147
|
+
const part = parts[i].split(" ");
|
|
2148
|
+
data.set(part[0], part.slice(1).join(" "));
|
|
2332
2149
|
}
|
|
2333
|
-
|
|
2334
|
-
|
|
2150
|
+
const position = {
|
|
2151
|
+
latitude: Number(data.get("LAT")),
|
|
2152
|
+
longitude: Number(data.get("LON"))
|
|
2153
|
+
};
|
|
2154
|
+
data.delete("LAT");
|
|
2155
|
+
data.delete("LON");
|
|
2156
|
+
ResultFormatter.position(decodeResult, position);
|
|
2157
|
+
const utc = data.get("UTC");
|
|
2158
|
+
if (utc) {
|
|
2159
|
+
ResultFormatter.time_of_day(
|
|
2160
|
+
decodeResult,
|
|
2161
|
+
DateTimeUtils.convertHHMMSSToTod(utc)
|
|
2162
|
+
);
|
|
2163
|
+
data.delete("UTC");
|
|
2335
2164
|
}
|
|
2336
|
-
|
|
2337
|
-
|
|
2165
|
+
const alt = data.get("ALT");
|
|
2166
|
+
if (alt) {
|
|
2167
|
+
ResultFormatter.altitude(decodeResult, Number(alt));
|
|
2168
|
+
data.delete("ALT");
|
|
2338
2169
|
}
|
|
2339
|
-
|
|
2340
|
-
|
|
2170
|
+
const fob = data.get("FOB");
|
|
2171
|
+
if (fob) {
|
|
2172
|
+
ResultFormatter.currentFuel(decodeResult, Number(fob));
|
|
2173
|
+
data.delete("FOB");
|
|
2174
|
+
}
|
|
2175
|
+
const eta = data.get("ETA");
|
|
2176
|
+
if (eta) {
|
|
2177
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(eta));
|
|
2178
|
+
data.delete("ETA");
|
|
2179
|
+
}
|
|
2180
|
+
let remaining = "";
|
|
2181
|
+
for (const [key, value] of data.entries()) {
|
|
2182
|
+
remaining += `/${key} ${value}`;
|
|
2183
|
+
}
|
|
2184
|
+
decodeResult.remaining.text = remaining;
|
|
2185
|
+
decodeResult.decoded = true;
|
|
2186
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
2187
|
+
return decodeResult;
|
|
2341
2188
|
}
|
|
2342
|
-
}
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
return
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2189
|
+
};
|
|
2190
|
+
|
|
2191
|
+
// lib/plugins/Label_20_POS.ts
|
|
2192
|
+
var Label_20_POS = class extends DecoderPlugin {
|
|
2193
|
+
name = "label-20-pos";
|
|
2194
|
+
qualifiers() {
|
|
2195
|
+
return {
|
|
2196
|
+
labels: ["20"],
|
|
2197
|
+
preambles: ["POS"]
|
|
2198
|
+
};
|
|
2199
|
+
}
|
|
2200
|
+
decode(message, options = {}) {
|
|
2201
|
+
const decodeResult = this.defaultResult();
|
|
2202
|
+
decodeResult.decoder.name = this.name;
|
|
2203
|
+
decodeResult.formatted.description = "Position Report";
|
|
2204
|
+
decodeResult.message = message;
|
|
2205
|
+
decodeResult.raw.preamble = message.text.substring(0, 3);
|
|
2206
|
+
const content = message.text.substring(3);
|
|
2207
|
+
const fields = content.split(",");
|
|
2208
|
+
if (fields.length == 11) {
|
|
2209
|
+
if (options.debug) {
|
|
2210
|
+
console.log(`DEBUG: ${this.name}: Variation 1 detected`);
|
|
2211
|
+
}
|
|
2212
|
+
const rawCoords = fields[0];
|
|
2213
|
+
ResultFormatter.position(
|
|
2356
2214
|
decodeResult,
|
|
2357
|
-
|
|
2358
|
-
"/"
|
|
2215
|
+
CoordinateUtils.decodeStringCoordinates(rawCoords)
|
|
2359
2216
|
);
|
|
2217
|
+
decodeResult.decoded = true;
|
|
2218
|
+
decodeResult.decoder.decodeLevel = "full";
|
|
2219
|
+
} else if (fields.length == 5) {
|
|
2220
|
+
if (options.debug) {
|
|
2221
|
+
console.log(`DEBUG: ${this.name}: Variation 2 detected`);
|
|
2222
|
+
}
|
|
2223
|
+
const position = CoordinateUtils.decodeStringCoordinates(fields[0]);
|
|
2224
|
+
if (position) {
|
|
2225
|
+
ResultFormatter.position(decodeResult, position);
|
|
2226
|
+
}
|
|
2227
|
+
decodeResult.decoded = true;
|
|
2228
|
+
decodeResult.decoder.decodeLevel = "full";
|
|
2229
|
+
} else {
|
|
2230
|
+
if (options.debug) {
|
|
2231
|
+
console.log(
|
|
2232
|
+
`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${content}`
|
|
2233
|
+
);
|
|
2234
|
+
}
|
|
2235
|
+
decodeResult.decoded = false;
|
|
2236
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2360
2237
|
}
|
|
2361
|
-
return
|
|
2362
|
-
}
|
|
2363
|
-
if (messageParts.length > 1) {
|
|
2364
|
-
ResultFormatter.unknown(decodeResult, messageParts.slice(1).join(","), "/");
|
|
2238
|
+
return decodeResult;
|
|
2365
2239
|
}
|
|
2366
|
-
|
|
2367
|
-
}
|
|
2368
|
-
function processMessageType(decodeResult, type) {
|
|
2369
|
-
if (type === "FPN") {
|
|
2370
|
-
decodeResult.formatted.description = "Flight Plan";
|
|
2371
|
-
} else if (type === "FTX") {
|
|
2372
|
-
decodeResult.formatted.description = "Free Text";
|
|
2373
|
-
} else if (type === "INI") {
|
|
2374
|
-
decodeResult.formatted.description = "Initial Report";
|
|
2375
|
-
} else if (type === "INR") {
|
|
2376
|
-
decodeResult.formatted.description = "In-Range Report";
|
|
2377
|
-
} else if (type === "LDI") {
|
|
2378
|
-
decodeResult.formatted.description = "Load Distribution Information";
|
|
2379
|
-
} else if (type === "PER") {
|
|
2380
|
-
decodeResult.formatted.description = "Performance Report";
|
|
2381
|
-
} else if (type === "POS") {
|
|
2382
|
-
decodeResult.formatted.description = "Position Report";
|
|
2383
|
-
} else if (type === "PRG") {
|
|
2384
|
-
decodeResult.formatted.description = "Progress Report";
|
|
2385
|
-
} else if (type === "PWI") {
|
|
2386
|
-
decodeResult.formatted.description = "Pilot Weather Information";
|
|
2387
|
-
} else if (type === "WXR") {
|
|
2388
|
-
decodeResult.formatted.description = "Weather Report";
|
|
2389
|
-
} else if (type === "REJ") {
|
|
2390
|
-
decodeResult.formatted.description = "Reject";
|
|
2391
|
-
} else if (type === "REQ") {
|
|
2392
|
-
decodeResult.formatted.description = "Request";
|
|
2393
|
-
} else if (type === "RES") {
|
|
2394
|
-
decodeResult.formatted.description = "Response";
|
|
2395
|
-
} else {
|
|
2396
|
-
decodeResult.formatted.description = "Unknown H1 Message";
|
|
2397
|
-
return false;
|
|
2398
|
-
}
|
|
2399
|
-
return true;
|
|
2400
|
-
}
|
|
2401
|
-
function processDateCode(decodeResult, data) {
|
|
2402
|
-
if (data.length === 1) {
|
|
2403
|
-
} else if (data.length === 2) {
|
|
2404
|
-
const date = data[0].substring(2, 4) + data[0].substring(0, 2) + data[0].substring(4, 6);
|
|
2405
|
-
const time = DateTimeUtils.convertDateTimeToEpoch(data[1], data[0]);
|
|
2406
|
-
decodeResult.raw.message_timestamp = time;
|
|
2407
|
-
}
|
|
2408
|
-
}
|
|
2409
|
-
function processWeatherQuery(decodeResult, data) {
|
|
2410
|
-
if (data.length !== 2) {
|
|
2411
|
-
ResultFormatter.unknown(decodeResult, data.join(":"), "WQ/");
|
|
2412
|
-
return;
|
|
2413
|
-
}
|
|
2414
|
-
const alts = data[0].split(".");
|
|
2415
|
-
const route = data[1].split(".");
|
|
2416
|
-
ResultFormatter.requestedAltitudes(
|
|
2417
|
-
decodeResult,
|
|
2418
|
-
alts.map((a) => parseInt(a, 10) * 100)
|
|
2419
|
-
);
|
|
2420
|
-
const waypoints = route.map((wp) => {
|
|
2421
|
-
return { name: wp };
|
|
2422
|
-
});
|
|
2423
|
-
ResultFormatter.route(decodeResult, { waypoints });
|
|
2424
|
-
}
|
|
2425
|
-
function processRoute(decodeResult, last, time, next, eta, then, date) {
|
|
2426
|
-
const lastTime = date ? DateTimeUtils.convertDateTimeToEpoch(time, date) : DateTimeUtils.convertHHMMSSToTod(time);
|
|
2427
|
-
const nextTime = date ? DateTimeUtils.convertDateTimeToEpoch(eta, date) : DateTimeUtils.convertHHMMSSToTod(eta);
|
|
2428
|
-
const timeFormat = date ? "epoch" : "tod";
|
|
2429
|
-
const lastWaypoint = RouteUtils.getWaypoint(last);
|
|
2430
|
-
lastWaypoint.time = lastTime;
|
|
2431
|
-
lastWaypoint.timeFormat = timeFormat;
|
|
2432
|
-
const nextWaypoint = RouteUtils.getWaypoint(next);
|
|
2433
|
-
nextWaypoint.time = nextTime;
|
|
2434
|
-
nextWaypoint.timeFormat = timeFormat;
|
|
2435
|
-
const thenWaypoint = RouteUtils.getWaypoint(then || "?");
|
|
2436
|
-
const waypoints = [lastWaypoint, nextWaypoint, thenWaypoint];
|
|
2437
|
-
ResultFormatter.route(decodeResult, { waypoints });
|
|
2438
|
-
}
|
|
2439
|
-
function processWindData(decodeResult, message) {
|
|
2440
|
-
const wind = [];
|
|
2441
|
-
const flightLevel = Number(message.slice(0, 3));
|
|
2442
|
-
const fields = message.slice(4).split(".");
|
|
2443
|
-
fields.forEach((field) => {
|
|
2444
|
-
if (field.length < 4) {
|
|
2445
|
-
return;
|
|
2446
|
-
}
|
|
2447
|
-
const data = field.split(",");
|
|
2448
|
-
const waypoint = { name: data[0] };
|
|
2449
|
-
const windData = data[1];
|
|
2450
|
-
const windDirection = parseInt(windData.slice(0, 3), 10);
|
|
2451
|
-
const windSpeed = parseInt(windData.slice(3), 10);
|
|
2452
|
-
if (data.length === 3) {
|
|
2453
|
-
const tempData = data[2];
|
|
2454
|
-
const tempFlightLevel = Number(tempData.slice(0, 3));
|
|
2455
|
-
const tempString = tempData.slice(3);
|
|
2456
|
-
const tempDegrees = Number(tempString.substring(1)) * (tempString.charAt(0) === "M" ? -1 : 1);
|
|
2457
|
-
wind.push({
|
|
2458
|
-
waypoint,
|
|
2459
|
-
flightLevel,
|
|
2460
|
-
windDirection,
|
|
2461
|
-
windSpeed,
|
|
2462
|
-
temperature: {
|
|
2463
|
-
flightLevel: tempFlightLevel,
|
|
2464
|
-
degreesC: tempDegrees
|
|
2465
|
-
}
|
|
2466
|
-
});
|
|
2467
|
-
} else {
|
|
2468
|
-
wind.push({
|
|
2469
|
-
waypoint,
|
|
2470
|
-
flightLevel,
|
|
2471
|
-
windDirection,
|
|
2472
|
-
windSpeed
|
|
2473
|
-
});
|
|
2474
|
-
}
|
|
2475
|
-
});
|
|
2476
|
-
ResultFormatter.windData(decodeResult, wind);
|
|
2477
|
-
}
|
|
2478
|
-
function processRunway(decodeResult, data) {
|
|
2479
|
-
const parts = data[0].split(".");
|
|
2480
|
-
const more = parts[0].split(",");
|
|
2481
|
-
ResultFormatter.departureRunway(decodeResult, more[0]);
|
|
2482
|
-
ResultFormatter.unknownArr(decodeResult, more.slice(1), ",");
|
|
2483
|
-
ResultFormatter.unknownArr(decodeResult, parts.slice(1), ".");
|
|
2484
|
-
ResultFormatter.departureAirport(decodeResult, data[1].split(",")[0]);
|
|
2485
|
-
ResultFormatter.unknownArr(decodeResult, data[1].split(",").slice(1), ",");
|
|
2486
|
-
}
|
|
2487
|
-
function crc16IbmSdlcRev(data) {
|
|
2488
|
-
let crc = 65535;
|
|
2489
|
-
const bytes = Buffer.from(data, "ascii");
|
|
2490
|
-
for (const byte of bytes) {
|
|
2491
|
-
crc ^= byte;
|
|
2492
|
-
for (let i = 0; i < 8; i++) {
|
|
2493
|
-
if ((crc & 1) !== 0) {
|
|
2494
|
-
crc = crc >>> 1 ^ 33800;
|
|
2495
|
-
} else {
|
|
2496
|
-
crc = crc >>> 1;
|
|
2497
|
-
}
|
|
2498
|
-
}
|
|
2499
|
-
}
|
|
2500
|
-
crc = (crc ^ 65535) & 65535;
|
|
2501
|
-
const nibble1 = crc >> 12 & 15;
|
|
2502
|
-
const nibble2 = crc >> 8 & 15;
|
|
2503
|
-
const nibble3 = crc >> 4 & 15;
|
|
2504
|
-
const nibble4 = crc & 15;
|
|
2505
|
-
return nibble4 << 12 | nibble3 << 8 | nibble2 << 4 | nibble1;
|
|
2506
|
-
}
|
|
2507
|
-
function crc16Genibus(data) {
|
|
2508
|
-
let crc = 65535;
|
|
2509
|
-
const polynomial = 4129;
|
|
2510
|
-
const bytes = Buffer.from(data, "ascii");
|
|
2511
|
-
for (const byte of bytes) {
|
|
2512
|
-
crc ^= byte << 8;
|
|
2513
|
-
for (let i = 0; i < 8; i++) {
|
|
2514
|
-
if ((crc & 32768) !== 0) {
|
|
2515
|
-
crc = (crc << 1 ^ polynomial) & 65535;
|
|
2516
|
-
} else {
|
|
2517
|
-
crc = crc << 1 & 65535;
|
|
2518
|
-
}
|
|
2519
|
-
}
|
|
2520
|
-
}
|
|
2521
|
-
return (crc ^ 65535) & 65535;
|
|
2522
|
-
}
|
|
2240
|
+
};
|
|
2523
2241
|
|
|
2524
|
-
// lib/plugins/
|
|
2525
|
-
var
|
|
2526
|
-
name = "label-
|
|
2242
|
+
// lib/plugins/Label_21_POS.ts
|
|
2243
|
+
var Label_21_POS = class extends DecoderPlugin {
|
|
2244
|
+
name = "label-21-pos";
|
|
2527
2245
|
qualifiers() {
|
|
2528
2246
|
return {
|
|
2529
|
-
labels: ["
|
|
2247
|
+
labels: ["21"],
|
|
2248
|
+
preambles: ["POS"]
|
|
2530
2249
|
};
|
|
2531
2250
|
}
|
|
2532
2251
|
decode(message, options = {}) {
|
|
2533
|
-
|
|
2252
|
+
const decodeResult = this.defaultResult();
|
|
2534
2253
|
decodeResult.decoder.name = this.name;
|
|
2254
|
+
decodeResult.formatted.description = "Position Report";
|
|
2535
2255
|
decodeResult.message = message;
|
|
2536
|
-
|
|
2537
|
-
const
|
|
2538
|
-
|
|
2539
|
-
if (
|
|
2540
|
-
|
|
2256
|
+
decodeResult.raw.preamble = message.text.substring(0, 3);
|
|
2257
|
+
const content = message.text.substring(3);
|
|
2258
|
+
const fields = content.split(",");
|
|
2259
|
+
if (fields.length == 9) {
|
|
2260
|
+
processPosition(decodeResult, fields[0].trim());
|
|
2261
|
+
ResultFormatter.time_of_day(
|
|
2262
|
+
decodeResult,
|
|
2263
|
+
DateTimeUtils.convertHHMMSSToTod(fields[2])
|
|
2264
|
+
);
|
|
2265
|
+
ResultFormatter.altitude(decodeResult, Number(fields[3]));
|
|
2266
|
+
ResultFormatter.temperature(decodeResult, fields[6].replace(/ /g, ""));
|
|
2267
|
+
ResultFormatter.eta(
|
|
2541
2268
|
decodeResult,
|
|
2542
|
-
|
|
2269
|
+
DateTimeUtils.convertHHMMSSToTod(fields[7])
|
|
2543
2270
|
);
|
|
2544
|
-
decodeResult
|
|
2271
|
+
ResultFormatter.arrivalAirport(decodeResult, fields[8]);
|
|
2272
|
+
ResultFormatter.unknownArr(decodeResult, [
|
|
2273
|
+
fields[1],
|
|
2274
|
+
fields[4],
|
|
2275
|
+
fields[5]
|
|
2276
|
+
]);
|
|
2277
|
+
decodeResult.decoded = true;
|
|
2278
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
2545
2279
|
} else {
|
|
2546
|
-
decoded = H1Helper.decodeH1Message(decodeResult, msg);
|
|
2547
|
-
}
|
|
2548
|
-
decodeResult.decoded = decoded;
|
|
2549
|
-
decodeResult.decoder.decodeLevel = !decodeResult.remaining.text ? "full" : "partial";
|
|
2550
|
-
if (decodeResult.formatted.items.length === 0) {
|
|
2551
2280
|
if (options.debug) {
|
|
2552
|
-
console.log(
|
|
2281
|
+
console.log(
|
|
2282
|
+
`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${content}`
|
|
2283
|
+
);
|
|
2553
2284
|
}
|
|
2554
|
-
ResultFormatter.unknown(decodeResult, message.text);
|
|
2555
2285
|
decodeResult.decoded = false;
|
|
2556
2286
|
decodeResult.decoder.decodeLevel = "none";
|
|
2557
2287
|
}
|
|
2558
2288
|
return decodeResult;
|
|
2559
2289
|
}
|
|
2560
2290
|
};
|
|
2291
|
+
function processPosition(decodeResult, value) {
|
|
2292
|
+
if (value.length !== 16 && value[0] !== "N" && value[0] !== "S" && value[8] !== "W" && value[8] !== "E") {
|
|
2293
|
+
return;
|
|
2294
|
+
}
|
|
2295
|
+
const latDir = value[0] === "N" ? 1 : -1;
|
|
2296
|
+
const lonDir = value[8] === "E" ? 1 : -1;
|
|
2297
|
+
const position = {
|
|
2298
|
+
latitude: latDir * Number(value.substring(1, 7)),
|
|
2299
|
+
longitude: lonDir * Number(value.substring(9, 15))
|
|
2300
|
+
};
|
|
2301
|
+
ResultFormatter.position(decodeResult, position);
|
|
2302
|
+
}
|
|
2561
2303
|
|
|
2562
|
-
// lib/plugins/
|
|
2563
|
-
var
|
|
2564
|
-
name = "label-
|
|
2304
|
+
// lib/plugins/Label_22_OFF.ts
|
|
2305
|
+
var Label_22_OFF = class extends DecoderPlugin {
|
|
2306
|
+
name = "label-22-off";
|
|
2565
2307
|
qualifiers() {
|
|
2566
2308
|
return {
|
|
2567
|
-
labels: ["
|
|
2568
|
-
preambles: ["
|
|
2309
|
+
labels: ["22"],
|
|
2310
|
+
preambles: ["OFF"]
|
|
2569
2311
|
};
|
|
2570
2312
|
}
|
|
2571
2313
|
decode(message, options = {}) {
|
|
2572
2314
|
const decodeResult = this.defaultResult();
|
|
2573
2315
|
decodeResult.decoder.name = this.name;
|
|
2574
|
-
decodeResult.formatted.description = "
|
|
2316
|
+
decodeResult.formatted.description = "Takeoff Report";
|
|
2575
2317
|
decodeResult.message = message;
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
if (
|
|
2579
|
-
|
|
2580
|
-
|
|
2318
|
+
if (message.text.startsWith("OFF01")) {
|
|
2319
|
+
const fields = message.text.substring(5).split("/");
|
|
2320
|
+
if (fields.length != 2) {
|
|
2321
|
+
decodeResult.decoded = false;
|
|
2322
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2323
|
+
return decodeResult;
|
|
2581
2324
|
}
|
|
2582
|
-
decodeResult
|
|
2583
|
-
ResultFormatter.
|
|
2584
|
-
ResultFormatter.arrivalAirport(decodeResult, results[4]);
|
|
2585
|
-
ResultFormatter.alternateAirport(decodeResult, results[5]);
|
|
2586
|
-
ResultFormatter.arrivalRunway(
|
|
2325
|
+
ResultFormatter.flightNumber(decodeResult, fields[0]);
|
|
2326
|
+
ResultFormatter.departureDay(
|
|
2587
2327
|
decodeResult,
|
|
2588
|
-
|
|
2328
|
+
Number(fields[1].substring(0, 2))
|
|
2589
2329
|
);
|
|
2590
|
-
|
|
2591
|
-
ResultFormatter.eta(
|
|
2330
|
+
ResultFormatter.arrivalDay(
|
|
2592
2331
|
decodeResult,
|
|
2593
|
-
|
|
2594
|
-
results[7] + "00",
|
|
2595
|
-
yymmdd.substring(4, 6) + yymmdd.substring(2, 4) + yymmdd.substring(0, 2)
|
|
2596
|
-
),
|
|
2597
|
-
"epoch"
|
|
2332
|
+
Number(fields[1].substring(2, 4))
|
|
2598
2333
|
);
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
if (options.debug) {
|
|
2622
|
-
console.log(`Decoder: Unknown 1L message: ${message.text}`);
|
|
2334
|
+
ResultFormatter.time_of_day(
|
|
2335
|
+
decodeResult,
|
|
2336
|
+
DateTimeUtils.convertHHMMSSToTod(fields[1].substring(4, 8))
|
|
2337
|
+
);
|
|
2338
|
+
ResultFormatter.departureAirport(
|
|
2339
|
+
decodeResult,
|
|
2340
|
+
fields[1].substring(8, 12)
|
|
2341
|
+
);
|
|
2342
|
+
ResultFormatter.arrivalAirport(decodeResult, fields[1].substring(12, 16));
|
|
2343
|
+
ResultFormatter.off(
|
|
2344
|
+
decodeResult,
|
|
2345
|
+
DateTimeUtils.convertHHMMSSToTod(fields[1].substring(16, 22))
|
|
2346
|
+
);
|
|
2347
|
+
ResultFormatter.unknown(decodeResult, fields[1].substring(22));
|
|
2348
|
+
decodeResult.decoded = true;
|
|
2349
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
2350
|
+
} else if (message.text.startsWith("OFF02\r\n")) {
|
|
2351
|
+
const fields = message.text.substring(7).split(",");
|
|
2352
|
+
if (fields.length != 4) {
|
|
2353
|
+
decodeResult.decoded = false;
|
|
2354
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2355
|
+
return decodeResult;
|
|
2623
2356
|
}
|
|
2624
|
-
decodeResult
|
|
2625
|
-
decodeResult
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
data.delete("DEP");
|
|
2640
|
-
}
|
|
2641
|
-
const des = data.get("DES");
|
|
2642
|
-
if (des) {
|
|
2643
|
-
ResultFormatter.arrivalAirport(decodeResult, des);
|
|
2644
|
-
data.delete("DES");
|
|
2645
|
-
}
|
|
2646
|
-
const eta = data.get("ETA");
|
|
2647
|
-
if (eta) {
|
|
2648
|
-
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(eta));
|
|
2649
|
-
data.delete("ETA");
|
|
2650
|
-
}
|
|
2651
|
-
const alt = data.get("ALT");
|
|
2652
|
-
if (alt) {
|
|
2653
|
-
ResultFormatter.altitude(decodeResult, Number(alt));
|
|
2654
|
-
data.delete("ALT");
|
|
2655
|
-
}
|
|
2656
|
-
const fn = data.get("FN");
|
|
2657
|
-
if (fn) {
|
|
2658
|
-
ResultFormatter.flightNumber(decodeResult, fn);
|
|
2659
|
-
data.delete("FN");
|
|
2660
|
-
}
|
|
2661
|
-
const day = data.get("DAY");
|
|
2662
|
-
const utc = data.get("UTC");
|
|
2663
|
-
if (day && utc) {
|
|
2664
|
-
decodeResult.raw.message_timestamp = Date.parse(day + " GMT+0000") / 1e3 + DateTimeUtils.convertHHMMSSToTod(utc);
|
|
2665
|
-
data.delete("DAY");
|
|
2666
|
-
data.delete("UTC");
|
|
2667
|
-
}
|
|
2668
|
-
const lat = data.get("LAT");
|
|
2669
|
-
const lon = data.get("LON");
|
|
2670
|
-
if (lat && lon) {
|
|
2671
|
-
ResultFormatter.position(decodeResult, {
|
|
2672
|
-
latitude: CoordinateUtils.getDirection(lat[0]) * Number(lat.substring(1)),
|
|
2673
|
-
longitude: CoordinateUtils.getDirection(lon[0]) * Number(lon.substring(1))
|
|
2674
|
-
});
|
|
2675
|
-
data.delete("LAT");
|
|
2676
|
-
data.delete("LON");
|
|
2677
|
-
}
|
|
2678
|
-
let remaining = "";
|
|
2679
|
-
for (const [key, value] of data.entries()) {
|
|
2680
|
-
if (key === "") {
|
|
2681
|
-
remaining += value;
|
|
2682
|
-
} else {
|
|
2683
|
-
remaining += `/${key} ${value}`;
|
|
2357
|
+
ResultFormatter.departureAirport(decodeResult, fields[0]);
|
|
2358
|
+
ResultFormatter.arrivalAirport(decodeResult, fields[1]);
|
|
2359
|
+
ResultFormatter.off(
|
|
2360
|
+
decodeResult,
|
|
2361
|
+
DateTimeUtils.convertHHMMSSToTod(fields[2])
|
|
2362
|
+
);
|
|
2363
|
+
ResultFormatter.unknown(decodeResult, fields[3]);
|
|
2364
|
+
decodeResult.decoded = true;
|
|
2365
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
2366
|
+
} else if (message.text.startsWith("OFF02")) {
|
|
2367
|
+
const fields = message.text.substring(5).split("/");
|
|
2368
|
+
if (fields.length != 2) {
|
|
2369
|
+
decodeResult.decoded = false;
|
|
2370
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2371
|
+
return decodeResult;
|
|
2684
2372
|
}
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
};
|
|
2692
|
-
|
|
2693
|
-
// lib/plugins/Label_1L_070.ts
|
|
2694
|
-
var Label_1L_070 = class extends DecoderPlugin {
|
|
2695
|
-
name = "label-1l-070";
|
|
2696
|
-
qualifiers() {
|
|
2697
|
-
return {
|
|
2698
|
-
labels: ["1L"],
|
|
2699
|
-
preambles: ["000000070"]
|
|
2700
|
-
};
|
|
2701
|
-
}
|
|
2702
|
-
decode(message, options = {}) {
|
|
2703
|
-
const decodeResult = this.defaultResult();
|
|
2704
|
-
decodeResult.decoder.name = this.name;
|
|
2705
|
-
decodeResult.formatted.description = "Position Report";
|
|
2706
|
-
decodeResult.message = message;
|
|
2707
|
-
if (!message.text.startsWith("000000070")) {
|
|
2708
|
-
if (options.debug) {
|
|
2709
|
-
console.log(`Decoder: Unknown 1L message: ${message.text}`);
|
|
2373
|
+
ResultFormatter.flightNumber(decodeResult, fields[0]);
|
|
2374
|
+
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(
|
|
2375
|
+
fields[1].substring(0, 14)
|
|
2376
|
+
);
|
|
2377
|
+
if (position) {
|
|
2378
|
+
ResultFormatter.position(decodeResult, position);
|
|
2710
2379
|
}
|
|
2711
|
-
decodeResult.
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2380
|
+
ResultFormatter.day(decodeResult, Number(fields[1].substring(14, 16)));
|
|
2381
|
+
ResultFormatter.time_of_day(
|
|
2382
|
+
decodeResult,
|
|
2383
|
+
DateTimeUtils.convertHHMMSSToTod(fields[1].substring(16, 20))
|
|
2384
|
+
);
|
|
2385
|
+
ResultFormatter.departureAirport(
|
|
2386
|
+
decodeResult,
|
|
2387
|
+
fields[1].substring(20, 24)
|
|
2388
|
+
);
|
|
2389
|
+
ResultFormatter.arrivalAirport(decodeResult, fields[1].substring(24, 28));
|
|
2390
|
+
ResultFormatter.off(
|
|
2391
|
+
decodeResult,
|
|
2392
|
+
DateTimeUtils.convertHHMMSSToTod(fields[1].substring(28, 32))
|
|
2393
|
+
);
|
|
2394
|
+
ResultFormatter.unknown(decodeResult, fields[1].substring(32, 36));
|
|
2395
|
+
ResultFormatter.eta(
|
|
2396
|
+
decodeResult,
|
|
2397
|
+
DateTimeUtils.convertHHMMSSToTod(fields[1].substring(36, 40))
|
|
2398
|
+
);
|
|
2399
|
+
decodeResult.decoded = true;
|
|
2400
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
2401
|
+
} else {
|
|
2718
2402
|
if (options.debug) {
|
|
2719
|
-
console.log(`
|
|
2403
|
+
console.log(`DEBUG: ${this.name}: Unknown variation.`);
|
|
2720
2404
|
}
|
|
2721
|
-
decodeResult.remaining.text = message.text;
|
|
2722
2405
|
decodeResult.decoded = false;
|
|
2723
2406
|
decodeResult.decoder.decodeLevel = "none";
|
|
2724
|
-
return decodeResult;
|
|
2725
2407
|
}
|
|
2726
|
-
ResultFormatter.departureAirport(decodeResult, parts[0]);
|
|
2727
|
-
ResultFormatter.arrivalAirport(decodeResult, parts[1]);
|
|
2728
|
-
ResultFormatter.time_of_day(
|
|
2729
|
-
decodeResult,
|
|
2730
|
-
DateTimeUtils.convertHHMMSSToTod(parts[2])
|
|
2731
|
-
);
|
|
2732
|
-
ResultFormatter.eta(
|
|
2733
|
-
decodeResult,
|
|
2734
|
-
DateTimeUtils.convertHHMMSSToTod(parts[3])
|
|
2735
|
-
);
|
|
2736
|
-
ResultFormatter.position(decodeResult, {
|
|
2737
|
-
latitude: CoordinateUtils.getDirection(parts[4][0]) * Number(parts[4].substring(1)),
|
|
2738
|
-
longitude: CoordinateUtils.getDirection(parts[5][0]) * Number(parts[5].substring(1))
|
|
2739
|
-
});
|
|
2740
|
-
decodeResult.remaining.text = parts[6];
|
|
2741
|
-
decodeResult.decoded = true;
|
|
2742
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
2743
2408
|
return decodeResult;
|
|
2744
2409
|
}
|
|
2745
2410
|
};
|
|
2746
2411
|
|
|
2747
|
-
// lib/plugins/
|
|
2748
|
-
var
|
|
2749
|
-
name = "label-
|
|
2412
|
+
// lib/plugins/Label_22_POS.ts
|
|
2413
|
+
var Label_22_POS = class extends DecoderPlugin {
|
|
2414
|
+
name = "label-22-pos";
|
|
2750
2415
|
qualifiers() {
|
|
2751
2416
|
return {
|
|
2752
|
-
labels: ["
|
|
2753
|
-
preambles: ["
|
|
2417
|
+
labels: ["22"],
|
|
2418
|
+
preambles: ["N", "S"]
|
|
2754
2419
|
};
|
|
2755
2420
|
}
|
|
2756
2421
|
decode(message, options = {}) {
|
|
@@ -2758,163 +2423,160 @@ var Label_1L_660 = class extends DecoderPlugin {
|
|
|
2758
2423
|
decodeResult.decoder.name = this.name;
|
|
2759
2424
|
decodeResult.formatted.description = "Position Report";
|
|
2760
2425
|
decodeResult.message = message;
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
console.log(`Decoder: Unknown 1L message: ${message.text}`);
|
|
2764
|
-
}
|
|
2765
|
-
decodeResult.remaining.text = message.text;
|
|
2766
|
-
decodeResult.decoded = false;
|
|
2767
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
2768
|
-
return decodeResult;
|
|
2769
|
-
}
|
|
2770
|
-
const parts = message.text.substring(9).split(",");
|
|
2771
|
-
if (parts.length !== 5) {
|
|
2426
|
+
const fields = message.text.split(",");
|
|
2427
|
+
if (fields.length !== 11) {
|
|
2772
2428
|
if (options.debug) {
|
|
2773
|
-
console.log(
|
|
2429
|
+
console.log(
|
|
2430
|
+
`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${fields.join(",")}`
|
|
2431
|
+
);
|
|
2774
2432
|
}
|
|
2775
|
-
decodeResult.remaining.text = message.text;
|
|
2776
2433
|
decodeResult.decoded = false;
|
|
2777
2434
|
decodeResult.decoder.decodeLevel = "none";
|
|
2778
2435
|
return decodeResult;
|
|
2779
2436
|
}
|
|
2780
|
-
const
|
|
2781
|
-
|
|
2782
|
-
);
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2437
|
+
const latStr = fields[0].substring(1, 8);
|
|
2438
|
+
const lonStr = fields[0].substring(9);
|
|
2439
|
+
const lat = Number(latStr) / 1e4;
|
|
2440
|
+
const lon = Number(lonStr) / 1e4;
|
|
2441
|
+
ResultFormatter.position(decodeResult, {
|
|
2442
|
+
latitude: CoordinateUtils.getDirection(fields[0][0]) * lat,
|
|
2443
|
+
longitude: CoordinateUtils.getDirection(fields[0][8]) * lon
|
|
2444
|
+
});
|
|
2787
2445
|
ResultFormatter.time_of_day(
|
|
2788
2446
|
decodeResult,
|
|
2789
|
-
DateTimeUtils.convertHHMMSSToTod(
|
|
2447
|
+
DateTimeUtils.convertHHMMSSToTod(fields[2])
|
|
2790
2448
|
);
|
|
2791
|
-
|
|
2792
|
-
ResultFormatter.
|
|
2793
|
-
const next = parts[1].substring(9);
|
|
2794
|
-
ResultFormatter.route(decodeResult, { waypoints: [{ name: next.trim() }] });
|
|
2795
|
-
decodeResult.remaining.text = parts.slice(2).join(",");
|
|
2449
|
+
ResultFormatter.altitude(decodeResult, Number(fields[3]));
|
|
2450
|
+
ResultFormatter.unknownArr(decodeResult, [fields[1], ...fields.slice(4)]);
|
|
2796
2451
|
decodeResult.decoded = true;
|
|
2797
2452
|
decodeResult.decoder.decodeLevel = "partial";
|
|
2798
2453
|
return decodeResult;
|
|
2799
2454
|
}
|
|
2800
2455
|
};
|
|
2801
2456
|
|
|
2802
|
-
// lib/plugins/
|
|
2803
|
-
var
|
|
2804
|
-
name = "label-
|
|
2457
|
+
// lib/plugins/Label_2P_FM3.ts
|
|
2458
|
+
var Label_2P_FM3 = class extends DecoderPlugin {
|
|
2459
|
+
name = "label-2p-fm3";
|
|
2805
2460
|
qualifiers() {
|
|
2806
2461
|
return {
|
|
2807
|
-
labels: ["
|
|
2808
|
-
preambles: ["+", "-"]
|
|
2462
|
+
labels: ["2P"]
|
|
2809
2463
|
};
|
|
2810
2464
|
}
|
|
2811
2465
|
decode(message, options = {}) {
|
|
2812
|
-
|
|
2466
|
+
let decodeResult = this.defaultResult();
|
|
2813
2467
|
decodeResult.decoder.name = this.name;
|
|
2814
|
-
decodeResult.formatted.description = "
|
|
2468
|
+
decodeResult.formatted.description = "Flight Report";
|
|
2815
2469
|
decodeResult.message = message;
|
|
2816
|
-
const parts = message.text.split("
|
|
2817
|
-
if (parts.length
|
|
2470
|
+
const parts = message.text.split(",");
|
|
2471
|
+
if (parts.length === 7) {
|
|
2472
|
+
const header = parts[0].split("FM3 ");
|
|
2473
|
+
if (header.length == 0) {
|
|
2474
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
2475
|
+
decodeResult.decoded = false;
|
|
2476
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2477
|
+
return decodeResult;
|
|
2478
|
+
}
|
|
2479
|
+
if (header[0].length > 0) {
|
|
2480
|
+
ResultFormatter.unknown(decodeResult, header[0].substring(0, 4));
|
|
2481
|
+
ResultFormatter.flightNumber(decodeResult, header[0].substring(4));
|
|
2482
|
+
}
|
|
2483
|
+
if (header[1].length === 4) {
|
|
2484
|
+
ResultFormatter.time_of_day(
|
|
2485
|
+
decodeResult,
|
|
2486
|
+
DateTimeUtils.convertHHMMSSToTod(header[1])
|
|
2487
|
+
);
|
|
2488
|
+
} else {
|
|
2489
|
+
ResultFormatter.time_of_day(
|
|
2490
|
+
decodeResult,
|
|
2491
|
+
DateTimeUtils.convertHHMMSSToTod(header[1])
|
|
2492
|
+
);
|
|
2493
|
+
}
|
|
2494
|
+
ResultFormatter.eta(
|
|
2495
|
+
decodeResult,
|
|
2496
|
+
DateTimeUtils.convertHHMMSSToTod(parts[1])
|
|
2497
|
+
);
|
|
2498
|
+
const lat = parts[2].replaceAll(" ", "");
|
|
2499
|
+
const lon = parts[3].replaceAll(" ", "");
|
|
2500
|
+
if (lat[0] === "N" || lat[0] === "S") {
|
|
2501
|
+
ResultFormatter.position(decodeResult, {
|
|
2502
|
+
latitude: CoordinateUtils.getDirection(lat[0]) * Number(lat.substring(1)),
|
|
2503
|
+
longitude: CoordinateUtils.getDirection(lon[0]) * Number(lon.substring(1))
|
|
2504
|
+
});
|
|
2505
|
+
} else {
|
|
2506
|
+
ResultFormatter.position(decodeResult, {
|
|
2507
|
+
latitude: Number(lat),
|
|
2508
|
+
longitude: Number(lon)
|
|
2509
|
+
});
|
|
2510
|
+
}
|
|
2511
|
+
ResultFormatter.altitude(decodeResult, Number(parts[4]));
|
|
2512
|
+
ResultFormatter.unknown(decodeResult, parts[5]);
|
|
2513
|
+
ResultFormatter.unknown(decodeResult, parts[6]);
|
|
2514
|
+
decodeResult.decoded = true;
|
|
2515
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
2516
|
+
} else {
|
|
2818
2517
|
if (options.debug) {
|
|
2819
|
-
console.log(`Decoder: Unknown
|
|
2518
|
+
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
2820
2519
|
}
|
|
2821
|
-
decodeResult
|
|
2520
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
2822
2521
|
decodeResult.decoded = false;
|
|
2823
2522
|
decodeResult.decoder.decodeLevel = "none";
|
|
2824
|
-
return decodeResult;
|
|
2825
|
-
}
|
|
2826
|
-
const data = /* @__PURE__ */ new Map();
|
|
2827
|
-
data.set("LAT", parts[0].replaceAll(" ", ""));
|
|
2828
|
-
data.set("LON", parts[1].replaceAll(" ", ""));
|
|
2829
|
-
for (let i = 2; i < parts.length; i++) {
|
|
2830
|
-
const part = parts[i].split(" ");
|
|
2831
|
-
data.set(part[0], part.slice(1).join(" "));
|
|
2832
|
-
}
|
|
2833
|
-
const position = {
|
|
2834
|
-
latitude: Number(data.get("LAT")),
|
|
2835
|
-
longitude: Number(data.get("LON"))
|
|
2836
|
-
};
|
|
2837
|
-
data.delete("LAT");
|
|
2838
|
-
data.delete("LON");
|
|
2839
|
-
ResultFormatter.position(decodeResult, position);
|
|
2840
|
-
const utc = data.get("UTC");
|
|
2841
|
-
if (utc) {
|
|
2842
|
-
ResultFormatter.time_of_day(
|
|
2843
|
-
decodeResult,
|
|
2844
|
-
DateTimeUtils.convertHHMMSSToTod(utc)
|
|
2845
|
-
);
|
|
2846
|
-
data.delete("UTC");
|
|
2847
|
-
}
|
|
2848
|
-
const alt = data.get("ALT");
|
|
2849
|
-
if (alt) {
|
|
2850
|
-
ResultFormatter.altitude(decodeResult, Number(alt));
|
|
2851
|
-
data.delete("ALT");
|
|
2852
|
-
}
|
|
2853
|
-
const fob = data.get("FOB");
|
|
2854
|
-
if (fob) {
|
|
2855
|
-
ResultFormatter.currentFuel(decodeResult, Number(fob));
|
|
2856
|
-
data.delete("FOB");
|
|
2857
|
-
}
|
|
2858
|
-
const eta = data.get("ETA");
|
|
2859
|
-
if (eta) {
|
|
2860
|
-
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(eta));
|
|
2861
|
-
data.delete("ETA");
|
|
2862
|
-
}
|
|
2863
|
-
let remaining = "";
|
|
2864
|
-
for (const [key, value] of data.entries()) {
|
|
2865
|
-
remaining += `/${key} ${value}`;
|
|
2866
2523
|
}
|
|
2867
|
-
decodeResult.remaining.text = remaining;
|
|
2868
|
-
decodeResult.decoded = true;
|
|
2869
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
2870
2524
|
return decodeResult;
|
|
2871
2525
|
}
|
|
2872
2526
|
};
|
|
2873
2527
|
|
|
2874
|
-
// lib/plugins/
|
|
2875
|
-
var
|
|
2876
|
-
name = "label-
|
|
2528
|
+
// lib/plugins/Label_2P_FM4.ts
|
|
2529
|
+
var Label_2P_FM4 = class extends DecoderPlugin {
|
|
2530
|
+
name = "label-2p-fm4";
|
|
2877
2531
|
qualifiers() {
|
|
2878
2532
|
return {
|
|
2879
|
-
labels: ["
|
|
2880
|
-
preambles: ["POS"]
|
|
2533
|
+
labels: ["2P"]
|
|
2881
2534
|
};
|
|
2882
2535
|
}
|
|
2883
2536
|
decode(message, options = {}) {
|
|
2884
|
-
|
|
2537
|
+
let decodeResult = this.defaultResult();
|
|
2885
2538
|
decodeResult.decoder.name = this.name;
|
|
2886
|
-
decodeResult.formatted.description = "
|
|
2539
|
+
decodeResult.formatted.description = "Flight Report";
|
|
2887
2540
|
decodeResult.message = message;
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2541
|
+
const parts = message.text.split(",");
|
|
2542
|
+
if (parts.length === 10) {
|
|
2543
|
+
const header = parts[0].split("FM4");
|
|
2544
|
+
if (header.length == 0) {
|
|
2545
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
2546
|
+
decodeResult.decoded = false;
|
|
2547
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2548
|
+
return decodeResult;
|
|
2894
2549
|
}
|
|
2895
|
-
|
|
2896
|
-
|
|
2550
|
+
if (header[0].length > 0) {
|
|
2551
|
+
ResultFormatter.unknown(decodeResult, header[0].substring(0, 4));
|
|
2552
|
+
ResultFormatter.flightNumber(decodeResult, header[0].substring(4));
|
|
2553
|
+
}
|
|
2554
|
+
ResultFormatter.departureAirport(decodeResult, header[1]);
|
|
2555
|
+
ResultFormatter.arrivalAirport(decodeResult, parts[1]);
|
|
2556
|
+
ResultFormatter.day(decodeResult, Number(parts[2].substring(0, 2)));
|
|
2557
|
+
ResultFormatter.time_of_day(
|
|
2897
2558
|
decodeResult,
|
|
2898
|
-
|
|
2559
|
+
DateTimeUtils.convertHHMMSSToTod(parts[2].substring(2))
|
|
2899
2560
|
);
|
|
2561
|
+
ResultFormatter.eta(
|
|
2562
|
+
decodeResult,
|
|
2563
|
+
DateTimeUtils.convertHHMMSSToTod(parts[3])
|
|
2564
|
+
);
|
|
2565
|
+
ResultFormatter.position(decodeResult, {
|
|
2566
|
+
latitude: Number(parts[4].replaceAll(" ", "")),
|
|
2567
|
+
longitude: Number(parts[5].replaceAll(" ", ""))
|
|
2568
|
+
});
|
|
2569
|
+
ResultFormatter.altitude(decodeResult, Number(parts[6]));
|
|
2570
|
+
ResultFormatter.heading(decodeResult, Number(parts[7]));
|
|
2571
|
+
ResultFormatter.unknown(decodeResult, parts[8]);
|
|
2572
|
+
ResultFormatter.unknown(decodeResult, parts[9]);
|
|
2900
2573
|
decodeResult.decoded = true;
|
|
2901
|
-
decodeResult.decoder.decodeLevel = "
|
|
2902
|
-
} else if (fields.length == 5) {
|
|
2903
|
-
if (options.debug) {
|
|
2904
|
-
console.log(`DEBUG: ${this.name}: Variation 2 detected`);
|
|
2905
|
-
}
|
|
2906
|
-
const position = CoordinateUtils.decodeStringCoordinates(fields[0]);
|
|
2907
|
-
if (position) {
|
|
2908
|
-
ResultFormatter.position(decodeResult, position);
|
|
2909
|
-
}
|
|
2910
|
-
decodeResult.decoded = true;
|
|
2911
|
-
decodeResult.decoder.decodeLevel = "full";
|
|
2574
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
2912
2575
|
} else {
|
|
2913
2576
|
if (options.debug) {
|
|
2914
|
-
console.log(
|
|
2915
|
-
`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${content}`
|
|
2916
|
-
);
|
|
2577
|
+
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
2917
2578
|
}
|
|
2579
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
2918
2580
|
decodeResult.decoded = false;
|
|
2919
2581
|
decodeResult.decoder.decodeLevel = "none";
|
|
2920
2582
|
}
|
|
@@ -2922,168 +2584,105 @@ var Label_20_POS = class extends DecoderPlugin {
|
|
|
2922
2584
|
}
|
|
2923
2585
|
};
|
|
2924
2586
|
|
|
2925
|
-
// lib/plugins/
|
|
2926
|
-
var
|
|
2927
|
-
name = "label-
|
|
2587
|
+
// lib/plugins/Label_2P_FM5.ts
|
|
2588
|
+
var Label_2P_FM5 = class extends DecoderPlugin {
|
|
2589
|
+
name = "label-2p-fm5";
|
|
2928
2590
|
qualifiers() {
|
|
2929
2591
|
return {
|
|
2930
|
-
labels: ["
|
|
2931
|
-
preambles: ["POS"]
|
|
2592
|
+
labels: ["2P"]
|
|
2932
2593
|
};
|
|
2933
2594
|
}
|
|
2934
2595
|
decode(message, options = {}) {
|
|
2935
|
-
|
|
2596
|
+
let decodeResult = this.defaultResult();
|
|
2936
2597
|
decodeResult.decoder.name = this.name;
|
|
2937
|
-
decodeResult.formatted.description = "
|
|
2598
|
+
decodeResult.formatted.description = "Flight Report";
|
|
2938
2599
|
decodeResult.message = message;
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2600
|
+
const parts = message.text.split(",");
|
|
2601
|
+
if (parts.length === 12) {
|
|
2602
|
+
const header = parts[0].split("FM5 ");
|
|
2603
|
+
if (header.length == 0) {
|
|
2604
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
2605
|
+
decodeResult.decoded = false;
|
|
2606
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2607
|
+
return decodeResult;
|
|
2608
|
+
}
|
|
2609
|
+
ResultFormatter.departureAirport(decodeResult, header[1]);
|
|
2610
|
+
ResultFormatter.arrivalAirport(decodeResult, parts[1]);
|
|
2944
2611
|
ResultFormatter.time_of_day(
|
|
2945
2612
|
decodeResult,
|
|
2946
|
-
DateTimeUtils.convertHHMMSSToTod(
|
|
2613
|
+
DateTimeUtils.convertHHMMSSToTod(parts[2])
|
|
2947
2614
|
);
|
|
2948
|
-
ResultFormatter.altitude(decodeResult, Number(fields[3]));
|
|
2949
|
-
ResultFormatter.temperature(decodeResult, fields[6].replace(/ /g, ""));
|
|
2950
2615
|
ResultFormatter.eta(
|
|
2951
2616
|
decodeResult,
|
|
2952
|
-
DateTimeUtils.convertHHMMSSToTod(
|
|
2617
|
+
DateTimeUtils.convertHHMMSSToTod(parts[3])
|
|
2953
2618
|
);
|
|
2954
|
-
ResultFormatter.
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
]);
|
|
2619
|
+
ResultFormatter.position(decodeResult, {
|
|
2620
|
+
latitude: Number(parts[4].replaceAll(" ", "")),
|
|
2621
|
+
longitude: Number(parts[5].replaceAll(" ", ""))
|
|
2622
|
+
});
|
|
2623
|
+
ResultFormatter.altitude(decodeResult, Number(parts[6]));
|
|
2624
|
+
ResultFormatter.unknown(decodeResult, parts[7]);
|
|
2625
|
+
ResultFormatter.unknown(decodeResult, parts[8]);
|
|
2626
|
+
ResultFormatter.unknown(decodeResult, parts[9]);
|
|
2627
|
+
ResultFormatter.flightNumber(decodeResult, parts[10].trim());
|
|
2628
|
+
ResultFormatter.unknown(decodeResult, parts[11]);
|
|
2960
2629
|
decodeResult.decoded = true;
|
|
2961
2630
|
decodeResult.decoder.decodeLevel = "partial";
|
|
2962
2631
|
} else {
|
|
2963
2632
|
if (options.debug) {
|
|
2964
|
-
console.log(
|
|
2965
|
-
`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${content}`
|
|
2966
|
-
);
|
|
2633
|
+
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
2967
2634
|
}
|
|
2635
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
2968
2636
|
decodeResult.decoded = false;
|
|
2969
2637
|
decodeResult.decoder.decodeLevel = "none";
|
|
2970
2638
|
}
|
|
2971
2639
|
return decodeResult;
|
|
2972
2640
|
}
|
|
2973
2641
|
};
|
|
2974
|
-
function processPosition(decodeResult, value) {
|
|
2975
|
-
if (value.length !== 16 && value[0] !== "N" && value[0] !== "S" && value[8] !== "W" && value[8] !== "E") {
|
|
2976
|
-
return;
|
|
2977
|
-
}
|
|
2978
|
-
const latDir = value[0] === "N" ? 1 : -1;
|
|
2979
|
-
const lonDir = value[8] === "E" ? 1 : -1;
|
|
2980
|
-
const position = {
|
|
2981
|
-
latitude: latDir * Number(value.substring(1, 7)),
|
|
2982
|
-
longitude: lonDir * Number(value.substring(9, 15))
|
|
2983
|
-
};
|
|
2984
|
-
ResultFormatter.position(decodeResult, position);
|
|
2985
|
-
}
|
|
2986
2642
|
|
|
2987
|
-
// lib/plugins/
|
|
2988
|
-
var
|
|
2989
|
-
name = "label-
|
|
2643
|
+
// lib/plugins/Label_24_Slash.ts
|
|
2644
|
+
var Label_24_Slash = class extends DecoderPlugin {
|
|
2645
|
+
name = "label-24-slash";
|
|
2990
2646
|
qualifiers() {
|
|
2991
2647
|
return {
|
|
2992
|
-
labels: ["
|
|
2993
|
-
preambles: ["
|
|
2648
|
+
labels: ["24"],
|
|
2649
|
+
preambles: ["/"]
|
|
2994
2650
|
};
|
|
2995
2651
|
}
|
|
2996
2652
|
decode(message, options = {}) {
|
|
2997
2653
|
const decodeResult = this.defaultResult();
|
|
2998
2654
|
decodeResult.decoder.name = this.name;
|
|
2999
|
-
decodeResult.formatted.description = "
|
|
2655
|
+
decodeResult.formatted.description = "Position Report";
|
|
3000
2656
|
decodeResult.message = message;
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
ResultFormatter.flightNumber(decodeResult, fields[0]);
|
|
3009
|
-
ResultFormatter.departureDay(
|
|
3010
|
-
decodeResult,
|
|
3011
|
-
Number(fields[1].substring(0, 2))
|
|
3012
|
-
);
|
|
3013
|
-
ResultFormatter.arrivalDay(
|
|
3014
|
-
decodeResult,
|
|
3015
|
-
Number(fields[1].substring(2, 4))
|
|
3016
|
-
);
|
|
3017
|
-
ResultFormatter.time_of_day(
|
|
3018
|
-
decodeResult,
|
|
3019
|
-
DateTimeUtils.convertHHMMSSToTod(fields[1].substring(4, 8))
|
|
3020
|
-
);
|
|
3021
|
-
ResultFormatter.departureAirport(
|
|
3022
|
-
decodeResult,
|
|
3023
|
-
fields[1].substring(8, 12)
|
|
3024
|
-
);
|
|
3025
|
-
ResultFormatter.arrivalAirport(decodeResult, fields[1].substring(12, 16));
|
|
3026
|
-
ResultFormatter.off(
|
|
3027
|
-
decodeResult,
|
|
3028
|
-
DateTimeUtils.convertHHMMSSToTod(fields[1].substring(16, 22))
|
|
3029
|
-
);
|
|
3030
|
-
ResultFormatter.unknown(decodeResult, fields[1].substring(22));
|
|
3031
|
-
decodeResult.decoded = true;
|
|
3032
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
3033
|
-
} else if (message.text.startsWith("OFF02\r\n")) {
|
|
3034
|
-
const fields = message.text.substring(7).split(",");
|
|
3035
|
-
if (fields.length != 4) {
|
|
3036
|
-
decodeResult.decoded = false;
|
|
3037
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
3038
|
-
return decodeResult;
|
|
3039
|
-
}
|
|
3040
|
-
ResultFormatter.departureAirport(decodeResult, fields[0]);
|
|
3041
|
-
ResultFormatter.arrivalAirport(decodeResult, fields[1]);
|
|
3042
|
-
ResultFormatter.off(
|
|
3043
|
-
decodeResult,
|
|
3044
|
-
DateTimeUtils.convertHHMMSSToTod(fields[2])
|
|
3045
|
-
);
|
|
3046
|
-
ResultFormatter.unknown(decodeResult, fields[3]);
|
|
3047
|
-
decodeResult.decoded = true;
|
|
3048
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
3049
|
-
} else if (message.text.startsWith("OFF02")) {
|
|
3050
|
-
const fields = message.text.substring(5).split("/");
|
|
3051
|
-
if (fields.length != 2) {
|
|
3052
|
-
decodeResult.decoded = false;
|
|
3053
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
3054
|
-
return decodeResult;
|
|
3055
|
-
}
|
|
3056
|
-
ResultFormatter.flightNumber(decodeResult, fields[0]);
|
|
3057
|
-
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(
|
|
3058
|
-
fields[1].substring(0, 14)
|
|
3059
|
-
);
|
|
3060
|
-
if (position) {
|
|
3061
|
-
ResultFormatter.position(decodeResult, position);
|
|
3062
|
-
}
|
|
3063
|
-
ResultFormatter.day(decodeResult, Number(fields[1].substring(14, 16)));
|
|
3064
|
-
ResultFormatter.time_of_day(
|
|
3065
|
-
decodeResult,
|
|
3066
|
-
DateTimeUtils.convertHHMMSSToTod(fields[1].substring(16, 20))
|
|
3067
|
-
);
|
|
3068
|
-
ResultFormatter.departureAirport(
|
|
3069
|
-
decodeResult,
|
|
3070
|
-
fields[1].substring(20, 24)
|
|
3071
|
-
);
|
|
3072
|
-
ResultFormatter.arrivalAirport(decodeResult, fields[1].substring(24, 28));
|
|
3073
|
-
ResultFormatter.off(
|
|
3074
|
-
decodeResult,
|
|
3075
|
-
DateTimeUtils.convertHHMMSSToTod(fields[1].substring(28, 32))
|
|
2657
|
+
const fields = message.text.split("/");
|
|
2658
|
+
if (fields.length == 10 && fields[0] == "" && fields[9] == "") {
|
|
2659
|
+
const ddmmyy = fields[1].substring(2, 4) + fields[1].substring(4, 6) + fields[1].substring(0, 2);
|
|
2660
|
+
const hhmmss = fields[2] + "00";
|
|
2661
|
+
decodeResult.raw.message_timestamp = DateTimeUtils.convertDateTimeToEpoch(
|
|
2662
|
+
hhmmss,
|
|
2663
|
+
ddmmyy
|
|
3076
2664
|
);
|
|
3077
|
-
ResultFormatter.
|
|
2665
|
+
ResultFormatter.flightNumber(decodeResult, fields[3]);
|
|
2666
|
+
ResultFormatter.altitude(decodeResult, Number(fields[4]));
|
|
2667
|
+
const lat = fields[5];
|
|
2668
|
+
const lon = fields[6];
|
|
2669
|
+
const position = {
|
|
2670
|
+
latitude: (lat[0] === "N" ? 1 : -1) * Number(lat.substring(1)),
|
|
2671
|
+
longitude: (lon[0] === "E" ? 1 : -1) * Number(lon.substring(1))
|
|
2672
|
+
};
|
|
2673
|
+
ResultFormatter.position(decodeResult, position);
|
|
3078
2674
|
ResultFormatter.eta(
|
|
3079
2675
|
decodeResult,
|
|
3080
|
-
DateTimeUtils.convertHHMMSSToTod(fields[
|
|
2676
|
+
DateTimeUtils.convertHHMMSSToTod(fields[8])
|
|
3081
2677
|
);
|
|
2678
|
+
ResultFormatter.unknown(decodeResult, fields[7]);
|
|
3082
2679
|
decodeResult.decoded = true;
|
|
3083
2680
|
decodeResult.decoder.decodeLevel = "partial";
|
|
3084
2681
|
} else {
|
|
3085
2682
|
if (options.debug) {
|
|
3086
|
-
console.log(
|
|
2683
|
+
console.log(
|
|
2684
|
+
`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}. Message: ${message.text}`
|
|
2685
|
+
);
|
|
3087
2686
|
}
|
|
3088
2687
|
decodeResult.decoded = false;
|
|
3089
2688
|
decodeResult.decoder.decodeLevel = "none";
|
|
@@ -3092,409 +2691,201 @@ var Label_22_OFF = class extends DecoderPlugin {
|
|
|
3092
2691
|
}
|
|
3093
2692
|
};
|
|
3094
2693
|
|
|
3095
|
-
// lib/plugins/
|
|
3096
|
-
var
|
|
3097
|
-
name = "label-
|
|
2694
|
+
// lib/plugins/Label_30_Slash_EA.ts
|
|
2695
|
+
var Label_30_Slash_EA = class extends DecoderPlugin {
|
|
2696
|
+
name = "label-30-slash-ea";
|
|
3098
2697
|
qualifiers() {
|
|
3099
2698
|
return {
|
|
3100
|
-
labels: ["
|
|
3101
|
-
preambles: ["
|
|
2699
|
+
labels: ["30"],
|
|
2700
|
+
preambles: ["/EA"]
|
|
3102
2701
|
};
|
|
3103
2702
|
}
|
|
3104
2703
|
decode(message, options = {}) {
|
|
3105
2704
|
const decodeResult = this.defaultResult();
|
|
3106
2705
|
decodeResult.decoder.name = this.name;
|
|
3107
|
-
decodeResult.formatted.description = "
|
|
2706
|
+
decodeResult.formatted.description = "ETA Report";
|
|
3108
2707
|
decodeResult.message = message;
|
|
3109
|
-
const
|
|
3110
|
-
if (
|
|
2708
|
+
const results = message.text.split(/\n|\//).slice(1);
|
|
2709
|
+
if (results) {
|
|
3111
2710
|
if (options.debug) {
|
|
3112
|
-
console.log(
|
|
3113
|
-
|
|
3114
|
-
);
|
|
2711
|
+
console.log("Label 30 EA: results");
|
|
2712
|
+
console.log(results);
|
|
3115
2713
|
}
|
|
3116
|
-
decodeResult.decoded = false;
|
|
3117
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
3118
|
-
return decodeResult;
|
|
3119
2714
|
}
|
|
3120
|
-
|
|
3121
|
-
const lonStr = fields[0].substring(9);
|
|
3122
|
-
const lat = Number(latStr) / 1e4;
|
|
3123
|
-
const lon = Number(lonStr) / 1e4;
|
|
3124
|
-
ResultFormatter.position(decodeResult, {
|
|
3125
|
-
latitude: CoordinateUtils.getDirection(fields[0][0]) * lat,
|
|
3126
|
-
longitude: CoordinateUtils.getDirection(fields[0][8]) * lon
|
|
3127
|
-
});
|
|
3128
|
-
ResultFormatter.time_of_day(
|
|
2715
|
+
ResultFormatter.eta(
|
|
3129
2716
|
decodeResult,
|
|
3130
|
-
DateTimeUtils.convertHHMMSSToTod(
|
|
2717
|
+
DateTimeUtils.convertHHMMSSToTod(results[0].substr(2, 4))
|
|
3131
2718
|
);
|
|
3132
|
-
|
|
3133
|
-
|
|
2719
|
+
if (results[1].substring(0, 2) === "DS") {
|
|
2720
|
+
ResultFormatter.arrivalAirport(decodeResult, results[1].substring(2, 6));
|
|
2721
|
+
ResultFormatter.unknown(decodeResult, "/".concat(results[2]));
|
|
2722
|
+
} else {
|
|
2723
|
+
ResultFormatter.unknown(
|
|
2724
|
+
decodeResult,
|
|
2725
|
+
"/".concat(results[1], "/", results[2])
|
|
2726
|
+
);
|
|
2727
|
+
}
|
|
3134
2728
|
decodeResult.decoded = true;
|
|
3135
2729
|
decodeResult.decoder.decodeLevel = "partial";
|
|
3136
2730
|
return decodeResult;
|
|
3137
2731
|
}
|
|
3138
2732
|
};
|
|
3139
2733
|
|
|
3140
|
-
// lib/plugins/
|
|
3141
|
-
var
|
|
3142
|
-
name = "label-
|
|
2734
|
+
// lib/plugins/Label_44_ETA.ts
|
|
2735
|
+
var Label_44_ETA = class extends DecoderPlugin {
|
|
2736
|
+
name = "label-44-eta";
|
|
3143
2737
|
qualifiers() {
|
|
3144
2738
|
return {
|
|
3145
|
-
labels: ["
|
|
2739
|
+
labels: ["44"],
|
|
2740
|
+
preambles: ["00ETA01", "00ETA02", "00ETA03", "ETA01", "ETA02", "ETA03"]
|
|
3146
2741
|
};
|
|
3147
2742
|
}
|
|
3148
2743
|
decode(message, options = {}) {
|
|
3149
|
-
|
|
2744
|
+
const decodeResult = this.defaultResult();
|
|
3150
2745
|
decodeResult.decoder.name = this.name;
|
|
3151
|
-
decodeResult.formatted.description = "
|
|
2746
|
+
decodeResult.formatted.description = "ETA Report";
|
|
3152
2747
|
decodeResult.message = message;
|
|
3153
|
-
const
|
|
3154
|
-
if (
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
decodeResult.decoded = false;
|
|
3159
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
3160
|
-
return decodeResult;
|
|
3161
|
-
}
|
|
3162
|
-
if (header[0].length > 0) {
|
|
3163
|
-
ResultFormatter.unknown(decodeResult, header[0].substring(0, 4));
|
|
3164
|
-
ResultFormatter.flightNumber(decodeResult, header[0].substring(4));
|
|
3165
|
-
}
|
|
3166
|
-
if (header[1].length === 4) {
|
|
3167
|
-
ResultFormatter.time_of_day(
|
|
3168
|
-
decodeResult,
|
|
3169
|
-
DateTimeUtils.convertHHMMSSToTod(header[1])
|
|
3170
|
-
);
|
|
3171
|
-
} else {
|
|
3172
|
-
ResultFormatter.time_of_day(
|
|
3173
|
-
decodeResult,
|
|
3174
|
-
DateTimeUtils.convertHHMMSSToTod(header[1])
|
|
3175
|
-
);
|
|
2748
|
+
const data = message.text.split(",");
|
|
2749
|
+
if (data.length >= 9) {
|
|
2750
|
+
if (options.debug) {
|
|
2751
|
+
console.log("Label 44 ETA Report: groups");
|
|
2752
|
+
console.log(data);
|
|
3176
2753
|
}
|
|
2754
|
+
ResultFormatter.position(
|
|
2755
|
+
decodeResult,
|
|
2756
|
+
CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1])
|
|
2757
|
+
);
|
|
2758
|
+
ResultFormatter.altitude(decodeResult, 100 * Number(data[2]));
|
|
2759
|
+
ResultFormatter.departureAirport(decodeResult, data[3]);
|
|
2760
|
+
ResultFormatter.arrivalAirport(decodeResult, data[4]);
|
|
2761
|
+
ResultFormatter.month(decodeResult, Number(data[5].substring(0, 2)));
|
|
2762
|
+
ResultFormatter.day(decodeResult, Number(data[5].substring(2, 4)));
|
|
2763
|
+
ResultFormatter.time_of_day(
|
|
2764
|
+
decodeResult,
|
|
2765
|
+
DateTimeUtils.convertHHMMSSToTod(data[6])
|
|
2766
|
+
);
|
|
3177
2767
|
ResultFormatter.eta(
|
|
3178
2768
|
decodeResult,
|
|
3179
|
-
DateTimeUtils.convertHHMMSSToTod(
|
|
2769
|
+
DateTimeUtils.convertHHMMSSToTod(data[7])
|
|
3180
2770
|
);
|
|
3181
|
-
const
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
});
|
|
3188
|
-
} else {
|
|
3189
|
-
ResultFormatter.position(decodeResult, {
|
|
3190
|
-
latitude: Number(lat),
|
|
3191
|
-
longitude: Number(lon)
|
|
3192
|
-
});
|
|
2771
|
+
const fuel = Number(data[8]);
|
|
2772
|
+
if (!isNaN(fuel)) {
|
|
2773
|
+
ResultFormatter.remainingFuel(decodeResult, Number(fuel));
|
|
2774
|
+
}
|
|
2775
|
+
if (data.length > 9) {
|
|
2776
|
+
ResultFormatter.unknownArr(decodeResult, data.slice(9));
|
|
3193
2777
|
}
|
|
3194
|
-
ResultFormatter.altitude(decodeResult, Number(parts[4]));
|
|
3195
|
-
ResultFormatter.unknown(decodeResult, parts[5]);
|
|
3196
|
-
ResultFormatter.unknown(decodeResult, parts[6]);
|
|
3197
|
-
decodeResult.decoded = true;
|
|
3198
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
3199
2778
|
} else {
|
|
3200
2779
|
if (options.debug) {
|
|
3201
|
-
console.log(`Decoder: Unknown
|
|
2780
|
+
console.log(`Decoder: Unknown 44 message: ${message.text}`);
|
|
3202
2781
|
}
|
|
3203
2782
|
ResultFormatter.unknown(decodeResult, message.text);
|
|
3204
2783
|
decodeResult.decoded = false;
|
|
3205
2784
|
decodeResult.decoder.decodeLevel = "none";
|
|
2785
|
+
return decodeResult;
|
|
3206
2786
|
}
|
|
2787
|
+
decodeResult.decoded = true;
|
|
2788
|
+
decodeResult.decoder.decodeLevel = "full";
|
|
3207
2789
|
return decodeResult;
|
|
3208
2790
|
}
|
|
3209
2791
|
};
|
|
3210
2792
|
|
|
3211
|
-
// lib/plugins/
|
|
3212
|
-
var
|
|
3213
|
-
name = "label-
|
|
2793
|
+
// lib/plugins/Label_44_IN.ts
|
|
2794
|
+
var Label_44_IN = class extends DecoderPlugin {
|
|
2795
|
+
name = "label-44-in";
|
|
3214
2796
|
qualifiers() {
|
|
3215
2797
|
return {
|
|
3216
|
-
labels: ["
|
|
2798
|
+
labels: ["44"],
|
|
2799
|
+
preambles: ["00IN01", "00IN02", "00IN03", "IN01", "IN02", "IN03"]
|
|
3217
2800
|
};
|
|
3218
2801
|
}
|
|
3219
2802
|
decode(message, options = {}) {
|
|
3220
|
-
|
|
2803
|
+
const decodeResult = this.defaultResult();
|
|
3221
2804
|
decodeResult.decoder.name = this.name;
|
|
3222
|
-
decodeResult.formatted.description = "
|
|
2805
|
+
decodeResult.formatted.description = "In Air Report";
|
|
3223
2806
|
decodeResult.message = message;
|
|
3224
|
-
const
|
|
3225
|
-
if (
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
decodeResult.decoded = false;
|
|
3230
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
3231
|
-
return decodeResult;
|
|
3232
|
-
}
|
|
3233
|
-
if (header[0].length > 0) {
|
|
3234
|
-
ResultFormatter.unknown(decodeResult, header[0].substring(0, 4));
|
|
3235
|
-
ResultFormatter.flightNumber(decodeResult, header[0].substring(4));
|
|
2807
|
+
const data = message.text.split(",");
|
|
2808
|
+
if (data.length >= 7) {
|
|
2809
|
+
if (options.debug) {
|
|
2810
|
+
console.log("Label 44 In Air Report: groups");
|
|
2811
|
+
console.log(data);
|
|
3236
2812
|
}
|
|
3237
|
-
ResultFormatter.
|
|
3238
|
-
ResultFormatter.arrivalAirport(decodeResult, parts[1]);
|
|
3239
|
-
ResultFormatter.day(decodeResult, Number(parts[2].substring(0, 2)));
|
|
3240
|
-
ResultFormatter.time_of_day(
|
|
2813
|
+
ResultFormatter.position(
|
|
3241
2814
|
decodeResult,
|
|
3242
|
-
|
|
2815
|
+
CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1])
|
|
3243
2816
|
);
|
|
3244
|
-
ResultFormatter.
|
|
2817
|
+
ResultFormatter.departureAirport(decodeResult, data[2]);
|
|
2818
|
+
ResultFormatter.arrivalAirport(decodeResult, data[3]);
|
|
2819
|
+
ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
|
|
2820
|
+
ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
|
|
2821
|
+
ResultFormatter.in(
|
|
3245
2822
|
decodeResult,
|
|
3246
|
-
DateTimeUtils.convertHHMMSSToTod(
|
|
2823
|
+
DateTimeUtils.convertHHMMSSToTod(data[5])
|
|
3247
2824
|
);
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
});
|
|
3252
|
-
ResultFormatter.altitude(decodeResult, Number(parts[6]));
|
|
3253
|
-
ResultFormatter.heading(decodeResult, Number(parts[7]));
|
|
3254
|
-
ResultFormatter.unknown(decodeResult, parts[8]);
|
|
3255
|
-
ResultFormatter.unknown(decodeResult, parts[9]);
|
|
3256
|
-
decodeResult.decoded = true;
|
|
3257
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
3258
|
-
} else {
|
|
3259
|
-
if (options.debug) {
|
|
3260
|
-
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
3261
|
-
}
|
|
3262
|
-
ResultFormatter.unknown(decodeResult, message.text);
|
|
3263
|
-
decodeResult.decoded = false;
|
|
3264
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
3265
|
-
}
|
|
3266
|
-
return decodeResult;
|
|
3267
|
-
}
|
|
3268
|
-
};
|
|
3269
|
-
|
|
3270
|
-
// lib/plugins/Label_2P_FM5.ts
|
|
3271
|
-
var Label_2P_FM5 = class extends DecoderPlugin {
|
|
3272
|
-
name = "label-2p-fm5";
|
|
3273
|
-
qualifiers() {
|
|
3274
|
-
return {
|
|
3275
|
-
labels: ["2P"]
|
|
3276
|
-
};
|
|
3277
|
-
}
|
|
3278
|
-
decode(message, options = {}) {
|
|
3279
|
-
let decodeResult = this.defaultResult();
|
|
3280
|
-
decodeResult.decoder.name = this.name;
|
|
3281
|
-
decodeResult.formatted.description = "Flight Report";
|
|
3282
|
-
decodeResult.message = message;
|
|
3283
|
-
const parts = message.text.split(",");
|
|
3284
|
-
if (parts.length === 12) {
|
|
3285
|
-
const header = parts[0].split("FM5 ");
|
|
3286
|
-
if (header.length == 0) {
|
|
3287
|
-
ResultFormatter.unknown(decodeResult, message.text);
|
|
3288
|
-
decodeResult.decoded = false;
|
|
3289
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
3290
|
-
return decodeResult;
|
|
2825
|
+
const fuel = Number(data[6]);
|
|
2826
|
+
if (!isNaN(fuel)) {
|
|
2827
|
+
ResultFormatter.remainingFuel(decodeResult, Number(fuel));
|
|
3291
2828
|
}
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
ResultFormatter.time_of_day(
|
|
3295
|
-
decodeResult,
|
|
3296
|
-
DateTimeUtils.convertHHMMSSToTod(parts[2])
|
|
3297
|
-
);
|
|
3298
|
-
ResultFormatter.eta(
|
|
3299
|
-
decodeResult,
|
|
3300
|
-
DateTimeUtils.convertHHMMSSToTod(parts[3])
|
|
3301
|
-
);
|
|
3302
|
-
ResultFormatter.position(decodeResult, {
|
|
3303
|
-
latitude: Number(parts[4].replaceAll(" ", "")),
|
|
3304
|
-
longitude: Number(parts[5].replaceAll(" ", ""))
|
|
3305
|
-
});
|
|
3306
|
-
ResultFormatter.altitude(decodeResult, Number(parts[6]));
|
|
3307
|
-
ResultFormatter.unknown(decodeResult, parts[7]);
|
|
3308
|
-
ResultFormatter.unknown(decodeResult, parts[8]);
|
|
3309
|
-
ResultFormatter.unknown(decodeResult, parts[9]);
|
|
3310
|
-
ResultFormatter.flightNumber(decodeResult, parts[10].trim());
|
|
3311
|
-
ResultFormatter.unknown(decodeResult, parts[11]);
|
|
3312
|
-
decodeResult.decoded = true;
|
|
3313
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
3314
|
-
} else {
|
|
3315
|
-
if (options.debug) {
|
|
3316
|
-
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
2829
|
+
if (data.length > 7) {
|
|
2830
|
+
ResultFormatter.unknownArr(decodeResult, data.slice(7));
|
|
3317
2831
|
}
|
|
3318
|
-
ResultFormatter.unknown(decodeResult, message.text);
|
|
3319
|
-
decodeResult.decoded = false;
|
|
3320
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
3321
|
-
}
|
|
3322
|
-
return decodeResult;
|
|
3323
|
-
}
|
|
3324
|
-
};
|
|
3325
|
-
|
|
3326
|
-
// lib/plugins/Label_2P_POS.ts
|
|
3327
|
-
var Label_2P_POS = class extends DecoderPlugin {
|
|
3328
|
-
name = "label-2p-pos";
|
|
3329
|
-
qualifiers() {
|
|
3330
|
-
return {
|
|
3331
|
-
labels: ["2P"]
|
|
3332
|
-
};
|
|
3333
|
-
}
|
|
3334
|
-
decode(message, options = {}) {
|
|
3335
|
-
let decodeResult = this.defaultResult();
|
|
3336
|
-
decodeResult.decoder.name = this.name;
|
|
3337
|
-
decodeResult.message = message;
|
|
3338
|
-
const msg = message.text.replace(/\n|\r/g, "");
|
|
3339
|
-
const parts = msg.split("/");
|
|
3340
|
-
let decoded = false;
|
|
3341
|
-
if (parts[0].length > 3) {
|
|
3342
|
-
decoded = H1Helper.decodeH1Message(
|
|
3343
|
-
decodeResult,
|
|
3344
|
-
msg.slice(parts[0].length - 3)
|
|
3345
|
-
);
|
|
3346
|
-
decodeResult.remaining.text = parts[0].slice(0, 3) + "/" + decodeResult.remaining.text;
|
|
3347
2832
|
} else {
|
|
3348
|
-
decoded = H1Helper.decodeH1Message(decodeResult, msg);
|
|
3349
|
-
}
|
|
3350
|
-
decodeResult.decoded = decoded;
|
|
3351
|
-
decodeResult.decoder.decodeLevel = !decodeResult.remaining.text ? "full" : "partial";
|
|
3352
|
-
if (decodeResult.formatted.items.length === 0) {
|
|
3353
2833
|
if (options.debug) {
|
|
3354
|
-
console.log(`Decoder: Unknown
|
|
2834
|
+
console.log(`Decoder: Unknown 44 message: ${message.text}`);
|
|
3355
2835
|
}
|
|
3356
2836
|
ResultFormatter.unknown(decodeResult, message.text);
|
|
3357
2837
|
decodeResult.decoded = false;
|
|
3358
2838
|
decodeResult.decoder.decodeLevel = "none";
|
|
3359
|
-
|
|
3360
|
-
return decodeResult;
|
|
3361
|
-
}
|
|
3362
|
-
};
|
|
3363
|
-
|
|
3364
|
-
// lib/plugins/Label_24_Slash.ts
|
|
3365
|
-
var Label_24_Slash = class extends DecoderPlugin {
|
|
3366
|
-
name = "label-24-slash";
|
|
3367
|
-
qualifiers() {
|
|
3368
|
-
return {
|
|
3369
|
-
labels: ["24"],
|
|
3370
|
-
preambles: ["/"]
|
|
3371
|
-
};
|
|
3372
|
-
}
|
|
3373
|
-
decode(message, options = {}) {
|
|
3374
|
-
const decodeResult = this.defaultResult();
|
|
3375
|
-
decodeResult.decoder.name = this.name;
|
|
3376
|
-
decodeResult.formatted.description = "Position Report";
|
|
3377
|
-
decodeResult.message = message;
|
|
3378
|
-
const fields = message.text.split("/");
|
|
3379
|
-
if (fields.length == 10 && fields[0] == "" && fields[9] == "") {
|
|
3380
|
-
const ddmmyy = fields[1].substring(2, 4) + fields[1].substring(4, 6) + fields[1].substring(0, 2);
|
|
3381
|
-
const hhmmss = fields[2] + "00";
|
|
3382
|
-
decodeResult.raw.message_timestamp = DateTimeUtils.convertDateTimeToEpoch(
|
|
3383
|
-
hhmmss,
|
|
3384
|
-
ddmmyy
|
|
3385
|
-
);
|
|
3386
|
-
ResultFormatter.flightNumber(decodeResult, fields[3]);
|
|
3387
|
-
ResultFormatter.altitude(decodeResult, Number(fields[4]));
|
|
3388
|
-
const lat = fields[5];
|
|
3389
|
-
const lon = fields[6];
|
|
3390
|
-
const position = {
|
|
3391
|
-
latitude: (lat[0] === "N" ? 1 : -1) * Number(lat.substring(1)),
|
|
3392
|
-
longitude: (lon[0] === "E" ? 1 : -1) * Number(lon.substring(1))
|
|
3393
|
-
};
|
|
3394
|
-
ResultFormatter.position(decodeResult, position);
|
|
3395
|
-
ResultFormatter.eta(
|
|
3396
|
-
decodeResult,
|
|
3397
|
-
DateTimeUtils.convertHHMMSSToTod(fields[8])
|
|
3398
|
-
);
|
|
3399
|
-
ResultFormatter.unknown(decodeResult, fields[7]);
|
|
3400
|
-
decodeResult.decoded = true;
|
|
3401
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
3402
|
-
} else {
|
|
3403
|
-
if (options.debug) {
|
|
3404
|
-
console.log(
|
|
3405
|
-
`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}. Message: ${message.text}`
|
|
3406
|
-
);
|
|
3407
|
-
}
|
|
3408
|
-
decodeResult.decoded = false;
|
|
3409
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
3410
|
-
}
|
|
3411
|
-
return decodeResult;
|
|
3412
|
-
}
|
|
3413
|
-
};
|
|
3414
|
-
|
|
3415
|
-
// lib/plugins/Label_30_Slash_EA.ts
|
|
3416
|
-
var Label_30_Slash_EA = class extends DecoderPlugin {
|
|
3417
|
-
name = "label-30-slash-ea";
|
|
3418
|
-
qualifiers() {
|
|
3419
|
-
return {
|
|
3420
|
-
labels: ["30"],
|
|
3421
|
-
preambles: ["/EA"]
|
|
3422
|
-
};
|
|
3423
|
-
}
|
|
3424
|
-
decode(message, options = {}) {
|
|
3425
|
-
const decodeResult = this.defaultResult();
|
|
3426
|
-
decodeResult.decoder.name = this.name;
|
|
3427
|
-
decodeResult.formatted.description = "ETA Report";
|
|
3428
|
-
decodeResult.message = message;
|
|
3429
|
-
const results = message.text.split(/\n|\//).slice(1);
|
|
3430
|
-
if (results) {
|
|
3431
|
-
if (options.debug) {
|
|
3432
|
-
console.log("Label 30 EA: results");
|
|
3433
|
-
console.log(results);
|
|
3434
|
-
}
|
|
3435
|
-
}
|
|
3436
|
-
ResultFormatter.eta(
|
|
3437
|
-
decodeResult,
|
|
3438
|
-
DateTimeUtils.convertHHMMSSToTod(results[0].substr(2, 4))
|
|
3439
|
-
);
|
|
3440
|
-
if (results[1].substring(0, 2) === "DS") {
|
|
3441
|
-
ResultFormatter.arrivalAirport(decodeResult, results[1].substring(2, 6));
|
|
3442
|
-
ResultFormatter.unknown(decodeResult, "/".concat(results[2]));
|
|
3443
|
-
} else {
|
|
3444
|
-
ResultFormatter.unknown(
|
|
3445
|
-
decodeResult,
|
|
3446
|
-
"/".concat(results[1], "/", results[2])
|
|
3447
|
-
);
|
|
2839
|
+
return decodeResult;
|
|
3448
2840
|
}
|
|
3449
2841
|
decodeResult.decoded = true;
|
|
3450
|
-
decodeResult.decoder.decodeLevel = "
|
|
2842
|
+
decodeResult.decoder.decodeLevel = "full";
|
|
3451
2843
|
return decodeResult;
|
|
3452
2844
|
}
|
|
3453
2845
|
};
|
|
3454
2846
|
|
|
3455
|
-
// lib/plugins/
|
|
3456
|
-
var
|
|
3457
|
-
name = "label-44-
|
|
2847
|
+
// lib/plugins/Label_44_OFF.ts
|
|
2848
|
+
var Label_44_OFF = class extends DecoderPlugin {
|
|
2849
|
+
name = "label-44-off";
|
|
3458
2850
|
qualifiers() {
|
|
3459
2851
|
return {
|
|
3460
2852
|
labels: ["44"],
|
|
3461
|
-
preambles: ["
|
|
2853
|
+
preambles: ["00OFF01", "00OFF02", "00OFF03", "OFF01", "OFF02", "OFF03"]
|
|
3462
2854
|
};
|
|
3463
2855
|
}
|
|
3464
2856
|
decode(message, options = {}) {
|
|
3465
2857
|
const decodeResult = this.defaultResult();
|
|
3466
2858
|
decodeResult.decoder.name = this.name;
|
|
3467
|
-
decodeResult.formatted.description = "
|
|
2859
|
+
decodeResult.formatted.description = "Off Runway Report";
|
|
3468
2860
|
decodeResult.message = message;
|
|
3469
2861
|
const data = message.text.split(",");
|
|
3470
|
-
if (data.length >=
|
|
2862
|
+
if (data.length >= 8) {
|
|
3471
2863
|
if (options.debug) {
|
|
3472
|
-
console.log("Label 44
|
|
2864
|
+
console.log("Label 44 Off Runway Report: groups");
|
|
3473
2865
|
console.log(data);
|
|
3474
2866
|
}
|
|
3475
2867
|
ResultFormatter.position(
|
|
3476
2868
|
decodeResult,
|
|
3477
2869
|
CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1])
|
|
3478
2870
|
);
|
|
3479
|
-
ResultFormatter.
|
|
3480
|
-
ResultFormatter.
|
|
3481
|
-
ResultFormatter.
|
|
3482
|
-
ResultFormatter.
|
|
3483
|
-
ResultFormatter.
|
|
3484
|
-
ResultFormatter.time_of_day(
|
|
2871
|
+
ResultFormatter.departureAirport(decodeResult, data[2]);
|
|
2872
|
+
ResultFormatter.arrivalAirport(decodeResult, data[3]);
|
|
2873
|
+
ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
|
|
2874
|
+
ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
|
|
2875
|
+
ResultFormatter.off(
|
|
3485
2876
|
decodeResult,
|
|
3486
|
-
DateTimeUtils.convertHHMMSSToTod(data[
|
|
2877
|
+
DateTimeUtils.convertHHMMSSToTod(data[5])
|
|
3487
2878
|
);
|
|
3488
2879
|
ResultFormatter.eta(
|
|
3489
2880
|
decodeResult,
|
|
3490
|
-
DateTimeUtils.convertHHMMSSToTod(data[
|
|
2881
|
+
DateTimeUtils.convertHHMMSSToTod(data[6])
|
|
3491
2882
|
);
|
|
3492
|
-
const fuel = Number(data[
|
|
2883
|
+
const fuel = Number(data[7]);
|
|
3493
2884
|
if (!isNaN(fuel)) {
|
|
3494
2885
|
ResultFormatter.remainingFuel(decodeResult, Number(fuel));
|
|
3495
2886
|
}
|
|
3496
|
-
if (data.length >
|
|
3497
|
-
ResultFormatter.unknownArr(decodeResult, data.slice(
|
|
2887
|
+
if (data.length > 8) {
|
|
2888
|
+
ResultFormatter.unknownArr(decodeResult, data.slice(8));
|
|
3498
2889
|
}
|
|
3499
2890
|
} else {
|
|
3500
2891
|
if (options.debug) {
|
|
@@ -3511,24 +2902,24 @@ var Label_44_ETA = class extends DecoderPlugin {
|
|
|
3511
2902
|
}
|
|
3512
2903
|
};
|
|
3513
2904
|
|
|
3514
|
-
// lib/plugins/
|
|
3515
|
-
var
|
|
3516
|
-
name = "label-44-
|
|
2905
|
+
// lib/plugins/Label_44_ON.ts
|
|
2906
|
+
var Label_44_ON = class extends DecoderPlugin {
|
|
2907
|
+
name = "label-44-on";
|
|
3517
2908
|
qualifiers() {
|
|
3518
2909
|
return {
|
|
3519
2910
|
labels: ["44"],
|
|
3520
|
-
preambles: ["
|
|
2911
|
+
preambles: ["00ON01", "00ON02", "00ON03", "ON01", "ON02", "ON03"]
|
|
3521
2912
|
};
|
|
3522
2913
|
}
|
|
3523
2914
|
decode(message, options = {}) {
|
|
3524
2915
|
const decodeResult = this.defaultResult();
|
|
3525
2916
|
decodeResult.decoder.name = this.name;
|
|
3526
|
-
decodeResult.formatted.description = "
|
|
2917
|
+
decodeResult.formatted.description = "On Runway Report";
|
|
3527
2918
|
decodeResult.message = message;
|
|
3528
2919
|
const data = message.text.split(",");
|
|
3529
2920
|
if (data.length >= 7) {
|
|
3530
2921
|
if (options.debug) {
|
|
3531
|
-
console.log("Label 44
|
|
2922
|
+
console.log("Label 44 On Runway Report: groups");
|
|
3532
2923
|
console.log(data);
|
|
3533
2924
|
}
|
|
3534
2925
|
ResultFormatter.position(
|
|
@@ -3539,7 +2930,7 @@ var Label_44_IN = class extends DecoderPlugin {
|
|
|
3539
2930
|
ResultFormatter.arrivalAirport(decodeResult, data[3]);
|
|
3540
2931
|
ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
|
|
3541
2932
|
ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
|
|
3542
|
-
ResultFormatter.
|
|
2933
|
+
ResultFormatter.on(
|
|
3543
2934
|
decodeResult,
|
|
3544
2935
|
DateTimeUtils.convertHHMMSSToTod(data[5])
|
|
3545
2936
|
);
|
|
@@ -3565,125 +2956,13 @@ var Label_44_IN = class extends DecoderPlugin {
|
|
|
3565
2956
|
}
|
|
3566
2957
|
};
|
|
3567
2958
|
|
|
3568
|
-
// lib/plugins/
|
|
3569
|
-
var
|
|
3570
|
-
name = "label-44-
|
|
2959
|
+
// lib/plugins/Label_44_POS.ts
|
|
2960
|
+
var Label_44_POS = class extends DecoderPlugin {
|
|
2961
|
+
name = "label-44-pos";
|
|
3571
2962
|
qualifiers() {
|
|
3572
2963
|
return {
|
|
3573
2964
|
labels: ["44"],
|
|
3574
|
-
preambles: ["
|
|
3575
|
-
};
|
|
3576
|
-
}
|
|
3577
|
-
decode(message, options = {}) {
|
|
3578
|
-
const decodeResult = this.defaultResult();
|
|
3579
|
-
decodeResult.decoder.name = this.name;
|
|
3580
|
-
decodeResult.formatted.description = "Off Runway Report";
|
|
3581
|
-
decodeResult.message = message;
|
|
3582
|
-
const data = message.text.split(",");
|
|
3583
|
-
if (data.length >= 8) {
|
|
3584
|
-
if (options.debug) {
|
|
3585
|
-
console.log("Label 44 Off Runway Report: groups");
|
|
3586
|
-
console.log(data);
|
|
3587
|
-
}
|
|
3588
|
-
ResultFormatter.position(
|
|
3589
|
-
decodeResult,
|
|
3590
|
-
CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1])
|
|
3591
|
-
);
|
|
3592
|
-
ResultFormatter.departureAirport(decodeResult, data[2]);
|
|
3593
|
-
ResultFormatter.arrivalAirport(decodeResult, data[3]);
|
|
3594
|
-
ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
|
|
3595
|
-
ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
|
|
3596
|
-
ResultFormatter.off(
|
|
3597
|
-
decodeResult,
|
|
3598
|
-
DateTimeUtils.convertHHMMSSToTod(data[5])
|
|
3599
|
-
);
|
|
3600
|
-
ResultFormatter.eta(
|
|
3601
|
-
decodeResult,
|
|
3602
|
-
DateTimeUtils.convertHHMMSSToTod(data[6])
|
|
3603
|
-
);
|
|
3604
|
-
const fuel = Number(data[7]);
|
|
3605
|
-
if (!isNaN(fuel)) {
|
|
3606
|
-
ResultFormatter.remainingFuel(decodeResult, Number(fuel));
|
|
3607
|
-
}
|
|
3608
|
-
if (data.length > 8) {
|
|
3609
|
-
ResultFormatter.unknownArr(decodeResult, data.slice(8));
|
|
3610
|
-
}
|
|
3611
|
-
} else {
|
|
3612
|
-
if (options.debug) {
|
|
3613
|
-
console.log(`Decoder: Unknown 44 message: ${message.text}`);
|
|
3614
|
-
}
|
|
3615
|
-
ResultFormatter.unknown(decodeResult, message.text);
|
|
3616
|
-
decodeResult.decoded = false;
|
|
3617
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
3618
|
-
return decodeResult;
|
|
3619
|
-
}
|
|
3620
|
-
decodeResult.decoded = true;
|
|
3621
|
-
decodeResult.decoder.decodeLevel = "full";
|
|
3622
|
-
return decodeResult;
|
|
3623
|
-
}
|
|
3624
|
-
};
|
|
3625
|
-
|
|
3626
|
-
// lib/plugins/Label_44_ON.ts
|
|
3627
|
-
var Label_44_ON = class extends DecoderPlugin {
|
|
3628
|
-
name = "label-44-on";
|
|
3629
|
-
qualifiers() {
|
|
3630
|
-
return {
|
|
3631
|
-
labels: ["44"],
|
|
3632
|
-
preambles: ["00ON01", "00ON02", "00ON03", "ON01", "ON02", "ON03"]
|
|
3633
|
-
};
|
|
3634
|
-
}
|
|
3635
|
-
decode(message, options = {}) {
|
|
3636
|
-
const decodeResult = this.defaultResult();
|
|
3637
|
-
decodeResult.decoder.name = this.name;
|
|
3638
|
-
decodeResult.formatted.description = "On Runway Report";
|
|
3639
|
-
decodeResult.message = message;
|
|
3640
|
-
const data = message.text.split(",");
|
|
3641
|
-
if (data.length >= 7) {
|
|
3642
|
-
if (options.debug) {
|
|
3643
|
-
console.log("Label 44 On Runway Report: groups");
|
|
3644
|
-
console.log(data);
|
|
3645
|
-
}
|
|
3646
|
-
ResultFormatter.position(
|
|
3647
|
-
decodeResult,
|
|
3648
|
-
CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1])
|
|
3649
|
-
);
|
|
3650
|
-
ResultFormatter.departureAirport(decodeResult, data[2]);
|
|
3651
|
-
ResultFormatter.arrivalAirport(decodeResult, data[3]);
|
|
3652
|
-
ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
|
|
3653
|
-
ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
|
|
3654
|
-
ResultFormatter.on(
|
|
3655
|
-
decodeResult,
|
|
3656
|
-
DateTimeUtils.convertHHMMSSToTod(data[5])
|
|
3657
|
-
);
|
|
3658
|
-
const fuel = Number(data[6]);
|
|
3659
|
-
if (!isNaN(fuel)) {
|
|
3660
|
-
ResultFormatter.remainingFuel(decodeResult, Number(fuel));
|
|
3661
|
-
}
|
|
3662
|
-
if (data.length > 7) {
|
|
3663
|
-
ResultFormatter.unknownArr(decodeResult, data.slice(7));
|
|
3664
|
-
}
|
|
3665
|
-
} else {
|
|
3666
|
-
if (options.debug) {
|
|
3667
|
-
console.log(`Decoder: Unknown 44 message: ${message.text}`);
|
|
3668
|
-
}
|
|
3669
|
-
ResultFormatter.unknown(decodeResult, message.text);
|
|
3670
|
-
decodeResult.decoded = false;
|
|
3671
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
3672
|
-
return decodeResult;
|
|
3673
|
-
}
|
|
3674
|
-
decodeResult.decoded = true;
|
|
3675
|
-
decodeResult.decoder.decodeLevel = "full";
|
|
3676
|
-
return decodeResult;
|
|
3677
|
-
}
|
|
3678
|
-
};
|
|
3679
|
-
|
|
3680
|
-
// lib/plugins/Label_44_POS.ts
|
|
3681
|
-
var Label_44_POS = class extends DecoderPlugin {
|
|
3682
|
-
name = "label-44-pos";
|
|
3683
|
-
qualifiers() {
|
|
3684
|
-
return {
|
|
3685
|
-
labels: ["44"],
|
|
3686
|
-
preambles: ["00POS01", "00POS02", "00POS03", "POS01", "POS02", "POS03"]
|
|
2965
|
+
preambles: ["00POS01", "00POS02", "00POS03", "POS01", "POS02", "POS03"]
|
|
3687
2966
|
};
|
|
3688
2967
|
}
|
|
3689
2968
|
decode(message, options = {}) {
|
|
@@ -3737,60 +3016,236 @@ var Label_44_POS = class extends DecoderPlugin {
|
|
|
3737
3016
|
}
|
|
3738
3017
|
};
|
|
3739
3018
|
|
|
3740
|
-
// lib/
|
|
3741
|
-
var
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3746
|
-
|
|
3747
|
-
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3019
|
+
// lib/utils/flight_plan_utils.ts
|
|
3020
|
+
var FlightPlanUtils = class _FlightPlanUtils {
|
|
3021
|
+
/**
|
|
3022
|
+
* Processes flight plan data
|
|
3023
|
+
*
|
|
3024
|
+
* Expected format is [header, fpei, val1, ... fpeiN, valN]
|
|
3025
|
+
*
|
|
3026
|
+
* @see https://atlaske-content.garmin.com/filestorage//email/outbound/attachments/GTN_Flight_Plan_and_User_Waypoint_transfer_Time1712844670119.pdf
|
|
3027
|
+
* @param decodeResult - results
|
|
3028
|
+
* @param data - original message split by ':'
|
|
3029
|
+
* @returns whether all fields were processed or not
|
|
3030
|
+
*/
|
|
3031
|
+
static processFlightPlan(decodeResult, data) {
|
|
3032
|
+
let allKnownFields = _FlightPlanUtils.parseHeader(decodeResult, data[0]);
|
|
3033
|
+
for (let i = 1; i < data.length; i += 2) {
|
|
3034
|
+
const fpei = data[i];
|
|
3035
|
+
const value = data[i + 1];
|
|
3036
|
+
switch (fpei) {
|
|
3037
|
+
case "A":
|
|
3038
|
+
_FlightPlanUtils.addProcedure(decodeResult, value, "arrival");
|
|
3039
|
+
break;
|
|
3040
|
+
case "AA":
|
|
3041
|
+
addArrivalAirport(decodeResult, value);
|
|
3042
|
+
break;
|
|
3043
|
+
case "AP":
|
|
3044
|
+
_FlightPlanUtils.addProcedure(decodeResult, value, "approach");
|
|
3045
|
+
break;
|
|
3046
|
+
case "CR":
|
|
3047
|
+
addCompanyRoute(decodeResult, value);
|
|
3048
|
+
break;
|
|
3049
|
+
case "D":
|
|
3050
|
+
_FlightPlanUtils.addProcedure(decodeResult, value, "departure");
|
|
3051
|
+
break;
|
|
3052
|
+
case "DA":
|
|
3053
|
+
addDepartureAirport(decodeResult, value);
|
|
3054
|
+
break;
|
|
3055
|
+
case "F":
|
|
3056
|
+
addRoute(decodeResult, value);
|
|
3057
|
+
break;
|
|
3058
|
+
case "FP":
|
|
3059
|
+
ResultFormatter.flightPlan(decodeResult, value.trim());
|
|
3060
|
+
break;
|
|
3061
|
+
case "R":
|
|
3062
|
+
addRunway(decodeResult, value);
|
|
3063
|
+
break;
|
|
3064
|
+
// case 'WS': // something about routes, has altitude, so current parsing won't work
|
|
3065
|
+
// break;
|
|
3066
|
+
default:
|
|
3067
|
+
if (allKnownFields) {
|
|
3068
|
+
decodeResult.remaining.text = "";
|
|
3069
|
+
allKnownFields = false;
|
|
3070
|
+
}
|
|
3071
|
+
decodeResult.remaining.text += `:${fpei}:${value}`;
|
|
3072
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
3758
3073
|
}
|
|
3759
|
-
ResultFormatter.unknown(decodeResult, message.text);
|
|
3760
|
-
decodeResult.decoded = false;
|
|
3761
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
3762
|
-
return decodeResult;
|
|
3763
3074
|
}
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3075
|
+
return allKnownFields;
|
|
3076
|
+
}
|
|
3077
|
+
static parseHeader(decodeResult, header) {
|
|
3078
|
+
let allKnownFields = true;
|
|
3079
|
+
if (header.startsWith("RF")) {
|
|
3080
|
+
decodeResult.formatted.items.push({
|
|
3081
|
+
type: "status",
|
|
3082
|
+
code: "ROUTE_STATUS",
|
|
3083
|
+
label: "Route Status",
|
|
3084
|
+
value: "Route Filed"
|
|
3774
3085
|
});
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
ResultFormatter.eta(
|
|
3779
|
-
decodeResult,
|
|
3780
|
-
DateTimeUtils.convertHHMMSSToTod(data[5])
|
|
3781
|
-
);
|
|
3782
|
-
if (data.length === 18) {
|
|
3783
|
-
ResultFormatter.unknownArr(decodeResult, data.slice(6, 8), ",");
|
|
3784
|
-
ResultFormatter.remainingFuel(decodeResult, parseFloat(data[8]));
|
|
3785
|
-
ResultFormatter.unknownArr(decodeResult, data.slice(9, 11), ",");
|
|
3786
|
-
ResultFormatter.arrivalRunway(decodeResult, data[11]);
|
|
3787
|
-
FlightPlanUtils.addProcedure(decodeResult, data[12], "arrival");
|
|
3788
|
-
ResultFormatter.unknownArr(decodeResult, data.slice(13, 18), ",");
|
|
3086
|
+
decodeResult.raw.route_status = "RF";
|
|
3087
|
+
if (header.length > 2) {
|
|
3088
|
+
addRoute(decodeResult, header.substring(2));
|
|
3789
3089
|
}
|
|
3090
|
+
} else if (header.startsWith("RP")) {
|
|
3091
|
+
decodeResult.raw.route_status = "RP";
|
|
3092
|
+
decodeResult.formatted.items.push({
|
|
3093
|
+
type: "status",
|
|
3094
|
+
code: "ROUTE_STATUS",
|
|
3095
|
+
label: "Route Status",
|
|
3096
|
+
value: "Route Planned"
|
|
3097
|
+
});
|
|
3098
|
+
decodeResult.raw.route_status = header;
|
|
3099
|
+
} else if (header.startsWith("RI")) {
|
|
3100
|
+
decodeResult.raw.route_status = "RI";
|
|
3101
|
+
decodeResult.formatted.items.push({
|
|
3102
|
+
type: "status",
|
|
3103
|
+
code: "ROUTE_STATUS",
|
|
3104
|
+
label: "Route Status",
|
|
3105
|
+
value: "Route Inactive"
|
|
3106
|
+
});
|
|
3107
|
+
} else if (header.startsWith("RM")) {
|
|
3108
|
+
decodeResult.raw.route_status = "RM";
|
|
3109
|
+
decodeResult.formatted.items.push({
|
|
3110
|
+
type: "status",
|
|
3111
|
+
code: "ROUTE_STATUS",
|
|
3112
|
+
label: "Route Status",
|
|
3113
|
+
value: "Route Mapped"
|
|
3114
|
+
});
|
|
3115
|
+
} else if (header.startsWith("RS")) {
|
|
3116
|
+
decodeResult.raw.route_status = "RS";
|
|
3117
|
+
decodeResult.formatted.items.push({
|
|
3118
|
+
type: "status",
|
|
3119
|
+
code: "ROUTE_STATUS",
|
|
3120
|
+
label: "Route Status",
|
|
3121
|
+
value: "Route Saved"
|
|
3122
|
+
});
|
|
3790
3123
|
} else {
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
|
|
3124
|
+
decodeResult.remaining.text += header;
|
|
3125
|
+
allKnownFields = false;
|
|
3126
|
+
}
|
|
3127
|
+
return allKnownFields;
|
|
3128
|
+
}
|
|
3129
|
+
static addProcedure(decodeResult, value, type) {
|
|
3130
|
+
if (decodeResult.raw.procedures === void 0) {
|
|
3131
|
+
decodeResult.raw.procedures = [];
|
|
3132
|
+
}
|
|
3133
|
+
const data = value.split(".");
|
|
3134
|
+
let waypoints;
|
|
3135
|
+
if (data.length > 1) {
|
|
3136
|
+
waypoints = data.slice(1).map((leg) => RouteUtils.getWaypoint(leg));
|
|
3137
|
+
}
|
|
3138
|
+
const route = { name: data[0], waypoints };
|
|
3139
|
+
decodeResult.raw.procedures.push({ type, route });
|
|
3140
|
+
const procedureName = type.substring(0, 1).toUpperCase() + type.slice(1);
|
|
3141
|
+
decodeResult.formatted.items.push({
|
|
3142
|
+
type: "procedure",
|
|
3143
|
+
code: "proc",
|
|
3144
|
+
label: `${procedureName} Procedure`,
|
|
3145
|
+
value: RouteUtils.routeToString(route)
|
|
3146
|
+
});
|
|
3147
|
+
}
|
|
3148
|
+
};
|
|
3149
|
+
function addArrivalAirport(decodeResult, value) {
|
|
3150
|
+
ResultFormatter.arrivalAirport(decodeResult, value);
|
|
3151
|
+
}
|
|
3152
|
+
function addDepartureAirport(decodeResult, value) {
|
|
3153
|
+
ResultFormatter.departureAirport(decodeResult, value);
|
|
3154
|
+
}
|
|
3155
|
+
function addRunway(decodeResult, value) {
|
|
3156
|
+
if (value.length === 8) {
|
|
3157
|
+
ResultFormatter.arrivalRunway(decodeResult, value.substring(4, 7));
|
|
3158
|
+
}
|
|
3159
|
+
ResultFormatter.departureRunway(decodeResult, value.substring(0, 3));
|
|
3160
|
+
}
|
|
3161
|
+
function addRoute(decodeResult, value) {
|
|
3162
|
+
const route = value.split(".");
|
|
3163
|
+
ResultFormatter.route(decodeResult, {
|
|
3164
|
+
waypoints: route.map((leg) => RouteUtils.getWaypoint(leg))
|
|
3165
|
+
});
|
|
3166
|
+
}
|
|
3167
|
+
function addCompanyRoute(decodeResult, value) {
|
|
3168
|
+
const segments = value.split(".");
|
|
3169
|
+
const parens_idx = segments[0].indexOf("(");
|
|
3170
|
+
let name;
|
|
3171
|
+
let runway;
|
|
3172
|
+
if (parens_idx === -1) {
|
|
3173
|
+
name = segments[0];
|
|
3174
|
+
} else {
|
|
3175
|
+
name = segments[0].slice(0, parens_idx);
|
|
3176
|
+
runway = segments[0].slice(parens_idx + 1, segments[0].indexOf(")"));
|
|
3177
|
+
}
|
|
3178
|
+
let waypoints;
|
|
3179
|
+
if (segments.length > 1) {
|
|
3180
|
+
waypoints = segments.slice(1).map((leg) => RouteUtils.getWaypoint(leg));
|
|
3181
|
+
}
|
|
3182
|
+
decodeResult.raw.company_route = {
|
|
3183
|
+
name,
|
|
3184
|
+
runway,
|
|
3185
|
+
waypoints
|
|
3186
|
+
};
|
|
3187
|
+
decodeResult.formatted.items.push({
|
|
3188
|
+
type: "company_route",
|
|
3189
|
+
code: "CR",
|
|
3190
|
+
label: "Company Route",
|
|
3191
|
+
value: RouteUtils.routeToString(decodeResult.raw.company_route)
|
|
3192
|
+
});
|
|
3193
|
+
}
|
|
3194
|
+
|
|
3195
|
+
// lib/plugins/Label_44_Slash.ts
|
|
3196
|
+
var Label_44_Slash = class extends DecoderPlugin {
|
|
3197
|
+
name = "label-44-slash";
|
|
3198
|
+
qualifiers() {
|
|
3199
|
+
return {
|
|
3200
|
+
labels: ["44"],
|
|
3201
|
+
preambles: [" /FB"]
|
|
3202
|
+
};
|
|
3203
|
+
}
|
|
3204
|
+
decode(message, options = {}) {
|
|
3205
|
+
const decodeResult = this.defaultResult();
|
|
3206
|
+
decodeResult.decoder.name = this.name;
|
|
3207
|
+
decodeResult.formatted.description = "Flight Briefing";
|
|
3208
|
+
decodeResult.message = message;
|
|
3209
|
+
const fields = message.text.split("/");
|
|
3210
|
+
if (fields.length !== 4) {
|
|
3211
|
+
if (options.debug) {
|
|
3212
|
+
console.log(`Decoder: Unknown 44 message: ${message.text}`);
|
|
3213
|
+
}
|
|
3214
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
3215
|
+
decodeResult.decoded = false;
|
|
3216
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
3217
|
+
return decodeResult;
|
|
3218
|
+
}
|
|
3219
|
+
ResultFormatter.unknownArr(decodeResult, fields.slice(0, 2), "/");
|
|
3220
|
+
const data = fields[3].split(",");
|
|
3221
|
+
if (data.length >= 6) {
|
|
3222
|
+
if (options.debug) {
|
|
3223
|
+
console.log("Label 44 Slash: groups");
|
|
3224
|
+
console.log(data);
|
|
3225
|
+
}
|
|
3226
|
+
ResultFormatter.position(decodeResult, {
|
|
3227
|
+
latitude: (data[0].charAt(0) === "S" ? -1 : 1) * parseFloat(data[0].slice(1).trim()),
|
|
3228
|
+
longitude: (data[1].charAt(0) === "W" ? -1 : 1) * parseFloat(data[1].slice(1).trim())
|
|
3229
|
+
});
|
|
3230
|
+
ResultFormatter.flightNumber(decodeResult, data[2]);
|
|
3231
|
+
ResultFormatter.unknown(decodeResult, data[3]);
|
|
3232
|
+
ResultFormatter.arrivalAirport(decodeResult, data[4]);
|
|
3233
|
+
ResultFormatter.eta(
|
|
3234
|
+
decodeResult,
|
|
3235
|
+
DateTimeUtils.convertHHMMSSToTod(data[5])
|
|
3236
|
+
);
|
|
3237
|
+
if (data.length === 18) {
|
|
3238
|
+
ResultFormatter.unknownArr(decodeResult, data.slice(6, 8), ",");
|
|
3239
|
+
ResultFormatter.remainingFuel(decodeResult, parseFloat(data[8]));
|
|
3240
|
+
ResultFormatter.unknownArr(decodeResult, data.slice(9, 11), ",");
|
|
3241
|
+
ResultFormatter.arrivalRunway(decodeResult, data[11]);
|
|
3242
|
+
FlightPlanUtils.addProcedure(decodeResult, data[12], "arrival");
|
|
3243
|
+
ResultFormatter.unknownArr(decodeResult, data.slice(13, 18), ",");
|
|
3244
|
+
}
|
|
3245
|
+
} else {
|
|
3246
|
+
if (options.debug) {
|
|
3247
|
+
console.log(`Decoder: Unknown 44 message: ${message.text}`);
|
|
3248
|
+
}
|
|
3794
3249
|
ResultFormatter.unknown(decodeResult, message.text);
|
|
3795
3250
|
decodeResult.decoded = false;
|
|
3796
3251
|
decodeResult.decoder.decodeLevel = "none";
|
|
@@ -3949,7 +3404,7 @@ var Label_4A_DIS = class extends DecoderPlugin {
|
|
|
3949
3404
|
DateTimeUtils.convertHHMMSSToTod(fields[1].substring(2) + "00")
|
|
3950
3405
|
);
|
|
3951
3406
|
ResultFormatter.callsign(decodeResult, fields[2]);
|
|
3952
|
-
ResultFormatter.
|
|
3407
|
+
ResultFormatter.text(decodeResult, fields.slice(3).join(""));
|
|
3953
3408
|
if (decodeResult.decoded) {
|
|
3954
3409
|
if (!decodeResult.remaining.text)
|
|
3955
3410
|
decodeResult.decoder.decodeLevel = "full";
|
|
@@ -4034,38 +3489,6 @@ var Label_4A_Slash_01 = class extends DecoderPlugin {
|
|
|
4034
3489
|
}
|
|
4035
3490
|
};
|
|
4036
3491
|
|
|
4037
|
-
// lib/plugins/Label_4J_POS.ts
|
|
4038
|
-
var Label_4J_POS = class extends DecoderPlugin {
|
|
4039
|
-
name = "label-4j-pos";
|
|
4040
|
-
qualifiers() {
|
|
4041
|
-
return {
|
|
4042
|
-
labels: ["4J"],
|
|
4043
|
-
preambles: ["POS/"]
|
|
4044
|
-
};
|
|
4045
|
-
}
|
|
4046
|
-
// copied from Label_H1.ts since i don't really want to have to have
|
|
4047
|
-
// something named like that decode more than 1 type
|
|
4048
|
-
// if we figure out a good name, i'll combine them
|
|
4049
|
-
decode(message, options = {}) {
|
|
4050
|
-
let decodeResult = this.defaultResult();
|
|
4051
|
-
decodeResult.decoder.name = this.name;
|
|
4052
|
-
decodeResult.message = message;
|
|
4053
|
-
const msg = message.text.replace(/\n|\r/g, "");
|
|
4054
|
-
const decoded = H1Helper.decodeH1Message(decodeResult, msg);
|
|
4055
|
-
decodeResult.decoded = decoded;
|
|
4056
|
-
decodeResult.decoder.decodeLevel = !decodeResult.remaining.text ? "full" : "partial";
|
|
4057
|
-
if (decodeResult.formatted.items.length === 0) {
|
|
4058
|
-
if (options.debug) {
|
|
4059
|
-
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
4060
|
-
}
|
|
4061
|
-
ResultFormatter.unknown(decodeResult, message.text);
|
|
4062
|
-
decodeResult.decoded = false;
|
|
4063
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
4064
|
-
}
|
|
4065
|
-
return decodeResult;
|
|
4066
|
-
}
|
|
4067
|
-
};
|
|
4068
|
-
|
|
4069
3492
|
// lib/plugins/Label_4N.ts
|
|
4070
3493
|
var Label_4N = class extends DecoderPlugin {
|
|
4071
3494
|
name = "label-4n";
|
|
@@ -4426,6 +3849,9 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
4426
3849
|
}
|
|
4427
3850
|
parseCsvFormat(text, results) {
|
|
4428
3851
|
const csvParts = text.split(",");
|
|
3852
|
+
if (csvParts.length !== 9) {
|
|
3853
|
+
return;
|
|
3854
|
+
}
|
|
4429
3855
|
const header = csvParts[0].trim().split(/\s+/);
|
|
4430
3856
|
ResultFormatter.unknown(results, header[0], " ");
|
|
4431
3857
|
ResultFormatter.unknown(results, header[1], " ");
|
|
@@ -4507,101 +3933,645 @@ var Label_83 = class extends DecoderPlugin {
|
|
|
4507
3933
|
ResultFormatter.unknown(decodeResult, text);
|
|
4508
3934
|
}
|
|
4509
3935
|
}
|
|
4510
|
-
if (decodeResult.decoded) {
|
|
4511
|
-
if (!decodeResult.remaining.text)
|
|
4512
|
-
decodeResult.decoder.decodeLevel = "full";
|
|
4513
|
-
else decodeResult.decoder.decodeLevel = "partial";
|
|
4514
|
-
} else {
|
|
4515
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
3936
|
+
if (decodeResult.decoded) {
|
|
3937
|
+
if (!decodeResult.remaining.text)
|
|
3938
|
+
decodeResult.decoder.decodeLevel = "full";
|
|
3939
|
+
else decodeResult.decoder.decodeLevel = "partial";
|
|
3940
|
+
} else {
|
|
3941
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
3942
|
+
}
|
|
3943
|
+
return decodeResult;
|
|
3944
|
+
}
|
|
3945
|
+
};
|
|
3946
|
+
|
|
3947
|
+
// lib/plugins/Label_8E.ts
|
|
3948
|
+
var Label_8E = class extends DecoderPlugin {
|
|
3949
|
+
name = "label-8e";
|
|
3950
|
+
qualifiers() {
|
|
3951
|
+
return {
|
|
3952
|
+
labels: ["8E"]
|
|
3953
|
+
};
|
|
3954
|
+
}
|
|
3955
|
+
decode(message, options = {}) {
|
|
3956
|
+
const decodeResult = this.defaultResult();
|
|
3957
|
+
decodeResult.decoder.name = this.name;
|
|
3958
|
+
decodeResult.formatted.description = "ETA Report";
|
|
3959
|
+
decodeResult.message = message;
|
|
3960
|
+
const regex = /^(?<arrival_icao>\w{4}),(?<arrival_eta>\d{4})$/;
|
|
3961
|
+
const results = message.text.match(regex);
|
|
3962
|
+
if (results?.groups) {
|
|
3963
|
+
if (options.debug) {
|
|
3964
|
+
console.log("Label 8E ETA: groups");
|
|
3965
|
+
console.log(results.groups);
|
|
3966
|
+
}
|
|
3967
|
+
ResultFormatter.eta(
|
|
3968
|
+
decodeResult,
|
|
3969
|
+
DateTimeUtils.convertHHMMSSToTod(results.groups.arrival_eta)
|
|
3970
|
+
);
|
|
3971
|
+
ResultFormatter.arrivalAirport(decodeResult, results.groups.arrival_icao);
|
|
3972
|
+
}
|
|
3973
|
+
decodeResult.decoded = true;
|
|
3974
|
+
decodeResult.decoder.decodeLevel = "full";
|
|
3975
|
+
return decodeResult;
|
|
3976
|
+
}
|
|
3977
|
+
};
|
|
3978
|
+
|
|
3979
|
+
// lib/plugins/Label_B6.ts
|
|
3980
|
+
var Label_B6_Forwardslash = class extends DecoderPlugin {
|
|
3981
|
+
name = "label-b6-forwardslash";
|
|
3982
|
+
qualifiers() {
|
|
3983
|
+
return {
|
|
3984
|
+
labels: ["B6"],
|
|
3985
|
+
preambles: ["/"]
|
|
3986
|
+
};
|
|
3987
|
+
}
|
|
3988
|
+
decode(message, options = {}) {
|
|
3989
|
+
const decodeResult = this.defaultResult();
|
|
3990
|
+
decodeResult.decoder.name = this.name;
|
|
3991
|
+
decodeResult.formatted.description = "CPDLC Message";
|
|
3992
|
+
decodeResult.message = message;
|
|
3993
|
+
if (options.debug) {
|
|
3994
|
+
console.log("CPDLC: " + message);
|
|
3995
|
+
}
|
|
3996
|
+
return decodeResult;
|
|
3997
|
+
}
|
|
3998
|
+
};
|
|
3999
|
+
|
|
4000
|
+
// lib/plugins/Label_ColonComma.ts
|
|
4001
|
+
var Label_ColonComma = class extends DecoderPlugin {
|
|
4002
|
+
name = "label-colon-comma";
|
|
4003
|
+
qualifiers() {
|
|
4004
|
+
return {
|
|
4005
|
+
labels: [":;"]
|
|
4006
|
+
};
|
|
4007
|
+
}
|
|
4008
|
+
decode(message, options = {}) {
|
|
4009
|
+
const decodeResult = this.defaultResult();
|
|
4010
|
+
decodeResult.decoder.name = this.name;
|
|
4011
|
+
decodeResult.raw.frequency = Number(message.text) / 1e3;
|
|
4012
|
+
decodeResult.formatted.description = "Aircraft Transceiver Frequency Change";
|
|
4013
|
+
decodeResult.formatted.items.push({
|
|
4014
|
+
type: "frequency",
|
|
4015
|
+
label: "Frequency",
|
|
4016
|
+
value: `${decodeResult.raw.frequency} MHz`,
|
|
4017
|
+
code: "FREQ"
|
|
4018
|
+
});
|
|
4019
|
+
decodeResult.decoded = true;
|
|
4020
|
+
decodeResult.decoder.decodeLevel = "full";
|
|
4021
|
+
return decodeResult;
|
|
4022
|
+
}
|
|
4023
|
+
};
|
|
4024
|
+
|
|
4025
|
+
// lib/utils/arinc_702_helper.ts
|
|
4026
|
+
var Arinc702Helper = class _Arinc702Helper {
|
|
4027
|
+
/**
|
|
4028
|
+
* Decodes an ARINC 702 message
|
|
4029
|
+
*
|
|
4030
|
+
* Steps:
|
|
4031
|
+
* 1. Check against known checksum algorithms to determine if message is valid
|
|
4032
|
+
* 2. Parse the Imbedded Message Identifier (IMI) to determine the type of message
|
|
4033
|
+
* 3. Iterate through the Information Elements (IEI) and decode known fields, while storing unknown fields for further analysis
|
|
4034
|
+
*
|
|
4035
|
+
* @param decodeResult - object to store decoded results in
|
|
4036
|
+
* @param message - message to decode
|
|
4037
|
+
* @returns boolean indicating if the message was successfully decoded
|
|
4038
|
+
*/
|
|
4039
|
+
static decodeH1Message(decodeResult, message) {
|
|
4040
|
+
decodeResult.remaining.text = "";
|
|
4041
|
+
const checksum = parseInt(message.slice(-4), 16);
|
|
4042
|
+
const data = message.slice(0, message.length - 4);
|
|
4043
|
+
let checksumAlgorithmUsed = "";
|
|
4044
|
+
if (crc16IbmSdlcRev(data) === checksum) {
|
|
4045
|
+
checksumAlgorithmUsed = "IBM-SDLC reversed";
|
|
4046
|
+
} else if (crc16Genibus(data) === checksum) {
|
|
4047
|
+
checksumAlgorithmUsed = "GENIBUS";
|
|
4048
|
+
} else {
|
|
4049
|
+
decodeResult.decoded = false;
|
|
4050
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
4051
|
+
return false;
|
|
4052
|
+
}
|
|
4053
|
+
const fields = data.split("/");
|
|
4054
|
+
const canDecode = parseMessageType(decodeResult, fields[0]);
|
|
4055
|
+
if (!canDecode) {
|
|
4056
|
+
decodeResult.decoded = false;
|
|
4057
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
4058
|
+
return false;
|
|
4059
|
+
}
|
|
4060
|
+
for (let i = 1; i < fields.length; ++i) {
|
|
4061
|
+
const iei = fields[i].substring(0, 2);
|
|
4062
|
+
const data2 = fields[i].substring(2);
|
|
4063
|
+
switch (iei) {
|
|
4064
|
+
case "AF":
|
|
4065
|
+
processAirField(decodeResult, data2.split(","));
|
|
4066
|
+
break;
|
|
4067
|
+
case "AK":
|
|
4068
|
+
ResultFormatter.unknown(decodeResult, fields[i], "/");
|
|
4069
|
+
break;
|
|
4070
|
+
case "CG":
|
|
4071
|
+
processCenterOfGravity(decodeResult, data2.split(","));
|
|
4072
|
+
break;
|
|
4073
|
+
case "DC":
|
|
4074
|
+
processDateCode(decodeResult, data2.split(","));
|
|
4075
|
+
break;
|
|
4076
|
+
case "DI":
|
|
4077
|
+
ResultFormatter.unknown(decodeResult, fields[i], "/");
|
|
4078
|
+
break;
|
|
4079
|
+
case "DT":
|
|
4080
|
+
processDT(decodeResult, data2.split(","));
|
|
4081
|
+
break;
|
|
4082
|
+
case "DQ":
|
|
4083
|
+
ResultFormatter.desiredAltitude(
|
|
4084
|
+
decodeResult,
|
|
4085
|
+
parseInt(data2, 10) * 100
|
|
4086
|
+
);
|
|
4087
|
+
break;
|
|
4088
|
+
case "ET":
|
|
4089
|
+
processETA(data2, decodeResult, fields, i);
|
|
4090
|
+
break;
|
|
4091
|
+
case "FB":
|
|
4092
|
+
ResultFormatter.currentFuel(decodeResult, parseInt(data2, 10));
|
|
4093
|
+
break;
|
|
4094
|
+
case "FN":
|
|
4095
|
+
decodeResult.raw.flight_number = data2;
|
|
4096
|
+
break;
|
|
4097
|
+
case "FX":
|
|
4098
|
+
ResultFormatter.text(decodeResult, data2);
|
|
4099
|
+
break;
|
|
4100
|
+
case "GA":
|
|
4101
|
+
ResultFormatter.groundAddress(decodeResult, data2);
|
|
4102
|
+
break;
|
|
4103
|
+
case "ID":
|
|
4104
|
+
processIdentification(decodeResult, data2.split(","));
|
|
4105
|
+
break;
|
|
4106
|
+
case "LR":
|
|
4107
|
+
processLandingReport(decodeResult, data2.split(","));
|
|
4108
|
+
break;
|
|
4109
|
+
case "MR":
|
|
4110
|
+
processMessageReference(decodeResult, data2.split(","));
|
|
4111
|
+
break;
|
|
4112
|
+
case "PR":
|
|
4113
|
+
processPerformanceData(decodeResult, data2.split(","));
|
|
4114
|
+
break;
|
|
4115
|
+
//case 'PR':
|
|
4116
|
+
// TODO: decode /PR fields
|
|
4117
|
+
// ResultFormatter.unknown(decodeResult, fields[i], '/');
|
|
4118
|
+
// break;
|
|
4119
|
+
case "PS":
|
|
4120
|
+
_Arinc702Helper.processPS(decodeResult, data2.split(","));
|
|
4121
|
+
break;
|
|
4122
|
+
case "RF":
|
|
4123
|
+
case "RI":
|
|
4124
|
+
case "RM":
|
|
4125
|
+
case "RP":
|
|
4126
|
+
case "RS":
|
|
4127
|
+
FlightPlanUtils.processFlightPlan(decodeResult, fields[i].split(":"));
|
|
4128
|
+
break;
|
|
4129
|
+
case "RN":
|
|
4130
|
+
ResultFormatter.routeNumber(decodeResult, data2);
|
|
4131
|
+
break;
|
|
4132
|
+
case "RW":
|
|
4133
|
+
processRunway(decodeResult, data2.split(":"));
|
|
4134
|
+
break;
|
|
4135
|
+
case "SN":
|
|
4136
|
+
decodeResult.raw.serial_number = data2;
|
|
4137
|
+
break;
|
|
4138
|
+
case "SP":
|
|
4139
|
+
ResultFormatter.startPoint(decodeResult, data2);
|
|
4140
|
+
break;
|
|
4141
|
+
case "TD":
|
|
4142
|
+
processTimeOfDeparture(decodeResult, data2.split(","));
|
|
4143
|
+
break;
|
|
4144
|
+
case "TS":
|
|
4145
|
+
_Arinc702Helper.processTimeStamp(decodeResult, data2.split(","));
|
|
4146
|
+
break;
|
|
4147
|
+
case "VR":
|
|
4148
|
+
ResultFormatter.version(decodeResult, parseInt(data2, 10) / 10);
|
|
4149
|
+
break;
|
|
4150
|
+
case "WD":
|
|
4151
|
+
processWindData(decodeResult, data2);
|
|
4152
|
+
break;
|
|
4153
|
+
case "WQ":
|
|
4154
|
+
processWeatherQuery(decodeResult, data2.split(":"));
|
|
4155
|
+
break;
|
|
4156
|
+
default:
|
|
4157
|
+
console.log(`Unknown IEI ${iei} in H1 message, data: ${data2}`);
|
|
4158
|
+
console.log(`Remaing text: ${decodeResult.remaining.text}`);
|
|
4159
|
+
ResultFormatter.unknown(decodeResult, fields[i], "/");
|
|
4160
|
+
}
|
|
4161
|
+
}
|
|
4162
|
+
ResultFormatter.checksumAlgorithm(decodeResult, checksumAlgorithmUsed);
|
|
4163
|
+
ResultFormatter.checksum(decodeResult, checksum);
|
|
4164
|
+
return true;
|
|
4165
|
+
}
|
|
4166
|
+
static processPS(decodeResult, data) {
|
|
4167
|
+
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(
|
|
4168
|
+
data[0]
|
|
4169
|
+
);
|
|
4170
|
+
if (position) {
|
|
4171
|
+
ResultFormatter.position(decodeResult, position);
|
|
4172
|
+
}
|
|
4173
|
+
if (data.length === 9) {
|
|
4174
|
+
processRoute(decodeResult, data[3], data[1], data[5], data[4], void 0);
|
|
4175
|
+
ResultFormatter.altitude(decodeResult, Number(data[2]) * 100);
|
|
4176
|
+
ResultFormatter.temperature(decodeResult, data[6]);
|
|
4177
|
+
ResultFormatter.unknown(decodeResult, data[7]);
|
|
4178
|
+
ResultFormatter.unknown(decodeResult, data[8]);
|
|
4179
|
+
}
|
|
4180
|
+
if (data.length === 14) {
|
|
4181
|
+
ResultFormatter.altitude(decodeResult, Number(data[3]) * 100);
|
|
4182
|
+
processRoute(decodeResult, data[1], data[2], data[4], data[5], data[6]);
|
|
4183
|
+
ResultFormatter.temperature(decodeResult, data[7]);
|
|
4184
|
+
ResultFormatter.unknownArr(decodeResult, data.slice(8));
|
|
4185
|
+
}
|
|
4186
|
+
}
|
|
4187
|
+
static processPosition(decodeResult, data) {
|
|
4188
|
+
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(
|
|
4189
|
+
data[0]
|
|
4190
|
+
);
|
|
4191
|
+
if (position) {
|
|
4192
|
+
ResultFormatter.position(decodeResult, position);
|
|
4193
|
+
}
|
|
4194
|
+
if (data.length >= 10) {
|
|
4195
|
+
ResultFormatter.altitude(decodeResult, Number(data[3]) * 100);
|
|
4196
|
+
processRoute(decodeResult, data[1], data[2], data[4], data[5], data[6]);
|
|
4197
|
+
ResultFormatter.temperature(decodeResult, data[7]);
|
|
4198
|
+
ResultFormatter.unknown(decodeResult, data[8]);
|
|
4199
|
+
ResultFormatter.unknown(decodeResult, data[9]);
|
|
4200
|
+
}
|
|
4201
|
+
if (data.length >= 14) {
|
|
4202
|
+
ResultFormatter.unknownArr(decodeResult, data.slice(10));
|
|
4203
|
+
}
|
|
4204
|
+
}
|
|
4205
|
+
static processTimeStamp(decodeResult, data) {
|
|
4206
|
+
if (data.length > 2) {
|
|
4207
|
+
const positionData = data.slice(1);
|
|
4208
|
+
positionData[0] = positionData[0].substring(6);
|
|
4209
|
+
this.processPosition(decodeResult, positionData);
|
|
4210
|
+
}
|
|
4211
|
+
let time = DateTimeUtils.convertDateTimeToEpoch(
|
|
4212
|
+
data[0],
|
|
4213
|
+
data[1].substring(0, 6)
|
|
4214
|
+
);
|
|
4215
|
+
if (Number.isNaN(time)) {
|
|
4216
|
+
const date = data[1].substring(2, 4) + data[1].substring(0, 2) + data[1].substring(4, 6);
|
|
4217
|
+
time = DateTimeUtils.convertDateTimeToEpoch(data[0], date);
|
|
4218
|
+
}
|
|
4219
|
+
decodeResult.raw.message_timestamp = time;
|
|
4220
|
+
}
|
|
4221
|
+
};
|
|
4222
|
+
function processETA(data, decodeResult, fields, i) {
|
|
4223
|
+
if (data.length === 5) {
|
|
4224
|
+
ResultFormatter.day(decodeResult, Number(data.substring(0, 1)));
|
|
4225
|
+
ResultFormatter.eta(
|
|
4226
|
+
decodeResult,
|
|
4227
|
+
DateTimeUtils.convertHHMMSSToTod(data.substring(1))
|
|
4228
|
+
);
|
|
4229
|
+
} else if (data.length === 6) {
|
|
4230
|
+
ResultFormatter.day(decodeResult, Number(data.substring(0, 2)));
|
|
4231
|
+
ResultFormatter.eta(
|
|
4232
|
+
decodeResult,
|
|
4233
|
+
DateTimeUtils.convertHHMMSSToTod(data.substring(2))
|
|
4234
|
+
);
|
|
4235
|
+
} else {
|
|
4236
|
+
ResultFormatter.unknown(decodeResult, fields[i], "/");
|
|
4237
|
+
}
|
|
4238
|
+
}
|
|
4239
|
+
function processAirField(decodeResult, data) {
|
|
4240
|
+
if (data.length === 2) {
|
|
4241
|
+
ResultFormatter.departureAirport(decodeResult, data[0]);
|
|
4242
|
+
ResultFormatter.arrivalAirport(decodeResult, data[1]);
|
|
4243
|
+
} else {
|
|
4244
|
+
ResultFormatter.unknown(decodeResult, data.join(","), "AF/");
|
|
4245
|
+
}
|
|
4246
|
+
}
|
|
4247
|
+
function processTimeOfDeparture(decodeResult, data) {
|
|
4248
|
+
if (data.length === 2) {
|
|
4249
|
+
decodeResult.raw.planned_departure_time = data[0];
|
|
4250
|
+
decodeResult.formatted.items.push({
|
|
4251
|
+
type: "ptd",
|
|
4252
|
+
code: "ptd",
|
|
4253
|
+
label: "Planned Departure Time",
|
|
4254
|
+
value: `YYYY-MM-${data[0].substring(0, 2)}T${data[0].substring(2, 4)}:${data[0].substring(4)}:00Z`
|
|
4255
|
+
});
|
|
4256
|
+
decodeResult.raw.estimated_departure_time = data[1];
|
|
4257
|
+
decodeResult.formatted.items.push({
|
|
4258
|
+
type: "etd",
|
|
4259
|
+
code: "etd",
|
|
4260
|
+
label: "Estimated Departure Time",
|
|
4261
|
+
value: `${data[1].substring(0, 2)}:${data[1].substring(2)}`
|
|
4262
|
+
});
|
|
4263
|
+
} else {
|
|
4264
|
+
ResultFormatter.unknown(decodeResult, data.join(","), "/TD");
|
|
4265
|
+
}
|
|
4266
|
+
}
|
|
4267
|
+
function processIdentification(decodeResult, data) {
|
|
4268
|
+
ResultFormatter.tail(decodeResult, data[0]);
|
|
4269
|
+
if (data.length > 1) {
|
|
4270
|
+
ResultFormatter.flightNumber(decodeResult, data[1]);
|
|
4271
|
+
}
|
|
4272
|
+
if (data.length > 2) {
|
|
4273
|
+
decodeResult.raw.mission_number = data[2];
|
|
4274
|
+
}
|
|
4275
|
+
}
|
|
4276
|
+
function processDT(decodeResult, data) {
|
|
4277
|
+
if (data.length === 9) {
|
|
4278
|
+
ResultFormatter.unknown(decodeResult, data[0]);
|
|
4279
|
+
if (!decodeResult.raw.arrival_icao) {
|
|
4280
|
+
ResultFormatter.arrivalAirport(decodeResult, data[1]);
|
|
4281
|
+
}
|
|
4282
|
+
ResultFormatter.arrivalRunway(decodeResult, data[2]);
|
|
4283
|
+
ResultFormatter.currentFuel(decodeResult, parseInt(data[3], 10));
|
|
4284
|
+
ResultFormatter.eta(
|
|
4285
|
+
decodeResult,
|
|
4286
|
+
DateTimeUtils.convertHHMMSSToTod(data[4])
|
|
4287
|
+
);
|
|
4288
|
+
ResultFormatter.unknown(decodeResult, data[5]);
|
|
4289
|
+
ResultFormatter.position(
|
|
4290
|
+
decodeResult,
|
|
4291
|
+
CoordinateUtils.decodeStringCoordinates(data[6])
|
|
4292
|
+
);
|
|
4293
|
+
ResultFormatter.unknown(decodeResult, data[7]);
|
|
4294
|
+
ResultFormatter.unknown(decodeResult, data[8]);
|
|
4295
|
+
return;
|
|
4296
|
+
}
|
|
4297
|
+
if (data.length === 4 || data.length === 5) {
|
|
4298
|
+
if (!decodeResult.raw.arrival_icao) {
|
|
4299
|
+
ResultFormatter.arrivalAirport(decodeResult, data[0]);
|
|
4300
|
+
}
|
|
4301
|
+
ResultFormatter.arrivalRunway(decodeResult, data[1]);
|
|
4302
|
+
ResultFormatter.currentFuel(decodeResult, parseInt(data[2], 10));
|
|
4303
|
+
ResultFormatter.eta(
|
|
4304
|
+
decodeResult,
|
|
4305
|
+
DateTimeUtils.convertHHMMSSToTod(data[3])
|
|
4306
|
+
);
|
|
4307
|
+
if (data.length > 4) {
|
|
4308
|
+
ResultFormatter.remainingFuel(decodeResult, Number(data[4]));
|
|
4309
|
+
}
|
|
4310
|
+
return;
|
|
4311
|
+
}
|
|
4312
|
+
ResultFormatter.unknownArr(decodeResult, data, ",");
|
|
4313
|
+
}
|
|
4314
|
+
function processLandingReport(decodeResult, data) {
|
|
4315
|
+
if (data.length === 19) {
|
|
4316
|
+
ResultFormatter.unknown(decodeResult, data[1]);
|
|
4317
|
+
ResultFormatter.flightNumber(decodeResult, data[2]);
|
|
4318
|
+
ResultFormatter.departureAirport(decodeResult, data[3]);
|
|
4319
|
+
ResultFormatter.arrivalAirport(decodeResult, data[4]);
|
|
4320
|
+
ResultFormatter.arrivalRunway(decodeResult, data[5]);
|
|
4321
|
+
ResultFormatter.unknown(decodeResult, data.slice(6, 19).join(","));
|
|
4322
|
+
} else {
|
|
4323
|
+
ResultFormatter.unknown(decodeResult, data.join(","));
|
|
4324
|
+
}
|
|
4325
|
+
}
|
|
4326
|
+
function processCenterOfGravity(decodeResult, data) {
|
|
4327
|
+
if (data.length === 1) {
|
|
4328
|
+
if (data[0] !== void 0 && data[0] !== "") {
|
|
4329
|
+
ResultFormatter.cg(decodeResult, parseInt(data[0], 10) / 10);
|
|
4330
|
+
}
|
|
4331
|
+
} else if (data.length === 3) {
|
|
4332
|
+
if (data[0] !== void 0 && data[0] !== "") {
|
|
4333
|
+
ResultFormatter.cg(decodeResult, parseInt(data[0], 10) / 10, "center");
|
|
4334
|
+
}
|
|
4335
|
+
if (data[1] !== void 0 && data[1] !== "") {
|
|
4336
|
+
ResultFormatter.cg(decodeResult, parseInt(data[1], 10) / 10, "lower");
|
|
4337
|
+
}
|
|
4338
|
+
if (data[2] !== void 0 && data[2] !== "") {
|
|
4339
|
+
ResultFormatter.cg(decodeResult, parseInt(data[2], 10) / 10, "upper");
|
|
4340
|
+
}
|
|
4341
|
+
} else {
|
|
4342
|
+
ResultFormatter.unknown(decodeResult, data.join(","));
|
|
4343
|
+
}
|
|
4344
|
+
}
|
|
4345
|
+
function parseMessageType(decodeResult, messagePart) {
|
|
4346
|
+
const messageParts = messagePart.split(",");
|
|
4347
|
+
const messageType = messageParts[0];
|
|
4348
|
+
if (messageType.startsWith("POS")) {
|
|
4349
|
+
Arinc702Helper.processPosition(
|
|
4350
|
+
decodeResult,
|
|
4351
|
+
messagePart.substring(3).split(",")
|
|
4352
|
+
);
|
|
4353
|
+
return processIMI(decodeResult, "POS");
|
|
4354
|
+
} else if (messageType.length === 6) {
|
|
4355
|
+
const part1 = processIMI(decodeResult, messageType.substring(0, 3));
|
|
4356
|
+
const description = decodeResult.formatted.description;
|
|
4357
|
+
const part2 = processIMI(decodeResult, messageType.substring(3, 6));
|
|
4358
|
+
decodeResult.formatted.description = description + " for " + decodeResult.formatted.description;
|
|
4359
|
+
if (messageParts.length > 1) {
|
|
4360
|
+
ResultFormatter.unknown(
|
|
4361
|
+
decodeResult,
|
|
4362
|
+
messageParts.slice(1).join(","),
|
|
4363
|
+
"/"
|
|
4364
|
+
);
|
|
4365
|
+
}
|
|
4366
|
+
return part1 && part2;
|
|
4367
|
+
}
|
|
4368
|
+
if (messageParts.length > 1) {
|
|
4369
|
+
ResultFormatter.unknown(decodeResult, messageParts.slice(1).join(","), "/");
|
|
4370
|
+
}
|
|
4371
|
+
return processIMI(decodeResult, messageType);
|
|
4372
|
+
}
|
|
4373
|
+
function processIMI(decodeResult, type) {
|
|
4374
|
+
if (type === "FPN") {
|
|
4375
|
+
decodeResult.formatted.description = "Flight Plan";
|
|
4376
|
+
} else if (type === "FTX") {
|
|
4377
|
+
decodeResult.formatted.description = "Free Text";
|
|
4378
|
+
} else if (type === "INI") {
|
|
4379
|
+
decodeResult.formatted.description = "Initial Report";
|
|
4380
|
+
} else if (type === "INR") {
|
|
4381
|
+
decodeResult.formatted.description = "In-Range Report";
|
|
4382
|
+
} else if (type === "LDI") {
|
|
4383
|
+
decodeResult.formatted.description = "Load Distribution Information";
|
|
4384
|
+
} else if (type === "PER") {
|
|
4385
|
+
decodeResult.formatted.description = "Performance Report";
|
|
4386
|
+
} else if (type === "POS") {
|
|
4387
|
+
decodeResult.formatted.description = "Position Report";
|
|
4388
|
+
} else if (type === "PRG") {
|
|
4389
|
+
decodeResult.formatted.description = "Progress Report";
|
|
4390
|
+
} else if (type === "PWI") {
|
|
4391
|
+
decodeResult.formatted.description = "Pilot Weather Information";
|
|
4392
|
+
} else if (type === "WXR") {
|
|
4393
|
+
decodeResult.formatted.description = "Weather Report";
|
|
4394
|
+
} else if (type === "REJ") {
|
|
4395
|
+
decodeResult.formatted.description = "Reject";
|
|
4396
|
+
} else if (type === "REQ") {
|
|
4397
|
+
decodeResult.formatted.description = "Request";
|
|
4398
|
+
} else if (type === "RES") {
|
|
4399
|
+
decodeResult.formatted.description = "Response";
|
|
4400
|
+
} else if (type === "SUM") {
|
|
4401
|
+
decodeResult.formatted.description = "Summary Report";
|
|
4402
|
+
} else {
|
|
4403
|
+
decodeResult.formatted.description = "Unknown H1 Message";
|
|
4404
|
+
return false;
|
|
4405
|
+
}
|
|
4406
|
+
return true;
|
|
4407
|
+
}
|
|
4408
|
+
function processPerformanceData(decodeResult, data) {
|
|
4409
|
+
if (data.length < 3) {
|
|
4410
|
+
ResultFormatter.unknownArr(decodeResult, data, ",");
|
|
4411
|
+
return;
|
|
4412
|
+
}
|
|
4413
|
+
if (data[2] !== void 0 && data[2] !== "") {
|
|
4414
|
+
const alt = Number(data[2]) * 100;
|
|
4415
|
+
if (!isNaN(alt) && alt > 0) {
|
|
4416
|
+
ResultFormatter.altitude(decodeResult, alt);
|
|
4417
|
+
}
|
|
4418
|
+
}
|
|
4419
|
+
if (data.length > 8 && data[8] !== void 0 && data[8] !== "") {
|
|
4420
|
+
ResultFormatter.temperature(decodeResult, data[8]);
|
|
4421
|
+
}
|
|
4422
|
+
const remaining = [];
|
|
4423
|
+
for (let i = 0; i < data.length; i++) {
|
|
4424
|
+
if (i === 2 && data[i] !== "" && !isNaN(Number(data[i])) && Number(data[i]) * 100 > 0) {
|
|
4425
|
+
continue;
|
|
4516
4426
|
}
|
|
4517
|
-
|
|
4427
|
+
if (i === 8 && data[i] !== "" && (data[i].startsWith("M") || data[i].startsWith("P") || !isNaN(Number(data[i])))) {
|
|
4428
|
+
continue;
|
|
4429
|
+
}
|
|
4430
|
+
remaining.push(data[i]);
|
|
4518
4431
|
}
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
// lib/plugins/Label_8E.ts
|
|
4522
|
-
var Label_8E = class extends DecoderPlugin {
|
|
4523
|
-
name = "label-8e";
|
|
4524
|
-
qualifiers() {
|
|
4525
|
-
return {
|
|
4526
|
-
labels: ["8E"]
|
|
4527
|
-
};
|
|
4432
|
+
if (remaining.length > 0 && remaining.some((r) => r !== "")) {
|
|
4433
|
+
ResultFormatter.unknown(decodeResult, remaining.join(","), "/PR");
|
|
4528
4434
|
}
|
|
4529
|
-
|
|
4530
|
-
|
|
4531
|
-
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
const
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4435
|
+
}
|
|
4436
|
+
function processDateCode(decodeResult, data) {
|
|
4437
|
+
if (data.length === 1) {
|
|
4438
|
+
} else if (data.length === 2) {
|
|
4439
|
+
const date = data[0].substring(2, 4) + data[0].substring(0, 2) + data[0].substring(4, 6);
|
|
4440
|
+
const time = DateTimeUtils.convertDateTimeToEpoch(data[1], data[0]);
|
|
4441
|
+
decodeResult.raw.message_timestamp = time;
|
|
4442
|
+
}
|
|
4443
|
+
}
|
|
4444
|
+
function processWeatherQuery(decodeResult, data) {
|
|
4445
|
+
if (data.length !== 2) {
|
|
4446
|
+
ResultFormatter.unknown(decodeResult, data.join(":"), "WQ/");
|
|
4447
|
+
return;
|
|
4448
|
+
}
|
|
4449
|
+
const alts = data[0].split(".");
|
|
4450
|
+
const route = data[1].split(".");
|
|
4451
|
+
ResultFormatter.requestedAltitudes(
|
|
4452
|
+
decodeResult,
|
|
4453
|
+
alts.map((a) => parseInt(a, 10) * 100)
|
|
4454
|
+
);
|
|
4455
|
+
const waypoints = route.map((wp) => {
|
|
4456
|
+
return { name: wp };
|
|
4457
|
+
});
|
|
4458
|
+
ResultFormatter.route(decodeResult, { waypoints });
|
|
4459
|
+
}
|
|
4460
|
+
function processRoute(decodeResult, last, time, next, eta, then, date) {
|
|
4461
|
+
const lastTime = date ? DateTimeUtils.convertDateTimeToEpoch(time, date) : DateTimeUtils.convertHHMMSSToTod(time);
|
|
4462
|
+
const nextTime = date ? DateTimeUtils.convertDateTimeToEpoch(eta, date) : DateTimeUtils.convertHHMMSSToTod(eta);
|
|
4463
|
+
const timeFormat = date ? "epoch" : "tod";
|
|
4464
|
+
const lastWaypoint = RouteUtils.getWaypoint(last);
|
|
4465
|
+
lastWaypoint.time = lastTime;
|
|
4466
|
+
lastWaypoint.timeFormat = timeFormat;
|
|
4467
|
+
const nextWaypoint = RouteUtils.getWaypoint(next);
|
|
4468
|
+
nextWaypoint.time = nextTime;
|
|
4469
|
+
nextWaypoint.timeFormat = timeFormat;
|
|
4470
|
+
const thenWaypoint = RouteUtils.getWaypoint(then || "?");
|
|
4471
|
+
const waypoints = [lastWaypoint, nextWaypoint, thenWaypoint];
|
|
4472
|
+
ResultFormatter.route(decodeResult, { waypoints });
|
|
4473
|
+
}
|
|
4474
|
+
function processWindData(decodeResult, message) {
|
|
4475
|
+
const wind = [];
|
|
4476
|
+
const flightLevel = Number(message.slice(0, 3));
|
|
4477
|
+
const fields = message.slice(4).split(".");
|
|
4478
|
+
fields.forEach((field) => {
|
|
4479
|
+
if (field.length < 4) {
|
|
4480
|
+
return;
|
|
4481
|
+
}
|
|
4482
|
+
const data = field.split(",");
|
|
4483
|
+
const waypoint = { name: data[0] };
|
|
4484
|
+
const windData = data[1];
|
|
4485
|
+
const windDirection = parseInt(windData.slice(0, 3), 10);
|
|
4486
|
+
const windSpeed = parseInt(windData.slice(3), 10);
|
|
4487
|
+
if (data.length === 3) {
|
|
4488
|
+
const tempData = data[2];
|
|
4489
|
+
const tempFlightLevel = Number(tempData.slice(0, 3));
|
|
4490
|
+
const tempString = tempData.slice(3);
|
|
4491
|
+
const tempDegrees = Number(tempString.substring(1)) * (tempString.charAt(0) === "M" ? -1 : 1);
|
|
4492
|
+
wind.push({
|
|
4493
|
+
waypoint,
|
|
4494
|
+
flightLevel,
|
|
4495
|
+
windDirection,
|
|
4496
|
+
windSpeed,
|
|
4497
|
+
temperature: {
|
|
4498
|
+
flightLevel: tempFlightLevel,
|
|
4499
|
+
degreesC: tempDegrees
|
|
4500
|
+
}
|
|
4501
|
+
});
|
|
4502
|
+
} else {
|
|
4503
|
+
wind.push({
|
|
4504
|
+
waypoint,
|
|
4505
|
+
flightLevel,
|
|
4506
|
+
windDirection,
|
|
4507
|
+
windSpeed
|
|
4508
|
+
});
|
|
4509
|
+
}
|
|
4510
|
+
});
|
|
4511
|
+
ResultFormatter.windData(decodeResult, wind);
|
|
4512
|
+
}
|
|
4513
|
+
function processRunway(decodeResult, data) {
|
|
4514
|
+
const parts = data[0].split(".");
|
|
4515
|
+
const more = parts[0].split(",");
|
|
4516
|
+
ResultFormatter.departureRunway(decodeResult, more[0]);
|
|
4517
|
+
ResultFormatter.unknownArr(decodeResult, more.slice(1), ",");
|
|
4518
|
+
ResultFormatter.unknownArr(decodeResult, parts.slice(1), ".");
|
|
4519
|
+
ResultFormatter.departureAirport(decodeResult, data[1].split(",")[0]);
|
|
4520
|
+
ResultFormatter.unknownArr(decodeResult, data[1].split(",").slice(1), ",");
|
|
4521
|
+
}
|
|
4522
|
+
function crc16IbmSdlcRev(data) {
|
|
4523
|
+
let crc = 65535;
|
|
4524
|
+
const bytes = Buffer.from(data, "ascii");
|
|
4525
|
+
for (const byte of bytes) {
|
|
4526
|
+
crc ^= byte;
|
|
4527
|
+
for (let i = 0; i < 8; i++) {
|
|
4528
|
+
if ((crc & 1) !== 0) {
|
|
4529
|
+
crc = crc >>> 1 ^ 33800;
|
|
4530
|
+
} else {
|
|
4531
|
+
crc = crc >>> 1;
|
|
4540
4532
|
}
|
|
4541
|
-
ResultFormatter.eta(
|
|
4542
|
-
decodeResult,
|
|
4543
|
-
DateTimeUtils.convertHHMMSSToTod(results.groups.arrival_eta)
|
|
4544
|
-
);
|
|
4545
|
-
ResultFormatter.arrivalAirport(decodeResult, results.groups.arrival_icao);
|
|
4546
4533
|
}
|
|
4547
|
-
decodeResult.decoded = true;
|
|
4548
|
-
decodeResult.decoder.decodeLevel = "full";
|
|
4549
|
-
return decodeResult;
|
|
4550
|
-
}
|
|
4551
|
-
};
|
|
4552
|
-
|
|
4553
|
-
// lib/plugins/Label_B6.ts
|
|
4554
|
-
var Label_B6_Forwardslash = class extends DecoderPlugin {
|
|
4555
|
-
name = "label-b6-forwardslash";
|
|
4556
|
-
qualifiers() {
|
|
4557
|
-
return {
|
|
4558
|
-
labels: ["B6"],
|
|
4559
|
-
preambles: ["/"]
|
|
4560
|
-
};
|
|
4561
4534
|
}
|
|
4562
|
-
|
|
4563
|
-
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4535
|
+
crc = (crc ^ 65535) & 65535;
|
|
4536
|
+
const nibble1 = crc >> 12 & 15;
|
|
4537
|
+
const nibble2 = crc >> 8 & 15;
|
|
4538
|
+
const nibble3 = crc >> 4 & 15;
|
|
4539
|
+
const nibble4 = crc & 15;
|
|
4540
|
+
return nibble4 << 12 | nibble3 << 8 | nibble2 << 4 | nibble1;
|
|
4541
|
+
}
|
|
4542
|
+
function crc16Genibus(data) {
|
|
4543
|
+
let crc = 65535;
|
|
4544
|
+
const polynomial = 4129;
|
|
4545
|
+
const bytes = Buffer.from(data, "ascii");
|
|
4546
|
+
for (const byte of bytes) {
|
|
4547
|
+
crc ^= byte << 8;
|
|
4548
|
+
for (let i = 0; i < 8; i++) {
|
|
4549
|
+
if ((crc & 32768) !== 0) {
|
|
4550
|
+
crc = (crc << 1 ^ polynomial) & 65535;
|
|
4551
|
+
} else {
|
|
4552
|
+
crc = crc << 1 & 65535;
|
|
4553
|
+
}
|
|
4569
4554
|
}
|
|
4570
|
-
return decodeResult;
|
|
4571
4555
|
}
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
return {
|
|
4579
|
-
labels: [":;"]
|
|
4580
|
-
};
|
|
4556
|
+
return (crc ^ 65535) & 65535;
|
|
4557
|
+
}
|
|
4558
|
+
function processMessageReference(decodeResult, data) {
|
|
4559
|
+
if (data.length !== 2) {
|
|
4560
|
+
ResultFormatter.unknown(decodeResult, data.join(","), "/MR");
|
|
4561
|
+
return;
|
|
4581
4562
|
}
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
decodeResult
|
|
4585
|
-
decodeResult.raw.frequency = Number(message.text) / 1e3;
|
|
4586
|
-
decodeResult.formatted.description = "Aircraft Transceiver Frequency Change";
|
|
4587
|
-
decodeResult.formatted.items.push({
|
|
4588
|
-
type: "frequency",
|
|
4589
|
-
label: "Frequency",
|
|
4590
|
-
value: `${decodeResult.raw.frequency} MHz`,
|
|
4591
|
-
code: "FREQ"
|
|
4592
|
-
});
|
|
4593
|
-
decodeResult.decoded = true;
|
|
4594
|
-
decodeResult.decoder.decodeLevel = "full";
|
|
4595
|
-
return decodeResult;
|
|
4563
|
+
ResultFormatter.sequenceNumber(decodeResult, parseInt(data[0], 10));
|
|
4564
|
+
if (data[1] !== "") {
|
|
4565
|
+
ResultFormatter.sequenceResponse(decodeResult, parseInt(data[1], 10));
|
|
4596
4566
|
}
|
|
4597
|
-
}
|
|
4567
|
+
}
|
|
4598
4568
|
|
|
4599
|
-
// lib/plugins/
|
|
4600
|
-
var
|
|
4601
|
-
name = "
|
|
4569
|
+
// lib/plugins/ARINC_702.ts
|
|
4570
|
+
var Arinc702 = class extends DecoderPlugin {
|
|
4571
|
+
name = "arinc-702";
|
|
4602
4572
|
qualifiers() {
|
|
4603
4573
|
return {
|
|
4604
|
-
labels: ["
|
|
4574
|
+
labels: ["*"]
|
|
4605
4575
|
};
|
|
4606
4576
|
}
|
|
4607
4577
|
decode(message, options = {}) {
|
|
@@ -4609,33 +4579,58 @@ var Label_H1 = class extends DecoderPlugin {
|
|
|
4609
4579
|
decodeResult.decoder.name = this.name;
|
|
4610
4580
|
decodeResult.message = message;
|
|
4611
4581
|
const msg = message.text.replace(/\n|\r/g, "");
|
|
4612
|
-
const parts = msg.split("#");
|
|
4613
4582
|
let decoded = false;
|
|
4583
|
+
decoded = Arinc702Helper.decodeH1Message(decodeResult, msg);
|
|
4584
|
+
if (decoded) {
|
|
4585
|
+
return this.processDecodeResult(decodeResult, decoded, options, message);
|
|
4586
|
+
}
|
|
4614
4587
|
if (msg.startsWith("/")) {
|
|
4615
4588
|
const headerData = msg.split(".");
|
|
4616
|
-
|
|
4589
|
+
decoded = Arinc702Helper.decodeH1Message(
|
|
4617
4590
|
decodeResult,
|
|
4618
4591
|
headerData.slice(1).join(".")
|
|
4619
4592
|
);
|
|
4620
|
-
if (
|
|
4593
|
+
if (decoded) {
|
|
4621
4594
|
decodeResult.remaining.text = headerData[0] + "." + decodeResult.remaining.text;
|
|
4622
|
-
|
|
4623
|
-
|
|
4595
|
+
return this.processDecodeResult(
|
|
4596
|
+
decodeResult,
|
|
4597
|
+
decoded,
|
|
4598
|
+
options,
|
|
4599
|
+
message
|
|
4600
|
+
);
|
|
4624
4601
|
}
|
|
4625
|
-
|
|
4626
|
-
|
|
4627
|
-
|
|
4628
|
-
|
|
4629
|
-
|
|
4630
|
-
decoded = H1Helper.decodeH1Message(
|
|
4602
|
+
}
|
|
4603
|
+
const hashParts = msg.split("#");
|
|
4604
|
+
if (hashParts.length == 2) {
|
|
4605
|
+
const offset = hashParts[0] === "- " || isNaN(parseInt(hashParts[1][1])) ? 3 : 4;
|
|
4606
|
+
decoded = Arinc702Helper.decodeH1Message(
|
|
4631
4607
|
decodeResult,
|
|
4632
|
-
msg.slice(
|
|
4608
|
+
msg.slice(hashParts[0].length + offset)
|
|
4633
4609
|
);
|
|
4634
|
-
if (decoded &&
|
|
4635
|
-
ResultFormatter.flightNumber(decodeResult,
|
|
4636
|
-
decodeResult.remaining.text =
|
|
4610
|
+
if (decoded && hashParts[0].length > 0) {
|
|
4611
|
+
ResultFormatter.flightNumber(decodeResult, hashParts[0].substring(4));
|
|
4612
|
+
decodeResult.remaining.text = hashParts[0].substring(0, 4) + "#" + hashParts[1].substring(0, offset - 1) + "/" + decodeResult.remaining.text;
|
|
4613
|
+
}
|
|
4614
|
+
if (decoded) {
|
|
4615
|
+
return this.processDecodeResult(
|
|
4616
|
+
decodeResult,
|
|
4617
|
+
decoded,
|
|
4618
|
+
options,
|
|
4619
|
+
message
|
|
4620
|
+
);
|
|
4637
4621
|
}
|
|
4638
4622
|
}
|
|
4623
|
+
const slashParts = msg.split("/");
|
|
4624
|
+
if (slashParts[0].length > 3) {
|
|
4625
|
+
decoded = Arinc702Helper.decodeH1Message(
|
|
4626
|
+
decodeResult,
|
|
4627
|
+
msg.slice(slashParts[0].length - 3)
|
|
4628
|
+
);
|
|
4629
|
+
decodeResult.remaining.text = slashParts[0].slice(0, 3) + "/" + decodeResult.remaining.text;
|
|
4630
|
+
}
|
|
4631
|
+
return this.processDecodeResult(decodeResult, decoded, options, message);
|
|
4632
|
+
}
|
|
4633
|
+
processDecodeResult(decodeResult, decoded, options, message) {
|
|
4639
4634
|
decodeResult.decoded = decoded;
|
|
4640
4635
|
decodeResult.decoder.decodeLevel = !decodeResult.remaining.text ? "full" : "partial";
|
|
4641
4636
|
if (decodeResult.formatted.items.length === 0) {
|
|
@@ -6254,6 +6249,7 @@ var MessageDecoder = class {
|
|
|
6254
6249
|
this.plugins = [];
|
|
6255
6250
|
this.debug = false;
|
|
6256
6251
|
this.registerPlugin(new CBand(this));
|
|
6252
|
+
this.registerPlugin(new Arinc702(this));
|
|
6257
6253
|
this.registerPlugin(new Label_ColonComma(this));
|
|
6258
6254
|
this.registerPlugin(new Label_5Z_Slash(this));
|
|
6259
6255
|
this.registerPlugin(new Label_10_LDR(this));
|
|
@@ -6268,7 +6264,6 @@ var MessageDecoder = class {
|
|
|
6268
6264
|
this.registerPlugin(new Label_16_N_Space(this));
|
|
6269
6265
|
this.registerPlugin(new Label_16_POSA1(this));
|
|
6270
6266
|
this.registerPlugin(new Label_16_TOD(this));
|
|
6271
|
-
this.registerPlugin(new Label_1J_2J_FTX(this));
|
|
6272
6267
|
this.registerPlugin(new Label_1L_3Line(this));
|
|
6273
6268
|
this.registerPlugin(new Label_1L_070(this));
|
|
6274
6269
|
this.registerPlugin(new Label_1L_660(this));
|
|
@@ -6281,7 +6276,6 @@ var MessageDecoder = class {
|
|
|
6281
6276
|
this.registerPlugin(new Label_2P_FM3(this));
|
|
6282
6277
|
this.registerPlugin(new Label_2P_FM4(this));
|
|
6283
6278
|
this.registerPlugin(new Label_2P_FM5(this));
|
|
6284
|
-
this.registerPlugin(new Label_2P_POS(this));
|
|
6285
6279
|
this.registerPlugin(new Label_30_Slash_EA(this));
|
|
6286
6280
|
this.registerPlugin(new Label_44_ETA(this));
|
|
6287
6281
|
this.registerPlugin(new Label_44_IN(this));
|
|
@@ -6294,7 +6288,6 @@ var MessageDecoder = class {
|
|
|
6294
6288
|
this.registerPlugin(new Label_4A_DIS(this));
|
|
6295
6289
|
this.registerPlugin(new Label_4A_DOOR(this));
|
|
6296
6290
|
this.registerPlugin(new Label_4A_Slash_01(this));
|
|
6297
|
-
this.registerPlugin(new Label_4J_POS(this));
|
|
6298
6291
|
this.registerPlugin(new Label_4N(this));
|
|
6299
6292
|
this.registerPlugin(new Label_4T_AGFSR(this));
|
|
6300
6293
|
this.registerPlugin(new Label_4T_ETA(this));
|
|
@@ -6304,7 +6297,6 @@ var MessageDecoder = class {
|
|
|
6304
6297
|
this.registerPlugin(new Label_H1_OHMA(this));
|
|
6305
6298
|
this.registerPlugin(new Label_H1_Paren(this));
|
|
6306
6299
|
this.registerPlugin(new Label_H1_WRN(this));
|
|
6307
|
-
this.registerPlugin(new Label_H1(this));
|
|
6308
6300
|
this.registerPlugin(new Label_H1_StarPOS(this));
|
|
6309
6301
|
this.registerPlugin(new Label_HX(this));
|
|
6310
6302
|
this.registerPlugin(new Label_58(this));
|