feat: Log unknown METAR parts with full string for debugging
Co-authored-by: aider (gemini/gemini-2.5-pro) <aider@aider.chat>
This commit is contained in:
+23
-13
@@ -60,8 +60,9 @@
|
|||||||
|
|
||||||
// --- Decoding Functions ---
|
// --- Decoding Functions ---
|
||||||
|
|
||||||
function decodeAirport(code) {
|
function decodeAirport(code, metarString) {
|
||||||
if (code === 'CYYC') return "CYYC: Calgary International Airport";
|
if (code === 'CYYC') return "CYYC: Calgary International Airport";
|
||||||
|
console.log(`Unknown Airport code: ${code} in METAR: ${metarString}`);
|
||||||
return `${code}: Unknown Airport`;
|
return `${code}: Unknown Airport`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,7 +90,7 @@
|
|||||||
return `${code}: Visibility ${vis} statute miles`;
|
return `${code}: Visibility ${vis} statute miles`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function decodeWeather(code) {
|
function decodeWeather(code, metarString) {
|
||||||
const originalCode = code;
|
const originalCode = code;
|
||||||
const intensityMap = {
|
const intensityMap = {
|
||||||
'-': 'Light ',
|
'-': 'Light ',
|
||||||
@@ -133,6 +134,7 @@
|
|||||||
} else if (weatherMap[chunk]) {
|
} else if (weatherMap[chunk]) {
|
||||||
decodedChunks.push(weatherMap[chunk]);
|
decodedChunks.push(weatherMap[chunk]);
|
||||||
} else {
|
} else {
|
||||||
|
console.log(`Unknown weather chunk: ${chunk} in code: ${code} in METAR: ${metarString}`);
|
||||||
decodedChunks.push(`unknown (${chunk})`);
|
decodedChunks.push(`unknown (${chunk})`);
|
||||||
}
|
}
|
||||||
if (precipitationTypes.includes(chunk)) {
|
if (precipitationTypes.includes(chunk)) {
|
||||||
@@ -149,7 +151,7 @@
|
|||||||
return `${originalCode}: ${decoding.trim()}${vicinity}`;
|
return `${originalCode}: ${decoding.trim()}${vicinity}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function decodeClouds(code) {
|
function decodeClouds(code, metarString) {
|
||||||
const coverMap = {
|
const coverMap = {
|
||||||
'SKC': 'Sky clear',
|
'SKC': 'Sky clear',
|
||||||
'CLR': 'Sky clear',
|
'CLR': 'Sky clear',
|
||||||
@@ -160,7 +162,10 @@
|
|||||||
};
|
};
|
||||||
const coverType = code.substring(0, 3);
|
const coverType = code.substring(0, 3);
|
||||||
const cover = coverMap[coverType];
|
const cover = coverMap[coverType];
|
||||||
if (!cover) return `${code}: Unknown cloud information`;
|
if (!cover) {
|
||||||
|
console.log(`Unknown cloud information: ${code} in METAR: ${metarString}`);
|
||||||
|
return `${code}: Unknown cloud information`;
|
||||||
|
}
|
||||||
|
|
||||||
if (coverType === 'SKC' || coverType === 'CLR') {
|
if (coverType === 'SKC' || coverType === 'CLR') {
|
||||||
return `${code}: ${cover}`;
|
return `${code}: ${cover}`;
|
||||||
@@ -188,7 +193,7 @@
|
|||||||
return `SLP${pressure}: Sea-level pressure ${hpa.toFixed(1)} hPa`;
|
return `SLP${pressure}: Sea-level pressure ${hpa.toFixed(1)} hPa`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function decodeCloudTypesRemark(code) {
|
function decodeCloudTypesRemark(code, metarString) {
|
||||||
const cloudTypes = {
|
const cloudTypes = {
|
||||||
'CI': 'Cirrus',
|
'CI': 'Cirrus',
|
||||||
'CC': 'Cirrocumulus',
|
'CC': 'Cirrocumulus',
|
||||||
@@ -208,7 +213,11 @@
|
|||||||
for (const match of matches) {
|
for (const match of matches) {
|
||||||
const cloudCode = match[1];
|
const cloudCode = match[1];
|
||||||
const oktas = match[2];
|
const oktas = match[2];
|
||||||
const cloudName = cloudTypes[cloudCode] || `Unknown cloud type (${cloudCode})`;
|
let cloudName = cloudTypes[cloudCode];
|
||||||
|
if (!cloudName) {
|
||||||
|
cloudName = `Unknown cloud type (${cloudCode})`;
|
||||||
|
console.log(`Unknown cloud type in remark: ${cloudCode} in METAR: ${metarString}`);
|
||||||
|
}
|
||||||
decodedParts.push(`${oktas}/8 ${cloudName}`);
|
decodedParts.push(`${oktas}/8 ${cloudName}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,7 +239,7 @@
|
|||||||
return `${code}: ${weatherName} obscuring ${oktas}/8 of the sky`;
|
return `${code}: ${weatherName} obscuring ${oktas}/8 of the sky`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function decodeRemarks(parts) {
|
function decodeRemarks(parts, metarString) {
|
||||||
let decoded = ["RMK: Remarks"];
|
let decoded = ["RMK: Remarks"];
|
||||||
const weatherRegex = /^([+-]|VC)?(MI|PR|BC|DR|BL|SH|TS|FZ|DZ|RA|SN|SG|IC|PL|GR|GS|UP|BR|FG|FU|VA|DU|SA|HZ|PY|PO|SQ|FC|SS|DS|TR)+$/;
|
const weatherRegex = /^([+-]|VC)?(MI|PR|BC|DR|BL|SH|TS|FZ|DZ|RA|SN|SG|IC|PL|GR|GS|UP|BR|FG|FU|VA|DU|SA|HZ|PY|PO|SQ|FC|SS|DS|TR)+$/;
|
||||||
const obscurationRegex = /^(FG|BR|FU|HZ|DU|SA)\d$/;
|
const obscurationRegex = /^(FG|BR|FU|HZ|DU|SA)\d$/;
|
||||||
@@ -263,7 +272,7 @@
|
|||||||
} else if (obscurationRegex.test(part)) {
|
} else if (obscurationRegex.test(part)) {
|
||||||
decoded.push(` - ${decodeObscurationRemark(part)}`);
|
decoded.push(` - ${decodeObscurationRemark(part)}`);
|
||||||
} else if (part.match(/^([A-Z]{2}\d)+$/)) {
|
} else if (part.match(/^([A-Z]{2}\d)+$/)) {
|
||||||
decoded.push(` - ${decodeCloudTypesRemark(part)}`);
|
decoded.push(` - ${decodeCloudTypesRemark(part, metarString)}`);
|
||||||
} else if (part === 'VIRGA' && i + 1 < parts.length && directions[parts[i+1]]) {
|
} else if (part === 'VIRGA' && i + 1 < parts.length && directions[parts[i+1]]) {
|
||||||
const direction = directions[parts[i+1]];
|
const direction = directions[parts[i+1]];
|
||||||
decoded.push(` - VIRGA ${parts[i+1]}: Virga to the ${direction.toLowerCase()}`);
|
decoded.push(` - VIRGA ${parts[i+1]}: Virga to the ${direction.toLowerCase()}`);
|
||||||
@@ -279,10 +288,11 @@
|
|||||||
decoded.push(` - ${part} ${parts[i+1]}: ${cloudName} clouds are translucent (thin)`);
|
decoded.push(` - ${part} ${parts[i+1]}: ${cloudName} clouds are translucent (thin)`);
|
||||||
i++; // Consume 'TR' part
|
i++; // Consume 'TR' part
|
||||||
} else if (weatherRegex.test(part)) {
|
} else if (weatherRegex.test(part)) {
|
||||||
decoded.push(` - ${decodeWeather(part)}`);
|
decoded.push(` - ${decodeWeather(part, metarString)}`);
|
||||||
} else if (part.match(/^(AC|CI|CC)/)) {
|
} else if (part.match(/^(AC|CI|CC)/)) {
|
||||||
decoded.push(` - ${part}: Cloud types and coverage details`);
|
decoded.push(` - ${part}: Cloud types and coverage details`);
|
||||||
} else {
|
} else {
|
||||||
|
console.log(`Other remark: ${part} in METAR: ${metarString}`);
|
||||||
decoded.push(` - ${part}: Other remark`);
|
decoded.push(` - ${part}: Other remark`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -300,7 +310,7 @@
|
|||||||
|
|
||||||
if (parts[index] && parts[index].length === 4 && parts[index].match(/^[A-Z][A-Z0-9]{3}$/)) {
|
if (parts[index] && parts[index].length === 4 && parts[index].match(/^[A-Z][A-Z0-9]{3}$/)) {
|
||||||
airportTimeAutoRaw.push(parts[index]);
|
airportTimeAutoRaw.push(parts[index]);
|
||||||
airportTimeAutoDecoded.push(decodeAirport(parts[index]));
|
airportTimeAutoDecoded.push(decodeAirport(parts[index], metarString));
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
if (parts[index] && parts[index].endsWith('Z')) {
|
if (parts[index] && parts[index].endsWith('Z')) {
|
||||||
@@ -331,9 +341,9 @@
|
|||||||
} else if (part.endsWith('SM') || part.match(/^\d+$/) || part.match(/^\d\/\dSM$/)) {
|
} else if (part.endsWith('SM') || part.match(/^\d+$/) || part.match(/^\d\/\dSM$/)) {
|
||||||
sections.push({ raw: part, decoded: decodeVisibility(part) });
|
sections.push({ raw: part, decoded: decodeVisibility(part) });
|
||||||
} else if (part.match(/^([+-]|VC)?(MI|PR|BC|DR|BL|SH|TS|FZ|DZ|RA|SN|SG|IC|PL|GR|GS|UP|BR|FG|FU|VA|DU|SA|HZ|PY|PO|SQ|FC|SS|DS|TR)+$/)) {
|
} else if (part.match(/^([+-]|VC)?(MI|PR|BC|DR|BL|SH|TS|FZ|DZ|RA|SN|SG|IC|PL|GR|GS|UP|BR|FG|FU|VA|DU|SA|HZ|PY|PO|SQ|FC|SS|DS|TR)+$/)) {
|
||||||
sections.push({ raw: part, decoded: decodeWeather(part) });
|
sections.push({ raw: part, decoded: decodeWeather(part, metarString) });
|
||||||
} else if (part.match(/^(SKC|CLR|FEW|SCT|BKN|OVC)/)) {
|
} else if (part.match(/^(SKC|CLR|FEW|SCT|BKN|OVC)/)) {
|
||||||
sections.push({ raw: part, decoded: decodeClouds(part) });
|
sections.push({ raw: part, decoded: decodeClouds(part, metarString) });
|
||||||
} else if (part.match(/^(M?\d{2})\/(M?\d{2})$/)) {
|
} else if (part.match(/^(M?\d{2})\/(M?\d{2})$/)) {
|
||||||
sections.push({ raw: part, decoded: decodeTempDew(part) });
|
sections.push({ raw: part, decoded: decodeTempDew(part) });
|
||||||
} else if (part.startsWith('A') && part.length === 5 && !isNaN(part.substring(1))) {
|
} else if (part.startsWith('A') && part.length === 5 && !isNaN(part.substring(1))) {
|
||||||
@@ -346,7 +356,7 @@
|
|||||||
const remarkParts = parts.slice(rmkIndex + 1);
|
const remarkParts = parts.slice(rmkIndex + 1);
|
||||||
sections.push({
|
sections.push({
|
||||||
raw: `RMK ${remarkParts.join(' ')}`,
|
raw: `RMK ${remarkParts.join(' ')}`,
|
||||||
decoded: decodeRemarks(remarkParts)
|
decoded: decodeRemarks(remarkParts, metarString)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user