added functional current, hourly, and daily forecasts via OpenWeatherMap One Call API

This commit is contained in:
Bryan Zhu
2020-07-01 05:08:04 -04:00
parent 1d2f929d3f
commit 85ed1b85ae
5 changed files with 244 additions and 168 deletions

View File

@@ -60,13 +60,13 @@ WeatherProvider.register("openweathermap", {
fetchWeatherData() {
this.fetchData(this.getUrl())
.then((data) => {
if (!data || !data.list || !data.list.length) {
if (!data) {
// Did not receive usable new data.
// Maybe this needs a better check?
return;
}
this.setFetchedLocation(`${data.lat},${data.lon}`);
this.setFetchedLocation(`(${data.lat},${data.lon})`);
const wData = this.generateWeatherObjectsFromOnecall(data);
this.setWeatherData(wData);
@@ -121,156 +121,13 @@ WeatherProvider.register("openweathermap", {
*/
generateWeatherObjectsFromOnecall(data) {
if (this.config.weatherEndpoint === "/onecall") {
return this.fetchOneCall(data);
return this.fetchOnecall(data);
}
// if weatherEndpoint does not match onecall, what should be returned?
const wData = {current: new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits), hours: [], days: []};
return wData;
},
/*
* fetch One Call forecast information (available for free subscription).
* factors in timezone offsets.
* minutely forecasts are excluded for the moment, see getParams().
*/
fetchOnecall(data) {
let precip = false;
// get current weather
const current = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
if (!isNaN(data.current)) {
current.date = moment(data.current.dt, "X").utcOffset(data.timezone_offset/60);
current.windSpeed = data.current.wind_speed;
current.windDirection = data.current.wind_deg;
current.sunrise = moment(data.current.sunrise, "X").utcOffset(data.timezone_offset/60);
current.sunset = moment(data.current.sunset, "X").utcOffset(data.timezone_offset/60);
current.temperature = data.current.temp;
current.weatherType = this.convertWeatherType(data.current.weather[0].icon);
current.humidity = data.current.humidity;
if (current.hasOwnProperty("rain") && !isNaN(current.rain["1h"])) {
if (this.config.units === "imperial") {
weather.rain = current.rain["1h"] / 25.4;
} else {
weather.rain = current.rain["1h"];
}
precip = true;
}
if (current.hasOwnProperty("snow") && !isNaN(current.snow["1h"])) {
if (this.config.units === "imperial") {
weather.snow = current.snow["1h"] / 25.4;
} else {
weather.snow = current.snow["1h"];
}
precip = true;
}
if (precip) {
current.precipitation = current.rain+current.snow;
}
current.feelsLikeTemp = data.current.feels_like;
}
let weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
// let onecallDailyFormat = "MMM DD"
// let onecallHourlyFormat = "HH"
// let onecallMinutelyFormat = "HH:mm"
// if (this.config.timeFormat === 12) {
// if (this.config.showPeriod === true) {
// if (this.config.showPeriodUpper === true) {
// onecallHourlyFormat = "hhA"
// onecallMinutelyFormat = "hh:mmA"
// } else {
// onecallHourlyFormat = "hha"
// onecallMinutelyFormat = "hh:mma"
// }
// } else {
// onecallHourlyFormat = "hh"
// onecallMinutelyFormat = "hh:mm"
// }
// }
// get hourly weather
const hours = [];
if (!isNaN(data.hourly)) {
for (const hour of data.hourly) {
weather.date = moment(hour.dt, "X").utcOffset(data.timezone_offset/60);
// weather.date = moment(hour.dt, "X").utcOffset(data.timezone_offset/60).format(onecallDailyFormat+","+onecallHourlyFormat);
weather.temperature = hour.temp;
weather.feelsLikeTemp = hour.feels_like;
weather.humidity = hour.humidity;
weather.windSpeed = hour.wind_speed;
weather.windDirection = hour.wind_deg;
weather.weatherType = this.convertWeatherType(hour.weather[0].icon);
precip = false;
if (hour.hasOwnProperty("rain") && !isNaN(hour.rain["1h"])) {
if (this.config.units === "imperial") {
weather.rain = hour.rain["1h"] / 25.4;
} else {
weather.rain = hour.rain["1h"];
}
precip = true;
}
if (hour.hasOwnProperty("snow") && !isNaN(hour.snow["1h"])) {
if (this.config.units === "imperial") {
weather.snow = hour.snow["1h"] / 25.4;
} else {
weather.snow = hour.snow["1h"];
}
precip = true;
}
if (precip) {
weather.precipitation = weather.rain+weather.snow;
}
hours.push(weather);
weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
}
}
// get daily weather
const days = [];
if (!isNaN(data.daily)) {
for (const day of data.daily) {
weather.date = moment(day.dt, "X").utcOffset(data.timezone_offset/60);
weather.sunrise = moment(day.sunrise, "X").utcOffset(data.timezone_offset/60);
weather.sunset = moment(day.sunset, "X").utcOffset(data.timezone_offset/60);
// weather.date = moment(day.dt, "X").utcOffset(data.timezone_offset/60).format(onecallDailyFormat);
// weather.sunrise = moment(day.sunrise, "X").utcOffset(data.timezone_offset/60).format(onecallMinutelyFormat);
// weather.sunset = moment(day.sunset, "X").utcOffset(data.timezone_offset/60).format(onecallMinutelyFormat);
weather.minTemperature = day.temp.min;
weather.maxTemperature = day.temp.max;
weather.humidity = day.humidity;
weather.windSpeed = day.wind_speed;
weather.windDirection = day.wind_deg;
weather.weatherType = this.convertWeatherType(day.weather[0].icon);
precip = false;
if (!isNaN(day.rain)) {
if (this.config.units === "imperial") {
weather.rain = day.rain / 25.4;
} else {
weather.rain = day.rain;
}
precip = true;
}
if (!isNaN(day.snow)) {
if (this.config.units === "imperial") {
weather.snow = day.snow / 25.4;
} else {
weather.snow = day.snow;
}
precip = true;
}
if (precip) {
weather.precipitation = weather.rain+weather.snow;
}
days.push(weather);
weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
}
}
return {current: current, hours: hours, days: days};
},
/*
* fetch forecast information for 3-hourly forecast (available for free subscription).
*/
@@ -397,6 +254,129 @@ WeatherProvider.register("openweathermap", {
return days;
},
/*
* Fetch One Call forecast information (available for free subscription).
* Factors in timezone offsets.
* Minutely forecasts are excluded for the moment, see getParams().
*/
fetchOnecall(data) {
let precip = false;
// get current weather, if requested
const current = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
if (data.hasOwnProperty("current")) {
current.date = moment(data.current.dt, "X").utcOffset(data.timezone_offset/60);
current.windSpeed = data.current.wind_speed;
current.windDirection = data.current.wind_deg;
current.sunrise = moment(data.current.sunrise, "X").utcOffset(data.timezone_offset/60);
current.sunset = moment(data.current.sunset, "X").utcOffset(data.timezone_offset/60);
current.temperature = data.current.temp;
current.weatherType = this.convertWeatherType(data.current.weather[0].icon);
current.humidity = data.current.humidity;
if (data.current.hasOwnProperty("rain") && !isNaN(data.current["rain"]["1h"])) {
if (this.config.units === "imperial") {
current.rain = data.current["rain"]["1h"] / 25.4;
} else {
current.rain = data.current["rain"]["1h"];
}
precip = true;
}
if (data.current.hasOwnProperty("snow") && !isNaN(data.current["snow"]["1h"])) {
if (this.config.units === "imperial") {
current.snow = data.current["snow"]["1h"] / 25.4;
} else {
current.snow = data.current["snow"]["1h"];
}
precip = true;
}
if (precip) {
current.precipitation = current.rain+current.snow;
}
current.feelsLikeTemp = data.current.feels_like;
}
let weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
// get hourly weather, if requested
const hours = [];
if (data.hasOwnProperty("hourly")) {
for (const hour of data.hourly) {
weather.date = moment(hour.dt, "X").utcOffset(data.timezone_offset/60);
// weather.date = moment(hour.dt, "X").utcOffset(data.timezone_offset/60).format(onecallDailyFormat+","+onecallHourlyFormat);
weather.temperature = hour.temp;
weather.feelsLikeTemp = hour.feels_like;
weather.humidity = hour.humidity;
weather.windSpeed = hour.wind_speed;
weather.windDirection = hour.wind_deg;
weather.weatherType = this.convertWeatherType(hour.weather[0].icon);
precip = false;
if (hour.hasOwnProperty("rain") && !isNaN(hour.rain["1h"])) {
if (this.config.units === "imperial") {
weather.rain = hour.rain["1h"] / 25.4;
} else {
weather.rain = hour.rain["1h"];
}
precip = true;
}
if (hour.hasOwnProperty("snow") && !isNaN(hour.snow["1h"])) {
if (this.config.units === "imperial") {
weather.snow = hour.snow["1h"] / 25.4;
} else {
weather.snow = hour.snow["1h"];
}
precip = true;
}
if (precip) {
weather.precipitation = weather.rain+weather.snow;
}
hours.push(weather);
weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
}
}
// get daily weather, if requested
const days = [];
if (data.hasOwnProperty("daily")) {
for (const day of data.daily) {
weather.date = moment(day.dt, "X").utcOffset(data.timezone_offset/60);
weather.sunrise = moment(day.sunrise, "X").utcOffset(data.timezone_offset/60);
weather.sunset = moment(day.sunset, "X").utcOffset(data.timezone_offset/60);
weather.minTemperature = day.temp.min;
weather.maxTemperature = day.temp.max;
weather.humidity = day.humidity;
weather.windSpeed = day.wind_speed;
weather.windDirection = day.wind_deg;
weather.weatherType = this.convertWeatherType(day.weather[0].icon);
precip = false;
if (!isNaN(day.rain)) {
if (this.config.units === "imperial") {
weather.rain = day.rain / 25.4;
} else {
weather.rain = day.rain;
}
precip = true;
}
if (!isNaN(day.snow)) {
if (this.config.units === "imperial") {
weather.snow = day.snow / 25.4;
} else {
weather.snow = day.snow;
}
precip = true;
}
if (precip) {
weather.precipitation = weather.rain+weather.snow;
}
days.push(weather);
weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
}
}
return {current: current, hours: hours, days: days};
},
/*
* Convert the OpenWeatherMap icons to a more usable name.
*/