diff --git a/metar.html b/metar.html index 90250d4..eed026d 100644 --- a/metar.html +++ b/metar.html @@ -147,9 +147,10 @@ } // Clouds - if (part.match(/^(BKN|OVC)/)) { + if (part.match(/^(BKN|OVC|VV)/)) { score += 1; - const ceilingAlt = parseInt(part.substring(3, 6)); + const altCode = part.startsWith('VV') ? part.substring(2, 5) : part.substring(3, 6); + const ceilingAlt = parseInt(altCode); if (!isNaN(ceilingAlt)) { const ceilingFt = ceilingAlt * 100; if (ceilingFt < 500) score += 8; @@ -285,6 +286,14 @@ } function decodeClouds(code, metarString) { + if (code.startsWith('VV')) { + const height = code.substring(2, 5); + if (height === '///') { + return `${code}: Vertical visibility sensor inoperative`; + } + const alt = parseInt(height) * 100; + return `${code}: Vertical visibility ${alt.toLocaleString()} feet`; + } const coverMap = { 'SKC': 'Sky clear', 'CLR': 'Sky clear', @@ -791,7 +800,7 @@ 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)+$/)) { sections.push({ raw: part, decoded: decodeWeather(part, metarString) }); - } else if (part.match(/^(SKC|CLR|FEW|SCT|BKN|OVC)/)) { + } else if (part.match(/^(VV|SKC|CLR|FEW|SCT|BKN|OVC)/)) { sections.push({ raw: part, decoded: decodeClouds(part, metarString) }); } else if (part.match(/^(M?\d{2})\/(M?\d{2})$/)) { sections.push({ raw: part, decoded: decodeTempDew(part) });