diff --git a/extension/sidepanel.js b/extension/sidepanel.js index 997721fc..2b04e5ec 100644 --- a/extension/sidepanel.js +++ b/extension/sidepanel.js @@ -20,6 +20,7 @@ const I18N = { settlementAirport: "结算机场", hko: "香港天文台 (HKO)", cwa: "交通部中央气象署 (CWA)", + noaa: "NOAA RCTP(台湾桃园国际机场)", city: "城市", refresh: "刷新数据", cityProfile: "城市档案", @@ -35,6 +36,9 @@ const I18N = { nearbyMonitoringSuffix: "个参与监控", today: "今天", omSeries: "OM预测", + noaaSettlementRef: "NOAA RCTP 结算参考", + noaaSettlementLegend: + "台北按 NOAA RCTP 最终完成质控后的最高整度摄氏值结算;图中曲线仅作结算参考。", loadCityDetailFailed: "加载城市详情失败", refreshFailed: "刷新温度数据失败", initFailed: "初始化失败", @@ -55,6 +59,7 @@ const I18N = { settlementAirport: "Settlement Airport", hko: "Hong Kong Observatory (HKO)", cwa: "Central Weather Administration (CWA)", + noaa: "NOAA RCTP (Taiwan Taoyuan International Airport)", city: "City", refresh: "Refresh data", cityProfile: "City Profile", @@ -70,6 +75,9 @@ const I18N = { nearbyMonitoringSuffix: " stations monitored", today: "Today", omSeries: "OM Forecast", + noaaSettlementRef: "NOAA RCTP Settlement Reference", + noaaSettlementLegend: + "Taipei settles on NOAA RCTP using the finalized highest rounded whole-degree Celsius reading; the plotted line is only a settlement reference.", loadCityDetailFailed: "Failed to load city detail", refreshFailed: "Failed to refresh weather data", initFailed: "Initialization failed", @@ -394,6 +402,12 @@ function getSettlementSourceDisplay(detail) { value: t("cwa") }; } + if (source === "noaa") { + return { + label: t("settlementSource"), + value: t("noaa") + }; + } const airport = detail?.risk?.airport || "--"; const icao = detail?.risk?.icao ? ` (${detail.risk.icao})` : ""; return { @@ -629,7 +643,10 @@ function drawTrendChart(detail) { const points = [...trend, ...obs]; const hoverPoints = []; const tempSymbol = detail?.temp_symbol || "°C"; - const obsSeriesLabel = String(detail?.current?.settlement_source_label || "OBS").toUpperCase(); + const sourceCode = String(detail?.current?.settlement_source || "").toLowerCase(); + const obsSeriesLabel = sourceCode === "noaa" + ? t("noaaSettlementRef") + : String(detail?.current?.settlement_source_label || "OBS").toUpperCase(); if (!points.length) { setChartHover([], tempSymbol); ctx.fillStyle = "#8ba0be"; @@ -788,14 +805,23 @@ function renderDetail(detail) { drawTrendChart(detail); renderForecast(detail); - const sourceTag = String(detail?.current?.settlement_source_label || "").toUpperCase() || "OBS"; + const sourceCode = String(detail?.current?.settlement_source || "").toLowerCase(); + const sourceTag = sourceCode === "noaa" + ? t("noaaSettlementRef") + : String(detail?.current?.settlement_source_label || "").toUpperCase() || "OBS"; const obs = getObservationRows(detail); if (obs.length >= 2) { const first = obs[0]; const last = obs[obs.length - 1]; - els.chartLegend.textContent = `${sourceTag}: ${first.temp}°C@${first.time} -> ${last.temp}°C@${last.time}`; + els.chartLegend.textContent = + sourceCode === "noaa" + ? `${sourceTag}: ${first.temp}°C@${first.time} -> ${last.temp}°C@${last.time} | ${t("noaaSettlementLegend")}` + : `${sourceTag}: ${first.temp}°C@${first.time} -> ${last.temp}°C@${last.time}`; } else { - els.chartLegend.textContent = `${sourceTag}: ${t("noContinuousObs")}`; + els.chartLegend.textContent = + sourceCode === "noaa" + ? `${sourceTag}: ${t("noContinuousObs")} | ${t("noaaSettlementLegend")}` + : `${sourceTag}: ${t("noContinuousObs")}`; } } diff --git a/frontend/components/dashboard/FutureForecastModal.tsx b/frontend/components/dashboard/FutureForecastModal.tsx index 20c32995..8a69fd53 100644 --- a/frontend/components/dashboard/FutureForecastModal.tsx +++ b/frontend/components/dashboard/FutureForecastModal.tsx @@ -452,6 +452,10 @@ export function FutureForecastModal() { "--score-position": scorePosition, } as CSSProperties & { "--score-position": string }; const weatherSummary = getWeatherSummary(detail, locale); + const isTaipeiNoaa = + store.selectedCity === "taipei" && + (detail.current?.settlement_source === "noaa" || + detail.current?.settlement_source_label === "NOAA"); const marketMidpoint = formatMarketPercent( marketScan?.market_price ?? marketScan?.yes_token?.implied_probability, ); @@ -551,11 +555,15 @@ export function FutureForecastModal() { ? locale === "en-US" ? "Hong Kong Observatory (HKO)" : "香港天文台 (HKO)" - : settlementSourceCode === "cwa" + : settlementSourceCode === "noaa" ? locale === "en-US" - ? "Central Weather Administration (CWA)" - : "交通部中央气象署 (CWA)" - : risk.airport + ? "NOAA RCTP (Taiwan Taoyuan International Airport)" + : "NOAA RCTP(台湾桃园国际机场)" + : settlementSourceCode === "cwa" + ? locale === "en-US" + ? "Central Weather Administration (CWA)" + : "交通部中央气象署 (CWA)" + : risk.airport ? `${risk.airport}${risk.icao ? ` (${risk.icao})` : ""}` : "--"; @@ -652,6 +660,24 @@ export function FutureForecastModal() {
+ {isTaipeiNoaa && ( +
+ {locale === "en-US" + ? "Taipei now settles against NOAA RCTP (Taiwan Taoyuan International Airport). The market uses the highest rounded whole-degree Celsius reading in the Temp column after the day is finalized." + : "台北当前按 NOAA RCTP(台湾桃园国际机场)结算。市场最终采用该日 Temp 列完成质控后的最高整度摄氏值,不按小数温度结算。"} +
+ )} {isToday ? (
+ {isTaipei && ( +
+ {t("lang") === "en-US" + ? "Taipei historical actuals are aligned to NOAA RCTP settlement rules: use the highest rounded whole-degree Celsius reading after the date is finalized." + : "台北历史对账已按 NOAA RCTP 结算口径对齐:采用该日最终完成质控后的最高整度摄氏值。"} +
+ )}
{isLoading ? ( diff --git a/frontend/lib/dashboard-official-sources.ts b/frontend/lib/dashboard-official-sources.ts index ae958d6d..d1d49f3b 100644 --- a/frontend/lib/dashboard-official-sources.ts +++ b/frontend/lib/dashboard-official-sources.ts @@ -60,8 +60,8 @@ const CITY_SPECIFIC_SOURCES: Record = { ], taipei: [ { - label: "CWA 中央气象署", - href: "https://www.cwa.gov.tw/V8/E/", + label: "NOAA RCTP Timeseries", + href: "https://www.weather.gov/wrh/timeseries?site=RCTP", kind: "agency", }, { @@ -70,8 +70,8 @@ const CITY_SPECIFIC_SOURCES: Record = { kind: "airport", }, { - label: "RCSS METAR", - href: "https://aviationweather.gov/data/metar/?id=RCSS&decoded=1&taf=1", + label: "RCTP METAR", + href: "https://aviationweather.gov/data/metar/?id=RCTP&decoded=1&taf=1", kind: "metar", }, ], diff --git a/frontend/lib/dashboard-utils.ts b/frontend/lib/dashboard-utils.ts index cb73632d..108d0596 100644 --- a/frontend/lib/dashboard-utils.ts +++ b/frontend/lib/dashboard-utils.ts @@ -40,7 +40,7 @@ function getObservationSourceCode(detail: CityDetail): string { .trim() .toLowerCase(); if (city === "hong kong") return "hko"; - if (city === "taipei") return "cwa"; + if (city === "taipei") return "noaa"; return "metar"; } @@ -52,6 +52,7 @@ function getObservationSourceTag(detail: CityDetail): string { const code = getObservationSourceCode(detail); if (code === "hko") return "HKO"; if (code === "cwa") return "CWA"; + if (code === "noaa") return "NOAA"; if (code === "mgm") return "MGM"; return "METAR"; } @@ -239,7 +240,7 @@ export function getTemperatureChartData( const observationTag = getObservationSourceTag(detail); const observationCode = getObservationSourceCode(detail); const settlementSource = - observationCode === "hko" || observationCode === "cwa"; + observationCode === "hko" || observationCode === "cwa" || observationCode === "noaa"; const officialObservationSource = settlementSource ? detail.settlement_today_obs?.length @@ -267,7 +268,11 @@ export function getTemperatureChartData( return `${icao} METAR`; })(); const observationDisplayTag = - settlementSource && shouldUseMetarFallback ? metarFallbackTag : observationTag; + settlementSource && shouldUseMetarFallback + ? metarFallbackTag + : observationCode === "noaa" + ? "NOAA RCTP" + : observationTag; const metarPoints = new Array(times.length).fill(null); observationSource.forEach((item) => { @@ -361,6 +366,12 @@ export function getTemperatureChartData( ? `Official ${observationTag} feed is sparse today, so the continuous observation line switches to ${metarFallbackTag}.` : `今日官方 ${observationTag} 点位较稀疏,连续实测线改用 ${metarFallbackTag}。`, ); + } else if (observationCode === "noaa") { + legendParts.push( + isEnglish(locale) + ? "Taipei settles on NOAA RCTP using the finalized highest rounded whole-degree Celsius reading; the plotted line is a settlement reference." + : "台北按 NOAA RCTP 最终完成质控后的最高整度摄氏值结算;图中曲线仅作为结算参考线。", + ); } return { @@ -374,9 +385,14 @@ export function getTemperatureChartData( offset, temps, }, - observationLabel: isEnglish(locale) - ? `${observationDisplayTag} Observation` - : `${observationDisplayTag} 实况`, + observationLabel: + observationCode === "noaa" && !shouldUseMetarFallback + ? isEnglish(locale) + ? `${observationDisplayTag} Settlement Reference` + : `${observationDisplayTag} 结算参考` + : isEnglish(locale) + ? `${observationDisplayTag} Observation` + : `${observationDisplayTag} 实况`, legendText: legendParts.join(" | "), max, min, @@ -1416,7 +1432,7 @@ export function getCityProfileStats(detail: CityDetail, locale: Locale = "zh-CN" const current = detail.current || {}; const nearbyCount = Array.isArray(detail.mgm_nearby) ? detail.mgm_nearby.length : 0; const sourceCode = getObservationSourceCode(detail); - const isOfficialSource = sourceCode === "hko" || sourceCode === "cwa"; + const isOfficialSource = sourceCode === "hko" || sourceCode === "cwa" || sourceCode === "noaa"; const sourceDisplay = (() => { if (sourceCode === "hko") { @@ -1429,6 +1445,11 @@ export function getCityProfileStats(detail: CityDetail, locale: Locale = "zh-CN" ? "Central Weather Administration (CWA)" : "交通部中央气象署 (CWA)"; } + if (sourceCode === "noaa") { + return isEnglish(locale) + ? "NOAA RCTP (Taiwan Taoyuan)" + : "NOAA RCTP(台湾桃园国际机场)"; + } const tag = getObservationSourceTag(detail); if (sourceCode === "mgm") { return isEnglish(locale) ? `MGM (${tag})` : `MGM (${tag})`; @@ -1491,7 +1512,7 @@ export function getSettlementRiskNarrative( ) { const risk = detail.risk || {}; const sourceCode = getObservationSourceCode(detail); - const stationTerm = sourceCode === "hko" || sourceCode === "cwa" + const stationTerm = sourceCode === "hko" || sourceCode === "cwa" || sourceCode === "noaa" ? isEnglish(locale) ? "settlement reference station" : "结算参考站" diff --git a/frontend/lib/i18n.ts b/frontend/lib/i18n.ts index f6b20eff..9e26e932 100644 --- a/frontend/lib/i18n.ts +++ b/frontend/lib/i18n.ts @@ -52,7 +52,7 @@ const MESSAGES: Record> = { "guide.title": "📎 PolyWeather 系统技术说明", "guide.closeAria": "关闭技术说明", "guide.footer": - "数据源以 METAR、香港天文台(HKO)、中央气象署(CWA)、Turkish MGM、Open-Meteo、weather.gov 为主。", + "数据源以 METAR、香港天文台(HKO)、NOAA RCTP、Turkish MGM、Open-Meteo、weather.gov 为主。", "history.title": "📊 历史准确率对账 - {city}", "history.closeAria": "关闭历史对账", @@ -214,7 +214,7 @@ const MESSAGES: Record> = { "guide.title": "📎 PolyWeather Technical Overview", "guide.closeAria": "Close technical overview", "guide.footer": - "Primary data sources are METAR, Hong Kong Observatory (HKO), CWA (Taiwan), Turkish MGM, Open-Meteo, and weather.gov.", + "Primary data sources are METAR, Hong Kong Observatory (HKO), NOAA RCTP, Turkish MGM, Open-Meteo, and weather.gov.", "history.title": "📊 Historical Reconciliation - {city}", "history.closeAria": "Close history reconciliation", diff --git a/src/analysis/city_query_service.py b/src/analysis/city_query_service.py index 989ceba3..fe4ae36e 100644 --- a/src/analysis/city_query_service.py +++ b/src/analysis/city_query_service.py @@ -37,6 +37,7 @@ def _resolve_settlement_source(city_meta: Dict[str, Any]) -> Tuple[str, str]: "metar": "METAR", "hko": "HKO", "cwa": "CWA", + "noaa": "NOAA", "mgm": "MGM", } return source, source_label_map.get(source, source.upper()) @@ -333,7 +334,7 @@ def build_city_query_report( sc_current = {} city_meta = CITY_REGISTRY.get(city_name.lower(), {}) settlement_source, settlement_source_label = _resolve_settlement_source(city_meta) - use_settlement_current = settlement_source in {"hko", "cwa"} and bool(sc_current) + use_settlement_current = settlement_source in {"hko", "cwa", "noaa"} and bool(sc_current) fallback_utc_offset = int(city_meta.get("tz_offset", 0)) nws_periods = ((weather_data.get("nws") or {}).get("forecast_periods") or []) if nws_periods: diff --git a/src/analysis/settlement_rounding.py b/src/analysis/settlement_rounding.py index 745819d9..bed93047 100644 --- a/src/analysis/settlement_rounding.py +++ b/src/analysis/settlement_rounding.py @@ -24,7 +24,7 @@ def is_exact_settlement_city(city: str) -> bool: if not city: return False c = str(city).lower().strip() - return c in ["hong kong", "hk", "taipei", "tpe", "臺北", "台北", "香港"] + return c in ["hong kong", "hk", "香港"] def apply_city_settlement(city: str, value: Optional[Number]) -> Optional[int]: @@ -38,4 +38,3 @@ def apply_city_settlement(city: str, value: Optional[Number]) -> Optional[int]: if is_exact_settlement_city(city): return int(math.floor(float(value))) return wu_round(value) - diff --git a/src/analysis/trend_engine.py b/src/analysis/trend_engine.py index 41ea50f6..f7a5b19f 100644 --- a/src/analysis/trend_engine.py +++ b/src/analysis/trend_engine.py @@ -28,6 +28,7 @@ SETTLEMENT_SOURCE_LABELS = { "metar": "METAR", "hko": "HKO", "cwa": "CWA", + "noaa": "NOAA", "mgm": "MGM", } diff --git a/src/data_collection/city_registry.py b/src/data_collection/city_registry.py index 483e0c56..afe083b2 100644 --- a/src/data_collection/city_registry.py +++ b/src/data_collection/city_registry.py @@ -75,18 +75,18 @@ CITY_REGISTRY = { }, "taipei": { "name": "Taipei", - "lat": 25.0377, - "lon": 121.5149, - "icao": "RCSS", - "settlement_source": "cwa", + "lat": 25.0777, + "lon": 121.2330, + "icao": "RCTP", + "settlement_source": "noaa", "tz_offset": 28800, "use_fahrenheit": False, "is_major": True, "risk_level": "low", "risk_emoji": "🟢", - "airport_name": "中央气象署台北站", - "distance_km": 1.5, - "warning": "盆地地形叠加都市热岛,夏季午后对流前后温度波动较快。", + "airport_name": "台湾桃园国际机场", + "distance_km": 28.1, + "warning": "市场现按 NOAA RCTP 整度°C口径结算,机场与台北市区温度不可混用。", }, "shanghai": { "name": "Shanghai", diff --git a/src/data_collection/settlement_sources.py b/src/data_collection/settlement_sources.py index 63a6974f..fa101112 100644 --- a/src/data_collection/settlement_sources.py +++ b/src/data_collection/settlement_sources.py @@ -1,6 +1,7 @@ from __future__ import annotations import csv +import math import time from datetime import datetime, timedelta, timezone from typing import Any, Dict, List, Optional @@ -11,6 +12,8 @@ from loguru import logger class SettlementSourceMixin: IMGW_METEO_API_BASE = "https://meteo.imgw.pl/api/v1" IMGW_METEO_API_TOKEN = "p4DXKjsYadfBV21TYrDk" + NOAA_WRH_MESO_TOKEN = "7c76618b66c74aee913bdbae4b448bdd" + NOAA_WRH_TIMESERIES_REFERER = "https://www.weather.gov/wrh/timeseries?site=RCTP" def _get_settlement_cache(self, key: str) -> Optional[Dict[str, Any]]: now_ts = time.time() @@ -81,6 +84,13 @@ class SettlementSourceMixin: except Exception: return None + @staticmethod + def _js_round(value: Any) -> Optional[int]: + parsed = SettlementSourceMixin._safe_float(value) + if parsed is None: + return None + return int(math.floor(float(parsed) + 0.5)) + @staticmethod def _pick_station_row( rows: List[Dict[str, str]], candidates: List[str] @@ -263,6 +273,109 @@ class SettlementSourceMixin: logger.warning(f"CWA Forecast request failed: {exc}") return None + def fetch_noaa_rctp_settlement_current(self) -> Optional[Dict[str, Any]]: + cache_key = "noaa:rctp" + cached = self._get_settlement_cache(cache_key) + if cached: + return cached + + try: + response = self.session.get( + "https://api.synopticdata.com/v2/stations/timeseries", + params={ + "STID": "RCTP", + "showemptystations": 1, + "recent": 2880, + "complete": 1, + "token": self.NOAA_WRH_MESO_TOKEN, + "obtimezone": "local", + }, + headers={ + "Referer": self.NOAA_WRH_TIMESERIES_REFERER, + "Origin": "https://www.weather.gov", + "User-Agent": "Mozilla/5.0", + }, + timeout=self.timeout, + ) + response.raise_for_status() + payload = response.json() if response.content else {} + stations = payload.get("STATION") or [] + station = stations[0] if isinstance(stations, list) and stations else None + if not isinstance(station, dict): + return None + + obs = station.get("OBSERVATIONS") or {} + stamps = obs.get("date_time") or [] + temps = obs.get("air_temp_set_1") or [] + humidity_list = obs.get("relative_humidity_set_1") or [] + wind_speed_list = obs.get("wind_speed_set_1") or [] + wind_dir_list = obs.get("wind_direction_set_1") or [] + if not isinstance(stamps, list) or not isinstance(temps, list) or not stamps or not temps: + return None + + target_date = datetime.now(timezone(timedelta(hours=8))).date() + today_rows: List[tuple[datetime, int]] = [] + latest_dt: Optional[datetime] = None + latest_temp: Optional[int] = None + latest_humidity: Optional[float] = None + latest_wind_speed_ms: Optional[float] = None + latest_wind_dir: Optional[float] = None + + for idx, stamp in enumerate(stamps): + raw_temp = temps[idx] if idx < len(temps) else None + rounded_temp = self._js_round(raw_temp) + if rounded_temp is None: + continue + try: + dt = datetime.strptime(str(stamp), "%Y-%m-%dT%H:%M:%S%z") + except Exception: + continue + if dt.date() == target_date: + today_rows.append((dt, rounded_temp)) + if latest_dt is None or dt >= latest_dt: + latest_dt = dt + latest_temp = rounded_temp + latest_humidity = self._safe_float(humidity_list[idx] if idx < len(humidity_list) else None) + latest_wind_speed_ms = self._safe_float(wind_speed_list[idx] if idx < len(wind_speed_list) else None) + latest_wind_dir = self._safe_float(wind_dir_list[idx] if idx < len(wind_dir_list) else None) + + if latest_dt is None or latest_temp is None: + return None + + max_so_far = None + max_temp_time = None + today_low = None + if today_rows: + max_so_far = max(temp for _, temp in today_rows) + today_low = min(temp for _, temp in today_rows) + for dt, temp in today_rows: + if temp == max_so_far: + max_temp_time = dt.strftime("%H:%M") + break + + result = { + "source": "noaa", + "source_label": "NOAA", + "station_code": "RCTP", + "station_name": str(station.get("NAME") or "Taiwan Taoyuan International Airport"), + "observation_time": latest_dt.isoformat(), + "current": { + "temp": latest_temp, + "max_temp_so_far": max_so_far, + "max_temp_time": max_temp_time, + "today_low": today_low, + "humidity": round(latest_humidity, 1) if latest_humidity is not None else None, + "wind_speed_kt": round(float(latest_wind_speed_ms) * 1.943844, 1) if latest_wind_speed_ms is not None else None, + "wind_dir": latest_wind_dir, + }, + "unit": "celsius", + } + self._set_settlement_cache(cache_key, result) + return result + except Exception as exc: + logger.warning(f"NOAA RCTP settlement fetch failed: {exc}") + return None + def _imgw_api_get(self, path: str, params: Optional[Dict[str, Any]] = None) -> Optional[Dict[str, Any]]: try: query = {"token": self.IMGW_METEO_API_TOKEN} @@ -346,5 +459,5 @@ class SettlementSourceMixin: if normalized == "hong kong": return self.fetch_hko_settlement_current() if normalized == "taipei": - return self.fetch_cwa_taipei_settlement_current() + return self.fetch_noaa_rctp_settlement_current() return None diff --git a/src/data_collection/weather_sources.py b/src/data_collection/weather_sources.py index 5bf30e9a..8fe70c4d 100644 --- a/src/data_collection/weather_sources.py +++ b/src/data_collection/weather_sources.py @@ -539,7 +539,7 @@ class WeatherDataCollector(OpenMeteoCacheMixin, SettlementSourceMixin, MetarSour if normalized == "hong kong": self._settlement_cache.pop("hko:hong_kong", None) elif normalized == "taipei": - self._settlement_cache.pop("cwa:taipei:466920", None) + self._settlement_cache.pop("noaa:rctp", None) def _uses_fahrenheit(self, city_lower: str) -> bool: return city_lower in self.US_CITIES @@ -557,10 +557,6 @@ class WeatherDataCollector(OpenMeteoCacheMixin, SettlementSourceMixin, MetarSour hko_forecast = self.fetch_hko_forecast() if hko_forecast: results["hko_forecast"] = hko_forecast - elif city_lower in ["taipei", "台北", "臺北", "tpe"]: - cwa_forecast = self.fetch_cwa_taipei_forecast() - if cwa_forecast: - results["cwa_forecast"] = cwa_forecast def _attach_turkish_mgm_data(self, results: Dict, city_lower: str) -> None: if city_lower not in self.TURKISH_PROVINCES: diff --git a/tmp_apikey.js b/tmp_apikey.js new file mode 100644 index 00000000..bf27db2e --- /dev/null +++ b/tmp_apikey.js @@ -0,0 +1,3 @@ +// This Synoptic API key is for weather.gov websites/queries +var mesoToken='7c76618b66c74aee913bdbae4b448bdd'; + diff --git a/tmp_obs.js b/tmp_obs.js new file mode 100644 index 00000000..ddaddf6f --- /dev/null +++ b/tmp_obs.js @@ -0,0 +1,3098 @@ +$(function() { + var myTabs = tabs({ + el: '#infotabs', + tabNavigationLinks: '.c-tabs-nav__link', + tabContentContainers: '.c-tab' + }); + myTabs.init(); + $('#container').html('
'); + // Sanitization + var ARGS = window.location.search.toLowerCase().replace('?',''); + if (ARGS) { + console.log('Parameters detected') + ARGS = ARGS.replaceAll('%20',''); + console.log(ARGS); + var args = ARGS.split('&'); + var site = ''; + var numHours = '72'; + var units = 'english'; + var chart ='on'; + var headers = 'on'; + var format = 'tabular'; + var hourly='false'; + var history = 'no'; + var pview = 'standard'; + var start = ''; + var end = ''; + var plot = ''; + var fontSize = 12; + for (i = 0; i < args.length; i++) { + var chunk = args[i].split('='); + if (chunk[0]=='site') { + if (1 < chunk[1].length && chunk[1].length < 10) { + site = chunk[1]; + } else { + popup(); + } + } else if (chunk[0]=='hours') { + if (isNaN(chunk[1])) { + popup(); + } else { + numHours = parseInt(chunk[1]); + if (1 > numHours || numHours > 720) { + popup(site); + } + } + } else if (chunk[0]=='units') { + if (chunk[1] == 'metric' || chunk[1] == 'english' || chunk[1] == 'english_k') { + units = chunk[1] + } else { + popup(site); + } + } else if (chunk[0]=='chart') { + if (chunk[1] == 'off') { + chart=chunk[1]; + $('#container').hide(); + } else if (chunk[1] == 'on') { + chart=chunk[1]; + } else{ + popup(site); + } + } else if (chunk[0]=='obs') { + if (chunk[1] == 'raw' || chunk[1] == 'tabular') { + format = chunk[1]; + } else { + popup(site); + } + } else if (chunk[0]=='font') { + if (parseInt(chunk[1])) { + fontSize = chunk[1]; + } else { + popup(site); + } + } else if (chunk[0]=='hourly') { + if (chunk[1] == 'true' || chunk[1] == 'false') { + hourly = chunk[1]; + } else { + popup(site); + } + } else if (chunk[0]=='headers') { + if (chunk[1] == 'none' || chunk[1] == 'min' || chunk[1] == 'on') { + headers = chunk[1]; + } else { + popup(site); + } + } else if (chunk[0]=='pview') { + if (chunk[1] == 'standard' || chunk[1] == 'full' || chunk[1] == 'measured') { + pview = chunk[1]; + } else { + popup(site); + } + } else if (chunk[0]=='plot') { + plot = chunk[1]; + } else if (chunk[0]=='fbclid') { + console.log('Facebook reference') + } else if (chunk[0] == 'start' && parseInt(chunk[1])) { + start = chunk[1]; + } else if (chunk[0] == 'end' && parseInt(chunk[1])) { + end = chunk[1]; + } else if (chunk[0] == 'history' && chunk[1] == 'yes') { + history = 'yes'; + } else { + popup(site); + } + } + if (!fontSize) { + fontSize = parseInt($('#OBS_DATA').css('font-size')); + } + if (site != '') { + $('#LBSITE').html('Users with low bandwidth, low computing power, or older devices may wish to click here .'); + monitorOBS(site,numHours,units,format,headers,chart,hourly,history,start,end,pview,fontSize,plot) + } else { + popup(); + } + } else { + popup(); + } + $('#HISTORY').click(function() { + if(this.checked) { + $('#STARTDATE').show(); + $('#STARTDATE').datepicker({ + altField: "#actualDate", + dateFormat: "yy-mm-dd", + maxDate: new Date, + onSelect:function (selectedDate) { + var MIN = new Date(selectedDate.split('-')[0], parseInt(selectedDate.split('-')[1]) - 1, selectedDate.split('-')[2]); + var MAX = new Date(selectedDate.split('-')[0], parseInt(selectedDate.split('-')[1]) - 1, selectedDate.split('-')[2]); + MAX.setDate(MAX.getDate()+29) + $('#ENDDATE').datepicker({ + dateFormat: "yy-mm-dd", + minDate: MIN, + maxDate: MAX + }) + $('#ENDDATE').show(); + } + }); + } else { + $('#STARTDATE').hide(); + $('#ENDDATE').hide(); + } + }); + // CSS hiding parts of the web page + $('.topnav').html(''); // HOME|FORECAST|PAST WX|SAFETY|INFO|EDUCATION|NEW|SEARCH|ABOUT + $('.topnav').css({'display': 'none', 'height' : '0px'}); // '' + $('#forecast-lookup').css({'display': 'none'}); // Local forecast by "City, St" or ZIP code + $('.five-sixth-last').css({'display': 'none'}); // "Top News" + $('.subMenuNav').html(''); // WR : Local Forecast Offices A-K|Local Forecast Offices L-Z|River Forecast Centers|Center Weather Service Units|Regional HQ + // WFOs: Cur Hazards|Cur Conditions|Radar|Forecasts|Rivers/Lakes|Climate|LocalPrograms + $('#myfcst-widget').hide(); // Customize Your Weather.gov + $('.five-sixth-first').css({'width' : '100%', 'padding-right': '0px', 'padding-left': '0px'}); // Add space from "Customize Your Weather.gov" to full width of page + $('.full-width-first').html(''); // FaceBook|Twitter|YouTube|RSS + $('.full-width-first').css({'display': 'none', 'height' : '0px'}); // '' + $('.footer').html(''); // Hide "Footer" + $('.footer').css({'display': 'none', 'height' : '0px'}); // '' + $('.full-width-border').css({'border-top' : 'white'}); // '' + $('.partial-width-borderbottom').css({'border-bottom' : 'white'}); // '' + + buildCustomMenu(SITE,numHours,units,format,headers,chart,hourly,history,start,end,pview,fontSize,plot) + $('#options').dialog({ + modal: true, + width: "75%", + maxWidth: "1000px", + autoOpen: false, + title: "Advanced Settings ", + closeOnEscape: true, + show: { effect: "fade", duration: 800 } + }); + $('#ABOUT').dialog({ + modal: true, + width: "75%", + maxWidth: "1000px", + autoOpen: false, + title: "About this page ", + closeOnEscape: true, + show: { effect: "fade", duration: 800 } + }); + $('#SETTINGS').click(function() { + $('#options').dialog('open'); + }); + $('#info').click(function() { + $('#ABOUT').dialog('open'); + }); + // Toggles + $('#unitsToggle').click(function() { + if (units == 'english') { + units = 'metric'; + } else if (units == 'metric') { + units = 'english_k'; + } else { + units = 'english'; + } + //var fontSize = parseInt($('#OBS_DATA').css('font-size')); + monitorOBS(site,numHours,units,format,headers,chart,hourly,history,start,end,pview,fontSize,plot); + }) + $('#dataToggle').click(function() { + if (hourly == 'true') { + hourly = 'false'; + } else { + hourly = 'true'; + } + //var fontSize = parseInt($('#OBS_DATA').css('font-size')); + monitorOBS(site,numHours,units,format,headers,chart,hourly,history,start,end,pview,fontSize,plot); + }) + $('#obsToggle').click(function() { + if (format == 'raw') { + format = 'tabular'; + } else { + format = 'raw'; + } + //var fontSize = parseInt($('#OBS_DATA').css('font-size')); + monitorOBS(site,numHours,units,format,headers,chart,hourly,history,start,end,pview,fontSize,plot); + }) + $('#hoursToggle').click(function() { + if (numHours < 168) { + numHours = 168; + } else { + numHours = 72; + } + //var fontSize = parseInt($('#OBS_DATA').css('font-size')); + monitorOBS(site,numHours,units,format,headers,chart,hourly,history,start,end,pview,fontSize,plot); + }) + $('#smallFont').click(function() { + //var fontSize = parseInt($('#OBS_DATA').css('font-size')); + console.log(fontSize); + fontSize = parseInt(fontSize) -1; + //$('#OBS_DATA').css({'font-size': fontSize}); + resizePage(fontSize); + }) + $('#resetFont').click(function() { + //$('#OBS_DATA').css({'font-size': 12}); + fontSize = 12; + resizePage(fontSize); + }) + $('#bigFont').click(function() { + //var fontSize = parseInt($('#OBS_DATA').css('font-size')); + console.log(fontSize); + fontSize = parseInt(fontSize) +1; + //$('#OBS_DATA').css({'font-size': fontSize}); + resizePage(fontSize); + }) +}) + +function popup(site) { + if (!site) { + site = 'kslc' + } + alert('Something is wrong!\n Valid arguments are "site"\n followed by a valid 2-6 letter identifier\n and optional arguments are:\n "hours" followed by an integer between 1 and 720\n "units" followed by "english", "english_k", or "metric" \n "obs" followed by "raw" (For ASOS/AWOS or Global METAR locations only)\n "headers" followed by "min" or "none"\n "chart" followed by "on" or "off"\n "hourly" followed by "true" or "false"\n "font" followed by an integer \n "pview" followed by "standard", "full" or "measured" \n Example:\nhttps://www.weather.gov/wrh/timeseries?site=kslc&hours=48&units=english&obs=raw&headers=off&chart=on&hourly=true&pview=full'); + window.location.href = 'https://www.weather.gov/wrh/timeseries?site='+site; +} + +function monitorOBS(SITE,numHours,units,format,headers,chart,hourly,history,start,end,pview,fontSize,plot) { + SITE = SITE.toUpperCase(); + console.log(SITE,numHours,units,format,headers,chart,hourly,history,start,end,pview,fontSize,plot); + window.setTimeout(function () { + //var fontSize = parseInt($('#OBS_DATA').css('font-size')); + monitorOBS(SITE,numHours,units,format,headers,chart,hourly,history,start,end,pview,fontSize,plot) + }, 300000); + if (history == 'yes') { + numHours = 720; + } + // Build out select dropdown for charts + $(".plot_select").empty(); + $(".plot_select").append(""); + $(".perm_select").empty(); + $(".perm_select").append(""); + // Toggle certain variables + if (units == 'english') { + $('#unitsToggle').html('Switch to Metric Units'); + } else if (units == 'metric') { + $('#unitsToggle').html('Switch to US Units w/ kts'); + } else { + $('#unitsToggle').html('Switch to US Units w/ mph'); + } + if (hourly == 'true') { + $('#dataToggle').html('Show All Data'); + } else { + $('#dataToggle').html('Show Hourly Data'); + } + if (format == 'raw') { + $('#obsToggle').html('Decoded Observations'); + } else { + $('#obsToggle').html('Raw Observations'); + } + if (numHours < 73) { + $('#hoursToggle').html('7 Days'); + } else { + $('#hoursToggle').html('3 Days'); + } + $('#SITE').html(''); + var numMinutes = numHours * 60; + if (history != 'yes') { + if (units == 'english') { + var InfoToGet = 'https://api.synopticdata.com/v2/stations/timeseries?STID='+SITE+'&showemptystations=1&units=temp|F,speed|mph,english&recent='+numMinutes+'&complete=1&token='+mesoToken+'&obtimezone=local'; + } else if (units == 'english_k') { + var InfoToGet = 'https://api.synopticdata.com/v2/stations/timeseries?STID='+SITE+'&showemptystations=1&units=temp|F,speed|kts,english&recent='+numMinutes+'&complete=1&token='+mesoToken+'&obtimezone=local'; + } else if (units == 'metric') { + var InfoToGet = 'https://api.synopticdata.com/v2/stations/timeseries?STID='+SITE+'&showemptystations=1&recent='+numMinutes+'&complete=1&token='+mesoToken+'&obtimezone=local'; + } + } else { + if (units == 'english') { + var InfoToGet = 'https://api.synopticdata.com/v2/stations/timeseries?STID='+SITE+'&showemptystations=1&units=temp|F,speed|mph,english&start='+start+'0000&end='+end+'2359&complete=1&token='+mesoToken+'&obtimezone=local'; + } else if (units == 'english') { + var InfoToGet = 'https://api.synopticdata.com/v2/stations/timeseries?STID='+SITE+'&showemptystations=1&units=temp|F,speed|kts,english&start='+start+'0000&end='+end+'2359&complete=1&token='+mesoToken+'&obtimezone=local'; + } else if (units == 'metric') { + var InfoToGet = 'https://api.synopticdata.com/v2/stations/timeseries?STID='+SITE+'&showemptystations=1&start='+start+'0000&end='+end+'2359&complete=1&token='+mesoToken+'&obtimezone=local'; + } + } + console.log(InfoToGet); + $.getJSON(InfoToGet, function(DATA) { + if (DATA.SUMMARY.RESPONSE_MESSAGE == "OK") { + // Metadata + var stnID = DATA.STATION[0].STID; + var stnNAM = DATA.STATION[0].NAME; + document.title = stnNAM; + if (headers == 'on') { + $('.location-pagetitle').html(stnNAM); + } else { + $('#icons').hide; + $('.header').html(''); // NOAA BANNER + $('.header').css({'display': 'none', 'height' : '0px'}); // '' + $('.center-content').html(''); // + $('.footer').html(''); // + $('.footer-legal').html(''); // + } + var stnLAT = DATA.STATION[0].LATITUDE; + var stnLON = DATA.STATION[0].LONGITUDE + var stnELE = DATA.STATION[0].ELEVATION; + var state = DATA.STATION[0].STATE; + var cwa = DATA.STATION[0].CWA; + var network = DATA.STATION[0].SHORTNAME; + console.log(network); + var NETWORK = network.toUpperCase(); + var nwsZone = DATA.STATION[0].NWSZONE; + if (network == 'GLOBAL-METAR') { + network = 'ASOS/AWOS'; + } + if (network == 'ASOS/AWOS') { + $('#obsToggle').show(); + } else { + $('#obsToggle').hide(); + } + // Needed for stuff we need to derive + var derived = 0; + var accum_true = 0; + var has_speed = 0; + var has_precip = 0; + var has_pressure = 0; + + // Building block for datasets + var EngHeader = ''; + var MetHeader = '
'; + var stamps = ''; + + if (DATA.STATION[0].hasOwnProperty('OBSERVATIONS') && DATA.STATION[0].OBSERVATIONS.hasOwnProperty('date_time')) { + stamps = DATA.STATION[0].OBSERVATIONS.date_time; + //console.log(stamps) + var numObs = DATA.STATION[0].OBSERVATIONS.date_time.length; + numObs = numObs - 1; + var tableData = ''; + // Loop through each observation + var METARString = '
'; + for (j = numObs; j > -1; j--) { + // Date and time + var MW_TIMESTAMP = DATA.STATION[0].OBSERVATIONS.date_time[j]; + var TIMEZONE = DATA.STATION[0].TIMEZONE; + var timestamp = moment(MW_TIMESTAMP).tz(TIMEZONE).format('MMM D, h:mm a') + var hours = moment(MW_TIMESTAMP).tz(TIMEZONE).format('h'); + hours = parseInt(hours); + var minutes = moment(MW_TIMESTAMP).tz(TIMEZONE).format('mm'); + + // Temperature + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('air_temp_set_1')) { + var ATData = DATA.STATION[0].OBSERVATIONS.air_temp_set_1; + if (j == 0) { + plot_menu("temperature","Temperature"); + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.air_temp_set_1[j] !== null) { + var TEMP_F = ''; + } else { + var TEMP_F = ''; + } + } else { + var TEMP_F = ''; + } + // Dew Point + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('dew_point_temperature_set_1d')) { + if (j == 0) { + plot_menu("dewpt","Dew Point"); + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.dew_point_temperature_set_1d[j] !== null) { + var DEWPOINT = ''; + } else { + var DEWPOINT = ''; + } + } else { + var DEWPOINT = ''; + } + // Relative Humidity + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('relative_humidity_set_1')) { + if (j == 0) { + plot_menu("rh","Relative Humidity"); + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.relative_humidity_set_1[j] !== null) { + var RH_PCT = ''; + } else { + var RH_PCT = ''; + } + } else { + var RH_PCT = ''; + } + // Heat Index + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('heat_index_set_1d')) { + if (j == 0) { + plot_menu("heat_index","Heat Index"); + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.heat_index_set_1d[j] !== null) { + var HI = ''; + } else { + var HI = ''; + } + } else { + var HI = ''; + } + // Wind Chill + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('wind_chill_set_1d')) { + if (j == 0) { + plot_menu("wind_chill","Wind Chill"); + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.wind_chill_set_1d[j] !== null) { + var WC = ''; + } else { + var WC = ''; + } + } else { + var WC = ''; + } + // Wind Direction + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('wind_direction_set_1')) { + if (j == 0) { + plot_menu("wind_dir","Wind Direction"); + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.wind_cardinal_direction_set_1d[j] !== null) { + var Wind_DIR = (DATA.STATION[0].OBSERVATIONS.wind_cardinal_direction_set_1d[j]); + var WIND_DIR = ''; + } else { + var WIND_DIR = ''; + } + } else { + var WIND_DIR = ''; + } + // Wind Speed & Gust + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('wind_speed_set_1')) { + var has_speed=1; + if (j == 0) { + plot_menu("wind_speedgust","Wind Speed & Gusts"); + if (units == 'english') { + EngHeader += ''; + } else if (units == 'english_k') { + EngHeader += ''; + } + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.wind_speed_set_1[j] !== null) { + if (units == 'english' || units == 'english_k') { + var WIND_SPD = Math.round(DATA.STATION[0].OBSERVATIONS.wind_speed_set_1[j]); + if (WIND_SPD < 20 ) { + WIND_SPD = ''; + } else if (WIND_GST < 12 ) { + WIND_SPD += 'G'+WIND_GST+''; + } else if (WIND_GST < 13 ) { + WIND_SPD += 'G'+WIND_GST+''; + } else { + WIND_SPD += 'G'+WIND_GST+''; + } + } else { + var WIND_GST =Math.round((DATA.STATION[0].OBSERVATIONS.wind_gust_set_1[j])*3.6); + if (WIND_GST < 17) { + WIND_SPD += 'G'+WIND_GST+''; + } else if (WIND_GST < 19 ) { + WIND_SPD += 'G'+WIND_GST+''; + } else if (WIND_GST < 21 ) { + WIND_SPD += 'G'+WIND_GST+''; + } else { + WIND_SPD += 'G'+WIND_GST+''; + } + } + } else { + WIND_SPD += ''; + } + } + } else { + var WIND_SPD = ''; + } + // Wind Gust, where there is no speed ... + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('wind_gust_set_1')) { + if (has_speed == 0) { + if (j == 0) { + plot_menu("wind_gust","Wind Gusts"); + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.wind_gust_set_1[j] !== null) { + if (units == 'english') { + var WIND_GST =Math.round(DATA.STATION[0].OBSERVATIONS.wind_gust_set_1[j]); + if (WIND_GST < 11 ) { + var WIND_GUST = ''; + } else if (WIND_GST < 12 ) { + var WIND_GUST = ''; + } else if (WIND_GST < 13 ) { + var WIND_GUST = ''; + } else { + var WIND_GUST = ''; + } + } else { + var WIND_GST =Math.round((DATA.STATION[0].OBSERVATIONS.wind_gust_set_1[j])*3.6); + if (WIND_GST < 17 ) { + var WIND_GUST = ''; + } else if (WIND_GST < 19 ) { + var WIND_GUST = ''; + } else if (WIND_GST < 21 ) { + var WIND_GUST = ''; + } else { + var WIND_GUST = ''; + } + } + } else { + var WIND_GUST = ''; + } + } else { + var WIND_GUST =''; + } + } else { + var WIND_GUST =''; + } + // Fuel Temperature + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('fuel_temp_set_1')) { + if (j == 0) { + plot_menu("fuel_temp","Fuel Temperature"); + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.fuel_temp_set_1[j] !== null) { + var FUEL_T = ''; + } else { + var FUEL_T = ''; + } + } else { + var FUEL_T = ''; + } + // Fuel Moisture + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('fuel_moisture_set_1')) { + if (j == 0) { + plot_menu("fuel_moisture","Fuel Moisture"); + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.fuel_moisture_set_1[j] !== null) { + var FUEL_PCT = ''; + } else { + var FUEL_PCT = ''; + } + } else { + var FUEL_PCT = ''; + } + // Visibility + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('visibility_set_1')) { + if (j == 0) { + plot_menu("vsby","Visibility"); + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.visibility_set_1[j] !== null) { + if (units == 'metric') { + var VISIBILITY =((DATA.STATION[0].OBSERVATIONS.visibility_set_1[j])*1.609).toFixed(1); + if (VISIBILITY <= 1.6 ) { + VISIBILITY = ''; + } else if (VISIBILITY <= 5 ) { + VISIBILITY = ''; + } else if (VISIBILITY < 11) { + VISIBILITY = ''; + } else { + VISIBILITY = ''; + } + } else { + var VISIBILITY =(DATA.STATION[0].OBSERVATIONS.visibility_set_1[j]).toFixed(2); + if (VISIBILITY <= 1 ) { + VISIBILITY = ''; + } else if (VISIBILITY <= 3 ) { + VISIBILITY = ''; + } else if (VISIBILITY < 7) { + VISIBILITY = ''; + } else { + VISIBILITY = ''; + } + } + } else { + var VISIBILITY = ''; + } + } else { + var VISIBILITY = ''; + } + // Present Weather + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('weather_cond_code_set_1')) { + if (j == 0) { + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.weather_cond_code_set_1[j] !== null) { + if (network == 'ASOS/AWOS') { + var WEATHER = parseInt(DATA.STATION[0].OBSERVATIONS.weather_cond_code_set_1[j]); + if (WEATHER < 80) { // + WX_ELEM1 = getWeatherCode(WEATHER); + WX_ELEM2 = ''; + WX_ELEM3 = ''; + } else if (WEATHER < 6400) { + WX1 = Math.floor (WEATHER / 80); + WX_ELEM1 = getWeatherCode(WX1); + WX2 = (WEATHER % 80); + WX_ELEM2 = getWeatherCode(WX2)+','; + WX_ELEM3 = ''; + } else { + WX1 = Math.floor (WEATHER / 6400); + WX_ELEM1 = getWeatherCode(WX1); + + WX2 = (WEATHER -(6400 * WX1)); + WX2 = Math.floor(WX2/80); + WX_ELEM2 = getWeatherCode(WX2)+','; + + WX3 = (WEATHER % 80); + WX_ELEM3 = getWeatherCode(WX3)+','; + //console.log(WEATHER,WX3,WX_ELEM3,WX2,WX_ELEM2,WX1,WX_ELEM1); + } + WEATHER = ''; + } else { + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('weather_condition_set_1d')) { + WEATHER = ''; + } else { + WEATHER = ''; + } + } + } else { + var WEATHER = ''; + } + } else { + var WEATHER = ''; + } + //Cloud Layers + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('cloud_layer_1_code_set_1')) { + if (j == 0) { + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.cloud_layer_1_code_set_1[j] !== null) { + var SKY1 =(DATA.STATION[0].OBSERVATIONS.cloud_layer_1_code_set_1[j]).toString(); + var COVERAGE1 = SKY1.substr(SKY1.length -1); + if (COVERAGE1 == "1") { + SKY_COND1 = 'CLR'; + } else if (COVERAGE1 == "2") { + SKY_COND1 = 'SCT'; + } else if (COVERAGE1 == "3") { + SKY_COND1 = 'BKN'; + } else if (COVERAGE1 == "4") { + SKY_COND1 = 'OVC'; + } else if (COVERAGE1 == "5") { + SKY_COND1 = 'VV'; + } else if (COVERAGE1 == "6") { + SKY_COND1 = 'FEW'; + } else { + SKY_COND1 = ''; + } + var DECK1 = parseInt(SKY1.slice(0, -1)); + if (isNaN(DECK1)) { + DECK1 = ''; + } else if (DECK1 < 10) { + DECK1 = "00"+DECK1; + } else if (DECK1 < 100) { + DECK1 = "0"+DECK1; + } else { + DECK1 = DECK1; + } + } else { + var SKY_COND1 = ''; + var DECK1 = ''; + } + } else { + var SKY_COND1 = ''; + var DECK1 = ''; + } + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('cloud_layer_2_code_set_1')) { + if (DATA.STATION[0].OBSERVATIONS.cloud_layer_2_code_set_1[j] !== null) { + var SKY2 =(DATA.STATION[0].OBSERVATIONS.cloud_layer_2_code_set_1[j]).toString(); + var COVERAGE2 = SKY2.substr(SKY2.length -1); + if (COVERAGE2 == "1") { + SKY_COND2 = 'CLR'; + } else if (COVERAGE2 == "2") { + SKY_COND2 = 'SCT'; + } else if (COVERAGE2 == "3") { + SKY_COND2 = 'BKN'; + } else if (COVERAGE2 == "4") { + SKY_COND2 = 'OVC'; + } else if (COVERAGE2 == "5") { + SKY_COND2 = 'VV'; + } else if (COVERAGE2 == "6") { + SKY_COND2 = 'FEW'; + } else { + SKY_COND2 = ''; + } + var DECK2 = parseInt(SKY2.slice(0, -1)); + if (isNaN(DECK2)) { + DECK2 = ''; + } else if (DECK2 < 10) { + DECK2 = "00"+DECK2; + } else if (DECK2 < 100) { + DECK2 = "0"+DECK2; + } else { + DECK2 = DECK2; + } + } else { + var SKY_COND2 = ''; + var DECK2 = ''; + } + } else { + var SKY_COND2 = ''; + var DECK2 = ''; + } + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('cloud_layer_3_code_set_1')) { + if (DATA.STATION[0].OBSERVATIONS.cloud_layer_3_code_set_1[j] !== null) { + var SKY3 =(DATA.STATION[0].OBSERVATIONS.cloud_layer_3_code_set_1[j]).toString(); + var COVERAGE3 = SKY3.substr(SKY3.length -1); + if (COVERAGE3 == "1") { + SKY_COND3 = 'CLR'; + } else if (COVERAGE3 == "2") { + SKY_COND3 = 'SCT'; + } else if (COVERAGE3 == "3") { + SKY_COND3 = 'BKN'; + } else if (COVERAGE3 == "4") { + SKY_COND3 = 'OVC'; + } else if (COVERAGE3 == "5") { + SKY_COND3 = 'VV'; + } else if (COVERAGE3 == "6") { + SKY_COND3 = 'FEW'; + } else { + SKY_COND3 = ''; + } + var DECK3 = parseInt(SKY3.slice(0, -1)); + if (isNaN(DECK3)) { + DECK3 = ''; + } else if (DECK3 < 10) { + DECK3 = "00"+DECK3; + } else if (DECK3 < 100) { + DECK3 = "0"+DECK3; + } else { + DECK3 = DECK3; + } + } else { + var SKY_COND3 = ''; + var DECK3 = ''; + } + } else { + var SKY_COND3 = ''; + var DECK3 = ''; + } + var SKY_COND = ''; + // If there was a cloud layer, THEN make the cloud cells + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('cloud_layer_1_code_set_1')) { + if (SKY_COND1 == "CLR" || SKY_COND1 == "FEW" || SKY_COND1 == "SCT") { + LAYER1 = SKY_COND1+DECK1; + } else if (DECK1 < 10) { + LAYER1 = ''+SKY_COND1+DECK1+''; + } else if (DECK1 < 31) { + LAYER1 = ''+SKY_COND1+DECK1+''; + } else if (DECK1 < 81) { + LAYER1 = ''+SKY_COND1+DECK1+''; + } else { + LAYER1 = SKY_COND1+DECK1; + } + + if (SKY_COND2 == "CLR" || SKY_COND2 == "FEW" || SKY_COND2 == "SCT") { + LAYER2 = SKY_COND2+DECK2; + } else if (DECK2 < 10) { + LAYER2 = ''+SKY_COND2+DECK2+''; + } else if (DECK2 < 31) { + LAYER2 = ''+SKY_COND2+DECK2+''; + } else if (DECK2 < 81) { + LAYER2 = ''+SKY_COND2+DECK2+''; + } else { + LAYER2 = SKY_COND2+DECK2; + } + if (SKY_COND3 == "CLR" || SKY_COND3 == "FEW" || SKY_COND3 == "SCT") { + LAYER3 = SKY_COND3+DECK3; + } else if (DECK3 < 10) { + LAYER3 = ''+SKY_COND3+DECK3+''; + } else if (DECK3 < 31) { + LAYER3 = ''+SKY_COND3+DECK3+''; + } else if (DECK3 < 81) { + LAYER3 = ''+SKY_COND3+DECK3+''; + } else { + LAYER3 = SKY_COND3+DECK3; + } + var SKY_COND = ''; + } + // Sea Level Pressure + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('sea_level_pressure_set_1')) { + if (j == 0) { + plot_menu("slp","Sea Level Pressure"); + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.sea_level_pressure_set_1[j] !== null) { + if (units == 'metric') { + var SEALEVEL = ''; + } else { + var SEALEVEL = ''; + } + } else { + var SEALEVEL = ''; + } + } else if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('sea_level_pressure_set_1d')) { + if (j == 0) { + plot_menu("slp","Sea Level Pressure"); + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.sea_level_pressure_set_1d[j] !== null) { + if (units == 'metric') { + var SEALEVEL = ''; + } else { + var SEALEVEL = ''; + } + } else { + var SEALEVEL = ''; + } + } else { + var SEALEVEL = ''; + } + // Station Pressure + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('pressure_set_1')) { + has_pressure = 1; + if (j == 0) { + plot_menu("stn_press","Station Pressure"); + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.pressure_set_1[j] !== null) { + if (units == 'metric') { + var P = ''; + } else { + if ((DATA.STATION[0].OBSERVATIONS.pressure_set_1[j]).toFixed(2) < 50) { + var P = ''; + } else { + var P = ''; + } + } + } else { + var P = ''; + } + } else { + var P = ''; + } + // Altimeter Setting + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('altimeter_set_1')) { + if (j == 0) { + if (has_pressure == 0) { + EngHeader += ''; + MetHeader += ''; + } + plot_menu("alstg","Altimeter Setting"); + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.altimeter_set_1[j] !== null) { + var stationP = calcStationP(DATA.STATION[0].OBSERVATIONS.altimeter_set_1[j],stnELE); + if (units == 'metric') { + if (has_pressure == 0) { + var ALTIMTER = ''; + } else { + var ALTIMTER = ''; + } + } else { + if (has_pressure == 0) { + var ALTIMTER = ''; + } else { + var ALTIMTER = ''; + } + } + } else { + if (has_pressure == 0) { + var ALTIMTER = ''; + } else { + var ALTIMTER = ''; + } + } + } else { + var ALTIMTER = ''; + } + // Station Pressure + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('station_pressure_set_1')) { + if (j == 0) { + plot_menu("stn_press_2","Station Pressure"); + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.station_pressure_set_1[j] !== null) { + if (units == 'metric') { + var STATION_P = ''; + } else { + var STATION_P = ''; + } + } else { + var STATION_P = ''; + } + } else { + var STATION_P = ''; + } + // Solar Radiation + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('solar_radiation_set_1')) { + if (j == 0) { + plot_menu("solar_rad","Solar Radiation"); + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.solar_radiation_set_1[j] !== null) { + var RAW_SOLAR = (Math.round(DATA.STATION[0].OBSERVATIONS.solar_radiation_set_1[j])); + var SOLAR_POSS = calcSolarPCT(MW_TIMESTAMP,stnLAT,stnLON); + var PCT = Math.round (100 * RAW_SOLAR / SOLAR_POSS); + if (PCT > 100) { + PCT = 100; + } + if (RAW_SOLAR > 0 && SOLAR_POSS > 0) { + var SOLAR = ''; + var SOLAR_PCT = ''; + } else { + var SOLAR = ''; + var SOLAR_PCT = ''; + } + } else { + var SOLAR = ''; + var SOLAR_PCT = ''; + } + } else { + var SOLAR = ''; + var SOLAR_PCT = ''; + } + // Surface Temperature + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('surface_temp_set_1')) { + if (j == 0) { + plot_menu("surface_temp","Surface Temperature"); + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.surface_temp_set_1[j] !== null) { + var SURF_T = ''; + } else { + var SURF_T = ''; + } + } else { + var SURF_T = ''; + } + // Soil Temperature + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('soil_temp_set_1')) { + if (j == 0) { + plot_menu("soil_temp","Soil Temperature"); + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.soil_temp_set_1[j] !== null) { + var SOIL_T = ''; + } else { + var SOIL_T = ''; + } + } else { + var SOIL_T = ''; + } + // Road Temperature + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('road_temp_set_1')) { + if (j == 0) { + plot_menu("road_temp","Road Temperature"); + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.road_temp_set_1[j] !== null) { + var ROAD_T = ''; + } else { + var ROAD_T = ''; + } + } else if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('road_temp_set_2')) { + if (j == 0) { + plot_menu("road_temp_2","Road Temperature"); + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.road_temp_set_2[j] !== null) { + var ROAD_T = ''; + } else { + var ROAD_T = ''; + } + } else { + var ROAD_T = ''; + } + // Road Sub-Surface Temp + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('road_subsurface_tmp_set_1')) { + if (j == 0) { + plot_menu("road_sub_temp","Road Sub-Surface Temp"); + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.road_subsurface_tmp_set_1[j] !== null) { + var SROAD_T = ''; + } else { + var SROAD_T = ''; + } + } else { + var SROAD_T = ''; + } + // If Accumulated Precip or any increment of precip up to one hour is set, + // we will calculate 1, 3, 6 and 24 hour precip values on our own. + // Synoptic does not consistently return ihigher interval data for those fields + // Even if we get those fields, we will disable any processing of that data down the line. + + // Accumulated Precip + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('precip_accum_set_1')) { + derived = 1; + accum_true = 1; + has_precip = 1; + if (j == 0) { + plot_menu("accum_pcpn","Accumulated Precip"); + if (pview == 'measured') { + EngHeader += ''; + MetHeader += ''; + } else { + EngHeader += ''; + MetHeader += ''; + } + } + if (DATA.STATION[0].OBSERVATIONS.precip_accum_set_1[j] !== null) { + var ACC_Precip = (DATA.STATION[0].OBSERVATIONS.precip_accum_set_1[j]).toFixed(2); + var oneHRprecip = ''; + var threeHRprecip = ''; + var sixHRprecip = ''; + var oneDAYprecip = ''; + if (pview == 'measured') { + oneHRprecip = ''; + threeHRprecip = ''; + sixHRprecip = ''; + oneDAYprecip = ''; + var ACC_PCPN = ''; + } else if (pview == 'full') { + oneHRprecip = getDerivedPrecip(60,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_set_1); + threeHRprecip = getDerivedPrecip(180,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_set_1); + sixHRprecip = getDerivedPrecip(360,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_set_1); + oneDAYprecip = getDerivedPrecip(1440,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_set_1); + var ACC_PCPN = ''; + } else if (numHours > numObs) { + oneHRprecip = getDerivedPrecip(60,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_set_1); + if (hours % 3 === 0 || j == numObs) { + threeHRprecip = getDerivedPrecip(180,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_set_1); + } + if (hours % 6 === 0 || j == numObs) { + sixHRprecip = getDerivedPrecip(360,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_set_1); + } + if (hours % 12 === 0 || j == numObs) { + oneDAYprecip = getDerivedPrecip(1440,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_set_1); + } + var ACC_PCPN = ''; + } else { + if (minutes == '00' || j == numObs) { + oneHRprecip = getDerivedPrecip(60,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_set_1); + if (hours % 3 === 0 || j == numObs) { + threeHRprecip = getDerivedPrecip(180,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_set_1); + } + if (hours % 6 === 0 || j == numObs) { + sixHRprecip = getDerivedPrecip(360,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_set_1); + } + if (hours % 12 === 0 || j == numObs) { + oneDAYprecip = getDerivedPrecip(1440,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_set_1); + } + } + var ACC_PCPN = ''; + } + } else { + if (pview == 'measured') { + var ACC_PCPN = ''; + } else { + var ACC_PCPN = ''; + } + } + } else { + var ACC_PCPN = ''; + } + // If we have accumulated precip, there is no need for any of these. + if (accum_true == 0) { + // 1 Minute Precip + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('precip_accum_one_minute_set_1')) { + derived = 1; + has_precip = 1; + if (j == 0) { + plot_menu("one_min_pcpn","1 Minute Precip"); + if (pview == 'measured') { + EngHeader += ''; + MetHeader += ''; + } else { + EngHeader += ''; + MetHeader += ''; + } + } + if (DATA.STATION[0].OBSERVATIONS.precip_accum_one_minute_set_1[j] !== null) { + var oneMINprecip = (DATA.STATION[0].OBSERVATIONS.precip_accum_one_minute_set_1[j]).toFixed(2); + if (oneMINprecip == '0.001' || oneMINprecip == '0.005') { + oneMINprecip = 'T'; + } + var oneHRprecip = ''; + var threeHRprecip = ''; + var sixHRprecip = ''; + var oneDAYprecip = ''; + if (pview == 'measured') { + var MIN_1_PCPN = ''; + } else if (pview == 'full') { + oneHRprecip = calcIncrementalPrecip (60,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_one_minute_set_1); + threeHRprecip = calcIncrementalPrecip (180,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_one_minute_set_1); + sixHRprecip = calcIncrementalPrecip (360,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_one_minute_set_1); + oneDAYprecip = calcIncrementalPrecip (1440,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_one_minute_set_1); + var MIN_1_PCPN = ''; + } else if (minutes == '00' || j == numObs) { + oneHRprecip = calcIncrementalPrecip (60,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_one_minute_set_1); + if (hours % 3 === 0 || j == numObs) { + threeHRprecip = calcIncrementalPrecip (180,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_one_minute_set_1); + } else { + threeHRprecip = ''; + } + if (hours % 6 === 0 || j == numObs) { + sixHRprecip = calcIncrementalPrecip (360,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_one_minute_set_1); + } else { + sixHRprecip = ''; + } + if (hours % 12 === 0 || j == numObs) { + oneDAYprecip = calcIncrementalPrecip (1440,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_one_minute_set_1); + } else { + oneDAYprecip = ''; + } + var MIN_1_PCPN = ''; + } else { + var MIN_1_PCPN = ''; + } + } else { + if (pview == 'measured') { + var MIN_1_PCPN = ''; + } else { + var MIN_1_PCPN = ''; + } + } + } else { + var MIN_1_PCPN = ''; + } + // 5 Minute Precip + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('precip_accum_five_minute_set_1')) { + derived = 1; + has_precip = 1; + if (j == 0) { + plot_menu("five_min_pcpn","5 Minute Precip"); + if (pview == 'measured') { + EngHeader += ''; + MetHeader += ''; + } else { + EngHeader += ''; + MetHeader += ''; + } + } + if (DATA.STATION[0].OBSERVATIONS.precip_accum_five_minute_set_1[j] !== null) { + var fiveMINprecip = (DATA.STATION[0].OBSERVATIONS.precip_accum_five_minute_set_1[j]).toFixed(2); + if (fiveMINprecip == '0.001' || fiveMINprecip == '0.005') { + fiveMINprecip = 'T'; + } + var oneHRprecip = ''; + var threeHRprecip = ''; + var sixHRprecip = ''; + var oneDAYprecip = ''; + if (pview == 'measured') { + var MIN_5_PCPN = ''; + } else if (pview == 'full') { + oneHRprecip = calcIncrementalPrecip (60,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_five_minute_set_1); + threeHRprecip = calcIncrementalPrecip (180,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_five_minute_set_1); + sixHRprecip = calcIncrementalPrecip (360,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_five_minute_set_1); + oneDAYprecip = calcIncrementalPrecip (1440,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_five_minute_set_1); + var MIN_5_PCPN = ''; + } else if (minutes == '00' || j == numObs) { + oneHRprecip = calcIncrementalPrecip (60,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_five_minute_set_1); + if (hours % 3 === 0 || j == numObs) { + threeHRprecip = calcIncrementalPrecip (180,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_five_minute_set_1); + } else { + threeHRprecip = ''; + } + if (hours % 6 === 0 || j == numObs) { + sixHRprecip = calcIncrementalPrecip (360,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_five_minute_set_1); + } else { + sixHRprecip = ''; + } + if (hours % 12 === 0 || j == numObs) { + oneDAYprecip = calcIncrementalPrecip (1440,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_five_minute_set_1); + } else { + oneDAYprecip = ''; + } + var MIN_5_PCPN = ''; + } else { + var MIN_5_PCPN = ''; + } + } else { + if (pview == 'measured') { + var MIN_5_PCPN = ''; + } else { + var MIN_5_PCPN = ''; + } + } + } else { + var MIN_5_PCPN = ''; + } + // 10 Minute Precip + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('precip_accum_ten_minute_set_1')) { + derived = 1; + has_precip = 1; + if (j == 0) { + plot_menu("ten_min_pcpn","10 Minute Precip"); + if (pview == 'measured') { + EngHeader += ''; + MetHeader += ''; + } else { + EngHeader += ''; + MetHeader += ''; + } + } + if (DATA.STATION[0].OBSERVATIONS.precip_accum_ten_minute_set_1[j] !== null) { + var tenMINprecip = (DATA.STATION[0].OBSERVATIONS.precip_accum_ten_minute_set_1[j]).toFixed(2); + var oneHRprecip = ''; + var threeHRprecip = ''; + var sixHRprecip = ''; + var oneDAYprecip = ''; + if (pview == 'measured') { + var MIN_10_PCPN = ''; + } else if (pview == 'full') { + oneHRprecip = calcIncrementalPrecip (60,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_ten_minute_set_1); + threeHRprecip = calcIncrementalPrecip (180,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_ten_minute_set_1); + sixHRprecip = calcIncrementalPrecip (360,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_ten_minute_set_1); + oneDAYprecip = calcIncrementalPrecip (1440,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_ten_minute_set_1); + var MIN_10_PCPN = ''; + } else if (minutes == '00' || j == numObs) { + oneHRprecip = calcIncrementalPrecip (60,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_ten_minute_set_1); + if (hours % 3 === 0 || j == numObs) { + threeHRprecip = calcIncrementalPrecip (180,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_ten_minute_set_1); + } else { + threeHRprecip = ''; + } + if (hours % 6 === 0 || j == numObs) { + sixHRprecip = calcIncrementalPrecip (360,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_ten_minute_set_1); + } else { + sixHRprecip = ''; + } + if (hours % 12 === 0 || j == numObs) { + oneDAYprecip = calcIncrementalPrecip (1440,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_ten_minute_set_1); + } else { + oneDAYprecip = ''; + } + var MIN_10_PCPN = ''; + } else { + var MIN_10_PCPN = ''; + } + } else { + if (pview == 'measured') { + var MIN_10_PCPN = ''; + } else { + var MIN_10_PCPN = ''; + } + } + } else { + var MIN_10_PCPN = ''; + } + // 15 Minute Precip + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('precip_accum_fifteen_minute_set_1')) { + derived = 1; + has_precip = 1; + if (j == 0) { + plot_menu("fifteen_min_pcpn","15 Minute Precip"); + if (pview == 'measured') { + EngHeader += ''; + MetHeader += ''; + } else { + EngHeader += ''; + MetHeader += ''; + } + } + if (DATA.STATION[0].OBSERVATIONS.precip_accum_fifteen_minute_set_1[j] !== null) { + var fifteenMINprecip = (DATA.STATION[0].OBSERVATIONS.precip_accum_fifteen_minute_set_1[j]).toFixed(2); + var oneHRprecip = ''; + var threeHRprecip = ''; + var sixHRprecip = ''; + var oneDAYprecip = ''; + if (pview == 'measured') { + var MIN_15_PCPN = ''; + } else if (pview == 'full') { + oneHRprecip = calcIncrementalPrecip (60,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_fifteen_minute_set_1); + threeHRprecip = calcIncrementalPrecip (180,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_fifteen_minute_set_1); + sixHRprecip = calcIncrementalPrecip (360,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_fifteen_minute_set_1); + oneDAYprecip = calcIncrementalPrecip (1440,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_fifteen_minute_set_1); + var MIN_15_PCPN = ''; + } else if (minutes == '00' || j == numObs) { + oneHRprecip = calcIncrementalPrecip (60,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_fifteen_minute_set_1); + if (hours % 3 === 0 || j == numObs) { + threeHRprecip = calcIncrementalPrecip (180,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_fifteen_minute_set_1); + } else { + threeHRprecip = ''; + } + if (hours % 6 === 0 || j == numObs) { + sixHRprecip = calcIncrementalPrecip (360,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_fifteen_minute_set_1); + } else { + sixHRprecip = ''; + } + if (hours % 12 === 0 || j == numObs) { + oneDAYprecip = calcIncrementalPrecip (1440,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_fifteen_minute_set_1); + } else { + oneDAYprecip = ''; + } + var MIN_15_PCPN = ''; + } else { + var MIN_15_PCPN = ''; + } + } else { + if (pview == 'measured') { + var MIN_15_PCPN = ''; + } else { + var MIN_15_PCPN = ''; + } + } + } else { + var MIN_15_PCPN = ''; + } + // 30 Minute Precip + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('precip_accum_30_minute_set_1')) { + derived = 1; + has_precip = 1; + if (j == 0) { + plot_menu("thirty_min_pcpn","30 Minute Precip"); + if (pview == 'measured') { + EngHeader += ''; + MetHeader += ''; + } else { + EngHeader += ''; + MetHeader += ''; + } + } + if (DATA.STATION[0].OBSERVATIONS.precip_accum_30_minute_set_1[j] !== null) { + var thirtyMINprecip = (DATA.STATION[0].OBSERVATIONS.precip_accum_30_minute_set_1[j]).toFixed(2); + var oneHRprecip = ''; + var threeHRprecip = ''; + var sixHRprecip = ''; + var oneDAYprecip = ''; + if (pview == 'measured') { + var MIN_30_PCPN = ''; + } else if (pview == 'full') { + oneHRprecip = calcIncrementalPrecip (60,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_30_minute_set_1); + threeHRprecip = calcIncrementalPrecip (180,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_30_minute_set_1); + sixHRprecip = calcIncrementalPrecip (360,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_30_minute_set_1); + oneDAYprecip = calcIncrementalPrecip (1440,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_30_minute_set_1); + var MIN_30_PCPN = ''; + } else if (minutes == '00' || j == numObs) { + var oneHRprecip = calcIncrementalPrecip (60,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_30_minute_set_1); + if (hours % 3 === 0 || j == numObs) { + var threeHRprecip = calcIncrementalPrecip (180,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_30_minute_set_1); + } else { + var threeHRprecip = ''; + } + if (hours % 6 === 0 || j == numObs) { + var sixHRprecip = calcIncrementalPrecip (360,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_30_minute_set_1); + } else { + var sixHRprecip = ''; + } + if (hours % 12 === 0 || j == numObs) { + var oneDAYprecip = calcIncrementalPrecip (1440,j,stamps,DATA.STATION[0].OBSERVATIONS.precip_accum_30_minute_set_1); + } else { + var oneDAYprecip = ''; + } + var MIN_30_PCPN = ''; + } else { + var MIN_30_PCPN = ''; + } + } else { + if (pview == 'measured') { + var MIN_30_PCPN = ''; + } else { + var MIN_30_PCPN = ''; + } + } + } else { + var MIN_30_PCPN = ''; + } + } else { + var MIN_1_PCPN = ''; + var MIN_5_PCPN = ''; + var MIN_10_PCPN = ''; + var MIN_15_PCPN = ''; + var MIN_30_PCPN = ''; + } + // We have built out 1, 3, 6 and 24 hour precip data with the 1, 5, 10, 15, and 30 minute data + // As such, if we did not get any 1, 5, 10, 15, or 30 minute data, test for 1, 3, 6, and 24 hout data + if (derived == '0') { + // 1 Hour Precip + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('precip_accum_one_hour_set_1')) { + has_precip = 1; + if (j == 0) { + plot_menu("one_hour_pcpn","1 Hour Precip"); + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.precip_accum_one_hour_set_1[j] !== null) { + if (parseFloat(DATA.STATION[0].OBSERVATIONS.precip_accum_one_hour_set_1[j]) == '0.001' || parseFloat(DATA.STATION[0].OBSERVATIONS.precip_accum_one_hour_set_1[j]) == '0.005') { + var HR_1_PCPN = ''; + } else { + var HR_1_PCPN = ''; + } + } else { + var HR_1_PCPN = ''; + } + } else { + var HR_1_PCPN = ''; + } + // 3 Hour Precip + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('precip_accum_three_hour_set_1')) { + has_precip = 1; + if (j == 0) { + plot_menu("three_hour_pcpn","3 Hour Precip"); + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.precip_accum_three_hour_set_1[j] !== null) { + if (parseFloat(DATA.STATION[0].OBSERVATIONS.precip_accum_three_hour_set_1[j]) == '0.001' || parseFloat(DATA.STATION[0].OBSERVATIONS.precip_accum_three_hour_set_1[j]) == '0.005') { + var HR_3_PCPN = ''; + } else { + var HR_3_PCPN = ''; + } + } else { + var HR_3_PCPN = ''; + } + } else { + var HR_3_PCPN = ''; + } + // 6 Hour Precip + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('precip_accum_six_hour_set_1')) { + has_precip = 1; + if (j == 0) { + plot_menu("six_hour_pcpn","6 Hour Precip"); + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.precip_accum_six_hour_set_1[j] !== null) { + if (parseFloat(DATA.STATION[0].OBSERVATIONS.precip_accum_six_hour_set_1[j]) == '0.001' || parseFloat(DATA.STATION[0].OBSERVATIONS.precip_accum_six_hour_set_1[j]) == '0.005') { + var HR_6_PCPN = ''; + } else { + var HR_6_PCPN = ''; + } + } else { + var HR_6_PCPN = ''; + } + } else { + var HR_6_PCPN = ''; + } + // 24 Hour Precip + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('precip_accum_24_hour_set_1')) { + has_precip = 1; + if (j == 0) { + plot_menu("twentyfour_hour_pcpn","24 Hour Precip"); + EngHeader += ''; + MetHeader += ''; + + } + if (DATA.STATION[0].OBSERVATIONS.precip_accum_24_hour_set_1[j] !== null) { + if (parseFloat(DATA.STATION[0].OBSERVATIONS.precip_accum_24_hour_set_1[j]) == '0.001' || parseFloat(DATA.STATION[0].OBSERVATIONS.precip_accum_24_hour_set_1[j]) == '0.005') { + var HR_24_PCPN = ''; + } else { + var HR_24_PCPN = ''; + } + } else { + var HR_24_PCPN = ''; + } + } else { + var HR_24_PCPN = ''; + } + } else { + var HR_1_PCPN = ''; + var HR_3_PCPN = ''; + var HR_6_PCPN = ''; + var HR_24_PCPN = ''; + } + // Precip since Midnight + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('precip_accum_since_local_midnight_set_1')) { + has_precip = 1; + if (j == 0) { + plot_menu("sincemid_pcpn","Precip since Midnight"); + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.precip_accum_since_local_midnight_set_1[j] !== null) { + var MIDNIGHT = ''; + } else { + var MIDNIGHT = ''; + } + } else { + var MIDNIGHT = ''; + } + // Precip since Midnight + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('precip_interval_set_1')) { + has_precip = 1; + if (j == 0) { + plot_menu("sincemid_pcpn","Precip Interval"); + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.precip_interval_set_1[j] !== null) { + var PRECIPINT = ''; + } else { + var PRECIPINT = ''; + } + } else { + var PRECIPINT = ''; + } + // Snow Depth + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('snow_depth_set_1')) { + if (j == 0) { + plot_menu("snow_depth","Snow Depth"); + if (pview == 'measured') { + EngHeader += ''; + MetHeader += ''; + } else { + EngHeader += ''; + MetHeader += 'Snowfall
3 hour
(mm)
'; + } + } + var curSnow = ''; + if (DATA.STATION[0].OBSERVATIONS.snow_depth_set_1[j] !== null) { + curSnow = (DATA.STATION[0].OBSERVATIONS.snow_depth_set_1[j]).toFixed(1); + var threeHRsnow = ''; + var sixHRsnow = '' + var oneDAYsnow = '' + if (pview == 'measured') { + threeHRsnow = ''; + sixHRsnow = '' + oneDAYsnow = '' + } else if (pview == 'full') { + threeHRsnow = getDerivedSnow(180,j,stamps,DATA.STATION[0].OBSERVATIONS.snow_depth_set_1); + sixHRsnow = getDerivedSnow(360,j,stamps,DATA.STATION[0].OBSERVATIONS.snow_depth_set_1); + oneDAYsnow = getDerivedSnow(1440,j,stamps,DATA.STATION[0].OBSERVATIONS.snow_depth_set_1); + } else if (minutes == '00' || j == numObs) { + if (hours % 3 === 0 || j == numObs) { + threeHRsnow = getDerivedSnow(180,j,stamps,DATA.STATION[0].OBSERVATIONS.snow_depth_set_1); + } + if (hours % 6 === 0 || j == numObs) { + sixHRsnow = getDerivedSnow(360,j,stamps,DATA.STATION[0].OBSERVATIONS.snow_depth_set_1); + } + if (hours % 12 === 0 || j == numObs) { + oneDAYsnow = getDerivedSnow(1440,j,stamps,DATA.STATION[0].OBSERVATIONS.snow_depth_set_1); + } + } + } + if (curSnow === undefined || DATA.STATION[0].OBSERVATIONS.snow_depth_set_1[j] === null) { + curSnow = ''; + } + if (threeHRsnow === undefined) { + threeHRsnow = ''; + } + if (sixHRsnow === undefined) { + sixHRsnow = ''; + } + if (oneDAYsnow === undefined) { + oneDAYsnow = ''; + } + if (pview == 'measured') { + var SNOW_DEPTH = ''; + } else { + var SNOW_DEPTH = ''; + } + } else { + var SNOW_DEPTH = ''; + } + // Snow Interval + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('snow_interval_set_1')) { + if (j == 0) { + plot_menu("snow_interval","Snow Interval"); + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.snow_interval_set_1[j] !== null) { + var SNOW_INTERVAL = ''; + } else { + var SNOW_INTERVAL = ''; + } + } else { + var SNOW_INTERVAL = ''; + } + var SNOW_HR_24 = ''; + // Snow Interval + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('snow_accum_set_1')) { + if (j == 0) { + plot_menu("snow_accum","Snow Interval"); + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.snow_accum_set_1[j] !== null) { + var SNOW_ACCUM = ''; + } else { + var SNOW_ACCUM = ''; + } + } else { + var SNOW_ACCUM = ''; + } + var SNOW_HR_24 = ''; + // Snow Water Equivalent + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('snow_water_equiv_set_1')) { + if (j == 0) { + plot_menu("snow_water","Snow Water Equivalent"); + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.snow_water_equiv_set_1[j] !== null) { + var SWE = ''; + } else { + var SWE = ''; + } + } else { + var SWE = ''; + } + // Snow Water Equivalent + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('snow_water_equiv_set_2')) { + if (j == 0) { + plot_menu("snow_water2","Daily Snow Water Equivalent"); + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.snow_water_equiv_set_2[j] !== null) { + var SWE2 = ''; + } else { + var SWE2 = ''; + } + } else { + var SWE2 = ''; + } + // 6 Hour Max T + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('air_temp_high_6_hour_set_1')) { + if (j == 0) { + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.air_temp_high_6_hour_set_1[j] !== null) { + var HR6_MAXT = ''; + } else { + var HR6_MAXT = ''; + } + } else { + var HR6_MAXT = ''; + } + // 6 Hour Min T + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('air_temp_low_6_hour_set_1')) { + if (j == 0) { + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.air_temp_low_6_hour_set_1[j] !== null) { + var HR6_MINT = ''; + } else { + var HR6_MINT = ''; + } + } else { + var HR6_MINT = ''; + } + // 24 Hour Max T + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('air_temp_high_24_hour_set_1')) { + if (j == 0) { + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.air_temp_high_24_hour_set_1[j] !== null) { + var HR24_MAXT = ''; + } else { + var HR24_MAXT = ''; + } + } else { + var HR24_MAXT = ''; + } + // 24 Hour Min T + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('air_temp_low_24_hour_set_1')) { + if (j == 0) { + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.air_temp_low_24_hour_set_1[j] !== null) { + var HR24_MINT = ''; + } else { + var HR24_MINT = ''; + } + } else { + var HR24_MINT = ''; + } + // Water Temperature + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('T_water_temp_set_1')) { + if (j == 0) { + plot_menu("water_temp","Water Temperature"); + EngHeader += ''; + MetHeader += ''; + } + if (DATA.STATION[0].OBSERVATIONS.T_water_temp_set_1[j] !== null) { + var WATER_T = ''; + } else { + var WATER_T = ''; + } + } else { + var WATER_T = ''; + } + // Append one row of data to the stream + // If the 'Hourly' flag is set to true, post only data between a range of 51 minutes past the hour to 4 minutes after. This should catch most stuff + if (hourly == 'true') { + if (network == 'ASOS/AWOS') { + // Actual ASOS/AWOS Sites report sea level pressure in "official" obs (METAR/SPECI) + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('sea_level_pressure_set_1')) { + if (DATA.STATION[0].OBSERVATIONS.sea_level_pressure_set_1[j] !== null) { + tableData += ''+TEMP_F+DEWPOINT+RH_PCT+HI+WC+WIND_DIR+WIND_SPD+WIND_GUST+FUEL_T+FUEL_PCT+VISIBILITY+WEATHER+SKY_COND+SEALEVEL+P+ALTIMTER+STATION_P+SOLAR+SOLAR_PCT+SURF_T+SOIL_T+ROAD_T+SROAD_T+ACC_PCPN+MIN_1_PCPN+MIN_5_PCPN+MIN_10_PCPN+MIN_15_PCPN+MIN_30_PCPN+HR_1_PCPN+HR_3_PCPN+HR_6_PCPN+HR_24_PCPN+MIDNIGHT+PRECIPINT+SNOW_DEPTH+SNOW_INTERVAL+SNOW_ACCUM+SNOW_HR_24+SWE+SWE2+HR6_MAXT+HR6_MINT+HR24_MAXT+HR24_MINT+WATER_T+''; + // METARS + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('metar_set_1')) { + if (DATA.STATION[0].OBSERVATIONS.metar_set_1[j] !== null) { + METARString += ''; + } else { + METARString += ''; + } + } + // SPECI + } else if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('metar_set_1')) { + if (DATA.STATION[0].OBSERVATIONS.metar_set_1[j] !== null) { + if (DATA.STATION[0].OBSERVATIONS.metar_set_1[j].toUpperCase().startsWith(SITE)) { + tableData += ''+TEMP_F+DEWPOINT+RH_PCT+HI+WC+WIND_DIR+WIND_SPD+WIND_GUST+FUEL_T+FUEL_PCT+VISIBILITY+WEATHER+SKY_COND+SEALEVEL+P+ALTIMTER+STATION_P+SOLAR+SOLAR_PCT+SURF_T+SOIL_T+ROAD_T+SROAD_T+ACC_PCPN+MIN_1_PCPN+MIN_5_PCPN+MIN_10_PCPN+MIN_15_PCPN+MIN_30_PCPN+HR_1_PCPN+HR_3_PCPN+HR_6_PCPN+HR_24_PCPN+MIDNIGHT+PRECIPINT+SNOW_DEPTH+SNOW_INTERVAL+SNOW_ACCUM+SNOW_HR_24+SWE+SWE2+HR6_MAXT+HR6_MINT+HR24_MAXT+HR24_MINT+WATER_T+''; + METARString += ''; + } + } else { + tableData += ''; + METARString += ''; + } + } else { + tableData += ''; + METARString += ''; + } + // Non fed sites + } else { + if (minutes.toString() == '51' || minutes.toString() == '52' || minutes.toString() == '53' || minutes.toString() == '54' || minutes.toString() == '55' || minutes.toString() == '56' || minutes.toString() == '57' || minutes.toString() == '58' || minutes.toString() == '59') { + tableData += ''+TEMP_F+DEWPOINT+RH_PCT+HI+WC+WIND_DIR+WIND_SPD+WIND_GUST+FUEL_T+FUEL_PCT+VISIBILITY+WEATHER+SKY_COND+SEALEVEL+P+ALTIMTER+STATION_P+SOLAR+SOLAR_PCT+SURF_T+SOIL_T+ROAD_T+SROAD_T+ACC_PCPN+MIN_1_PCPN+MIN_5_PCPN+MIN_10_PCPN+MIN_15_PCPN+MIN_30_PCPN+HR_1_PCPN+HR_3_PCPN+HR_6_PCPN+HR_24_PCPN+MIDNIGHT+PRECIPINT+SNOW_DEPTH+SNOW_INTERVAL+SNOW_ACCUM+SNOW_HR_24+SWE+SWE2+HR6_MAXT+HR6_MINT+HR24_MAXT+HR24_MINT+WATER_T+''; + METARString += ''; + } else { + tableData += ''; + METARString += ''; + } + } + } else if (minutes.toString() == '00' || minutes.toString() == '01' || minutes.toString() == '02' || minutes.toString() == '03' || minutes.toString() == '04' || minutes.toString() == '56' || minutes.toString() == '57' || minutes.toString() == '58' || minutes.toString() == '59') { + tableData += ''+TEMP_F+DEWPOINT+RH_PCT+HI+WC+WIND_DIR+WIND_SPD+WIND_GUST+FUEL_T+FUEL_PCT+VISIBILITY+WEATHER+SKY_COND+SEALEVEL+P+ALTIMTER+STATION_P+SOLAR+SOLAR_PCT+SURF_T+SOIL_T+ROAD_T+SROAD_T+ACC_PCPN+MIN_1_PCPN+MIN_5_PCPN+MIN_10_PCPN+MIN_15_PCPN+MIN_30_PCPN+HR_1_PCPN+HR_3_PCPN+HR_6_PCPN+HR_24_PCPN+MIDNIGHT+PRECIPINT+SNOW_DEPTH+SNOW_INTERVAL+SNOW_ACCUM+SNOW_HR_24+SWE+SWE2+HR6_MAXT+HR6_MINT+HR24_MAXT+HR24_MINT+WATER_T+''; + } else if (numHours >= numObs) { + tableData += ''+TEMP_F+DEWPOINT+RH_PCT+HI+WC+WIND_DIR+WIND_SPD+WIND_GUST+FUEL_T+FUEL_PCT+VISIBILITY+WEATHER+SKY_COND+SEALEVEL+P+ALTIMTER+STATION_P+SOLAR+SOLAR_PCT+SURF_T+SOIL_T+ROAD_T+SROAD_T+ACC_PCPN+MIN_1_PCPN+MIN_5_PCPN+MIN_10_PCPN+MIN_15_PCPN+MIN_30_PCPN+HR_1_PCPN+HR_3_PCPN+HR_6_PCPN+HR_24_PCPN+MIDNIGHT+PRECIPINT+SNOW_DEPTH+SNOW_INTERVAL+SNOW_ACCUM+SNOW_HR_24+SWE+SWE2+HR6_MAXT+HR6_MINT+HR24_MAXT+HR24_MINT+WATER_T+''; + } else { + tableData += ''; + } + } else if (hourly == 'false') { + // METARS + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('metar_set_1')) { + if (DATA.STATION[0].OBSERVATIONS.metar_set_1[j] !== null) { + METARString += ''; + } else { + METARString += ''; + } + } + tableData += ''+TEMP_F+DEWPOINT+RH_PCT+HI+WC+WIND_DIR+WIND_SPD+WIND_GUST+FUEL_T+FUEL_PCT+VISIBILITY+WEATHER+SKY_COND+SEALEVEL+P+ALTIMTER+STATION_P+SOLAR+SOLAR_PCT+SURF_T+SOIL_T+ROAD_T+SROAD_T+ACC_PCPN+MIN_1_PCPN+MIN_5_PCPN+MIN_10_PCPN+MIN_15_PCPN+MIN_30_PCPN+HR_1_PCPN+HR_3_PCPN+HR_6_PCPN+HR_24_PCPN+MIDNIGHT+PRECIPINT+SNOW_DEPTH+SNOW_INTERVAL+SNOW_ACCUM+SNOW_HR_24+SWE+SWE2+HR6_MAXT+HR6_MINT+HR24_MAXT+HR24_MINT+WATER_T+''; + } + } // Successful return of data + if (cwa !== null) { + var officeLink = ' - '+cwa+''; + var selectedObs = '
For selected observations near this location: click here

 ' + } else { + var officeLink = ''; + var selectedObs = ''; + } + if (headers == 'none') { + var header0 = ''; + var CSS = ''; + var divToWrite = '.content'; + } else if (headers == 'min') { + var header0 = '

Weather conditions for:
'+stnNAM+', '+ state +' ('+NETWORK+officeLink+')
Elev: '+stnELE+' ft; Lat/Lon: '+stnLAT+'/'+stnLON+'

'; + var CSS = ''; + var divToWrite = '.content'; + } else { + if (has_precip == 1 || network == 'ASOS/AWOS') { + var header0 = '

Weather conditions for:
'+stnNAM+', '+ state +' ('+NETWORK+officeLink+')
Elev: '+stnELE+' ft; Lat/Lon: '+stnLAT+'/'+stnLON+'

Get Yearly Precip Total (non QA/QC\'d data)
Get Water Year Precip Total (non QA/QC\'d data):
'+selectedObs; + var CSS = ''; + var divToWrite = '#OBS'; + } else { + var header0 = '

Weather conditions for:
'+stnNAM+', '+ state +' ('+NETWORK+officeLink+')
Elev: '+stnELE+' ft; Lat/Lon: '+stnLAT+'/'+stnLON+'
 

'+selectedObs; + var CSS = ''; + var divToWrite = '#OBS'; + } + } + if (format == 'raw' && network == 'ASOS/AWOS') { + $(divToWrite).html(CSS+ header0 + EngHeader + METARString+'
Temp.
 
(°F)
Temp.
 
(°C)
'+Math.round(DATA.STATION[0].OBSERVATIONS.air_temp_set_1[j])+' Dew
Point
(°F)
Dew
Point
(°C)
'+Math.round(DATA.STATION[0].OBSERVATIONS.dew_point_temperature_set_1d[j])+' Relative
Humidity
(%)
Relative
Humidity
(%)
'+Math.round(DATA.STATION[0].OBSERVATIONS.relative_humidity_set_1[j])+' Heat
Index
(°F)
Heat
Index
(°C)
'+Math.round(DATA.STATION[0].OBSERVATIONS.heat_index_set_1d[j])+' Wind
Chill
(°F)
Wind
Chill
(°C)
'+Math.round(DATA.STATION[0].OBSERVATIONS.wind_chill_set_1d[j])+' Wind
Direction
 
Wind
Direction
 
'+Wind_DIR+' Wind
Speed
(mph)
Wind
Speed
(kts)
Wind
Speed
(kph)
'+WIND_SPD; + } else if (WIND_SPD < 40 ) { + WIND_SPD = ''+WIND_SPD+''; + } else if (WIND_SPD < 58 ) { + WIND_SPD = ''+WIND_SPD+''; + } else { + WIND_SPD = ''+WIND_SPD+''; + } + } else { + var WIND_SPD = Math.round((DATA.STATION[0].OBSERVATIONS.wind_speed_set_1[j])*3.6); + if (WIND_SPD < 32 ) { + WIND_SPD = ''+WIND_SPD; + } else if (WIND_SPD < 64 ) { + WIND_SPD = ''+WIND_SPD+''; + } else if (WIND_SPD < 93 ) { + WIND_SPD = ''+WIND_SPD+''; + } else { + WIND_SPD = ''+WIND_SPD+''; + } + } + } else { + var WIND_SPD = ' '; + } + if (DATA.STATION[0].OBSERVATIONS.hasOwnProperty('wind_gust_set_1')) { + if (DATA.STATION[0].OBSERVATIONS.wind_gust_set_1[j] !== null) { + if (units == 'english' || units == 'english_k') { + var WIND_GST =Math.round(DATA.STATION[0].OBSERVATIONS.wind_gust_set_1[j]); + if (WIND_GST < 11 ) { + WIND_SPD += 'G'+WIND_GST+'Wind
Gust
(mph)
Wind
Gust
(kph)
'+WIND_GST+''+WIND_GST+''+WIND_GST+'G'+WIND_GST+''+WIND_GST+''+WIND_GST+''+WIND_GST+'G'+WIND_GST+' Fuel
Temp.
(°F)
Fuel
Temp.
(°F)
'+Math.round(DATA.STATION[0].OBSERVATIONS.fuel_temp_set_1[j])+' Fuel
Moisture
(%)
Fuel
Moisture
(%)
'+Math.round(DATA.STATION[0].OBSERVATIONS.fuel_moisture_set_1[j])+' Visibility
 
(miles)
Visibility
 
(km)
'+VISIBILITY.replace('-','< ')+''+VISIBILITY+''+Math.round(VISIBILITY)+''+Math.round(VISIBILITY)+''+VISIBILITY.replace('-','< ')+''+VISIBILITY+''+VISIBILITY+''+VISIBILITY+' Weather
 
 
Weather
 
 
'+WX_ELEM3+' '+WX_ELEM2+' '+WX_ELEM1+''+(DATA.STATION[0].OBSERVATIONS.weather_condition_set_1d[j])+'  Clouds
 
(x100 ft)
Clouds
 
(x100 ft)
'+LAYER1+' '+LAYER2+' '+LAYER3+'Sea Level
Pressure
(mb)
Sea Level
Pressure
(mb)
'+((DATA.STATION[0].OBSERVATIONS.sea_level_pressure_set_1[j])/100).toFixed(2)+''+(DATA.STATION[0].OBSERVATIONS.sea_level_pressure_set_1[j]).toFixed(2)+' Sea Level
Pressure
(mb)
Sea Level
Pressure
(mb)
'+((DATA.STATION[0].OBSERVATIONS.sea_level_pressure_set_1d[j])/100).toFixed(2)+''+(DATA.STATION[0].OBSERVATIONS.sea_level_pressure_set_1d[j]).toFixed(2)+' Station
Pressure
(in Hg)
Station
Pressure
(mb)
'+((DATA.STATION[0].OBSERVATIONS.pressure_set_1[j])/100).toFixed(2)+''+(DATA.STATION[0].OBSERVATIONS.pressure_set_1[j]).toFixed(2)+''+((DATA.STATION[0].OBSERVATIONS.pressure_set_1[j])/33.684).toFixed(2)+' Station
Pressure
(in Hg)
Station
Pressure
(mb)
Altimeter
Setting
(in Hg)
Altimeter
Setting
(mb)
'+(stationP/100).toFixed(2)+''+((DATA.STATION[0].OBSERVATIONS.altimeter_set_1[j])/100).toFixed(2)+''+((DATA.STATION[0].OBSERVATIONS.altimeter_set_1[j])/100).toFixed(2)+''+stationP+''+(DATA.STATION[0].OBSERVATIONS.altimeter_set_1[j]).toFixed(2)+''+(DATA.STATION[0].OBSERVATIONS.altimeter_set_1[j]).toFixed(2)+'   Station
Pressure
(in Hg)
Station
Pressure
(mb)
'+((DATA.STATION[0].OBSERVATIONS.station_pressure_set_1[j])/100).toFixed(2)+''+(DATA.STATION[0].OBSERVATIONS.station_pressure_set_1[j]).toFixed(2)+' Solar
Radiation
(W/m²)
Percent
Possible
(%)
Solar
Radiation
(W/m²)
Percent
Possible
(%)
'+RAW_SOLAR+''+PCT+' %0--  Surface
Temp.
(°F)
Surface
Temp.
(°C)
'+Math.round(DATA.STATION[0].OBSERVATIONS.surface_temp_set_1[j])+' Soil
Temp.
(°F)
Soil
Temp.
(°C)
'+Math.round(DATA.STATION[0].OBSERVATIONS.soil_temp_set_1[j])+' Road
Temp.
(°F)
Road
Temp.
(°C)
'+Math.round(DATA.STATION[0].OBSERVATIONS.road_temp_set_1[j])+' Road
Temp.
(°F)
Road
Temp.
(°C)
'+Math.round(DATA.STATION[0].OBSERVATIONS.road_temp_set_2[j])+' Road
Temp.
(°F)
Road
Temp.
(°C)
'+Math.round(DATA.STATION[0].OBSERVATIONS.road_subsurface_tmp_set_1[j])+' Accumulated
Precip
(in)
Accumulated
Precip
(mm)
Accumulated
Precip
(in)
1 Hour
Precip
(in)
3 Hour
Precip
(in)
6 Hour
Precip
(in)
24 Hour
Precip
(in)
Accumulated
Precip
(mm)
1 Hour
Precip
(mm)
3 Hour
Precip
(mm)
6 Hour
Precip
(mm)
24 Hour
Precip
(mm)
'+ACC_Precip+''+ACC_Precip+''+oneHRprecip+''+threeHRprecip+''+sixHRprecip+''+oneDAYprecip+''+ACC_Precip+''+oneHRprecip+''+threeHRprecip+''+sixHRprecip+''+oneDAYprecip+''+ACC_Precip+''+oneHRprecip+''+threeHRprecip+''+sixHRprecip+''+oneDAYprecip+'      1 Min.
Precip
(in)
1 Min.
Precip
(mm)
1 Min.
Precip
(in)
1 Hour
Precip
(in)
3 Hour
Precip
(in)
6 Hour
Precip
(in)
24 Hour
Precip
(in)
1 Min.
Precip
(mm)
1 Hour
Precip
(mm)
3 Hour
Precip
(mm)
6 Hour
Precip
(mm)
24 Hour
Precip
(mm)
'+oneMINprecip+''+oneMINprecip+''+oneHRprecip+''+threeHRprecip+''+sixHRprecip+''+oneDAYprecip+''+oneMINprecip+''+oneHRprecip+''+threeHRprecip+''+sixHRprecip+''+oneDAYprecip+''+oneMINprecip+'          5 Min.
Precip
(in)
5 Min.
Precip
(mm)
5 Min.
Precip
(in)
1 Hour
Precip
(in)
3 Hour
Precip
(in)
6 Hour
Precip
(in)
24 Hour
Precip
(in)
5 Min.
Precip
(mm)
1 Hour
Precip
(mm)
3 Hour
Precip
(mm)
6 Hour
Precip
(mm)
24 Hour
Precip
(mm)
'+fiveMINprecip+''+fiveMINprecip+''+oneHRprecip+''+threeHRprecip+''+sixHRprecip+''+oneDAYprecip+''+fiveMINprecip+''+oneHRprecip+''+threeHRprecip+''+sixHRprecip+''+oneDAYprecip+''+fiveMINprecip+'          10 Min.
Precip
(in)
10 Min.
Precip
(mm)
10 Min.
Precip
(in)
1 Hour
Precip
(in)
3 Hour
Precip
(in)
6 Hour
Precip
(in)
24 Hour
Precip
(in)
10 Min.
Precip
(mm)
1 Hour
Precip
(mm)
3 Hour
Precip
(mm)
6 Hour
Precip
(mm)
24 Hour
Precip
(mm)
'+tenMINprecip+''+tenMINprecip+''+oneHRprecip+''+threeHRprecip+''+sixHRprecip+''+oneDAYprecip+''+tenMINprecip+''+oneHRprecip+''+threeHRprecip+''+sixHRprecip+''+oneDAYprecip+''+tenMINprecip+'          15 Min.
Precip
(in)
15 Min.
Precip
(mm)
15 Min.
Precip
(in)
1 Hour
Precip
(in)
3 Hour
Precip
(in)
6 Hour
Precip
(in)
24 Hour
Precip
(in)
15 Min.
Precip
(mm)
1 Hour
Precip
(mm)
3 Hour
Precip
(mm)
6 Hour
Precip
(mm)
24 Hour
Precip
(mm)
'+fifteenMINprecip+''+fifteenMINprecip+''+oneHRprecip+''+threeHRprecip+''+sixHRprecip+''+oneDAYprecip+''+fifteenMINprecip+''+oneHRprecip+''+threeHRprecip+''+sixHRprecip+''+oneDAYprecip+''+fifteenMINprecip+'          30 Min.
Precip
(in)
30 Min.
Precip
(mm)
30 Min.
Precip
(in)
1 Hour
Precip
(in)
3 Hour
Precip
(in)
6 Hour
Precip
(in)
24 Hour
Precip
(in)
30 Min.
Precip
(mm)
1 Hour
Precip
(mm)
3 Hour
Precip
(mm)
6 Hour
Precip
(mm)
24 Hour
Precip
(mm)
'+thirtyMINprecip+''+thirtyMINprecip+''+oneHRprecip+''+threeHRprecip+''+sixHRprecip+''+oneDAYprecip+''+thirtyMINprecip+''+oneHRprecip+''+threeHRprecip+''+sixHRprecip+''+oneDAYprecip+''+(DATA.STATION[0].OBSERVATIONS.precip_accum_30_minute_set_1[j]).toFixed(2)+'          1 Hour
Precip
(in)
1 Hour
Precip
(mm)
T'+(DATA.STATION[0].OBSERVATIONS.precip_accum_one_hour_set_1[j]).toFixed(2)+' 3 Hour
Precip
(in)
3 Hour
Precip
(mm)
T'+(DATA.STATION[0].OBSERVATIONS.precip_accum_three_hour_set_1[j]).toFixed(2)+' 6 Hour
Precip
(in)
6 Hour
Precip
(mm)
T'+(DATA.STATION[0].OBSERVATIONS.precip_accum_six_hour_set_1[j]).toFixed(2)+' 24 Hour
Precip
(in)
24 Hour
Precip
(mm)
T'+(DATA.STATION[0].OBSERVATIONS.precip_accum_24_hour_set_1[j]).toFixed(2)+' Precip
Since 12am
(in)
Precip
Since 12am
(mm)
'+(DATA.STATION[0].OBSERVATIONS.precip_accum_since_local_midnight_set_1[j]).toFixed(2)+' Precip
Interval
(in)
Precip
Interval
(mm)
'+(DATA.STATION[0].OBSERVATIONS.precip_interval_set_1[j]).toFixed(2)+' Snow
Depth
(in)
Snow
Depth
(mm)
Snow
Depth
(in)
Snowfall
3 hour
(in)
Snowfall
6 Hour
(in)
Snowfall
24 Hour
(in)
Snow
Depth
(mm)
Snowfall
6 Hour
(mm)
Snowfall
24 Hour
(mm)
'+curSnow+''+curSnow+''+threeHRsnow+''+sixHRsnow+''+oneDAYsnow+'Snow
Interval
(in)
Snow
Interval
(mm)
'+(DATA.STATION[0].OBSERVATIONS.snow_interval_set_1[j]).toFixed(1)+' Snow
Interval
(in)
Snow
Interval
(mm)
'+(DATA.STATION[0].OBSERVATIONS.snow_accum_set_1[j]).toFixed(1)+' Snow/Water
Equivalent
(in)
Snow/Water
Equivalent
(mm)
'+(DATA.STATION[0].OBSERVATIONS.snow_water_equiv_set_1[j]).toFixed(2)+' Daily
SWE
(in)
Daily
SWE
(mm)
'+(DATA.STATION[0].OBSERVATIONS.snow_water_equiv_set_2[j]).toFixed(2)+' 6 Hr
Max
(°F)
6 Hr
Max
(°C)
'+Math.round(DATA.STATION[0].OBSERVATIONS.air_temp_high_6_hour_set_1[j])+' 6 Hr
Min
(°F)
6 Hr
Min
(°C)
'+Math.round(DATA.STATION[0].OBSERVATIONS.air_temp_low_6_hour_set_1[j])+' 24 Hr
Max
(°F)
24 Hr
Max
(°C)
'+Math.round(DATA.STATION[0].OBSERVATIONS.air_temp_high_24_hour_set_1[j])+' 24 Hr
Min
(°F)
24 Hr
Min
(°C)
'+Math.round(DATA.STATION[0].OBSERVATIONS.air_temp_low_24_hour_set_1[j])+' Water
Temp.
(°F)
Water
Temp.
(°C)
'+Math.round(DATA.STATION[0].OBSERVATIONS.T_water_temp_set_1[j])+' 
'+timestamp+'
'+DATA.STATION[0].OBSERVATIONS.metar_set_1[j]+'
'+timestamp+'
SPECI '+DATA.STATION[0].OBSERVATIONS.metar_set_1[j]+'
'+timestamp+'
'+DATA.STATION[0].OBSERVATIONS.metar_set_1[j]+'
'+timestamp+'
'+timestamp+'
'+DATA.STATION[0].OBSERVATIONS.metar_set_1[j]+'
'+timestamp+'
'); + $('#HEADER').hide(); + } else if (units == 'english' || units == 'english_k') { + $(divToWrite).html(CSS+ header0 + EngHeader +'' + tableData+''); + $('#HEADER').show(); + } else { + $(divToWrite).html(CSS+ header0 + MetHeader +'' + tableData+''); + $('#HEADER').show(); + } + //if (fontSize !== undefined || fontSize != '12') { + // $('#OBS_DATA').css({'font-size': fontSize}); + //resizePage(); + //} else { + // resizePage(); + //} + if (chart == 'on') { + var DATA1 = ''; + var DATA2 = ''; + var DATA3 = ''; + var chartLabel = ''; + if (DATA.STATION[0].OBSERVATIONS.air_temp_set_1) { + var chartBit = '1'; + DATA1 = DATA.STATION[0].OBSERVATIONS.air_temp_set_1; + chartLabel += 'Temperature'; + } + if (DATA.STATION[0].OBSERVATIONS.dew_point_temperature_set_1d) { + DATA2 = DATA.STATION[0].OBSERVATIONS.dew_point_temperature_set_1d; + if (chartLabel) { + chartLabel += '& Dew Point'; + } else { + chartLabel += 'Dew Point'; + } + } + if (DATA.STATION[0].OBSERVATIONS.relative_humidity_set_1) { + DATA3 = DATA.STATION[0].OBSERVATIONS.relative_humidity_set_1 + if (chartLabel) { + chartLabel += '& Relative Humidity'; + } else { + chartLabel += 'Relative Humidity'; + } + } + if (DATA.STATION[0].OBSERVATIONS.sea_level_pressure_set_1) { + SLPData = DATA.STATION[0].OBSERVATIONS.sea_level_pressure_set_1; + } else { + SLPData = undefined; + } + if (plot) { + $('#'+plot).click(); + } else if (chartLabel) { + makeLineChart(''+stamps+'',''+DATA1+'',chartLabel,units,TIMEZONE,''+DATA2+'',''+DATA3+'',network,hourly,numHours,''+SLPData+''); + } else { + $('#container').hide(); + } + } + } else { + // Station has not reported in the specified number of hours + $('#container').hide(); + SITE = SITE.replace('COOP',''); + $('#OBS').html('

'+SITE +' has no data available for the requested time period

'); + } + resizePage(fontSize); + } else { //if (DATA.SUMMARY.RESPONSE_MESSAGE.substr(0,33) == 'No stations found for this request') { + // Maybe this is a COOP site, so let's check, just in case + if (SITE.toLowerCase().substr(0,4) != 'coop') { + monitorOBS('COOP'+SITE,numHours,units,format,headers,chart,hourly,history,start,end,pview,fontSize) + // Station ID not valid + } else { + $('#container').hide(); + SITE = SITE.replace('COOP',''); + $('#OBS').html('

'+SITE +' is not a valid station identifier.

'); + } + } + }) +} +///////////////////////////////////// +function plot_menu(in_id,in_string) { + var out_string=""; + $(".plot_select").append(out_string); + $(".perm_select").append(out_string); +} +$(function(){ + $('.plot_select').change(function(){ + $( "#" + $(this).val() ).trigger( "click" ); + }); +}); +///////////////////////////////////// +function getWeatherCode(WEATHER) { + // Documentation: https://blog.synopticlabs.org/blog/2016/09/26/weather-condition-codes.html + // Coloring from MesoWest: + // '/TS|SQ|FC/ $r_wx"; } + // '/RA|SN|GS|GR $r_wx"; } + // '/FG|FU|BS/ $r_wx"; } + // '/BR|HZ/ $r_wx"; } + if (WEATHER == -3) { + HTML = 'FC'; + DESC = 'Water Spout'; + } else if (WEATHER == -2) { + HTML = 'FC'; + DESC = 'Funnel Cloud'; + } else if (WEATHER == -1) { + HTML = 'FC'; + DESC = 'Tornado'; + } else if (WEATHER == 1) { + HTML = 'RA'; + DESC = 'Rain'; + } else if (WEATHER == 2) { + HTML = 'DZ'; + DESC = 'Drizzle'; + } else if (WEATHER == 3) { + HTML = 'SN'; + DESC = 'Snow'; + } else if (WEATHER == 4) { + HTML = 'GR'; + DESC = 'Hail'; + } else if (WEATHER == 5) { + HTML = 'TS'; + DESC = 'Thunder'; + } else if (WEATHER == 6) { + HTML = 'HZ'; + DESC = 'Haze'; + } else if (WEATHER == 7) { + HTML = 'FU'; + DESC = 'Smoke'; + } else if (WEATHER == 8) { + HTML = 'DU'; + DESC = 'Dust'; + } else if (WEATHER == 9) { + HTML = 'FG'; + DESC = 'Fog'; + } else if (WEATHER == 10) { + HTML = 'SQ'; + DESC = 'Squalls'; + } else if (WEATHER == 11) { + HTML = 'VA'; + DESC = 'Volcanic Ash'; + } else if (WEATHER == 13) { + HTML = '-RA'; + DESC = 'Lt rain'; + } else if (WEATHER == 14) { + HTML = '+RA'; + DESC = 'Hvy rain'; + } else if (WEATHER == 15) { + HTML = 'ZR'; + DESC = 'Freezing rain'; + } else if (WEATHER == 16) { + HTML = 'SH'; + DESC = 'Shwrs'; + } else if (WEATHER == 17) { + HTML = '-DZ'; + DESC = 'Lt drizzle'; + } else if (WEATHER == 18) { + HTML = '+DZ'; + DESC = 'Hvy drizzle'; + } else if (WEATHER == 19) { + HTML = 'FZDZ'; + DESC = 'Freezing drizzle'; + } else if (WEATHER == 20) { + HTML = '-SN'; + DESC = 'Lt snow'; + } else if (WEATHER == 21) { + HTML = '+SN'; + DESC = 'Hvy snow'; + } else if (WEATHER == 22) { + HTML = 'SN'; + DESC = 'Snow'; + } else if (WEATHER == 23) { + HTML = 'PL'; + DESC = 'Ice pellets'; + } else if (WEATHER == 24) { + HTML = 'SG'; + DESC = 'Snow grains'; + } else if (WEATHER == 25) { + HTML = 'GS'; + DESC = 'Snow pellets'; + } else if (WEATHER == 26) { + HTML = '-GR'; + DESC = 'Lt hail'; + } else if (WEATHER == 27) { + HTML = '+GR'; + DESC = 'Hvy hail'; + } else if (WEATHER == 28) { + HTML = '-TS'; + DESC = 'Lt thunderstorm'; + } else if (WEATHER == 29) { + HTML = '+TS'; + DESC = 'Hvy thunderstorm'; + } else if (WEATHER == 30) { + HTML = 'FZFG'; + DESC = 'Freezing Fog'; + } else if (WEATHER == 31) { + HTML = 'BR'; + DESC = 'Mist'; + } else if (WEATHER == 32) { + HTML = 'BLSN'; + DESC = 'Blowing snow'; + } else if (WEATHER == 33) { + HTML = 'BLDU'; + DESC = 'Blowing dust'; + } else if (WEATHER == 34) { + HTML = 'BLPY'; + DESC = 'Blowing spray'; + } else if (WEATHER == 35) { + HTML = 'BLSA'; + DESC = 'Blowing sand'; + } else if (WEATHER == 36) { + HTML = 'IC'; + DESC = 'Ice crystals'; + } else if (WEATHER == 37) { + HTML = 'IC'; + DESC = 'Ice needles'; + } else if (WEATHER == 38) { + HTML = '-GR'; + DESC = 'Lt hail'; + } else if (WEATHER == 39) { + HTML = 'FUHZ'; + DESC = 'Smoke, haze'; + } else if (WEATHER == 40) { + HTML = 'DU'; + DESC = 'Dust whirls'; + } else if (WEATHER == 41) { + HTML = 'UP'; + DESC = 'Unknown precipitation'; + } else if (WEATHER == 49) { + HTML = '-ZR'; + DESC = 'Lt freezing rain'; + } else if (WEATHER == 50) { + HTML = '+ZR'; + DESC = 'Heavy freezing rain'; + } else if (WEATHER == 51) { + HTML = '-SH'; + DESC = 'Lt shwrs'; + } else if (WEATHER == 52) { + HTML = '+SH'; + DESC = 'Hvy shwrs'; + } else if (WEATHER == 53) { + HTML = '-FZDZ'; + DESC = 'Lt freezing drizzle'; + } else if (WEATHER == 54) { + HTML = '+FZDZ'; + DESC = 'Hvy freezing drizzle'; + } else if (WEATHER == 55) { + HTML = '-SN'; + DESC = 'Lt snow'; + } else if (WEATHER == 56) { + HTML = '+SN'; + DESC = 'Hvy snow'; + } else if (WEATHER == 57) { + HTML = '-PL'; + DESC = 'Lt ice pellets'; + } else if (WEATHER == 58) { + HTML = '+PL'; + DESC = 'Hvy ice pellets'; + } else if (WEATHER == 59) { + HTML = '-SG'; + DESC = 'Lt snow grains'; + } else if (WEATHER == 60) { + HTML = '+SG'; + DESC = 'Heavy snow grains'; + } else if (WEATHER == 61) { + HTML = '-GS'; + DESC = 'Lt snow pellets'; + } else if (WEATHER == 62) { + HTML = '+GS'; + DESC = 'Hvy snow pellets'; + } else if (WEATHER == 63) { + HTML = 'PL'; + DESC = 'Ice pellets'; + } else if (WEATHER == 64) { + HTML = '-IC'; + DESC = 'Lt ice crystals'; + } else if (WEATHER == 65) { + HTML = '+IC'; + DESC = 'Hvy ice crystals'; + } else if (WEATHER == 66) { + HTML = 'TSRA'; + DESC = 'Thunder shwr'; + } else if (WEATHER == 67) { + HTML = 'GS'; + DESC = 'Snow pellets'; + } else if (WEATHER == 68) { + HTML = '+BLDU'; + DESC = 'Hvy blowing dust'; + } else if (WEATHER == 69) { + HTML = '+BLSA'; + DESC = 'Hvy blowing sand'; + } else if (WEATHER == 69) { + HTML = '+BLSN'; + DESC = 'Hvy blowing snow'; + } else if (WEATHER == 75) { + HTML = '-PL'; + DESC = 'Lt ice pellets'; + } else if (WEATHER == 76) { + HTML = '+PL'; + DESC = 'Hvy ice pellets'; + } else if (WEATHER == 77) { + HTML = '-TSRA'; + DESC = 'Lt thunder shwr'; + } else if (WEATHER == 78) { + HTML = '+TSRA'; + DESC = 'Hvy thunder shwr'; + } + return(DESC); +} + +// Not needed, but still here +function getWindDir(windDir) { + var cardDir = ''; + if (windDir < 22) { + cardDir = 'N'; + } else if (windDir < 68) { + cardDir = 'NE'; + } else if (windDir < 113) { + cardDir = 'E'; + } else if (windDir < 158) { + cardDir = 'SE'; + } else if (windDir < 203) { + cardDir = 'S'; + } else if (windDir < 248) { + cardDir = 'SW'; + } else if (windDir < 293) { + cardDir = 'W'; + } else if (windDir < 338) { + cardDir = 'NW'; + } else { + cardDir = 'N'; + } + return cardDir; +} + +// Not needed, but still here +function calcWindChill(TEMP,SPEED,SYS) { + if (TEMP != 'undefined' && SPEED != 'undefined') { + if (SYS == 'metric') { + TEMP = (TEMP*9/5) +32; + SPEED = (SPEED*2.237); + } + if (TEMP < 50 && SPEED > 3) { + var WC = (Math.round(35.74+0.6215*TEMP - 35.75 * Math.pow(SPEED,0.16) + 0.4275 * TEMP * Math.pow(SPEED,0.16)).toFixed(0)); + if (SYS == 'metric') { + WC = Math.round((WC-32)*5/9); + } + return (''+WC+''); + } else { + return (' '); + } + } else { + return (' '); + } +} + +// Old WRH Function +function calcSolarPCT(dattim,xlat,xlon) { + var utcMoment = moment.utc(dattim); + var d = new Date(utcMoment.format()); + var rd = new Date(utcMoment.format()); + rd.setHours(rd.getHours() - 1); + var hours = utcMoment.format("H"); + var minutes = d.getMinutes(); + minutes = minutes < 10 ? '0' + minutes : minutes; + var solpot = 0; + while (rd < d) { + var start = new Date(rd.getFullYear(), 0, 0); + var diff = rd - start; + var oneDay = 1000 * 60 * 60 * 24; + var julday = Math.floor(diff / oneDay) - 1; + var hr = rd.getHours(); + hr = utcMoment.format("H") - 1; + var min = rd.getMinutes(); + min = utcMoment.format('m'); + xt24 = hr + (min / 60.); + + var degrad = 0.017453293; + var dpd = 0.986301; + var solset = -999; + var sinob = Math.sin(23.5 * degrad); + var julian = (julday) + hr; + var xlong; + if (julian > 80.) { + xlong = dpd * (julian - 80.); + } else { + xlong = dpd * (julian + 285.); + } + xlong = xlong * degrad; + declin = Math.asin(sinob * Math.sin(xlong)); + decdeg = declin / degrad; + + djul = julian * 360. / 365.; + rjul = djul * degrad; + eccfac = 1.000110 + 0.034221 * Math.cos(rjul) + 0.00128 * Math.sin(rjul) + 0.000719 * Math.cos(2 * rjul) + 0.000077 * Math.sin(2 * rjul); + solcon = 1370. * eccfac; + tlocap = xt24 + (xlon / 15.); + omega = 15. * (tlocap - 12.) * degrad; + xxlat = xlat * degrad; + fracsc = Math.sin(declin) * Math.sin(xxlat) + Math.cos(declin) * Math.cos(xxlat) * Math.cos(omega); + solpot = solpot + (fracsc * solcon); + utcMoment.add(10, 'm'); + rd = new Date(rd.getTime() + 10 * 60000); + } + solpot = solpot / 6.; + if (solpot > 0) { + return(solpot.toFixed(0)); + } else { + return '--'; + } +} + +function makeLineChart(TIME,DATA0,LABEL,units,TIMEZONE,DATA1,DATA2,network,hourly,numHours,SLP) { + $('#container').show(); + var ARRAY0 = []; + var ARRAY1 = []; + var ARRAY2 = []; + var stamp = TIME; + var MAXVAL = -1000; + var MINVAL = 1000; + TIME = TIME.split(','); + DATA0 = DATA0.split(','); + if (DATA1) { + DATA1 = DATA1.split(','); + } + if (DATA2) { + DATA2 = DATA2.split(','); + } + if (SLP) { + SLP = SLP.split(','); + } + var numPoints = TIME.length; + if (hourly == 'true') { + var numObsPerHour = numPoints/numHours; + var numChartableObs = numPoints/numObsPerHour; + if (numChartableObs > 1000) { + var increment = Math.ceil(numPoints/numObsPerHour) + } else { + var increment = 1; + } + } else if (numPoints > 1000) { + var increment = Math.ceil(numPoints/1000); + } else { + var increment = 1; + } + console.log('We have '+numPoints+' pieces of time stamped'); + console.log('data to chart. After calculating the best ') + console.log('scenario, we are going to increment every'); + console.log(increment+ ' piece of data on the chart.'); + for (i=0; i < numPoints; i+=increment) { + var minutes = (moment(TIME[i]).tz(TIMEZONE).format('mm')).toString(); + //console.log(TIME[i]); + var tmpTimestamp = parseInt(moment(TIME[i]).format('x')); + if (LABEL == 'Temperature' || LABEL == 'Dew Point Temperature' || LABEL == 'Wind Chill' || LABEL == 'Fuel Temperature' || LABEL == 'Road Temperature' || LABEL == 'Subsurface Road Temperature' || LABEL == 'Water Temperature' || LABEL == 'Relative Humidity' || LABEL == 'Fuel Moisture' ||LABEL == 'Wind Speed & Gusts' || LABEL == 'Solar Radiation') { + var plotValue0 = Math.round(DATA0[i]); + if (plotValue0 >= MAXVAL) { + MAXVAL = plotValue0; + } + if (plotValue0 <= MINVAL) { + MINVAL = plotValue0; + } + if (LABEL == 'Wind Chill' && (Math.round(DATA0[i]) =='0')) { + var plotValue0 = null; + } + if (DATA1) { + var plotValue1 = Math.round(DATA1[i]); + if (plotValue1 >= MAXVAL) { + MAXVAL = plotValue1; + } + if (plotValue1 <= MINVAL) { + MINVAL = plotValue1; + } + if (LABEL == 'Wind Speed & Gusts' && (Math.round(DATA1[i]) =='0')) { + var plotValue1 = null; + } + } + if (DATA2) { + var plotValue2 = Math.round(DATA2[i]); + } + } else { + var plotValue0 = parseFloat(DATA0[i]); + if (plotValue0 >= MAXVAL) { + MAXVAL = plotValue0; + } + if (plotValue0 <= MINVAL) { + MINVAL = plotValue0; + } + if (DATA1) { + var plotValue1 = parseFloat(DATA1[i]); + if (plotValue1 >= MAXVAL) { + MAXVAL = plotValue1; + } + if (plotValue1 <= MINVAL) { + MINVAL = plotValue1; + } + } + if (DATA2) { + var plotValue2 = parseFloat(DATA2[i]); + } + } + if (hourly == 'true') { + if (network == 'ASOS/AWOS') { + if (SLP[i] !='') { + ARRAY0.push({ + x: tmpTimestamp, + y: plotValue0 + }) + if (DATA1) { + ARRAY1.push({ + x: tmpTimestamp, + y: plotValue1 + }) + } + if (DATA2) { + ARRAY2.push({ + x: tmpTimestamp, + y: plotValue2 + }) + } + } + } else if (minutes == '00' || minutes == '01' || minutes == '02' || minutes == '03' || minutes == '04' || minutes == '56' || minutes == '57' || minutes == '58' || minutes == '59') { + ARRAY0.push({ + x: tmpTimestamp, + y: plotValue0 + }) + if (DATA1) { + ARRAY1.push({ + x: tmpTimestamp, + y: plotValue1 + }) + } + if (DATA2) { + ARRAY2.push({ + x: tmpTimestamp, + y: plotValue2 + }) + } + } else if (numHours >= numPoints) { + ARRAY0.push({ + x: tmpTimestamp, + y: plotValue0 + }) + if (DATA1) { + ARRAY1.push({ + x: tmpTimestamp, + y: plotValue1 + }) + } + if (DATA2) { + ARRAY2.push({ + x: tmpTimestamp, + y: plotValue2 + }) + } + } else { + ARRAY0=ARRAY0; + ARRAY1=ARRAY1; + ARRAY2=ARRAY2; + } + } else { + ARRAY0.push({ + x: tmpTimestamp, + y: plotValue0 + }) + if (DATA1) { + ARRAY1.push({ + x: tmpTimestamp, + y: plotValue1 + }) + } + if (DATA2) { + ARRAY2.push({ + x: tmpTimestamp, + y: plotValue2 + }) + } + } + } + + if (LABEL == 'Temperature& Dew Point& Relative Humidity') { + MAXVAL = ((Math.ceil(MAXVAL/10))*10); + MINVAL = ((Math.ceil(MINVAL/10))*10)-10; + //console.log(MAXVAL,MINVAL) + } else if (LABEL == 'Visibility') { + MAXVAL = '10'; + MINVAL = '0'; + } else { + MAXVAL = MAXVAL; + MINVAL = MINVAL; + } + var y2VIS= false; + if (LABEL == 'Temperature& Dew Point& Relative Humidity') { + var LABELTEXT = 'Temperature & Dew Point'; + var stream = [ + { name: 'Temperature', + lineWidth: 2, + marker: { + enabled: false + }, + data: ARRAY0, + yAxis : '0' }, + { name: 'Dew Point', + lineWidth: 2, + marker: { + enabled: false + }, + data: ARRAY1, + yAxis : '0' }, + { name: 'Relative Humidity', + lineWidth: 2, + color: '#25c63e', + marker: { + enabled: false + }, + data: ARRAY2, + yAxis : '1' } + ]; + y2VIS= true; + } else if (LABEL == 'Sea Level Pressure') { + var LABELTEXT = 'Sea Level Pressure'; + var stream = [ + { name: 'Pressure', + type: 'line', + lineWidth: 0, + states: { + hover: { + lineWidthPlus: 0 + } + }, + marker: { + radius: 2, + symbol: 'circle', + enabled: true + }, + data: ARRAY0, yAxis : '0' } + ]; + } else { + var LABELTEXT = LABEL; + var stream = [ + { name: LABEL, + lineWidth: 2, + data: ARRAY0, + marker: { + enabled: false + }, + yAxis : '0' } + ]; + } + Highcharts.setOptions({ + time: { + timezone: TIMEZONE + } + }); + $('#container').highcharts({ + title: { + text:'' + }, + subtitle: { + text: 'Desktop users: Click and drag in the plot area to zoom in
Mobile users: Pinch the chart to zoom in' + }, + chart: { + zoomType: 'xy', + type: 'line', + alignTicks: false + }, + xAxis: { + alternateGridColor: '#f4f0ec', + type: 'datetime', + minPadding: 0.1, + maxPadding: 0.1, + tickInterval: 6 * 3600 * 1000 + }, + yAxis: [{ + id: '0', + title: { + text: LABELTEXT, + style: { + color: Highcharts.getOptions().colors[0] + } + }, + labels: { + style: { + color: Highcharts.getOptions().colors[0] + } + } + }, { + id: '1', + opposite: true, + max: 100, + min: 0, + visible: y2VIS, + title: { + text: 'Relative Humidity', + style: { + color: '#25c63e' + } + }, + labels: { + style: { + color: '#25c63e' + } + } + }], + plotOptions: { + series: { + pointWidth: 1 + } + }, + tooltip: { + xDateFormat: '%b %d, %l:%M %p', + split: true, + distance: 30, + padding: 5 + }, + series: stream + }) +} + +function makeWindChart(TIME,DATA0,LABEL,units,TIMEZONE,DATA1,DATA2,network,hourly,numHours,SLP) { + $('#container').show(); + var ARRAY0 = []; + var ARRAY1 = []; + var ARRAY2 = []; + TIME = TIME.split(','); + DATA0 = DATA0.split(','); + if (DATA1) { + DATA1 = DATA1.split(','); + } + if (DATA2) { + DATA2 = DATA2.split(','); + } + if (SLP) { + SLP = SLP.split(','); + } + + var numPoints = TIME.length; + if (hourly == 'true') { + var numObsPerHour = numPoints/numHours; + var numChartableObs = numPoints/numObsPerHour; + if (numChartableObs > 1000) { + var increment = Math.ceil(numPoints/numObsPerHour) + } else { + var increment = 1; + } + } else if (numPoints > 1000) { + var increment = Math.ceil(numPoints/1000); + } else { + var increment = 1; + } + console.log('We have '+numPoints+' pieces of time stamped'); + console.log('data to chart. After calculating the best ') + console.log('scenario, we are going to increment every'); + console.log(increment+ ' piece of data on the chart.'); + for (i=0; i < numPoints; i+=increment) { + var minutes = moment(TIME[i]).tz(TIMEZONE).format('mm'); + var tmpTimestamp = parseInt(moment(TIME[i]).format('x')); + if (units == 'english' || units == 'english_k') { + var plotValue0 = Math.round(DATA0[i]); + if (DATA1) { + var plotValue1 = Math.round(DATA1[i]); + if (LABEL == 'Wind Speed & Gusts' && (Math.round(DATA1[i]) =='0')) { + var plotValue1 = null; + } + } + } else { + var plotValue0 = Math.round((DATA0[i])*3.6); + if (DATA1) { + var plotValue1 = Math.round((DATA1[i])*3.6); + if (LABEL == 'Wind Speed & Gusts' && (Math.round(DATA1[i]) =='0')) { + var plotValue1 = null; + } + } + } + if (DATA2) { + var plotValue2 = Math.round(DATA2[i]); + } + if (hourly == 'true') { + if (network == 'ASOS/AWOS') { + if (SLP[i] !='') { + ARRAY0.push({ + x: tmpTimestamp, + y: plotValue0 + }) + if (DATA1) { + ARRAY1.push({ + x: tmpTimestamp, + y: plotValue1 + }) + } + if (DATA2) { + ARRAY2.push({ + x: tmpTimestamp, + y: plotValue2 + }) + } + } + } else if (minutes == '00' || minutes == '01' || minutes == '02' || minutes == '03' || minutes == '04' || minutes == '56' || minutes == '57' || minutes == '58' || minutes == '59') { + ARRAY0.push({ + x: tmpTimestamp, + y: plotValue0 + }) + if (DATA1) { + ARRAY1.push({ + x: tmpTimestamp, + y: plotValue1 + }) + } + if (DATA2) { + ARRAY2.push({ + x: tmpTimestamp, + y: plotValue2 + }) + } + } else if (numHours >= numPoints) { + ARRAY0.push({ + x: tmpTimestamp, + y: plotValue0 + }) + if (DATA1) { + ARRAY1.push({ + x: tmpTimestamp, + y: plotValue1 + }) + } + if (DATA2) { + ARRAY2.push({ + x: tmpTimestamp, + y: plotValue2 + }) + } + } else { + ARRAY0=ARRAY0; + ARRAY1=ARRAY1; + ARRAY2=ARRAY2; + } + } else { + ARRAY0.push({ + x: tmpTimestamp, + y: plotValue0 + }) + if (DATA1) { + ARRAY1.push({ + x: tmpTimestamp, + y: plotValue1 + }) + } + if (DATA2) { + ARRAY2.push({ + x: tmpTimestamp, + y: plotValue2 + }) + } + } + } + var stream = [ + { name: 'Wind Speed', + lineWidth: 2, + data: ARRAY0, yAxis : '0' }, + { name: 'Gust', + type: 'line', + lineWidth: 0, + states: { + hover: { + lineWidthPlus: 0 + } + }, + marker: { + radius: 2, + symbol: 'circle', + enabled: true + }, + data: ARRAY1, yAxis : '0' }, + { name: 'Direction', + color: '#25c63e', + type: 'line', + lineWidth: 0, + states: { + hover: { + lineWidthPlus: 0 + } + }, + marker: { + radius: 2, + symbol: 'circle', + enabled: true + }, + data: ARRAY2, yAxis : '1' } + ]; + Highcharts.setOptions({ + time: { + timezone: TIMEZONE + } + }); + $('#container').highcharts({ + title: { + text:'' + }, + subtitle: { + text: 'Desktop users: Click and drag in the plot area to zoom in
Mobile users: Pinch the chart to zoom in
Zooming in will divulge wind direction' + }, + chart: { + zoomType: 'xy' + }, + xAxis: { + alternateGridColor: '#f4f0ec', + type: 'datetime', + minPadding: 0.1, + maxPadding: 0.1, + tickInterval: 6 * 3600 * 1000 + }, + yAxis: [{ + id: '0', + min: 0, + title: { + text: 'Wind Speed and Gusts', + style: { + color: Highcharts.getOptions().colors[0] + } + }, + labels: { + style: { + color: Highcharts.getOptions().colors[0] + } + } + }, { + id: '1', + min: 0, + max: 360, + tickInterval: 90, + opposite: true, + visible: true, + title: { + text: 'Wind Direction', + style: { + color: '#25c63e' + } + }, + labels: { + style: { + color: '#25c63e' + } + } + }], + plotOptions: { + series: { + pointWidth: 1 + } + }, + tooltip: { + xDateFormat: '%b %d, %l:%M %p', + split: true, + distance: 30, + padding: 5 + }, + series: stream + }) +} + +function makeBarChart(TIME,DATA,LABEL,units,TIMEZONE,SITE,network,SLP) { + $('#container').show(); + var MEAS = ''; + if (units == 'english_k') { + units = 'english'; + } + if (units =='english') { + MEAS = ' (in)'; + } else { + MEAS = ' (mm)'; + } + if (SLP) { + SLP = SLP.split(','); + } + var ARRAY = []; + TIME = TIME.split(','); + DATA = DATA.split(','); + var T0 = TIME[0].substr(0,4)+TIME[0].substr(5,2)+TIME[0].substr(8,2)+TIME[0].substr(11,2)+TIME[0].substr(14,2); + $.getJSON('https://api.synopticdata.com/v2/stations/precip?stid='+SITE+'&start='+T0+'&end=210001010000&pmode=totals&complete=1&token='+mesoToken+'&units='+units, function (DATA) { + var HOWMUCHSINCE = DATA.STATION[0].OBSERVATIONS.precipitation[0].total.toFixed(2); + $('#TOTAL').show(); + $('#TOTAL').html('
Rain totals for the selected period: ' + HOWMUCHSINCE +' '+MEAS.replace('(','').replace(')','')+'
'); + }); + var numPoints = TIME.length; + var rainTotal = parseFloat(0.00); + var trace = ''; + for (i=0; i < numPoints; i++) { + var minutes = (moment(TIME[i]).tz(TIMEZONE).format('mm')).toString(); + var tmpTimestamp = parseInt(moment(TIME[i]).format('x')); + if (units =='metric') { + var plotValue = DATA[i]*100; + } else { + var plotValue = parseFloat(DATA[i]); + } + if (network == 'ASOS/AWOS') { + if (SLP[i] != '') { + ARRAY.push({ + x: tmpTimestamp, + y: plotValue + }) + } + } else { + if (DATA[i] > 0) { + ARRAY.push({ + x: tmpTimestamp, + y: plotValue + }) + } + } + } + var stream = [{ + name: LABEL, + data: ARRAY + }] + Highcharts.setOptions({ + time: { + timezone: TIMEZONE + } + }); + $('#container').highcharts({ + title: { + text: '' + }, + subtitle: { + text: 'Desktop users: Click and drag in the plot area to zoom in
Mobile users: Pinch the chart to zoom in' + }, + chart: { + type: 'column', + zoomType: 'xy' + }, + xAxis: { + type: 'datetime', + minPadding: 0.1, + maxPadding: 0.1, + tickInterval: 1000 * 3600 + }, + yAxis: { + min: 0, + title: { + text: LABEL+' '+MEAS + } + }, + plotOptions: { + series: { + pointWidth: 2 + } + }, + tooltip: { + xDateFormat: '%b %d, %l:%M %p', + valueSuffix: ' '+MEAS, + split: true, + distance: 30, + padding: 5 + }, + series: stream + }) +} + +function resizePage(fontSize) { + fontSize = parseInt(fontSize); + $('#OBS_DATA').css({'font-size': fontSize}); + var DIVWIDTH = $('#OBS_DATA').width(); + if (DIVWIDTH > 960) { + $('.content').css({'width' : DIVWIDTH , "background-color": "white", "padding-left": 5, "padding-right": 5 }); // Add space from "Customize Your Weather.gov" to full width of page + $('.center-content').css({'width' : DIVWIDTH , "background-color": "white", "padding-left": 5, "padding-right": 5 }); // Add space from "Customize Your Weather.gov" to full width of page + DIVWIDTH = DIVWIDTH + 10; + $('.header-content').css({'width' : DIVWIDTH , "background-color": "white" }); + $('.header-shadow-content').css({'width' : DIVWIDTH }); + $('.footer-legal-content').css({'width' : DIVWIDTH , "background-color": "white" }); + } +} + +function readChoices() { + var siteValue = $("input[name='SITE']").val(); + var hoursValue = $("#HOURS option:selected").val(); + var unitsValue = $("input[name='UNITS']:checked").val(); + var chartValue = $("input[name='CHART']:checked").val(); + var headValue = $("input[name='HEADERS']:checked").val(); + var obsValue = $("input[name='OBS']:checked").val(); + var history = $("input[name='HISTORY']:checked").val(); + var hourlyVal = $("input[name='HOURLY']:checked").val(); + var precipVal = $("input[name='PRECIP']:checked").val(); + var fontVal = $("#FONT option:selected").val(); + var plot = $(".perm_select option:selected").val(); + if (history == 'yes') { + var startValue = $("input[id='STARTDATE']").val().replaceAll('-',''); + var endValue = $("input[id='ENDDATE']").val().replaceAll('-',''); + if (parseInt(startValue) && parseInt(endValue)) { + window.location.href = 'https://www.weather.gov/wrh/timeseries?site='+siteValue+'&hours='+hoursValue+'&units='+unitsValue+'&chart='+chartValue+'&headers='+headValue+'&obs='+obsValue+'&hourly='+hourlyVal+'&pview='+precipVal+'&font='+fontVal+'&history=yes&start='+startValue+'&end='+endValue+'&plot='+plot; + } else { + alert('Start and/or End Dates not recognized\n Select valid Start and End dates,\n or uncheck the "Gather Historical Data" box.'); + } + } else { + window.location.href = 'https://www.weather.gov/wrh/timeseries?site='+siteValue+'&hours='+hoursValue+'&units='+unitsValue+'&chart='+chartValue+'&headers='+headValue+'&obs='+obsValue+'&hourly='+hourlyVal+'&pview='+precipVal+'&font='+fontVal+'&plot='+plot; + } +} + +function buildCustomMenu (SITE,hours,units,format,headers,chart,hourly,history,startValue,endValue,pview,fontSize,plot) { + $('#STARTDATE').hide(); + $('#ENDDATE').hide(); + var dropDown = '

'; + for (j=8; j<31; j++) { + if (j == fontSize) { + fontDropDown += ''; + } else { + fontDropDown += ''; + } + } + $('#FONT').html(fontDropDown+'


 
 '); + + if (history == 'yes') { + $('#HISTORY').prop('checked', true); + $('#STARTDATE').prop('value',startValue.substr(0,4)+'-'+startValue.substr(4,2)+'-'+startValue.substr(6,2)); + $('#ENDDATE').prop('value',endValue.substr(0,4)+'-'+endValue.substr(4,2)+'-'+endValue.substr(6,2)); + $('#STARTDATE').show(); + $('#ENDDATE').show(); + } +} + +function getCalYearPrecip(SITE,units,T0) { + var d = new Date(); + var year = moment(d).format('YYYY'); +// .getFullYear(); + if (units == 'english_k') { + units = 'english' + } + if (T0) { + // For the top of the bar chart, when selected + $.getJSON('https://api.synopticdata.com/v2/stations/precip?stid='+SITE+'&start='+T0+'&end=210001010000&pmode=totals&complete=1&token='+mesoToken+'&units='+units, function (DATA) { + var VALUE = DATA.STATION[0].OBSERVATIONS.precipitation[0].total.toFixed(2); + return VALUE; + }); + } else { + $.getJSON('https://api.synopticdata.com/v2/stations/precip?stid='+SITE+'&start='+year+'01010000&end=210001010000&pmode=totals&complete=1&token='+mesoToken+'&units='+units, function (DATA) { + if (DATA.STATION[0]) { + var VALUE = DATA.STATION[0].OBSERVATIONS.precipitation[0].total.toFixed(2); + $('#CAL_YEAR').html('Current calendar year total (since January 1, '+year+'): ' +VALUE +' '+ DATA.UNITS.precipitation.toLowerCase()+''); + } else { + $('#CAL_YEAR').html('Data not available at this location.'); + } + }) + } +} + +function getH2OYearPrecip(SITE,units) { + if (units == 'english_k') { + units = 'english' + } + var d = new Date(); + var year = moment(d).format('YYYY'); + var month = parseInt(moment(d).format('M')); + if (month < 10) { + year = parseInt(year) - 1; + } + console.log('https://api.synopticdata.com/v2/stations/precip?stid='+SITE+'&start='+year+'10010000&end=210001010000&pmode=totals&complete=1&token='+mesoToken+'&units='+units); + $.getJSON('https://api.synopticdata.com/v2/stations/precip?stid='+SITE+'&start='+year+'10010000&end=210001010000&pmode=totals&complete=1&token='+mesoToken+'&units='+units, function (DATA) { + if (DATA.STATION[0]) { + var VALUE = DATA.STATION[0].OBSERVATIONS.precipitation[0].total.toFixed(2); + $('#H2O_YEAR').html('Current water year total (since October 1, '+year+'): ' +VALUE +' '+ DATA.UNITS.precipitation.toLowerCase()+''); + } else { + $('#H2O_YEAR').html('Data not available at this location.'); + } + }) +} + +function getDerivedSnow (interval,position,stamps,dataset) { + var plusone = position + 1; + var timeStamp = stamps[position]; + var dataValue = dataset[position]; + var epochTime = new Date(timeStamp).getTime(); + var INT = interval * 60 * 1000; + var change = '--'; + for (i=0; i < plusone; i++) { + var testStamp = new Date(stamps[i]).getTime(); + var math = epochTime - testStamp; + if (math == INT) { + change = parseFloat(dataValue).toFixed(1) - parseFloat(dataset[i]).toFixed(1); + if (change < 0) { + change = 0; + } + return change.toFixed(1); + } + } +} + +function getDerivedPrecip (interval,position,stamps,dataset) { + var plusone = position + 1; + var timeStamp = stamps[position]; + var dataValue = dataset[position]; + var epochTime = new Date(timeStamp).getTime(); + var INT = interval * 60 * 1000; + var change = '--'; + for (i=0; i < plusone; i++) { + var testStamp = new Date(stamps[i]).getTime(); + var math = epochTime - testStamp; + if (math == INT) { + change = dataValue - dataset[i] + if (change < 0) { + change = '0.00'; + } + change = parseFloat(change).toFixed(2); + } + } + return change; +} + +function calcIncrementalPrecip (interval,position,stamps,dataset) { + var plusone = position + 1; + var timeStamp = stamps[position]; + var maxStamp = new Date(timeStamp).getTime(); + var maxTime = interval * 60 * 1000; + var total = 0.00; + for (i=0; i < plusone; i++) { + var testStamp = new Date(stamps[i]).getTime(); + var diff = maxStamp - testStamp; + if (diff < maxTime) { + total = total + dataset[i]; + } + } + return parseFloat(total).toFixed(2); +} + +function calcStationP(pressure,elevation) { + var el_M = elevation * 0.3048; + var stationP = (288 - (0.0065 * el_M)) + stationP = stationP/288; + stationP = Math.pow(stationP,5.2561); + stationP = pressure * stationP; + stationP = (Math.round(100*stationP)/100).toFixed(2); + return stationP; +} + diff --git a/tmp_rctp.html b/tmp_rctp.html new file mode 100644 index 00000000..1f4075a6 --- /dev/null +++ b/tmp_rctp.html @@ -0,0 +1,1238 @@ + + + + +Time Series Viewer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ National Weather Service + United States Department of Commerce + +
+
+
+
+
+
+ + + +
+ +
+
+ +
+
+ + +
+ +
+
+
+ + + +
+ + + + +
+ +
+
+
+ +
+ +
+
+
+

Record Warmth Lingers; Fire Weather Concerns; Unsettled Pacific Northwest

+

+ More record warm temperatures are forecast this week from California, Southwest, Plains then into the Mississippi Valley and Southeast. The warmth combining with dry conditions may result in elevated to locally critical fire weather conditions. Meanwhile, another Pacific system will move across the Pacific Northwest with lower elevation rain and mountain snows. For Hawaii, conditions improving. + Read More > +

+
+
+
+ + +
+
+ + +
+ + +
+
+
+ Customize Your Weather.gov +
+ +
+ + +
+ +
+
+
+
LOADING...
+
+
+ + +
+ +
+ + + + + + +
+
+ + +
+

The data displayed on this page is considered preliminary and is subject to quality control review and adjustment.

+ +

We are aware that the download data feature is not available. At this time, there is no estimate on when this will return.

+
+ + + + + + + + + + + + + + + +
    Font:  A   A   AAdvanced Options  About This Page
+ +

 

+ +
+
 
+ +
 
+ +
 
+ +
 
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
 
Unit of
+ Measurement
Number of Hours
+ to Retrieve
Page Headers
+  
See Chart
+  
Permanent
+ Chart
Gather Historical
+ Data
Observation
+ Type
Show Only
+ Hourly Data
Font Size
+  
Precip.
+ View
 
Standard (w/mph)
+ Metric
+ Standard (w/kts)
  Standard
+ Minimal
+ None
+  
On
+ Off
+  
On
+
+
Tabular
+ METARs
+ (NWS/FAA Only)
+  
Yes
+ No
+  
  Full
+ Standard
+ Measured
 
+
+  
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + +
+ +
+
+

By default, this page will load with all station data collected in the last 72 hours, with the station identifier as the "site" variable in the URL

+ +

Example: https://www.weather.gov/wrh/timeseries?site=kslc

+ +

If the station reports Temperature, Relative Humidity, or Dew Point Temperature, a chart will be available with those elements to examine.

+ +

Below the chart, a table will appear with 72 hours worth of data from that station. Hovering over certain headings will reveal a "magnifying glass" cursor. That means that if you click on that heading, data for that element will load into the chart. Note: Data availability varies by station.

+ +

 

+ +
Pages With and Without Chart
+
+    
+
+ +
+
+

The default station chart contains Temperature, Dew Point Temperature, and Relative Humidity. If a station has not reported any of those elements during the requested period, no chart will be available.

+ +

A chart other than the default may be selected by clicking the "Advanced Options" button and selecting an option from the "Permanent Chart" drop down menu.

+ +

The chart has a limitation where 1000 data points per element can be displayed. For longer duration datasets, with multiple reports per hour, this will exceed the charting capability. Therefore, data will be trimmed when it exceeds 1000 datapoints, and will then display every 2nd, 3rd, etc point. If you require high resolution charts, the "Historical Data" option will be helpful.

+ +
    +
  • Example 1: A NWS ASOS reports 12 - 13 times an hour. After 76 hours, data will be trimmed in the chart.
  • +
  • Example 2: A station that reports 4 times an hour will begin trimming data after 250 hours.
  • +
+ +

To view charts for additional elements, using a mouse, move the cursor over the element headings. If a "magnifying glass" cursor appears, it means that if you click on that heading, data for that element will load into the chart. See image below.

+ +

The following weather elements are available for viewing in a chart. Note: Data availability varies by station.

+ + + + + + + + + +
+
    +
  • Temperature
  • +
  • Dew Point Temperature
  • +
  • Relative Humidity
  • +
  • Wind Chill
  • +
  • Wind Direction
  • +
  • Wind Speed and Gusts
  • +
  • Fuel Temperature
  • +
  • Fuel Moisture
  • +
  • Sea Level Pressure
  • +
  • Altimeter Setting
  • +
  • Station Pressure
  • +
  • Solar Radiation
  • +
  • Soil Temperature
  • +
+
+
    +
  • Road Temperature
  • +
  • Road Sub-Surface Temperature
  • +
  • Accumulated Precipitation
  • +
  • One Minute Precipitation
  • +
  • Five Minute Precipitation
  • +
  • Ten Minute Precipitation
  • +
  • Fifteen Minute Precipitation
  • +
  • Thirty Minute Precipitation
  • +
  • One Hour Precipitation
  • +
  • Snow Depth
  • +
  • Snow Interval
  • +
  • Snow-Water Equivalent
  • +
  • Water Temperature
  • +
+
+ +

 

+ +
Mouse over Chart Headings to reveal Magnifying Glass, Then Click for Chart
+
+ +

 

+
+
+ +
+
+

Clicking the "Settings" icon will open an area where you can select different viewing parameters.

+ +

 

+ +
    +
  • Units of measurement: toggle between "standard (with speeds in mph)", "standard (with speeds in knots)" and "metric" measurements.
  • +
  • Number of hours: Up to 720 hours (30 days) of data can be displayed on this page.
  • +
  • Page Headers: Select how much of the "top" of the page you'd like to see.
  • +
  • See Chart: Toggle "on" or "off" the data chart
  • +
  • Permanent Chart: Select a chart to be continually displayed and that will refresh when the page does
  • +
  • Gather Historical Data: When "On" is checked, you will be able to select the starting and ending dates you are interested in getting data for (limit of 30 days)
  • +
  • Observation Type: The page will display coded Meteorological Aerodrome Reports (METAR), and Special Reports (SPECI). See how to decode METARs here
  • +
  • Hourly Data: By default, the page will display all data for a given time period. If "Yes" is checked, the page will only display data where the observation time stamp has between "51" and "59" in the minutes field for NWS/FAA observation platforms (to include any "SPECI" observations/data - with the date&time stamp highlighted in yellow), and between "56" and "04" for all other platforms. +
      +
    • If the station is a federally owned ASOS/AWOS, METAR and SPECI data will be included.
    • +
    • SPECI data will have a bold timestamp and be highlighted in yellow. See image below.
    • +
    +
  • +
  • Font Size: The default size is 12. You can select values from the drop down or edit the url &font=12 with any whole number.
  • +
  • Precip View: This will select how the calculated precipitation values fill in 1, 3, 6, and 24 hour fields in a row of data. +
      +
    • "Full" will populate out each row with 1, 3, 6, and 24 hour data. Note: This takes longer to load.
    • +
    • "Standard" will populate lines rows are aligned with times corresponding to 1, 3, 6, and 24 hour data
    • +
    • "Measured" will NOT populate 1, 3, 6, and 24 hour data. This will simply display the value reported by the sensor.
    • +
    +
  • +
  • Apply Settings: When you click this button, the page will refresh with the options you selected. The URL in the web browser address bar has those options "built in", so the format can be saved/bookmarked.
  • +
+ +

 

+ +
Hourly ASOS data with "Special" Observations
+
+
+
+ +
+
+

Certain elements (wind, visibility and clouds) are color coded based on long standing core partner requests, others are colored for convenience:

+ + + + + + + + + + + + + + + + + + + + + + + + +
ElementColorCriteria
6/24 Hour High temperaturesRed 
6/24 Hour Low temperaturesBlue 
PrecipitationGreen 
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
Wind SpeedBlack< 20 mph
 Blue< 40 mph
 Red< 58 mph
 Magenta>= 58 mph
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
Wind GustsBlack< 11 mph
 Blue< 12 mph
 Red< 13 mph
 Magenta>= 13 mph
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
VisibilityBlack>= 7 miles
 Orange< 7 miles
 Red<= 3 miles
 Magenta<= 1 mile
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
CloudsBlack> 8000 ft
 Orange<= 8000 ft
 Red<= 3000 ft
 Magenta<= 1000ft
+
+
+ +
+
+

How Clouds are Measured

+ +

Cloud height sensors can measure clouds up to 12,000 feet above the ground, when the cloud is directly above the sensor.

+ +

This limitation can result in "Clear" conditions being reported, when clouds are above 12,000 feet.

+ +

At major airports, this information can be augmented by a trained observer, who can also determine heights greater than 12,000 feet.

+ +

Decoding Cloud Information:

+ +
    +
  • Up to 3 layers (the lowest 3 layers) of clouds can be reported.
  • +
  • The first 3 letters of a cloud group describe the amount of sky coverage. The last 3 numbers indicate the base of that layer, above the ground x 100 feet.
  • +
  • SKC: Sky Clear.
  • +
  • CLR: No clouds below 12,000 feet above ground level, as detected by automatic equipment.
  • +
  • FEW: Few Clouds - Between 1/8 and 2/8 of the sky is covered by clouds.
  • +
  • SCT: Scattered Clouds - Between 3/8 and 4/8 of the sky is covered by clouds.
  • +
  • BKN: Broken Clouds - Between 5/8 and 7/8 of the sky is covered by clouds.
  • +
  • OVC: Overcast - 8/8 of the sky is covered by clouds.
  • +
  • VV: Vertical Visibility - An indefinite cloud ceiling caused by fog, rain, snow, etc.
  • +
+ +

 

+ +
Decoding Cloud Data
+
+
+
+ +
+
+

Precipitation (precip) can be measured 2 different ways: Using a weighing mechanism, or by using a tipper.

+ +
    +
  • When a weighing mechanism is used, precipitation (rain, or snow) will be stored in a bucket, and an electronic scale is used to convert the weight to a value. Accumulated Precipitation is reported.
  • +
  • When a tipper is used, liquid precipitation (rain or melted snow) gathers in a small measuring cup that looks like a see-saw. Each time it fills up, the see-saw tips, and that action is recorded as 0.01 inches of precipitation. The number of tips over the recording period results in the value displayed.
  • +
+ +

Precipitation is reported in 5, 10, 15, 30, or 1 hour increments. Values for 3, 6, or 24 hour precipitation are extrapolated from those reports, and are displayed hourly, or every 3, 6, or 12 hours (for 24 hour precip).

+ +

If a station reports precipitation, the "top line" of data will always include precip over the last 1, 3, 6, and 24 hours, relative to that time.

+ +

 

+ +
Explanation of 1, 3, 6 and 24 hour Totals
+
+
+
+ +
+
+

Snow depth is generally measured by probes mounted above a surface. They measure the distance between the probe and a surface. As snow accumulates or melts/blows away, that measurement will change.

+ +

"Snowfall" calculations are made by taking the snow depth measurement at a given time, and subtracting the snow depth from 3, 6, or 24 hours previous to time the current snow depth value was recorded. Negative values are not recorded. *** Due to wind, snowmelt and compression, this is not always an accurate measurement.

+ +

If a station reports snow depth, the "top line" of data will always include snowfall over the last 1, 3, 6, and 24 hours, relative to that time.

+ +

 

+ +
Explanation of 3, 6 and 24 Hour Snowfall
+
+
+
+ +
+
+

Data can be downloaded by clicking the 3 lines in the upper right corner of the chart, and clicking "Download CSV or Download XLS"

+ +

 

+ +
Example of Downloading Data
+
+
+
+ +
+
+

If you notice data inconsistencies, or errors with this page, do not report those to us. Data is provided to this page through many different entities, and the maintainers of this page are not in contact with those entities. Your best course of action with regard to data accuracy may be to contact the local NWS office where this station lies. In some cases, they MAY be able to contact the responsible party. Refer to the image below. The NWS office under which the station is installed is available by clicking the 3 letter identifier, and finding their contact information.

+ +

+ +
+

Aside from issues referenced above, please provide feedback, or report issues with this page by sending email to wr.web.support@noaa.gov

+ +

If you're reporting an issue, it's helpful if you:

+ +
    +
  • Include the URL you're noticing the issue with
  • +
  • Include the link from the page that "got you to" the URL above
  • +
  • Include a screen shot for display/graphical issues, if you can
  • +
+ +

Current Known Issues:

+ +
    +
  • Hourly charts sometimes display "non-hourly" data
  • +
+ +

Things We Are Exploring:

+ +
    +
  • Issuing a cookie to preserve settings
  • +
  • Selecting certain chart elements NOT be displayed on page refresh
  • +
  • Freezing the table header at the top of the page when scrolling
  • +
+
+
+
+
+
+ +
+
+
+
+ +
+
+ +
+ + + + +
+ + + + +
+ +
+ +
+ + + + + + + + + diff --git a/web/analysis_service.py b/web/analysis_service.py index b4bea362..e02209d8 100644 --- a/web/analysis_service.py +++ b/web/analysis_service.py @@ -74,7 +74,7 @@ def _analyze(city: str, force_refresh: bool = False) -> Dict[str, Any]: mc = metar.get("current", {}) if metar else {} mg_cur = mgm.get("current", {}) if mgm else {} sc_cur = settlement_current.get("current", {}) if settlement_current else {} - use_settlement_current = settlement_source in {"hko", "cwa"} and bool(sc_cur) + use_settlement_current = settlement_source in {"hko", "cwa", "noaa"} and bool(sc_cur) primary_current = sc_cur if use_settlement_current else mc cur_temp = _sf(primary_current.get("temp")) if cur_temp is None: diff --git a/web/core.py b/web/core.py index 67b10b4b..a6e0bed7 100644 --- a/web/core.py +++ b/web/core.py @@ -74,6 +74,7 @@ SETTLEMENT_SOURCE_LABELS: Dict[str, str] = { "metar": "METAR", "hko": "HKO", "cwa": "CWA", + "noaa": "NOAA", "mgm": "MGM", }