ws4kp-linhanced/server/scripts/modules/localforecast.mjs

97 lines
2.8 KiB
JavaScript
Raw Normal View History

2020-09-04 13:02:20 -05:00
// display text based local forecast
2022-11-22 16:19:10 -06:00
import STATUS from './status.mjs';
import { json } from './utils/fetch.mjs';
2022-11-22 16:29:10 -06:00
import WeatherDisplay from './weatherdisplay.mjs';
2022-12-06 16:14:56 -06:00
import { registerDisplay } from './navigation.mjs';
2025-02-23 23:29:39 -06:00
import settings from './settings.mjs';
2020-09-04 13:02:20 -05:00
class LocalForecast extends WeatherDisplay {
2020-10-29 16:44:28 -05:00
constructor(navId, elemId) {
2022-11-21 21:50:22 -06:00
super(navId, elemId, 'Local Forecast', true);
2020-09-04 13:02:20 -05:00
// set timings
2020-10-29 16:44:28 -05:00
this.timing.baseDelay = 5000;
2020-09-04 13:02:20 -05:00
}
2025-04-02 20:52:33 -05:00
async getData(weatherParameters, refresh) {
if (!super.getData(weatherParameters, refresh)) return;
2020-09-04 13:02:20 -05:00
// get raw data
2025-04-02 20:52:33 -05:00
const rawData = await this.getRawData(this.weatherParameters);
// check for data, or if there's old data available
if (!rawData && !this.data) {
// fail for no old or new data
this.setStatus(STATUS.failed);
return;
}
2025-04-02 20:52:33 -05:00
// store the data
this.data = rawData || this.data;
2020-09-04 13:02:20 -05:00
// parse raw data
2025-04-02 20:52:33 -05:00
const conditions = parse(this.data);
2020-09-04 13:02:20 -05:00
// read each text
2022-08-04 11:07:35 -05:00
this.screenTexts = conditions.map((condition) => {
2020-09-04 13:02:20 -05:00
// process the text
2020-10-29 16:44:28 -05:00
let text = `${condition.DayName.toUpperCase()}...`;
2022-12-06 16:25:28 -06:00
const conditionText = condition.Text;
2020-09-04 13:02:20 -05:00
text += conditionText.toUpperCase().replace('...', ' ');
2022-08-04 11:07:35 -05:00
return text;
});
2020-10-29 16:44:28 -05:00
2022-08-04 11:07:35 -05:00
// fill the forecast texts
const templates = this.screenTexts.map((text) => this.fillTemplate('forecast', { text }));
const forecastsElem = this.elem.querySelector('.forecasts');
forecastsElem.innerHTML = '';
forecastsElem.append(...templates);
// increase each forecast height to a multiple of container height
2025-05-16 14:42:11 -05:00
this.pageHeight = forecastsElem.parentNode.offsetHeight;
2022-08-04 11:07:35 -05:00
templates.forEach((forecast) => {
const newHeight = Math.ceil(forecast.scrollHeight / this.pageHeight) * this.pageHeight;
forecast.style.height = `${newHeight}px`;
2020-09-04 13:02:20 -05:00
});
2022-08-04 11:07:35 -05:00
this.timing.totalScreens = forecastsElem.scrollHeight / this.pageHeight;
this.calcNavTiming();
this.setStatus(STATUS.loaded);
2020-09-04 13:02:20 -05:00
}
// get the unformatted data (also used by extended forecast)
async getRawData(weatherParameters) {
// request us or si units
try {
2022-11-22 16:19:10 -06:00
return await json(weatherParameters.forecast, {
2020-09-04 13:02:20 -05:00
data: {
2025-02-23 23:29:39 -06:00
units: settings.units.value,
2020-09-04 13:02:20 -05:00
},
2022-12-12 13:53:33 -06:00
retryCount: 3,
stillWaiting: () => this.stillWaiting(),
2020-09-04 13:02:20 -05:00
});
2023-01-06 14:39:39 -06:00
} catch (error) {
2020-09-04 13:02:20 -05:00
console.error(`GetWeatherForecast failed: ${weatherParameters.forecast}`);
2023-01-06 14:39:39 -06:00
console.error(error.status, error.responseJSON);
2020-09-04 13:02:20 -05:00
return false;
}
}
async drawCanvas() {
super.drawCanvas();
2022-08-04 11:07:35 -05:00
const top = -this.screenIndex * this.pageHeight;
this.elem.querySelector('.forecasts').style.top = `${top}px`;
2020-09-04 13:02:20 -05:00
this.finishDraw();
}
2020-10-29 16:44:28 -05:00
}
2022-12-06 16:14:56 -06:00
2022-12-09 13:51:51 -06:00
// format the forecast
// only use the first 6 lines
const parse = (forecast) => forecast.properties.periods.slice(0, 6).map((text) => ({
// format day and text
DayName: text.name.toUpperCase(),
Text: text.detailedForecast,
}));
2022-12-06 16:14:56 -06:00
// register display
2022-12-14 16:28:33 -06:00
registerDisplay(new LocalForecast(7, 'local-forecast'));