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