From a8dfe3bef6130ab72e320116fd5f9f0f926a8731 Mon Sep 17 00:00:00 2001 From: rejas Date: Sat, 9 Oct 2021 09:28:46 +0200 Subject: [PATCH 01/21] Cleanup openweathermap logic a little --- .../weather/providers/openweathermap.js | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/modules/default/weather/providers/openweathermap.js b/modules/default/weather/providers/openweathermap.js index 5f4cfa8385..d631404ff8 100644 --- a/modules/default/weather/providers/openweathermap.js +++ b/modules/default/weather/providers/openweathermap.js @@ -30,14 +30,14 @@ WeatherProvider.register("openweathermap", { fetchCurrentWeather() { this.fetchData(this.getUrl()) .then((data) => { + let currentWeather; if (this.config.weatherEndpoint === "/onecall") { - const weatherData = this.generateWeatherObjectsFromOnecall(data); - this.setCurrentWeather(weatherData.current); + currentWeather = this.generateWeatherObjectsFromOnecall(data).current; this.setFetchedLocation(`${data.timezone}`); } else { - const currentWeather = this.generateWeatherObjectFromCurrentWeather(data); - this.setCurrentWeather(currentWeather); + currentWeather = this.generateWeatherObjectFromCurrentWeather(data); } + this.setCurrentWeather(currentWeather); }) .catch(function (request) { Log.error("Could not load data ... ", request); @@ -49,15 +49,17 @@ WeatherProvider.register("openweathermap", { fetchWeatherForecast() { this.fetchData(this.getUrl()) .then((data) => { + let forecast; + let location; if (this.config.weatherEndpoint === "/onecall") { - const weatherData = this.generateWeatherObjectsFromOnecall(data); - this.setWeatherForecast(weatherData.days); - this.setFetchedLocation(`${data.timezone}`); + forecast = this.generateWeatherObjectsFromOnecall(data).days; + location = `${data.timezone}`; } else { - const forecast = this.generateWeatherObjectsFromForecast(data.list); - this.setWeatherForecast(forecast); - this.setFetchedLocation(`${data.city.name}, ${data.city.country}`); + forecast = this.generateWeatherObjectsFromForecast(data.list); + location = `${data.city.name}, ${data.city.country}`; } + this.setWeatherForecast(forecast); + this.setFetchedLocation(location); }) .catch(function (request) { Log.error("Could not load data ... ", request); @@ -125,6 +127,7 @@ WeatherProvider.register("openweathermap", { generateWeatherObjectFromCurrentWeather(currentWeatherData) { const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + currentWeather.date = moment.unix(currentWeatherData.dt); currentWeather.humidity = currentWeatherData.main.humidity; currentWeather.temperature = currentWeatherData.main.temp; currentWeather.feelsLikeTemp = currentWeatherData.main.feels_like; From 1f695dc67a163d33b001f2b88675500dd4e65c46 Mon Sep 17 00:00:00 2001 From: rejas Date: Fri, 6 May 2022 18:11:35 +0200 Subject: [PATCH 02/21] Convert temperature only when displaying it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit And NOT when importing it into the module. Internally we always use metric °C --- .../default/weather/providers/envcanada.js | 29 ++++++------------- .../default/weather/providers/ukmetoffice.js | 15 +++------- .../weather/providers/ukmetofficedatahub.js | 19 +++++------- .../default/weather/providers/weathergov.js | 20 ++++--------- modules/default/weather/weather.js | 9 +++++- 5 files changed, 34 insertions(+), 58 deletions(-) diff --git a/modules/default/weather/providers/envcanada.js b/modules/default/weather/providers/envcanada.js index 0d3e34ae95..fd65306672 100644 --- a/modules/default/weather/providers/envcanada.js +++ b/modules/default/weather/providers/envcanada.js @@ -161,7 +161,7 @@ WeatherProvider.register("envcanada", { // EC finds no current temp. In this scenario, MM will end up displaying a current temp of null; if (ECdoc.querySelector("siteData currentConditions temperature").textContent) { - currentWeather.temperature = this.convertTemp(ECdoc.querySelector("siteData currentConditions temperature").textContent); + currentWeather.temperature = ECdoc.querySelector("siteData currentConditions temperature").textContent; this.cacheCurrentTemp = currentWeather.temperature; } else { currentWeather.temperature = this.cacheCurrentTemp; @@ -190,11 +190,11 @@ WeatherProvider.register("envcanada", { currentWeather.feelsLikeTemp = currentWeather.temperature; if (ECdoc.querySelector("siteData currentConditions windChill")) { - currentWeather.feelsLikeTemp = this.convertTemp(ECdoc.querySelector("siteData currentConditions windChill").textContent); + currentWeather.feelsLikeTemp = ECdoc.querySelector("siteData currentConditions windChill").textContent; } if (ECdoc.querySelector("siteData currentConditions humidex")) { - currentWeather.feelsLikeTemp = this.convertTemp(ECdoc.querySelector("siteData currentConditions humidex").textContent); + currentWeather.feelsLikeTemp = ECdoc.querySelector("siteData currentConditions humidex").textContent; } } @@ -399,7 +399,7 @@ WeatherProvider.register("envcanada", { // Capture the temperature - weather.temperature = this.convertTemp(hourGroup[stepHour].querySelector("temperature").textContent); + weather.temperature = hourGroup[stepHour].querySelector("temperature").textContent; // Capture Likelihood of Precipitation (LOP) and unit-of-measure values @@ -450,7 +450,7 @@ WeatherProvider.register("envcanada", { weather.minTemperature = this.todayTempCacheMin; weather.maxTemperature = this.todayTempCacheMax; } else { - weather.minTemperature = this.convertTemp(currentTemp); + weather.minTemperature = currentTemp; weather.maxTemperature = weather.minTemperature; } } @@ -463,14 +463,14 @@ WeatherProvider.register("envcanada", { // if (todayClass === "low") { - weather.minTemperature = this.convertTemp(todayTemp); + weather.minTemperature = todayTemp; if (today === 0 && fullDay === true) { this.todayTempCacheMin = weather.minTemperature; } } if (todayClass === "high") { - weather.maxTemperature = this.convertTemp(todayTemp); + weather.maxTemperature = todayTemp; if (today === 0 && fullDay === true) { this.todayTempCacheMax = weather.maxTemperature; } @@ -482,11 +482,11 @@ WeatherProvider.register("envcanada", { if (fullDay === true) { if (nextClass === "low") { - weather.minTemperature = this.convertTemp(nextTemp); + weather.minTemperature = nextTemp; } if (nextClass === "high") { - weather.maxTemperature = this.convertTemp(nextTemp); + weather.maxTemperature = nextTemp; } } }, @@ -539,17 +539,6 @@ WeatherProvider.register("envcanada", { // // Unit conversions // - // - // Convert C to F temps - // - convertTemp(temp) { - if (this.config.tempUnits === "imperial") { - return 1.8 * temp + 32; - } else { - return temp; - } - }, - // // Convert km/h to mph // diff --git a/modules/default/weather/providers/ukmetoffice.js b/modules/default/weather/providers/ukmetoffice.js index 23ec29bfdb..134ceb6617 100644 --- a/modules/default/weather/providers/ukmetoffice.js +++ b/modules/default/weather/providers/ukmetoffice.js @@ -103,8 +103,8 @@ WeatherProvider.register("ukmetoffice", { if (timeInMins >= p && timeInMins - 180 < p) { // finally got the one we want, so populate weather object currentWeather.humidity = rep.H; - currentWeather.temperature = this.convertTemp(rep.T); - currentWeather.feelsLikeTemp = this.convertTemp(rep.F); + currentWeather.temperature = rep.T; + currentWeather.feelsLikeTemp = rep.F; currentWeather.precipitation = parseInt(rep.Pp); currentWeather.windSpeed = this.convertWindSpeed(rep.S); currentWeather.windDirection = this.convertWindDirection(rep.D); @@ -140,8 +140,8 @@ WeatherProvider.register("ukmetoffice", { if (periodDate.isSameOrAfter(moment.utc().startOf("day"))) { // populate the weather object weather.date = moment.utc(dateStr.substr(0, 10), "YYYY-MM-DD"); - weather.minTemperature = this.convertTemp(period.Rep[1].Nm); - weather.maxTemperature = this.convertTemp(period.Rep[0].Dm); + weather.minTemperature = period.Rep[1].Nm; + weather.maxTemperature = period.Rep[0].Dm; weather.weatherType = this.convertWeatherType(period.Rep[0].W); weather.precipitation = parseInt(period.Rep[0].PPd); @@ -192,13 +192,6 @@ WeatherProvider.register("ukmetoffice", { return weatherTypes.hasOwnProperty(weatherType) ? weatherTypes[weatherType] : null; }, - /* - * Convert temp (from degrees C) if required - */ - convertTemp(tempInC) { - return this.tempUnits === "imperial" ? (tempInC * 9) / 5 + 32 : tempInC; - }, - /* * Convert wind speed (from mph to m/s or km/h) if required */ diff --git a/modules/default/weather/providers/ukmetofficedatahub.js b/modules/default/weather/providers/ukmetofficedatahub.js index 508d700d8c..3c694b538b 100644 --- a/modules/default/weather/providers/ukmetofficedatahub.js +++ b/modules/default/weather/providers/ukmetofficedatahub.js @@ -130,15 +130,15 @@ WeatherProvider.register("ukmetofficedatahub", { currentWeather.date = forecastTime; currentWeather.windSpeed = this.convertWindSpeed(forecastDataHours[hour].windSpeed10m); currentWeather.windDirection = forecastDataHours[hour].windDirectionFrom10m; - currentWeather.temperature = this.convertTemp(forecastDataHours[hour].screenTemperature); - currentWeather.minTemperature = this.convertTemp(forecastDataHours[hour].minScreenAirTemp); - currentWeather.maxTemperature = this.convertTemp(forecastDataHours[hour].maxScreenAirTemp); + currentWeather.temperature = forecastDataHours[hour].screenTemperature; + currentWeather.minTemperature = forecastDataHours[hour].minScreenAirTemp; + currentWeather.maxTemperature = forecastDataHours[hour].maxScreenAirTemp; currentWeather.weatherType = this.convertWeatherType(forecastDataHours[hour].significantWeatherCode); currentWeather.humidity = forecastDataHours[hour].screenRelativeHumidity; currentWeather.rain = forecastDataHours[hour].totalPrecipAmount; currentWeather.snow = forecastDataHours[hour].totalSnowAmount; currentWeather.precipitation = forecastDataHours[hour].probOfPrecipitation; - currentWeather.feelsLikeTemp = this.convertTemp(forecastDataHours[hour].feelsLikeTemperature); + currentWeather.feelsLikeTemp = forecastDataHours[hour].feelsLikeTemperature; // Pass on full details, so they can be used in custom templates // Note the units of the supplied data when using this (see top of file) @@ -202,8 +202,8 @@ WeatherProvider.register("ukmetofficedatahub", { // Check if forecast is for today or in the future (i.e., ignore yesterday's forecast) if (forecastDate.isSameOrAfter(today)) { forecastWeather.date = forecastDate; - forecastWeather.minTemperature = this.convertTemp(forecastDataDays[day].nightMinScreenTemperature); - forecastWeather.maxTemperature = this.convertTemp(forecastDataDays[day].dayMaxScreenTemperature); + forecastWeather.minTemperature = forecastDataDays[day].nightMinScreenTemperature; + forecastWeather.maxTemperature = forecastDataDays[day].dayMaxScreenTemperature; // Using daytime forecast values forecastWeather.windSpeed = this.convertWindSpeed(forecastDataDays[day].midday10MWindSpeed); @@ -214,7 +214,7 @@ WeatherProvider.register("ukmetofficedatahub", { forecastWeather.humidity = forecastDataDays[day].middayRelativeHumidity; forecastWeather.rain = forecastDataDays[day].dayProbabilityOfRain; forecastWeather.snow = forecastDataDays[day].dayProbabilityOfSnow; - forecastWeather.feelsLikeTemp = this.convertTemp(forecastDataDays[day].dayMaxFeelsLikeTemp); + forecastWeather.feelsLikeTemp = forecastDataDays[day].dayMaxFeelsLikeTemp; // Pass on full details, so they can be used in custom templates // Note the units of the supplied data when using this (see top of file) @@ -232,11 +232,6 @@ WeatherProvider.register("ukmetofficedatahub", { this.fetchedLocationName = name; }, - // Convert temperatures to Fahrenheit (from degrees C), if required - convertTemp(tempInC) { - return this.config.tempUnits === "imperial" ? (tempInC * 9) / 5 + 32 : tempInC; - }, - // Convert wind speed from metres per second // To keep the supplied metres per second units, use "mps" // To use kilometres per hour, use "kph" diff --git a/modules/default/weather/providers/weathergov.js b/modules/default/weather/providers/weathergov.js index eb2c42798c..2f4ba04253 100644 --- a/modules/default/weather/providers/weathergov.js +++ b/modules/default/weather/providers/weathergov.js @@ -204,21 +204,21 @@ WeatherProvider.register("weathergov", { const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); currentWeather.date = moment(currentWeatherData.timestamp); - currentWeather.temperature = this.convertTemp(currentWeatherData.temperature.value); + currentWeather.temperature = currentWeatherData.temperature.value; currentWeather.windSpeed = this.convertSpeed(currentWeatherData.windSpeed.value); currentWeather.windDirection = currentWeatherData.windDirection.value; - currentWeather.minTemperature = this.convertTemp(currentWeatherData.minTemperatureLast24Hours.value); - currentWeather.maxTemperature = this.convertTemp(currentWeatherData.maxTemperatureLast24Hours.value); + currentWeather.minTemperature = currentWeatherData.minTemperatureLast24Hours.value; + currentWeather.maxTemperature = currentWeatherData.maxTemperatureLast24Hours.value; currentWeather.humidity = Math.round(currentWeatherData.relativeHumidity.value); currentWeather.rain = null; currentWeather.snow = null; currentWeather.precipitation = this.convertLength(currentWeatherData.precipitationLastHour.value); if (currentWeatherData.heatIndex.value !== null) { - currentWeather.feelsLikeTemp = this.convertTemp(currentWeatherData.heatIndex.value); + currentWeather.feelsLikeTemp = currentWeatherData.heatIndex.value; } else if (currentWeatherData.windChill.value !== null) { - currentWeather.feelsLikeTemp = this.convertTemp(currentWeatherData.windChill.value); + currentWeather.feelsLikeTemp = currentWeatherData.windChill.value; } else { - currentWeather.feelsLikeTemp = this.convertTemp(currentWeatherData.temperature.value); + currentWeather.feelsLikeTemp = currentWeatherData.temperature.value; } // determine the sunrise/sunset times - not supplied in weather.gov data currentWeather.updateSunTime(this.config.lat, this.config.lon); @@ -298,14 +298,6 @@ WeatherProvider.register("weathergov", { /* * Unit conversions */ - // conversion to fahrenheit - convertTemp(temp) { - if (this.config.tempUnits === "imperial") { - return (9 / 5) * temp + 32; - } else { - return temp; - } - }, // conversion to mph or kmh convertSpeed(metSec) { if (this.config.windUnits === "imperial") { diff --git a/modules/default/weather/weather.js b/modules/default/weather/weather.js index 6a02d182f9..5137a608fe 100644 --- a/modules/default/weather/weather.js +++ b/modules/default/weather/weather.js @@ -195,6 +195,13 @@ Module.register("weather", { return roundValue === "-0" ? 0 : roundValue; }, + /* + * Convert temp (from degrees C) if required + */ + convertTemp(tempInC) { + return this.config.tempUnits === "imperial" ? tempInC * 1.8 + 32 : tempInC; + }, + addFilters() { this.nunjucksEnvironment().addFilter( "formatTime", @@ -222,7 +229,7 @@ Module.register("weather", { function (value, type) { if (type === "temperature") { if (this.config.tempUnits === "metric" || this.config.tempUnits === "imperial") { - value += "°"; + value = this.convertTemp(value) + "°"; } if (this.config.degreeLabel) { if (this.config.tempUnits === "metric") { From 1d0d8deea4c255a87a7af9aa6f159c23ba4e1428 Mon Sep 17 00:00:00 2001 From: rejas Date: Fri, 6 May 2022 19:49:27 +0200 Subject: [PATCH 03/21] Convert windspeed only when displaying it --- modules/default/weather/current.njk | 10 +----- .../default/weather/providers/envcanada.js | 16 +-------- .../default/weather/providers/ukmetoffice.js | 9 +---- .../weather/providers/ukmetofficedatahub.js | 20 ++--------- .../default/weather/providers/weathergov.js | 14 +------- modules/default/weather/weather.js | 35 +++++++++++++++++-- modules/default/weather/weatherobject.js | 11 ++---- 7 files changed, 41 insertions(+), 74 deletions(-) diff --git a/modules/default/weather/current.njk b/modules/default/weather/current.njk index bfeb0b8f13..ae542caa9a 100644 --- a/modules/default/weather/current.njk +++ b/modules/default/weather/current.njk @@ -3,15 +3,7 @@
- {% if config.useBeaufort %} - {{ current.beaufortWindSpeed() | round }} - {% else %} - {% if config.useKmh %} - {{ current.kmhWindSpeed() | round }} - {% else %} - {{ current.windSpeed | round }} - {% endif %} - {% endif %} + {{ current.windSpeed | unit("wind") | round }} {% if config.showWindDirection %} {% if config.showWindDirectionAsArrow %} diff --git a/modules/default/weather/providers/envcanada.js b/modules/default/weather/providers/envcanada.js index fd65306672..301eee0b57 100644 --- a/modules/default/weather/providers/envcanada.js +++ b/modules/default/weather/providers/envcanada.js @@ -167,7 +167,7 @@ WeatherProvider.register("envcanada", { currentWeather.temperature = this.cacheCurrentTemp; } - currentWeather.windSpeed = this.convertWind(ECdoc.querySelector("siteData currentConditions wind speed").textContent); + currentWeather.windSpeed = ECdoc.querySelector("siteData currentConditions wind speed").textContent; currentWeather.windDirection = ECdoc.querySelector("siteData currentConditions wind bearing").textContent; @@ -536,20 +536,6 @@ WeatherProvider.register("envcanada", { } }, - // - // Unit conversions - // - // - // Convert km/h to mph - // - convertWind(kilo) { - if (this.config.windUnits === "imperial") { - return kilo / 1.609344; - } else { - return kilo; - } - }, - // // Convert the icons to a more usable name. // diff --git a/modules/default/weather/providers/ukmetoffice.js b/modules/default/weather/providers/ukmetoffice.js index 134ceb6617..bf1df9b657 100644 --- a/modules/default/weather/providers/ukmetoffice.js +++ b/modules/default/weather/providers/ukmetoffice.js @@ -106,7 +106,7 @@ WeatherProvider.register("ukmetoffice", { currentWeather.temperature = rep.T; currentWeather.feelsLikeTemp = rep.F; currentWeather.precipitation = parseInt(rep.Pp); - currentWeather.windSpeed = this.convertWindSpeed(rep.S); + currentWeather.windSpeed = this.convertWindToMetric(rep.S); currentWeather.windDirection = this.convertWindDirection(rep.D); currentWeather.weatherType = this.convertWeatherType(rep.W); } @@ -192,13 +192,6 @@ WeatherProvider.register("ukmetoffice", { return weatherTypes.hasOwnProperty(weatherType) ? weatherTypes[weatherType] : null; }, - /* - * Convert wind speed (from mph to m/s or km/h) if required - */ - convertWindSpeed(windInMph) { - return this.windUnits === "metric" ? (this.useKmh ? windInMph * 1.60934 : windInMph / 2.23694) : windInMph; - }, - /* * Convert the wind direction cardinal to value */ diff --git a/modules/default/weather/providers/ukmetofficedatahub.js b/modules/default/weather/providers/ukmetofficedatahub.js index 3c694b538b..97e77c51a3 100644 --- a/modules/default/weather/providers/ukmetofficedatahub.js +++ b/modules/default/weather/providers/ukmetofficedatahub.js @@ -52,7 +52,7 @@ WeatherProvider.register("ukmetofficedatahub", { apiSecret: "", lat: 0, lon: 0, - windUnits: "mph" + windUnits: "imperial" }, // Build URL with query strings according to DataHub API (https://metoffice.apiconnect.ibmcloud.com/metoffice/production/api) @@ -128,7 +128,7 @@ WeatherProvider.register("ukmetofficedatahub", { let forecastTime = moment.utc(forecastDataHours[hour].time); if (nowUtc.isSameOrAfter(forecastTime) && nowUtc.isBefore(moment(forecastTime.add(1, "h")))) { currentWeather.date = forecastTime; - currentWeather.windSpeed = this.convertWindSpeed(forecastDataHours[hour].windSpeed10m); + currentWeather.windSpeed = forecastDataHours[hour].windSpeed10m; currentWeather.windDirection = forecastDataHours[hour].windDirectionFrom10m; currentWeather.temperature = forecastDataHours[hour].screenTemperature; currentWeather.minTemperature = forecastDataHours[hour].minScreenAirTemp; @@ -232,22 +232,6 @@ WeatherProvider.register("ukmetofficedatahub", { this.fetchedLocationName = name; }, - // Convert wind speed from metres per second - // To keep the supplied metres per second units, use "mps" - // To use kilometres per hour, use "kph" - // Else assumed imperial and the value is returned in miles per hour (a Met Office user is likely to be UK-based) - convertWindSpeed(windInMpS) { - if (this.config.windUnits === "mps") { - return windInMpS; - } - - if (this.config.windUnits === "kph" || this.config.windUnits === "metric" || this.config.useKmh) { - return windInMpS * 3.6; - } - - return windInMpS * 2.23694; - }, - // Match the Met Office "significant weather code" to a weathericons.css icon // Use: https://metoffice.apiconnect.ibmcloud.com/metoffice/production/node/264 // and: https://erikflowers.github.io/weather-icons/ diff --git a/modules/default/weather/providers/weathergov.js b/modules/default/weather/providers/weathergov.js index 2f4ba04253..5a963ac7f9 100644 --- a/modules/default/weather/providers/weathergov.js +++ b/modules/default/weather/providers/weathergov.js @@ -205,7 +205,7 @@ WeatherProvider.register("weathergov", { currentWeather.date = moment(currentWeatherData.timestamp); currentWeather.temperature = currentWeatherData.temperature.value; - currentWeather.windSpeed = this.convertSpeed(currentWeatherData.windSpeed.value); + currentWeather.windSpeed = currentWeatherData.windSpeed.value; currentWeather.windDirection = currentWeatherData.windDirection.value; currentWeather.minTemperature = currentWeatherData.minTemperatureLast24Hours.value; currentWeather.maxTemperature = currentWeatherData.maxTemperatureLast24Hours.value; @@ -298,18 +298,6 @@ WeatherProvider.register("weathergov", { /* * Unit conversions */ - // conversion to mph or kmh - convertSpeed(metSec) { - if (this.config.windUnits === "imperial") { - return metSec * 2.23694; - } else { - if (this.config.useKmh) { - return metSec * 3.6; - } else { - return metSec; - } - } - }, // conversion to inches convertLength(meters) { if (this.config.units === "imperial") { diff --git a/modules/default/weather/weather.js b/modules/default/weather/weather.js index 5137a608fe..72ecbe93ef 100644 --- a/modules/default/weather/weather.js +++ b/modules/default/weather/weather.js @@ -195,13 +195,41 @@ Module.register("weather", { return roundValue === "-0" ? 0 : roundValue; }, - /* + /** * Convert temp (from degrees C) if required + * + * @param tempInC + * @returns {number|*} */ convertTemp(tempInC) { return this.config.tempUnits === "imperial" ? tempInC * 1.8 + 32 : tempInC; }, + convertWind(windInMS) { + if (this.config.useBeaufort) { + return this.beaufortWindSpeed(windInMS); + } else if (this.config.useKmh) { + return (windInMS * 60 * 60) / 1000; + } else if (this.config.windUnits === "imperial") return windInMS * 2.23694; + + return windInMS; + }, + + /** + * TODO + * @returns {number} + */ + beaufortWindSpeed(speedInMS) { + const windInKmh = this.config.windUnits === "imperial" ? speedInMS * 1.609344 : this.config.useKmh ? speedInMS : (speedInMS * 60 * 60) / 1000; + const speeds = [1, 5, 11, 19, 28, 38, 49, 61, 74, 88, 102, 117, 1000]; + for (const [index, speed] of speeds.entries()) { + if (speed > windInKmh) { + return index; + } + } + return 12; + }, + addFilters() { this.nunjucksEnvironment().addFilter( "formatTime", @@ -252,8 +280,11 @@ Module.register("weather", { } } else if (type === "humidity") { value += "%"; + } else if (type === "wind") { + if (this.config.windUnits === "metric" || this.config.tempUnits === "imperial") { + value = this.convertWind(value); + } } - return value; }.bind(this) ); diff --git a/modules/default/weather/weatherobject.js b/modules/default/weather/weatherobject.js index 8df71721b4..85cff1e58c 100644 --- a/modules/default/weather/weatherobject.js +++ b/modules/default/weather/weatherobject.js @@ -78,15 +78,8 @@ class WeatherObject { } } - beaufortWindSpeed() { - const windInKmh = this.windUnits === "imperial" ? this.windSpeed * 1.609344 : this.useKmh ? this.windSpeed : (this.windSpeed * 60 * 60) / 1000; - const speeds = [1, 5, 11, 19, 28, 38, 49, 61, 74, 88, 102, 117, 1000]; - for (const [index, speed] of speeds.entries()) { - if (speed > windInKmh) { - return index; - } - } - return 12; + convertWindToMetric(mph) { + return mph / 2.2369362920544; } kmhWindSpeed() { From a42523372f87bc009b3598d91ccc6427f2a09d6e Mon Sep 17 00:00:00 2001 From: rejas Date: Sat, 7 May 2022 11:27:28 +0200 Subject: [PATCH 04/21] Use metric units when fetching data in openweathermap we convert it to imperial when needed from the ui --- modules/default/weather/providers/openweathermap.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/default/weather/providers/openweathermap.js b/modules/default/weather/providers/openweathermap.js index d631404ff8..acb76558ea 100644 --- a/modules/default/weather/providers/openweathermap.js +++ b/modules/default/weather/providers/openweathermap.js @@ -474,7 +474,7 @@ WeatherProvider.register("openweathermap", { return; } - params += "&units=" + this.config.units; + params += "&units=metric"; // WeatherProviders should use metric internally and use the units only for when displaying data params += "&lang=" + this.config.lang; params += "&APPID=" + this.config.apiKey; From f33352116de560c406ed102ee65a56a3e79d97dd Mon Sep 17 00:00:00 2001 From: veeck Date: Wed, 17 Aug 2022 17:52:37 +0200 Subject: [PATCH 05/21] Make weatherbit also fetch metric units only --- modules/default/weather/providers/weatherbit.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/modules/default/weather/providers/weatherbit.js b/modules/default/weather/providers/weatherbit.js index 7c8010a837..c8304d80b7 100644 --- a/modules/default/weather/providers/weatherbit.js +++ b/modules/default/weather/providers/weatherbit.js @@ -23,11 +23,6 @@ WeatherProvider.register("weatherbit", { lon: 0 }, - units: { - imperial: "I", - metric: "M" - }, - fetchedLocation: function () { return this.fetchedLocationName || ""; }, @@ -95,8 +90,7 @@ WeatherProvider.register("weatherbit", { // Create a URL from the config and base URL. getUrl() { - const units = this.units[this.config.units] || "auto"; - return `${this.config.apiBase}${this.config.weatherEndpoint}?lat=${this.config.lat}&lon=${this.config.lon}&units=${units}&key=${this.config.apiKey}`; + return `${this.config.apiBase}${this.config.weatherEndpoint}?lat=${this.config.lat}&lon=${this.config.lon}&units=M&key=${this.config.apiKey}`; }, // Implement WeatherDay generator. From d2e4e51ed3808e3afbaf7f55d430c4dc137456fb Mon Sep 17 00:00:00 2001 From: veeck Date: Thu, 18 Aug 2022 23:25:40 +0200 Subject: [PATCH 06/21] Make darksky also fetch metric units only --- modules/default/weather/providers/darksky.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/modules/default/weather/providers/darksky.js b/modules/default/weather/providers/darksky.js index b5bf20e3b2..cb0247a567 100644 --- a/modules/default/weather/providers/darksky.js +++ b/modules/default/weather/providers/darksky.js @@ -26,11 +26,6 @@ WeatherProvider.register("darksky", { lon: 0 }, - units: { - imperial: "us", - metric: "si" - }, - fetchCurrentWeather() { this.fetchData(this.getUrl()) .then((data) => { @@ -67,8 +62,7 @@ WeatherProvider.register("darksky", { // Create a URL from the config and base URL. getUrl() { - const units = this.units[this.config.units] || "auto"; - return `${this.config.apiBase}${this.config.weatherEndpoint}/${this.config.apiKey}/${this.config.lat},${this.config.lon}?units=${units}&lang=${this.config.lang}`; + return `${this.config.apiBase}${this.config.weatherEndpoint}/${this.config.apiKey}/${this.config.lat},${this.config.lon}?units=si&lang=${this.config.lang}`; }, // Implement WeatherDay generator. From 1b0dfc98089731ef13fb1213c590c22e8e0788b2 Mon Sep 17 00:00:00 2001 From: veeck Date: Sat, 27 Aug 2022 16:45:52 +0200 Subject: [PATCH 07/21] Fix documentation and forecast in ukmetofficedata provider --- .../default/weather/providers/ukmetofficedatahub.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/modules/default/weather/providers/ukmetofficedatahub.js b/modules/default/weather/providers/ukmetofficedatahub.js index 97e77c51a3..5e78cb6f13 100644 --- a/modules/default/weather/providers/ukmetofficedatahub.js +++ b/modules/default/weather/providers/ukmetofficedatahub.js @@ -20,11 +20,9 @@ * weatherProvider: "ukmetofficedatahub", * apiBase: "https://api-metoffice.apiconnect.ibmcloud.com/metoffice/production/v0/forecasts/point/", * apiKey: "[YOUR API KEY]", - * apiSecret: "[YOUR API SECRET]]", + * apiSecret: "[YOUR API SECRET]", * lat: [LATITUDE (DECIMAL)], - * lon: [LONGITUDE (DECIMAL)], - * windUnits: "mps" | "kph" | "mph" (default) - * tempUnits: "imperial" | "metric" (default) + * lon: [LONGITUDE (DECIMAL)] * * At time of writing, free accounts are limited to 360 requests a day per service (hourly, 3hourly, daily); take this in mind when * setting your update intervals. For reference, 360 requests per day is once every 4 minutes. @@ -51,8 +49,7 @@ WeatherProvider.register("ukmetofficedatahub", { apiKey: "", apiSecret: "", lat: 0, - lon: 0, - windUnits: "imperial" + lon: 0 }, // Build URL with query strings according to DataHub API (https://metoffice.apiconnect.ibmcloud.com/metoffice/production/api) @@ -206,7 +203,7 @@ WeatherProvider.register("ukmetofficedatahub", { forecastWeather.maxTemperature = forecastDataDays[day].dayMaxScreenTemperature; // Using daytime forecast values - forecastWeather.windSpeed = this.convertWindSpeed(forecastDataDays[day].midday10MWindSpeed); + forecastWeather.windSpeed = forecastDataDays[day].midday10MWindSpeed; forecastWeather.windDirection = forecastDataDays[day].midday10MWindDirection; forecastWeather.weatherType = this.convertWeatherType(forecastDataDays[day].daySignificantWeatherCode); forecastWeather.precipitation = forecastDataDays[day].dayProbabilityOfPrecipitation; From 9c7ab71c4834d3f090c6d729a1cb0212a82ad9d0 Mon Sep 17 00:00:00 2001 From: veeck Date: Wed, 19 Oct 2022 09:18:59 +0200 Subject: [PATCH 08/21] Fix ukmetoffice and move helper function into weatherobject --- .../default/weather/providers/ukmetoffice.js | 35 ++----------------- modules/default/weather/weatherobject.js | 26 ++++++++++++++ 2 files changed, 28 insertions(+), 33 deletions(-) diff --git a/modules/default/weather/providers/ukmetoffice.js b/modules/default/weather/providers/ukmetoffice.js index bf1df9b657..dc38a556f3 100644 --- a/modules/default/weather/providers/ukmetoffice.js +++ b/modules/default/weather/providers/ukmetoffice.js @@ -21,11 +21,6 @@ WeatherProvider.register("ukmetoffice", { apiKey: "" }, - units: { - imperial: "us", - metric: "si" - }, - // Overwrite the fetchCurrentWeather method. fetchCurrentWeather() { this.fetchData(this.getUrl("3hourly")) @@ -106,8 +101,8 @@ WeatherProvider.register("ukmetoffice", { currentWeather.temperature = rep.T; currentWeather.feelsLikeTemp = rep.F; currentWeather.precipitation = parseInt(rep.Pp); - currentWeather.windSpeed = this.convertWindToMetric(rep.S); - currentWeather.windDirection = this.convertWindDirection(rep.D); + currentWeather.windSpeed = currentWeather.convertWindToMetric(rep.S); + currentWeather.windDirection = currentWeather.valueWindDirection(rep.D); currentWeather.weatherType = this.convertWeatherType(rep.W); } } @@ -192,32 +187,6 @@ WeatherProvider.register("ukmetoffice", { return weatherTypes.hasOwnProperty(weatherType) ? weatherTypes[weatherType] : null; }, - /* - * Convert the wind direction cardinal to value - */ - convertWindDirection(windDirection) { - const windCardinals = { - N: 0, - NNE: 22, - NE: 45, - ENE: 67, - E: 90, - ESE: 112, - SE: 135, - SSE: 157, - S: 180, - SSW: 202, - SW: 225, - WSW: 247, - W: 270, - WNW: 292, - NW: 315, - NNW: 337 - }; - - return windCardinals.hasOwnProperty(windDirection) ? windCardinals[windDirection] : null; - }, - /** * Generates an url with api parameters based on the config. * diff --git a/modules/default/weather/weatherobject.js b/modules/default/weather/weatherobject.js index 85cff1e58c..4ee50d7b90 100644 --- a/modules/default/weather/weatherobject.js +++ b/modules/default/weather/weatherobject.js @@ -78,6 +78,32 @@ class WeatherObject { } } + /* + * Convert the wind direction cardinal to value + */ + valueWindDirection(windDirection) { + const windCardinals = { + N: 0, + NNE: 22, + NE: 45, + ENE: 67, + E: 90, + ESE: 112, + SE: 135, + SSE: 157, + S: 180, + SSW: 202, + SW: 225, + WSW: 247, + W: 270, + WNW: 292, + NW: 315, + NNW: 337 + }; + + return windCardinals.hasOwnProperty(windDirection) ? windCardinals[windDirection] : null; + } + convertWindToMetric(mph) { return mph / 2.2369362920544; } From e1f6f4130c5b6d6057dc1f2f4e85376a65abec3f Mon Sep 17 00:00:00 2001 From: veeck Date: Wed, 19 Oct 2022 09:19:45 +0200 Subject: [PATCH 09/21] Add tests for new conversion functions --- tests/unit/functions/weather_object_spec.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/unit/functions/weather_object_spec.js b/tests/unit/functions/weather_object_spec.js index 4eb6a61517..17b22cf2be 100644 --- a/tests/unit/functions/weather_object_spec.js +++ b/tests/unit/functions/weather_object_spec.js @@ -25,6 +25,14 @@ describe("WeatherObject", () => { expect(weatherobject.isDayTime()).toBe(false); }); + it("should convert windspeed correctly from mph to mps", () => { + expect(Math.round(weatherobject.convertWindToMetric(93.951324266285))).toBe(42); + }); + + it("should convert wind direction correctly from cardinal to value", () => { + expect(weatherobject.valueWindDirection("SSE")).toBe(157); + }); + afterAll(() => { moment.tz.setDefault(originalTimeZone); }); From 220471b0d61c490a3c848973ea7e3fd7898e381d Mon Sep 17 00:00:00 2001 From: veeck Date: Mon, 29 Aug 2022 17:07:49 +0200 Subject: [PATCH 10/21] Use metric units when calling weathergov api also convert wind to m/s remove dead code --- .../default/weather/providers/weathergov.js | 32 ++----------------- modules/default/weather/weatherobject.js | 4 +++ 2 files changed, 7 insertions(+), 29 deletions(-) diff --git a/modules/default/weather/providers/weathergov.js b/modules/default/weather/providers/weathergov.js index 5a963ac7f9..5fa4a60408 100644 --- a/modules/default/weather/providers/weathergov.js +++ b/modules/default/weather/providers/weathergov.js @@ -131,8 +131,8 @@ WeatherProvider.register("weathergov", { } this.fetchedLocationName = data.properties.relativeLocation.properties.city + ", " + data.properties.relativeLocation.properties.state; Log.log("Forecast location is " + this.fetchedLocationName); - this.forecastURL = data.properties.forecast; - this.forecastHourlyURL = data.properties.forecastHourly; + this.forecastURL = data.properties.forecast + "?units=si"; + this.forecastHourlyURL = data.properties.forecastHourly + "?units=si"; this.forecastGridDataURL = data.properties.forecastGridData; this.observationStationsURL = data.properties.observationStations; // with this URL, we chain another promise for the station obs URL @@ -205,7 +205,7 @@ WeatherProvider.register("weathergov", { currentWeather.date = moment(currentWeatherData.timestamp); currentWeather.temperature = currentWeatherData.temperature.value; - currentWeather.windSpeed = currentWeatherData.windSpeed.value; + currentWeather.windSpeed = currentWeather.convertWindToMs(currentWeatherData.windSpeed.value); currentWeather.windDirection = currentWeatherData.windDirection.value; currentWeather.minTemperature = currentWeatherData.minTemperatureLast24Hours.value; currentWeather.maxTemperature = currentWeatherData.maxTemperatureLast24Hours.value; @@ -375,31 +375,5 @@ WeatherProvider.register("weathergov", { } return null; - }, - - /* - Convert the direction into Degrees - */ - convertWindDirection(windDirection) { - const windCardinals = { - N: 0, - NNE: 22, - NE: 45, - ENE: 67, - E: 90, - ESE: 112, - SE: 135, - SSE: 157, - S: 180, - SSW: 202, - SW: 225, - WSW: 247, - W: 270, - WNW: 292, - NW: 315, - NNW: 337 - }; - - return windCardinals.hasOwnProperty(windDirection) ? windCardinals[windDirection] : null; } }); diff --git a/modules/default/weather/weatherobject.js b/modules/default/weather/weatherobject.js index 4ee50d7b90..087ea39652 100644 --- a/modules/default/weather/weatherobject.js +++ b/modules/default/weather/weatherobject.js @@ -108,6 +108,10 @@ class WeatherObject { return mph / 2.2369362920544; } + convertWindToMs(kmh) { + return kmh * 0.27777777777778; + } + kmhWindSpeed() { return this.windUnits === "imperial" ? this.windSpeed * 1.609344 : (this.windSpeed * 60 * 60) / 1000; } From 2bc71095fe3b2a9cabcaa054fca2182fb7737092 Mon Sep 17 00:00:00 2001 From: veeck Date: Mon, 29 Aug 2022 17:38:53 +0200 Subject: [PATCH 11/21] Fix wind speed display --- modules/default/weather/weather.js | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/modules/default/weather/weather.js b/modules/default/weather/weather.js index 72ecbe93ef..c874bc5131 100644 --- a/modules/default/weather/weather.js +++ b/modules/default/weather/weather.js @@ -198,8 +198,8 @@ Module.register("weather", { /** * Convert temp (from degrees C) if required * - * @param tempInC - * @returns {number|*} + * @param {number} tempInC + * @returns {number} */ convertTemp(tempInC) { return this.config.tempUnits === "imperial" ? tempInC * 1.8 + 32 : tempInC; @@ -216,7 +216,9 @@ Module.register("weather", { }, /** - * TODO + * Convert wind (from m/s) if required + * + * @param {number} speedInMS * @returns {number} */ beaufortWindSpeed(speedInMS) { @@ -256,9 +258,7 @@ Module.register("weather", { "unit", function (value, type) { if (type === "temperature") { - if (this.config.tempUnits === "metric" || this.config.tempUnits === "imperial") { - value = this.convertTemp(value) + "°"; - } + value = this.convertTemp(value) + "°"; if (this.config.degreeLabel) { if (this.config.tempUnits === "metric") { value += "C"; @@ -281,9 +281,7 @@ Module.register("weather", { } else if (type === "humidity") { value += "%"; } else if (type === "wind") { - if (this.config.windUnits === "metric" || this.config.tempUnits === "imperial") { - value = this.convertWind(value); - } + value = this.convertWind(value); } return value; }.bind(this) From 89ab15a1c504184b86006fb0722807c17687c79f Mon Sep 17 00:00:00 2001 From: veeck Date: Mon, 29 Aug 2022 18:06:55 +0200 Subject: [PATCH 12/21] Convert wind kmh from envcanada to m/s fix some typos too --- modules/default/weather/providers/envcanada.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/modules/default/weather/providers/envcanada.js b/modules/default/weather/providers/envcanada.js index 301eee0b57..d843ff504f 100644 --- a/modules/default/weather/providers/envcanada.js +++ b/modules/default/weather/providers/envcanada.js @@ -11,13 +11,13 @@ * https://dd.weather.gc.ca/citypage_weather/schema/ * https://eccc-msc.github.io/open-data/msc-datamart/readme_en/ * - * This module supports Canadian locations only and requires 2 additional config parms: + * This module supports Canadian locations only and requires 2 additional config parameters: * * siteCode - the city/town unique identifier for which weather is to be displayed. Format is 's0000000'. * * provCode - the 2-character province code for the selected city/town. * - * Example: for Toronto, Ontario, the following parms would be used + * Example: for Toronto, Ontario, the following parameters would be used * * siteCode: 's0000458', * provCode: 'ON' @@ -64,10 +64,6 @@ WeatherProvider.register("envcanada", { start: function () { Log.info(`Weather provider: ${this.providerName} started.`); this.setFetchedLocation(this.config.location); - - // Ensure kmH are ignored since these are custom-handled by this Provider - - this.config.useKmh = false; }, // @@ -167,7 +163,7 @@ WeatherProvider.register("envcanada", { currentWeather.temperature = this.cacheCurrentTemp; } - currentWeather.windSpeed = ECdoc.querySelector("siteData currentConditions wind speed").textContent; + currentWeather.windSpeed = currentWeather.convertWindToMs(ECdoc.querySelector("siteData currentConditions wind speed").textContent); currentWeather.windDirection = ECdoc.querySelector("siteData currentConditions wind bearing").textContent; @@ -326,7 +322,7 @@ WeatherProvider.register("envcanada", { days.push(weather); // - // Now do the the rest of the forecast starting at nextDay. We will process each day using 2 EC + // Now do the rest of the forecast starting at nextDay. We will process each day using 2 EC // forecast Elements. This will address the fact that the EC forecast always includes Today and // Tonight for each day. This is why we iterate through the forecast by a a count of 2, with each // iteration looking at the current Element and the next Element. From 9116799fa675b173e30fdf0a036e5a43086629b4 Mon Sep 17 00:00:00 2001 From: veeck Date: Mon, 29 Aug 2022 18:18:59 +0200 Subject: [PATCH 13/21] Cleanup weatherflow call, use metric always also convert km/h to m/s for wind value --- .../default/weather/providers/weatherflow.js | 37 +------------------ 1 file changed, 2 insertions(+), 35 deletions(-) diff --git a/modules/default/weather/providers/weatherflow.js b/modules/default/weather/providers/weatherflow.js index a847fabd06..720686e061 100644 --- a/modules/default/weather/providers/weatherflow.js +++ b/modules/default/weather/providers/weatherflow.js @@ -23,23 +23,6 @@ WeatherProvider.register("weatherflow", { stationid: "" }, - units: { - imperial: { - temp: "f", - wind: "mph", - pressure: "hpa", - precip: "in", - distance: "mi" - }, - metric: { - temp: "c", - wind: "kph", - pressure: "mb", - precip: "mm", - distance: "km" - } - }, - fetchCurrentWeather() { this.fetchData(this.getUrl()) .then((data) => { @@ -48,7 +31,7 @@ WeatherProvider.register("weatherflow", { currentWeather.humidity = data.current_conditions.relative_humidity; currentWeather.temperature = data.current_conditions.air_temperature; - currentWeather.windSpeed = data.current_conditions.wind_avg; + currentWeather.windSpeed = currentWeather.convertWindToMs(data.current_conditions.wind_avg); currentWeather.windDirection = data.current_conditions.wind_direction; currentWeather.weatherType = data.forecast.daily[0].icon; currentWeather.sunrise = moment.unix(data.forecast.daily[0].sunrise); @@ -88,22 +71,6 @@ WeatherProvider.register("weatherflow", { // Create a URL from the config and base URL. getUrl() { - return ( - this.config.apiBase + - "better_forecast?station_id=" + - this.config.stationid + - "&units_temp=" + - this.units[this.config.units].temp + - "&units_wind=" + - this.units[this.config.units].wind + - "&units_pressure=" + - this.units[this.config.units].pressure + - "&units_precip=" + - this.units[this.config.units].precip + - "&units_distance=" + - this.units[this.config.units].distance + - "&token=" + - this.config.token - ); + return `${this.config.apiBase}better_forecast?station_id=${this.config.stationid}&units_temp=c&units_wind=kph&units_pressure=mb&units_precip=mm&units_distance=km&token=${this.config.token}`; } }); From 02ff38ba6ecf5b1a6946497368285eb1eb4f3a07 Mon Sep 17 00:00:00 2001 From: veeck Date: Fri, 16 Sep 2022 23:46:43 +0200 Subject: [PATCH 14/21] Deprecate useKmh and useBeafort, use windUnits instead --- modules/default/weather/providers/darksky.js | 4 +-- .../weather/providers/openweathermap.js | 20 ++++++------ .../default/weather/providers/ukmetoffice.js | 4 +-- .../weather/providers/ukmetofficedatahub.js | 4 +-- .../default/weather/providers/weatherflow.js | 4 +-- .../default/weather/providers/weathergov.js | 6 ++-- modules/default/weather/weather.js | 32 ++++++++++++------- modules/default/weather/weatherobject.js | 12 ++----- 8 files changed, 45 insertions(+), 41 deletions(-) diff --git a/modules/default/weather/providers/darksky.js b/modules/default/weather/providers/darksky.js index cb0247a567..f6a5c2da36 100644 --- a/modules/default/weather/providers/darksky.js +++ b/modules/default/weather/providers/darksky.js @@ -67,7 +67,7 @@ WeatherProvider.register("darksky", { // Implement WeatherDay generator. generateWeatherDayFromCurrentWeather(currentWeatherData) { - const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); currentWeather.date = moment(); currentWeather.humidity = parseFloat(currentWeatherData.currently.humidity); @@ -85,7 +85,7 @@ WeatherProvider.register("darksky", { const days = []; for (const forecast of forecasts) { - const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); weather.date = moment.unix(forecast.time); weather.minTemperature = forecast.temperatureMin; diff --git a/modules/default/weather/providers/openweathermap.js b/modules/default/weather/providers/openweathermap.js index acb76558ea..9d216403a5 100644 --- a/modules/default/weather/providers/openweathermap.js +++ b/modules/default/weather/providers/openweathermap.js @@ -125,7 +125,7 @@ WeatherProvider.register("openweathermap", { * Generate a WeatherObject based on currentWeatherInformation */ generateWeatherObjectFromCurrentWeather(currentWeatherData) { - const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); currentWeather.date = moment.unix(currentWeatherData.dt); currentWeather.humidity = currentWeatherData.main.humidity; @@ -150,7 +150,7 @@ WeatherProvider.register("openweathermap", { return this.fetchForecastDaily(forecasts); } // if weatherEndpoint does not match forecast or forecast/daily, what should be returned? - return [new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh)]; + return [new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits)]; }, /* @@ -161,7 +161,7 @@ WeatherProvider.register("openweathermap", { return this.fetchOnecall(data); } // if weatherEndpoint does not match onecall, what should be returned? - return { current: new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh), hours: [], days: [] }; + return { current: new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits), hours: [], days: [] }; }, /* @@ -177,7 +177,7 @@ WeatherProvider.register("openweathermap", { let snow = 0; // variable for date let date = ""; - let weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + let weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); for (const forecast of forecasts) { if (date !== moment.unix(forecast.dt).format("YYYY-MM-DD")) { @@ -190,7 +190,7 @@ WeatherProvider.register("openweathermap", { // push weather information to days array days.push(weather); // create new weather-object - weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); minTemp = []; maxTemp = []; @@ -253,7 +253,7 @@ WeatherProvider.register("openweathermap", { const days = []; for (const forecast of forecasts) { - const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); weather.date = moment.unix(forecast.dt); weather.minTemperature = forecast.temp.min; @@ -299,7 +299,7 @@ WeatherProvider.register("openweathermap", { let precip = false; // get current weather, if requested - const current = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + const current = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); if (data.hasOwnProperty("current")) { current.date = moment.unix(data.current.dt).utcOffset(data.timezone_offset / 60); current.windSpeed = data.current.wind_speed; @@ -331,7 +331,7 @@ WeatherProvider.register("openweathermap", { current.feelsLikeTemp = data.current.feels_like; } - let weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + let weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); // get hourly weather, if requested const hours = []; @@ -366,7 +366,7 @@ WeatherProvider.register("openweathermap", { } hours.push(weather); - weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); } } @@ -405,7 +405,7 @@ WeatherProvider.register("openweathermap", { } days.push(weather); - weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); } } diff --git a/modules/default/weather/providers/ukmetoffice.js b/modules/default/weather/providers/ukmetoffice.js index dc38a556f3..49c4968473 100644 --- a/modules/default/weather/providers/ukmetoffice.js +++ b/modules/default/weather/providers/ukmetoffice.js @@ -75,7 +75,7 @@ WeatherProvider.register("ukmetoffice", { * Generate a WeatherObject based on currentWeatherInformation */ generateWeatherObjectFromCurrentWeather(currentWeatherData) { - const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); const location = currentWeatherData.SiteRep.DV.Location; // data times are always UTC @@ -125,7 +125,7 @@ WeatherProvider.register("ukmetoffice", { // loop round the (5) periods getting the data // for each period array, Day is [0], Night is [1] for (const period of forecasts.SiteRep.DV.Location.Period) { - const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); // data times are always UTC const dateStr = period.value; diff --git a/modules/default/weather/providers/ukmetofficedatahub.js b/modules/default/weather/providers/ukmetofficedatahub.js index 5e78cb6f13..2258b274bd 100644 --- a/modules/default/weather/providers/ukmetofficedatahub.js +++ b/modules/default/weather/providers/ukmetofficedatahub.js @@ -112,7 +112,7 @@ WeatherProvider.register("ukmetofficedatahub", { // Create a WeatherObject using current weather data (data for the current hour) generateWeatherObjectFromCurrentWeather(currentWeatherData) { - const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); // Extract the actual forecasts let forecastDataHours = currentWeatherData.features[0].properties.timeSeries; @@ -191,7 +191,7 @@ WeatherProvider.register("ukmetofficedatahub", { // Go through each day in the forecasts for (let day in forecastDataDays) { - const forecastWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + const forecastWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); // Get date of forecast let forecastDate = moment.utc(forecastDataDays[day].time); diff --git a/modules/default/weather/providers/weatherflow.js b/modules/default/weather/providers/weatherflow.js index 720686e061..88a4c2cb2d 100644 --- a/modules/default/weather/providers/weatherflow.js +++ b/modules/default/weather/providers/weatherflow.js @@ -26,7 +26,7 @@ WeatherProvider.register("weatherflow", { fetchCurrentWeather() { this.fetchData(this.getUrl()) .then((data) => { - const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); currentWeather.date = moment(); currentWeather.humidity = data.current_conditions.relative_humidity; @@ -50,7 +50,7 @@ WeatherProvider.register("weatherflow", { const days = []; for (const forecast of data.forecast.daily) { - const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); weather.date = moment.unix(forecast.day_start_local); weather.minTemperature = forecast.air_temp_low; diff --git a/modules/default/weather/providers/weathergov.js b/modules/default/weather/providers/weathergov.js index 5fa4a60408..28013c9844 100644 --- a/modules/default/weather/providers/weathergov.js +++ b/modules/default/weather/providers/weathergov.js @@ -201,7 +201,7 @@ WeatherProvider.register("weathergov", { * ... object needs data in units based on config! */ generateWeatherObjectFromCurrentWeather(currentWeatherData) { - const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); currentWeather.date = moment(currentWeatherData.timestamp); currentWeather.temperature = currentWeatherData.temperature.value; @@ -247,7 +247,7 @@ WeatherProvider.register("weathergov", { let maxTemp = []; // variable for date let date = ""; - let weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + let weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); weather.precipitation = 0; for (const forecast of forecasts) { @@ -259,7 +259,7 @@ WeatherProvider.register("weathergov", { // push weather information to days array days.push(weather); // create new weather-object - weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); minTemp = []; maxTemp = []; diff --git a/modules/default/weather/weather.js b/modules/default/weather/weather.js index c874bc5131..fc5ce285c4 100644 --- a/modules/default/weather/weather.js +++ b/modules/default/weather/weather.js @@ -13,7 +13,6 @@ Module.register("weather", { roundTemp: false, type: "current", // current, forecast, daily (equivalent to forecast), hourly (only with OpenWeatherMap /onecall endpoint) units: config.units, - useKmh: false, tempUnits: config.units, windUnits: config.units, updateInterval: 10 * 60 * 1000, // every 10 minutes @@ -23,7 +22,6 @@ Module.register("weather", { showPeriodUpper: false, showWindDirection: true, showWindDirectionAsArrow: false, - useBeaufort: true, lang: config.language, showHumidity: false, showSun: true, @@ -77,6 +75,14 @@ Module.register("weather", { start: function () { moment.locale(this.config.lang); + if (this.config.useKmh) { + console.warn("Your are using the deprecated config values 'useKmh'. Please switch to windUnits!"); + this.windUnits = "kmh"; + } else if (this.config.useBeaufort) { + console.warn("Your are using the deprecated config values 'useBeaufort'. Please switch to windUnits!"); + this.windUnits = "beaufort"; + } + // Initialize the weather provider. this.weatherProvider = WeatherProvider.initialize(this.config.weatherProvider, this); @@ -206,23 +212,27 @@ Module.register("weather", { }, convertWind(windInMS) { - if (this.config.useBeaufort) { - return this.beaufortWindSpeed(windInMS); - } else if (this.config.useKmh) { - return (windInMS * 60 * 60) / 1000; - } else if (this.config.windUnits === "imperial") return windInMS * 2.23694; - - return windInMS; + switch (this.config.windUnits) { + case "beaufort": + return this.beaufortWindSpeed(windInMS); + case "kmh": + return (windInMS * 3600) / 1000; + case "imperial": + return windInMS * 2.2369362920544; + case "metric": + default: + return windInMS; + } }, /** - * Convert wind (from m/s) if required + * Convert wind (from m/s) to beaufort scale * * @param {number} speedInMS * @returns {number} */ beaufortWindSpeed(speedInMS) { - const windInKmh = this.config.windUnits === "imperial" ? speedInMS * 1.609344 : this.config.useKmh ? speedInMS : (speedInMS * 60 * 60) / 1000; + const windInKmh = (speedInMS * 3600) / 1000; const speeds = [1, 5, 11, 19, 28, 38, 49, 61, 74, 88, 102, 117, 1000]; for (const [index, speed] of speeds.entries()) { if (speed > windInKmh) { diff --git a/modules/default/weather/weatherobject.js b/modules/default/weather/weatherobject.js index 087ea39652..d82da138a2 100644 --- a/modules/default/weather/weatherobject.js +++ b/modules/default/weather/weatherobject.js @@ -18,13 +18,11 @@ class WeatherObject { * @param {string} units what units to use, "imperial" or "metric" * @param {string} tempUnits what tempunits to use * @param {string} windUnits what windunits to use - * @param {boolean} useKmh use kmh if true, mps if false */ - constructor(units, tempUnits, windUnits, useKmh) { + constructor(units, tempUnits, windUnits) { this.units = units; this.tempUnits = tempUnits; this.windUnits = windUnits; - this.useKmh = useKmh; this.date = null; this.windSpeed = null; this.windDirection = null; @@ -112,10 +110,6 @@ class WeatherObject { return kmh * 0.27777777777778; } - kmhWindSpeed() { - return this.windUnits === "imperial" ? this.windSpeed * 1.609344 : (this.windSpeed * 60 * 60) / 1000; - } - nextSunAction() { return moment().isBetween(this.sunrise, this.sunset) ? "sunset" : "sunrise"; } @@ -124,8 +118,8 @@ class WeatherObject { if (this.feelsLikeTemp) { return this.feelsLikeTemp; } - const windInMph = this.windUnits === "imperial" ? this.windSpeed : this.windSpeed * 2.23694; - const tempInF = this.tempUnits === "imperial" ? this.temperature : (this.temperature * 9) / 5 + 32; + const windInMph = this.windSpeed * 2.2369362920544; + const tempInF = (this.temperature * 9) / 5 + 32; let feelsLike = tempInF; if (windInMph > 3 && tempInF < 50) { From e68a9abfb5826c5eae32ac3a2fbe8a6abcd14ce1 Mon Sep 17 00:00:00 2001 From: veeck Date: Fri, 16 Sep 2022 23:52:53 +0200 Subject: [PATCH 15/21] Add knots to possible windUnits --- modules/default/weather/weather.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/default/weather/weather.js b/modules/default/weather/weather.js index fc5ce285c4..523949aba6 100644 --- a/modules/default/weather/weather.js +++ b/modules/default/weather/weather.js @@ -217,6 +217,8 @@ Module.register("weather", { return this.beaufortWindSpeed(windInMS); case "kmh": return (windInMS * 3600) / 1000; + case "knots": + return windInMS * 1.943844; case "imperial": return windInMS * 2.2369362920544; case "metric": From fc16b3e2de22b3630e8124c94bfa63788f265995 Mon Sep 17 00:00:00 2001 From: veeck Date: Sun, 18 Sep 2022 22:02:06 +0200 Subject: [PATCH 16/21] Remove last usage of units from weatherobject, simplify constructor --- modules/default/weather/providers/darksky.js | 4 ++-- .../default/weather/providers/envcanada.js | 8 ++++---- .../weather/providers/openweathermap.js | 20 +++++++++---------- modules/default/weather/providers/smhi.js | 5 ++--- .../default/weather/providers/ukmetoffice.js | 4 ++-- .../weather/providers/ukmetofficedatahub.js | 4 ++-- .../default/weather/providers/weatherbit.js | 4 ++-- .../default/weather/providers/weatherflow.js | 4 ++-- .../default/weather/providers/weathergov.js | 6 +++--- modules/default/weather/weatherobject.js | 11 ++-------- 10 files changed, 31 insertions(+), 39 deletions(-) diff --git a/modules/default/weather/providers/darksky.js b/modules/default/weather/providers/darksky.js index f6a5c2da36..aa48a12bd8 100644 --- a/modules/default/weather/providers/darksky.js +++ b/modules/default/weather/providers/darksky.js @@ -67,7 +67,7 @@ WeatherProvider.register("darksky", { // Implement WeatherDay generator. generateWeatherDayFromCurrentWeather(currentWeatherData) { - const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + const currentWeather = new WeatherObject(); currentWeather.date = moment(); currentWeather.humidity = parseFloat(currentWeatherData.currently.humidity); @@ -85,7 +85,7 @@ WeatherProvider.register("darksky", { const days = []; for (const forecast of forecasts) { - const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + const weather = new WeatherObject(); weather.date = moment.unix(forecast.time); weather.minTemperature = forecast.temperatureMin; diff --git a/modules/default/weather/providers/envcanada.js b/modules/default/weather/providers/envcanada.js index d843ff504f..fdea195bf0 100644 --- a/modules/default/weather/providers/envcanada.js +++ b/modules/default/weather/providers/envcanada.js @@ -146,7 +146,7 @@ WeatherProvider.register("envcanada", { // generateWeatherObjectFromCurrentWeather(ECdoc) { - const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + const currentWeather = new WeatherObject(); // There are instances where EC will update weather data and current temperature will not be // provided. While this is a defect in the EC systems, we need to accommodate to avoid a current temp @@ -221,7 +221,7 @@ WeatherProvider.register("envcanada", { const days = []; - const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + const weather = new WeatherObject(); const foreBaseDates = ECdoc.querySelectorAll("siteData forecastGroup dateTime"); const baseDate = foreBaseDates[1].querySelector("timeStamp").textContent; @@ -331,7 +331,7 @@ WeatherProvider.register("envcanada", { let lastDate = moment(baseDate, "YYYYMMDDhhmmss"); for (let stepDay = nextDay; stepDay < lastDay; stepDay += 2) { - let weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + let weather = new WeatherObject(); // Add 1 to the date to reflect the current forecast day we are building @@ -385,7 +385,7 @@ WeatherProvider.register("envcanada", { const hourGroup = ECdoc.querySelectorAll("siteData hourlyForecastGroup hourlyForecast"); for (let stepHour = 0; stepHour < 24; stepHour += 1) { - const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + const weather = new WeatherObject(); // Determine local time by applying UTC offset to the forecast timestamp diff --git a/modules/default/weather/providers/openweathermap.js b/modules/default/weather/providers/openweathermap.js index 9d216403a5..f5f786fa01 100644 --- a/modules/default/weather/providers/openweathermap.js +++ b/modules/default/weather/providers/openweathermap.js @@ -125,7 +125,7 @@ WeatherProvider.register("openweathermap", { * Generate a WeatherObject based on currentWeatherInformation */ generateWeatherObjectFromCurrentWeather(currentWeatherData) { - const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + const currentWeather = new WeatherObject(); currentWeather.date = moment.unix(currentWeatherData.dt); currentWeather.humidity = currentWeatherData.main.humidity; @@ -150,7 +150,7 @@ WeatherProvider.register("openweathermap", { return this.fetchForecastDaily(forecasts); } // if weatherEndpoint does not match forecast or forecast/daily, what should be returned? - return [new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits)]; + return [new WeatherObject()]; }, /* @@ -161,7 +161,7 @@ WeatherProvider.register("openweathermap", { return this.fetchOnecall(data); } // if weatherEndpoint does not match onecall, what should be returned? - return { current: new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits), hours: [], days: [] }; + return { current: new WeatherObject(), hours: [], days: [] }; }, /* @@ -177,7 +177,7 @@ WeatherProvider.register("openweathermap", { let snow = 0; // variable for date let date = ""; - let weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + let weather = new WeatherObject(); for (const forecast of forecasts) { if (date !== moment.unix(forecast.dt).format("YYYY-MM-DD")) { @@ -190,7 +190,7 @@ WeatherProvider.register("openweathermap", { // push weather information to days array days.push(weather); // create new weather-object - weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + weather = new WeatherObject(); minTemp = []; maxTemp = []; @@ -253,7 +253,7 @@ WeatherProvider.register("openweathermap", { const days = []; for (const forecast of forecasts) { - const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + const weather = new WeatherObject(); weather.date = moment.unix(forecast.dt); weather.minTemperature = forecast.temp.min; @@ -299,7 +299,7 @@ WeatherProvider.register("openweathermap", { let precip = false; // get current weather, if requested - const current = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + const current = new WeatherObject(); if (data.hasOwnProperty("current")) { current.date = moment.unix(data.current.dt).utcOffset(data.timezone_offset / 60); current.windSpeed = data.current.wind_speed; @@ -331,7 +331,7 @@ WeatherProvider.register("openweathermap", { current.feelsLikeTemp = data.current.feels_like; } - let weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + let weather = new WeatherObject(); // get hourly weather, if requested const hours = []; @@ -366,7 +366,7 @@ WeatherProvider.register("openweathermap", { } hours.push(weather); - weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + weather = new WeatherObject(); } } @@ -405,7 +405,7 @@ WeatherProvider.register("openweathermap", { } days.push(weather); - weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + weather = new WeatherObject(); } } diff --git a/modules/default/weather/providers/smhi.js b/modules/default/weather/providers/smhi.js index d3ff79ac72..60c6961719 100644 --- a/modules/default/weather/providers/smhi.js +++ b/modules/default/weather/providers/smhi.js @@ -134,8 +134,7 @@ WeatherProvider.register("smhi", { * @returns {WeatherObject} The converted weatherdata at the specified location */ convertWeatherDataToObject(weatherData, coordinates) { - // Weather data is only for Sweden and nobody in Sweden would use imperial - let currentWeather = new WeatherObject("metric", "metric", "metric"); + let currentWeather = new WeatherObject(); currentWeather.date = moment(weatherData.validTime); currentWeather.updateSunTime(coordinates.lat, coordinates.lon); @@ -191,7 +190,7 @@ WeatherProvider.register("smhi", { for (const weatherObject of allWeatherObjects) { //If its the first object or if a day/hour change we need to reset the summary object if (!currentWeather || !currentWeather.date.isSame(weatherObject.date, groupBy)) { - currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + currentWeather = new WeatherObject(); dayWeatherTypes = []; currentWeather.temperature = weatherObject.temperature; currentWeather.date = weatherObject.date; diff --git a/modules/default/weather/providers/ukmetoffice.js b/modules/default/weather/providers/ukmetoffice.js index 49c4968473..773d0b37ee 100644 --- a/modules/default/weather/providers/ukmetoffice.js +++ b/modules/default/weather/providers/ukmetoffice.js @@ -75,7 +75,7 @@ WeatherProvider.register("ukmetoffice", { * Generate a WeatherObject based on currentWeatherInformation */ generateWeatherObjectFromCurrentWeather(currentWeatherData) { - const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + const currentWeather = new WeatherObject(); const location = currentWeatherData.SiteRep.DV.Location; // data times are always UTC @@ -125,7 +125,7 @@ WeatherProvider.register("ukmetoffice", { // loop round the (5) periods getting the data // for each period array, Day is [0], Night is [1] for (const period of forecasts.SiteRep.DV.Location.Period) { - const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + const weather = new WeatherObject(); // data times are always UTC const dateStr = period.value; diff --git a/modules/default/weather/providers/ukmetofficedatahub.js b/modules/default/weather/providers/ukmetofficedatahub.js index 2258b274bd..049f9c4da3 100644 --- a/modules/default/weather/providers/ukmetofficedatahub.js +++ b/modules/default/weather/providers/ukmetofficedatahub.js @@ -112,7 +112,7 @@ WeatherProvider.register("ukmetofficedatahub", { // Create a WeatherObject using current weather data (data for the current hour) generateWeatherObjectFromCurrentWeather(currentWeatherData) { - const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + const currentWeather = new WeatherObject(); // Extract the actual forecasts let forecastDataHours = currentWeatherData.features[0].properties.timeSeries; @@ -191,7 +191,7 @@ WeatherProvider.register("ukmetofficedatahub", { // Go through each day in the forecasts for (let day in forecastDataDays) { - const forecastWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + const forecastWeather = new WeatherObject(); // Get date of forecast let forecastDate = moment.utc(forecastDataDays[day].time); diff --git a/modules/default/weather/providers/weatherbit.js b/modules/default/weather/providers/weatherbit.js index c8304d80b7..75f49a6984 100644 --- a/modules/default/weather/providers/weatherbit.js +++ b/modules/default/weather/providers/weatherbit.js @@ -100,7 +100,7 @@ WeatherProvider.register("weatherbit", { let tzOffset = d.getTimezoneOffset(); tzOffset = tzOffset * -1; - const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + const currentWeather = new WeatherObject(); currentWeather.date = moment.unix(currentWeatherData.data[0].ts); currentWeather.humidity = parseFloat(currentWeatherData.data[0].rh); @@ -120,7 +120,7 @@ WeatherProvider.register("weatherbit", { const days = []; for (const forecast of forecasts) { - const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + const weather = new WeatherObject(); weather.date = moment(forecast.datetime, "YYYY-MM-DD"); weather.minTemperature = forecast.min_temp; diff --git a/modules/default/weather/providers/weatherflow.js b/modules/default/weather/providers/weatherflow.js index 88a4c2cb2d..06ab8f71d5 100644 --- a/modules/default/weather/providers/weatherflow.js +++ b/modules/default/weather/providers/weatherflow.js @@ -26,7 +26,7 @@ WeatherProvider.register("weatherflow", { fetchCurrentWeather() { this.fetchData(this.getUrl()) .then((data) => { - const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + const currentWeather = new WeatherObject(); currentWeather.date = moment(); currentWeather.humidity = data.current_conditions.relative_humidity; @@ -50,7 +50,7 @@ WeatherProvider.register("weatherflow", { const days = []; for (const forecast of data.forecast.daily) { - const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + const weather = new WeatherObject(); weather.date = moment.unix(forecast.day_start_local); weather.minTemperature = forecast.air_temp_low; diff --git a/modules/default/weather/providers/weathergov.js b/modules/default/weather/providers/weathergov.js index 28013c9844..84d8033b16 100644 --- a/modules/default/weather/providers/weathergov.js +++ b/modules/default/weather/providers/weathergov.js @@ -201,7 +201,7 @@ WeatherProvider.register("weathergov", { * ... object needs data in units based on config! */ generateWeatherObjectFromCurrentWeather(currentWeatherData) { - const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + const currentWeather = new WeatherObject(); currentWeather.date = moment(currentWeatherData.timestamp); currentWeather.temperature = currentWeatherData.temperature.value; @@ -247,7 +247,7 @@ WeatherProvider.register("weathergov", { let maxTemp = []; // variable for date let date = ""; - let weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + let weather = new WeatherObject(); weather.precipitation = 0; for (const forecast of forecasts) { @@ -259,7 +259,7 @@ WeatherProvider.register("weathergov", { // push weather information to days array days.push(weather); // create new weather-object - weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + weather = new WeatherObject(); minTemp = []; maxTemp = []; diff --git a/modules/default/weather/weatherobject.js b/modules/default/weather/weatherobject.js index d82da138a2..eb90db1aa9 100644 --- a/modules/default/weather/weatherobject.js +++ b/modules/default/weather/weatherobject.js @@ -14,15 +14,8 @@ class WeatherObject { /** * Constructor for a WeatherObject - * - * @param {string} units what units to use, "imperial" or "metric" - * @param {string} tempUnits what tempunits to use - * @param {string} windUnits what windunits to use */ - constructor(units, tempUnits, windUnits) { - this.units = units; - this.tempUnits = tempUnits; - this.windUnits = windUnits; + constructor() { this.date = null; this.windSpeed = null; this.windDirection = null; @@ -137,7 +130,7 @@ class WeatherObject { 1.99 * Math.pow(10, -6) * tempInF * tempInF * this.humidity * this.humidity; } - return this.tempUnits === "imperial" ? feelsLike : ((feelsLike - 32) * 5) / 9; + return ((feelsLike - 32) * 5) / 9; } /** From a9fecbe432f47cb31981fb8dc708807f4fb4317a Mon Sep 17 00:00:00 2001 From: veeck Date: Sun, 2 Oct 2022 11:08:52 +0200 Subject: [PATCH 17/21] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 92864bc48b..a1f013121b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ Special thanks to: @rejas, @sdetweil - Updated da translation - Rework weather module - Use fetch instead of XMLHttpRequest in weatherprovider + - Reworked how weatherproviders handle units - Use unix() method for parsing times, fix suntimes on the way ### Fixed From cf8eb1661b60f41120640419626a3791afae9253 Mon Sep 17 00:00:00 2001 From: veeck Date: Wed, 19 Oct 2022 09:34:12 +0200 Subject: [PATCH 18/21] Update and fix weather tests especially move sunset/sunrise to e2e tests --- modules/default/weather/weather.js | 2 +- .../modules/weather/currentweather_options.js | 2 +- tests/e2e/modules/weather_current_spec.js | 77 ++++--------------- tests/e2e/modules/weather_forecast_spec.js | 2 +- tests/electron/helpers/weather-setup.js | 29 +++++++ tests/electron/modules/weather_spec.js | 28 +++++++ 6 files changed, 76 insertions(+), 64 deletions(-) create mode 100644 tests/electron/helpers/weather-setup.js create mode 100644 tests/electron/modules/weather_spec.js diff --git a/modules/default/weather/weather.js b/modules/default/weather/weather.js index 523949aba6..d68e5a36ad 100644 --- a/modules/default/weather/weather.js +++ b/modules/default/weather/weather.js @@ -208,7 +208,7 @@ Module.register("weather", { * @returns {number} */ convertTemp(tempInC) { - return this.config.tempUnits === "imperial" ? tempInC * 1.8 + 32 : tempInC; + return this.config.tempUnits === "imperial" ? this.roundValue(tempInC * 1.8 + 32) : tempInC; }, convertWind(windInMS) { diff --git a/tests/configs/modules/weather/currentweather_options.js b/tests/configs/modules/weather/currentweather_options.js index bd433f6435..2dd9216327 100644 --- a/tests/configs/modules/weather/currentweather_options.js +++ b/tests/configs/modules/weather/currentweather_options.js @@ -11,7 +11,7 @@ let config = { config: { location: "Munich", mockData: '"#####WEATHERDATA#####"', - useBeaufort: false, + windUnits: "beaufort", showWindDirectionAsArrow: true, showSun: false, showHumidity: true, diff --git a/tests/e2e/modules/weather_current_spec.js b/tests/e2e/modules/weather_current_spec.js index 694782b160..daa792bbdb 100644 --- a/tests/e2e/modules/weather_current_spec.js +++ b/tests/e2e/modules/weather_current_spec.js @@ -14,39 +14,15 @@ describe("Weather module", () => { }); it("should render wind speed and wind direction", async () => { - await weatherFunc.getText(".weather .normal.medium span:nth-child(2)", "6 WSW"); // now "12" + await weatherFunc.getText(".weather .normal.medium span:nth-child(2)", "12 WSW"); }); it("should render temperature with icon", async () => { - await weatherFunc.getText(".weather .large.light span.bright", "1.5°"); // now "1°C" + await weatherFunc.getText(".weather .large.light span.bright", "1.5°"); }); it("should render feels like temperature", async () => { - await weatherFunc.getText(".weather .normal.medium.feelslike span.dimmed", "Feels like -5.6°"); // now "Feels like -6°C" - }); - }); - - describe("Default configuration with sunrise", () => { - beforeAll(async () => { - const sunrise = moment().startOf("day").unix(); - const sunset = moment().startOf("day").unix(); - await weatherFunc.startApp("tests/configs/modules/weather/currentweather_default.js", { sys: { sunrise, sunset } }); - }); - - it("should render sunrise", async () => { - await weatherFunc.getText(".weather .normal.medium span:nth-child(4)", "12:00 am"); - }); - }); - - describe("Default configuration with sunset", () => { - beforeAll(async () => { - const sunrise = moment().startOf("day").unix(); - const sunset = moment().endOf("day").unix(); - await weatherFunc.startApp("tests/configs/modules/weather/currentweather_default.js", { sys: { sunrise, sunset } }); - }); - - it("should render sunset", async () => { - await weatherFunc.getText(".weather .normal.medium span:nth-child(4)", "11:59 pm"); + await weatherFunc.getText(".weather .normal.medium.feelslike span.dimmed", "Feels like -5.6°"); }); }); }); @@ -66,65 +42,44 @@ describe("Weather module", () => { await weatherFunc.startApp("tests/configs/modules/weather/currentweather_options.js", {}); }); - it("should render useBeaufort = false", async () => { - await weatherFunc.getText(".weather .normal.medium span:nth-child(2)", "12"); + it("should render windUnits in beaufort", async () => { + await weatherFunc.getText(".weather .normal.medium span:nth-child(2)", "6"); }); - it("should render showWindDirectionAsArrow = true", async () => { + it("should render windDirection with an arrow", async () => { const elem = await helpers.waitForElement(".weather .normal.medium sup i.fa-long-arrow-alt-up"); expect(elem).not.toBe(null); expect(elem.outerHTML).toContain("transform:rotate(250deg);"); }); - it("should render showHumidity = true", async () => { + it("should render humidity", async () => { await weatherFunc.getText(".weather .normal.medium span:nth-child(3)", "93.7"); }); - it("should render degreeLabel = true for temp", async () => { + it("should render degreeLabel for temp", async () => { await weatherFunc.getText(".weather .large.light span.bright", "1°C"); }); - it("should render degreeLabel = true for feels like", async () => { + it("should render degreeLabel for feels like", async () => { await weatherFunc.getText(".weather .normal.medium.feelslike span.dimmed", "Feels like -6°C"); }); }); - describe("Current weather units", () => { + describe("Current weather with imperial units", () => { beforeAll(async () => { - await weatherFunc.startApp("tests/configs/modules/weather/currentweather_units.js", { - main: { - temp: (1.49 * 9) / 5 + 32, - temp_min: (1 * 9) / 5 + 32, - temp_max: (2 * 9) / 5 + 32 - }, - wind: { - speed: 11.8 * 2.23694 - } - }); - }); - - it("should render imperial units for wind", async () => { - await weatherFunc.getText(".weather .normal.medium span:nth-child(2)", "6 WSW"); - }); - - it("should render imperial units for temp", async () => { - await weatherFunc.getText(".weather .large.light span.bright", "34,7°"); - }); - - it("should render imperial units for feels like", async () => { - await weatherFunc.getText(".weather .normal.medium.feelslike span.dimmed", "Feels like 22,0°"); + await weatherFunc.startApp("tests/configs/modules/weather/currentweather_units.js", {}); }); - it("should render custom decimalSymbol = ',' for humidity", async () => { - await weatherFunc.getText(".weather .normal.medium span:nth-child(3)", "93,7"); + it("should render wind in imperial units", async () => { + await weatherFunc.getText(".weather .normal.medium span:nth-child(2)", "26 WSW"); }); - it("should render custom decimalSymbol = ',' for temp", async () => { + it("should render temperatures in fahrenheit", async () => { await weatherFunc.getText(".weather .large.light span.bright", "34,7°"); }); - it("should render custom decimalSymbol = ',' for feels like", async () => { - await weatherFunc.getText(".weather .normal.medium.feelslike span.dimmed", "Feels like 22,0°"); + it("should render 'feels like' in fahrenheit", async () => { + await weatherFunc.getText(".weather .normal.medium.feelslike span.dimmed", "Feels like 21,9°"); }); }); }); diff --git a/tests/e2e/modules/weather_forecast_spec.js b/tests/e2e/modules/weather_forecast_spec.js index 9268c6d157..cd03691609 100644 --- a/tests/e2e/modules/weather_forecast_spec.js +++ b/tests/e2e/modules/weather_forecast_spec.js @@ -86,7 +86,7 @@ describe("Weather module: Weather Forecast", () => { await weatherFunc.startApp("tests/configs/modules/weather/forecastweather_units.js", {}); }); - const temperatures = ["24_4°", "21_0°", "22_9°", "23_4°", "20_6°"]; + const temperatures = ["75_9°", "69_8°", "73_2°", "74_1°", "69_1°"]; for (const [index, temp] of temperatures.entries()) { it("should render custom decimalSymbol = '_' for temp " + temp, async () => { await weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(3)`, temp); diff --git a/tests/electron/helpers/weather-setup.js b/tests/electron/helpers/weather-setup.js new file mode 100644 index 0000000000..2c9b9ad1f5 --- /dev/null +++ b/tests/electron/helpers/weather-setup.js @@ -0,0 +1,29 @@ +const helpers = require("./global-setup"); +const path = require("path"); +const fs = require("fs"); +const { generateWeather, generateWeatherForecast } = require("../../mocks/weather_test"); + +exports.getText = async (element, result) => { + const elem = await helpers.getElement(element); + await expect(elem).not.toBe(null); + const text = await elem.textContent(); + await expect( + text + .trim() + .replace(/(\r\n|\n|\r)/gm, "") + .replace(/[ ]+/g, " ") + ).toBe(result); +}; + +exports.startApp = async (configFile, systemDate) => { + let mockWeather; + if (configFile.includes("forecast")) { + mockWeather = generateWeatherForecast(); + } else { + mockWeather = generateWeather(); + } + let content = fs.readFileSync(path.resolve(__dirname + "../../../../" + configFile)).toString(); + content = content.replace("#####WEATHERDATA#####", mockWeather); + fs.writeFileSync(path.resolve(__dirname + "../../../../config/config.js"), content); + await helpers.startApplication("", systemDate); +}; diff --git a/tests/electron/modules/weather_spec.js b/tests/electron/modules/weather_spec.js new file mode 100644 index 0000000000..fe77743110 --- /dev/null +++ b/tests/electron/modules/weather_spec.js @@ -0,0 +1,28 @@ +const helpers = require("../helpers/global-setup"); +const weatherHelper = require("../helpers/weather-setup"); + +describe("Weather module", () => { + afterEach(async () => { + await helpers.stopApplication(); + }); + + describe("Current weather with sunrise", () => { + beforeAll(async () => { + await weatherHelper.startApp("tests/configs/modules/weather/currentweather_default.js", "13 Jan 2019 00:30:00 GMT"); + }); + + it("should render sunrise", async () => { + await weatherHelper.getText(".weather .normal.medium span:nth-child(4)", "7:00 am"); + }); + }); + + describe("Current weather with sunset", () => { + beforeAll(async () => { + await weatherHelper.startApp("tests/configs/modules/weather/currentweather_default.js", "13 Jan 2019 12:30:00 GMT"); + }); + + it("should render sunset", async () => { + await weatherHelper.getText(".weather .normal.medium span:nth-child(4)", "3:45 pm"); + }); + }); +}); From d51f1557a4e76a66da49f904f40289e6ffa4734a Mon Sep 17 00:00:00 2001 From: veeck Date: Wed, 19 Oct 2022 11:43:17 +0200 Subject: [PATCH 19/21] Cleanup logging --- modules/default/weather/providers/smhi.js | 2 +- modules/default/weather/weather.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/default/weather/providers/smhi.js b/modules/default/weather/providers/smhi.js index 60c6961719..bb0d2cb2e7 100644 --- a/modules/default/weather/providers/smhi.js +++ b/modules/default/weather/providers/smhi.js @@ -75,7 +75,7 @@ WeatherProvider.register("smhi", { setConfig(config) { this.config = config; if (!config.precipitationValue || ["pmin", "pmean", "pmedian", "pmax"].indexOf(config.precipitationValue) === -1) { - console.log("invalid or not set: " + config.precipitationValue); + Log.log("invalid or not set: " + config.precipitationValue); config.precipitationValue = this.defaults.precipitationValue; } }, diff --git a/modules/default/weather/weather.js b/modules/default/weather/weather.js index d68e5a36ad..f540f2eb1b 100644 --- a/modules/default/weather/weather.js +++ b/modules/default/weather/weather.js @@ -76,10 +76,10 @@ Module.register("weather", { moment.locale(this.config.lang); if (this.config.useKmh) { - console.warn("Your are using the deprecated config values 'useKmh'. Please switch to windUnits!"); + Log.warn("Your are using the deprecated config values 'useKmh'. Please switch to windUnits!"); this.windUnits = "kmh"; } else if (this.config.useBeaufort) { - console.warn("Your are using the deprecated config values 'useBeaufort'. Please switch to windUnits!"); + Log.warn("Your are using the deprecated config values 'useBeaufort'. Please switch to windUnits!"); this.windUnits = "beaufort"; } From 4094ebbd93e90deeacb0f543633ff77cb0bf9cde Mon Sep 17 00:00:00 2001 From: veeck Date: Wed, 19 Oct 2022 16:51:37 +0200 Subject: [PATCH 20/21] Update jsdoc --- modules/default/weather/weather.js | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/modules/default/weather/weather.js b/modules/default/weather/weather.js index f540f2eb1b..58780b32c9 100644 --- a/modules/default/weather/weather.js +++ b/modules/default/weather/weather.js @@ -202,15 +202,25 @@ Module.register("weather", { }, /** - * Convert temp (from degrees C) if required + * Convert temp (from degrees C) into imperial or metric unit depending on + * your config * - * @param {number} tempInC - * @returns {number} + * @param {number} tempInC the temperature you want to convert in celsius + * @returns {number} the temperature converted to what is defined in the config */ convertTemp(tempInC) { return this.config.tempUnits === "imperial" ? this.roundValue(tempInC * 1.8 + 32) : tempInC; }, + /** + * + * Convert wind speed (from meters per second) into whatever is defined in + * your config. Can be 'beaufort', 'kmh', 'knots, 'imperial' (mph) or + * 'metric' (mps) + * + * @param {number} windInMS the windspeed you want to convert + * @returns {number} the windspeed converted to what is defined in the config + */ convertWind(windInMS) { switch (this.config.windUnits) { case "beaufort": @@ -230,8 +240,8 @@ Module.register("weather", { /** * Convert wind (from m/s) to beaufort scale * - * @param {number} speedInMS - * @returns {number} + * @param {number} speedInMS the windspeed you want to convert + * @returns {number} the speed in beaufort */ beaufortWindSpeed(speedInMS) { const windInKmh = (speedInMS * 3600) / 1000; From 6cd855774c095f9c7ab81a13438ec3b3c2055f61 Mon Sep 17 00:00:00 2001 From: veeck Date: Thu, 20 Oct 2022 11:35:04 +0200 Subject: [PATCH 21/21] Final cleanups --- modules/default/weather/providers/weathergov.js | 4 ++-- tests/e2e/modules/weather_current_spec.js | 1 - tests/unit/functions/weather_object_spec.js | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/modules/default/weather/providers/weathergov.js b/modules/default/weather/providers/weathergov.js index 84d8033b16..7e39335ab7 100644 --- a/modules/default/weather/providers/weathergov.js +++ b/modules/default/weather/providers/weathergov.js @@ -171,7 +171,7 @@ WeatherProvider.register("weathergov", { const days = []; // variable for date - let weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + let weather = new WeatherObject(); for (const forecast of forecasts) { weather.date = moment(forecast.startTime.slice(0, 19)); if (forecast.windSpeed.search(" ") < 0) { @@ -187,7 +187,7 @@ WeatherProvider.register("weathergov", { days.push(weather); - weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + weather = new WeatherObject(); } // push weather information to days array diff --git a/tests/e2e/modules/weather_current_spec.js b/tests/e2e/modules/weather_current_spec.js index daa792bbdb..97ae3eec85 100644 --- a/tests/e2e/modules/weather_current_spec.js +++ b/tests/e2e/modules/weather_current_spec.js @@ -1,4 +1,3 @@ -const moment = require("moment"); const helpers = require("../helpers/global-setup"); const weatherFunc = require("../helpers/weather-functions"); diff --git a/tests/unit/functions/weather_object_spec.js b/tests/unit/functions/weather_object_spec.js index 17b22cf2be..57535e70e8 100644 --- a/tests/unit/functions/weather_object_spec.js +++ b/tests/unit/functions/weather_object_spec.js @@ -10,7 +10,7 @@ describe("WeatherObject", () => { beforeAll(() => { originalTimeZone = moment.tz.guess(); moment.tz.setDefault("Africa/Dar_es_Salaam"); - weatherobject = new WeatherObject("metric", "metric", "metric", true); + weatherobject = new WeatherObject(); }); it("should return true for daytime at noon", () => {