diff --git a/modules/default/weather/providers/openweathermap.js b/modules/default/weather/providers/openweathermap.js index bf1dddfc..92551ca5 100755 --- a/modules/default/weather/providers/openweathermap.js +++ b/modules/default/weather/providers/openweathermap.js @@ -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. */ diff --git a/modules/default/weather/wdatacurrent.njk b/modules/default/weather/wdatacurrent.njk new file mode 100644 index 00000000..700b4355 --- /dev/null +++ b/modules/default/weather/wdatacurrent.njk @@ -0,0 +1,83 @@ +{% if wData %} + {% set current = wData.current %} + {% if not config.onlyTemp %} +
+ + + {% if config.useBeaufort %} + {{ current.beaufortWindSpeed() | round }} + {% else %} + {{ current.windSpeed | round }} + {% endif %} + {% if config.showWindDirection %} + + {% if config.showWindDirectionAsArrow %} + + {% else %} + {{ current.cardinalWindDirection() | translate }} + {% endif %} +   + + {% endif %} + + {% if config.showHumidity and current.humidity %} + {{ current.humidity | decimalSymbol }}  + {% endif %} + {% if config.showSun %} + + + {% if current.nextSunAction() === "sunset" %} + {{ current.sunset | formatTime }} + {% else %} + {{ current.sunrise | formatTime }} + {% endif %} + + {% endif %} +
+ {% endif %} +
+ + + {{ current.temperature | roundValue | unit("temperature") | decimalSymbol }} + +
+
+ {% if config.showIndoorTemperature and indoor.temperature %} +
+ + + {{ indoor.temperature | roundValue | unit("temperature") | decimalSymbol }} + +
+ {% endif %} + {% if config.showIndoorHumidity and indoor.humidity %} +
+ + + {{ indoor.humidity | roundValue | unit("humidity") | decimalSymbol }} + +
+ {% endif %} +
+ {% if (config.showFeelsLike or config.showPrecipitationAmount) and not config.onlyTemp %} +
+ {% if config.showFeelsLike %} + + {{ "FEELS" | translate }} {{ current.feelsLike() | roundValue | unit("temperature") | decimalSymbol }} + + {% endif %} + {% if config.showPrecipitationAmount %} + + {{ "PRECIP" | translate }} {{ current.precipitation | unit("precip") }} + + {% endif %} +
+ {% endif %} +{% else %} +
+ {{ "LOADING" | translate | safe }} +
+{% endif %} + + + diff --git a/modules/default/weather/wdatadaily.njk b/modules/default/weather/wdatadaily.njk new file mode 100644 index 00000000..99d588e7 --- /dev/null +++ b/modules/default/weather/wdatadaily.njk @@ -0,0 +1,32 @@ +{% if wData %} + {% set numSteps = wData.days | calcNumEntries %} + {% set currentStep = 0 %} + + {% set days = wData.days.slice(0, numSteps) %} + {% for day in days %} + + + + + + {% if config.showPrecipitationAmount %} + + {% endif %} + + {% set currentStep = currentStep + 1 %} + {% endfor %} +
{{ day.date.format('ddd') }} + {{ day.maxTemperature | roundValue | unit("temperature") }} + + {{ day.minTemperature | roundValue | unit("temperature") }} + + {{ day.precipitation | unit("precip") }} +
+{% else %} +
+ {{ "LOADING" | translate | safe }} +
+{% endif %} + + + diff --git a/modules/default/weather/wdatahourly.njk b/modules/default/weather/wdatahourly.njk index c69e425f..140c8b0d 100644 --- a/modules/default/weather/wdatahourly.njk +++ b/modules/default/weather/wdatahourly.njk @@ -5,9 +5,9 @@ {% set hours = wData.hours.slice(0, numSteps) %} {% for hour in hours %} - {{ hour.date | formatTimeMoment }} + {{ hour.date | formatTime }} - + {{ hour.temperature | roundValue | unit("temperature") }} {% if config.showPrecipitationAmount %} diff --git a/modules/default/weather/weather.js b/modules/default/weather/weather.js index 09046071..ef2a3bd6 100644 --- a/modules/default/weather/weather.js +++ b/modules/default/weather/weather.js @@ -193,25 +193,6 @@ Module.register("weather", { return date.format("HH:mm"); }.bind(this) ); - this.nunjucksEnvironment().addFilter( - "formatTimeMoment", - function (date) { - - if (this.config.timeFormat !== 24) { - if (this.config.showPeriod) { - if (this.config.showPeriodUpper) { - return date.format("h:mm A"); - } else { - return date.format("h:mm a"); - } - } else { - return date.format("h:mm"); - } - } - - return date.format("HH:mm"); - }.bind(this) - ); this.nunjucksEnvironment().addFilter( "unit", @@ -230,7 +211,7 @@ Module.register("weather", { } } } else if (type === "precip") { - if (isNaN(value) || value === 0 || value.toFixed(2) === "0.00") { + if (value === null || isNaN(value) || value === 0 || value.toFixed(2) === "0.00") { value = ""; } else { if (this.config.weatherProvider === "ukmetoffice" || this.config.weatherProvider === "ukmetofficedatahub") {