hourly and travel forecast silent reload

This commit is contained in:
Matt Walsh
2025-04-02 16:45:11 -05:00
parent 23cc1a1f7a
commit 8fa00b34b4
13 changed files with 54 additions and 48 deletions

View File

@@ -23,7 +23,7 @@ class CurrentWeather extends WeatherDisplay {
async getData(_weatherParameters, refresh) { async getData(_weatherParameters, refresh) {
// always load the data for use in the lower scroll // always load the data for use in the lower scroll
const superResult = super.getData(_weatherParameters); const superResult = super.getData(_weatherParameters, refresh);
const weatherParameters = _weatherParameters ?? this.weatherParameters; const weatherParameters = _weatherParameters ?? this.weatherParameters;
// filter for 4-letter observation stations, only those contain sky conditions and thus an icon // filter for 4-letter observation stations, only those contain sky conditions and thus an icon

View File

@@ -19,7 +19,7 @@ class ExtendedForecast extends WeatherDisplay {
} }
async getData(_weatherParameters, refresh) { async getData(_weatherParameters, refresh) {
if (!super.getData(_weatherParameters)) return; if (!super.getData(_weatherParameters, refresh)) return;
const weatherParameters = _weatherParameters ?? this.weatherParameters; const weatherParameters = _weatherParameters ?? this.weatherParameters;
// request us or si units // request us or si units

View File

@@ -28,7 +28,7 @@ class Hazards extends WeatherDisplay {
async getData(weatherParameters, refresh) { async getData(weatherParameters, refresh) {
// super checks for enabled // super checks for enabled
const superResult = super.getData(weatherParameters); const superResult = super.getData(weatherParameters, refresh);
const alert = this.checkbox.querySelector('.alert'); const alert = this.checkbox.querySelector('.alert');
alert.classList.remove('show'); alert.classList.remove('show');

View File

@@ -24,7 +24,7 @@ class HourlyGraph extends WeatherDisplay {
} }
async getData(_weatherParameters, refresh) { async getData(_weatherParameters, refresh) {
if (!super.getData()) return; if (!super.getData(undefined, refresh)) return;
const data = await getHourlyData(() => this.stillWaiting()); const data = await getHourlyData(() => this.stillWaiting());
if (data === undefined) { if (data === undefined) {

View File

@@ -29,21 +29,28 @@ class Hourly extends WeatherDisplay {
async getData(weatherParameters, refresh) { async getData(weatherParameters, refresh) {
// super checks for enabled // super checks for enabled
const superResponse = super.getData(weatherParameters); const superResponse = super.getData(weatherParameters, refresh);
let forecast; let forecast;
try { try {
// get the forecast // get the forecast
forecast = await json(weatherParameters.forecastGridData, { retryCount: 3, stillWaiting: () => this.stillWaiting() }); forecast = await json(this.weatherParameters.forecastGridData, { retryCount: 3, stillWaiting: () => this.stillWaiting() });
// parse the forecast
this.data = await parseForecast(forecast.properties);
} catch (error) { } catch (error) {
console.error('Get hourly forecast failed'); console.error('Get hourly forecast failed');
console.error(error.status, error.responseJSON); console.error(error.status, error.responseJSON);
// use old data if available
if (this.data) {
console.log('Using previous hourly forecast');
// don't return, this.data is usable from the previous update
} else {
if (this.isEnabled) this.setStatus(STATUS.failed); if (this.isEnabled) this.setStatus(STATUS.failed);
// return undefined to other subscribers // return undefined to other subscribers
this.getDataCallback(undefined); this.getDataCallback(undefined);
return; return;
} }
}
this.data = await parseForecast(forecast.properties);
this.getDataCallback(); this.getDataCallback();
if (!superResponse) return; if (!superResponse) return;

View File

@@ -17,7 +17,7 @@ class LatestObservations extends WeatherDisplay {
} }
async getData(_weatherParameters, refresh) { async getData(_weatherParameters, refresh) {
if (!super.getData(_weatherParameters)) return; if (!super.getData(_weatherParameters, refresh)) return;
const weatherParameters = _weatherParameters ?? this.weatherParameters; const weatherParameters = _weatherParameters ?? this.weatherParameters;
// calculate distance to each station // calculate distance to each station

View File

@@ -15,7 +15,7 @@ class LocalForecast extends WeatherDisplay {
} }
async getData(_weatherParameters, refresh) { async getData(_weatherParameters, refresh) {
if (!super.getData(_weatherParameters)) return; if (!super.getData(_weatherParameters, refresh)) return;
const weatherParameters = _weatherParameters ?? this.weatherParameters; const weatherParameters = _weatherParameters ?? this.weatherParameters;
// get raw data // get raw data

View File

@@ -43,7 +43,7 @@ class Radar extends WeatherDisplay {
} }
async getData(_weatherParameters, refresh) { async getData(_weatherParameters, refresh) {
if (!super.getData(_weatherParameters)) return; if (!super.getData(_weatherParameters, refresh)) return;
const weatherParameters = _weatherParameters ?? this.weatherParameters; const weatherParameters = _weatherParameters ?? this.weatherParameters;
// ALASKA AND HAWAII AREN'T SUPPORTED! // ALASKA AND HAWAII AREN'T SUPPORTED!

View File

@@ -22,7 +22,7 @@ class RegionalForecast extends WeatherDisplay {
} }
async getData(_weatherParameters, refresh) { async getData(_weatherParameters, refresh) {
if (!super.getData(_weatherParameters)) return; if (!super.getData(_weatherParameters, refresh)) return;
const weatherParameters = _weatherParameters ?? this.weatherParameters; const weatherParameters = _weatherParameters ?? this.weatherParameters;
// pre-load the base map // pre-load the base map

View File

@@ -26,20 +26,42 @@ class TravelForecast extends WeatherDisplay {
if (extra !== 0) this.timing.delay.push(Math.round(this.extra * this.cityHeight)); if (extra !== 0) this.timing.delay.push(Math.round(this.extra * this.cityHeight));
// add the final 3 second delay // add the final 3 second delay
this.timing.delay.push(150); this.timing.delay.push(150);
// add previous data cache
this.previousData = [];
} }
async getData(weatherParameters, refresh) { async getData(weatherParameters, refresh) {
// super checks for enabled // super checks for enabled
if (!super.getData(this.weatherParameters)) return; if (!super.getData(weatherParameters, refresh)) return;
const forecastPromises = TravelCities.map(async (city) => {
// clear stored data if not refresh
if (!refresh) {
this.previousData = [];
}
const forecastPromises = TravelCities.map(async (city, index) => {
try { try {
// get point then forecast // get point then forecast
if (!city.point) throw new Error('No pre-loaded point'); if (!city.point) throw new Error('No pre-loaded point');
const forecast = await json(`https://api.weather.gov/gridpoints/${city.point.wfo}/${city.point.x},${city.point.y}/forecast`, { let forecast;
try {
forecast = await json(`https://api.weather.gov/gridpoints/${city.point.wfo}/${city.point.x},${city.point.y}/forecast`, {
data: { data: {
units: settings.units.value, units: settings.units.value,
}, },
}); });
// store for the next run
this.previousData[index] = forecast;
} catch (e) {
// if there's previous data use it
if (this.previousData?.[index]) {
forecast = this.previousData?.[index];
} else {
// otherwise re-throw for the standard error handling
throw (e);
}
}
// determine today or tomorrow (shift periods by 1 if tomorrow) // determine today or tomorrow (shift periods by 1 if tomorrow)
const todayShift = forecast.properties.periods[0].isDaytime ? 0 : 1; const todayShift = forecast.properties.periods[0].isDaytime ? 0 : 1;
// return a pared-down forecast // return a pared-down forecast

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -133,7 +133,7 @@
<div id="divTwcBottomRight"> <div id="divTwcBottomRight">
<div id="ToggleMedia"> <div id="ToggleMedia">
<img class="navButton off" src="images/nav/ic_volume_off_white_24dp_2x.png" title="Unmute" /> <img class="navButton off" src="images/nav/ic_volume_off_white_24dp_2x.png" title="Unmute" />
<img class="navButton on" src="images/nav/ic_volume_on_white_24dp_2x.png" title="Unmute" /> <img class="navButton on" src="images/nav/ic_volume_on_white_24dp_2x.png" title="Mute" />
</div> </div>
<img id="ToggleFullScreen" class="navButton" src="images/nav/ic_fullscreen_white_24dp_2x.png" title="Enter Fullscreen" /> <img id="ToggleFullScreen" class="navButton" src="images/nav/ic_fullscreen_white_24dp_2x.png" title="Enter Fullscreen" />
</div> </div>