ws4kp/server/scripts/modules/localforecast.mjs

96 lines
2.7 KiB
JavaScript
Raw Normal View History

2020-09-04 18:02:20 +00:00
// display text based local forecast
2022-11-22 22:19:10 +00:00
import STATUS from './status.mjs';
import { json } from './utils/fetch.mjs';
2022-11-22 22:29:10 +00:00
import WeatherDisplay from './weatherdisplay.mjs';
2022-12-06 22:14:56 +00:00
import { registerDisplay } from './navigation.mjs';
2020-09-04 18:02:20 +00:00
class LocalForecast extends WeatherDisplay {
2020-10-29 21:44:28 +00:00
constructor(navId, elemId) {
2022-11-22 03:50:22 +00:00
super(navId, elemId, 'Local Forecast', true);
2020-09-04 18:02:20 +00:00
// set timings
2020-10-29 21:44:28 +00:00
this.timing.baseDelay = 5000;
2020-09-04 18:02:20 +00:00
}
2020-10-29 21:44:28 +00:00
async getData(_weatherParameters) {
2022-12-07 17:02:51 +00:00
if (!super.getData(_weatherParameters)) return;
2020-10-29 21:44:28 +00:00
const weatherParameters = _weatherParameters ?? this.weatherParameters;
2020-09-04 18:02:20 +00:00
// get raw data
const rawData = await this.getRawData(weatherParameters);
// check for data
if (!rawData) {
this.setStatus(STATUS.failed);
return;
}
2020-09-04 18:02:20 +00:00
// parse raw data
2022-12-09 19:51:51 +00:00
const conditions = parse(rawData);
2020-09-04 18:02:20 +00:00
// read each text
2022-08-04 16:07:35 +00:00
this.screenTexts = conditions.map((condition) => {
2020-09-04 18:02:20 +00:00
// process the text
2020-10-29 21:44:28 +00:00
let text = `${condition.DayName.toUpperCase()}...`;
2022-12-06 22:25:28 +00:00
const conditionText = condition.Text;
2020-09-04 18:02:20 +00:00
text += conditionText.toUpperCase().replace('...', ' ');
2022-08-04 16:07:35 +00:00
return text;
});
2020-10-29 21:44:28 +00:00
2022-08-04 16:07:35 +00: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
this.pageHeight = forecastsElem.parentNode.getBoundingClientRect().height;
templates.forEach((forecast) => {
const newHeight = Math.ceil(forecast.scrollHeight / this.pageHeight) * this.pageHeight;
forecast.style.height = `${newHeight}px`;
2020-09-04 18:02:20 +00:00
});
2022-08-04 16:07:35 +00:00
this.timing.totalScreens = forecastsElem.scrollHeight / this.pageHeight;
this.calcNavTiming();
this.setStatus(STATUS.loaded);
2020-09-04 18:02:20 +00:00
}
// get the unformatted data (also used by extended forecast)
async getRawData(weatherParameters) {
// request us or si units
try {
2022-11-22 22:19:10 +00:00
return await json(weatherParameters.forecast, {
2020-09-04 18:02:20 +00:00
data: {
2022-12-06 22:25:28 +00:00
units: 'us',
2020-09-04 18:02:20 +00:00
},
2022-12-12 19:53:33 +00:00
retryCount: 3,
stillWaiting: () => this.stillWaiting(),
2020-09-04 18:02:20 +00:00
});
} catch (e) {
console.error(`GetWeatherForecast failed: ${weatherParameters.forecast}`);
2020-09-23 16:49:15 +00:00
console.error(e.status, e.responseJSON);
2020-09-09 19:29:03 +00:00
this.setStatus(STATUS.failed);
2020-09-04 18:02:20 +00:00
return false;
}
}
async drawCanvas() {
super.drawCanvas();
2022-08-04 16:07:35 +00:00
const top = -this.screenIndex * this.pageHeight;
this.elem.querySelector('.forecasts').style.top = `${top}px`;
2020-09-04 18:02:20 +00:00
this.finishDraw();
}
2020-10-29 21:44:28 +00:00
}
2022-12-06 22:14:56 +00:00
2022-12-09 19:51:51 +00: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 22:14:56 +00:00
// register display
2022-12-14 22:28:33 +00:00
registerDisplay(new LocalForecast(7, 'local-forecast'));