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) });