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