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