From 0710f2238cb3f0239c17f2a8466e9b3a20312044 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Sat, 8 Jun 2024 23:16:29 -0500 Subject: [PATCH] Add basic support for active weather alerts yikes nobody should stake their life on how well this works, but it does seem to basically work.. --- src/router/index.js | 6 ++++ src/stores/weather.js | 67 +++++++++++++++++++++++++++++++++++++-- src/views/AlertsView.vue | 51 +++++++++++++++++++++++++++++ src/views/WeatherView.vue | 12 +++++++ 4 files changed, 134 insertions(+), 2 deletions(-) create mode 100644 src/views/AlertsView.vue diff --git a/src/router/index.js b/src/router/index.js index 464d998..7430367 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -1,6 +1,7 @@ import { createRouter, createWebHistory } from 'vue-router' import HomeView from '../views/HomeView.vue' import WeatherView from '../views/WeatherView.vue' +import AlertsView from '../views/AlertsView.vue' import HourlyView from '../views/HourlyView.vue' import EditListView from '../views/EditListView.vue' @@ -17,6 +18,11 @@ const router = createRouter({ name: 'weather', component: WeatherView, }, + { + path: '/alerts', + name: 'alerts', + component: AlertsView, + }, { path: '/hourly', name: 'hourly', diff --git a/src/stores/weather.js b/src/stores/weather.js index c8c91ab..cf79fcf 100644 --- a/src/stores/weather.js +++ b/src/stores/weather.js @@ -10,6 +10,7 @@ const getDefaults = () => { coordinates, cityState, weather: null, + alerts: null, forecast: null, radarLatestURL: null, radarLoopURL: null, @@ -32,14 +33,17 @@ export const useWeatherStore = defineStore('weather', { this.setForecast(null) this.radarLatestURL = null this.radarLoopURL = null + this.alerts = null }, async getWeather() { if (!this.weather) { + let url + let response - const url = `https://api.weather.gov/points/${this.coordinates}` - const response = await fetch(url) + url = `https://api.weather.gov/points/${this.coordinates}` + response = await fetch(url) const weather = await response.json() if (weather.status == 404) { throw new Error(`Data not found for ${this.coordinates}`) @@ -57,6 +61,65 @@ export const useWeatherStore = defineStore('weather', { this.radarLoopURL = `https://radar.weather.gov/ridge/standard/${station}_loop.gif` this.setWeather(weather) + + // fetch zone to get its official id + url = weather.properties.forecastZone + response = await fetch(url) + const zone = await response.json() + + // fetch alerts for zone + url = `https://api.weather.gov/alerts/active/zone/${zone.properties.id}` + response = await fetch(url) + const zoneAlerts = await response.json() + + // fetch county to get its official id + url = weather.properties.county + response = await fetch(url) + const county = await response.json() + + // fetch alerts for county + url = `https://api.weather.gov/alerts/active/zone/${county.properties.id}` + response = await fetch(url) + const countyAlerts = await response.json() + + const newAlerts = {} + + // use latest timestamp from either zone or county + newAlerts.updated = zoneAlerts.updated + if (countyAlerts.updated > zoneAlerts.updated) { + newAlerts.updated = countyAlerts.updated + } + + // collect all alert "features" but de-duplicate them + newAlerts.features = {} + for (let feature of zoneAlerts.features) { + newAlerts.features[feature.properties.id] = feature + } + for (let feature of countyAlerts.features) { + newAlerts.features[feature.properties.id] = feature + } + newAlerts.features = Object.values(newAlerts.features) + + // put "likely" before "possible" alerts + newAlerts.features.sort((a, b) => { + + if (a.properties.certainty == 'Likely' && b.properties.certainty == 'Possible') { + return -1 + } + if (a.properties.certainty == 'Possible' && b.properties.certainty == 'Likely') { + return 1 + } + + // if (a.properties.certainty == b.properties.certainty) { + // return 0 + // } + + // TODO: what else should this do? + return 0 + }) + + // we have our final alerts + this.alerts = newAlerts } return this.weather diff --git a/src/views/AlertsView.vue b/src/views/AlertsView.vue new file mode 100644 index 0000000..a397565 --- /dev/null +++ b/src/views/AlertsView.vue @@ -0,0 +1,51 @@ + + + + + diff --git a/src/views/WeatherView.vue b/src/views/WeatherView.vue index 2c144a5..4d30a98 100644 --- a/src/views/WeatherView.vue +++ b/src/views/WeatherView.vue @@ -10,6 +10,7 @@ export default { data() { return { coordinates: null, + alerts: null, } }, @@ -48,6 +49,7 @@ export default { const forecast = await this.weatherStore.getForecast() this.coordinates = this.weatherStore.coordinates + this.alerts = this.weatherStore.alerts }, getShortForecast(period) { @@ -77,6 +79,16 @@ export default { +
+ +

Watches In Effect

+

Updated {{ new Date(alerts.updated).toLocaleTimeString('en-US', {timeStyle: 'short'}) }}

+
+
+